Chromium Code Reviews| 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 |