Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: Source/core/rendering/svg/RenderSVGResourceMasker.cpp

Issue 908243002: Move rendering/svg/RenderSVGResource* to layout/svg. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "core/rendering/svg/RenderSVGResourceMasker.h"
22
23 #include "core/dom/ElementTraversal.h"
24 #include "core/layout/svg/SVGLayoutSupport.h"
25 #include "core/paint/SVGPaintContext.h"
26 #include "core/svg/SVGElement.h"
27 #include "platform/graphics/GraphicsContextStateSaver.h"
28 #include "platform/transforms/AffineTransform.h"
29 #include "third_party/skia/include/core/SkPicture.h"
30
31 namespace blink {
32
33 RenderSVGResourceMasker::RenderSVGResourceMasker(SVGMaskElement* node)
34 : RenderSVGResourceContainer(node)
35 {
36 }
37
38 RenderSVGResourceMasker::~RenderSVGResourceMasker()
39 {
40 }
41
42 void RenderSVGResourceMasker::removeAllClientsFromCache(bool markForInvalidation )
43 {
44 m_maskContentPicture.clear();
45 m_maskContentBoundaries = FloatRect();
46 markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInval idation : ParentOnlyInvalidation);
47 }
48
49 void RenderSVGResourceMasker::removeClientFromCache(LayoutObject* client, bool m arkForInvalidation)
50 {
51 ASSERT(client);
52 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidati on : ParentOnlyInvalidation);
53 }
54
55 bool RenderSVGResourceMasker::prepareEffect(LayoutObject* object, GraphicsContex t* context)
56 {
57 ASSERT(object);
58 ASSERT(context);
59 ASSERT(style());
60 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
61
62 clearInvalidationMask();
63
64 FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordi nates();
65 if (paintInvalidationRect.isEmpty() || !element()->hasChildren())
66 return false;
67
68 // Content layer start.
69 context->beginTransparencyLayer(1, &paintInvalidationRect);
70
71 return true;
72 }
73
74 void RenderSVGResourceMasker::finishEffect(LayoutObject* object, GraphicsContext * context)
75 {
76 ASSERT(object);
77 ASSERT(context);
78 ASSERT(style());
79 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
80
81 FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordi nates();
82
83 const SVGLayoutStyle& svgStyle = style()->svgStyle();
84 ColorFilter maskLayerFilter = svgStyle.maskType() == MT_LUMINANCE
85 ? ColorFilterLuminanceToAlpha : ColorFilterNone;
86 ColorFilter maskContentFilter = svgStyle.colorInterpolation() == CI_LINEARRG B
87 ? ColorFilterSRGBToLinearRGB : ColorFilterNone;
88
89 // Mask layer start.
90 context->beginLayer(1, SkXfermode::kDstIn_Mode, &paintInvalidationRect, mask LayerFilter);
91 {
92 // Draw the mask with color conversion (when needed).
93 GraphicsContextStateSaver maskContentSaver(*context);
94 context->setColorFilter(maskContentFilter);
95
96 drawMaskForRenderer(context, object->objectBoundingBox());
97 }
98
99 // Transfer mask layer -> content layer (DstIn)
100 context->endLayer();
101 // Transfer content layer -> backdrop (SrcOver)
102 context->endLayer();
103 }
104
105 void RenderSVGResourceMasker::drawMaskForRenderer(GraphicsContext* context, cons t FloatRect& targetBoundingBox)
106 {
107 ASSERT(context);
108
109 AffineTransform contentTransformation;
110 SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskCo ntentUnits()->currentValue()->enumValue();
111 if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
112 contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox .y());
113 contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetB oundingBox.height());
114 context->concatCTM(contentTransformation);
115 }
116
117 if (!m_maskContentPicture) {
118 SubtreeContentTransformScope contentTransformScope(contentTransformation );
119 createPicture(context);
120 }
121
122 context->drawPicture(m_maskContentPicture.get());
123 }
124
125 void RenderSVGResourceMasker::createPicture(GraphicsContext* context)
126 {
127 ASSERT(context);
128
129 // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinat es) to avoid the intersection
130 // with local clips/mask, which may yield incorrect results when mixing obje ctBoundingBox and
131 // userSpaceOnUse units (http://crbug.com/294900).
132 FloatRect bounds = strokeBoundingBox();
133 context->beginRecording(bounds);
134 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
135 LayoutObject* renderer = childElement->renderer();
136 if (!renderer)
137 continue;
138 const LayoutStyle* style = renderer->style();
139 if (!style || style->display() == NONE || style->visibility() != VISIBLE )
140 continue;
141
142 SVGPaintContext::paintSubtree(context, renderer);
143 }
144 m_maskContentPicture = context->endRecording();
145 }
146
147 void RenderSVGResourceMasker::calculateMaskContentPaintInvalidationRect()
148 {
149 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
150 LayoutObject* renderer = childElement->renderer();
151 if (!renderer)
152 continue;
153 const LayoutStyle* style = renderer->style();
154 if (!style || style->display() == NONE || style->visibility() != VISIBLE )
155 continue;
156 m_maskContentBoundaries.unite(renderer->localToParentTransform().mapRect (renderer->paintInvalidationRectInLocalCoordinates()));
157 }
158 }
159
160 FloatRect RenderSVGResourceMasker::resourceBoundingBox(const LayoutObject* objec t)
161 {
162 SVGMaskElement* maskElement = toSVGMaskElement(element());
163 ASSERT(maskElement);
164
165 FloatRect objectBoundingBox = object->objectBoundingBox();
166 FloatRect maskBoundaries = SVGLengthContext::resolveRectangle<SVGMaskElement >(maskElement, maskElement->maskUnits()->currentValue()->enumValue(), objectBoun dingBox);
167
168 // Resource was not layouted yet. Give back clipping rect of the mask.
169 if (selfNeedsLayout())
170 return maskBoundaries;
171
172 if (m_maskContentBoundaries.isEmpty())
173 calculateMaskContentPaintInvalidationRect();
174
175 FloatRect maskRect = m_maskContentBoundaries;
176 if (maskElement->maskContentUnits()->currentValue()->value() == SVGUnitTypes ::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
177 AffineTransform transform;
178 transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
179 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h eight());
180 maskRect = transform.mapRect(maskRect);
181 }
182
183 maskRect.intersect(maskBoundaries);
184 return maskRect;
185 }
186
187 }
OLDNEW
« no previous file with comments | « Source/core/rendering/svg/RenderSVGResourceMasker.h ('k') | Source/core/rendering/svg/RenderSVGResourcePaintServer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698