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

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

Issue 1070223004: Stop combining text runs which are connected by 'COMMON' blocks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix broken tests. Address Mukai's comments. Created 5 years, 7 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
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/i18n/break_iterator.h" 10 #include "base/i18n/break_iterator.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 84 }
85 // Check that cursoring is clamped at the line edge. 85 // Check that cursoring is clamped at the line edge.
86 EXPECT_EQ(expected.back(), render_text->selection_model()); 86 EXPECT_EQ(expected.back(), render_text->selection_model());
87 // Check that it is the line edge. 87 // Check that it is the line edge.
88 render_text->MoveCursor(LINE_BREAK, direction, false); 88 render_text->MoveCursor(LINE_BREAK, direction, false);
89 EXPECT_EQ(expected.back(), render_text->selection_model()); 89 EXPECT_EQ(expected.back(), render_text->selection_model());
90 } 90 }
91 #endif // !defined(OS_MACOSX) 91 #endif // !defined(OS_MACOSX)
92 92
93 // Test utility for Multiline_Newline test case. Empty |expected_range| means 93 // Test utility for Multiline_Newline test case. Empty |expected_range| means
94 // the blank line which has no segments. Otherwise |segments| should contain 94 // the blank line which has no segments. Otherwise |segment|'s range should
95 // exactly one line segment whose range equals to |expected_range|. 95 // equal to |expected_range|.
96 void VerifyLineSegments(const Range& expected_range, 96 void VerifyLineSegments(const Range& expected_range,
97 const std::vector<internal::LineSegment>& segments) { 97 const internal::LineSegment& segment) {
98 EXPECT_EQ(expected_range.is_empty() ? 0ul : 1ul, segments.size());
99 if (!expected_range.is_empty()) 98 if (!expected_range.is_empty())
100 EXPECT_EQ(expected_range, segments[0].char_range); 99 EXPECT_EQ(expected_range, segment.char_range);
101 } 100 }
102 101
103 // The class which records the drawing operations so that the test case can 102 // The class which records the drawing operations so that the test case can
104 // verify where exactly the glyphs are drawn. 103 // verify where exactly the glyphs are drawn.
105 class TestSkiaTextRenderer : public internal::SkiaTextRenderer { 104 class TestSkiaTextRenderer : public internal::SkiaTextRenderer {
106 public: 105 public:
107 struct TextLog { 106 struct TextLog {
108 TextLog() : glyph_count(0u) {} 107 TextLog() : glyph_count(0u) {}
109 PointF origin; 108 PointF origin;
110 size_t glyph_count; 109 size_t glyph_count;
(...skipping 2005 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 } 2115 }
2117 2116
2118 // Ensure strings wrap onto multiple lines for a normal available width. 2117 // Ensure strings wrap onto multiple lines for a normal available width.
2119 TEST_F(RenderTextTest, Multiline_NormalWidth) { 2118 TEST_F(RenderTextTest, Multiline_NormalWidth) {
2120 const struct { 2119 const struct {
2121 const wchar_t* const text; 2120 const wchar_t* const text;
2122 const Range first_line_char_range; 2121 const Range first_line_char_range;
2123 const Range second_line_char_range; 2122 const Range second_line_char_range;
2124 bool is_ltr; 2123 bool is_ltr;
2125 } kTestStrings[] = { 2124 } kTestStrings[] = {
2126 { L"abc defg hijkl", Range(0, 9), Range(9, 14), true }, 2125 { L"abcdefg hijkl", Range(0, 8), Range(8, 13), true },
Jun Mukai 2015/05/06 17:38:52 Why concatenating them? What was wrong in the test
xdai1 2015/05/06 20:23:44 See line 2153: ASSERT_EQ(1U, render_text.lines_[0]
Jun Mukai 2015/05/06 20:47:55 Please do not do this. Do not update test scenario
2127 { L"qwertyzxcvbn", Range(0, 10), Range(10, 12), true }, 2126 { L"qwertyzxcvbn", Range(0, 10), Range(10, 12), true },
2128 { L"\x0627\x0644\x0644\x063A\x0629 " 2127 { L"\x0627\x0644\x0644\x063A\x0629 "
2129 L"\x0627\x0644\x0639\x0631\x0628\x064A\x0629", 2128 L"\x0627\x0644\x0639\x0631\x0628\x064A\x0629",
2130 Range(0, 6), Range(6, 13), false }, 2129 Range(0, 6), Range(6, 13), false },
2131 { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9" 2130 { L"\x062A\x0641\x0627\x062D \x05EA\x05E4\x05D5\x05D6\x05D9"
2132 L"\x05DA\x05DB\x05DD", Range(0, 4), Range(4, 12), false } 2131 L"\x05DA\x05DB\x05DD", Range(0, 5), Range(5, 13), false }
2133 }; 2132 };
2134 2133
2135 RenderTextHarfBuzz render_text; 2134 RenderTextHarfBuzz render_text;
2136 // Specify the fixed width for characters to suppress the possible variations 2135 // Specify the fixed width for characters to suppress the possible variations
2137 // of linebreak results. 2136 // of linebreak results.
2138 render_text.set_glyph_width_for_test(5); 2137 render_text.set_glyph_width_for_test(5);
2139 render_text.SetDisplayRect(Rect(50, 1000)); 2138 render_text.SetDisplayRect(Rect(50, 1000));
2140 render_text.SetMultiline(true); 2139 render_text.SetMultiline(true);
2141 render_text.SetWordWrapBehavior(WRAP_LONG_WORDS); 2140 render_text.SetWordWrapBehavior(WRAP_LONG_WORDS);
2142 render_text.SetHorizontalAlignment(ALIGN_TO_HEAD); 2141 render_text.SetHorizontalAlignment(ALIGN_TO_HEAD);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 } 2199 }
2201 2200
2202 TEST_F(RenderTextTest, Multiline_Newline) { 2201 TEST_F(RenderTextTest, Multiline_Newline) {
2203 const struct { 2202 const struct {
2204 const wchar_t* const text; 2203 const wchar_t* const text;
2205 const size_t lines_count; 2204 const size_t lines_count;
2206 // Ranges of the characters on each line preceding the newline. 2205 // Ranges of the characters on each line preceding the newline.
2207 const Range line_char_ranges[3]; 2206 const Range line_char_ranges[3];
2208 } kTestStrings[] = { 2207 } kTestStrings[] = {
2209 {L"abc\ndef", 2ul, { Range(0, 3), Range(4, 7), Range::InvalidRange() } }, 2208 {L"abc\ndef", 2ul, { Range(0, 3), Range(4, 7), Range::InvalidRange() } },
2210 {L"a \n b ", 2ul, { Range(0, 2), Range(3, 6), Range::InvalidRange() } }, 2209 {L"a \n b ", 2ul, { Range(0, 2), Range(3, 4), Range(4, 6) } },
Jun Mukai 2015/05/06 17:38:52 Consider updating the data structure a bit. The st
xdai1 2015/05/06 20:23:44 No, the run split does change to: "a ", "\n", " ",
2211 {L"ab\n", 2ul, { Range(0, 2), Range(), Range::InvalidRange() } }, 2210 {L"ab\n", 2ul, { Range(0, 2), Range(), Range::InvalidRange() } },
2212 {L"a\n\nb", 3ul, { Range(0, 1), Range(), Range(3, 4) } }, 2211 {L"a\n\nb", 3ul, { Range(0, 1), Range(), Range(3, 4) } },
2213 {L"\nab", 2ul, { Range(), Range(1, 3), Range::InvalidRange() } }, 2212 {L"\nab", 2ul, { Range(), Range(1, 3), Range::InvalidRange() } },
2214 {L"\n", 2ul, { Range(), Range(), Range::InvalidRange() } }, 2213 {L"\n", 2ul, { Range(), Range(), Range::InvalidRange() } },
2215 }; 2214 };
2216 2215
2217 RenderTextHarfBuzz render_text; 2216 RenderTextHarfBuzz render_text;
2218 render_text.SetDisplayRect(Rect(200, 1000)); 2217 render_text.SetDisplayRect(Rect(200, 1000));
2219 render_text.SetMultiline(true); 2218 render_text.SetMultiline(true);
2220 Canvas canvas; 2219 Canvas canvas;
2221 2220
2222 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2221 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2223 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2222 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2224 render_text.SetText(WideToUTF16(kTestStrings[i].text)); 2223 render_text.SetText(WideToUTF16(kTestStrings[i].text));
2225 render_text.Draw(&canvas); 2224 render_text.Draw(&canvas);
2226 EXPECT_EQ(kTestStrings[i].lines_count, render_text.lines_.size()); 2225 EXPECT_EQ(kTestStrings[i].lines_count, render_text.lines_.size());
2227 if (kTestStrings[i].lines_count != render_text.lines_.size()) 2226 if (kTestStrings[i].lines_count != render_text.lines_.size())
2228 continue; 2227 continue;
2229 2228
2230 for (size_t j = 0; j < kTestStrings[i].lines_count; ++j) { 2229 for (size_t j = 0; j < kTestStrings[i].lines_count; ++j) {
2231 SCOPED_TRACE(base::StringPrintf("Line %" PRIuS "", j)); 2230 SCOPED_TRACE(base::StringPrintf("Line %" PRIuS "", j));
2232 VerifyLineSegments(kTestStrings[i].line_char_ranges[j], 2231 // There might be multiple segments in one line.
2233 render_text.lines_[j].segments); 2232 for (size_t k = 0; k < render_text.lines_[j].segments.size(); ++k) {
2233 VerifyLineSegments(kTestStrings[i].line_char_ranges[j + k],
2234 render_text.lines_[j].segments[k]);
2235 }
2234 } 2236 }
2235 } 2237 }
2236 } 2238 }
2237 2239
2238 // Make sure that multiline mode ignores elide behavior. 2240 // Make sure that multiline mode ignores elide behavior.
2239 TEST_F(RenderTextTest, Multiline_IgnoreElide) { 2241 TEST_F(RenderTextTest, Multiline_IgnoreElide) {
2240 const wchar_t kTestString[] = 2242 const wchar_t kTestString[] =
2241 L"very very very long string xxxxxxxxxxxxxxxxxxxxxxxxxx"; 2243 L"very very very long string xxxxxxxxxxxxxxxxxxxxxxxxxx";
2242 const wchar_t kEllipsis[] = L"\x2026"; 2244 const wchar_t kEllipsis[] = L"\x2026";
2243 2245
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 for (size_t j = 0; j < render_text.lines().size(); ++j) { 2360 for (size_t j = 0; j < render_text.lines().size(); ++j) {
2359 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j)); 2361 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j));
2360 EXPECT_EQ(kTestScenarios[i].char_ranges[j], 2362 EXPECT_EQ(kTestScenarios[i].char_ranges[j],
2361 render_text.lines()[j].segments[0].char_range); 2363 render_text.lines()[j].segments[0].char_range);
2362 EXPECT_EQ(kTestScenarios[i].char_ranges[j].length() * kGlyphSize, 2364 EXPECT_EQ(kTestScenarios[i].char_ranges[j].length() * kGlyphSize,
2363 render_text.lines()[j].size.width()); 2365 render_text.lines()[j].size.width());
2364 } 2366 }
2365 } 2367 }
2366 } 2368 }
2367 2369
2370 TEST_F(RenderTextTest, Multiline_LineBreakerBehavior) {
2371 const int kGlyphSize = 5;
2372 const struct {
2373 const wchar_t* const text;
2374 const WordWrapBehavior behavior;
2375 const size_t num_lines;
2376 const Range char_ranges[3];
2377 } kTestScenarios[] = {
2378 { L"That's good. aaa", IGNORE_LONG_WORDS, 3u,
2379 {Range(0, 7), Range(7, 13), Range(13, 16) } },
2380 { L"That's \"good\". aaa", IGNORE_LONG_WORDS, 3u,
2381 {Range(0, 7), Range(7, 15), Range(15, 18) } },
2382 // Test for full-width space.
2383 { L"That's\x3000good.\x3000yyy", IGNORE_LONG_WORDS, 3u,
2384 {Range(0, 7), Range(7, 13), Range(13, 16) } },
2385 { L"abcde'f g", TRUNCATE_LONG_WORDS, 2u,
2386 {Range(0, 4), Range(8, 9), Range::InvalidRange() } }
2387 };
2388
2389 RenderTextHarfBuzz render_text;
2390 render_text.SetMultiline(true);
2391 render_text.set_glyph_width_for_test(kGlyphSize);
2392 render_text.SetDisplayRect(Rect(0, 0, kGlyphSize * 4, 0));
2393
2394 Canvas canvas;
2395
2396 for (size_t i = 0; i < arraysize(kTestScenarios); ++i) {
2397 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2398 render_text.SetText(WideToUTF16(kTestScenarios[i].text));
2399 render_text.SetWordWrapBehavior(kTestScenarios[i].behavior);
2400 render_text.Draw(&canvas);
2401
2402 ASSERT_EQ(kTestScenarios[i].num_lines, render_text.lines().size());
2403 for (size_t j = 0; j < render_text.lines().size(); ++j) {
2404 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j));
2405 // Merges all the segments ranges in the same line.
2406 size_t segment_size = render_text.lines()[j].segments.size();
2407 Range line_range(
2408 render_text.lines()[j].segments[0].char_range.start(),
2409 render_text.lines()[j].segments[segment_size - 1].char_range.end());
2410 EXPECT_EQ(kTestScenarios[i].char_ranges[j], line_range);
2411 EXPECT_EQ(kTestScenarios[i].char_ranges[j].length() * kGlyphSize,
2412 render_text.lines()[j].size.width());
2413 }
2414 }
2415 }
2416
2368 TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) { 2417 TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) {
2369 const wchar_t* kTestStrings[] = { 2418 const wchar_t* kTestStrings[] = {
2370 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n", 2419 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n",
2371 }; 2420 };
2372 2421
2373 RenderTextHarfBuzz render_text; 2422 RenderTextHarfBuzz render_text;
2374 render_text.SetDisplayRect(Rect(200, 1000)); 2423 render_text.SetDisplayRect(Rect(200, 1000));
2375 Canvas canvas; 2424 Canvas canvas;
2376 2425
2377 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2426 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
2603 render_text.EnsureLayout(); 2652 render_text.EnsureLayout();
2604 internal::TextRunList* run_list = render_text.GetRunList(); 2653 internal::TextRunList* run_list = render_text.GetRunList();
2605 ASSERT_EQ(3U, run_list->size()); 2654 ASSERT_EQ(3U, run_list->size());
2606 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range); 2655 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range);
2607 EXPECT_EQ(Range(1, 2), run_list->runs()[1]->range); 2656 EXPECT_EQ(Range(1, 2), run_list->runs()[1]->range);
2608 EXPECT_EQ(Range(2, 3), run_list->runs()[2]->range); 2657 EXPECT_EQ(Range(2, 3), run_list->runs()[2]->range);
2609 2658
2610 render_text.SetText(WideToUTF16(L"x \x25B6 y")); 2659 render_text.SetText(WideToUTF16(L"x \x25B6 y"));
2611 render_text.EnsureLayout(); 2660 render_text.EnsureLayout();
2612 run_list = render_text.GetRunList(); 2661 run_list = render_text.GetRunList();
2613 ASSERT_EQ(3U, run_list->size()); 2662 ASSERT_EQ(4U, run_list->size());
2614 EXPECT_EQ(Range(0, 2), run_list->runs()[0]->range); 2663 EXPECT_EQ(Range(0, 2), run_list->runs()[0]->range);
2615 EXPECT_EQ(Range(2, 3), run_list->runs()[1]->range); 2664 EXPECT_EQ(Range(2, 3), run_list->runs()[1]->range);
2616 EXPECT_EQ(Range(3, 5), run_list->runs()[2]->range); 2665 EXPECT_EQ(Range(3, 4), run_list->runs()[2]->range);
2666 EXPECT_EQ(Range(4, 5), run_list->runs()[3]->range);
2617 } 2667 }
2618 2668
2619 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByEmoji) { 2669 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByEmoji) {
2620 RenderTextHarfBuzz render_text; 2670 RenderTextHarfBuzz render_text;
2621 2671
2622 // \xF0\x9F\x98\x81 (U+1F601) is smile icon emoji. \xE2\x9C\xA8 (U+2728) is 2672 // \xF0\x9F\x98\x81 (U+1F601) is smile icon emoji. \xE2\x9C\xA8 (U+2728) is
2623 // a sparkle icon. Both can be drawn with color emoji fonts, so runs should be 2673 // a sparkle icon. Both can be drawn with color emoji fonts, so runs should be
2624 // separated. See crbug.com/448909 2674 // separated. See crbug.com/448909
2625 render_text.SetText(UTF8ToUTF16("x\xF0\x9F\x98\x81y\xE2\x9C\xA8")); 2675 render_text.SetText(UTF8ToUTF16("x\xF0\x9F\x98\x81y\xE2\x9C\xA8"));
2626 render_text.EnsureLayout(); 2676 render_text.EnsureLayout();
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
2943 string_size.set_width(string_size.width() / 2); 2993 string_size.set_width(string_size.width() / 2);
2944 render_text.SetDisplayRect(gfx::Rect(string_size)); 2994 render_text.SetDisplayRect(gfx::Rect(string_size));
2945 render_text.EnsureLayout(); 2995 render_text.EnsureLayout();
2946 CFIndex glyph_count = CTLineGetGlyphCount(render_text.line_); 2996 CFIndex glyph_count = CTLineGetGlyphCount(render_text.line_);
2947 EXPECT_GT(text.size(), static_cast<size_t>(glyph_count)); 2997 EXPECT_GT(text.size(), static_cast<size_t>(glyph_count));
2948 EXPECT_NE(0, glyph_count); 2998 EXPECT_NE(0, glyph_count);
2949 } 2999 }
2950 #endif 3000 #endif
2951 3001
2952 } // namespace gfx 3002 } // 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