Chromium Code Reviews

Side by Side Diff: Source/core/paint/SVGInlineTextBoxPainter.cpp

Issue 638933002: Introduce SVGPaintServer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Pass GCSS only - not GCSS and GC. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "config.h" 5 #include "config.h"
6 #include "core/paint/SVGInlineTextBoxPainter.h" 6 #include "core/paint/SVGInlineTextBoxPainter.h"
7 7
8 #include "core/dom/DocumentMarkerController.h" 8 #include "core/dom/DocumentMarkerController.h"
9 #include "core/dom/RenderedDocumentMarker.h" 9 #include "core/dom/RenderedDocumentMarker.h"
10 #include "core/editing/Editor.h" 10 #include "core/editing/Editor.h"
11 #include "core/frame/LocalFrame.h" 11 #include "core/frame/LocalFrame.h"
12 #include "core/paint/InlinePainter.h" 12 #include "core/paint/InlinePainter.h"
13 #include "core/paint/InlineTextBoxPainter.h" 13 #include "core/paint/InlineTextBoxPainter.h"
14 #include "core/paint/SVGPaintServer.h"
14 #include "core/rendering/PaintInfo.h" 15 #include "core/rendering/PaintInfo.h"
15 #include "core/rendering/RenderInline.h" 16 #include "core/rendering/RenderInline.h"
16 #include "core/rendering/RenderTheme.h" 17 #include "core/rendering/RenderTheme.h"
17 #include "core/rendering/style/ShadowList.h" 18 #include "core/rendering/style/ShadowList.h"
18 #include "core/rendering/svg/RenderSVGInlineText.h" 19 #include "core/rendering/svg/RenderSVGInlineText.h"
19 #include "core/rendering/svg/RenderSVGResource.h" 20 #include "core/rendering/svg/RenderSVGResource.h"
20 #include "core/rendering/svg/RenderSVGResourceSolidColor.h"
21 #include "core/rendering/svg/SVGInlineTextBox.h" 21 #include "core/rendering/svg/SVGInlineTextBox.h"
22 #include "core/rendering/svg/SVGRenderSupport.h" 22 #include "core/rendering/svg/SVGRenderSupport.h"
23 #include "core/rendering/svg/SVGResourcesCache.h" 23 #include "core/rendering/svg/SVGResourcesCache.h"
24 24
25 namespace blink { 25 namespace blink {
26 26
27 static inline bool textShouldBePainted(RenderSVGInlineText& textRenderer) 27 static inline bool textShouldBePainted(RenderSVGInlineText& textRenderer)
28 { 28 {
29 // Font::pixelSize(), returns FontDescription::computedPixelSize(), which re turns "int(x + 0.5)". 29 // Font::pixelSize(), returns FontDescription::computedPixelSize(), which re turns "int(x + 0.5)".
30 // If the absolute font size on screen is below x=0.5, don't render anything . 30 // If the absolute font size on screen is below x=0.5, don't render anything .
(...skipping 100 matching lines...)
131 // Spec: Line-through should be drawn after the text is filled and strok ed; thus, the line-through is rendered on top of the text. 131 // Spec: Line-through should be drawn after the text is filled and strok ed; thus, the line-through is rendered on top of the text.
132 if (decorations & TextDecorationLineThrough) 132 if (decorations & TextDecorationLineThrough)
133 paintDecoration(paintInfo.context, TextDecorationLineThrough, fragme nt); 133 paintDecoration(paintInfo.context, TextDecorationLineThrough, fragme nt);
134 } 134 }
135 135
136 // finally, paint the outline if any 136 // finally, paint the outline if any
137 if (style->hasOutline() && parentRenderer.isRenderInline()) 137 if (style->hasOutline() && parentRenderer.isRenderInline())
138 InlinePainter(toRenderInline(parentRenderer)).paintOutline(paintInfo, pa intOffset); 138 InlinePainter(toRenderInline(parentRenderer)).paintOutline(paintInfo, pa intOffset);
139 } 139 }
140 140
141 class PaintingResourceScope {
142 public:
143 PaintingResourceScope(RenderObject& renderer)
144 : m_renderer(renderer)
145 , m_paintingResource(0)
146 {
147 }
148 ~PaintingResourceScope() { ASSERT(!m_paintingResource); }
149
150 bool acquirePaintingResource(GraphicsContext*&, RenderStyle*, RenderSVGResou rceModeFlags);
151 void releasePaintingResource(GraphicsContext*&);
152
153 private:
154 RenderObject& m_renderer;
155 RenderSVGResource* m_paintingResource;
156 };
157
158 bool PaintingResourceScope::acquirePaintingResource(GraphicsContext*& context, R enderStyle* style, RenderSVGResourceModeFlags resourceModeFlags)
159 {
160 ASSERT(style);
161 RenderSVGResourceMode resourceMode = static_cast<RenderSVGResourceMode>(reso urceModeFlags & (ApplyToFillMode | ApplyToStrokeMode));
162 ASSERT(resourceMode == ApplyToFillMode || resourceMode == ApplyToStrokeMode) ;
163
164 bool hasFallback = false;
165 m_paintingResource = RenderSVGResource::requestPaintingResource(resourceMode , &m_renderer, style, hasFallback);
166 if (!m_paintingResource)
167 return false;
168
169 if (!m_paintingResource->applyResource(&m_renderer, style, context, resource ModeFlags)) {
170 if (hasFallback) {
171 m_paintingResource = RenderSVGResource::sharedSolidPaintingResource( );
172 m_paintingResource->applyResource(&m_renderer, style, context, resou rceModeFlags);
173 }
174 }
175 return true;
176 }
177
178 void PaintingResourceScope::releasePaintingResource(GraphicsContext*& context)
179 {
180 ASSERT(m_paintingResource);
181
182 m_paintingResource->postApplyResource(context);
183 m_paintingResource = 0;
184 }
185
186 void SVGInlineTextBoxPainter::paintSelectionBackground(PaintInfo& paintInfo) 141 void SVGInlineTextBoxPainter::paintSelectionBackground(PaintInfo& paintInfo)
187 { 142 {
188 if (m_svgInlineTextBox.renderer().style()->visibility() != VISIBLE) 143 if (m_svgInlineTextBox.renderer().style()->visibility() != VISIBLE)
189 return; 144 return;
190 145
191 RenderObject& parentRenderer = m_svgInlineTextBox.parent()->renderer(); 146 RenderObject& parentRenderer = m_svgInlineTextBox.parent()->renderer();
192 ASSERT(!parentRenderer.document().printing()); 147 ASSERT(!parentRenderer.document().printing());
193 148
194 // Determine whether or not we're selected. 149 // Determine whether or not we're selected.
195 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; 150 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
(...skipping 125 matching lines...)
321 276
322 if (fragment.width <= 0 && thickness <= 0) 277 if (fragment.width <= 0 && thickness <= 0)
323 return; 278 return;
324 279
325 float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont. fontMetrics(), thickness); 280 float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont. fontMetrics(), thickness);
326 FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scal ingFactor); 281 FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scal ingFactor);
327 282
328 Path path; 283 Path path;
329 path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness / scalingFactor))); 284 path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness / scalingFactor)));
330 285
331 PaintingResourceScope resourceScope(*decorationRenderer); 286 GraphicsContextStateSaver stateSaver(*context, false);
332 if (resourceScope.acquirePaintingResource(context, decorationStyle, resource Mode)) { 287 if (!SVGPaintServer::updateGraphicsContext(stateSaver, decorationStyle, *dec orationRenderer, resourceMode))
333 SVGRenderSupport::fillOrStrokePath(context, resourceMode, path); 288 return;
334 resourceScope.releasePaintingResource(context); 289 SVGRenderSupport::fillOrStrokePath(context, resourceMode, path);
335 }
336 } 290 }
337 291
338 void SVGInlineTextBoxPainter::paintTextWithShadows(GraphicsContext* context, Ren derStyle* style, 292 void SVGInlineTextBoxPainter::paintTextWithShadows(GraphicsContext* context, Ren derStyle* style,
339 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en dPosition, 293 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en dPosition,
340 RenderSVGResourceMode resourceMode) 294 RenderSVGResourceMode resourceMode)
341 { 295 {
342 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(m_svgInlineTextBox .renderer()); 296 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(m_svgInlineTextBox .renderer());
343 297
344 float scalingFactor = textRenderer.scalingFactor(); 298 float scalingFactor = textRenderer.scalingFactor();
345 ASSERT(scalingFactor); 299 ASSERT(scalingFactor);
346 300
347 const Font& scaledFont = textRenderer.scaledFont(); 301 const Font& scaledFont = textRenderer.scaledFont();
348 const ShadowList* shadowList = style->textShadow(); 302 const ShadowList* shadowList = style->textShadow();
349 303
350 // Text shadows are disabled when printing. http://crbug.com/258321 304 // Text shadows are disabled when printing. http://crbug.com/258321
351 bool hasShadow = shadowList && !context->printing(); 305 bool hasShadow = shadowList && !context->printing();
352 306
353 FloatPoint textOrigin(fragment.x, fragment.y); 307 FloatPoint textOrigin(fragment.x, fragment.y);
354 FloatSize textSize(fragment.width, fragment.height); 308 FloatSize textSize(fragment.width, fragment.height);
355 309
310 GraphicsContextStateSaver stateSaver(*context, false);
356 if (scalingFactor != 1) { 311 if (scalingFactor != 1) {
357 textOrigin.scale(scalingFactor, scalingFactor); 312 textOrigin.scale(scalingFactor, scalingFactor);
358 textSize.scale(scalingFactor); 313 textSize.scale(scalingFactor);
359 context->save(); 314 stateSaver.save();
360 context->scale(1 / scalingFactor, 1 / scalingFactor); 315 context->scale(1 / scalingFactor, 1 / scalingFactor);
361 } 316 }
362 317
318 if (!SVGPaintServer::updateGraphicsContext(stateSaver, style, m_svgInlineTex tBox.parent()->renderer(), resourceMode | ApplyToTextMode))
319 return;
320
363 if (hasShadow) 321 if (hasShadow)
364 context->setDrawLooper(shadowList->createDrawLooper(DrawLooperBuilder::S hadowRespectsAlpha)); 322 context->setDrawLooper(shadowList->createDrawLooper(DrawLooperBuilder::S hadowRespectsAlpha));
365 323
366 PaintingResourceScope resourceScope(m_svgInlineTextBox.parent()->renderer()) ; 324 context->setTextDrawingMode(resourceMode == ApplyToFillMode ? TextModeFill : TextModeStroke);
367 if (resourceScope.acquirePaintingResource(context, style, resourceMode | App lyToTextMode)) {
368 context->setTextDrawingMode(resourceMode == ApplyToFillMode ? TextModeFi ll : TextModeStroke);
369 325
370 if (scalingFactor != 1 && resourceMode == ApplyToStrokeMode) 326 if (scalingFactor != 1 && resourceMode == ApplyToStrokeMode)
371 context->setStrokeThickness(context->strokeThickness() * scalingFact or); 327 context->setStrokeThickness(context->strokeThickness() * scalingFactor);
372 328
373 TextRunPaintInfo textRunPaintInfo(textRun); 329 TextRunPaintInfo textRunPaintInfo(textRun);
374 textRunPaintInfo.from = startPosition; 330 textRunPaintInfo.from = startPosition;
375 textRunPaintInfo.to = endPosition; 331 textRunPaintInfo.to = endPosition;
376 332
377 float baseline = scaledFont.fontMetrics().floatAscent(); 333 float baseline = scaledFont.fontMetrics().floatAscent();
378 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - bas eline, 334 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - baselin e,
379 textSize.width(), textSize.height()); 335 textSize.width(), textSize.height());
380 336
381 scaledFont.drawText(context, textRunPaintInfo, textOrigin); 337 scaledFont.drawText(context, textRunPaintInfo, textOrigin);
382 resourceScope.releasePaintingResource(context);
383 }
384 338
385 if (scalingFactor != 1) 339 if (hasShadow && !stateSaver.saved())
f(malita) 2014/10/10 15:49:07 Could we saveIfNeeded in the hasShadow conditional
fs 2014/10/10 16:10:23 Done.
386 context->restore();
387 else if (hasShadow)
388 context->clearShadow(); 340 context->clearShadow();
389 } 341 }
390 342
391 void SVGInlineTextBoxPainter::paintText(GraphicsContext* context, RenderStyle* s tyle, 343 void SVGInlineTextBoxPainter::paintText(GraphicsContext* context, RenderStyle* s tyle,
392 RenderStyle* selectionStyle, const SVGTextFragment& fragment, 344 RenderStyle* selectionStyle, const SVGTextFragment& fragment,
393 RenderSVGResourceMode resourceMode, bool hasSelection, bool paintSelectedTex tOnly) 345 RenderSVGResourceMode resourceMode, bool hasSelection, bool paintSelectedTex tOnly)
394 { 346 {
395 ASSERT(style); 347 ASSERT(style);
396 ASSERT(selectionStyle); 348 ASSERT(selectionStyle);
397 349
(...skipping 84 matching lines...)
482 434
483 fragmentRect = fragmentTransform.mapRect(fragmentRect); 435 fragmentRect = fragmentTransform.mapRect(fragmentRect);
484 markerRect.unite(fragmentRect); 436 markerRect.unite(fragmentRect);
485 } 437 }
486 } 438 }
487 439
488 toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsolu teQuad(markerRect).enclosingBoundingBox()); 440 toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsolu teQuad(markerRect).enclosingBoundingBox());
489 } 441 }
490 442
491 } // namespace blink 443 } // namespace blink
OLDNEW

Powered by Google App Engine