| 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/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "ui/gfx/break_list.h" | 14 #include "ui/gfx/break_list.h" |
| 14 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
| 15 | 16 |
| 16 #if defined(OS_WIN) | 17 #if defined(OS_WIN) |
| 17 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" |
| 18 #include "ui/gfx/render_text_win.h" | 19 #include "ui/gfx/render_text_win.h" |
| (...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1287 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1288 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 1288 render_text->SetText(ASCIIToUTF16("abcdefg")); | 1289 render_text->SetText(ASCIIToUTF16("abcdefg")); |
| 1289 render_text->SetFontList(FontList("Arial, 13px")); | 1290 render_text->SetFontList(FontList("Arial, 13px")); |
| 1290 | 1291 |
| 1291 // Set display area's size equal to the font size. | 1292 // Set display area's size equal to the font size. |
| 1292 const Size font_size(render_text->GetContentWidth(), | 1293 const Size font_size(render_text->GetContentWidth(), |
| 1293 render_text->GetStringSize().height()); | 1294 render_text->GetStringSize().height()); |
| 1294 Rect display_rect(font_size); | 1295 Rect display_rect(font_size); |
| 1295 render_text->SetDisplayRect(display_rect); | 1296 render_text->SetDisplayRect(display_rect); |
| 1296 | 1297 |
| 1297 Vector2d offset = render_text->GetTextOffset(); | 1298 Vector2d offset = render_text->GetLineOffset(0); |
| 1298 EXPECT_TRUE(offset.IsZero()); | 1299 EXPECT_TRUE(offset.IsZero()); |
| 1299 | 1300 |
| 1300 // Set display area's size greater than font size. | 1301 // Set display area's size greater than font size. |
| 1301 const int kEnlargement = 2; | 1302 const int kEnlargement = 2; |
| 1302 display_rect.Inset(0, 0, -kEnlargement, -kEnlargement); | 1303 display_rect.Inset(0, 0, -kEnlargement, -kEnlargement); |
| 1303 render_text->SetDisplayRect(display_rect); | 1304 render_text->SetDisplayRect(display_rect); |
| 1304 | 1305 |
| 1305 // Check the default horizontal and vertical alignment. | 1306 // Check the default horizontal and vertical alignment. |
| 1306 offset = render_text->GetTextOffset(); | 1307 offset = render_text->GetLineOffset(0); |
| 1307 EXPECT_EQ(kEnlargement / 2, offset.y()); | 1308 EXPECT_EQ(kEnlargement / 2, offset.y()); |
| 1308 EXPECT_EQ(0, offset.x()); | 1309 EXPECT_EQ(0, offset.x()); |
| 1309 | 1310 |
| 1310 // Check explicitly setting the horizontal alignment. | 1311 // Check explicitly setting the horizontal alignment. |
| 1311 render_text->SetHorizontalAlignment(ALIGN_LEFT); | 1312 render_text->SetHorizontalAlignment(ALIGN_LEFT); |
| 1312 offset = render_text->GetTextOffset(); | 1313 offset = render_text->GetLineOffset(0); |
| 1313 EXPECT_EQ(0, offset.x()); | 1314 EXPECT_EQ(0, offset.x()); |
| 1314 render_text->SetHorizontalAlignment(ALIGN_CENTER); | 1315 render_text->SetHorizontalAlignment(ALIGN_CENTER); |
| 1315 offset = render_text->GetTextOffset(); | 1316 offset = render_text->GetLineOffset(0); |
| 1316 EXPECT_EQ(kEnlargement / 2, offset.x()); | 1317 EXPECT_EQ(kEnlargement / 2, offset.x()); |
| 1317 render_text->SetHorizontalAlignment(ALIGN_RIGHT); | 1318 render_text->SetHorizontalAlignment(ALIGN_RIGHT); |
| 1318 offset = render_text->GetTextOffset(); | 1319 offset = render_text->GetLineOffset(0); |
| 1319 EXPECT_EQ(kEnlargement, offset.x()); | 1320 EXPECT_EQ(kEnlargement, offset.x()); |
| 1320 | 1321 |
| 1321 // Check explicitly setting the vertical alignment. | 1322 // Check explicitly setting the vertical alignment. |
| 1322 render_text->SetVerticalAlignment(ALIGN_TOP); | 1323 render_text->SetVerticalAlignment(ALIGN_TOP); |
| 1323 offset = render_text->GetTextOffset(); | 1324 offset = render_text->GetLineOffset(0); |
| 1324 EXPECT_EQ(0, offset.y()); | 1325 EXPECT_EQ(0, offset.y()); |
| 1325 render_text->SetVerticalAlignment(ALIGN_VCENTER); | 1326 render_text->SetVerticalAlignment(ALIGN_VCENTER); |
| 1326 offset = render_text->GetTextOffset(); | 1327 offset = render_text->GetLineOffset(0); |
| 1327 EXPECT_EQ(kEnlargement / 2, offset.y()); | 1328 EXPECT_EQ(kEnlargement / 2, offset.y()); |
| 1328 render_text->SetVerticalAlignment(ALIGN_BOTTOM); | 1329 render_text->SetVerticalAlignment(ALIGN_BOTTOM); |
| 1329 offset = render_text->GetTextOffset(); | 1330 offset = render_text->GetLineOffset(0); |
| 1330 EXPECT_EQ(kEnlargement, offset.y()); | 1331 EXPECT_EQ(kEnlargement, offset.y()); |
| 1331 | 1332 |
| 1332 SetRTL(was_rtl); | 1333 SetRTL(was_rtl); |
| 1333 } | 1334 } |
| 1334 | 1335 |
| 1335 TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) { | 1336 TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) { |
| 1336 // This only checks the default horizontal alignment in RTL mode; all other | 1337 // This only checks the default horizontal alignment in RTL mode; all other |
| 1337 // GetTextOffset() attributes are checked by the test above. | 1338 // GetLineOffset(0) attributes are checked by the test above. |
| 1338 const bool was_rtl = base::i18n::IsRTL(); | 1339 const bool was_rtl = base::i18n::IsRTL(); |
| 1339 SetRTL(true); | 1340 SetRTL(true); |
| 1340 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1341 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 1341 render_text->SetText(ASCIIToUTF16("abcdefg")); | 1342 render_text->SetText(ASCIIToUTF16("abcdefg")); |
| 1342 render_text->SetFontList(FontList("Arial, 13px")); | 1343 render_text->SetFontList(FontList("Arial, 13px")); |
| 1343 const int kEnlargement = 2; | 1344 const int kEnlargement = 2; |
| 1344 const Size font_size(render_text->GetContentWidth() + kEnlargement, | 1345 const Size font_size(render_text->GetContentWidth() + kEnlargement, |
| 1345 render_text->GetStringSize().height()); | 1346 render_text->GetStringSize().height()); |
| 1346 Rect display_rect(font_size); | 1347 Rect display_rect(font_size); |
| 1347 render_text->SetDisplayRect(display_rect); | 1348 render_text->SetDisplayRect(display_rect); |
| 1348 Vector2d offset = render_text->GetTextOffset(); | 1349 Vector2d offset = render_text->GetLineOffset(0); |
| 1349 EXPECT_EQ(kEnlargement, offset.x()); | 1350 EXPECT_EQ(kEnlargement, offset.x()); |
| 1350 SetRTL(was_rtl); | 1351 SetRTL(was_rtl); |
| 1351 } | 1352 } |
| 1352 | 1353 |
| 1353 TEST_F(RenderTextTest, SameFontForParentheses) { | 1354 TEST_F(RenderTextTest, SameFontForParentheses) { |
| 1354 struct { | 1355 struct { |
| 1355 const char16 left_char; | 1356 const char16 left_char; |
| 1356 const char16 right_char; | 1357 const char16 right_char; |
| 1357 } punctuation_pairs[] = { | 1358 } punctuation_pairs[] = { |
| 1358 { '(', ')' }, | 1359 { '(', ')' }, |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1645 render_text->MoveCursorTo(SelectionModel(gfx::Range(0, 1), CURSOR_FORWARD)); | 1646 render_text->MoveCursorTo(SelectionModel(gfx::Range(0, 1), CURSOR_FORWARD)); |
| 1646 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); | 1647 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); |
| 1647 // Draw the text. It shouldn't hit any DCHECKs or crash. | 1648 // Draw the text. It shouldn't hit any DCHECKs or crash. |
| 1648 // See http://crbug.com/214150 | 1649 // See http://crbug.com/214150 |
| 1649 render_text->Draw(&canvas); | 1650 render_text->Draw(&canvas); |
| 1650 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); | 1651 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); |
| 1651 } | 1652 } |
| 1652 } | 1653 } |
| 1653 | 1654 |
| 1654 #if defined(OS_WIN) | 1655 #if defined(OS_WIN) |
| 1656 // Ensure strings wrap onto multiple lines for a small available width. |
| 1657 TEST_F(RenderTextTest, Multiline_MinWidth) { |
| 1658 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, |
| 1659 kRtlLtr, kRtlLtrRtl }; |
| 1660 |
| 1661 scoped_ptr<RenderTextWin> render_text( |
| 1662 static_cast<RenderTextWin*>(RenderText::CreateInstance())); |
| 1663 render_text->SetDisplayRect(Rect(1, 1000)); |
| 1664 render_text->SetMultiline(true); |
| 1665 Canvas canvas; |
| 1666 |
| 1667 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { |
| 1668 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); |
| 1669 render_text->SetText(WideToUTF16(kTestStrings[i])); |
| 1670 render_text->Draw(&canvas); |
| 1671 EXPECT_GT(render_text->lines_.size(), 1U); |
| 1672 } |
| 1673 } |
| 1674 |
| 1675 // Ensure strings wrap onto multiple lines for a normal available width. |
| 1676 TEST_F(RenderTextTest, Multiline_NormalWidth) { |
| 1677 const struct { |
| 1678 const wchar_t* const text; |
| 1679 const Range first_line_char_range; |
| 1680 const Range second_line_char_range; |
| 1681 } kTestStrings[] = { |
| 1682 { L"abc defg hijkl", Range(0, 9), Range(9, 14) }, |
| 1683 { L"qwertyuiop", Range(0, 8), Range(8, 10) }, |
| 1684 { L"\x0647\x0630\x0627 \x0647\x0648 \x0627\x0644\x0628\x0627\x0628", |
| 1685 Range(0, 7), Range(7, 12) } |
| 1686 }; |
| 1687 |
| 1688 scoped_ptr<RenderTextWin> render_text( |
| 1689 static_cast<RenderTextWin*>(RenderText::CreateInstance())); |
| 1690 render_text->SetDisplayRect(Rect(50, 1000)); |
| 1691 render_text->SetMultiline(true); |
| 1692 Canvas canvas; |
| 1693 |
| 1694 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestStrings); ++i) { |
| 1695 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); |
| 1696 render_text->SetText(WideToUTF16(kTestStrings[i].text)); |
| 1697 render_text->Draw(&canvas); |
| 1698 ASSERT_EQ(2U, render_text->lines_.size()); |
| 1699 ASSERT_EQ(1U, render_text->lines_[0].segments.size()); |
| 1700 EXPECT_EQ(kTestStrings[i].first_line_char_range, |
| 1701 render_text->lines_[0].segments[0].char_range); |
| 1702 ASSERT_EQ(1U, render_text->lines_[1].segments.size()); |
| 1703 EXPECT_EQ(kTestStrings[i].second_line_char_range, |
| 1704 render_text->lines_[1].segments[0].char_range); |
| 1705 } |
| 1706 } |
| 1707 |
| 1708 // Ensure strings don't wrap onto multiple lines for a sufficient available |
| 1709 // width. |
| 1710 TEST_F(RenderTextTest, Multiline_SufficientWidth) { |
| 1711 const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c", |
| 1712 L"\x62E\x628\x632", L"\x62E \x628 \x632" }; |
| 1713 |
| 1714 scoped_ptr<RenderTextWin> render_text( |
| 1715 static_cast<RenderTextWin*>(RenderText::CreateInstance())); |
| 1716 render_text->SetDisplayRect(Rect(30, 1000)); |
| 1717 render_text->SetMultiline(true); |
| 1718 Canvas canvas; |
| 1719 |
| 1720 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { |
| 1721 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); |
| 1722 render_text->SetText(WideToUTF16(kTestStrings[i])); |
| 1723 render_text->Draw(&canvas); |
| 1724 EXPECT_EQ(1U, render_text->lines_.size()); |
| 1725 } |
| 1726 } |
| 1727 #endif // defined(OS_WIN) |
| 1728 |
| 1729 #if defined(OS_WIN) |
| 1655 TEST_F(RenderTextTest, Win_BreakRunsByUnicodeBlocks) { | 1730 TEST_F(RenderTextTest, Win_BreakRunsByUnicodeBlocks) { |
| 1656 scoped_ptr<RenderTextWin> render_text( | 1731 scoped_ptr<RenderTextWin> render_text( |
| 1657 static_cast<RenderTextWin*>(RenderText::CreateInstance())); | 1732 static_cast<RenderTextWin*>(RenderText::CreateInstance())); |
| 1658 | 1733 |
| 1659 render_text->SetText(WideToUTF16(L"x\x25B6y")); | 1734 render_text->SetText(WideToUTF16(L"x\x25B6y")); |
| 1660 render_text->EnsureLayout(); | 1735 render_text->EnsureLayout(); |
| 1661 ASSERT_EQ(3U, render_text->runs_.size()); | 1736 ASSERT_EQ(3U, render_text->runs_.size()); |
| 1662 EXPECT_EQ(Range(0, 1), render_text->runs_[0]->range); | 1737 EXPECT_EQ(Range(0, 1), render_text->runs_[0]->range); |
| 1663 EXPECT_EQ(Range(1, 2), render_text->runs_[1]->range); | 1738 EXPECT_EQ(Range(1, 2), render_text->runs_[1]->range); |
| 1664 EXPECT_EQ(Range(2, 3), render_text->runs_[2]->range); | 1739 EXPECT_EQ(Range(2, 3), render_text->runs_[2]->range); |
| 1665 | 1740 |
| 1666 render_text->SetText(WideToUTF16(L"x \x25B6 y")); | 1741 render_text->SetText(WideToUTF16(L"x \x25B6 y")); |
| 1667 render_text->EnsureLayout(); | 1742 render_text->EnsureLayout(); |
| 1668 ASSERT_EQ(3U, render_text->runs_.size()); | 1743 ASSERT_EQ(3U, render_text->runs_.size()); |
| 1669 EXPECT_EQ(Range(0, 2), render_text->runs_[0]->range); | 1744 EXPECT_EQ(Range(0, 2), render_text->runs_[0]->range); |
| 1670 EXPECT_EQ(Range(2, 3), render_text->runs_[1]->range); | 1745 EXPECT_EQ(Range(2, 3), render_text->runs_[1]->range); |
| 1671 EXPECT_EQ(Range(3, 5), render_text->runs_[2]->range); | 1746 EXPECT_EQ(Range(3, 5), render_text->runs_[2]->range); |
| 1672 | 1747 |
| 1673 } | 1748 } |
| 1674 #endif // !defined(OS_WIN) | 1749 #endif // !defined(OS_WIN) |
| 1675 | 1750 |
| 1676 } // namespace gfx | 1751 } // namespace gfx |
| OLD | NEW |