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/style/ClipPathOperation.h" | 8 #include "core/style/ClipPathOperation.h" |
9 #include "platform/graphics/paint/ClipPathRecorder.h" | 9 #include "platform/graphics/paint/ClipPathRecorder.h" |
10 | 10 |
11 namespace blink { | 11 namespace blink { |
12 | 12 |
13 ClipPathClipper::ClipPathClipper( | 13 ClipPathClipper::ClipPathClipper( |
14 GraphicsContext& context, | 14 GraphicsContext& context, |
15 const LayoutObject& layoutObject, | 15 const LayoutObject& layoutObject, |
16 const FloatRect& referenceBox, | 16 const FloatRect& referenceBox, |
17 const FloatRect& visualOverflowRect, | |
18 const FloatPoint& origin) | 17 const FloatPoint& origin) |
19 : m_resourceClipper(nullptr) | 18 : m_resourceClipper(nullptr) |
20 , m_clipperState(SVGClipPainter::ClipperNotApplied) | 19 , m_clipperState(SVGClipPainter::ClipperNotApplied) |
21 , m_layoutObject(layoutObject) | 20 , m_layoutObject(layoutObject) |
22 , m_context(context) | 21 , m_context(context) |
23 { | 22 { |
24 DCHECK(layoutObject.styleRef().clipPath()); | 23 DCHECK(layoutObject.styleRef().clipPath()); |
25 ClipPathOperation* clipPathOperation = layoutObject.styleRef().clipPath(); | 24 ClipPathOperation* clipPathOperation = layoutObject.styleRef().clipPath(); |
26 if (clipPathOperation->type() == ClipPathOperation::SHAPE) { | 25 if (clipPathOperation->type() == ClipPathOperation::SHAPE) { |
27 ShapeClipPathOperation* shape = toShapeClipPathOperation(clipPathOperati
on); | 26 ShapeClipPathOperation* shape = toShapeClipPathOperation(clipPathOperati
on); |
28 if (shape->isValid()) | 27 if (!shape->isValid()) |
29 m_clipPathRecorder.emplace(context, layoutObject, shape->path(refere
nceBox)); | 28 return; |
| 29 m_clipPathRecorder.emplace(context, layoutObject, shape->path(referenceB
ox)); |
30 } else { | 30 } else { |
31 DCHECK_EQ(clipPathOperation->type(), ClipPathOperation::REFERENCE); | 31 DCHECK_EQ(clipPathOperation->type(), ClipPathOperation::REFERENCE); |
32 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClip
PathOperation(clipPathOperation); | 32 ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClip
PathOperation(clipPathOperation); |
33 Document& document = layoutObject.document(); | |
34 // TODO(fs): It doesn't work with forward or external SVG references (ht
tps://bugs.webkit.org/show_bug.cgi?id=90405) | 33 // TODO(fs): It doesn't work with forward or external SVG references (ht
tps://bugs.webkit.org/show_bug.cgi?id=90405) |
35 Element* element = document.getElementById(referenceClipPathOperation->f
ragment()); | 34 Element* element = layoutObject.document().getElementById(referenceClipP
athOperation->fragment()); |
36 if (isSVGClipPathElement(element) && element->layoutObject()) { | 35 if (!isSVGClipPathElement(element) || !element->layoutObject()) |
37 m_resourceClipper = toLayoutSVGResourceClipper(toLayoutSVGResourceCo
ntainer(element->layoutObject())); | 36 return; |
38 // When SVG applies the clip, and the coordinate system is "userspac
e on use", we must explicitly pass in | 37 LayoutSVGResourceClipper* clipper = toLayoutSVGResourceClipper(toLayoutS
VGResourceContainer(element->layoutObject())); |
39 // the offset to have the clip paint in the correct location. When t
he coordinate system is | 38 // Compute the (conservative) bounds of the clip-path. |
40 // "object bounding box" the offset should already be accounted for
in the visualOverflowRect. | 39 FloatRect clipPathBounds = clipper->resourceBoundingBox(referenceBox); |
41 FloatPoint originTranslation = m_resourceClipper->clipPathUnits() ==
SVGUnitTypes::kSvgUnitTypeUserspaceonuse ? | 40 // When SVG applies the clip, and the coordinate system is "userspace on
use", we must explicitly pass in |
42 origin : FloatPoint(); | 41 // the offset to have the clip paint in the correct location. When the c
oordinate system is |
43 if (!SVGClipPainter(*m_resourceClipper).prepareEffect(layoutObject,
referenceBox, | 42 // "object bounding box" the offset should already be accounted for in t
he reference box. |
44 visualOverflowRect, originTranslation, context, m_clipperState))
{ | 43 FloatPoint originTranslation; |
45 // No need to "finish" the clipper if this failed. | 44 if (clipper->clipPathUnits() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse
) { |
46 m_resourceClipper = nullptr; | 45 clipPathBounds.moveBy(origin); |
47 } | 46 originTranslation = origin; |
48 } | 47 } |
| 48 if (!SVGClipPainter(*clipper).prepareEffect(layoutObject, referenceBox, |
| 49 clipPathBounds, originTranslation, context, m_clipperState)) |
| 50 return; |
| 51 m_resourceClipper = clipper; |
49 } | 52 } |
50 } | 53 } |
51 | 54 |
52 ClipPathClipper::~ClipPathClipper() | 55 ClipPathClipper::~ClipPathClipper() |
53 { | 56 { |
54 if (m_resourceClipper) | 57 if (m_resourceClipper) |
55 SVGClipPainter(*m_resourceClipper).finishEffect(m_layoutObject, m_contex
t, m_clipperState); | 58 SVGClipPainter(*m_resourceClipper).finishEffect(m_layoutObject, m_contex
t, m_clipperState); |
56 } | 59 } |
57 | 60 |
58 } // namespace blink | 61 } // namespace blink |
OLD | NEW |