layout/base/nsChangeHint.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:4e01d80fb42d
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___ */

mercurial