Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "core/paint/SVGClipPainter.h" | 5 #include "core/paint/SVGClipPainter.h" |
| 6 | 6 |
| 7 #include "core/dom/ElementTraversal.h" | 7 #include "core/dom/ElementTraversal.h" |
| 8 #include "core/layout/svg/LayoutSVGResourceClipper.h" | 8 #include "core/layout/svg/LayoutSVGResourceClipper.h" |
| 9 #include "core/layout/svg/SVGLayoutSupport.h" | |
| 9 #include "core/layout/svg/SVGResources.h" | 10 #include "core/layout/svg/SVGResources.h" |
| 10 #include "core/layout/svg/SVGResourcesCache.h" | 11 #include "core/layout/svg/SVGResourcesCache.h" |
| 11 #include "core/paint/LayoutObjectDrawingRecorder.h" | 12 #include "core/paint/LayoutObjectDrawingRecorder.h" |
| 12 #include "core/paint/PaintInfo.h" | 13 #include "core/paint/PaintInfo.h" |
| 13 #include "core/paint/TransformRecorder.h" | 14 #include "core/paint/TransformRecorder.h" |
| 14 #include "platform/graphics/paint/ClipPathDisplayItem.h" | 15 #include "platform/graphics/paint/ClipPathDisplayItem.h" |
| 15 #include "platform/graphics/paint/CompositingRecorder.h" | 16 #include "platform/graphics/paint/CompositingRecorder.h" |
| 16 #include "platform/graphics/paint/DrawingDisplayItem.h" | 17 #include "platform/graphics/paint/DrawingDisplayItem.h" |
| 17 #include "platform/graphics/paint/PaintController.h" | 18 #include "platform/graphics/paint/PaintController.h" |
| 19 #include "platform/graphics/paint/SkPictureBuilder.h" | |
| 18 | 20 |
| 19 namespace blink { | 21 namespace blink { |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 class SVGClipExpansionCycleHelper { | 25 class SVGClipExpansionCycleHelper { |
| 24 public: | 26 public: |
| 25 SVGClipExpansionCycleHelper(LayoutSVGResourceClipper& clip) : m_clip(clip) { clip.beginClipExpansion(); } | 27 SVGClipExpansionCycleHelper(LayoutSVGResourceClipper& clip) : m_clip(clip) { clip.beginClipExpansion(); } |
| 26 ~SVGClipExpansionCycleHelper() { m_clip.endClipExpansion(); } | 28 ~SVGClipExpansionCycleHelper() { m_clip.endClipExpansion(); } |
| 27 private: | 29 private: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 context.getPaintController().createAndAppend<BeginClipPathDisplayItem>(t arget, clipPath); | 61 context.getPaintController().createAndAppend<BeginClipPathDisplayItem>(t arget, clipPath); |
| 60 return true; | 62 return true; |
| 61 } | 63 } |
| 62 | 64 |
| 63 // Fall back to masking. | 65 // Fall back to masking. |
| 64 clipperState = ClipperAppliedMask; | 66 clipperState = ClipperAppliedMask; |
| 65 | 67 |
| 66 // Begin compositing the clip mask. | 68 // Begin compositing the clip mask. |
| 67 CompositingRecorder::beginCompositing(context, target, SkXfermode::kSrcOver_ Mode, 1, &paintInvalidationRect); | 69 CompositingRecorder::beginCompositing(context, target, SkXfermode::kSrcOver_ Mode, 1, &paintInvalidationRect); |
| 68 { | 70 { |
| 69 TransformRecorder recorder(context, target, animatedLocalTransform); | 71 if (!drawClipAsMask(context, target, targetBoundingBox, paintInvalidatio nRect, animatedLocalTransform)) { |
| 70 | |
| 71 // clipPath can also be clipped by another clipPath. | |
| 72 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObj ect(&m_clip); | |
| 73 LayoutSVGResourceClipper* clipPathClipper = resources ? resources->clipp er() : 0; | |
| 74 ClipperState clipPathClipperState = ClipperNotApplied; | |
| 75 if (clipPathClipper && !SVGClipPainter(*clipPathClipper).prepareEffect(m _clip, targetBoundingBox, paintInvalidationRect, context, clipPathClipperState)) { | |
| 76 // End the clip mask's compositor. | 72 // End the clip mask's compositor. |
| 77 CompositingRecorder::endCompositing(context, target); | 73 CompositingRecorder::endCompositing(context, target); |
| 78 return false; | 74 return false; |
| 79 } | 75 } |
| 80 | |
| 81 drawClipMaskContent(context, target, targetBoundingBox, paintInvalidatio nRect); | |
| 82 | |
| 83 if (clipPathClipper) | |
| 84 SVGClipPainter(*clipPathClipper).finishEffect(m_clip, context, clipP athClipperState); | |
| 85 } | 76 } |
| 86 | 77 |
| 87 // Masked content layer start. | 78 // Masked content layer start. |
| 88 CompositingRecorder::beginCompositing(context, target, SkXfermode::kSrcIn_Mo de, 1, &paintInvalidationRect); | 79 CompositingRecorder::beginCompositing(context, target, SkXfermode::kSrcIn_Mo de, 1, &paintInvalidationRect); |
| 89 | 80 |
| 90 return true; | 81 return true; |
| 91 } | 82 } |
| 92 | 83 |
| 93 void SVGClipPainter::finishEffect(const LayoutObject& target, GraphicsContext& c ontext, ClipperState& clipperState) | 84 void SVGClipPainter::finishEffect(const LayoutObject& target, GraphicsContext& c ontext, ClipperState& clipperState) |
| 94 { | 85 { |
| 95 switch (clipperState) { | 86 switch (clipperState) { |
| 96 case ClipperAppliedPath: | 87 case ClipperAppliedPath: |
| 97 // Path-only clipping, no layers to restore but we need to emit an end t o the clip path display item. | 88 // Path-only clipping, no layers to restore but we need to emit an end t o the clip path display item. |
| 98 context.getPaintController().endItem<EndClipPathDisplayItem>(target); | 89 context.getPaintController().endItem<EndClipPathDisplayItem>(target); |
| 99 break; | 90 break; |
| 100 case ClipperAppliedMask: | 91 case ClipperAppliedMask: |
| 101 // Transfer content -> clip mask (SrcIn) | 92 // Transfer content -> clip mask (SrcIn) |
| 102 CompositingRecorder::endCompositing(context, target); | 93 CompositingRecorder::endCompositing(context, target); |
| 103 | 94 |
| 104 // Transfer clip mask -> bg (SrcOver) | 95 // Transfer clip mask -> bg (SrcOver) |
| 105 CompositingRecorder::endCompositing(context, target); | 96 CompositingRecorder::endCompositing(context, target); |
| 106 break; | 97 break; |
| 107 default: | 98 default: |
| 108 ASSERT_NOT_REACHED(); | 99 ASSERT_NOT_REACHED(); |
| 109 } | 100 } |
| 110 } | 101 } |
| 111 | 102 |
| 112 void SVGClipPainter::drawClipMaskContent(GraphicsContext& context, const LayoutO bject& layoutObject, const FloatRect& targetBoundingBox, const FloatRect& target PaintInvalidationRect) | 103 bool SVGClipPainter::drawClipAsMask(GraphicsContext& context, const LayoutObject & layoutObject, const FloatRect& targetBoundingBox, const FloatRect& targetPaint InvalidationRect, const AffineTransform& localTransform) |
| 113 { | 104 { |
| 114 AffineTransform contentTransformation; | 105 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, layoutO bject, DisplayItem::SVGClip)) |
| 115 RefPtr<const SkPicture> clipContentPicture = m_clip.createContentPicture(con tentTransformation, targetBoundingBox, context); | 106 return true; |
| 116 | 107 |
| 117 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, layoutO bject, DisplayItem::SVGClip)) | 108 SkPictureBuilder maskPictureBuilder(targetPaintInvalidationRect, nullptr, &c ontext); |
| 118 return; | 109 GraphicsContext& maskContext = maskPictureBuilder.context(); |
| 110 { | |
| 111 TransformRecorder recorder(maskContext, layoutObject, localTransform); | |
| 112 | |
| 113 // Create a clipPathClipper if this clipPath is clipped by another clipP ath. | |
| 114 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObj ect(&m_clip); | |
| 115 LayoutSVGResourceClipper* clipPathClipper = resources ? resources->clipp er() : nullptr; | |
| 116 ClipperState clipPathClipperState = ClipperNotApplied; | |
| 117 if (clipPathClipper && !SVGClipPainter(*clipPathClipper).prepareEffect(m _clip, targetBoundingBox, targetPaintInvalidationRect, maskContext, clipPathClip perState)) | |
| 118 return false; | |
| 119 | |
| 120 { | |
| 121 AffineTransform contentTransform; | |
| 122 if (m_clip.clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUN DINGBOX) { | |
| 123 contentTransform.translate(targetBoundingBox.x(), targetBounding Box.y()); | |
| 124 contentTransform.scaleNonUniform(targetBoundingBox.width(), targ etBoundingBox.height()); | |
| 125 } | |
| 126 SubtreeContentTransformScope contentTransformScope(contentTransform) ; | |
|
chrishtr
2016/03/29 18:45:40
This used to be allocated only if m_clipContentPic
chrishtr
2016/03/29 19:05:31
Per offline conversation: SubtreeContentTransformS
| |
| 127 | |
| 128 TransformRecorder contentTransformRecorder(maskContext, layoutObject , contentTransform); | |
| 129 RefPtr<const SkPicture> clipContentPicture = m_clip.createContentPic ture(); | |
| 130 maskContext.getPaintController().createAndAppend<DrawingDisplayItem> (layoutObject, DisplayItem::SVGClip, clipContentPicture.get()); | |
| 131 } | |
| 132 | |
| 133 if (clipPathClipper) | |
| 134 SVGClipPainter(*clipPathClipper).finishEffect(m_clip, maskContext, c lipPathClipperState); | |
| 135 } | |
| 119 | 136 |
| 120 LayoutObjectDrawingRecorder drawingRecorder(context, layoutObject, DisplayIt em::SVGClip, targetPaintInvalidationRect); | 137 LayoutObjectDrawingRecorder drawingRecorder(context, layoutObject, DisplayIt em::SVGClip, targetPaintInvalidationRect); |
| 121 context.save(); | 138 RefPtr<SkPicture> maskPicture = maskPictureBuilder.endRecording(); |
| 122 context.concatCTM(contentTransformation); | 139 context.drawPicture(maskPicture.get()); |
| 123 context.drawPicture(clipContentPicture.get()); | 140 return true; |
| 124 context.restore(); | |
| 125 } | 141 } |
| 126 | 142 |
| 127 } // namespace blink | 143 } // namespace blink |
| OLD | NEW |