OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "core/paint/PaintPropertyTreeBuilder.h" | |
7 | |
8 #include "core/frame/FrameView.h" | |
9 #include "core/layout/LayoutView.h" | |
10 #include "core/paint/ObjectPaintProperties.h" | |
11 #include "core/paint/PaintLayer.h" | |
12 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | |
13 #include "platform/transforms/TransformationMatrix.h" | |
14 | |
15 namespace blink { | |
16 | |
17 struct PaintPropertyTreeBuilder::WalkContext { | |
pdr.
2015/10/14 17:52:07
CurrentPropertyTreeContext?
trchen
2015/10/14 22:51:13
I'm thinking just Context... Being a nested class
| |
18 explicit WalkContext(TransformPaintPropertyNode* newCurrentTransform = nullp tr) : currentTransform(newCurrentTransform) { } | |
19 TransformPaintPropertyNode* currentTransform; | |
20 }; | |
21 | |
22 struct PaintPropertyTreeBuilder::WalkContextHTML : public WalkContext { | |
pdr.
2015/10/14 17:52:07
Does this need to be so abstract? What other subcl
trchen
2015/10/14 22:51:13
I'm thinking of SVG. They are different because th
| |
23 static WalkContextHTML contextForDocumentNode(TransformPaintPropertyNode* fi xed, TransformPaintPropertyNode* absolute) { return WalkContextHTML(fixed, absol ute); } | |
24 | |
25 LayoutPoint paintOffset; | |
26 | |
27 TransformPaintPropertyNode* transformForOutOfFlowPositioned; | |
28 LayoutPoint paintOffsetForOutOfFlowPositioned; | |
29 | |
30 TransformPaintPropertyNode* transformForFixedPositioned; | |
31 LayoutPoint paintOffsetForFixedPositioned; | |
32 private: | |
33 WalkContextHTML(TransformPaintPropertyNode* fixed, TransformPaintPropertyNod e* absolute) | |
34 : WalkContext(absolute) | |
35 , transformForOutOfFlowPositioned(absolute) | |
36 , transformForFixedPositioned(fixed) | |
37 { | |
38 } | |
39 }; | |
40 | |
41 void PaintPropertyTreeBuilder::buildPropertyTrees(FrameView& rootFrame) | |
42 { | |
43 walk(rootFrame, WalkContext()); | |
44 } | |
45 | |
46 void PaintPropertyTreeBuilder::walk(FrameView& frameView, const WalkContext& con text) | |
47 { | |
48 ObjectPaintProperties& properties = frameView.ensureObjectPaintProperties(); | |
49 | |
50 TransformationMatrix frameTranslate; | |
51 frameTranslate.translate(frameView.x(), frameView.y()); | |
52 TransformPaintPropertyNode* transformNodeForSelf = new TransformPaintPropert yNode(frameTranslate, FloatPoint3D(), context.currentTransform); | |
53 properties.setTransformNodeForSelf(adoptRef(transformNodeForSelf)); | |
54 | |
55 TransformationMatrix frameScroll; | |
56 frameScroll.translate(-frameView.scrollX(), -frameView.scrollY()); | |
57 TransformPaintPropertyNode* transformNodeForDescendants = new TransformPaint PropertyNode(frameScroll, FloatPoint3D(), transformNodeForSelf); | |
58 properties.setTransformNodeForDescendants(adoptRef(transformNodeForDescendan ts)); | |
59 | |
60 if (LayoutView* layoutView = frameView.layoutView()) | |
61 walk(*layoutView, WalkContextHTML::contextForDocumentNode(transformNodeF orSelf, transformNodeForDescendants)); | |
62 } | |
63 | |
64 static bool shouldCreateTransformNodeForSelf(LayoutBoxModelObject& object) | |
65 { | |
66 // TODO(trchen): Eliminate PaintLayer dependency. | |
67 PaintLayer* layer = object.layer(); | |
68 if (!layer) | |
69 return false; | |
70 | |
71 return layer->paintsWithTransform(GlobalPaintNormalPhase); | |
72 } | |
73 | |
74 static FloatPoint perspectiveOrigin(const LayoutBox& box) | |
75 { | |
76 const ComputedStyle& style = box.styleRef(); | |
77 | |
78 FloatSize borderBoxSize(box.size()); | |
79 return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBoxS ize.width()), floatValueForLength(style.perspectiveOriginY(), borderBoxSize.heig ht())); | |
80 } | |
81 | |
82 void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const WalkCont extHTML& context) | |
83 { | |
84 ASSERT(object.isBox() != object.isLayoutInline()); // Either or. | |
85 | |
86 WalkContextHTML localContext(context); | |
87 RefPtr<TransformPaintPropertyNode> newTransformNodeForSelf; | |
88 RefPtr<TransformPaintPropertyNode> newTransformNodeForDescendants; | |
89 | |
90 const ComputedStyle& style = object.styleRef(); | |
91 // TODO(trchen): There is some insanity going on with tables. Double check r esults. | |
92 switch (style.position()) { | |
93 case StaticPosition: | |
94 break; | |
95 case RelativePosition: | |
96 localContext.paintOffset += object.offsetForInFlowPosition(); | |
97 break; | |
98 case AbsolutePosition: | |
99 localContext.currentTransform = context.transformForOutOfFlowPositioned; | |
100 localContext.paintOffset = context.paintOffsetForOutOfFlowPositioned; | |
101 break; | |
102 case StickyPosition: | |
103 localContext.paintOffset += object.offsetForInFlowPosition(); | |
104 break; | |
105 case FixedPosition: | |
106 localContext.currentTransform = context.transformForFixedPositioned; | |
107 localContext.paintOffset = context.paintOffsetForFixedPositioned; | |
108 break; | |
109 default: | |
110 ASSERT_NOT_REACHED(); | |
111 } | |
112 if (object.isBox()) | |
113 localContext.paintOffset += toLayoutBox(object).locationOffset(); | |
114 | |
115 bool hasTransform = object.isBox() && style.hasTransform(); | |
pdr.
2015/10/14 18:44:15
I think it's important to unblock some work that d
trchen
2015/10/14 22:51:13
We need to keep track of paint offset in order to
pdr.
2015/10/15 04:53:52
In order to land this, we will need a ridiculous n
trchen
2015/10/15 23:24:31
IMO without paint offset handling the code will be
| |
116 if (shouldCreateTransformNodeForSelf(object)) { | |
117 TransformationMatrix matrix; | |
118 if (hasTransform) | |
119 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedSty le::IncludeTransformOrigin, ComputedStyle::IncludeMotionPath, ComputedStyle::Inc ludeIndependentTransformProperties); | |
120 matrix.translateRight(localContext.paintOffset.x(), localContext.paintOf fset.y()); | |
121 // TODO(jbroman): Put the real transform origin here, instead of using a | |
122 // matrix with the origin baked in. | |
123 newTransformNodeForSelf = adoptRef(new TransformPaintPropertyNode(matrix , FloatPoint3D(), localContext.currentTransform)); | |
124 localContext.currentTransform = newTransformNodeForSelf.get(); | |
125 localContext.paintOffset = LayoutPoint(); | |
126 } else { | |
127 ASSERT(!hasTransform); | |
128 } | |
129 | |
130 if (object.isBox() && style.hasPerspective()) { | |
131 FloatPoint origin = perspectiveOrigin(toLayoutBox(object)); | |
132 TransformationMatrix matrix; | |
133 matrix.applyPerspective(style.perspective()); | |
134 matrix.translate(-origin.x(), -origin.y()); | |
jbroman
2015/10/14 15:11:58
TransformationMatrix::applyTransformOrigin
trchen
2015/10/14 22:51:13
Done.
| |
135 matrix.translateRight(origin.x(), origin.y()); | |
136 matrix.translateRight(localContext.paintOffset.x(), localContext.paintOf fset.y()); | |
137 newTransformNodeForDescendants = adoptRef(new TransformPaintPropertyNode (matrix, FloatPoint3D(), localContext.currentTransform)); | |
138 localContext.currentTransform = newTransformNodeForDescendants.get(); | |
139 localContext.paintOffset = LayoutPoint(); | |
140 } | |
141 | |
142 if (style.position() != StaticPosition || hasTransform) { | |
143 localContext.transformForOutOfFlowPositioned = localContext.currentTrans form; | |
144 localContext.paintOffsetForOutOfFlowPositioned = localContext.paintOffse t; | |
145 } | |
146 | |
147 if (hasTransform) { | |
148 localContext.transformForFixedPositioned = localContext.currentTransform ; | |
149 localContext.paintOffsetForFixedPositioned = localContext.paintOffset; | |
150 } | |
151 | |
152 if (object.hasOverflowClip()) { | |
153 PaintLayer* layer = object.layer(); | |
154 ASSERT(layer); | |
155 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); | |
156 if (!scrollOffset.isZero() || layer->scrollsOverflow()) { | |
157 TransformationMatrix matrix; | |
158 matrix.translate(-scrollOffset.width(), -scrollOffset.height()); | |
159 newTransformNodeForDescendants = adoptRef(new TransformPaintProperty Node(matrix, FloatPoint3D(), localContext.currentTransform)); | |
160 localContext.currentTransform = newTransformNodeForDescendants.get() ; | |
161 } | |
162 } | |
163 | |
164 if (newTransformNodeForSelf || newTransformNodeForDescendants) { | |
165 ObjectPaintProperties& properties = object.ensureObjectPaintProperties() ; | |
166 properties.setTransformNodeForSelf(newTransformNodeForSelf.release()); | |
167 properties.setTransformNodeForDescendants(newTransformNodeForDescendants .release()); | |
168 } else { | |
169 object.setObjectPaintProperties(nullptr); | |
170 } | |
171 | |
172 if (object.isSVGRoot()) { | |
173 // TODO(trchen): Implement SVG walk. | |
174 return; | |
175 } | |
176 | |
177 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { | |
178 if (child->isText()) | |
179 continue; | |
180 walk(toLayoutBoxModelObject(*child), localContext); | |
181 } | |
182 } | |
183 | |
184 } // namespace blink | |
OLD | NEW |