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

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp

Issue 1461223002: Implement SVG's transform and effect paint property nodes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address reviewer comments Created 5 years 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
OLDNEW
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 "config.h" 5 #include "config.h"
6 #include "core/paint/PaintPropertyTreeBuilder.h" 6 #include "core/paint/PaintPropertyTreeBuilder.h"
7 7
8 #include "core/frame/FrameView.h" 8 #include "core/frame/FrameView.h"
9 #include "core/layout/LayoutView.h" 9 #include "core/layout/LayoutView.h"
10 #include "core/paint/ObjectPaintProperties.h" 10 #include "core/paint/ObjectPaintProperties.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get(); 72 localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get();
73 localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint(); 73 localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint();
74 74
75 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); 75 frameView.setPreTranslation(newTransformNodeForPreTranslation.release());
76 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( )); 76 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( ));
77 77
78 if (LayoutView* layoutView = frameView.layoutView()) 78 if (LayoutView* layoutView = frameView.layoutView())
79 walk(*layoutView, localContext); 79 walk(*layoutView, localContext);
80 } 80 }
81 81
82 static void deriveBorderBoxFromContainerContext(const LayoutBoxModelObject& obje ct, PaintPropertyTreeBuilderContext& context) 82 static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain tPropertyTreeBuilderContext& context)
83 { 83 {
84 if (!object.isBoxModelObject())
85 return;
86
87 const LayoutBoxModelObject& boxModelObject = toLayoutBoxModelObject(object);
88
84 // TODO(trchen): There is some insanity going on with tables. Double check r esults. 89 // TODO(trchen): There is some insanity going on with tables. Double check r esults.
85 switch (object.styleRef().position()) { 90 switch (object.styleRef().position()) {
86 case StaticPosition: 91 case StaticPosition:
87 break; 92 break;
88 case RelativePosition: 93 case RelativePosition:
89 context.paintOffset += object.offsetForInFlowPosition(); 94 context.paintOffset += boxModelObject.offsetForInFlowPosition();
90 break; 95 break;
91 case AbsolutePosition: 96 case AbsolutePosition:
92 context.currentTransform = context.transformForOutOfFlowPositioned; 97 context.currentTransform = context.transformForOutOfFlowPositioned;
93 context.paintOffset = context.paintOffsetForOutOfFlowPositioned; 98 context.paintOffset = context.paintOffsetForOutOfFlowPositioned;
94 break; 99 break;
95 case StickyPosition: 100 case StickyPosition:
96 context.paintOffset += object.offsetForInFlowPosition(); 101 context.paintOffset += boxModelObject.offsetForInFlowPosition();
97 break; 102 break;
98 case FixedPosition: 103 case FixedPosition:
99 context.currentTransform = context.transformForFixedPositioned; 104 context.currentTransform = context.transformForFixedPositioned;
100 context.paintOffset = context.paintOffsetForFixedPositioned; 105 context.paintOffset = context.paintOffsetForFixedPositioned;
101 break; 106 break;
102 default: 107 default:
103 ASSERT_NOT_REACHED(); 108 ASSERT_NOT_REACHED();
104 } 109 }
105 if (object.isBox()) 110 if (boxModelObject.isBox())
106 context.paintOffset += toLayoutBox(object).locationOffset(); 111 context.paintOffset += toLayoutBox(boxModelObject).locationOffset();
107 } 112 }
108 113
109 static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeed ed(const LayoutBoxModelObject& object, PaintPropertyTreeBuilderContext& context) 114 static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeed ed(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
110 { 115 {
111 // TODO(trchen): Eliminate PaintLayer dependency. 116 bool shouldCreatePaintOffsetTranslationNode = false;
112 bool shouldCreatePaintOffsetTranslationNode = object.layer() && object.layer ()->paintsWithTransform(GlobalPaintNormalPhase); 117 if (object.isSVGRoot()) {
118 // SVG doesn't use paint offset internally so emit a paint offset at the html->svg boundary.
119 shouldCreatePaintOffsetTranslationNode = true;
120 } else if (object.isBoxModelObject()) {
121 // TODO(trchen): Eliminate PaintLayer dependency.
122 PaintLayer* layer = toLayoutBoxModelObject(object).layer();
123 shouldCreatePaintOffsetTranslationNode = layer && layer->paintsWithTrans form(GlobalPaintNormalPhase);
124 }
113 125
114 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat ionNode) 126 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat ionNode)
115 return nullptr; 127 return nullptr;
116 128
117 TransformationMatrix matrix; 129 TransformationMatrix matrix;
118 matrix.translate(context.paintOffset.x(), context.paintOffset.y()); 130 matrix.translate(context.paintOffset.x(), context.paintOffset.y());
119 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create( 131 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create(
120 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()), 132 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()),
121 FloatPoint3D(), context.currentTransform); 133 FloatPoint3D(), context.currentTransform);
122 context.currentTransform = newTransformNodeForPaintOffsetTranslation.get(); 134 context.currentTransform = newTransformNodeForPaintOffsetTranslation.get();
123 context.paintOffset = LayoutPoint(); 135 context.paintOffset = LayoutPoint();
124 return newTransformNodeForPaintOffsetTranslation.release(); 136 return newTransformNodeForPaintOffsetTranslation.release();
125 } 137 }
126 138
127 static FloatPoint3D transformOrigin(const LayoutBox& box) 139 static FloatPoint3D transformOrigin(const LayoutBox& box)
128 { 140 {
129 const ComputedStyle& style = box.styleRef(); 141 const ComputedStyle& style = box.styleRef();
130 FloatSize borderBoxSize(box.size()); 142 FloatSize borderBoxSize(box.size());
131 return FloatPoint3D( 143 return FloatPoint3D(
132 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), 144 floatValueForLength(style.transformOriginX(), borderBoxSize.width()),
133 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), 145 floatValueForLength(style.transformOriginY(), borderBoxSize.height()),
134 style.transformOriginZ()); 146 style.transformOriginZ());
135 } 147 }
136 148
137 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utBoxModelObject& object, PaintPropertyTreeBuilderContext& context) 149 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utObject& object, PaintPropertyTreeBuilderContext& context)
138 { 150 {
151 if (object.isSVG() && !object.isSVGRoot()) {
152 const AffineTransform& transform = object.localToParentTransform();
153 if (transform.isIdentity())
154 return nullptr;
155
156 // SVG's transform origin is baked into the localToParentTransform.
157 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = Transf ormPaintPropertyNode::create(
158 transform, FloatPoint3D(0, 0, 0), context.currentTransform);
159 context.currentTransform = newTransformNodeForTransform.get();
160 return newTransformNodeForTransform.release();
161 }
162
139 const ComputedStyle& style = object.styleRef(); 163 const ComputedStyle& style = object.styleRef();
140 if (!object.isBox() || !style.hasTransform()) 164 if (!object.isBox() || !style.hasTransform())
141 return nullptr; 165 return nullptr;
142 166
143 ASSERT(context.paintOffset == LayoutPoint()); 167 ASSERT(context.paintOffset == LayoutPoint());
144 168
145 TransformationMatrix matrix; 169 TransformationMatrix matrix;
146 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin, 170 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin,
147 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties); 171 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties);
148 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create( 172 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create(
149 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); 173 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform);
150 context.currentTransform = newTransformNodeForTransform.get(); 174 context.currentTransform = newTransformNodeForTransform.get();
151 return newTransformNodeForTransform.release(); 175 return newTransformNodeForTransform.release();
152 } 176 }
153 177
154 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutBoxM odelObject& object, PaintPropertyTreeBuilderContext& context) 178 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context)
155 { 179 {
156 const ComputedStyle& style = object.styleRef(); 180 const ComputedStyle& style = object.styleRef();
157 if (!object.isBox() || !style.hasOpacity()) 181 if (!style.hasOpacity())
158 return nullptr; 182 return nullptr;
159 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); 183 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect);
160 context.currentEffect = newEffectNode.get(); 184 context.currentEffect = newEffectNode.get();
161 return newEffectNode.release(); 185 return newEffectNode.release();
162 } 186 }
163 187
164 static FloatPoint perspectiveOrigin(const LayoutBox& box) 188 static FloatPoint perspectiveOrigin(const LayoutBox& box)
165 { 189 {
166 const ComputedStyle& style = box.styleRef(); 190 const ComputedStyle& style = box.styleRef();
167 FloatSize borderBoxSize(box.size()); 191 FloatSize borderBoxSize(box.size());
168 return FloatPoint( 192 return FloatPoint(
169 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), 193 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()),
170 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())) ; 194 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())) ;
171 } 195 }
172 196
173 static PassRefPtr<TransformPaintPropertyNode> createPerspectiveIfNeeded(const La youtBoxModelObject& object, PaintPropertyTreeBuilderContext& context) 197 static PassRefPtr<TransformPaintPropertyNode> createPerspectiveIfNeeded(const La youtObject& object, PaintPropertyTreeBuilderContext& context)
174 { 198 {
175 const ComputedStyle& style = object.styleRef(); 199 const ComputedStyle& style = object.styleRef();
176 if (!object.isBox() || !style.hasPerspective()) 200 if (!object.isBox() || !style.hasPerspective())
177 return nullptr; 201 return nullptr;
178 202
179 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = Transfor mPaintPropertyNode::create( 203 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = Transfor mPaintPropertyNode::create(
180 TransformationMatrix().applyPerspective(style.perspective()), 204 TransformationMatrix().applyPerspective(style.perspective()),
181 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), context.currentTransform); 205 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), context.currentTransform);
182 context.currentTransform = newTransformNodeForPerspective.get(); 206 context.currentTransform = newTransformNodeForPerspective.get();
183 return newTransformNodeForPerspective.release(); 207 return newTransformNodeForPerspective.release();
184 } 208 }
185 209
186 static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(co nst LayoutBoxModelObject& object, PaintPropertyTreeBuilderContext& context) 210 static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(co nst LayoutObject& object, PaintPropertyTreeBuilderContext& context)
187 { 211 {
188 if (!object.hasOverflowClip()) 212 if (!object.isBoxModelObject() || !object.hasOverflowClip())
189 return nullptr; 213 return nullptr;
190 214
191 PaintLayer* layer = object.layer(); 215 PaintLayer* layer = toLayoutBoxModelObject(object).layer();
192 ASSERT(layer); 216 ASSERT(layer);
193 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); 217 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset();
194 if (scrollOffset.isZero() && !layer->scrollsOverflow()) 218 if (scrollOffset.isZero() && !layer->scrollsOverflow())
195 return nullptr; 219 return nullptr;
196 220
197 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( 221 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create(
198 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), 222 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()),
199 FloatPoint3D(), context.currentTransform); 223 FloatPoint3D(), context.currentTransform);
200 context.currentTransform = newTransformNodeForScrollTranslation.get(); 224 context.currentTransform = newTransformNodeForScrollTranslation.get();
201 return newTransformNodeForScrollTranslation.release(); 225 return newTransformNodeForScrollTranslation.release();
202 } 226 }
203 227
204 static void updateOutOfFlowContext(const LayoutBoxModelObject& object, PaintProp ertyTreeBuilderContext& context) 228 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree BuilderContext& context)
205 { 229 {
206 const ComputedStyle& style = object.styleRef(); 230 const ComputedStyle& style = object.styleRef();
207 bool hasTransform = object.isBox() && style.hasTransform(); 231 bool hasTransform = object.isBox() && style.hasTransform();
208 if (style.position() != StaticPosition || hasTransform) { 232 if (style.position() != StaticPosition || hasTransform) {
trchen 2015/11/20 22:52:09 || object.isSVGForeignObject()
209 context.transformForOutOfFlowPositioned = context.currentTransform; 233 context.transformForOutOfFlowPositioned = context.currentTransform;
210 context.paintOffsetForOutOfFlowPositioned = context.paintOffset; 234 context.paintOffsetForOutOfFlowPositioned = context.paintOffset;
211 } 235 }
212 if (hasTransform) { 236 if (hasTransform) {
trchen 2015/11/20 22:52:09 ditto
213 context.transformForFixedPositioned = context.currentTransform; 237 context.transformForFixedPositioned = context.currentTransform;
214 context.paintOffsetForFixedPositioned = context.paintOffset; 238 context.paintOffsetForFixedPositioned = context.paintOffset;
215 } 239 }
216 } 240 }
217 241
218 void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const PaintPro pertyTreeBuilderContext& context) 242 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre eBuilderContext& context)
219 { 243 {
220 ASSERT(object.isBox() != object.isLayoutInline()); // Either or.
221
222 PaintPropertyTreeBuilderContext localContext(context); 244 PaintPropertyTreeBuilderContext localContext(context);
223 245
224 deriveBorderBoxFromContainerContext(object, localContext); 246 deriveBorderBoxFromContainerContext(object, localContext);
225 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); 247 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext);
226 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); 248 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext);
227 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); 249 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext);
228 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); 250 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext);
229 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); 251 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext);
230 updateOutOfFlowContext(object, localContext); 252 updateOutOfFlowContext(object, localContext);
231 253
232 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newTransformNodeForPerspective || newTransformNodeForScrol lTranslation) { 254 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newTransformNodeForPerspective || newTransformNodeForScrol lTranslation) {
233 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( 255 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create(
234 newTransformNodeForPaintOffsetTranslation.release(), 256 newTransformNodeForPaintOffsetTranslation.release(),
235 newTransformNodeForTransform.release(), 257 newTransformNodeForTransform.release(),
236 newEffectNode.release(), 258 newEffectNode.release(),
237 newTransformNodeForPerspective.release(), 259 newTransformNodeForPerspective.release(),
238 newTransformNodeForScrollTranslation.release()); 260 newTransformNodeForScrollTranslation.release());
239 object.setObjectPaintProperties(updatedPaintProperties.release()); 261 object.setObjectPaintProperties(updatedPaintProperties.release());
240 } else { 262 } else {
241 object.clearObjectPaintProperties(); 263 object.clearObjectPaintProperties();
242 } 264 }
243 265
244 // TODO(trchen): Walk subframes for LayoutFrame. 266 // TODO(trchen): Walk subframes for LayoutFrame.
245 267
246 // TODO(trchen): Implement SVG walk.
247 if (object.isSVGRoot()) {
248 return;
249 }
250
251 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { 268 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) {
252 if (child->isText()) 269 if (child->isBoxModelObject() || child->isSVG())
253 continue; 270 walk(*child, localContext);
254 walk(toLayoutBoxModelObject(*child), localContext);
255 } 271 }
256 } 272 }
257 273
258 } // namespace blink 274 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698