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/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 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1136 const FontList font_list("Arial,Symbol, 16px"); | 1137 const FontList font_list("Arial,Symbol, 16px"); |
| 1137 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1138 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 1138 render_text->SetFontList(font_list); | 1139 render_text->SetFontList(font_list); |
| 1139 | 1140 |
| 1140 // The empty string respects FontList metrics for non-zero height | 1141 // The empty string respects FontList metrics for non-zero height |
| 1141 // and baseline. | 1142 // and baseline. |
| 1142 render_text->SetText(base::string16()); | 1143 render_text->SetText(base::string16()); |
| 1143 EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); | 1144 EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); |
| 1144 EXPECT_EQ(0, render_text->GetStringSize().width()); | 1145 EXPECT_EQ(0, render_text->GetStringSize().width()); |
| 1145 EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); | 1146 EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); |
| 1146 | |
| 1147 render_text->SetText(UTF8ToUTF16(" ")); | |
|
msw
2013/09/11 17:32:37
Why did you remove this?
ckocagil
2013/09/11 20:31:16
Added back. See my comment above LineBreaker in re
| |
| 1148 EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); | |
| 1149 EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); | |
| 1150 } | 1147 } |
| 1151 #endif // !defined(OS_MACOSX) | 1148 #endif // !defined(OS_MACOSX) |
| 1152 | 1149 |
| 1153 TEST_F(RenderTextTest, StringSizeRespectsFontListMetrics) { | 1150 TEST_F(RenderTextTest, StringSizeRespectsFontListMetrics) { |
| 1154 // Check that Arial and Symbol have different font metrics. | 1151 // Check that Arial and Symbol have different font metrics. |
| 1155 Font arial_font("Arial", 16); | 1152 Font arial_font("Arial", 16); |
| 1156 Font symbol_font("Symbol", 16); | 1153 Font symbol_font("Symbol", 16); |
| 1157 EXPECT_NE(arial_font.GetHeight(), symbol_font.GetHeight()); | 1154 EXPECT_NE(arial_font.GetHeight(), symbol_font.GetHeight()); |
| 1158 EXPECT_NE(arial_font.GetBaseline(), symbol_font.GetBaseline()); | 1155 EXPECT_NE(arial_font.GetBaseline(), symbol_font.GetBaseline()); |
| 1159 // "a" should be rendered with Arial, not with Symbol. | 1156 // "a" should be rendered with Arial, not with Symbol. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1175 ASSERT_LT(smaller_font.GetBaseline(), larger_font.GetBaseline()); | 1172 ASSERT_LT(smaller_font.GetBaseline(), larger_font.GetBaseline()); |
| 1176 | 1173 |
| 1177 // Check |smaller_font_text| is rendered with the smaller font. | 1174 // Check |smaller_font_text| is rendered with the smaller font. |
| 1178 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1175 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 1179 render_text->SetText(UTF8ToUTF16(smaller_font_text)); | 1176 render_text->SetText(UTF8ToUTF16(smaller_font_text)); |
| 1180 render_text->SetFont(smaller_font); | 1177 render_text->SetFont(smaller_font); |
| 1181 EXPECT_EQ(smaller_font.GetHeight(), render_text->GetStringSize().height()); | 1178 EXPECT_EQ(smaller_font.GetHeight(), render_text->GetStringSize().height()); |
| 1182 EXPECT_EQ(smaller_font.GetBaseline(), render_text->GetBaseline()); | 1179 EXPECT_EQ(smaller_font.GetBaseline(), render_text->GetBaseline()); |
| 1183 | 1180 |
| 1184 // Layout the same text with mixed fonts. The text should be rendered with | 1181 // Layout the same text with mixed fonts. The text should be rendered with |
| 1185 // the smaller font, but the height and baseline are determined with the | 1182 // the smaller font, and the height and baseline are determined with the |
| 1186 // metrics of the font list, which is equal to the larger font. | 1183 // metrics of the smaller font. |
|
msw
2013/09/11 17:32:37
Why has this changed? I think it was correct befor
ckocagil
2013/09/11 20:31:16
Reverted the changes to existing tests. See my com
| |
| 1187 std::vector<Font> fonts; | 1184 std::vector<Font> fonts; |
| 1188 fonts.push_back(smaller_font); // The primary font is the smaller font. | 1185 fonts.push_back(smaller_font); // The primary font is the smaller font. |
| 1189 fonts.push_back(larger_font); | 1186 fonts.push_back(larger_font); |
| 1190 const FontList font_list(fonts); | 1187 const FontList font_list(fonts); |
| 1191 render_text->SetFontList(font_list); | 1188 render_text->SetFontList(font_list); |
| 1192 EXPECT_LT(smaller_font.GetHeight(), render_text->GetStringSize().height()); | 1189 EXPECT_EQ(smaller_font.GetHeight(), render_text->GetStringSize().height()); |
| 1193 EXPECT_LT(smaller_font.GetBaseline(), render_text->GetBaseline()); | 1190 EXPECT_EQ(smaller_font.GetBaseline(), render_text->GetBaseline()); |
| 1194 EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); | |
| 1195 EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); | |
| 1196 } | 1191 } |
| 1197 | 1192 |
| 1198 TEST_F(RenderTextTest, SetFont) { | 1193 TEST_F(RenderTextTest, SetFont) { |
| 1199 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1194 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 1200 render_text->SetFont(Font("Arial", 12)); | 1195 render_text->SetFont(Font("Arial", 12)); |
| 1201 EXPECT_EQ("Arial", render_text->GetPrimaryFont().GetFontName()); | 1196 EXPECT_EQ("Arial", render_text->GetPrimaryFont().GetFontName()); |
| 1202 EXPECT_EQ(12, render_text->GetPrimaryFont().GetFontSize()); | 1197 EXPECT_EQ(12, render_text->GetPrimaryFont().GetFontSize()); |
| 1203 } | 1198 } |
| 1204 | 1199 |
| 1205 TEST_F(RenderTextTest, SetFontList) { | 1200 TEST_F(RenderTextTest, SetFontList) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1287 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1282 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 1288 render_text->SetText(ASCIIToUTF16("abcdefg")); | 1283 render_text->SetText(ASCIIToUTF16("abcdefg")); |
| 1289 render_text->SetFontList(FontList("Arial, 13px")); | 1284 render_text->SetFontList(FontList("Arial, 13px")); |
| 1290 | 1285 |
| 1291 // Set display area's size equal to the font size. | 1286 // Set display area's size equal to the font size. |
| 1292 const Size font_size(render_text->GetContentWidth(), | 1287 const Size font_size(render_text->GetContentWidth(), |
| 1293 render_text->GetStringSize().height()); | 1288 render_text->GetStringSize().height()); |
| 1294 Rect display_rect(font_size); | 1289 Rect display_rect(font_size); |
| 1295 render_text->SetDisplayRect(display_rect); | 1290 render_text->SetDisplayRect(display_rect); |
| 1296 | 1291 |
| 1297 Vector2d offset = render_text->GetTextOffset(); | 1292 Vector2d offset = render_text->GetLineOffset(0); |
| 1298 EXPECT_TRUE(offset.IsZero()); | 1293 EXPECT_TRUE(offset.IsZero()); |
| 1299 | 1294 |
| 1300 // Set display area's size greater than font size. | 1295 // Set display area's size greater than font size. |
| 1301 const int kEnlargement = 2; | 1296 const int kEnlargement = 2; |
| 1302 display_rect.Inset(0, 0, -kEnlargement, -kEnlargement); | 1297 display_rect.Inset(0, 0, -kEnlargement, -kEnlargement); |
| 1303 render_text->SetDisplayRect(display_rect); | 1298 render_text->SetDisplayRect(display_rect); |
| 1304 | 1299 |
| 1305 // Check the default horizontal and vertical alignment. | 1300 // Check the default horizontal and vertical alignment. |
| 1306 offset = render_text->GetTextOffset(); | 1301 offset = render_text->GetLineOffset(0); |
| 1307 EXPECT_EQ(kEnlargement / 2, offset.y()); | 1302 EXPECT_EQ(kEnlargement / 2, offset.y()); |
| 1308 EXPECT_EQ(0, offset.x()); | 1303 EXPECT_EQ(0, offset.x()); |
| 1309 | 1304 |
| 1310 // Check explicitly setting the horizontal alignment. | 1305 // Check explicitly setting the horizontal alignment. |
| 1311 render_text->SetHorizontalAlignment(ALIGN_LEFT); | 1306 render_text->SetHorizontalAlignment(ALIGN_LEFT); |
| 1312 offset = render_text->GetTextOffset(); | 1307 offset = render_text->GetLineOffset(0); |
| 1313 EXPECT_EQ(0, offset.x()); | 1308 EXPECT_EQ(0, offset.x()); |
| 1314 render_text->SetHorizontalAlignment(ALIGN_CENTER); | 1309 render_text->SetHorizontalAlignment(ALIGN_CENTER); |
| 1315 offset = render_text->GetTextOffset(); | 1310 offset = render_text->GetLineOffset(0); |
| 1316 EXPECT_EQ(kEnlargement / 2, offset.x()); | 1311 EXPECT_EQ(kEnlargement / 2, offset.x()); |
| 1317 render_text->SetHorizontalAlignment(ALIGN_RIGHT); | 1312 render_text->SetHorizontalAlignment(ALIGN_RIGHT); |
| 1318 offset = render_text->GetTextOffset(); | 1313 offset = render_text->GetLineOffset(0); |
| 1319 EXPECT_EQ(kEnlargement, offset.x()); | 1314 EXPECT_EQ(kEnlargement, offset.x()); |
| 1320 | 1315 |
| 1321 // Check explicitly setting the vertical alignment. | 1316 // Check explicitly setting the vertical alignment. |
| 1322 render_text->SetVerticalAlignment(ALIGN_TOP); | 1317 render_text->SetVerticalAlignment(ALIGN_TOP); |
| 1323 offset = render_text->GetTextOffset(); | 1318 offset = render_text->GetLineOffset(0); |
| 1324 EXPECT_EQ(0, offset.y()); | 1319 EXPECT_EQ(0, offset.y()); |
| 1325 render_text->SetVerticalAlignment(ALIGN_VCENTER); | 1320 render_text->SetVerticalAlignment(ALIGN_VCENTER); |
| 1326 offset = render_text->GetTextOffset(); | 1321 offset = render_text->GetLineOffset(0); |
| 1327 EXPECT_EQ(kEnlargement / 2, offset.y()); | 1322 EXPECT_EQ(kEnlargement / 2, offset.y()); |
| 1328 render_text->SetVerticalAlignment(ALIGN_BOTTOM); | 1323 render_text->SetVerticalAlignment(ALIGN_BOTTOM); |
| 1329 offset = render_text->GetTextOffset(); | 1324 offset = render_text->GetLineOffset(0); |
| 1330 EXPECT_EQ(kEnlargement, offset.y()); | 1325 EXPECT_EQ(kEnlargement, offset.y()); |
| 1331 | 1326 |
| 1332 SetRTL(was_rtl); | 1327 SetRTL(was_rtl); |
| 1333 } | 1328 } |
| 1334 | 1329 |
| 1335 TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) { | 1330 TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) { |
| 1336 // This only checks the default horizontal alignment in RTL mode; all other | 1331 // This only checks the default horizontal alignment in RTL mode; all other |
| 1337 // GetTextOffset() attributes are checked by the test above. | 1332 // GetLineOffset(0) attributes are checked by the test above. |
| 1338 const bool was_rtl = base::i18n::IsRTL(); | 1333 const bool was_rtl = base::i18n::IsRTL(); |
| 1339 SetRTL(true); | 1334 SetRTL(true); |
| 1340 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1335 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 1341 render_text->SetText(ASCIIToUTF16("abcdefg")); | 1336 render_text->SetText(ASCIIToUTF16("abcdefg")); |
| 1342 render_text->SetFontList(FontList("Arial, 13px")); | 1337 render_text->SetFontList(FontList("Arial, 13px")); |
| 1343 const int kEnlargement = 2; | 1338 const int kEnlargement = 2; |
| 1344 const Size font_size(render_text->GetContentWidth() + kEnlargement, | 1339 const Size font_size(render_text->GetContentWidth() + kEnlargement, |
| 1345 render_text->GetStringSize().height()); | 1340 render_text->GetStringSize().height()); |
| 1346 Rect display_rect(font_size); | 1341 Rect display_rect(font_size); |
| 1347 render_text->SetDisplayRect(display_rect); | 1342 render_text->SetDisplayRect(display_rect); |
| 1348 Vector2d offset = render_text->GetTextOffset(); | 1343 Vector2d offset = render_text->GetLineOffset(0); |
| 1349 EXPECT_EQ(kEnlargement, offset.x()); | 1344 EXPECT_EQ(kEnlargement, offset.x()); |
| 1350 SetRTL(was_rtl); | 1345 SetRTL(was_rtl); |
| 1351 } | 1346 } |
| 1352 | 1347 |
| 1353 TEST_F(RenderTextTest, SameFontForParentheses) { | 1348 TEST_F(RenderTextTest, SameFontForParentheses) { |
| 1354 struct { | 1349 struct { |
| 1355 const char16 left_char; | 1350 const char16 left_char; |
| 1356 const char16 right_char; | 1351 const char16 right_char; |
| 1357 } punctuation_pairs[] = { | 1352 } punctuation_pairs[] = { |
| 1358 { '(', ')' }, | 1353 { '(', ')' }, |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1644 const int expected_width = render_text->GetStringSize().width(); | 1639 const int expected_width = render_text->GetStringSize().width(); |
| 1645 render_text->MoveCursorTo(SelectionModel(ui::Range(0, 1), CURSOR_FORWARD)); | 1640 render_text->MoveCursorTo(SelectionModel(ui::Range(0, 1), CURSOR_FORWARD)); |
| 1646 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); | 1641 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); |
| 1647 // Draw the text. It shouldn't hit any DCHECKs or crash. | 1642 // Draw the text. It shouldn't hit any DCHECKs or crash. |
| 1648 // See http://crbug.com/214150 | 1643 // See http://crbug.com/214150 |
| 1649 render_text->Draw(&canvas); | 1644 render_text->Draw(&canvas); |
| 1650 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); | 1645 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); |
| 1651 } | 1646 } |
| 1652 } | 1647 } |
| 1653 | 1648 |
| 1649 #if defined(OS_WIN) | |
| 1650 TEST_F(RenderTextTest, Multiline_MinWidth) { | |
|
msw
2013/09/11 17:32:37
nit: Add high-level comments explaining what each
ckocagil
2013/09/11 20:31:16
Done.
| |
| 1651 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, | |
| 1652 kRtlLtr, kRtlLtrRtl }; | |
| 1653 | |
| 1654 scoped_ptr<RenderTextWin> render_text( | |
| 1655 static_cast<RenderTextWin*>(RenderText::CreateInstance())); | |
| 1656 render_text->SetDisplayRect(Rect(Point(), Size(1, 1000))); | |
| 1657 render_text->SetMultiline(true); | |
| 1658 Canvas canvas; | |
| 1659 | |
| 1660 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { | |
| 1661 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); | |
| 1662 render_text->SetText(WideToUTF16(kTestStrings[i])); | |
| 1663 render_text->Draw(&canvas); | |
| 1664 EXPECT_GT(render_text->lines_.size(), 1U); | |
| 1665 } | |
| 1666 } | |
| 1667 | |
| 1668 TEST_F(RenderTextTest, Multiline_NormalWidth) { | |
| 1669 const struct { | |
| 1670 const wchar_t* const text; | |
| 1671 const ui::Range first_line_char_range; | |
| 1672 const ui::Range second_line_char_range; | |
| 1673 } kTestStrings[] = { | |
| 1674 { L"abc defg hijkl", ui::Range(0, 9), ui::Range(9, 14) }, | |
| 1675 { L"qwertyuiop", ui::Range(0, 8), ui::Range(8, 10) }, | |
| 1676 { L"\x0647\x0630\x0627 \x0647\x0648 \x0627\x0644\x0628\x0627\x0628", | |
| 1677 ui::Range(0, 7), ui::Range(7, 12) } | |
| 1678 }; | |
| 1679 | |
| 1680 scoped_ptr<RenderTextWin> render_text( | |
| 1681 static_cast<RenderTextWin*>(RenderText::CreateInstance())); | |
| 1682 render_text->SetDisplayRect(Rect(Point(), Size(50, 1000))); | |
| 1683 render_text->SetMultiline(true); | |
| 1684 Canvas canvas; | |
| 1685 | |
| 1686 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestStrings); ++i) { | |
| 1687 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); | |
| 1688 render_text->SetText(WideToUTF16(kTestStrings[i].text)); | |
| 1689 render_text->Draw(&canvas); | |
| 1690 CheckLineIntegrity(render_text->lines_, render_text->runs_); | |
|
msw
2013/09/11 17:32:37
You shouldn't need to call this explicitly here, i
ckocagil
2013/09/11 20:31:16
Done.
| |
| 1691 ASSERT_EQ(2U, render_text->lines_.size()); | |
| 1692 ASSERT_EQ(1U, render_text->lines_[0].segments.size()); | |
| 1693 EXPECT_EQ(kTestStrings[i].first_line_char_range, | |
| 1694 render_text->lines_[0].segments[0].char_range); | |
| 1695 ASSERT_EQ(1U, render_text->lines_[1].segments.size()); | |
| 1696 EXPECT_EQ(kTestStrings[i].second_line_char_range, | |
| 1697 render_text->lines_[1].segments[0].char_range); | |
| 1698 } | |
| 1699 } | |
| 1700 | |
| 1701 TEST_F(RenderTextTest, Multiline_SufficientWidth) { | |
| 1702 const wchar_t* kTestStrings[] = { L"", L" ", | |
| 1703 L".", L" . ", | |
| 1704 L"abc", L"a b c", | |
| 1705 L"\x62E\x628\x632", L"\x62E \x628 \x632" }; | |
| 1706 | |
| 1707 scoped_ptr<RenderTextWin> render_text( | |
| 1708 static_cast<RenderTextWin*>(RenderText::CreateInstance())); | |
| 1709 render_text->SetDisplayRect(Rect(Point(), Size(30, 1000))); | |
| 1710 render_text->SetMultiline(true); | |
| 1711 Canvas canvas; | |
| 1712 | |
| 1713 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { | |
| 1714 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); | |
| 1715 render_text->SetText(WideToUTF16(kTestStrings[i])); | |
| 1716 render_text->Draw(&canvas); | |
| 1717 EXPECT_EQ(1U, render_text->lines_.size()); | |
| 1718 } | |
| 1719 } | |
| 1720 #endif // defined(OS_WIN) | |
| 1721 | |
| 1654 } // namespace gfx | 1722 } // namespace gfx |
| OLD | NEW |