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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 int left, | 187 int left, |
188 int top, | 188 int top, |
189 int width, | 189 int width, |
190 int height) const { | 190 int height) const { |
191 ASSERT_LT(top, row_count_) << string_; | 191 ASSERT_LT(top, row_count_) << string_; |
192 ASSERT_LE(top + height, row_count_) << string_; | 192 ASSERT_LE(top + height, row_count_) << string_; |
193 ASSERT_LT(left, stride_) << string_; | 193 ASSERT_LT(left, stride_) << string_; |
194 ASSERT_LE(left + width, stride_) << string_ << ", left " << left | 194 ASSERT_LE(left + width, stride_) << string_ << ", left " << left |
195 << ", width " << width << ", stride_ " | 195 << ", width " << width << ", stride_ " |
196 << stride_; | 196 << stride_; |
197 // Only report the first N failures. | |
198 uint32_t fail_limit = 5; | |
197 for (int y = top; y < top + height; ++y) { | 199 for (int y = top; y < top + height; ++y) { |
198 for (int x = left; x < left + width; ++x) { | 200 for (int x = left; x < left + width; ++x) { |
199 SkColor buffer_color = buffer_[x + y * stride_]; | 201 SkColor buffer_color = buffer_[x + y * stride_]; |
202 if (color != buffer_color && !(--fail_limit)) { | |
203 EXPECT_TRUE(fail_limit) << "fail_limit reached"; | |
204 return; | |
205 } | |
200 EXPECT_EQ(color, buffer_color) << string_ << " at " << x << ", " << y; | 206 EXPECT_EQ(color, buffer_color) << string_ << " at " << x << ", " << y; |
201 } | 207 } |
202 } | 208 } |
203 } | 209 } |
204 | 210 |
211 void EnsureSolidBorder(SkColor color, const Rect& rect) const { | |
212 { | |
213 SCOPED_TRACE("EnsureSolidBorder Top Side"); | |
214 EnsureSolidRect(SK_ColorWHITE, 0, 0, stride_, rect.y()); | |
215 } | |
216 { | |
217 SCOPED_TRACE("EnsureSolidBorder Bottom Side"); | |
218 EnsureSolidRect(SK_ColorWHITE, 0, rect.bottom(), stride_, | |
219 row_count_ - rect.bottom()); | |
220 } | |
221 { | |
222 SCOPED_TRACE("EnsureSolidBorder Left Side"); | |
223 EnsureSolidRect(SK_ColorWHITE, 0, rect.y(), rect.x(), rect.height()); | |
224 } | |
225 { | |
226 SCOPED_TRACE("EnsureSolidBorder Right Side"); | |
227 EnsureSolidRect(SK_ColorWHITE, rect.right(), rect.y(), | |
228 stride_ - rect.right(), rect.height()); | |
229 } | |
230 } | |
231 | |
205 private: | 232 private: |
206 const wchar_t* string_; | 233 const wchar_t* string_; |
207 const SkColor* buffer_; | 234 const SkColor* buffer_; |
208 int stride_; | 235 int stride_; |
209 int row_count_; | 236 int row_count_; |
210 | 237 |
211 DISALLOW_COPY_AND_ASSIGN(TestRectangleBuffer); | 238 DISALLOW_COPY_AND_ASSIGN(TestRectangleBuffer); |
212 }; | 239 }; |
213 | 240 |
214 } // namespace | 241 } // namespace |
(...skipping 2476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2691 render_text->SetText(kString); | 2718 render_text->SetText(kString); |
2692 render_text->ApplyStyle(BOLD, true, Range(0, 3)); | 2719 render_text->ApplyStyle(BOLD, true, Range(0, 3)); |
2693 render_text->SetElideBehavior(ELIDE_TAIL); | 2720 render_text->SetElideBehavior(ELIDE_TAIL); |
2694 | 2721 |
2695 render_text->SetDisplayRect(Rect(0, 0, 500, 100)); | 2722 render_text->SetDisplayRect(Rect(0, 0, 500, 100)); |
2696 EXPECT_EQ(kString, render_text->GetDisplayText()); | 2723 EXPECT_EQ(kString, render_text->GetDisplayText()); |
2697 render_text->SetDisplayRect(Rect(0, 0, render_text->GetContentWidth(), 100)); | 2724 render_text->SetDisplayRect(Rect(0, 0, render_text->GetContentWidth(), 100)); |
2698 EXPECT_EQ(kString, render_text->GetDisplayText()); | 2725 EXPECT_EQ(kString, render_text->GetDisplayText()); |
2699 } | 2726 } |
2700 | 2727 |
2728 // TODO(dschuyler): Alignment tests disabled on Mac because RenderTextMac | |
2729 // does not implement this yet. | |
2730 #if !defined(OS_MACOSX) | |
2731 TEST_F(RenderTextTest, VerticalAlignment) { | |
msw
2015/04/01 15:07:17
Can you add a separate test for multiline vertical
| |
2732 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | |
2733 const wchar_t* string = L"g Hello g"; | |
msw
2015/04/01 15:07:18
nit: inline this below
| |
2734 render_text->SetText(WideToUTF16(string)); | |
2735 render_text->ApplyStyle(BOLD, true, Range(0, 3)); | |
msw
2015/04/01 15:07:18
Why apply bold? Do you check this somehow?
| |
2736 const Size kCanvasSize(171, 50); | |
msw
2015/04/01 15:07:18
nit: where did 171 come from? That seems awfully s
| |
2737 const int kTestSize = 10; | |
2738 const Size string_size(render_text->GetContentWidth(), | |
2739 render_text->GetStringSize().height()); | |
2740 // The + 1 accounts for legacy behavior in GetAlignmentOffset(). | |
2741 const int kCenterBegin = (kCanvasSize.width() + 1 - string_size.width()) / 2; | |
2742 const int kRightBegin = kCanvasSize.width() - string_size.width() - kTestSize; | |
2743 // TODO(dschuyler): Determine where the need for the -1 below originates from. | |
2744 const int kMiddleBegin = | |
2745 ((kCanvasSize.height()) / 2) - 1 + | |
msw
2015/04/01 15:07:17
nit: remove the "kCanvasSize.height()" parens, opt
| |
2746 (render_text->GetBaseline() - render_text->GetDisplayTextBaseline()); | |
2747 const int kBottomBegin = | |
2748 kCanvasSize.height() - string_size.height() - kTestSize; | |
2749 | |
2750 struct Tests { | |
2751 HorizontalAlignment horizontal; | |
msw
2015/04/01 15:07:17
Is testing vertical alignment functionality for ea
| |
2752 VerticalAlignment vertical; | |
2753 int x; | |
2754 int y; | |
2755 } const kTests[] = { | |
2756 {ALIGN_LEFT, VALIGN_TOP, kTestSize, kTestSize}, | |
2757 {ALIGN_LEFT, VALIGN_MIDDLE, kTestSize, kMiddleBegin}, | |
2758 {ALIGN_LEFT, VALIGN_BOTTOM, kTestSize, kBottomBegin}, | |
2759 {ALIGN_CENTER, VALIGN_TOP, kCenterBegin, kTestSize}, | |
2760 {ALIGN_CENTER, VALIGN_MIDDLE, kCenterBegin, kMiddleBegin}, | |
2761 {ALIGN_CENTER, VALIGN_BOTTOM, kCenterBegin, kBottomBegin}, | |
2762 {ALIGN_RIGHT, VALIGN_TOP, kRightBegin, kTestSize}, | |
2763 {ALIGN_RIGHT, VALIGN_MIDDLE, kRightBegin, kMiddleBegin}, | |
2764 {ALIGN_RIGHT, VALIGN_BOTTOM, kRightBegin, kBottomBegin}, | |
2765 }; | |
2766 | |
2767 skia::RefPtr<SkSurface> surface = skia::AdoptRef( | |
msw
2015/04/01 15:07:18
Remove this, it's no longer necessary.
| |
2768 SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); | |
2769 render_text->SetColor(SK_ColorBLACK); | |
msw
2015/04/01 15:07:18
ditto: Remove this, it's no longer necessary.
| |
2770 Rect bounds = Rect(kTestSize, kTestSize, kCanvasSize.width() - kTestSize * 2, | |
2771 kCanvasSize.height() - kTestSize * 2); | |
2772 render_text->SetDisplayRect(bounds); | |
2773 // Allow the RenderText to paint outside of its display rect. | |
2774 render_text->set_clip_to_display_rect(false); | |
msw
2015/04/01 15:07:18
ditto: Remove this, it's no longer necessary.
| |
2775 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width()); | |
2776 ASSERT_LE(string_size.height() + kTestSize * 2, kCanvasSize.height()); | |
2777 for (const auto& test : kTests) { | |
2778 SCOPED_TRACE(base::StringPrintf("VerticalAlignement H %i, V %i", | |
msw
2015/04/01 15:07:18
nit: "Alignment", but again, the test name isn't n
| |
2779 test.horizontal, test.vertical)); | |
2780 | |
2781 surface->getCanvas()->clear(SK_ColorWHITE); | |
msw
2015/04/01 15:07:18
ditto: Remove this, it's no longer necessary.
| |
2782 render_text->SetHorizontalAlignment(test.horizontal); | |
2783 render_text->SetVerticalAlignment(test.vertical); | |
2784 EXPECT_EQ(test.x - kTestSize, render_text->GetAlignmentOffset(0).x()); | |
2785 EXPECT_EQ(test.y - kTestSize, render_text->GetAlignmentOffset(0).y()); | |
2786 } | |
2787 } | |
2788 #endif // !defined(OS_MACOSX) | |
2789 | |
2701 // TODO(derat): Figure out why this fails on Windows: http://crbug.com/427184 | 2790 // TODO(derat): Figure out why this fails on Windows: http://crbug.com/427184 |
2702 #if !defined(OS_WIN) | 2791 #if !defined(OS_WIN) |
2703 // Ensure that RenderText examines all of the fonts in its FontList before | 2792 // Ensure that RenderText examines all of the fonts in its FontList before |
2704 // falling back to other fonts. | 2793 // falling back to other fonts. |
2705 TEST_F(RenderTextTest, HarfBuzz_FontListFallback) { | 2794 TEST_F(RenderTextTest, HarfBuzz_FontListFallback) { |
2706 // Double-check that the requested fonts are present. | 2795 // Double-check that the requested fonts are present. |
2707 FontList font_list("Arial, Symbol, 12px"); | 2796 FontList font_list("Arial, Symbol, 12px"); |
2708 const std::vector<Font>& fonts = font_list.GetFonts(); | 2797 const std::vector<Font>& fonts = font_list.GetFonts(); |
2709 ASSERT_EQ(2u, fonts.size()); | 2798 ASSERT_EQ(2u, fonts.size()); |
2710 ASSERT_EQ("arial", | 2799 ASSERT_EQ("arial", |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2785 SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); | 2874 SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); |
2786 scoped_ptr<Canvas> canvas( | 2875 scoped_ptr<Canvas> canvas( |
2787 Canvas::CreateCanvasWithoutScaling(surface->getCanvas(), 1.0f)); | 2876 Canvas::CreateCanvasWithoutScaling(surface->getCanvas(), 1.0f)); |
2788 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 2877 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
2789 render_text->SetHorizontalAlignment(ALIGN_LEFT); | 2878 render_text->SetHorizontalAlignment(ALIGN_LEFT); |
2790 render_text->SetColor(SK_ColorBLACK); | 2879 render_text->SetColor(SK_ColorBLACK); |
2791 | 2880 |
2792 for (auto string : kTestStrings) { | 2881 for (auto string : kTestStrings) { |
2793 surface->getCanvas()->clear(SK_ColorWHITE); | 2882 surface->getCanvas()->clear(SK_ColorWHITE); |
2794 render_text->SetText(WideToUTF16(string)); | 2883 render_text->SetText(WideToUTF16(string)); |
2795 const Size string_size = render_text->GetStringSize(); | 2884 const Size string_size(render_text->GetContentWidth(), |
2885 render_text->GetStringSize().height()); | |
2796 render_text->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2)); | 2886 render_text->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2)); |
2797 render_text->ApplyBaselineStyle(SUPERIOR, Range(3, 4)); | 2887 render_text->ApplyBaselineStyle(SUPERIOR, Range(3, 4)); |
2798 render_text->ApplyBaselineStyle(INFERIOR, Range(5, 6)); | 2888 render_text->ApplyBaselineStyle(INFERIOR, Range(5, 6)); |
2799 render_text->ApplyBaselineStyle(SUBSCRIPT, Range(7, 8)); | 2889 render_text->ApplyBaselineStyle(SUBSCRIPT, Range(7, 8)); |
2800 render_text->SetStyle(BOLD, true); | 2890 render_text->SetStyle(BOLD, true); |
2801 render_text->SetDisplayRect( | 2891 render_text->SetDisplayRect( |
2802 Rect(kTestSize, kTestSize, string_size.width(), string_size.height())); | 2892 Rect(kTestSize, kTestSize, string_size.width(), string_size.height())); |
2803 // Allow the RenderText to paint outside of its display rect. | 2893 // Allow the RenderText to paint outside of its display rect. |
2804 render_text->set_clip_to_display_rect(false); | 2894 render_text->set_clip_to_display_rect(false); |
2805 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width()); | 2895 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width()); |
2896 ASSERT_LE(string_size.height() + kTestSize * 2, kCanvasSize.height()); | |
2806 | 2897 |
2807 render_text->Draw(canvas.get()); | 2898 render_text->Draw(canvas.get()); |
2808 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); | |
2809 const uint32* buffer = | 2899 const uint32* buffer = |
2810 static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); | 2900 static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); |
2811 ASSERT_NE(nullptr, buffer); | 2901 ASSERT_NE(nullptr, buffer); |
2812 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), | 2902 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), |
2813 kCanvasSize.height()); | 2903 kCanvasSize.height()); |
2904 // TODO(dschuyler): After platform issues are resolved below, change to | |
2905 // using EnsureSolidBorder() rather than EnsureSolidRect(). | |
2814 { | 2906 { |
2815 #if !defined(OS_CHROMEOS) | 2907 #if !defined(OS_CHROMEOS) |
2816 // TODO(dschuyler): On ChromeOS text draws above the GetStringSize rect. | 2908 // TODO(dschuyler): On ChromeOS text draws above the GetStringSize rect. |
2817 SCOPED_TRACE("TextDoesntClip Top Side"); | 2909 SCOPED_TRACE("TextDoesntClip Top Side"); |
2818 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), | 2910 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), |
2819 kTestSize); | 2911 kTestSize); |
2820 #endif | 2912 #endif |
2821 } | 2913 } |
2822 { | 2914 { |
2823 SCOPED_TRACE("TextDoesntClip Bottom Side"); | 2915 SCOPED_TRACE("TextDoesntClip Bottom Side"); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2868 SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); | 2960 SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height())); |
2869 scoped_ptr<Canvas> canvas( | 2961 scoped_ptr<Canvas> canvas( |
2870 Canvas::CreateCanvasWithoutScaling(surface->getCanvas(), 1.0f)); | 2962 Canvas::CreateCanvasWithoutScaling(surface->getCanvas(), 1.0f)); |
2871 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 2963 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
2872 render_text->SetHorizontalAlignment(ALIGN_LEFT); | 2964 render_text->SetHorizontalAlignment(ALIGN_LEFT); |
2873 render_text->SetColor(SK_ColorBLACK); | 2965 render_text->SetColor(SK_ColorBLACK); |
2874 | 2966 |
2875 for (auto string : kTestStrings) { | 2967 for (auto string : kTestStrings) { |
2876 surface->getCanvas()->clear(SK_ColorWHITE); | 2968 surface->getCanvas()->clear(SK_ColorWHITE); |
2877 render_text->SetText(WideToUTF16(string)); | 2969 render_text->SetText(WideToUTF16(string)); |
2878 const Size string_size = render_text->GetStringSize(); | 2970 const Size string_size(render_text->GetContentWidth(), |
2971 render_text->GetStringSize().height()); | |
2879 int fake_width = string_size.width() / 2; | 2972 int fake_width = string_size.width() / 2; |
2880 int fake_height = string_size.height() / 2; | 2973 int fake_height = string_size.height() / 2; |
2881 render_text->SetDisplayRect( | 2974 const Rect bounds(kTestSize, kTestSize, fake_width, fake_height); |
2882 Rect(kTestSize, kTestSize, fake_width, fake_height)); | 2975 render_text->SetDisplayRect(bounds); |
2883 render_text->set_clip_to_display_rect(true); | 2976 render_text->set_clip_to_display_rect(true); |
2977 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width()); | |
2978 ASSERT_LE(string_size.height() + kTestSize * 2, kCanvasSize.height()); | |
2884 render_text->Draw(canvas.get()); | 2979 render_text->Draw(canvas.get()); |
2885 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); | |
2886 const uint32* buffer = | 2980 const uint32* buffer = |
2887 static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); | 2981 static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); |
2888 ASSERT_NE(nullptr, buffer); | 2982 ASSERT_NE(nullptr, buffer); |
2889 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), | 2983 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), |
2890 kCanvasSize.height()); | 2984 kCanvasSize.height()); |
2891 { | 2985 rect_buffer.EnsureSolidBorder(SK_ColorWHITE, bounds); |
2892 SCOPED_TRACE("TextDoesClip Top Side"); | |
2893 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), | |
2894 kTestSize); | |
2895 } | |
2896 | |
2897 { | |
2898 SCOPED_TRACE("TextDoesClip Bottom Side"); | |
2899 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, kTestSize + fake_height, | |
2900 kCanvasSize.width(), kTestSize); | |
2901 } | |
2902 { | |
2903 SCOPED_TRACE("TextDoesClip Left Side"); | |
2904 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, kTestSize, kTestSize, | |
2905 fake_height); | |
2906 } | |
2907 { | |
2908 SCOPED_TRACE("TextDoesClip Right Side"); | |
2909 rect_buffer.EnsureSolidRect(SK_ColorWHITE, kTestSize + fake_width, | |
2910 kTestSize, kTestSize, fake_height); | |
2911 } | |
2912 } | 2986 } |
2913 } | 2987 } |
2914 | 2988 |
2915 #if defined(OS_MACOSX) | 2989 #if defined(OS_MACOSX) |
2916 TEST_F(RenderTextTest, Mac_ElidedText) { | 2990 TEST_F(RenderTextTest, Mac_ElidedText) { |
2917 RenderTextMac render_text; | 2991 RenderTextMac render_text; |
2918 base::string16 text(ASCIIToUTF16("This is an example.")); | 2992 base::string16 text(ASCIIToUTF16("This is an example.")); |
2919 render_text.SetText(text); | 2993 render_text.SetText(text); |
2920 gfx::Size string_size = render_text.GetStringSize(); | 2994 gfx::Size string_size = render_text.GetStringSize(); |
2921 render_text.SetDisplayRect(gfx::Rect(string_size)); | 2995 render_text.SetDisplayRect(gfx::Rect(string_size)); |
2922 render_text.EnsureLayout(); | 2996 render_text.EnsureLayout(); |
2923 // NOTE: Character and glyph counts are only comparable for simple text. | 2997 // NOTE: Character and glyph counts are only comparable for simple text. |
2924 EXPECT_EQ(text.size(), | 2998 EXPECT_EQ(text.size(), |
2925 static_cast<size_t>(CTLineGetGlyphCount(render_text.line_))); | 2999 static_cast<size_t>(CTLineGetGlyphCount(render_text.line_))); |
2926 | 3000 |
2927 render_text.SetElideBehavior(ELIDE_TAIL); | 3001 render_text.SetElideBehavior(ELIDE_TAIL); |
2928 string_size.set_width(string_size.width() / 2); | 3002 string_size.set_width(string_size.width() / 2); |
2929 render_text.SetDisplayRect(gfx::Rect(string_size)); | 3003 render_text.SetDisplayRect(gfx::Rect(string_size)); |
2930 render_text.EnsureLayout(); | 3004 render_text.EnsureLayout(); |
2931 CFIndex glyph_count = CTLineGetGlyphCount(render_text.line_); | 3005 CFIndex glyph_count = CTLineGetGlyphCount(render_text.line_); |
2932 EXPECT_GT(text.size(), static_cast<size_t>(glyph_count)); | 3006 EXPECT_GT(text.size(), static_cast<size_t>(glyph_count)); |
2933 EXPECT_NE(0, glyph_count); | 3007 EXPECT_NE(0, glyph_count); |
2934 } | 3008 } |
2935 #endif | 3009 #endif |
2936 | 3010 |
2937 } // namespace gfx | 3011 } // namespace gfx |
OLD | NEW |