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 <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
7 #include <algorithm> | 10 #include <algorithm> |
8 | 11 |
9 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
10 #include "base/i18n/break_iterator.h" | 13 #include "base/i18n/break_iterator.h" |
| 14 #include "base/macros.h" |
11 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
12 #include "base/strings/string_split.h" | 16 #include "base/strings/string_split.h" |
13 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
14 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
15 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "build/build_config.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
17 #include "third_party/skia/include/core/SkSurface.h" | 22 #include "third_party/skia/include/core/SkSurface.h" |
18 #include "ui/gfx/break_list.h" | 23 #include "ui/gfx/break_list.h" |
19 #include "ui/gfx/canvas.h" | 24 #include "ui/gfx/canvas.h" |
20 #include "ui/gfx/color_utils.h" | 25 #include "ui/gfx/color_utils.h" |
21 #include "ui/gfx/font.h" | 26 #include "ui/gfx/font.h" |
22 #include "ui/gfx/geometry/point.h" | 27 #include "ui/gfx/geometry/point.h" |
23 #include "ui/gfx/geometry/point_f.h" | 28 #include "ui/gfx/geometry/point_f.h" |
24 #include "ui/gfx/range/range.h" | 29 #include "ui/gfx/range/range.h" |
25 #include "ui/gfx/range/range_f.h" | 30 #include "ui/gfx/range/range_f.h" |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 154 } |
150 | 155 |
151 void GetDecorationLogAndReset(std::vector<DecorationLog>* decoration_log) { | 156 void GetDecorationLogAndReset(std::vector<DecorationLog>* decoration_log) { |
152 decoration_log_.swap(*decoration_log); | 157 decoration_log_.swap(*decoration_log); |
153 decoration_log_.clear(); | 158 decoration_log_.clear(); |
154 } | 159 } |
155 | 160 |
156 private: | 161 private: |
157 // internal::SkiaTextRenderer: | 162 // internal::SkiaTextRenderer: |
158 void DrawPosText(const SkPoint* pos, | 163 void DrawPosText(const SkPoint* pos, |
159 const uint16* glyphs, | 164 const uint16_t* glyphs, |
160 size_t glyph_count) override { | 165 size_t glyph_count) override { |
161 TextLog log_entry; | 166 TextLog log_entry; |
162 log_entry.glyph_count = glyph_count; | 167 log_entry.glyph_count = glyph_count; |
163 if (glyph_count > 0) { | 168 if (glyph_count > 0) { |
164 log_entry.origin = | 169 log_entry.origin = |
165 PointF(SkScalarToFloat(pos[0].x()), SkScalarToFloat(pos[0].y())); | 170 PointF(SkScalarToFloat(pos[0].x()), SkScalarToFloat(pos[0].y())); |
166 for (size_t i = 1U; i < glyph_count; ++i) { | 171 for (size_t i = 1U; i < glyph_count; ++i) { |
167 log_entry.origin.SetToMin( | 172 log_entry.origin.SetToMin( |
168 PointF(SkScalarToFloat(pos[i].x()), SkScalarToFloat(pos[i].y()))); | 173 PointF(SkScalarToFloat(pos[i].x()), SkScalarToFloat(pos[i].y()))); |
169 } | 174 } |
(...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2606 text_log[0].glyph_count); | 2611 text_log[0].glyph_count); |
2607 EXPECT_EQ(run_list->runs()[run_list->logical_to_visual(1)]->glyph_count, | 2612 EXPECT_EQ(run_list->runs()[run_list->logical_to_visual(1)]->glyph_count, |
2608 text_log[1].glyph_count); | 2613 text_log[1].glyph_count); |
2609 EXPECT_LT(text_log[0].origin.x(), text_log[1].origin.x()); | 2614 EXPECT_LT(text_log[0].origin.x(), text_log[1].origin.x()); |
2610 } | 2615 } |
2611 } | 2616 } |
2612 | 2617 |
2613 // Test TextRunHarfBuzz's cluster finding logic. | 2618 // Test TextRunHarfBuzz's cluster finding logic. |
2614 TEST_F(RenderTextTest, HarfBuzz_Clusters) { | 2619 TEST_F(RenderTextTest, HarfBuzz_Clusters) { |
2615 struct { | 2620 struct { |
2616 uint32 glyph_to_char[4]; | 2621 uint32_t glyph_to_char[4]; |
2617 Range chars[4]; | 2622 Range chars[4]; |
2618 Range glyphs[4]; | 2623 Range glyphs[4]; |
2619 bool is_rtl; | 2624 bool is_rtl; |
2620 } cases[] = { | 2625 } cases[] = { |
2621 { // From string "A B C D" to glyphs "a b c d". | 2626 { // From string "A B C D" to glyphs "a b c d". |
2622 { 0, 1, 2, 3 }, | 2627 { 0, 1, 2, 3 }, |
2623 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) }, | 2628 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) }, |
2624 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) }, | 2629 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) }, |
2625 false | 2630 false |
2626 }, | 2631 }, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2694 auto first_grapheme_bounds = run->GetGraphemeBounds(iter, 0); | 2699 auto first_grapheme_bounds = run->GetGraphemeBounds(iter, 0); |
2695 EXPECT_EQ(first_grapheme_bounds, run->GetGraphemeBounds(iter, 1)); | 2700 EXPECT_EQ(first_grapheme_bounds, run->GetGraphemeBounds(iter, 1)); |
2696 auto second_grapheme_bounds = run->GetGraphemeBounds(iter, 2); | 2701 auto second_grapheme_bounds = run->GetGraphemeBounds(iter, 2); |
2697 EXPECT_EQ(first_grapheme_bounds.end(), second_grapheme_bounds.start()); | 2702 EXPECT_EQ(first_grapheme_bounds.end(), second_grapheme_bounds.start()); |
2698 } | 2703 } |
2699 } | 2704 } |
2700 | 2705 |
2701 // Test the partition of a multi-grapheme cluster into grapheme ranges. | 2706 // Test the partition of a multi-grapheme cluster into grapheme ranges. |
2702 TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemePartition) { | 2707 TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemePartition) { |
2703 struct { | 2708 struct { |
2704 uint32 glyph_to_char[2]; | 2709 uint32_t glyph_to_char[2]; |
2705 Range bounds[4]; | 2710 Range bounds[4]; |
2706 bool is_rtl; | 2711 bool is_rtl; |
2707 } cases[] = { | 2712 } cases[] = { |
2708 { // From string "A B C D" to glyphs "a bcd". | 2713 { // From string "A B C D" to glyphs "a bcd". |
2709 { 0, 1 }, | 2714 { 0, 1 }, |
2710 { Range(0, 10), Range(10, 13), Range(13, 17), Range(17, 20) }, | 2715 { Range(0, 10), Range(10, 13), Range(13, 17), Range(17, 20) }, |
2711 false | 2716 false |
2712 }, | 2717 }, |
2713 { // From string "A B C D" to glyphs "ab cd". | 2718 { // From string "A B C D" to glyphs "ab cd". |
2714 { 0, 2 }, | 2719 { 0, 2 }, |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3028 render_text->ApplyBaselineStyle(SUBSCRIPT, Range(7, 8)); | 3033 render_text->ApplyBaselineStyle(SUBSCRIPT, Range(7, 8)); |
3029 render_text->SetStyle(BOLD, true); | 3034 render_text->SetStyle(BOLD, true); |
3030 render_text->SetDisplayRect( | 3035 render_text->SetDisplayRect( |
3031 Rect(kTestSize, kTestSize, string_size.width(), string_size.height())); | 3036 Rect(kTestSize, kTestSize, string_size.width(), string_size.height())); |
3032 // Allow the RenderText to paint outside of its display rect. | 3037 // Allow the RenderText to paint outside of its display rect. |
3033 render_text->set_clip_to_display_rect(false); | 3038 render_text->set_clip_to_display_rect(false); |
3034 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width()); | 3039 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width()); |
3035 | 3040 |
3036 render_text->Draw(&canvas); | 3041 render_text->Draw(&canvas); |
3037 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); | 3042 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); |
3038 const uint32* buffer = | 3043 const uint32_t* buffer = |
3039 static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); | 3044 static_cast<const uint32_t*>(surface->peekPixels(nullptr, nullptr)); |
3040 ASSERT_NE(nullptr, buffer); | 3045 ASSERT_NE(nullptr, buffer); |
3041 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), | 3046 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), |
3042 kCanvasSize.height()); | 3047 kCanvasSize.height()); |
3043 { | 3048 { |
3044 #if !defined(OS_CHROMEOS) | 3049 #if !defined(OS_CHROMEOS) |
3045 // TODO(dschuyler): On ChromeOS text draws above the GetStringSize rect. | 3050 // TODO(dschuyler): On ChromeOS text draws above the GetStringSize rect. |
3046 SCOPED_TRACE("TextDoesntClip Top Side"); | 3051 SCOPED_TRACE("TextDoesntClip Top Side"); |
3047 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), | 3052 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), |
3048 kTestSize); | 3053 kTestSize); |
3049 #endif | 3054 #endif |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3104 surface->getCanvas()->clear(SK_ColorWHITE); | 3109 surface->getCanvas()->clear(SK_ColorWHITE); |
3105 render_text->SetText(WideToUTF16(string)); | 3110 render_text->SetText(WideToUTF16(string)); |
3106 const Size string_size = render_text->GetStringSize(); | 3111 const Size string_size = render_text->GetStringSize(); |
3107 int fake_width = string_size.width() / 2; | 3112 int fake_width = string_size.width() / 2; |
3108 int fake_height = string_size.height() / 2; | 3113 int fake_height = string_size.height() / 2; |
3109 render_text->SetDisplayRect( | 3114 render_text->SetDisplayRect( |
3110 Rect(kTestSize, kTestSize, fake_width, fake_height)); | 3115 Rect(kTestSize, kTestSize, fake_width, fake_height)); |
3111 render_text->set_clip_to_display_rect(true); | 3116 render_text->set_clip_to_display_rect(true); |
3112 render_text->Draw(&canvas); | 3117 render_text->Draw(&canvas); |
3113 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); | 3118 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); |
3114 const uint32* buffer = | 3119 const uint32_t* buffer = |
3115 static_cast<const uint32*>(surface->peekPixels(nullptr, nullptr)); | 3120 static_cast<const uint32_t*>(surface->peekPixels(nullptr, nullptr)); |
3116 ASSERT_NE(nullptr, buffer); | 3121 ASSERT_NE(nullptr, buffer); |
3117 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), | 3122 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), |
3118 kCanvasSize.height()); | 3123 kCanvasSize.height()); |
3119 { | 3124 { |
3120 SCOPED_TRACE("TextDoesClip Top Side"); | 3125 SCOPED_TRACE("TextDoesClip Top Side"); |
3121 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), | 3126 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), |
3122 kTestSize); | 3127 kTestSize); |
3123 } | 3128 } |
3124 | 3129 |
3125 { | 3130 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3194 backend[i]->SetColor(SK_ColorRED); | 3199 backend[i]->SetColor(SK_ColorRED); |
3195 test_api.DrawVisualText(&renderer); | 3200 test_api.DrawVisualText(&renderer); |
3196 | 3201 |
3197 renderer.GetTextLogAndReset(&text_log); | 3202 renderer.GetTextLogAndReset(&text_log); |
3198 EXPECT_EQ(1u, text_log.size()); | 3203 EXPECT_EQ(1u, text_log.size()); |
3199 EXPECT_EQ(SK_ColorRED, text_log[0].color); | 3204 EXPECT_EQ(SK_ColorRED, text_log[0].color); |
3200 } | 3205 } |
3201 } | 3206 } |
3202 | 3207 |
3203 } // namespace gfx | 3208 } // namespace gfx |
OLD | NEW |