OLD | NEW |
---|---|
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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 // Test utility for Multiline_Newline test case. Empty |expected_range| means | 83 // Test utility for Multiline_Newline test case. Empty |expected_range| means |
84 // the blank line which has no segments. Otherwise |segments| should contain | 84 // the blank line which has no segments. Otherwise |segments| should contain |
85 // exactly one line segment whose range equals to |expected_range|. | 85 // exactly one line segment whose range equals to |expected_range|. |
86 void VerifyLineSegments(const Range& expected_range, | 86 void VerifyLineSegments(const Range& expected_range, |
87 const std::vector<internal::LineSegment>& segments) { | 87 const std::vector<internal::LineSegment>& segments) { |
88 EXPECT_EQ(expected_range.is_empty() ? 0ul : 1ul, segments.size()); | 88 EXPECT_EQ(expected_range.is_empty() ? 0ul : 1ul, segments.size()); |
89 if (!expected_range.is_empty()) | 89 if (!expected_range.is_empty()) |
90 EXPECT_EQ(expected_range, segments[0].char_range); | 90 EXPECT_EQ(expected_range, segments[0].char_range); |
91 } | 91 } |
92 | 92 |
93 class TestSkiaTextRenderer : public internal::SkiaTextRenderer { | |
msw
2015/02/14 03:03:09
nit: add a comment.
Jun Mukai
2015/02/18 00:24:13
Done.
| |
94 public: | |
95 struct TextLog { | |
96 TextLog() : glyph_count(0u) {} | |
97 gfx::RectF bounds; | |
98 size_t glyph_count; | |
99 }; | |
100 | |
101 struct DecorationLog { | |
102 DecorationLog(int x, int y, int width, bool underline, bool strike, | |
103 bool diagonal_strike) | |
104 : x(x), y(y), width(width), underline(underline), strike(strike), | |
105 diagonal_strike(diagonal_strike) {} | |
106 int x; | |
107 int y; | |
108 int width; | |
109 bool underline; | |
110 bool strike; | |
111 bool diagonal_strike; | |
112 }; | |
113 | |
114 explicit TestSkiaTextRenderer(Canvas* canvas) | |
115 : internal::SkiaTextRenderer(canvas) {} | |
116 ~TestSkiaTextRenderer() override {} | |
117 | |
118 void GetDrawTextLogAndReset(std::vector<TextLog>* draw_text_log) { | |
119 draw_text_log_.swap(*draw_text_log); | |
120 draw_text_log_.clear(); | |
121 } | |
122 | |
123 void GetDecorationLogAndReset(std::vector<DecorationLog>* decoration_log) { | |
124 decoration_log_.swap(*decoration_log); | |
125 decoration_log_.clear(); | |
126 } | |
127 | |
128 private: | |
129 // internal::SkiaTextRenderer: | |
130 void DrawPosText(const SkPoint* pos, | |
131 const uint16* glyphs, | |
132 size_t glyph_count) override { | |
133 TextLog log_entry; | |
134 log_entry.glyph_count = glyph_count; | |
135 for (size_t i = 0u; i < glyph_count; ++i) { | |
msw
2015/02/14 03:03:10
nit: remove curly braces.
Jun Mukai
2015/02/18 00:24:13
Modified the code a bit and now it needs curly bra
| |
136 log_entry.bounds.Union(gfx::RectF(pos[i].x(), pos[i].y(), 1, 1)); | |
msw
2015/02/14 03:03:10
q: are the 1x1 bounds really faithful to what's ha
Jun Mukai
2015/02/18 00:24:13
It is unknown the actual width and height for the
| |
137 } | |
138 draw_text_log_.push_back(log_entry); | |
139 internal::SkiaTextRenderer::DrawPosText(pos, glyphs, glyph_count); | |
140 } | |
141 | |
142 void DrawDecorations(int x, int y, int width, bool underline, bool strike, | |
143 bool diagonal_strike) override { | |
144 decoration_log_.push_back( | |
145 DecorationLog(x, y, width, underline, strike, diagonal_strike)); | |
146 internal::SkiaTextRenderer::DrawDecorations( | |
147 x, y, width, underline, strike, diagonal_strike); | |
148 } | |
149 | |
150 std::vector<TextLog> draw_text_log_; | |
msw
2015/02/14 03:03:10
nit: rename |text_log_| to parallel |decoration_lo
Jun Mukai
2015/02/18 00:24:13
Done.
| |
151 std::vector<DecorationLog> decoration_log_; | |
152 }; | |
153 | |
93 } // namespace | 154 } // namespace |
94 | 155 |
95 class RenderTextTest : public testing::Test { | 156 class RenderTextTest : public testing::Test { |
96 }; | 157 }; |
97 | 158 |
98 TEST_F(RenderTextTest, DefaultStyle) { | 159 TEST_F(RenderTextTest, DefaultStyle) { |
99 // Check the default styles applied to new instances and adjusted text. | 160 // Check the default styles applied to new instances and adjusted text. |
100 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 161 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
101 EXPECT_TRUE(render_text->text().empty()); | 162 EXPECT_TRUE(render_text->text().empty()); |
102 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; | 163 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; |
(...skipping 1809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1912 EXPECT_GT(render_text.lines_.size(), 1U); | 1973 EXPECT_GT(render_text.lines_.size(), 1U); |
1913 } | 1974 } |
1914 } | 1975 } |
1915 | 1976 |
1916 // Ensure strings wrap onto multiple lines for a normal available width. | 1977 // Ensure strings wrap onto multiple lines for a normal available width. |
1917 TEST_F(RenderTextTest, Multiline_NormalWidth) { | 1978 TEST_F(RenderTextTest, Multiline_NormalWidth) { |
1918 const struct { | 1979 const struct { |
1919 const wchar_t* const text; | 1980 const wchar_t* const text; |
1920 const Range first_line_char_range; | 1981 const Range first_line_char_range; |
1921 const Range second_line_char_range; | 1982 const Range second_line_char_range; |
1983 bool is_ltr; | |
1922 } kTestStrings[] = { | 1984 } kTestStrings[] = { |
1923 { L"abc defg hijkl", Range(0, 9), Range(9, 14) }, | 1985 { L"abc defg hijkl", Range(0, 9), Range(9, 14), true }, |
1924 { L"qwertyzxcvbn", Range(0, 10), Range(10, 12) }, | 1986 { L"qwertyzxcvbn", Range(0, 10), Range(10, 12), true }, |
1987 { L"\x0627\x0644\x0644\x063A\x0629 " | |
1988 L"\x0627\x0644\x0639\x0631\x0628\x064A\x0629", | |
1989 Range(0, 6), Range(6, 13), false }, | |
1925 { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9" | 1990 { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9" |
1926 L"\x05DA\x05DB\x05DD", Range(4, 12), Range(0, 4) } | 1991 L"\x05DA\x05DB\x05DD", Range(0, 4), Range(4, 12), false } |
1927 }; | 1992 }; |
1928 | 1993 |
1929 RenderTextHarfBuzz render_text; | 1994 RenderTextHarfBuzz render_text; |
1930 // Specify the fixed width for characters to suppress the possible variations | 1995 // Specify the fixed width for characters to suppress the possible variations |
1931 // of linebreak results. | 1996 // of linebreak results. |
1932 render_text.set_glyph_width_for_test(5); | 1997 render_text.set_glyph_width_for_test(5); |
1933 render_text.SetDisplayRect(Rect(50, 1000)); | 1998 render_text.SetDisplayRect(Rect(50, 1000)); |
1934 render_text.SetMultiline(true); | 1999 render_text.SetMultiline(true); |
2000 render_text.SetHorizontalAlignment(ALIGN_TO_HEAD); | |
2001 | |
1935 Canvas canvas; | 2002 Canvas canvas; |
2003 TestSkiaTextRenderer renderer(&canvas); | |
1936 | 2004 |
1937 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { | 2005 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { |
1938 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); | 2006 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); |
1939 render_text.SetText(WideToUTF16(kTestStrings[i].text)); | 2007 render_text.SetText(WideToUTF16(kTestStrings[i].text)); |
1940 render_text.Draw(&canvas); | 2008 render_text.EnsureLayout(); |
2009 render_text.DrawVisualTextInternal(&renderer); | |
2010 | |
1941 ASSERT_EQ(2U, render_text.lines_.size()); | 2011 ASSERT_EQ(2U, render_text.lines_.size()); |
1942 ASSERT_EQ(1U, render_text.lines_[0].segments.size()); | 2012 ASSERT_EQ(1U, render_text.lines_[0].segments.size()); |
1943 EXPECT_EQ(kTestStrings[i].first_line_char_range, | 2013 EXPECT_EQ(kTestStrings[i].first_line_char_range, |
1944 render_text.lines_[0].segments[0].char_range); | 2014 render_text.lines_[0].segments[0].char_range); |
1945 ASSERT_EQ(1U, render_text.lines_[1].segments.size()); | 2015 ASSERT_EQ(1U, render_text.lines_[1].segments.size()); |
1946 EXPECT_EQ(kTestStrings[i].second_line_char_range, | 2016 EXPECT_EQ(kTestStrings[i].second_line_char_range, |
1947 render_text.lines_[1].segments[0].char_range); | 2017 render_text.lines_[1].segments[0].char_range); |
2018 | |
2019 std::vector<TestSkiaTextRenderer::TextLog> draw_text_log; | |
2020 renderer.GetDrawTextLogAndReset(&draw_text_log); | |
2021 ASSERT_EQ(2U, draw_text_log.size()); | |
2022 EXPECT_EQ(kTestStrings[i].first_line_char_range.length(), | |
msw
2015/02/14 03:03:10
nit: comparing the char ranges to the glyph counts
Jun Mukai
2015/02/18 00:24:13
That's true, added.
| |
2023 draw_text_log[0].glyph_count); | |
2024 EXPECT_EQ(kTestStrings[i].second_line_char_range.length(), | |
2025 draw_text_log[1].glyph_count); | |
2026 EXPECT_LT(draw_text_log[0].bounds.y(), draw_text_log[1].bounds.y()); | |
2027 if (kTestStrings[i].is_ltr) { | |
2028 EXPECT_EQ(0, draw_text_log[0].bounds.x()); | |
2029 EXPECT_EQ(0, draw_text_log[1].bounds.x()); | |
2030 } else { | |
2031 EXPECT_LT(0, draw_text_log[0].bounds.x()); | |
2032 EXPECT_LT(0, draw_text_log[1].bounds.x()); | |
2033 } | |
1948 } | 2034 } |
1949 } | 2035 } |
1950 | 2036 |
1951 // Ensure strings don't wrap onto multiple lines for a sufficient available | 2037 // Ensure strings don't wrap onto multiple lines for a sufficient available |
1952 // width. | 2038 // width. |
1953 TEST_F(RenderTextTest, Multiline_SufficientWidth) { | 2039 TEST_F(RenderTextTest, Multiline_SufficientWidth) { |
1954 const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c", | 2040 const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c", |
1955 L"\x62E\x628\x632", L"\x62E \x628 \x632" }; | 2041 L"\x62E\x628\x632", L"\x62E \x628 \x632" }; |
1956 | 2042 |
1957 RenderTextHarfBuzz render_text; | 2043 RenderTextHarfBuzz render_text; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2014 | 2100 |
2015 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { | 2101 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { |
2016 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); | 2102 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); |
2017 render_text.SetText(WideToUTF16(kTestStrings[i])); | 2103 render_text.SetText(WideToUTF16(kTestStrings[i])); |
2018 render_text.Draw(&canvas); | 2104 render_text.Draw(&canvas); |
2019 | 2105 |
2020 EXPECT_EQ(1U, render_text.lines_.size()); | 2106 EXPECT_EQ(1U, render_text.lines_.size()); |
2021 } | 2107 } |
2022 } | 2108 } |
2023 | 2109 |
2110 TEST_F(RenderTextTest, HarfBuzz_RTLDrawingPositions) { | |
msw
2015/02/14 03:03:10
What value does this add over your new test cases
msw
2015/02/18 18:58:37
Ping! Why not just add this as a test case of Mult
Jun Mukai
2015/02/18 19:55:56
This verifies the visual position in a line, while
| |
2111 RenderTextHarfBuzz render_text; | |
2112 render_text.SetText(WideToUTF16( | |
2113 L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9" | |
2114 L"\x05DA\x05DB\x05DD")); | |
2115 | |
2116 Canvas canvas; | |
2117 TestSkiaTextRenderer renderer(&canvas); | |
2118 | |
2119 render_text.EnsureLayout(); | |
2120 render_text.DrawVisualTextInternal(&renderer); | |
2121 | |
2122 std::vector<TestSkiaTextRenderer::TextLog> draw_text_log; | |
2123 renderer.GetDrawTextLogAndReset(&draw_text_log); | |
2124 | |
2125 EXPECT_EQ(2U, draw_text_log.size()); | |
2126 | |
2127 EXPECT_EQ(8U, draw_text_log[0].glyph_count); | |
2128 EXPECT_EQ(4U, draw_text_log[1].glyph_count); | |
2129 EXPECT_LT(draw_text_log[0].bounds.x(), draw_text_log[1].bounds.x()); | |
2130 } | |
2131 | |
2024 // Test TextRunHarfBuzz's cluster finding logic. | 2132 // Test TextRunHarfBuzz's cluster finding logic. |
2025 TEST_F(RenderTextTest, HarfBuzz_Clusters) { | 2133 TEST_F(RenderTextTest, HarfBuzz_Clusters) { |
2026 struct { | 2134 struct { |
2027 uint32 glyph_to_char[4]; | 2135 uint32 glyph_to_char[4]; |
2028 Range chars[4]; | 2136 Range chars[4]; |
2029 Range glyphs[4]; | 2137 Range glyphs[4]; |
2030 bool is_rtl; | 2138 bool is_rtl; |
2031 } cases[] = { | 2139 } cases[] = { |
2032 { // From string "A B C D" to glyphs "a b c d". | 2140 { // From string "A B C D" to glyphs "a b c d". |
2033 { 0, 1, 2, 3 }, | 2141 { 0, 1, 2, 3 }, |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2383 base::StringToLowerASCII(fonts[0].GetActualFontNameForTesting())); | 2491 base::StringToLowerASCII(fonts[0].GetActualFontNameForTesting())); |
2384 | 2492 |
2385 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 2493 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
2386 render_text->SetDisplayRect(Rect(0, 0, 25, 25)); | 2494 render_text->SetDisplayRect(Rect(0, 0, 25, 25)); |
2387 render_text->SetFontList(font_list); | 2495 render_text->SetFontList(font_list); |
2388 EXPECT_GT(render_text->GetBaseline(), font_list.GetBaseline()); | 2496 EXPECT_GT(render_text->GetBaseline(), font_list.GetBaseline()); |
2389 } | 2497 } |
2390 #endif | 2498 #endif |
2391 | 2499 |
2392 } // namespace gfx | 2500 } // namespace gfx |
OLD | NEW |