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

Generated by: LCOV version 1.13