1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/nsChangeHint.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,249 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* constants for what needs to be recomputed in response to style changes */ 1.10 + 1.11 +#ifndef nsChangeHint_h___ 1.12 +#define nsChangeHint_h___ 1.13 + 1.14 +#include "nsDebug.h" 1.15 + 1.16 +// Defines for various style related constants 1.17 + 1.18 +enum nsChangeHint { 1.19 + // change was visual only (e.g., COLOR=) 1.20 + // Invalidates all descendant frames (including following 1.21 + // placeholders to out-of-flow frames). 1.22 + nsChangeHint_RepaintFrame = 0x01, 1.23 + 1.24 + // For reflow, we want flags to give us arbitrary FrameNeedsReflow behavior. 1.25 + // just do a FrameNeedsReflow. 1.26 + nsChangeHint_NeedReflow = 0x02, 1.27 + 1.28 + // Invalidate intrinsic widths on the frame's ancestors. Must not be set 1.29 + // without setting nsChangeHint_NeedReflow. 1.30 + nsChangeHint_ClearAncestorIntrinsics = 0x04, 1.31 + 1.32 + // Invalidate intrinsic widths on the frame's descendants. Must not be set 1.33 + // without also setting nsChangeHint_ClearAncestorIntrinsics. 1.34 + nsChangeHint_ClearDescendantIntrinsics = 0x08, 1.35 + 1.36 + // Force unconditional reflow of all descendants. Must not be set without 1.37 + // setting nsChangeHint_NeedReflow, but is independent of both the 1.38 + // Clear*Intrinsics flags. 1.39 + nsChangeHint_NeedDirtyReflow = 0x10, 1.40 + 1.41 + // change requires view to be updated, if there is one (e.g., clip:). 1.42 + // Updates all descendants (including following placeholders to out-of-flows). 1.43 + nsChangeHint_SyncFrameView = 0x20, 1.44 + 1.45 + // The currently shown mouse cursor needs to be updated 1.46 + nsChangeHint_UpdateCursor = 0x40, 1.47 + 1.48 + /** 1.49 + * Used when the computed value (a URI) of one or more of an element's 1.50 + * filter/mask/clip/etc CSS properties changes, causing the element's frame 1.51 + * to start/stop referencing (or reference different) SVG resource elements. 1.52 + * (_Not_ used to handle changes to referenced resource elements.) Using this 1.53 + * hint results in nsSVGEffects::UpdateEffects being called on the element's 1.54 + * frame. 1.55 + */ 1.56 + nsChangeHint_UpdateEffects = 0x80, 1.57 + 1.58 + /** 1.59 + * Visual change only, but the change can be handled entirely by 1.60 + * updating the layer(s) for the frame. 1.61 + * Updates all descendants (including following placeholders to out-of-flows). 1.62 + */ 1.63 + nsChangeHint_UpdateOpacityLayer = 0x100, 1.64 + /** 1.65 + * Updates all descendants. Any placeholder descendants' out-of-flows 1.66 + * are also descendants of the transformed frame, so they're updated. 1.67 + */ 1.68 + nsChangeHint_UpdateTransformLayer = 0x200, 1.69 + 1.70 + /** 1.71 + * Change requires frame change (e.g., display:). 1.72 + * This subsumes all the above. Reconstructs all frame descendants, 1.73 + * including following placeholders to out-of-flows. 1.74 + */ 1.75 + nsChangeHint_ReconstructFrame = 0x400, 1.76 + 1.77 + /** 1.78 + * The frame's overflow area has changed, either through a change in its 1.79 + * transform or a change in its position. Does not update any descendant 1.80 + * frames. 1.81 + */ 1.82 + nsChangeHint_UpdateOverflow = 0x800, 1.83 + 1.84 + /** 1.85 + * The frame's overflow area has changed, through a change in its transform. 1.86 + * Does not update any descendant frames. 1.87 + */ 1.88 + nsChangeHint_UpdatePostTransformOverflow = 0x1000, 1.89 + 1.90 + /** 1.91 + * The children-only transform of an SVG frame changed, requiring the 1.92 + * overflow rects of the frame's immediate children to be updated. 1.93 + */ 1.94 + nsChangeHint_ChildrenOnlyTransform = 0x2000, 1.95 + 1.96 + /** 1.97 + * The frame's offsets have changed, while its dimensions might have 1.98 + * changed as well. This hint is used for positioned frames if their 1.99 + * offset changes. If we decide that the dimensions are likely to 1.100 + * change, this will trigger a reflow. 1.101 + * 1.102 + * Note that this should probably be used in combination with 1.103 + * nsChangeHint_UpdateOverflow in order to get the overflow areas of 1.104 + * the ancestors updated as well. 1.105 + */ 1.106 + nsChangeHint_RecomputePosition = 0x4000, 1.107 + 1.108 + /** 1.109 + * Behaves like ReconstructFrame, but only if the frame has descendants 1.110 + * that are absolutely or fixed position. Use this hint when a style change 1.111 + * has changed whether the frame is a container for fixed-pos or abs-pos 1.112 + * elements, but reframing is otherwise not needed. 1.113 + */ 1.114 + nsChangeHint_AddOrRemoveTransform = 0x8000, 1.115 + 1.116 + /** 1.117 + * This change hint has *no* change handling behavior. However, it 1.118 + * exists to be a non-inherited hint, because when the border-style 1.119 + * changes, and it's inherited by a child, that might require a reflow 1.120 + * due to the border-width change on the child. 1.121 + */ 1.122 + nsChangeHint_BorderStyleNoneChange = 0x10000, 1.123 + 1.124 + /** 1.125 + * SVG textPath needs to be recomputed because the path has changed. 1.126 + * This means that the glyph positions of the text need to be recomputed. 1.127 + */ 1.128 + nsChangeHint_UpdateTextPath = 0x20000 1.129 + 1.130 + // IMPORTANT NOTE: When adding new hints, consider whether you need to 1.131 + // add them to NS_HintsNotHandledForDescendantsIn() below. 1.132 +}; 1.133 + 1.134 +// Redefine these operators to return nothing. This will catch any use 1.135 +// of these operators on hints. We should not be using these operators 1.136 +// on nsChangeHints 1.137 +inline void operator<(nsChangeHint s1, nsChangeHint s2) {} 1.138 +inline void operator>(nsChangeHint s1, nsChangeHint s2) {} 1.139 +inline void operator!=(nsChangeHint s1, nsChangeHint s2) {} 1.140 +inline void operator==(nsChangeHint s1, nsChangeHint s2) {} 1.141 +inline void operator<=(nsChangeHint s1, nsChangeHint s2) {} 1.142 +inline void operator>=(nsChangeHint s1, nsChangeHint s2) {} 1.143 + 1.144 +// Operators on nsChangeHints 1.145 + 1.146 +// Merge two hints, taking the union 1.147 +inline nsChangeHint NS_CombineHint(nsChangeHint aH1, nsChangeHint aH2) { 1.148 + return (nsChangeHint)(aH1 | aH2); 1.149 +} 1.150 + 1.151 +// Merge two hints, taking the union 1.152 +inline nsChangeHint NS_SubtractHint(nsChangeHint aH1, nsChangeHint aH2) { 1.153 + return (nsChangeHint)(aH1 & ~aH2); 1.154 +} 1.155 + 1.156 +// Merge the "src" hint into the "dst" hint 1.157 +// Returns true iff the destination changed 1.158 +inline bool NS_UpdateHint(nsChangeHint& aDest, nsChangeHint aSrc) { 1.159 + nsChangeHint r = (nsChangeHint)(aDest | aSrc); 1.160 + bool changed = (int)r != (int)aDest; 1.161 + aDest = r; 1.162 + return changed; 1.163 +} 1.164 + 1.165 +// Returns true iff the second hint contains all the hints of the first hint 1.166 +inline bool NS_IsHintSubset(nsChangeHint aSubset, nsChangeHint aSuperSet) { 1.167 + return (aSubset & aSuperSet) == aSubset; 1.168 +} 1.169 + 1.170 +/** 1.171 + * We have an optimization when processing change hints which prevents 1.172 + * us from visiting the descendants of a node when a hint on that node 1.173 + * is being processed. This optimization does not apply in some of the 1.174 + * cases where applying a hint to an element does not necessarily result 1.175 + * in the same hint being handled on the descendants. 1.176 + */ 1.177 + 1.178 +// The most hints that NS_HintsNotHandledForDescendantsIn could possibly return: 1.179 +#define nsChangeHint_Hints_NotHandledForDescendants nsChangeHint( \ 1.180 + nsChangeHint_UpdateTransformLayer | \ 1.181 + nsChangeHint_UpdateEffects | \ 1.182 + nsChangeHint_UpdateOpacityLayer | \ 1.183 + nsChangeHint_UpdateOverflow | \ 1.184 + nsChangeHint_UpdatePostTransformOverflow | \ 1.185 + nsChangeHint_ChildrenOnlyTransform | \ 1.186 + nsChangeHint_RecomputePosition | \ 1.187 + nsChangeHint_AddOrRemoveTransform | \ 1.188 + nsChangeHint_BorderStyleNoneChange | \ 1.189 + nsChangeHint_NeedReflow | \ 1.190 + nsChangeHint_ClearAncestorIntrinsics) 1.191 + 1.192 +inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) { 1.193 + nsChangeHint result = nsChangeHint(aChangeHint & ( 1.194 + nsChangeHint_UpdateTransformLayer | 1.195 + nsChangeHint_UpdateEffects | 1.196 + nsChangeHint_UpdateOpacityLayer | 1.197 + nsChangeHint_UpdateOverflow | 1.198 + nsChangeHint_UpdatePostTransformOverflow | 1.199 + nsChangeHint_ChildrenOnlyTransform | 1.200 + nsChangeHint_RecomputePosition | 1.201 + nsChangeHint_AddOrRemoveTransform | 1.202 + nsChangeHint_BorderStyleNoneChange)); 1.203 + 1.204 + if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aChangeHint) && 1.205 + NS_IsHintSubset(nsChangeHint_NeedReflow, aChangeHint)) { 1.206 + // If NeedDirtyReflow is *not* set, then NeedReflow is a 1.207 + // non-inherited hint. 1.208 + NS_UpdateHint(result, nsChangeHint_NeedReflow); 1.209 + } 1.210 + 1.211 + if (!NS_IsHintSubset(nsChangeHint_ClearDescendantIntrinsics, aChangeHint) && 1.212 + NS_IsHintSubset(nsChangeHint_ClearAncestorIntrinsics, aChangeHint)) { 1.213 + // If ClearDescendantIntrinsics is *not* set, then 1.214 + // ClearAncestorIntrinsics is a non-inherited hint. 1.215 + NS_UpdateHint(result, nsChangeHint_ClearAncestorIntrinsics); 1.216 + } 1.217 + 1.218 + NS_ABORT_IF_FALSE(NS_IsHintSubset(result, 1.219 + nsChangeHint_Hints_NotHandledForDescendants), 1.220 + "something is inconsistent"); 1.221 + 1.222 + return result; 1.223 +} 1.224 + 1.225 +// Redefine the old NS_STYLE_HINT constants in terms of the new hint structure 1.226 +#define NS_STYLE_HINT_NONE \ 1.227 + nsChangeHint(0) 1.228 +#define NS_STYLE_HINT_VISUAL \ 1.229 + nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView) 1.230 +#define nsChangeHint_AllReflowHints \ 1.231 + nsChangeHint(nsChangeHint_NeedReflow | \ 1.232 + nsChangeHint_ClearAncestorIntrinsics | \ 1.233 + nsChangeHint_ClearDescendantIntrinsics | \ 1.234 + nsChangeHint_NeedDirtyReflow) 1.235 +#define NS_STYLE_HINT_REFLOW \ 1.236 + nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_AllReflowHints) 1.237 +#define NS_STYLE_HINT_FRAMECHANGE \ 1.238 + nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_ReconstructFrame) 1.239 + 1.240 +/** 1.241 + * |nsRestyleHint| is a bitfield for the result of 1.242 + * |HasStateDependentStyle| and |HasAttributeDependentStyle|. When no 1.243 + * restyling is necessary, use |nsRestyleHint(0)|. 1.244 + */ 1.245 +enum nsRestyleHint { 1.246 + eRestyle_Self = 0x1, 1.247 + eRestyle_Subtree = 0x2, /* self and descendants */ 1.248 + eRestyle_LaterSiblings = 0x4 /* implies "and descendants" */ 1.249 +}; 1.250 + 1.251 + 1.252 +#endif /* nsChangeHint_h___ */