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/i18n/break_iterator.h" | 10 #include "base/i18n/break_iterator.h" |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 class RenderTextTest : public testing::Test { | 167 class RenderTextTest : public testing::Test { |
| 168 }; | 168 }; |
| 169 | 169 |
| 170 TEST_F(RenderTextTest, DefaultStyle) { | 170 TEST_F(RenderTextTest, DefaultStyle) { |
| 171 // Check the default styles applied to new instances and adjusted text. | 171 // Check the default styles applied to new instances and adjusted text. |
| 172 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 172 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 173 EXPECT_TRUE(render_text->text().empty()); | 173 EXPECT_TRUE(render_text->text().empty()); |
| 174 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; | 174 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; |
| 175 for (size_t i = 0; i < arraysize(cases); ++i) { | 175 for (size_t i = 0; i < arraysize(cases); ++i) { |
| 176 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLACK)); | 176 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLACK)); |
| 177 EXPECT_TRUE( | |
| 178 render_text->baselines().EqualsValueForTesting(NORMAL_BASELINE)); | |
| 177 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 179 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 178 EXPECT_TRUE(render_text->styles()[style].EqualsValueForTesting(false)); | 180 EXPECT_TRUE(render_text->styles()[style].EqualsValueForTesting(false)); |
| 179 render_text->SetText(WideToUTF16(cases[i])); | 181 render_text->SetText(WideToUTF16(cases[i])); |
| 180 } | 182 } |
| 181 } | 183 } |
| 182 | 184 |
| 183 TEST_F(RenderTextTest, SetColorAndStyle) { | 185 TEST_F(RenderTextTest, SetColorAndStyle) { |
| 184 // Ensure custom default styles persist across setting and clearing text. | 186 // Ensure custom default styles persist across setting and clearing text. |
| 185 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 187 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 186 const SkColor color = SK_ColorRED; | 188 const SkColor color = SK_ColorRED; |
| 187 render_text->SetColor(color); | 189 render_text->SetColor(color); |
| 190 render_text->SetBaselineStyle(SUPERSCRIPT); | |
| 188 render_text->SetStyle(BOLD, true); | 191 render_text->SetStyle(BOLD, true); |
| 189 render_text->SetStyle(UNDERLINE, false); | 192 render_text->SetStyle(UNDERLINE, false); |
| 190 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; | 193 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; |
| 191 for (size_t i = 0; i < arraysize(cases); ++i) { | 194 for (size_t i = 0; i < arraysize(cases); ++i) { |
| 192 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(color)); | 195 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(color)); |
| 196 EXPECT_TRUE(render_text->baselines().EqualsValueForTesting(SUPERSCRIPT)); | |
| 193 EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(true)); | 197 EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(true)); |
| 194 EXPECT_TRUE(render_text->styles()[UNDERLINE].EqualsValueForTesting(false)); | 198 EXPECT_TRUE(render_text->styles()[UNDERLINE].EqualsValueForTesting(false)); |
| 195 render_text->SetText(WideToUTF16(cases[i])); | 199 render_text->SetText(WideToUTF16(cases[i])); |
| 196 | 200 |
| 197 // Ensure custom default styles can be applied after text has been set. | 201 // Ensure custom default styles can be applied after text has been set. |
| 198 if (i == 1) | 202 if (i == 1) |
| 199 render_text->SetStyle(STRIKE, true); | 203 render_text->SetStyle(STRIKE, true); |
| 200 if (i >= 1) | 204 if (i >= 1) |
| 201 EXPECT_TRUE(render_text->styles()[STRIKE].EqualsValueForTesting(true)); | 205 EXPECT_TRUE(render_text->styles()[STRIKE].EqualsValueForTesting(true)); |
| 202 } | 206 } |
| 203 } | 207 } |
| 204 | 208 |
| 205 TEST_F(RenderTextTest, ApplyColorAndStyle) { | 209 TEST_F(RenderTextTest, ApplyColorAndStyle) { |
| 206 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 210 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| 207 render_text->SetText(ASCIIToUTF16("012345678")); | 211 render_text->SetText(ASCIIToUTF16("012345678")); |
| 208 | 212 |
| 209 // Apply a ranged color and style and check the resulting breaks. | 213 // Apply a ranged color and style and check the resulting breaks. |
| 210 render_text->ApplyColor(SK_ColorRED, Range(1, 4)); | 214 render_text->ApplyColor(SK_ColorRED, Range(1, 4)); |
| 215 render_text->ApplyBaselineStyle(SUPERIOR, Range(2, 4)); | |
| 211 render_text->ApplyStyle(BOLD, true, Range(2, 5)); | 216 render_text->ApplyStyle(BOLD, true, Range(2, 5)); |
| 212 std::vector<std::pair<size_t, SkColor> > expected_color; | 217 std::vector<std::pair<size_t, SkColor> > expected_color; |
| 213 expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorBLACK)); | 218 expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorBLACK)); |
| 214 expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorRED)); | 219 expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorRED)); |
| 215 expected_color.push_back(std::pair<size_t, SkColor>(4, SK_ColorBLACK)); | 220 expected_color.push_back(std::pair<size_t, SkColor>(4, SK_ColorBLACK)); |
| 216 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); | 221 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); |
| 222 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_style; | |
| 223 expected_baseline_style.push_back( | |
| 224 std::pair<size_t, BaselineStyle>(0, NORMAL_BASELINE)); | |
| 225 expected_baseline_style.push_back( | |
| 226 std::pair<size_t, BaselineStyle>(2, SUPERIOR)); | |
| 227 expected_baseline_style.push_back( | |
| 228 std::pair<size_t, BaselineStyle>(4, NORMAL_BASELINE)); | |
| 229 EXPECT_TRUE( | |
| 230 render_text->baselines().EqualsForTesting(expected_baseline_style)); | |
| 217 std::vector<std::pair<size_t, bool> > expected_style; | 231 std::vector<std::pair<size_t, bool> > expected_style; |
| 218 expected_style.push_back(std::pair<size_t, bool>(0, false)); | 232 expected_style.push_back(std::pair<size_t, bool>(0, false)); |
| 219 expected_style.push_back(std::pair<size_t, bool>(2, true)); | 233 expected_style.push_back(std::pair<size_t, bool>(2, true)); |
| 220 expected_style.push_back(std::pair<size_t, bool>(5, false)); | 234 expected_style.push_back(std::pair<size_t, bool>(5, false)); |
| 221 EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style)); | 235 EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style)); |
| 222 | 236 |
| 223 // Ensure setting a color and style overrides the ranged colors and styles. | 237 // Ensure setting a color, baseline, and style overrides the ranged colors, |
| 238 // baseline, and styles. | |
| 224 render_text->SetColor(SK_ColorBLUE); | 239 render_text->SetColor(SK_ColorBLUE); |
| 225 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLUE)); | 240 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLUE)); |
| 241 render_text->SetBaselineStyle(SUBSCRIPT); | |
| 242 EXPECT_TRUE(render_text->baselines().EqualsValueForTesting(SUBSCRIPT)); | |
| 226 render_text->SetStyle(BOLD, false); | 243 render_text->SetStyle(BOLD, false); |
| 227 EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(false)); | 244 EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(false)); |
| 228 | 245 |
| 229 // Apply a color and style over the text end and check the resulting breaks. | 246 // Apply a color, baseline, and style over the text end and check the |
| 230 // (INT_MAX should be used instead of the text length for the range end) | 247 // resulting breaks (INT_MAX should be used instead of the text length for |
| 248 // the range end) | |
| 231 const size_t text_length = render_text->text().length(); | 249 const size_t text_length = render_text->text().length(); |
| 232 render_text->ApplyColor(SK_ColorRED, Range(0, text_length)); | 250 render_text->ApplyColor(SK_ColorRED, Range(0, text_length)); |
| 251 render_text->ApplyBaselineStyle(SUPERIOR, Range(0, text_length)); | |
| 233 render_text->ApplyStyle(BOLD, true, Range(2, text_length)); | 252 render_text->ApplyStyle(BOLD, true, Range(2, text_length)); |
| 234 std::vector<std::pair<size_t, SkColor> > expected_color_end; | 253 std::vector<std::pair<size_t, SkColor> > expected_color_end; |
| 235 expected_color_end.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED)); | 254 expected_color_end.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED)); |
| 236 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color_end)); | 255 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color_end)); |
| 256 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_end; | |
| 257 expected_baseline_end.push_back( | |
| 258 std::pair<size_t, BaselineStyle>(0, SUPERIOR)); | |
| 259 EXPECT_TRUE(render_text->baselines().EqualsForTesting(expected_baseline_end)); | |
| 237 std::vector<std::pair<size_t, bool> > expected_style_end; | 260 std::vector<std::pair<size_t, bool> > expected_style_end; |
| 238 expected_style_end.push_back(std::pair<size_t, bool>(0, false)); | 261 expected_style_end.push_back(std::pair<size_t, bool>(0, false)); |
| 239 expected_style_end.push_back(std::pair<size_t, bool>(2, true)); | 262 expected_style_end.push_back(std::pair<size_t, bool>(2, true)); |
| 240 EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style_end)); | 263 EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style_end)); |
| 241 | 264 |
| 242 // Ensure ranged values adjust to accommodate text length changes. | 265 // Ensure ranged values adjust to accommodate text length changes. |
| 243 render_text->ApplyStyle(ITALIC, true, Range(0, 2)); | 266 render_text->ApplyStyle(ITALIC, true, Range(0, 2)); |
| 244 render_text->ApplyStyle(ITALIC, true, Range(3, 6)); | 267 render_text->ApplyStyle(ITALIC, true, Range(3, 6)); |
| 245 render_text->ApplyStyle(ITALIC, true, Range(7, text_length)); | 268 render_text->ApplyStyle(ITALIC, true, Range(7, text_length)); |
| 246 std::vector<std::pair<size_t, bool> > expected_italic; | 269 std::vector<std::pair<size_t, bool> > expected_italic; |
| (...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2536 render_text->SetColor(SK_ColorBLACK); | 2559 render_text->SetColor(SK_ColorBLACK); |
| 2537 | 2560 |
| 2538 for (auto string : kTestStrings) { | 2561 for (auto string : kTestStrings) { |
| 2539 surface->getCanvas()->clear(SK_ColorWHITE); | 2562 surface->getCanvas()->clear(SK_ColorWHITE); |
| 2540 render_text->SetText(WideToUTF16(string)); | 2563 render_text->SetText(WideToUTF16(string)); |
| 2541 render_text->SetStyle(BOLD, true); | 2564 render_text->SetStyle(BOLD, true); |
| 2542 render_text->Draw(canvas.get()); | 2565 render_text->Draw(canvas.get()); |
| 2543 int width = render_text->GetStringSize().width(); | 2566 int width = render_text->GetStringSize().width(); |
| 2544 ASSERT_LT(width + kTestWidth, kCanvasSize.width()); | 2567 ASSERT_LT(width + kTestWidth, kCanvasSize.width()); |
| 2545 const uint32* buffer = static_cast<const uint32*>( | 2568 const uint32* buffer = static_cast<const uint32*>( |
| 2546 surface->peekPixels(NULL, NULL)); | 2569 surface->peekPixels(NULL, NULL)); |
|
msw
2015/02/26 03:36:54
nit: nullptr
dschuyler
2015/02/26 23:15:55
Done.
| |
| 2547 ASSERT_NE(nullptr, buffer); | 2570 ASSERT_NE(nullptr, buffer); |
| 2548 | 2571 |
| 2549 for (int y = 0; y < kCanvasSize.height(); ++y) { | 2572 for (int y = 0; y < kCanvasSize.height(); ++y) { |
| 2550 // Allow one column of anti-aliased pixels past the expected width. | 2573 // Allow one column of anti-aliased pixels past the expected width. |
| 2551 SkColor color = buffer[width + y * kCanvasSize.width()]; | 2574 SkColor color = buffer[width + y * kCanvasSize.width()]; |
| 2552 EXPECT_LT(220U, color_utils::GetLuminanceForColor(color)) << string; | 2575 EXPECT_LT(220U, color_utils::GetLuminanceForColor(color)) << string; |
| 2553 for (int x = 1; x < kTestWidth; ++x) { | 2576 for (int x = 1; x < kTestWidth; ++x) { |
| 2554 color = buffer[width + x + y * kCanvasSize.width()]; | 2577 color = buffer[width + x + y * kCanvasSize.width()]; |
| 2555 EXPECT_EQ(SK_ColorWHITE, color) << string; | 2578 EXPECT_EQ(SK_ColorWHITE, color) << string; |
| 2556 } | 2579 } |
| 2557 } | 2580 } |
| 2558 } | 2581 } |
| 2559 } | 2582 } |
| 2560 | 2583 |
| 2584 // Ensure that the width reported by RenderText is sufficient for drawing. Draws | |
| 2585 // to a canvas and checks whether any pixel beyond the bounding rectangle is | |
| 2586 // colored. | |
| 2587 TEST_F(RenderTextTest, TextBaselineStyleDoesntClip) { | |
|
msw
2015/02/26 03:36:53
It might be nice to combine the two tests, or mayb
dschuyler
2015/02/26 23:15:55
I realized that TextDoesntClipt was a subset of Te
| |
| 2588 const wchar_t* kTestStrings[] = { | |
| 2589 L"TEST_______", | |
| 2590 L"WWWWWWWWWW", | |
| 2591 L"gAXAXAXAXAXAXA", | |
| 2592 L"g\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5", | |
| 2593 L"\x0647\x0654\x0647\x0654\x0647\x0654\x0647\x0654\x0645\x0631\x062D" | |
| 2594 L"\x0628\x0627"}; | |
| 2595 const Size kCanvasSize(300, 50); | |
| 2596 const int kTestSize = 10; | |
| 2597 | |
| 2598 skia::RefPtr<SkSurface> surface = skia::AdoptRef( | |
| 2599 SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); | |
| 2600 scoped_ptr<Canvas> canvas( | |
| 2601 Canvas::CreateCanvasWithoutScaling(surface->getCanvas(), 1.0f)); | |
| 2602 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | |
| 2603 render_text->SetDisplayRect(Rect(kCanvasSize)); | |
| 2604 render_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
|
msw
2015/02/26 03:36:53
nit: you can remove all gfx:: qualifiers in this t
dschuyler
2015/02/26 23:15:55
Done.
| |
| 2605 render_text->SetColor(SK_ColorBLACK); | |
| 2606 | |
| 2607 for (auto string : kTestStrings) { | |
| 2608 surface->getCanvas()->clear(SK_ColorWHITE); | |
| 2609 render_text->SetText(WideToUTF16(string)); | |
| 2610 render_text->ApplyBaselineStyle(SUPERSCRIPT, gfx::Range(1, 2)); | |
| 2611 render_text->ApplyBaselineStyle(SUPERIOR, gfx::Range(3, 4)); | |
| 2612 render_text->ApplyBaselineStyle(INFERIOR, gfx::Range(5, 6)); | |
| 2613 render_text->ApplyBaselineStyle(SUBSCRIPT, gfx::Range(7, 8)); | |
| 2614 render_text->SetStyle(BOLD, true); | |
| 2615 render_text->SetDisplayRect( | |
| 2616 Rect(kTestSize, 0, kCanvasSize.width() - kTestSize, | |
|
msw
2015/02/26 03:36:54
Shouldn't the width be render_text->GetStringSize(
dschuyler
2015/02/26 23:15:55
If the intent were to clip to the rect, yes. The
| |
| 2617 render_text->GetStringSize().height() + kTestSize * 2)); | |
| 2618 #if 1 | |
| 2619 // REMOVE(dschuyler): This should be removed because it creates a fake | |
| 2620 // success for this test by clipping the text. | |
| 2621 render_text->SetDisplayRect(Rect(kTestSize, kTestSize, | |
| 2622 kCanvasSize.width() - kTestSize, | |
| 2623 render_text->GetStringSize().height())); | |
| 2624 #endif | |
| 2625 render_text->Draw(canvas.get()); | |
| 2626 int width = render_text->GetStringSize().width(); | |
| 2627 ASSERT_LT(width + kTestSize, kCanvasSize.width()); | |
| 2628 const uint32* buffer = | |
| 2629 static_cast<const uint32*>(surface->peekPixels(NULL, NULL)); | |
|
msw
2015/02/26 03:36:53
nit: nullptr
dschuyler
2015/02/26 23:15:55
Done.
| |
| 2630 ASSERT_NE(nullptr, buffer); | |
| 2631 // Top side. | |
| 2632 for (int y = 0; y < kTestSize; ++y) { | |
|
msw
2015/02/26 03:36:53
I don't think you can assume the text will be vert
dschuyler
2015/02/26 23:15:55
Thanks for pointing out the clip to display rect f
| |
| 2633 for (int x = 0; x < kCanvasSize.width(); ++x) { | |
| 2634 SkColor color = buffer[x + y * kCanvasSize.width()]; | |
| 2635 EXPECT_EQ(SK_ColorWHITE, color) << string << " at " << x << ", " << y; | |
| 2636 } | |
| 2637 } | |
| 2638 // Bottom side. | |
| 2639 int underside = (kTestSize + render_text->GetStringSize().height()); | |
| 2640 for (int y = underside; y < underside + kTestSize; ++y) { | |
| 2641 for (int x = 0; x < kCanvasSize.width(); ++x) { | |
| 2642 SkColor color = buffer[x + y * kCanvasSize.width()]; | |
| 2643 EXPECT_EQ(SK_ColorWHITE, color) << string << " at " << x << ", " << y; | |
| 2644 } | |
| 2645 } | |
| 2646 // Left side. | |
| 2647 for (int y = 0; y < kCanvasSize.height(); ++y) { | |
| 2648 int current_y = y * kCanvasSize.width(); | |
| 2649 SkColor color; | |
| 2650 for (int x = 0; x < kTestSize; ++x) { | |
| 2651 color = buffer[x + current_y]; | |
| 2652 EXPECT_EQ(SK_ColorWHITE, color) << string << " at " << x << ", " << y; | |
| 2653 } | |
| 2654 } | |
| 2655 // Right side. | |
| 2656 for (int y = 0; y < kCanvasSize.height(); ++y) { | |
| 2657 // Allow one column of anti-aliased pixels past the expected width. | |
| 2658 SkColor color = buffer[kTestSize + width + y * kCanvasSize.width()]; | |
| 2659 EXPECT_LT(220U, color_utils::GetLuminanceForColor(color)) << string; | |
| 2660 for (int x = 1; x < kTestSize; ++x) { | |
| 2661 color = buffer[kTestSize + width + x + y * kCanvasSize.width()]; | |
| 2662 EXPECT_EQ(SK_ColorWHITE, color) << string << " at " << x << ", " << y; | |
| 2663 } | |
| 2664 } | |
| 2665 } | |
| 2666 } | |
| 2667 | |
| 2561 } // namespace gfx | 2668 } // namespace gfx |
| OLD | NEW |