Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: third_party/WebKit/Source/core/paint/NGTextFragmentPainter.cpp

Issue 2842983002: [LayoutNG] Paint inlines from the fragment tree
Patch Set: Rebase w/HEAD Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 "core/paint/NGTextFragmentPainter.h"
6
7 #include "core/frame/LocalFrame.h"
8 #include "core/layout/ng/inline/ng_physical_text_fragment.h"
9 #include "core/paint/NGTextPainter.h"
10 #include "core/paint/PaintInfo.h"
11 #include "core/paint/TextPainterBase.h"
12 #include "core/style/AppliedTextDecoration.h"
13 #include "platform/graphics/GraphicsContextStateSaver.h"
14 #include "platform/graphics/paint/DrawingRecorder.h"
15 #include "platform/wtf/Optional.h"
16
17 namespace blink {
18
19 namespace {
20 static void PrepareContextForDecoration(
21 GraphicsContext& context,
22 GraphicsContextStateSaver& state_saver,
23 bool is_horizontal,
24 const TextPainterBase::Style& text_style,
25 const LayoutRect& box_rect) {
26 TextPainterBase::UpdateGraphicsContext(context, text_style, is_horizontal,
27 state_saver);
28 }
29
30 static void RestoreContextFromDecoration(GraphicsContext& context,
31 const LayoutRect& box_rect) {}
32
33 static void PaintDecorationsExceptLineThrough(
34 NGTextPainter& text_painter,
35 bool& has_line_through_decoration,
36 const NGPhysicalTextFragment* fragment,
37 const DecorationInfo& decoration_info,
38 const PaintInfo& paint_info,
39 const Vector<AppliedTextDecoration>& decorations) {
40 GraphicsContext& context = paint_info.context;
41 GraphicsContextStateSaver state_saver(context);
42 context.SetStrokeThickness(decoration_info.thickness);
43
44 // text-underline-position may flip underline and overline.
45 ResolvedUnderlinePosition underline_position =
46 decoration_info.underline_position;
47 bool flip_underline_and_overline = false;
48 if (underline_position == ResolvedUnderlinePosition::kOver) {
49 flip_underline_and_overline = true;
50 underline_position = ResolvedUnderlinePosition::kUnder;
51 }
52
53 // for (const AppliedTextDecoration& decoration : decorations) {
54 // TextDecoration lines = decoration.Lines();
55 // if (flip_underline_and_overline) {
56 // lines = static_cast<TextDecoration>(
57 // lines ^ (kTextDecorationUnderline | kTextDecorationOverline));
58 // }
59 // if ((lines & kTextDecorationUnderline) && decoration_info.font_data) {
60 // const int underline_offset = 0;
61 // text_painter.PaintDecorationUnderOrOverLine(context, decoration_info,
62 // decoration,
63 // underline_offset);
64 // }
65 // if (lines & kTextDecorationOverline) {
66 // const int overline_offset = 0;
67 // text_painter.PaintDecorationUnderOrOverLine(context, decoration_info,
68 // decoration,
69 // overline_offset);
70 // }
71 // // We could instead build a vector of the TextDecoration instances needing
72 // // line-through but this is a rare case so better to avoid vector
73 // overhead. has_line_through_decoration |= ((lines &
74 // kTextDecorationLineThrough) != 0);
75 //}
76 }
77
78 } // anonymous namespace
79
80 void NGTextFragmentPainter::Paint(const Document& document,
81 const PaintInfo& paint_info,
82 const LayoutPoint& paint_offset) {
83 // TODO(eae): Move
84 static unsigned short kCNoTruncation = USHRT_MAX;
85 static unsigned short kCFullTruncation = USHRT_MAX - 1;
86
87 const ComputedStyle& style_to_use = text_fragment_->Style();
88
89 NGPhysicalSize size_;
90 NGPhysicalOffset offset_;
91
92 // We round the y-axis to ensure consistent line heights.
93 LayoutPoint adjusted_paint_offset =
94 LayoutPoint(paint_offset.X(), LayoutUnit(paint_offset.Y().Round()));
95
96 NGPhysicalOffset offset = text_fragment_->Offset();
97 LayoutPoint box_origin(offset.left, offset.top);
98 box_origin.Move(adjusted_paint_offset.X(), adjusted_paint_offset.Y());
99
100 LayoutRect box_rect(box_origin, LayoutSize(text_fragment_->Size().width,
101 text_fragment_->Size().height));
102
103 GraphicsContext& context = paint_info.context;
104
105 bool is_printing = paint_info.IsPrinting();
106
107 // Determine whether or not we're selected.
108 // bool have_selection = !is_printing &&
109 // paint_info.phase != kPaintPhaseTextClip &&
110 // inline_text_box_.GetSelectionState() != SelectionNone;
111 bool have_selection = false;
112 if (!have_selection && paint_info.phase == kPaintPhaseSelection) {
113 // When only painting the selection, don't bother to paint if there is none.
114 return;
115 }
116
117 // Determine text colors.
118 TextPainterBase::Style text_style =
119 TextPainterBase::TextPaintingStyle(document, style_to_use, paint_info);
120 // TextPainterBase::Style selection_style =
121 // TextPainter::SelectionPaintingStyle(
122 // text_fragment_.GetLineLayoutItem(), have_selection, paint_info,
123 // text_style);
124 TextPainterBase::Style selection_style = text_style;
125 bool paint_selected_text_only = (paint_info.phase == kPaintPhaseSelection);
126 bool paint_selected_text_separately =
127 !paint_selected_text_only && text_style != selection_style;
128
129 // Set our font.
130 const Font& font = style_to_use.GetFont();
131 const SimpleFontData* font_data = font.PrimaryFont();
132 DCHECK(font_data);
133
134 int ascent = font_data ? font_data->GetFontMetrics().Ascent() : 0;
135 LayoutPoint text_origin(box_origin.X(), box_origin.Y() + ascent);
136
137 // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
138 // include selection and composition highlights.
139 if (paint_info.phase != kPaintPhaseSelection &&
140 paint_info.phase != kPaintPhaseTextClip && !is_printing) {
141 // PaintDocumentMarkers(paint_info, box_origin, style_to_use, font,
142 // DocumentMarkerPaintPhase::kBackground);
143
144 // const LayoutObject& text_box_layout_object = InlineLayoutObject();
145 // if (have_selection && !PaintsCompositionMarkers(text_box_layout_object))
146 // {
147 // if (combined_text)
148 // PaintSelection<InlineTextBoxPainter::PaintOptions::kCombinedText>(
149 // context, box_rect, style_to_use, font, selection_style.fill_color,
150 // combined_text);
151 // else
152 // PaintSelection<InlineTextBoxPainter::PaintOptions::kNormal>(
153 // context, box_rect, style_to_use, font,
154 // selection_style.fill_color);
155 //}
156 }
157
158 // 2. Now paint the foreground, including text and decorations.
159 int selection_start = 0;
160 int selection_end = 0;
161 // if (paint_selected_text_only || paint_selected_text_separately)
162 // text_fragment_.SelectionStartEnd(selection_start, selection_end);
163
164 // bool respect_hyphen =
165 // selection_end == static_cast<int>(text_fragment_.Len()) &&
166 // text_fragment_.HasHyphen();
167 // if (respect_hyphen)
168 // selection_end = text_run.length();
169
170 unsigned length = text_fragment_->Text().length();
171
172 bool ltr = true;
173 bool flow_is_ltr = true;
174 if (text_fragment_->Truncation() != kCNoTruncation) {
175 // In a mixed-direction flow the ellipsis is at the start of the text
176 // rather than at the end of it.
177 selection_start =
178 ltr == flow_is_ltr
179 ? std::min<int>(selection_start, text_fragment_->Truncation())
180 : std::max<int>(selection_start, text_fragment_->Truncation());
181 selection_end =
182 ltr == flow_is_ltr
183 ? std::min<int>(selection_end, text_fragment_->Truncation())
184 : std::max<int>(selection_end, text_fragment_->Truncation());
185 length = ltr == flow_is_ltr ? text_fragment_->Truncation() : length;
186 }
187
188 NGTextPainter text_painter(context, font, text_fragment_, text_origin,
189 box_rect, text_fragment_->IsHorizontal());
190 TextEmphasisPosition emphasis_mark_position;
191 // bool has_text_emphasis = text_fragment_->GetEmphasisMarkPosition(
192 // style_to_use, emphasis_mark_position);
193 emphasis_mark_position = kTextEmphasisPositionOver;
194 bool has_text_emphasis = false;
195 if (has_text_emphasis) {
196 text_painter.SetEmphasisMark(style_to_use.TextEmphasisMarkString(),
197 emphasis_mark_position);
198 }
199 // if (combined_text)
200 // text_painter.SetCombinedText(combined_text);
201 if (text_fragment_->Truncation() != kCNoTruncation && ltr != flow_is_ltr)
202 text_painter.SetEllipsisOffset(text_fragment_->Truncation());
203
204 bool should_rotate = false;
205
206 if (!paint_selected_text_only) {
207 // Paint text decorations except line-through.
208 DecorationInfo decoration_info;
209 bool has_line_through_decoration = false;
210 if (style_to_use.TextDecorationsInEffect() != TextDecoration::kNone &&
211 text_fragment_->Truncation() != kCFullTruncation) {
212 LayoutPoint local_origin = LayoutPoint(box_origin);
213 LayoutUnit width = text_fragment_->Size().width;
214 // const NGPhysicalTextFragment* decorating_box =
215 // EnclosingUnderlineObject(&text_fragment_);
216 const ComputedStyle* decorating_box_style = nullptr;
217 // FontBaseline baseline_type = text_fragment_->Root().BaselineType();
218 FontBaseline baseline_type = kAlphabeticBaseline;
219
220 text_painter.ComputeDecorationInfo(decoration_info, box_origin,
221 local_origin, width, baseline_type,
222 style_to_use, decorating_box_style);
223
224 GraphicsContextStateSaver state_saver(context, false);
225 PrepareContextForDecoration(context, state_saver,
226 text_fragment_->IsHorizontal(), text_style,
227 box_rect);
228 PaintDecorationsExceptLineThrough(
229 text_painter, has_line_through_decoration, text_fragment_,
230 decoration_info, paint_info, style_to_use.AppliedTextDecorations());
231 RestoreContextFromDecoration(context, box_rect);
232 }
233
234 int start_offset = 0;
235 int end_offset = length;
236 // Where the text and its flow have opposite directions then our offset into
237 // the text given by |truncation| is at the start of the part that will be
238 // visible.
239 if (text_fragment_->Truncation() != kCNoTruncation && ltr != flow_is_ltr) {
240 start_offset = text_fragment_->Truncation();
241 end_offset = length;
242 }
243
244 if (paint_selected_text_separately && selection_start < selection_end) {
245 start_offset = selection_end;
246 end_offset = selection_start;
247 }
248
249 text_painter.Paint(start_offset, end_offset, length, text_style);
250
251 // Paint line-through decoration if needed.
252 if (has_line_through_decoration) {
253 GraphicsContextStateSaver state_saver(context, false);
254 PrepareContextForDecoration(context, state_saver,
255 text_fragment_->IsHorizontal(), text_style,
256 box_rect);
257 text_painter.PaintDecorationsOnlyLineThrough(
258 decoration_info, paint_info, style_to_use.AppliedTextDecorations());
259 RestoreContextFromDecoration(context, box_rect);
260 }
261 }
262
263 if ((paint_selected_text_only || paint_selected_text_separately) &&
264 selection_start < selection_end) {
265 // paint only the text that is selected
266 text_painter.Paint(selection_start, selection_end, length, selection_style);
267 }
268
269 // if (paint_info.phase == kPaintPhaseForeground)
270 // PaintDocumentMarkers(paint_info, box_origin, style_to_use, font,
271 // DocumentMarkerPaintPhase::kForeground);
272
273 if (should_rotate) {
274 context.ConcatCTM(TextPainterBase::Rotation(
275 box_rect, TextPainterBase::kCounterclockwise));
276 }
277 }
278
279 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/NGTextFragmentPainter.h ('k') | third_party/WebKit/Source/core/paint/NGTextPainter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698