LCOV - code coverage report
Current view: top level - layout/style - nsStyleStruct.h (source / functions) Hit Total Coverage
Test: output.info Lines: 287 493 58.2 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /*
       8             :  * structs that contain the data provided by ComputedStyle, the
       9             :  * internal API for computed style data for an element
      10             :  */
      11             : 
      12             : #ifndef nsStyleStruct_h___
      13             : #define nsStyleStruct_h___
      14             : 
      15             : #include "mozilla/Attributes.h"
      16             : #include "mozilla/Maybe.h"
      17             : #include "mozilla/SheetType.h"
      18             : #include "mozilla/StaticPtr.h"
      19             : #include "mozilla/StyleComplexColor.h"
      20             : #include "mozilla/UniquePtr.h"
      21             : #include "nsColor.h"
      22             : #include "nsCoord.h"
      23             : #include "nsMargin.h"
      24             : #include "nsFont.h"
      25             : #include "nsStyleAutoArray.h"
      26             : #include "nsStyleCoord.h"
      27             : #include "nsStyleConsts.h"
      28             : #include "nsChangeHint.h"
      29             : #include "nsTimingFunction.h"
      30             : #include "nsCOMPtr.h"
      31             : #include "nsCOMArray.h"
      32             : #include "nsTArray.h"
      33             : #include "nsCSSValue.h"
      34             : #include "imgRequestProxy.h"
      35             : #include "Orientation.h"
      36             : #include "CounterStyleManager.h"
      37             : #include <cstddef> // offsetof()
      38             : #include <utility>
      39             : #include "X11UndefineNone.h"
      40             : 
      41             : class nsIFrame;
      42             : class nsIURI;
      43             : class nsTextFrame;
      44             : class imgIContainer;
      45             : class nsPresContext;
      46             : struct nsStyleDisplay;
      47             : struct nsStyleVisibility;
      48             : namespace mozilla {
      49             : class ComputedStyle;
      50             : namespace dom {
      51             : class ImageTracker;
      52             : } // namespace dom
      53             : } // namespace mozilla
      54             : 
      55             : namespace mozilla {
      56             : 
      57             : struct Position {
      58             :   using Coord = nsStyleCoord::CalcValue;
      59             : 
      60             :   Coord mXPosition, mYPosition;
      61             : 
      62             :   // Initialize nothing
      63         840 :   Position() {}
      64             : 
      65             :   // Sets both mXPosition and mYPosition to the given percent value for the
      66             :   // initial property-value (e.g. 0.0f for "0% 0%", or 0.5f for "50% 50%")
      67             :   void SetInitialPercentValues(float aPercentVal);
      68             : 
      69             :   // Sets both mXPosition and mYPosition to 0 (app units) for the
      70             :   // initial property-value as a length with no percentage component.
      71             :   void SetInitialZeroValues();
      72             : 
      73             :   // True if the effective background image position described by this depends
      74             :   // on the size of the corresponding frame.
      75           0 :   bool DependsOnPositioningAreaSize() const {
      76           0 :     return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
      77             :   }
      78             : 
      79         180 :   bool operator==(const Position& aOther) const {
      80         360 :     return mXPosition == aOther.mXPosition &&
      81         360 :       mYPosition == aOther.mYPosition;
      82             :   }
      83         180 :   bool operator!=(const Position& aOther) const {
      84         180 :     return !(*this == aOther);
      85             :   }
      86             : };
      87             : 
      88             : } // namespace mozilla
      89             : 
      90             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont
      91             : {
      92             :   nsStyleFont(const nsFont& aFont, const nsPresContext* aContext);
      93             :   nsStyleFont(const nsStyleFont& aStyleFont);
      94             :   explicit nsStyleFont(const nsPresContext* aContext);
      95         352 :   ~nsStyleFont() {
      96         176 :     MOZ_COUNT_DTOR(nsStyleFont);
      97         176 :   }
      98             :   void FinishStyle(nsPresContext*, const nsStyleFont*) {}
      99             :   const static bool kHasFinishStyle = false;
     100             : 
     101             :   nsChangeHint CalcDifference(const nsStyleFont& aNewData) const;
     102             : 
     103             :   /**
     104             :    * Return aSize multiplied by the current text zoom factor (in aPresContext).
     105             :    * aSize is allowed to be negative, but the caller is expected to deal with
     106             :    * negative results.  The result is clamped to nscoord_MIN .. nscoord_MAX.
     107             :    */
     108             :   static nscoord ZoomText(const nsPresContext* aPresContext, nscoord aSize);
     109             :   /**
     110             :    * Return aSize divided by the current text zoom factor (in aPresContext).
     111             :    * aSize is allowed to be negative, but the caller is expected to deal with
     112             :    * negative results.  The result is clamped to nscoord_MIN .. nscoord_MAX.
     113             :    */
     114             :   static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
     115             :   static already_AddRefed<nsAtom> GetLanguage(const nsPresContext* aPresContext);
     116             : 
     117             :   void EnableZoom(nsPresContext* aContext, bool aEnable);
     118             : 
     119             :   nsFont  mFont;        // [inherited]
     120             :   nscoord mSize;        // [inherited] Our "computed size". Can be different
     121             :                         // from mFont.size which is our "actual size" and is
     122             :                         // enforced to be >= the user's preferred min-size.
     123             :                         // mFont.size should be used for display purposes
     124             :                         // while mSize is the value to return in
     125             :                         // getComputedStyle() for example.
     126             : 
     127             :   // In stylo these three track whether the size is keyword-derived
     128             :   // and if so if it has been modified by a factor/offset
     129             :   float mFontSizeFactor;
     130             :   nscoord mFontSizeOffset;
     131             :   uint8_t mFontSizeKeyword; // NS_STYLE_FONT_SIZE_*, is NS_STYLE_FONT_SIZE_NO_KEYWORD
     132             :                             // when not keyword-derived
     133             : 
     134             :   uint8_t mGenericID;   // [inherited] generic CSS font family, if any;
     135             :                         // value is a kGenericFont_* constant, see nsFont.h.
     136             : 
     137             :   // MathML scriptlevel support
     138             :   int8_t  mScriptLevel;          // [inherited]
     139             :   // MathML  mathvariant support
     140             :   uint8_t mMathVariant;          // [inherited]
     141             :   // MathML displaystyle support
     142             :   uint8_t mMathDisplay;         // [inherited]
     143             : 
     144             :   // allow different min font-size for certain cases
     145             :   uint8_t mMinFontSizeRatio;     // [inherited] percent * 100
     146             : 
     147             :   // was mLanguage set based on a lang attribute in the document?
     148             :   bool mExplicitLanguage;        // [inherited]
     149             : 
     150             :   // should calls to ZoomText() and UnZoomText() be made to the font
     151             :   // size on this nsStyleFont?
     152             :   bool mAllowZoom;               // [inherited]
     153             : 
     154             :   // The value mSize would have had if scriptminsize had never been applied
     155             :   nscoord mScriptUnconstrainedSize;
     156             :   nscoord mScriptMinSize;        // [inherited] length
     157             :   float   mScriptSizeMultiplier; // [inherited]
     158             :   RefPtr<nsAtom> mLanguage;   // [inherited]
     159             : };
     160             : 
     161         574 : struct nsStyleGradientStop
     162             : {
     163             :   nsStyleCoord mLocation; // percent, coord, calc, none
     164             :   mozilla::StyleComplexColor mColor;
     165             :   bool mIsInterpolationHint;
     166             : 
     167             :   // Use ==/!= on nsStyleGradient instead of on the gradient stop.
     168             :   bool operator==(const nsStyleGradientStop&) const = delete;
     169             :   bool operator!=(const nsStyleGradientStop&) const = delete;
     170             : };
     171             : 
     172             : class nsStyleGradient final
     173             : {
     174             : public:
     175             :   nsStyleGradient();
     176             :   uint8_t mShape;  // NS_STYLE_GRADIENT_SHAPE_*
     177             :   uint8_t mSize;   // NS_STYLE_GRADIENT_SIZE_*;
     178             :                    // not used (must be FARTHEST_CORNER) for linear shape
     179             :   bool mRepeating;
     180             :   bool mLegacySyntax; // If true, serialization should use a vendor prefix.
     181             :   // XXXdholbert This will hopefully be going away soon, if bug 1337655 sticks:
     182             :   bool mMozLegacySyntax; // (Only makes sense when mLegacySyntax is true.)
     183             :                          // If true, serialization should use -moz prefix.
     184             :                          // Else, serialization should use -webkit prefix.
     185             : 
     186             :   nsStyleCoord mBgPosX; // percent, coord, calc, none
     187             :   nsStyleCoord mBgPosY; // percent, coord, calc, none
     188             :   nsStyleCoord mAngle;  // none, angle
     189             : 
     190             :   nsStyleCoord mRadiusX; // percent, coord, calc, none
     191             :   nsStyleCoord mRadiusY; // percent, coord, calc, none
     192             : 
     193             :   // stops are in the order specified in the stylesheet
     194             :   nsTArray<nsStyleGradientStop> mStops;
     195             : 
     196             :   bool operator==(const nsStyleGradient& aOther) const;
     197             :   bool operator!=(const nsStyleGradient& aOther) const {
     198             :     return !(*this == aOther);
     199             :   }
     200             : 
     201             :   bool IsOpaque();
     202             :   bool HasCalc();
     203             :   uint32_t Hash(PLDHashNumber aHash);
     204             : 
     205         592 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleGradient)
     206             : 
     207             : private:
     208             :   // Private destructor, to discourage deletion outside of Release():
     209         364 :   ~nsStyleGradient() {}
     210             : 
     211             :   nsStyleGradient(const nsStyleGradient& aOther) = delete;
     212             :   nsStyleGradient& operator=(const nsStyleGradient& aOther) = delete;
     213             : };
     214             : 
     215             : /**
     216             :  * A wrapper for an imgRequestProxy that supports off-main-thread creation
     217             :  * and equality comparison.
     218             :  *
     219             :  * An nsStyleImageRequest can be created using the constructor that takes the
     220             :  * URL, base URI, referrer and principal that can be used to initiate an image
     221             :  * load and produce an imgRequestProxy later.
     222             :  *
     223             :  * This can be called from any thread.  The nsStyleImageRequest is not
     224             :  * considered "resolved" at this point, and the Resolve() method must be called
     225             :  * later to initiate the image load and make calls to get() valid.
     226             :  *
     227             :  * Calls to TrackImage(), UntrackImage(), LockImage(), UnlockImage() and
     228             :  * RequestDiscard() are made to the imgRequestProxy and ImageTracker as
     229             :  * appropriate, according to the mode flags passed in to the constructor.
     230             :  *
     231             :  * The constructor receives a css::ImageValue to represent the url()
     232             :  * information, which is held on to for the comparisons done in
     233             :  * DefinitelyEquals().
     234             :  */
     235             : class nsStyleImageRequest
     236             : {
     237             : public:
     238             :   typedef mozilla::css::URLValueData URLValueData;
     239             : 
     240             :   // Flags describing whether the imgRequestProxy must be tracked in the
     241             :   // ImageTracker, whether LockImage/UnlockImage calls will be made
     242             :   // when obtaining and releasing the imgRequestProxy, and whether
     243             :   // RequestDiscard will be called on release.
     244             :   enum class Mode : uint8_t {
     245             :     // The imgRequestProxy will be added to the ImageTracker when resolved
     246             :     // Without this flag, the nsStyleImageRequest itself will call LockImage/
     247             :     // UnlockImage on the imgRequestProxy, rather than leaving locking to the
     248             :     // ImageTracker to manage.
     249             :     //
     250             :     // This flag is currently used by all nsStyleImageRequests except
     251             :     // those for list-style-image and cursor.
     252             :     Track = 0x1,
     253             : 
     254             :     // The imgRequestProxy will have its RequestDiscard method called when
     255             :     // the nsStyleImageRequest is going away.
     256             :     //
     257             :     // This is currently used only for cursor images.
     258             :     Discard = 0x2,
     259             :   };
     260             : 
     261             :   // Can be called from any thread, but Resolve() must be called later
     262             :   // on the main thread before get() can be used.
     263             :   nsStyleImageRequest(Mode aModeFlags, mozilla::css::ImageValue* aImageValue);
     264             : 
     265             :   bool Resolve(nsPresContext*, const nsStyleImageRequest* aOldImageRequest);
     266             :   bool IsResolved() const { return mResolved; }
     267             : 
     268          60 :   imgRequestProxy* get() {
     269          60 :     MOZ_ASSERT(IsResolved(), "Resolve() must be called first");
     270          60 :     MOZ_ASSERT(NS_IsMainThread());
     271         120 :     return mRequestProxy.get();
     272             :   }
     273             :   const imgRequestProxy* get() const {
     274             :     return const_cast<nsStyleImageRequest*>(this)->get();
     275             :   }
     276             : 
     277             :   // Returns whether the ImageValue objects in the two nsStyleImageRequests
     278             :   // return true from URLValueData::DefinitelyEqualURIs.
     279             :   bool DefinitelyEquals(const nsStyleImageRequest& aOther) const;
     280             : 
     281         120 :   mozilla::css::ImageValue* GetImageValue() const { return mImageValue; }
     282             : 
     283             :   already_AddRefed<nsIURI> GetImageURI() const;
     284         890 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest);
     285             : 
     286             : private:
     287             :   ~nsStyleImageRequest();
     288             :   nsStyleImageRequest& operator=(const nsStyleImageRequest& aOther) = delete;
     289             : 
     290             :   void MaybeTrackAndLock();
     291             : 
     292             :   RefPtr<imgRequestProxy> mRequestProxy;
     293             :   RefPtr<mozilla::css::ImageValue> mImageValue;
     294             :   RefPtr<mozilla::dom::ImageTracker> mImageTracker;
     295             : 
     296             :   // Cache DocGroup for dispatching events in the destructor.
     297             :   RefPtr<mozilla::dom::DocGroup> mDocGroup;
     298             : 
     299             :   Mode mModeFlags;
     300             :   bool mResolved;
     301             : };
     302             : 
     303         240 : MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsStyleImageRequest::Mode)
     304             : 
     305             : enum nsStyleImageType {
     306             :   eStyleImageType_Null,
     307             :   eStyleImageType_Image,
     308             :   eStyleImageType_Gradient,
     309             :   eStyleImageType_Element,
     310             :   eStyleImageType_URL
     311             : };
     312             : 
     313           0 : struct CachedBorderImageData
     314             : {
     315           0 :   ~CachedBorderImageData() {
     316           0 :     PurgeCachedImages();
     317           0 :   }
     318             : 
     319             :   // Caller are expected to ensure that the value of aSVGViewportSize is
     320             :   // different from the cached one since the method won't do the check.
     321             :   void SetCachedSVGViewportSize(const mozilla::Maybe<nsSize>& aSVGViewportSize);
     322             :   const mozilla::Maybe<nsSize>& GetCachedSVGViewportSize();
     323             :   void PurgeCachedImages();
     324             :   void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage);
     325             :   imgIContainer* GetSubImage(uint8_t aIndex);
     326             : 
     327             : private:
     328             :   // If this is a SVG border-image, we save the size of the SVG viewport that
     329             :   // we used when rasterizing any cached border-image subimages. (The viewport
     330             :   // size matters for percent-valued sizes & positions in inner SVG doc).
     331             :   mozilla::Maybe<nsSize> mCachedSVGViewportSize;
     332             :   nsCOMArray<imgIContainer> mSubImages;
     333             : };
     334             : 
     335             : /**
     336             :  * Represents a paintable image of one of the following types.
     337             :  * (1) A real image loaded from an external source.
     338             :  * (2) A CSS linear or radial gradient.
     339             :  * (3) An element within a document, or an <img>, <video>, or <canvas> element
     340             :  *     not in a document.
     341             :  * (*) Optionally a crop rect can be set to paint a partial (rectangular)
     342             :  * region of an image. (Currently, this feature is only supported with an
     343             :  * image of type (1)).
     344             :  */
     345             : struct nsStyleImage
     346             : {
     347             :   typedef mozilla::css::URLValue     URLValue;
     348             :   typedef mozilla::css::URLValueData URLValueData;
     349             : 
     350             :   nsStyleImage();
     351             :   ~nsStyleImage();
     352             :   nsStyleImage(const nsStyleImage& aOther);
     353             :   nsStyleImage& operator=(const nsStyleImage& aOther);
     354             : 
     355             :   void SetNull();
     356             :   void SetImageRequest(already_AddRefed<nsStyleImageRequest> aImage);
     357             :   void SetGradientData(nsStyleGradient* aGradient);
     358             :   void SetElementId(already_AddRefed<nsAtom> aElementId);
     359             :   void SetCropRect(mozilla::UniquePtr<nsStyleSides> aCropRect);
     360             :   void SetURLValue(already_AddRefed<URLValue> aData);
     361             : 
     362        1514 :   void ResolveImage(nsPresContext* aContext, const nsStyleImage* aOldImage) {
     363        1514 :     MOZ_ASSERT(mType != eStyleImageType_Image || mImage);
     364        1514 :     if (mType == eStyleImageType_Image && !mImage->IsResolved()) {
     365             :       const nsStyleImageRequest* oldRequest =
     366           0 :         (aOldImage && aOldImage->GetType() == eStyleImageType_Image)
     367           4 :         ? aOldImage->ImageRequest() : nullptr;
     368           4 :       mImage->Resolve(aContext, oldRequest);
     369             :     }
     370        1514 :   }
     371             : 
     372             :   nsStyleImageType GetType() const {
     373             :     return mType;
     374             :   }
     375           8 :   nsStyleImageRequest* ImageRequest() const {
     376           8 :     MOZ_ASSERT(mType == eStyleImageType_Image, "Data is not an image!");
     377           8 :     MOZ_ASSERT(mImage);
     378           8 :     return mImage;
     379             :   }
     380           4 :   imgRequestProxy* GetImageData() const {
     381           4 :     return ImageRequest()->get();
     382             :   }
     383          68 :   nsStyleGradient* GetGradientData() const {
     384          68 :     NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
     385          68 :     return mGradient;
     386             :   }
     387           4 :   bool IsResolved() const {
     388           4 :     return mType != eStyleImageType_Image || ImageRequest()->IsResolved();
     389             :   }
     390           0 :   const nsAtom* GetElementId() const {
     391           0 :     NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
     392           0 :     return mElementId;
     393             :   }
     394           0 :   const mozilla::UniquePtr<nsStyleSides>& GetCropRect() const {
     395           0 :     NS_ASSERTION(mType == eStyleImageType_Image,
     396             :                  "Only image data can have a crop rect");
     397           0 :     return mCropRect;
     398             :   }
     399             : 
     400             :   already_AddRefed<nsIURI> GetImageURI() const;
     401             : 
     402             :   URLValueData* GetURLValue() const;
     403             : 
     404             :   /**
     405             :    * Compute the actual crop rect in pixels, using the source image bounds.
     406             :    * The computation involves converting percentage unit to pixel unit and
     407             :    * clamping each side value to fit in the source image bounds.
     408             :    * @param aActualCropRect the computed actual crop rect.
     409             :    * @param aIsEntireImage true iff |aActualCropRect| is identical to the
     410             :    * source image bounds.
     411             :    * @return true iff |aActualCropRect| holds a meaningful value.
     412             :    */
     413             :   bool ComputeActualCropRect(nsIntRect& aActualCropRect,
     414             :                                bool* aIsEntireImage = nullptr) const;
     415             : 
     416             :   /**
     417             :    * Starts the decoding of a image. Returns true if the current frame of the
     418             :    * image is complete. The return value is intended to be used instead of
     419             :    * IsComplete because IsComplete may not be up to date if notifications
     420             :    * from decoding are pending because they are being sent async.
     421             :    */
     422             :   bool StartDecoding() const;
     423             :   /**
     424             :    * @return true if the item is definitely opaque --- i.e., paints every
     425             :    * pixel within its bounds opaquely, and the bounds contains at least a pixel.
     426             :    */
     427             :   bool IsOpaque() const;
     428             :   /**
     429             :    * @return true if this image is fully loaded, and its size is calculated;
     430             :    * always returns true if |mType| is |eStyleImageType_Gradient| or
     431             :    * |eStyleImageType_Element|.
     432             :    */
     433             :   bool IsComplete() const;
     434             :   /**
     435             :    * @return true if this image is loaded without error;
     436             :    * always returns true if |mType| is |eStyleImageType_Gradient| or
     437             :    * |eStyleImageType_Element|.
     438             :    */
     439             :   bool IsLoaded() const;
     440             :   /**
     441             :    * @return true if it is 100% confident that this image contains no pixel
     442             :    * to draw.
     443             :    */
     444             :   bool IsEmpty() const {
     445             :     // There are some other cases when the image will be empty, for example
     446             :     // when the crop rect is empty. However, checking the emptiness of crop
     447             :     // rect is non-trivial since each side value can be specified with
     448             :     // percentage unit, which can not be evaluated until the source image size
     449             :     // is available. Therefore, we currently postpone the evaluation of crop
     450             :     // rect until the actual rendering time --- alternatively until GetOpaqueRegion()
     451             :     // is called.
     452             :     return mType == eStyleImageType_Null;
     453             :   }
     454             : 
     455             :   bool operator==(const nsStyleImage& aOther) const;
     456          18 :   bool operator!=(const nsStyleImage& aOther) const {
     457          18 :     return !(*this == aOther);
     458             :   }
     459             : 
     460           0 :   bool ImageDataEquals(const nsStyleImage& aOther) const
     461             :   {
     462           0 :     return GetType() == eStyleImageType_Image &&
     463           0 :            aOther.GetType() == eStyleImageType_Image &&
     464           0 :            GetImageData() == aOther.GetImageData();
     465             :   }
     466             : 
     467             :   // These methods are used for the caller to caches the sub images created
     468             :   // during a border-image paint operation
     469             :   inline void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) const;
     470             :   inline imgIContainer* GetSubImage(uint8_t aIndex) const;
     471             :   void PurgeCacheForViewportChange(
     472             :     const mozilla::Maybe<nsSize>& aSVGViewportSize,
     473             :     const bool aHasIntrinsicRatio) const;
     474             : 
     475             : private:
     476             :   void DoCopy(const nsStyleImage& aOther);
     477             :   void EnsureCachedBIData() const;
     478             : 
     479             :   // This variable keeps some cache data for border image and is lazily
     480             :   // allocated since it is only used in border image case.
     481             :   mozilla::UniquePtr<CachedBorderImageData> mCachedBIData;
     482             : 
     483             :   nsStyleImageType mType;
     484             :   union {
     485             :     nsStyleImageRequest* mImage;
     486             :     nsStyleGradient* mGradient;
     487             :     URLValue* mURLValue; // See the comment in SetStyleImage's 'case
     488             :                          // eCSSUnit_URL' section to know why we need to
     489             :                          // store URLValues separately from mImage.
     490             :     nsAtom* mElementId;
     491             :   };
     492             : 
     493             :   // This is _currently_ used only in conjunction with eStyleImageType_Image.
     494             :   mozilla::UniquePtr<nsStyleSides> mCropRect;
     495             : };
     496             : 
     497             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColor
     498             : {
     499             :   explicit nsStyleColor(const nsPresContext* aContext);
     500             :   nsStyleColor(const nsStyleColor& aOther);
     501         740 :   ~nsStyleColor() {
     502         370 :     MOZ_COUNT_DTOR(nsStyleColor);
     503         370 :   }
     504             :   void FinishStyle(nsPresContext*, const nsStyleColor*) {}
     505             :   const static bool kHasFinishStyle = false;
     506             : 
     507             :   nsChangeHint CalcDifference(const nsStyleColor& aNewData) const;
     508             : 
     509             :   // Don't add ANY members to this struct!  We can achieve caching in the rule
     510             :   // tree (rather than the style tree) by letting color stay by itself! -dwh
     511             :   nscolor mColor;                 // [inherited]
     512             : };
     513             : 
     514             : struct nsStyleImageLayers {
     515             :   // Indices into kBackgroundLayerTable and kMaskLayerTable
     516             :   enum {
     517             :     shorthand = 0,
     518             :     color,
     519             :     image,
     520             :     repeat,
     521             :     positionX,
     522             :     positionY,
     523             :     clip,
     524             :     origin,
     525             :     size,
     526             :     attachment,
     527             :     maskMode,
     528             :     composite
     529             :   };
     530             : 
     531             :   enum class LayerType : uint8_t {
     532             :     Background = 0,
     533             :     Mask
     534             :   };
     535             : 
     536             :   explicit nsStyleImageLayers(LayerType aType);
     537             :   nsStyleImageLayers(const nsStyleImageLayers &aSource);
     538         880 :   ~nsStyleImageLayers() {
     539         440 :     MOZ_COUNT_DTOR(nsStyleImageLayers);
     540         440 :   }
     541             : 
     542             :   static bool IsInitialPositionForLayerType(mozilla::Position aPosition, LayerType aType);
     543             : 
     544             :   struct Size {
     545             :     struct Dimension : public nsStyleCoord::CalcValue {
     546           0 :       nscoord ResolveLengthPercentage(nscoord aAvailable) const {
     547           0 :         double d = double(mPercent) * double(aAvailable) + double(mLength);
     548           0 :         if (d < 0.0) {
     549             :           return 0;
     550             :         }
     551           0 :         return NSToCoordRoundWithClamp(float(d));
     552             :       }
     553             :     };
     554             :     Dimension mWidth, mHeight;
     555             : 
     556             :     bool IsInitialValue() const {
     557           0 :       return mWidthType == eAuto && mHeightType == eAuto;
     558             :     }
     559             : 
     560           0 :     nscoord ResolveWidthLengthPercentage(const nsSize& aBgPositioningArea) const {
     561           0 :       MOZ_ASSERT(mWidthType == eLengthPercentage,
     562             :                  "resolving non-length/percent dimension!");
     563           0 :       return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
     564             :     }
     565             : 
     566           0 :     nscoord ResolveHeightLengthPercentage(const nsSize& aBgPositioningArea) const {
     567           0 :       MOZ_ASSERT(mHeightType == eLengthPercentage,
     568             :                  "resolving non-length/percent dimension!");
     569           0 :       return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
     570             :     }
     571             : 
     572             :     // Except for eLengthPercentage, Dimension types which might change
     573             :     // how a layer is painted when the corresponding frame's dimensions
     574             :     // change *must* precede all dimension types which are agnostic to
     575             :     // frame size; see DependsOnDependsOnPositioningAreaSizeSize.
     576             :     enum DimensionType {
     577             :       // If one of mWidth and mHeight is eContain or eCover, then both are.
     578             :       // NOTE: eContain and eCover *must* be equal to NS_STYLE_BG_SIZE_CONTAIN
     579             :       // and NS_STYLE_BG_SIZE_COVER (in kBackgroundSizeKTable).
     580             :       eContain, eCover,
     581             : 
     582             :       eAuto,
     583             :       eLengthPercentage,
     584             :       eDimensionType_COUNT
     585             :     };
     586             :     uint8_t mWidthType, mHeightType;
     587             : 
     588             :     // True if the effective image size described by this depends on the size of
     589             :     // the corresponding frame, when aImage (which must not have null type) is
     590             :     // the background image.
     591             :     bool DependsOnPositioningAreaSize(const nsStyleImage& aImage) const;
     592             : 
     593             :     // Initialize nothing
     594         700 :     Size() {}
     595             : 
     596             :     // Initialize to initial values
     597             :     void SetInitialValues();
     598             : 
     599             :     bool operator==(const Size& aOther) const;
     600           6 :     bool operator!=(const Size& aOther) const {
     601           6 :       return !(*this == aOther);
     602             :     }
     603             :   };
     604             : 
     605             :   struct Repeat {
     606             :     mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat;
     607             : 
     608             :     // Initialize nothing
     609         700 :     Repeat() {}
     610             : 
     611           0 :     bool IsInitialValue() const {
     612           0 :       return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat &&
     613           0 :              mYRepeat == mozilla::StyleImageLayerRepeat::Repeat;
     614             :     }
     615             : 
     616           0 :     bool DependsOnPositioningAreaSize() const {
     617           0 :       return mXRepeat == mozilla::StyleImageLayerRepeat::Space ||
     618           0 :              mYRepeat == mozilla::StyleImageLayerRepeat::Space;
     619             :     }
     620             : 
     621             :     // Initialize to initial values
     622             :     void SetInitialValues() {
     623         140 :       mXRepeat = mozilla::StyleImageLayerRepeat::Repeat;
     624         140 :       mYRepeat = mozilla::StyleImageLayerRepeat::Repeat;
     625             :     }
     626             : 
     627           6 :     bool operator==(const Repeat& aOther) const {
     628          12 :       return mXRepeat == aOther.mXRepeat &&
     629          12 :              mYRepeat == aOther.mYRepeat;
     630             :     }
     631           6 :     bool operator!=(const Repeat& aOther) const {
     632           6 :       return !(*this == aOther);
     633             :     }
     634             :   };
     635             : 
     636         560 :   struct Layer {
     637             :     typedef mozilla::StyleGeometryBox StyleGeometryBox;
     638             :     typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment;
     639             : 
     640             :     nsStyleImage  mImage;         // [reset]
     641             :     mozilla::Position mPosition;  // [reset]
     642             :     Size          mSize;          // [reset]
     643             :     StyleGeometryBox  mClip;      // [reset] See nsStyleConsts.h
     644             :     MOZ_INIT_OUTSIDE_CTOR
     645             :       StyleGeometryBox mOrigin;   // [reset] See nsStyleConsts.h
     646             :     StyleImageLayerAttachment mAttachment;
     647             :                                   // [reset] See nsStyleConsts.h
     648             :                                   // background-only property
     649             :                                   // This property is used for background layer
     650             :                                   // only. For a mask layer, it should always
     651             :                                   // be the initial value, which is
     652             :                                   // StyleImageLayerAttachment::Scroll.
     653             :     uint8_t       mBlendMode;     // [reset] See nsStyleConsts.h
     654             :                                   // background-only property
     655             :                                   // This property is used for background layer
     656             :                                   // only. For a mask layer, it should always
     657             :                                   // be the initial value, which is
     658             :                                   // NS_STYLE_BLEND_NORMAL.
     659             :     uint8_t       mComposite;     // [reset] See nsStyleConsts.h
     660             :                                   // mask-only property
     661             :                                   // This property is used for mask layer only.
     662             :                                   // For a background layer, it should always
     663             :                                   // be the initial value, which is
     664             :                                   // NS_STYLE_COMPOSITE_MODE_ADD.
     665             :     uint8_t       mMaskMode;      // [reset] See nsStyleConsts.h
     666             :                                   // mask-only property
     667             :                                   // This property is used for mask layer only.
     668             :                                   // For a background layer, it should always
     669             :                                   // be the initial value, which is
     670             :                                   // NS_STYLE_MASK_MODE_MATCH_SOURCE.
     671             :     Repeat        mRepeat;        // [reset] See nsStyleConsts.h
     672             : 
     673             :     // This constructor does not initialize mRepeat or mOrigin and Initialize()
     674             :     // must be called to do that.
     675             :     Layer();
     676             :     ~Layer();
     677             : 
     678             :     // Initialize mRepeat and mOrigin by specified layer type
     679             :     void Initialize(LayerType aType);
     680             : 
     681         738 :     void ResolveImage(nsPresContext* aContext, const Layer* aOldLayer) {
     682         738 :       mImage.ResolveImage(aContext, aOldLayer ? &aOldLayer->mImage : nullptr);
     683         738 :     }
     684             : 
     685             :     // True if the rendering of this layer might change when the size
     686             :     // of the background positioning area changes.  This is true for any
     687             :     // non-solid-color background whose position or size depends on
     688             :     // the size of the positioning area.  It's also true for SVG images
     689             :     // whose root <svg> node has a viewBox.
     690             :     bool RenderingMightDependOnPositioningAreaSizeChange() const;
     691             : 
     692             :     // Compute the change hint required by changes in just this layer.
     693             :     nsChangeHint CalcDifference(const Layer& aNewLayer) const;
     694             : 
     695             :     // An equality operator that compares the images using URL-equality
     696             :     // rather than pointer-equality.
     697             :     bool operator==(const Layer& aOther) const;
     698             :     bool operator!=(const Layer& aOther) const {
     699             :       return !(*this == aOther);
     700             :     }
     701             :   };
     702             : 
     703             :   // The (positive) number of computed values of each property, since
     704             :   // the lengths of the lists are independent.
     705             :   uint32_t mAttachmentCount,
     706             :            mClipCount,
     707             :            mOriginCount,
     708             :            mRepeatCount,
     709             :            mPositionXCount,
     710             :            mPositionYCount,
     711             :            mImageCount,
     712             :            mSizeCount,
     713             :            mMaskModeCount,
     714             :            mBlendModeCount,
     715             :            mCompositeCount;
     716             : 
     717             :   // Layers are stored in an array, matching the top-to-bottom order in
     718             :   // which they are specified in CSS.  The number of layers to be used
     719             :   // should come from the background-image property.  We create
     720             :   // additional |Layer| objects for *any* property, not just
     721             :   // background-image.  This means that the bottommost layer that
     722             :   // callers in layout care about (which is also the one whose
     723             :   // background-clip applies to the background-color) may not be last
     724             :   // layer.  In layers below the bottom layer, properties will be
     725             :   // uninitialized unless their count, above, indicates that they are
     726             :   // present.
     727             :   nsStyleAutoArray<Layer> mLayers;
     728             : 
     729        1484 :   const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
     730             : 
     731         738 :   void ResolveImages(nsPresContext* aContext, const nsStyleImageLayers* aOldLayers) {
     732        1476 :     for (uint32_t i = 0; i < mImageCount; ++i) {
     733             :       const Layer* oldLayer =
     734          92 :         (aOldLayers && aOldLayers->mLayers.Length() > i)
     735         784 :         ? &aOldLayers->mLayers[i]
     736         738 :         : nullptr;
     737         738 :       mLayers[i].ResolveImage(aContext, oldLayer);
     738             :     }
     739         738 :   }
     740             : 
     741             :   // Fill unspecified layers by cycling through their values
     742             :   // till they all are of length aMaxItemCount
     743             :   void FillAllLayers(uint32_t aMaxItemCount);
     744             : 
     745             :   nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
     746             :                               nsStyleImageLayers::LayerType aType) const;
     747             : 
     748             :   nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
     749             :   nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther);
     750             :   bool operator==(const nsStyleImageLayers& aOther) const;
     751             : 
     752             :   static const nsCSSPropertyID kBackgroundLayerTable[];
     753             :   static const nsCSSPropertyID kMaskLayerTable[];
     754             : 
     755             :   #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
     756             :     for (uint32_t var_ = (layers_).mImageCount; var_-- != 0; )
     757             :   #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, start_, count_) \
     758             :     NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, "Invalid layer start!"); \
     759             :     NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
     760             :     for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
     761             : };
     762             : 
     763             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
     764             :   explicit nsStyleBackground(const nsPresContext* aContext);
     765             :   nsStyleBackground(const nsStyleBackground& aOther);
     766             :   ~nsStyleBackground();
     767             : 
     768             :   // Resolves and tracks the images in mImage.  Only called with a Servo-backed
     769             :   // style system, where those images must be resolved later than the OMT
     770             :   // nsStyleBackground constructor call.
     771             :   void FinishStyle(nsPresContext*, const nsStyleBackground*);
     772             :   const static bool kHasFinishStyle = true;
     773             : 
     774             :   nsChangeHint CalcDifference(const nsStyleBackground& aNewData) const;
     775             : 
     776             :   // Return the background color as nscolor.
     777             :   nscolor BackgroundColor(const nsIFrame* aFrame) const;
     778             :   nscolor BackgroundColor(mozilla::ComputedStyle* aStyle) const;
     779             : 
     780             :   // True if this background is completely transparent.
     781             :   bool IsTransparent(const nsIFrame* aFrame) const;
     782             :   bool IsTransparent(mozilla::ComputedStyle* aStyle) const;
     783             : 
     784             :   // We have to take slower codepaths for fixed background attachment,
     785             :   // but we don't want to do that when there's no image.
     786             :   // Not inline because it uses an nsCOMPtr<imgIRequest>
     787             :   // FIXME: Should be in nsStyleStructInlines.h.
     788             :   bool HasFixedBackground(nsIFrame* aFrame) const;
     789             : 
     790             :   // Checks to see if this has a non-empty image with "local" attachment.
     791             :   // This is defined in nsStyleStructInlines.h.
     792             :   inline bool HasLocalBackground() const;
     793             : 
     794        1484 :   const nsStyleImageLayers::Layer& BottomLayer() const { return mImage.BottomLayer(); }
     795             : 
     796             :   nsStyleImageLayers mImage;
     797             :   mozilla::StyleComplexColor mBackgroundColor;       // [reset]
     798             : };
     799             : 
     800             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin
     801             : {
     802             :   explicit nsStyleMargin(const nsPresContext* aContext);
     803             :   nsStyleMargin(const nsStyleMargin& aMargin);
     804         612 :   ~nsStyleMargin() {
     805         306 :     MOZ_COUNT_DTOR(nsStyleMargin);
     806         306 :   }
     807             :   void FinishStyle(nsPresContext*, const nsStyleMargin*) {}
     808             :   const static bool kHasFinishStyle = false;
     809             : 
     810             :   nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const;
     811             : 
     812        6724 :   bool GetMargin(nsMargin& aMargin) const
     813             :   {
     814        6724 :     if (!mMargin.ConvertsToLength()) {
     815             :       return false;
     816             :     }
     817             : 
     818       60498 :     NS_FOR_CSS_SIDES(side) {
     819       53776 :       aMargin.Side(side) = mMargin.ToLength(side);
     820             :     }
     821             :     return true;
     822             :   }
     823             : 
     824             :   // Return true if either the start or end side in the axis is 'auto'.
     825             :   // (defined in WritingModes.h since we need the full WritingMode type)
     826             :   inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const;
     827             :   inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
     828             : 
     829             :   nsStyleSides  mMargin; // [reset] coord, percent, calc, auto
     830             : };
     831             : 
     832             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding
     833             : {
     834             :   explicit nsStylePadding(const nsPresContext* aContext);
     835             :   nsStylePadding(const nsStylePadding& aPadding);
     836         736 :   ~nsStylePadding() {
     837         368 :     MOZ_COUNT_DTOR(nsStylePadding);
     838         368 :   }
     839             :   void FinishStyle(nsPresContext*, const nsStylePadding*) {}
     840             :   const static bool kHasFinishStyle = false;
     841             : 
     842             :   nsChangeHint CalcDifference(const nsStylePadding& aNewData) const;
     843             : 
     844             :   nsStyleSides  mPadding;         // [reset] coord, percent, calc
     845             : 
     846         306 :   bool IsWidthDependent() const {
     847         306 :     return !mPadding.ConvertsToLength();
     848             :   }
     849             : 
     850        5630 :   bool GetPadding(nsMargin& aPadding) const
     851             :   {
     852        5630 :     if (!mPadding.ConvertsToLength()) {
     853             :       return false;
     854             :     }
     855             : 
     856       50670 :     NS_FOR_CSS_SIDES(side) {
     857             :       // Clamp negative calc() to 0.
     858       67560 :       aPadding.Side(side) = std::max(mPadding.ToLength(side), 0);
     859             :     }
     860             :     return true;
     861             :   }
     862             : };
     863             : 
     864             : struct nsCSSShadowItem
     865             : {
     866             :   nscoord mXOffset;
     867             :   nscoord mYOffset;
     868             :   nscoord mRadius;
     869             :   nscoord mSpread;
     870             : 
     871             :   nscolor      mColor;
     872             :   bool mHasColor; // Whether mColor should be used
     873             :   bool mInset;
     874             : 
     875          86 :   nsCSSShadowItem()
     876          86 :     : mXOffset(0)
     877          86 :     , mYOffset(0)
     878         128 :     , mRadius(0)
     879          64 :     , mSpread(0)
     880          64 :     , mColor(NS_RGB(0, 0, 0))
     881             :     , mHasColor(false)
     882           0 :     , mInset(false)
     883           0 :   {
     884           0 :     MOZ_COUNT_CTOR(nsCSSShadowItem);
     885           0 :   }
     886           0 :   ~nsCSSShadowItem() {
     887           0 :     MOZ_COUNT_DTOR(nsCSSShadowItem);
     888           0 :   }
     889           0 : 
     890             :   bool operator==(const nsCSSShadowItem& aOther) const {
     891           0 :     return (mXOffset == aOther.mXOffset &&
     892           0 :             mYOffset == aOther.mYOffset &&
     893             :             mRadius == aOther.mRadius &&
     894             :             mHasColor == aOther.mHasColor &&
     895             :             mSpread == aOther.mSpread &&
     896             :             mInset == aOther.mInset &&
     897             :             (!mHasColor || mColor == aOther.mColor));
     898             :   }
     899          74 :   bool operator!=(const nsCSSShadowItem& aOther) const {
     900             :     return !(*this == aOther);
     901             :   }
     902             : };
     903             : 
     904             : class nsCSSShadowArray final
     905          74 : {
     906         148 : public:
     907             :   void* operator new(size_t aBaseSize, uint32_t aArrayLen) {
     908             :     // We can allocate both this nsCSSShadowArray and the
     909          62 :     // actual array in one allocation. The amount of memory to
     910             :     // allocate is equal to the class's size + the number of bytes for all
     911          74 :     // but the first array item (because aBaseSize includes one
     912         148 :     // item, see the private declarations)
     913             :     return ::operator new(aBaseSize +
     914          98 :                           (aArrayLen - 1) * sizeof(nsCSSShadowItem));
     915             :   }
     916             : 
     917          12 :   void operator delete(void* aPtr) { ::operator delete(aPtr); }
     918             : 
     919          74 :   explicit nsCSSShadowArray(uint32_t aArrayLen) :
     920             :     mLength(aArrayLen)
     921             :   {
     922             :     for (uint32_t i = 1; i < mLength; ++i) {
     923         124 :       // Make sure we call the constructors of each nsCSSShadowItem
     924          64 :       // (the first one is called for us because we declared it under private)
     925           2 :       new (&mArray[i]) nsCSSShadowItem();
     926             :     }
     927          62 :   }
     928             : 
     929             : private:
     930             :   // Private destructor, to discourage deletion outside of Release():
     931          50 :   ~nsCSSShadowArray() {
     932          50 :     for (uint32_t i = 1; i < mLength; ++i) {
     933          50 :       mArray[i].~nsCSSShadowItem();
     934             :     }
     935           0 :   }
     936           0 : 
     937           0 : public:
     938             :   uint32_t Length() const { return mLength; }
     939             :   nsCSSShadowItem* ShadowAt(uint32_t i) {
     940          84 :     MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
     941         140 :     return &mArray[i];
     942          84 :   }
     943             :   const nsCSSShadowItem* ShadowAt(uint32_t i) const {
     944             :     MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
     945             :     return &mArray[i];
     946             :   }
     947             : 
     948             :   bool HasShadowWithInset(bool aInset) {
     949           0 :     for (uint32_t i = 0; i < mLength; ++i) {
     950           0 :       if (mArray[i].mInset == aInset) {
     951             :         return true;
     952             :       }
     953             :     }
     954           0 :     return false;
     955           0 :   }
     956             : 
     957             :   bool operator==(const nsCSSShadowArray& aOther) const {
     958             :     if (mLength != aOther.Length()) {
     959             :       return false;
     960             :     }
     961             : 
     962             :     for (uint32_t i = 0; i < mLength; ++i) {
     963         334 :       if (ShadowAt(i) != aOther.ShadowAt(i)) {
     964             :         return false;
     965             :       }
     966             :     }
     967             : 
     968             :     return true;
     969             :   }
     970             : 
     971             :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSShadowArray)
     972             : 
     973             : private:
     974             :   uint32_t mLength;
     975             :   nsCSSShadowItem mArray[1]; // This MUST be the last item
     976             : };
     977             : 
     978             : // Border widths are rounded to the nearest-below integer number of pixels,
     979             : // but values between zero and one device pixels are always rounded up to
     980             : // one device pixel.
     981             : #define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
     982             :   ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
     983             : // Outline offset is rounded to the nearest integer number of pixels, but values
     984             : // between zero and one device pixels are always rounded up to one device pixel.
     985             : // Note that the offset can be negative.
     986         100 : #define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
     987         100 :   (((l) == 0) ? 0 : \
     988             :     ((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
     989             :                 std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
     990             : 
     991             : // Returns if the given border style type is visible or not
     992             : static bool IsVisibleBorderStyle(uint8_t aStyle)
     993             : {
     994             :   return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
     995             :           aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
     996             : }
     997             : 
     998             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
     999             : {
    1000             :   explicit nsStyleBorder(const nsPresContext* aContext);
    1001             :   nsStyleBorder(const nsStyleBorder& aBorder);
    1002             :   ~nsStyleBorder();
    1003             : 
    1004             :   // Resolves and tracks mBorderImageSource.  Only called with a Servo-backed
    1005             :   // style system, where those images must be resolved later than the OMT
    1006             :   // nsStyleBorder constructor call.
    1007             :   void FinishStyle(nsPresContext*, const nsStyleBorder*);
    1008             :   const static bool kHasFinishStyle = true;
    1009             : 
    1010             :   nsChangeHint CalcDifference(const nsStyleBorder& aNewData) const;
    1011         192 : 
    1012             :   // Return whether aStyle is a visible style.  Invisible styles cause
    1013             :   // the relevant computed border width to be 0.
    1014             :   // Note that this does *not* consider the effects of 'border-image':
    1015           0 :   // if border-style is none, but there is a loaded border image,
    1016             :   // HasVisibleStyle will be false even though there *is* a border.
    1017             :   bool HasVisibleStyle(mozilla::Side aSide) const
    1018           0 :   {
    1019           0 :     return IsVisibleBorderStyle(mBorderStyle[aSide]);
    1020           0 :   }
    1021           0 : 
    1022             :   // aBorderWidth is in twips
    1023           0 :   void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth)
    1024             :   {
    1025             :     nscoord roundedWidth =
    1026             :       NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
    1027             :     mBorder.Side(aSide) = roundedWidth;
    1028             :     if (HasVisibleStyle(aSide)) {
    1029             :       mComputedBorder.Side(aSide) = roundedWidth;
    1030          16 :     }
    1031             :   }
    1032             : 
    1033        1144 :   // Get the computed border (plus rounding).  This does consider the
    1034             :   // effects of 'border-style: none', but does not consider
    1035        2288 :   // 'border-image'.
    1036             :   const nsMargin& GetComputedBorder() const
    1037             :   {
    1038             :     return mComputedBorder;
    1039             :   }
    1040             : 
    1041             :   bool HasBorder() const
    1042             :   {
    1043             :     return mComputedBorder != nsMargin(0,0,0,0) || !mBorderImageSource.IsEmpty();
    1044          88 :   }
    1045             : 
    1046             :   // Get the actual border width for a particular side, in appunits.  Note that
    1047         172 :   // this is zero if and only if there is no border to be painted for this
    1048             :   // side.  That is, this value takes into account the border style and the
    1049         172 :   // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
    1050         172 :   nscoord GetComputedBorderWidth(mozilla::Side aSide) const
    1051             :   {
    1052             :     return GetComputedBorder().Side(aSide);
    1053           0 :   }
    1054             : 
    1055           0 :   uint8_t GetBorderStyle(mozilla::Side aSide) const
    1056           0 :   {
    1057           0 :     NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
    1058           0 :     return mBorderStyle[aSide];
    1059           0 :   }
    1060             : 
    1061             :   void SetBorderStyle(mozilla::Side aSide, uint8_t aStyle)
    1062             :   {
    1063           2 :     NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
    1064             :     mBorderStyle[aSide] = aStyle;
    1065             :     mComputedBorder.Side(aSide) =
    1066             :       (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
    1067             :   }
    1068         876 : 
    1069             :   inline bool IsBorderImageLoaded() const
    1070         876 :   {
    1071           0 :     return mBorderImageSource.IsLoaded();
    1072             :   }
    1073             : 
    1074             :   nsMargin GetImageOutset() const;
    1075             : 
    1076             :   imgIRequest* GetBorderImageRequest() const
    1077             :   {
    1078             :     if (mBorderImageSource.GetType() == eStyleImageType_Image) {
    1079             :       return mBorderImageSource.GetImageData();
    1080             :     }
    1081             :     return nullptr;
    1082             :   }
    1083             : 
    1084             : public:
    1085             :   nsStyleCorners mBorderRadius;       // [reset] coord, percent
    1086             :   nsStyleImage   mBorderImageSource;  // [reset]
    1087             :   nsStyleSides   mBorderImageSlice;   // [reset] factor, percent
    1088             :   nsStyleSides   mBorderImageWidth;   // [reset] length, factor, percent, auto
    1089             :   nsStyleSides   mBorderImageOutset;  // [reset] length, factor
    1090             : 
    1091             :   uint8_t        mBorderImageFill;    // [reset]
    1092             :   mozilla::StyleBorderImageRepeat mBorderImageRepeatH; // [reset]
    1093             :   mozilla::StyleBorderImageRepeat mBorderImageRepeatV; // [reset]
    1094             :   mozilla::StyleFloatEdge mFloatEdge; // [reset]
    1095             :   mozilla::StyleBoxDecorationBreak mBoxDecorationBreak; // [reset]
    1096             : 
    1097             : protected:
    1098             :   uint8_t       mBorderStyle[4];  // [reset] See nsStyleConsts.h
    1099             : 
    1100             : public:
    1101           0 :   // [reset] the colors to use for a simple border.
    1102           0 :   // not used for -moz-border-colors
    1103           0 :   mozilla::StyleComplexColor mBorderTopColor;
    1104           0 :   mozilla::StyleComplexColor mBorderRightColor;
    1105           0 :   mozilla::StyleComplexColor mBorderBottomColor;
    1106           0 :   mozilla::StyleComplexColor mBorderLeftColor;
    1107             : 
    1108           0 :   mozilla::StyleComplexColor&
    1109             :   BorderColorFor(mozilla::Side aSide) {
    1110             :     switch (aSide) {
    1111             :     case mozilla::eSideTop:    return mBorderTopColor;
    1112             :     case mozilla::eSideRight:  return mBorderRightColor;
    1113         268 :     case mozilla::eSideBottom: return mBorderBottomColor;
    1114         268 :     case mozilla::eSideLeft:   return mBorderLeftColor;
    1115          88 :     }
    1116          60 :     MOZ_ASSERT_UNREACHABLE("Unknown side");
    1117          60 :     return mBorderTopColor;
    1118          60 :   }
    1119             : 
    1120           0 :   const mozilla::StyleComplexColor&
    1121             :   BorderColorFor(mozilla::Side aSide) const {
    1122             :     switch (aSide) {
    1123             :     case mozilla::eSideTop:    return mBorderTopColor;
    1124             :     case mozilla::eSideRight:  return mBorderRightColor;
    1125           0 :     case mozilla::eSideBottom: return mBorderBottomColor;
    1126           0 :     case mozilla::eSideLeft:   return mBorderLeftColor;
    1127             :     }
    1128             :     MOZ_ASSERT_UNREACHABLE("Unknown side");
    1129             :     return mBorderTopColor;
    1130           0 :   }
    1131             : 
    1132           0 :   static mozilla::StyleComplexColor nsStyleBorder::*
    1133             :   BorderColorFieldFor(mozilla::Side aSide) {
    1134           0 :     switch (aSide) {
    1135             :       case mozilla::eSideTop:
    1136           0 :         return &nsStyleBorder::mBorderTopColor;
    1137             :       case mozilla::eSideRight:
    1138             :         return &nsStyleBorder::mBorderRightColor;
    1139             :       case mozilla::eSideBottom:
    1140             :         return &nsStyleBorder::mBorderBottomColor;
    1141             :       case mozilla::eSideLeft:
    1142             :         return &nsStyleBorder::mBorderLeftColor;
    1143             :     }
    1144             :     MOZ_ASSERT_UNREACHABLE("Unknown side");
    1145             :     return nullptr;
    1146             :   }
    1147             : 
    1148             : protected:
    1149             :   // mComputedBorder holds the CSS2.1 computed border-width values.
    1150             :   // In particular, these widths take into account the border-style
    1151             :   // for the relevant side, and the values are rounded to the nearest
    1152             :   // device pixel (which is not part of the definition of computed
    1153             :   // values). The presence or absence of a border-image does not
    1154             :   // affect border-width values.
    1155             :   nsMargin      mComputedBorder;
    1156             : 
    1157             :   // mBorder holds the nscoord values for the border widths as they
    1158             :   // would be if all the border-style values were visible (not hidden
    1159             :   // or none).  This member exists so that when we create structs
    1160             :   // using the copy constructor during style resolution the new
    1161             :   // structs will know what the specified values of the border were in
    1162             :   // case they have more specific rules setting the border style.
    1163             :   //
    1164             :   // Note that this isn't quite the CSS specified value, since this
    1165             :   // has had the enumerated border widths converted to lengths, and
    1166             :   // all lengths converted to twips.  But it's not quite the computed
    1167             :   // value either. The values are rounded to the nearest device pixel.
    1168             :   nsMargin      mBorder;
    1169             : 
    1170             : private:
    1171             :   nscoord       mTwipsPerPixel;
    1172          64 : 
    1173          32 :   nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
    1174          32 : };
    1175             : 
    1176             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline
    1177             : {
    1178             :   explicit nsStyleOutline(const nsPresContext* aContext);
    1179             :   nsStyleOutline(const nsStyleOutline& aOutline);
    1180             :   ~nsStyleOutline() {
    1181             :     MOZ_COUNT_DTOR(nsStyleOutline);
    1182             :   }
    1183             :   void FinishStyle(nsPresContext*, const nsStyleOutline*) {}
    1184             :   const static bool kHasFinishStyle = false;
    1185             : 
    1186             :   void RecalcData();
    1187             :   nsChangeHint CalcDifference(const nsStyleOutline& aNewData) const;
    1188             : 
    1189             :   nsStyleCorners  mOutlineRadius; // [reset] coord, percent, calc
    1190             : 
    1191             :   // This is the specified value of outline-width, but with length values
    1192             :   // computed to absolute.  mActualOutlineWidth stores the outline-width
    1193             :   // value used by layout.  (We must store mOutlineWidth for the same
    1194             :   // style struct resolution reasons that we do nsStyleBorder::mBorder;
    1195             :   // see that field's comment.)
    1196             :   nscoord       mOutlineWidth;    // [reset] coord, enum (see nsStyleConsts.h)
    1197             :   nscoord       mOutlineOffset;   // [reset]
    1198        2498 :   mozilla::StyleComplexColor mOutlineColor; // [reset]
    1199             :   uint8_t       mOutlineStyle;    // [reset] See nsStyleConsts.h
    1200        4996 : 
    1201        2498 :   nscoord GetOutlineWidth() const
    1202        2498 :   {
    1203             :     return mActualOutlineWidth;
    1204             :   }
    1205             : 
    1206             :   bool ShouldPaintOutline() const
    1207             :   {
    1208             :     return mOutlineStyle == NS_STYLE_BORDER_STYLE_AUTO ||
    1209             :            (GetOutlineWidth() > 0 &&
    1210             :             mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE);
    1211             :   }
    1212             : 
    1213             : protected:
    1214             :   // The actual value of outline-width is the computed value (an absolute
    1215             :   // length, forced to zero when outline-style is none) rounded to device
    1216             :   // pixels.  This is the value used by layout.
    1217             :   nscoord       mActualOutlineWidth;
    1218             :   nscoord       mTwipsPerPixel;
    1219           6 : };
    1220             : 
    1221             : 
    1222             : /**
    1223        1028 :  * An object that allows sharing of arrays that store 'quotes' property
    1224             :  * values.  This is particularly important for inheritance, where we want
    1225             :  * to share the same 'quotes' value with a parent ComputedStyle.
    1226             :  */
    1227           0 : class nsStyleQuoteValues
    1228             : {
    1229             : public:
    1230             :   typedef nsTArray<std::pair<nsString, nsString>> QuotePairArray;
    1231             :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleQuoteValues);
    1232             :   QuotePairArray mQuotePairs;
    1233             : 
    1234             : private:
    1235             :   ~nsStyleQuoteValues() {}
    1236             : };
    1237             : 
    1238             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList
    1239             : {
    1240             :   explicit nsStyleList(const nsPresContext* aContext);
    1241             :   nsStyleList(const nsStyleList& aStyleList);
    1242           0 :   ~nsStyleList();
    1243           0 : 
    1244           0 :   void FinishStyle(nsPresContext*, const nsStyleList*);
    1245           0 :   const static bool kHasFinishStyle = true;
    1246             : 
    1247          68 :   nsChangeHint CalcDifference(const nsStyleList& aNewData,
    1248             :                               const nsStyleDisplay* aOldDisplay) const;
    1249         136 : 
    1250             :   static void Shutdown() {
    1251             :     sInitialQuotes = nullptr;
    1252             :     sNoneQuotes = nullptr;
    1253             :   }
    1254             : 
    1255             :   imgRequestProxy* GetListStyleImage() const
    1256             :   {
    1257             :     return mListStyleImage ? mListStyleImage->get() : nullptr;
    1258             :   }
    1259             : 
    1260             :   already_AddRefed<nsIURI> GetListStyleImageURI() const;
    1261             : 
    1262             :   const nsStyleQuoteValues::QuotePairArray& GetQuotePairs() const;
    1263             : 
    1264             :   void SetQuotesInherit(const nsStyleList* aOther);
    1265             :   void SetQuotesInitial();
    1266             :   void SetQuotesNone();
    1267             :   void SetQuotes(nsStyleQuoteValues::QuotePairArray&& aValues);
    1268             : 
    1269             :   uint8_t mListStylePosition;                  // [inherited]
    1270             :   RefPtr<nsStyleImageRequest> mListStyleImage; // [inherited]
    1271             : 
    1272             :   mozilla::CounterStylePtr mCounterStyle;      // [inherited]
    1273             : 
    1274             : private:
    1275             :   RefPtr<nsStyleQuoteValues> mQuotes;   // [inherited]
    1276             :   nsStyleList& operator=(const nsStyleList& aOther) = delete;
    1277             : public:
    1278        8352 :   nsRect        mImageRegion;           // [inherited] the rect to use within an image
    1279             : 
    1280             : private:
    1281             :   // nsStyleQuoteValues objects representing two common values, for sharing.
    1282             :   static mozilla::StaticRefPtr<nsStyleQuoteValues> sInitialQuotes;
    1283             :   static mozilla::StaticRefPtr<nsStyleQuoteValues> sNoneQuotes;
    1284             : };
    1285             : 
    1286             : struct nsStyleGridLine
    1287             : {
    1288             :   // http://dev.w3.org/csswg/css-grid/#typedef-grid-line
    1289             :   // XXXmats we could optimize memory size here
    1290             :   bool mHasSpan;
    1291             :   int32_t mInteger;  // 0 means not provided
    1292         280 :   nsString mLineName;  // Empty string means not provided.
    1293         280 : 
    1294         280 :   // These are the limits that we choose to clamp grid line numbers to.
    1295             :   // http://dev.w3.org/csswg/css-grid/#overlarge-grids
    1296             :   // mInteger is clamped to this range:
    1297         280 :   static const int32_t kMinLine = -10000;
    1298             :   static const int32_t kMaxLine = 10000;
    1299        7400 : 
    1300        7400 :   nsStyleGridLine()
    1301        7400 :     : mHasSpan(false)
    1302        7400 :     , mInteger(0)
    1303             :     // mLineName get its default constructor, the empty string
    1304        7400 :   {
    1305             :   }
    1306        7400 : 
    1307        7400 :   nsStyleGridLine(const nsStyleGridLine& aOther)
    1308       14800 :   {
    1309        7400 :     (*this) = aOther;
    1310             :   }
    1311         368 : 
    1312             :   void operator=(const nsStyleGridLine& aOther)
    1313         368 :   {
    1314         736 :     mHasSpan = aOther.mHasSpan;
    1315         736 :     mInteger = aOther.mInteger;
    1316             :     mLineName = aOther.mLineName;
    1317             :   }
    1318             : 
    1319             :   bool operator!=(const nsStyleGridLine& aOther) const
    1320             :   {
    1321             :     return mHasSpan != aOther.mHasSpan ||
    1322             :            mInteger != aOther.mInteger ||
    1323             :            mLineName != aOther.mLineName;
    1324             :   }
    1325             : 
    1326             :   void SetToInteger(uint32_t value)
    1327             :   {
    1328             :     mHasSpan = false;
    1329             :     mInteger = value;
    1330             :     mLineName.Truncate();
    1331             :   }
    1332           0 : 
    1333             :   void SetAuto()
    1334           0 :   {
    1335           0 :     mHasSpan = false;
    1336             :     mInteger = 0;
    1337             :     mLineName.Truncate();
    1338           0 :   }
    1339             : 
    1340             :   bool IsAuto() const
    1341             :   {
    1342             :     bool haveInitialValues =  mInteger == 0 && mLineName.IsEmpty();
    1343             :     MOZ_ASSERT(!(haveInitialValues && mHasSpan),
    1344             :                "should not have 'span' when other components are "
    1345             :                "at their initial values");
    1346             :     return haveInitialValues;
    1347             :   }
    1348             : };
    1349             : 
    1350             : // Computed value of the grid-template-columns or grid-template-rows property
    1351             : // (but *not* grid-template-areas.)
    1352             : // http://dev.w3.org/csswg/css-grid/#track-sizing
    1353             : //
    1354             : // This represents either:
    1355             : // * none:
    1356             : //   mIsSubgrid is false, all three arrays are empty
    1357             : // * <track-list>:
    1358             : //   mIsSubgrid is false,
    1359             : //   mMinTrackSizingFunctions and mMaxTrackSizingFunctions
    1360             : //   are of identical non-zero size,
    1361             : //   and mLineNameLists is one element longer than that.
    1362             : //   (Delimiting N columns requires N+1 lines:
    1363             : //   one before each track, plus one at the very end.)
    1364             : //
    1365             : //   An omitted <line-names> is still represented in mLineNameLists,
    1366             : //   as an empty sub-array.
    1367             : //
    1368             : //   A <track-size> specified as a single <track-breadth> is represented
    1369             : //   as identical min and max sizing functions.
    1370             : //   A 'fit-content(size)' <track-size> is represented as eStyleUnit_None
    1371             : //   in the min sizing function and 'size' in the max sizing function.
    1372             : //
    1373             : //   The units for nsStyleCoord are:
    1374             : //   * eStyleUnit_Percent represents a <percentage>
    1375             : //   * eStyleUnit_FlexFraction represents a <flex> flexible fraction
    1376             : //   * eStyleUnit_Coord represents a <length>
    1377             : //   * eStyleUnit_Enumerated represents min-content or max-content
    1378             : // * subgrid <line-name-list>?:
    1379             : //   mIsSubgrid is true,
    1380             : //   mLineNameLists may or may not be empty,
    1381             : //   mMinTrackSizingFunctions and mMaxTrackSizingFunctions are empty.
    1382           0 : //
    1383             : // If mRepeatAutoIndex != -1 then that index is an <auto-repeat> and
    1384             : // mIsAutoFill == true means it's an 'auto-fill', otherwise 'auto-fit'.
    1385             : // mRepeatAutoLineNameListBefore is the list of line names before the track
    1386             : // size, mRepeatAutoLineNameListAfter the names after.  (They are empty
    1387             : // when there is no <auto-repeat> track, i.e. when mRepeatAutoIndex == -1).
    1388             : // When mIsSubgrid is true, mRepeatAutoLineNameListBefore contains the line
    1389             : // names and mRepeatAutoLineNameListAfter is empty.
    1390             : struct nsStyleGridTemplate
    1391             : {
    1392             :   nsTArray<nsTArray<nsString>> mLineNameLists;
    1393           0 :   nsTArray<nsStyleCoord> mMinTrackSizingFunctions;
    1394           0 :   nsTArray<nsStyleCoord> mMaxTrackSizingFunctions;
    1395             :   nsTArray<nsString> mRepeatAutoLineNameListBefore;
    1396           0 :   nsTArray<nsString> mRepeatAutoLineNameListAfter;
    1397             :   int16_t mRepeatAutoIndex; // -1 or the track index for an auto-fill/fit track
    1398           0 :   bool mIsAutoFill : 1;
    1399             :   bool mIsSubgrid : 1;
    1400           0 : 
    1401             :   nsStyleGridTemplate()
    1402           0 :     : mRepeatAutoIndex(-1)
    1403           0 :     , mIsAutoFill(false)
    1404           0 :     , mIsSubgrid(false)
    1405           0 :   {
    1406           0 :   }
    1407           0 : 
    1408           0 :   inline bool operator==(const nsStyleGridTemplate& aOther) const {
    1409           0 :     return
    1410             :       mIsSubgrid == aOther.mIsSubgrid &&
    1411             :       mLineNameLists == aOther.mLineNameLists &&
    1412             :       mMinTrackSizingFunctions == aOther.mMinTrackSizingFunctions &&
    1413           0 :       mMaxTrackSizingFunctions == aOther.mMaxTrackSizingFunctions &&
    1414             :       mIsAutoFill == aOther.mIsAutoFill &&
    1415             :       mRepeatAutoIndex == aOther.mRepeatAutoIndex &&
    1416           0 :       mRepeatAutoLineNameListBefore == aOther.mRepeatAutoLineNameListBefore &&
    1417           0 :       mRepeatAutoLineNameListAfter == aOther.mRepeatAutoLineNameListAfter;
    1418           0 :   }
    1419             : 
    1420             :   bool HasRepeatAuto() const {
    1421             :     return mRepeatAutoIndex != -1;
    1422             :   }
    1423             : 
    1424             :   bool IsRepeatAutoIndex(uint32_t aIndex) const {
    1425             :     MOZ_ASSERT(aIndex < uint32_t(2*nsStyleGridLine::kMaxLine));
    1426             :     return int32_t(aIndex) == mRepeatAutoIndex;
    1427             :   }
    1428             : };
    1429             : 
    1430             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition
    1431             : {
    1432             :   explicit nsStylePosition(const nsPresContext* aContext);
    1433             :   nsStylePosition(const nsStylePosition& aOther);
    1434             :   ~nsStylePosition();
    1435             :   void FinishStyle(nsPresContext*, const nsStylePosition*) {}
    1436             :   const static bool kHasFinishStyle = false;
    1437             : 
    1438             :   nsChangeHint CalcDifference(const nsStylePosition& aNewData,
    1439             :                               const nsStyleVisibility* aOldStyleVisibility) const;
    1440             : 
    1441             :   /**
    1442             :    * Return the used value for 'align-self' given our parent ComputedStyle
    1443             :    * aParent (or null for the root).
    1444             :    */
    1445             :   uint8_t UsedAlignSelf(mozilla::ComputedStyle* aParent) const;
    1446             : 
    1447             :   /**
    1448             :    * Return the used value for 'justify-self' given our parent ComputedStyle
    1449             :    * aParent (or null for the root).
    1450             :    */
    1451             :   uint8_t UsedJustifySelf(mozilla::ComputedStyle* aParent) const;
    1452             : 
    1453             :   mozilla::Position mObjectPosition;    // [reset]
    1454             :   nsStyleSides  mOffset;                // [reset] coord, percent, calc, auto
    1455             :   nsStyleCoord  mWidth;                 // [reset] coord, percent, enum, calc, auto
    1456             :   nsStyleCoord  mMinWidth;              // [reset] coord, percent, enum, calc
    1457             :   nsStyleCoord  mMaxWidth;              // [reset] coord, percent, enum, calc, none
    1458             :   nsStyleCoord  mHeight;                // [reset] coord, percent, calc, auto
    1459             :   nsStyleCoord  mMinHeight;             // [reset] coord, percent, calc
    1460             :   nsStyleCoord  mMaxHeight;             // [reset] coord, percent, calc, none
    1461             :   nsStyleCoord  mFlexBasis;             // [reset] coord, percent, enum, calc, auto
    1462             :   nsStyleCoord  mGridAutoColumnsMin;    // [reset] coord, percent, enum, calc, flex
    1463             :   nsStyleCoord  mGridAutoColumnsMax;    // [reset] coord, percent, enum, calc, flex
    1464             :   nsStyleCoord  mGridAutoRowsMin;       // [reset] coord, percent, enum, calc, flex
    1465             :   nsStyleCoord  mGridAutoRowsMax;       // [reset] coord, percent, enum, calc, flex
    1466             :   uint8_t       mGridAutoFlow;          // [reset] enumerated. See nsStyleConsts.h
    1467             :   mozilla::StyleBoxSizing mBoxSizing;   // [reset] see nsStyleConsts.h
    1468             : 
    1469             :   uint16_t      mAlignContent;          // [reset] fallback value in the high byte
    1470             :   uint8_t       mAlignItems;            // [reset] see nsStyleConsts.h
    1471             :   uint8_t       mAlignSelf;             // [reset] see nsStyleConsts.h
    1472             :   uint16_t      mJustifyContent;        // [reset] fallback value in the high byte
    1473             :   // We cascade mSpecifiedJustifyItems, to handle the auto value, but store the
    1474             :   // computed value in mJustifyItems.
    1475             :   //
    1476             :   // They're effectively only different in this regard: mJustifyItems is set to
    1477             :   // mSpecifiedJustifyItems, except when the latter is AUTO -- in that case,
    1478             :   // mJustifyItems is set to NORMAL, or to the parent ComputedStyle's
    1479             :   // mJustifyItems if it has the legacy flag.
    1480             :   //
    1481             :   // This last part happens in ComputedStyle::ApplyStyleFixups.
    1482             :   uint8_t       mSpecifiedJustifyItems; // [reset] see nsStyleConsts.h
    1483             :   uint8_t       mJustifyItems;          // [reset] see nsStyleConsts.h
    1484             :   uint8_t       mJustifySelf;           // [reset] see nsStyleConsts.h
    1485             :   uint8_t       mFlexDirection;         // [reset] see nsStyleConsts.h
    1486             :   uint8_t       mFlexWrap;              // [reset] see nsStyleConsts.h
    1487             :   uint8_t       mObjectFit;             // [reset] see nsStyleConsts.h
    1488             :   int32_t       mOrder;                 // [reset] integer
    1489             :   float         mFlexGrow;              // [reset] float
    1490             :   float         mFlexShrink;            // [reset] float
    1491             :   nsStyleCoord  mZIndex;                // [reset] integer, auto
    1492             :   mozilla::UniquePtr<nsStyleGridTemplate> mGridTemplateColumns;
    1493             :   mozilla::UniquePtr<nsStyleGridTemplate> mGridTemplateRows;
    1494             : 
    1495             :   // nullptr for 'none'
    1496             :   RefPtr<mozilla::css::GridTemplateAreasValue> mGridTemplateAreas;
    1497             : 
    1498             :   nsStyleGridLine mGridColumnStart;
    1499             :   nsStyleGridLine mGridColumnEnd;
    1500             :   nsStyleGridLine mGridRowStart;
    1501             :   nsStyleGridLine mGridRowEnd;
    1502          24 :   nsStyleCoord    mColumnGap;       // [reset] normal, coord, percent, calc
    1503             :   nsStyleCoord    mRowGap;          // [reset] normal, coord, percent, calc
    1504          26 : 
    1505          26 :   // FIXME: Logical-coordinate equivalents to these WidthDepends... and
    1506             :   // HeightDepends... methods have been introduced (see below); we probably
    1507             :   // want to work towards removing the physical methods, and using the logical
    1508             :   // ones in all cases.
    1509             : 
    1510             :   bool WidthDependsOnContainer() const
    1511             :     {
    1512             :       return mWidth.GetUnit() == eStyleUnit_Auto ||
    1513             :         WidthCoordDependsOnContainer(mWidth);
    1514             :     }
    1515             : 
    1516             :   // NOTE: For a flex item, "min-width:auto" is supposed to behave like
    1517          22 :   // "min-content", which does depend on the container, so you might think we'd
    1518             :   // need a special case for "flex item && min-width:auto" here.  However,
    1519          22 :   // we don't actually need that special-case code, because flex items are
    1520             :   // explicitly supposed to *ignore* their min-width (i.e. behave like it's 0)
    1521             :   // until the flex container explicitly considers it.  So -- since the flex
    1522             :   // container doesn't rely on this method, we don't need to worry about
    1523             :   // special behavior for flex items' "min-width:auto" values here.
    1524             :   bool MinWidthDependsOnContainer() const
    1525             :     { return WidthCoordDependsOnContainer(mMinWidth); }
    1526             :   bool MaxWidthDependsOnContainer() const
    1527             :     { return WidthCoordDependsOnContainer(mMaxWidth); }
    1528         960 : 
    1529             :   // Note that these functions count 'auto' as depending on the
    1530        1034 :   // container since that's the case for absolutely positioned elements.
    1531        1108 :   // However, some callers do not care about this case and should check
    1532             :   // for it, since it is the most common case.
    1533             :   // FIXME: We should probably change the assumption to be the other way
    1534             :   // around.
    1535             :   // Consider this as part of moving to the logical-coordinate APIs.
    1536             :   bool HeightDependsOnContainer() const
    1537        1916 :     {
    1538             :       return mHeight.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
    1539        1916 :         HeightCoordDependsOnContainer(mHeight);
    1540             :     }
    1541        1002 : 
    1542             :   // NOTE: The comment above MinWidthDependsOnContainer about flex items
    1543        3006 :   // applies here, too.
    1544             :   bool MinHeightDependsOnContainer() const
    1545             :     { return HeightCoordDependsOnContainer(mMinHeight); }
    1546             :   bool MaxHeightDependsOnContainer() const
    1547             :     { return HeightCoordDependsOnContainer(mMaxHeight); }
    1548             : 
    1549             :   bool OffsetHasPercent(mozilla::Side aSide) const
    1550             :   {
    1551             :     return mOffset.Get(aSide).HasPercent();
    1552             :   }
    1553             : 
    1554             :   // Logical-coordinate accessors for width and height properties,
    1555             :   // given a WritingMode value. The definitions of these methods are
    1556             :   // found in WritingModes.h (after the WritingMode class is fully
    1557             :   // declared).
    1558             :   inline nsStyleCoord& ISize(mozilla::WritingMode aWM);
    1559             :   inline nsStyleCoord& MinISize(mozilla::WritingMode aWM);
    1560             :   inline nsStyleCoord& MaxISize(mozilla::WritingMode aWM);
    1561             :   inline nsStyleCoord& BSize(mozilla::WritingMode aWM);
    1562             :   inline nsStyleCoord& MinBSize(mozilla::WritingMode aWM);
    1563             :   inline nsStyleCoord& MaxBSize(mozilla::WritingMode aWM);
    1564             :   inline const nsStyleCoord& ISize(mozilla::WritingMode aWM) const;
    1565             :   inline const nsStyleCoord& MinISize(mozilla::WritingMode aWM) const;
    1566             :   inline const nsStyleCoord& MaxISize(mozilla::WritingMode aWM) const;
    1567             :   inline const nsStyleCoord& BSize(mozilla::WritingMode aWM) const;
    1568             :   inline const nsStyleCoord& MinBSize(mozilla::WritingMode aWM) const;
    1569             :   inline const nsStyleCoord& MaxBSize(mozilla::WritingMode aWM) const;
    1570             :   inline bool ISizeDependsOnContainer(mozilla::WritingMode aWM) const;
    1571             :   inline bool MinISizeDependsOnContainer(mozilla::WritingMode aWM) const;
    1572             :   inline bool MaxISizeDependsOnContainer(mozilla::WritingMode aWM) const;
    1573             :   inline bool BSizeDependsOnContainer(mozilla::WritingMode aWM) const;
    1574             :   inline bool MinBSizeDependsOnContainer(mozilla::WritingMode aWM) const;
    1575        1990 :   inline bool MaxBSizeDependsOnContainer(mozilla::WritingMode aWM) const;
    1576             : 
    1577             :   const nsStyleGridTemplate& GridTemplateColumns() const;
    1578         400 :   const nsStyleGridTemplate& GridTemplateRows() const;
    1579             : 
    1580         140 : private:
    1581             :   static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
    1582           4 :   static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
    1583           4 :     { return aCoord.HasPercent(); }
    1584           0 : };
    1585           4 : 
    1586             : struct nsStyleTextOverflowSide
    1587             : {
    1588             :   nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
    1589             : 
    1590             :   bool operator==(const nsStyleTextOverflowSide& aOther) const {
    1591             :     return mType == aOther.mType &&
    1592             :            (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
    1593             :             mString == aOther.mString);
    1594             :   }
    1595         256 :   bool operator!=(const nsStyleTextOverflowSide& aOther) const {
    1596             :     return !(*this == aOther);
    1597          70 :   }
    1598           2 : 
    1599           2 :   nsString mString;
    1600             :   uint8_t  mType;
    1601           2 : };
    1602           2 : 
    1603             : struct nsStyleTextOverflow
    1604             : {
    1605             :   nsStyleTextOverflow() : mLogicalDirections(true) {}
    1606           0 :   bool operator==(const nsStyleTextOverflow& aOther) const {
    1607           0 :     return mLeft == aOther.mLeft && mRight == aOther.mRight;
    1608             :   }
    1609           0 :   bool operator!=(const nsStyleTextOverflow& aOther) const {
    1610           0 :     return !(*this == aOther);
    1611             :   }
    1612             : 
    1613             :   // Returns the value to apply on the left side.
    1614           0 :   const nsStyleTextOverflowSide& GetLeft(uint8_t aDirection) const {
    1615           0 :     NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
    1616             :                  aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
    1617           0 :     return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
    1618           0 :              mLeft : mRight;
    1619             :   }
    1620             : 
    1621             :   // Returns the value to apply on the right side.
    1622             :   const nsStyleTextOverflowSide& GetRight(uint8_t aDirection) const {
    1623           0 :     NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
    1624             :                  aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
    1625             :     return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
    1626             :              mRight : mLeft;
    1627             :   }
    1628           0 : 
    1629             :   // Returns the first value that was specified.
    1630             :   const nsStyleTextOverflowSide* GetFirstValue() const {
    1631             :     return mLogicalDirections ? &mRight : &mLeft;
    1632             :   }
    1633             : 
    1634             :   // Returns the second value, or null if there was only one value specified.
    1635             :   const nsStyleTextOverflowSide* GetSecondValue() const {
    1636             :     return mLogicalDirections ? nullptr : &mRight;
    1637             :   }
    1638             : 
    1639             :   nsStyleTextOverflowSide mLeft;  // start side when mLogicalDirections is true
    1640             :   nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
    1641             :   bool mLogicalDirections;  // true when only one value was specified
    1642             : };
    1643             : 
    1644             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset
    1645             : {
    1646             :   explicit nsStyleTextReset(const nsPresContext* aContext);
    1647             :   nsStyleTextReset(const nsStyleTextReset& aOther);
    1648             :   ~nsStyleTextReset();
    1649             :   void FinishStyle(nsPresContext*, const nsStyleTextReset*) {}
    1650             :   const static bool kHasFinishStyle = false;
    1651             : 
    1652             :   // Note the difference between this and
    1653             :   // ComputedStyle::HasTextDecorationLines.
    1654             :   bool HasTextDecorationLines() const {
    1655             :     return mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_NONE &&
    1656             :            mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
    1657             :   }
    1658             : 
    1659             :   nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const;
    1660             : 
    1661             :   nsStyleTextOverflow mTextOverflow;    // [reset] enum, string
    1662             : 
    1663             :   uint8_t mTextDecorationLine;          // [reset] see nsStyleConsts.h
    1664             :   uint8_t mTextDecorationStyle;         // [reset] see nsStyleConsts.h
    1665             :   uint8_t mUnicodeBidi;                 // [reset] see nsStyleConsts.h
    1666             :   nscoord mInitialLetterSink;           // [reset] 0 means normal
    1667             :   float mInitialLetterSize;             // [reset] 0.0f means normal
    1668             :   mozilla::StyleComplexColor mTextDecorationColor; // [reset]
    1669             : };
    1670             : 
    1671             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText
    1672             : {
    1673             :   explicit nsStyleText(const nsPresContext* aContext);
    1674             :   nsStyleText(const nsStyleText& aOther);
    1675             :   ~nsStyleText();
    1676             :   void FinishStyle(nsPresContext*, const nsStyleText*) {}
    1677             :   const static bool kHasFinishStyle = false;
    1678             : 
    1679             :   nsChangeHint CalcDifference(const nsStyleText& aNewData) const;
    1680             : 
    1681             :   uint8_t mTextAlign;                   // [inherited] see nsStyleConsts.h
    1682             :   uint8_t mTextAlignLast;               // [inherited] see nsStyleConsts.h
    1683             :   bool mTextAlignTrue : 1;              // [inherited] see nsStyleConsts.h
    1684             :   bool mTextAlignLastTrue : 1;          // [inherited] see nsStyleConsts.h
    1685             :   mozilla::StyleTextJustify mTextJustify;   // [inherited]
    1686             :   uint8_t mTextTransform;               // [inherited] see nsStyleConsts.h
    1687             :   mozilla::StyleWhiteSpace mWhiteSpace;     // [inherited] see nsStyleConsts.h
    1688             :   uint8_t mWordBreak;                   // [inherited] see nsStyleConsts.h
    1689             :   uint8_t mOverflowWrap;                // [inherited] see nsStyleConsts.h
    1690             :   mozilla::StyleHyphens mHyphens;       // [inherited] see nsStyleConsts.h
    1691             :   uint8_t mRubyAlign;                   // [inherited] see nsStyleConsts.h
    1692             :   uint8_t mRubyPosition;                // [inherited] see nsStyleConsts.h
    1693             :   uint8_t mTextSizeAdjust;              // [inherited] see nsStyleConsts.h
    1694             :   uint8_t mTextCombineUpright;          // [inherited] see nsStyleConsts.h
    1695             :   uint8_t mControlCharacterVisibility;  // [inherited] see nsStyleConsts.h
    1696             :   uint8_t mTextEmphasisPosition;        // [inherited] see nsStyleConsts.h
    1697             :   uint8_t mTextEmphasisStyle;           // [inherited] see nsStyleConsts.h
    1698             :   uint8_t mTextRendering;               // [inherited] see nsStyleConsts.h
    1699             :   mozilla::StyleComplexColor mTextEmphasisColor;      // [inherited]
    1700             :   mozilla::StyleComplexColor mWebkitTextFillColor;    // [inherited]
    1701             :   mozilla::StyleComplexColor mWebkitTextStrokeColor;  // [inherited]
    1702             : 
    1703             :   nsStyleCoord mTabSize;                // [inherited] coord, factor, calc
    1704             :   nsStyleCoord mWordSpacing;            // [inherited] coord, percent, calc
    1705             :   nsStyleCoord mLetterSpacing;          // [inherited] coord, normal
    1706         172 :   nsStyleCoord mLineHeight;             // [inherited] coord, factor, normal
    1707         172 :   nsStyleCoord mTextIndent;             // [inherited] coord, percent, calc
    1708         172 :   nscoord mWebkitTextStrokeWidth;       // [inherited] coord
    1709         172 : 
    1710             :   RefPtr<nsCSSShadowArray> mTextShadow; // [inherited] nullptr in case of a zero-length
    1711             : 
    1712          30 :   nsString mTextEmphasisStyleString;    // [inherited]
    1713          30 : 
    1714          30 :   bool WhiteSpaceIsSignificant() const {
    1715          30 :     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
    1716             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
    1717             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
    1718          26 :   }
    1719          26 : 
    1720          22 :   bool NewlineIsSignificantStyle() const {
    1721          48 :     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
    1722          26 :            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
    1723             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
    1724             :   }
    1725             : 
    1726           8 :   bool WhiteSpaceOrNewlineIsSignificant() const {
    1727           8 :     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
    1728             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
    1729             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreLine ||
    1730          88 :            mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
    1731          88 :   }
    1732          88 : 
    1733          88 :   bool TabIsSignificant() const {
    1734             :     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
    1735             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap;
    1736          10 :   }
    1737          10 : 
    1738          10 :   bool WhiteSpaceCanWrapStyle() const {
    1739             :     return mWhiteSpace == mozilla::StyleWhiteSpace::Normal ||
    1740             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
    1741             :            mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
    1742          88 :   }
    1743             : 
    1744             :   bool WordCanWrapStyle() const {
    1745             :     return WhiteSpaceCanWrapStyle() &&
    1746             :            mOverflowWrap == NS_STYLE_OVERFLOWWRAP_BREAK_WORD;
    1747             :   }
    1748             : 
    1749             :   bool HasTextEmphasis() const {
    1750             :     return !mTextEmphasisStyleString.IsEmpty();
    1751             :   }
    1752             : 
    1753             :   bool HasWebkitTextStroke() const {
    1754             :     return mWebkitTextStrokeWidth > 0;
    1755             :   }
    1756             : 
    1757             :   // These are defined in nsStyleStructInlines.h.
    1758             :   inline bool HasTextShadow() const;
    1759             :   inline nsCSSShadowArray* GetTextShadow() const;
    1760             : 
    1761             :   // The aContextFrame argument on each of these is the frame this
    1762             :   // style struct is for.  If the frame is for SVG text or inside ruby,
    1763             :   // the return value will be massaged to be something that makes sense
    1764             :   // for those cases.
    1765             :   inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const;
    1766             :   inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
    1767             :   inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
    1768             : 
    1769             :   mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const;
    1770             : };
    1771             : 
    1772             : struct nsStyleImageOrientation
    1773             : {
    1774             :   static nsStyleImageOrientation CreateAsAngleAndFlip(double aRadians,
    1775             :                                                       bool aFlip) {
    1776             :     uint8_t orientation(0);
    1777             : 
    1778             :     // Compute the final angle value, rounding to the closest quarter turn.
    1779             :     double roundedAngle = fmod(aRadians, 2 * M_PI);
    1780             :     if (roundedAngle < 0) {
    1781             :       roundedAngle = roundedAngle + 2 * M_PI;
    1782             :     }
    1783             :     if      (roundedAngle < 0.25 * M_PI) { orientation = ANGLE_0;  }
    1784             :     else if (roundedAngle < 0.75 * M_PI) { orientation = ANGLE_90; }
    1785             :     else if (roundedAngle < 1.25 * M_PI) { orientation = ANGLE_180;}
    1786             :     else if (roundedAngle < 1.75 * M_PI) { orientation = ANGLE_270;}
    1787             :     else                                 { orientation = ANGLE_0;  }
    1788             : 
    1789           0 :     // Add a bit for 'flip' if needed.
    1790             :     if (aFlip) {
    1791           0 :       orientation |= FLIP_MASK;
    1792           0 :     }
    1793           0 : 
    1794             :     return nsStyleImageOrientation(orientation);
    1795           0 :   }
    1796             : 
    1797             :   static nsStyleImageOrientation CreateAsOrientationAndFlip(uint8_t aOrientation,
    1798             :                                                             bool aFlip) {
    1799             :     MOZ_ASSERT(aOrientation <= ANGLE_270);
    1800             :     if (aFlip) {
    1801             :       aOrientation |= FLIP_MASK;
    1802             :     }
    1803           0 :     return nsStyleImageOrientation(aOrientation);
    1804             :   }
    1805             : 
    1806             :   static nsStyleImageOrientation CreateAsFlip() {
    1807          70 :     return nsStyleImageOrientation(FLIP_MASK);
    1808             :   }
    1809             : 
    1810           0 :   static nsStyleImageOrientation CreateAsFromImage() {
    1811           0 :     return nsStyleImageOrientation(FROM_IMAGE_MASK);
    1812             :   }
    1813             : 
    1814             :   // The default constructor yields 0 degrees of rotation and no flip.
    1815             :   nsStyleImageOrientation() : mOrientation(0) { }
    1816             : 
    1817           0 :   bool IsDefault()   const { return mOrientation == 0; }
    1818           0 :   bool IsFlipped()   const { return mOrientation & FLIP_MASK; }
    1819             :   bool IsFromImage() const { return mOrientation & FROM_IMAGE_MASK; }
    1820           0 :   bool SwapsWidthAndHeight() const {
    1821           0 :     uint8_t angle = mOrientation & ORIENTATION_MASK;
    1822           0 :     return (angle == ANGLE_90) || (angle == ANGLE_270);
    1823             :   }
    1824           0 : 
    1825           0 :   mozilla::image::Angle Angle() const {
    1826             :     switch (mOrientation & ORIENTATION_MASK) {
    1827             :       case ANGLE_0:   return mozilla::image::Angle::D0;
    1828             :       case ANGLE_90:  return mozilla::image::Angle::D90;
    1829           0 :       case ANGLE_180: return mozilla::image::Angle::D180;
    1830           0 :       case ANGLE_270: return mozilla::image::Angle::D270;
    1831           0 :       default:
    1832           0 :         NS_NOTREACHED("Unexpected angle");
    1833           0 :         return mozilla::image::Angle::D0;
    1834           0 :     }
    1835             :   }
    1836           0 : 
    1837           0 :   nsStyleCoord AngleAsCoord() const {
    1838             :     switch (mOrientation & ORIENTATION_MASK) {
    1839             :       case ANGLE_0:   return nsStyleCoord(0.0f,   eStyleUnit_Degree);
    1840             :       case ANGLE_90:  return nsStyleCoord(90.0f,  eStyleUnit_Degree);
    1841             :       case ANGLE_180: return nsStyleCoord(180.0f, eStyleUnit_Degree);
    1842          60 :       case ANGLE_270: return nsStyleCoord(270.0f, eStyleUnit_Degree);
    1843             :       default:
    1844             :         NS_NOTREACHED("Unexpected angle");
    1845             :         return nsStyleCoord();
    1846          60 :     }
    1847             :   }
    1848             : 
    1849             :   bool operator==(const nsStyleImageOrientation& aOther) const {
    1850             :     return aOther.mOrientation == mOrientation;
    1851             :   }
    1852             : 
    1853             :   bool operator!=(const nsStyleImageOrientation& aOther) const {
    1854             :     return !(*this == aOther);
    1855             :   }
    1856             : 
    1857             : protected:
    1858             :   enum Bits {
    1859             :     ORIENTATION_MASK = 0x1 | 0x2,  // The bottom two bits are the angle.
    1860             :     FLIP_MASK        = 0x4,        // Whether the image should be flipped.
    1861             :     FROM_IMAGE_MASK  = 0x8,        // Whether the image's inherent orientation
    1862             :   };                               // should be used.
    1863             : 
    1864             :   enum Angles {
    1865             :     ANGLE_0   = 0,
    1866             :     ANGLE_90  = 1,
    1867             :     ANGLE_180 = 2,
    1868             :     ANGLE_270 = 3,
    1869             :   };
    1870             : 
    1871             :   explicit nsStyleImageOrientation(uint8_t aOrientation)
    1872             :     : mOrientation(aOrientation)
    1873             :   { }
    1874         172 : 
    1875          86 :   uint8_t mOrientation;
    1876          86 : };
    1877             : 
    1878             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility
    1879             : {
    1880             :   explicit nsStyleVisibility(const nsPresContext* aContext);
    1881             :   nsStyleVisibility(const nsStyleVisibility& aVisibility);
    1882             :   ~nsStyleVisibility() {
    1883             :     MOZ_COUNT_DTOR(nsStyleVisibility);
    1884             :   }
    1885             :   void FinishStyle(nsPresContext*, const nsStyleVisibility*) {}
    1886             :   const static bool kHasFinishStyle = false;
    1887             : 
    1888             :   nsChangeHint CalcDifference(const nsStyleVisibility& aNewData) const;
    1889             : 
    1890             :   nsStyleImageOrientation mImageOrientation;  // [inherited]
    1891           0 :   uint8_t mDirection;                  // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
    1892             :   uint8_t mVisible;                    // [inherited]
    1893             :   uint8_t mImageRendering;             // [inherited] see nsStyleConsts.h
    1894             :   uint8_t mWritingMode;                // [inherited] see nsStyleConsts.h
    1895           0 :   uint8_t mTextOrientation;            // [inherited] see nsStyleConsts.h
    1896             :   uint8_t mColorAdjust;                // [inherited] see nsStyleConsts.h
    1897             : 
    1898             :   bool IsVisible() const {
    1899             :     return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
    1900             :   }
    1901             : 
    1902        3236 :   bool IsVisibleOrCollapsed() const {
    1903             :     return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
    1904        6594 :             (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
    1905             :   }
    1906             : };
    1907             : 
    1908             : namespace mozilla {
    1909             : 
    1910             : struct StyleTransition
    1911           4 : {
    1912             :   StyleTransition() { /* leaves uninitialized; see also SetInitialValues */ }
    1913             :   explicit StyleTransition(const StyleTransition& aCopy);
    1914             : 
    1915           0 :   void SetInitialValues();
    1916             : 
    1917             :   // Delay and Duration are in milliseconds
    1918             : 
    1919             :   const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
    1920             :   float GetDelay() const { return mDelay; }
    1921             :   float GetDuration() const { return mDuration; }
    1922             :   nsCSSPropertyID GetProperty() const { return mProperty; }
    1923             :   nsAtom* GetUnknownProperty() const { return mUnknownProperty; }
    1924             : 
    1925             :   void SetTimingFunction(const nsTimingFunction& aTimingFunction)
    1926             :     { mTimingFunction = aTimingFunction; }
    1927             :   void SetDelay(float aDelay) { mDelay = aDelay; }
    1928             :   void SetDuration(float aDuration) { mDuration = aDuration; }
    1929             : 
    1930             :   nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
    1931             : 
    1932             :   bool operator==(const StyleTransition& aOther) const;
    1933             :   bool operator!=(const StyleTransition& aOther) const
    1934             :     { return !(*this == aOther); }
    1935             : 
    1936             : private:
    1937             :   nsTimingFunction mTimingFunction;
    1938        3234 :   float mDuration;
    1939             :   float mDelay;
    1940        6570 :   nsCSSPropertyID mProperty;
    1941             :   RefPtr<nsAtom> mUnknownProperty; // used when mProperty is
    1942             :                                       // eCSSProperty_UNKNOWN or
    1943             :                                       // eCSSPropertyExtra_variable
    1944             : };
    1945             : 
    1946             : struct StyleAnimation
    1947           0 : {
    1948             :   StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
    1949             :   explicit StyleAnimation(const StyleAnimation& aCopy);
    1950           0 : 
    1951             :   void SetInitialValues();
    1952             : 
    1953             :   // Delay and Duration are in milliseconds
    1954             : 
    1955             :   const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
    1956             :   float GetDelay() const { return mDelay; }
    1957             :   float GetDuration() const { return mDuration; }
    1958             :   nsAtom* GetName() const { return mName; }
    1959             :   dom::PlaybackDirection GetDirection() const { return mDirection; }
    1960           2 :   dom::FillMode GetFillMode() const { return mFillMode; }
    1961           0 :   uint8_t GetPlayState() const { return mPlayState; }
    1962             :   float GetIterationCount() const { return mIterationCount; }
    1963             : 
    1964             :   void SetTimingFunction(const nsTimingFunction& aTimingFunction)
    1965             :     { mTimingFunction = aTimingFunction; }
    1966             :   void SetDelay(float aDelay) { mDelay = aDelay; }
    1967             :   void SetDuration(float aDuration) { mDuration = aDuration; }
    1968             :   void SetName(already_AddRefed<nsAtom> aName) { mName = aName; }
    1969             :   void SetName(nsAtom* aName) { mName = aName; }
    1970             :   void SetDirection(dom::PlaybackDirection aDirection) { mDirection = aDirection; }
    1971             :   void SetFillMode(dom::FillMode aFillMode) { mFillMode = aFillMode; }
    1972             :   void SetPlayState(uint8_t aPlayState) { mPlayState = aPlayState; }
    1973             :   void SetIterationCount(float aIterationCount)
    1974             :     { mIterationCount = aIterationCount; }
    1975             : 
    1976             :   nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
    1977             : 
    1978             :   bool operator==(const StyleAnimation& aOther) const;
    1979             :   bool operator!=(const StyleAnimation& aOther) const
    1980             :     { return !(*this == aOther); }
    1981             : 
    1982             : private:
    1983             :   nsTimingFunction mTimingFunction;
    1984             :   float mDuration;
    1985           0 :   float mDelay;
    1986             :   RefPtr<nsAtom> mName; // nsGkAtoms::_empty for 'none'
    1987             :   dom::PlaybackDirection mDirection;
    1988           0 :   dom::FillMode mFillMode;
    1989           0 :   uint8_t mPlayState;
    1990           0 :   float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
    1991             : };
    1992           0 : 
    1993           0 : class StyleBasicShape final
    1994             : {
    1995             : public:
    1996             :   explicit StyleBasicShape(StyleBasicShapeType type)
    1997             :     : mType(type),
    1998             :       mFillRule(StyleFillRule::Nonzero)
    1999             :   {
    2000             :     mPosition.SetInitialPercentValues(0.5f);
    2001             :   }
    2002             : 
    2003             :   StyleBasicShapeType GetShapeType() const { return mType; }
    2004             :   nsCSSKeyword GetShapeTypeName() const;
    2005           0 : 
    2006           0 :   StyleFillRule GetFillRule() const { return mFillRule; }
    2007             :   void SetFillRule(StyleFillRule aFillRule)
    2008             :   {
    2009           0 :     MOZ_ASSERT(mType == StyleBasicShapeType::Polygon, "expected polygon");
    2010             :     mFillRule = aFillRule;
    2011             :   }
    2012             : 
    2013             :   mozilla::Position& GetPosition() {
    2014             :     MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
    2015             :                mType == StyleBasicShapeType::Ellipse,
    2016             :                "expected circle or ellipse");
    2017             :     return mPosition;
    2018           0 :   }
    2019           0 :   const mozilla::Position& GetPosition() const {
    2020           0 :     MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
    2021           0 :                mType == StyleBasicShapeType::Ellipse,
    2022           0 :                "expected circle or ellipse");
    2023           0 :     return mPosition;
    2024             :   }
    2025             : 
    2026             :   bool HasRadius() const {
    2027             :     MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
    2028             :     nsStyleCoord zero;
    2029           0 :     zero.SetCoordValue(0);
    2030           0 :     NS_FOR_CSS_HALF_CORNERS(corner) {
    2031           0 :       if (mRadius.Get(corner) != zero) {
    2032             :         return true;
    2033             :       }
    2034             :     }
    2035             :     return false;
    2036             :   }
    2037             :   nsStyleCorners& GetRadius() {
    2038             :     MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
    2039             :     return mRadius;
    2040             :   }
    2041             :   const nsStyleCorners& GetRadius() const {
    2042           0 :     MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
    2043             :     return mRadius;
    2044             :   }
    2045             : 
    2046             :   // mCoordinates has coordinates for polygon or radii for
    2047             :   // ellipse and circle.
    2048             :   nsTArray<nsStyleCoord>& Coordinates()
    2049             :   {
    2050           0 :     return mCoordinates;
    2051             :   }
    2052           0 : 
    2053           0 :   const nsTArray<nsStyleCoord>& Coordinates() const
    2054           0 :   {
    2055           0 :     return mCoordinates;
    2056           0 :   }
    2057             : 
    2058             :   bool operator==(const StyleBasicShape& aOther) const
    2059             :   {
    2060             :     return mType == aOther.mType &&
    2061             :            mFillRule == aOther.mFillRule &&
    2062             :            mCoordinates == aOther.mCoordinates &&
    2063             :            mPosition == aOther.mPosition &&
    2064             :            mRadius == aOther.mRadius;
    2065             :   }
    2066             :   bool operator!=(const StyleBasicShape& aOther) const {
    2067             :     return !(*this == aOther);
    2068             :   }
    2069             : 
    2070             : private:
    2071             :   StyleBasicShapeType mType;
    2072             :   StyleFillRule mFillRule;
    2073             : 
    2074             :   // mCoordinates has coordinates for polygon or radii for
    2075             :   // ellipse and circle.
    2076             :   // (top, right, bottom, left) for inset
    2077             :   nsTArray<nsStyleCoord> mCoordinates;
    2078         420 :   // position of center for ellipse or circle
    2079             :   mozilla::Position mPosition;
    2080             :   // corner radii for inset (0 if not set)
    2081             :   nsStyleCorners mRadius;
    2082        1146 : };
    2083        1146 : 
    2084        1146 : struct StyleShapeSource final
    2085             : {
    2086             :   StyleShapeSource() = default;
    2087             : 
    2088             :   StyleShapeSource(const StyleShapeSource& aSource);
    2089             : 
    2090          78 :   ~StyleShapeSource()
    2091             :   {
    2092          78 :   }
    2093             : 
    2094             :   StyleShapeSource& operator=(const StyleShapeSource& aOther);
    2095             : 
    2096             :   bool operator==(const StyleShapeSource& aOther) const;
    2097             : 
    2098             :   bool operator!=(const StyleShapeSource& aOther) const
    2099             :   {
    2100           0 :     return !(*this == aOther);
    2101             :   }
    2102           0 : 
    2103             :   StyleShapeSourceType GetType() const
    2104           0 :   {
    2105           0 :     return mType;
    2106             :   }
    2107             : 
    2108             :   css::URLValue* GetURL() const
    2109             :   {
    2110           0 :     MOZ_ASSERT(mType == StyleShapeSourceType::URL, "Wrong shape source type!");
    2111             :     return mShapeImage
    2112           0 :       ? static_cast<css::URLValue*>(mShapeImage->GetURLValue())
    2113           0 :       : nullptr;
    2114             :   }
    2115             : 
    2116             :   void SetURL(css::URLValue* aValue);
    2117             : 
    2118             :   const UniquePtr<nsStyleImage>& GetShapeImage() const
    2119             :   {
    2120             :     MOZ_ASSERT(mType == StyleShapeSourceType::Image, "Wrong shape source type!");
    2121             :     return mShapeImage;
    2122             :   }
    2123           0 : 
    2124             :   // Iff we have "shape-outside:<image>" with an image URI (not a gradient),
    2125           0 :   // this method returns the corresponding imgIRequest*. Else, returns
    2126           0 :   // null.
    2127             :   imgIRequest* GetShapeImageData() const;
    2128             : 
    2129             :   void SetShapeImage(UniquePtr<nsStyleImage> aShapeImage);
    2130             : 
    2131             :   const UniquePtr<StyleBasicShape>& GetBasicShape() const
    2132           0 :   {
    2133             :     MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
    2134           0 :     return mBasicShape;
    2135             :   }
    2136             : 
    2137           0 :   void SetBasicShape(UniquePtr<StyleBasicShape> aBasicShape,
    2138             :                      StyleGeometryBox aReferenceBox);
    2139             : 
    2140             :   StyleGeometryBox GetReferenceBox() const
    2141             :   {
    2142             :     MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
    2143             :                mType == StyleShapeSourceType::Shape,
    2144             :                "Wrong shape source type!");
    2145             :     return mReferenceBox;
    2146             :   }
    2147             : 
    2148             :   void SetReferenceBox(StyleGeometryBox aReferenceBox);
    2149             : 
    2150             : private:
    2151             :   void* operator new(size_t) = delete;
    2152             : 
    2153             :   void DoCopy(const StyleShapeSource& aOther);
    2154             : 
    2155             :   mozilla::UniquePtr<StyleBasicShape> mBasicShape;
    2156             :   mozilla::UniquePtr<nsStyleImage> mShapeImage;
    2157             :   StyleShapeSourceType mType = StyleShapeSourceType::None;
    2158             :   StyleGeometryBox mReferenceBox = StyleGeometryBox::NoBox;
    2159             : };
    2160             : 
    2161             : } // namespace mozilla
    2162             : 
    2163             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
    2164             : {
    2165             :   typedef mozilla::StyleGeometryBox StyleGeometryBox;
    2166             : 
    2167             :   explicit nsStyleDisplay(const nsPresContext* aContext);
    2168             :   nsStyleDisplay(const nsStyleDisplay& aOther);
    2169             :   ~nsStyleDisplay();
    2170             : 
    2171             :   void FinishStyle(nsPresContext*, const nsStyleDisplay*);
    2172             :   const static bool kHasFinishStyle = true;
    2173             : 
    2174             :   nsChangeHint CalcDifference(const nsStyleDisplay& aNewData) const;
    2175             : 
    2176             :   // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
    2177             :   // mBinding->mOriginPrincipal.
    2178             :   RefPtr<mozilla::css::URLValue> mBinding; // [reset]
    2179             :   mozilla::StyleDisplay mDisplay;          // [reset] see nsStyleConsts.h StyleDisplay
    2180             :   mozilla::StyleDisplay mOriginalDisplay;  // [reset] saved mDisplay for
    2181             :                                            //         position:absolute/fixed
    2182             :                                            //         and float:left/right;
    2183             :                                            //         otherwise equal to
    2184             :                                            //         mDisplay
    2185             :   uint8_t mContain;             // [reset] see nsStyleConsts.h NS_STYLE_CONTAIN_*
    2186             :   uint8_t mAppearance;          // [reset]
    2187             :   uint8_t mPosition;            // [reset] see nsStyleConsts.h
    2188             : 
    2189             :   // [reset] See StyleFloat in nsStyleConsts.h.
    2190             :   mozilla::StyleFloat mFloat;
    2191             :   // [reset] Save mFloat for position:absolute/fixed; otherwise equal to mFloat.
    2192             :   mozilla::StyleFloat mOriginalFloat;
    2193             : 
    2194             :   mozilla::StyleClear mBreakType;  // [reset]
    2195             :   uint8_t mBreakInside;         // [reset] NS_STYLE_PAGE_BREAK_AUTO/AVOID
    2196             :   bool mBreakBefore;    // [reset]
    2197             :   bool mBreakAfter;     // [reset]
    2198             :   uint8_t mOverflowX;           // [reset] see nsStyleConsts.h
    2199             :   uint8_t mOverflowY;           // [reset] see nsStyleConsts.h
    2200             :   uint8_t mOverflowClipBoxBlock;     // [reset] see nsStyleConsts.h
    2201             :   uint8_t mOverflowClipBoxInline;    // [reset] see nsStyleConsts.h
    2202             :   uint8_t mResize;              // [reset] see nsStyleConsts.h
    2203             :   mozilla::StyleOrient mOrient; // [reset] see nsStyleConsts.h
    2204             :   uint8_t mIsolation;           // [reset] see nsStyleConsts.h
    2205             :   uint8_t mTopLayer;            // [reset] see nsStyleConsts.h
    2206             :   uint8_t mWillChangeBitField;  // [reset] see nsStyleConsts.h. Stores a
    2207             :                                 // bitfield representation of the properties
    2208             :                                 // that are frequently queried. This should
    2209             :                                 // match mWillChange. Also tracks if any of the
    2210             :                                 // properties in the will-change list require
    2211             :                                 // a stacking context.
    2212             :   nsTArray<RefPtr<nsAtom>> mWillChange;
    2213             : 
    2214             :   uint8_t mTouchAction;         // [reset] see nsStyleConsts.h
    2215             :   uint8_t mScrollBehavior;      // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_*
    2216             :   mozilla::StyleOverscrollBehavior mOverscrollBehaviorX;  // [reset] see nsStyleConsts.h
    2217             :   mozilla::StyleOverscrollBehavior mOverscrollBehaviorY;  // [reset] see nsStyleConsts.h
    2218             :   uint8_t mScrollSnapTypeX;     // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
    2219             :   uint8_t mScrollSnapTypeY;     // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
    2220             :   nsStyleCoord mScrollSnapPointsX; // [reset]
    2221             :   nsStyleCoord mScrollSnapPointsY; // [reset]
    2222             :   mozilla::Position mScrollSnapDestination; // [reset]
    2223             :   nsTArray<mozilla::Position> mScrollSnapCoordinate; // [reset]
    2224             : 
    2225             :   // mSpecifiedTransform is the list of transform functions as
    2226             :   // specified, or null to indicate there is no transform.  (inherit or
    2227             :   // initial are replaced by an actual list of transform functions, or
    2228             :   // null, as appropriate.)
    2229             :   uint8_t mBackfaceVisibility;
    2230             :   uint8_t mTransformStyle;
    2231             :   StyleGeometryBox mTransformBox; // [reset] see nsStyleConsts.h
    2232             :   RefPtr<nsCSSValueSharedList> mSpecifiedTransform; // [reset]
    2233             :   RefPtr<nsCSSValueSharedList> mSpecifiedRotate; // [reset]
    2234             :   RefPtr<nsCSSValueSharedList> mSpecifiedTranslate; // [reset]
    2235             :   RefPtr<nsCSSValueSharedList> mSpecifiedScale; // [reset]
    2236             : 
    2237             :   // Used to store the final combination of mSpecifiedTranslate,
    2238             :   // mSpecifiedRotate, mSpecifiedScale and mSpecifiedTransform.
    2239             :   // Use GetCombinedTransform() to get the final transform, instead of
    2240             :   // accessing mCombinedTransform directly.
    2241             :   RefPtr<nsCSSValueSharedList> mCombinedTransform;
    2242             : 
    2243             :   nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
    2244             :   nsStyleCoord mChildPerspective; // [reset] none, coord
    2245             :   nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
    2246             : 
    2247             :   nsStyleCoord mVerticalAlign;  // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
    2248             : 
    2249             :   nsStyleAutoArray<mozilla::StyleTransition> mTransitions; // [reset]
    2250          12 : 
    2251             :   // The number of elements in mTransitions that are not from repeating
    2252          12 :   // a list due to another property being longer.
    2253             :   uint32_t mTransitionTimingFunctionCount,
    2254           4 :            mTransitionDurationCount,
    2255             :            mTransitionDelayCount,
    2256           4 :            mTransitionPropertyCount;
    2257             : 
    2258           4 :   nsCSSPropertyID GetTransitionProperty(uint32_t aIndex) const
    2259             :   {
    2260           4 :     return mTransitions[aIndex % mTransitionPropertyCount].GetProperty();
    2261             :   }
    2262           4 :   float GetTransitionDelay(uint32_t aIndex) const
    2263             :   {
    2264           8 :     return mTransitions[aIndex % mTransitionDelayCount].GetDelay();
    2265             :   }
    2266           4 :   float GetTransitionDuration(uint32_t aIndex) const
    2267             :   {
    2268             :     return mTransitions[aIndex % mTransitionDurationCount].GetDuration();
    2269             :   }
    2270          12 :   const nsTimingFunction& GetTransitionTimingFunction(uint32_t aIndex) const
    2271          12 :   {
    2272           8 :     return mTransitions[aIndex % mTransitionTimingFunctionCount].GetTimingFunction();
    2273             :   }
    2274             :   float GetTransitionCombinedDuration(uint32_t aIndex) const
    2275             :   {
    2276             :     // https://drafts.csswg.org/css-transitions/#transition-combined-duration
    2277             :     return
    2278             :       std::max(mTransitions[aIndex % mTransitionDurationCount].GetDuration(),
    2279             :                0.0f)
    2280             :         + mTransitions[aIndex % mTransitionDelayCount].GetDelay();
    2281             :   }
    2282             : 
    2283             :   nsStyleAutoArray<mozilla::StyleAnimation> mAnimations; // [reset]
    2284             : 
    2285             :   // The number of elements in mAnimations that are not from repeating
    2286             :   // a list due to another property being longer.
    2287             :   uint32_t mAnimationTimingFunctionCount,
    2288           0 :            mAnimationDurationCount,
    2289             :            mAnimationDelayCount,
    2290           0 :            mAnimationNameCount,
    2291             :            mAnimationDirectionCount,
    2292           0 :            mAnimationFillModeCount,
    2293             :            mAnimationPlayStateCount,
    2294           0 :            mAnimationIterationCountCount;
    2295             : 
    2296           0 :   nsAtom* GetAnimationName(uint32_t aIndex) const
    2297             :   {
    2298           0 :     return mAnimations[aIndex % mAnimationNameCount].GetName();
    2299             :   }
    2300           0 :   float GetAnimationDelay(uint32_t aIndex) const
    2301             :   {
    2302           0 :     return mAnimations[aIndex % mAnimationDelayCount].GetDelay();
    2303             :   }
    2304           0 :   float GetAnimationDuration(uint32_t aIndex) const
    2305             :   {
    2306           0 :     return mAnimations[aIndex % mAnimationDurationCount].GetDuration();
    2307             :   }
    2308           0 :   mozilla::dom::PlaybackDirection GetAnimationDirection(uint32_t aIndex) const
    2309             :   {
    2310           0 :     return mAnimations[aIndex % mAnimationDirectionCount].GetDirection();
    2311             :   }
    2312           0 :   mozilla::dom::FillMode GetAnimationFillMode(uint32_t aIndex) const
    2313             :   {
    2314           0 :     return mAnimations[aIndex % mAnimationFillModeCount].GetFillMode();
    2315             :   }
    2316           0 :   uint8_t GetAnimationPlayState(uint32_t aIndex) const
    2317             :   {
    2318           0 :     return mAnimations[aIndex % mAnimationPlayStateCount].GetPlayState();
    2319             :   }
    2320             :   float GetAnimationIterationCount(uint32_t aIndex) const
    2321             :   {
    2322             :     return mAnimations[aIndex % mAnimationIterationCountCount].GetIterationCount();
    2323             :   }
    2324             :   const nsTimingFunction& GetAnimationTimingFunction(uint32_t aIndex) const
    2325             :   {
    2326             :     return mAnimations[aIndex % mAnimationTimingFunctionCount].GetTimingFunction();
    2327             :   }
    2328             : 
    2329          20 :   // The threshold used for extracting a shape from shape-outside: <image>.
    2330          20 :   float mShapeImageThreshold = 0.0f; // [reset]
    2331           4 : 
    2332           0 :   // The margin around a shape-outside: <image>.
    2333          20 :   nsStyleCoord mShapeMargin;
    2334          20 : 
    2335             :   mozilla::StyleShapeSource mShapeOutside; // [reset]
    2336             : 
    2337             :   bool IsBlockInsideStyle() const {
    2338             :     return mozilla::StyleDisplay::Block == mDisplay ||
    2339             :            mozilla::StyleDisplay::ListItem == mDisplay ||
    2340           2 :            mozilla::StyleDisplay::InlineBlock == mDisplay ||
    2341           2 :            mozilla::StyleDisplay::TableCaption == mDisplay ||
    2342           2 :            mozilla::StyleDisplay::FlowRoot == mDisplay;
    2343           2 :     // Should TABLE_CELL be included here?  They have
    2344           2 :     // block frames nested inside of them.
    2345           2 :     // (But please audit all callers before changing.)
    2346           2 :   }
    2347           2 : 
    2348             :   bool IsBlockOutsideStyle() const {
    2349             :     return mozilla::StyleDisplay::Block == mDisplay ||
    2350         570 :            mozilla::StyleDisplay::Flex == mDisplay ||
    2351         570 :            mozilla::StyleDisplay::WebkitBox == mDisplay ||
    2352         570 :            mozilla::StyleDisplay::Grid == mDisplay ||
    2353         570 :            mozilla::StyleDisplay::ListItem == mDisplay ||
    2354         980 :            mozilla::StyleDisplay::Table == mDisplay ||
    2355         490 :            mozilla::StyleDisplay::FlowRoot == mDisplay;
    2356         980 :   }
    2357         490 : 
    2358         980 :   static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) {
    2359         490 :     return mozilla::StyleDisplay::Inline == aDisplay ||
    2360         490 :            mozilla::StyleDisplay::InlineBlock == aDisplay ||
    2361             :            mozilla::StyleDisplay::InlineTable == aDisplay ||
    2362         490 :            mozilla::StyleDisplay::MozInlineBox == aDisplay ||
    2363             :            mozilla::StyleDisplay::InlineFlex == aDisplay ||
    2364        1060 :            mozilla::StyleDisplay::WebkitInlineBox == aDisplay ||
    2365         570 :            mozilla::StyleDisplay::InlineGrid == aDisplay ||
    2366             :            mozilla::StyleDisplay::MozInlineGrid == aDisplay ||
    2367             :            mozilla::StyleDisplay::MozInlineStack == aDisplay ||
    2368             :            mozilla::StyleDisplay::Ruby == aDisplay ||
    2369         544 :            mozilla::StyleDisplay::RubyBase == aDisplay ||
    2370             :            mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
    2371             :            mozilla::StyleDisplay::RubyText == aDisplay ||
    2372             :            mozilla::StyleDisplay::RubyTextContainer == aDisplay ||
    2373          26 :            mozilla::StyleDisplay::Contents == aDisplay;
    2374             :   }
    2375             : 
    2376         946 :   bool IsInlineOutsideStyle() const {
    2377         946 :     return IsDisplayTypeInlineOutside(mDisplay);
    2378             :   }
    2379         946 : 
    2380         946 :   bool IsOriginalDisplayInlineOutsideStyle() const {
    2381         946 :     return IsDisplayTypeInlineOutside(mOriginalDisplay);
    2382         946 :   }
    2383        1892 : 
    2384         946 :   bool IsInnerTableStyle() const {
    2385             :     return mozilla::StyleDisplay::TableCaption == mDisplay ||
    2386             :            mozilla::StyleDisplay::TableCell == mDisplay ||
    2387             :            IsInternalTableStyleExceptCell();
    2388        1196 :   }
    2389             : 
    2390             :   bool IsInternalTableStyleExceptCell() const {
    2391             :     return mozilla::StyleDisplay::TableRow == mDisplay ||
    2392        4630 :            mozilla::StyleDisplay::TableRowGroup == mDisplay ||
    2393        1196 :            mozilla::StyleDisplay::TableHeaderGroup == mDisplay ||
    2394             :            mozilla::StyleDisplay::TableFooterGroup == mDisplay ||
    2395             :            mozilla::StyleDisplay::TableColumn == mDisplay ||
    2396             :            mozilla::StyleDisplay::TableColumnGroup == mDisplay;
    2397        2172 :   }
    2398        2172 : 
    2399             :   bool IsFloatingStyle() const {
    2400             :     return mozilla::StyleFloat::None != mFloat;
    2401          92 :   }
    2402             : 
    2403             :   bool IsAbsolutelyPositionedStyle() const {
    2404             :     return NS_STYLE_POSITION_ABSOLUTE == mPosition ||
    2405             :            NS_STYLE_POSITION_FIXED == mPosition;
    2406             :   }
    2407             : 
    2408             :   bool IsRelativelyPositionedStyle() const {
    2409           0 :     return NS_STYLE_POSITION_RELATIVE == mPosition ||
    2410           0 :            NS_STYLE_POSITION_STICKY == mPosition;
    2411             :   }
    2412             :   bool IsPositionForcingStackingContext() const {
    2413             :     return NS_STYLE_POSITION_STICKY == mPosition ||
    2414           0 :            NS_STYLE_POSITION_FIXED == mPosition;
    2415             :   }
    2416             : 
    2417             :   static bool IsRubyDisplayType(mozilla::StyleDisplay aDisplay) {
    2418             :     return mozilla::StyleDisplay::Ruby == aDisplay ||
    2419             :            IsInternalRubyDisplayType(aDisplay);
    2420             :   }
    2421             : 
    2422             :   static bool IsInternalRubyDisplayType(mozilla::StyleDisplay aDisplay) {
    2423             :     return mozilla::StyleDisplay::RubyBase == aDisplay ||
    2424         256 :            mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
    2425         256 :            mozilla::StyleDisplay::RubyText == aDisplay ||
    2426             :            mozilla::StyleDisplay::RubyTextContainer == aDisplay;
    2427             :   }
    2428             : 
    2429             :   bool IsRubyDisplayType() const {
    2430             :     return IsRubyDisplayType(mDisplay);
    2431             :   }
    2432             : 
    2433             :   bool IsInternalRubyDisplayType() const {
    2434        4048 :     return IsInternalRubyDisplayType(mDisplay);
    2435       23672 :   }
    2436       11682 : 
    2437       11836 :   bool IsOutOfFlowStyle() const {
    2438        7942 :     return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());
    2439             :   }
    2440             : 
    2441           0 :   bool IsScrollableOverflow() const {
    2442           0 :     // mOverflowX and mOverflowY always match when one of them is
    2443             :     // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
    2444             :     return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
    2445        3982 :            mOverflowX != NS_STYLE_OVERFLOW_CLIP;
    2446        3982 :   }
    2447             : 
    2448             :   bool IsContainPaint() const {
    2449             :     return (NS_STYLE_CONTAIN_PAINT & mContain) &&
    2450           0 :            !IsInternalRubyDisplayType() &&
    2451             :            !IsInternalTableStyleExceptCell();
    2452             :   }
    2453             : 
    2454             :   /* Returns whether the element has the -moz-transform property
    2455             :    * or a related property. */
    2456             :   bool HasTransformStyle() const {
    2457             :     return mSpecifiedTransform || mSpecifiedRotate || mSpecifiedTranslate ||
    2458             :            mSpecifiedScale ||
    2459             :            mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
    2460             :            (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM);
    2461             :   }
    2462             : 
    2463             :   bool HasIndividualTransform() const {
    2464             :     return mSpecifiedRotate || mSpecifiedTranslate || mSpecifiedScale;
    2465             :   }
    2466             : 
    2467             :   bool HasPerspectiveStyle() const {
    2468             :     return mChildPerspective.GetUnit() == eStyleUnit_Coord;
    2469             :   }
    2470             : 
    2471             :   bool BackfaceIsHidden() const {
    2472             :     return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
    2473             :   }
    2474             : 
    2475             :   // These are defined in nsStyleStructInlines.h.
    2476             : 
    2477             :   // The aContextFrame argument on each of these is the frame this
    2478             :   // style struct is for.  If the frame is for SVG text, the return
    2479             :   // value will be massaged to be something that makes sense for
    2480             :   // SVG text.
    2481             :   inline bool IsBlockInside(const nsIFrame* aContextFrame) const;
    2482             :   inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
    2483             :   inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
    2484             :   inline bool IsOriginalDisplayInlineOutside(const nsIFrame* aContextFrame) const;
    2485             :   inline mozilla::StyleDisplay GetDisplay(const nsIFrame* aContextFrame) const;
    2486             :   inline bool IsFloating(const nsIFrame* aContextFrame) const;
    2487             :   inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
    2488             :   inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
    2489             : 
    2490             :   // These methods are defined in nsStyleStructInlines.h.
    2491             : 
    2492             :   /**
    2493             :    * Returns whether the element is a containing block for its
    2494             :    * absolutely positioned descendants.
    2495             :    * aContextFrame is the frame for which this is the nsStyleDisplay.
    2496             :    */
    2497             :   inline bool IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const;
    2498             : 
    2499             :   /**
    2500             :    * The same as IsAbsPosContainingBlock, except skipping the tests that
    2501             :    * are based on the frame rather than the ComputedStyle (thus
    2502             :    * potentially returning a false positive).
    2503             :    */
    2504             :   inline bool IsAbsPosContainingBlockForAppropriateFrame(
    2505             :     mozilla::ComputedStyle&) const;
    2506             : 
    2507             :   /**
    2508             :    * Returns true when the element has the transform property
    2509             :    * or a related property, and supports CSS transforms.
    2510             :    * aContextFrame is the frame for which this is the nsStyleDisplay.
    2511             :    */
    2512             :   inline bool HasTransform(const nsIFrame* aContextFrame) const;
    2513             : 
    2514             :   /**
    2515             :    * Returns true when the element has the perspective property,
    2516             :    * and supports CSS transforms. aContextFrame is the frame for
    2517             :    * which this is the nsStyleDisplay.
    2518             :    */
    2519             :   inline bool HasPerspective(const nsIFrame* aContextFrame) const;
    2520             : 
    2521             :   /**
    2522             :    * Returns true when the element is a containing block for its fixed-pos
    2523             :    * descendants.
    2524             :    * aContextFrame is the frame for which this is the nsStyleDisplay.
    2525             :    */
    2526             :   inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const;
    2527             : 
    2528             :   /**
    2529             :    * The same as IsFixedPosContainingBlock, except skipping the tests that
    2530             :    * are based on the frame rather than the ComputedStyle (thus
    2531             :    * potentially returning a false positive).
    2532             :    */
    2533             :   inline bool IsFixedPosContainingBlockForAppropriateFrame(
    2534             :     mozilla::ComputedStyle&) const;
    2535             : 
    2536             :   /**
    2537             :    * Returns the final combined transform.
    2538             :    **/
    2539             :   already_AddRefed<nsCSSValueSharedList> GetCombinedTransform() const {
    2540             :     if (mCombinedTransform) {
    2541             :       return do_AddRef(mCombinedTransform);
    2542             :     }
    2543             : 
    2544             :     // backward compatible to gecko-backed style system.
    2545             :     return mSpecifiedTransform ? do_AddRef(mSpecifiedTransform) : nullptr;
    2546             :   }
    2547             : 
    2548             : private:
    2549             :   // Helpers for above functions, which do some but not all of the tests
    2550             :   // for them (since transform must be tested separately for each).
    2551             :   inline bool HasAbsPosContainingBlockStyleInternal() const;
    2552             :   inline bool HasFixedPosContainingBlockStyleInternal(
    2553             :     mozilla::ComputedStyle&) const;
    2554             :   void GenerateCombinedTransform();
    2555             : public:
    2556             :   // Return the 'float' and 'clear' properties, with inline-{start,end} values
    2557             :   // resolved to {left,right} according to the given writing mode. These are
    2558             :   // defined in WritingModes.h.
    2559             :   inline mozilla::StyleFloat PhysicalFloats(mozilla::WritingMode aWM) const;
    2560             :   inline mozilla::StyleClear PhysicalBreakType(mozilla::WritingMode aWM) const;
    2561             : };
    2562             : 
    2563             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable
    2564             : {
    2565             :   explicit nsStyleTable(const nsPresContext* aContext);
    2566             :   nsStyleTable(const nsStyleTable& aOther);
    2567             :   ~nsStyleTable();
    2568             :   void FinishStyle(nsPresContext*, const nsStyleTable*) {}
    2569             :   const static bool kHasFinishStyle = false;
    2570             : 
    2571             :   nsChangeHint CalcDifference(const nsStyleTable& aNewData) const;
    2572             : 
    2573             :   uint8_t       mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
    2574             :   int32_t       mSpan;          // [reset] the number of columns spanned by a colgroup or col
    2575             : };
    2576             : 
    2577             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder
    2578             : {
    2579             :   explicit nsStyleTableBorder(const nsPresContext* aContext);
    2580             :   nsStyleTableBorder(const nsStyleTableBorder& aOther);
    2581             :   ~nsStyleTableBorder();
    2582             :   void FinishStyle(nsPresContext*, const nsStyleTableBorder*) {}
    2583             :   const static bool kHasFinishStyle = false;
    2584             : 
    2585             :   nsChangeHint CalcDifference(const nsStyleTableBorder& aNewData) const;
    2586             : 
    2587             :   nscoord       mBorderSpacingCol;// [inherited]
    2588             :   nscoord       mBorderSpacingRow;// [inherited]
    2589             :   uint8_t       mBorderCollapse;// [inherited]
    2590             :   uint8_t       mCaptionSide;   // [inherited]
    2591             :   uint8_t       mEmptyCells;    // [inherited]
    2592             : };
    2593             : 
    2594             : enum nsStyleContentType {
    2595             :   eStyleContentType_String        = 1,
    2596             :   eStyleContentType_Image         = 10,
    2597             :   eStyleContentType_Attr          = 20,
    2598             :   eStyleContentType_Counter       = 30,
    2599             :   eStyleContentType_Counters      = 31,
    2600             :   eStyleContentType_OpenQuote     = 40,
    2601             :   eStyleContentType_CloseQuote    = 41,
    2602             :   eStyleContentType_NoOpenQuote   = 42,
    2603             :   eStyleContentType_NoCloseQuote  = 43,
    2604             :   eStyleContentType_AltContent    = 50,
    2605             :   eStyleContentType_Uninitialized
    2606             : };
    2607             : 
    2608             : struct nsStyleContentAttr {
    2609             :   RefPtr<nsAtom> mName; // Non-null.
    2610             :   RefPtr<nsAtom> mNamespaceURL; // May be null.
    2611             : 
    2612             :   bool operator==(const nsStyleContentAttr& aOther) const
    2613             :   {
    2614             :     return mName == aOther.mName && mNamespaceURL == aOther.mNamespaceURL;
    2615             :   }
    2616             : };
    2617             : 
    2618             : class nsStyleContentData
    2619             : {
    2620             : public:
    2621             :   nsStyleContentData()
    2622             :     : mType(eStyleContentType_Uninitialized)
    2623             :   {
    2624             :     MOZ_COUNT_CTOR(nsStyleContentData);
    2625             :     mContent.mString = nullptr;
    2626             :   }
    2627             :   nsStyleContentData(const nsStyleContentData&);
    2628             : 
    2629             :   ~nsStyleContentData();
    2630             :   nsStyleContentData& operator=(const nsStyleContentData& aOther);
    2631             :   bool operator==(const nsStyleContentData& aOther) const;
    2632             : 
    2633             :   bool operator!=(const nsStyleContentData& aOther) const {
    2634             :     return !(*this == aOther);
    2635             :   }
    2636             : 
    2637             :   nsStyleContentType GetType() const { return mType; }
    2638             : 
    2639             :   char16_t* GetString() const
    2640             :   {
    2641             :     MOZ_ASSERT(mType == eStyleContentType_String);
    2642             :     return mContent.mString;
    2643             :   }
    2644             : 
    2645             :   const nsStyleContentAttr* GetAttr() const {
    2646             :     MOZ_ASSERT(mType == eStyleContentType_Attr);
    2647             :     MOZ_ASSERT(mContent.mAttr);
    2648             :     return mContent.mAttr;
    2649             :    }
    2650             : 
    2651             :   struct CounterFunction
    2652             :   {
    2653             :     nsString mIdent;
    2654             :     // This is only used when it is a counters() function.
    2655             :     nsString mSeparator;
    2656             :     mozilla::CounterStylePtr mCounterStyle;
    2657             : 
    2658             :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CounterFunction)
    2659             : 
    2660             :     bool operator==(const CounterFunction& aOther) const;
    2661             :     bool operator!=(const CounterFunction& aOther) const {
    2662             :       return !(*this == aOther);
    2663             :     }
    2664             :   private:
    2665             :     ~CounterFunction() {}
    2666             :   };
    2667             : 
    2668             :   CounterFunction* GetCounters() const
    2669             :   {
    2670             :     MOZ_ASSERT(mType == eStyleContentType_Counter ||
    2671             :                mType == eStyleContentType_Counters);
    2672             :     MOZ_ASSERT(mContent.mCounters->mCounterStyle.IsResolved(),
    2673             :                "Counter style should have been resolved");
    2674             :     return mContent.mCounters;
    2675             :   }
    2676             : 
    2677             :   nsStyleImageRequest* ImageRequest() const
    2678             :   {
    2679             :     MOZ_ASSERT(mType == eStyleContentType_Image);
    2680             :     MOZ_ASSERT(mContent.mImage);
    2681             :     return mContent.mImage;
    2682             :   }
    2683             : 
    2684             :   imgRequestProxy* GetImage() const
    2685             :   {
    2686             :     return ImageRequest()->get();
    2687             :   }
    2688             : 
    2689             :   void SetKeyword(nsStyleContentType aType)
    2690             :   {
    2691             :     MOZ_ASSERT(aType == eStyleContentType_OpenQuote ||
    2692             :                aType == eStyleContentType_CloseQuote ||
    2693             :                aType == eStyleContentType_NoOpenQuote ||
    2694             :                aType == eStyleContentType_NoCloseQuote ||
    2695             :                aType == eStyleContentType_AltContent);
    2696             :     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
    2697             :                "should only initialize nsStyleContentData once");
    2698             :     mType = aType;
    2699             :   }
    2700             : 
    2701             :   void SetString(nsStyleContentType aType, const char16_t* aString)
    2702             :   {
    2703             :     MOZ_ASSERT(aType == eStyleContentType_String);
    2704             :     MOZ_ASSERT(aString);
    2705             :     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
    2706             :                "should only initialize nsStyleContentData once");
    2707             :     mType = aType;
    2708             :     mContent.mString = NS_strdup(aString);
    2709             :   }
    2710             : 
    2711             :   void SetCounters(nsStyleContentType aType,
    2712             :                    already_AddRefed<CounterFunction> aCounterFunction)
    2713             :   {
    2714             :     MOZ_ASSERT(aType == eStyleContentType_Counter ||
    2715             :                aType == eStyleContentType_Counters);
    2716             :     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
    2717             :                "should only initialize nsStyleContentData once");
    2718             :     mType = aType;
    2719             :     mContent.mCounters = aCounterFunction.take();
    2720             :     MOZ_ASSERT(mContent.mCounters);
    2721             :   }
    2722             : 
    2723             :   void SetImageRequest(already_AddRefed<nsStyleImageRequest> aRequest)
    2724             :   {
    2725             :     MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
    2726             :                "should only initialize nsStyleContentData once");
    2727             :     mType = eStyleContentType_Image;
    2728             :     mContent.mImage = aRequest.take();
    2729             :     MOZ_ASSERT(mContent.mImage);
    2730             :   }
    2731             : 
    2732             :   void Resolve(nsPresContext*, const nsStyleContentData*);
    2733             : 
    2734             : private:
    2735             :   nsStyleContentType mType;
    2736             :   union {
    2737             :     char16_t *mString;
    2738             :     nsStyleContentAttr* mAttr;
    2739             :     nsStyleImageRequest* mImage;
    2740             :     CounterFunction* mCounters;
    2741             :   } mContent;
    2742             : };
    2743             : 
    2744             : struct nsStyleCounterData
    2745             : {
    2746             :   nsString  mCounter;
    2747             :   int32_t   mValue;
    2748             : 
    2749             :   bool operator==(const nsStyleCounterData& aOther) const {
    2750             :     return mValue == aOther.mValue && mCounter == aOther.mCounter;
    2751             :   }
    2752             : 
    2753             :   bool operator!=(const nsStyleCounterData& aOther) const {
    2754             :     return !(*this == aOther);
    2755             :   }
    2756             : };
    2757             : 
    2758             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent
    2759             : {
    2760             :   explicit nsStyleContent(const nsPresContext* aContext);
    2761             :   nsStyleContent(const nsStyleContent& aContent);
    2762             :   ~nsStyleContent();
    2763             :   void FinishStyle(nsPresContext*, const nsStyleContent*);
    2764             :   const static bool kHasFinishStyle = true;
    2765             : 
    2766             :   nsChangeHint CalcDifference(const nsStyleContent& aNewData) const;
    2767             : 
    2768             :   uint32_t ContentCount() const { return mContents.Length(); } // [reset]
    2769             : 
    2770             :   const nsStyleContentData& ContentAt(uint32_t aIndex) const {
    2771             :     return mContents[aIndex];
    2772             :   }
    2773             : 
    2774             :   nsStyleContentData& ContentAt(uint32_t aIndex) { return mContents[aIndex]; }
    2775             : 
    2776             :   void AllocateContents(uint32_t aCount) {
    2777             :     // We need to run the destructors of the elements of mContents, so we
    2778             :     // delete and reallocate even if aCount == mContentCount.  (If
    2779             :     // nsStyleContentData had its members private and managed their
    2780             :     // ownership on setting, we wouldn't need this, but that seems
    2781             :     // unnecessary at this point.)
    2782             :     mContents.Clear();
    2783             :     mContents.SetLength(aCount);
    2784             :   }
    2785             : 
    2786             :   uint32_t CounterIncrementCount() const { return mIncrements.Length(); }  // [reset]
    2787             :   const nsStyleCounterData& CounterIncrementAt(uint32_t aIndex) const {
    2788             :     return mIncrements[aIndex];
    2789             :   }
    2790             : 
    2791             :   void AllocateCounterIncrements(uint32_t aCount) {
    2792             :     mIncrements.Clear();
    2793             :     mIncrements.SetLength(aCount);
    2794             :   }
    2795             : 
    2796             :   void SetCounterIncrementAt(uint32_t aIndex, const nsString& aCounter, int32_t aIncrement) {
    2797             :     mIncrements[aIndex].mCounter = aCounter;
    2798             :     mIncrements[aIndex].mValue = aIncrement;
    2799             :   }
    2800             : 
    2801             :   uint32_t CounterResetCount() const { return mResets.Length(); }  // [reset]
    2802             :   const nsStyleCounterData& CounterResetAt(uint32_t aIndex) const {
    2803             :     return mResets[aIndex];
    2804             :   }
    2805             : 
    2806             :   void AllocateCounterResets(uint32_t aCount) {
    2807             :     mResets.Clear();
    2808             :     mResets.SetLength(aCount);
    2809             :   }
    2810             : 
    2811             :   void SetCounterResetAt(uint32_t aIndex, const nsString& aCounter, int32_t aValue) {
    2812             :     mResets[aIndex].mCounter = aCounter;
    2813             :     mResets[aIndex].mValue = aValue;
    2814             :   }
    2815             : 
    2816             : protected:
    2817             :   nsTArray<nsStyleContentData> mContents;
    2818             :   nsTArray<nsStyleCounterData> mIncrements;
    2819             :   nsTArray<nsStyleCounterData> mResets;
    2820             : };
    2821             : 
    2822             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset
    2823             : {
    2824             :   explicit nsStyleUIReset(const nsPresContext* aContext);
    2825             :   nsStyleUIReset(const nsStyleUIReset& aOther);
    2826             :   ~nsStyleUIReset();
    2827             :   void FinishStyle(nsPresContext*, const nsStyleUIReset*) {}
    2828             :   const static bool kHasFinishStyle = false;
    2829             : 
    2830             :   nsChangeHint CalcDifference(const nsStyleUIReset& aNewData) const;
    2831             : 
    2832             :   mozilla::StyleUserSelect     mUserSelect;     // [reset](selection-style)
    2833             :   uint8_t mForceBrokenImageIcon; // [reset] (0 if not forcing, otherwise forcing)
    2834             :   uint8_t                      mIMEMode;        // [reset]
    2835             :   mozilla::StyleWindowDragging mWindowDragging; // [reset]
    2836             :   uint8_t                      mWindowShadow;   // [reset]
    2837             :   float                        mWindowOpacity;  // [reset]
    2838             :   RefPtr<nsCSSValueSharedList> mSpecifiedWindowTransform; // [reset]
    2839             :   nsStyleCoord                 mWindowTransformOrigin[2]; // [reset] percent, coord, calc
    2840             : };
    2841             : 
    2842             : struct nsCursorImage
    2843             : {
    2844             :   bool mHaveHotspot;
    2845             :   float mHotspotX, mHotspotY;
    2846             :   RefPtr<nsStyleImageRequest> mImage;
    2847             : 
    2848             :   nsCursorImage();
    2849             :   nsCursorImage(const nsCursorImage& aOther);
    2850             : 
    2851             :   nsCursorImage& operator=(const nsCursorImage& aOther);
    2852             : 
    2853             :   bool operator==(const nsCursorImage& aOther) const;
    2854             :   bool operator!=(const nsCursorImage& aOther) const
    2855             :   {
    2856             :     return !(*this == aOther);
    2857             :   }
    2858             : 
    2859             :   imgRequestProxy* GetImage() const {
    2860             :     return mImage->get();
    2861             :   }
    2862             : };
    2863             : 
    2864             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUserInterface
    2865             : {
    2866             :   explicit nsStyleUserInterface(const nsPresContext* aContext);
    2867             :   nsStyleUserInterface(const nsStyleUserInterface& aOther);
    2868             :   ~nsStyleUserInterface();
    2869             : 
    2870             :   void FinishStyle(nsPresContext*, const nsStyleUserInterface*);
    2871             :   const static bool kHasFinishStyle = true;
    2872             : 
    2873             :   nsChangeHint CalcDifference(const nsStyleUserInterface& aNewData) const;
    2874             : 
    2875             :   mozilla::StyleUserInput   mUserInput;       // [inherited]
    2876             :   mozilla::StyleUserModify  mUserModify;      // [inherited] (modify-content)
    2877             :   mozilla::StyleUserFocus   mUserFocus;       // [inherited] (auto-select)
    2878             :   uint8_t                   mPointerEvents;   // [inherited] see nsStyleConsts.h
    2879             : 
    2880             :   uint8_t mCursor;                            // [inherited] See nsStyleConsts.h
    2881             :   nsTArray<nsCursorImage> mCursorImages;      // [inherited] images and coords
    2882             :   mozilla::StyleComplexColor mCaretColor;     // [inherited]
    2883             : 
    2884             :   mozilla::StyleComplexColor mScrollbarFaceColor;   // [inherited]
    2885             :   mozilla::StyleComplexColor mScrollbarTrackColor;  // [inherited]
    2886             : 
    2887             :   inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
    2888             : 
    2889             :   bool HasCustomScrollbars() const
    2890             :   {
    2891             :     return !mScrollbarFaceColor.IsAuto() || !mScrollbarTrackColor.IsAuto();
    2892             :   }
    2893             : };
    2894             : 
    2895             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL
    2896             : {
    2897             :   explicit nsStyleXUL(const nsPresContext* aContext);
    2898             :   nsStyleXUL(const nsStyleXUL& aSource);
    2899             :   ~nsStyleXUL();
    2900             :   void FinishStyle(nsPresContext*, const nsStyleXUL*) {}
    2901             :   const static bool kHasFinishStyle = false;
    2902             : 
    2903             :   nsChangeHint CalcDifference(const nsStyleXUL& aNewData) const;
    2904             : 
    2905             :   float         mBoxFlex;               // [reset] see nsStyleConsts.h
    2906             :   uint32_t      mBoxOrdinal;            // [reset] see nsStyleConsts.h
    2907             :   mozilla::StyleBoxAlign mBoxAlign;         // [reset]
    2908             :   mozilla::StyleBoxDirection mBoxDirection; // [reset]
    2909             :   mozilla::StyleBoxOrient mBoxOrient;       // [reset]
    2910             :   mozilla::StyleBoxPack mBoxPack;           // [reset]
    2911             :   mozilla::StyleStackSizing mStackSizing;   // [reset] see nsStyleConsts.h
    2912             : };
    2913             : 
    2914             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn
    2915             : {
    2916             :   explicit nsStyleColumn(const nsPresContext* aContext);
    2917             :   nsStyleColumn(const nsStyleColumn& aSource);
    2918             :   ~nsStyleColumn();
    2919             :   void FinishStyle(nsPresContext*, const nsStyleColumn*) {}
    2920             :   const static bool kHasFinishStyle = false;
    2921             : 
    2922             :   nsChangeHint CalcDifference(const nsStyleColumn& aNewData) const;
    2923             : 
    2924             :   /**
    2925             :    * This is the maximum number of columns we can process. It's used in both
    2926             :    * nsColumnSetFrame and nsRuleNode.
    2927             :    */
    2928             :   static const uint32_t kMaxColumnCount = 1000;
    2929             : 
    2930             :   uint32_t     mColumnCount; // [reset] see nsStyleConsts.h
    2931             :   nsStyleCoord mColumnWidth; // [reset] coord, auto
    2932             : 
    2933             :   mozilla::StyleComplexColor mColumnRuleColor; // [reset]
    2934             :   uint8_t      mColumnRuleStyle;  // [reset]
    2935             :   uint8_t      mColumnFill;  // [reset] see nsStyleConsts.h
    2936             :   uint8_t      mColumnSpan;  // [reset] see nsStyleConsts.h
    2937             : 
    2938             :   void SetColumnRuleWidth(nscoord aWidth) {
    2939             :     mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
    2940             :   }
    2941             : 
    2942             :   nscoord GetComputedColumnRuleWidth() const {
    2943             :     return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
    2944             :   }
    2945             : 
    2946             : protected:
    2947             :   nscoord mColumnRuleWidth;  // [reset] coord
    2948             :   nscoord mTwipsPerPixel;
    2949             : };
    2950             : 
    2951             : enum nsStyleSVGPaintType : uint8_t {
    2952             :   eStyleSVGPaintType_None = 1,
    2953             :   eStyleSVGPaintType_Color,
    2954             :   eStyleSVGPaintType_Server,
    2955             :   eStyleSVGPaintType_ContextFill,
    2956             :   eStyleSVGPaintType_ContextStroke
    2957             : };
    2958             : 
    2959             : enum nsStyleSVGFallbackType : uint8_t {
    2960             :   eStyleSVGFallbackType_NotSet,
    2961             :   eStyleSVGFallbackType_None,
    2962             :   eStyleSVGFallbackType_Color,
    2963             : };
    2964             : 
    2965             : enum nsStyleSVGOpacitySource : uint8_t {
    2966             :   eStyleSVGOpacitySource_Normal,
    2967             :   eStyleSVGOpacitySource_ContextFillOpacity,
    2968             :   eStyleSVGOpacitySource_ContextStrokeOpacity
    2969             : };
    2970             : 
    2971             : class nsStyleSVGPaint
    2972             : {
    2973             : public:
    2974             :   explicit nsStyleSVGPaint(nsStyleSVGPaintType aType = nsStyleSVGPaintType(0));
    2975             :   nsStyleSVGPaint(const nsStyleSVGPaint& aSource);
    2976             :   ~nsStyleSVGPaint();
    2977             : 
    2978             :   nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
    2979             : 
    2980             :   nsStyleSVGPaintType Type() const { return mType; }
    2981             : 
    2982             :   void SetNone();
    2983             :   void SetColor(nscolor aColor);
    2984             :   void SetPaintServer(mozilla::css::URLValue* aPaintServer,
    2985             :                       nsStyleSVGFallbackType aFallbackType,
    2986             :                       nscolor aFallbackColor);
    2987             :   void SetPaintServer(mozilla::css::URLValue* aPaintServer) {
    2988             :     SetPaintServer(aPaintServer, eStyleSVGFallbackType_NotSet,
    2989             :                    NS_RGB(0, 0, 0));
    2990             :   }
    2991             :   void SetContextValue(nsStyleSVGPaintType aType,
    2992             :                        nsStyleSVGFallbackType aFallbackType,
    2993             :                        nscolor aFallbackColor);
    2994             :   void SetContextValue(nsStyleSVGPaintType aType) {
    2995             :     SetContextValue(aType, eStyleSVGFallbackType_NotSet, NS_RGB(0, 0, 0));
    2996             :   }
    2997             : 
    2998             :   nscolor GetColor() const {
    2999             :     MOZ_ASSERT(mType == eStyleSVGPaintType_Color);
    3000             :     return mPaint.mColor;
    3001             :   }
    3002             : 
    3003             :   mozilla::css::URLValue* GetPaintServer() const {
    3004             :     MOZ_ASSERT(mType == eStyleSVGPaintType_Server);
    3005             :     return mPaint.mPaintServer;
    3006             :   }
    3007             : 
    3008             :   nsStyleSVGFallbackType GetFallbackType() const {
    3009             :     return mFallbackType;
    3010             :   }
    3011             : 
    3012             :   nscolor GetFallbackColor() const {
    3013             :     MOZ_ASSERT(mType == eStyleSVGPaintType_Server ||
    3014             :                mType == eStyleSVGPaintType_ContextFill ||
    3015             :                mType == eStyleSVGPaintType_ContextStroke);
    3016             :     return mFallbackColor;
    3017             :   }
    3018             : 
    3019             :   bool operator==(const nsStyleSVGPaint& aOther) const;
    3020             :   bool operator!=(const nsStyleSVGPaint& aOther) const {
    3021             :     return !(*this == aOther);
    3022             :   }
    3023             : 
    3024             : private:
    3025             :   void Reset();
    3026             :   void Assign(const nsStyleSVGPaint& aOther);
    3027             : 
    3028             :   union {
    3029             :     nscolor mColor;
    3030             :     mozilla::css::URLValue* mPaintServer;
    3031             :   } mPaint;
    3032             :   nsStyleSVGPaintType mType;
    3033             :   nsStyleSVGFallbackType mFallbackType;
    3034             :   nscolor mFallbackColor;
    3035             : };
    3036             : 
    3037             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG
    3038             : {
    3039             :   explicit nsStyleSVG(const nsPresContext* aContext);
    3040             :   nsStyleSVG(const nsStyleSVG& aSource);
    3041             :   ~nsStyleSVG();
    3042             :   void FinishStyle(nsPresContext*, const nsStyleSVG*) {}
    3043             :   const static bool kHasFinishStyle = false;
    3044             : 
    3045             :   nsChangeHint CalcDifference(const nsStyleSVG& aNewData) const;
    3046             : 
    3047             :   nsStyleSVGPaint  mFill;             // [inherited]
    3048             :   nsStyleSVGPaint  mStroke;           // [inherited]
    3049             :   RefPtr<mozilla::css::URLValue> mMarkerEnd;   // [inherited]
    3050             :   RefPtr<mozilla::css::URLValue> mMarkerMid;   // [inherited]
    3051             :   RefPtr<mozilla::css::URLValue> mMarkerStart; // [inherited]
    3052             :   nsTArray<nsStyleCoord> mStrokeDasharray;  // [inherited] coord, percent, factor
    3053             :   nsTArray<RefPtr<nsAtom>> mContextProps;
    3054             : 
    3055             :   nsStyleCoord     mStrokeDashoffset; // [inherited] coord, percent, factor
    3056             :   nsStyleCoord     mStrokeWidth;      // [inherited] coord, percent, factor
    3057             : 
    3058             :   float            mFillOpacity;      // [inherited]
    3059             :   float            mStrokeMiterlimit; // [inherited]
    3060             :   float            mStrokeOpacity;    // [inherited]
    3061             : 
    3062             :   mozilla::StyleFillRule    mClipRule;  // [inherited]
    3063             :   uint8_t          mColorInterpolation; // [inherited] see nsStyleConsts.h
    3064             :   uint8_t          mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
    3065             :   mozilla::StyleFillRule    mFillRule;         // [inherited] see nsStyleConsts.h
    3066             :   uint8_t          mPaintOrder;       // [inherited] see nsStyleConsts.h
    3067             :   uint8_t          mShapeRendering;   // [inherited] see nsStyleConsts.h
    3068             :   uint8_t          mStrokeLinecap;    // [inherited] see nsStyleConsts.h
    3069             :   uint8_t          mStrokeLinejoin;   // [inherited] see nsStyleConsts.h
    3070             :   uint8_t          mTextAnchor;       // [inherited] see nsStyleConsts.h
    3071             :   uint8_t          mContextPropsBits; // [inherited] see nsStyleConsts.h.
    3072             :                                       // Stores a bitfield representation of
    3073             :                                       // the specified properties.
    3074             : 
    3075             :   /// Returns true if style has been set to expose the computed values of
    3076             :   /// certain properties (such as 'fill') to the contents of any linked images.
    3077             :   bool ExposesContextProperties() const {
    3078             :     return bool(mContextPropsBits);
    3079             :   }
    3080             : 
    3081             :   nsStyleSVGOpacitySource FillOpacitySource() const {
    3082             :     uint8_t value = (mContextFlags & FILL_OPACITY_SOURCE_MASK) >>
    3083             :                     FILL_OPACITY_SOURCE_SHIFT;
    3084             :     return nsStyleSVGOpacitySource(value);
    3085             :   }
    3086             :   nsStyleSVGOpacitySource StrokeOpacitySource() const {
    3087             :     uint8_t value = (mContextFlags & STROKE_OPACITY_SOURCE_MASK) >>
    3088             :                     STROKE_OPACITY_SOURCE_SHIFT;
    3089             :     return nsStyleSVGOpacitySource(value);
    3090             :   }
    3091             :   bool StrokeDasharrayFromObject() const {
    3092             :     return mContextFlags & STROKE_DASHARRAY_CONTEXT;
    3093             :   }
    3094             :   bool StrokeDashoffsetFromObject() const {
    3095             :     return mContextFlags & STROKE_DASHOFFSET_CONTEXT;
    3096             :   }
    3097             :   bool StrokeWidthFromObject() const {
    3098             :     return mContextFlags & STROKE_WIDTH_CONTEXT;
    3099             :   }
    3100             : 
    3101             :   void SetFillOpacitySource(nsStyleSVGOpacitySource aValue) {
    3102             :     mContextFlags = (mContextFlags & ~FILL_OPACITY_SOURCE_MASK) |
    3103             :                     (aValue << FILL_OPACITY_SOURCE_SHIFT);
    3104             :   }
    3105             :   void SetStrokeOpacitySource(nsStyleSVGOpacitySource aValue) {
    3106             :     mContextFlags = (mContextFlags & ~STROKE_OPACITY_SOURCE_MASK) |
    3107             :                     (aValue << STROKE_OPACITY_SOURCE_SHIFT);
    3108             :   }
    3109             :   void SetStrokeDasharrayFromObject(bool aValue) {
    3110             :     mContextFlags = (mContextFlags & ~STROKE_DASHARRAY_CONTEXT) |
    3111             :                     (aValue ? STROKE_DASHARRAY_CONTEXT : 0);
    3112             :   }
    3113             :   void SetStrokeDashoffsetFromObject(bool aValue) {
    3114             :     mContextFlags = (mContextFlags & ~STROKE_DASHOFFSET_CONTEXT) |
    3115             :                     (aValue ? STROKE_DASHOFFSET_CONTEXT : 0);
    3116             :   }
    3117             :   void SetStrokeWidthFromObject(bool aValue) {
    3118             :     mContextFlags = (mContextFlags & ~STROKE_WIDTH_CONTEXT) |
    3119             :                     (aValue ? STROKE_WIDTH_CONTEXT : 0);
    3120             :   }
    3121             : 
    3122             :   bool HasMarker() const {
    3123             :     return mMarkerStart || mMarkerMid || mMarkerEnd;
    3124             :   }
    3125             : 
    3126             :   /**
    3127             :    * Returns true if the stroke is not "none" and the stroke-opacity is greater
    3128             :    * than zero. This ignores stroke-widths as that depends on the context.
    3129             :    */
    3130             :   bool HasStroke() const {
    3131             :     return mStroke.Type() != eStyleSVGPaintType_None && mStrokeOpacity > 0;
    3132             :   }
    3133             : 
    3134             :   /**
    3135             :    * Returns true if the fill is not "none" and the fill-opacity is greater
    3136             :    * than zero.
    3137             :    */
    3138             :   bool HasFill() const {
    3139             :     return mFill.Type() != eStyleSVGPaintType_None && mFillOpacity > 0;
    3140             :   }
    3141             : 
    3142             : private:
    3143             :   // Flags to represent the use of context-fill and context-stroke
    3144             :   // for fill-opacity or stroke-opacity, and context-value for stroke-dasharray,
    3145             :   // stroke-dashoffset and stroke-width.
    3146             : 
    3147             :   // fill-opacity: context-{fill,stroke}
    3148             :   static const uint8_t FILL_OPACITY_SOURCE_MASK   = 0x03;
    3149             :   // stroke-opacity: context-{fill,stroke}
    3150             :   static const uint8_t STROKE_OPACITY_SOURCE_MASK = 0x0C;
    3151             :   // stroke-dasharray: context-value
    3152             :   static const uint8_t STROKE_DASHARRAY_CONTEXT   = 0x10;
    3153             :   // stroke-dashoffset: context-value
    3154             :   static const uint8_t STROKE_DASHOFFSET_CONTEXT  = 0x20;
    3155             :   // stroke-width: context-value
    3156             :   static const uint8_t STROKE_WIDTH_CONTEXT       = 0x40;
    3157             :   static const uint8_t FILL_OPACITY_SOURCE_SHIFT   = 0;
    3158             :   static const uint8_t STROKE_OPACITY_SOURCE_SHIFT = 2;
    3159             : 
    3160             :   uint8_t          mContextFlags;     // [inherited]
    3161             : };
    3162             : 
    3163             : struct nsStyleFilter
    3164             : {
    3165             :   nsStyleFilter();
    3166             :   nsStyleFilter(const nsStyleFilter& aSource);
    3167             :   ~nsStyleFilter();
    3168             :   void FinishStyle(nsPresContext*, const nsStyleFilter*) {}
    3169             :   const static bool kHasFinishStyle = false;
    3170             : 
    3171             :   nsStyleFilter& operator=(const nsStyleFilter& aOther);
    3172             : 
    3173             :   bool operator==(const nsStyleFilter& aOther) const;
    3174             :   bool operator!=(const nsStyleFilter& aOther) const {
    3175             :     return !(*this == aOther);
    3176             :   }
    3177             : 
    3178             :   uint32_t GetType() const {
    3179             :     return mType;
    3180             :   }
    3181             : 
    3182             :   const nsStyleCoord& GetFilterParameter() const {
    3183             :     NS_ASSERTION(mType != NS_STYLE_FILTER_DROP_SHADOW &&
    3184             :                  mType != NS_STYLE_FILTER_URL &&
    3185             :                  mType != NS_STYLE_FILTER_NONE, "wrong filter type");
    3186             :     return mFilterParameter;
    3187             :   }
    3188             :   void SetFilterParameter(const nsStyleCoord& aFilterParameter,
    3189             :                           int32_t aType);
    3190             : 
    3191             :   mozilla::css::URLValue* GetURL() const {
    3192             :     MOZ_ASSERT(mType == NS_STYLE_FILTER_URL, "wrong filter type");
    3193             :     return mURL;
    3194             :   }
    3195             : 
    3196             :   bool SetURL(mozilla::css::URLValue* aValue);
    3197             : 
    3198             :   nsCSSShadowArray* GetDropShadow() const {
    3199             :     NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type");
    3200             :     return mDropShadow;
    3201             :   }
    3202             :   void SetDropShadow(nsCSSShadowArray* aDropShadow);
    3203             : 
    3204             : private:
    3205             :   void ReleaseRef();
    3206             : 
    3207             :   uint32_t mType; // see NS_STYLE_FILTER_* constants in nsStyleConsts.h
    3208             :   nsStyleCoord mFilterParameter; // coord, percent, factor, angle
    3209             :   union {
    3210             :     mozilla::css::URLValue* mURL;
    3211             :     nsCSSShadowArray* mDropShadow;
    3212             :   };
    3213             : };
    3214             : 
    3215             : template<>
    3216             : struct nsTArray_CopyChooser<nsStyleFilter>
    3217             : {
    3218             :   typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
    3219             : };
    3220             : 
    3221             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset
    3222             : {
    3223             :   explicit nsStyleSVGReset(const nsPresContext* aContext);
    3224             :   nsStyleSVGReset(const nsStyleSVGReset& aSource);
    3225             :   ~nsStyleSVGReset();
    3226             : 
    3227             :   // Resolves and tracks the images in mMask.  Only called with a Servo-backed
    3228             :   // style system, where those images must be resolved later than the OMT
    3229             :   // nsStyleSVGReset constructor call.
    3230             :   void FinishStyle(nsPresContext*, const nsStyleSVGReset*);
    3231             :   const static bool kHasFinishStyle = true;
    3232             : 
    3233             :   nsChangeHint CalcDifference(const nsStyleSVGReset& aNewData) const;
    3234             : 
    3235             :   bool HasClipPath() const {
    3236             :     return mClipPath.GetType() != mozilla::StyleShapeSourceType::None;
    3237             :   }
    3238             : 
    3239             :   bool HasMask() const;
    3240             : 
    3241             :   bool HasNonScalingStroke() const {
    3242             :     return mVectorEffect == NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE;
    3243             :   }
    3244             : 
    3245             :   nsStyleImageLayers    mMask;
    3246             :   mozilla::StyleShapeSource mClipPath;// [reset]
    3247             :   mozilla::StyleComplexColor mStopColor;     // [reset]
    3248             :   mozilla::StyleComplexColor mFloodColor;    // [reset]
    3249             :   mozilla::StyleComplexColor mLightingColor; // [reset]
    3250             : 
    3251             :   float            mStopOpacity;      // [reset]
    3252             :   float            mFloodOpacity;     // [reset]
    3253             : 
    3254             :   uint8_t          mDominantBaseline; // [reset] see nsStyleConsts.h
    3255             :   uint8_t          mVectorEffect;     // [reset] see nsStyleConsts.h
    3256             :   uint8_t          mMaskType;         // [reset] see nsStyleConsts.h
    3257             : };
    3258             : 
    3259             : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects
    3260             : {
    3261             :   explicit nsStyleEffects(const nsPresContext* aContext);
    3262             :   nsStyleEffects(const nsStyleEffects& aSource);
    3263             :   ~nsStyleEffects();
    3264             :   void FinishStyle(nsPresContext*, const nsStyleEffects*) {}
    3265             :   const static bool kHasFinishStyle = false;
    3266             : 
    3267             :   nsChangeHint CalcDifference(const nsStyleEffects& aNewData) const;
    3268             : 
    3269             :   bool HasFilters() const {
    3270             :     return !mFilters.IsEmpty();
    3271             :   }
    3272             : 
    3273             :   nsTArray<nsStyleFilter>  mFilters;   // [reset]
    3274             :   RefPtr<nsCSSShadowArray> mBoxShadow; // [reset] nullptr for 'none'
    3275             :   nsRect  mClip;                       // [reset] offsets from UL border edge
    3276             :   float   mOpacity;                    // [reset]
    3277             :   uint8_t mClipFlags;                  // [reset] see nsStyleConsts.h
    3278             :   uint8_t mMixBlendMode;               // [reset] see nsStyleConsts.h
    3279             : };
    3280             : 
    3281             : #define STATIC_ASSERT_TYPE_LAYOUTS_MATCH(T1, T2)                               \
    3282             :   static_assert(sizeof(T1) == sizeof(T2),                                      \
    3283             :       "Size mismatch between " #T1 " and " #T2);                               \
    3284             :   static_assert(alignof(T1) == alignof(T2),                                    \
    3285             :       "Align mismatch between " #T1 " and " #T2);                              \
    3286             : 
    3287             : #define STATIC_ASSERT_FIELD_OFFSET_MATCHES(T1, T2, field)                      \
    3288             :   static_assert(offsetof(T1, field) == offsetof(T2, field),                    \
    3289             :       "Field offset mismatch of " #field " between " #T1 " and " #T2);         \
    3290             : 
    3291             : /**
    3292             :  * These *_Simple types are used to map Gecko types to layout-equivalent but
    3293             :  * simpler Rust types, to aid Rust binding generation.
    3294             :  *
    3295             :  * If something in this types or the assertions below needs to change, ask
    3296             :  * bholley, heycam or emilio before!
    3297             :  *
    3298             :  * <div rustbindgen="true" replaces="nsPoint">
    3299             :  */
    3300             : struct nsPoint_Simple {
    3301             :   nscoord x, y;
    3302             : };
    3303             : 
    3304             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple);
    3305             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x);
    3306             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y);
    3307             : 
    3308             : /**
    3309             :  * <div rustbindgen="true" replaces="nsMargin">
    3310             :  */
    3311             : struct nsMargin_Simple {
    3312             :   nscoord top, right, bottom, left;
    3313             : };
    3314             : 
    3315             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple);
    3316             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top);
    3317             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right);
    3318             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom);
    3319             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left);
    3320             : 
    3321             : /**
    3322             :  * <div rustbindgen="true" replaces="nsRect">
    3323             :  */
    3324             : struct nsRect_Simple {
    3325             :   nscoord x, y, width, height;
    3326             : };
    3327             : 
    3328             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple);
    3329             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x);
    3330             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y);
    3331             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width);
    3332             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height);
    3333             : 
    3334             : /**
    3335             :  * <div rustbindgen="true" replaces="nsSize">
    3336             :  */
    3337             : struct nsSize_Simple {
    3338             :   nscoord width, height;
    3339             : };
    3340             : 
    3341             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple);
    3342             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width);
    3343             : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height);
    3344             : 
    3345             : /**
    3346             :  * <div rustbindgen="true" replaces="mozilla::UniquePtr">
    3347             :  *
    3348             :  * TODO(Emilio): This is a workaround and we should be able to get rid of this
    3349             :  * one.
    3350             :  */
    3351             : template<typename T>
    3352             : struct UniquePtr_Simple {
    3353             :   T* mPtr;
    3354             : };
    3355             : 
    3356             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(mozilla::UniquePtr<int>, UniquePtr_Simple<int>);
    3357             : 
    3358             : /**
    3359             :  * <div rustbindgen replaces="nsTArray"></div>
    3360             :  */
    3361             : template<typename T>
    3362             : class nsTArray_Simple {
    3363             :   T* mBuffer;
    3364             : public:
    3365             :   // The existence of a destructor here prevents bindgen from deriving the Clone
    3366             :   // trait via a simple memory copy.
    3367             :   ~nsTArray_Simple() {};
    3368             : };
    3369             : 
    3370             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<nsStyleImageLayers::Layer>,
    3371             :                                  nsTArray_Simple<nsStyleImageLayers::Layer>);
    3372             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleTransition>,
    3373             :                                  nsTArray_Simple<mozilla::StyleTransition>);
    3374             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleAnimation>,
    3375             :                                  nsTArray_Simple<mozilla::StyleAnimation>);
    3376             : 
    3377             : /**
    3378             :  * <div rustbindgen replaces="nsCOMArray"></div>
    3379             :  *
    3380             :  * mozilla::ArrayIterator doesn't work well with bindgen.
    3381             :  */
    3382             : template<typename T>
    3383             : class nsCOMArray_Simple {
    3384             :   nsTArray<nsISupports*> mBuffer;
    3385             : };
    3386             : 
    3387             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsCOMArray<nsIContent>,
    3388             :                                  nsCOMArray_Simple<nsIContent>);
    3389             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsCOMArray<nsINode>,
    3390             :                                  nsCOMArray_Simple<nsINode>);
    3391             : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsCOMArray<imgIContainer>,
    3392             :                                  nsCOMArray_Simple<imgIContainer>);
    3393             : 
    3394             : #endif /* nsStyleStruct_h___ */

Generated by: LCOV version 1.13-14-ga5dd952