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

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

Issue 882643005: Add multiline support to RenderTextHarfBuzz. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 5 years, 10 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
« no previous file with comments | « ui/gfx/render_text_harfbuzz.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 render_text->MoveCursor(CHARACTER_BREAK, direction, false); 73 render_text->MoveCursor(CHARACTER_BREAK, direction, false);
74 } 74 }
75 // Check that cursoring is clamped at the line edge. 75 // Check that cursoring is clamped at the line edge.
76 EXPECT_EQ(expected.back(), render_text->selection_model()); 76 EXPECT_EQ(expected.back(), render_text->selection_model());
77 // Check that it is the line edge. 77 // Check that it is the line edge.
78 render_text->MoveCursor(LINE_BREAK, direction, false); 78 render_text->MoveCursor(LINE_BREAK, direction, false);
79 EXPECT_EQ(expected.back(), render_text->selection_model()); 79 EXPECT_EQ(expected.back(), render_text->selection_model());
80 } 80 }
81 #endif // !defined(OS_MACOSX) 81 #endif // !defined(OS_MACOSX)
82 82
83 // Test utility for Multiline_Newline test case. Empty |expected_range| means
84 // the blank line which has no segments. Otherwise |segments| should contain
85 // exactly one line segment whose range equals to |expected_range|.
86 void VerifyLineSegments(const Range& expected_range,
87 const std::vector<internal::LineSegment>& segments,
88 const std::string& message) {
89 EXPECT_EQ(expected_range.length() == 0 ? 0ul : 1ul, segments.size())
msw 2015/02/05 23:49:46 nit: expected_range.is_empty(), ditto below.
Jun Mukai 2015/02/06 01:00:53 Done.
90 << message;
91 if (expected_range.length() != 0)
92 EXPECT_EQ(expected_range, segments[0].char_range) << message;
93 }
94
83 } // namespace 95 } // namespace
84 96
85 class RenderTextTest : public testing::Test { 97 class RenderTextTest : public testing::Test {
86 }; 98 };
87 99
88 TEST_F(RenderTextTest, DefaultStyle) { 100 TEST_F(RenderTextTest, DefaultStyle) {
89 // Check the default styles applied to new instances and adjusted text. 101 // Check the default styles applied to new instances and adjusted text.
90 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 102 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
91 EXPECT_TRUE(render_text->text().empty()); 103 EXPECT_TRUE(render_text->text().empty());
92 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 104 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" };
(...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 render_text->SetText(WideToUTF16(kTestStrings[i])); 1868 render_text->SetText(WideToUTF16(kTestStrings[i]));
1857 const int expected_width = render_text->GetStringSize().width(); 1869 const int expected_width = render_text->GetStringSize().width();
1858 render_text->MoveCursorTo(SelectionModel(Range(0, 1), CURSOR_FORWARD)); 1870 render_text->MoveCursorTo(SelectionModel(Range(0, 1), CURSOR_FORWARD));
1859 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); 1871 EXPECT_EQ(expected_width, render_text->GetStringSize().width());
1860 // Drawing the text should not DCHECK or crash; see http://crbug.com/262119 1872 // Drawing the text should not DCHECK or crash; see http://crbug.com/262119
1861 render_text->Draw(&canvas); 1873 render_text->Draw(&canvas);
1862 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 1874 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD));
1863 } 1875 }
1864 } 1876 }
1865 1877
1866 // TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline.
1867 // Ensure strings wrap onto multiple lines for a small available width. 1878 // Ensure strings wrap onto multiple lines for a small available width.
1868 TEST_F(RenderTextTest, DISABLED_Multiline_MinWidth) { 1879 TEST_F(RenderTextTest, Multiline_MinWidth) {
1869 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, 1880 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl,
1870 kRtlLtr, kRtlLtrRtl }; 1881 kRtlLtr, kRtlLtrRtl };
1871 1882
1872 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1883 RenderTextHarfBuzz render_text;
1873 render_text->SetDisplayRect(Rect(1, 1000)); 1884 render_text.SetDisplayRect(Rect(1, 1000));
1874 render_text->SetMultiline(true); 1885 render_text.SetMultiline(true);
1875 Canvas canvas; 1886 Canvas canvas;
1876 1887
1877 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1888 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
1878 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 1889 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
1879 render_text->SetText(WideToUTF16(kTestStrings[i])); 1890 render_text.SetText(WideToUTF16(kTestStrings[i]));
1880 render_text->Draw(&canvas); 1891 render_text.Draw(&canvas);
1881 EXPECT_GT(render_text->lines_.size(), 1U); 1892 EXPECT_GT(render_text.lines_.size(), 1U);
1882 } 1893 }
1883 } 1894 }
1884 1895
1885 // TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline.
1886 // Ensure strings wrap onto multiple lines for a normal available width. 1896 // Ensure strings wrap onto multiple lines for a normal available width.
1887 TEST_F(RenderTextTest, DISABLED_Multiline_NormalWidth) { 1897 TEST_F(RenderTextTest, Multiline_NormalWidth) {
1888 const struct { 1898 const struct {
1889 const wchar_t* const text; 1899 const wchar_t* const text;
1890 const Range first_line_char_range; 1900 const Range first_line_char_range;
1891 const Range second_line_char_range; 1901 const Range second_line_char_range;
1892 } kTestStrings[] = { 1902 } kTestStrings[] = {
1893 { L"abc defg hijkl", Range(0, 9), Range(9, 14) }, 1903 { L"abc defg hijkl", Range(0, 9), Range(9, 14) },
1894 { L"qwertyzxcvbn", Range(0, 8), Range(8, 12) }, 1904 { L"qwertyzxcvbn", Range(0, 10), Range(10, 12) },
1895 { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9\x05DD", 1905 { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9"
1896 Range(4, 10), Range(0, 4) } 1906 L"\x05DA\x05DB\x05DD", Range(4, 12), Range(0, 4) }
1897 }; 1907 };
1898 1908
1899 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1909 RenderTextHarfBuzz render_text;
1900 render_text->SetDisplayRect(Rect(50, 1000)); 1910 // Specify the fixed width for characters to suppress the possible variations
1901 render_text->SetMultiline(true); 1911 // of linebreak results.
1912 render_text.set_glyph_width_for_test(5);
1913 render_text.SetDisplayRect(Rect(50, 1000));
1914 render_text.SetMultiline(true);
1902 Canvas canvas; 1915 Canvas canvas;
1903 1916
1904 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1917 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
1905 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 1918 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
1906 render_text->SetText(WideToUTF16(kTestStrings[i].text)); 1919 render_text.SetText(WideToUTF16(kTestStrings[i].text));
1907 render_text->Draw(&canvas); 1920 render_text.Draw(&canvas);
1908 ASSERT_EQ(2U, render_text->lines_.size()); 1921 ASSERT_EQ(2U, render_text.lines_.size());
1909 ASSERT_EQ(1U, render_text->lines_[0].segments.size()); 1922 ASSERT_EQ(1U, render_text.lines_[0].segments.size());
1910 EXPECT_EQ(kTestStrings[i].first_line_char_range, 1923 EXPECT_EQ(kTestStrings[i].first_line_char_range,
1911 render_text->lines_[0].segments[0].char_range); 1924 render_text.lines_[0].segments[0].char_range);
1912 ASSERT_EQ(1U, render_text->lines_[1].segments.size()); 1925 ASSERT_EQ(1U, render_text.lines_[1].segments.size());
1913 EXPECT_EQ(kTestStrings[i].second_line_char_range, 1926 EXPECT_EQ(kTestStrings[i].second_line_char_range,
1914 render_text->lines_[1].segments[0].char_range); 1927 render_text.lines_[1].segments[0].char_range);
1915 } 1928 }
1916 } 1929 }
1917 1930
1918 // TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline.
1919 // Ensure strings don't wrap onto multiple lines for a sufficient available 1931 // Ensure strings don't wrap onto multiple lines for a sufficient available
1920 // width. 1932 // width.
1921 TEST_F(RenderTextTest, DISABLED_Multiline_SufficientWidth) { 1933 TEST_F(RenderTextTest, Multiline_SufficientWidth) {
1922 const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c", 1934 const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c",
1923 L"\x62E\x628\x632", L"\x62E \x628 \x632" }; 1935 L"\x62E\x628\x632", L"\x62E \x628 \x632" };
1924 1936
1925 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1937 RenderTextHarfBuzz render_text;
1926 render_text->SetDisplayRect(Rect(30, 1000)); 1938 render_text.SetDisplayRect(Rect(1000, 1000));
1927 render_text->SetMultiline(true); 1939 render_text.SetMultiline(true);
1928 Canvas canvas; 1940 Canvas canvas;
1929 1941
1930 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1942 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
1931 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 1943 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
1932 render_text->SetText(WideToUTF16(kTestStrings[i])); 1944 render_text.SetText(WideToUTF16(kTestStrings[i]));
1933 render_text->Draw(&canvas); 1945 render_text.Draw(&canvas);
1934 EXPECT_EQ(1U, render_text->lines_.size()); 1946 EXPECT_EQ(1U, render_text.lines_.size());
1935 } 1947 }
1936 } 1948 }
1937 1949
1938 // TODO(ckocagil): Enable for RenderTextHarfBuzz after implementing multiline. 1950 TEST_F(RenderTextTest, Multiline_Newline) {
1939 TEST_F(RenderTextTest, DISABLED_Multiline_Newline) {
1940 const struct { 1951 const struct {
1941 const wchar_t* const text; 1952 const wchar_t* const text;
1953 const size_t lines_count;
1942 // Ranges of the characters on each line preceding the newline. 1954 // Ranges of the characters on each line preceding the newline.
1943 const Range first_line_char_range; 1955 const Range first_line_char_range;
1944 const Range second_line_char_range; 1956 const Range second_line_char_range;
1957 const Range third_line_char_range;
1945 } kTestStrings[] = { 1958 } kTestStrings[] = {
1946 { L"abc\ndef", Range(0, 3), Range(4, 7) }, 1959 {L"abc\ndef", 2ul, Range(0, 3), Range(4, 7), Range::InvalidRange()},
1947 { L"a \n b ", Range(0, 2), Range(3, 6) }, 1960 {L"a \n b ", 2ul, Range(0, 2), Range(3, 6), Range::InvalidRange()},
1948 { L"\n" , Range::InvalidRange(), Range::InvalidRange() } 1961 {L"ab\n", 2ul, Range(0, 2), Range(), Range::InvalidRange()},
1962 {L"a\n\nb", 3ul, Range(0, 1), Range(), Range(3, 4)},
1963 {L"\nab", 2ul, Range(), Range(1, 3), Range::InvalidRange()},
1964 {L"\n", 2ul, Range(), Range(), Range::InvalidRange()},
1949 }; 1965 };
1950 1966
1951 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1967 RenderTextHarfBuzz render_text;
1952 render_text->SetDisplayRect(Rect(200, 1000)); 1968 render_text.SetDisplayRect(Rect(200, 1000));
1953 render_text->SetMultiline(true); 1969 render_text.SetMultiline(true);
1954 Canvas canvas; 1970 Canvas canvas;
1955 1971
1956 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1972 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
1957 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 1973 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
1958 render_text->SetText(WideToUTF16(kTestStrings[i].text)); 1974 render_text.SetText(WideToUTF16(kTestStrings[i].text));
1959 render_text->Draw(&canvas); 1975 render_text.Draw(&canvas);
1976 EXPECT_EQ(kTestStrings[i].lines_count, render_text.lines_.size());
1977 if (kTestStrings[i].lines_count != render_text.lines_.size())
1978 continue;
1960 1979
1961 ASSERT_EQ(2U, render_text->lines_.size()); 1980 VerifyLineSegments(kTestStrings[i].first_line_char_range,
msw 2015/02/05 23:49:47 optional nit: Make kTestStrings contain an array o
Jun Mukai 2015/02/06 01:00:53 Done.
1962 1981 render_text.lines_[0].segments, "first line");
1963 const Range first_expected_range = kTestStrings[i].first_line_char_range; 1982 VerifyLineSegments(kTestStrings[i].second_line_char_range,
1964 ASSERT_EQ(first_expected_range.IsValid() ? 2U : 1U, 1983 render_text.lines_[1].segments, "second line");
1965 render_text->lines_[0].segments.size()); 1984 if (kTestStrings[i].lines_count > 2) {
1966 if (first_expected_range.IsValid()) 1985 VerifyLineSegments(kTestStrings[i].third_line_char_range,
1967 EXPECT_EQ(first_expected_range, 1986 render_text.lines_[2].segments, "third line");
1968 render_text->lines_[0].segments[0].char_range); 1987 }
1969
1970 const internal::LineSegment& newline_segment =
1971 render_text->lines_[0].segments[first_expected_range.IsValid() ? 1 : 0];
1972 ASSERT_EQ(1U, newline_segment.char_range.length());
1973 EXPECT_EQ(L'\n', kTestStrings[i].text[newline_segment.char_range.start()]);
1974
1975 const Range second_expected_range = kTestStrings[i].second_line_char_range;
1976 ASSERT_EQ(second_expected_range.IsValid() ? 1U : 0U,
1977 render_text->lines_[1].segments.size());
1978 if (second_expected_range.IsValid())
1979 EXPECT_EQ(second_expected_range,
1980 render_text->lines_[1].segments[0].char_range);
1981 } 1988 }
1982 } 1989 }
1983 1990
1991 TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) {
1992 const wchar_t* kTestStrings[] = {
1993 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n",
1994 };
1995
1996 RenderTextHarfBuzz render_text;
1997 render_text.SetDisplayRect(Rect(200, 1000));
1998 Canvas canvas;
1999
2000 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2001 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2002 render_text.SetText(WideToUTF16(kTestStrings[i]));
2003 render_text.Draw(&canvas);
2004
2005 EXPECT_EQ(1U, render_text.lines_.size());
2006 }
2007 }
2008
1984 // Test TextRunHarfBuzz's cluster finding logic. 2009 // Test TextRunHarfBuzz's cluster finding logic.
1985 TEST_F(RenderTextTest, HarfBuzz_Clusters) { 2010 TEST_F(RenderTextTest, HarfBuzz_Clusters) {
1986 struct { 2011 struct {
1987 uint32 glyph_to_char[4]; 2012 uint32 glyph_to_char[4];
1988 Range chars[4]; 2013 Range chars[4];
1989 Range glyphs[4]; 2014 Range glyphs[4];
1990 bool is_rtl; 2015 bool is_rtl;
1991 } cases[] = { 2016 } cases[] = {
1992 { // From string "A B C D" to glyphs "a b c d". 2017 { // From string "A B C D" to glyphs "a b c d".
1993 { 0, 1, 2, 3 }, 2018 { 0, 1, 2, 3 },
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
2343 base::StringToLowerASCII(fonts[0].GetActualFontNameForTesting())); 2368 base::StringToLowerASCII(fonts[0].GetActualFontNameForTesting()));
2344 2369
2345 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 2370 scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
2346 render_text->SetDisplayRect(Rect(0, 0, 25, 25)); 2371 render_text->SetDisplayRect(Rect(0, 0, 25, 25));
2347 render_text->SetFontList(font_list); 2372 render_text->SetFontList(font_list);
2348 EXPECT_GT(render_text->GetBaseline(), font_list.GetBaseline()); 2373 EXPECT_GT(render_text->GetBaseline(), font_list.GetBaseline());
2349 } 2374 }
2350 #endif 2375 #endif
2351 2376
2352 } // namespace gfx 2377 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text_harfbuzz.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698