Chromium Code Reviews| Index: ui/gfx/render_text_unittest.cc |
| diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc |
| index e7829f65d6b86089256f61d473a1303e14908990..ee0b55419fbe993a0f5645e68d3a44cf29e9a613 100644 |
| --- a/ui/gfx/render_text_unittest.cc |
| +++ b/ui/gfx/render_text_unittest.cc |
| @@ -36,6 +36,49 @@ namespace gfx { |
| namespace { |
| +class TestRectangleBuffer { |
|
msw
2015/02/27 01:28:19
nit: move to the end of the namespace, or at least
dschuyler
2015/02/27 03:05:35
Done.
|
| + public: |
| + TestRectangleBuffer(const wchar_t* string, |
| + const SkColor* buffer, |
| + uint32_t stride, |
| + uint32_t row_count) |
| + : string_(string), |
| + buffer_(buffer), |
| + stride_(stride), |
| + row_count_(row_count) {} |
| + |
| + void EnsureSolidRect(SkColor color, |
| + int top, |
| + int left, |
| + int width, |
| + int height) const; |
| + |
| + protected: |
| + const wchar_t* string_; |
| + const SkColor* buffer_; |
| + int stride_; |
| + int row_count_; |
| +}; |
|
msw
2015/02/27 01:28:19
nit: disallow copy and assign
dschuyler
2015/02/27 03:05:35
Done.
|
| + |
| +// Test whether any values in the rectangular area are anything other than |
| +// |color|. |
| +void TestRectangleBuffer::EnsureSolidRect(SkColor color, |
|
msw
2015/02/27 01:28:19
nit: define this inline with the declaration above
dschuyler
2015/02/27 03:05:35
Done.
|
| + int left, |
| + int top, |
| + int width, |
| + int height) const { |
| + ASSERT_LT(top, row_count_) << string_; |
| + ASSERT_LE(top + height, row_count_) << string_; |
| + ASSERT_LT(left, stride_) << string_; |
| + ASSERT_LE(left + width, stride_) << string_; |
| + for (int y = top; y < top + height; ++y) { |
| + for (int x = left; x < left + width; ++x) { |
| + SkColor color = buffer_[x + y * stride_]; |
| + EXPECT_EQ(SK_ColorWHITE, color) << string_ << " at " << x << ", " << y; |
| + } |
| + } |
| +} |
| + |
| // Various weak, LTR, RTL, and Bidi string cases with three characters each. |
| const wchar_t kWeak[] = L" . "; |
| const wchar_t kLtr[] = L"abc"; |
| @@ -174,6 +217,8 @@ TEST_F(RenderTextTest, DefaultStyle) { |
| const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; |
| for (size_t i = 0; i < arraysize(cases); ++i) { |
| EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLACK)); |
| + EXPECT_TRUE( |
| + render_text->baselines().EqualsValueForTesting(NORMAL_BASELINE)); |
| for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| EXPECT_TRUE(render_text->styles()[style].EqualsValueForTesting(false)); |
| render_text->SetText(WideToUTF16(cases[i])); |
| @@ -185,11 +230,13 @@ TEST_F(RenderTextTest, SetColorAndStyle) { |
| scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| const SkColor color = SK_ColorRED; |
| render_text->SetColor(color); |
| + render_text->SetBaselineStyle(SUPERSCRIPT); |
| render_text->SetStyle(BOLD, true); |
| render_text->SetStyle(UNDERLINE, false); |
| const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; |
| for (size_t i = 0; i < arraysize(cases); ++i) { |
| EXPECT_TRUE(render_text->colors().EqualsValueForTesting(color)); |
| + EXPECT_TRUE(render_text->baselines().EqualsValueForTesting(SUPERSCRIPT)); |
| EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(true)); |
| EXPECT_TRUE(render_text->styles()[UNDERLINE].EqualsValueForTesting(false)); |
| render_text->SetText(WideToUTF16(cases[i])); |
| @@ -208,32 +255,51 @@ TEST_F(RenderTextTest, ApplyColorAndStyle) { |
| // Apply a ranged color and style and check the resulting breaks. |
| render_text->ApplyColor(SK_ColorRED, Range(1, 4)); |
| + render_text->ApplyBaselineStyle(SUPERIOR, Range(2, 4)); |
| render_text->ApplyStyle(BOLD, true, Range(2, 5)); |
| std::vector<std::pair<size_t, SkColor> > expected_color; |
| expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorBLACK)); |
| expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorRED)); |
| expected_color.push_back(std::pair<size_t, SkColor>(4, SK_ColorBLACK)); |
| EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); |
| + std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_style; |
| + expected_baseline_style.push_back( |
| + std::pair<size_t, BaselineStyle>(0, NORMAL_BASELINE)); |
| + expected_baseline_style.push_back( |
| + std::pair<size_t, BaselineStyle>(2, SUPERIOR)); |
| + expected_baseline_style.push_back( |
| + std::pair<size_t, BaselineStyle>(4, NORMAL_BASELINE)); |
| + EXPECT_TRUE( |
| + render_text->baselines().EqualsForTesting(expected_baseline_style)); |
| std::vector<std::pair<size_t, bool> > expected_style; |
| expected_style.push_back(std::pair<size_t, bool>(0, false)); |
| expected_style.push_back(std::pair<size_t, bool>(2, true)); |
| expected_style.push_back(std::pair<size_t, bool>(5, false)); |
| EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style)); |
| - // Ensure setting a color and style overrides the ranged colors and styles. |
| + // Ensure setting a color, baseline, and style overrides the ranged colors, |
| + // baseline, and styles. |
| render_text->SetColor(SK_ColorBLUE); |
| EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLUE)); |
| + render_text->SetBaselineStyle(SUBSCRIPT); |
| + EXPECT_TRUE(render_text->baselines().EqualsValueForTesting(SUBSCRIPT)); |
| render_text->SetStyle(BOLD, false); |
| EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(false)); |
| - // Apply a color and style over the text end and check the resulting breaks. |
| - // (INT_MAX should be used instead of the text length for the range end) |
| + // Apply a color, baseline, and style over the text end and check the |
| + // resulting breaks (INT_MAX should be used instead of the text length for |
| + // the range end) |
| const size_t text_length = render_text->text().length(); |
| render_text->ApplyColor(SK_ColorRED, Range(0, text_length)); |
| + render_text->ApplyBaselineStyle(SUPERIOR, Range(0, text_length)); |
| render_text->ApplyStyle(BOLD, true, Range(2, text_length)); |
| std::vector<std::pair<size_t, SkColor> > expected_color_end; |
| expected_color_end.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED)); |
| EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color_end)); |
| + std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_end; |
| + expected_baseline_end.push_back( |
| + std::pair<size_t, BaselineStyle>(0, SUPERIOR)); |
| + EXPECT_TRUE(render_text->baselines().EqualsForTesting(expected_baseline_end)); |
| std::vector<std::pair<size_t, bool> > expected_style_end; |
| expected_style_end.push_back(std::pair<size_t, bool>(0, false)); |
| expected_style_end.push_back(std::pair<size_t, bool>(2, true)); |
| @@ -2520,11 +2586,18 @@ TEST_F(RenderTextTest, HarfBuzz_UniscribeFallback) { |
| #endif // defined(OS_WIN) |
| // Ensure that the width reported by RenderText is sufficient for drawing. Draws |
| -// to a canvas and checks whether any pixel beyond the width is colored. |
| +// to a canvas and checks whether any pixel beyond the bounding rectangle is |
| +// colored. |
| TEST_F(RenderTextTest, TextDoesntClip) { |
| - const wchar_t* kTestStrings[] = { L"Save", L"Remove", L"TEST", L"W", L"WWW" }; |
| + const wchar_t* kTestStrings[] = { |
| + L"TEST_______", |
| + L"WWWWWWWWWW", |
| + L"gAXAXAXAXAXAXA", |
| + L"g\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5", |
| + L"\x0647\x0654\x0647\x0654\x0647\x0654\x0647\x0654\x0645\x0631\x062D" |
| + L"\x0628\x0627"}; |
| const Size kCanvasSize(300, 50); |
| - const int kTestWidth = 10; |
| + const int kTestSize = 10; |
| skia::RefPtr<SkSurface> surface = skia::AdoptRef( |
| SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); |
| @@ -2532,29 +2605,96 @@ TEST_F(RenderTextTest, TextDoesntClip) { |
| Canvas::CreateCanvasWithoutScaling(surface->getCanvas(), 1.0f)); |
| scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| render_text->SetDisplayRect(Rect(kCanvasSize)); |
| - render_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| + render_text->SetHorizontalAlignment(ALIGN_LEFT); |
| render_text->SetColor(SK_ColorBLACK); |
| for (auto string : kTestStrings) { |
| surface->getCanvas()->clear(SK_ColorWHITE); |
| render_text->SetText(WideToUTF16(string)); |
| + render_text->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2)); |
| + render_text->ApplyBaselineStyle(SUPERIOR, Range(3, 4)); |
| + render_text->ApplyBaselineStyle(INFERIOR, Range(5, 6)); |
| + render_text->ApplyBaselineStyle(SUBSCRIPT, Range(7, 8)); |
| render_text->SetStyle(BOLD, true); |
| + render_text->SetDisplayRect(Rect(kTestSize, kTestSize, |
| + render_text->GetStringSize().width(), |
| + render_text->GetStringSize().height())); |
| +#if 0 |
| + // ADD(dschuyler): This should be added because without it there is a fake |
|
msw
2015/02/27 01:28:19
We shouldn't land this as-is... If we can't make a
dschuyler
2015/02/27 03:05:35
I've added in some test print code for this CL (wh
msw
2015/02/27 03:48:05
Remove print debugging code, but feel free to shar
|
| + // success for this test by clipping the text. |
| + |
| + // Allow the RenderText to paint outside of its display rect. |
| + render_text->set_clip_to_display_rect(false); |
| +#endif |
| render_text->Draw(canvas.get()); |
| int width = render_text->GetStringSize().width(); |
| - ASSERT_LT(width + kTestWidth, kCanvasSize.width()); |
| - const uint32* buffer = static_cast<const uint32*>( |
| - surface->peekPixels(NULL, NULL)); |
| + ASSERT_LT(width + kTestSize, kCanvasSize.width()); |
| + const uint32* buffer = |
| + static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); |
| ASSERT_NE(nullptr, buffer); |
| + TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), |
| + kCanvasSize.height()); |
| + // Top side. |
| + rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), |
| + kTestSize); |
| + // Bottom side. |
| + rect_buffer.EnsureSolidRect( |
| + SK_ColorWHITE, 0, kTestSize + render_text->GetStringSize().height(), |
| + kCanvasSize.width(), kTestSize); |
| + // Left side. |
| + rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, kTestSize, kTestSize, |
| + render_text->GetStringSize().height()); |
| + // Right side. |
| + rect_buffer.EnsureSolidRect( |
| + SK_ColorWHITE, kTestSize + render_text->GetStringSize().width(), |
| + kTestSize, kTestSize, render_text->GetStringSize().height()); |
| + } |
| +} |
| - for (int y = 0; y < kCanvasSize.height(); ++y) { |
| - // Allow one column of anti-aliased pixels past the expected width. |
| - SkColor color = buffer[width + y * kCanvasSize.width()]; |
| - EXPECT_LT(220U, color_utils::GetLuminanceForColor(color)) << string; |
| - for (int x = 1; x < kTestWidth; ++x) { |
| - color = buffer[width + x + y * kCanvasSize.width()]; |
| - EXPECT_EQ(SK_ColorWHITE, color) << string; |
| - } |
| - } |
| +// Ensure that the text will clip to the display rect. Draws to a canvas and |
| +// checks whether any pixel beyond the bounding rectangle is colored. |
| +TEST_F(RenderTextTest, TextDoesClip) { |
| + const wchar_t* kTestStrings[] = {L"TEST", L"W", L"WWWW", L"gAXAXWWWW"}; |
| + const Size kCanvasSize(300, 50); |
| + const int kTestSize = 10; |
| + |
| + skia::RefPtr<SkSurface> surface = skia::AdoptRef( |
| + SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); |
| + scoped_ptr<Canvas> canvas( |
| + Canvas::CreateCanvasWithoutScaling(surface->getCanvas(), 1.0f)); |
| + scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
| + render_text->SetDisplayRect(Rect(kCanvasSize)); |
| + render_text->SetHorizontalAlignment(ALIGN_LEFT); |
| + render_text->SetColor(SK_ColorBLACK); |
| + |
| + for (auto string : kTestStrings) { |
| + surface->getCanvas()->clear(SK_ColorWHITE); |
| + render_text->SetText(WideToUTF16(string)); |
| + int fake_width = render_text->GetStringSize().width() / 2; |
| + int fake_height = render_text->GetStringSize().height() / 2; |
| + render_text->SetDisplayRect( |
| + Rect(kTestSize, kTestSize, fake_width, fake_height)); |
| + render_text->set_clip_to_display_rect(true); |
| + render_text->Draw(canvas.get()); |
| + int width = render_text->GetStringSize().width(); |
| + ASSERT_LT(width + kTestSize, kCanvasSize.width()); |
| + const uint32* buffer = |
| + static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); |
| + ASSERT_NE(nullptr, buffer); |
| + TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), |
| + kCanvasSize.height()); |
| + // Top side. |
| + rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), |
| + kTestSize); |
| + // Bottom side. |
| + rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, kTestSize + fake_height, |
| + kCanvasSize.width(), kTestSize); |
| + // Left side. |
| + rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, kTestSize, kTestSize, |
| + fake_height); |
| + // Right side. |
| + rect_buffer.EnsureSolidRect(SK_ColorWHITE, kTestSize + fake_width, |
| + kTestSize, kTestSize, fake_height); |
| } |
| } |