layout/base/nsChangeHint.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial