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/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
817 EXPECT_EQ(4U, render_text->cursor_position()); | 817 EXPECT_EQ(4U, render_text->cursor_position()); |
818 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); | 818 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); |
819 EXPECT_EQ(2U, render_text->cursor_position()); | 819 EXPECT_EQ(2U, render_text->cursor_position()); |
820 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); | 820 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); |
821 EXPECT_EQ(0U, render_text->cursor_position()); | 821 EXPECT_EQ(0U, render_text->cursor_position()); |
822 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); | 822 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); |
823 EXPECT_EQ(0U, render_text->cursor_position()); | 823 EXPECT_EQ(0U, render_text->cursor_position()); |
824 } | 824 } |
825 #endif | 825 #endif |
826 | 826 |
827 // TODO(ckocagil): Fix the behavior and re-enable. http://crbug.com/383265 | |
828 #if 0 | |
msw
2014/07/25 08:00:10
Leave these tests running with CreateNativeInstanc
ckocagil
2014/07/26 01:55:04
Done.
| |
827 TEST_F(RenderTextTest, MoveCursorLeftRight_MeiryoUILigatures) { | 829 TEST_F(RenderTextTest, MoveCursorLeftRight_MeiryoUILigatures) { |
828 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 830 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
829 // Meiryo UI uses single-glyph ligatures for 'ff' and 'ffi', but each letter | 831 // Meiryo UI uses single-glyph ligatures for 'ff' and 'ffi', but each letter |
830 // (code point) has unique bounds, so mid-glyph cursoring should be possible. | 832 // (code point) has unique bounds, so mid-glyph cursoring should be possible. |
831 render_text->SetFontList(FontList("Meiryo UI, 12px")); | 833 render_text->SetFontList(FontList("Meiryo UI, 12px")); |
832 render_text->SetText(WideToUTF16(L"ff ffi")); | 834 render_text->SetText(WideToUTF16(L"ff ffi")); |
833 EXPECT_EQ(0U, render_text->cursor_position()); | 835 EXPECT_EQ(0U, render_text->cursor_position()); |
834 for (size_t i = 0; i < render_text->text().length(); ++i) { | 836 for (size_t i = 0; i < render_text->text().length(); ++i) { |
835 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); | 837 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); |
836 EXPECT_EQ(i + 1, render_text->cursor_position()); | 838 EXPECT_EQ(i + 1, render_text->cursor_position()); |
837 } | 839 } |
838 EXPECT_EQ(6U, render_text->cursor_position()); | 840 EXPECT_EQ(6U, render_text->cursor_position()); |
839 } | 841 } |
842 #endif | |
840 | 843 |
841 TEST_F(RenderTextTest, GraphemePositions) { | 844 TEST_F(RenderTextTest, GraphemePositions) { |
842 // LTR 2-character grapheme, LTR abc, LTR 2-character grapheme. | 845 // LTR 2-character grapheme, LTR abc, LTR 2-character grapheme. |
843 const base::string16 kText1 = | 846 const base::string16 kText1 = |
844 WideToUTF16(L"\x0915\x093f" L"abc" L"\x0915\x093f"); | 847 WideToUTF16(L"\x0915\x093f" L"abc" L"\x0915\x093f"); |
845 | 848 |
846 // LTR ab, LTR 2-character grapheme, LTR cd. | 849 // LTR ab, LTR 2-character grapheme, LTR cd. |
847 const base::string16 kText2 = WideToUTF16(L"ab" L"\x0915\x093f" L"cd"); | 850 const base::string16 kText2 = WideToUTF16(L"ab" L"\x0915\x093f" L"cd"); |
848 | 851 |
849 // The below is 'MUSICAL SYMBOL G CLEF', which is represented in UTF-16 as | 852 // The below is 'MUSICAL SYMBOL G CLEF', which is represented in UTF-16 as |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1236 EXPECT_EQ(3U, render_text->cursor_position()); | 1239 EXPECT_EQ(3U, render_text->cursor_position()); |
1237 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); | 1240 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); |
1238 EXPECT_EQ(5U, render_text->cursor_position()); | 1241 EXPECT_EQ(5U, render_text->cursor_position()); |
1239 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); | 1242 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); |
1240 EXPECT_EQ(6U, render_text->cursor_position()); | 1243 EXPECT_EQ(6U, render_text->cursor_position()); |
1241 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); | 1244 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); |
1242 EXPECT_EQ(6U, render_text->cursor_position()); | 1245 EXPECT_EQ(6U, render_text->cursor_position()); |
1243 } | 1246 } |
1244 #endif | 1247 #endif |
1245 | 1248 |
1246 #if defined(OS_WIN) | 1249 // TODO(ckocagil): Remove when RenderTextWin goes away. |
1250 #if 0 | |
1247 TEST_F(RenderTextTest, Win_LogicalClusters) { | 1251 TEST_F(RenderTextTest, Win_LogicalClusters) { |
1248 scoped_ptr<RenderTextWin> render_text( | 1252 scoped_ptr<RenderTextWin> render_text( |
1249 static_cast<RenderTextWin*>(RenderText::CreateInstance())); | 1253 static_cast<RenderTextWin*>(RenderText::CreateInstance())); |
1250 | 1254 |
1251 const base::string16 test_string = | 1255 const base::string16 test_string = |
1252 WideToUTF16(L"\x0930\x0930\x0930\x0930\x0930"); | 1256 WideToUTF16(L"\x0930\x0930\x0930\x0930\x0930"); |
1253 render_text->SetText(test_string); | 1257 render_text->SetText(test_string); |
1254 render_text->EnsureLayout(); | 1258 render_text->EnsureLayout(); |
1255 ASSERT_EQ(1U, render_text->runs_.size()); | 1259 ASSERT_EQ(1U, render_text->runs_.size()); |
1256 WORD* logical_clusters = render_text->runs_[0]->logical_clusters.get(); | 1260 WORD* logical_clusters = render_text->runs_[0]->logical_clusters.get(); |
1257 for (size_t i = 0; i < test_string.length(); ++i) | 1261 for (size_t i = 0; i < test_string.length(); ++i) |
1258 EXPECT_EQ(i, logical_clusters[i]); | 1262 EXPECT_EQ(i, logical_clusters[i]); |
1259 } | 1263 } |
1260 #endif // defined(OS_WIN) | 1264 #endif |
1261 | 1265 |
1262 TEST_F(RenderTextTest, StringSizeSanity) { | 1266 TEST_F(RenderTextTest, StringSizeSanity) { |
1263 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1267 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
1264 render_text->SetText(UTF8ToUTF16("Hello World")); | 1268 render_text->SetText(UTF8ToUTF16("Hello World")); |
1265 const Size string_size = render_text->GetStringSize(); | 1269 const Size string_size = render_text->GetStringSize(); |
1266 EXPECT_GT(string_size.width(), 0); | 1270 EXPECT_GT(string_size.width(), 0); |
1267 EXPECT_GT(string_size.height(), 0); | 1271 EXPECT_GT(string_size.height(), 0); |
1268 } | 1272 } |
1269 | 1273 |
1270 TEST_F(RenderTextTest, StringSizeLongStrings) { | 1274 TEST_F(RenderTextTest, StringSizeLongStrings) { |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1567 }; | 1571 }; |
1568 | 1572 |
1569 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(large_content_cases); i++) { | 1573 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(large_content_cases); i++) { |
1570 render_text->SetHorizontalAlignment(large_content_cases[i].alignment); | 1574 render_text->SetHorizontalAlignment(large_content_cases[i].alignment); |
1571 render_text->SetDisplayOffset(large_content_cases[i].offset); | 1575 render_text->SetDisplayOffset(large_content_cases[i].offset); |
1572 EXPECT_EQ(large_content_cases[i].expected_offset, | 1576 EXPECT_EQ(large_content_cases[i].expected_offset, |
1573 render_text->GetUpdatedDisplayOffset().x()); | 1577 render_text->GetUpdatedDisplayOffset().x()); |
1574 } | 1578 } |
1575 } | 1579 } |
1576 | 1580 |
1581 // TODO(ckocagil): Fix the behavior and re-enable. http://crbug.com/396776 | |
1582 #if 0 | |
1577 TEST_F(RenderTextTest, SameFontForParentheses) { | 1583 TEST_F(RenderTextTest, SameFontForParentheses) { |
1578 struct { | 1584 struct { |
1579 const base::char16 left_char; | 1585 const base::char16 left_char; |
1580 const base::char16 right_char; | 1586 const base::char16 right_char; |
1581 } punctuation_pairs[] = { | 1587 } punctuation_pairs[] = { |
1582 { '(', ')' }, | 1588 { '(', ')' }, |
1583 { '{', '}' }, | 1589 { '{', '}' }, |
1584 { '<', '>' }, | 1590 { '<', '>' }, |
1585 }; | 1591 }; |
1586 struct { | 1592 struct { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1641 ASSERT_NE(-1, end_paren_span_index); | 1647 ASSERT_NE(-1, end_paren_span_index); |
1642 | 1648 |
1643 const Font& start_font = spans[start_paren_span_index].first; | 1649 const Font& start_font = spans[start_paren_span_index].first; |
1644 const Font& end_font = spans[end_paren_span_index].first; | 1650 const Font& end_font = spans[end_paren_span_index].first; |
1645 EXPECT_EQ(start_font.GetFontName(), end_font.GetFontName()); | 1651 EXPECT_EQ(start_font.GetFontName(), end_font.GetFontName()); |
1646 EXPECT_EQ(start_font.GetFontSize(), end_font.GetFontSize()); | 1652 EXPECT_EQ(start_font.GetFontSize(), end_font.GetFontSize()); |
1647 EXPECT_EQ(start_font.GetStyle(), end_font.GetStyle()); | 1653 EXPECT_EQ(start_font.GetStyle(), end_font.GetStyle()); |
1648 } | 1654 } |
1649 } | 1655 } |
1650 } | 1656 } |
1657 #endif | |
1651 | 1658 |
1652 // Make sure the caret width is always >=1 so that the correct | 1659 // Make sure the caret width is always >=1 so that the correct |
1653 // caret is drawn at high DPI. crbug.com/164100. | 1660 // caret is drawn at high DPI. crbug.com/164100. |
1654 TEST_F(RenderTextTest, CaretWidth) { | 1661 TEST_F(RenderTextTest, CaretWidth) { |
1655 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1662 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
1656 render_text->SetText(ASCIIToUTF16("abcdefg")); | 1663 render_text->SetText(ASCIIToUTF16("abcdefg")); |
1657 EXPECT_GE(render_text->GetUpdatedCursorBounds().width(), 1); | 1664 EXPECT_GE(render_text->GetUpdatedCursorBounds().width(), 1); |
1658 } | 1665 } |
1659 | 1666 |
1660 TEST_F(RenderTextTest, SelectWord) { | 1667 TEST_F(RenderTextTest, SelectWord) { |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1863 render_text->SetText(WideToUTF16(kTestStrings[i])); | 1870 render_text->SetText(WideToUTF16(kTestStrings[i])); |
1864 const int expected_width = render_text->GetStringSize().width(); | 1871 const int expected_width = render_text->GetStringSize().width(); |
1865 render_text->MoveCursorTo(SelectionModel(Range(0, 1), CURSOR_FORWARD)); | 1872 render_text->MoveCursorTo(SelectionModel(Range(0, 1), CURSOR_FORWARD)); |
1866 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); | 1873 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); |
1867 // Drawing the text should not DCHECK or crash; see http://crbug.com/262119 | 1874 // Drawing the text should not DCHECK or crash; see http://crbug.com/262119 |
1868 render_text->Draw(&canvas); | 1875 render_text->Draw(&canvas); |
1869 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); | 1876 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); |
1870 } | 1877 } |
1871 } | 1878 } |
1872 | 1879 |
1873 #if defined(OS_WIN) | 1880 // TODO(ckocagil): Enable after implementing RenderTextHarfBuzz multiline mode. |
1881 #if 0 | |
1874 // Ensure strings wrap onto multiple lines for a small available width. | 1882 // Ensure strings wrap onto multiple lines for a small available width. |
1875 TEST_F(RenderTextTest, Multiline_MinWidth) { | 1883 TEST_F(RenderTextTest, Multiline_MinWidth) { |
1876 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, | 1884 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, |
1877 kRtlLtr, kRtlLtrRtl }; | 1885 kRtlLtr, kRtlLtrRtl }; |
1878 | 1886 |
1879 scoped_ptr<RenderTextWin> render_text( | 1887 scoped_ptr<RenderTextWin> render_text( |
1880 static_cast<RenderTextWin*>(RenderText::CreateInstance())); | 1888 static_cast<RenderTextWin*>(RenderText::CreateInstance())); |
1881 render_text->SetDisplayRect(Rect(1, 1000)); | 1889 render_text->SetDisplayRect(Rect(1, 1000)); |
1882 render_text->SetMultiline(true); | 1890 render_text->SetMultiline(true); |
1883 Canvas canvas; | 1891 Canvas canvas; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1981 EXPECT_EQ(L'\n', kTestStrings[i].text[newline_segment.char_range.start()]); | 1989 EXPECT_EQ(L'\n', kTestStrings[i].text[newline_segment.char_range.start()]); |
1982 | 1990 |
1983 const Range second_expected_range = kTestStrings[i].second_line_char_range; | 1991 const Range second_expected_range = kTestStrings[i].second_line_char_range; |
1984 ASSERT_EQ(second_expected_range.IsValid() ? 1U : 0U, | 1992 ASSERT_EQ(second_expected_range.IsValid() ? 1U : 0U, |
1985 render_text->lines_[1].segments.size()); | 1993 render_text->lines_[1].segments.size()); |
1986 if (second_expected_range.IsValid()) | 1994 if (second_expected_range.IsValid()) |
1987 EXPECT_EQ(second_expected_range, | 1995 EXPECT_EQ(second_expected_range, |
1988 render_text->lines_[1].segments[0].char_range); | 1996 render_text->lines_[1].segments[0].char_range); |
1989 } | 1997 } |
1990 } | 1998 } |
1999 #endif | |
1991 | 2000 |
1992 TEST_F(RenderTextTest, Win_BreakRunsByUnicodeBlocks) { | 2001 // TODO(ckocagil): Remove when RenderTextWin goes away. |
msw
2014/07/25 08:00:10
Does RenderTextHarfBuzz not suffer from the http:/
ckocagil
2014/07/26 01:55:04
No, and there's a HarfBuzz version of this test, n
| |
2002 #if 0 | |
2003 TEST_F(RenderTextTest, BreakRunsByUnicodeBlocks) { | |
1993 scoped_ptr<RenderTextWin> render_text( | 2004 scoped_ptr<RenderTextWin> render_text( |
1994 static_cast<RenderTextWin*>(RenderText::CreateInstance())); | 2005 static_cast<RenderTextWin*>(RenderText::CreateInstance())); |
1995 | 2006 |
1996 // The '\x25B6' "play character" should break runs. http://crbug.com/278913 | 2007 // The '\x25B6' "play character" should break runs. http://crbug.com/278913 |
1997 render_text->SetText(WideToUTF16(L"x\x25B6y")); | 2008 render_text->SetText(WideToUTF16(L"x\x25B6y")); |
1998 render_text->EnsureLayout(); | 2009 render_text->EnsureLayout(); |
1999 ASSERT_EQ(3U, render_text->runs_.size()); | 2010 ASSERT_EQ(3U, render_text->runs_.size()); |
2000 EXPECT_EQ(Range(0, 1), render_text->runs_[0]->range); | 2011 EXPECT_EQ(Range(0, 1), render_text->runs_[0]->range); |
2001 EXPECT_EQ(Range(1, 2), render_text->runs_[1]->range); | 2012 EXPECT_EQ(Range(1, 2), render_text->runs_[1]->range); |
2002 EXPECT_EQ(Range(2, 3), render_text->runs_[2]->range); | 2013 EXPECT_EQ(Range(2, 3), render_text->runs_[2]->range); |
2003 | 2014 |
2004 render_text->SetText(WideToUTF16(L"x \x25B6 y")); | 2015 render_text->SetText(WideToUTF16(L"x \x25B6 y")); |
2005 render_text->EnsureLayout(); | 2016 render_text->EnsureLayout(); |
2006 ASSERT_EQ(3U, render_text->runs_.size()); | 2017 ASSERT_EQ(3U, render_text->runs_.size()); |
2007 EXPECT_EQ(Range(0, 2), render_text->runs_[0]->range); | 2018 EXPECT_EQ(Range(0, 2), render_text->runs_[0]->range); |
2008 EXPECT_EQ(Range(2, 3), render_text->runs_[1]->range); | 2019 EXPECT_EQ(Range(2, 3), render_text->runs_[1]->range); |
2009 EXPECT_EQ(Range(3, 5), render_text->runs_[2]->range); | 2020 EXPECT_EQ(Range(3, 5), render_text->runs_[2]->range); |
2010 } | 2021 } |
2011 #endif // defined(OS_WIN) | 2022 #endif |
2012 | 2023 |
2013 TEST_F(RenderTextTest, HarfBuzz_CharToGlyph) { | 2024 TEST_F(RenderTextTest, HarfBuzz_CharToGlyph) { |
2014 struct { | 2025 struct { |
2015 uint32 glyph_to_char[4]; | 2026 uint32 glyph_to_char[4]; |
2016 size_t char_to_glyph_expected[4]; | 2027 size_t char_to_glyph_expected[4]; |
2017 Range char_range_to_glyph_range_expected[4]; | 2028 Range char_range_to_glyph_range_expected[4]; |
2018 bool is_rtl; | 2029 bool is_rtl; |
2019 } cases[] = { | 2030 } cases[] = { |
2020 { // From string "A B C D" to glyphs "a b c d". | 2031 { // From string "A B C D" to glyphs "a b c d". |
2021 { 0, 1, 2, 3 }, | 2032 { 0, 1, 2, 3 }, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2120 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { | 2131 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { |
2121 render_text->SetText(WideToUTF16(kTestStrings[i])); | 2132 render_text->SetText(WideToUTF16(kTestStrings[i])); |
2122 render_text->EnsureLayout(); | 2133 render_text->EnsureLayout(); |
2123 | 2134 |
2124 for (size_t j = 0; j < render_text->text().length(); ++j) | 2135 for (size_t j = 0; j < render_text->text().length(); ++j) |
2125 EXPECT_FALSE(render_text->GetGlyphBounds(j).is_empty()); | 2136 EXPECT_FALSE(render_text->GetGlyphBounds(j).is_empty()); |
2126 } | 2137 } |
2127 } | 2138 } |
2128 | 2139 |
2129 } // namespace gfx | 2140 } // namespace gfx |
OLD | NEW |