|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 /* constants for what needs to be recomputed in response to style changes */ |
|
7 |
|
8 #ifndef nsChangeHint_h___ |
|
9 #define nsChangeHint_h___ |
|
10 |
|
11 #include "nsDebug.h" |
|
12 |
|
13 // Defines for various style related constants |
|
14 |
|
15 enum nsChangeHint { |
|
16 // change was visual only (e.g., COLOR=) |
|
17 // Invalidates all descendant frames (including following |
|
18 // placeholders to out-of-flow frames). |
|
19 nsChangeHint_RepaintFrame = 0x01, |
|
20 |
|
21 // For reflow, we want flags to give us arbitrary FrameNeedsReflow behavior. |
|
22 // just do a FrameNeedsReflow. |
|
23 nsChangeHint_NeedReflow = 0x02, |
|
24 |
|
25 // Invalidate intrinsic widths on the frame's ancestors. Must not be set |
|
26 // without setting nsChangeHint_NeedReflow. |
|
27 nsChangeHint_ClearAncestorIntrinsics = 0x04, |
|
28 |
|
29 // Invalidate intrinsic widths on the frame's descendants. Must not be set |
|
30 // without also setting nsChangeHint_ClearAncestorIntrinsics. |
|
31 nsChangeHint_ClearDescendantIntrinsics = 0x08, |
|
32 |
|
33 // Force unconditional reflow of all descendants. Must not be set without |
|
34 // setting nsChangeHint_NeedReflow, but is independent of both the |
|
35 // Clear*Intrinsics flags. |
|
36 nsChangeHint_NeedDirtyReflow = 0x10, |
|
37 |
|
38 // change requires view to be updated, if there is one (e.g., clip:). |
|
39 // Updates all descendants (including following placeholders to out-of-flows). |
|
40 nsChangeHint_SyncFrameView = 0x20, |
|
41 |
|
42 // The currently shown mouse cursor needs to be updated |
|
43 nsChangeHint_UpdateCursor = 0x40, |
|
44 |
|
45 /** |
|
46 * Used when the computed value (a URI) of one or more of an element's |
|
47 * filter/mask/clip/etc CSS properties changes, causing the element's frame |
|
48 * to start/stop referencing (or reference different) SVG resource elements. |
|
49 * (_Not_ used to handle changes to referenced resource elements.) Using this |
|
50 * hint results in nsSVGEffects::UpdateEffects being called on the element's |
|
51 * frame. |
|
52 */ |
|
53 nsChangeHint_UpdateEffects = 0x80, |
|
54 |
|
55 /** |
|
56 * Visual change only, but the change can be handled entirely by |
|
57 * updating the layer(s) for the frame. |
|
58 * Updates all descendants (including following placeholders to out-of-flows). |
|
59 */ |
|
60 nsChangeHint_UpdateOpacityLayer = 0x100, |
|
61 /** |
|
62 * Updates all descendants. Any placeholder descendants' out-of-flows |
|
63 * are also descendants of the transformed frame, so they're updated. |
|
64 */ |
|
65 nsChangeHint_UpdateTransformLayer = 0x200, |
|
66 |
|
67 /** |
|
68 * Change requires frame change (e.g., display:). |
|
69 * This subsumes all the above. Reconstructs all frame descendants, |
|
70 * including following placeholders to out-of-flows. |
|
71 */ |
|
72 nsChangeHint_ReconstructFrame = 0x400, |
|
73 |
|
74 /** |
|
75 * The frame's overflow area has changed, either through a change in its |
|
76 * transform or a change in its position. Does not update any descendant |
|
77 * frames. |
|
78 */ |
|
79 nsChangeHint_UpdateOverflow = 0x800, |
|
80 |
|
81 /** |
|
82 * The frame's overflow area has changed, through a change in its transform. |
|
83 * Does not update any descendant frames. |
|
84 */ |
|
85 nsChangeHint_UpdatePostTransformOverflow = 0x1000, |
|
86 |
|
87 /** |
|
88 * The children-only transform of an SVG frame changed, requiring the |
|
89 * overflow rects of the frame's immediate children to be updated. |
|
90 */ |
|
91 nsChangeHint_ChildrenOnlyTransform = 0x2000, |
|
92 |
|
93 /** |
|
94 * The frame's offsets have changed, while its dimensions might have |
|
95 * changed as well. This hint is used for positioned frames if their |
|
96 * offset changes. If we decide that the dimensions are likely to |
|
97 * change, this will trigger a reflow. |
|
98 * |
|
99 * Note that this should probably be used in combination with |
|
100 * nsChangeHint_UpdateOverflow in order to get the overflow areas of |
|
101 * the ancestors updated as well. |
|
102 */ |
|
103 nsChangeHint_RecomputePosition = 0x4000, |
|
104 |
|
105 /** |
|
106 * Behaves like ReconstructFrame, but only if the frame has descendants |
|
107 * that are absolutely or fixed position. Use this hint when a style change |
|
108 * has changed whether the frame is a container for fixed-pos or abs-pos |
|
109 * elements, but reframing is otherwise not needed. |
|
110 */ |
|
111 nsChangeHint_AddOrRemoveTransform = 0x8000, |
|
112 |
|
113 /** |
|
114 * This change hint has *no* change handling behavior. However, it |
|
115 * exists to be a non-inherited hint, because when the border-style |
|
116 * changes, and it's inherited by a child, that might require a reflow |
|
117 * due to the border-width change on the child. |
|
118 */ |
|
119 nsChangeHint_BorderStyleNoneChange = 0x10000, |
|
120 |
|
121 /** |
|
122 * SVG textPath needs to be recomputed because the path has changed. |
|
123 * This means that the glyph positions of the text need to be recomputed. |
|
124 */ |
|
125 nsChangeHint_UpdateTextPath = 0x20000 |
|
126 |
|
127 // IMPORTANT NOTE: When adding new hints, consider whether you need to |
|
128 // add them to NS_HintsNotHandledForDescendantsIn() below. |
|
129 }; |
|
130 |
|
131 // Redefine these operators to return nothing. This will catch any use |
|
132 // of these operators on hints. We should not be using these operators |
|
133 // on nsChangeHints |
|
134 inline void operator<(nsChangeHint s1, nsChangeHint s2) {} |
|
135 inline void operator>(nsChangeHint s1, nsChangeHint s2) {} |
|
136 inline void operator!=(nsChangeHint s1, nsChangeHint s2) {} |
|
137 inline void operator==(nsChangeHint s1, nsChangeHint s2) {} |
|
138 inline void operator<=(nsChangeHint s1, nsChangeHint s2) {} |
|
139 inline void operator>=(nsChangeHint s1, nsChangeHint s2) {} |
|
140 |
|
141 // Operators on nsChangeHints |
|
142 |
|
143 // Merge two hints, taking the union |
|
144 inline nsChangeHint NS_CombineHint(nsChangeHint aH1, nsChangeHint aH2) { |
|
145 return (nsChangeHint)(aH1 | aH2); |
|
146 } |
|
147 |
|
148 // Merge two hints, taking the union |
|
149 inline nsChangeHint NS_SubtractHint(nsChangeHint aH1, nsChangeHint aH2) { |
|
150 return (nsChangeHint)(aH1 & ~aH2); |
|
151 } |
|
152 |
|
153 // Merge the "src" hint into the "dst" hint |
|
154 // Returns true iff the destination changed |
|
155 inline bool NS_UpdateHint(nsChangeHint& aDest, nsChangeHint aSrc) { |
|
156 nsChangeHint r = (nsChangeHint)(aDest | aSrc); |
|
157 bool changed = (int)r != (int)aDest; |
|
158 aDest = r; |
|
159 return changed; |
|
160 } |
|
161 |
|
162 // Returns true iff the second hint contains all the hints of the first hint |
|
163 inline bool NS_IsHintSubset(nsChangeHint aSubset, nsChangeHint aSuperSet) { |
|
164 return (aSubset & aSuperSet) == aSubset; |
|
165 } |
|
166 |
|
167 /** |
|
168 * We have an optimization when processing change hints which prevents |
|
169 * us from visiting the descendants of a node when a hint on that node |
|
170 * is being processed. This optimization does not apply in some of the |
|
171 * cases where applying a hint to an element does not necessarily result |
|
172 * in the same hint being handled on the descendants. |
|
173 */ |
|
174 |
|
175 // The most hints that NS_HintsNotHandledForDescendantsIn could possibly return: |
|
176 #define nsChangeHint_Hints_NotHandledForDescendants nsChangeHint( \ |
|
177 nsChangeHint_UpdateTransformLayer | \ |
|
178 nsChangeHint_UpdateEffects | \ |
|
179 nsChangeHint_UpdateOpacityLayer | \ |
|
180 nsChangeHint_UpdateOverflow | \ |
|
181 nsChangeHint_UpdatePostTransformOverflow | \ |
|
182 nsChangeHint_ChildrenOnlyTransform | \ |
|
183 nsChangeHint_RecomputePosition | \ |
|
184 nsChangeHint_AddOrRemoveTransform | \ |
|
185 nsChangeHint_BorderStyleNoneChange | \ |
|
186 nsChangeHint_NeedReflow | \ |
|
187 nsChangeHint_ClearAncestorIntrinsics) |
|
188 |
|
189 inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) { |
|
190 nsChangeHint result = nsChangeHint(aChangeHint & ( |
|
191 nsChangeHint_UpdateTransformLayer | |
|
192 nsChangeHint_UpdateEffects | |
|
193 nsChangeHint_UpdateOpacityLayer | |
|
194 nsChangeHint_UpdateOverflow | |
|
195 nsChangeHint_UpdatePostTransformOverflow | |
|
196 nsChangeHint_ChildrenOnlyTransform | |
|
197 nsChangeHint_RecomputePosition | |
|
198 nsChangeHint_AddOrRemoveTransform | |
|
199 nsChangeHint_BorderStyleNoneChange)); |
|
200 |
|
201 if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aChangeHint) && |
|
202 NS_IsHintSubset(nsChangeHint_NeedReflow, aChangeHint)) { |
|
203 // If NeedDirtyReflow is *not* set, then NeedReflow is a |
|
204 // non-inherited hint. |
|
205 NS_UpdateHint(result, nsChangeHint_NeedReflow); |
|
206 } |
|
207 |
|
208 if (!NS_IsHintSubset(nsChangeHint_ClearDescendantIntrinsics, aChangeHint) && |
|
209 NS_IsHintSubset(nsChangeHint_ClearAncestorIntrinsics, aChangeHint)) { |
|
210 // If ClearDescendantIntrinsics is *not* set, then |
|
211 // ClearAncestorIntrinsics is a non-inherited hint. |
|
212 NS_UpdateHint(result, nsChangeHint_ClearAncestorIntrinsics); |
|
213 } |
|
214 |
|
215 NS_ABORT_IF_FALSE(NS_IsHintSubset(result, |
|
216 nsChangeHint_Hints_NotHandledForDescendants), |
|
217 "something is inconsistent"); |
|
218 |
|
219 return result; |
|
220 } |
|
221 |
|
222 // Redefine the old NS_STYLE_HINT constants in terms of the new hint structure |
|
223 #define NS_STYLE_HINT_NONE \ |
|
224 nsChangeHint(0) |
|
225 #define NS_STYLE_HINT_VISUAL \ |
|
226 nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView) |
|
227 #define nsChangeHint_AllReflowHints \ |
|
228 nsChangeHint(nsChangeHint_NeedReflow | \ |
|
229 nsChangeHint_ClearAncestorIntrinsics | \ |
|
230 nsChangeHint_ClearDescendantIntrinsics | \ |
|
231 nsChangeHint_NeedDirtyReflow) |
|
232 #define NS_STYLE_HINT_REFLOW \ |
|
233 nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_AllReflowHints) |
|
234 #define NS_STYLE_HINT_FRAMECHANGE \ |
|
235 nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_ReconstructFrame) |
|
236 |
|
237 /** |
|
238 * |nsRestyleHint| is a bitfield for the result of |
|
239 * |HasStateDependentStyle| and |HasAttributeDependentStyle|. When no |
|
240 * restyling is necessary, use |nsRestyleHint(0)|. |
|
241 */ |
|
242 enum nsRestyleHint { |
|
243 eRestyle_Self = 0x1, |
|
244 eRestyle_Subtree = 0x2, /* self and descendants */ |
|
245 eRestyle_LaterSiblings = 0x4 /* implies "and descendants" */ |
|
246 }; |
|
247 |
|
248 |
|
249 #endif /* nsChangeHint_h___ */ |