Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1152)

Side by Side Diff: ui/gfx/render_text_unittest.cc

Issue 351963002: RenderTextHarfBuzz: Allow mid-glyph cursors in multi-grapheme clusters (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments addressed Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/render_text.h" 5 #include "ui/gfx/render_text.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 1992 matching lines...) Expand 10 before | Expand all | Expand 10 after
2003 2003
2004 render_text->SetText(WideToUTF16(L"x \x25B6 y")); 2004 render_text->SetText(WideToUTF16(L"x \x25B6 y"));
2005 render_text->EnsureLayout(); 2005 render_text->EnsureLayout();
2006 ASSERT_EQ(3U, render_text->runs_.size()); 2006 ASSERT_EQ(3U, render_text->runs_.size());
2007 EXPECT_EQ(Range(0, 2), render_text->runs_[0]->range); 2007 EXPECT_EQ(Range(0, 2), render_text->runs_[0]->range);
2008 EXPECT_EQ(Range(2, 3), render_text->runs_[1]->range); 2008 EXPECT_EQ(Range(2, 3), render_text->runs_[1]->range);
2009 EXPECT_EQ(Range(3, 5), render_text->runs_[2]->range); 2009 EXPECT_EQ(Range(3, 5), render_text->runs_[2]->range);
2010 } 2010 }
2011 #endif // defined(OS_WIN) 2011 #endif // defined(OS_WIN)
2012 2012
2013 TEST_F(RenderTextTest, HarfBuzz_CharToGlyph) { 2013 // Test TextRunHarfBuzz's cluster finding logic.
2014 TEST_F(RenderTextTest, HarfBuzz_Clusters) {
2014 struct { 2015 struct {
2015 uint32 glyph_to_char[4]; 2016 uint32 glyph_to_char[4];
2016 size_t char_to_glyph_expected[4]; 2017 Range chars[4];
2017 Range char_range_to_glyph_range_expected[4]; 2018 Range glyphs[4];
2018 bool is_rtl; 2019 bool is_rtl;
2019 } cases[] = { 2020 } cases[] = {
2020 { // From string "A B C D" to glyphs "a b c d". 2021 { // From string "A B C D" to glyphs "a b c d".
2021 { 0, 1, 2, 3 }, 2022 { 0, 1, 2, 3 },
2022 { 0, 1, 2, 3 }, 2023 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) },
2023 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) }, 2024 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) },
2024 false 2025 false
2025 }, 2026 },
2026 { // From string "A B C D" to glyphs "d b c a". 2027 { // From string "A B C D" to glyphs "d c b a".
2027 { 3, 2, 1, 0 }, 2028 { 3, 2, 1, 0 },
2028 { 3, 2, 1, 0 }, 2029 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) },
2029 { Range(3, 4), Range(2, 3), Range(1, 2), Range(0, 1) }, 2030 { Range(3, 4), Range(2, 3), Range(1, 2), Range(0, 1) },
2030 true 2031 true
2031 }, 2032 },
2032 { // From string "A B C D" to glyphs "ab c c d". 2033 { // From string "A B C D" to glyphs "ab c c d".
2033 { 0, 2, 2, 3 }, 2034 { 0, 2, 2, 3 },
2034 { 0, 0, 1, 3 }, 2035 { Range(0, 2), Range(0, 2), Range(2, 3), Range(3, 4) },
2035 { Range(0, 1), Range(0, 1), Range(1, 3), Range(3, 4) }, 2036 { Range(0, 1), Range(0, 1), Range(1, 3), Range(3, 4) },
2036 false 2037 false
2037 }, 2038 },
2038 { // From string "A B C D" to glyphs "d c c ba". 2039 { // From string "A B C D" to glyphs "d c c ba".
2039 { 3, 2, 2, 0 }, 2040 { 3, 2, 2, 0 },
2040 { 3, 3, 1, 0 }, 2041 { Range(0, 2), Range(0, 2), Range(2, 3), Range(3, 4) },
2041 { Range(3, 4), Range(3, 4), Range(1, 3), Range(0, 1) }, 2042 { Range(3, 4), Range(3, 4), Range(1, 3), Range(0, 1) },
2042 true 2043 true
2043 }, 2044 },
2044 }; 2045 };
2045 2046
2046 internal::TextRunHarfBuzz run; 2047 internal::TextRunHarfBuzz run;
2047 run.range = Range(0, 4); 2048 run.range = Range(0, 4);
2048 run.glyph_count = 4; 2049 run.glyph_count = 4;
2049 run.glyph_to_char.reset(new uint32[4]); 2050 run.glyph_to_char.resize(4);
2050 2051
2051 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 2052 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2052 std::copy(cases[i].glyph_to_char, cases[i].glyph_to_char + 4, 2053 std::copy(cases[i].glyph_to_char, cases[i].glyph_to_char + 4,
2053 run.glyph_to_char.get()); 2054 run.glyph_to_char.begin());
2054 run.is_rtl = cases[i].is_rtl; 2055 run.is_rtl = cases[i].is_rtl;
2056
2055 for (size_t j = 0; j < 4; ++j) { 2057 for (size_t j = 0; j < 4; ++j) {
2056 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS ", char %" PRIuS, i, j)); 2058 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS ", char %" PRIuS, i, j));
2057 EXPECT_EQ(cases[i].char_to_glyph_expected[j], run.CharToGlyph(j)); 2059 Range chars;
2058 EXPECT_EQ(cases[i].char_range_to_glyph_range_expected[j], 2060 Range glyphs;
2059 run.CharRangeToGlyphRange(Range(j, j + 1))); 2061 run.GetClusterAt(j, &chars, &glyphs);
2062 EXPECT_EQ(cases[i].chars[j], chars);
2063 EXPECT_EQ(cases[i].glyphs[j], glyphs);
2064 EXPECT_EQ(cases[i].glyphs[j], run.CharRangeToGlyphRange(chars));
2060 } 2065 }
2061 } 2066 }
2062 } 2067 }
2068
2069 // Ensure that graphemes with multiple code points do not get split.
2070 TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemeCases) {
2071 const base::string16 cases[] = {
2072 // "A" with a combining umlaut, followed by a "B".
2073 L"A\x0308" L"B",
2074 // Devanagari biconsonantal conjunct "ki", followed by an "a".
2075 L"\x0915\x093f\x0905",
2076 // Thai consonant and vowel pair "cho chan" + "sara am", followed by Thai
2077 // digit 0.
2078 L"\x0e08\x0e33\x0E50",
2079 };
2080
2081 RenderTextHarfBuzz render_text;
2082
2083 for (size_t i = 0; i < arraysize(cases); ++i) {
2084 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS, i));
2085
2086 render_text.SetText(cases[i]);
2087 render_text.EnsureLayout();
2088 ASSERT_EQ(1U, render_text.runs_.size());
2089 internal::TextRunHarfBuzz* run = render_text.runs_[0];
2090
2091 base::i18n::BreakIterator* iter = render_text.grapheme_iterator();
2092 Range first_grapheme_bounds = run->GetGraphemeBounds(cases[i], iter, 0);
2093 EXPECT_EQ(first_grapheme_bounds, run->GetGraphemeBounds(cases[i], iter, 1));
2094 Range second_grapheme_bounds = run->GetGraphemeBounds(cases[i], iter, 2);
2095 EXPECT_EQ(first_grapheme_bounds.end(), second_grapheme_bounds.start());
2096 }
2097 }
2098
2099 // Test the partition of a multi-grapheme cluster into grapheme ranges.
2100 TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemePartition) {
2101 struct {
2102 uint32 glyph_to_char[2];
2103 Range bounds[4];
2104 bool is_rtl;
2105 } cases[] = {
2106 { // From string "A B C D" to glyphs "a bcd".
2107 { 0, 1 },
2108 { Range(0, 10), Range(10, 13), Range(13, 17), Range(17, 20) },
2109 false
2110 },
2111 { // From string "A B C D" to glyphs "ab cd".
2112 { 0, 2 },
2113 { Range(0, 5), Range(5, 10), Range(10, 15), Range(15, 20) },
2114 false
2115 },
2116 { // From string "A B C D" to glyphs "dcb a".
msw 2014/07/25 00:37:01 nit: maybe add RTL case "dc ba" for good measure?
ckocagil 2014/07/29 23:13:42 Done.
2117 { 1, 0 },
2118 { Range(10, 20), Range(7, 10), Range(3, 7), Range(0, 3) },
2119 true
2120 },
2121 };
2122
2123 internal::TextRunHarfBuzz run;
2124 run.range = Range(0, 4);
2125 run.glyph_count = 2;
2126 run.glyph_to_char.resize(2);
2127 run.positions.reset(new SkPoint[4]);
2128 run.width = 20;
2129
2130 const base::string16 kString = ASCIIToUTF16("abcd");
2131 scoped_ptr<base::i18n::BreakIterator> iter(new base::i18n::BreakIterator(
2132 kString, base::i18n::BreakIterator::BREAK_CHARACTER));
2133 if (!iter->Init())
msw 2014/07/25 00:37:01 Make this ASSERT_TRUE(iter-Init());
ckocagil 2014/07/29 23:13:42 Done.
2134 iter.reset();
2135
2136 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
2137 std::copy(cases[i].glyph_to_char, cases[i].glyph_to_char + 2,
2138 run.glyph_to_char.begin());
2139 run.is_rtl = cases[i].is_rtl;
2140 for (int j = 0; j < 2; ++j)
2141 run.positions[j].set(j * 10, 0);
2142
2143 for (size_t j = 0; j < 4; ++j) {
2144 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS ", char %" PRIuS, i, j));
2145 EXPECT_EQ(cases[i].bounds[j],
2146 run.GetGraphemeBounds(kString, iter.get(), j));
2147 }
2148 }
2149 }
2063 2150
2064 TEST_F(RenderTextTest, HarfBuzz_RunDirection) { 2151 TEST_F(RenderTextTest, HarfBuzz_RunDirection) {
2065 RenderTextHarfBuzz render_text; 2152 RenderTextHarfBuzz render_text;
2066 const base::string16 mixed = 2153 const base::string16 mixed =
2067 WideToUTF16(L"\x05D0\x05D1" L"1234" L"\x05D2\x05D3"); 2154 WideToUTF16(L"\x05D0\x05D1" L"1234" L"\x05D2\x05D3");
2068 render_text.SetText(mixed); 2155 render_text.SetText(mixed);
2069 render_text.EnsureLayout(); 2156 render_text.EnsureLayout();
2070 ASSERT_EQ(3U, render_text.runs_.size()); 2157 ASSERT_EQ(3U, render_text.runs_.size());
2071 EXPECT_TRUE(render_text.runs_[0]->is_rtl); 2158 EXPECT_TRUE(render_text.runs_[0]->is_rtl);
2072 EXPECT_FALSE(render_text.runs_[1]->is_rtl); 2159 EXPECT_FALSE(render_text.runs_[1]->is_rtl);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2207 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2121 render_text->SetText(WideToUTF16(kTestStrings[i])); 2208 render_text->SetText(WideToUTF16(kTestStrings[i]));
2122 render_text->EnsureLayout(); 2209 render_text->EnsureLayout();
2123 2210
2124 for (size_t j = 0; j < render_text->text().length(); ++j) 2211 for (size_t j = 0; j < render_text->text().length(); ++j)
2125 EXPECT_FALSE(render_text->GetGlyphBounds(j).is_empty()); 2212 EXPECT_FALSE(render_text->GetGlyphBounds(j).is_empty());
2126 } 2213 }
2127 } 2214 }
2128 2215
2129 } // namespace gfx 2216 } // namespace gfx
OLDNEW
« ui/gfx/render_text_harfbuzz.cc ('K') | « ui/gfx/render_text_harfbuzz.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698