LCOV - code coverage report
Current view: directory - objdir/dist/include - nsStyleStruct.h (source / functions) Found Hit Coverage
Test: app.info Lines: 29 0 0.0 %
Date: 2012-06-02 Functions: 11 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Mats Palmgren <matspal@gmail.com>
      24                 :  *   Masayuki Nakano <masayuki@d-toybox.com>
      25                 :  *   Rob Arnold <robarnold@mozilla.com>
      26                 :  *   Jonathon Jongsma <jonathon.jongsma@collabora.co.uk>, Collabora Ltd.
      27                 :  *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
      28                 :  *
      29                 :  * Alternatively, the contents of this file may be used under the terms of
      30                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      31                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      32                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      33                 :  * of those above. If you wish to allow use of your version of this file only
      34                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      35                 :  * use your version of this file under the terms of the MPL, indicate your
      36                 :  * decision by deleting the provisions above and replace them with the notice
      37                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      38                 :  * the provisions above, a recipient may use your version of this file under
      39                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      40                 :  *
      41                 :  * ***** END LICENSE BLOCK ***** */
      42                 : 
      43                 : /*
      44                 :  * structs that contain the data provided by nsStyleContext, the
      45                 :  * internal API for computed style data for an element
      46                 :  */
      47                 : 
      48                 : #ifndef nsStyleStruct_h___
      49                 : #define nsStyleStruct_h___
      50                 : 
      51                 : #include "mozilla/Attributes.h"
      52                 : 
      53                 : #include "nsColor.h"
      54                 : #include "nsCoord.h"
      55                 : #include "nsMargin.h"
      56                 : #include "nsRect.h"
      57                 : #include "nsFont.h"
      58                 : #include "nsStyleCoord.h"
      59                 : #include "nsStyleConsts.h"
      60                 : #include "nsChangeHint.h"
      61                 : #include "nsPresContext.h"
      62                 : #include "nsCOMPtr.h"
      63                 : #include "nsCOMArray.h"
      64                 : #include "nsTArray.h"
      65                 : #include "nsIAtom.h"
      66                 : #include "nsIURI.h"
      67                 : #include "nsCSSValue.h"
      68                 : #include "nsStyleTransformMatrix.h"
      69                 : #include "nsAlgorithm.h"
      70                 : #include "imgIRequest.h"
      71                 : #include "gfxRect.h"
      72                 : 
      73                 : class nsIFrame;
      74                 : class imgIRequest;
      75                 : class imgIContainer;
      76                 : struct nsCSSValueList;
      77                 : 
      78                 : // Includes nsStyleStructID.
      79                 : #include "nsStyleStructFwd.h"
      80                 : 
      81                 : // Bits for each struct.
      82                 : // NS_STYLE_INHERIT_BIT defined in nsStyleStructFwd.h
      83                 : #define NS_STYLE_INHERIT_MASK             0x007fffff
      84                 : 
      85                 : // Additional bits for nsStyleContext's mBits:
      86                 : // See nsStyleContext::HasTextDecorationLines
      87                 : #define NS_STYLE_HAS_TEXT_DECORATION_LINES 0x00800000
      88                 : // See nsStyleContext::HasPseudoElementData.
      89                 : #define NS_STYLE_HAS_PSEUDO_ELEMENT_DATA  0x01000000
      90                 : // See nsStyleContext::RelevantLinkIsVisited
      91                 : #define NS_STYLE_RELEVANT_LINK_VISITED    0x02000000
      92                 : // See nsStyleContext::IsStyleIfVisited
      93                 : #define NS_STYLE_IS_STYLE_IF_VISITED      0x04000000
      94                 : // See nsStyleContext::GetPseudoEnum
      95                 : #define NS_STYLE_CONTEXT_TYPE_MASK        0xf8000000
      96                 : #define NS_STYLE_CONTEXT_TYPE_SHIFT       27
      97                 : 
      98                 : // Additional bits for nsRuleNode's mDependentBits:
      99                 : #define NS_RULE_NODE_GC_MARK              0x02000000
     100                 : #define NS_RULE_NODE_IS_IMPORTANT         0x08000000
     101                 : #define NS_RULE_NODE_LEVEL_MASK           0xf0000000
     102                 : #define NS_RULE_NODE_LEVEL_SHIFT          28
     103                 : 
     104                 : // The lifetime of these objects is managed by the presshell's arena.
     105                 : 
     106                 : // Each struct must implement a static ForceCompare() function returning a
     107                 : // boolean.  Structs that can return a hint that doesn't guarantee that the
     108                 : // change will be applied to all descendants must return true from
     109                 : // ForceCompare(), so that we will make sure to compare those structs in
     110                 : // nsStyleContext::CalcStyleDifference.
     111                 : 
     112                 : struct nsStyleFont {
     113                 :   nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext);
     114                 :   nsStyleFont(const nsStyleFont& aStyleFont);
     115                 :   nsStyleFont(nsPresContext *aPresContext);
     116                 : private:
     117                 :   void Init(nsPresContext *aPresContext);
     118                 : public:
     119                 :   ~nsStyleFont(void) {
     120                 :     MOZ_COUNT_DTOR(nsStyleFont);
     121                 :   }
     122                 : 
     123                 :   nsChangeHint CalcDifference(const nsStyleFont& aOther) const;
     124                 : #ifdef DEBUG
     125                 :   static nsChangeHint MaxDifference();
     126                 : #endif
     127                 :   static bool ForceCompare() { return false; }
     128                 :   static nsChangeHint CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2);
     129                 : 
     130                 :   static nscoord ZoomText(nsPresContext* aPresContext, nscoord aSize);
     131                 :   static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
     132                 : 
     133                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
     134                 :   void Destroy(nsPresContext* aContext);
     135                 : 
     136                 :   nsFont  mFont;        // [inherited]
     137                 :   nscoord mSize;        // [inherited] Our "computed size". Can be different
     138                 :                         // from mFont.size which is our "actual size" and is
     139                 :                         // enforced to be >= the user's preferred min-size.
     140                 :                         // mFont.size should be used for display purposes
     141                 :                         // while mSize is the value to return in
     142                 :                         // getComputedStyle() for example.
     143                 :   PRUint8 mGenericID;   // [inherited] generic CSS font family, if any;
     144                 :                         // value is a kGenericFont_* constant, see nsFont.h.
     145                 : 
     146                 :   // MathML scriptlevel support
     147                 :   PRInt8  mScriptLevel;          // [inherited]
     148                 :   // The value mSize would have had if scriptminsize had never been applied
     149                 :   nscoord mScriptUnconstrainedSize;
     150                 :   nscoord mScriptMinSize;        // [inherited] length
     151                 :   float   mScriptSizeMultiplier; // [inherited]
     152                 :   nsCOMPtr<nsIAtom> mLanguage;   // [inherited]
     153                 : };
     154                 : 
     155                 : struct nsStyleGradientStop {
     156                 :   nsStyleCoord mLocation; // percent, coord, none
     157                 :   nscolor mColor;
     158                 : };
     159                 : 
     160                 : class nsStyleGradient {
     161                 : public:
     162                 :   nsStyleGradient();
     163                 :   PRUint8 mShape;  // NS_STYLE_GRADIENT_SHAPE_*
     164                 :   PRUint8 mSize;   // NS_STYLE_GRADIENT_SIZE_*;
     165                 :                    // not used (must be FARTHEST_CORNER) for linear shape
     166                 :   bool mRepeating;
     167                 :   bool mToCorner;
     168                 : 
     169                 :   nsStyleCoord mBgPosX; // percent, coord, calc, none
     170                 :   nsStyleCoord mBgPosY; // percent, coord, calc, none
     171                 :   nsStyleCoord mAngle;  // none, angle
     172                 : 
     173                 :   // stops are in the order specified in the stylesheet
     174                 :   nsTArray<nsStyleGradientStop> mStops;
     175                 : 
     176                 :   bool operator==(const nsStyleGradient& aOther) const;
     177                 :   bool operator!=(const nsStyleGradient& aOther) const {
     178                 :     return !(*this == aOther);
     179                 :   };
     180                 : 
     181                 :   bool IsOpaque();
     182                 : 
     183                 :   NS_INLINE_DECL_REFCOUNTING(nsStyleGradient)
     184                 : 
     185                 : private:
     186                 :   ~nsStyleGradient() {}
     187                 : 
     188                 :   nsStyleGradient(const nsStyleGradient& aOther) MOZ_DELETE;
     189                 :   nsStyleGradient& operator=(const nsStyleGradient& aOther) MOZ_DELETE;
     190                 : };
     191                 : 
     192                 : enum nsStyleImageType {
     193                 :   eStyleImageType_Null,
     194                 :   eStyleImageType_Image,
     195                 :   eStyleImageType_Gradient,
     196                 :   eStyleImageType_Element
     197                 : };
     198                 : 
     199                 : /**
     200                 :  * Represents a paintable image of one of the following types.
     201                 :  * (1) A real image loaded from an external source.
     202                 :  * (2) A CSS linear or radial gradient.
     203                 :  * (3) An element within a document, or an <img>, <video>, or <canvas> element
     204                 :  *     not in a document.
     205                 :  * (*) Optionally a crop rect can be set to paint a partial (rectangular)
     206                 :  * region of an image. (Currently, this feature is only supported with an
     207                 :  * image of type (1)).
     208                 :  *
     209                 :  * This struct is currently used only for 'background-image', but it may be
     210                 :  * used by other CSS properties such as 'border-image', 'list-style-image', and
     211                 :  * 'content' in the future (bug 507052).
     212                 :  */
     213                 : struct nsStyleImage {
     214                 :   nsStyleImage();
     215                 :   ~nsStyleImage();
     216                 :   nsStyleImage(const nsStyleImage& aOther);
     217                 :   nsStyleImage& operator=(const nsStyleImage& aOther);
     218                 : 
     219                 :   void SetNull();
     220                 :   void SetImageData(imgIRequest* aImage);
     221                 :   void TrackImage(nsPresContext* aContext);
     222                 :   void UntrackImage(nsPresContext* aContext);
     223                 :   void SetGradientData(nsStyleGradient* aGradient);
     224                 :   void SetElementId(const PRUnichar* aElementId);
     225                 :   void SetCropRect(nsStyleSides* aCropRect);
     226                 : 
     227                 :   nsStyleImageType GetType() const {
     228                 :     return mType;
     229                 :   }
     230                 :   imgIRequest* GetImageData() const {
     231                 :     NS_ABORT_IF_FALSE(mType == eStyleImageType_Image, "Data is not an image!");
     232                 :     NS_ABORT_IF_FALSE(mImageTracked,
     233                 :                       "Should be tracking any image we're going to use!");
     234                 :     return mImage;
     235                 :   }
     236                 :   nsStyleGradient* GetGradientData() const {
     237                 :     NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
     238                 :     return mGradient;
     239                 :   }
     240                 :   const PRUnichar* GetElementId() const {
     241                 :     NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
     242                 :     return mElementId;
     243                 :   }
     244                 :   nsStyleSides* GetCropRect() const {
     245                 :     NS_ASSERTION(mType == eStyleImageType_Image,
     246                 :                  "Only image data can have a crop rect");
     247                 :     return mCropRect;
     248                 :   }
     249                 : 
     250                 :   /**
     251                 :    * Compute the actual crop rect in pixels, using the source image bounds.
     252                 :    * The computation involves converting percentage unit to pixel unit and
     253                 :    * clamping each side value to fit in the source image bounds.
     254                 :    * @param aActualCropRect the computed actual crop rect.
     255                 :    * @param aIsEntireImage true iff |aActualCropRect| is identical to the
     256                 :    * source image bounds.
     257                 :    * @return true iff |aActualCropRect| holds a meaningful value.
     258                 :    */
     259                 :   bool ComputeActualCropRect(nsIntRect& aActualCropRect,
     260                 :                                bool* aIsEntireImage = nsnull) const;
     261                 : 
     262                 :   /**
     263                 :    * Requests a decode on the image.
     264                 :    */
     265                 :   nsresult RequestDecode() const;
     266                 :   /**
     267                 :    * @return true if the item is definitely opaque --- i.e., paints every
     268                 :    * pixel within its bounds opaquely, and the bounds contains at least a pixel.
     269                 :    */
     270                 :   bool IsOpaque() const;
     271                 :   /**
     272                 :    * @return true if this image is fully loaded, and its size is calculated;
     273                 :    * always returns true if |mType| is |eStyleImageType_Gradient| or
     274                 :    * |eStyleImageType_Element|.
     275                 :    */
     276                 :   bool IsComplete() const;
     277                 :   /**
     278                 :    * @return true if it is 100% confident that this image contains no pixel
     279                 :    * to draw.
     280                 :    */
     281                 :   bool IsEmpty() const {
     282                 :     // There are some other cases when the image will be empty, for example
     283                 :     // when the crop rect is empty. However, checking the emptiness of crop
     284                 :     // rect is non-trivial since each side value can be specified with
     285                 :     // percentage unit, which can not be evaluated until the source image size
     286                 :     // is available. Therefore, we currently postpone the evaluation of crop
     287                 :     // rect until the actual rendering time --- alternatively until GetOpaqueRegion()
     288                 :     // is called.
     289                 :     return mType == eStyleImageType_Null;
     290                 :   }
     291                 : 
     292                 :   bool operator==(const nsStyleImage& aOther) const;
     293                 :   bool operator!=(const nsStyleImage& aOther) const {
     294                 :     return !(*this == aOther);
     295                 :   }
     296                 : 
     297                 : private:
     298                 :   void DoCopy(const nsStyleImage& aOther);
     299                 : 
     300                 :   nsStyleImageType mType;
     301                 :   union {
     302                 :     imgIRequest* mImage;
     303                 :     nsStyleGradient* mGradient;
     304                 :     PRUnichar* mElementId;
     305                 :   };
     306                 :   // This is _currently_ used only in conjunction with eStyleImageType_Image.
     307                 :   nsAutoPtr<nsStyleSides> mCropRect;
     308                 : #ifdef DEBUG
     309                 :   bool mImageTracked;
     310                 : #endif
     311                 : };
     312                 : 
     313                 : struct nsStyleColor {
     314                 :   nsStyleColor(nsPresContext* aPresContext);
     315                 :   nsStyleColor(const nsStyleColor& aOther);
     316                 :   ~nsStyleColor(void) {
     317                 :     MOZ_COUNT_DTOR(nsStyleColor);
     318                 :   }
     319                 : 
     320                 :   nsChangeHint CalcDifference(const nsStyleColor& aOther) const;
     321                 : #ifdef DEBUG
     322                 :   static nsChangeHint MaxDifference();
     323                 : #endif
     324                 :   static bool ForceCompare() { return false; }
     325                 : 
     326                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     327                 :     return aContext->AllocateFromShell(sz);
     328                 :   }
     329                 :   void Destroy(nsPresContext* aContext) {
     330                 :     this->~nsStyleColor();
     331                 :     aContext->FreeToShell(sizeof(nsStyleColor), this);
     332                 :   }
     333                 : 
     334                 :   // Don't add ANY members to this struct!  We can achieve caching in the rule
     335                 :   // tree (rather than the style tree) by letting color stay by itself! -dwh
     336                 :   nscolor mColor;                 // [inherited]
     337                 : };
     338                 : 
     339                 : struct nsStyleBackground {
     340                 :   nsStyleBackground();
     341                 :   nsStyleBackground(const nsStyleBackground& aOther);
     342                 :   ~nsStyleBackground();
     343                 : 
     344                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     345                 :     return aContext->AllocateFromShell(sz);
     346                 :   }
     347                 :   void Destroy(nsPresContext* aContext);
     348                 : 
     349                 :   nsChangeHint CalcDifference(const nsStyleBackground& aOther) const;
     350                 : #ifdef DEBUG
     351                 :   static nsChangeHint MaxDifference();
     352                 : #endif
     353                 :   static bool ForceCompare() { return false; }
     354                 : 
     355                 :   struct Position;
     356                 :   friend struct Position;
     357                 :   struct Position {
     358                 :     typedef nsStyleCoord::Calc PositionCoord;
     359                 :     PositionCoord mXPosition, mYPosition;
     360                 : 
     361                 :     // Initialize nothing
     362                 :     Position() {}
     363                 : 
     364                 :     // Initialize to initial values
     365                 :     void SetInitialValues();
     366                 : 
     367                 :     // True if the effective background image position described by this depends
     368                 :     // on the size of the corresponding frame.
     369                 :     bool DependsOnFrameSize() const {
     370                 :       return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
     371                 :     }
     372                 : 
     373                 :     bool operator==(const Position& aOther) const {
     374                 :       return mXPosition == aOther.mXPosition &&
     375                 :              mYPosition == aOther.mYPosition;
     376                 :     }
     377                 :     bool operator!=(const Position& aOther) const {
     378                 :       return !(*this == aOther);
     379                 :     }
     380                 :   };
     381                 : 
     382                 :   struct Size;
     383                 :   friend struct Size;
     384                 :   struct Size {
     385                 :     struct Dimension : public nsStyleCoord::Calc {
     386                 :       nscoord ResolveLengthPercentage(nscoord aAvailable) const {
     387                 :         double d = double(mPercent) * double(aAvailable) + double(mLength);
     388                 :         if (d < 0.0)
     389                 :           return 0;
     390                 :         return NSToCoordRoundWithClamp(float(d));
     391                 :       }
     392                 :     };
     393                 :     Dimension mWidth, mHeight;
     394                 : 
     395                 :     nscoord ResolveWidthLengthPercentage(const nsSize& aBgPositioningArea) const {
     396                 :       NS_ABORT_IF_FALSE(mWidthType == eLengthPercentage,
     397                 :                         "resolving non-length/percent dimension!");
     398                 :       return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
     399                 :     }
     400                 : 
     401                 :     nscoord ResolveHeightLengthPercentage(const nsSize& aBgPositioningArea) const {
     402                 :       NS_ABORT_IF_FALSE(mHeightType == eLengthPercentage,
     403                 :                         "resolving non-length/percent dimension!");
     404                 :       return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
     405                 :     }
     406                 : 
     407                 :     // Except for eLengthPercentage, Dimension types which might change
     408                 :     // how a layer is painted when the corresponding frame's dimensions
     409                 :     // change *must* precede all dimension types which are agnostic to
     410                 :     // frame size; see DependsOnFrameSize.
     411                 :     enum DimensionType {
     412                 :       // If one of mWidth and mHeight is eContain or eCover, then both are.
     413                 :       // Also, these two values must equal the corresponding values in
     414                 :       // kBackgroundSizeKTable.
     415                 :       eContain, eCover,
     416                 : 
     417                 :       eAuto,
     418                 :       eLengthPercentage,
     419                 :       eDimensionType_COUNT
     420                 :     };
     421                 :     PRUint8 mWidthType, mHeightType;
     422                 : 
     423                 :     // True if the effective image size described by this depends on the size of
     424                 :     // the corresponding frame, when aImage (which must not have null type) is
     425                 :     // the background image.
     426                 :     bool DependsOnFrameSize(const nsStyleImage& aImage) const;
     427                 : 
     428                 :     // Initialize nothing
     429                 :     Size() {}
     430                 : 
     431                 :     // Initialize to initial values
     432                 :     void SetInitialValues();
     433                 : 
     434                 :     bool operator==(const Size& aOther) const;
     435                 :     bool operator!=(const Size& aOther) const {
     436                 :       return !(*this == aOther);
     437                 :     }
     438                 :   };
     439                 :   
     440                 :   struct Repeat;
     441                 :   friend struct Repeat;
     442                 :   struct Repeat {
     443                 :     PRUint8 mXRepeat, mYRepeat;
     444                 :     
     445                 :     // Initialize nothing
     446                 :     Repeat() {}
     447                 : 
     448                 :     // Initialize to initial values
     449                 :     void SetInitialValues();
     450                 : 
     451                 :     bool operator==(const Repeat& aOther) const {
     452                 :       return mXRepeat == aOther.mXRepeat &&
     453                 :              mYRepeat == aOther.mYRepeat;
     454                 :     }
     455                 :     bool operator!=(const Repeat& aOther) const {
     456                 :       return !(*this == aOther);
     457                 :     }
     458                 :   };
     459                 : 
     460                 :   struct Layer;
     461                 :   friend struct Layer;
     462                 :   struct Layer {
     463                 :     PRUint8 mAttachment;                // [reset] See nsStyleConsts.h
     464                 :     PRUint8 mClip;                      // [reset] See nsStyleConsts.h
     465                 :     PRUint8 mOrigin;                    // [reset] See nsStyleConsts.h
     466                 :     Repeat mRepeat;                     // [reset] See nsStyleConsts.h
     467                 :     Position mPosition;                 // [reset]
     468                 :     nsStyleImage mImage;                // [reset]
     469                 :     Size mSize;                         // [reset]
     470                 : 
     471                 :     // Initializes only mImage
     472                 :     Layer();
     473                 :     ~Layer();
     474                 : 
     475                 :     // Register/unregister images with the document. We do this only
     476                 :     // after the dust has settled in ComputeBackgroundData.
     477                 :     void TrackImages(nsPresContext* aContext) {
     478                 :       if (mImage.GetType() == eStyleImageType_Image)
     479                 :         mImage.TrackImage(aContext);
     480                 :     }
     481                 :     void UntrackImages(nsPresContext* aContext) {
     482                 :       if (mImage.GetType() == eStyleImageType_Image)
     483                 :         mImage.UntrackImage(aContext);
     484                 :     }
     485                 : 
     486                 :     void SetInitialValues();
     487                 : 
     488                 :     // True if the rendering of this layer might change when the size
     489                 :     // of the corresponding frame changes.  This is true for any
     490                 :     // non-solid-color background whose position or size depends on
     491                 :     // the frame size.  It's also true for SVG images whose root <svg>
     492                 :     // node has a viewBox.
     493                 :     bool RenderingMightDependOnFrameSize() const;
     494                 : 
     495                 :     // An equality operator that compares the images using URL-equality
     496                 :     // rather than pointer-equality.
     497                 :     bool operator==(const Layer& aOther) const;
     498                 :     bool operator!=(const Layer& aOther) const {
     499                 :       return !(*this == aOther);
     500                 :     }
     501                 :   };
     502                 : 
     503                 :   // The (positive) number of computed values of each property, since
     504                 :   // the lengths of the lists are independent.
     505                 :   PRUint32 mAttachmentCount,
     506                 :            mClipCount,
     507                 :            mOriginCount,
     508                 :            mRepeatCount,
     509                 :            mPositionCount,
     510                 :            mImageCount,
     511                 :            mSizeCount;
     512                 :   // Layers are stored in an array, matching the top-to-bottom order in
     513                 :   // which they are specified in CSS.  The number of layers to be used
     514                 :   // should come from the background-image property.  We create
     515                 :   // additional |Layer| objects for *any* property, not just
     516                 :   // background-image.  This means that the bottommost layer that
     517                 :   // callers in layout care about (which is also the one whose
     518                 :   // background-clip applies to the background-color) may not be last
     519                 :   // layer.  In layers below the bottom layer, properties will be
     520                 :   // uninitialized unless their count, above, indicates that they are
     521                 :   // present.
     522                 :   nsAutoTArray<Layer, 1> mLayers;
     523                 : 
     524                 :   const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
     525                 : 
     526                 :   #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
     527                 :     for (PRUint32 var_ = (stylebg_)->mImageCount; var_-- != 0; )
     528                 : 
     529                 :   nscolor mBackgroundColor;       // [reset]
     530                 : 
     531                 :   // FIXME: This (now background-break in css3-background) should
     532                 :   // probably move into a different struct so that everything in
     533                 :   // nsStyleBackground is set by the background shorthand.
     534                 :   PRUint8 mBackgroundInlinePolicy; // [reset] See nsStyleConsts.h
     535                 : 
     536                 :   // True if this background is completely transparent.
     537                 :   bool IsTransparent() const;
     538                 : 
     539                 :   // We have to take slower codepaths for fixed background attachment,
     540                 :   // but we don't want to do that when there's no image.
     541                 :   // Not inline because it uses an nsCOMPtr<imgIRequest>
     542                 :   // FIXME: Should be in nsStyleStructInlines.h.
     543                 :   bool HasFixedBackground() const;
     544                 : };
     545                 : 
     546                 : // See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
     547                 : // this is hard to replace with 'currentColor'.
     548                 : #define BORDER_COLOR_FOREGROUND   0x20
     549                 : #define OUTLINE_COLOR_INITIAL     0x80
     550                 : // FOREGROUND | INITIAL(OUTLINE)
     551                 : #define BORDER_COLOR_SPECIAL      0xA0
     552                 : #define BORDER_STYLE_MASK         0x1F
     553                 : 
     554                 : #define NS_SPACING_MARGIN   0
     555                 : #define NS_SPACING_PADDING  1
     556                 : #define NS_SPACING_BORDER   2
     557                 : 
     558                 : 
     559                 : struct nsStyleMargin {
     560                 :   nsStyleMargin(void);
     561                 :   nsStyleMargin(const nsStyleMargin& aMargin);
     562                 :   ~nsStyleMargin(void) {
     563                 :     MOZ_COUNT_DTOR(nsStyleMargin);
     564                 :   }
     565                 : 
     566                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
     567                 :   void Destroy(nsPresContext* aContext);
     568                 : 
     569                 :   void RecalcData();
     570                 :   nsChangeHint CalcDifference(const nsStyleMargin& aOther) const;
     571                 : #ifdef DEBUG
     572                 :   static nsChangeHint MaxDifference();
     573                 : #endif
     574                 :   static bool ForceCompare() { return true; }
     575                 : 
     576                 :   nsStyleSides  mMargin;          // [reset] coord, percent, calc, auto
     577                 : 
     578                 :   bool IsWidthDependent() const { return !mHasCachedMargin; }
     579               0 :   bool GetMargin(nsMargin& aMargin) const
     580                 :   {
     581               0 :     if (mHasCachedMargin) {
     582               0 :       aMargin = mCachedMargin;
     583               0 :       return true;
     584                 :     }
     585               0 :     return false;
     586                 :   }
     587                 : 
     588                 : protected:
     589                 :   bool          mHasCachedMargin;
     590                 :   nsMargin      mCachedMargin;
     591                 : };
     592                 : 
     593                 : 
     594                 : struct nsStylePadding {
     595                 :   nsStylePadding(void);
     596                 :   nsStylePadding(const nsStylePadding& aPadding);
     597                 :   ~nsStylePadding(void) {
     598                 :     MOZ_COUNT_DTOR(nsStylePadding);
     599                 :   }
     600                 : 
     601                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
     602                 :   void Destroy(nsPresContext* aContext);
     603                 : 
     604                 :   void RecalcData();
     605                 :   nsChangeHint CalcDifference(const nsStylePadding& aOther) const;
     606                 : #ifdef DEBUG
     607                 :   static nsChangeHint MaxDifference();
     608                 : #endif
     609                 :   static bool ForceCompare() { return true; }
     610                 : 
     611                 :   nsStyleSides  mPadding;         // [reset] coord, percent, calc
     612                 : 
     613                 :   bool IsWidthDependent() const { return !mHasCachedPadding; }
     614               0 :   bool GetPadding(nsMargin& aPadding) const
     615                 :   {
     616               0 :     if (mHasCachedPadding) {
     617               0 :       aPadding = mCachedPadding;
     618               0 :       return true;
     619                 :     }
     620               0 :     return false;
     621                 :   }
     622                 : 
     623                 : protected:
     624                 :   bool          mHasCachedPadding;
     625                 :   nsMargin      mCachedPadding;
     626                 : };
     627                 : 
     628                 : struct nsBorderColors {
     629                 :   nsBorderColors* mNext;
     630                 :   nscolor mColor;
     631                 : 
     632                 :   nsBorderColors() : mNext(nsnull), mColor(NS_RGB(0,0,0)) {}
     633                 :   nsBorderColors(const nscolor& aColor) : mNext(nsnull), mColor(aColor) {}
     634                 :   ~nsBorderColors();
     635                 : 
     636                 :   nsBorderColors* Clone() const { return Clone(true); }
     637                 : 
     638                 :   static bool Equal(const nsBorderColors* c1,
     639                 :                       const nsBorderColors* c2) {
     640                 :     if (c1 == c2)
     641                 :       return true;
     642                 :     while (c1 && c2) {
     643                 :       if (c1->mColor != c2->mColor)
     644                 :         return false;
     645                 :       c1 = c1->mNext;
     646                 :       c2 = c2->mNext;
     647                 :     }
     648                 :     // both should be NULL if these are equal, otherwise one
     649                 :     // has more colors than another
     650                 :     return !c1 && !c2;
     651                 :   }
     652                 : 
     653                 : private:
     654                 :   nsBorderColors* Clone(bool aDeep) const;
     655                 : };
     656                 : 
     657                 : struct nsCSSShadowItem {
     658                 :   nscoord mXOffset;
     659                 :   nscoord mYOffset;
     660                 :   nscoord mRadius;
     661                 :   nscoord mSpread;
     662                 : 
     663                 :   nscolor      mColor;
     664                 :   bool mHasColor; // Whether mColor should be used
     665                 :   bool mInset;
     666                 : 
     667                 :   nsCSSShadowItem() : mHasColor(false) {
     668                 :     MOZ_COUNT_CTOR(nsCSSShadowItem);
     669                 :   }
     670                 :   ~nsCSSShadowItem() {
     671                 :     MOZ_COUNT_DTOR(nsCSSShadowItem);
     672                 :   }
     673                 : 
     674                 :   bool operator==(const nsCSSShadowItem& aOther) {
     675                 :     return (mXOffset == aOther.mXOffset &&
     676                 :             mYOffset == aOther.mYOffset &&
     677                 :             mRadius == aOther.mRadius &&
     678                 :             mHasColor == aOther.mHasColor &&
     679                 :             mSpread == aOther.mSpread &&
     680                 :             mInset == aOther.mInset &&
     681                 :             (!mHasColor || mColor == aOther.mColor));
     682                 :   }
     683                 :   bool operator!=(const nsCSSShadowItem& aOther) {
     684                 :     return !(*this == aOther);
     685                 :   }
     686                 : };
     687                 : 
     688                 : class nsCSSShadowArray {
     689                 :   public:
     690                 :     void* operator new(size_t aBaseSize, PRUint32 aArrayLen) {
     691                 :       // We can allocate both this nsCSSShadowArray and the
     692                 :       // actual array in one allocation. The amount of memory to
     693                 :       // allocate is equal to the class's size + the number of bytes for all
     694                 :       // but the first array item (because aBaseSize includes one
     695                 :       // item, see the private declarations)
     696                 :       return ::operator new(aBaseSize +
     697                 :                             (aArrayLen - 1) * sizeof(nsCSSShadowItem));
     698                 :     }
     699                 : 
     700                 :     nsCSSShadowArray(PRUint32 aArrayLen) :
     701                 :       mLength(aArrayLen)
     702                 :     {
     703                 :       MOZ_COUNT_CTOR(nsCSSShadowArray);
     704                 :       for (PRUint32 i = 1; i < mLength; ++i) {
     705                 :         // Make sure we call the constructors of each nsCSSShadowItem
     706                 :         // (the first one is called for us because we declared it under private)
     707                 :         new (&mArray[i]) nsCSSShadowItem();
     708                 :       }
     709                 :     }
     710                 :     ~nsCSSShadowArray() {
     711                 :       MOZ_COUNT_DTOR(nsCSSShadowArray);
     712                 :       for (PRUint32 i = 1; i < mLength; ++i) {
     713                 :         mArray[i].~nsCSSShadowItem();
     714                 :       }
     715                 :     }
     716                 : 
     717                 :     PRUint32 Length() const { return mLength; }
     718                 :     nsCSSShadowItem* ShadowAt(PRUint32 i) {
     719                 :       NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
     720                 :       return &mArray[i];
     721                 :     }
     722                 :     const nsCSSShadowItem* ShadowAt(PRUint32 i) const {
     723                 :       NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!");
     724                 :       return &mArray[i];
     725                 :     }
     726                 : 
     727                 :     NS_INLINE_DECL_REFCOUNTING(nsCSSShadowArray)
     728                 : 
     729                 :   private:
     730                 :     PRUint32 mLength;
     731                 :     nsCSSShadowItem mArray[1]; // This MUST be the last item
     732                 : };
     733                 : 
     734                 : // Border widths are rounded to the nearest-below integer number of pixels,
     735                 : // but values between zero and one device pixels are always rounded up to
     736                 : // one device pixel.
     737                 : #define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
     738                 :   ((l) == 0) ? 0 : NS_MAX((tpp), (l) / (tpp) * (tpp))
     739                 : // Outline offset is rounded to the nearest integer number of pixels, but values
     740                 : // between zero and one device pixels are always rounded up to one device pixel.
     741                 : // Note that the offset can be negative.
     742                 : #define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
     743                 :   (((l) == 0) ? 0 : \
     744                 :     ((l) > 0) ? NS_MAX( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
     745                 :                 NS_MIN(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
     746                 : 
     747                 : // Returns if the given border style type is visible or not
     748               0 : static bool IsVisibleBorderStyle(PRUint8 aStyle)
     749                 : {
     750                 :   return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
     751               0 :           aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
     752                 : }
     753                 : 
     754                 : struct nsStyleBorder {
     755                 :   nsStyleBorder(nsPresContext* aContext);
     756                 :   nsStyleBorder(const nsStyleBorder& aBorder);
     757                 :   ~nsStyleBorder();
     758                 : 
     759                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
     760                 :   void Destroy(nsPresContext* aContext);
     761                 : 
     762                 :   nsChangeHint CalcDifference(const nsStyleBorder& aOther) const;
     763                 : #ifdef DEBUG
     764                 :   static nsChangeHint MaxDifference();
     765                 : #endif
     766                 :   static bool ForceCompare() { return false; }
     767                 :   bool ImageBorderDiffers() const;
     768                 : 
     769                 :   nsStyleCorners mBorderRadius;    // [reset] coord, percent, calc
     770                 :   nsStyleSides  mBorderImageSplit; // [reset] integer, percent
     771                 :   PRUint8       mFloatEdge;       // [reset] see nsStyleConsts.h
     772                 :   PRUint8       mBorderImageHFill; // [reset]
     773                 :   PRUint8       mBorderImageVFill; // [reset]
     774                 :   nsBorderColors** mBorderColors; // [reset] multiple levels of color for a border.
     775                 :   nsRefPtr<nsCSSShadowArray> mBoxShadow; // [reset] NULL for 'none'
     776                 :   bool          mHaveBorderImageWidth; // [reset]
     777                 :   nsMargin      mBorderImageWidth; // [reset]
     778                 : 
     779                 :   void EnsureBorderColors() {
     780                 :     if (!mBorderColors) {
     781                 :       mBorderColors = new nsBorderColors*[4];
     782                 :       if (mBorderColors)
     783                 :         for (PRInt32 i = 0; i < 4; i++)
     784                 :           mBorderColors[i] = nsnull;
     785                 :     }
     786                 :   }
     787                 : 
     788                 :   void ClearBorderColors(mozilla::css::Side aSide) {
     789                 :     if (mBorderColors && mBorderColors[aSide]) {
     790                 :       delete mBorderColors[aSide];
     791                 :       mBorderColors[aSide] = nsnull;
     792                 :     }
     793                 :   }
     794                 : 
     795                 :   // Return whether aStyle is a visible style.  Invisible styles cause
     796                 :   // the relevant computed border width to be 0.
     797                 :   // Note that this does *not* consider the effects of 'border-image':
     798                 :   // if border-style is none, but there is a loaded border image,
     799                 :   // HasVisibleStyle will be false even though there *is* a border.
     800                 :   bool HasVisibleStyle(mozilla::css::Side aSide)
     801                 :   {
     802                 :     return IsVisibleBorderStyle(GetBorderStyle(aSide));
     803                 :   }
     804                 : 
     805                 :   // aBorderWidth is in twips
     806                 :   void SetBorderWidth(mozilla::css::Side aSide, nscoord aBorderWidth)
     807                 :   {
     808                 :     nscoord roundedWidth =
     809                 :       NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
     810                 :     mBorder.Side(aSide) = roundedWidth;
     811                 :     if (HasVisibleStyle(aSide))
     812                 :       mComputedBorder.Side(aSide) = roundedWidth;
     813                 :   }
     814                 : 
     815                 :   void SetBorderImageWidthOverride(mozilla::css::Side aSide, nscoord aBorderWidth)
     816                 :   {
     817                 :     mBorderImageWidth.Side(aSide) =
     818                 :       NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
     819                 :   }
     820                 : 
     821                 :   // Get the actual border, in twips.  (If there is no border-image
     822                 :   // loaded, this is the same as GetComputedBorder.  If there is a
     823                 :   // border-image loaded, it uses the border-image width overrides if
     824                 :   // present, and otherwise mBorder, which is GetComputedBorder without
     825                 :   // considering border-style: none.)
     826                 :   const nsMargin& GetActualBorder() const;
     827                 : 
     828                 :   // Get the computed border (plus rounding).  This does consider the
     829                 :   // effects of 'border-style: none', but does not consider
     830                 :   // 'border-image'.
     831                 :   const nsMargin& GetComputedBorder() const
     832                 :   {
     833                 :     return mComputedBorder;
     834                 :   }
     835                 : 
     836                 :   // Get the actual border width for a particular side, in appunits.  Note that
     837                 :   // this is zero if and only if there is no border to be painted for this
     838                 :   // side.  That is, this value takes into account the border style and the
     839                 :   // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
     840               0 :   nscoord GetActualBorderWidth(mozilla::css::Side aSide) const
     841                 :   {
     842               0 :     return GetActualBorder().Side(aSide);
     843                 :   }
     844                 : 
     845                 :   PRUint8 GetBorderStyle(mozilla::css::Side aSide) const
     846                 :   {
     847                 :     NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
     848                 :     return (mBorderStyle[aSide] & BORDER_STYLE_MASK);
     849                 :   }
     850                 : 
     851                 :   void SetBorderStyle(mozilla::css::Side aSide, PRUint8 aStyle)
     852                 :   {
     853                 :     NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
     854                 :     mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
     855                 :     mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
     856                 :     mComputedBorder.Side(aSide) =
     857                 :       (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
     858                 :   }
     859                 : 
     860                 :   // Defined in nsStyleStructInlines.h
     861                 :   inline bool IsBorderImageLoaded() const;
     862                 :   inline nsresult RequestDecode();
     863                 : 
     864                 :   void GetBorderColor(mozilla::css::Side aSide, nscolor& aColor,
     865                 :                       bool& aForeground) const
     866                 :   {
     867                 :     aForeground = false;
     868                 :     NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
     869                 :     if ((mBorderStyle[aSide] & BORDER_COLOR_SPECIAL) == 0)
     870                 :       aColor = mBorderColor[aSide];
     871                 :     else if (mBorderStyle[aSide] & BORDER_COLOR_FOREGROUND)
     872                 :       aForeground = true;
     873                 :     else
     874                 :       NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
     875                 :   }
     876                 : 
     877                 :   void SetBorderColor(mozilla::css::Side aSide, nscolor aColor)
     878                 :   {
     879                 :     NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
     880                 :     mBorderColor[aSide] = aColor;
     881                 :     mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
     882                 :   }
     883                 : 
     884                 :   // These are defined in nsStyleStructInlines.h
     885                 :   inline void SetBorderImage(imgIRequest* aImage);
     886                 :   inline imgIRequest* GetBorderImage() const;
     887                 : 
     888                 :   bool HasBorderImage() {return !!mBorderImage;}
     889                 : 
     890                 :   void TrackImage(nsPresContext* aContext);
     891                 :   void UntrackImage(nsPresContext* aContext);
     892                 : 
     893                 :   // These methods are used for the caller to caches the sub images created during
     894                 :   // a border-image paint operation
     895                 :   inline void SetSubImage(PRUint8 aIndex, imgIContainer* aSubImage) const;
     896                 :   inline imgIContainer* GetSubImage(PRUint8 aIndex) const;
     897                 : 
     898                 :   void GetCompositeColors(PRInt32 aIndex, nsBorderColors** aColors) const
     899                 :   {
     900                 :     if (!mBorderColors)
     901                 :       *aColors = nsnull;
     902                 :     else
     903                 :       *aColors = mBorderColors[aIndex];
     904                 :   }
     905                 : 
     906                 :   void AppendBorderColor(PRInt32 aIndex, nscolor aColor)
     907                 :   {
     908                 :     NS_ASSERTION(aIndex >= 0 && aIndex <= 3, "bad side for composite border color");
     909                 :     nsBorderColors* colorEntry = new nsBorderColors(aColor);
     910                 :     if (!mBorderColors[aIndex])
     911                 :       mBorderColors[aIndex] = colorEntry;
     912                 :     else {
     913                 :       nsBorderColors* last = mBorderColors[aIndex];
     914                 :       while (last->mNext)
     915                 :         last = last->mNext;
     916                 :       last->mNext = colorEntry;
     917                 :     }
     918                 :     mBorderStyle[aIndex] &= ~BORDER_COLOR_SPECIAL;
     919                 :   }
     920                 : 
     921                 :   void SetBorderToForeground(mozilla::css::Side aSide)
     922                 :   {
     923                 :     NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
     924                 :     mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
     925                 :     mBorderStyle[aSide] |= BORDER_COLOR_FOREGROUND;
     926                 :   }
     927                 : 
     928                 : #ifdef DEBUG
     929                 :   bool mImageTracked;
     930                 : #endif
     931                 : 
     932                 : protected:
     933                 :   // mComputedBorder holds the CSS2.1 computed border-width values.  In
     934                 :   // particular, these widths take into account the border-style for the
     935                 :   // relevant side and the values are rounded to the nearest device
     936                 :   // pixel.  They are also rounded (which is not part of the definition
     937                 :   // of computed values).  However, they do *not* take into account the
     938                 :   // presence of border-image.  See GetActualBorder above for how to
     939                 :   // really get the actual border.
     940                 :   nsMargin      mComputedBorder;
     941                 : 
     942                 :   // mBorder holds the nscoord values for the border widths as they would be if
     943                 :   // all the border-style values were visible (not hidden or none).  This
     944                 :   // member exists so that when we create structs using the copy
     945                 :   // constructor during style resolution the new structs will know what the
     946                 :   // specified values of the border were in case they have more specific rules
     947                 :   // setting the border style.  Note that this isn't quite the CSS specified
     948                 :   // value, since this has had the enumerated border widths converted to
     949                 :   // lengths, and all lengths converted to twips.  But it's not quite the
     950                 :   // computed value either. The values are rounded to the nearest device pixel
     951                 :   // We also use these values when we have a loaded border-image that
     952                 :   // does not have width overrides.
     953                 :   nsMargin      mBorder;
     954                 : 
     955                 :   PRUint8       mBorderStyle[4];  // [reset] See nsStyleConsts.h
     956                 :   nscolor       mBorderColor[4];  // [reset] the colors to use for a simple border.  not used
     957                 :                                   // if -moz-border-colors is specified
     958                 : private:
     959                 :   nsCOMPtr<imgIRequest> mBorderImage; // [reset]
     960                 : 
     961                 :   // Cache used by callers for border-image painting
     962                 :   nsCOMArray<imgIContainer> mSubImages;
     963                 : 
     964                 :   nscoord       mTwipsPerPixel;
     965                 : 
     966                 :   nsStyleBorder& operator=(const nsStyleBorder& aOther) MOZ_DELETE;
     967                 : };
     968                 : 
     969                 : 
     970                 : struct nsStyleOutline {
     971                 :   nsStyleOutline(nsPresContext* aPresContext);
     972                 :   nsStyleOutline(const nsStyleOutline& aOutline);
     973                 :   ~nsStyleOutline(void) {
     974                 :     MOZ_COUNT_DTOR(nsStyleOutline);
     975                 :   }
     976                 : 
     977                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     978                 :     return aContext->AllocateFromShell(sz);
     979                 :   }
     980                 :   void Destroy(nsPresContext* aContext) {
     981                 :     this->~nsStyleOutline();
     982                 :     aContext->FreeToShell(sizeof(nsStyleOutline), this);
     983                 :   }
     984                 : 
     985                 :   void RecalcData(nsPresContext* aContext);
     986                 :   nsChangeHint CalcDifference(const nsStyleOutline& aOther) const;
     987                 : #ifdef DEBUG
     988                 :   static nsChangeHint MaxDifference();
     989                 : #endif
     990                 :   static bool ForceCompare() { return false; }
     991                 : 
     992                 :   nsStyleCorners  mOutlineRadius; // [reset] coord, percent, calc
     993                 : 
     994                 :   // Note that this is a specified value.  You can get the actual values
     995                 :   // with GetOutlineWidth.  You cannot get the computed value directly.
     996                 :   nsStyleCoord  mOutlineWidth;    // [reset] coord, enum (see nsStyleConsts.h)
     997                 :   nscoord       mOutlineOffset;   // [reset]
     998                 : 
     999                 :   bool GetOutlineWidth(nscoord& aWidth) const
    1000                 :   {
    1001                 :     if (mHasCachedOutline) {
    1002                 :       aWidth = mCachedOutlineWidth;
    1003                 :       return true;
    1004                 :     }
    1005                 :     return false;
    1006                 :   }
    1007                 : 
    1008                 :   PRUint8 GetOutlineStyle(void) const
    1009                 :   {
    1010                 :     return (mOutlineStyle & BORDER_STYLE_MASK);
    1011                 :   }
    1012                 : 
    1013                 :   void SetOutlineStyle(PRUint8 aStyle)
    1014                 :   {
    1015                 :     mOutlineStyle &= ~BORDER_STYLE_MASK;
    1016                 :     mOutlineStyle |= (aStyle & BORDER_STYLE_MASK);
    1017                 :   }
    1018                 : 
    1019                 :   // false means initial value
    1020                 :   bool GetOutlineColor(nscolor& aColor) const
    1021                 :   {
    1022                 :     if ((mOutlineStyle & BORDER_COLOR_SPECIAL) == 0) {
    1023                 :       aColor = mOutlineColor;
    1024                 :       return true;
    1025                 :     }
    1026                 :     return false;
    1027                 :   }
    1028                 : 
    1029                 :   void SetOutlineColor(nscolor aColor)
    1030                 :   {
    1031                 :     mOutlineColor = aColor;
    1032                 :     mOutlineStyle &= ~BORDER_COLOR_SPECIAL;
    1033                 :   }
    1034                 : 
    1035                 :   void SetOutlineInitialColor()
    1036                 :   {
    1037                 :     mOutlineStyle |= OUTLINE_COLOR_INITIAL;
    1038                 :   }
    1039                 : 
    1040                 :   bool GetOutlineInitialColor() const
    1041                 :   {
    1042                 :     return !!(mOutlineStyle & OUTLINE_COLOR_INITIAL);
    1043                 :   }
    1044                 : 
    1045                 : protected:
    1046                 :   // This value is the actual value, so it's rounded to the nearest device
    1047                 :   // pixel.
    1048                 :   nscoord       mCachedOutlineWidth;
    1049                 : 
    1050                 :   nscolor       mOutlineColor;    // [reset]
    1051                 : 
    1052                 :   bool          mHasCachedOutline;
    1053                 :   PRUint8       mOutlineStyle;    // [reset] See nsStyleConsts.h
    1054                 : 
    1055                 :   nscoord       mTwipsPerPixel;
    1056                 : };
    1057                 : 
    1058                 : 
    1059                 : struct nsStyleList {
    1060                 :   nsStyleList(void);
    1061                 :   nsStyleList(const nsStyleList& aStyleList);
    1062                 :   ~nsStyleList(void);
    1063                 : 
    1064                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1065                 :     return aContext->AllocateFromShell(sz);
    1066                 :   }
    1067                 :   void Destroy(nsPresContext* aContext) {
    1068                 :     this->~nsStyleList();
    1069                 :     aContext->FreeToShell(sizeof(nsStyleList), this);
    1070                 :   }
    1071                 : 
    1072                 :   nsChangeHint CalcDifference(const nsStyleList& aOther) const;
    1073                 : #ifdef DEBUG
    1074                 :   static nsChangeHint MaxDifference();
    1075                 : #endif
    1076                 :   static bool ForceCompare() { return false; }
    1077                 : 
    1078                 :   imgIRequest* GetListStyleImage() const { return mListStyleImage; }
    1079                 :   void SetListStyleImage(imgIRequest* aReq)
    1080                 :   {
    1081                 :     if (mListStyleImage)
    1082                 :       mListStyleImage->UnlockImage();
    1083                 :     mListStyleImage = aReq;
    1084                 :     if (mListStyleImage)
    1085                 :       mListStyleImage->LockImage();
    1086                 :   }
    1087                 : 
    1088                 :   PRUint8   mListStyleType;             // [inherited] See nsStyleConsts.h
    1089                 :   PRUint8   mListStylePosition;         // [inherited]
    1090                 : private:
    1091                 :   nsCOMPtr<imgIRequest> mListStyleImage; // [inherited]
    1092                 :   nsStyleList& operator=(const nsStyleList& aOther) MOZ_DELETE;
    1093                 : public:
    1094                 :   nsRect        mImageRegion;           // [inherited] the rect to use within an image
    1095                 : };
    1096                 : 
    1097                 : struct nsStylePosition {
    1098                 :   nsStylePosition(void);
    1099                 :   nsStylePosition(const nsStylePosition& aOther);
    1100                 :   ~nsStylePosition(void);
    1101                 : 
    1102                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1103                 :     return aContext->AllocateFromShell(sz);
    1104                 :   }
    1105                 :   void Destroy(nsPresContext* aContext) {
    1106                 :     this->~nsStylePosition();
    1107                 :     aContext->FreeToShell(sizeof(nsStylePosition), this);
    1108                 :   }
    1109                 : 
    1110                 :   nsChangeHint CalcDifference(const nsStylePosition& aOther) const;
    1111                 : #ifdef DEBUG
    1112                 :   static nsChangeHint MaxDifference();
    1113                 : #endif
    1114                 :   static bool ForceCompare() { return true; }
    1115                 : 
    1116                 :   nsStyleSides  mOffset;                // [reset] coord, percent, calc, auto
    1117                 :   nsStyleCoord  mWidth;                 // [reset] coord, percent, enum, calc, auto
    1118                 :   nsStyleCoord  mMinWidth;              // [reset] coord, percent, enum, calc
    1119                 :   nsStyleCoord  mMaxWidth;              // [reset] coord, percent, enum, calc, none
    1120                 :   nsStyleCoord  mHeight;                // [reset] coord, percent, calc, auto
    1121                 :   nsStyleCoord  mMinHeight;             // [reset] coord, percent, calc
    1122                 :   nsStyleCoord  mMaxHeight;             // [reset] coord, percent, calc, none
    1123                 :   PRUint8       mBoxSizing;             // [reset] see nsStyleConsts.h
    1124                 :   nsStyleCoord  mZIndex;                // [reset] integer, auto
    1125                 : 
    1126                 :   bool WidthDependsOnContainer() const
    1127                 :     { return WidthCoordDependsOnContainer(mWidth); }
    1128                 :   bool MinWidthDependsOnContainer() const
    1129                 :     { return WidthCoordDependsOnContainer(mMinWidth); }
    1130                 :   bool MaxWidthDependsOnContainer() const
    1131                 :     { return WidthCoordDependsOnContainer(mMaxWidth); }
    1132                 : 
    1133                 :   // Note that these functions count 'auto' as depending on the
    1134                 :   // container since that's the case for absolutely positioned elements.
    1135                 :   // However, some callers do not care about this case and should check
    1136                 :   // for it, since it is the most common case.
    1137                 :   // FIXME: We should probably change the assumption to be the other way
    1138                 :   // around.
    1139                 :   bool HeightDependsOnContainer() const
    1140                 :     { return HeightCoordDependsOnContainer(mHeight); }
    1141                 :   bool MinHeightDependsOnContainer() const
    1142                 :     { return HeightCoordDependsOnContainer(mMinHeight); }
    1143                 :   bool MaxHeightDependsOnContainer() const
    1144                 :     { return HeightCoordDependsOnContainer(mMaxHeight); }
    1145                 : 
    1146                 :   bool OffsetHasPercent(mozilla::css::Side aSide) const
    1147                 :   {
    1148                 :     return mOffset.Get(aSide).HasPercent();
    1149                 :   }
    1150                 : 
    1151                 : private:
    1152                 :   static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
    1153                 :   static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
    1154                 :   {
    1155                 :     return aCoord.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
    1156                 :            aCoord.HasPercent();
    1157                 :   }
    1158                 : };
    1159                 : 
    1160                 : struct nsStyleTextOverflowSide {
    1161                 :   nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
    1162                 : 
    1163                 :   bool operator==(const nsStyleTextOverflowSide& aOther) const {
    1164                 :     return mType == aOther.mType &&
    1165                 :            (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
    1166                 :             mString == aOther.mString);
    1167                 :   }
    1168                 :   bool operator!=(const nsStyleTextOverflowSide& aOther) const {
    1169                 :     return !(*this == aOther);
    1170                 :   }
    1171                 : 
    1172                 :   nsString mString;
    1173                 :   PRUint8  mType;
    1174                 : };
    1175                 : 
    1176                 : struct nsStyleTextOverflow {
    1177                 :   nsStyleTextOverflow() : mLogicalDirections(true) {}
    1178                 :   bool operator==(const nsStyleTextOverflow& aOther) const {
    1179                 :     return mLeft == aOther.mLeft && mRight == aOther.mRight;
    1180                 :   }
    1181                 :   bool operator!=(const nsStyleTextOverflow& aOther) const {
    1182                 :     return !(*this == aOther);
    1183                 :   }
    1184                 : 
    1185                 :   // Returns the value to apply on the left side.
    1186                 :   const nsStyleTextOverflowSide& GetLeft(PRUint8 aDirection) const {
    1187                 :     NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
    1188                 :                  aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
    1189                 :     return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
    1190                 :              mLeft : mRight;
    1191                 :   }
    1192                 : 
    1193                 :   // Returns the value to apply on the right side.
    1194                 :   const nsStyleTextOverflowSide& GetRight(PRUint8 aDirection) const {
    1195                 :     NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
    1196                 :                  aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
    1197                 :     return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
    1198                 :              mRight : mLeft;
    1199                 :   }
    1200                 : 
    1201                 :   // Returns the first value that was specified.
    1202                 :   const nsStyleTextOverflowSide* GetFirstValue() const {
    1203                 :     return mLogicalDirections ? &mRight : &mLeft;
    1204                 :   }
    1205                 : 
    1206                 :   // Returns the second value, or null if there was only one value specified.
    1207                 :   const nsStyleTextOverflowSide* GetSecondValue() const {
    1208                 :     return mLogicalDirections ? nsnull : &mRight;
    1209                 :   }
    1210                 : 
    1211                 :   nsStyleTextOverflowSide mLeft;  // start side when mLogicalDirections is true
    1212                 :   nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
    1213                 :   bool mLogicalDirections;  // true when only one value was specified
    1214                 : };
    1215                 : 
    1216                 : struct nsStyleTextReset {
    1217                 :   nsStyleTextReset(void);
    1218                 :   nsStyleTextReset(const nsStyleTextReset& aOther);
    1219                 :   ~nsStyleTextReset(void);
    1220                 : 
    1221                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1222                 :     return aContext->AllocateFromShell(sz);
    1223                 :   }
    1224                 :   void Destroy(nsPresContext* aContext) {
    1225                 :     this->~nsStyleTextReset();
    1226                 :     aContext->FreeToShell(sizeof(nsStyleTextReset), this);
    1227                 :   }
    1228                 : 
    1229                 :   PRUint8 GetDecorationStyle() const
    1230                 :   {
    1231                 :     return (mTextDecorationStyle & BORDER_STYLE_MASK);
    1232                 :   }
    1233                 : 
    1234                 :   void SetDecorationStyle(PRUint8 aStyle)
    1235                 :   {
    1236                 :     NS_ABORT_IF_FALSE((aStyle & BORDER_STYLE_MASK) == aStyle,
    1237                 :                       "style doesn't fit");
    1238                 :     mTextDecorationStyle &= ~BORDER_STYLE_MASK;
    1239                 :     mTextDecorationStyle |= (aStyle & BORDER_STYLE_MASK);
    1240                 :   }
    1241                 : 
    1242                 :   void GetDecorationColor(nscolor& aColor, bool& aForeground) const
    1243                 :   {
    1244                 :     aForeground = false;
    1245                 :     if ((mTextDecorationStyle & BORDER_COLOR_SPECIAL) == 0) {
    1246                 :       aColor = mTextDecorationColor;
    1247                 :     } else if (mTextDecorationStyle & BORDER_COLOR_FOREGROUND) {
    1248                 :       aForeground = true;
    1249                 :     } else {
    1250                 :       NS_NOTREACHED("OUTLINE_COLOR_INITIAL should not be set here");
    1251                 :     }
    1252                 :   }
    1253                 : 
    1254                 :   void SetDecorationColor(nscolor aColor)
    1255                 :   {
    1256                 :     mTextDecorationColor = aColor;
    1257                 :     mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
    1258                 :   }
    1259                 : 
    1260                 :   void SetDecorationColorToForeground()
    1261                 :   {
    1262                 :     mTextDecorationStyle &= ~BORDER_COLOR_SPECIAL;
    1263                 :     mTextDecorationStyle |= BORDER_COLOR_FOREGROUND;
    1264                 :   }
    1265                 : 
    1266                 :   nsChangeHint CalcDifference(const nsStyleTextReset& aOther) const;
    1267                 : #ifdef DEBUG
    1268                 :   static nsChangeHint MaxDifference();
    1269                 : #endif
    1270                 :   static bool ForceCompare() { return false; }
    1271                 : 
    1272                 :   nsStyleCoord  mVerticalAlign;         // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
    1273                 :   nsStyleTextOverflow mTextOverflow;    // [reset] enum, string
    1274                 : 
    1275                 :   PRUint8 mTextBlink;                   // [reset] see nsStyleConsts.h
    1276                 :   PRUint8 mTextDecorationLine;          // [reset] see nsStyleConsts.h
    1277                 :   PRUint8 mUnicodeBidi;                 // [reset] see nsStyleConsts.h
    1278                 : protected:
    1279                 :   PRUint8 mTextDecorationStyle;         // [reset] see nsStyleConsts.h
    1280                 : 
    1281                 :   nscolor mTextDecorationColor;         // [reset] the colors to use for a decoration lines, not used at currentColor
    1282                 : };
    1283                 : 
    1284                 : struct nsStyleText {
    1285                 :   nsStyleText(void);
    1286                 :   nsStyleText(const nsStyleText& aOther);
    1287                 :   ~nsStyleText(void);
    1288                 : 
    1289                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1290                 :     return aContext->AllocateFromShell(sz);
    1291                 :   }
    1292                 :   void Destroy(nsPresContext* aContext) {
    1293                 :     this->~nsStyleText();
    1294                 :     aContext->FreeToShell(sizeof(nsStyleText), this);
    1295                 :   }
    1296                 : 
    1297                 :   nsChangeHint CalcDifference(const nsStyleText& aOther) const;
    1298                 : #ifdef DEBUG
    1299                 :   static nsChangeHint MaxDifference();
    1300                 : #endif
    1301                 :   static bool ForceCompare() { return false; }
    1302                 : 
    1303                 :   PRUint8 mTextAlign;                   // [inherited] see nsStyleConsts.h
    1304                 :   PRUint8 mTextAlignLast;               // [inherited] see nsStyleConsts.h
    1305                 :   PRUint8 mTextTransform;               // [inherited] see nsStyleConsts.h
    1306                 :   PRUint8 mWhiteSpace;                  // [inherited] see nsStyleConsts.h
    1307                 :   PRUint8 mWordWrap;                    // [inherited] see nsStyleConsts.h
    1308                 :   PRUint8 mHyphens;                     // [inherited] see nsStyleConsts.h
    1309                 :   PRUint8 mTextSizeAdjust;              // [inherited] see nsStyleConsts.h
    1310                 :   PRInt32 mTabSize;                     // [inherited] see nsStyleConsts.h
    1311                 : 
    1312                 :   nsStyleCoord  mLetterSpacing;         // [inherited] coord, normal
    1313                 :   nsStyleCoord  mLineHeight;            // [inherited] coord, factor, normal
    1314                 :   nsStyleCoord  mTextIndent;            // [inherited] coord, percent, calc
    1315                 :   nscoord mWordSpacing;                 // [inherited]
    1316                 : 
    1317                 :   nsRefPtr<nsCSSShadowArray> mTextShadow; // [inherited] NULL in case of a zero-length
    1318                 : 
    1319               0 :   bool WhiteSpaceIsSignificant() const {
    1320                 :     return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
    1321               0 :            mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP;
    1322                 :   }
    1323                 : 
    1324                 :   bool NewlineIsSignificant() const {
    1325                 :     return mWhiteSpace == NS_STYLE_WHITESPACE_PRE ||
    1326                 :            mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
    1327                 :            mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
    1328                 :   }
    1329                 : 
    1330                 :   bool WhiteSpaceCanWrap() const {
    1331                 :     return mWhiteSpace == NS_STYLE_WHITESPACE_NORMAL ||
    1332                 :            mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP ||
    1333                 :            mWhiteSpace == NS_STYLE_WHITESPACE_PRE_LINE;
    1334                 :   }
    1335                 : 
    1336                 :   bool WordCanWrap() const {
    1337                 :     return WhiteSpaceCanWrap() && mWordWrap == NS_STYLE_WORDWRAP_BREAK_WORD;
    1338                 :   }
    1339                 : };
    1340                 : 
    1341                 : struct nsStyleVisibility {
    1342                 :   nsStyleVisibility(nsPresContext* aPresContext);
    1343                 :   nsStyleVisibility(const nsStyleVisibility& aVisibility);
    1344                 :   ~nsStyleVisibility() {
    1345                 :     MOZ_COUNT_DTOR(nsStyleVisibility);
    1346                 :   }
    1347                 : 
    1348                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1349                 :     return aContext->AllocateFromShell(sz);
    1350                 :   }
    1351                 :   void Destroy(nsPresContext* aContext) {
    1352                 :     this->~nsStyleVisibility();
    1353                 :     aContext->FreeToShell(sizeof(nsStyleVisibility), this);
    1354                 :   }
    1355                 : 
    1356                 :   nsChangeHint CalcDifference(const nsStyleVisibility& aOther) const;
    1357                 : #ifdef DEBUG
    1358                 :   static nsChangeHint MaxDifference();
    1359                 : #endif
    1360                 :   static bool ForceCompare() { return false; }
    1361                 : 
    1362                 :   PRUint8 mDirection;                  // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
    1363                 :   PRUint8   mVisible;                  // [inherited]
    1364                 :   PRUint8 mPointerEvents;              // [inherited] see nsStyleConsts.h
    1365                 : 
    1366               0 :   bool IsVisible() const {
    1367               0 :     return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
    1368                 :   }
    1369                 : 
    1370               0 :   bool IsVisibleOrCollapsed() const {
    1371                 :     return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
    1372               0 :             (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
    1373                 :   }
    1374                 : };
    1375                 : 
    1376                 : struct nsTimingFunction {
    1377                 :   enum Type { Function, StepStart, StepEnd };
    1378                 : 
    1379                 :   explicit nsTimingFunction(PRInt32 aTimingFunctionType
    1380                 :                               = NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE)
    1381                 :   {
    1382                 :     AssignFromKeyword(aTimingFunctionType);
    1383                 :   }
    1384                 : 
    1385                 :   nsTimingFunction(float x1, float y1, float x2, float y2)
    1386                 :     : mType(Function)
    1387                 :   {
    1388                 :     mFunc.mX1 = x1;
    1389                 :     mFunc.mY1 = y1;
    1390                 :     mFunc.mX2 = x2;
    1391                 :     mFunc.mY2 = y2;
    1392                 :   }
    1393                 : 
    1394                 :   nsTimingFunction(Type aType, PRUint32 aSteps)
    1395                 :     : mType(aType)
    1396                 :   {
    1397                 :     NS_ABORT_IF_FALSE(mType == StepStart || mType == StepEnd, "wrong type");
    1398                 :     mSteps = aSteps;
    1399                 :   }
    1400                 : 
    1401                 :   nsTimingFunction(const nsTimingFunction& aOther)
    1402                 :   {
    1403                 :     *this = aOther;
    1404                 :   }
    1405                 : 
    1406                 :   Type mType;
    1407                 :   union {
    1408                 :     struct {
    1409                 :       float mX1;
    1410                 :       float mY1;
    1411                 :       float mX2;
    1412                 :       float mY2;
    1413                 :     } mFunc;
    1414                 :     PRUint32 mSteps;
    1415                 :   };
    1416                 : 
    1417                 :   nsTimingFunction&
    1418                 :   operator=(const nsTimingFunction& aOther)
    1419                 :   {
    1420                 :     if (&aOther == this)
    1421                 :       return *this;
    1422                 : 
    1423                 :     mType = aOther.mType;
    1424                 : 
    1425                 :     if (mType == Function) {
    1426                 :       mFunc.mX1 = aOther.mFunc.mX1;
    1427                 :       mFunc.mY1 = aOther.mFunc.mY1;
    1428                 :       mFunc.mX2 = aOther.mFunc.mX2;
    1429                 :       mFunc.mY2 = aOther.mFunc.mY2;
    1430                 :     } else {
    1431                 :       mSteps = aOther.mSteps;
    1432                 :     }
    1433                 : 
    1434                 :     return *this;
    1435                 :   }
    1436                 : 
    1437                 :   bool operator==(const nsTimingFunction& aOther) const
    1438                 :   {
    1439                 :     if (mType != aOther.mType) {
    1440                 :       return false;
    1441                 :     }
    1442                 :     if (mType == Function) {
    1443                 :       return mFunc.mX1 == aOther.mFunc.mX1 && mFunc.mY1 == aOther.mFunc.mY1 &&
    1444                 :              mFunc.mX2 == aOther.mFunc.mX2 && mFunc.mY2 == aOther.mFunc.mY2;
    1445                 :     }
    1446                 :     return mSteps == aOther.mSteps;
    1447                 :   }
    1448                 : 
    1449                 :   bool operator!=(const nsTimingFunction& aOther) const
    1450                 :   {
    1451                 :     return !(*this == aOther);
    1452                 :   }
    1453                 : 
    1454                 : private:
    1455                 :   void AssignFromKeyword(PRInt32 aTimingFunctionType);
    1456                 : };
    1457                 : 
    1458                 : struct nsTransition {
    1459                 :   nsTransition() { /* leaves uninitialized; see also SetInitialValues */ }
    1460                 :   explicit nsTransition(const nsTransition& aCopy);
    1461                 : 
    1462                 :   void SetInitialValues();
    1463                 : 
    1464                 :   // Delay and Duration are in milliseconds
    1465                 : 
    1466                 :   const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
    1467                 :   float GetDelay() const { return mDelay; }
    1468                 :   float GetDuration() const { return mDuration; }
    1469                 :   nsCSSProperty GetProperty() const { return mProperty; }
    1470                 :   nsIAtom* GetUnknownProperty() const { return mUnknownProperty; }
    1471                 : 
    1472                 :   void SetTimingFunction(const nsTimingFunction& aTimingFunction)
    1473                 :     { mTimingFunction = aTimingFunction; }
    1474                 :   void SetDelay(float aDelay) { mDelay = aDelay; }
    1475                 :   void SetDuration(float aDuration) { mDuration = aDuration; }
    1476                 :   void SetProperty(nsCSSProperty aProperty)
    1477                 :     {
    1478                 :       NS_ASSERTION(aProperty != eCSSProperty_UNKNOWN, "invalid property");
    1479                 :       mProperty = aProperty;
    1480                 :     }
    1481                 :   void SetUnknownProperty(const nsAString& aUnknownProperty);
    1482                 :   void CopyPropertyFrom(const nsTransition& aOther)
    1483                 :     {
    1484                 :       mProperty = aOther.mProperty;
    1485                 :       mUnknownProperty = aOther.mUnknownProperty;
    1486                 :     }
    1487                 : 
    1488                 :   nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
    1489                 : 
    1490                 : private:
    1491                 :   nsTimingFunction mTimingFunction;
    1492                 :   float mDuration;
    1493                 :   float mDelay;
    1494                 :   nsCSSProperty mProperty;
    1495                 :   nsCOMPtr<nsIAtom> mUnknownProperty; // used when mProperty is
    1496                 :                                       // eCSSProperty_UNKNOWN
    1497                 : };
    1498                 : 
    1499                 : struct nsAnimation {
    1500                 :   nsAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
    1501                 :   explicit nsAnimation(const nsAnimation& aCopy);
    1502                 : 
    1503                 :   void SetInitialValues();
    1504                 : 
    1505                 :   // Delay and Duration are in milliseconds
    1506                 : 
    1507                 :   const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
    1508                 :   float GetDelay() const { return mDelay; }
    1509                 :   float GetDuration() const { return mDuration; }
    1510                 :   const nsString& GetName() const { return mName; }
    1511                 :   PRUint8 GetDirection() const { return mDirection; }
    1512                 :   PRUint8 GetFillMode() const { return mFillMode; }
    1513                 :   PRUint8 GetPlayState() const { return mPlayState; }
    1514                 :   float GetIterationCount() const { return mIterationCount; }
    1515                 : 
    1516                 :   void SetTimingFunction(const nsTimingFunction& aTimingFunction)
    1517                 :     { mTimingFunction = aTimingFunction; }
    1518                 :   void SetDelay(float aDelay) { mDelay = aDelay; }
    1519                 :   void SetDuration(float aDuration) { mDuration = aDuration; }
    1520                 :   void SetName(const nsSubstring& aName) { mName = aName; }
    1521                 :   void SetDirection(PRUint8 aDirection) { mDirection = aDirection; }
    1522                 :   void SetFillMode(PRUint8 aFillMode) { mFillMode = aFillMode; }
    1523                 :   void SetPlayState(PRUint8 aPlayState) { mPlayState = aPlayState; }
    1524                 :   void SetIterationCount(float aIterationCount)
    1525                 :     { mIterationCount = aIterationCount; }
    1526                 : 
    1527                 :   nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
    1528                 : 
    1529                 : private:
    1530                 :   nsTimingFunction mTimingFunction;
    1531                 :   float mDuration;
    1532                 :   float mDelay;
    1533                 :   nsString mName; // empty string for 'none'
    1534                 :   PRUint8 mDirection;
    1535                 :   PRUint8 mFillMode;
    1536                 :   PRUint8 mPlayState;
    1537                 :   float mIterationCount; // NS_IEEEPositiveInfinity() means infinite
    1538                 : };
    1539                 : 
    1540                 : struct nsStyleDisplay {
    1541                 :   nsStyleDisplay();
    1542                 :   nsStyleDisplay(const nsStyleDisplay& aOther);
    1543                 :   ~nsStyleDisplay() {
    1544                 :     MOZ_COUNT_DTOR(nsStyleDisplay);
    1545                 :   }
    1546                 : 
    1547                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1548                 :     return aContext->AllocateFromShell(sz);
    1549                 :   }
    1550                 :   void Destroy(nsPresContext* aContext) {
    1551                 :     this->~nsStyleDisplay();
    1552                 :     aContext->FreeToShell(sizeof(nsStyleDisplay), this);
    1553                 :   }
    1554                 : 
    1555                 :   nsChangeHint CalcDifference(const nsStyleDisplay& aOther) const;
    1556                 : #ifdef DEBUG
    1557                 :   static nsChangeHint MaxDifference();
    1558                 : #endif
    1559                 :   static bool ForceCompare() { return true; }
    1560                 : 
    1561                 :   // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
    1562                 :   // mBinding->mOriginPrincipal.
    1563                 :   nsRefPtr<nsCSSValue::URL> mBinding;    // [reset]
    1564                 :   nsRect    mClip;              // [reset] offsets from upper-left border edge
    1565                 :   float   mOpacity;             // [reset]
    1566                 :   PRUint8 mDisplay;             // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
    1567                 :   PRUint8 mOriginalDisplay;     // [reset] saved mDisplay for position:absolute/fixed
    1568                 :                                 //         and float:left/right; otherwise equal
    1569                 :                                 //         to mDisplay
    1570                 :   PRUint8 mAppearance;          // [reset]
    1571                 :   PRUint8 mPosition;            // [reset] see nsStyleConsts.h
    1572                 :   PRUint8 mFloats;              // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*
    1573                 :   PRUint8 mOriginalFloats;      // [reset] saved mFloats for position:absolute/fixed;
    1574                 :                                 //         otherwise equal to mFloats
    1575                 :   PRUint8 mBreakType;           // [reset] see nsStyleConsts.h NS_STYLE_CLEAR_*
    1576                 :   bool mBreakBefore;    // [reset]
    1577                 :   bool mBreakAfter;     // [reset]
    1578                 :   PRUint8 mOverflowX;           // [reset] see nsStyleConsts.h
    1579                 :   PRUint8 mOverflowY;           // [reset] see nsStyleConsts.h
    1580                 :   PRUint8 mResize;              // [reset] see nsStyleConsts.h
    1581                 :   PRUint8   mClipFlags;         // [reset] see nsStyleConsts.h
    1582                 :   PRUint8 mOrient;              // [reset] see nsStyleConsts.h
    1583                 : 
    1584                 :   // mSpecifiedTransform is the list of transform functions as
    1585                 :   // specified, or null to indicate there is no transform.  (inherit or
    1586                 :   // initial are replaced by an actual list of transform functions, or
    1587                 :   // null, as appropriate.) (owned by the style rule)
    1588                 :   const nsCSSValueList *mSpecifiedTransform; // [reset]
    1589                 :   nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
    1590                 :   nsStyleCoord mChildPerspective; // [reset] coord
    1591                 :   nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
    1592                 :   PRUint8 mBackfaceVisibility;
    1593                 :   PRUint8 mTransformStyle;
    1594                 : 
    1595                 :   nsAutoTArray<nsTransition, 1> mTransitions; // [reset]
    1596                 :   // The number of elements in mTransitions that are not from repeating
    1597                 :   // a list due to another property being longer.
    1598                 :   PRUint32 mTransitionTimingFunctionCount,
    1599                 :            mTransitionDurationCount,
    1600                 :            mTransitionDelayCount,
    1601                 :            mTransitionPropertyCount;
    1602                 : 
    1603                 :   nsAutoTArray<nsAnimation, 1> mAnimations; // [reset]
    1604                 :   // The number of elements in mAnimations that are not from repeating
    1605                 :   // a list due to another property being longer.
    1606                 :   PRUint32 mAnimationTimingFunctionCount,
    1607                 :            mAnimationDurationCount,
    1608                 :            mAnimationDelayCount,
    1609                 :            mAnimationNameCount,
    1610                 :            mAnimationDirectionCount,
    1611                 :            mAnimationFillModeCount,
    1612                 :            mAnimationPlayStateCount,
    1613                 :            mAnimationIterationCountCount;
    1614                 : 
    1615                 :   bool IsBlockInside() const {
    1616                 :     return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
    1617                 :            NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
    1618                 :            NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay;
    1619                 :     // Should TABLE_CELL and TABLE_CAPTION go here?  They have
    1620                 :     // block frames nested inside of them.
    1621                 :     // (But please audit all callers before changing.)
    1622                 :   }
    1623                 : 
    1624                 :   bool IsBlockOutside() const {
    1625                 :     return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
    1626                 :            NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
    1627                 :            NS_STYLE_DISPLAY_TABLE == mDisplay;
    1628                 :   }
    1629                 : 
    1630                 :   static bool IsDisplayTypeInlineOutside(PRUint8 aDisplay) {
    1631                 :     return NS_STYLE_DISPLAY_INLINE == aDisplay ||
    1632                 :            NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay ||
    1633                 :            NS_STYLE_DISPLAY_INLINE_TABLE == aDisplay ||
    1634                 :            NS_STYLE_DISPLAY_INLINE_BOX == aDisplay ||
    1635                 :            NS_STYLE_DISPLAY_INLINE_GRID == aDisplay ||
    1636                 :            NS_STYLE_DISPLAY_INLINE_STACK == aDisplay;
    1637                 :   }
    1638                 : 
    1639                 :   bool IsInlineOutside() const {
    1640                 :     return IsDisplayTypeInlineOutside(mDisplay);
    1641                 :   }
    1642                 : 
    1643                 :   bool IsOriginalDisplayInlineOutside() const {
    1644                 :     return IsDisplayTypeInlineOutside(mOriginalDisplay);
    1645                 :   }
    1646                 : 
    1647               0 :   bool IsFloating() const {
    1648               0 :     return NS_STYLE_FLOAT_NONE != mFloats;
    1649                 :   }
    1650                 : 
    1651               0 :   bool IsAbsolutelyPositioned() const {return (NS_STYLE_POSITION_ABSOLUTE == mPosition) ||
    1652               0 :                                                 (NS_STYLE_POSITION_FIXED == mPosition);}
    1653                 : 
    1654                 :   /* Returns true if we're positioned or there's a transform in effect. */
    1655               0 :   bool IsPositioned() const {
    1656               0 :     return IsAbsolutelyPositioned() ||
    1657               0 :       NS_STYLE_POSITION_RELATIVE == mPosition || HasTransform();
    1658                 :   }
    1659                 : 
    1660                 :   bool IsScrollableOverflow() const {
    1661                 :     // mOverflowX and mOverflowY always match when one of them is
    1662                 :     // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
    1663                 :     return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
    1664                 :            mOverflowX != NS_STYLE_OVERFLOW_CLIP;
    1665                 :   }
    1666                 : 
    1667                 :   /* Returns whether the element has the -moz-transform property. */
    1668               0 :   bool HasTransform() const {
    1669                 :     return mSpecifiedTransform != nsnull || 
    1670                 :            mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
    1671               0 :            mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
    1672                 :   }
    1673                 : };
    1674                 : 
    1675                 : struct nsStyleTable {
    1676                 :   nsStyleTable(void);
    1677                 :   nsStyleTable(const nsStyleTable& aOther);
    1678                 :   ~nsStyleTable(void);
    1679                 : 
    1680                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1681                 :     return aContext->AllocateFromShell(sz);
    1682                 :   }
    1683                 :   void Destroy(nsPresContext* aContext) {
    1684                 :     this->~nsStyleTable();
    1685                 :     aContext->FreeToShell(sizeof(nsStyleTable), this);
    1686                 :   }
    1687                 : 
    1688                 :   nsChangeHint CalcDifference(const nsStyleTable& aOther) const;
    1689                 : #ifdef DEBUG
    1690                 :   static nsChangeHint MaxDifference();
    1691                 : #endif
    1692                 :   static bool ForceCompare() { return false; }
    1693                 : 
    1694                 :   PRUint8       mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
    1695                 :   PRUint8       mFrame;         // [reset] see nsStyleConsts.h NS_STYLE_TABLE_FRAME_*
    1696                 :   PRUint8       mRules;         // [reset] see nsStyleConsts.h NS_STYLE_TABLE_RULES_*
    1697                 :   PRInt32       mCols;          // [reset] an integer if set, or see nsStyleConsts.h NS_STYLE_TABLE_COLS_*
    1698                 :   PRInt32       mSpan;          // [reset] the number of columns spanned by a colgroup or col
    1699                 : };
    1700                 : 
    1701                 : struct nsStyleTableBorder {
    1702                 :   nsStyleTableBorder(nsPresContext* aContext);
    1703                 :   nsStyleTableBorder(const nsStyleTableBorder& aOther);
    1704                 :   ~nsStyleTableBorder(void);
    1705                 : 
    1706                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1707                 :     return aContext->AllocateFromShell(sz);
    1708                 :   }
    1709                 :   void Destroy(nsPresContext* aContext) {
    1710                 :     this->~nsStyleTableBorder();
    1711                 :     aContext->FreeToShell(sizeof(nsStyleTableBorder), this);
    1712                 :   }
    1713                 : 
    1714                 :   nsChangeHint CalcDifference(const nsStyleTableBorder& aOther) const;
    1715                 : #ifdef DEBUG
    1716                 :   static nsChangeHint MaxDifference();
    1717                 : #endif
    1718                 :   static bool ForceCompare() { return false; }
    1719                 : 
    1720                 :   nscoord       mBorderSpacingX;// [inherited]
    1721                 :   nscoord       mBorderSpacingY;// [inherited]
    1722                 :   PRUint8       mBorderCollapse;// [inherited]
    1723                 :   PRUint8       mCaptionSide;   // [inherited]
    1724                 :   PRUint8       mEmptyCells;    // [inherited]
    1725                 : };
    1726                 : 
    1727                 : enum nsStyleContentType {
    1728                 :   eStyleContentType_String        = 1,
    1729                 :   eStyleContentType_Image         = 10,
    1730                 :   eStyleContentType_Attr          = 20,
    1731                 :   eStyleContentType_Counter       = 30,
    1732                 :   eStyleContentType_Counters      = 31,
    1733                 :   eStyleContentType_OpenQuote     = 40,
    1734                 :   eStyleContentType_CloseQuote    = 41,
    1735                 :   eStyleContentType_NoOpenQuote   = 42,
    1736                 :   eStyleContentType_NoCloseQuote  = 43,
    1737                 :   eStyleContentType_AltContent    = 50
    1738                 : };
    1739                 : 
    1740                 : struct nsStyleContentData {
    1741                 :   nsStyleContentType  mType;
    1742                 :   union {
    1743                 :     PRUnichar *mString;
    1744                 :     imgIRequest *mImage;
    1745                 :     nsCSSValue::Array* mCounters;
    1746                 :   } mContent;
    1747                 : #ifdef DEBUG
    1748                 :   bool mImageTracked;
    1749                 : #endif
    1750                 : 
    1751                 :   nsStyleContentData()
    1752                 :     : mType(nsStyleContentType(0))
    1753                 : #ifdef DEBUG
    1754                 :     , mImageTracked(false)
    1755                 : #endif
    1756                 :   { mContent.mString = nsnull; }
    1757                 : 
    1758                 :   ~nsStyleContentData();
    1759                 :   nsStyleContentData& operator=(const nsStyleContentData& aOther);
    1760                 :   bool operator==(const nsStyleContentData& aOther) const;
    1761                 : 
    1762                 :   bool operator!=(const nsStyleContentData& aOther) const {
    1763                 :     return !(*this == aOther);
    1764                 :   }
    1765                 : 
    1766                 :   void TrackImage(nsPresContext* aContext);
    1767                 :   void UntrackImage(nsPresContext* aContext);
    1768                 : 
    1769                 :   void SetImage(imgIRequest* aRequest)
    1770                 :   {
    1771                 :     NS_ABORT_IF_FALSE(!mImageTracked,
    1772                 :                       "Setting a new image without untracking the old one!");
    1773                 :     NS_ABORT_IF_FALSE(mType == eStyleContentType_Image, "Wrong type!");
    1774                 :     NS_IF_ADDREF(mContent.mImage = aRequest);
    1775                 :   }
    1776                 : private:
    1777                 :   nsStyleContentData(const nsStyleContentData&); // not to be implemented
    1778                 : };
    1779                 : 
    1780                 : struct nsStyleCounterData {
    1781                 :   nsString  mCounter;
    1782                 :   PRInt32   mValue;
    1783                 : };
    1784                 : 
    1785                 : 
    1786                 : #define DELETE_ARRAY_IF(array)  if (array) { delete[] array; array = nsnull; }
    1787                 : 
    1788                 : struct nsStyleQuotes {
    1789                 :   nsStyleQuotes();
    1790                 :   nsStyleQuotes(const nsStyleQuotes& aQuotes);
    1791                 :   ~nsStyleQuotes();
    1792                 : 
    1793                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1794                 :     return aContext->AllocateFromShell(sz);
    1795                 :   }
    1796                 :   void Destroy(nsPresContext* aContext) {
    1797                 :     this->~nsStyleQuotes();
    1798                 :     aContext->FreeToShell(sizeof(nsStyleQuotes), this);
    1799                 :   }
    1800                 : 
    1801                 :   void SetInitial();
    1802                 :   void CopyFrom(const nsStyleQuotes& aSource);
    1803                 : 
    1804                 :   nsChangeHint CalcDifference(const nsStyleQuotes& aOther) const;
    1805                 : #ifdef DEBUG
    1806                 :   static nsChangeHint MaxDifference();
    1807                 : #endif
    1808                 :   static bool ForceCompare() { return false; }
    1809                 : 
    1810                 :   PRUint32  QuotesCount(void) const { return mQuotesCount; } // [inherited]
    1811                 : 
    1812                 :   const nsString* OpenQuoteAt(PRUint32 aIndex) const
    1813                 :   {
    1814                 :     NS_ASSERTION(aIndex < mQuotesCount, "out of range");
    1815                 :     return mQuotes + (aIndex * 2);
    1816                 :   }
    1817                 :   const nsString* CloseQuoteAt(PRUint32 aIndex) const
    1818                 :   {
    1819                 :     NS_ASSERTION(aIndex < mQuotesCount, "out of range");
    1820                 :     return mQuotes + (aIndex * 2 + 1);
    1821                 :   }
    1822                 :   nsresult  GetQuotesAt(PRUint32 aIndex, nsString& aOpen, nsString& aClose) const {
    1823                 :     if (aIndex < mQuotesCount) {
    1824                 :       aIndex *= 2;
    1825                 :       aOpen = mQuotes[aIndex];
    1826                 :       aClose = mQuotes[++aIndex];
    1827                 :       return NS_OK;
    1828                 :     }
    1829                 :     return NS_ERROR_ILLEGAL_VALUE;
    1830                 :   }
    1831                 : 
    1832                 :   nsresult  AllocateQuotes(PRUint32 aCount) {
    1833                 :     if (aCount != mQuotesCount) {
    1834                 :       DELETE_ARRAY_IF(mQuotes);
    1835                 :       if (aCount) {
    1836                 :         mQuotes = new nsString[aCount * 2];
    1837                 :         if (! mQuotes) {
    1838                 :           mQuotesCount = 0;
    1839                 :           return NS_ERROR_OUT_OF_MEMORY;
    1840                 :         }
    1841                 :       }
    1842                 :       mQuotesCount = aCount;
    1843                 :     }
    1844                 :     return NS_OK;
    1845                 :   }
    1846                 : 
    1847                 :   nsresult  SetQuotesAt(PRUint32 aIndex, const nsString& aOpen, const nsString& aClose) {
    1848                 :     if (aIndex < mQuotesCount) {
    1849                 :       aIndex *= 2;
    1850                 :       mQuotes[aIndex] = aOpen;
    1851                 :       mQuotes[++aIndex] = aClose;
    1852                 :       return NS_OK;
    1853                 :     }
    1854                 :     return NS_ERROR_ILLEGAL_VALUE;
    1855                 :   }
    1856                 : 
    1857                 : protected:
    1858                 :   PRUint32            mQuotesCount;
    1859                 :   nsString*           mQuotes;
    1860                 : };
    1861                 : 
    1862                 : struct nsStyleContent {
    1863                 :   nsStyleContent(void);
    1864                 :   nsStyleContent(const nsStyleContent& aContent);
    1865                 :   ~nsStyleContent(void);
    1866                 : 
    1867                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1868                 :     return aContext->AllocateFromShell(sz);
    1869                 :   }
    1870                 :   void Destroy(nsPresContext* aContext);
    1871                 : 
    1872                 :   nsChangeHint CalcDifference(const nsStyleContent& aOther) const;
    1873                 : #ifdef DEBUG
    1874                 :   static nsChangeHint MaxDifference();
    1875                 : #endif
    1876                 :   static bool ForceCompare() { return false; }
    1877                 : 
    1878                 :   PRUint32  ContentCount(void) const  { return mContentCount; } // [reset]
    1879                 : 
    1880                 :   const nsStyleContentData& ContentAt(PRUint32 aIndex) const {
    1881                 :     NS_ASSERTION(aIndex < mContentCount, "out of range");
    1882                 :     return mContents[aIndex];
    1883                 :   }
    1884                 : 
    1885                 :   nsStyleContentData& ContentAt(PRUint32 aIndex) {
    1886                 :     NS_ASSERTION(aIndex < mContentCount, "out of range");
    1887                 :     return mContents[aIndex];
    1888                 :   }
    1889                 : 
    1890                 :   nsresult AllocateContents(PRUint32 aCount);
    1891                 : 
    1892                 :   PRUint32  CounterIncrementCount(void) const { return mIncrementCount; }  // [reset]
    1893                 :   const nsStyleCounterData* GetCounterIncrementAt(PRUint32 aIndex) const {
    1894                 :     NS_ASSERTION(aIndex < mIncrementCount, "out of range");
    1895                 :     return &mIncrements[aIndex];
    1896                 :   }
    1897                 : 
    1898                 :   nsresult  AllocateCounterIncrements(PRUint32 aCount) {
    1899                 :     if (aCount != mIncrementCount) {
    1900                 :       DELETE_ARRAY_IF(mIncrements);
    1901                 :       if (aCount) {
    1902                 :         mIncrements = new nsStyleCounterData[aCount];
    1903                 :         if (! mIncrements) {
    1904                 :           mIncrementCount = 0;
    1905                 :           return NS_ERROR_OUT_OF_MEMORY;
    1906                 :         }
    1907                 :       }
    1908                 :       mIncrementCount = aCount;
    1909                 :     }
    1910                 :     return NS_OK;
    1911                 :   }
    1912                 : 
    1913                 :   nsresult  SetCounterIncrementAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aIncrement) {
    1914                 :     if (aIndex < mIncrementCount) {
    1915                 :       mIncrements[aIndex].mCounter = aCounter;
    1916                 :       mIncrements[aIndex].mValue = aIncrement;
    1917                 :       return NS_OK;
    1918                 :     }
    1919                 :     return NS_ERROR_ILLEGAL_VALUE;
    1920                 :   }
    1921                 : 
    1922                 :   PRUint32  CounterResetCount(void) const { return mResetCount; }  // [reset]
    1923                 :   const nsStyleCounterData* GetCounterResetAt(PRUint32 aIndex) const {
    1924                 :     NS_ASSERTION(aIndex < mResetCount, "out of range");
    1925                 :     return &mResets[aIndex];
    1926                 :   }
    1927                 : 
    1928                 :   nsresult  AllocateCounterResets(PRUint32 aCount) {
    1929                 :     if (aCount != mResetCount) {
    1930                 :       DELETE_ARRAY_IF(mResets);
    1931                 :       if (aCount) {
    1932                 :         mResets = new nsStyleCounterData[aCount];
    1933                 :         if (! mResets) {
    1934                 :           mResetCount = 0;
    1935                 :           return NS_ERROR_OUT_OF_MEMORY;
    1936                 :         }
    1937                 :       }
    1938                 :       mResetCount = aCount;
    1939                 :     }
    1940                 :     return NS_OK;
    1941                 :   }
    1942                 : 
    1943                 :   nsresult  SetCounterResetAt(PRUint32 aIndex, const nsString& aCounter, PRInt32 aValue) {
    1944                 :     if (aIndex < mResetCount) {
    1945                 :       mResets[aIndex].mCounter = aCounter;
    1946                 :       mResets[aIndex].mValue = aValue;
    1947                 :       return NS_OK;
    1948                 :     }
    1949                 :     return NS_ERROR_ILLEGAL_VALUE;
    1950                 :   }
    1951                 : 
    1952                 :   nsStyleCoord  mMarkerOffset;  // [reset] coord, auto
    1953                 : 
    1954                 : protected:
    1955                 :   nsStyleContentData* mContents;
    1956                 :   nsStyleCounterData* mIncrements;
    1957                 :   nsStyleCounterData* mResets;
    1958                 : 
    1959                 :   PRUint32            mContentCount;
    1960                 :   PRUint32            mIncrementCount;
    1961                 :   PRUint32            mResetCount;
    1962                 : };
    1963                 : 
    1964                 : struct nsStyleUIReset {
    1965                 :   nsStyleUIReset(void);
    1966                 :   nsStyleUIReset(const nsStyleUIReset& aOther);
    1967                 :   ~nsStyleUIReset(void);
    1968                 : 
    1969                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    1970                 :     return aContext->AllocateFromShell(sz);
    1971                 :   }
    1972                 :   void Destroy(nsPresContext* aContext) {
    1973                 :     this->~nsStyleUIReset();
    1974                 :     aContext->FreeToShell(sizeof(nsStyleUIReset), this);
    1975                 :   }
    1976                 : 
    1977                 :   nsChangeHint CalcDifference(const nsStyleUIReset& aOther) const;
    1978                 : #ifdef DEBUG
    1979                 :   static nsChangeHint MaxDifference();
    1980                 : #endif
    1981                 :   static bool ForceCompare() { return false; }
    1982                 : 
    1983                 :   PRUint8   mUserSelect;      // [reset] (selection-style)
    1984                 :   PRUint8   mForceBrokenImageIcon; // [reset]  (0 if not forcing, otherwise forcing)
    1985                 :   PRUint8   mIMEMode;         // [reset]
    1986                 :   PRUint8   mWindowShadow;    // [reset]
    1987                 : };
    1988                 : 
    1989                 : struct nsCursorImage {
    1990                 :   bool mHaveHotspot;
    1991                 :   float mHotspotX, mHotspotY;
    1992                 : 
    1993                 :   nsCursorImage();
    1994                 :   nsCursorImage(const nsCursorImage& aOther);
    1995                 :   ~nsCursorImage();
    1996                 : 
    1997                 :   nsCursorImage& operator=(const nsCursorImage& aOther);
    1998                 :   /*
    1999                 :    * We hide mImage and force access through the getter and setter so that we
    2000                 :    * can lock the images we use. Cursor images are likely to be small, so we
    2001                 :    * don't care about discarding them. See bug 512260.
    2002                 :    * */
    2003                 :   void SetImage(imgIRequest *aImage) {
    2004                 :     if (mImage)
    2005                 :       mImage->UnlockImage();
    2006                 :     mImage = aImage;
    2007                 :     if (mImage)
    2008                 :       mImage->LockImage();
    2009                 :   }
    2010                 :   imgIRequest* GetImage() const {
    2011                 :     return mImage;
    2012                 :   }
    2013                 : 
    2014                 : private:
    2015                 :   nsCOMPtr<imgIRequest> mImage;
    2016                 : };
    2017                 : 
    2018                 : struct nsStyleUserInterface {
    2019                 :   nsStyleUserInterface(void);
    2020                 :   nsStyleUserInterface(const nsStyleUserInterface& aOther);
    2021                 :   ~nsStyleUserInterface(void);
    2022                 : 
    2023                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    2024                 :     return aContext->AllocateFromShell(sz);
    2025                 :   }
    2026                 :   void Destroy(nsPresContext* aContext) {
    2027                 :     this->~nsStyleUserInterface();
    2028                 :     aContext->FreeToShell(sizeof(nsStyleUserInterface), this);
    2029                 :   }
    2030                 : 
    2031                 :   nsChangeHint CalcDifference(const nsStyleUserInterface& aOther) const;
    2032                 : #ifdef DEBUG
    2033                 :   static nsChangeHint MaxDifference();
    2034                 : #endif
    2035                 :   static bool ForceCompare() { return false; }
    2036                 : 
    2037                 :   PRUint8   mUserInput;       // [inherited]
    2038                 :   PRUint8   mUserModify;      // [inherited] (modify-content)
    2039                 :   PRUint8   mUserFocus;       // [inherited] (auto-select)
    2040                 : 
    2041                 :   PRUint8   mCursor;          // [inherited] See nsStyleConsts.h
    2042                 : 
    2043                 :   PRUint32 mCursorArrayLength;
    2044                 :   nsCursorImage *mCursorArray;// [inherited] The specified URL values
    2045                 :                               //   and coordinates.  Takes precedence over
    2046                 :                               //   mCursor.  Zero-length array is represented
    2047                 :                               //   by null pointer.
    2048                 : 
    2049                 :   // Does not free mCursorArray; the caller is responsible for calling
    2050                 :   // |delete [] mCursorArray| first if it is needed.
    2051                 :   void CopyCursorArrayFrom(const nsStyleUserInterface& aSource);
    2052                 : };
    2053                 : 
    2054                 : struct nsStyleXUL {
    2055                 :   nsStyleXUL();
    2056                 :   nsStyleXUL(const nsStyleXUL& aSource);
    2057                 :   ~nsStyleXUL();
    2058                 : 
    2059                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    2060                 :     return aContext->AllocateFromShell(sz);
    2061                 :   }
    2062                 :   void Destroy(nsPresContext* aContext) {
    2063                 :     this->~nsStyleXUL();
    2064                 :     aContext->FreeToShell(sizeof(nsStyleXUL), this);
    2065                 :   }
    2066                 : 
    2067                 :   nsChangeHint CalcDifference(const nsStyleXUL& aOther) const;
    2068                 : #ifdef DEBUG
    2069                 :   static nsChangeHint MaxDifference();
    2070                 : #endif
    2071                 :   static bool ForceCompare() { return false; }
    2072                 : 
    2073                 :   float         mBoxFlex;               // [reset] see nsStyleConsts.h
    2074                 :   PRUint32      mBoxOrdinal;            // [reset] see nsStyleConsts.h
    2075                 :   PRUint8       mBoxAlign;              // [reset] see nsStyleConsts.h
    2076                 :   PRUint8       mBoxDirection;          // [reset] see nsStyleConsts.h
    2077                 :   PRUint8       mBoxOrient;             // [reset] see nsStyleConsts.h
    2078                 :   PRUint8       mBoxPack;               // [reset] see nsStyleConsts.h
    2079                 :   bool          mStretchStack;          // [reset] see nsStyleConsts.h
    2080                 : };
    2081                 : 
    2082                 : struct nsStyleColumn {
    2083                 :   nsStyleColumn(nsPresContext* aPresContext);
    2084                 :   nsStyleColumn(const nsStyleColumn& aSource);
    2085                 :   ~nsStyleColumn();
    2086                 : 
    2087                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    2088                 :     return aContext->AllocateFromShell(sz);
    2089                 :   }
    2090                 :   void Destroy(nsPresContext* aContext) {
    2091                 :     this->~nsStyleColumn();
    2092                 :     aContext->FreeToShell(sizeof(nsStyleColumn), this);
    2093                 :   }
    2094                 : 
    2095                 :   nsChangeHint CalcDifference(const nsStyleColumn& aOther) const;
    2096                 : #ifdef DEBUG
    2097                 :   static nsChangeHint MaxDifference();
    2098                 : #endif
    2099                 :   static bool ForceCompare() { return false; }
    2100                 : 
    2101                 :   PRUint32     mColumnCount; // [reset] see nsStyleConsts.h
    2102                 :   nsStyleCoord mColumnWidth; // [reset] coord, auto
    2103                 :   nsStyleCoord mColumnGap;   // [reset] coord, normal
    2104                 : 
    2105                 :   nscolor      mColumnRuleColor;  // [reset]
    2106                 :   PRUint8      mColumnRuleStyle;  // [reset]
    2107                 :   PRUint8      mColumnFill;  // [reset] see nsStyleConsts.h
    2108                 : 
    2109                 :   // See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
    2110                 :   // this is hard to replace with 'currentColor'.
    2111                 :   bool mColumnRuleColorIsForeground;
    2112                 : 
    2113                 :   void SetColumnRuleWidth(nscoord aWidth) {
    2114                 :     mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
    2115                 :   }
    2116                 : 
    2117                 :   nscoord GetComputedColumnRuleWidth() const {
    2118                 :     return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
    2119                 :   }
    2120                 : 
    2121                 : protected:
    2122                 :   nscoord mColumnRuleWidth;  // [reset] coord
    2123                 :   nscoord mTwipsPerPixel;
    2124                 : };
    2125                 : 
    2126                 : enum nsStyleSVGPaintType {
    2127                 :   eStyleSVGPaintType_None = 1,
    2128                 :   eStyleSVGPaintType_Color,
    2129                 :   eStyleSVGPaintType_Server
    2130                 : };
    2131                 : 
    2132                 : struct nsStyleSVGPaint
    2133                 : {
    2134                 :   union {
    2135                 :     nscolor mColor;
    2136                 :     nsIURI *mPaintServer;
    2137                 :   } mPaint;
    2138                 :   nsStyleSVGPaintType mType;
    2139                 :   nscolor mFallbackColor;
    2140                 : 
    2141                 :   nsStyleSVGPaint() : mType(nsStyleSVGPaintType(0)) { mPaint.mPaintServer = nsnull; }
    2142                 :   ~nsStyleSVGPaint();
    2143                 :   void SetType(nsStyleSVGPaintType aType);
    2144                 :   nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
    2145                 :   bool operator==(const nsStyleSVGPaint& aOther) const;
    2146                 : 
    2147                 :   bool operator!=(const nsStyleSVGPaint& aOther) const {
    2148                 :     return !(*this == aOther);
    2149                 :   }
    2150                 : };
    2151                 : 
    2152                 : struct nsStyleSVG {
    2153                 :   nsStyleSVG();
    2154                 :   nsStyleSVG(const nsStyleSVG& aSource);
    2155                 :   ~nsStyleSVG();
    2156                 : 
    2157                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    2158                 :     return aContext->AllocateFromShell(sz);
    2159                 :   }
    2160                 :   void Destroy(nsPresContext* aContext) {
    2161                 :     this->~nsStyleSVG();
    2162                 :     aContext->FreeToShell(sizeof(nsStyleSVG), this);
    2163                 :   }
    2164                 : 
    2165                 :   nsChangeHint CalcDifference(const nsStyleSVG& aOther) const;
    2166                 : #ifdef DEBUG
    2167                 :   static nsChangeHint MaxDifference();
    2168                 : #endif
    2169                 :   static bool ForceCompare() { return false; }
    2170                 : 
    2171                 :   nsStyleSVGPaint  mFill;             // [inherited]
    2172                 :   nsStyleSVGPaint  mStroke;           // [inherited]
    2173                 :   nsCOMPtr<nsIURI> mMarkerEnd;        // [inherited]
    2174                 :   nsCOMPtr<nsIURI> mMarkerMid;        // [inherited]
    2175                 :   nsCOMPtr<nsIURI> mMarkerStart;      // [inherited]
    2176                 :   nsStyleCoord    *mStrokeDasharray;  // [inherited] coord, percent, factor
    2177                 : 
    2178                 :   nsStyleCoord     mStrokeDashoffset; // [inherited] coord, percent, factor
    2179                 :   nsStyleCoord     mStrokeWidth;      // [inherited] coord, percent, factor
    2180                 : 
    2181                 :   float            mFillOpacity;      // [inherited]
    2182                 :   float            mStrokeMiterlimit; // [inherited]
    2183                 :   float            mStrokeOpacity;    // [inherited]
    2184                 : 
    2185                 :   PRUint32         mStrokeDasharrayLength;
    2186                 :   PRUint8          mClipRule;         // [inherited]
    2187                 :   PRUint8          mColorInterpolation; // [inherited] see nsStyleConsts.h
    2188                 :   PRUint8          mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
    2189                 :   PRUint8          mFillRule;         // [inherited] see nsStyleConsts.h
    2190                 :   PRUint8          mImageRendering;   // [inherited] see nsStyleConsts.h
    2191                 :   PRUint8          mShapeRendering;   // [inherited] see nsStyleConsts.h
    2192                 :   PRUint8          mStrokeLinecap;    // [inherited] see nsStyleConsts.h
    2193                 :   PRUint8          mStrokeLinejoin;   // [inherited] see nsStyleConsts.h
    2194                 :   PRUint8          mTextAnchor;       // [inherited] see nsStyleConsts.h
    2195                 :   PRUint8          mTextRendering;    // [inherited] see nsStyleConsts.h
    2196                 : };
    2197                 : 
    2198                 : struct nsStyleSVGReset {
    2199                 :   nsStyleSVGReset();
    2200                 :   nsStyleSVGReset(const nsStyleSVGReset& aSource);
    2201                 :   ~nsStyleSVGReset();
    2202                 : 
    2203                 :   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
    2204                 :     return aContext->AllocateFromShell(sz);
    2205                 :   }
    2206                 :   void Destroy(nsPresContext* aContext) {
    2207                 :     this->~nsStyleSVGReset();
    2208                 :     aContext->FreeToShell(sizeof(nsStyleSVGReset), this);
    2209                 :   }
    2210                 : 
    2211                 :   nsChangeHint CalcDifference(const nsStyleSVGReset& aOther) const;
    2212                 : #ifdef DEBUG
    2213                 :   static nsChangeHint MaxDifference();
    2214                 : #endif
    2215                 :   static bool ForceCompare() { return false; }
    2216                 : 
    2217                 :   nsCOMPtr<nsIURI> mClipPath;         // [reset]
    2218                 :   nsCOMPtr<nsIURI> mFilter;           // [reset]
    2219                 :   nsCOMPtr<nsIURI> mMask;             // [reset]
    2220                 :   nscolor          mStopColor;        // [reset]
    2221                 :   nscolor          mFloodColor;       // [reset]
    2222                 :   nscolor          mLightingColor;    // [reset]
    2223                 : 
    2224                 :   float            mStopOpacity;      // [reset]
    2225                 :   float            mFloodOpacity;     // [reset]
    2226                 : 
    2227                 :   PRUint8          mDominantBaseline; // [reset] see nsStyleConsts.h
    2228                 : };
    2229                 : 
    2230                 : #endif /* nsStyleStruct_h___ */

Generated by: LCOV version 1.7