// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/base/ime/composition_text_util_pango.h" #include #include #include #include "base/basictypes.h" #include "base/logging.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/composition_text.h" namespace { struct AttributeInfo { int type; int value; int start_offset; int end_offset; }; struct Underline { unsigned start_offset; unsigned end_offset; uint32 color; bool thick; uint32 background_color; }; struct TestData { const char* text; const AttributeInfo attrs[10]; const Underline underlines[10]; }; const TestData kTestData[] = { // Normal case {"One Two Three", {{PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 0, 3}, {PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_DOUBLE, 4, 7}, {PANGO_ATTR_BACKGROUND, 0, 4, 7}, {PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 8, 13}, {0, 0, 0, 0}}, {{0, 3, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {4, 7, SK_ColorBLACK, true, SK_ColorTRANSPARENT}, {8, 13, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {0, 0, 0, false, SK_ColorTRANSPARENT}}}, // Offset overflow. {"One Two Three", {{PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 0, 3}, {PANGO_ATTR_BACKGROUND, 0, 4, 7}, {PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 8, 20}, {0, 0, 0, 0}}, {{0, 3, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {4, 7, SK_ColorBLACK, true, SK_ColorTRANSPARENT}, {8, 13, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {0, 0, 0, false, SK_ColorTRANSPARENT}}}, // Error underline. {"One Two Three", {{PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 0, 3}, {PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_ERROR, 4, 7}, {PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 8, 13}, {0, 0, 0, 0}}, {{0, 3, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {4, 7, SK_ColorRED, false, SK_ColorTRANSPARENT}, {8, 13, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {0, 0, 0, false, SK_ColorTRANSPARENT}}}, // Default underline. {"One Two Three", {{0, 0, 0, 0}}, {{0, 13, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {0, 0, 0, false, SK_ColorTRANSPARENT}}}, // Unicode, including non-BMP characters: "123你好𠀀𠀁一丁 456" {"123\xE4\xBD\xA0\xE5\xA5\xBD\xF0\xA0\x80\x80\xF0\xA0\x80\x81\xE4\xB8\x80" "\xE4\xB8\x81 456", {{PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 0, 3}, {PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 3, 5}, {PANGO_ATTR_BACKGROUND, 0, 5, 7}, {PANGO_ATTR_UNDERLINE, PANGO_UNDERLINE_SINGLE, 7, 13}, {0, 0, 0, 0}}, {{0, 3, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {3, 5, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {5, 9, SK_ColorBLACK, true, SK_ColorTRANSPARENT}, {9, 15, SK_ColorBLACK, false, SK_ColorTRANSPARENT}, {0, 0, 0, false, SK_ColorTRANSPARENT}}}, }; void CompareUnderline(const Underline& a, const ui::CompositionUnderline& b) { EXPECT_EQ(a.start_offset, b.start_offset); EXPECT_EQ(a.end_offset, b.end_offset); EXPECT_EQ(a.color, b.color); EXPECT_EQ(a.thick, b.thick); EXPECT_EQ(a.background_color, b.background_color); } TEST(CompositionTextUtilPangoTest, ExtractCompositionText) { for (size_t i = 0; i < arraysize(kTestData); ++i) { const char* text = kTestData[i].text; const AttributeInfo* attrs = kTestData[i].attrs; SCOPED_TRACE(testing::Message() << "Testing:" << i << " text:" << text); PangoAttrList* pango_attrs = pango_attr_list_new(); for (size_t a = 0; attrs[a].type; ++a) { PangoAttribute* pango_attr = NULL; switch (attrs[a].type) { case PANGO_ATTR_UNDERLINE: pango_attr = pango_attr_underline_new( static_cast(attrs[a].value)); break; case PANGO_ATTR_BACKGROUND: pango_attr = pango_attr_background_new(0, 0, 0); break; default: NOTREACHED(); } pango_attr->start_index = g_utf8_offset_to_pointer(text, attrs[a].start_offset) - text; pango_attr->end_index = g_utf8_offset_to_pointer(text, attrs[a].end_offset) - text; pango_attr_list_insert(pango_attrs, pango_attr); } ui::CompositionText result; ui::ExtractCompositionTextFromGtkPreedit(text, pango_attrs, 0, &result); const Underline* underlines = kTestData[i].underlines; for (size_t u = 0; underlines[u].color && u < result.underlines.size(); ++u) { SCOPED_TRACE(testing::Message() << "Underline:" << u); CompareUnderline(underlines[u], result.underlines[u]); } pango_attr_list_unref(pango_attrs); } } } // namespace