layout/style/nsStyleStruct.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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 /*
michael@0 7 * structs that contain the data provided by nsStyleContext, the
michael@0 8 * internal API for computed style data for an element
michael@0 9 */
michael@0 10
michael@0 11 #ifndef nsStyleStruct_h___
michael@0 12 #define nsStyleStruct_h___
michael@0 13
michael@0 14 #include "mozilla/Attributes.h"
michael@0 15 #include "mozilla/CSSVariableValues.h"
michael@0 16 #include "nsColor.h"
michael@0 17 #include "nsCoord.h"
michael@0 18 #include "nsMargin.h"
michael@0 19 #include "nsRect.h"
michael@0 20 #include "nsFont.h"
michael@0 21 #include "nsStyleCoord.h"
michael@0 22 #include "nsStyleConsts.h"
michael@0 23 #include "nsChangeHint.h"
michael@0 24 #include "nsPresContext.h"
michael@0 25 #include "nsCOMPtr.h"
michael@0 26 #include "nsCOMArray.h"
michael@0 27 #include "nsTArray.h"
michael@0 28 #include "nsIAtom.h"
michael@0 29 #include "nsCSSValue.h"
michael@0 30 #include "imgRequestProxy.h"
michael@0 31 #include "Orientation.h"
michael@0 32 #include <algorithm>
michael@0 33
michael@0 34 class nsIFrame;
michael@0 35 class nsIURI;
michael@0 36 class imgIContainer;
michael@0 37
michael@0 38 // Includes nsStyleStructID.
michael@0 39 #include "nsStyleStructFwd.h"
michael@0 40
michael@0 41 // Bits for each struct.
michael@0 42 // NS_STYLE_INHERIT_BIT defined in nsStyleStructFwd.h
michael@0 43 #define NS_STYLE_INHERIT_MASK 0x000ffffff
michael@0 44
michael@0 45 // Additional bits for nsStyleContext's mBits:
michael@0 46 // See nsStyleContext::HasTextDecorationLines
michael@0 47 #define NS_STYLE_HAS_TEXT_DECORATION_LINES 0x001000000
michael@0 48 // See nsStyleContext::HasPseudoElementData.
michael@0 49 #define NS_STYLE_HAS_PSEUDO_ELEMENT_DATA 0x002000000
michael@0 50 // See nsStyleContext::RelevantLinkIsVisited
michael@0 51 #define NS_STYLE_RELEVANT_LINK_VISITED 0x004000000
michael@0 52 // See nsStyleContext::IsStyleIfVisited
michael@0 53 #define NS_STYLE_IS_STYLE_IF_VISITED 0x008000000
michael@0 54 // See nsStyleContext::GetPseudoEnum
michael@0 55 #define NS_STYLE_CONTEXT_TYPE_MASK 0x1f0000000
michael@0 56 #define NS_STYLE_CONTEXT_TYPE_SHIFT 28
michael@0 57
michael@0 58 // Additional bits for nsRuleNode's mDependentBits:
michael@0 59 #define NS_RULE_NODE_GC_MARK 0x02000000
michael@0 60 #define NS_RULE_NODE_USED_DIRECTLY 0x04000000
michael@0 61 #define NS_RULE_NODE_IS_IMPORTANT 0x08000000
michael@0 62 #define NS_RULE_NODE_LEVEL_MASK 0xf0000000
michael@0 63 #define NS_RULE_NODE_LEVEL_SHIFT 28
michael@0 64
michael@0 65 // The lifetime of these objects is managed by the presshell's arena.
michael@0 66
michael@0 67 struct nsStyleFont {
michael@0 68 nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext);
michael@0 69 nsStyleFont(const nsStyleFont& aStyleFont);
michael@0 70 nsStyleFont(nsPresContext *aPresContext);
michael@0 71 private:
michael@0 72 void Init(nsPresContext *aPresContext);
michael@0 73 public:
michael@0 74 ~nsStyleFont(void) {
michael@0 75 MOZ_COUNT_DTOR(nsStyleFont);
michael@0 76 }
michael@0 77
michael@0 78 nsChangeHint CalcDifference(const nsStyleFont& aOther) const;
michael@0 79 static nsChangeHint MaxDifference() {
michael@0 80 return NS_STYLE_HINT_REFLOW;
michael@0 81 }
michael@0 82 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 83 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 84 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 85 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 86 nsChangeHint_ClearAncestorIntrinsics);
michael@0 87 }
michael@0 88 static nsChangeHint CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
michael@0 89
michael@0 90 static nscoord ZoomText(nsPresContext* aPresContext, nscoord aSize);
michael@0 91 static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
michael@0 92
michael@0 93 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
michael@0 94 void Destroy(nsPresContext* aContext);
michael@0 95
michael@0 96 void EnableZoom(nsPresContext* aContext, bool aEnable);
michael@0 97
michael@0 98 nsFont mFont; // [inherited]
michael@0 99 nscoord mSize; // [inherited] Our "computed size". Can be different
michael@0 100 // from mFont.size which is our "actual size" and is
michael@0 101 // enforced to be >= the user's preferred min-size.
michael@0 102 // mFont.size should be used for display purposes
michael@0 103 // while mSize is the value to return in
michael@0 104 // getComputedStyle() for example.
michael@0 105 uint8_t mGenericID; // [inherited] generic CSS font family, if any;
michael@0 106 // value is a kGenericFont_* constant, see nsFont.h.
michael@0 107
michael@0 108 // MathML scriptlevel support
michael@0 109 int8_t mScriptLevel; // [inherited]
michael@0 110 // MathML mathvariant support
michael@0 111 uint8_t mMathVariant; // [inherited]
michael@0 112 // MathML displaystyle support
michael@0 113 uint8_t mMathDisplay; // [inherited]
michael@0 114
michael@0 115 // was mLanguage set based on a lang attribute in the document?
michael@0 116 bool mExplicitLanguage; // [inherited]
michael@0 117
michael@0 118 // should calls to ZoomText() and UnZoomText() be made to the font
michael@0 119 // size on this nsStyleFont?
michael@0 120 bool mAllowZoom; // [inherited]
michael@0 121
michael@0 122 // The value mSize would have had if scriptminsize had never been applied
michael@0 123 nscoord mScriptUnconstrainedSize;
michael@0 124 nscoord mScriptMinSize; // [inherited] length
michael@0 125 float mScriptSizeMultiplier; // [inherited]
michael@0 126 nsCOMPtr<nsIAtom> mLanguage; // [inherited]
michael@0 127 };
michael@0 128
michael@0 129 struct nsStyleGradientStop {
michael@0 130 nsStyleCoord mLocation; // percent, coord, calc, none
michael@0 131 nscolor mColor;
michael@0 132 };
michael@0 133
michael@0 134 class nsStyleGradient MOZ_FINAL {
michael@0 135 public:
michael@0 136 nsStyleGradient();
michael@0 137 uint8_t mShape; // NS_STYLE_GRADIENT_SHAPE_*
michael@0 138 uint8_t mSize; // NS_STYLE_GRADIENT_SIZE_*;
michael@0 139 // not used (must be FARTHEST_CORNER) for linear shape
michael@0 140 bool mRepeating;
michael@0 141 bool mLegacySyntax;
michael@0 142
michael@0 143 nsStyleCoord mBgPosX; // percent, coord, calc, none
michael@0 144 nsStyleCoord mBgPosY; // percent, coord, calc, none
michael@0 145 nsStyleCoord mAngle; // none, angle
michael@0 146
michael@0 147 nsStyleCoord mRadiusX; // percent, coord, calc, none
michael@0 148 nsStyleCoord mRadiusY; // percent, coord, calc, none
michael@0 149
michael@0 150 // stops are in the order specified in the stylesheet
michael@0 151 nsTArray<nsStyleGradientStop> mStops;
michael@0 152
michael@0 153 bool operator==(const nsStyleGradient& aOther) const;
michael@0 154 bool operator!=(const nsStyleGradient& aOther) const {
michael@0 155 return !(*this == aOther);
michael@0 156 }
michael@0 157
michael@0 158 bool IsOpaque();
michael@0 159 bool HasCalc();
michael@0 160 uint32_t Hash(PLDHashNumber aHash);
michael@0 161
michael@0 162 NS_INLINE_DECL_REFCOUNTING(nsStyleGradient)
michael@0 163
michael@0 164 private:
michael@0 165 // Private destructor, to discourage deletion outside of Release():
michael@0 166 ~nsStyleGradient() {}
michael@0 167
michael@0 168 nsStyleGradient(const nsStyleGradient& aOther) MOZ_DELETE;
michael@0 169 nsStyleGradient& operator=(const nsStyleGradient& aOther) MOZ_DELETE;
michael@0 170 };
michael@0 171
michael@0 172 enum nsStyleImageType {
michael@0 173 eStyleImageType_Null,
michael@0 174 eStyleImageType_Image,
michael@0 175 eStyleImageType_Gradient,
michael@0 176 eStyleImageType_Element
michael@0 177 };
michael@0 178
michael@0 179 /**
michael@0 180 * Represents a paintable image of one of the following types.
michael@0 181 * (1) A real image loaded from an external source.
michael@0 182 * (2) A CSS linear or radial gradient.
michael@0 183 * (3) An element within a document, or an <img>, <video>, or <canvas> element
michael@0 184 * not in a document.
michael@0 185 * (*) Optionally a crop rect can be set to paint a partial (rectangular)
michael@0 186 * region of an image. (Currently, this feature is only supported with an
michael@0 187 * image of type (1)).
michael@0 188 */
michael@0 189 struct nsStyleImage {
michael@0 190 nsStyleImage();
michael@0 191 ~nsStyleImage();
michael@0 192 nsStyleImage(const nsStyleImage& aOther);
michael@0 193 nsStyleImage& operator=(const nsStyleImage& aOther);
michael@0 194
michael@0 195 void SetNull();
michael@0 196 void SetImageData(imgIRequest* aImage);
michael@0 197 void TrackImage(nsPresContext* aContext);
michael@0 198 void UntrackImage(nsPresContext* aContext);
michael@0 199 void SetGradientData(nsStyleGradient* aGradient);
michael@0 200 void SetElementId(const char16_t* aElementId);
michael@0 201 void SetCropRect(nsStyleSides* aCropRect);
michael@0 202
michael@0 203 nsStyleImageType GetType() const {
michael@0 204 return mType;
michael@0 205 }
michael@0 206 imgIRequest* GetImageData() const {
michael@0 207 NS_ABORT_IF_FALSE(mType == eStyleImageType_Image, "Data is not an image!");
michael@0 208 NS_ABORT_IF_FALSE(mImageTracked,
michael@0 209 "Should be tracking any image we're going to use!");
michael@0 210 return mImage;
michael@0 211 }
michael@0 212 nsStyleGradient* GetGradientData() const {
michael@0 213 NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
michael@0 214 return mGradient;
michael@0 215 }
michael@0 216 const char16_t* GetElementId() const {
michael@0 217 NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
michael@0 218 return mElementId;
michael@0 219 }
michael@0 220 nsStyleSides* GetCropRect() const {
michael@0 221 NS_ASSERTION(mType == eStyleImageType_Image,
michael@0 222 "Only image data can have a crop rect");
michael@0 223 return mCropRect;
michael@0 224 }
michael@0 225
michael@0 226 /**
michael@0 227 * Compute the actual crop rect in pixels, using the source image bounds.
michael@0 228 * The computation involves converting percentage unit to pixel unit and
michael@0 229 * clamping each side value to fit in the source image bounds.
michael@0 230 * @param aActualCropRect the computed actual crop rect.
michael@0 231 * @param aIsEntireImage true iff |aActualCropRect| is identical to the
michael@0 232 * source image bounds.
michael@0 233 * @return true iff |aActualCropRect| holds a meaningful value.
michael@0 234 */
michael@0 235 bool ComputeActualCropRect(nsIntRect& aActualCropRect,
michael@0 236 bool* aIsEntireImage = nullptr) const;
michael@0 237
michael@0 238 /**
michael@0 239 * Starts the decoding of a image.
michael@0 240 */
michael@0 241 nsresult StartDecoding() const;
michael@0 242 /**
michael@0 243 * @return true if the item is definitely opaque --- i.e., paints every
michael@0 244 * pixel within its bounds opaquely, and the bounds contains at least a pixel.
michael@0 245 */
michael@0 246 bool IsOpaque() const;
michael@0 247 /**
michael@0 248 * @return true if this image is fully loaded, and its size is calculated;
michael@0 249 * always returns true if |mType| is |eStyleImageType_Gradient| or
michael@0 250 * |eStyleImageType_Element|.
michael@0 251 */
michael@0 252 bool IsComplete() const;
michael@0 253 /**
michael@0 254 * @return true if this image is loaded without error;
michael@0 255 * always returns true if |mType| is |eStyleImageType_Gradient| or
michael@0 256 * |eStyleImageType_Element|.
michael@0 257 */
michael@0 258 bool IsLoaded() const;
michael@0 259 /**
michael@0 260 * @return true if it is 100% confident that this image contains no pixel
michael@0 261 * to draw.
michael@0 262 */
michael@0 263 bool IsEmpty() const {
michael@0 264 // There are some other cases when the image will be empty, for example
michael@0 265 // when the crop rect is empty. However, checking the emptiness of crop
michael@0 266 // rect is non-trivial since each side value can be specified with
michael@0 267 // percentage unit, which can not be evaluated until the source image size
michael@0 268 // is available. Therefore, we currently postpone the evaluation of crop
michael@0 269 // rect until the actual rendering time --- alternatively until GetOpaqueRegion()
michael@0 270 // is called.
michael@0 271 return mType == eStyleImageType_Null;
michael@0 272 }
michael@0 273
michael@0 274 bool operator==(const nsStyleImage& aOther) const;
michael@0 275 bool operator!=(const nsStyleImage& aOther) const {
michael@0 276 return !(*this == aOther);
michael@0 277 }
michael@0 278
michael@0 279 bool ImageDataEquals(const nsStyleImage& aOther) const
michael@0 280 {
michael@0 281 return GetType() == eStyleImageType_Image &&
michael@0 282 aOther.GetType() == eStyleImageType_Image &&
michael@0 283 GetImageData() == aOther.GetImageData();
michael@0 284 }
michael@0 285
michael@0 286 // These methods are used for the caller to caches the sub images created
michael@0 287 // during a border-image paint operation
michael@0 288 inline void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) const;
michael@0 289 inline imgIContainer* GetSubImage(uint8_t aIndex) const;
michael@0 290
michael@0 291 private:
michael@0 292 void DoCopy(const nsStyleImage& aOther);
michael@0 293
michael@0 294 // Cache for border-image painting.
michael@0 295 nsCOMArray<imgIContainer> mSubImages;
michael@0 296
michael@0 297 nsStyleImageType mType;
michael@0 298 union {
michael@0 299 imgIRequest* mImage;
michael@0 300 nsStyleGradient* mGradient;
michael@0 301 char16_t* mElementId;
michael@0 302 };
michael@0 303 // This is _currently_ used only in conjunction with eStyleImageType_Image.
michael@0 304 nsAutoPtr<nsStyleSides> mCropRect;
michael@0 305 #ifdef DEBUG
michael@0 306 bool mImageTracked;
michael@0 307 #endif
michael@0 308 };
michael@0 309
michael@0 310 struct nsStyleColor {
michael@0 311 nsStyleColor(nsPresContext* aPresContext);
michael@0 312 nsStyleColor(const nsStyleColor& aOther);
michael@0 313 ~nsStyleColor(void) {
michael@0 314 MOZ_COUNT_DTOR(nsStyleColor);
michael@0 315 }
michael@0 316
michael@0 317 nsChangeHint CalcDifference(const nsStyleColor& aOther) const;
michael@0 318 static nsChangeHint MaxDifference() {
michael@0 319 return NS_STYLE_HINT_VISUAL;
michael@0 320 }
michael@0 321 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 322 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 323 // nsChangeHint_ClearAncestorIntrinsics at all.
michael@0 324 return nsChangeHint(0);
michael@0 325 }
michael@0 326
michael@0 327 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 328 return aContext->AllocateFromShell(sz);
michael@0 329 }
michael@0 330 void Destroy(nsPresContext* aContext) {
michael@0 331 this->~nsStyleColor();
michael@0 332 aContext->FreeToShell(sizeof(nsStyleColor), this);
michael@0 333 }
michael@0 334
michael@0 335 // Don't add ANY members to this struct! We can achieve caching in the rule
michael@0 336 // tree (rather than the style tree) by letting color stay by itself! -dwh
michael@0 337 nscolor mColor; // [inherited]
michael@0 338 };
michael@0 339
michael@0 340 struct nsStyleBackground {
michael@0 341 nsStyleBackground();
michael@0 342 nsStyleBackground(const nsStyleBackground& aOther);
michael@0 343 ~nsStyleBackground();
michael@0 344
michael@0 345 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 346 return aContext->AllocateFromShell(sz);
michael@0 347 }
michael@0 348 void Destroy(nsPresContext* aContext);
michael@0 349
michael@0 350 nsChangeHint CalcDifference(const nsStyleBackground& aOther) const;
michael@0 351 static nsChangeHint MaxDifference() {
michael@0 352 return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
michael@0 353 }
michael@0 354 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 355 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 356 // nsChangeHint_ClearAncestorIntrinsics at all.
michael@0 357 return nsChangeHint(0);
michael@0 358 }
michael@0 359
michael@0 360 struct Position;
michael@0 361 friend struct Position;
michael@0 362 struct Position {
michael@0 363 typedef nsStyleCoord::Calc PositionCoord;
michael@0 364 PositionCoord mXPosition, mYPosition;
michael@0 365
michael@0 366 // Initialize nothing
michael@0 367 Position() {}
michael@0 368
michael@0 369 // Initialize to initial values
michael@0 370 void SetInitialValues();
michael@0 371
michael@0 372 // True if the effective background image position described by this depends
michael@0 373 // on the size of the corresponding frame.
michael@0 374 bool DependsOnPositioningAreaSize() const {
michael@0 375 return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
michael@0 376 }
michael@0 377
michael@0 378 bool operator==(const Position& aOther) const {
michael@0 379 return mXPosition == aOther.mXPosition &&
michael@0 380 mYPosition == aOther.mYPosition;
michael@0 381 }
michael@0 382 bool operator!=(const Position& aOther) const {
michael@0 383 return !(*this == aOther);
michael@0 384 }
michael@0 385 };
michael@0 386
michael@0 387 struct Size;
michael@0 388 friend struct Size;
michael@0 389 struct Size {
michael@0 390 struct Dimension : public nsStyleCoord::Calc {
michael@0 391 nscoord ResolveLengthPercentage(nscoord aAvailable) const {
michael@0 392 double d = double(mPercent) * double(aAvailable) + double(mLength);
michael@0 393 if (d < 0.0)
michael@0 394 return 0;
michael@0 395 return NSToCoordRoundWithClamp(float(d));
michael@0 396 }
michael@0 397 };
michael@0 398 Dimension mWidth, mHeight;
michael@0 399
michael@0 400 nscoord ResolveWidthLengthPercentage(const nsSize& aBgPositioningArea) const {
michael@0 401 NS_ABORT_IF_FALSE(mWidthType == eLengthPercentage,
michael@0 402 "resolving non-length/percent dimension!");
michael@0 403 return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
michael@0 404 }
michael@0 405
michael@0 406 nscoord ResolveHeightLengthPercentage(const nsSize& aBgPositioningArea) const {
michael@0 407 NS_ABORT_IF_FALSE(mHeightType == eLengthPercentage,
michael@0 408 "resolving non-length/percent dimension!");
michael@0 409 return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
michael@0 410 }
michael@0 411
michael@0 412 // Except for eLengthPercentage, Dimension types which might change
michael@0 413 // how a layer is painted when the corresponding frame's dimensions
michael@0 414 // change *must* precede all dimension types which are agnostic to
michael@0 415 // frame size; see DependsOnDependsOnPositioningAreaSizeSize.
michael@0 416 enum DimensionType {
michael@0 417 // If one of mWidth and mHeight is eContain or eCover, then both are.
michael@0 418 // Also, these two values must equal the corresponding values in
michael@0 419 // kBackgroundSizeKTable.
michael@0 420 eContain, eCover,
michael@0 421
michael@0 422 eAuto,
michael@0 423 eLengthPercentage,
michael@0 424 eDimensionType_COUNT
michael@0 425 };
michael@0 426 uint8_t mWidthType, mHeightType;
michael@0 427
michael@0 428 // True if the effective image size described by this depends on the size of
michael@0 429 // the corresponding frame, when aImage (which must not have null type) is
michael@0 430 // the background image.
michael@0 431 bool DependsOnPositioningAreaSize(const nsStyleImage& aImage) const;
michael@0 432
michael@0 433 // Initialize nothing
michael@0 434 Size() {}
michael@0 435
michael@0 436 // Initialize to initial values
michael@0 437 void SetInitialValues();
michael@0 438
michael@0 439 bool operator==(const Size& aOther) const;
michael@0 440 bool operator!=(const Size& aOther) const {
michael@0 441 return !(*this == aOther);
michael@0 442 }
michael@0 443 };
michael@0 444
michael@0 445 struct Repeat;
michael@0 446 friend struct Repeat;
michael@0 447 struct Repeat {
michael@0 448 uint8_t mXRepeat, mYRepeat;
michael@0 449
michael@0 450 // Initialize nothing
michael@0 451 Repeat() {}
michael@0 452
michael@0 453 // Initialize to initial values
michael@0 454 void SetInitialValues();
michael@0 455
michael@0 456 bool operator==(const Repeat& aOther) const {
michael@0 457 return mXRepeat == aOther.mXRepeat &&
michael@0 458 mYRepeat == aOther.mYRepeat;
michael@0 459 }
michael@0 460 bool operator!=(const Repeat& aOther) const {
michael@0 461 return !(*this == aOther);
michael@0 462 }
michael@0 463 };
michael@0 464
michael@0 465 struct Layer;
michael@0 466 friend struct Layer;
michael@0 467 struct Layer {
michael@0 468 uint8_t mAttachment; // [reset] See nsStyleConsts.h
michael@0 469 uint8_t mClip; // [reset] See nsStyleConsts.h
michael@0 470 uint8_t mOrigin; // [reset] See nsStyleConsts.h
michael@0 471 uint8_t mBlendMode; // [reset] See nsStyleConsts.h
michael@0 472 Repeat mRepeat; // [reset] See nsStyleConsts.h
michael@0 473 Position mPosition; // [reset]
michael@0 474 nsStyleImage mImage; // [reset]
michael@0 475 Size mSize; // [reset]
michael@0 476
michael@0 477 // Initializes only mImage
michael@0 478 Layer();
michael@0 479 ~Layer();
michael@0 480
michael@0 481 // Register/unregister images with the document. We do this only
michael@0 482 // after the dust has settled in ComputeBackgroundData.
michael@0 483 void TrackImages(nsPresContext* aContext) {
michael@0 484 if (mImage.GetType() == eStyleImageType_Image)
michael@0 485 mImage.TrackImage(aContext);
michael@0 486 }
michael@0 487 void UntrackImages(nsPresContext* aContext) {
michael@0 488 if (mImage.GetType() == eStyleImageType_Image)
michael@0 489 mImage.UntrackImage(aContext);
michael@0 490 }
michael@0 491
michael@0 492 void SetInitialValues();
michael@0 493
michael@0 494 // True if the rendering of this layer might change when the size
michael@0 495 // of the background positioning area changes. This is true for any
michael@0 496 // non-solid-color background whose position or size depends on
michael@0 497 // the size of the positioning area. It's also true for SVG images
michael@0 498 // whose root <svg> node has a viewBox.
michael@0 499 bool RenderingMightDependOnPositioningAreaSizeChange() const;
michael@0 500
michael@0 501 // An equality operator that compares the images using URL-equality
michael@0 502 // rather than pointer-equality.
michael@0 503 bool operator==(const Layer& aOther) const;
michael@0 504 bool operator!=(const Layer& aOther) const {
michael@0 505 return !(*this == aOther);
michael@0 506 }
michael@0 507 };
michael@0 508
michael@0 509 // The (positive) number of computed values of each property, since
michael@0 510 // the lengths of the lists are independent.
michael@0 511 uint32_t mAttachmentCount,
michael@0 512 mClipCount,
michael@0 513 mOriginCount,
michael@0 514 mRepeatCount,
michael@0 515 mPositionCount,
michael@0 516 mImageCount,
michael@0 517 mSizeCount,
michael@0 518 mBlendModeCount;
michael@0 519 // Layers are stored in an array, matching the top-to-bottom order in
michael@0 520 // which they are specified in CSS. The number of layers to be used
michael@0 521 // should come from the background-image property. We create
michael@0 522 // additional |Layer| objects for *any* property, not just
michael@0 523 // background-image. This means that the bottommost layer that
michael@0 524 // callers in layout care about (which is also the one whose
michael@0 525 // background-clip applies to the background-color) may not be last
michael@0 526 // layer. In layers below the bottom layer, properties will be
michael@0 527 // uninitialized unless their count, above, indicates that they are
michael@0 528 // present.
michael@0 529 nsAutoTArray<Layer, 1> mLayers;
michael@0 530
michael@0 531 const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
michael@0 532
michael@0 533 #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
michael@0 534 for (uint32_t var_ = (stylebg_) ? (stylebg_)->mImageCount : 1; var_-- != 0; )
michael@0 535 #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, stylebg_, start_, count_) \
michael@0 536 NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < ((stylebg_) ? (stylebg_)->mImageCount : 1), "Invalid layer start!"); \
michael@0 537 NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
michael@0 538 for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
michael@0 539
michael@0 540 nscolor mBackgroundColor; // [reset]
michael@0 541
michael@0 542 // FIXME: This (now background-break in css3-background) should
michael@0 543 // probably move into a different struct so that everything in
michael@0 544 // nsStyleBackground is set by the background shorthand.
michael@0 545 uint8_t mBackgroundInlinePolicy; // [reset] See nsStyleConsts.h
michael@0 546
michael@0 547 // True if this background is completely transparent.
michael@0 548 bool IsTransparent() const;
michael@0 549
michael@0 550 // We have to take slower codepaths for fixed background attachment,
michael@0 551 // but we don't want to do that when there's no image.
michael@0 552 // Not inline because it uses an nsCOMPtr<imgIRequest>
michael@0 553 // FIXME: Should be in nsStyleStructInlines.h.
michael@0 554 bool HasFixedBackground() const;
michael@0 555 };
michael@0 556
michael@0 557 // See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
michael@0 558 // this is hard to replace with 'currentColor'.
michael@0 559 #define BORDER_COLOR_FOREGROUND 0x20
michael@0 560 #define OUTLINE_COLOR_INITIAL 0x80
michael@0 561 // FOREGROUND | INITIAL(OUTLINE)
michael@0 562 #define BORDER_COLOR_SPECIAL 0xA0
michael@0 563 #define BORDER_STYLE_MASK 0x1F
michael@0 564
michael@0 565 #define NS_SPACING_MARGIN 0
michael@0 566 #define NS_SPACING_PADDING 1
michael@0 567 #define NS_SPACING_BORDER 2
michael@0 568
michael@0 569
michael@0 570 struct nsStyleMargin {
michael@0 571 nsStyleMargin(void);
michael@0 572 nsStyleMargin(const nsStyleMargin& aMargin);
michael@0 573 ~nsStyleMargin(void) {
michael@0 574 MOZ_COUNT_DTOR(nsStyleMargin);
michael@0 575 }
michael@0 576
michael@0 577 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
michael@0 578 void Destroy(nsPresContext* aContext);
michael@0 579
michael@0 580 void RecalcData();
michael@0 581 nsChangeHint CalcDifference(const nsStyleMargin& aOther) const;
michael@0 582 static nsChangeHint MaxDifference() {
michael@0 583 return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
michael@0 584 NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
michael@0 585 nsChangeHint_NeedDirtyReflow));
michael@0 586 }
michael@0 587 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 588 // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and
michael@0 589 // nsChangeHint_NeedReflow as inherited hints.
michael@0 590 return nsChangeHint(0);
michael@0 591 }
michael@0 592
michael@0 593 nsStyleSides mMargin; // [reset] coord, percent, calc, auto
michael@0 594
michael@0 595 bool IsWidthDependent() const { return !mHasCachedMargin; }
michael@0 596 bool GetMargin(nsMargin& aMargin) const
michael@0 597 {
michael@0 598 if (mHasCachedMargin) {
michael@0 599 aMargin = mCachedMargin;
michael@0 600 return true;
michael@0 601 }
michael@0 602 return false;
michael@0 603 }
michael@0 604
michael@0 605 protected:
michael@0 606 bool mHasCachedMargin;
michael@0 607 nsMargin mCachedMargin;
michael@0 608 };
michael@0 609
michael@0 610
michael@0 611 struct nsStylePadding {
michael@0 612 nsStylePadding(void);
michael@0 613 nsStylePadding(const nsStylePadding& aPadding);
michael@0 614 ~nsStylePadding(void) {
michael@0 615 MOZ_COUNT_DTOR(nsStylePadding);
michael@0 616 }
michael@0 617
michael@0 618 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
michael@0 619 void Destroy(nsPresContext* aContext);
michael@0 620
michael@0 621 void RecalcData();
michael@0 622 nsChangeHint CalcDifference(const nsStylePadding& aOther) const;
michael@0 623 static nsChangeHint MaxDifference() {
michael@0 624 return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
michael@0 625 nsChangeHint_ClearDescendantIntrinsics);
michael@0 626 }
michael@0 627 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 628 // CalcDifference can return nsChangeHint_ClearAncestorIntrinsics as an
michael@0 629 // inherited hint.
michael@0 630 return nsChangeHint(0);
michael@0 631 }
michael@0 632
michael@0 633 nsStyleSides mPadding; // [reset] coord, percent, calc
michael@0 634
michael@0 635 bool IsWidthDependent() const { return !mHasCachedPadding; }
michael@0 636 bool GetPadding(nsMargin& aPadding) const
michael@0 637 {
michael@0 638 if (mHasCachedPadding) {
michael@0 639 aPadding = mCachedPadding;
michael@0 640 return true;
michael@0 641 }
michael@0 642 return false;
michael@0 643 }
michael@0 644
michael@0 645 protected:
michael@0 646 bool mHasCachedPadding;
michael@0 647 nsMargin mCachedPadding;
michael@0 648 };
michael@0 649
michael@0 650 struct nsBorderColors {
michael@0 651 nsBorderColors* mNext;
michael@0 652 nscolor mColor;
michael@0 653
michael@0 654 nsBorderColors() : mNext(nullptr), mColor(NS_RGB(0,0,0)) {}
michael@0 655 nsBorderColors(const nscolor& aColor) : mNext(nullptr), mColor(aColor) {}
michael@0 656 ~nsBorderColors();
michael@0 657
michael@0 658 nsBorderColors* Clone() const { return Clone(true); }
michael@0 659
michael@0 660 static bool Equal(const nsBorderColors* c1,
michael@0 661 const nsBorderColors* c2) {
michael@0 662 if (c1 == c2)
michael@0 663 return true;
michael@0 664 while (c1 && c2) {
michael@0 665 if (c1->mColor != c2->mColor)
michael@0 666 return false;
michael@0 667 c1 = c1->mNext;
michael@0 668 c2 = c2->mNext;
michael@0 669 }
michael@0 670 // both should be nullptr if these are equal, otherwise one
michael@0 671 // has more colors than another
michael@0 672 return !c1 && !c2;
michael@0 673 }
michael@0 674
michael@0 675 private:
michael@0 676 nsBorderColors* Clone(bool aDeep) const;
michael@0 677 };
michael@0 678
michael@0 679 struct nsCSSShadowItem {
michael@0 680 nscoord mXOffset;
michael@0 681 nscoord mYOffset;
michael@0 682 nscoord mRadius;
michael@0 683 nscoord mSpread;
michael@0 684
michael@0 685 nscolor mColor;
michael@0 686 bool mHasColor; // Whether mColor should be used
michael@0 687 bool mInset;
michael@0 688
michael@0 689 nsCSSShadowItem() : mHasColor(false) {
michael@0 690 MOZ_COUNT_CTOR(nsCSSShadowItem);
michael@0 691 }
michael@0 692 ~nsCSSShadowItem() {
michael@0 693 MOZ_COUNT_DTOR(nsCSSShadowItem);
michael@0 694 }
michael@0 695
michael@0 696 bool operator==(const nsCSSShadowItem& aOther) const {
michael@0 697 return (mXOffset == aOther.mXOffset &&
michael@0 698 mYOffset == aOther.mYOffset &&
michael@0 699 mRadius == aOther.mRadius &&
michael@0 700 mHasColor == aOther.mHasColor &&
michael@0 701 mSpread == aOther.mSpread &&
michael@0 702 mInset == aOther.mInset &&
michael@0 703 (!mHasColor || mColor == aOther.mColor));
michael@0 704 }
michael@0 705 bool operator!=(const nsCSSShadowItem& aOther) const {
michael@0 706 return !(*this == aOther);
michael@0 707 }
michael@0 708 };
michael@0 709
michael@0 710 class nsCSSShadowArray MOZ_FINAL {
michael@0 711 public:
michael@0 712 void* operator new(size_t aBaseSize, uint32_t aArrayLen) {
michael@0 713 // We can allocate both this nsCSSShadowArray and the
michael@0 714 // actual array in one allocation. The amount of memory to
michael@0 715 // allocate is equal to the class's size + the number of bytes for all
michael@0 716 // but the first array item (because aBaseSize includes one
michael@0 717 // item, see the private declarations)
michael@0 718 return ::operator new(aBaseSize +
michael@0 719 (aArrayLen - 1) * sizeof(nsCSSShadowItem));
michael@0 720 }
michael@0 721
michael@0 722 nsCSSShadowArray(uint32_t aArrayLen) :
michael@0 723 mLength(aArrayLen)
michael@0 724 {
michael@0 725 MOZ_COUNT_CTOR(nsCSSShadowArray);
michael@0 726 for (uint32_t i = 1; i < mLength; ++i) {
michael@0 727 // Make sure we call the constructors of each nsCSSShadowItem
michael@0 728 // (the first one is called for us because we declared it under private)
michael@0 729 new (&mArray[i]) nsCSSShadowItem();
michael@0 730 }
michael@0 731 }
michael@0 732
michael@0 733 private:
michael@0 734 // Private destructor, to discourage deletion outside of Release():
michael@0 735 ~nsCSSShadowArray() {
michael@0 736 MOZ_COUNT_DTOR(nsCSSShadowArray);
michael@0 737 for (uint32_t i = 1; i < mLength; ++i) {
michael@0 738 mArray[i].~nsCSSShadowItem();
michael@0 739 }
michael@0 740 }
michael@0 741
michael@0 742 public:
michael@0 743 uint32_t Length() const { return mLength; }
michael@0 744 nsCSSShadowItem* ShadowAt(uint32_t i) {
michael@0 745 NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
michael@0 746 return &mArray[i];
michael@0 747 }
michael@0 748 const nsCSSShadowItem* ShadowAt(uint32_t i) const {
michael@0 749 NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
michael@0 750 return &mArray[i];
michael@0 751 }
michael@0 752
michael@0 753 bool HasShadowWithInset(bool aInset) {
michael@0 754 for (uint32_t i = 0; i < mLength; ++i) {
michael@0 755 if (mArray[i].mInset == aInset)
michael@0 756 return true;
michael@0 757 }
michael@0 758 return false;
michael@0 759 }
michael@0 760
michael@0 761 bool operator==(const nsCSSShadowArray& aOther) const {
michael@0 762 if (mLength != aOther.Length())
michael@0 763 return false;
michael@0 764
michael@0 765 for (uint32_t i = 0; i < mLength; ++i) {
michael@0 766 if (ShadowAt(i) != aOther.ShadowAt(i))
michael@0 767 return false;
michael@0 768 }
michael@0 769
michael@0 770 return true;
michael@0 771 }
michael@0 772
michael@0 773 NS_INLINE_DECL_REFCOUNTING(nsCSSShadowArray)
michael@0 774
michael@0 775 private:
michael@0 776 uint32_t mLength;
michael@0 777 nsCSSShadowItem mArray[1]; // This MUST be the last item
michael@0 778 };
michael@0 779
michael@0 780 // Border widths are rounded to the nearest-below integer number of pixels,
michael@0 781 // but values between zero and one device pixels are always rounded up to
michael@0 782 // one device pixel.
michael@0 783 #define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
michael@0 784 ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
michael@0 785 // Outline offset is rounded to the nearest integer number of pixels, but values
michael@0 786 // between zero and one device pixels are always rounded up to one device pixel.
michael@0 787 // Note that the offset can be negative.
michael@0 788 #define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
michael@0 789 (((l) == 0) ? 0 : \
michael@0 790 ((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
michael@0 791 std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
michael@0 792
michael@0 793 // Returns if the given border style type is visible or not
michael@0 794 static bool IsVisibleBorderStyle(uint8_t aStyle)
michael@0 795 {
michael@0 796 return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
michael@0 797 aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
michael@0 798 }
michael@0 799
michael@0 800 struct nsStyleBorder {
michael@0 801 nsStyleBorder(nsPresContext* aContext);
michael@0 802 nsStyleBorder(const nsStyleBorder& aBorder);
michael@0 803 ~nsStyleBorder();
michael@0 804
michael@0 805 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
michael@0 806 void Destroy(nsPresContext* aContext);
michael@0 807
michael@0 808 nsChangeHint CalcDifference(const nsStyleBorder& aOther) const;
michael@0 809 static nsChangeHint MaxDifference() {
michael@0 810 return NS_CombineHint(NS_STYLE_HINT_REFLOW,
michael@0 811 nsChangeHint_BorderStyleNoneChange);
michael@0 812 }
michael@0 813 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 814 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 815 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 816 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 817 nsChangeHint_ClearAncestorIntrinsics);
michael@0 818 }
michael@0 819
michael@0 820 void EnsureBorderColors() {
michael@0 821 if (!mBorderColors) {
michael@0 822 mBorderColors = new nsBorderColors*[4];
michael@0 823 if (mBorderColors)
michael@0 824 for (int32_t i = 0; i < 4; i++)
michael@0 825 mBorderColors[i] = nullptr;
michael@0 826 }
michael@0 827 }
michael@0 828
michael@0 829 void ClearBorderColors(mozilla::css::Side aSide) {
michael@0 830 if (mBorderColors && mBorderColors[aSide]) {
michael@0 831 delete mBorderColors[aSide];
michael@0 832 mBorderColors[aSide] = nullptr;
michael@0 833 }
michael@0 834 }
michael@0 835
michael@0 836 // Return whether aStyle is a visible style. Invisible styles cause
michael@0 837 // the relevant computed border width to be 0.
michael@0 838 // Note that this does *not* consider the effects of 'border-image':
michael@0 839 // if border-style is none, but there is a loaded border image,
michael@0 840 // HasVisibleStyle will be false even though there *is* a border.
michael@0 841 bool HasVisibleStyle(mozilla::css::Side aSide) const
michael@0 842 {
michael@0 843 return IsVisibleBorderStyle(GetBorderStyle(aSide));
michael@0 844 }
michael@0 845
michael@0 846 // aBorderWidth is in twips
michael@0 847 void SetBorderWidth(mozilla::css::Side aSide, nscoord aBorderWidth)
michael@0 848 {
michael@0 849 nscoord roundedWidth =
michael@0 850 NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
michael@0 851 mBorder.Side(aSide) = roundedWidth;
michael@0 852 if (HasVisibleStyle(aSide))
michael@0 853 mComputedBorder.Side(aSide) = roundedWidth;
michael@0 854 }
michael@0 855
michael@0 856 // Get the computed border (plus rounding). This does consider the
michael@0 857 // effects of 'border-style: none', but does not consider
michael@0 858 // 'border-image'.
michael@0 859 const nsMargin& GetComputedBorder() const
michael@0 860 {
michael@0 861 return mComputedBorder;
michael@0 862 }
michael@0 863
michael@0 864 bool HasBorder() const
michael@0 865 {
michael@0 866 return mComputedBorder != nsMargin(0,0,0,0) || !mBorderImageSource.IsEmpty();
michael@0 867 }
michael@0 868
michael@0 869 // Get the actual border width for a particular side, in appunits. Note that
michael@0 870 // this is zero if and only if there is no border to be painted for this
michael@0 871 // side. That is, this value takes into account the border style and the
michael@0 872 // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
michael@0 873 nscoord GetComputedBorderWidth(mozilla::css::Side aSide) const
michael@0 874 {
michael@0 875 return GetComputedBorder().Side(aSide);
michael@0 876 }
michael@0 877
michael@0 878 uint8_t GetBorderStyle(mozilla::css::Side aSide) const
michael@0 879 {
michael@0 880 NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
michael@0 881 return (mBorderStyle[aSide] & BORDER_STYLE_MASK);
michael@0 882 }
michael@0 883
michael@0 884 void SetBorderStyle(mozilla::css::Side aSide, uint8_t aStyle)
michael@0 885 {
michael@0 886 NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
michael@0 887 mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
michael@0 888 mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
michael@0 889 mComputedBorder.Side(aSide) =
michael@0 890 (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
michael@0 891 }
michael@0 892
michael@0 893 inline bool IsBorderImageLoaded() const
michael@0 894 {
michael@0 895 return mBorderImageSource.IsLoaded();
michael@0 896 }
michael@0 897
michael@0 898 // Defined in nsStyleStructInlines.h
michael@0 899 inline nsresult RequestDecode();
michael@0 900
michael@0 901 void GetBorderColor(mozilla::css::Side aSide, nscolor& aColor,
michael@0 902 bool& aForeground) const
michael@0 903 {
michael@0 904 aForeground = false;
michael@0 905 NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
michael@0 906 if ((mBorderStyle[aSide] & BORDER_COLOR_SPECIAL) == 0)
michael@0 907 aColor = mBorderColor[aSide];
michael@0 908 else if (mBorderStyle[aSide] & BORDER_COLOR_FOREGROUND)
michael@0 909 aForeground = true;
michael@0 910 else
michael@0 911 NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
michael@0 912 }
michael@0 913
michael@0 914 void SetBorderColor(mozilla::css::Side aSide, nscolor aColor)
michael@0 915 {
michael@0 916 NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
michael@0 917 mBorderColor[aSide] = aColor;
michael@0 918 mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
michael@0 919 }
michael@0 920
michael@0 921 void TrackImage(nsPresContext* aContext)
michael@0 922 {
michael@0 923 if (mBorderImageSource.GetType() == eStyleImageType_Image) {
michael@0 924 mBorderImageSource.TrackImage(aContext);
michael@0 925 }
michael@0 926 }
michael@0 927 void UntrackImage(nsPresContext* aContext)
michael@0 928 {
michael@0 929 if (mBorderImageSource.GetType() == eStyleImageType_Image) {
michael@0 930 mBorderImageSource.UntrackImage(aContext);
michael@0 931 }
michael@0 932 }
michael@0 933
michael@0 934 nsMargin GetImageOutset() const;
michael@0 935
michael@0 936 void GetCompositeColors(int32_t aIndex, nsBorderColors** aColors) const
michael@0 937 {
michael@0 938 if (!mBorderColors)
michael@0 939 *aColors = nullptr;
michael@0 940 else
michael@0 941 *aColors = mBorderColors[aIndex];
michael@0 942 }
michael@0 943
michael@0 944 void AppendBorderColor(int32_t aIndex, nscolor aColor)
michael@0 945 {
michael@0 946 NS_ASSERTION(aIndex >= 0 && aIndex <= 3, "bad side for composite border color");
michael@0 947 nsBorderColors* colorEntry = new nsBorderColors(aColor);
michael@0 948 if (!mBorderColors[aIndex])
michael@0 949 mBorderColors[aIndex] = colorEntry;
michael@0 950 else {
michael@0 951 nsBorderColors* last = mBorderColors[aIndex];
michael@0 952 while (last->mNext)
michael@0 953 last = last->mNext;
michael@0 954 last->mNext = colorEntry;
michael@0 955 }
michael@0 956 mBorderStyle[aIndex] &= ~BORDER_COLOR_SPECIAL;
michael@0 957 }
michael@0 958
michael@0 959 void SetBorderToForeground(mozilla::css::Side aSide)
michael@0 960 {
michael@0 961 NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
michael@0 962 mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
michael@0 963 mBorderStyle[aSide] |= BORDER_COLOR_FOREGROUND;
michael@0 964 }
michael@0 965
michael@0 966 imgIRequest* GetBorderImageRequest() const
michael@0 967 {
michael@0 968 if (mBorderImageSource.GetType() == eStyleImageType_Image) {
michael@0 969 return mBorderImageSource.GetImageData();
michael@0 970 }
michael@0 971 return nullptr;
michael@0 972 }
michael@0 973
michael@0 974 public:
michael@0 975 nsBorderColors** mBorderColors; // [reset] composite (stripe) colors
michael@0 976 nsRefPtr<nsCSSShadowArray> mBoxShadow; // [reset] nullptr for 'none'
michael@0 977
michael@0 978 public:
michael@0 979 nsStyleCorners mBorderRadius; // [reset] coord, percent
michael@0 980 nsStyleImage mBorderImageSource; // [reset]
michael@0 981 nsStyleSides mBorderImageSlice; // [reset] factor, percent
michael@0 982 nsStyleSides mBorderImageWidth; // [reset] length, factor, percent, auto
michael@0 983 nsStyleSides mBorderImageOutset; // [reset] length, factor
michael@0 984
michael@0 985 uint8_t mBorderImageFill; // [reset]
michael@0 986 uint8_t mBorderImageRepeatH; // [reset] see nsStyleConsts.h
michael@0 987 uint8_t mBorderImageRepeatV; // [reset]
michael@0 988 uint8_t mFloatEdge; // [reset]
michael@0 989
michael@0 990 protected:
michael@0 991 // mComputedBorder holds the CSS2.1 computed border-width values.
michael@0 992 // In particular, these widths take into account the border-style
michael@0 993 // for the relevant side, and the values are rounded to the nearest
michael@0 994 // device pixel (which is not part of the definition of computed
michael@0 995 // values). The presence or absence of a border-image does not
michael@0 996 // affect border-width values.
michael@0 997 nsMargin mComputedBorder;
michael@0 998
michael@0 999 // mBorder holds the nscoord values for the border widths as they
michael@0 1000 // would be if all the border-style values were visible (not hidden
michael@0 1001 // or none). This member exists so that when we create structs
michael@0 1002 // using the copy constructor during style resolution the new
michael@0 1003 // structs will know what the specified values of the border were in
michael@0 1004 // case they have more specific rules setting the border style.
michael@0 1005 //
michael@0 1006 // Note that this isn't quite the CSS specified value, since this
michael@0 1007 // has had the enumerated border widths converted to lengths, and
michael@0 1008 // all lengths converted to twips. But it's not quite the computed
michael@0 1009 // value either. The values are rounded to the nearest device pixel.
michael@0 1010 nsMargin mBorder;
michael@0 1011
michael@0 1012 uint8_t mBorderStyle[4]; // [reset] See nsStyleConsts.h
michael@0 1013 nscolor mBorderColor[4]; // [reset] the colors to use for a simple
michael@0 1014 // border. not used for -moz-border-colors
michael@0 1015 private:
michael@0 1016 nscoord mTwipsPerPixel;
michael@0 1017
michael@0 1018 nsStyleBorder& operator=(const nsStyleBorder& aOther) MOZ_DELETE;
michael@0 1019 };
michael@0 1020
michael@0 1021
michael@0 1022 struct nsStyleOutline {
michael@0 1023 nsStyleOutline(nsPresContext* aPresContext);
michael@0 1024 nsStyleOutline(const nsStyleOutline& aOutline);
michael@0 1025 ~nsStyleOutline(void) {
michael@0 1026 MOZ_COUNT_DTOR(nsStyleOutline);
michael@0 1027 }
michael@0 1028
michael@0 1029 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 1030 return aContext->AllocateFromShell(sz);
michael@0 1031 }
michael@0 1032 void Destroy(nsPresContext* aContext) {
michael@0 1033 this->~nsStyleOutline();
michael@0 1034 aContext->FreeToShell(sizeof(nsStyleOutline), this);
michael@0 1035 }
michael@0 1036
michael@0 1037 void RecalcData(nsPresContext* aContext);
michael@0 1038 nsChangeHint CalcDifference(const nsStyleOutline& aOther) const;
michael@0 1039 static nsChangeHint MaxDifference() {
michael@0 1040 return NS_CombineHint(nsChangeHint_AllReflowHints,
michael@0 1041 nsChangeHint_RepaintFrame);
michael@0 1042 }
michael@0 1043 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 1044 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 1045 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 1046 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 1047 nsChangeHint_ClearAncestorIntrinsics);
michael@0 1048 }
michael@0 1049
michael@0 1050 nsStyleCorners mOutlineRadius; // [reset] coord, percent, calc
michael@0 1051
michael@0 1052 // Note that this is a specified value. You can get the actual values
michael@0 1053 // with GetOutlineWidth. You cannot get the computed value directly.
michael@0 1054 nsStyleCoord mOutlineWidth; // [reset] coord, enum (see nsStyleConsts.h)
michael@0 1055 nscoord mOutlineOffset; // [reset]
michael@0 1056
michael@0 1057 bool GetOutlineWidth(nscoord& aWidth) const
michael@0 1058 {
michael@0 1059 if (mHasCachedOutline) {
michael@0 1060 aWidth = mCachedOutlineWidth;
michael@0 1061 return true;
michael@0 1062 }
michael@0 1063 return false;
michael@0 1064 }
michael@0 1065
michael@0 1066 uint8_t GetOutlineStyle(void) const
michael@0 1067 {
michael@0 1068 return (mOutlineStyle & BORDER_STYLE_MASK);
michael@0 1069 }
michael@0 1070
michael@0 1071 void SetOutlineStyle(uint8_t aStyle)
michael@0 1072 {
michael@0 1073 mOutlineStyle &= ~BORDER_STYLE_MASK;
michael@0 1074 mOutlineStyle |= (aStyle & BORDER_STYLE_MASK);
michael@0 1075 }
michael@0 1076
michael@0 1077 // false means initial value
michael@0 1078 bool GetOutlineColor(nscolor& aColor) const
michael@0 1079 {
michael@0 1080 if ((mOutlineStyle & BORDER_COLOR_SPECIAL) == 0) {
michael@0 1081 aColor = mOutlineColor;
michael@0 1082 return true;
michael@0 1083 }
michael@0 1084 return false;
michael@0 1085 }
michael@0 1086
michael@0 1087 void SetOutlineColor(nscolor aColor)
michael@0 1088 {
michael@0 1089 mOutlineColor = aColor;
michael@0 1090 mOutlineStyle &= ~BORDER_COLOR_SPECIAL;
michael@0 1091 }
michael@0 1092
michael@0 1093 void SetOutlineInitialColor()
michael@0 1094 {
michael@0 1095 mOutlineStyle |= OUTLINE_COLOR_INITIAL;
michael@0 1096 }
michael@0 1097
michael@0 1098 bool GetOutlineInitialColor() const
michael@0 1099 {
michael@0 1100 return !!(mOutlineStyle & OUTLINE_COLOR_INITIAL);
michael@0 1101 }
michael@0 1102
michael@0 1103 protected:
michael@0 1104 // This value is the actual value, so it's rounded to the nearest device
michael@0 1105 // pixel.
michael@0 1106 nscoord mCachedOutlineWidth;
michael@0 1107
michael@0 1108 nscolor mOutlineColor; // [reset]
michael@0 1109
michael@0 1110 bool mHasCachedOutline;
michael@0 1111 uint8_t mOutlineStyle; // [reset] See nsStyleConsts.h
michael@0 1112
michael@0 1113 nscoord mTwipsPerPixel;
michael@0 1114 };
michael@0 1115
michael@0 1116
michael@0 1117 struct nsStyleList {
michael@0 1118 nsStyleList(void);
michael@0 1119 nsStyleList(const nsStyleList& aStyleList);
michael@0 1120 ~nsStyleList(void);
michael@0 1121
michael@0 1122 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 1123 return aContext->AllocateFromShell(sz);
michael@0 1124 }
michael@0 1125 void Destroy(nsPresContext* aContext) {
michael@0 1126 this->~nsStyleList();
michael@0 1127 aContext->FreeToShell(sizeof(nsStyleList), this);
michael@0 1128 }
michael@0 1129
michael@0 1130 nsChangeHint CalcDifference(const nsStyleList& aOther) const;
michael@0 1131 static nsChangeHint MaxDifference() {
michael@0 1132 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 1133 }
michael@0 1134 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 1135 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 1136 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 1137 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 1138 nsChangeHint_ClearAncestorIntrinsics);
michael@0 1139 }
michael@0 1140
michael@0 1141 imgRequestProxy* GetListStyleImage() const { return mListStyleImage; }
michael@0 1142 void SetListStyleImage(imgRequestProxy* aReq)
michael@0 1143 {
michael@0 1144 if (mListStyleImage)
michael@0 1145 mListStyleImage->UnlockImage();
michael@0 1146 mListStyleImage = aReq;
michael@0 1147 if (mListStyleImage)
michael@0 1148 mListStyleImage->LockImage();
michael@0 1149 }
michael@0 1150
michael@0 1151 uint8_t mListStyleType; // [inherited] See nsStyleConsts.h
michael@0 1152 uint8_t mListStylePosition; // [inherited]
michael@0 1153 private:
michael@0 1154 nsRefPtr<imgRequestProxy> mListStyleImage; // [inherited]
michael@0 1155 nsStyleList& operator=(const nsStyleList& aOther) MOZ_DELETE;
michael@0 1156 public:
michael@0 1157 nsRect mImageRegion; // [inherited] the rect to use within an image
michael@0 1158 };
michael@0 1159
michael@0 1160 // Computed value of the grid-template-columns or grid-columns-rows property
michael@0 1161 // (but *not* grid-template-areas.)
michael@0 1162 // http://dev.w3.org/csswg/css-grid/#track-sizing
michael@0 1163 //
michael@0 1164 // This represents either:
michael@0 1165 // * none:
michael@0 1166 // mIsSubgrid is false, all three arrays are empty
michael@0 1167 // * <track-list>:
michael@0 1168 // mIsSubgrid is false,
michael@0 1169 // mMinTrackSizingFunctions and mMaxTrackSizingFunctions
michael@0 1170 // are of identical non-zero size,
michael@0 1171 // and mLineNameLists is one element longer than that.
michael@0 1172 // (Delimiting N columns requires N+1 lines:
michael@0 1173 // one before each track, plus one at the very end.)
michael@0 1174 //
michael@0 1175 // An omitted <line-names> is still represented in mLineNameLists,
michael@0 1176 // as an empty sub-array.
michael@0 1177 //
michael@0 1178 // A <track-size> specified as a single <track-breadth> is represented
michael@0 1179 // as identical min and max sizing functions.
michael@0 1180 //
michael@0 1181 // The units for nsStyleCoord are:
michael@0 1182 // * eStyleUnit_Percent represents a <percentage>
michael@0 1183 // * eStyleUnit_FlexFraction represents a <flex> flexible fraction
michael@0 1184 // * eStyleUnit_Coord represents a <length>
michael@0 1185 // * eStyleUnit_Enumerated represents min-content or max-content
michael@0 1186 // * subgrid <line-name-list>?:
michael@0 1187 // mIsSubgrid is true,
michael@0 1188 // mLineNameLists may or may not be empty,
michael@0 1189 // mMinTrackSizingFunctions and mMaxTrackSizingFunctions are empty.
michael@0 1190 struct nsStyleGridTemplate {
michael@0 1191 bool mIsSubgrid;
michael@0 1192 nsTArray<nsTArray<nsString>> mLineNameLists;
michael@0 1193 nsTArray<nsStyleCoord> mMinTrackSizingFunctions;
michael@0 1194 nsTArray<nsStyleCoord> mMaxTrackSizingFunctions;
michael@0 1195
michael@0 1196 nsStyleGridTemplate()
michael@0 1197 : mIsSubgrid(false)
michael@0 1198 {
michael@0 1199 }
michael@0 1200
michael@0 1201 inline bool operator!=(const nsStyleGridTemplate& aOther) const {
michael@0 1202 return mLineNameLists != aOther.mLineNameLists ||
michael@0 1203 mMinTrackSizingFunctions != aOther.mMinTrackSizingFunctions ||
michael@0 1204 mMaxTrackSizingFunctions != aOther.mMaxTrackSizingFunctions;
michael@0 1205 }
michael@0 1206 };
michael@0 1207
michael@0 1208 struct nsStyleGridLine {
michael@0 1209 // http://dev.w3.org/csswg/css-grid/#typedef-grid-line
michael@0 1210 bool mHasSpan;
michael@0 1211 int32_t mInteger; // 0 means not provided
michael@0 1212 nsString mLineName; // Empty string means not provided.
michael@0 1213
michael@0 1214 nsStyleGridLine()
michael@0 1215 : mHasSpan(false)
michael@0 1216 , mInteger(0)
michael@0 1217 // mLineName get its default constructor, the empty string
michael@0 1218 {
michael@0 1219 }
michael@0 1220
michael@0 1221 nsStyleGridLine(const nsStyleGridLine& aOther)
michael@0 1222 {
michael@0 1223 (*this) = aOther;
michael@0 1224 }
michael@0 1225
michael@0 1226 void operator=(const nsStyleGridLine& aOther)
michael@0 1227 {
michael@0 1228 mHasSpan = aOther.mHasSpan;
michael@0 1229 mInteger = aOther.mInteger;
michael@0 1230 mLineName = aOther.mLineName;
michael@0 1231 }
michael@0 1232
michael@0 1233 bool operator!=(const nsStyleGridLine& aOther) const
michael@0 1234 {
michael@0 1235 return mHasSpan != aOther.mHasSpan ||
michael@0 1236 mInteger != aOther.mInteger ||
michael@0 1237 mLineName != aOther.mLineName;
michael@0 1238 }
michael@0 1239
michael@0 1240 void SetToInteger(uint32_t value)
michael@0 1241 {
michael@0 1242 mHasSpan = false;
michael@0 1243 mInteger = value;
michael@0 1244 mLineName.Truncate();
michael@0 1245 }
michael@0 1246
michael@0 1247 void SetAuto()
michael@0 1248 {
michael@0 1249 mHasSpan = false;
michael@0 1250 mInteger = 0;
michael@0 1251 mLineName.Truncate();
michael@0 1252 }
michael@0 1253
michael@0 1254 bool IsAuto() const
michael@0 1255 {
michael@0 1256 bool haveInitialValues = mInteger == 0 && mLineName.IsEmpty();
michael@0 1257 MOZ_ASSERT(!(haveInitialValues && mHasSpan),
michael@0 1258 "should not have 'span' when other components are "
michael@0 1259 "at their initial values");
michael@0 1260 return haveInitialValues;
michael@0 1261 }
michael@0 1262 };
michael@0 1263
michael@0 1264 struct nsStylePosition {
michael@0 1265 nsStylePosition(void);
michael@0 1266 nsStylePosition(const nsStylePosition& aOther);
michael@0 1267 ~nsStylePosition(void);
michael@0 1268
michael@0 1269 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 1270 return aContext->AllocateFromShell(sz);
michael@0 1271 }
michael@0 1272 void Destroy(nsPresContext* aContext) {
michael@0 1273 this->~nsStylePosition();
michael@0 1274 aContext->FreeToShell(sizeof(nsStylePosition), this);
michael@0 1275 }
michael@0 1276
michael@0 1277 nsChangeHint CalcDifference(const nsStylePosition& aOther) const;
michael@0 1278 static nsChangeHint MaxDifference() {
michael@0 1279 return NS_CombineHint(NS_STYLE_HINT_REFLOW,
michael@0 1280 nsChangeHint(nsChangeHint_RecomputePosition |
michael@0 1281 nsChangeHint_UpdateOverflow));
michael@0 1282 }
michael@0 1283 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 1284 // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and
michael@0 1285 // nsChangeHint_NeedReflow as inherited hints.
michael@0 1286 return nsChangeHint(0);
michael@0 1287 }
michael@0 1288
michael@0 1289 nsStyleSides mOffset; // [reset] coord, percent, calc, auto
michael@0 1290 nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto
michael@0 1291 nsStyleCoord mMinWidth; // [reset] coord, percent, enum, calc
michael@0 1292 nsStyleCoord mMaxWidth; // [reset] coord, percent, enum, calc, none
michael@0 1293 nsStyleCoord mHeight; // [reset] coord, percent, calc, auto
michael@0 1294 nsStyleCoord mMinHeight; // [reset] coord, percent, calc
michael@0 1295 nsStyleCoord mMaxHeight; // [reset] coord, percent, calc, none
michael@0 1296 nsStyleCoord mFlexBasis; // [reset] coord, percent, enum, calc, auto
michael@0 1297 nsStyleCoord mGridAutoColumnsMin; // [reset] coord, percent, enum, calc, flex
michael@0 1298 nsStyleCoord mGridAutoColumnsMax; // [reset] coord, percent, enum, calc, flex
michael@0 1299 nsStyleCoord mGridAutoRowsMin; // [reset] coord, percent, enum, calc, flex
michael@0 1300 nsStyleCoord mGridAutoRowsMax; // [reset] coord, percent, enum, calc, flex
michael@0 1301 uint8_t mGridAutoFlow; // [reset] enumerated. See nsStyleConsts.h
michael@0 1302 uint8_t mBoxSizing; // [reset] see nsStyleConsts.h
michael@0 1303 uint8_t mAlignContent; // [reset] see nsStyleConsts.h
michael@0 1304 uint8_t mAlignItems; // [reset] see nsStyleConsts.h
michael@0 1305 uint8_t mAlignSelf; // [reset] see nsStyleConsts.h
michael@0 1306 uint8_t mFlexDirection; // [reset] see nsStyleConsts.h
michael@0 1307 uint8_t mFlexWrap; // [reset] see nsStyleConsts.h
michael@0 1308 uint8_t mJustifyContent; // [reset] see nsStyleConsts.h
michael@0 1309 int32_t mOrder; // [reset] integer
michael@0 1310 float mFlexGrow; // [reset] float
michael@0 1311 float mFlexShrink; // [reset] float
michael@0 1312 nsStyleCoord mZIndex; // [reset] integer, auto
michael@0 1313 // NOTE: Fields so far can be memcpy()'ed, while following fields
michael@0 1314 // need to have their copy constructor called when we're being copied.
michael@0 1315 // See nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
michael@0 1316 // in nsStyleStruct.cpp
michael@0 1317 nsStyleGridTemplate mGridTemplateColumns;
michael@0 1318 nsStyleGridTemplate mGridTemplateRows;
michael@0 1319
michael@0 1320 // nullptr for 'none'
michael@0 1321 nsRefPtr<mozilla::css::GridTemplateAreasValue> mGridTemplateAreas;
michael@0 1322
michael@0 1323 // We represent the "grid-auto-position" property in two parts:
michael@0 1324 nsStyleGridLine mGridAutoPositionColumn;
michael@0 1325 nsStyleGridLine mGridAutoPositionRow;
michael@0 1326
michael@0 1327 nsStyleGridLine mGridColumnStart;
michael@0 1328 nsStyleGridLine mGridColumnEnd;
michael@0 1329 nsStyleGridLine mGridRowStart;
michael@0 1330 nsStyleGridLine mGridRowEnd;
michael@0 1331
michael@0 1332 bool WidthDependsOnContainer() const
michael@0 1333 { return WidthCoordDependsOnContainer(mWidth); }
michael@0 1334 bool MinWidthDependsOnContainer() const
michael@0 1335 { return WidthCoordDependsOnContainer(mMinWidth); }
michael@0 1336 bool MaxWidthDependsOnContainer() const
michael@0 1337 { return WidthCoordDependsOnContainer(mMaxWidth); }
michael@0 1338
michael@0 1339 // Note that these functions count 'auto' as depending on the
michael@0 1340 // container since that's the case for absolutely positioned elements.
michael@0 1341 // However, some callers do not care about this case and should check
michael@0 1342 // for it, since it is the most common case.
michael@0 1343 // FIXME: We should probably change the assumption to be the other way
michael@0 1344 // around.
michael@0 1345 bool HeightDependsOnContainer() const
michael@0 1346 { return HeightCoordDependsOnContainer(mHeight); }
michael@0 1347 bool MinHeightDependsOnContainer() const
michael@0 1348 { return HeightCoordDependsOnContainer(mMinHeight); }
michael@0 1349 bool MaxHeightDependsOnContainer() const
michael@0 1350 { return HeightCoordDependsOnContainer(mMaxHeight); }
michael@0 1351
michael@0 1352 bool OffsetHasPercent(mozilla::css::Side aSide) const
michael@0 1353 {
michael@0 1354 return mOffset.Get(aSide).HasPercent();
michael@0 1355 }
michael@0 1356
michael@0 1357 private:
michael@0 1358 static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
michael@0 1359 static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
michael@0 1360 {
michael@0 1361 return aCoord.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
michael@0 1362 aCoord.HasPercent();
michael@0 1363 }
michael@0 1364 };
michael@0 1365
michael@0 1366 struct nsStyleTextOverflowSide {
michael@0 1367 nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
michael@0 1368
michael@0 1369 bool operator==(const nsStyleTextOverflowSide& aOther) const {
michael@0 1370 return mType == aOther.mType &&
michael@0 1371 (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
michael@0 1372 mString == aOther.mString);
michael@0 1373 }
michael@0 1374 bool operator!=(const nsStyleTextOverflowSide& aOther) const {
michael@0 1375 return !(*this == aOther);
michael@0 1376 }
michael@0 1377
michael@0 1378 nsString mString;
michael@0 1379 uint8_t mType;
michael@0 1380 };
michael@0 1381
michael@0 1382 struct nsStyleTextOverflow {
michael@0 1383 nsStyleTextOverflow() : mLogicalDirections(true) {}
michael@0 1384 bool operator==(const nsStyleTextOverflow& aOther) const {
michael@0 1385 return mLeft == aOther.mLeft && mRight == aOther.mRight;
michael@0 1386 }
michael@0 1387 bool operator!=(const nsStyleTextOverflow& aOther) const {
michael@0 1388 return !(*this == aOther);
michael@0 1389 }
michael@0 1390
michael@0 1391 // Returns the value to apply on the left side.
michael@0 1392 const nsStyleTextOverflowSide& GetLeft(uint8_t aDirection) const {
michael@0 1393 NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
michael@0 1394 aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
michael@0 1395 return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
michael@0 1396 mLeft : mRight;
michael@0 1397 }
michael@0 1398
michael@0 1399 // Returns the value to apply on the right side.
michael@0 1400 const nsStyleTextOverflowSide& GetRight(uint8_t aDirection) const {
michael@0 1401 NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
michael@0 1402 aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
michael@0 1403 return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
michael@0 1404 mRight : mLeft;
michael@0 1405 }
michael@0 1406
michael@0 1407 // Returns the first value that was specified.
michael@0 1408 const nsStyleTextOverflowSide* GetFirstValue() const {
michael@0 1409 return mLogicalDirections ? &mRight : &mLeft;
michael@0 1410 }
michael@0 1411
michael@0 1412 // Returns the second value, or null if there was only one value specified.
michael@0 1413 const nsStyleTextOverflowSide* GetSecondValue() const {
michael@0 1414 return mLogicalDirections ? nullptr : &mRight;
michael@0 1415 }
michael@0 1416
michael@0 1417 nsStyleTextOverflowSide mLeft; // start side when mLogicalDirections is true
michael@0 1418 nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
michael@0 1419 bool mLogicalDirections; // true when only one value was specified
michael@0 1420 };
michael@0 1421
michael@0 1422 struct nsStyleTextReset {
michael@0 1423 nsStyleTextReset(void);
michael@0 1424 nsStyleTextReset(const nsStyleTextReset& aOther);
michael@0 1425 ~nsStyleTextReset(void);
michael@0 1426
michael@0 1427 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 1428 return aContext->AllocateFromShell(sz);
michael@0 1429 }
michael@0 1430 void Destroy(nsPresContext* aContext) {
michael@0 1431 this->~nsStyleTextReset();
michael@0 1432 aContext->FreeToShell(sizeof(nsStyleTextReset), this);
michael@0 1433 }
michael@0 1434
michael@0 1435 uint8_t GetDecorationStyle() const
michael@0 1436 {
michael@0 1437 return (mTextDecorationStyle & BORDER_STYLE_MASK);
michael@0 1438 }
michael@0 1439
michael@0 1440 void SetDecorationStyle(uint8_t aStyle)
michael@0 1441 {
michael@0 1442 NS_ABORT_IF_FALSE((aStyle & BORDER_STYLE_MASK) == aStyle,
michael@0 1443 "style doesn't fit");
michael@0 1444 mTextDecorationStyle &= ~BORDER_STYLE_MASK;
michael@0 1445 mTextDecorationStyle |= (aStyle & BORDER_STYLE_MASK);
michael@0 1446 }
michael@0 1447
michael@0 1448 void GetDecorationColor(nscolor& aColor, bool& aForeground) const
michael@0 1449 {
michael@0 1450 aForeground = false;
michael@0 1451 if ((mTextDecorationStyle & BORDER_COLOR_SPECIAL) == 0) {
michael@0 1452 aColor = mTextDecorationColor;
michael@0 1453 } else if (mTextDecorationStyle & BORDER_COLOR_FOREGROUND) {
michael@0 1454 aForeground = true;
michael@0 1455 } else {
michael@0 1456 NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
michael@0 1457 }
michael@0 1458 }
michael@0 1459
michael@0 1460 void SetDecorationColor(nscolor aColor)
michael@0 1461 {
michael@0 1462 mTextDecorationColor = aColor;
michael@0 1463 mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
michael@0 1464 }
michael@0 1465
michael@0 1466 void SetDecorationColorToForeground()
michael@0 1467 {
michael@0 1468 mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
michael@0 1469 mTextDecorationStyle |= BORDER_COLOR_FOREGROUND;
michael@0 1470 }
michael@0 1471
michael@0 1472 nsChangeHint CalcDifference(const nsStyleTextReset& aOther) const;
michael@0 1473 static nsChangeHint MaxDifference() {
michael@0 1474 return NS_STYLE_HINT_REFLOW;
michael@0 1475 }
michael@0 1476 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 1477 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 1478 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 1479 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 1480 nsChangeHint_ClearAncestorIntrinsics);
michael@0 1481 }
michael@0 1482
michael@0 1483 nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
michael@0 1484 nsStyleTextOverflow mTextOverflow; // [reset] enum, string
michael@0 1485
michael@0 1486 uint8_t mTextDecorationLine; // [reset] see nsStyleConsts.h
michael@0 1487 uint8_t mUnicodeBidi; // [reset] see nsStyleConsts.h
michael@0 1488 protected:
michael@0 1489 uint8_t mTextDecorationStyle; // [reset] see nsStyleConsts.h
michael@0 1490
michael@0 1491 nscolor mTextDecorationColor; // [reset] the colors to use for a decoration lines, not used at currentColor
michael@0 1492 };
michael@0 1493
michael@0 1494 struct nsStyleText {
michael@0 1495 nsStyleText(void);
michael@0 1496 nsStyleText(const nsStyleText& aOther);
michael@0 1497 ~nsStyleText(void);
michael@0 1498
michael@0 1499 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 1500 return aContext->AllocateFromShell(sz);
michael@0 1501 }
michael@0 1502 void Destroy(nsPresContext* aContext) {
michael@0 1503 this->~nsStyleText();
michael@0 1504 aContext->FreeToShell(sizeof(nsStyleText), this);
michael@0 1505 }
michael@0 1506
michael@0 1507 nsChangeHint CalcDifference(const nsStyleText& aOther) const;
michael@0 1508 static nsChangeHint MaxDifference() {
michael@0 1509 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 1510 }
michael@0 1511 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 1512 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 1513 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 1514 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 1515 nsChangeHint_ClearAncestorIntrinsics);
michael@0 1516 }
michael@0 1517
michael@0 1518 uint8_t mTextAlign; // [inherited] see nsStyleConsts.h
michael@0 1519 uint8_t mTextAlignLast; // [inherited] see nsStyleConsts.h
michael@0 1520 bool mTextAlignTrue : 1; // [inherited] see nsStyleConsts.h
michael@0 1521 bool mTextAlignLastTrue : 1; // [inherited] see nsStyleConsts.h
michael@0 1522 uint8_t mTextTransform; // [inherited] see nsStyleConsts.h
michael@0 1523 uint8_t mWhiteSpace; // [inherited] see nsStyleConsts.h
michael@0 1524 uint8_t mWordBreak; // [inherited] see nsStyleConsts.h
michael@0 1525 uint8_t mWordWrap; // [inherited] see nsStyleConsts.h
michael@0 1526 uint8_t mHyphens; // [inherited] see nsStyleConsts.h
michael@0 1527 uint8_t mTextSizeAdjust; // [inherited] see nsStyleConsts.h
michael@0 1528 uint8_t mTextOrientation; // [inherited] see nsStyleConsts.h
michael@0 1529 uint8_t mTextCombineUpright; // [inherited] see nsStyleConsts.h
michael@0 1530 uint8_t mControlCharacterVisibility; // [inherited] see nsStyleConsts.h
michael@0 1531 int32_t mTabSize; // [inherited] see nsStyleConsts.h
michael@0 1532
michael@0 1533 nscoord mWordSpacing; // [inherited]
michael@0 1534 nsStyleCoord mLetterSpacing; // [inherited] coord, normal
michael@0 1535 nsStyleCoord mLineHeight; // [inherited] coord, factor, normal
michael@0 1536 nsStyleCoord mTextIndent; // [inherited] coord, percent, calc
michael@0 1537
michael@0 1538 nsRefPtr<nsCSSShadowArray> mTextShadow; // [inherited] nullptr in case of a zero-length
michael@0 1539
michael@0 1540 bool WhiteSpaceIsSignificant() const {
michael@0 1541 return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
michael@0 1542 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
michael@0 1543 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_DISCARD_NEWLINES;
michael@0 1544 }
michael@0 1545
michael@0 1546 bool NewlineIsSignificant() const {
michael@0 1547 return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
michael@0 1548 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
michael@0 1549 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
michael@0 1550 }
michael@0 1551
michael@0 1552 bool NewlineIsDiscarded() const {
michael@0 1553 return mWhiteSpace == NS_STYLE_WHITESPACE_PRE_DISCARD_NEWLINES;
michael@0 1554 }
michael@0 1555
michael@0 1556 bool WhiteSpaceOrNewlineIsSignificant() const {
michael@0 1557 return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
michael@0 1558 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
michael@0 1559 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE ||
michael@0 1560 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_DISCARD_NEWLINES;
michael@0 1561 }
michael@0 1562
michael@0 1563 bool WhiteSpaceCanWrapStyle() const {
michael@0 1564 return mWhiteSpace == NS_STYLE_WHITESPACE_NORMAL ||
michael@0 1565 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
michael@0 1566 mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
michael@0 1567 }
michael@0 1568
michael@0 1569 bool WordCanWrapStyle() const {
michael@0 1570 return WhiteSpaceCanWrapStyle() &&
michael@0 1571 mWordWrap == NS_STYLE_WORDWRAP_BREAK_WORD;
michael@0 1572 }
michael@0 1573
michael@0 1574 // These are defined in nsStyleStructInlines.h.
michael@0 1575 inline bool HasTextShadow() const;
michael@0 1576 inline nsCSSShadowArray* GetTextShadow() const;
michael@0 1577
michael@0 1578 // The aContextFrame argument on each of these is the frame this
michael@0 1579 // style struct is for. If the frame is for SVG text, the return
michael@0 1580 // value will be massaged to be something that makes sense for
michael@0 1581 // SVG text.
michael@0 1582 inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
michael@0 1583 inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
michael@0 1584 };
michael@0 1585
michael@0 1586 struct nsStyleImageOrientation {
michael@0 1587 static nsStyleImageOrientation CreateAsAngleAndFlip(double aRadians,
michael@0 1588 bool aFlip) {
michael@0 1589 uint8_t orientation(0);
michael@0 1590
michael@0 1591 // Compute the final angle value, rounding to the closest quarter turn.
michael@0 1592 double roundedAngle = fmod(aRadians, 2 * M_PI);
michael@0 1593 if (roundedAngle < 0.25 * M_PI) orientation = ANGLE_0;
michael@0 1594 else if (roundedAngle < 0.75 * M_PI) orientation = ANGLE_90;
michael@0 1595 else if (roundedAngle < 1.25 * M_PI) orientation = ANGLE_180;
michael@0 1596 else if (roundedAngle < 1.75 * M_PI) orientation = ANGLE_270;
michael@0 1597 else orientation = ANGLE_0;
michael@0 1598
michael@0 1599 // Add a bit for 'flip' if needed.
michael@0 1600 if (aFlip)
michael@0 1601 orientation |= FLIP_MASK;
michael@0 1602
michael@0 1603 return nsStyleImageOrientation(orientation);
michael@0 1604 }
michael@0 1605
michael@0 1606 static nsStyleImageOrientation CreateAsFlip() {
michael@0 1607 return nsStyleImageOrientation(FLIP_MASK);
michael@0 1608 }
michael@0 1609
michael@0 1610 static nsStyleImageOrientation CreateAsFromImage() {
michael@0 1611 return nsStyleImageOrientation(FROM_IMAGE_MASK);
michael@0 1612 }
michael@0 1613
michael@0 1614 // The default constructor yields 0 degrees of rotation and no flip.
michael@0 1615 nsStyleImageOrientation() : mOrientation(0) { }
michael@0 1616
michael@0 1617 bool IsDefault() const { return mOrientation == 0; }
michael@0 1618 bool IsFlipped() const { return mOrientation & FLIP_MASK; }
michael@0 1619 bool IsFromImage() const { return mOrientation & FROM_IMAGE_MASK; }
michael@0 1620
michael@0 1621 mozilla::image::Angle Angle() const {
michael@0 1622 switch (mOrientation & ORIENTATION_MASK) {
michael@0 1623 case ANGLE_0: return mozilla::image::Angle::D0;
michael@0 1624 case ANGLE_90: return mozilla::image::Angle::D90;
michael@0 1625 case ANGLE_180: return mozilla::image::Angle::D180;
michael@0 1626 case ANGLE_270: return mozilla::image::Angle::D270;
michael@0 1627 default:
michael@0 1628 NS_NOTREACHED("Unexpected angle");
michael@0 1629 return mozilla::image::Angle::D0;
michael@0 1630 }
michael@0 1631 }
michael@0 1632
michael@0 1633 nsStyleCoord AngleAsCoord() const {
michael@0 1634 switch (mOrientation & ORIENTATION_MASK) {
michael@0 1635 case ANGLE_0: return nsStyleCoord(0.0f, eStyleUnit_Degree);
michael@0 1636 case ANGLE_90: return nsStyleCoord(90.0f, eStyleUnit_Degree);
michael@0 1637 case ANGLE_180: return nsStyleCoord(180.0f, eStyleUnit_Degree);
michael@0 1638 case ANGLE_270: return nsStyleCoord(270.0f, eStyleUnit_Degree);
michael@0 1639 default:
michael@0 1640 NS_NOTREACHED("Unexpected angle");
michael@0 1641 return nsStyleCoord();
michael@0 1642 }
michael@0 1643 }
michael@0 1644
michael@0 1645 bool operator==(const nsStyleImageOrientation& aOther) const {
michael@0 1646 return aOther.mOrientation == mOrientation;
michael@0 1647 }
michael@0 1648
michael@0 1649 bool operator!=(const nsStyleImageOrientation& aOther) const {
michael@0 1650 return !(*this == aOther);
michael@0 1651 }
michael@0 1652
michael@0 1653 protected:
michael@0 1654 enum Bits {
michael@0 1655 ORIENTATION_MASK = 0x1 | 0x2, // The bottom two bits are the angle.
michael@0 1656 FLIP_MASK = 0x4, // Whether the image should be flipped.
michael@0 1657 FROM_IMAGE_MASK = 0x8, // Whether the image's inherent orientation
michael@0 1658 }; // should be used.
michael@0 1659
michael@0 1660 enum Angles {
michael@0 1661 ANGLE_0 = 0,
michael@0 1662 ANGLE_90 = 1,
michael@0 1663 ANGLE_180 = 2,
michael@0 1664 ANGLE_270 = 3,
michael@0 1665 };
michael@0 1666
michael@0 1667 explicit nsStyleImageOrientation(uint8_t aOrientation)
michael@0 1668 : mOrientation(aOrientation)
michael@0 1669 { }
michael@0 1670
michael@0 1671 uint8_t mOrientation;
michael@0 1672 };
michael@0 1673
michael@0 1674 struct nsStyleVisibility {
michael@0 1675 nsStyleVisibility(nsPresContext* aPresContext);
michael@0 1676 nsStyleVisibility(const nsStyleVisibility& aVisibility);
michael@0 1677 ~nsStyleVisibility() {
michael@0 1678 MOZ_COUNT_DTOR(nsStyleVisibility);
michael@0 1679 }
michael@0 1680
michael@0 1681 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 1682 return aContext->AllocateFromShell(sz);
michael@0 1683 }
michael@0 1684 void Destroy(nsPresContext* aContext) {
michael@0 1685 this->~nsStyleVisibility();
michael@0 1686 aContext->FreeToShell(sizeof(nsStyleVisibility), this);
michael@0 1687 }
michael@0 1688
michael@0 1689 nsChangeHint CalcDifference(const nsStyleVisibility& aOther) const;
michael@0 1690 static nsChangeHint MaxDifference() {
michael@0 1691 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 1692 }
michael@0 1693 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 1694 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 1695 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 1696 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 1697 nsChangeHint_ClearAncestorIntrinsics);
michael@0 1698 }
michael@0 1699
michael@0 1700 nsStyleImageOrientation mImageOrientation; // [inherited]
michael@0 1701 uint8_t mDirection; // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
michael@0 1702 uint8_t mVisible; // [inherited]
michael@0 1703 uint8_t mPointerEvents; // [inherited] see nsStyleConsts.h
michael@0 1704 uint8_t mWritingMode; // [inherited] see nsStyleConsts.h
michael@0 1705
michael@0 1706 bool IsVisible() const {
michael@0 1707 return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
michael@0 1708 }
michael@0 1709
michael@0 1710 bool IsVisibleOrCollapsed() const {
michael@0 1711 return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
michael@0 1712 (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
michael@0 1713 }
michael@0 1714
michael@0 1715 inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
michael@0 1716 };
michael@0 1717
michael@0 1718 struct nsTimingFunction {
michael@0 1719 enum Type { Function, StepStart, StepEnd };
michael@0 1720
michael@0 1721 explicit nsTimingFunction(int32_t aTimingFunctionType
michael@0 1722 = NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE)
michael@0 1723 {
michael@0 1724 AssignFromKeyword(aTimingFunctionType);
michael@0 1725 }
michael@0 1726
michael@0 1727 nsTimingFunction(float x1, float y1, float x2, float y2)
michael@0 1728 : mType(Function)
michael@0 1729 {
michael@0 1730 mFunc.mX1 = x1;
michael@0 1731 mFunc.mY1 = y1;
michael@0 1732 mFunc.mX2 = x2;
michael@0 1733 mFunc.mY2 = y2;
michael@0 1734 }
michael@0 1735
michael@0 1736 nsTimingFunction(Type aType, uint32_t aSteps)
michael@0 1737 : mType(aType)
michael@0 1738 {
michael@0 1739 NS_ABORT_IF_FALSE(mType == StepStart || mType == StepEnd, "wrong type");
michael@0 1740 mSteps = aSteps;
michael@0 1741 }
michael@0 1742
michael@0 1743 nsTimingFunction(const nsTimingFunction& aOther)
michael@0 1744 {
michael@0 1745 *this = aOther;
michael@0 1746 }
michael@0 1747
michael@0 1748 Type mType;
michael@0 1749 union {
michael@0 1750 struct {
michael@0 1751 float mX1;
michael@0 1752 float mY1;
michael@0 1753 float mX2;
michael@0 1754 float mY2;
michael@0 1755 } mFunc;
michael@0 1756 uint32_t mSteps;
michael@0 1757 };
michael@0 1758
michael@0 1759 nsTimingFunction&
michael@0 1760 operator=(const nsTimingFunction& aOther)
michael@0 1761 {
michael@0 1762 if (&aOther == this)
michael@0 1763 return *this;
michael@0 1764
michael@0 1765 mType = aOther.mType;
michael@0 1766
michael@0 1767 if (mType == Function) {
michael@0 1768 mFunc.mX1 = aOther.mFunc.mX1;
michael@0 1769 mFunc.mY1 = aOther.mFunc.mY1;
michael@0 1770 mFunc.mX2 = aOther.mFunc.mX2;
michael@0 1771 mFunc.mY2 = aOther.mFunc.mY2;
michael@0 1772 } else {
michael@0 1773 mSteps = aOther.mSteps;
michael@0 1774 }
michael@0 1775
michael@0 1776 return *this;
michael@0 1777 }
michael@0 1778
michael@0 1779 bool operator==(const nsTimingFunction& aOther) const
michael@0 1780 {
michael@0 1781 if (mType != aOther.mType) {
michael@0 1782 return false;
michael@0 1783 }
michael@0 1784 if (mType == Function) {
michael@0 1785 return mFunc.mX1 == aOther.mFunc.mX1 && mFunc.mY1 == aOther.mFunc.mY1 &&
michael@0 1786 mFunc.mX2 == aOther.mFunc.mX2 && mFunc.mY2 == aOther.mFunc.mY2;
michael@0 1787 }
michael@0 1788 return mSteps == aOther.mSteps;
michael@0 1789 }
michael@0 1790
michael@0 1791 bool operator!=(const nsTimingFunction& aOther) const
michael@0 1792 {
michael@0 1793 return !(*this == aOther);
michael@0 1794 }
michael@0 1795
michael@0 1796 private:
michael@0 1797 void AssignFromKeyword(int32_t aTimingFunctionType);
michael@0 1798 };
michael@0 1799
michael@0 1800 struct nsTransition {
michael@0 1801 nsTransition() { /* leaves uninitialized; see also SetInitialValues */ }
michael@0 1802 explicit nsTransition(const nsTransition& aCopy);
michael@0 1803
michael@0 1804 void SetInitialValues();
michael@0 1805
michael@0 1806 // Delay and Duration are in milliseconds
michael@0 1807
michael@0 1808 const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
michael@0 1809 float GetDelay() const { return mDelay; }
michael@0 1810 float GetDuration() const { return mDuration; }
michael@0 1811 nsCSSProperty GetProperty() const { return mProperty; }
michael@0 1812 nsIAtom* GetUnknownProperty() const { return mUnknownProperty; }
michael@0 1813
michael@0 1814 void SetTimingFunction(const nsTimingFunction& aTimingFunction)
michael@0 1815 { mTimingFunction = aTimingFunction; }
michael@0 1816 void SetDelay(float aDelay) { mDelay = aDelay; }
michael@0 1817 void SetDuration(float aDuration) { mDuration = aDuration; }
michael@0 1818 void SetProperty(nsCSSProperty aProperty)
michael@0 1819 {
michael@0 1820 NS_ASSERTION(aProperty != eCSSProperty_UNKNOWN, "invalid property");
michael@0 1821 mProperty = aProperty;
michael@0 1822 }
michael@0 1823 void SetUnknownProperty(const nsAString& aUnknownProperty);
michael@0 1824 void CopyPropertyFrom(const nsTransition& aOther)
michael@0 1825 {
michael@0 1826 mProperty = aOther.mProperty;
michael@0 1827 mUnknownProperty = aOther.mUnknownProperty;
michael@0 1828 }
michael@0 1829
michael@0 1830 nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
michael@0 1831
michael@0 1832 private:
michael@0 1833 nsTimingFunction mTimingFunction;
michael@0 1834 float mDuration;
michael@0 1835 float mDelay;
michael@0 1836 nsCSSProperty mProperty;
michael@0 1837 nsCOMPtr<nsIAtom> mUnknownProperty; // used when mProperty is
michael@0 1838 // eCSSProperty_UNKNOWN
michael@0 1839 };
michael@0 1840
michael@0 1841 struct nsAnimation {
michael@0 1842 nsAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
michael@0 1843 explicit nsAnimation(const nsAnimation& aCopy);
michael@0 1844
michael@0 1845 void SetInitialValues();
michael@0 1846
michael@0 1847 // Delay and Duration are in milliseconds
michael@0 1848
michael@0 1849 const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
michael@0 1850 float GetDelay() const { return mDelay; }
michael@0 1851 float GetDuration() const { return mDuration; }
michael@0 1852 const nsString& GetName() const { return mName; }
michael@0 1853 uint8_t GetDirection() const { return mDirection; }
michael@0 1854 uint8_t GetFillMode() const { return mFillMode; }
michael@0 1855 uint8_t GetPlayState() const { return mPlayState; }
michael@0 1856 float GetIterationCount() const { return mIterationCount; }
michael@0 1857
michael@0 1858 void SetTimingFunction(const nsTimingFunction& aTimingFunction)
michael@0 1859 { mTimingFunction = aTimingFunction; }
michael@0 1860 void SetDelay(float aDelay) { mDelay = aDelay; }
michael@0 1861 void SetDuration(float aDuration) { mDuration = aDuration; }
michael@0 1862 void SetName(const nsSubstring& aName) { mName = aName; }
michael@0 1863 void SetDirection(uint8_t aDirection) { mDirection = aDirection; }
michael@0 1864 void SetFillMode(uint8_t aFillMode) { mFillMode = aFillMode; }
michael@0 1865 void SetPlayState(uint8_t aPlayState) { mPlayState = aPlayState; }
michael@0 1866 void SetIterationCount(float aIterationCount)
michael@0 1867 { mIterationCount = aIterationCount; }
michael@0 1868
michael@0 1869 nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
michael@0 1870
michael@0 1871 private:
michael@0 1872 nsTimingFunction mTimingFunction;
michael@0 1873 float mDuration;
michael@0 1874 float mDelay;
michael@0 1875 nsString mName; // empty string for 'none'
michael@0 1876 uint8_t mDirection;
michael@0 1877 uint8_t mFillMode;
michael@0 1878 uint8_t mPlayState;
michael@0 1879 float mIterationCount; // NS_IEEEPositiveInfinity() means infinite
michael@0 1880 };
michael@0 1881
michael@0 1882 struct nsStyleDisplay {
michael@0 1883 nsStyleDisplay();
michael@0 1884 nsStyleDisplay(const nsStyleDisplay& aOther);
michael@0 1885 ~nsStyleDisplay() {
michael@0 1886 MOZ_COUNT_DTOR(nsStyleDisplay);
michael@0 1887 }
michael@0 1888
michael@0 1889 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 1890 return aContext->AllocateFromShell(sz);
michael@0 1891 }
michael@0 1892 void Destroy(nsPresContext* aContext) {
michael@0 1893 this->~nsStyleDisplay();
michael@0 1894 aContext->FreeToShell(sizeof(nsStyleDisplay), this);
michael@0 1895 }
michael@0 1896
michael@0 1897 nsChangeHint CalcDifference(const nsStyleDisplay& aOther) const;
michael@0 1898 static nsChangeHint MaxDifference() {
michael@0 1899 // All the parts of FRAMECHANGE are present in CalcDifference.
michael@0 1900 return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
michael@0 1901 nsChangeHint_UpdateOpacityLayer |
michael@0 1902 nsChangeHint_UpdateTransformLayer |
michael@0 1903 nsChangeHint_UpdateOverflow |
michael@0 1904 nsChangeHint_UpdatePostTransformOverflow |
michael@0 1905 nsChangeHint_AddOrRemoveTransform);
michael@0 1906 }
michael@0 1907 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 1908 // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and
michael@0 1909 // nsChangeHint_NeedReflow as inherited hints.
michael@0 1910 return nsChangeHint(0);
michael@0 1911 }
michael@0 1912
michael@0 1913 // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
michael@0 1914 // mBinding->mOriginPrincipal.
michael@0 1915 nsRefPtr<mozilla::css::URLValue> mBinding; // [reset]
michael@0 1916 nsRect mClip; // [reset] offsets from upper-left border edge
michael@0 1917 float mOpacity; // [reset]
michael@0 1918 uint8_t mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
michael@0 1919 uint8_t mOriginalDisplay; // [reset] saved mDisplay for position:absolute/fixed
michael@0 1920 // and float:left/right; otherwise equal
michael@0 1921 // to mDisplay
michael@0 1922 uint8_t mAppearance; // [reset]
michael@0 1923 uint8_t mPosition; // [reset] see nsStyleConsts.h
michael@0 1924 uint8_t mFloats; // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*
michael@0 1925 uint8_t mOriginalFloats; // [reset] saved mFloats for position:absolute/fixed;
michael@0 1926 // otherwise equal to mFloats
michael@0 1927 uint8_t mBreakType; // [reset] see nsStyleConsts.h NS_STYLE_CLEAR_*
michael@0 1928 uint8_t mBreakInside; // [reset] NS_STYLE_PAGE_BREAK_AUTO/AVOID
michael@0 1929 bool mBreakBefore; // [reset]
michael@0 1930 bool mBreakAfter; // [reset]
michael@0 1931 uint8_t mOverflowX; // [reset] see nsStyleConsts.h
michael@0 1932 uint8_t mOverflowY; // [reset] see nsStyleConsts.h
michael@0 1933 uint8_t mOverflowClipBox; // [reset] see nsStyleConsts.h
michael@0 1934 uint8_t mResize; // [reset] see nsStyleConsts.h
michael@0 1935 uint8_t mClipFlags; // [reset] see nsStyleConsts.h
michael@0 1936 uint8_t mOrient; // [reset] see nsStyleConsts.h
michael@0 1937 uint8_t mMixBlendMode; // [reset] see nsStyleConsts.h
michael@0 1938 uint8_t mWillChangeBitField; // [reset] see nsStyleConsts.h. Stores a
michael@0 1939 // bitfield representation of the properties
michael@0 1940 // that are frequently queried. This should
michael@0 1941 // match mWillChange. Also tracks if any of the
michael@0 1942 // properties in the will-change list require
michael@0 1943 // a stacking context.
michael@0 1944 nsAutoTArray<nsString, 1> mWillChange;
michael@0 1945
michael@0 1946 uint8_t mTouchAction; // [reset] see nsStyleConsts.h
michael@0 1947
michael@0 1948 // mSpecifiedTransform is the list of transform functions as
michael@0 1949 // specified, or null to indicate there is no transform. (inherit or
michael@0 1950 // initial are replaced by an actual list of transform functions, or
michael@0 1951 // null, as appropriate.)
michael@0 1952 uint8_t mBackfaceVisibility;
michael@0 1953 uint8_t mTransformStyle;
michael@0 1954 nsRefPtr<nsCSSValueSharedList> mSpecifiedTransform; // [reset]
michael@0 1955 nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
michael@0 1956 nsStyleCoord mChildPerspective; // [reset] coord
michael@0 1957 nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
michael@0 1958
michael@0 1959 nsAutoTArray<nsTransition, 1> mTransitions; // [reset]
michael@0 1960 // The number of elements in mTransitions that are not from repeating
michael@0 1961 // a list due to another property being longer.
michael@0 1962 uint32_t mTransitionTimingFunctionCount,
michael@0 1963 mTransitionDurationCount,
michael@0 1964 mTransitionDelayCount,
michael@0 1965 mTransitionPropertyCount;
michael@0 1966
michael@0 1967 nsAutoTArray<nsAnimation, 1> mAnimations; // [reset]
michael@0 1968 // The number of elements in mAnimations that are not from repeating
michael@0 1969 // a list due to another property being longer.
michael@0 1970 uint32_t mAnimationTimingFunctionCount,
michael@0 1971 mAnimationDurationCount,
michael@0 1972 mAnimationDelayCount,
michael@0 1973 mAnimationNameCount,
michael@0 1974 mAnimationDirectionCount,
michael@0 1975 mAnimationFillModeCount,
michael@0 1976 mAnimationPlayStateCount,
michael@0 1977 mAnimationIterationCountCount;
michael@0 1978
michael@0 1979 bool IsBlockInsideStyle() const {
michael@0 1980 return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
michael@0 1981 NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
michael@0 1982 NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay;
michael@0 1983 // Should TABLE_CELL and TABLE_CAPTION go here? They have
michael@0 1984 // block frames nested inside of them.
michael@0 1985 // (But please audit all callers before changing.)
michael@0 1986 }
michael@0 1987
michael@0 1988 bool IsBlockOutsideStyle() const {
michael@0 1989 return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
michael@0 1990 NS_STYLE_DISPLAY_FLEX == mDisplay ||
michael@0 1991 NS_STYLE_DISPLAY_GRID == mDisplay ||
michael@0 1992 NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
michael@0 1993 NS_STYLE_DISPLAY_TABLE == mDisplay;
michael@0 1994 }
michael@0 1995
michael@0 1996 static bool IsDisplayTypeInlineOutside(uint8_t aDisplay) {
michael@0 1997 return NS_STYLE_DISPLAY_INLINE == aDisplay ||
michael@0 1998 NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay ||
michael@0 1999 NS_STYLE_DISPLAY_INLINE_TABLE == aDisplay ||
michael@0 2000 NS_STYLE_DISPLAY_INLINE_BOX == aDisplay ||
michael@0 2001 NS_STYLE_DISPLAY_INLINE_FLEX == aDisplay ||
michael@0 2002 NS_STYLE_DISPLAY_INLINE_GRID == aDisplay ||
michael@0 2003 NS_STYLE_DISPLAY_INLINE_XUL_GRID == aDisplay ||
michael@0 2004 NS_STYLE_DISPLAY_INLINE_STACK == aDisplay;
michael@0 2005 }
michael@0 2006
michael@0 2007 bool IsInlineOutsideStyle() const {
michael@0 2008 return IsDisplayTypeInlineOutside(mDisplay);
michael@0 2009 }
michael@0 2010
michael@0 2011 bool IsOriginalDisplayInlineOutsideStyle() const {
michael@0 2012 return IsDisplayTypeInlineOutside(mOriginalDisplay);
michael@0 2013 }
michael@0 2014
michael@0 2015 bool IsInnerTableStyle() const {
michael@0 2016 return NS_STYLE_DISPLAY_TABLE_CAPTION == mDisplay ||
michael@0 2017 NS_STYLE_DISPLAY_TABLE_CELL == mDisplay ||
michael@0 2018 NS_STYLE_DISPLAY_TABLE_ROW == mDisplay ||
michael@0 2019 NS_STYLE_DISPLAY_TABLE_ROW_GROUP == mDisplay ||
michael@0 2020 NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == mDisplay ||
michael@0 2021 NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == mDisplay ||
michael@0 2022 NS_STYLE_DISPLAY_TABLE_COLUMN == mDisplay ||
michael@0 2023 NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == mDisplay;
michael@0 2024 }
michael@0 2025
michael@0 2026 bool IsFloatingStyle() const {
michael@0 2027 return NS_STYLE_FLOAT_NONE != mFloats;
michael@0 2028 }
michael@0 2029
michael@0 2030 bool IsAbsolutelyPositionedStyle() const {
michael@0 2031 return NS_STYLE_POSITION_ABSOLUTE == mPosition ||
michael@0 2032 NS_STYLE_POSITION_FIXED == mPosition;
michael@0 2033 }
michael@0 2034
michael@0 2035 bool IsRelativelyPositionedStyle() const {
michael@0 2036 return NS_STYLE_POSITION_RELATIVE == mPosition ||
michael@0 2037 NS_STYLE_POSITION_STICKY == mPosition;
michael@0 2038 }
michael@0 2039
michael@0 2040 bool IsScrollableOverflow() const {
michael@0 2041 // mOverflowX and mOverflowY always match when one of them is
michael@0 2042 // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
michael@0 2043 return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
michael@0 2044 mOverflowX != NS_STYLE_OVERFLOW_CLIP;
michael@0 2045 }
michael@0 2046
michael@0 2047 /* Returns whether the element has the -moz-transform property
michael@0 2048 * or a related property. */
michael@0 2049 bool HasTransformStyle() const {
michael@0 2050 return mSpecifiedTransform != nullptr ||
michael@0 2051 mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
michael@0 2052 (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM);
michael@0 2053 }
michael@0 2054
michael@0 2055 bool HasPerspectiveStyle() const {
michael@0 2056 return mChildPerspective.GetUnit() == eStyleUnit_Coord;
michael@0 2057 }
michael@0 2058
michael@0 2059 bool BackfaceIsHidden() const {
michael@0 2060 return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
michael@0 2061 }
michael@0 2062
michael@0 2063 // These are defined in nsStyleStructInlines.h.
michael@0 2064
michael@0 2065 // The aContextFrame argument on each of these is the frame this
michael@0 2066 // style struct is for. If the frame is for SVG text, the return
michael@0 2067 // value will be massaged to be something that makes sense for
michael@0 2068 // SVG text.
michael@0 2069 inline bool IsBlockInside(const nsIFrame* aContextFrame) const;
michael@0 2070 inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
michael@0 2071 inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
michael@0 2072 inline bool IsOriginalDisplayInlineOutside(const nsIFrame* aContextFrame) const;
michael@0 2073 inline uint8_t GetDisplay(const nsIFrame* aContextFrame) const;
michael@0 2074 inline bool IsFloating(const nsIFrame* aContextFrame) const;
michael@0 2075 inline bool IsPositioned(const nsIFrame* aContextFrame) const;
michael@0 2076 inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
michael@0 2077 inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
michael@0 2078
michael@0 2079 /* Returns whether the element has the -moz-transform property
michael@0 2080 * or a related property, and supports CSS transforms. */
michael@0 2081 inline bool HasTransform(const nsIFrame* aContextFrame) const;
michael@0 2082 };
michael@0 2083
michael@0 2084 struct nsStyleTable {
michael@0 2085 nsStyleTable(void);
michael@0 2086 nsStyleTable(const nsStyleTable& aOther);
michael@0 2087 ~nsStyleTable(void);
michael@0 2088
michael@0 2089 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2090 return aContext->AllocateFromShell(sz);
michael@0 2091 }
michael@0 2092 void Destroy(nsPresContext* aContext) {
michael@0 2093 this->~nsStyleTable();
michael@0 2094 aContext->FreeToShell(sizeof(nsStyleTable), this);
michael@0 2095 }
michael@0 2096
michael@0 2097 nsChangeHint CalcDifference(const nsStyleTable& aOther) const;
michael@0 2098 static nsChangeHint MaxDifference() {
michael@0 2099 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 2100 }
michael@0 2101 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2102 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2103 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2104 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2105 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2106 }
michael@0 2107
michael@0 2108 uint8_t mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
michael@0 2109 uint8_t mFrame; // [reset] see nsStyleConsts.h NS_STYLE_TABLE_FRAME_*
michael@0 2110 uint8_t mRules; // [reset] see nsStyleConsts.h NS_STYLE_TABLE_RULES_*
michael@0 2111 int32_t mSpan; // [reset] the number of columns spanned by a colgroup or col
michael@0 2112 };
michael@0 2113
michael@0 2114 struct nsStyleTableBorder {
michael@0 2115 nsStyleTableBorder(nsPresContext* aContext);
michael@0 2116 nsStyleTableBorder(const nsStyleTableBorder& aOther);
michael@0 2117 ~nsStyleTableBorder(void);
michael@0 2118
michael@0 2119 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2120 return aContext->AllocateFromShell(sz);
michael@0 2121 }
michael@0 2122 void Destroy(nsPresContext* aContext) {
michael@0 2123 this->~nsStyleTableBorder();
michael@0 2124 aContext->FreeToShell(sizeof(nsStyleTableBorder), this);
michael@0 2125 }
michael@0 2126
michael@0 2127 nsChangeHint CalcDifference(const nsStyleTableBorder& aOther) const;
michael@0 2128 static nsChangeHint MaxDifference() {
michael@0 2129 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 2130 }
michael@0 2131 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2132 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2133 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2134 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2135 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2136 }
michael@0 2137
michael@0 2138 nscoord mBorderSpacingX;// [inherited]
michael@0 2139 nscoord mBorderSpacingY;// [inherited]
michael@0 2140 uint8_t mBorderCollapse;// [inherited]
michael@0 2141 uint8_t mCaptionSide; // [inherited]
michael@0 2142 uint8_t mEmptyCells; // [inherited]
michael@0 2143 };
michael@0 2144
michael@0 2145 enum nsStyleContentType {
michael@0 2146 eStyleContentType_String = 1,
michael@0 2147 eStyleContentType_Image = 10,
michael@0 2148 eStyleContentType_Attr = 20,
michael@0 2149 eStyleContentType_Counter = 30,
michael@0 2150 eStyleContentType_Counters = 31,
michael@0 2151 eStyleContentType_OpenQuote = 40,
michael@0 2152 eStyleContentType_CloseQuote = 41,
michael@0 2153 eStyleContentType_NoOpenQuote = 42,
michael@0 2154 eStyleContentType_NoCloseQuote = 43,
michael@0 2155 eStyleContentType_AltContent = 50,
michael@0 2156 eStyleContentType_Uninitialized
michael@0 2157 };
michael@0 2158
michael@0 2159 struct nsStyleContentData {
michael@0 2160 nsStyleContentType mType;
michael@0 2161 union {
michael@0 2162 char16_t *mString;
michael@0 2163 imgRequestProxy *mImage;
michael@0 2164 nsCSSValue::Array* mCounters;
michael@0 2165 } mContent;
michael@0 2166 #ifdef DEBUG
michael@0 2167 bool mImageTracked;
michael@0 2168 #endif
michael@0 2169
michael@0 2170 nsStyleContentData()
michael@0 2171 : mType(eStyleContentType_Uninitialized)
michael@0 2172 #ifdef DEBUG
michael@0 2173 , mImageTracked(false)
michael@0 2174 #endif
michael@0 2175 { mContent.mString = nullptr; }
michael@0 2176
michael@0 2177 ~nsStyleContentData();
michael@0 2178 nsStyleContentData& operator=(const nsStyleContentData& aOther);
michael@0 2179 bool operator==(const nsStyleContentData& aOther) const;
michael@0 2180
michael@0 2181 bool operator!=(const nsStyleContentData& aOther) const {
michael@0 2182 return !(*this == aOther);
michael@0 2183 }
michael@0 2184
michael@0 2185 void TrackImage(nsPresContext* aContext);
michael@0 2186 void UntrackImage(nsPresContext* aContext);
michael@0 2187
michael@0 2188 void SetImage(imgRequestProxy* aRequest)
michael@0 2189 {
michael@0 2190 NS_ABORT_IF_FALSE(!mImageTracked,
michael@0 2191 "Setting a new image without untracking the old one!");
michael@0 2192 NS_ABORT_IF_FALSE(mType == eStyleContentType_Image, "Wrong type!");
michael@0 2193 NS_IF_ADDREF(mContent.mImage = aRequest);
michael@0 2194 }
michael@0 2195 private:
michael@0 2196 nsStyleContentData(const nsStyleContentData&); // not to be implemented
michael@0 2197 };
michael@0 2198
michael@0 2199 struct nsStyleCounterData {
michael@0 2200 nsString mCounter;
michael@0 2201 int32_t mValue;
michael@0 2202 };
michael@0 2203
michael@0 2204
michael@0 2205 #define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nullptr; }
michael@0 2206
michael@0 2207 struct nsStyleQuotes {
michael@0 2208 nsStyleQuotes();
michael@0 2209 nsStyleQuotes(const nsStyleQuotes& aQuotes);
michael@0 2210 ~nsStyleQuotes();
michael@0 2211
michael@0 2212 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2213 return aContext->AllocateFromShell(sz);
michael@0 2214 }
michael@0 2215 void Destroy(nsPresContext* aContext) {
michael@0 2216 this->~nsStyleQuotes();
michael@0 2217 aContext->FreeToShell(sizeof(nsStyleQuotes), this);
michael@0 2218 }
michael@0 2219
michael@0 2220 void SetInitial();
michael@0 2221 void CopyFrom(const nsStyleQuotes& aSource);
michael@0 2222
michael@0 2223 nsChangeHint CalcDifference(const nsStyleQuotes& aOther) const;
michael@0 2224 static nsChangeHint MaxDifference() {
michael@0 2225 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 2226 }
michael@0 2227 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2228 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2229 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2230 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2231 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2232 }
michael@0 2233
michael@0 2234 uint32_t QuotesCount(void) const { return mQuotesCount; } // [inherited]
michael@0 2235
michael@0 2236 const nsString* OpenQuoteAt(uint32_t aIndex) const
michael@0 2237 {
michael@0 2238 NS_ASSERTION(aIndex < mQuotesCount, "out of range");
michael@0 2239 return mQuotes + (aIndex * 2);
michael@0 2240 }
michael@0 2241 const nsString* CloseQuoteAt(uint32_t aIndex) const
michael@0 2242 {
michael@0 2243 NS_ASSERTION(aIndex < mQuotesCount, "out of range");
michael@0 2244 return mQuotes + (aIndex * 2 + 1);
michael@0 2245 }
michael@0 2246 nsresult GetQuotesAt(uint32_t aIndex, nsString& aOpen, nsString& aClose) const {
michael@0 2247 if (aIndex < mQuotesCount) {
michael@0 2248 aIndex *= 2;
michael@0 2249 aOpen = mQuotes[aIndex];
michael@0 2250 aClose = mQuotes[++aIndex];
michael@0 2251 return NS_OK;
michael@0 2252 }
michael@0 2253 return NS_ERROR_ILLEGAL_VALUE;
michael@0 2254 }
michael@0 2255
michael@0 2256 nsresult AllocateQuotes(uint32_t aCount) {
michael@0 2257 if (aCount != mQuotesCount) {
michael@0 2258 DELETE_ARRAY_IF(mQuotes);
michael@0 2259 if (aCount) {
michael@0 2260 mQuotes = new nsString[aCount * 2];
michael@0 2261 if (! mQuotes) {
michael@0 2262 mQuotesCount = 0;
michael@0 2263 return NS_ERROR_OUT_OF_MEMORY;
michael@0 2264 }
michael@0 2265 }
michael@0 2266 mQuotesCount = aCount;
michael@0 2267 }
michael@0 2268 return NS_OK;
michael@0 2269 }
michael@0 2270
michael@0 2271 nsresult SetQuotesAt(uint32_t aIndex, const nsString& aOpen, const nsString& aClose) {
michael@0 2272 if (aIndex < mQuotesCount) {
michael@0 2273 aIndex *= 2;
michael@0 2274 mQuotes[aIndex] = aOpen;
michael@0 2275 mQuotes[++aIndex] = aClose;
michael@0 2276 return NS_OK;
michael@0 2277 }
michael@0 2278 return NS_ERROR_ILLEGAL_VALUE;
michael@0 2279 }
michael@0 2280
michael@0 2281 protected:
michael@0 2282 uint32_t mQuotesCount;
michael@0 2283 nsString* mQuotes;
michael@0 2284 };
michael@0 2285
michael@0 2286 struct nsStyleContent {
michael@0 2287 nsStyleContent(void);
michael@0 2288 nsStyleContent(const nsStyleContent& aContent);
michael@0 2289 ~nsStyleContent(void);
michael@0 2290
michael@0 2291 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2292 return aContext->AllocateFromShell(sz);
michael@0 2293 }
michael@0 2294 void Destroy(nsPresContext* aContext);
michael@0 2295
michael@0 2296 nsChangeHint CalcDifference(const nsStyleContent& aOther) const;
michael@0 2297 static nsChangeHint MaxDifference() {
michael@0 2298 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 2299 }
michael@0 2300 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2301 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2302 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2303 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2304 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2305 }
michael@0 2306
michael@0 2307 uint32_t ContentCount(void) const { return mContentCount; } // [reset]
michael@0 2308
michael@0 2309 const nsStyleContentData& ContentAt(uint32_t aIndex) const {
michael@0 2310 NS_ASSERTION(aIndex < mContentCount, "out of range");
michael@0 2311 return mContents[aIndex];
michael@0 2312 }
michael@0 2313
michael@0 2314 nsStyleContentData& ContentAt(uint32_t aIndex) {
michael@0 2315 NS_ASSERTION(aIndex < mContentCount, "out of range");
michael@0 2316 return mContents[aIndex];
michael@0 2317 }
michael@0 2318
michael@0 2319 nsresult AllocateContents(uint32_t aCount);
michael@0 2320
michael@0 2321 uint32_t CounterIncrementCount(void) const { return mIncrementCount; } // [reset]
michael@0 2322 const nsStyleCounterData* GetCounterIncrementAt(uint32_t aIndex) const {
michael@0 2323 NS_ASSERTION(aIndex < mIncrementCount, "out of range");
michael@0 2324 return &mIncrements[aIndex];
michael@0 2325 }
michael@0 2326
michael@0 2327 nsresult AllocateCounterIncrements(uint32_t aCount) {
michael@0 2328 if (aCount != mIncrementCount) {
michael@0 2329 DELETE_ARRAY_IF(mIncrements);
michael@0 2330 if (aCount) {
michael@0 2331 mIncrements = new nsStyleCounterData[aCount];
michael@0 2332 if (! mIncrements) {
michael@0 2333 mIncrementCount = 0;
michael@0 2334 return NS_ERROR_OUT_OF_MEMORY;
michael@0 2335 }
michael@0 2336 }
michael@0 2337 mIncrementCount = aCount;
michael@0 2338 }
michael@0 2339 return NS_OK;
michael@0 2340 }
michael@0 2341
michael@0 2342 nsresult SetCounterIncrementAt(uint32_t aIndex, const nsString& aCounter, int32_t aIncrement) {
michael@0 2343 if (aIndex < mIncrementCount) {
michael@0 2344 mIncrements[aIndex].mCounter = aCounter;
michael@0 2345 mIncrements[aIndex].mValue = aIncrement;
michael@0 2346 return NS_OK;
michael@0 2347 }
michael@0 2348 return NS_ERROR_ILLEGAL_VALUE;
michael@0 2349 }
michael@0 2350
michael@0 2351 uint32_t CounterResetCount(void) const { return mResetCount; } // [reset]
michael@0 2352 const nsStyleCounterData* GetCounterResetAt(uint32_t aIndex) const {
michael@0 2353 NS_ASSERTION(aIndex < mResetCount, "out of range");
michael@0 2354 return &mResets[aIndex];
michael@0 2355 }
michael@0 2356
michael@0 2357 nsresult AllocateCounterResets(uint32_t aCount) {
michael@0 2358 if (aCount != mResetCount) {
michael@0 2359 DELETE_ARRAY_IF(mResets);
michael@0 2360 if (aCount) {
michael@0 2361 mResets = new nsStyleCounterData[aCount];
michael@0 2362 if (! mResets) {
michael@0 2363 mResetCount = 0;
michael@0 2364 return NS_ERROR_OUT_OF_MEMORY;
michael@0 2365 }
michael@0 2366 }
michael@0 2367 mResetCount = aCount;
michael@0 2368 }
michael@0 2369 return NS_OK;
michael@0 2370 }
michael@0 2371
michael@0 2372 nsresult SetCounterResetAt(uint32_t aIndex, const nsString& aCounter, int32_t aValue) {
michael@0 2373 if (aIndex < mResetCount) {
michael@0 2374 mResets[aIndex].mCounter = aCounter;
michael@0 2375 mResets[aIndex].mValue = aValue;
michael@0 2376 return NS_OK;
michael@0 2377 }
michael@0 2378 return NS_ERROR_ILLEGAL_VALUE;
michael@0 2379 }
michael@0 2380
michael@0 2381 nsStyleCoord mMarkerOffset; // [reset] coord, auto
michael@0 2382
michael@0 2383 protected:
michael@0 2384 nsStyleContentData* mContents;
michael@0 2385 nsStyleCounterData* mIncrements;
michael@0 2386 nsStyleCounterData* mResets;
michael@0 2387
michael@0 2388 uint32_t mContentCount;
michael@0 2389 uint32_t mIncrementCount;
michael@0 2390 uint32_t mResetCount;
michael@0 2391 };
michael@0 2392
michael@0 2393 struct nsStyleUIReset {
michael@0 2394 nsStyleUIReset(void);
michael@0 2395 nsStyleUIReset(const nsStyleUIReset& aOther);
michael@0 2396 ~nsStyleUIReset(void);
michael@0 2397
michael@0 2398 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2399 return aContext->AllocateFromShell(sz);
michael@0 2400 }
michael@0 2401 void Destroy(nsPresContext* aContext) {
michael@0 2402 this->~nsStyleUIReset();
michael@0 2403 aContext->FreeToShell(sizeof(nsStyleUIReset), this);
michael@0 2404 }
michael@0 2405
michael@0 2406 nsChangeHint CalcDifference(const nsStyleUIReset& aOther) const;
michael@0 2407 static nsChangeHint MaxDifference() {
michael@0 2408 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 2409 }
michael@0 2410 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2411 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2412 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2413 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2414 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2415 }
michael@0 2416
michael@0 2417 uint8_t mUserSelect; // [reset] (selection-style)
michael@0 2418 uint8_t mForceBrokenImageIcon; // [reset] (0 if not forcing, otherwise forcing)
michael@0 2419 uint8_t mIMEMode; // [reset]
michael@0 2420 uint8_t mWindowShadow; // [reset]
michael@0 2421 };
michael@0 2422
michael@0 2423 struct nsCursorImage {
michael@0 2424 bool mHaveHotspot;
michael@0 2425 float mHotspotX, mHotspotY;
michael@0 2426
michael@0 2427 nsCursorImage();
michael@0 2428 nsCursorImage(const nsCursorImage& aOther);
michael@0 2429 ~nsCursorImage();
michael@0 2430
michael@0 2431 nsCursorImage& operator=(const nsCursorImage& aOther);
michael@0 2432 /*
michael@0 2433 * We hide mImage and force access through the getter and setter so that we
michael@0 2434 * can lock the images we use. Cursor images are likely to be small, so we
michael@0 2435 * don't care about discarding them. See bug 512260.
michael@0 2436 * */
michael@0 2437 void SetImage(imgIRequest *aImage) {
michael@0 2438 if (mImage)
michael@0 2439 mImage->UnlockImage();
michael@0 2440 mImage = aImage;
michael@0 2441 if (mImage)
michael@0 2442 mImage->LockImage();
michael@0 2443 }
michael@0 2444 imgIRequest* GetImage() const {
michael@0 2445 return mImage;
michael@0 2446 }
michael@0 2447
michael@0 2448 private:
michael@0 2449 nsCOMPtr<imgIRequest> mImage;
michael@0 2450 };
michael@0 2451
michael@0 2452 struct nsStyleUserInterface {
michael@0 2453 nsStyleUserInterface(void);
michael@0 2454 nsStyleUserInterface(const nsStyleUserInterface& aOther);
michael@0 2455 ~nsStyleUserInterface(void);
michael@0 2456
michael@0 2457 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2458 return aContext->AllocateFromShell(sz);
michael@0 2459 }
michael@0 2460 void Destroy(nsPresContext* aContext) {
michael@0 2461 this->~nsStyleUserInterface();
michael@0 2462 aContext->FreeToShell(sizeof(nsStyleUserInterface), this);
michael@0 2463 }
michael@0 2464
michael@0 2465 nsChangeHint CalcDifference(const nsStyleUserInterface& aOther) const;
michael@0 2466 static nsChangeHint MaxDifference() {
michael@0 2467 return nsChangeHint(nsChangeHint_UpdateCursor | NS_STYLE_HINT_FRAMECHANGE);
michael@0 2468 }
michael@0 2469 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2470 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2471 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2472 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2473 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2474 }
michael@0 2475
michael@0 2476 uint8_t mUserInput; // [inherited]
michael@0 2477 uint8_t mUserModify; // [inherited] (modify-content)
michael@0 2478 uint8_t mUserFocus; // [inherited] (auto-select)
michael@0 2479
michael@0 2480 uint8_t mCursor; // [inherited] See nsStyleConsts.h
michael@0 2481
michael@0 2482 uint32_t mCursorArrayLength;
michael@0 2483 nsCursorImage *mCursorArray;// [inherited] The specified URL values
michael@0 2484 // and coordinates. Takes precedence over
michael@0 2485 // mCursor. Zero-length array is represented
michael@0 2486 // by null pointer.
michael@0 2487
michael@0 2488 // Does not free mCursorArray; the caller is responsible for calling
michael@0 2489 // |delete [] mCursorArray| first if it is needed.
michael@0 2490 void CopyCursorArrayFrom(const nsStyleUserInterface& aSource);
michael@0 2491 };
michael@0 2492
michael@0 2493 struct nsStyleXUL {
michael@0 2494 nsStyleXUL();
michael@0 2495 nsStyleXUL(const nsStyleXUL& aSource);
michael@0 2496 ~nsStyleXUL();
michael@0 2497
michael@0 2498 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2499 return aContext->AllocateFromShell(sz);
michael@0 2500 }
michael@0 2501 void Destroy(nsPresContext* aContext) {
michael@0 2502 this->~nsStyleXUL();
michael@0 2503 aContext->FreeToShell(sizeof(nsStyleXUL), this);
michael@0 2504 }
michael@0 2505
michael@0 2506 nsChangeHint CalcDifference(const nsStyleXUL& aOther) const;
michael@0 2507 static nsChangeHint MaxDifference() {
michael@0 2508 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 2509 }
michael@0 2510 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2511 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2512 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2513 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2514 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2515 }
michael@0 2516
michael@0 2517 float mBoxFlex; // [reset] see nsStyleConsts.h
michael@0 2518 uint32_t mBoxOrdinal; // [reset] see nsStyleConsts.h
michael@0 2519 uint8_t mBoxAlign; // [reset] see nsStyleConsts.h
michael@0 2520 uint8_t mBoxDirection; // [reset] see nsStyleConsts.h
michael@0 2521 uint8_t mBoxOrient; // [reset] see nsStyleConsts.h
michael@0 2522 uint8_t mBoxPack; // [reset] see nsStyleConsts.h
michael@0 2523 bool mStretchStack; // [reset] see nsStyleConsts.h
michael@0 2524 };
michael@0 2525
michael@0 2526 struct nsStyleColumn {
michael@0 2527 nsStyleColumn(nsPresContext* aPresContext);
michael@0 2528 nsStyleColumn(const nsStyleColumn& aSource);
michael@0 2529 ~nsStyleColumn();
michael@0 2530
michael@0 2531 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2532 return aContext->AllocateFromShell(sz);
michael@0 2533 }
michael@0 2534 void Destroy(nsPresContext* aContext) {
michael@0 2535 this->~nsStyleColumn();
michael@0 2536 aContext->FreeToShell(sizeof(nsStyleColumn), this);
michael@0 2537 }
michael@0 2538
michael@0 2539 nsChangeHint CalcDifference(const nsStyleColumn& aOther) const;
michael@0 2540 static nsChangeHint MaxDifference() {
michael@0 2541 return NS_STYLE_HINT_FRAMECHANGE;
michael@0 2542 }
michael@0 2543 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2544 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2545 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2546 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2547 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2548 }
michael@0 2549
michael@0 2550 /**
michael@0 2551 * This is the maximum number of columns we can process. It's used in both
michael@0 2552 * nsColumnSetFrame and nsRuleNode.
michael@0 2553 */
michael@0 2554 static const uint32_t kMaxColumnCount;
michael@0 2555
michael@0 2556 uint32_t mColumnCount; // [reset] see nsStyleConsts.h
michael@0 2557 nsStyleCoord mColumnWidth; // [reset] coord, auto
michael@0 2558 nsStyleCoord mColumnGap; // [reset] coord, normal
michael@0 2559
michael@0 2560 nscolor mColumnRuleColor; // [reset]
michael@0 2561 uint8_t mColumnRuleStyle; // [reset]
michael@0 2562 uint8_t mColumnFill; // [reset] see nsStyleConsts.h
michael@0 2563
michael@0 2564 // See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
michael@0 2565 // this is hard to replace with 'currentColor'.
michael@0 2566 bool mColumnRuleColorIsForeground;
michael@0 2567
michael@0 2568 void SetColumnRuleWidth(nscoord aWidth) {
michael@0 2569 mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
michael@0 2570 }
michael@0 2571
michael@0 2572 nscoord GetComputedColumnRuleWidth() const {
michael@0 2573 return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
michael@0 2574 }
michael@0 2575
michael@0 2576 protected:
michael@0 2577 nscoord mColumnRuleWidth; // [reset] coord
michael@0 2578 nscoord mTwipsPerPixel;
michael@0 2579 };
michael@0 2580
michael@0 2581 enum nsStyleSVGPaintType {
michael@0 2582 eStyleSVGPaintType_None = 1,
michael@0 2583 eStyleSVGPaintType_Color,
michael@0 2584 eStyleSVGPaintType_Server,
michael@0 2585 eStyleSVGPaintType_ContextFill,
michael@0 2586 eStyleSVGPaintType_ContextStroke
michael@0 2587 };
michael@0 2588
michael@0 2589 enum nsStyleSVGOpacitySource {
michael@0 2590 eStyleSVGOpacitySource_Normal,
michael@0 2591 eStyleSVGOpacitySource_ContextFillOpacity,
michael@0 2592 eStyleSVGOpacitySource_ContextStrokeOpacity
michael@0 2593 };
michael@0 2594
michael@0 2595 struct nsStyleSVGPaint
michael@0 2596 {
michael@0 2597 union {
michael@0 2598 nscolor mColor;
michael@0 2599 nsIURI *mPaintServer;
michael@0 2600 } mPaint;
michael@0 2601 nsStyleSVGPaintType mType;
michael@0 2602 nscolor mFallbackColor;
michael@0 2603
michael@0 2604 nsStyleSVGPaint() : mType(nsStyleSVGPaintType(0)) { mPaint.mPaintServer = nullptr; }
michael@0 2605 ~nsStyleSVGPaint();
michael@0 2606 void SetType(nsStyleSVGPaintType aType);
michael@0 2607 nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
michael@0 2608 bool operator==(const nsStyleSVGPaint& aOther) const;
michael@0 2609
michael@0 2610 bool operator!=(const nsStyleSVGPaint& aOther) const {
michael@0 2611 return !(*this == aOther);
michael@0 2612 }
michael@0 2613 };
michael@0 2614
michael@0 2615 struct nsStyleSVG {
michael@0 2616 nsStyleSVG();
michael@0 2617 nsStyleSVG(const nsStyleSVG& aSource);
michael@0 2618 ~nsStyleSVG();
michael@0 2619
michael@0 2620 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2621 return aContext->AllocateFromShell(sz);
michael@0 2622 }
michael@0 2623 void Destroy(nsPresContext* aContext) {
michael@0 2624 this->~nsStyleSVG();
michael@0 2625 aContext->FreeToShell(sizeof(nsStyleSVG), this);
michael@0 2626 }
michael@0 2627
michael@0 2628 nsChangeHint CalcDifference(const nsStyleSVG& aOther) const;
michael@0 2629 static nsChangeHint MaxDifference() {
michael@0 2630 return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects,
michael@0 2631 NS_CombineHint(nsChangeHint_NeedReflow, nsChangeHint_NeedDirtyReflow)), // XXX remove nsChangeHint_NeedDirtyReflow: bug 876085
michael@0 2632 nsChangeHint_RepaintFrame);
michael@0 2633 }
michael@0 2634 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2635 // CalcDifference never returns nsChangeHint_NeedReflow as an inherited hint
michael@0 2636 // and never returns nsChangeHint_ClearAncestorIntrinsics at all.
michael@0 2637 return nsChangeHint_NeedReflow;
michael@0 2638 }
michael@0 2639
michael@0 2640 nsStyleSVGPaint mFill; // [inherited]
michael@0 2641 nsStyleSVGPaint mStroke; // [inherited]
michael@0 2642 nsCOMPtr<nsIURI> mMarkerEnd; // [inherited]
michael@0 2643 nsCOMPtr<nsIURI> mMarkerMid; // [inherited]
michael@0 2644 nsCOMPtr<nsIURI> mMarkerStart; // [inherited]
michael@0 2645 nsStyleCoord *mStrokeDasharray; // [inherited] coord, percent, factor
michael@0 2646
michael@0 2647 nsStyleCoord mStrokeDashoffset; // [inherited] coord, percent, factor
michael@0 2648 nsStyleCoord mStrokeWidth; // [inherited] coord, percent, factor
michael@0 2649
michael@0 2650 float mFillOpacity; // [inherited]
michael@0 2651 float mStrokeMiterlimit; // [inherited]
michael@0 2652 float mStrokeOpacity; // [inherited]
michael@0 2653
michael@0 2654 uint32_t mStrokeDasharrayLength;
michael@0 2655 uint8_t mClipRule; // [inherited]
michael@0 2656 uint8_t mColorInterpolation; // [inherited] see nsStyleConsts.h
michael@0 2657 uint8_t mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
michael@0 2658 uint8_t mFillRule; // [inherited] see nsStyleConsts.h
michael@0 2659 uint8_t mImageRendering; // [inherited] see nsStyleConsts.h
michael@0 2660 uint8_t mPaintOrder; // [inherited] see nsStyleConsts.h
michael@0 2661 uint8_t mShapeRendering; // [inherited] see nsStyleConsts.h
michael@0 2662 uint8_t mStrokeLinecap; // [inherited] see nsStyleConsts.h
michael@0 2663 uint8_t mStrokeLinejoin; // [inherited] see nsStyleConsts.h
michael@0 2664 uint8_t mTextAnchor; // [inherited] see nsStyleConsts.h
michael@0 2665 uint8_t mTextRendering; // [inherited] see nsStyleConsts.h
michael@0 2666
michael@0 2667 // In SVG glyphs, whether we inherit fill or stroke opacity from the outer
michael@0 2668 // text object.
michael@0 2669 // Use 3 bits to avoid signedness problems in MSVC.
michael@0 2670 nsStyleSVGOpacitySource mFillOpacitySource : 3;
michael@0 2671 nsStyleSVGOpacitySource mStrokeOpacitySource : 3;
michael@0 2672
michael@0 2673 // SVG glyph outer object inheritance for other properties
michael@0 2674 bool mStrokeDasharrayFromObject : 1;
michael@0 2675 bool mStrokeDashoffsetFromObject : 1;
michael@0 2676 bool mStrokeWidthFromObject : 1;
michael@0 2677
michael@0 2678 bool HasMarker() const {
michael@0 2679 return mMarkerStart || mMarkerMid || mMarkerEnd;
michael@0 2680 }
michael@0 2681
michael@0 2682 /**
michael@0 2683 * Returns true if the stroke is not "none" and the stroke-opacity is greater
michael@0 2684 * than zero. This ignores stroke-widths as that depends on the context.
michael@0 2685 */
michael@0 2686 bool HasStroke() const {
michael@0 2687 return mStroke.mType != eStyleSVGPaintType_None && mStrokeOpacity > 0;
michael@0 2688 }
michael@0 2689
michael@0 2690 /**
michael@0 2691 * Returns true if the fill is not "none" and the fill-opacity is greater
michael@0 2692 * than zero.
michael@0 2693 */
michael@0 2694 bool HasFill() const {
michael@0 2695 return mFill.mType != eStyleSVGPaintType_None && mFillOpacity > 0;
michael@0 2696 }
michael@0 2697 };
michael@0 2698
michael@0 2699 struct nsStyleFilter {
michael@0 2700 nsStyleFilter();
michael@0 2701 nsStyleFilter(const nsStyleFilter& aSource);
michael@0 2702 ~nsStyleFilter();
michael@0 2703
michael@0 2704 nsStyleFilter& operator=(const nsStyleFilter& aOther);
michael@0 2705
michael@0 2706 bool operator==(const nsStyleFilter& aOther) const;
michael@0 2707
michael@0 2708 int32_t GetType() const {
michael@0 2709 return mType;
michael@0 2710 }
michael@0 2711
michael@0 2712 const nsStyleCoord& GetFilterParameter() const {
michael@0 2713 NS_ASSERTION(mType != NS_STYLE_FILTER_DROP_SHADOW &&
michael@0 2714 mType != NS_STYLE_FILTER_URL &&
michael@0 2715 mType != NS_STYLE_FILTER_NONE, "wrong filter type");
michael@0 2716 return mFilterParameter;
michael@0 2717 }
michael@0 2718 void SetFilterParameter(const nsStyleCoord& aFilterParameter,
michael@0 2719 int32_t aType);
michael@0 2720
michael@0 2721 nsIURI* GetURL() const {
michael@0 2722 NS_ASSERTION(mType == NS_STYLE_FILTER_URL, "wrong filter type");
michael@0 2723 return mURL;
michael@0 2724 }
michael@0 2725 void SetURL(nsIURI* aURL);
michael@0 2726
michael@0 2727 nsCSSShadowArray* GetDropShadow() const {
michael@0 2728 NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type");
michael@0 2729 return mDropShadow;
michael@0 2730 }
michael@0 2731 void SetDropShadow(nsCSSShadowArray* aDropShadow);
michael@0 2732
michael@0 2733 private:
michael@0 2734 void ReleaseRef();
michael@0 2735
michael@0 2736 int32_t mType; // see NS_STYLE_FILTER_* constants in nsStyleConsts.h
michael@0 2737 nsStyleCoord mFilterParameter; // coord, percent, factor, angle
michael@0 2738 union {
michael@0 2739 nsIURI* mURL;
michael@0 2740 nsCSSShadowArray* mDropShadow;
michael@0 2741 };
michael@0 2742 };
michael@0 2743
michael@0 2744 template<>
michael@0 2745 struct nsTArray_CopyChooser<nsStyleFilter> {
michael@0 2746 typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
michael@0 2747 };
michael@0 2748
michael@0 2749 struct nsStyleSVGReset {
michael@0 2750 nsStyleSVGReset();
michael@0 2751 nsStyleSVGReset(const nsStyleSVGReset& aSource);
michael@0 2752 ~nsStyleSVGReset();
michael@0 2753
michael@0 2754 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2755 return aContext->AllocateFromShell(sz);
michael@0 2756 }
michael@0 2757 void Destroy(nsPresContext* aContext) {
michael@0 2758 this->~nsStyleSVGReset();
michael@0 2759 aContext->FreeToShell(sizeof(nsStyleSVGReset), this);
michael@0 2760 }
michael@0 2761
michael@0 2762 nsChangeHint CalcDifference(const nsStyleSVGReset& aOther) const;
michael@0 2763 static nsChangeHint MaxDifference() {
michael@0 2764 return NS_CombineHint(nsChangeHint_UpdateEffects,
michael@0 2765 NS_CombineHint(nsChangeHint_UpdateOverflow, NS_STYLE_HINT_REFLOW));
michael@0 2766 }
michael@0 2767 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2768 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2769 // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
michael@0 2770 return NS_CombineHint(nsChangeHint_NeedReflow,
michael@0 2771 nsChangeHint_ClearAncestorIntrinsics);
michael@0 2772 }
michael@0 2773
michael@0 2774 bool HasFilters() const {
michael@0 2775 return mFilters.Length() > 0;
michael@0 2776 }
michael@0 2777
michael@0 2778 nsCOMPtr<nsIURI> mClipPath; // [reset]
michael@0 2779 nsTArray<nsStyleFilter> mFilters; // [reset]
michael@0 2780 nsCOMPtr<nsIURI> mMask; // [reset]
michael@0 2781 nscolor mStopColor; // [reset]
michael@0 2782 nscolor mFloodColor; // [reset]
michael@0 2783 nscolor mLightingColor; // [reset]
michael@0 2784
michael@0 2785 float mStopOpacity; // [reset]
michael@0 2786 float mFloodOpacity; // [reset]
michael@0 2787
michael@0 2788 uint8_t mDominantBaseline; // [reset] see nsStyleConsts.h
michael@0 2789 uint8_t mVectorEffect; // [reset] see nsStyleConsts.h
michael@0 2790 uint8_t mMaskType; // [reset] see nsStyleConsts.h
michael@0 2791 };
michael@0 2792
michael@0 2793 struct nsStyleVariables {
michael@0 2794 nsStyleVariables();
michael@0 2795 nsStyleVariables(const nsStyleVariables& aSource);
michael@0 2796 ~nsStyleVariables();
michael@0 2797
michael@0 2798 void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
michael@0 2799 return aContext->AllocateFromShell(sz);
michael@0 2800 }
michael@0 2801 void Destroy(nsPresContext* aContext) {
michael@0 2802 this->~nsStyleVariables();
michael@0 2803 aContext->FreeToShell(sizeof(nsStyleVariables), this);
michael@0 2804 }
michael@0 2805
michael@0 2806 nsChangeHint CalcDifference(const nsStyleVariables& aOther) const;
michael@0 2807 static nsChangeHint MaxDifference() {
michael@0 2808 return nsChangeHint(0);
michael@0 2809 }
michael@0 2810 static nsChangeHint MaxDifferenceNeverInherited() {
michael@0 2811 // CalcDifference never returns nsChangeHint_NeedReflow or
michael@0 2812 // nsChangeHint_ClearAncestorIntrinsics at all.
michael@0 2813 return nsChangeHint(0);
michael@0 2814 }
michael@0 2815
michael@0 2816 mozilla::CSSVariableValues mVariables;
michael@0 2817 };
michael@0 2818
michael@0 2819 #endif /* nsStyleStruct_h___ */

mercurial