| OLD | NEW |
| 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/SVGShapePainter.h" | 6 #include "core/paint/SVGShapePainter.h" |
| 7 | 7 |
| 8 #include "core/layout/PaintInfo.h" | 8 #include "core/layout/PaintInfo.h" |
| 9 #include "core/layout/svg/LayoutSVGPath.h" | 9 #include "core/layout/svg/LayoutSVGPath.h" |
| 10 #include "core/layout/svg/LayoutSVGResourceMarker.h" | 10 #include "core/layout/svg/LayoutSVGResourceMarker.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 static bool setupNonScalingStrokeContext(AffineTransform& strokeTransform, Graph
icsContextStateSaver& stateSaver) | 28 static bool setupNonScalingStrokeContext(AffineTransform& strokeTransform, Graph
icsContextStateSaver& stateSaver) |
| 29 { | 29 { |
| 30 if (!strokeTransform.isInvertible()) | 30 if (!strokeTransform.isInvertible()) |
| 31 return false; | 31 return false; |
| 32 | 32 |
| 33 stateSaver.save(); | 33 stateSaver.save(); |
| 34 stateSaver.context()->concatCTM(strokeTransform.inverse()); | 34 stateSaver.context()->concatCTM(strokeTransform.inverse()); |
| 35 return true; | 35 return true; |
| 36 } | 36 } |
| 37 | 37 |
| 38 static bool paintForLayoutObject(const PaintInfo& paintInfo, const ComputedStyle
& style, LayoutObject& layoutObject, LayoutSVGResourceMode resourceMode, SkPaint
& paint, const AffineTransform* additionalPaintServerTransform = nullptr) | |
| 39 { | |
| 40 if (paintInfo.isRenderingClipPathAsMaskImage()) { | |
| 41 if (resourceMode == ApplyToStrokeMode) | |
| 42 return false; | |
| 43 paint.setColor(SVGComputedStyle::initialFillPaintColor().rgb()); | |
| 44 paint.setShader(nullptr); | |
| 45 return true; | |
| 46 } | |
| 47 | |
| 48 SVGPaintServer paintServer = SVGPaintServer::requestForLayoutObject(layoutOb
ject, style, resourceMode); | |
| 49 if (!paintServer.isValid()) | |
| 50 return false; | |
| 51 | |
| 52 if (additionalPaintServerTransform && paintServer.isTransformDependent()) | |
| 53 paintServer.prependTransform(*additionalPaintServerTransform); | |
| 54 | |
| 55 const SVGComputedStyle& svgStyle = style.svgStyle(); | |
| 56 float paintAlpha = resourceMode == ApplyToFillMode ? svgStyle.fillOpacity()
: svgStyle.strokeOpacity(); | |
| 57 paintServer.applyToSkPaint(paint, paintAlpha); | |
| 58 | |
| 59 paint.setFilterQuality(WebCoreInterpolationQualityToSkFilterQuality(Interpol
ationDefault)); | |
| 60 | |
| 61 // TODO(fs): The color filter can set when generating a picture for a mask - | |
| 62 // due to color-interpolation. We could also just apply the | |
| 63 // color-interpolation property from the the shape itself (which could mean | |
| 64 // the paintserver if it has it specified), since that would be more in line | |
| 65 // with the spec for color-interpolation. For now, just steal it from the GC | |
| 66 // though. | |
| 67 // Additionally, it's not really safe/guaranteed to be correct, as | |
| 68 // something down the paint pipe may want to farther tweak the color | |
| 69 // filter, which could yield incorrect results. (Consider just using | |
| 70 // saveLayer() w/ this color filter explicitly instead.) | |
| 71 paint.setColorFilter(paintInfo.context->colorFilter()); | |
| 72 return true; | |
| 73 } | |
| 74 | |
| 75 static SkPath::FillType fillRuleFromStyle(const PaintInfo& paintInfo, const SVGC
omputedStyle& svgStyle) | 38 static SkPath::FillType fillRuleFromStyle(const PaintInfo& paintInfo, const SVGC
omputedStyle& svgStyle) |
| 76 { | 39 { |
| 77 return WebCoreWindRuleToSkFillType(paintInfo.isRenderingClipPathAsMaskImage(
) ? svgStyle.clipRule() : svgStyle.fillRule()); | 40 return WebCoreWindRuleToSkFillType(paintInfo.isRenderingClipPathAsMaskImage(
) ? svgStyle.clipRule() : svgStyle.fillRule()); |
| 78 } | 41 } |
| 79 | 42 |
| 80 void SVGShapePainter::paint(const PaintInfo& paintInfo) | 43 void SVGShapePainter::paint(const PaintInfo& paintInfo) |
| 81 { | 44 { |
| 82 ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_renderSVGShape); | 45 ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_renderSVGShape); |
| 83 if (paintInfo.phase != PaintPhaseForeground | 46 if (paintInfo.phase != PaintPhaseForeground |
| 84 || m_renderSVGShape.style()->visibility() == HIDDEN | 47 || m_renderSVGShape.style()->visibility() == HIDDEN |
| (...skipping 10 matching lines...) Expand all Loading... |
| 95 LayoutObjectDrawingRecorder recorder(*paintContext.paintInfo().conte
xt, m_renderSVGShape, paintContext.paintInfo().phase, boundingBox); | 58 LayoutObjectDrawingRecorder recorder(*paintContext.paintInfo().conte
xt, m_renderSVGShape, paintContext.paintInfo().phase, boundingBox); |
| 96 if (!recorder.canUseCachedDrawing()) { | 59 if (!recorder.canUseCachedDrawing()) { |
| 97 const SVGComputedStyle& svgStyle = m_renderSVGShape.style()->svg
Style(); | 60 const SVGComputedStyle& svgStyle = m_renderSVGShape.style()->svg
Style(); |
| 98 | 61 |
| 99 bool shouldAntiAlias = svgStyle.shapeRendering() != SR_CRISPEDGE
S; | 62 bool shouldAntiAlias = svgStyle.shapeRendering() != SR_CRISPEDGE
S; |
| 100 | 63 |
| 101 for (int i = 0; i < 3; i++) { | 64 for (int i = 0; i < 3; i++) { |
| 102 switch (svgStyle.paintOrderType(i)) { | 65 switch (svgStyle.paintOrderType(i)) { |
| 103 case PT_FILL: { | 66 case PT_FILL: { |
| 104 SkPaint fillPaint; | 67 SkPaint fillPaint; |
| 105 if (!paintForLayoutObject(paintContext.paintInfo(), m_re
nderSVGShape.styleRef(), m_renderSVGShape, ApplyToFillMode, fillPaint)) | 68 if (!SVGPaintContext::paintForLayoutObject(paintContext.
paintInfo(), m_renderSVGShape.styleRef(), m_renderSVGShape, ApplyToFillMode, fil
lPaint)) |
| 106 break; | 69 break; |
| 107 fillPaint.setAntiAlias(shouldAntiAlias); | 70 fillPaint.setAntiAlias(shouldAntiAlias); |
| 108 fillShape(paintContext.paintInfo().context, fillPaint, f
illRuleFromStyle(paintContext.paintInfo(), svgStyle)); | 71 fillShape(paintContext.paintInfo().context, fillPaint, f
illRuleFromStyle(paintContext.paintInfo(), svgStyle)); |
| 109 break; | 72 break; |
| 110 } | 73 } |
| 111 case PT_STROKE: | 74 case PT_STROKE: |
| 112 if (svgStyle.hasVisibleStroke()) { | 75 if (svgStyle.hasVisibleStroke()) { |
| 113 GraphicsContextStateSaver stateSaver(*paintContext.p
aintInfo().context, false); | 76 GraphicsContextStateSaver stateSaver(*paintContext.p
aintInfo().context, false); |
| 114 AffineTransform nonScalingTransform; | 77 AffineTransform nonScalingTransform; |
| 115 const AffineTransform* additionalPaintServerTransfor
m = 0; | 78 const AffineTransform* additionalPaintServerTransfor
m = 0; |
| 116 | 79 |
| 117 if (m_renderSVGShape.hasNonScalingStroke()) { | 80 if (m_renderSVGShape.hasNonScalingStroke()) { |
| 118 nonScalingTransform = m_renderSVGShape.nonScalin
gStrokeTransform(); | 81 nonScalingTransform = m_renderSVGShape.nonScalin
gStrokeTransform(); |
| 119 if (!setupNonScalingStrokeContext(nonScalingTran
sform, stateSaver)) | 82 if (!setupNonScalingStrokeContext(nonScalingTran
sform, stateSaver)) |
| 120 return; | 83 return; |
| 121 | 84 |
| 122 // Non-scaling stroke needs to reset the transfo
rm back to the host transform. | 85 // Non-scaling stroke needs to reset the transfo
rm back to the host transform. |
| 123 additionalPaintServerTransform = &nonScalingTran
sform; | 86 additionalPaintServerTransform = &nonScalingTran
sform; |
| 124 } | 87 } |
| 125 | 88 |
| 126 SkPaint strokePaint; | 89 SkPaint strokePaint; |
| 127 if (!paintForLayoutObject(paintContext.paintInfo(),
m_renderSVGShape.styleRef(), m_renderSVGShape, ApplyToStrokeMode, strokePaint, a
dditionalPaintServerTransform)) | 90 if (!SVGPaintContext::paintForLayoutObject(paintCont
ext.paintInfo(), m_renderSVGShape.styleRef(), m_renderSVGShape, ApplyToStrokeMod
e, strokePaint, additionalPaintServerTransform)) |
| 128 break; | 91 break; |
| 129 strokePaint.setAntiAlias(shouldAntiAlias); | 92 strokePaint.setAntiAlias(shouldAntiAlias); |
| 130 | 93 |
| 131 StrokeData strokeData; | 94 StrokeData strokeData; |
| 132 SVGLayoutSupport::applyStrokeStyleToStrokeData(strok
eData, m_renderSVGShape.styleRef(), m_renderSVGShape); | 95 SVGLayoutSupport::applyStrokeStyleToStrokeData(strok
eData, m_renderSVGShape.styleRef(), m_renderSVGShape); |
| 133 strokeData.setupPaint(&strokePaint); | 96 strokeData.setupPaint(&strokePaint); |
| 134 | 97 |
| 135 strokeShape(paintContext.paintInfo().context, stroke
Paint); | 98 strokeShape(paintContext.paintInfo().context, stroke
Paint); |
| 136 } | 99 } |
| 137 break; | 100 break; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 // This open-codes LayoutSVGShape::nonScalingStrokePath, because the | 247 // This open-codes LayoutSVGShape::nonScalingStrokePath, because the |
| 285 // requirements here differ (we have a temporary path that we can | 248 // requirements here differ (we have a temporary path that we can |
| 286 // mutate.) | 249 // mutate.) |
| 287 if (m_renderSVGShape.hasNonScalingStroke()) | 250 if (m_renderSVGShape.hasNonScalingStroke()) |
| 288 tempPath.transform(nonScalingTransform); | 251 tempPath.transform(nonScalingTransform); |
| 289 context->drawPath(tempPath.skPath(), fillPaint); | 252 context->drawPath(tempPath.skPath(), fillPaint); |
| 290 } | 253 } |
| 291 } | 254 } |
| 292 | 255 |
| 293 } // namespace blink | 256 } // namespace blink |
| OLD | NEW |