blob: a2056cfc0e9164431ba40280731f8de56387f671 [file] [log] [blame]
// 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 <pango/pango-attributes.h>
#include <string>
#include <utility>
#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<PangoUnderline>(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