| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/ClipPathClipper.h" | 5 #include "core/paint/ClipPathClipper.h" |
| 6 | 6 |
| 7 #include "core/layout/svg/LayoutSVGResourceClipper.h" | 7 #include "core/layout/svg/LayoutSVGResourceClipper.h" |
| 8 #include "core/layout/svg/SVGResources.h" |
| 9 #include "core/layout/svg/SVGResourcesCache.h" |
| 10 #include "core/paint/SVGClipPainter.h" |
| 8 #include "core/style/ClipPathOperation.h" | 11 #include "core/style/ClipPathOperation.h" |
| 9 #include "platform/graphics/paint/ClipPathRecorder.h" | 12 #include "platform/graphics/paint/ClipPathRecorder.h" |
| 10 | 13 |
| 11 namespace blink { | 14 namespace blink { |
| 12 | 15 |
| 16 namespace { |
| 17 |
| 18 LayoutSVGResourceClipper* resolveElementReference( |
| 19 const LayoutObject& layoutObject, |
| 20 const ReferenceClipPathOperation& referenceClipPathOperation) |
| 21 { |
| 22 if (layoutObject.isSVG() && !layoutObject.isSVGRoot()) { |
| 23 // The reference will have been resolved in |
| 24 // SVGResources::buildResources, so we can just use the LayoutObject's |
| 25 // SVGResources. |
| 26 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObj
ect(&layoutObject); |
| 27 return resources ? resources->clipper() : nullptr; |
| 28 } |
| 29 // TODO(fs): It doesn't work with forward or external SVG references (https:
//bugs.webkit.org/show_bug.cgi?id=90405) |
| 30 Element* element = layoutObject.document().getElementById(referenceClipPathO
peration.fragment()); |
| 31 if (!isSVGClipPathElement(element) || !element->layoutObject()) |
| 32 return nullptr; |
| 33 return toLayoutSVGResourceClipper(toLayoutSVGResourceContainer(element->layo
utObject())); |
| 34 } |
| 35 |
| 36 } // namespace |
| 37 |
| 13 ClipPathClipper::ClipPathClipper( | 38 ClipPathClipper::ClipPathClipper( |
| 14 GraphicsContext& context, | 39 GraphicsContext& context, |
| 15 const LayoutObject& layoutObject, | 40 const LayoutObject& layoutObject, |
| 16 const FloatRect& referenceBox, | 41 const FloatRect& referenceBox, |
| 17 const FloatPoint& origin) | 42 const FloatPoint& origin) |
| 18 : m_resourceClipper(nullptr) | 43 : m_resourceClipper(nullptr) |
| 19 , m_clipperState(SVGClipPainter::ClipperNotApplied) | 44 , m_clipperState(ClipperState::NotApplied) |
| 20 , m_layoutObject(layoutObject) | 45 , m_layoutObject(layoutObject) |
| 21 , m_context(context) | 46 , m_context(context) |
| 22 { | 47 { |
| 23 DCHECK(layoutObject.styleRef().clipPath()); | 48 DCHECK(layoutObject.styleRef().clipPath()); |
| 24 ClipPathOperation* clipPathOperation = layoutObject.styleRef().clipPath(); | 49 ClipPathOperation* clipPathOperation = layoutObject.styleRef().clipPath(); |
| 25 if (clipPathOperation->type() == ClipPathOperation::SHAPE) { | 50 if (clipPathOperation->type() == ClipPathOperation::SHAPE) { |
| 26 ShapeClipPathOperation* shape = toShapeClipPathOperation(clipPathOperati
on); | 51 ShapeClipPathOperation* shape = toShapeClipPathOperation(clipPathOperati
on); |
| 27 if (!shape->isValid()) | 52 if (!shape->isValid()) |
| 28 return; | 53 return; |
| 29 m_clipPathRecorder.emplace(context, layoutObject, shape->path(referenceB
ox)); | 54 m_clipPathRecorder.emplace(context, layoutObject, shape->path(referenceB
ox)); |
| 55 m_clipperState = ClipperState::AppliedPath; |
| 30 } else { | 56 } else { |
| 31 DCHECK_EQ(clipPathOperation->type(), ClipPathOperation::REFERENCE); | 57 DCHECK_EQ(clipPathOperation->type(), ClipPathOperation::REFERENCE); |
| 32 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClip
PathOperation(clipPathOperation); | 58 LayoutSVGResourceClipper* clipper = resolveElementReference( |
| 33 // TODO(fs): It doesn't work with forward or external SVG references (ht
tps://bugs.webkit.org/show_bug.cgi?id=90405) | 59 layoutObject, toReferenceClipPathOperation(*clipPathOperation)); |
| 34 Element* element = layoutObject.document().getElementById(referenceClipP
athOperation->fragment()); | 60 if (!clipper) |
| 35 if (!isSVGClipPathElement(element) || !element->layoutObject()) | |
| 36 return; | 61 return; |
| 37 LayoutSVGResourceClipper* clipper = toLayoutSVGResourceClipper(toLayoutS
VGResourceContainer(element->layoutObject())); | |
| 38 // Compute the (conservative) bounds of the clip-path. | 62 // Compute the (conservative) bounds of the clip-path. |
| 39 FloatRect clipPathBounds = clipper->resourceBoundingBox(referenceBox); | 63 FloatRect clipPathBounds = clipper->resourceBoundingBox(referenceBox); |
| 40 // When SVG applies the clip, and the coordinate system is "userspace on
use", we must explicitly pass in | 64 // When SVG applies the clip, and the coordinate system is "userspace on
use", we must explicitly pass in |
| 41 // the offset to have the clip paint in the correct location. When the c
oordinate system is | 65 // the offset to have the clip paint in the correct location. When the c
oordinate system is |
| 42 // "object bounding box" the offset should already be accounted for in t
he reference box. | 66 // "object bounding box" the offset should already be accounted for in t
he reference box. |
| 43 FloatPoint originTranslation; | 67 FloatPoint originTranslation; |
| 44 if (clipper->clipPathUnits() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse
) { | 68 if (clipper->clipPathUnits() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse
) { |
| 45 clipPathBounds.moveBy(origin); | 69 clipPathBounds.moveBy(origin); |
| 46 originTranslation = origin; | 70 originTranslation = origin; |
| 47 } | 71 } |
| 48 if (!SVGClipPainter(*clipper).prepareEffect(layoutObject, referenceBox, | 72 if (!SVGClipPainter(*clipper).prepareEffect(layoutObject, referenceBox, |
| 49 clipPathBounds, originTranslation, context, m_clipperState)) | 73 clipPathBounds, originTranslation, context, m_clipperState)) |
| 50 return; | 74 return; |
| 51 m_resourceClipper = clipper; | 75 m_resourceClipper = clipper; |
| 52 } | 76 } |
| 53 } | 77 } |
| 54 | 78 |
| 55 ClipPathClipper::~ClipPathClipper() | 79 ClipPathClipper::~ClipPathClipper() |
| 56 { | 80 { |
| 57 if (m_resourceClipper) | 81 if (m_resourceClipper) |
| 58 SVGClipPainter(*m_resourceClipper).finishEffect(m_layoutObject, m_contex
t, m_clipperState); | 82 SVGClipPainter(*m_resourceClipper).finishEffect(m_layoutObject, m_contex
t, m_clipperState); |
| 59 } | 83 } |
| 60 | 84 |
| 61 } // namespace blink | 85 } // namespace blink |
| OLD | NEW |