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

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: Created 5 years, 1 month 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 shouldCreatePaintOffsetTranslationNode = toLayoutBoxModelObject(object). layer() && toLayoutBoxModelObject(object).layer()->paintsWithTransform(GlobalPai ntNormalPhase);
jbroman 2015/11/20 19:09:20 nit: extract toLayoutBoxModelObject(object).layer(
pdr. 2015/11/20 19:33:41 I actually refactored this slightly differently so
jbroman 2015/11/20 19:53:40 ...which is exactly what I asked you to do?
123 }
113 124
114 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat ionNode) 125 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat ionNode)
115 return nullptr; 126 return nullptr;
116 127
117 TransformationMatrix matrix; 128 TransformationMatrix matrix;
118 matrix.translate(context.paintOffset.x(), context.paintOffset.y()); 129 matrix.translate(context.paintOffset.x(), context.paintOffset.y());
119 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create( 130 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create(
120 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()), 131 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()),
121 FloatPoint3D(), context.currentTransform); 132 FloatPoint3D(), context.currentTransform);
122 context.currentTransform = newTransformNodeForPaintOffsetTranslation.get(); 133 context.currentTransform = newTransformNodeForPaintOffsetTranslation.get();
123 context.paintOffset = LayoutPoint(); 134 context.paintOffset = LayoutPoint();
124 return newTransformNodeForPaintOffsetTranslation.release(); 135 return newTransformNodeForPaintOffsetTranslation.release();
125 } 136 }
126 137
127 static FloatPoint3D transformOrigin(const LayoutBox& box) 138 static FloatPoint3D transformOrigin(const LayoutBox& box)
128 { 139 {
129 const ComputedStyle& style = box.styleRef(); 140 const ComputedStyle& style = box.styleRef();
130 FloatSize borderBoxSize(box.size()); 141 FloatSize borderBoxSize(box.size());
131 return FloatPoint3D( 142 return FloatPoint3D(
132 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), 143 floatValueForLength(style.transformOriginX(), borderBoxSize.width()),
133 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), 144 floatValueForLength(style.transformOriginY(), borderBoxSize.height()),
134 style.transformOriginZ()); 145 style.transformOriginZ());
135 } 146 }
136 147
137 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utBoxModelObject& object, PaintPropertyTreeBuilderContext& context) 148 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utObject& object, PaintPropertyTreeBuilderContext& context)
138 { 149 {
150 if (object.isSVG() && !object.isSVGRoot()) {
151 const AffineTransform& transform = object.localToParentTransform();
152 if (transform.isIdentity())
153 return nullptr;
154
155 // SVG's transform origin is baked into the localToParentTransform.
156 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = Transf ormPaintPropertyNode::create(
157 transform, FloatPoint3D(0, 0, 0), context.currentTransform);
158 context.currentTransform = newTransformNodeForTransform.get();
159 return newTransformNodeForTransform.release();
160 }
161
139 const ComputedStyle& style = object.styleRef(); 162 const ComputedStyle& style = object.styleRef();
140 if (!object.isBox() || !style.hasTransform()) 163 if (!object.isBox() || !style.hasTransform())
141 return nullptr; 164 return nullptr;
142 165
143 ASSERT(context.paintOffset == LayoutPoint()); 166 ASSERT(context.paintOffset == LayoutPoint());
144 167
145 TransformationMatrix matrix; 168 TransformationMatrix matrix;
146 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin, 169 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin,
147 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties); 170 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties);
148 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create( 171 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create(
149 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); 172 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform);
150 context.currentTransform = newTransformNodeForTransform.get(); 173 context.currentTransform = newTransformNodeForTransform.get();
151 return newTransformNodeForTransform.release(); 174 return newTransformNodeForTransform.release();
152 } 175 }
153 176
154 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutBoxM odelObject& object, PaintPropertyTreeBuilderContext& context) 177 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context)
155 { 178 {
156 const ComputedStyle& style = object.styleRef(); 179 const ComputedStyle& style = object.styleRef();
157 if (!object.isBox() || !style.hasOpacity()) 180 if (!style.hasOpacity())
158 return nullptr; 181 return nullptr;
159 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); 182 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect);
160 context.currentEffect = newEffectNode.get(); 183 context.currentEffect = newEffectNode.get();
161 return newEffectNode.release(); 184 return newEffectNode.release();
162 } 185 }
163 186
164 static FloatPoint perspectiveOrigin(const LayoutBox& box) 187 static FloatPoint perspectiveOrigin(const LayoutBox& box)
165 { 188 {
166 const ComputedStyle& style = box.styleRef(); 189 const ComputedStyle& style = box.styleRef();
167 FloatSize borderBoxSize(box.size()); 190 FloatSize borderBoxSize(box.size());
168 return FloatPoint( 191 return FloatPoint(
169 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), 192 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()),
170 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())) ; 193 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())) ;
171 } 194 }
172 195
173 static PassRefPtr<TransformPaintPropertyNode> createPerspectiveIfNeeded(const La youtBoxModelObject& object, PaintPropertyTreeBuilderContext& context) 196 static PassRefPtr<TransformPaintPropertyNode> createPerspectiveIfNeeded(const La youtObject& object, PaintPropertyTreeBuilderContext& context)
174 { 197 {
175 const ComputedStyle& style = object.styleRef(); 198 const ComputedStyle& style = object.styleRef();
176 if (!object.isBox() || !style.hasPerspective()) 199 if (!object.isBox() || !style.hasPerspective())
177 return nullptr; 200 return nullptr;
178 201
179 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = Transfor mPaintPropertyNode::create( 202 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = Transfor mPaintPropertyNode::create(
180 TransformationMatrix().applyPerspective(style.perspective()), 203 TransformationMatrix().applyPerspective(style.perspective()),
181 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), context.currentTransform); 204 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), context.currentTransform);
182 context.currentTransform = newTransformNodeForPerspective.get(); 205 context.currentTransform = newTransformNodeForPerspective.get();
183 return newTransformNodeForPerspective.release(); 206 return newTransformNodeForPerspective.release();
184 } 207 }
185 208
186 static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(co nst LayoutBoxModelObject& object, PaintPropertyTreeBuilderContext& context) 209 static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(co nst LayoutObject& object, PaintPropertyTreeBuilderContext& context)
187 { 210 {
188 if (!object.hasOverflowClip()) 211 if (!object.isBoxModelObject() || !object.hasOverflowClip())
189 return nullptr; 212 return nullptr;
190 213
191 PaintLayer* layer = object.layer(); 214 PaintLayer* layer = toLayoutBoxModelObject(object).layer();
192 ASSERT(layer); 215 ASSERT(layer);
193 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); 216 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset();
194 if (scrollOffset.isZero() && !layer->scrollsOverflow()) 217 if (scrollOffset.isZero() && !layer->scrollsOverflow())
195 return nullptr; 218 return nullptr;
196 219
197 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( 220 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create(
198 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), 221 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()),
199 FloatPoint3D(), context.currentTransform); 222 FloatPoint3D(), context.currentTransform);
200 context.currentTransform = newTransformNodeForScrollTranslation.get(); 223 context.currentTransform = newTransformNodeForScrollTranslation.get();
201 return newTransformNodeForScrollTranslation.release(); 224 return newTransformNodeForScrollTranslation.release();
202 } 225 }
203 226
204 static void updateOutOfFlowContext(const LayoutBoxModelObject& object, PaintProp ertyTreeBuilderContext& context) 227 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree BuilderContext& context)
205 { 228 {
206 const ComputedStyle& style = object.styleRef(); 229 const ComputedStyle& style = object.styleRef();
207 bool hasTransform = object.isBox() && style.hasTransform(); 230 bool hasTransform = object.isBox() && style.hasTransform();
208 if (style.position() != StaticPosition || hasTransform) { 231 if (style.position() != StaticPosition || hasTransform) {
209 context.transformForOutOfFlowPositioned = context.currentTransform; 232 context.transformForOutOfFlowPositioned = context.currentTransform;
210 context.paintOffsetForOutOfFlowPositioned = context.paintOffset; 233 context.paintOffsetForOutOfFlowPositioned = context.paintOffset;
211 } 234 }
212 if (hasTransform) { 235 if (hasTransform) {
213 context.transformForFixedPositioned = context.currentTransform; 236 context.transformForFixedPositioned = context.currentTransform;
214 context.paintOffsetForFixedPositioned = context.paintOffset; 237 context.paintOffsetForFixedPositioned = context.paintOffset;
215 } 238 }
216 } 239 }
217 240
218 void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const PaintPro pertyTreeBuilderContext& context) 241 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre eBuilderContext& context)
219 { 242 {
220 ASSERT(object.isBox() != object.isLayoutInline()); // Either or.
221
222 PaintPropertyTreeBuilderContext localContext(context); 243 PaintPropertyTreeBuilderContext localContext(context);
223 244
224 deriveBorderBoxFromContainerContext(object, localContext); 245 deriveBorderBoxFromContainerContext(object, localContext);
225 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); 246 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext);
226 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); 247 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext);
227 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); 248 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext);
228 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); 249 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext);
229 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); 250 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext);
230 updateOutOfFlowContext(object, localContext); 251 updateOutOfFlowContext(object, localContext);
231 252
232 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newTransformNodeForPerspective || newTransformNodeForScrol lTranslation) { 253 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newTransformNodeForPerspective || newTransformNodeForScrol lTranslation) {
233 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( 254 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create(
234 newTransformNodeForPaintOffsetTranslation.release(), 255 newTransformNodeForPaintOffsetTranslation.release(),
235 newTransformNodeForTransform.release(), 256 newTransformNodeForTransform.release(),
236 newEffectNode.release(), 257 newEffectNode.release(),
237 newTransformNodeForPerspective.release(), 258 newTransformNodeForPerspective.release(),
238 newTransformNodeForScrollTranslation.release()); 259 newTransformNodeForScrollTranslation.release());
239 object.setObjectPaintProperties(updatedPaintProperties.release()); 260 object.setObjectPaintProperties(updatedPaintProperties.release());
240 } else { 261 } else {
241 object.clearObjectPaintProperties(); 262 object.clearObjectPaintProperties();
242 } 263 }
243 264
244 // TODO(trchen): Walk subframes for LayoutFrame. 265 // TODO(trchen): Walk subframes for LayoutFrame.
245 266
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()) { 267 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) {
252 if (child->isText()) 268 if (child->isBoxModelObject() || child->isSVG())
253 continue; 269 walk(*child, localContext);
254 walk(toLayoutBoxModelObject(*child), localContext);
255 } 270 }
256 } 271 }
257 272
258 } // namespace blink 273 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698