1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "third_party/blink/renderer/core/paint/text_painter.h"
6
7 #include <memory>
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
10 #include "third_party/blink/renderer/core/css/css_property_names.h"
11 #include "third_party/blink/renderer/core/css_value_keywords.h"
12 #include "third_party/blink/renderer/core/frame/settings.h"
13 #include "third_party/blink/renderer/core/layout/api/line_layout_text.h"
14 #include "third_party/blink/renderer/core/paint/paint_info.h"
15 #include "third_party/blink/renderer/core/style/shadow_data.h"
16 #include "third_party/blink/renderer/core/style/shadow_list.h"
17 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
18 #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
19
20 namespace blink {
21 namespace {
22
23 class TextPainterTest : public RenderingTest {
24 public:
TextPainterTest()25 TextPainterTest()
26 : layout_text_(nullptr),
27 paint_controller_(std::make_unique<PaintController>()),
28 context_(*paint_controller_) {}
29
30 protected:
GetLineLayoutText()31 LineLayoutText GetLineLayoutText() { return LineLayoutText(layout_text_); }
32
CreatePaintInfo(bool uses_text_as_clip,bool is_printing)33 PaintInfo CreatePaintInfo(bool uses_text_as_clip, bool is_printing) {
34 return PaintInfo(
35 context_, IntRect(),
36 uses_text_as_clip ? PaintPhase::kTextClip
37 : PaintPhase::kSelfBlockBackgroundOnly,
38 is_printing ? kGlobalPaintPrinting : kGlobalPaintNormalPhase, 0);
39 }
40
41 protected:
SetUp()42 void SetUp() override {
43 RenderingTest::SetUp();
44 SetBodyInnerHTML("Hello world");
45 UpdateLayoutText();
46 }
UpdateLayoutText()47 void UpdateLayoutText() {
48 layout_text_ =
49 ToLayoutText(GetDocument().body()->firstChild()->GetLayoutObject());
50 ASSERT_TRUE(layout_text_);
51 ASSERT_EQ("Hello world", layout_text_->GetText());
52 }
53
54 LayoutText* layout_text_;
55 std::unique_ptr<PaintController> paint_controller_;
56 GraphicsContext context_;
57 };
58
TEST_F(TextPainterTest,TextPaintingStyle_Simple)59 TEST_F(TextPainterTest, TextPaintingStyle_Simple) {
60 GetDocument().body()->SetInlineStyleProperty(CSSPropertyID::kColor,
61 CSSValueID::kBlue);
62 UpdateAllLifecyclePhasesForTest();
63
64 TextPaintStyle text_style = TextPainter::TextPaintingStyle(
65 GetLineLayoutText().GetDocument(), GetLineLayoutText().StyleRef(),
66 CreatePaintInfo(false /* usesTextAsClip */, false /* isPrinting */));
67 EXPECT_EQ(Color(0, 0, 255), text_style.fill_color);
68 EXPECT_EQ(Color(0, 0, 255), text_style.stroke_color);
69 EXPECT_EQ(Color(0, 0, 255), text_style.emphasis_mark_color);
70 EXPECT_EQ(0, text_style.stroke_width);
71 EXPECT_EQ(nullptr, text_style.shadow);
72 }
73
TEST_F(TextPainterTest,TextPaintingStyle_AllProperties)74 TEST_F(TextPainterTest, TextPaintingStyle_AllProperties) {
75 GetDocument().body()->SetInlineStyleProperty(
76 CSSPropertyID::kWebkitTextFillColor, CSSValueID::kRed);
77 GetDocument().body()->SetInlineStyleProperty(
78 CSSPropertyID::kWebkitTextStrokeColor, CSSValueID::kLime);
79 GetDocument().body()->SetInlineStyleProperty(
80 CSSPropertyID::kWebkitTextEmphasisColor, CSSValueID::kBlue);
81 GetDocument().body()->SetInlineStyleProperty(
82 CSSPropertyID::kWebkitTextStrokeWidth, 4,
83 CSSPrimitiveValue::UnitType::kPixels);
84 GetDocument().body()->SetInlineStyleProperty(CSSPropertyID::kTextShadow,
85 "1px 2px 3px yellow");
86 UpdateAllLifecyclePhasesForTest();
87
88 TextPaintStyle text_style = TextPainter::TextPaintingStyle(
89 GetLineLayoutText().GetDocument(), GetLineLayoutText().StyleRef(),
90 CreatePaintInfo(false /* usesTextAsClip */, false /* isPrinting */));
91 EXPECT_EQ(Color(255, 0, 0), text_style.fill_color);
92 EXPECT_EQ(Color(0, 255, 0), text_style.stroke_color);
93 EXPECT_EQ(Color(0, 0, 255), text_style.emphasis_mark_color);
94 EXPECT_EQ(4, text_style.stroke_width);
95 ASSERT_NE(nullptr, text_style.shadow);
96 EXPECT_EQ(1u, text_style.shadow->Shadows().size());
97 EXPECT_EQ(1, text_style.shadow->Shadows()[0].X());
98 EXPECT_EQ(2, text_style.shadow->Shadows()[0].Y());
99 EXPECT_EQ(3, text_style.shadow->Shadows()[0].Blur());
100 EXPECT_EQ(Color(255, 255, 0),
101 text_style.shadow->Shadows()[0].GetColor().GetColor());
102 }
103
TEST_F(TextPainterTest,TextPaintingStyle_UsesTextAsClip)104 TEST_F(TextPainterTest, TextPaintingStyle_UsesTextAsClip) {
105 GetDocument().body()->SetInlineStyleProperty(
106 CSSPropertyID::kWebkitTextFillColor, CSSValueID::kRed);
107 GetDocument().body()->SetInlineStyleProperty(
108 CSSPropertyID::kWebkitTextStrokeColor, CSSValueID::kLime);
109 GetDocument().body()->SetInlineStyleProperty(
110 CSSPropertyID::kWebkitTextEmphasisColor, CSSValueID::kBlue);
111 GetDocument().body()->SetInlineStyleProperty(
112 CSSPropertyID::kWebkitTextStrokeWidth, 4,
113 CSSPrimitiveValue::UnitType::kPixels);
114 GetDocument().body()->SetInlineStyleProperty(CSSPropertyID::kTextShadow,
115 "1px 2px 3px yellow");
116 UpdateAllLifecyclePhasesForTest();
117
118 TextPaintStyle text_style = TextPainter::TextPaintingStyle(
119 GetLineLayoutText().GetDocument(), GetLineLayoutText().StyleRef(),
120 CreatePaintInfo(true /* usesTextAsClip */, false /* isPrinting */));
121 EXPECT_EQ(Color::kBlack, text_style.fill_color);
122 EXPECT_EQ(Color::kBlack, text_style.stroke_color);
123 EXPECT_EQ(Color::kBlack, text_style.emphasis_mark_color);
124 EXPECT_EQ(4, text_style.stroke_width);
125 EXPECT_EQ(nullptr, text_style.shadow);
126 }
127
TEST_F(TextPainterTest,TextPaintingStyle_ForceBackgroundToWhite_NoAdjustmentNeeded)128 TEST_F(TextPainterTest,
129 TextPaintingStyle_ForceBackgroundToWhite_NoAdjustmentNeeded) {
130 GetDocument().body()->SetInlineStyleProperty(
131 CSSPropertyID::kWebkitTextFillColor, CSSValueID::kRed);
132 GetDocument().body()->SetInlineStyleProperty(
133 CSSPropertyID::kWebkitTextStrokeColor, CSSValueID::kLime);
134 GetDocument().body()->SetInlineStyleProperty(
135 CSSPropertyID::kWebkitTextEmphasisColor, CSSValueID::kBlue);
136 GetDocument().body()->SetInlineStyleProperty(
137 CSSPropertyID::kWebkitPrintColorAdjust, CSSValueID::kEconomy);
138 GetDocument().GetSettings()->SetShouldPrintBackgrounds(false);
139 FloatSize page_size(500, 800);
140 GetFrame().StartPrinting(page_size, page_size, 1);
141 UpdateAllLifecyclePhasesForTest();
142 // In LayoutNG, printing currently forces layout tree reattachment,
143 // so we need to re-get layout_text_.
144 UpdateLayoutText();
145
146 TextPaintStyle text_style = TextPainter::TextPaintingStyle(
147 GetLineLayoutText().GetDocument(), GetLineLayoutText().StyleRef(),
148 CreatePaintInfo(false /* usesTextAsClip */, true /* isPrinting */));
149 EXPECT_EQ(Color(255, 0, 0), text_style.fill_color);
150 EXPECT_EQ(Color(0, 255, 0), text_style.stroke_color);
151 EXPECT_EQ(Color(0, 0, 255), text_style.emphasis_mark_color);
152 }
153
TEST_F(TextPainterTest,TextPaintingStyle_ForceBackgroundToWhite_Darkened)154 TEST_F(TextPainterTest, TextPaintingStyle_ForceBackgroundToWhite_Darkened) {
155 GetDocument().body()->SetInlineStyleProperty(
156 CSSPropertyID::kWebkitTextFillColor, "rgb(255, 220, 220)");
157 GetDocument().body()->SetInlineStyleProperty(
158 CSSPropertyID::kWebkitTextStrokeColor, "rgb(220, 255, 220)");
159 GetDocument().body()->SetInlineStyleProperty(
160 CSSPropertyID::kWebkitTextEmphasisColor, "rgb(220, 220, 255)");
161 GetDocument().body()->SetInlineStyleProperty(
162 CSSPropertyID::kWebkitPrintColorAdjust, CSSValueID::kEconomy);
163 GetDocument().GetSettings()->SetShouldPrintBackgrounds(false);
164 FloatSize page_size(500, 800);
165 GetFrame().StartPrinting(page_size, page_size, 1);
166 GetDocument().View()->UpdateLifecyclePhasesForPrinting();
167 // In LayoutNG, printing currently forces layout tree reattachment,
168 // so we need to re-get layout_text_.
169 UpdateLayoutText();
170
171 TextPaintStyle text_style = TextPainter::TextPaintingStyle(
172 GetLineLayoutText().GetDocument(), GetLineLayoutText().StyleRef(),
173 CreatePaintInfo(false /* usesTextAsClip */, true /* isPrinting */));
174 EXPECT_EQ(Color(255, 220, 220).Dark(), text_style.fill_color);
175 EXPECT_EQ(Color(220, 255, 220).Dark(), text_style.stroke_color);
176 EXPECT_EQ(Color(220, 220, 255).Dark(), text_style.emphasis_mark_color);
177 }
178
179 } // namespace
180 } // namespace blink
181