layout/style/nsStyleStruct.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/style/nsStyleStruct.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2819 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/*
    1.10 + * structs that contain the data provided by nsStyleContext, the
    1.11 + * internal API for computed style data for an element
    1.12 + */
    1.13 +
    1.14 +#ifndef nsStyleStruct_h___
    1.15 +#define nsStyleStruct_h___
    1.16 +
    1.17 +#include "mozilla/Attributes.h"
    1.18 +#include "mozilla/CSSVariableValues.h"
    1.19 +#include "nsColor.h"
    1.20 +#include "nsCoord.h"
    1.21 +#include "nsMargin.h"
    1.22 +#include "nsRect.h"
    1.23 +#include "nsFont.h"
    1.24 +#include "nsStyleCoord.h"
    1.25 +#include "nsStyleConsts.h"
    1.26 +#include "nsChangeHint.h"
    1.27 +#include "nsPresContext.h"
    1.28 +#include "nsCOMPtr.h"
    1.29 +#include "nsCOMArray.h"
    1.30 +#include "nsTArray.h"
    1.31 +#include "nsIAtom.h"
    1.32 +#include "nsCSSValue.h"
    1.33 +#include "imgRequestProxy.h"
    1.34 +#include "Orientation.h"
    1.35 +#include <algorithm>
    1.36 +
    1.37 +class nsIFrame;
    1.38 +class nsIURI;
    1.39 +class imgIContainer;
    1.40 +
    1.41 +// Includes nsStyleStructID.
    1.42 +#include "nsStyleStructFwd.h"
    1.43 +
    1.44 +// Bits for each struct.
    1.45 +// NS_STYLE_INHERIT_BIT defined in nsStyleStructFwd.h
    1.46 +#define NS_STYLE_INHERIT_MASK              0x000ffffff
    1.47 +
    1.48 +// Additional bits for nsStyleContext's mBits:
    1.49 +// See nsStyleContext::HasTextDecorationLines
    1.50 +#define NS_STYLE_HAS_TEXT_DECORATION_LINES 0x001000000
    1.51 +// See nsStyleContext::HasPseudoElementData.
    1.52 +#define NS_STYLE_HAS_PSEUDO_ELEMENT_DATA   0x002000000
    1.53 +// See nsStyleContext::RelevantLinkIsVisited
    1.54 +#define NS_STYLE_RELEVANT_LINK_VISITED     0x004000000
    1.55 +// See nsStyleContext::IsStyleIfVisited
    1.56 +#define NS_STYLE_IS_STYLE_IF_VISITED       0x008000000
    1.57 +// See nsStyleContext::GetPseudoEnum
    1.58 +#define NS_STYLE_CONTEXT_TYPE_MASK         0x1f0000000
    1.59 +#define NS_STYLE_CONTEXT_TYPE_SHIFT        28
    1.60 +
    1.61 +// Additional bits for nsRuleNode's mDependentBits:
    1.62 +#define NS_RULE_NODE_GC_MARK                0x02000000
    1.63 +#define NS_RULE_NODE_USED_DIRECTLY          0x04000000
    1.64 +#define NS_RULE_NODE_IS_IMPORTANT           0x08000000
    1.65 +#define NS_RULE_NODE_LEVEL_MASK             0xf0000000
    1.66 +#define NS_RULE_NODE_LEVEL_SHIFT            28
    1.67 +
    1.68 +// The lifetime of these objects is managed by the presshell's arena.
    1.69 +
    1.70 +struct nsStyleFont {
    1.71 +  nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext);
    1.72 +  nsStyleFont(const nsStyleFont& aStyleFont);
    1.73 +  nsStyleFont(nsPresContext *aPresContext);
    1.74 +private:
    1.75 +  void Init(nsPresContext *aPresContext);
    1.76 +public:
    1.77 +  ~nsStyleFont(void) {
    1.78 +    MOZ_COUNT_DTOR(nsStyleFont);
    1.79 +  }
    1.80 +
    1.81 +  nsChangeHint CalcDifference(const nsStyleFont& aOther) const;
    1.82 +  static nsChangeHint MaxDifference() {
    1.83 +    return NS_STYLE_HINT_REFLOW;
    1.84 +  }
    1.85 +  static nsChangeHint MaxDifferenceNeverInherited() {
    1.86 +    // CalcDifference never returns nsChangeHint_NeedReflow or
    1.87 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
    1.88 +    return NS_CombineHint(nsChangeHint_NeedReflow,
    1.89 +                          nsChangeHint_ClearAncestorIntrinsics);
    1.90 +  }
    1.91 +  static nsChangeHint CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
    1.92 +
    1.93 +  static nscoord ZoomText(nsPresContext* aPresContext, nscoord aSize);
    1.94 +  static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
    1.95 +
    1.96 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
    1.97 +  void Destroy(nsPresContext* aContext);
    1.98 +
    1.99 +  void EnableZoom(nsPresContext* aContext, bool aEnable);
   1.100 +
   1.101 +  nsFont  mFont;        // [inherited]
   1.102 +  nscoord mSize;        // [inherited] Our "computed size". Can be different
   1.103 +                        // from mFont.size which is our "actual size" and is
   1.104 +                        // enforced to be >= the user's preferred min-size.
   1.105 +                        // mFont.size should be used for display purposes
   1.106 +                        // while mSize is the value to return in
   1.107 +                        // getComputedStyle() for example.
   1.108 +  uint8_t mGenericID;   // [inherited] generic CSS font family, if any;
   1.109 +                        // value is a kGenericFont_* constant, see nsFont.h.
   1.110 +
   1.111 +  // MathML scriptlevel support
   1.112 +  int8_t  mScriptLevel;          // [inherited]
   1.113 +  // MathML  mathvariant support
   1.114 +  uint8_t mMathVariant;          // [inherited]
   1.115 +  // MathML displaystyle support
   1.116 +  uint8_t mMathDisplay;         // [inherited]
   1.117 +
   1.118 +  // was mLanguage set based on a lang attribute in the document?
   1.119 +  bool mExplicitLanguage;        // [inherited]
   1.120 +
   1.121 +  // should calls to ZoomText() and UnZoomText() be made to the font
   1.122 +  // size on this nsStyleFont?
   1.123 +  bool mAllowZoom;               // [inherited]
   1.124 +
   1.125 +  // The value mSize would have had if scriptminsize had never been applied
   1.126 +  nscoord mScriptUnconstrainedSize;
   1.127 +  nscoord mScriptMinSize;        // [inherited] length
   1.128 +  float   mScriptSizeMultiplier; // [inherited]
   1.129 +  nsCOMPtr<nsIAtom> mLanguage;   // [inherited]
   1.130 +};
   1.131 +
   1.132 +struct nsStyleGradientStop {
   1.133 +  nsStyleCoord mLocation; // percent, coord, calc, none
   1.134 +  nscolor mColor;
   1.135 +};
   1.136 +
   1.137 +class nsStyleGradient MOZ_FINAL {
   1.138 +public:
   1.139 +  nsStyleGradient();
   1.140 +  uint8_t mShape;  // NS_STYLE_GRADIENT_SHAPE_*
   1.141 +  uint8_t mSize;   // NS_STYLE_GRADIENT_SIZE_*;
   1.142 +                   // not used (must be FARTHEST_CORNER) for linear shape
   1.143 +  bool mRepeating;
   1.144 +  bool mLegacySyntax;
   1.145 +
   1.146 +  nsStyleCoord mBgPosX; // percent, coord, calc, none
   1.147 +  nsStyleCoord mBgPosY; // percent, coord, calc, none
   1.148 +  nsStyleCoord mAngle;  // none, angle
   1.149 +
   1.150 +  nsStyleCoord mRadiusX; // percent, coord, calc, none
   1.151 +  nsStyleCoord mRadiusY; // percent, coord, calc, none
   1.152 +
   1.153 +  // stops are in the order specified in the stylesheet
   1.154 +  nsTArray<nsStyleGradientStop> mStops;
   1.155 +
   1.156 +  bool operator==(const nsStyleGradient& aOther) const;
   1.157 +  bool operator!=(const nsStyleGradient& aOther) const {
   1.158 +    return !(*this == aOther);
   1.159 +  }
   1.160 +
   1.161 +  bool IsOpaque();
   1.162 +  bool HasCalc();
   1.163 +  uint32_t Hash(PLDHashNumber aHash);
   1.164 +
   1.165 +  NS_INLINE_DECL_REFCOUNTING(nsStyleGradient)
   1.166 +
   1.167 +private:
   1.168 +  // Private destructor, to discourage deletion outside of Release():
   1.169 +  ~nsStyleGradient() {}
   1.170 +
   1.171 +  nsStyleGradient(const nsStyleGradient& aOther) MOZ_DELETE;
   1.172 +  nsStyleGradient& operator=(const nsStyleGradient& aOther) MOZ_DELETE;
   1.173 +};
   1.174 +
   1.175 +enum nsStyleImageType {
   1.176 +  eStyleImageType_Null,
   1.177 +  eStyleImageType_Image,
   1.178 +  eStyleImageType_Gradient,
   1.179 +  eStyleImageType_Element
   1.180 +};
   1.181 +
   1.182 +/**
   1.183 + * Represents a paintable image of one of the following types.
   1.184 + * (1) A real image loaded from an external source.
   1.185 + * (2) A CSS linear or radial gradient.
   1.186 + * (3) An element within a document, or an <img>, <video>, or <canvas> element
   1.187 + *     not in a document.
   1.188 + * (*) Optionally a crop rect can be set to paint a partial (rectangular)
   1.189 + * region of an image. (Currently, this feature is only supported with an
   1.190 + * image of type (1)).
   1.191 + */
   1.192 +struct nsStyleImage {
   1.193 +  nsStyleImage();
   1.194 +  ~nsStyleImage();
   1.195 +  nsStyleImage(const nsStyleImage& aOther);
   1.196 +  nsStyleImage& operator=(const nsStyleImage& aOther);
   1.197 +
   1.198 +  void SetNull();
   1.199 +  void SetImageData(imgIRequest* aImage);
   1.200 +  void TrackImage(nsPresContext* aContext);
   1.201 +  void UntrackImage(nsPresContext* aContext);
   1.202 +  void SetGradientData(nsStyleGradient* aGradient);
   1.203 +  void SetElementId(const char16_t* aElementId);
   1.204 +  void SetCropRect(nsStyleSides* aCropRect);
   1.205 +
   1.206 +  nsStyleImageType GetType() const {
   1.207 +    return mType;
   1.208 +  }
   1.209 +  imgIRequest* GetImageData() const {
   1.210 +    NS_ABORT_IF_FALSE(mType == eStyleImageType_Image, "Data is not an image!");
   1.211 +    NS_ABORT_IF_FALSE(mImageTracked,
   1.212 +                      "Should be tracking any image we're going to use!");
   1.213 +    return mImage;
   1.214 +  }
   1.215 +  nsStyleGradient* GetGradientData() const {
   1.216 +    NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
   1.217 +    return mGradient;
   1.218 +  }
   1.219 +  const char16_t* GetElementId() const {
   1.220 +    NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
   1.221 +    return mElementId;
   1.222 +  }
   1.223 +  nsStyleSides* GetCropRect() const {
   1.224 +    NS_ASSERTION(mType == eStyleImageType_Image,
   1.225 +                 "Only image data can have a crop rect");
   1.226 +    return mCropRect;
   1.227 +  }
   1.228 +
   1.229 +  /**
   1.230 +   * Compute the actual crop rect in pixels, using the source image bounds.
   1.231 +   * The computation involves converting percentage unit to pixel unit and
   1.232 +   * clamping each side value to fit in the source image bounds.
   1.233 +   * @param aActualCropRect the computed actual crop rect.
   1.234 +   * @param aIsEntireImage true iff |aActualCropRect| is identical to the
   1.235 +   * source image bounds.
   1.236 +   * @return true iff |aActualCropRect| holds a meaningful value.
   1.237 +   */
   1.238 +  bool ComputeActualCropRect(nsIntRect& aActualCropRect,
   1.239 +                               bool* aIsEntireImage = nullptr) const;
   1.240 +
   1.241 +  /**
   1.242 +   * Starts the decoding of a image.
   1.243 +   */
   1.244 +  nsresult StartDecoding() const;
   1.245 +  /**
   1.246 +   * @return true if the item is definitely opaque --- i.e., paints every
   1.247 +   * pixel within its bounds opaquely, and the bounds contains at least a pixel.
   1.248 +   */
   1.249 +  bool IsOpaque() const;
   1.250 +  /**
   1.251 +   * @return true if this image is fully loaded, and its size is calculated;
   1.252 +   * always returns true if |mType| is |eStyleImageType_Gradient| or
   1.253 +   * |eStyleImageType_Element|.
   1.254 +   */
   1.255 +  bool IsComplete() const;
   1.256 +  /**
   1.257 +   * @return true if this image is loaded without error;
   1.258 +   * always returns true if |mType| is |eStyleImageType_Gradient| or
   1.259 +   * |eStyleImageType_Element|.
   1.260 +   */
   1.261 +  bool IsLoaded() const;
   1.262 +  /**
   1.263 +   * @return true if it is 100% confident that this image contains no pixel
   1.264 +   * to draw.
   1.265 +   */
   1.266 +  bool IsEmpty() const {
   1.267 +    // There are some other cases when the image will be empty, for example
   1.268 +    // when the crop rect is empty. However, checking the emptiness of crop
   1.269 +    // rect is non-trivial since each side value can be specified with
   1.270 +    // percentage unit, which can not be evaluated until the source image size
   1.271 +    // is available. Therefore, we currently postpone the evaluation of crop
   1.272 +    // rect until the actual rendering time --- alternatively until GetOpaqueRegion()
   1.273 +    // is called.
   1.274 +    return mType == eStyleImageType_Null;
   1.275 +  }
   1.276 +
   1.277 +  bool operator==(const nsStyleImage& aOther) const;
   1.278 +  bool operator!=(const nsStyleImage& aOther) const {
   1.279 +    return !(*this == aOther);
   1.280 +  }
   1.281 +
   1.282 +  bool ImageDataEquals(const nsStyleImage& aOther) const
   1.283 +  {
   1.284 +    return GetType() == eStyleImageType_Image &&
   1.285 +           aOther.GetType() == eStyleImageType_Image &&
   1.286 +           GetImageData() == aOther.GetImageData();
   1.287 +  }
   1.288 +
   1.289 +  // These methods are used for the caller to caches the sub images created
   1.290 +  // during a border-image paint operation
   1.291 +  inline void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) const;
   1.292 +  inline imgIContainer* GetSubImage(uint8_t aIndex) const;
   1.293 +
   1.294 +private:
   1.295 +  void DoCopy(const nsStyleImage& aOther);
   1.296 +
   1.297 +  // Cache for border-image painting.
   1.298 +  nsCOMArray<imgIContainer> mSubImages;
   1.299 +
   1.300 +  nsStyleImageType mType;
   1.301 +  union {
   1.302 +    imgIRequest* mImage;
   1.303 +    nsStyleGradient* mGradient;
   1.304 +    char16_t* mElementId;
   1.305 +  };
   1.306 +  // This is _currently_ used only in conjunction with eStyleImageType_Image.
   1.307 +  nsAutoPtr<nsStyleSides> mCropRect;
   1.308 +#ifdef DEBUG
   1.309 +  bool mImageTracked;
   1.310 +#endif
   1.311 +};
   1.312 +
   1.313 +struct nsStyleColor {
   1.314 +  nsStyleColor(nsPresContext* aPresContext);
   1.315 +  nsStyleColor(const nsStyleColor& aOther);
   1.316 +  ~nsStyleColor(void) {
   1.317 +    MOZ_COUNT_DTOR(nsStyleColor);
   1.318 +  }
   1.319 +
   1.320 +  nsChangeHint CalcDifference(const nsStyleColor& aOther) const;
   1.321 +  static nsChangeHint MaxDifference() {
   1.322 +    return NS_STYLE_HINT_VISUAL;
   1.323 +  }
   1.324 +  static nsChangeHint MaxDifferenceNeverInherited() {
   1.325 +    // CalcDifference never returns nsChangeHint_NeedReflow or
   1.326 +    // nsChangeHint_ClearAncestorIntrinsics at all.
   1.327 +    return nsChangeHint(0);
   1.328 +  }
   1.329 +
   1.330 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
   1.331 +    return aContext->AllocateFromShell(sz);
   1.332 +  }
   1.333 +  void Destroy(nsPresContext* aContext) {
   1.334 +    this->~nsStyleColor();
   1.335 +    aContext->FreeToShell(sizeof(nsStyleColor), this);
   1.336 +  }
   1.337 +
   1.338 +  // Don't add ANY members to this struct!  We can achieve caching in the rule
   1.339 +  // tree (rather than the style tree) by letting color stay by itself! -dwh
   1.340 +  nscolor mColor;                 // [inherited]
   1.341 +};
   1.342 +
   1.343 +struct nsStyleBackground {
   1.344 +  nsStyleBackground();
   1.345 +  nsStyleBackground(const nsStyleBackground& aOther);
   1.346 +  ~nsStyleBackground();
   1.347 +
   1.348 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
   1.349 +    return aContext->AllocateFromShell(sz);
   1.350 +  }
   1.351 +  void Destroy(nsPresContext* aContext);
   1.352 +
   1.353 +  nsChangeHint CalcDifference(const nsStyleBackground& aOther) const;
   1.354 +  static nsChangeHint MaxDifference() {
   1.355 +    return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
   1.356 +  }
   1.357 +  static nsChangeHint MaxDifferenceNeverInherited() {
   1.358 +    // CalcDifference never returns nsChangeHint_NeedReflow or
   1.359 +    // nsChangeHint_ClearAncestorIntrinsics at all.
   1.360 +    return nsChangeHint(0);
   1.361 +  }
   1.362 +
   1.363 +  struct Position;
   1.364 +  friend struct Position;
   1.365 +  struct Position {
   1.366 +    typedef nsStyleCoord::Calc PositionCoord;
   1.367 +    PositionCoord mXPosition, mYPosition;
   1.368 +
   1.369 +    // Initialize nothing
   1.370 +    Position() {}
   1.371 +
   1.372 +    // Initialize to initial values
   1.373 +    void SetInitialValues();
   1.374 +
   1.375 +    // True if the effective background image position described by this depends
   1.376 +    // on the size of the corresponding frame.
   1.377 +    bool DependsOnPositioningAreaSize() const {
   1.378 +      return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
   1.379 +    }
   1.380 +
   1.381 +    bool operator==(const Position& aOther) const {
   1.382 +      return mXPosition == aOther.mXPosition &&
   1.383 +             mYPosition == aOther.mYPosition;
   1.384 +    }
   1.385 +    bool operator!=(const Position& aOther) const {
   1.386 +      return !(*this == aOther);
   1.387 +    }
   1.388 +  };
   1.389 +
   1.390 +  struct Size;
   1.391 +  friend struct Size;
   1.392 +  struct Size {
   1.393 +    struct Dimension : public nsStyleCoord::Calc {
   1.394 +      nscoord ResolveLengthPercentage(nscoord aAvailable) const {
   1.395 +        double d = double(mPercent) * double(aAvailable) + double(mLength);
   1.396 +        if (d < 0.0)
   1.397 +          return 0;
   1.398 +        return NSToCoordRoundWithClamp(float(d));
   1.399 +      }
   1.400 +    };
   1.401 +    Dimension mWidth, mHeight;
   1.402 +
   1.403 +    nscoord ResolveWidthLengthPercentage(const nsSize& aBgPositioningArea) const {
   1.404 +      NS_ABORT_IF_FALSE(mWidthType == eLengthPercentage,
   1.405 +                        "resolving non-length/percent dimension!");
   1.406 +      return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
   1.407 +    }
   1.408 +
   1.409 +    nscoord ResolveHeightLengthPercentage(const nsSize& aBgPositioningArea) const {
   1.410 +      NS_ABORT_IF_FALSE(mHeightType == eLengthPercentage,
   1.411 +                        "resolving non-length/percent dimension!");
   1.412 +      return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
   1.413 +    }
   1.414 +
   1.415 +    // Except for eLengthPercentage, Dimension types which might change
   1.416 +    // how a layer is painted when the corresponding frame's dimensions
   1.417 +    // change *must* precede all dimension types which are agnostic to
   1.418 +    // frame size; see DependsOnDependsOnPositioningAreaSizeSize.
   1.419 +    enum DimensionType {
   1.420 +      // If one of mWidth and mHeight is eContain or eCover, then both are.
   1.421 +      // Also, these two values must equal the corresponding values in
   1.422 +      // kBackgroundSizeKTable.
   1.423 +      eContain, eCover,
   1.424 +
   1.425 +      eAuto,
   1.426 +      eLengthPercentage,
   1.427 +      eDimensionType_COUNT
   1.428 +    };
   1.429 +    uint8_t mWidthType, mHeightType;
   1.430 +
   1.431 +    // True if the effective image size described by this depends on the size of
   1.432 +    // the corresponding frame, when aImage (which must not have null type) is
   1.433 +    // the background image.
   1.434 +    bool DependsOnPositioningAreaSize(const nsStyleImage& aImage) const;
   1.435 +
   1.436 +    // Initialize nothing
   1.437 +    Size() {}
   1.438 +
   1.439 +    // Initialize to initial values
   1.440 +    void SetInitialValues();
   1.441 +
   1.442 +    bool operator==(const Size& aOther) const;
   1.443 +    bool operator!=(const Size& aOther) const {
   1.444 +      return !(*this == aOther);
   1.445 +    }
   1.446 +  };
   1.447 +  
   1.448 +  struct Repeat;
   1.449 +  friend struct Repeat;
   1.450 +  struct Repeat {
   1.451 +    uint8_t mXRepeat, mYRepeat;
   1.452 +    
   1.453 +    // Initialize nothing
   1.454 +    Repeat() {}
   1.455 +
   1.456 +    // Initialize to initial values
   1.457 +    void SetInitialValues();
   1.458 +
   1.459 +    bool operator==(const Repeat& aOther) const {
   1.460 +      return mXRepeat == aOther.mXRepeat &&
   1.461 +             mYRepeat == aOther.mYRepeat;
   1.462 +    }
   1.463 +    bool operator!=(const Repeat& aOther) const {
   1.464 +      return !(*this == aOther);
   1.465 +    }
   1.466 +  };
   1.467 +
   1.468 +  struct Layer;
   1.469 +  friend struct Layer;
   1.470 +  struct Layer {
   1.471 +    uint8_t mAttachment;                // [reset] See nsStyleConsts.h
   1.472 +    uint8_t mClip;                      // [reset] See nsStyleConsts.h
   1.473 +    uint8_t mOrigin;                    // [reset] See nsStyleConsts.h
   1.474 +    uint8_t mBlendMode;                 // [reset] See nsStyleConsts.h
   1.475 +    Repeat mRepeat;                     // [reset] See nsStyleConsts.h
   1.476 +    Position mPosition;                 // [reset]
   1.477 +    nsStyleImage mImage;                // [reset]
   1.478 +    Size mSize;                         // [reset]
   1.479 +
   1.480 +    // Initializes only mImage
   1.481 +    Layer();
   1.482 +    ~Layer();
   1.483 +
   1.484 +    // Register/unregister images with the document. We do this only
   1.485 +    // after the dust has settled in ComputeBackgroundData.
   1.486 +    void TrackImages(nsPresContext* aContext) {
   1.487 +      if (mImage.GetType() == eStyleImageType_Image)
   1.488 +        mImage.TrackImage(aContext);
   1.489 +    }
   1.490 +    void UntrackImages(nsPresContext* aContext) {
   1.491 +      if (mImage.GetType() == eStyleImageType_Image)
   1.492 +        mImage.UntrackImage(aContext);
   1.493 +    }
   1.494 +
   1.495 +    void SetInitialValues();
   1.496 +
   1.497 +    // True if the rendering of this layer might change when the size
   1.498 +    // of the background positioning area changes.  This is true for any
   1.499 +    // non-solid-color background whose position or size depends on
   1.500 +    // the size of the positioning area.  It's also true for SVG images
   1.501 +    // whose root <svg> node has a viewBox.
   1.502 +    bool RenderingMightDependOnPositioningAreaSizeChange() const;
   1.503 +
   1.504 +    // An equality operator that compares the images using URL-equality
   1.505 +    // rather than pointer-equality.
   1.506 +    bool operator==(const Layer& aOther) const;
   1.507 +    bool operator!=(const Layer& aOther) const {
   1.508 +      return !(*this == aOther);
   1.509 +    }
   1.510 +  };
   1.511 +
   1.512 +  // The (positive) number of computed values of each property, since
   1.513 +  // the lengths of the lists are independent.
   1.514 +  uint32_t mAttachmentCount,
   1.515 +           mClipCount,
   1.516 +           mOriginCount,
   1.517 +           mRepeatCount,
   1.518 +           mPositionCount,
   1.519 +           mImageCount,
   1.520 +           mSizeCount,
   1.521 +           mBlendModeCount;
   1.522 +  // Layers are stored in an array, matching the top-to-bottom order in
   1.523 +  // which they are specified in CSS.  The number of layers to be used
   1.524 +  // should come from the background-image property.  We create
   1.525 +  // additional |Layer| objects for *any* property, not just
   1.526 +  // background-image.  This means that the bottommost layer that
   1.527 +  // callers in layout care about (which is also the one whose
   1.528 +  // background-clip applies to the background-color) may not be last
   1.529 +  // layer.  In layers below the bottom layer, properties will be
   1.530 +  // uninitialized unless their count, above, indicates that they are
   1.531 +  // present.
   1.532 +  nsAutoTArray<Layer, 1> mLayers;
   1.533 +
   1.534 +  const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
   1.535 +
   1.536 +  #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
   1.537 +    for (uint32_t var_ = (stylebg_) ? (stylebg_)->mImageCount : 1; var_-- != 0; )
   1.538 +  #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, stylebg_, start_, count_) \
   1.539 +    NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < ((stylebg_) ? (stylebg_)->mImageCount : 1), "Invalid layer start!"); \
   1.540 +    NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
   1.541 +    for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
   1.542 +
   1.543 +  nscolor mBackgroundColor;       // [reset]
   1.544 +
   1.545 +  // FIXME: This (now background-break in css3-background) should
   1.546 +  // probably move into a different struct so that everything in
   1.547 +  // nsStyleBackground is set by the background shorthand.
   1.548 +  uint8_t mBackgroundInlinePolicy; // [reset] See nsStyleConsts.h
   1.549 +
   1.550 +  // True if this background is completely transparent.
   1.551 +  bool IsTransparent() const;
   1.552 +
   1.553 +  // We have to take slower codepaths for fixed background attachment,
   1.554 +  // but we don't want to do that when there's no image.
   1.555 +  // Not inline because it uses an nsCOMPtr<imgIRequest>
   1.556 +  // FIXME: Should be in nsStyleStructInlines.h.
   1.557 +  bool HasFixedBackground() const;
   1.558 +};
   1.559 +
   1.560 +// See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
   1.561 +// this is hard to replace with 'currentColor'.
   1.562 +#define BORDER_COLOR_FOREGROUND   0x20
   1.563 +#define OUTLINE_COLOR_INITIAL     0x80
   1.564 +// FOREGROUND | INITIAL(OUTLINE)
   1.565 +#define BORDER_COLOR_SPECIAL      0xA0
   1.566 +#define BORDER_STYLE_MASK         0x1F
   1.567 +
   1.568 +#define NS_SPACING_MARGIN   0
   1.569 +#define NS_SPACING_PADDING  1
   1.570 +#define NS_SPACING_BORDER   2
   1.571 +
   1.572 +
   1.573 +struct nsStyleMargin {
   1.574 +  nsStyleMargin(void);
   1.575 +  nsStyleMargin(const nsStyleMargin& aMargin);
   1.576 +  ~nsStyleMargin(void) {
   1.577 +    MOZ_COUNT_DTOR(nsStyleMargin);
   1.578 +  }
   1.579 +
   1.580 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
   1.581 +  void Destroy(nsPresContext* aContext);
   1.582 +
   1.583 +  void RecalcData();
   1.584 +  nsChangeHint CalcDifference(const nsStyleMargin& aOther) const;
   1.585 +  static nsChangeHint MaxDifference() {
   1.586 +    return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
   1.587 +                           NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
   1.588 +                                          nsChangeHint_NeedDirtyReflow));
   1.589 +  }
   1.590 +  static nsChangeHint MaxDifferenceNeverInherited() {
   1.591 +    // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and
   1.592 +    // nsChangeHint_NeedReflow as inherited hints.
   1.593 +    return nsChangeHint(0);
   1.594 +  }
   1.595 +
   1.596 +  nsStyleSides  mMargin;          // [reset] coord, percent, calc, auto
   1.597 +
   1.598 +  bool IsWidthDependent() const { return !mHasCachedMargin; }
   1.599 +  bool GetMargin(nsMargin& aMargin) const
   1.600 +  {
   1.601 +    if (mHasCachedMargin) {
   1.602 +      aMargin = mCachedMargin;
   1.603 +      return true;
   1.604 +    }
   1.605 +    return false;
   1.606 +  }
   1.607 +
   1.608 +protected:
   1.609 +  bool          mHasCachedMargin;
   1.610 +  nsMargin      mCachedMargin;
   1.611 +};
   1.612 +
   1.613 +
   1.614 +struct nsStylePadding {
   1.615 +  nsStylePadding(void);
   1.616 +  nsStylePadding(const nsStylePadding& aPadding);
   1.617 +  ~nsStylePadding(void) {
   1.618 +    MOZ_COUNT_DTOR(nsStylePadding);
   1.619 +  }
   1.620 +
   1.621 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
   1.622 +  void Destroy(nsPresContext* aContext);
   1.623 +
   1.624 +  void RecalcData();
   1.625 +  nsChangeHint CalcDifference(const nsStylePadding& aOther) const;
   1.626 +  static nsChangeHint MaxDifference() {
   1.627 +    return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
   1.628 +                           nsChangeHint_ClearDescendantIntrinsics);
   1.629 +  }
   1.630 +  static nsChangeHint MaxDifferenceNeverInherited() {
   1.631 +    // CalcDifference can return nsChangeHint_ClearAncestorIntrinsics as an
   1.632 +    // inherited hint.
   1.633 +    return nsChangeHint(0);
   1.634 +  }
   1.635 +
   1.636 +  nsStyleSides  mPadding;         // [reset] coord, percent, calc
   1.637 +
   1.638 +  bool IsWidthDependent() const { return !mHasCachedPadding; }
   1.639 +  bool GetPadding(nsMargin& aPadding) const
   1.640 +  {
   1.641 +    if (mHasCachedPadding) {
   1.642 +      aPadding = mCachedPadding;
   1.643 +      return true;
   1.644 +    }
   1.645 +    return false;
   1.646 +  }
   1.647 +
   1.648 +protected:
   1.649 +  bool          mHasCachedPadding;
   1.650 +  nsMargin      mCachedPadding;
   1.651 +};
   1.652 +
   1.653 +struct nsBorderColors {
   1.654 +  nsBorderColors* mNext;
   1.655 +  nscolor mColor;
   1.656 +
   1.657 +  nsBorderColors() : mNext(nullptr), mColor(NS_RGB(0,0,0)) {}
   1.658 +  nsBorderColors(const nscolor& aColor) : mNext(nullptr), mColor(aColor) {}
   1.659 +  ~nsBorderColors();
   1.660 +
   1.661 +  nsBorderColors* Clone() const { return Clone(true); }
   1.662 +
   1.663 +  static bool Equal(const nsBorderColors* c1,
   1.664 +                      const nsBorderColors* c2) {
   1.665 +    if (c1 == c2)
   1.666 +      return true;
   1.667 +    while (c1 && c2) {
   1.668 +      if (c1->mColor != c2->mColor)
   1.669 +        return false;
   1.670 +      c1 = c1->mNext;
   1.671 +      c2 = c2->mNext;
   1.672 +    }
   1.673 +    // both should be nullptr if these are equal, otherwise one
   1.674 +    // has more colors than another
   1.675 +    return !c1 && !c2;
   1.676 +  }
   1.677 +
   1.678 +private:
   1.679 +  nsBorderColors* Clone(bool aDeep) const;
   1.680 +};
   1.681 +
   1.682 +struct nsCSSShadowItem {
   1.683 +  nscoord mXOffset;
   1.684 +  nscoord mYOffset;
   1.685 +  nscoord mRadius;
   1.686 +  nscoord mSpread;
   1.687 +
   1.688 +  nscolor      mColor;
   1.689 +  bool mHasColor; // Whether mColor should be used
   1.690 +  bool mInset;
   1.691 +
   1.692 +  nsCSSShadowItem() : mHasColor(false) {
   1.693 +    MOZ_COUNT_CTOR(nsCSSShadowItem);
   1.694 +  }
   1.695 +  ~nsCSSShadowItem() {
   1.696 +    MOZ_COUNT_DTOR(nsCSSShadowItem);
   1.697 +  }
   1.698 +
   1.699 +  bool operator==(const nsCSSShadowItem& aOther) const {
   1.700 +    return (mXOffset == aOther.mXOffset &&
   1.701 +            mYOffset == aOther.mYOffset &&
   1.702 +            mRadius == aOther.mRadius &&
   1.703 +            mHasColor == aOther.mHasColor &&
   1.704 +            mSpread == aOther.mSpread &&
   1.705 +            mInset == aOther.mInset &&
   1.706 +            (!mHasColor || mColor == aOther.mColor));
   1.707 +  }
   1.708 +  bool operator!=(const nsCSSShadowItem& aOther) const {
   1.709 +    return !(*this == aOther);
   1.710 +  }
   1.711 +};
   1.712 +
   1.713 +class nsCSSShadowArray MOZ_FINAL {
   1.714 +  public:
   1.715 +    void* operator new(size_t aBaseSize, uint32_t aArrayLen) {
   1.716 +      // We can allocate both this nsCSSShadowArray and the
   1.717 +      // actual array in one allocation. The amount of memory to
   1.718 +      // allocate is equal to the class's size + the number of bytes for all
   1.719 +      // but the first array item (because aBaseSize includes one
   1.720 +      // item, see the private declarations)
   1.721 +      return ::operator new(aBaseSize +
   1.722 +                            (aArrayLen - 1) * sizeof(nsCSSShadowItem));
   1.723 +    }
   1.724 +
   1.725 +    nsCSSShadowArray(uint32_t aArrayLen) :
   1.726 +      mLength(aArrayLen)
   1.727 +    {
   1.728 +      MOZ_COUNT_CTOR(nsCSSShadowArray);
   1.729 +      for (uint32_t i = 1; i < mLength; ++i) {
   1.730 +        // Make sure we call the constructors of each nsCSSShadowItem
   1.731 +        // (the first one is called for us because we declared it under private)
   1.732 +        new (&mArray[i]) nsCSSShadowItem();
   1.733 +      }
   1.734 +    }
   1.735 +
   1.736 +private:
   1.737 +    // Private destructor, to discourage deletion outside of Release():
   1.738 +    ~nsCSSShadowArray() {
   1.739 +      MOZ_COUNT_DTOR(nsCSSShadowArray);
   1.740 +      for (uint32_t i = 1; i < mLength; ++i) {
   1.741 +        mArray[i].~nsCSSShadowItem();
   1.742 +      }
   1.743 +    }
   1.744 +
   1.745 +public:
   1.746 +    uint32_t Length() const { return mLength; }
   1.747 +    nsCSSShadowItem* ShadowAt(uint32_t i) {
   1.748 +      NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
   1.749 +      return &mArray[i];
   1.750 +    }
   1.751 +    const nsCSSShadowItem* ShadowAt(uint32_t i) const {
   1.752 +      NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
   1.753 +      return &mArray[i];
   1.754 +    }
   1.755 +
   1.756 +    bool HasShadowWithInset(bool aInset) {
   1.757 +      for (uint32_t i = 0; i < mLength; ++i) {
   1.758 +        if (mArray[i].mInset == aInset)
   1.759 +          return true;
   1.760 +      }
   1.761 +      return false;
   1.762 +    }
   1.763 +
   1.764 +    bool operator==(const nsCSSShadowArray& aOther) const {
   1.765 +      if (mLength != aOther.Length())
   1.766 +        return false;
   1.767 +
   1.768 +      for (uint32_t i = 0; i < mLength; ++i) {
   1.769 +        if (ShadowAt(i) != aOther.ShadowAt(i))
   1.770 +          return false;
   1.771 +      }
   1.772 +
   1.773 +      return true;
   1.774 +    }
   1.775 +
   1.776 +    NS_INLINE_DECL_REFCOUNTING(nsCSSShadowArray)
   1.777 +
   1.778 +  private:
   1.779 +    uint32_t mLength;
   1.780 +    nsCSSShadowItem mArray[1]; // This MUST be the last item
   1.781 +};
   1.782 +
   1.783 +// Border widths are rounded to the nearest-below integer number of pixels,
   1.784 +// but values between zero and one device pixels are always rounded up to
   1.785 +// one device pixel.
   1.786 +#define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
   1.787 +  ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
   1.788 +// Outline offset is rounded to the nearest integer number of pixels, but values
   1.789 +// between zero and one device pixels are always rounded up to one device pixel.
   1.790 +// Note that the offset can be negative.
   1.791 +#define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
   1.792 +  (((l) == 0) ? 0 : \
   1.793 +    ((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
   1.794 +                std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
   1.795 +
   1.796 +// Returns if the given border style type is visible or not
   1.797 +static bool IsVisibleBorderStyle(uint8_t aStyle)
   1.798 +{
   1.799 +  return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
   1.800 +          aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
   1.801 +}
   1.802 +
   1.803 +struct nsStyleBorder {
   1.804 +  nsStyleBorder(nsPresContext* aContext);
   1.805 +  nsStyleBorder(const nsStyleBorder& aBorder);
   1.806 +  ~nsStyleBorder();
   1.807 +
   1.808 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
   1.809 +  void Destroy(nsPresContext* aContext);
   1.810 +
   1.811 +  nsChangeHint CalcDifference(const nsStyleBorder& aOther) const;
   1.812 +  static nsChangeHint MaxDifference() {
   1.813 +    return NS_CombineHint(NS_STYLE_HINT_REFLOW,
   1.814 +                          nsChangeHint_BorderStyleNoneChange);
   1.815 +  }
   1.816 +  static nsChangeHint MaxDifferenceNeverInherited() {
   1.817 +    // CalcDifference never returns nsChangeHint_NeedReflow or
   1.818 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
   1.819 +    return NS_CombineHint(nsChangeHint_NeedReflow,
   1.820 +                          nsChangeHint_ClearAncestorIntrinsics);
   1.821 +  }
   1.822 +
   1.823 +  void EnsureBorderColors() {
   1.824 +    if (!mBorderColors) {
   1.825 +      mBorderColors = new nsBorderColors*[4];
   1.826 +      if (mBorderColors)
   1.827 +        for (int32_t i = 0; i < 4; i++)
   1.828 +          mBorderColors[i] = nullptr;
   1.829 +    }
   1.830 +  }
   1.831 +
   1.832 +  void ClearBorderColors(mozilla::css::Side aSide) {
   1.833 +    if (mBorderColors && mBorderColors[aSide]) {
   1.834 +      delete mBorderColors[aSide];
   1.835 +      mBorderColors[aSide] = nullptr;
   1.836 +    }
   1.837 +  }
   1.838 +
   1.839 +  // Return whether aStyle is a visible style.  Invisible styles cause
   1.840 +  // the relevant computed border width to be 0.
   1.841 +  // Note that this does *not* consider the effects of 'border-image':
   1.842 +  // if border-style is none, but there is a loaded border image,
   1.843 +  // HasVisibleStyle will be false even though there *is* a border.
   1.844 +  bool HasVisibleStyle(mozilla::css::Side aSide) const
   1.845 +  {
   1.846 +    return IsVisibleBorderStyle(GetBorderStyle(aSide));
   1.847 +  }
   1.848 +
   1.849 +  // aBorderWidth is in twips
   1.850 +  void SetBorderWidth(mozilla::css::Side aSide, nscoord aBorderWidth)
   1.851 +  {
   1.852 +    nscoord roundedWidth =
   1.853 +      NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
   1.854 +    mBorder.Side(aSide) = roundedWidth;
   1.855 +    if (HasVisibleStyle(aSide))
   1.856 +      mComputedBorder.Side(aSide) = roundedWidth;
   1.857 +  }
   1.858 +
   1.859 +  // Get the computed border (plus rounding).  This does consider the
   1.860 +  // effects of 'border-style: none', but does not consider
   1.861 +  // 'border-image'.
   1.862 +  const nsMargin& GetComputedBorder() const
   1.863 +  {
   1.864 +    return mComputedBorder;
   1.865 +  }
   1.866 +
   1.867 +  bool HasBorder() const
   1.868 +  {
   1.869 +    return mComputedBorder != nsMargin(0,0,0,0) || !mBorderImageSource.IsEmpty();
   1.870 +  }
   1.871 +
   1.872 +  // Get the actual border width for a particular side, in appunits.  Note that
   1.873 +  // this is zero if and only if there is no border to be painted for this
   1.874 +  // side.  That is, this value takes into account the border style and the
   1.875 +  // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
   1.876 +  nscoord GetComputedBorderWidth(mozilla::css::Side aSide) const
   1.877 +  {
   1.878 +    return GetComputedBorder().Side(aSide);
   1.879 +  }
   1.880 +
   1.881 +  uint8_t GetBorderStyle(mozilla::css::Side aSide) const
   1.882 +  {
   1.883 +    NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
   1.884 +    return (mBorderStyle[aSide] & BORDER_STYLE_MASK);
   1.885 +  }
   1.886 +
   1.887 +  void SetBorderStyle(mozilla::css::Side aSide, uint8_t aStyle)
   1.888 +  {
   1.889 +    NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
   1.890 +    mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
   1.891 +    mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
   1.892 +    mComputedBorder.Side(aSide) =
   1.893 +      (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
   1.894 +  }
   1.895 +
   1.896 +  inline bool IsBorderImageLoaded() const
   1.897 +  {
   1.898 +    return mBorderImageSource.IsLoaded();
   1.899 +  }
   1.900 +
   1.901 +  // Defined in nsStyleStructInlines.h
   1.902 +  inline nsresult RequestDecode();
   1.903 +
   1.904 +  void GetBorderColor(mozilla::css::Side aSide, nscolor& aColor,
   1.905 +                      bool& aForeground) const
   1.906 +  {
   1.907 +    aForeground = false;
   1.908 +    NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
   1.909 +    if ((mBorderStyle[aSide] & BORDER_COLOR_SPECIAL) == 0)
   1.910 +      aColor = mBorderColor[aSide];
   1.911 +    else if (mBorderStyle[aSide] & BORDER_COLOR_FOREGROUND)
   1.912 +      aForeground = true;
   1.913 +    else
   1.914 +      NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
   1.915 +  }
   1.916 +
   1.917 +  void SetBorderColor(mozilla::css::Side aSide, nscolor aColor)
   1.918 +  {
   1.919 +    NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
   1.920 +    mBorderColor[aSide] = aColor;
   1.921 +    mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
   1.922 +  }
   1.923 +
   1.924 +  void TrackImage(nsPresContext* aContext)
   1.925 +  {
   1.926 +    if (mBorderImageSource.GetType() == eStyleImageType_Image) {
   1.927 +      mBorderImageSource.TrackImage(aContext);
   1.928 +    }
   1.929 +  }
   1.930 +  void UntrackImage(nsPresContext* aContext)
   1.931 +  {
   1.932 +    if (mBorderImageSource.GetType() == eStyleImageType_Image) {
   1.933 +      mBorderImageSource.UntrackImage(aContext);
   1.934 +    }
   1.935 +  }
   1.936 +
   1.937 +  nsMargin GetImageOutset() const;
   1.938 +
   1.939 +  void GetCompositeColors(int32_t aIndex, nsBorderColors** aColors) const
   1.940 +  {
   1.941 +    if (!mBorderColors)
   1.942 +      *aColors = nullptr;
   1.943 +    else
   1.944 +      *aColors = mBorderColors[aIndex];
   1.945 +  }
   1.946 +
   1.947 +  void AppendBorderColor(int32_t aIndex, nscolor aColor)
   1.948 +  {
   1.949 +    NS_ASSERTION(aIndex >= 0 && aIndex <= 3, "bad side for composite border color");
   1.950 +    nsBorderColors* colorEntry = new nsBorderColors(aColor);
   1.951 +    if (!mBorderColors[aIndex])
   1.952 +      mBorderColors[aIndex] = colorEntry;
   1.953 +    else {
   1.954 +      nsBorderColors* last = mBorderColors[aIndex];
   1.955 +      while (last->mNext)
   1.956 +        last = last->mNext;
   1.957 +      last->mNext = colorEntry;
   1.958 +    }
   1.959 +    mBorderStyle[aIndex] &= ~BORDER_COLOR_SPECIAL;
   1.960 +  }
   1.961 +
   1.962 +  void SetBorderToForeground(mozilla::css::Side aSide)
   1.963 +  {
   1.964 +    NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
   1.965 +    mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
   1.966 +    mBorderStyle[aSide] |= BORDER_COLOR_FOREGROUND;
   1.967 +  }
   1.968 +
   1.969 +  imgIRequest* GetBorderImageRequest() const
   1.970 +  {
   1.971 +    if (mBorderImageSource.GetType() == eStyleImageType_Image) {
   1.972 +      return mBorderImageSource.GetImageData();
   1.973 +    }
   1.974 +    return nullptr;
   1.975 +  }
   1.976 +
   1.977 +public:
   1.978 +  nsBorderColors** mBorderColors;        // [reset] composite (stripe) colors
   1.979 +  nsRefPtr<nsCSSShadowArray> mBoxShadow; // [reset] nullptr for 'none'
   1.980 +
   1.981 +public:
   1.982 +  nsStyleCorners mBorderRadius;       // [reset] coord, percent
   1.983 +  nsStyleImage   mBorderImageSource;  // [reset]
   1.984 +  nsStyleSides   mBorderImageSlice;   // [reset] factor, percent
   1.985 +  nsStyleSides   mBorderImageWidth;   // [reset] length, factor, percent, auto
   1.986 +  nsStyleSides   mBorderImageOutset;  // [reset] length, factor
   1.987 +
   1.988 +  uint8_t        mBorderImageFill;    // [reset]
   1.989 +  uint8_t        mBorderImageRepeatH; // [reset] see nsStyleConsts.h
   1.990 +  uint8_t        mBorderImageRepeatV; // [reset]
   1.991 +  uint8_t        mFloatEdge;          // [reset]
   1.992 +
   1.993 +protected:
   1.994 +  // mComputedBorder holds the CSS2.1 computed border-width values.
   1.995 +  // In particular, these widths take into account the border-style
   1.996 +  // for the relevant side, and the values are rounded to the nearest
   1.997 +  // device pixel (which is not part of the definition of computed
   1.998 +  // values). The presence or absence of a border-image does not
   1.999 +  // affect border-width values.
  1.1000 +  nsMargin      mComputedBorder;
  1.1001 +
  1.1002 +  // mBorder holds the nscoord values for the border widths as they
  1.1003 +  // would be if all the border-style values were visible (not hidden
  1.1004 +  // or none).  This member exists so that when we create structs
  1.1005 +  // using the copy constructor during style resolution the new
  1.1006 +  // structs will know what the specified values of the border were in
  1.1007 +  // case they have more specific rules setting the border style.
  1.1008 +  //
  1.1009 +  // Note that this isn't quite the CSS specified value, since this
  1.1010 +  // has had the enumerated border widths converted to lengths, and
  1.1011 +  // all lengths converted to twips.  But it's not quite the computed
  1.1012 +  // value either. The values are rounded to the nearest device pixel.
  1.1013 +  nsMargin      mBorder;
  1.1014 +
  1.1015 +  uint8_t       mBorderStyle[4];  // [reset] See nsStyleConsts.h
  1.1016 +  nscolor       mBorderColor[4];  // [reset] the colors to use for a simple
  1.1017 +                                  // border.  not used for -moz-border-colors
  1.1018 +private:
  1.1019 +  nscoord       mTwipsPerPixel;
  1.1020 +
  1.1021 +  nsStyleBorder& operator=(const nsStyleBorder& aOther) MOZ_DELETE;
  1.1022 +};
  1.1023 +
  1.1024 +
  1.1025 +struct nsStyleOutline {
  1.1026 +  nsStyleOutline(nsPresContext* aPresContext);
  1.1027 +  nsStyleOutline(const nsStyleOutline& aOutline);
  1.1028 +  ~nsStyleOutline(void) {
  1.1029 +    MOZ_COUNT_DTOR(nsStyleOutline);
  1.1030 +  }
  1.1031 +
  1.1032 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.1033 +    return aContext->AllocateFromShell(sz);
  1.1034 +  }
  1.1035 +  void Destroy(nsPresContext* aContext) {
  1.1036 +    this->~nsStyleOutline();
  1.1037 +    aContext->FreeToShell(sizeof(nsStyleOutline), this);
  1.1038 +  }
  1.1039 +
  1.1040 +  void RecalcData(nsPresContext* aContext);
  1.1041 +  nsChangeHint CalcDifference(const nsStyleOutline& aOther) const;
  1.1042 +  static nsChangeHint MaxDifference() {
  1.1043 +    return NS_CombineHint(nsChangeHint_AllReflowHints,
  1.1044 +                          nsChangeHint_RepaintFrame);
  1.1045 +  }
  1.1046 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.1047 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.1048 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.1049 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.1050 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.1051 +  }
  1.1052 +
  1.1053 +  nsStyleCorners  mOutlineRadius; // [reset] coord, percent, calc
  1.1054 +
  1.1055 +  // Note that this is a specified value.  You can get the actual values
  1.1056 +  // with GetOutlineWidth.  You cannot get the computed value directly.
  1.1057 +  nsStyleCoord  mOutlineWidth;    // [reset] coord, enum (see nsStyleConsts.h)
  1.1058 +  nscoord       mOutlineOffset;   // [reset]
  1.1059 +
  1.1060 +  bool GetOutlineWidth(nscoord& aWidth) const
  1.1061 +  {
  1.1062 +    if (mHasCachedOutline) {
  1.1063 +      aWidth = mCachedOutlineWidth;
  1.1064 +      return true;
  1.1065 +    }
  1.1066 +    return false;
  1.1067 +  }
  1.1068 +
  1.1069 +  uint8_t GetOutlineStyle(void) const
  1.1070 +  {
  1.1071 +    return (mOutlineStyle & BORDER_STYLE_MASK);
  1.1072 +  }
  1.1073 +
  1.1074 +  void SetOutlineStyle(uint8_t aStyle)
  1.1075 +  {
  1.1076 +    mOutlineStyle &= ~BORDER_STYLE_MASK;
  1.1077 +    mOutlineStyle |= (aStyle & BORDER_STYLE_MASK);
  1.1078 +  }
  1.1079 +
  1.1080 +  // false means initial value
  1.1081 +  bool GetOutlineColor(nscolor& aColor) const
  1.1082 +  {
  1.1083 +    if ((mOutlineStyle & BORDER_COLOR_SPECIAL) == 0) {
  1.1084 +      aColor = mOutlineColor;
  1.1085 +      return true;
  1.1086 +    }
  1.1087 +    return false;
  1.1088 +  }
  1.1089 +
  1.1090 +  void SetOutlineColor(nscolor aColor)
  1.1091 +  {
  1.1092 +    mOutlineColor = aColor;
  1.1093 +    mOutlineStyle &= ~BORDER_COLOR_SPECIAL;
  1.1094 +  }
  1.1095 +
  1.1096 +  void SetOutlineInitialColor()
  1.1097 +  {
  1.1098 +    mOutlineStyle |= OUTLINE_COLOR_INITIAL;
  1.1099 +  }
  1.1100 +
  1.1101 +  bool GetOutlineInitialColor() const
  1.1102 +  {
  1.1103 +    return !!(mOutlineStyle & OUTLINE_COLOR_INITIAL);
  1.1104 +  }
  1.1105 +
  1.1106 +protected:
  1.1107 +  // This value is the actual value, so it's rounded to the nearest device
  1.1108 +  // pixel.
  1.1109 +  nscoord       mCachedOutlineWidth;
  1.1110 +
  1.1111 +  nscolor       mOutlineColor;    // [reset]
  1.1112 +
  1.1113 +  bool          mHasCachedOutline;
  1.1114 +  uint8_t       mOutlineStyle;    // [reset] See nsStyleConsts.h
  1.1115 +
  1.1116 +  nscoord       mTwipsPerPixel;
  1.1117 +};
  1.1118 +
  1.1119 +
  1.1120 +struct nsStyleList {
  1.1121 +  nsStyleList(void);
  1.1122 +  nsStyleList(const nsStyleList& aStyleList);
  1.1123 +  ~nsStyleList(void);
  1.1124 +
  1.1125 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.1126 +    return aContext->AllocateFromShell(sz);
  1.1127 +  }
  1.1128 +  void Destroy(nsPresContext* aContext) {
  1.1129 +    this->~nsStyleList();
  1.1130 +    aContext->FreeToShell(sizeof(nsStyleList), this);
  1.1131 +  }
  1.1132 +
  1.1133 +  nsChangeHint CalcDifference(const nsStyleList& aOther) const;
  1.1134 +  static nsChangeHint MaxDifference() {
  1.1135 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.1136 +  }
  1.1137 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.1138 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.1139 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.1140 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.1141 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.1142 +  }
  1.1143 +
  1.1144 +  imgRequestProxy* GetListStyleImage() const { return mListStyleImage; }
  1.1145 +  void SetListStyleImage(imgRequestProxy* aReq)
  1.1146 +  {
  1.1147 +    if (mListStyleImage)
  1.1148 +      mListStyleImage->UnlockImage();
  1.1149 +    mListStyleImage = aReq;
  1.1150 +    if (mListStyleImage)
  1.1151 +      mListStyleImage->LockImage();
  1.1152 +  }
  1.1153 +
  1.1154 +  uint8_t   mListStyleType;             // [inherited] See nsStyleConsts.h
  1.1155 +  uint8_t   mListStylePosition;         // [inherited]
  1.1156 +private:
  1.1157 +  nsRefPtr<imgRequestProxy> mListStyleImage; // [inherited]
  1.1158 +  nsStyleList& operator=(const nsStyleList& aOther) MOZ_DELETE;
  1.1159 +public:
  1.1160 +  nsRect        mImageRegion;           // [inherited] the rect to use within an image
  1.1161 +};
  1.1162 +
  1.1163 +// Computed value of the grid-template-columns or grid-columns-rows property
  1.1164 +// (but *not* grid-template-areas.)
  1.1165 +// http://dev.w3.org/csswg/css-grid/#track-sizing
  1.1166 +//
  1.1167 +// This represents either:
  1.1168 +// * none:
  1.1169 +//   mIsSubgrid is false, all three arrays are empty
  1.1170 +// * <track-list>:
  1.1171 +//   mIsSubgrid is false,
  1.1172 +//   mMinTrackSizingFunctions and mMaxTrackSizingFunctions
  1.1173 +//   are of identical non-zero size,
  1.1174 +//   and mLineNameLists is one element longer than that.
  1.1175 +//   (Delimiting N columns requires N+1 lines:
  1.1176 +//   one before each track, plus one at the very end.)
  1.1177 +//
  1.1178 +//   An omitted <line-names> is still represented in mLineNameLists,
  1.1179 +//   as an empty sub-array.
  1.1180 +//
  1.1181 +//   A <track-size> specified as a single <track-breadth> is represented
  1.1182 +//   as identical min and max sizing functions.
  1.1183 +//
  1.1184 +//   The units for nsStyleCoord are:
  1.1185 +//   * eStyleUnit_Percent represents a <percentage>
  1.1186 +//   * eStyleUnit_FlexFraction represents a <flex> flexible fraction
  1.1187 +//   * eStyleUnit_Coord represents a <length>
  1.1188 +//   * eStyleUnit_Enumerated represents min-content or max-content
  1.1189 +// * subgrid <line-name-list>?:
  1.1190 +//   mIsSubgrid is true,
  1.1191 +//   mLineNameLists may or may not be empty,
  1.1192 +//   mMinTrackSizingFunctions and mMaxTrackSizingFunctions are empty.
  1.1193 +struct nsStyleGridTemplate {
  1.1194 +  bool mIsSubgrid;
  1.1195 +  nsTArray<nsTArray<nsString>> mLineNameLists;
  1.1196 +  nsTArray<nsStyleCoord> mMinTrackSizingFunctions;
  1.1197 +  nsTArray<nsStyleCoord> mMaxTrackSizingFunctions;
  1.1198 +
  1.1199 +  nsStyleGridTemplate()
  1.1200 +    : mIsSubgrid(false)
  1.1201 +  {
  1.1202 +  }
  1.1203 +
  1.1204 +  inline bool operator!=(const nsStyleGridTemplate& aOther) const {
  1.1205 +    return mLineNameLists != aOther.mLineNameLists ||
  1.1206 +           mMinTrackSizingFunctions != aOther.mMinTrackSizingFunctions ||
  1.1207 +           mMaxTrackSizingFunctions != aOther.mMaxTrackSizingFunctions;
  1.1208 +  }
  1.1209 +};
  1.1210 +
  1.1211 +struct nsStyleGridLine {
  1.1212 +  // http://dev.w3.org/csswg/css-grid/#typedef-grid-line
  1.1213 +  bool mHasSpan;
  1.1214 +  int32_t mInteger;  // 0 means not provided
  1.1215 +  nsString mLineName;  // Empty string means not provided.
  1.1216 +
  1.1217 +  nsStyleGridLine()
  1.1218 +    : mHasSpan(false)
  1.1219 +    , mInteger(0)
  1.1220 +    // mLineName get its default constructor, the empty string
  1.1221 +  {
  1.1222 +  }
  1.1223 +
  1.1224 +  nsStyleGridLine(const nsStyleGridLine& aOther)
  1.1225 +  {
  1.1226 +    (*this) = aOther;
  1.1227 +  }
  1.1228 +
  1.1229 +  void operator=(const nsStyleGridLine& aOther)
  1.1230 +  {
  1.1231 +    mHasSpan = aOther.mHasSpan;
  1.1232 +    mInteger = aOther.mInteger;
  1.1233 +    mLineName = aOther.mLineName;
  1.1234 +  }
  1.1235 +
  1.1236 +  bool operator!=(const nsStyleGridLine& aOther) const
  1.1237 +  {
  1.1238 +    return mHasSpan != aOther.mHasSpan ||
  1.1239 +           mInteger != aOther.mInteger ||
  1.1240 +           mLineName != aOther.mLineName;
  1.1241 +  }
  1.1242 +
  1.1243 +  void SetToInteger(uint32_t value)
  1.1244 +  {
  1.1245 +    mHasSpan = false;
  1.1246 +    mInteger = value;
  1.1247 +    mLineName.Truncate();
  1.1248 +  }
  1.1249 +
  1.1250 +  void SetAuto()
  1.1251 +  {
  1.1252 +    mHasSpan = false;
  1.1253 +    mInteger = 0;
  1.1254 +    mLineName.Truncate();
  1.1255 +  }
  1.1256 +
  1.1257 +  bool IsAuto() const
  1.1258 +  {
  1.1259 +    bool haveInitialValues =  mInteger == 0 && mLineName.IsEmpty();
  1.1260 +    MOZ_ASSERT(!(haveInitialValues && mHasSpan),
  1.1261 +               "should not have 'span' when other components are "
  1.1262 +               "at their initial values");
  1.1263 +    return haveInitialValues;
  1.1264 +  }
  1.1265 +};
  1.1266 +
  1.1267 +struct nsStylePosition {
  1.1268 +  nsStylePosition(void);
  1.1269 +  nsStylePosition(const nsStylePosition& aOther);
  1.1270 +  ~nsStylePosition(void);
  1.1271 +
  1.1272 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.1273 +    return aContext->AllocateFromShell(sz);
  1.1274 +  }
  1.1275 +  void Destroy(nsPresContext* aContext) {
  1.1276 +    this->~nsStylePosition();
  1.1277 +    aContext->FreeToShell(sizeof(nsStylePosition), this);
  1.1278 +  }
  1.1279 +
  1.1280 +  nsChangeHint CalcDifference(const nsStylePosition& aOther) const;
  1.1281 +  static nsChangeHint MaxDifference() {
  1.1282 +    return NS_CombineHint(NS_STYLE_HINT_REFLOW,
  1.1283 +                          nsChangeHint(nsChangeHint_RecomputePosition |
  1.1284 +                                       nsChangeHint_UpdateOverflow));
  1.1285 +  }
  1.1286 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.1287 +    // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and
  1.1288 +    // nsChangeHint_NeedReflow as inherited hints.
  1.1289 +    return nsChangeHint(0);
  1.1290 +  }
  1.1291 +
  1.1292 +  nsStyleSides  mOffset;                // [reset] coord, percent, calc, auto
  1.1293 +  nsStyleCoord  mWidth;                 // [reset] coord, percent, enum, calc, auto
  1.1294 +  nsStyleCoord  mMinWidth;              // [reset] coord, percent, enum, calc
  1.1295 +  nsStyleCoord  mMaxWidth;              // [reset] coord, percent, enum, calc, none
  1.1296 +  nsStyleCoord  mHeight;                // [reset] coord, percent, calc, auto
  1.1297 +  nsStyleCoord  mMinHeight;             // [reset] coord, percent, calc
  1.1298 +  nsStyleCoord  mMaxHeight;             // [reset] coord, percent, calc, none
  1.1299 +  nsStyleCoord  mFlexBasis;             // [reset] coord, percent, enum, calc, auto
  1.1300 +  nsStyleCoord  mGridAutoColumnsMin;    // [reset] coord, percent, enum, calc, flex
  1.1301 +  nsStyleCoord  mGridAutoColumnsMax;    // [reset] coord, percent, enum, calc, flex
  1.1302 +  nsStyleCoord  mGridAutoRowsMin;       // [reset] coord, percent, enum, calc, flex
  1.1303 +  nsStyleCoord  mGridAutoRowsMax;       // [reset] coord, percent, enum, calc, flex
  1.1304 +  uint8_t       mGridAutoFlow;          // [reset] enumerated. See nsStyleConsts.h
  1.1305 +  uint8_t       mBoxSizing;             // [reset] see nsStyleConsts.h
  1.1306 +  uint8_t       mAlignContent;          // [reset] see nsStyleConsts.h
  1.1307 +  uint8_t       mAlignItems;            // [reset] see nsStyleConsts.h
  1.1308 +  uint8_t       mAlignSelf;             // [reset] see nsStyleConsts.h
  1.1309 +  uint8_t       mFlexDirection;         // [reset] see nsStyleConsts.h
  1.1310 +  uint8_t       mFlexWrap;              // [reset] see nsStyleConsts.h
  1.1311 +  uint8_t       mJustifyContent;        // [reset] see nsStyleConsts.h
  1.1312 +  int32_t       mOrder;                 // [reset] integer
  1.1313 +  float         mFlexGrow;              // [reset] float
  1.1314 +  float         mFlexShrink;            // [reset] float
  1.1315 +  nsStyleCoord  mZIndex;                // [reset] integer, auto
  1.1316 +  // NOTE: Fields so far can be memcpy()'ed, while following fields
  1.1317 +  // need to have their copy constructor called when we're being copied.
  1.1318 +  // See nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
  1.1319 +  // in nsStyleStruct.cpp
  1.1320 +  nsStyleGridTemplate mGridTemplateColumns;
  1.1321 +  nsStyleGridTemplate mGridTemplateRows;
  1.1322 +
  1.1323 +  // nullptr for 'none'
  1.1324 +  nsRefPtr<mozilla::css::GridTemplateAreasValue> mGridTemplateAreas;
  1.1325 +
  1.1326 +  // We represent the "grid-auto-position" property in two parts:
  1.1327 +  nsStyleGridLine mGridAutoPositionColumn;
  1.1328 +  nsStyleGridLine mGridAutoPositionRow;
  1.1329 +
  1.1330 +  nsStyleGridLine mGridColumnStart;
  1.1331 +  nsStyleGridLine mGridColumnEnd;
  1.1332 +  nsStyleGridLine mGridRowStart;
  1.1333 +  nsStyleGridLine mGridRowEnd;
  1.1334 +
  1.1335 +  bool WidthDependsOnContainer() const
  1.1336 +    { return WidthCoordDependsOnContainer(mWidth); }
  1.1337 +  bool MinWidthDependsOnContainer() const
  1.1338 +    { return WidthCoordDependsOnContainer(mMinWidth); }
  1.1339 +  bool MaxWidthDependsOnContainer() const
  1.1340 +    { return WidthCoordDependsOnContainer(mMaxWidth); }
  1.1341 +
  1.1342 +  // Note that these functions count 'auto' as depending on the
  1.1343 +  // container since that's the case for absolutely positioned elements.
  1.1344 +  // However, some callers do not care about this case and should check
  1.1345 +  // for it, since it is the most common case.
  1.1346 +  // FIXME: We should probably change the assumption to be the other way
  1.1347 +  // around.
  1.1348 +  bool HeightDependsOnContainer() const
  1.1349 +    { return HeightCoordDependsOnContainer(mHeight); }
  1.1350 +  bool MinHeightDependsOnContainer() const
  1.1351 +    { return HeightCoordDependsOnContainer(mMinHeight); }
  1.1352 +  bool MaxHeightDependsOnContainer() const
  1.1353 +    { return HeightCoordDependsOnContainer(mMaxHeight); }
  1.1354 +
  1.1355 +  bool OffsetHasPercent(mozilla::css::Side aSide) const
  1.1356 +  {
  1.1357 +    return mOffset.Get(aSide).HasPercent();
  1.1358 +  }
  1.1359 +
  1.1360 +private:
  1.1361 +  static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
  1.1362 +  static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
  1.1363 +  {
  1.1364 +    return aCoord.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
  1.1365 +           aCoord.HasPercent();
  1.1366 +  }
  1.1367 +};
  1.1368 +
  1.1369 +struct nsStyleTextOverflowSide {
  1.1370 +  nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
  1.1371 +
  1.1372 +  bool operator==(const nsStyleTextOverflowSide& aOther) const {
  1.1373 +    return mType == aOther.mType &&
  1.1374 +           (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
  1.1375 +            mString == aOther.mString);
  1.1376 +  }
  1.1377 +  bool operator!=(const nsStyleTextOverflowSide& aOther) const {
  1.1378 +    return !(*this == aOther);
  1.1379 +  }
  1.1380 +
  1.1381 +  nsString mString;
  1.1382 +  uint8_t  mType;
  1.1383 +};
  1.1384 +
  1.1385 +struct nsStyleTextOverflow {
  1.1386 +  nsStyleTextOverflow() : mLogicalDirections(true) {}
  1.1387 +  bool operator==(const nsStyleTextOverflow& aOther) const {
  1.1388 +    return mLeft == aOther.mLeft && mRight == aOther.mRight;
  1.1389 +  }
  1.1390 +  bool operator!=(const nsStyleTextOverflow& aOther) const {
  1.1391 +    return !(*this == aOther);
  1.1392 +  }
  1.1393 +
  1.1394 +  // Returns the value to apply on the left side.
  1.1395 +  const nsStyleTextOverflowSide& GetLeft(uint8_t aDirection) const {
  1.1396 +    NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
  1.1397 +                 aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
  1.1398 +    return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
  1.1399 +             mLeft : mRight;
  1.1400 +  }
  1.1401 +
  1.1402 +  // Returns the value to apply on the right side.
  1.1403 +  const nsStyleTextOverflowSide& GetRight(uint8_t aDirection) const {
  1.1404 +    NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
  1.1405 +                 aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
  1.1406 +    return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
  1.1407 +             mRight : mLeft;
  1.1408 +  }
  1.1409 +
  1.1410 +  // Returns the first value that was specified.
  1.1411 +  const nsStyleTextOverflowSide* GetFirstValue() const {
  1.1412 +    return mLogicalDirections ? &mRight : &mLeft;
  1.1413 +  }
  1.1414 +
  1.1415 +  // Returns the second value, or null if there was only one value specified.
  1.1416 +  const nsStyleTextOverflowSide* GetSecondValue() const {
  1.1417 +    return mLogicalDirections ? nullptr : &mRight;
  1.1418 +  }
  1.1419 +
  1.1420 +  nsStyleTextOverflowSide mLeft;  // start side when mLogicalDirections is true
  1.1421 +  nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
  1.1422 +  bool mLogicalDirections;  // true when only one value was specified
  1.1423 +};
  1.1424 +
  1.1425 +struct nsStyleTextReset {
  1.1426 +  nsStyleTextReset(void);
  1.1427 +  nsStyleTextReset(const nsStyleTextReset& aOther);
  1.1428 +  ~nsStyleTextReset(void);
  1.1429 +
  1.1430 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.1431 +    return aContext->AllocateFromShell(sz);
  1.1432 +  }
  1.1433 +  void Destroy(nsPresContext* aContext) {
  1.1434 +    this->~nsStyleTextReset();
  1.1435 +    aContext->FreeToShell(sizeof(nsStyleTextReset), this);
  1.1436 +  }
  1.1437 +
  1.1438 +  uint8_t GetDecorationStyle() const
  1.1439 +  {
  1.1440 +    return (mTextDecorationStyle & BORDER_STYLE_MASK);
  1.1441 +  }
  1.1442 +
  1.1443 +  void SetDecorationStyle(uint8_t aStyle)
  1.1444 +  {
  1.1445 +    NS_ABORT_IF_FALSE((aStyle & BORDER_STYLE_MASK) == aStyle,
  1.1446 +                      "style doesn't fit");
  1.1447 +    mTextDecorationStyle &= ~BORDER_STYLE_MASK;
  1.1448 +    mTextDecorationStyle |= (aStyle & BORDER_STYLE_MASK);
  1.1449 +  }
  1.1450 +
  1.1451 +  void GetDecorationColor(nscolor& aColor, bool& aForeground) const
  1.1452 +  {
  1.1453 +    aForeground = false;
  1.1454 +    if ((mTextDecorationStyle & BORDER_COLOR_SPECIAL) == 0) {
  1.1455 +      aColor = mTextDecorationColor;
  1.1456 +    } else if (mTextDecorationStyle & BORDER_COLOR_FOREGROUND) {
  1.1457 +      aForeground = true;
  1.1458 +    } else {
  1.1459 +      NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
  1.1460 +    }
  1.1461 +  }
  1.1462 +
  1.1463 +  void SetDecorationColor(nscolor aColor)
  1.1464 +  {
  1.1465 +    mTextDecorationColor = aColor;
  1.1466 +    mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
  1.1467 +  }
  1.1468 +
  1.1469 +  void SetDecorationColorToForeground()
  1.1470 +  {
  1.1471 +    mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
  1.1472 +    mTextDecorationStyle |= BORDER_COLOR_FOREGROUND;
  1.1473 +  }
  1.1474 +
  1.1475 +  nsChangeHint CalcDifference(const nsStyleTextReset& aOther) const;
  1.1476 +  static nsChangeHint MaxDifference() {
  1.1477 +    return NS_STYLE_HINT_REFLOW;
  1.1478 +  }
  1.1479 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.1480 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.1481 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.1482 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.1483 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.1484 +  }
  1.1485 +
  1.1486 +  nsStyleCoord  mVerticalAlign;         // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
  1.1487 +  nsStyleTextOverflow mTextOverflow;    // [reset] enum, string
  1.1488 +
  1.1489 +  uint8_t mTextDecorationLine;          // [reset] see nsStyleConsts.h
  1.1490 +  uint8_t mUnicodeBidi;                 // [reset] see nsStyleConsts.h
  1.1491 +protected:
  1.1492 +  uint8_t mTextDecorationStyle;         // [reset] see nsStyleConsts.h
  1.1493 +
  1.1494 +  nscolor mTextDecorationColor;         // [reset] the colors to use for a decoration lines, not used at currentColor
  1.1495 +};
  1.1496 +
  1.1497 +struct nsStyleText {
  1.1498 +  nsStyleText(void);
  1.1499 +  nsStyleText(const nsStyleText& aOther);
  1.1500 +  ~nsStyleText(void);
  1.1501 +
  1.1502 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.1503 +    return aContext->AllocateFromShell(sz);
  1.1504 +  }
  1.1505 +  void Destroy(nsPresContext* aContext) {
  1.1506 +    this->~nsStyleText();
  1.1507 +    aContext->FreeToShell(sizeof(nsStyleText), this);
  1.1508 +  }
  1.1509 +
  1.1510 +  nsChangeHint CalcDifference(const nsStyleText& aOther) const;
  1.1511 +  static nsChangeHint MaxDifference() {
  1.1512 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.1513 +  }
  1.1514 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.1515 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.1516 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.1517 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.1518 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.1519 +  }
  1.1520 +
  1.1521 +  uint8_t mTextAlign;                   // [inherited] see nsStyleConsts.h
  1.1522 +  uint8_t mTextAlignLast;               // [inherited] see nsStyleConsts.h
  1.1523 +  bool mTextAlignTrue : 1;              // [inherited] see nsStyleConsts.h
  1.1524 +  bool mTextAlignLastTrue : 1;          // [inherited] see nsStyleConsts.h
  1.1525 +  uint8_t mTextTransform;               // [inherited] see nsStyleConsts.h
  1.1526 +  uint8_t mWhiteSpace;                  // [inherited] see nsStyleConsts.h
  1.1527 +  uint8_t mWordBreak;                   // [inherited] see nsStyleConsts.h
  1.1528 +  uint8_t mWordWrap;                    // [inherited] see nsStyleConsts.h
  1.1529 +  uint8_t mHyphens;                     // [inherited] see nsStyleConsts.h
  1.1530 +  uint8_t mTextSizeAdjust;              // [inherited] see nsStyleConsts.h
  1.1531 +  uint8_t mTextOrientation;             // [inherited] see nsStyleConsts.h
  1.1532 +  uint8_t mTextCombineUpright;          // [inherited] see nsStyleConsts.h
  1.1533 +  uint8_t mControlCharacterVisibility;  // [inherited] see nsStyleConsts.h
  1.1534 +  int32_t mTabSize;                     // [inherited] see nsStyleConsts.h
  1.1535 +
  1.1536 +  nscoord mWordSpacing;                 // [inherited]
  1.1537 +  nsStyleCoord  mLetterSpacing;         // [inherited] coord, normal
  1.1538 +  nsStyleCoord  mLineHeight;            // [inherited] coord, factor, normal
  1.1539 +  nsStyleCoord  mTextIndent;            // [inherited] coord, percent, calc
  1.1540 +
  1.1541 +  nsRefPtr<nsCSSShadowArray> mTextShadow; // [inherited] nullptr in case of a zero-length
  1.1542 +
  1.1543 +  bool WhiteSpaceIsSignificant() const {
  1.1544 +    return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
  1.1545 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1.1546 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_DISCARD_NEWLINES;
  1.1547 +  }
  1.1548 +
  1.1549 +  bool NewlineIsSignificant() const {
  1.1550 +    return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
  1.1551 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1.1552 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
  1.1553 +  }
  1.1554 +
  1.1555 +  bool NewlineIsDiscarded() const {
  1.1556 +    return mWhiteSpace == NS_STYLE_WHITESPACE_PRE_DISCARD_NEWLINES;
  1.1557 +  }
  1.1558 +
  1.1559 +  bool WhiteSpaceOrNewlineIsSignificant() const {
  1.1560 +    return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
  1.1561 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1.1562 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE ||
  1.1563 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_DISCARD_NEWLINES;
  1.1564 +  }
  1.1565 +
  1.1566 +  bool WhiteSpaceCanWrapStyle() const {
  1.1567 +    return mWhiteSpace == NS_STYLE_WHITESPACE_NORMAL ||
  1.1568 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
  1.1569 +           mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
  1.1570 +  }
  1.1571 +
  1.1572 +  bool WordCanWrapStyle() const {
  1.1573 +    return WhiteSpaceCanWrapStyle() &&
  1.1574 +           mWordWrap == NS_STYLE_WORDWRAP_BREAK_WORD;
  1.1575 +  }
  1.1576 +
  1.1577 +  // These are defined in nsStyleStructInlines.h.
  1.1578 +  inline bool HasTextShadow() const;
  1.1579 +  inline nsCSSShadowArray* GetTextShadow() const;
  1.1580 +
  1.1581 +  // The aContextFrame argument on each of these is the frame this
  1.1582 +  // style struct is for.  If the frame is for SVG text, the return
  1.1583 +  // value will be massaged to be something that makes sense for
  1.1584 +  // SVG text.
  1.1585 +  inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
  1.1586 +  inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
  1.1587 +};
  1.1588 +
  1.1589 +struct nsStyleImageOrientation {
  1.1590 +  static nsStyleImageOrientation CreateAsAngleAndFlip(double aRadians,
  1.1591 +                                                      bool aFlip) {
  1.1592 +    uint8_t orientation(0);
  1.1593 +
  1.1594 +    // Compute the final angle value, rounding to the closest quarter turn.
  1.1595 +    double roundedAngle = fmod(aRadians, 2 * M_PI);
  1.1596 +    if      (roundedAngle < 0.25 * M_PI) orientation = ANGLE_0;
  1.1597 +    else if (roundedAngle < 0.75 * M_PI) orientation = ANGLE_90;
  1.1598 +    else if (roundedAngle < 1.25 * M_PI) orientation = ANGLE_180;
  1.1599 +    else if (roundedAngle < 1.75 * M_PI) orientation = ANGLE_270;
  1.1600 +    else                                 orientation = ANGLE_0;
  1.1601 +
  1.1602 +    // Add a bit for 'flip' if needed.
  1.1603 +    if (aFlip)
  1.1604 +      orientation |= FLIP_MASK;
  1.1605 +
  1.1606 +    return nsStyleImageOrientation(orientation);
  1.1607 +  }
  1.1608 +
  1.1609 +  static nsStyleImageOrientation CreateAsFlip() {
  1.1610 +    return nsStyleImageOrientation(FLIP_MASK);
  1.1611 +  }
  1.1612 +
  1.1613 +  static nsStyleImageOrientation CreateAsFromImage() {
  1.1614 +    return nsStyleImageOrientation(FROM_IMAGE_MASK);
  1.1615 +  }
  1.1616 +
  1.1617 +  // The default constructor yields 0 degrees of rotation and no flip.
  1.1618 +  nsStyleImageOrientation() : mOrientation(0) { }
  1.1619 +
  1.1620 +  bool IsDefault()   const { return mOrientation == 0; }
  1.1621 +  bool IsFlipped()   const { return mOrientation & FLIP_MASK; }
  1.1622 +  bool IsFromImage() const { return mOrientation & FROM_IMAGE_MASK; }
  1.1623 +
  1.1624 +  mozilla::image::Angle Angle() const {
  1.1625 +    switch (mOrientation & ORIENTATION_MASK) {
  1.1626 +      case ANGLE_0:   return mozilla::image::Angle::D0;
  1.1627 +      case ANGLE_90:  return mozilla::image::Angle::D90;
  1.1628 +      case ANGLE_180: return mozilla::image::Angle::D180;
  1.1629 +      case ANGLE_270: return mozilla::image::Angle::D270;
  1.1630 +      default:
  1.1631 +        NS_NOTREACHED("Unexpected angle");
  1.1632 +        return mozilla::image::Angle::D0;
  1.1633 +    }
  1.1634 +  }
  1.1635 +
  1.1636 +  nsStyleCoord AngleAsCoord() const {
  1.1637 +    switch (mOrientation & ORIENTATION_MASK) {
  1.1638 +      case ANGLE_0:   return nsStyleCoord(0.0f,   eStyleUnit_Degree);
  1.1639 +      case ANGLE_90:  return nsStyleCoord(90.0f,  eStyleUnit_Degree);
  1.1640 +      case ANGLE_180: return nsStyleCoord(180.0f, eStyleUnit_Degree);
  1.1641 +      case ANGLE_270: return nsStyleCoord(270.0f, eStyleUnit_Degree);
  1.1642 +      default:
  1.1643 +        NS_NOTREACHED("Unexpected angle");
  1.1644 +        return nsStyleCoord();
  1.1645 +    }
  1.1646 +  }
  1.1647 +
  1.1648 +  bool operator==(const nsStyleImageOrientation& aOther) const {
  1.1649 +    return aOther.mOrientation == mOrientation;
  1.1650 +  }
  1.1651 +
  1.1652 +  bool operator!=(const nsStyleImageOrientation& aOther) const {
  1.1653 +    return !(*this == aOther);
  1.1654 +  }
  1.1655 +
  1.1656 +protected:
  1.1657 +  enum Bits {
  1.1658 +    ORIENTATION_MASK = 0x1 | 0x2,  // The bottom two bits are the angle.
  1.1659 +    FLIP_MASK        = 0x4,        // Whether the image should be flipped.
  1.1660 +    FROM_IMAGE_MASK  = 0x8,        // Whether the image's inherent orientation
  1.1661 +  };                               // should be used.
  1.1662 +
  1.1663 +  enum Angles {
  1.1664 +    ANGLE_0   = 0,
  1.1665 +    ANGLE_90  = 1,
  1.1666 +    ANGLE_180 = 2,
  1.1667 +    ANGLE_270 = 3,
  1.1668 +  };
  1.1669 +
  1.1670 +  explicit nsStyleImageOrientation(uint8_t aOrientation)
  1.1671 +    : mOrientation(aOrientation)
  1.1672 +  { }
  1.1673 +
  1.1674 +  uint8_t mOrientation;
  1.1675 +};
  1.1676 +
  1.1677 +struct nsStyleVisibility {
  1.1678 +  nsStyleVisibility(nsPresContext* aPresContext);
  1.1679 +  nsStyleVisibility(const nsStyleVisibility& aVisibility);
  1.1680 +  ~nsStyleVisibility() {
  1.1681 +    MOZ_COUNT_DTOR(nsStyleVisibility);
  1.1682 +  }
  1.1683 +
  1.1684 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.1685 +    return aContext->AllocateFromShell(sz);
  1.1686 +  }
  1.1687 +  void Destroy(nsPresContext* aContext) {
  1.1688 +    this->~nsStyleVisibility();
  1.1689 +    aContext->FreeToShell(sizeof(nsStyleVisibility), this);
  1.1690 +  }
  1.1691 +
  1.1692 +  nsChangeHint CalcDifference(const nsStyleVisibility& aOther) const;
  1.1693 +  static nsChangeHint MaxDifference() {
  1.1694 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.1695 +  }
  1.1696 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.1697 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.1698 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.1699 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.1700 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.1701 +  }
  1.1702 +
  1.1703 +  nsStyleImageOrientation mImageOrientation;  // [inherited]
  1.1704 +  uint8_t mDirection;                  // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
  1.1705 +  uint8_t mVisible;                    // [inherited]
  1.1706 +  uint8_t mPointerEvents;              // [inherited] see nsStyleConsts.h
  1.1707 +  uint8_t mWritingMode;                // [inherited] see nsStyleConsts.h
  1.1708 +
  1.1709 +  bool IsVisible() const {
  1.1710 +    return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
  1.1711 +  }
  1.1712 +
  1.1713 +  bool IsVisibleOrCollapsed() const {
  1.1714 +    return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
  1.1715 +            (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
  1.1716 +  }
  1.1717 +
  1.1718 +  inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
  1.1719 +};
  1.1720 +
  1.1721 +struct nsTimingFunction {
  1.1722 +  enum Type { Function, StepStart, StepEnd };
  1.1723 +
  1.1724 +  explicit nsTimingFunction(int32_t aTimingFunctionType
  1.1725 +                              = NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE)
  1.1726 +  {
  1.1727 +    AssignFromKeyword(aTimingFunctionType);
  1.1728 +  }
  1.1729 +
  1.1730 +  nsTimingFunction(float x1, float y1, float x2, float y2)
  1.1731 +    : mType(Function)
  1.1732 +  {
  1.1733 +    mFunc.mX1 = x1;
  1.1734 +    mFunc.mY1 = y1;
  1.1735 +    mFunc.mX2 = x2;
  1.1736 +    mFunc.mY2 = y2;
  1.1737 +  }
  1.1738 +
  1.1739 +  nsTimingFunction(Type aType, uint32_t aSteps)
  1.1740 +    : mType(aType)
  1.1741 +  {
  1.1742 +    NS_ABORT_IF_FALSE(mType == StepStart || mType == StepEnd, "wrong type");
  1.1743 +    mSteps = aSteps;
  1.1744 +  }
  1.1745 +
  1.1746 +  nsTimingFunction(const nsTimingFunction& aOther)
  1.1747 +  {
  1.1748 +    *this = aOther;
  1.1749 +  }
  1.1750 +
  1.1751 +  Type mType;
  1.1752 +  union {
  1.1753 +    struct {
  1.1754 +      float mX1;
  1.1755 +      float mY1;
  1.1756 +      float mX2;
  1.1757 +      float mY2;
  1.1758 +    } mFunc;
  1.1759 +    uint32_t mSteps;
  1.1760 +  };
  1.1761 +
  1.1762 +  nsTimingFunction&
  1.1763 +  operator=(const nsTimingFunction& aOther)
  1.1764 +  {
  1.1765 +    if (&aOther == this)
  1.1766 +      return *this;
  1.1767 +
  1.1768 +    mType = aOther.mType;
  1.1769 +
  1.1770 +    if (mType == Function) {
  1.1771 +      mFunc.mX1 = aOther.mFunc.mX1;
  1.1772 +      mFunc.mY1 = aOther.mFunc.mY1;
  1.1773 +      mFunc.mX2 = aOther.mFunc.mX2;
  1.1774 +      mFunc.mY2 = aOther.mFunc.mY2;
  1.1775 +    } else {
  1.1776 +      mSteps = aOther.mSteps;
  1.1777 +    }
  1.1778 +
  1.1779 +    return *this;
  1.1780 +  }
  1.1781 +
  1.1782 +  bool operator==(const nsTimingFunction& aOther) const
  1.1783 +  {
  1.1784 +    if (mType != aOther.mType) {
  1.1785 +      return false;
  1.1786 +    }
  1.1787 +    if (mType == Function) {
  1.1788 +      return mFunc.mX1 == aOther.mFunc.mX1 && mFunc.mY1 == aOther.mFunc.mY1 &&
  1.1789 +             mFunc.mX2 == aOther.mFunc.mX2 && mFunc.mY2 == aOther.mFunc.mY2;
  1.1790 +    }
  1.1791 +    return mSteps == aOther.mSteps;
  1.1792 +  }
  1.1793 +
  1.1794 +  bool operator!=(const nsTimingFunction& aOther) const
  1.1795 +  {
  1.1796 +    return !(*this == aOther);
  1.1797 +  }
  1.1798 +
  1.1799 +private:
  1.1800 +  void AssignFromKeyword(int32_t aTimingFunctionType);
  1.1801 +};
  1.1802 +
  1.1803 +struct nsTransition {
  1.1804 +  nsTransition() { /* leaves uninitialized; see also SetInitialValues */ }
  1.1805 +  explicit nsTransition(const nsTransition& aCopy);
  1.1806 +
  1.1807 +  void SetInitialValues();
  1.1808 +
  1.1809 +  // Delay and Duration are in milliseconds
  1.1810 +
  1.1811 +  const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
  1.1812 +  float GetDelay() const { return mDelay; }
  1.1813 +  float GetDuration() const { return mDuration; }
  1.1814 +  nsCSSProperty GetProperty() const { return mProperty; }
  1.1815 +  nsIAtom* GetUnknownProperty() const { return mUnknownProperty; }
  1.1816 +
  1.1817 +  void SetTimingFunction(const nsTimingFunction& aTimingFunction)
  1.1818 +    { mTimingFunction = aTimingFunction; }
  1.1819 +  void SetDelay(float aDelay) { mDelay = aDelay; }
  1.1820 +  void SetDuration(float aDuration) { mDuration = aDuration; }
  1.1821 +  void SetProperty(nsCSSProperty aProperty)
  1.1822 +    {
  1.1823 +      NS_ASSERTION(aProperty != eCSSProperty_UNKNOWN, "invalid property");
  1.1824 +      mProperty = aProperty;
  1.1825 +    }
  1.1826 +  void SetUnknownProperty(const nsAString& aUnknownProperty);
  1.1827 +  void CopyPropertyFrom(const nsTransition& aOther)
  1.1828 +    {
  1.1829 +      mProperty = aOther.mProperty;
  1.1830 +      mUnknownProperty = aOther.mUnknownProperty;
  1.1831 +    }
  1.1832 +
  1.1833 +  nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
  1.1834 +
  1.1835 +private:
  1.1836 +  nsTimingFunction mTimingFunction;
  1.1837 +  float mDuration;
  1.1838 +  float mDelay;
  1.1839 +  nsCSSProperty mProperty;
  1.1840 +  nsCOMPtr<nsIAtom> mUnknownProperty; // used when mProperty is
  1.1841 +                                      // eCSSProperty_UNKNOWN
  1.1842 +};
  1.1843 +
  1.1844 +struct nsAnimation {
  1.1845 +  nsAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
  1.1846 +  explicit nsAnimation(const nsAnimation& aCopy);
  1.1847 +
  1.1848 +  void SetInitialValues();
  1.1849 +
  1.1850 +  // Delay and Duration are in milliseconds
  1.1851 +
  1.1852 +  const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
  1.1853 +  float GetDelay() const { return mDelay; }
  1.1854 +  float GetDuration() const { return mDuration; }
  1.1855 +  const nsString& GetName() const { return mName; }
  1.1856 +  uint8_t GetDirection() const { return mDirection; }
  1.1857 +  uint8_t GetFillMode() const { return mFillMode; }
  1.1858 +  uint8_t GetPlayState() const { return mPlayState; }
  1.1859 +  float GetIterationCount() const { return mIterationCount; }
  1.1860 +
  1.1861 +  void SetTimingFunction(const nsTimingFunction& aTimingFunction)
  1.1862 +    { mTimingFunction = aTimingFunction; }
  1.1863 +  void SetDelay(float aDelay) { mDelay = aDelay; }
  1.1864 +  void SetDuration(float aDuration) { mDuration = aDuration; }
  1.1865 +  void SetName(const nsSubstring& aName) { mName = aName; }
  1.1866 +  void SetDirection(uint8_t aDirection) { mDirection = aDirection; }
  1.1867 +  void SetFillMode(uint8_t aFillMode) { mFillMode = aFillMode; }
  1.1868 +  void SetPlayState(uint8_t aPlayState) { mPlayState = aPlayState; }
  1.1869 +  void SetIterationCount(float aIterationCount)
  1.1870 +    { mIterationCount = aIterationCount; }
  1.1871 +
  1.1872 +  nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
  1.1873 +
  1.1874 +private:
  1.1875 +  nsTimingFunction mTimingFunction;
  1.1876 +  float mDuration;
  1.1877 +  float mDelay;
  1.1878 +  nsString mName; // empty string for 'none'
  1.1879 +  uint8_t mDirection;
  1.1880 +  uint8_t mFillMode;
  1.1881 +  uint8_t mPlayState;
  1.1882 +  float mIterationCount; // NS_IEEEPositiveInfinity() means infinite
  1.1883 +};
  1.1884 +
  1.1885 +struct nsStyleDisplay {
  1.1886 +  nsStyleDisplay();
  1.1887 +  nsStyleDisplay(const nsStyleDisplay& aOther);
  1.1888 +  ~nsStyleDisplay() {
  1.1889 +    MOZ_COUNT_DTOR(nsStyleDisplay);
  1.1890 +  }
  1.1891 +
  1.1892 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.1893 +    return aContext->AllocateFromShell(sz);
  1.1894 +  }
  1.1895 +  void Destroy(nsPresContext* aContext) {
  1.1896 +    this->~nsStyleDisplay();
  1.1897 +    aContext->FreeToShell(sizeof(nsStyleDisplay), this);
  1.1898 +  }
  1.1899 +
  1.1900 +  nsChangeHint CalcDifference(const nsStyleDisplay& aOther) const;
  1.1901 +  static nsChangeHint MaxDifference() {
  1.1902 +    // All the parts of FRAMECHANGE are present in CalcDifference.
  1.1903 +    return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
  1.1904 +                        nsChangeHint_UpdateOpacityLayer |
  1.1905 +                        nsChangeHint_UpdateTransformLayer |
  1.1906 +                        nsChangeHint_UpdateOverflow |
  1.1907 +                        nsChangeHint_UpdatePostTransformOverflow |
  1.1908 +                        nsChangeHint_AddOrRemoveTransform);
  1.1909 +  }
  1.1910 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.1911 +    // CalcDifference can return both nsChangeHint_ClearAncestorIntrinsics and
  1.1912 +    // nsChangeHint_NeedReflow as inherited hints.
  1.1913 +    return nsChangeHint(0);
  1.1914 +  }
  1.1915 +
  1.1916 +  // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
  1.1917 +  // mBinding->mOriginPrincipal.
  1.1918 +  nsRefPtr<mozilla::css::URLValue> mBinding;    // [reset]
  1.1919 +  nsRect  mClip;                // [reset] offsets from upper-left border edge
  1.1920 +  float   mOpacity;             // [reset]
  1.1921 +  uint8_t mDisplay;             // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
  1.1922 +  uint8_t mOriginalDisplay;     // [reset] saved mDisplay for position:absolute/fixed
  1.1923 +                                //         and float:left/right; otherwise equal
  1.1924 +                                //         to mDisplay
  1.1925 +  uint8_t mAppearance;          // [reset]
  1.1926 +  uint8_t mPosition;            // [reset] see nsStyleConsts.h
  1.1927 +  uint8_t mFloats;              // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*
  1.1928 +  uint8_t mOriginalFloats;      // [reset] saved mFloats for position:absolute/fixed;
  1.1929 +                                //         otherwise equal to mFloats
  1.1930 +  uint8_t mBreakType;           // [reset] see nsStyleConsts.h NS_STYLE_CLEAR_*
  1.1931 +  uint8_t mBreakInside;         // [reset] NS_STYLE_PAGE_BREAK_AUTO/AVOID
  1.1932 +  bool mBreakBefore;    // [reset]
  1.1933 +  bool mBreakAfter;     // [reset]
  1.1934 +  uint8_t mOverflowX;           // [reset] see nsStyleConsts.h
  1.1935 +  uint8_t mOverflowY;           // [reset] see nsStyleConsts.h
  1.1936 +  uint8_t mOverflowClipBox;     // [reset] see nsStyleConsts.h
  1.1937 +  uint8_t mResize;              // [reset] see nsStyleConsts.h
  1.1938 +  uint8_t mClipFlags;           // [reset] see nsStyleConsts.h
  1.1939 +  uint8_t mOrient;              // [reset] see nsStyleConsts.h
  1.1940 +  uint8_t mMixBlendMode;        // [reset] see nsStyleConsts.h
  1.1941 +  uint8_t mWillChangeBitField;  // [reset] see nsStyleConsts.h. Stores a
  1.1942 +                                // bitfield representation of the properties
  1.1943 +                                // that are frequently queried. This should
  1.1944 +                                // match mWillChange. Also tracks if any of the
  1.1945 +                                // properties in the will-change list require
  1.1946 +                                // a stacking context.
  1.1947 +  nsAutoTArray<nsString, 1> mWillChange;
  1.1948 +
  1.1949 +  uint8_t mTouchAction;         // [reset] see nsStyleConsts.h
  1.1950 +
  1.1951 +  // mSpecifiedTransform is the list of transform functions as
  1.1952 +  // specified, or null to indicate there is no transform.  (inherit or
  1.1953 +  // initial are replaced by an actual list of transform functions, or
  1.1954 +  // null, as appropriate.)
  1.1955 +  uint8_t mBackfaceVisibility;
  1.1956 +  uint8_t mTransformStyle;
  1.1957 +  nsRefPtr<nsCSSValueSharedList> mSpecifiedTransform; // [reset]
  1.1958 +  nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
  1.1959 +  nsStyleCoord mChildPerspective; // [reset] coord
  1.1960 +  nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
  1.1961 +
  1.1962 +  nsAutoTArray<nsTransition, 1> mTransitions; // [reset]
  1.1963 +  // The number of elements in mTransitions that are not from repeating
  1.1964 +  // a list due to another property being longer.
  1.1965 +  uint32_t mTransitionTimingFunctionCount,
  1.1966 +           mTransitionDurationCount,
  1.1967 +           mTransitionDelayCount,
  1.1968 +           mTransitionPropertyCount;
  1.1969 +
  1.1970 +  nsAutoTArray<nsAnimation, 1> mAnimations; // [reset]
  1.1971 +  // The number of elements in mAnimations that are not from repeating
  1.1972 +  // a list due to another property being longer.
  1.1973 +  uint32_t mAnimationTimingFunctionCount,
  1.1974 +           mAnimationDurationCount,
  1.1975 +           mAnimationDelayCount,
  1.1976 +           mAnimationNameCount,
  1.1977 +           mAnimationDirectionCount,
  1.1978 +           mAnimationFillModeCount,
  1.1979 +           mAnimationPlayStateCount,
  1.1980 +           mAnimationIterationCountCount;
  1.1981 +
  1.1982 +  bool IsBlockInsideStyle() const {
  1.1983 +    return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
  1.1984 +           NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
  1.1985 +           NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay;
  1.1986 +    // Should TABLE_CELL and TABLE_CAPTION go here?  They have
  1.1987 +    // block frames nested inside of them.
  1.1988 +    // (But please audit all callers before changing.)
  1.1989 +  }
  1.1990 +
  1.1991 +  bool IsBlockOutsideStyle() const {
  1.1992 +    return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
  1.1993 +           NS_STYLE_DISPLAY_FLEX == mDisplay ||
  1.1994 +           NS_STYLE_DISPLAY_GRID == mDisplay ||
  1.1995 +           NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
  1.1996 +           NS_STYLE_DISPLAY_TABLE == mDisplay;
  1.1997 +  }
  1.1998 +
  1.1999 +  static bool IsDisplayTypeInlineOutside(uint8_t aDisplay) {
  1.2000 +    return NS_STYLE_DISPLAY_INLINE == aDisplay ||
  1.2001 +           NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay ||
  1.2002 +           NS_STYLE_DISPLAY_INLINE_TABLE == aDisplay ||
  1.2003 +           NS_STYLE_DISPLAY_INLINE_BOX == aDisplay ||
  1.2004 +           NS_STYLE_DISPLAY_INLINE_FLEX == aDisplay ||
  1.2005 +           NS_STYLE_DISPLAY_INLINE_GRID == aDisplay ||
  1.2006 +           NS_STYLE_DISPLAY_INLINE_XUL_GRID == aDisplay ||
  1.2007 +           NS_STYLE_DISPLAY_INLINE_STACK == aDisplay;
  1.2008 +  }
  1.2009 +
  1.2010 +  bool IsInlineOutsideStyle() const {
  1.2011 +    return IsDisplayTypeInlineOutside(mDisplay);
  1.2012 +  }
  1.2013 +
  1.2014 +  bool IsOriginalDisplayInlineOutsideStyle() const {
  1.2015 +    return IsDisplayTypeInlineOutside(mOriginalDisplay);
  1.2016 +  }
  1.2017 +
  1.2018 +  bool IsInnerTableStyle() const {
  1.2019 +    return NS_STYLE_DISPLAY_TABLE_CAPTION == mDisplay ||
  1.2020 +           NS_STYLE_DISPLAY_TABLE_CELL == mDisplay ||
  1.2021 +           NS_STYLE_DISPLAY_TABLE_ROW == mDisplay ||
  1.2022 +           NS_STYLE_DISPLAY_TABLE_ROW_GROUP == mDisplay ||
  1.2023 +           NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == mDisplay ||
  1.2024 +           NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == mDisplay ||
  1.2025 +           NS_STYLE_DISPLAY_TABLE_COLUMN == mDisplay ||
  1.2026 +           NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == mDisplay;
  1.2027 +  }
  1.2028 +
  1.2029 +  bool IsFloatingStyle() const {
  1.2030 +    return NS_STYLE_FLOAT_NONE != mFloats;
  1.2031 +  }
  1.2032 +
  1.2033 +  bool IsAbsolutelyPositionedStyle() const {
  1.2034 +    return NS_STYLE_POSITION_ABSOLUTE == mPosition ||
  1.2035 +           NS_STYLE_POSITION_FIXED == mPosition;
  1.2036 +  }
  1.2037 +
  1.2038 +  bool IsRelativelyPositionedStyle() const {
  1.2039 +    return NS_STYLE_POSITION_RELATIVE == mPosition ||
  1.2040 +           NS_STYLE_POSITION_STICKY == mPosition;
  1.2041 +  }
  1.2042 +
  1.2043 +  bool IsScrollableOverflow() const {
  1.2044 +    // mOverflowX and mOverflowY always match when one of them is
  1.2045 +    // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
  1.2046 +    return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
  1.2047 +           mOverflowX != NS_STYLE_OVERFLOW_CLIP;
  1.2048 +  }
  1.2049 +
  1.2050 +  /* Returns whether the element has the -moz-transform property
  1.2051 +   * or a related property. */
  1.2052 +  bool HasTransformStyle() const {
  1.2053 +    return mSpecifiedTransform != nullptr ||
  1.2054 +           mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
  1.2055 +           (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM);
  1.2056 +  }
  1.2057 +
  1.2058 +  bool HasPerspectiveStyle() const {
  1.2059 +    return mChildPerspective.GetUnit() == eStyleUnit_Coord;
  1.2060 +  }
  1.2061 +
  1.2062 +  bool BackfaceIsHidden() const {
  1.2063 +    return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
  1.2064 +  }
  1.2065 +
  1.2066 +  // These are defined in nsStyleStructInlines.h.
  1.2067 +
  1.2068 +  // The aContextFrame argument on each of these is the frame this
  1.2069 +  // style struct is for.  If the frame is for SVG text, the return
  1.2070 +  // value will be massaged to be something that makes sense for
  1.2071 +  // SVG text.
  1.2072 +  inline bool IsBlockInside(const nsIFrame* aContextFrame) const;
  1.2073 +  inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
  1.2074 +  inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
  1.2075 +  inline bool IsOriginalDisplayInlineOutside(const nsIFrame* aContextFrame) const;
  1.2076 +  inline uint8_t GetDisplay(const nsIFrame* aContextFrame) const;
  1.2077 +  inline bool IsFloating(const nsIFrame* aContextFrame) const;
  1.2078 +  inline bool IsPositioned(const nsIFrame* aContextFrame) const;
  1.2079 +  inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
  1.2080 +  inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
  1.2081 +
  1.2082 +  /* Returns whether the element has the -moz-transform property
  1.2083 +   * or a related property, and supports CSS transforms. */
  1.2084 +  inline bool HasTransform(const nsIFrame* aContextFrame) const;
  1.2085 +};
  1.2086 +
  1.2087 +struct nsStyleTable {
  1.2088 +  nsStyleTable(void);
  1.2089 +  nsStyleTable(const nsStyleTable& aOther);
  1.2090 +  ~nsStyleTable(void);
  1.2091 +
  1.2092 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2093 +    return aContext->AllocateFromShell(sz);
  1.2094 +  }
  1.2095 +  void Destroy(nsPresContext* aContext) {
  1.2096 +    this->~nsStyleTable();
  1.2097 +    aContext->FreeToShell(sizeof(nsStyleTable), this);
  1.2098 +  }
  1.2099 +
  1.2100 +  nsChangeHint CalcDifference(const nsStyleTable& aOther) const;
  1.2101 +  static nsChangeHint MaxDifference() {
  1.2102 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.2103 +  }
  1.2104 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2105 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2106 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2107 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2108 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2109 +  }
  1.2110 +
  1.2111 +  uint8_t       mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
  1.2112 +  uint8_t       mFrame;         // [reset] see nsStyleConsts.h NS_STYLE_TABLE_FRAME_*
  1.2113 +  uint8_t       mRules;         // [reset] see nsStyleConsts.h NS_STYLE_TABLE_RULES_*
  1.2114 +  int32_t       mSpan;          // [reset] the number of columns spanned by a colgroup or col
  1.2115 +};
  1.2116 +
  1.2117 +struct nsStyleTableBorder {
  1.2118 +  nsStyleTableBorder(nsPresContext* aContext);
  1.2119 +  nsStyleTableBorder(const nsStyleTableBorder& aOther);
  1.2120 +  ~nsStyleTableBorder(void);
  1.2121 +
  1.2122 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2123 +    return aContext->AllocateFromShell(sz);
  1.2124 +  }
  1.2125 +  void Destroy(nsPresContext* aContext) {
  1.2126 +    this->~nsStyleTableBorder();
  1.2127 +    aContext->FreeToShell(sizeof(nsStyleTableBorder), this);
  1.2128 +  }
  1.2129 +
  1.2130 +  nsChangeHint CalcDifference(const nsStyleTableBorder& aOther) const;
  1.2131 +  static nsChangeHint MaxDifference() {
  1.2132 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.2133 +  }
  1.2134 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2135 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2136 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2137 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2138 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2139 +  }
  1.2140 +
  1.2141 +  nscoord       mBorderSpacingX;// [inherited]
  1.2142 +  nscoord       mBorderSpacingY;// [inherited]
  1.2143 +  uint8_t       mBorderCollapse;// [inherited]
  1.2144 +  uint8_t       mCaptionSide;   // [inherited]
  1.2145 +  uint8_t       mEmptyCells;    // [inherited]
  1.2146 +};
  1.2147 +
  1.2148 +enum nsStyleContentType {
  1.2149 +  eStyleContentType_String        = 1,
  1.2150 +  eStyleContentType_Image         = 10,
  1.2151 +  eStyleContentType_Attr          = 20,
  1.2152 +  eStyleContentType_Counter       = 30,
  1.2153 +  eStyleContentType_Counters      = 31,
  1.2154 +  eStyleContentType_OpenQuote     = 40,
  1.2155 +  eStyleContentType_CloseQuote    = 41,
  1.2156 +  eStyleContentType_NoOpenQuote   = 42,
  1.2157 +  eStyleContentType_NoCloseQuote  = 43,
  1.2158 +  eStyleContentType_AltContent    = 50,
  1.2159 +  eStyleContentType_Uninitialized
  1.2160 +};
  1.2161 +
  1.2162 +struct nsStyleContentData {
  1.2163 +  nsStyleContentType  mType;
  1.2164 +  union {
  1.2165 +    char16_t *mString;
  1.2166 +    imgRequestProxy *mImage;
  1.2167 +    nsCSSValue::Array* mCounters;
  1.2168 +  } mContent;
  1.2169 +#ifdef DEBUG
  1.2170 +  bool mImageTracked;
  1.2171 +#endif
  1.2172 +
  1.2173 +  nsStyleContentData()
  1.2174 +    : mType(eStyleContentType_Uninitialized)
  1.2175 +#ifdef DEBUG
  1.2176 +    , mImageTracked(false)
  1.2177 +#endif
  1.2178 +  { mContent.mString = nullptr; }
  1.2179 +
  1.2180 +  ~nsStyleContentData();
  1.2181 +  nsStyleContentData& operator=(const nsStyleContentData& aOther);
  1.2182 +  bool operator==(const nsStyleContentData& aOther) const;
  1.2183 +
  1.2184 +  bool operator!=(const nsStyleContentData& aOther) const {
  1.2185 +    return !(*this == aOther);
  1.2186 +  }
  1.2187 +
  1.2188 +  void TrackImage(nsPresContext* aContext);
  1.2189 +  void UntrackImage(nsPresContext* aContext);
  1.2190 +
  1.2191 +  void SetImage(imgRequestProxy* aRequest)
  1.2192 +  {
  1.2193 +    NS_ABORT_IF_FALSE(!mImageTracked,
  1.2194 +                      "Setting a new image without untracking the old one!");
  1.2195 +    NS_ABORT_IF_FALSE(mType == eStyleContentType_Image, "Wrong type!");
  1.2196 +    NS_IF_ADDREF(mContent.mImage = aRequest);
  1.2197 +  }
  1.2198 +private:
  1.2199 +  nsStyleContentData(const nsStyleContentData&); // not to be implemented
  1.2200 +};
  1.2201 +
  1.2202 +struct nsStyleCounterData {
  1.2203 +  nsString  mCounter;
  1.2204 +  int32_t   mValue;
  1.2205 +};
  1.2206 +
  1.2207 +
  1.2208 +#define DELETE_ARRAY_IF(array)  if (array) { delete[] array; array = nullptr; }
  1.2209 +
  1.2210 +struct nsStyleQuotes {
  1.2211 +  nsStyleQuotes();
  1.2212 +  nsStyleQuotes(const nsStyleQuotes& aQuotes);
  1.2213 +  ~nsStyleQuotes();
  1.2214 +
  1.2215 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2216 +    return aContext->AllocateFromShell(sz);
  1.2217 +  }
  1.2218 +  void Destroy(nsPresContext* aContext) {
  1.2219 +    this->~nsStyleQuotes();
  1.2220 +    aContext->FreeToShell(sizeof(nsStyleQuotes), this);
  1.2221 +  }
  1.2222 +
  1.2223 +  void SetInitial();
  1.2224 +  void CopyFrom(const nsStyleQuotes& aSource);
  1.2225 +
  1.2226 +  nsChangeHint CalcDifference(const nsStyleQuotes& aOther) const;
  1.2227 +  static nsChangeHint MaxDifference() {
  1.2228 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.2229 +  }
  1.2230 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2231 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2232 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2233 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2234 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2235 +  }
  1.2236 +
  1.2237 +  uint32_t  QuotesCount(void) const { return mQuotesCount; } // [inherited]
  1.2238 +
  1.2239 +  const nsString* OpenQuoteAt(uint32_t aIndex) const
  1.2240 +  {
  1.2241 +    NS_ASSERTION(aIndex < mQuotesCount, "out of range");
  1.2242 +    return mQuotes + (aIndex * 2);
  1.2243 +  }
  1.2244 +  const nsString* CloseQuoteAt(uint32_t aIndex) const
  1.2245 +  {
  1.2246 +    NS_ASSERTION(aIndex < mQuotesCount, "out of range");
  1.2247 +    return mQuotes + (aIndex * 2 + 1);
  1.2248 +  }
  1.2249 +  nsresult  GetQuotesAt(uint32_t aIndex, nsString& aOpen, nsString& aClose) const {
  1.2250 +    if (aIndex < mQuotesCount) {
  1.2251 +      aIndex *= 2;
  1.2252 +      aOpen = mQuotes[aIndex];
  1.2253 +      aClose = mQuotes[++aIndex];
  1.2254 +      return NS_OK;
  1.2255 +    }
  1.2256 +    return NS_ERROR_ILLEGAL_VALUE;
  1.2257 +  }
  1.2258 +
  1.2259 +  nsresult  AllocateQuotes(uint32_t aCount) {
  1.2260 +    if (aCount != mQuotesCount) {
  1.2261 +      DELETE_ARRAY_IF(mQuotes);
  1.2262 +      if (aCount) {
  1.2263 +        mQuotes = new nsString[aCount * 2];
  1.2264 +        if (! mQuotes) {
  1.2265 +          mQuotesCount = 0;
  1.2266 +          return NS_ERROR_OUT_OF_MEMORY;
  1.2267 +        }
  1.2268 +      }
  1.2269 +      mQuotesCount = aCount;
  1.2270 +    }
  1.2271 +    return NS_OK;
  1.2272 +  }
  1.2273 +
  1.2274 +  nsresult  SetQuotesAt(uint32_t aIndex, const nsString& aOpen, const nsString& aClose) {
  1.2275 +    if (aIndex < mQuotesCount) {
  1.2276 +      aIndex *= 2;
  1.2277 +      mQuotes[aIndex] = aOpen;
  1.2278 +      mQuotes[++aIndex] = aClose;
  1.2279 +      return NS_OK;
  1.2280 +    }
  1.2281 +    return NS_ERROR_ILLEGAL_VALUE;
  1.2282 +  }
  1.2283 +
  1.2284 +protected:
  1.2285 +  uint32_t            mQuotesCount;
  1.2286 +  nsString*           mQuotes;
  1.2287 +};
  1.2288 +
  1.2289 +struct nsStyleContent {
  1.2290 +  nsStyleContent(void);
  1.2291 +  nsStyleContent(const nsStyleContent& aContent);
  1.2292 +  ~nsStyleContent(void);
  1.2293 +
  1.2294 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2295 +    return aContext->AllocateFromShell(sz);
  1.2296 +  }
  1.2297 +  void Destroy(nsPresContext* aContext);
  1.2298 +
  1.2299 +  nsChangeHint CalcDifference(const nsStyleContent& aOther) const;
  1.2300 +  static nsChangeHint MaxDifference() {
  1.2301 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.2302 +  }
  1.2303 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2304 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2305 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2306 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2307 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2308 +  }
  1.2309 +
  1.2310 +  uint32_t  ContentCount(void) const  { return mContentCount; } // [reset]
  1.2311 +
  1.2312 +  const nsStyleContentData& ContentAt(uint32_t aIndex) const {
  1.2313 +    NS_ASSERTION(aIndex < mContentCount, "out of range");
  1.2314 +    return mContents[aIndex];
  1.2315 +  }
  1.2316 +
  1.2317 +  nsStyleContentData& ContentAt(uint32_t aIndex) {
  1.2318 +    NS_ASSERTION(aIndex < mContentCount, "out of range");
  1.2319 +    return mContents[aIndex];
  1.2320 +  }
  1.2321 +
  1.2322 +  nsresult AllocateContents(uint32_t aCount);
  1.2323 +
  1.2324 +  uint32_t  CounterIncrementCount(void) const { return mIncrementCount; }  // [reset]
  1.2325 +  const nsStyleCounterData* GetCounterIncrementAt(uint32_t aIndex) const {
  1.2326 +    NS_ASSERTION(aIndex < mIncrementCount, "out of range");
  1.2327 +    return &mIncrements[aIndex];
  1.2328 +  }
  1.2329 +
  1.2330 +  nsresult  AllocateCounterIncrements(uint32_t aCount) {
  1.2331 +    if (aCount != mIncrementCount) {
  1.2332 +      DELETE_ARRAY_IF(mIncrements);
  1.2333 +      if (aCount) {
  1.2334 +        mIncrements = new nsStyleCounterData[aCount];
  1.2335 +        if (! mIncrements) {
  1.2336 +          mIncrementCount = 0;
  1.2337 +          return NS_ERROR_OUT_OF_MEMORY;
  1.2338 +        }
  1.2339 +      }
  1.2340 +      mIncrementCount = aCount;
  1.2341 +    }
  1.2342 +    return NS_OK;
  1.2343 +  }
  1.2344 +
  1.2345 +  nsresult  SetCounterIncrementAt(uint32_t aIndex, const nsString& aCounter, int32_t aIncrement) {
  1.2346 +    if (aIndex < mIncrementCount) {
  1.2347 +      mIncrements[aIndex].mCounter = aCounter;
  1.2348 +      mIncrements[aIndex].mValue = aIncrement;
  1.2349 +      return NS_OK;
  1.2350 +    }
  1.2351 +    return NS_ERROR_ILLEGAL_VALUE;
  1.2352 +  }
  1.2353 +
  1.2354 +  uint32_t  CounterResetCount(void) const { return mResetCount; }  // [reset]
  1.2355 +  const nsStyleCounterData* GetCounterResetAt(uint32_t aIndex) const {
  1.2356 +    NS_ASSERTION(aIndex < mResetCount, "out of range");
  1.2357 +    return &mResets[aIndex];
  1.2358 +  }
  1.2359 +
  1.2360 +  nsresult  AllocateCounterResets(uint32_t aCount) {
  1.2361 +    if (aCount != mResetCount) {
  1.2362 +      DELETE_ARRAY_IF(mResets);
  1.2363 +      if (aCount) {
  1.2364 +        mResets = new nsStyleCounterData[aCount];
  1.2365 +        if (! mResets) {
  1.2366 +          mResetCount = 0;
  1.2367 +          return NS_ERROR_OUT_OF_MEMORY;
  1.2368 +        }
  1.2369 +      }
  1.2370 +      mResetCount = aCount;
  1.2371 +    }
  1.2372 +    return NS_OK;
  1.2373 +  }
  1.2374 +
  1.2375 +  nsresult  SetCounterResetAt(uint32_t aIndex, const nsString& aCounter, int32_t aValue) {
  1.2376 +    if (aIndex < mResetCount) {
  1.2377 +      mResets[aIndex].mCounter = aCounter;
  1.2378 +      mResets[aIndex].mValue = aValue;
  1.2379 +      return NS_OK;
  1.2380 +    }
  1.2381 +    return NS_ERROR_ILLEGAL_VALUE;
  1.2382 +  }
  1.2383 +
  1.2384 +  nsStyleCoord  mMarkerOffset;  // [reset] coord, auto
  1.2385 +
  1.2386 +protected:
  1.2387 +  nsStyleContentData* mContents;
  1.2388 +  nsStyleCounterData* mIncrements;
  1.2389 +  nsStyleCounterData* mResets;
  1.2390 +
  1.2391 +  uint32_t            mContentCount;
  1.2392 +  uint32_t            mIncrementCount;
  1.2393 +  uint32_t            mResetCount;
  1.2394 +};
  1.2395 +
  1.2396 +struct nsStyleUIReset {
  1.2397 +  nsStyleUIReset(void);
  1.2398 +  nsStyleUIReset(const nsStyleUIReset& aOther);
  1.2399 +  ~nsStyleUIReset(void);
  1.2400 +
  1.2401 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2402 +    return aContext->AllocateFromShell(sz);
  1.2403 +  }
  1.2404 +  void Destroy(nsPresContext* aContext) {
  1.2405 +    this->~nsStyleUIReset();
  1.2406 +    aContext->FreeToShell(sizeof(nsStyleUIReset), this);
  1.2407 +  }
  1.2408 +
  1.2409 +  nsChangeHint CalcDifference(const nsStyleUIReset& aOther) const;
  1.2410 +  static nsChangeHint MaxDifference() {
  1.2411 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.2412 +  }
  1.2413 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2414 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2415 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2416 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2417 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2418 +  }
  1.2419 +
  1.2420 +  uint8_t   mUserSelect;      // [reset] (selection-style)
  1.2421 +  uint8_t   mForceBrokenImageIcon; // [reset]  (0 if not forcing, otherwise forcing)
  1.2422 +  uint8_t   mIMEMode;         // [reset]
  1.2423 +  uint8_t   mWindowShadow;    // [reset]
  1.2424 +};
  1.2425 +
  1.2426 +struct nsCursorImage {
  1.2427 +  bool mHaveHotspot;
  1.2428 +  float mHotspotX, mHotspotY;
  1.2429 +
  1.2430 +  nsCursorImage();
  1.2431 +  nsCursorImage(const nsCursorImage& aOther);
  1.2432 +  ~nsCursorImage();
  1.2433 +
  1.2434 +  nsCursorImage& operator=(const nsCursorImage& aOther);
  1.2435 +  /*
  1.2436 +   * We hide mImage and force access through the getter and setter so that we
  1.2437 +   * can lock the images we use. Cursor images are likely to be small, so we
  1.2438 +   * don't care about discarding them. See bug 512260.
  1.2439 +   * */
  1.2440 +  void SetImage(imgIRequest *aImage) {
  1.2441 +    if (mImage)
  1.2442 +      mImage->UnlockImage();
  1.2443 +    mImage = aImage;
  1.2444 +    if (mImage)
  1.2445 +      mImage->LockImage();
  1.2446 +  }
  1.2447 +  imgIRequest* GetImage() const {
  1.2448 +    return mImage;
  1.2449 +  }
  1.2450 +
  1.2451 +private:
  1.2452 +  nsCOMPtr<imgIRequest> mImage;
  1.2453 +};
  1.2454 +
  1.2455 +struct nsStyleUserInterface {
  1.2456 +  nsStyleUserInterface(void);
  1.2457 +  nsStyleUserInterface(const nsStyleUserInterface& aOther);
  1.2458 +  ~nsStyleUserInterface(void);
  1.2459 +
  1.2460 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2461 +    return aContext->AllocateFromShell(sz);
  1.2462 +  }
  1.2463 +  void Destroy(nsPresContext* aContext) {
  1.2464 +    this->~nsStyleUserInterface();
  1.2465 +    aContext->FreeToShell(sizeof(nsStyleUserInterface), this);
  1.2466 +  }
  1.2467 +
  1.2468 +  nsChangeHint CalcDifference(const nsStyleUserInterface& aOther) const;
  1.2469 +  static nsChangeHint MaxDifference() {
  1.2470 +    return nsChangeHint(nsChangeHint_UpdateCursor | NS_STYLE_HINT_FRAMECHANGE);
  1.2471 +  }
  1.2472 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2473 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2474 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2475 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2476 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2477 +  }
  1.2478 +
  1.2479 +  uint8_t   mUserInput;       // [inherited]
  1.2480 +  uint8_t   mUserModify;      // [inherited] (modify-content)
  1.2481 +  uint8_t   mUserFocus;       // [inherited] (auto-select)
  1.2482 +
  1.2483 +  uint8_t   mCursor;          // [inherited] See nsStyleConsts.h
  1.2484 +
  1.2485 +  uint32_t mCursorArrayLength;
  1.2486 +  nsCursorImage *mCursorArray;// [inherited] The specified URL values
  1.2487 +                              //   and coordinates.  Takes precedence over
  1.2488 +                              //   mCursor.  Zero-length array is represented
  1.2489 +                              //   by null pointer.
  1.2490 +
  1.2491 +  // Does not free mCursorArray; the caller is responsible for calling
  1.2492 +  // |delete [] mCursorArray| first if it is needed.
  1.2493 +  void CopyCursorArrayFrom(const nsStyleUserInterface& aSource);
  1.2494 +};
  1.2495 +
  1.2496 +struct nsStyleXUL {
  1.2497 +  nsStyleXUL();
  1.2498 +  nsStyleXUL(const nsStyleXUL& aSource);
  1.2499 +  ~nsStyleXUL();
  1.2500 +
  1.2501 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2502 +    return aContext->AllocateFromShell(sz);
  1.2503 +  }
  1.2504 +  void Destroy(nsPresContext* aContext) {
  1.2505 +    this->~nsStyleXUL();
  1.2506 +    aContext->FreeToShell(sizeof(nsStyleXUL), this);
  1.2507 +  }
  1.2508 +
  1.2509 +  nsChangeHint CalcDifference(const nsStyleXUL& aOther) const;
  1.2510 +  static nsChangeHint MaxDifference() {
  1.2511 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.2512 +  }
  1.2513 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2514 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2515 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2516 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2517 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2518 +  }
  1.2519 +
  1.2520 +  float         mBoxFlex;               // [reset] see nsStyleConsts.h
  1.2521 +  uint32_t      mBoxOrdinal;            // [reset] see nsStyleConsts.h
  1.2522 +  uint8_t       mBoxAlign;              // [reset] see nsStyleConsts.h
  1.2523 +  uint8_t       mBoxDirection;          // [reset] see nsStyleConsts.h
  1.2524 +  uint8_t       mBoxOrient;             // [reset] see nsStyleConsts.h
  1.2525 +  uint8_t       mBoxPack;               // [reset] see nsStyleConsts.h
  1.2526 +  bool          mStretchStack;          // [reset] see nsStyleConsts.h
  1.2527 +};
  1.2528 +
  1.2529 +struct nsStyleColumn {
  1.2530 +  nsStyleColumn(nsPresContext* aPresContext);
  1.2531 +  nsStyleColumn(const nsStyleColumn& aSource);
  1.2532 +  ~nsStyleColumn();
  1.2533 +
  1.2534 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2535 +    return aContext->AllocateFromShell(sz);
  1.2536 +  }
  1.2537 +  void Destroy(nsPresContext* aContext) {
  1.2538 +    this->~nsStyleColumn();
  1.2539 +    aContext->FreeToShell(sizeof(nsStyleColumn), this);
  1.2540 +  }
  1.2541 +
  1.2542 +  nsChangeHint CalcDifference(const nsStyleColumn& aOther) const;
  1.2543 +  static nsChangeHint MaxDifference() {
  1.2544 +    return NS_STYLE_HINT_FRAMECHANGE;
  1.2545 +  }
  1.2546 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2547 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2548 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2549 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2550 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2551 +  }
  1.2552 +
  1.2553 +  /**
  1.2554 +   * This is the maximum number of columns we can process. It's used in both
  1.2555 +   * nsColumnSetFrame and nsRuleNode.
  1.2556 +   */
  1.2557 +  static const uint32_t kMaxColumnCount;
  1.2558 +
  1.2559 +  uint32_t     mColumnCount; // [reset] see nsStyleConsts.h
  1.2560 +  nsStyleCoord mColumnWidth; // [reset] coord, auto
  1.2561 +  nsStyleCoord mColumnGap;   // [reset] coord, normal
  1.2562 +
  1.2563 +  nscolor      mColumnRuleColor;  // [reset]
  1.2564 +  uint8_t      mColumnRuleStyle;  // [reset]
  1.2565 +  uint8_t      mColumnFill;  // [reset] see nsStyleConsts.h
  1.2566 +
  1.2567 +  // See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
  1.2568 +  // this is hard to replace with 'currentColor'.
  1.2569 +  bool mColumnRuleColorIsForeground;
  1.2570 +
  1.2571 +  void SetColumnRuleWidth(nscoord aWidth) {
  1.2572 +    mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
  1.2573 +  }
  1.2574 +
  1.2575 +  nscoord GetComputedColumnRuleWidth() const {
  1.2576 +    return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
  1.2577 +  }
  1.2578 +
  1.2579 +protected:
  1.2580 +  nscoord mColumnRuleWidth;  // [reset] coord
  1.2581 +  nscoord mTwipsPerPixel;
  1.2582 +};
  1.2583 +
  1.2584 +enum nsStyleSVGPaintType {
  1.2585 +  eStyleSVGPaintType_None = 1,
  1.2586 +  eStyleSVGPaintType_Color,
  1.2587 +  eStyleSVGPaintType_Server,
  1.2588 +  eStyleSVGPaintType_ContextFill,
  1.2589 +  eStyleSVGPaintType_ContextStroke
  1.2590 +};
  1.2591 +
  1.2592 +enum nsStyleSVGOpacitySource {
  1.2593 +  eStyleSVGOpacitySource_Normal,
  1.2594 +  eStyleSVGOpacitySource_ContextFillOpacity,
  1.2595 +  eStyleSVGOpacitySource_ContextStrokeOpacity
  1.2596 +};
  1.2597 +
  1.2598 +struct nsStyleSVGPaint
  1.2599 +{
  1.2600 +  union {
  1.2601 +    nscolor mColor;
  1.2602 +    nsIURI *mPaintServer;
  1.2603 +  } mPaint;
  1.2604 +  nsStyleSVGPaintType mType;
  1.2605 +  nscolor mFallbackColor;
  1.2606 +
  1.2607 +  nsStyleSVGPaint() : mType(nsStyleSVGPaintType(0)) { mPaint.mPaintServer = nullptr; }
  1.2608 +  ~nsStyleSVGPaint();
  1.2609 +  void SetType(nsStyleSVGPaintType aType);
  1.2610 +  nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
  1.2611 +  bool operator==(const nsStyleSVGPaint& aOther) const;
  1.2612 +
  1.2613 +  bool operator!=(const nsStyleSVGPaint& aOther) const {
  1.2614 +    return !(*this == aOther);
  1.2615 +  }
  1.2616 +};
  1.2617 +
  1.2618 +struct nsStyleSVG {
  1.2619 +  nsStyleSVG();
  1.2620 +  nsStyleSVG(const nsStyleSVG& aSource);
  1.2621 +  ~nsStyleSVG();
  1.2622 +
  1.2623 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2624 +    return aContext->AllocateFromShell(sz);
  1.2625 +  }
  1.2626 +  void Destroy(nsPresContext* aContext) {
  1.2627 +    this->~nsStyleSVG();
  1.2628 +    aContext->FreeToShell(sizeof(nsStyleSVG), this);
  1.2629 +  }
  1.2630 +
  1.2631 +  nsChangeHint CalcDifference(const nsStyleSVG& aOther) const;
  1.2632 +  static nsChangeHint MaxDifference() {
  1.2633 +    return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects,
  1.2634 +             NS_CombineHint(nsChangeHint_NeedReflow, nsChangeHint_NeedDirtyReflow)), // XXX remove nsChangeHint_NeedDirtyReflow: bug 876085
  1.2635 +                                         nsChangeHint_RepaintFrame);
  1.2636 +  }
  1.2637 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2638 +    // CalcDifference never returns nsChangeHint_NeedReflow as an inherited hint
  1.2639 +    // and never returns nsChangeHint_ClearAncestorIntrinsics at all.
  1.2640 +    return nsChangeHint_NeedReflow;
  1.2641 +  }
  1.2642 +
  1.2643 +  nsStyleSVGPaint  mFill;             // [inherited]
  1.2644 +  nsStyleSVGPaint  mStroke;           // [inherited]
  1.2645 +  nsCOMPtr<nsIURI> mMarkerEnd;        // [inherited]
  1.2646 +  nsCOMPtr<nsIURI> mMarkerMid;        // [inherited]
  1.2647 +  nsCOMPtr<nsIURI> mMarkerStart;      // [inherited]
  1.2648 +  nsStyleCoord    *mStrokeDasharray;  // [inherited] coord, percent, factor
  1.2649 +
  1.2650 +  nsStyleCoord     mStrokeDashoffset; // [inherited] coord, percent, factor
  1.2651 +  nsStyleCoord     mStrokeWidth;      // [inherited] coord, percent, factor
  1.2652 +
  1.2653 +  float            mFillOpacity;      // [inherited]
  1.2654 +  float            mStrokeMiterlimit; // [inherited]
  1.2655 +  float            mStrokeOpacity;    // [inherited]
  1.2656 +
  1.2657 +  uint32_t         mStrokeDasharrayLength;
  1.2658 +  uint8_t          mClipRule;         // [inherited]
  1.2659 +  uint8_t          mColorInterpolation; // [inherited] see nsStyleConsts.h
  1.2660 +  uint8_t          mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
  1.2661 +  uint8_t          mFillRule;         // [inherited] see nsStyleConsts.h
  1.2662 +  uint8_t          mImageRendering;   // [inherited] see nsStyleConsts.h
  1.2663 +  uint8_t          mPaintOrder;       // [inherited] see nsStyleConsts.h
  1.2664 +  uint8_t          mShapeRendering;   // [inherited] see nsStyleConsts.h
  1.2665 +  uint8_t          mStrokeLinecap;    // [inherited] see nsStyleConsts.h
  1.2666 +  uint8_t          mStrokeLinejoin;   // [inherited] see nsStyleConsts.h
  1.2667 +  uint8_t          mTextAnchor;       // [inherited] see nsStyleConsts.h
  1.2668 +  uint8_t          mTextRendering;    // [inherited] see nsStyleConsts.h
  1.2669 +
  1.2670 +  // In SVG glyphs, whether we inherit fill or stroke opacity from the outer
  1.2671 +  // text object.
  1.2672 +  // Use 3 bits to avoid signedness problems in MSVC.
  1.2673 +  nsStyleSVGOpacitySource mFillOpacitySource    : 3;
  1.2674 +  nsStyleSVGOpacitySource mStrokeOpacitySource  : 3;
  1.2675 +
  1.2676 +  // SVG glyph outer object inheritance for other properties
  1.2677 +  bool mStrokeDasharrayFromObject   : 1;
  1.2678 +  bool mStrokeDashoffsetFromObject  : 1;
  1.2679 +  bool mStrokeWidthFromObject       : 1;
  1.2680 +
  1.2681 +  bool HasMarker() const {
  1.2682 +    return mMarkerStart || mMarkerMid || mMarkerEnd;
  1.2683 +  }
  1.2684 +
  1.2685 +  /**
  1.2686 +   * Returns true if the stroke is not "none" and the stroke-opacity is greater
  1.2687 +   * than zero. This ignores stroke-widths as that depends on the context.
  1.2688 +   */
  1.2689 +  bool HasStroke() const {
  1.2690 +    return mStroke.mType != eStyleSVGPaintType_None && mStrokeOpacity > 0;
  1.2691 +  }
  1.2692 +
  1.2693 +  /**
  1.2694 +   * Returns true if the fill is not "none" and the fill-opacity is greater
  1.2695 +   * than zero.
  1.2696 +   */
  1.2697 +  bool HasFill() const {
  1.2698 +    return mFill.mType != eStyleSVGPaintType_None && mFillOpacity > 0;
  1.2699 +  }
  1.2700 +};
  1.2701 +
  1.2702 +struct nsStyleFilter {
  1.2703 +  nsStyleFilter();
  1.2704 +  nsStyleFilter(const nsStyleFilter& aSource);
  1.2705 +  ~nsStyleFilter();
  1.2706 +
  1.2707 +  nsStyleFilter& operator=(const nsStyleFilter& aOther);
  1.2708 +
  1.2709 +  bool operator==(const nsStyleFilter& aOther) const;
  1.2710 +
  1.2711 +  int32_t GetType() const {
  1.2712 +    return mType;
  1.2713 +  }
  1.2714 +
  1.2715 +  const nsStyleCoord& GetFilterParameter() const {
  1.2716 +    NS_ASSERTION(mType != NS_STYLE_FILTER_DROP_SHADOW &&
  1.2717 +                 mType != NS_STYLE_FILTER_URL &&
  1.2718 +                 mType != NS_STYLE_FILTER_NONE, "wrong filter type");
  1.2719 +    return mFilterParameter;
  1.2720 +  }
  1.2721 +  void SetFilterParameter(const nsStyleCoord& aFilterParameter,
  1.2722 +                          int32_t aType);
  1.2723 +
  1.2724 +  nsIURI* GetURL() const {
  1.2725 +    NS_ASSERTION(mType == NS_STYLE_FILTER_URL, "wrong filter type");
  1.2726 +    return mURL;
  1.2727 +  }
  1.2728 +  void SetURL(nsIURI* aURL);
  1.2729 +
  1.2730 +  nsCSSShadowArray* GetDropShadow() const {
  1.2731 +    NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type");
  1.2732 +    return mDropShadow;
  1.2733 +  }
  1.2734 +  void SetDropShadow(nsCSSShadowArray* aDropShadow);
  1.2735 +
  1.2736 +private:
  1.2737 +  void ReleaseRef();
  1.2738 +
  1.2739 +  int32_t mType; // see NS_STYLE_FILTER_* constants in nsStyleConsts.h
  1.2740 +  nsStyleCoord mFilterParameter; // coord, percent, factor, angle
  1.2741 +  union {
  1.2742 +    nsIURI* mURL;
  1.2743 +    nsCSSShadowArray* mDropShadow;
  1.2744 +  };
  1.2745 +};
  1.2746 +
  1.2747 +template<>
  1.2748 +struct nsTArray_CopyChooser<nsStyleFilter> {
  1.2749 +  typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
  1.2750 +};
  1.2751 +
  1.2752 +struct nsStyleSVGReset {
  1.2753 +  nsStyleSVGReset();
  1.2754 +  nsStyleSVGReset(const nsStyleSVGReset& aSource);
  1.2755 +  ~nsStyleSVGReset();
  1.2756 +
  1.2757 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2758 +    return aContext->AllocateFromShell(sz);
  1.2759 +  }
  1.2760 +  void Destroy(nsPresContext* aContext) {
  1.2761 +    this->~nsStyleSVGReset();
  1.2762 +    aContext->FreeToShell(sizeof(nsStyleSVGReset), this);
  1.2763 +  }
  1.2764 +
  1.2765 +  nsChangeHint CalcDifference(const nsStyleSVGReset& aOther) const;
  1.2766 +  static nsChangeHint MaxDifference() {
  1.2767 +    return NS_CombineHint(nsChangeHint_UpdateEffects,
  1.2768 +            NS_CombineHint(nsChangeHint_UpdateOverflow, NS_STYLE_HINT_REFLOW));
  1.2769 +  }
  1.2770 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2771 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2772 +    // nsChangeHint_ClearAncestorIntrinsics as inherited hints.
  1.2773 +    return NS_CombineHint(nsChangeHint_NeedReflow,
  1.2774 +                          nsChangeHint_ClearAncestorIntrinsics);
  1.2775 +  }
  1.2776 +
  1.2777 +  bool HasFilters() const {
  1.2778 +    return mFilters.Length() > 0;
  1.2779 +  }
  1.2780 +
  1.2781 +  nsCOMPtr<nsIURI> mClipPath;         // [reset]
  1.2782 +  nsTArray<nsStyleFilter> mFilters;   // [reset]
  1.2783 +  nsCOMPtr<nsIURI> mMask;             // [reset]
  1.2784 +  nscolor          mStopColor;        // [reset]
  1.2785 +  nscolor          mFloodColor;       // [reset]
  1.2786 +  nscolor          mLightingColor;    // [reset]
  1.2787 +
  1.2788 +  float            mStopOpacity;      // [reset]
  1.2789 +  float            mFloodOpacity;     // [reset]
  1.2790 +
  1.2791 +  uint8_t          mDominantBaseline; // [reset] see nsStyleConsts.h
  1.2792 +  uint8_t          mVectorEffect;     // [reset] see nsStyleConsts.h
  1.2793 +  uint8_t          mMaskType;         // [reset] see nsStyleConsts.h
  1.2794 +};
  1.2795 +
  1.2796 +struct nsStyleVariables {
  1.2797 +  nsStyleVariables();
  1.2798 +  nsStyleVariables(const nsStyleVariables& aSource);
  1.2799 +  ~nsStyleVariables();
  1.2800 +
  1.2801 +  void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
  1.2802 +    return aContext->AllocateFromShell(sz);
  1.2803 +  }
  1.2804 +  void Destroy(nsPresContext* aContext) {
  1.2805 +    this->~nsStyleVariables();
  1.2806 +    aContext->FreeToShell(sizeof(nsStyleVariables), this);
  1.2807 +  }
  1.2808 +
  1.2809 +  nsChangeHint CalcDifference(const nsStyleVariables& aOther) const;
  1.2810 +  static nsChangeHint MaxDifference() {
  1.2811 +    return nsChangeHint(0);
  1.2812 +  }
  1.2813 +  static nsChangeHint MaxDifferenceNeverInherited() {
  1.2814 +    // CalcDifference never returns nsChangeHint_NeedReflow or
  1.2815 +    // nsChangeHint_ClearAncestorIntrinsics at all.
  1.2816 +    return nsChangeHint(0);
  1.2817 +  }
  1.2818 +
  1.2819 +  mozilla::CSSVariableValues mVariables;
  1.2820 +};
  1.2821 +
  1.2822 +#endif /* nsStyleStruct_h___ */

mercurial