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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |