From 728b7eff5801c696bd5b4c00f7618c15c9c3a102 Mon Sep 17 00:00:00 2001 From: "huangs@chromium.org" Date: Fri, 20 Jun 2014 19:23:48 +0000 Subject: Passing BackgroundColorSpan and UnderlineSpan from Clank to Blink. This CL enables custom color to be specified for IME composition. Its Blink counterpart is https://codereview.chromium.org/313233002/ . Details: - Prerequesite: the Blink change, since we assume WebCore::CompositionUnderline and blink::WebCompositionUnderline have been updated. - Prerequesite CL: https://codereview.chromium.org/319553002/ to allow structures to temporarily mismatch, without triggering compiler assert. - Adding background_color to ui::CompositionUnderline. - To pass data from Android to Native C++, using JNI generator with callback: In C++, ImeAdapterAndroid::SetComposingText() calls Java to iterate over spans, then dispatch BackgroundColorSpan and UnderlineSpan data to C++ code and populate list of blink::WebCompositionUnderline. We'll need to split this CL when we commit. BUG=135900 Review URL: https://codereview.chromium.org/313053007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278794 0039d316-1c4b-4281-b951-d872f2087c98 --- ui/aura/remote_window_tree_host_win.cc | 1 + ui/base/ime/composition_text_util_pango.cc | 11 +- .../ime/composition_text_util_pango_unittest.cc | 113 ++++++++++----------- ui/base/ime/composition_underline.h | 44 ++++---- ui/base/ime/input_method_chromeos.cc | 18 ++-- ui/base/ime/input_method_chromeos_unittest.cc | 10 ++ ui/base/ime/win/imm32_manager.cc | 18 ++-- 7 files changed, 121 insertions(+), 94 deletions(-) (limited to 'ui') diff --git a/ui/aura/remote_window_tree_host_win.cc b/ui/aura/remote_window_tree_host_win.cc index 018406f..0cd5ee8 100644 --- a/ui/aura/remote_window_tree_host_win.cc +++ b/ui/aura/remote_window_tree_host_win.cc @@ -77,6 +77,7 @@ void FillCompositionText( composition_text->underlines[i].end_offset = underlines[i].end_offset; composition_text->underlines[i].color = SK_ColorBLACK; composition_text->underlines[i].thick = underlines[i].thick; + composition_text->underlines[i].background_color = SK_ColorTRANSPARENT; } } diff --git a/ui/base/ime/composition_text_util_pango.cc b/ui/base/ime/composition_text_util_pango.cc index 98dadb6..325cdd6 100644 --- a/ui/base/ime/composition_text_util_pango.cc +++ b/ui/base/ime/composition_text_util_pango.cc @@ -75,8 +75,11 @@ void ExtractCompositionTextFromGtkPreedit(const gchar* utf8_text, if (background_attr || underline_attr) { // Use a black thin underline by default. - CompositionUnderline underline( - char16_offsets[start], char16_offsets[end], SK_ColorBLACK, false); + CompositionUnderline underline(char16_offsets[start], + char16_offsets[end], + SK_ColorBLACK, + false, + SK_ColorTRANSPARENT); // Always use thick underline for a range with background color, which // is usually the selection range. @@ -108,8 +111,8 @@ void ExtractCompositionTextFromGtkPreedit(const gchar* utf8_text, // Use a black thin underline by default. if (composition->underlines.empty()) { - composition->underlines.push_back( - CompositionUnderline(0, length, SK_ColorBLACK, false)); + composition->underlines.push_back(CompositionUnderline( + 0, length, SK_ColorBLACK, false, SK_ColorTRANSPARENT)); } } diff --git a/ui/base/ime/composition_text_util_pango_unittest.cc b/ui/base/ime/composition_text_util_pango_unittest.cc index 957adf1..a2056cf 100644 --- a/ui/base/ime/composition_text_util_pango_unittest.cc +++ b/ui/base/ime/composition_text_util_pango_unittest.cc @@ -28,6 +28,7 @@ struct Underline { unsigned end_offset; uint32 color; bool thick; + uint32 background_color; }; struct TestData { @@ -37,64 +38,59 @@ struct TestData { }; 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 }, - { 4, 7, SK_ColorBLACK, true }, - { 8, 13, SK_ColorBLACK, false }, - { 0, 0, 0, false } } - }, - - // 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 }, - { 4, 7, SK_ColorBLACK, true }, - { 8, 13, SK_ColorBLACK, false }, - { 0, 0, 0, false} } - }, - - // 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 }, - { 4, 7, SK_ColorRED, false }, - { 8, 13, SK_ColorBLACK, false }, - { 0, 0, 0, false} } - }, - - // Default underline. - { "One Two Three", - { { 0, 0, 0, 0 } }, - { { 0, 13, SK_ColorBLACK, false }, - { 0, 0, 0, false } } - }, - - // 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 }, - { 3, 5, SK_ColorBLACK, false }, - { 5, 9, SK_ColorBLACK, true }, - { 9, 15, SK_ColorBLACK, false }, - { 0, 0, 0, false } } - }, + // 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, @@ -103,6 +99,7 @@ void CompareUnderline(const Underline& a, 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) { diff --git a/ui/base/ime/composition_underline.h b/ui/base/ime/composition_underline.h index c8d09d8..a8c44b6 100644 --- a/ui/base/ime/composition_underline.h +++ b/ui/base/ime/composition_underline.h @@ -7,6 +7,7 @@ #include +#include "base/basictypes.h" #include "third_party/skia/include/core/SkColor.h" namespace ui { @@ -15,34 +16,43 @@ namespace ui { // third_party/WebKit/public/web/WebCompositionUnderline.h struct CompositionUnderline { CompositionUnderline() - : start_offset(0), - end_offset(0), - color(0), - thick(false) {} - - CompositionUnderline(unsigned s, unsigned e, SkColor c, bool t) - : start_offset(s), - end_offset(e), - color(c), - thick(t) {} + : start_offset(0), + end_offset(0), + color(SK_ColorTRANSPARENT), + thick(false), + background_color(SK_ColorTRANSPARENT) {} + + // TODO(huangs): remove this constructor. + CompositionUnderline(uint32 s, uint32 e, SkColor c, bool t) + : start_offset(s), + end_offset(e), + color(c), + thick(t), + background_color(SK_ColorTRANSPARENT) {} + + CompositionUnderline(uint32 s, uint32 e, SkColor c, bool t, SkColor bc) + : start_offset(s), + end_offset(e), + color(c), + thick(t), + background_color(bc) {} bool operator==(const CompositionUnderline& rhs) const { return (this->start_offset == rhs.start_offset) && - (this->end_offset == rhs.end_offset) && - (this->color == rhs.color) && - (this->thick == rhs.thick); + (this->end_offset == rhs.end_offset) && (this->color == rhs.color) && + (this->thick == rhs.thick) && + (this->background_color == rhs.background_color); } bool operator!=(const CompositionUnderline& rhs) const { return !(*this == rhs); } - // Though use of unsigned is discouraged, we use it here to make sure it's - // identical to blink::WebCompositionUnderline. - unsigned start_offset; - unsigned end_offset; + uint32 start_offset; + uint32 end_offset; SkColor color; bool thick; + SkColor background_color; }; typedef std::vector CompositionUnderlines; diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index 799b3a3..a37cb72 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc @@ -608,9 +608,11 @@ void InputMethodChromeOS::ExtractCompositionText( const uint32 end = underline_attributes[i].end_index; if (start >= end) continue; - CompositionUnderline underline( - char16_offsets[start], char16_offsets[end], - SK_ColorBLACK, false /* thick */); + CompositionUnderline underline(char16_offsets[start], + char16_offsets[end], + SK_ColorBLACK, + false /* thick */, + SK_ColorTRANSPARENT); if (underline_attributes[i].type == chromeos::CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE) underline.thick = true; @@ -625,9 +627,11 @@ void InputMethodChromeOS::ExtractCompositionText( if (text.selection_start() < text.selection_end()) { const uint32 start = text.selection_start(); const uint32 end = text.selection_end(); - CompositionUnderline underline( - char16_offsets[start], char16_offsets[end], - SK_ColorBLACK, true /* thick */); + CompositionUnderline underline(char16_offsets[start], + char16_offsets[end], + SK_ColorBLACK, + true /* thick */, + SK_ColorTRANSPARENT); out_composition->underlines.push_back(underline); // If the cursor is at start or end of this underline, then we treat @@ -645,7 +649,7 @@ void InputMethodChromeOS::ExtractCompositionText( // Use a black thin underline by default. if (out_composition->underlines.empty()) { out_composition->underlines.push_back(CompositionUnderline( - 0, length, SK_ColorBLACK, false /* thick */)); + 0, length, SK_ColorBLACK, false /* thick */, SK_ColorTRANSPARENT)); } } diff --git a/ui/base/ime/input_method_chromeos_unittest.cc b/ui/base/ime/input_method_chromeos_unittest.cc index 70c786c..0470f0c 100644 --- a/ui/base/ime/input_method_chromeos_unittest.cc +++ b/ui/base/ime/input_method_chromeos_unittest.cc @@ -673,6 +673,8 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_SingleUnderline) { // Single underline represents as black thin line. EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color); EXPECT_FALSE(composition_text.underlines[0].thick); + EXPECT_EQ(static_cast(SK_ColorTRANSPARENT), + composition_text.underlines[0].background_color); } TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_DoubleUnderline) { @@ -703,6 +705,8 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_DoubleUnderline) { // Double underline represents as black thick line. EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color); EXPECT_TRUE(composition_text.underlines[0].thick); + EXPECT_EQ(static_cast(SK_ColorTRANSPARENT), + composition_text.underlines[0].background_color); } TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_ErrorUnderline) { @@ -758,6 +762,8 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_Selection) { composition_text.underlines[0].end_offset); EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color); EXPECT_TRUE(composition_text.underlines[0].thick); + EXPECT_EQ(static_cast(SK_ColorTRANSPARENT), + composition_text.underlines[0].background_color); } TEST_F(InputMethodChromeOSTest, @@ -790,6 +796,8 @@ TEST_F(InputMethodChromeOSTest, composition_text.underlines[0].end_offset); EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color); EXPECT_TRUE(composition_text.underlines[0].thick); + EXPECT_EQ(static_cast(SK_ColorTRANSPARENT), + composition_text.underlines[0].background_color); } TEST_F(InputMethodChromeOSTest, @@ -822,6 +830,8 @@ TEST_F(InputMethodChromeOSTest, composition_text.underlines[0].end_offset); EXPECT_EQ(SK_ColorBLACK, composition_text.underlines[0].color); EXPECT_TRUE(composition_text.underlines[0].thick); + EXPECT_EQ(static_cast(SK_ColorTRANSPARENT), + composition_text.underlines[0].background_color); } TEST_F(InputMethodChromeOSTest, SurroundingText_NoSelectionTest) { diff --git a/ui/base/ime/win/imm32_manager.cc b/ui/base/ime/win/imm32_manager.cc index e1c9e9a..7ad2d87 100644 --- a/ui/base/ime/win/imm32_manager.cc +++ b/ui/base/ime/win/imm32_manager.cc @@ -83,10 +83,11 @@ void GetCompositionUnderlines(HIMC imm_context, underline.end_offset = clause_data[i+1]; underline.color = SK_ColorBLACK; underline.thick = false; + underline.background_color = SK_ColorTRANSPARENT; // Use thick underline for the target clause. - if (underline.start_offset >= static_cast(target_start) && - underline.end_offset <= static_cast(target_end)) { + if (underline.start_offset >= static_cast(target_start) && + underline.end_offset <= static_cast(target_end)) { underline.thick = true; } underlines->push_back(underline); @@ -342,21 +343,22 @@ void IMM32Manager::GetCompositionInfo(HIMC imm_context, LPARAM lparam, if (!composition->underlines.size()) { CompositionUnderline underline; underline.color = SK_ColorBLACK; + underline.background_color = SK_ColorTRANSPARENT; if (target_start > 0) { - underline.start_offset = 0; - underline.end_offset = target_start; + underline.start_offset = 0U; + underline.end_offset = static_cast(target_start); underline.thick = false; composition->underlines.push_back(underline); } if (target_end > target_start) { - underline.start_offset = target_start; - underline.end_offset = target_end; + underline.start_offset = static_cast(target_start); + underline.end_offset = static_cast(target_end); underline.thick = true; composition->underlines.push_back(underline); } if (target_end < length) { - underline.start_offset = target_end; - underline.end_offset = length; + underline.start_offset = static_cast(target_end); + underline.end_offset = static_cast(length); underline.thick = false; composition->underlines.push_back(underline); } -- cgit v1.1