LCOV - code coverage report
Current view: directory - layout/style - nsStyleStruct.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1482 0 0.0 %
Date: 2012-07-07 Functions: 199 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                 :  *   David Hyatt (hyatt@netscape.com)
      24                 :  *   Mats Palmgren <matspal@gmail.com>
      25                 :  *   Michael Ventnor <m.ventnor@gmail.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                 : #include "nsStyleStruct.h"
      49                 : #include "nsStyleStructInlines.h"
      50                 : #include "nsStyleConsts.h"
      51                 : #include "nsThemeConstants.h"
      52                 : #include "nsString.h"
      53                 : #include "nsPresContext.h"
      54                 : #include "nsIWidget.h"
      55                 : #include "nsIStyleRule.h"
      56                 : #include "nsCRTGlue.h"
      57                 : #include "nsCSSProps.h"
      58                 : 
      59                 : #include "nsCOMPtr.h"
      60                 : #include "nsIFrame.h"
      61                 : #include "nsHTMLReflowState.h"
      62                 : #include "prenv.h"
      63                 : 
      64                 : #include "nsSVGUtils.h"
      65                 : #include "nsBidiUtils.h"
      66                 : #include "nsLayoutUtils.h"
      67                 : 
      68                 : #include "imgIRequest.h"
      69                 : #include "imgIContainer.h"
      70                 : #include "prlog.h"
      71                 : 
      72                 : MOZ_STATIC_ASSERT((((1 << nsStyleStructID_Length) - 1) &
      73                 :                    ~(NS_STYLE_INHERIT_MASK)) == 0,
      74                 :                   "Not enough bits in NS_STYLE_INHERIT_MASK");
      75                 : 
      76               0 : inline bool IsFixedUnit(const nsStyleCoord& aCoord, bool aEnumOK)
      77                 : {
      78               0 :   return aCoord.ConvertsToLength() || 
      79               0 :          (aEnumOK && aCoord.GetUnit() == eStyleUnit_Enumerated);
      80                 : }
      81                 : 
      82               0 : static bool EqualURIs(nsIURI *aURI1, nsIURI *aURI2)
      83                 : {
      84                 :   bool eq;
      85                 :   return aURI1 == aURI2 ||    // handle null==null, and optimize
      86                 :          (aURI1 && aURI2 &&
      87               0 :           NS_SUCCEEDED(aURI1->Equals(aURI2, &eq)) && // not equal on fail
      88               0 :           eq);
      89                 : }
      90                 : 
      91               0 : static bool EqualURIs(nsCSSValue::URL *aURI1, nsCSSValue::URL *aURI2)
      92                 : {
      93                 :   return aURI1 == aURI2 ||    // handle null==null, and optimize
      94               0 :          (aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
      95                 : }
      96                 : 
      97               0 : static bool EqualImages(imgIRequest *aImage1, imgIRequest* aImage2)
      98                 : {
      99               0 :   if (aImage1 == aImage2) {
     100               0 :     return true;
     101                 :   }
     102                 : 
     103               0 :   if (!aImage1 || !aImage2) {
     104               0 :     return false;
     105                 :   }
     106                 : 
     107               0 :   nsCOMPtr<nsIURI> uri1, uri2;
     108               0 :   aImage1->GetURI(getter_AddRefs(uri1));
     109               0 :   aImage2->GetURI(getter_AddRefs(uri2));
     110               0 :   return EqualURIs(uri1, uri2);
     111                 : }
     112                 : 
     113                 : // A nullsafe wrapper for strcmp. We depend on null-safety.
     114               0 : static int safe_strcmp(const PRUnichar* a, const PRUnichar* b)
     115                 : {
     116               0 :   if (!a || !b) {
     117               0 :     return (int)(a - b);
     118                 :   }
     119               0 :   return NS_strcmp(a, b);
     120                 : }
     121                 : 
     122                 : static nsChangeHint CalcShadowDifference(nsCSSShadowArray* lhs,
     123                 :                                          nsCSSShadowArray* rhs);
     124                 : 
     125                 : // --------------------
     126                 : // nsStyleFont
     127                 : //
     128               0 : nsStyleFont::nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext)
     129                 :   : mFont(aFont),
     130               0 :     mGenericID(kGenericFont_NONE)
     131                 : {
     132               0 :   MOZ_COUNT_CTOR(nsStyleFont);
     133               0 :   Init(aPresContext);
     134               0 : }
     135                 : 
     136               0 : nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
     137                 :   : mFont(aSrc.mFont)
     138                 :   , mSize(aSrc.mSize)
     139                 :   , mGenericID(aSrc.mGenericID)
     140                 :   , mScriptLevel(aSrc.mScriptLevel)
     141                 :   , mScriptUnconstrainedSize(aSrc.mScriptUnconstrainedSize)
     142                 :   , mScriptMinSize(aSrc.mScriptMinSize)
     143                 :   , mScriptSizeMultiplier(aSrc.mScriptSizeMultiplier)
     144               0 :   , mLanguage(aSrc.mLanguage)
     145                 : {
     146               0 :   MOZ_COUNT_CTOR(nsStyleFont);
     147               0 : }
     148                 : 
     149               0 : nsStyleFont::nsStyleFont(nsPresContext* aPresContext)
     150                 :   // passing nsnull to GetDefaultFont make it use the doc language
     151               0 :   : mFont(*(aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, nsnull))),
     152               0 :     mGenericID(kGenericFont_NONE)
     153                 : {
     154               0 :   MOZ_COUNT_CTOR(nsStyleFont);
     155               0 :   Init(aPresContext);
     156               0 : }
     157                 : 
     158                 : void
     159               0 : nsStyleFont::Init(nsPresContext* aPresContext)
     160                 : {
     161               0 :   mSize = mFont.size = nsStyleFont::ZoomText(aPresContext, mFont.size);
     162               0 :   mScriptUnconstrainedSize = mSize;
     163                 :   mScriptMinSize = aPresContext->CSSTwipsToAppUnits(
     164               0 :       NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT));
     165               0 :   mScriptLevel = 0;
     166               0 :   mScriptSizeMultiplier = NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER;
     167                 : 
     168               0 :   nsAutoString language;
     169               0 :   aPresContext->Document()->GetContentLanguage(language);
     170               0 :   language.StripWhitespace();
     171                 : 
     172                 :   // Content-Language may be a comma-separated list of language codes,
     173                 :   // in which case the HTML5 spec says to treat it as unknown
     174               0 :   if (!language.IsEmpty() &&
     175               0 :       language.FindChar(PRUnichar(',')) == kNotFound) {
     176               0 :     mLanguage = do_GetAtom(language);
     177                 :   } else {
     178                 :     // we didn't find a (usable) Content-Language, so we fall back
     179                 :     // to whatever the presContext guessed from the charset
     180               0 :     mLanguage = aPresContext->GetLanguageFromCharset();
     181                 :   }
     182               0 : }
     183                 : 
     184                 : void* 
     185               0 : nsStyleFont::operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     186               0 :   void* result = aContext->AllocateFromShell(sz);
     187               0 :   if (result)
     188               0 :     memset(result, 0, sz);
     189               0 :   return result;
     190                 : }
     191                 :   
     192                 : void 
     193               0 : nsStyleFont::Destroy(nsPresContext* aContext) {
     194               0 :   this->~nsStyleFont();
     195               0 :   aContext->FreeToShell(sizeof(nsStyleFont), this);
     196               0 : }
     197                 : 
     198               0 : nsChangeHint nsStyleFont::CalcDifference(const nsStyleFont& aOther) const
     199                 : {
     200               0 :   if (mSize != aOther.mSize ||
     201               0 :       mLanguage != aOther.mLanguage) {
     202               0 :     return NS_STYLE_HINT_REFLOW;
     203                 :   }
     204               0 :   return CalcFontDifference(mFont, aOther.mFont);
     205                 : }
     206                 : 
     207                 : #ifdef DEBUG
     208                 : /* static */
     209               0 : nsChangeHint nsStyleFont::MaxDifference()
     210                 : {
     211               0 :   return NS_STYLE_HINT_REFLOW;
     212                 : }
     213                 : #endif
     214                 : 
     215                 : /* static */ nscoord
     216               0 : nsStyleFont::ZoomText(nsPresContext *aPresContext, nscoord aSize)
     217                 : {
     218               0 :   return nscoord(float(aSize) * aPresContext->TextZoom());
     219                 : }
     220                 : 
     221                 : /* static */ nscoord
     222               0 : nsStyleFont::UnZoomText(nsPresContext *aPresContext, nscoord aSize)
     223                 : {
     224               0 :   return nscoord(float(aSize) / aPresContext->TextZoom());
     225                 : }
     226                 : 
     227               0 : nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont& aFont2)
     228                 : {
     229               0 :   if ((aFont1.size == aFont2.size) && 
     230                 :       (aFont1.sizeAdjust == aFont2.sizeAdjust) && 
     231                 :       (aFont1.style == aFont2.style) &&
     232                 :       (aFont1.variant == aFont2.variant) &&
     233                 :       (aFont1.weight == aFont2.weight) &&
     234                 :       (aFont1.stretch == aFont2.stretch) &&
     235               0 :       (aFont1.name == aFont2.name) &&
     236               0 :       (aFont1.featureSettings == aFont2.featureSettings) &&
     237               0 :       (aFont1.languageOverride == aFont2.languageOverride)) {
     238               0 :     if ((aFont1.decorations == aFont2.decorations)) {
     239               0 :       return NS_STYLE_HINT_NONE;
     240                 :     }
     241               0 :     return NS_STYLE_HINT_VISUAL;
     242                 :   }
     243               0 :   return NS_STYLE_HINT_REFLOW;
     244                 : }
     245                 : 
     246               0 : static bool IsFixedData(const nsStyleSides& aSides, bool aEnumOK)
     247                 : {
     248               0 :   NS_FOR_CSS_SIDES(side) {
     249               0 :     if (!IsFixedUnit(aSides.Get(side), aEnumOK))
     250               0 :       return false;
     251                 :   }
     252               0 :   return true;
     253                 : }
     254                 : 
     255               0 : static nscoord CalcCoord(const nsStyleCoord& aCoord, 
     256                 :                          const nscoord* aEnumTable, 
     257                 :                          PRInt32 aNumEnums)
     258                 : {
     259               0 :   if (aCoord.GetUnit() == eStyleUnit_Enumerated) {
     260               0 :     NS_ABORT_IF_FALSE(aEnumTable, "must have enum table");
     261               0 :     PRInt32 value = aCoord.GetIntValue();
     262               0 :     if (0 <= value && value < aNumEnums) {
     263               0 :       return aEnumTable[aCoord.GetIntValue()];
     264                 :     }
     265               0 :     NS_NOTREACHED("unexpected enum value");
     266               0 :     return 0;
     267                 :   }
     268               0 :   NS_ABORT_IF_FALSE(aCoord.ConvertsToLength(), "unexpected unit");
     269               0 :   return nsRuleNode::ComputeCoordPercentCalc(aCoord, 0);
     270                 : }
     271                 : 
     272               0 : nsStyleMargin::nsStyleMargin() {
     273               0 :   MOZ_COUNT_CTOR(nsStyleMargin);
     274               0 :   nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
     275               0 :   NS_FOR_CSS_SIDES(side) {
     276               0 :     mMargin.Set(side, zero);
     277                 :   }
     278               0 :   mHasCachedMargin = false;
     279               0 : }
     280                 : 
     281               0 : nsStyleMargin::nsStyleMargin(const nsStyleMargin& aSrc) {
     282               0 :   MOZ_COUNT_CTOR(nsStyleMargin);
     283               0 :   mMargin = aSrc.mMargin;
     284               0 :   mHasCachedMargin = false;
     285               0 : }
     286                 : 
     287                 : void* 
     288               0 : nsStyleMargin::operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     289               0 :   void* result = aContext->AllocateFromShell(sz);
     290               0 :   if (result)
     291               0 :     memset(result, 0, sz);
     292               0 :   return result;
     293                 : }
     294                 :   
     295                 : void 
     296               0 : nsStyleMargin::Destroy(nsPresContext* aContext) {
     297               0 :   this->~nsStyleMargin();
     298               0 :   aContext->FreeToShell(sizeof(nsStyleMargin), this);
     299               0 : }
     300                 : 
     301                 : 
     302               0 : void nsStyleMargin::RecalcData()
     303                 : {
     304               0 :   if (IsFixedData(mMargin, false)) {
     305               0 :     NS_FOR_CSS_SIDES(side) {
     306               0 :       mCachedMargin.Side(side) = CalcCoord(mMargin.Get(side), nsnull, 0);
     307                 :     }
     308               0 :     mHasCachedMargin = true;
     309                 :   }
     310                 :   else
     311               0 :     mHasCachedMargin = false;
     312               0 : }
     313                 : 
     314               0 : nsChangeHint nsStyleMargin::CalcDifference(const nsStyleMargin& aOther) const
     315                 : {
     316               0 :   if (mMargin == aOther.mMargin) {
     317               0 :     return NS_STYLE_HINT_NONE;
     318                 :   }
     319                 :   // Margin differences can't affect descendant intrinsic sizes and
     320                 :   // don't need to force children to reflow.
     321                 :   return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
     322                 :                          NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
     323               0 :                                         nsChangeHint_NeedDirtyReflow));
     324                 : }
     325                 : 
     326                 : #ifdef DEBUG
     327                 : /* static */
     328               0 : nsChangeHint nsStyleMargin::MaxDifference()
     329                 : {
     330                 :   return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
     331                 :                          NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
     332               0 :                                         nsChangeHint_NeedDirtyReflow));
     333                 : }
     334                 : #endif
     335                 : 
     336               0 : nsStylePadding::nsStylePadding() {
     337               0 :   MOZ_COUNT_CTOR(nsStylePadding);
     338               0 :   nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
     339               0 :   NS_FOR_CSS_SIDES(side) {
     340               0 :     mPadding.Set(side, zero);
     341                 :   }
     342               0 :   mHasCachedPadding = false;
     343               0 : }
     344                 : 
     345               0 : nsStylePadding::nsStylePadding(const nsStylePadding& aSrc) {
     346               0 :   MOZ_COUNT_CTOR(nsStylePadding);
     347               0 :   mPadding = aSrc.mPadding;
     348               0 :   mHasCachedPadding = false;
     349               0 : }
     350                 : 
     351                 : void* 
     352               0 : nsStylePadding::operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     353               0 :   void* result = aContext->AllocateFromShell(sz);
     354               0 :   if (result)
     355               0 :     memset(result, 0, sz);
     356               0 :   return result;
     357                 : }
     358                 :   
     359                 : void 
     360               0 : nsStylePadding::Destroy(nsPresContext* aContext) {
     361               0 :   this->~nsStylePadding();
     362               0 :   aContext->FreeToShell(sizeof(nsStylePadding), this);
     363               0 : }
     364                 : 
     365               0 : void nsStylePadding::RecalcData()
     366                 : {
     367               0 :   if (IsFixedData(mPadding, false)) {
     368               0 :     NS_FOR_CSS_SIDES(side) {
     369                 :       // Clamp negative calc() to 0.
     370               0 :       mCachedPadding.Side(side) =
     371               0 :         NS_MAX(CalcCoord(mPadding.Get(side), nsnull, 0), 0);
     372                 :     }
     373               0 :     mHasCachedPadding = true;
     374                 :   }
     375                 :   else
     376               0 :     mHasCachedPadding = false;
     377               0 : }
     378                 : 
     379               0 : nsChangeHint nsStylePadding::CalcDifference(const nsStylePadding& aOther) const
     380                 : {
     381               0 :   if (mPadding == aOther.mPadding) {
     382               0 :     return NS_STYLE_HINT_NONE;
     383                 :   }
     384                 :   // Padding differences can't affect descendant intrinsic sizes, but do need
     385                 :   // to force children to reflow so that we can reposition them, since their
     386                 :   // offsets are from our frame bounds but our content rect's position within
     387                 :   // those bounds is moving.
     388                 :   return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
     389               0 :                          nsChangeHint_ClearDescendantIntrinsics);
     390                 : }
     391                 : 
     392                 : #ifdef DEBUG
     393                 : /* static */
     394               0 : nsChangeHint nsStylePadding::MaxDifference()
     395                 : {
     396                 :   return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
     397               0 :                          nsChangeHint_ClearDescendantIntrinsics);
     398                 : }
     399                 : #endif
     400                 : 
     401               0 : nsStyleBorder::nsStyleBorder(nsPresContext* aPresContext)
     402                 :   : mHaveBorderImageWidth(false)
     403                 : #ifdef DEBUG
     404                 :   , mImageTracked(false)
     405                 : #endif
     406                 :   , mComputedBorder(0, 0, 0, 0)
     407               0 :   , mBorderImage(nsnull)
     408                 : {
     409               0 :   MOZ_COUNT_CTOR(nsStyleBorder);
     410                 :   nscoord medium =
     411               0 :     (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
     412               0 :   NS_FOR_CSS_SIDES(side) {
     413               0 :     mBorder.Side(side) = medium;
     414               0 :     mBorderStyle[side] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
     415               0 :     mBorderColor[side] = NS_RGB(0, 0, 0);
     416                 :   }
     417               0 :   NS_FOR_CSS_HALF_CORNERS(corner) {
     418               0 :     mBorderRadius.Set(corner, nsStyleCoord(0, nsStyleCoord::CoordConstructor));
     419                 :   }
     420                 : 
     421               0 :   mBorderColors = nsnull;
     422               0 :   mBoxShadow = nsnull;
     423                 : 
     424               0 :   mFloatEdge = NS_STYLE_FLOAT_EDGE_CONTENT;
     425                 : 
     426               0 :   mTwipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
     427               0 : }
     428                 : 
     429               0 : nsBorderColors::~nsBorderColors()
     430                 : {
     431               0 :   NS_CSS_DELETE_LIST_MEMBER(nsBorderColors, this, mNext);
     432               0 : }
     433                 : 
     434                 : nsBorderColors*
     435               0 : nsBorderColors::Clone(bool aDeep) const
     436                 : {
     437               0 :   nsBorderColors* result = new nsBorderColors(mColor);
     438               0 :   if (NS_UNLIKELY(!result))
     439               0 :     return result;
     440               0 :   if (aDeep)
     441               0 :     NS_CSS_CLONE_LIST_MEMBER(nsBorderColors, this, mNext, result, (false));
     442               0 :   return result;
     443                 : }
     444                 : 
     445               0 : nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
     446                 :   : mBorderRadius(aSrc.mBorderRadius),
     447                 :     mBorderImageSplit(aSrc.mBorderImageSplit),
     448                 :     mFloatEdge(aSrc.mFloatEdge),
     449                 :     mBorderImageHFill(aSrc.mBorderImageHFill),
     450                 :     mBorderImageVFill(aSrc.mBorderImageVFill),
     451                 :     mBorderColors(nsnull),
     452                 :     mBoxShadow(aSrc.mBoxShadow),
     453                 :     mHaveBorderImageWidth(aSrc.mHaveBorderImageWidth),
     454                 :     mBorderImageWidth(aSrc.mBorderImageWidth),
     455                 :     mComputedBorder(aSrc.mComputedBorder),
     456                 :     mBorder(aSrc.mBorder),
     457                 :     mBorderImage(aSrc.mBorderImage),
     458               0 :     mTwipsPerPixel(aSrc.mTwipsPerPixel)
     459                 : {
     460               0 :   MOZ_COUNT_CTOR(nsStyleBorder);
     461               0 :   if (aSrc.mBorderColors) {
     462               0 :     EnsureBorderColors();
     463               0 :     for (PRInt32 i = 0; i < 4; i++)
     464               0 :       if (aSrc.mBorderColors[i])
     465               0 :         mBorderColors[i] = aSrc.mBorderColors[i]->Clone();
     466                 :       else
     467               0 :         mBorderColors[i] = nsnull;
     468                 :   }
     469                 : 
     470               0 :   NS_FOR_CSS_SIDES(side) {
     471               0 :     mBorderStyle[side] = aSrc.mBorderStyle[side];
     472               0 :     mBorderColor[side] = aSrc.mBorderColor[side];
     473                 :   }
     474               0 :   NS_FOR_CSS_HALF_CORNERS(corner) {
     475               0 :     mBorderRadius.Set(corner, aSrc.mBorderRadius.Get(corner));
     476                 :   }
     477               0 : }
     478                 : 
     479               0 : nsStyleBorder::~nsStyleBorder()
     480                 : {
     481               0 :   NS_ABORT_IF_FALSE(!mImageTracked,
     482                 :                     "nsStyleBorder being destroyed while still tracking image!");
     483               0 :   MOZ_COUNT_DTOR(nsStyleBorder);
     484               0 :   if (mBorderColors) {
     485               0 :     for (PRInt32 i = 0; i < 4; i++)
     486               0 :       delete mBorderColors[i];
     487               0 :     delete [] mBorderColors;
     488                 :   }
     489               0 : }
     490                 : 
     491                 : void* 
     492               0 : nsStyleBorder::operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     493               0 :   void* result = aContext->AllocateFromShell(sz);
     494               0 :   if (result)
     495               0 :     memset(result, 0, sz);
     496               0 :   return result;
     497                 : }
     498                 :   
     499                 : void 
     500               0 : nsStyleBorder::Destroy(nsPresContext* aContext) {
     501               0 :   if (mBorderImage)
     502               0 :     UntrackImage(aContext);
     503               0 :   this->~nsStyleBorder();
     504               0 :   aContext->FreeToShell(sizeof(nsStyleBorder), this);
     505               0 : }
     506                 : 
     507                 : 
     508               0 : nsChangeHint nsStyleBorder::CalcDifference(const nsStyleBorder& aOther) const
     509                 : {
     510                 :   nsChangeHint shadowDifference =
     511               0 :     CalcShadowDifference(mBoxShadow, aOther.mBoxShadow);
     512                 : 
     513                 :   // Note that differences in mBorder don't affect rendering (which should only
     514                 :   // use mComputedBorder), so don't need to be tested for here.
     515                 :   // XXXbz we should be able to return a more specific change hint for
     516                 :   // at least GetActualBorder() differences...
     517               0 :   if (mTwipsPerPixel != aOther.mTwipsPerPixel ||
     518               0 :       GetActualBorder() != aOther.GetActualBorder() || 
     519                 :       mFloatEdge != aOther.mFloatEdge ||
     520                 :       (shadowDifference & nsChangeHint_ReflowFrame))
     521               0 :     return NS_STYLE_HINT_REFLOW;
     522                 : 
     523                 :   // Note that mBorderStyle stores not only the border style but also
     524                 :   // color-related flags.  Given that we've already done an mComputedBorder
     525                 :   // comparison, border-style differences can only lead to a VISUAL hint.  So
     526                 :   // it's OK to just compare the values directly -- if either the actual
     527                 :   // style or the color flags differ we want to repaint.
     528               0 :   NS_FOR_CSS_SIDES(ix) {
     529               0 :     if (mBorderStyle[ix] != aOther.mBorderStyle[ix] || 
     530               0 :         mBorderColor[ix] != aOther.mBorderColor[ix])
     531               0 :       return NS_STYLE_HINT_VISUAL;
     532                 :   }
     533                 : 
     534               0 :   if (mBorderRadius != aOther.mBorderRadius ||
     535               0 :       !mBorderColors != !aOther.mBorderColors)
     536               0 :     return NS_STYLE_HINT_VISUAL;
     537                 : 
     538               0 :   if (IsBorderImageLoaded() || aOther.IsBorderImageLoaded()) {
     539               0 :     if (mBorderImage != aOther.mBorderImage ||
     540                 :         mBorderImageHFill != aOther.mBorderImageHFill ||
     541                 :         mBorderImageVFill != aOther.mBorderImageVFill ||
     542               0 :         mBorderImageSplit != aOther.mBorderImageSplit)
     543               0 :       return NS_STYLE_HINT_VISUAL;
     544                 :     // The call to GetActualBorder above already considered
     545                 :     // mBorderImageWidth and mHaveBorderImageWidth.
     546                 :   }
     547                 : 
     548                 :   // Note that at this point if mBorderColors is non-null so is
     549                 :   // aOther.mBorderColors
     550               0 :   if (mBorderColors) {
     551               0 :     NS_FOR_CSS_SIDES(ix) {
     552               0 :       if (!nsBorderColors::Equal(mBorderColors[ix],
     553               0 :                                  aOther.mBorderColors[ix]))
     554               0 :         return NS_STYLE_HINT_VISUAL;
     555                 :     }
     556                 :   }
     557                 : 
     558               0 :   return shadowDifference;
     559                 : }
     560                 : 
     561                 : #ifdef DEBUG
     562                 : /* static */
     563               0 : nsChangeHint nsStyleBorder::MaxDifference()
     564                 : {
     565               0 :   return NS_STYLE_HINT_REFLOW;
     566                 : }
     567                 : #endif
     568                 : 
     569                 : bool
     570               0 : nsStyleBorder::ImageBorderDiffers() const
     571                 : {
     572                 :   return mComputedBorder !=
     573               0 :            (mHaveBorderImageWidth ? mBorderImageWidth : mBorder);
     574                 : }
     575                 : 
     576                 : const nsMargin&
     577               0 : nsStyleBorder::GetActualBorder() const
     578                 : {
     579               0 :   if (IsBorderImageLoaded())
     580               0 :     if (mHaveBorderImageWidth)
     581               0 :       return mBorderImageWidth;
     582                 :     else
     583               0 :       return mBorder;
     584                 :   else
     585               0 :     return mComputedBorder;
     586                 : }
     587                 : 
     588                 : void
     589               0 : nsStyleBorder::TrackImage(nsPresContext* aContext)
     590                 : {
     591                 :   // Sanity
     592               0 :   NS_ABORT_IF_FALSE(!mImageTracked, "Already tracking image!");
     593               0 :   NS_ABORT_IF_FALSE(mBorderImage, "Can't track null image!");
     594                 : 
     595                 :   // Register the image with the document
     596               0 :   nsIDocument* doc = aContext->Document();
     597               0 :   if (doc)
     598               0 :     doc->AddImage(mBorderImage);
     599                 : 
     600                 :   // Mark state
     601                 : #ifdef DEBUG
     602               0 :   mImageTracked = true;
     603                 : #endif
     604               0 : }
     605                 : 
     606                 : void
     607               0 : nsStyleBorder::UntrackImage(nsPresContext* aContext)
     608                 : {
     609                 :   // Sanity
     610               0 :   NS_ABORT_IF_FALSE(mImageTracked, "Image not tracked!");
     611               0 :   NS_ABORT_IF_FALSE(mBorderImage, "Can't track null image!");
     612                 : 
     613                 :   // Unregister the image with the document
     614               0 :   nsIDocument* doc = aContext->Document();
     615               0 :   if (doc)
     616               0 :     doc->RemoveImage(mBorderImage);
     617                 : 
     618                 :   // Mark state
     619                 : #ifdef DEBUG
     620               0 :   mImageTracked = false;
     621                 : #endif
     622               0 : }
     623                 : 
     624               0 : nsStyleOutline::nsStyleOutline(nsPresContext* aPresContext)
     625                 : {
     626               0 :   MOZ_COUNT_CTOR(nsStyleOutline);
     627                 :   // spacing values not inherited
     628               0 :   nsStyleCoord zero(0, nsStyleCoord::CoordConstructor);
     629               0 :   NS_FOR_CSS_HALF_CORNERS(corner) {
     630               0 :     mOutlineRadius.Set(corner, zero);
     631                 :   }
     632                 : 
     633               0 :   mOutlineOffset = 0;
     634                 : 
     635               0 :   mOutlineWidth = nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
     636               0 :   mOutlineStyle = NS_STYLE_BORDER_STYLE_NONE;
     637               0 :   mOutlineColor = NS_RGB(0, 0, 0);
     638                 : 
     639               0 :   mHasCachedOutline = false;
     640               0 :   mTwipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
     641               0 : }
     642                 : 
     643               0 : nsStyleOutline::nsStyleOutline(const nsStyleOutline& aSrc) {
     644               0 :   MOZ_COUNT_CTOR(nsStyleOutline);
     645               0 :   memcpy((nsStyleOutline*)this, &aSrc, sizeof(nsStyleOutline));
     646               0 : }
     647                 : 
     648                 : void 
     649               0 : nsStyleOutline::RecalcData(nsPresContext* aContext)
     650                 : {
     651               0 :   if (NS_STYLE_BORDER_STYLE_NONE == GetOutlineStyle()) {
     652               0 :     mCachedOutlineWidth = 0;
     653               0 :     mHasCachedOutline = true;
     654               0 :   } else if (IsFixedUnit(mOutlineWidth, true)) {
     655                 :     // Clamp negative calc() to 0.
     656                 :     mCachedOutlineWidth =
     657               0 :       NS_MAX(CalcCoord(mOutlineWidth, aContext->GetBorderWidthTable(), 3), 0);
     658                 :     mCachedOutlineWidth =
     659               0 :       NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth, mTwipsPerPixel);
     660               0 :     mHasCachedOutline = true;
     661                 :   }
     662                 :   else
     663               0 :     mHasCachedOutline = false;
     664               0 : }
     665                 : 
     666               0 : nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const
     667                 : {
     668                 :   bool outlineWasVisible =
     669               0 :     mCachedOutlineWidth > 0 && mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
     670                 :   bool outlineIsVisible = 
     671               0 :     aOther.mCachedOutlineWidth > 0 && aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
     672               0 :   if (outlineWasVisible != outlineIsVisible ||
     673                 :       (outlineIsVisible && (mOutlineOffset != aOther.mOutlineOffset ||
     674               0 :                             mOutlineWidth != aOther.mOutlineWidth ||
     675                 :                             mTwipsPerPixel != aOther.mTwipsPerPixel))) {
     676               0 :     return NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame);
     677                 :   }
     678               0 :   if ((mOutlineStyle != aOther.mOutlineStyle) ||
     679                 :       (mOutlineColor != aOther.mOutlineColor) ||
     680               0 :       (mOutlineRadius != aOther.mOutlineRadius)) {
     681               0 :     return nsChangeHint_RepaintFrame;
     682                 :   }
     683               0 :   return NS_STYLE_HINT_NONE;
     684                 : }
     685                 : 
     686                 : #ifdef DEBUG
     687                 : /* static */
     688               0 : nsChangeHint nsStyleOutline::MaxDifference()
     689                 : {
     690               0 :   return NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame);
     691                 : }
     692                 : #endif
     693                 : 
     694                 : // --------------------
     695                 : // nsStyleList
     696                 : //
     697               0 : nsStyleList::nsStyleList() 
     698                 :   : mListStyleType(NS_STYLE_LIST_STYLE_DISC),
     699               0 :     mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE)
     700                 : {
     701               0 :   MOZ_COUNT_CTOR(nsStyleList);
     702               0 : }
     703                 : 
     704               0 : nsStyleList::~nsStyleList() 
     705                 : {
     706               0 :   MOZ_COUNT_DTOR(nsStyleList);
     707               0 : }
     708                 : 
     709               0 : nsStyleList::nsStyleList(const nsStyleList& aSource)
     710                 :   : mListStyleType(aSource.mListStyleType),
     711                 :     mListStylePosition(aSource.mListStylePosition),
     712               0 :     mImageRegion(aSource.mImageRegion)
     713                 : {
     714               0 :   SetListStyleImage(aSource.GetListStyleImage());
     715               0 :   MOZ_COUNT_CTOR(nsStyleList);
     716               0 : }
     717                 : 
     718               0 : nsChangeHint nsStyleList::CalcDifference(const nsStyleList& aOther) const
     719                 : {
     720               0 :   if (mListStylePosition != aOther.mListStylePosition)
     721               0 :     return NS_STYLE_HINT_FRAMECHANGE;
     722               0 :   if (EqualImages(mListStyleImage, aOther.mListStyleImage) &&
     723                 :       mListStyleType == aOther.mListStyleType) {
     724               0 :     if (mImageRegion.IsEqualInterior(aOther.mImageRegion))
     725               0 :       return NS_STYLE_HINT_NONE;
     726               0 :     if (mImageRegion.width == aOther.mImageRegion.width &&
     727                 :         mImageRegion.height == aOther.mImageRegion.height)
     728               0 :       return NS_STYLE_HINT_VISUAL;
     729                 :   }
     730               0 :   return NS_STYLE_HINT_REFLOW;
     731                 : }
     732                 : 
     733                 : #ifdef DEBUG
     734                 : /* static */
     735               0 : nsChangeHint nsStyleList::MaxDifference()
     736                 : {
     737               0 :   return NS_STYLE_HINT_FRAMECHANGE;
     738                 : }
     739                 : #endif
     740                 : 
     741                 : // --------------------
     742                 : // nsStyleXUL
     743                 : //
     744               0 : nsStyleXUL::nsStyleXUL() 
     745                 : { 
     746               0 :   MOZ_COUNT_CTOR(nsStyleXUL);
     747               0 :   mBoxAlign  = NS_STYLE_BOX_ALIGN_STRETCH;
     748               0 :   mBoxDirection = NS_STYLE_BOX_DIRECTION_NORMAL;
     749               0 :   mBoxFlex = 0.0f;
     750               0 :   mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL;
     751               0 :   mBoxPack   = NS_STYLE_BOX_PACK_START;
     752               0 :   mBoxOrdinal = 1;
     753               0 :   mStretchStack = true;
     754               0 : }
     755                 : 
     756               0 : nsStyleXUL::~nsStyleXUL() 
     757                 : {
     758               0 :   MOZ_COUNT_DTOR(nsStyleXUL);
     759               0 : }
     760                 : 
     761               0 : nsStyleXUL::nsStyleXUL(const nsStyleXUL& aSource)
     762                 : {
     763               0 :   MOZ_COUNT_CTOR(nsStyleXUL);
     764               0 :   memcpy((nsStyleXUL*)this, &aSource, sizeof(nsStyleXUL));
     765               0 : }
     766                 : 
     767               0 : nsChangeHint nsStyleXUL::CalcDifference(const nsStyleXUL& aOther) const
     768                 : {
     769               0 :   if (mBoxAlign == aOther.mBoxAlign &&
     770                 :       mBoxDirection == aOther.mBoxDirection &&
     771                 :       mBoxFlex == aOther.mBoxFlex &&
     772                 :       mBoxOrient == aOther.mBoxOrient &&
     773                 :       mBoxPack == aOther.mBoxPack &&
     774                 :       mBoxOrdinal == aOther.mBoxOrdinal)
     775               0 :     return NS_STYLE_HINT_NONE;
     776               0 :   if (mBoxOrdinal != aOther.mBoxOrdinal)
     777               0 :     return NS_STYLE_HINT_FRAMECHANGE;
     778               0 :   return NS_STYLE_HINT_REFLOW;
     779                 : }
     780                 : 
     781                 : #ifdef DEBUG
     782                 : /* static */
     783               0 : nsChangeHint nsStyleXUL::MaxDifference()
     784                 : {
     785               0 :   return NS_STYLE_HINT_FRAMECHANGE;
     786                 : }
     787                 : #endif
     788                 : 
     789                 : // --------------------
     790                 : // nsStyleColumn
     791                 : //
     792               0 : nsStyleColumn::nsStyleColumn(nsPresContext* aPresContext)
     793                 : {
     794               0 :   MOZ_COUNT_CTOR(nsStyleColumn);
     795               0 :   mColumnCount = NS_STYLE_COLUMN_COUNT_AUTO;
     796               0 :   mColumnWidth.SetAutoValue();
     797               0 :   mColumnGap.SetNormalValue();
     798                 : 
     799               0 :   mColumnRuleWidth = (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
     800               0 :   mColumnRuleStyle = NS_STYLE_BORDER_STYLE_NONE;
     801               0 :   mColumnRuleColor = NS_RGB(0, 0, 0);
     802               0 :   mColumnRuleColorIsForeground = true;
     803                 : 
     804               0 :   mTwipsPerPixel = aPresContext->AppUnitsPerDevPixel();
     805               0 : }
     806                 : 
     807               0 : nsStyleColumn::~nsStyleColumn() 
     808                 : {
     809               0 :   MOZ_COUNT_DTOR(nsStyleColumn);
     810               0 : }
     811                 : 
     812               0 : nsStyleColumn::nsStyleColumn(const nsStyleColumn& aSource)
     813                 : {
     814               0 :   MOZ_COUNT_CTOR(nsStyleColumn);
     815               0 :   memcpy((nsStyleColumn*)this, &aSource, sizeof(nsStyleColumn));
     816               0 : }
     817                 : 
     818               0 : nsChangeHint nsStyleColumn::CalcDifference(const nsStyleColumn& aOther) const
     819                 : {
     820               0 :   if ((mColumnWidth.GetUnit() == eStyleUnit_Auto)
     821               0 :       != (aOther.mColumnWidth.GetUnit() == eStyleUnit_Auto) ||
     822                 :       mColumnCount != aOther.mColumnCount)
     823                 :     // We force column count changes to do a reframe, because it's tricky to handle
     824                 :     // some edge cases where the column count gets smaller and content overflows.
     825                 :     // XXX not ideal
     826               0 :     return NS_STYLE_HINT_FRAMECHANGE;
     827                 : 
     828               0 :   if (mColumnWidth != aOther.mColumnWidth ||
     829               0 :       mColumnGap != aOther.mColumnGap)
     830               0 :     return NS_STYLE_HINT_REFLOW;
     831                 : 
     832               0 :   if (GetComputedColumnRuleWidth() != aOther.GetComputedColumnRuleWidth() ||
     833                 :       mColumnRuleStyle != aOther.mColumnRuleStyle ||
     834                 :       mColumnRuleColor != aOther.mColumnRuleColor ||
     835                 :       mColumnRuleColorIsForeground != aOther.mColumnRuleColorIsForeground)
     836               0 :     return NS_STYLE_HINT_VISUAL;
     837                 : 
     838               0 :   return NS_STYLE_HINT_NONE;
     839                 : }
     840                 : 
     841                 : #ifdef DEBUG
     842                 : /* static */
     843               0 : nsChangeHint nsStyleColumn::MaxDifference()
     844                 : {
     845               0 :   return NS_STYLE_HINT_FRAMECHANGE;
     846                 : }
     847                 : #endif
     848                 : 
     849                 : // --------------------
     850                 : // nsStyleSVG
     851                 : //
     852               0 : nsStyleSVG::nsStyleSVG() 
     853                 : {
     854               0 :     MOZ_COUNT_CTOR(nsStyleSVG);
     855               0 :     mFill.mType              = eStyleSVGPaintType_Color;
     856               0 :     mFill.mPaint.mColor      = NS_RGB(0,0,0);
     857               0 :     mFill.mFallbackColor     = NS_RGB(0,0,0);
     858               0 :     mStroke.mType            = eStyleSVGPaintType_None;
     859               0 :     mStroke.mPaint.mColor    = NS_RGB(0,0,0);
     860               0 :     mStroke.mFallbackColor   = NS_RGB(0,0,0);
     861               0 :     mStrokeDasharray         = nsnull;
     862                 : 
     863               0 :     mStrokeDashoffset.SetCoordValue(0);
     864               0 :     mStrokeWidth.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
     865                 : 
     866               0 :     mFillOpacity             = 1.0f;
     867               0 :     mStrokeMiterlimit        = 4.0f;
     868               0 :     mStrokeOpacity           = 1.0f;
     869                 : 
     870               0 :     mStrokeDasharrayLength   = 0;
     871               0 :     mClipRule                = NS_STYLE_FILL_RULE_NONZERO;
     872               0 :     mColorInterpolation      = NS_STYLE_COLOR_INTERPOLATION_SRGB;
     873               0 :     mColorInterpolationFilters = NS_STYLE_COLOR_INTERPOLATION_LINEARRGB;
     874               0 :     mFillRule                = NS_STYLE_FILL_RULE_NONZERO;
     875               0 :     mImageRendering          = NS_STYLE_IMAGE_RENDERING_AUTO;
     876               0 :     mShapeRendering          = NS_STYLE_SHAPE_RENDERING_AUTO;
     877               0 :     mStrokeLinecap           = NS_STYLE_STROKE_LINECAP_BUTT;
     878               0 :     mStrokeLinejoin          = NS_STYLE_STROKE_LINEJOIN_MITER;
     879               0 :     mTextAnchor              = NS_STYLE_TEXT_ANCHOR_START;
     880               0 :     mTextRendering           = NS_STYLE_TEXT_RENDERING_AUTO;
     881               0 : }
     882                 : 
     883               0 : nsStyleSVG::~nsStyleSVG() 
     884                 : {
     885               0 :   MOZ_COUNT_DTOR(nsStyleSVG);
     886               0 :   delete [] mStrokeDasharray;
     887               0 : }
     888                 : 
     889               0 : nsStyleSVG::nsStyleSVG(const nsStyleSVG& aSource)
     890                 : {
     891               0 :   MOZ_COUNT_CTOR(nsStyleSVG);
     892               0 :   mFill = aSource.mFill;
     893               0 :   mStroke = aSource.mStroke;
     894                 : 
     895               0 :   mMarkerEnd = aSource.mMarkerEnd;
     896               0 :   mMarkerMid = aSource.mMarkerMid;
     897               0 :   mMarkerStart = aSource.mMarkerStart;
     898                 : 
     899               0 :   mStrokeDasharrayLength = aSource.mStrokeDasharrayLength;
     900               0 :   if (aSource.mStrokeDasharray) {
     901               0 :     mStrokeDasharray = new nsStyleCoord[mStrokeDasharrayLength];
     902               0 :     if (mStrokeDasharray)
     903                 :       memcpy(mStrokeDasharray,
     904                 :              aSource.mStrokeDasharray,
     905               0 :              mStrokeDasharrayLength * sizeof(nsStyleCoord));
     906                 :     else
     907               0 :       mStrokeDasharrayLength = 0;
     908                 :   } else {
     909               0 :     mStrokeDasharray = nsnull;
     910                 :   }
     911                 : 
     912               0 :   mStrokeDashoffset = aSource.mStrokeDashoffset;
     913               0 :   mStrokeWidth = aSource.mStrokeWidth;
     914                 : 
     915               0 :   mFillOpacity = aSource.mFillOpacity;
     916               0 :   mStrokeMiterlimit = aSource.mStrokeMiterlimit;
     917               0 :   mStrokeOpacity = aSource.mStrokeOpacity;
     918                 : 
     919               0 :   mClipRule = aSource.mClipRule;
     920               0 :   mColorInterpolation = aSource.mColorInterpolation;
     921               0 :   mColorInterpolationFilters = aSource.mColorInterpolationFilters;
     922               0 :   mFillRule = aSource.mFillRule;
     923               0 :   mImageRendering = aSource.mImageRendering;
     924               0 :   mShapeRendering = aSource.mShapeRendering;
     925               0 :   mStrokeLinecap = aSource.mStrokeLinecap;
     926               0 :   mStrokeLinejoin = aSource.mStrokeLinejoin;
     927               0 :   mTextAnchor = aSource.mTextAnchor;
     928               0 :   mTextRendering = aSource.mTextRendering;
     929               0 : }
     930                 : 
     931               0 : static bool PaintURIChanged(const nsStyleSVGPaint& aPaint1,
     932                 :                               const nsStyleSVGPaint& aPaint2)
     933                 : {
     934               0 :   if (aPaint1.mType != aPaint2.mType) {
     935                 :     return aPaint1.mType == eStyleSVGPaintType_Server ||
     936               0 :            aPaint2.mType == eStyleSVGPaintType_Server;
     937                 :   }
     938                 :   return aPaint1.mType == eStyleSVGPaintType_Server &&
     939               0 :     !EqualURIs(aPaint1.mPaint.mPaintServer, aPaint2.mPaint.mPaintServer);
     940                 : }
     941                 : 
     942               0 : nsChangeHint nsStyleSVG::CalcDifference(const nsStyleSVG& aOther) const
     943                 : {
     944               0 :   nsChangeHint hint = nsChangeHint(0);
     945                 : 
     946               0 :   if (mTextRendering != aOther.mTextRendering) {
     947               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     948                 :     // May be needed for non-svg frames
     949               0 :     NS_UpdateHint(hint, nsChangeHint_ReflowFrame);
     950                 :   }
     951                 : 
     952               0 :   if (!EqualURIs(mMarkerEnd, aOther.mMarkerEnd) ||
     953               0 :       !EqualURIs(mMarkerMid, aOther.mMarkerMid) ||
     954               0 :       !EqualURIs(mMarkerStart, aOther.mMarkerStart)) {
     955               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     956               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateEffects);
     957               0 :     return hint;
     958                 :   }
     959                 : 
     960               0 :   if (mFill != aOther.mFill ||
     961               0 :       mStroke != aOther.mStroke) {
     962               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     963               0 :     if (PaintURIChanged(mFill, aOther.mFill) ||
     964               0 :         PaintURIChanged(mStroke, aOther.mStroke)) {
     965               0 :       NS_UpdateHint(hint, nsChangeHint_UpdateEffects);
     966                 :     }
     967                 :     // Nothing more to do, below we can only set "repaint"
     968               0 :     return hint;
     969                 :   }
     970                 : 
     971               0 :   if ( mStrokeDashoffset      != aOther.mStrokeDashoffset      ||
     972               0 :        mStrokeWidth           != aOther.mStrokeWidth           ||
     973                 : 
     974                 :        mFillOpacity           != aOther.mFillOpacity           ||
     975                 :        mStrokeMiterlimit      != aOther.mStrokeMiterlimit      ||
     976                 :        mStrokeOpacity         != aOther.mStrokeOpacity         ||
     977                 : 
     978                 :        mClipRule              != aOther.mClipRule              ||
     979                 :        mColorInterpolation    != aOther.mColorInterpolation    ||
     980                 :        mColorInterpolationFilters != aOther.mColorInterpolationFilters ||
     981                 :        mFillRule              != aOther.mFillRule              ||
     982                 :        mImageRendering        != aOther.mImageRendering        ||
     983                 :        mShapeRendering        != aOther.mShapeRendering        ||
     984                 :        mStrokeDasharrayLength != aOther.mStrokeDasharrayLength ||
     985                 :        mStrokeLinecap         != aOther.mStrokeLinecap         ||
     986                 :        mStrokeLinejoin        != aOther.mStrokeLinejoin        ||
     987                 :        mTextAnchor            != aOther.mTextAnchor) {
     988               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     989               0 :     return hint;
     990                 :   }
     991                 : 
     992                 :   // length of stroke dasharrays are the same (tested above) - check entries
     993               0 :   for (PRUint32 i=0; i<mStrokeDasharrayLength; i++)
     994               0 :     if (mStrokeDasharray[i] != aOther.mStrokeDasharray[i]) {
     995               0 :       NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     996               0 :       return hint;
     997                 :     }
     998                 : 
     999               0 :   return hint;
    1000                 : }
    1001                 : 
    1002                 : #ifdef DEBUG
    1003                 : /* static */
    1004               0 : nsChangeHint nsStyleSVG::MaxDifference()
    1005                 : {
    1006                 :   return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects,
    1007                 :                                        nsChangeHint_ReflowFrame),
    1008               0 :                                        nsChangeHint_RepaintFrame);
    1009                 : }
    1010                 : #endif
    1011                 : 
    1012                 : // --------------------
    1013                 : // nsStyleSVGReset
    1014                 : //
    1015               0 : nsStyleSVGReset::nsStyleSVGReset() 
    1016                 : {
    1017               0 :     MOZ_COUNT_CTOR(nsStyleSVGReset);
    1018               0 :     mStopColor               = NS_RGB(0,0,0);
    1019               0 :     mFloodColor              = NS_RGB(0,0,0);
    1020               0 :     mLightingColor           = NS_RGB(255,255,255);
    1021               0 :     mClipPath                = nsnull;
    1022               0 :     mFilter                  = nsnull;
    1023               0 :     mMask                    = nsnull;
    1024               0 :     mStopOpacity             = 1.0f;
    1025               0 :     mFloodOpacity            = 1.0f;
    1026               0 :     mDominantBaseline        = NS_STYLE_DOMINANT_BASELINE_AUTO;
    1027               0 : }
    1028                 : 
    1029               0 : nsStyleSVGReset::~nsStyleSVGReset() 
    1030                 : {
    1031               0 :   MOZ_COUNT_DTOR(nsStyleSVGReset);
    1032               0 : }
    1033                 : 
    1034               0 : nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
    1035                 : {
    1036               0 :   MOZ_COUNT_CTOR(nsStyleSVGReset);
    1037               0 :   mStopColor = aSource.mStopColor;
    1038               0 :   mFloodColor = aSource.mFloodColor;
    1039               0 :   mLightingColor = aSource.mLightingColor;
    1040               0 :   mClipPath = aSource.mClipPath;
    1041               0 :   mFilter = aSource.mFilter;
    1042               0 :   mMask = aSource.mMask;
    1043               0 :   mStopOpacity = aSource.mStopOpacity;
    1044               0 :   mFloodOpacity = aSource.mFloodOpacity;
    1045               0 :   mDominantBaseline = aSource.mDominantBaseline;
    1046               0 : }
    1047                 : 
    1048               0 : nsChangeHint nsStyleSVGReset::CalcDifference(const nsStyleSVGReset& aOther) const
    1049                 : {
    1050               0 :   nsChangeHint hint = nsChangeHint(0);
    1051                 : 
    1052               0 :   if (!EqualURIs(mClipPath, aOther.mClipPath) ||
    1053               0 :       !EqualURIs(mFilter, aOther.mFilter)     ||
    1054               0 :       !EqualURIs(mMask, aOther.mMask)) {
    1055               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateEffects);
    1056               0 :     NS_UpdateHint(hint, nsChangeHint_ReflowFrame);
    1057               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
    1058               0 :   } else if (mStopColor        != aOther.mStopColor     ||
    1059                 :              mFloodColor       != aOther.mFloodColor    ||
    1060                 :              mLightingColor    != aOther.mLightingColor ||
    1061                 :              mStopOpacity      != aOther.mStopOpacity   ||
    1062                 :              mFloodOpacity     != aOther.mFloodOpacity  ||
    1063                 :              mDominantBaseline != aOther.mDominantBaseline)
    1064               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
    1065                 : 
    1066               0 :   return hint;
    1067                 : }
    1068                 : 
    1069                 : #ifdef DEBUG
    1070                 : /* static */
    1071               0 : nsChangeHint nsStyleSVGReset::MaxDifference()
    1072                 : {
    1073                 :   return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects,
    1074                 :                                        nsChangeHint_ReflowFrame),
    1075               0 :                                        nsChangeHint_RepaintFrame);
    1076                 : }
    1077                 : #endif
    1078                 : 
    1079                 : // nsStyleSVGPaint implementation
    1080               0 : nsStyleSVGPaint::~nsStyleSVGPaint()
    1081                 : {
    1082               0 :   if (mType == eStyleSVGPaintType_Server) {
    1083               0 :     NS_IF_RELEASE(mPaint.mPaintServer);
    1084                 :   }
    1085               0 : }
    1086                 : 
    1087                 : void
    1088               0 : nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType)
    1089                 : {
    1090               0 :   if (mType == eStyleSVGPaintType_Server) {
    1091               0 :     this->~nsStyleSVGPaint();
    1092               0 :     new (this) nsStyleSVGPaint();
    1093                 :   }
    1094               0 :   mType = aType;
    1095               0 : }
    1096                 : 
    1097               0 : nsStyleSVGPaint& nsStyleSVGPaint::operator=(const nsStyleSVGPaint& aOther) 
    1098                 : {
    1099               0 :   if (this == &aOther)
    1100               0 :     return *this;
    1101                 : 
    1102               0 :   SetType(aOther.mType);
    1103                 : 
    1104               0 :   mFallbackColor = aOther.mFallbackColor;
    1105               0 :   if (mType == eStyleSVGPaintType_Server) {
    1106               0 :     mPaint.mPaintServer = aOther.mPaint.mPaintServer;
    1107               0 :     NS_IF_ADDREF(mPaint.mPaintServer);
    1108                 :   } else {
    1109               0 :     mPaint.mColor = aOther.mPaint.mColor;
    1110                 :   }
    1111               0 :   return *this;
    1112                 : }
    1113                 : 
    1114               0 : bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const
    1115                 : {
    1116               0 :   if (mType != aOther.mType)
    1117               0 :     return false;
    1118               0 :   if (mType == eStyleSVGPaintType_Server)
    1119               0 :     return EqualURIs(mPaint.mPaintServer, aOther.mPaint.mPaintServer) &&
    1120               0 :            mFallbackColor == aOther.mFallbackColor;
    1121               0 :   if (mType == eStyleSVGPaintType_None)
    1122               0 :     return true;
    1123               0 :   return mPaint.mColor == aOther.mPaint.mColor;
    1124                 : }
    1125                 : 
    1126                 : 
    1127                 : // --------------------
    1128                 : // nsStylePosition
    1129                 : //
    1130               0 : nsStylePosition::nsStylePosition(void) 
    1131                 : { 
    1132               0 :   MOZ_COUNT_CTOR(nsStylePosition);
    1133                 :   // positioning values not inherited
    1134               0 :   nsStyleCoord  autoCoord(eStyleUnit_Auto);
    1135               0 :   mOffset.SetLeft(autoCoord);
    1136               0 :   mOffset.SetTop(autoCoord);
    1137               0 :   mOffset.SetRight(autoCoord);
    1138               0 :   mOffset.SetBottom(autoCoord);
    1139               0 :   mWidth.SetAutoValue();
    1140               0 :   mMinWidth.SetCoordValue(0);
    1141               0 :   mMaxWidth.SetNoneValue();
    1142               0 :   mHeight.SetAutoValue();
    1143               0 :   mMinHeight.SetCoordValue(0);
    1144               0 :   mMaxHeight.SetNoneValue();
    1145               0 :   mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
    1146               0 :   mZIndex.SetAutoValue();
    1147               0 : }
    1148                 : 
    1149               0 : nsStylePosition::~nsStylePosition(void) 
    1150                 : { 
    1151               0 :   MOZ_COUNT_DTOR(nsStylePosition);
    1152               0 : }
    1153                 : 
    1154               0 : nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
    1155                 : {
    1156               0 :   MOZ_COUNT_CTOR(nsStylePosition);
    1157               0 :   memcpy((nsStylePosition*)this, &aSource, sizeof(nsStylePosition));
    1158               0 : }
    1159                 : 
    1160               0 : nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) const
    1161                 : {
    1162                 :   nsChangeHint hint =
    1163               0 :     (mZIndex == aOther.mZIndex) ? NS_STYLE_HINT_NONE : nsChangeHint_RepaintFrame;
    1164                 : 
    1165               0 :   if (mBoxSizing != aOther.mBoxSizing) {
    1166                 :     // Can affect both widths and heights; just a bad scene.
    1167               0 :     return NS_CombineHint(hint, nsChangeHint_ReflowFrame);
    1168                 :   }
    1169                 : 
    1170               0 :   if (mHeight != aOther.mHeight ||
    1171               0 :       mMinHeight != aOther.mMinHeight ||
    1172               0 :       mMaxHeight != aOther.mMaxHeight) {
    1173                 :     // Height changes can affect descendant intrinsic sizes due to replaced
    1174                 :     // elements with percentage heights in descendants which also have
    1175                 :     // percentage heights.  And due to our not-so-great computation of mVResize
    1176                 :     // in nsHTMLReflowState, they do need to force reflow of the whole subtree.
    1177                 :     // XXXbz due to XUL caching heights as well, height changes also need to
    1178                 :     // clear ancestor intrinsics!
    1179               0 :     return NS_CombineHint(hint, nsChangeHint_ReflowFrame);
    1180                 :   }
    1181                 : 
    1182               0 :   if ((mWidth == aOther.mWidth) &&
    1183               0 :       (mMinWidth == aOther.mMinWidth) &&
    1184               0 :       (mMaxWidth == aOther.mMaxWidth)) {
    1185               0 :     if (mOffset == aOther.mOffset) {
    1186               0 :       return hint;
    1187                 :     } else {
    1188                 :       // Offset changes only affect positioned content, and can't affect any
    1189                 :       // intrinsic widths.  They also don't need to force reflow of
    1190                 :       // descendants.
    1191               0 :       return NS_CombineHint(hint, nsChangeHint_NeedReflow);
    1192                 :     }
    1193                 :   }
    1194                 : 
    1195                 :   // None of our width differences can affect descendant intrinsic
    1196                 :   // sizes and none of them need to force children to reflow.
    1197                 :   return
    1198                 :     NS_CombineHint(hint,
    1199                 :                    NS_SubtractHint(nsChangeHint_ReflowFrame,
    1200                 :                                    NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
    1201               0 :                                                   nsChangeHint_NeedDirtyReflow)));
    1202                 : }
    1203                 : 
    1204                 : #ifdef DEBUG
    1205                 : /* static */
    1206               0 : nsChangeHint nsStylePosition::MaxDifference()
    1207                 : {
    1208               0 :   return NS_STYLE_HINT_REFLOW;
    1209                 : }
    1210                 : #endif
    1211                 : 
    1212                 : /* static */ bool
    1213               0 : nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord &aCoord)
    1214                 : {
    1215               0 :   return aCoord.GetUnit() == eStyleUnit_Auto ||
    1216               0 :          aCoord.HasPercent() ||
    1217               0 :          (aCoord.GetUnit() == eStyleUnit_Enumerated &&
    1218               0 :           (aCoord.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT ||
    1219               0 :            aCoord.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE));
    1220                 : }
    1221                 : 
    1222                 : // --------------------
    1223                 : // nsStyleTable
    1224                 : //
    1225                 : 
    1226               0 : nsStyleTable::nsStyleTable() 
    1227                 : { 
    1228               0 :   MOZ_COUNT_CTOR(nsStyleTable);
    1229                 :   // values not inherited
    1230               0 :   mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
    1231               0 :   mCols  = NS_STYLE_TABLE_COLS_NONE;
    1232               0 :   mFrame = NS_STYLE_TABLE_FRAME_NONE;
    1233               0 :   mRules = NS_STYLE_TABLE_RULES_NONE;
    1234               0 :   mSpan = 1;
    1235               0 : }
    1236                 : 
    1237               0 : nsStyleTable::~nsStyleTable(void) 
    1238                 : {
    1239               0 :   MOZ_COUNT_DTOR(nsStyleTable);
    1240               0 : }
    1241                 : 
    1242               0 : nsStyleTable::nsStyleTable(const nsStyleTable& aSource)
    1243                 : {
    1244               0 :   MOZ_COUNT_CTOR(nsStyleTable);
    1245               0 :   memcpy((nsStyleTable*)this, &aSource, sizeof(nsStyleTable));
    1246               0 : }
    1247                 : 
    1248               0 : nsChangeHint nsStyleTable::CalcDifference(const nsStyleTable& aOther) const
    1249                 : {
    1250                 :   // Changes in mRules may require reframing (if border-collapse stuff changes, for example).
    1251               0 :   if (mRules != aOther.mRules || mSpan != aOther.mSpan ||
    1252                 :       mLayoutStrategy != aOther.mLayoutStrategy)
    1253               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    1254               0 :   if (mFrame != aOther.mFrame || mCols != aOther.mCols)
    1255               0 :     return NS_STYLE_HINT_REFLOW;
    1256               0 :   return NS_STYLE_HINT_NONE;
    1257                 : }
    1258                 : 
    1259                 : #ifdef DEBUG
    1260                 : /* static */
    1261               0 : nsChangeHint nsStyleTable::MaxDifference()
    1262                 : {
    1263               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    1264                 : }
    1265                 : #endif
    1266                 : 
    1267                 : // -----------------------
    1268                 : // nsStyleTableBorder
    1269                 : 
    1270               0 : nsStyleTableBorder::nsStyleTableBorder(nsPresContext* aPresContext) 
    1271                 : { 
    1272               0 :   MOZ_COUNT_CTOR(nsStyleTableBorder);
    1273               0 :   mBorderCollapse = NS_STYLE_BORDER_SEPARATE;
    1274                 : 
    1275               0 :   nsCompatibility compatMode = eCompatibility_FullStandards;
    1276               0 :   if (aPresContext)
    1277               0 :     compatMode = aPresContext->CompatibilityMode();
    1278                 :   mEmptyCells = (compatMode == eCompatibility_NavQuirks)
    1279                 :                   ? NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND     
    1280               0 :                   : NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
    1281               0 :   mCaptionSide = NS_STYLE_CAPTION_SIDE_TOP;
    1282               0 :   mBorderSpacingX = 0;
    1283               0 :   mBorderSpacingY = 0;
    1284               0 : }
    1285                 : 
    1286               0 : nsStyleTableBorder::~nsStyleTableBorder(void) 
    1287                 : {
    1288               0 :   MOZ_COUNT_DTOR(nsStyleTableBorder);
    1289               0 : }
    1290                 : 
    1291               0 : nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder& aSource)
    1292                 : {
    1293               0 :   MOZ_COUNT_CTOR(nsStyleTableBorder);
    1294               0 :   memcpy((nsStyleTableBorder*)this, &aSource, sizeof(nsStyleTableBorder));
    1295               0 : }
    1296                 : 
    1297               0 : nsChangeHint nsStyleTableBorder::CalcDifference(const nsStyleTableBorder& aOther) const
    1298                 : {
    1299                 :   // Border-collapse changes need a reframe, because we use a different frame
    1300                 :   // class for table cells in the collapsed border model.  This is used to
    1301                 :   // conserve memory when using the separated border model (collapsed borders
    1302                 :   // require extra state to be stored).
    1303               0 :   if (mBorderCollapse != aOther.mBorderCollapse) {
    1304               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    1305                 :   }
    1306                 :   
    1307               0 :   if ((mCaptionSide == aOther.mCaptionSide) &&
    1308                 :       (mBorderSpacingX == aOther.mBorderSpacingX) &&
    1309                 :       (mBorderSpacingY == aOther.mBorderSpacingY)) {
    1310               0 :     if (mEmptyCells == aOther.mEmptyCells)
    1311               0 :       return NS_STYLE_HINT_NONE;
    1312               0 :     return NS_STYLE_HINT_VISUAL;
    1313                 :   }
    1314                 :   else
    1315               0 :     return NS_STYLE_HINT_REFLOW;
    1316                 : }
    1317                 : 
    1318                 : #ifdef DEBUG
    1319                 : /* static */
    1320               0 : nsChangeHint nsStyleTableBorder::MaxDifference()
    1321                 : {
    1322               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    1323                 : }
    1324                 : #endif
    1325                 : 
    1326                 : // --------------------
    1327                 : // nsStyleColor
    1328                 : //
    1329                 : 
    1330               0 : nsStyleColor::nsStyleColor(nsPresContext* aPresContext)
    1331                 : {
    1332               0 :   MOZ_COUNT_CTOR(nsStyleColor);
    1333               0 :   mColor = aPresContext->DefaultColor();
    1334               0 : }
    1335                 : 
    1336               0 : nsStyleColor::nsStyleColor(const nsStyleColor& aSource)
    1337                 : {
    1338               0 :   MOZ_COUNT_CTOR(nsStyleColor);
    1339               0 :   mColor = aSource.mColor;
    1340               0 : }
    1341                 : 
    1342               0 : nsChangeHint nsStyleColor::CalcDifference(const nsStyleColor& aOther) const
    1343                 : {
    1344               0 :   if (mColor == aOther.mColor)
    1345               0 :     return NS_STYLE_HINT_NONE;
    1346               0 :   return NS_STYLE_HINT_VISUAL;
    1347                 : }
    1348                 : 
    1349                 : #ifdef DEBUG
    1350                 : /* static */
    1351               0 : nsChangeHint nsStyleColor::MaxDifference()
    1352                 : {
    1353               0 :   return NS_STYLE_HINT_VISUAL;
    1354                 : }
    1355                 : #endif
    1356                 : 
    1357                 : // --------------------
    1358                 : // nsStyleGradient
    1359                 : //
    1360                 : bool
    1361               0 : nsStyleGradient::operator==(const nsStyleGradient& aOther) const
    1362                 : {
    1363               0 :   NS_ABORT_IF_FALSE(mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
    1364                 :                     mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
    1365                 :                     "incorrect combination of shape and size");
    1366               0 :   NS_ABORT_IF_FALSE(aOther.mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
    1367                 :                     aOther.mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
    1368                 :                     "incorrect combination of shape and size");
    1369                 : 
    1370               0 :   if (mShape != aOther.mShape ||
    1371                 :       mSize != aOther.mSize ||
    1372                 :       mRepeating != aOther.mRepeating ||
    1373                 :       mToCorner != aOther.mToCorner ||
    1374               0 :       mBgPosX != aOther.mBgPosX ||
    1375               0 :       mBgPosY != aOther.mBgPosY ||
    1376               0 :       mAngle != aOther.mAngle)
    1377               0 :     return false;
    1378                 : 
    1379               0 :   if (mStops.Length() != aOther.mStops.Length())
    1380               0 :     return false;
    1381                 : 
    1382               0 :   for (PRUint32 i = 0; i < mStops.Length(); i++) {
    1383               0 :     if (mStops[i].mLocation != aOther.mStops[i].mLocation ||
    1384               0 :         mStops[i].mColor != aOther.mStops[i].mColor)
    1385               0 :       return false;
    1386                 :   }
    1387                 : 
    1388               0 :   return true;
    1389                 : }
    1390                 : 
    1391               0 : nsStyleGradient::nsStyleGradient(void)
    1392                 :   : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR)
    1393                 :   , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)
    1394                 :   , mRepeating(false)
    1395               0 :   , mToCorner(false)
    1396                 : {
    1397               0 : }
    1398                 : 
    1399                 : bool
    1400               0 : nsStyleGradient::IsOpaque()
    1401                 : {
    1402               0 :   for (PRUint32 i = 0; i < mStops.Length(); i++) {
    1403               0 :     if (NS_GET_A(mStops[i].mColor) < 255)
    1404               0 :       return false;
    1405                 :   }
    1406               0 :   return true;
    1407                 : }
    1408                 : 
    1409                 : // --------------------
    1410                 : // nsStyleImage
    1411                 : //
    1412                 : 
    1413               0 : nsStyleImage::nsStyleImage()
    1414                 :   : mType(eStyleImageType_Null)
    1415                 :   , mCropRect(nsnull)
    1416                 : #ifdef DEBUG
    1417               0 :   , mImageTracked(false)
    1418                 : #endif
    1419                 : {
    1420               0 :   MOZ_COUNT_CTOR(nsStyleImage);
    1421               0 : }
    1422                 : 
    1423               0 : nsStyleImage::~nsStyleImage()
    1424                 : {
    1425               0 :   MOZ_COUNT_DTOR(nsStyleImage);
    1426               0 :   if (mType != eStyleImageType_Null)
    1427               0 :     SetNull();
    1428               0 : }
    1429                 : 
    1430               0 : nsStyleImage::nsStyleImage(const nsStyleImage& aOther)
    1431                 :   : mType(eStyleImageType_Null)
    1432                 :   , mCropRect(nsnull)
    1433                 : #ifdef DEBUG
    1434               0 :   , mImageTracked(false)
    1435                 : #endif
    1436                 : {
    1437                 :   // We need our own copy constructor because we don't want
    1438                 :   // to copy the reference count
    1439               0 :   MOZ_COUNT_CTOR(nsStyleImage);
    1440               0 :   DoCopy(aOther);
    1441               0 : }
    1442                 : 
    1443                 : nsStyleImage&
    1444               0 : nsStyleImage::operator=(const nsStyleImage& aOther)
    1445                 : {
    1446               0 :   if (this != &aOther)
    1447               0 :     DoCopy(aOther);
    1448                 : 
    1449               0 :   return *this;
    1450                 : }
    1451                 : 
    1452                 : void
    1453               0 : nsStyleImage::DoCopy(const nsStyleImage& aOther)
    1454                 : {
    1455               0 :   SetNull();
    1456                 : 
    1457               0 :   if (aOther.mType == eStyleImageType_Image)
    1458               0 :     SetImageData(aOther.mImage);
    1459               0 :   else if (aOther.mType == eStyleImageType_Gradient)
    1460               0 :     SetGradientData(aOther.mGradient);
    1461               0 :   else if (aOther.mType == eStyleImageType_Element)
    1462               0 :     SetElementId(aOther.mElementId);
    1463                 : 
    1464               0 :   SetCropRect(aOther.mCropRect);
    1465               0 : }
    1466                 : 
    1467                 : void
    1468               0 : nsStyleImage::SetNull()
    1469                 : {
    1470               0 :   NS_ABORT_IF_FALSE(!mImageTracked,
    1471                 :                     "Calling SetNull() with image tracked!");
    1472                 : 
    1473               0 :   if (mType == eStyleImageType_Gradient)
    1474               0 :     mGradient->Release();
    1475               0 :   else if (mType == eStyleImageType_Image)
    1476               0 :     NS_RELEASE(mImage);
    1477               0 :   else if (mType == eStyleImageType_Element)
    1478               0 :     NS_Free(mElementId);
    1479                 : 
    1480               0 :   mType = eStyleImageType_Null;
    1481               0 :   mCropRect = nsnull;
    1482               0 : }
    1483                 : 
    1484                 : void
    1485               0 : nsStyleImage::SetImageData(imgIRequest* aImage)
    1486                 : {
    1487               0 :   NS_ABORT_IF_FALSE(!mImageTracked,
    1488                 :                     "Setting a new image without untracking the old one!");
    1489                 : 
    1490               0 :   NS_IF_ADDREF(aImage);
    1491                 : 
    1492               0 :   if (mType != eStyleImageType_Null)
    1493               0 :     SetNull();
    1494                 : 
    1495               0 :   if (aImage) {
    1496               0 :     mImage = aImage;
    1497               0 :     mType = eStyleImageType_Image;
    1498                 :   }
    1499               0 : }
    1500                 : 
    1501                 : void
    1502               0 : nsStyleImage::TrackImage(nsPresContext* aContext)
    1503                 : {
    1504                 :   // Sanity
    1505               0 :   NS_ABORT_IF_FALSE(!mImageTracked, "Already tracking image!");
    1506               0 :   NS_ABORT_IF_FALSE(mType == eStyleImageType_Image,
    1507                 :                     "Can't track image when there isn't one!");
    1508                 : 
    1509                 :   // Register the image with the document
    1510               0 :   nsIDocument* doc = aContext->Document();
    1511               0 :   if (doc)
    1512               0 :     doc->AddImage(mImage);
    1513                 : 
    1514                 :   // Mark state
    1515                 : #ifdef DEBUG
    1516               0 :   mImageTracked = true;
    1517                 : #endif
    1518               0 : }
    1519                 : 
    1520                 : void
    1521               0 : nsStyleImage::UntrackImage(nsPresContext* aContext)
    1522                 : {
    1523                 :   // Sanity
    1524               0 :   NS_ABORT_IF_FALSE(mImageTracked, "Image not tracked!");
    1525               0 :   NS_ABORT_IF_FALSE(mType == eStyleImageType_Image,
    1526                 :                     "Can't untrack image when there isn't one!");
    1527                 : 
    1528                 :   // Unregister the image with the document
    1529               0 :   nsIDocument* doc = aContext->Document();
    1530               0 :   if (doc)
    1531               0 :     doc->RemoveImage(mImage);
    1532                 : 
    1533                 :   // Mark state
    1534                 : #ifdef DEBUG
    1535               0 :   mImageTracked = false;
    1536                 : #endif
    1537               0 : }
    1538                 : 
    1539                 : void
    1540               0 : nsStyleImage::SetGradientData(nsStyleGradient* aGradient)
    1541                 : {
    1542               0 :   if (aGradient)
    1543               0 :     aGradient->AddRef();
    1544                 : 
    1545               0 :   if (mType != eStyleImageType_Null)
    1546               0 :     SetNull();
    1547                 : 
    1548               0 :   if (aGradient) {
    1549               0 :     mGradient = aGradient;
    1550               0 :     mType = eStyleImageType_Gradient;
    1551                 :   }
    1552               0 : }
    1553                 : 
    1554                 : void
    1555               0 : nsStyleImage::SetElementId(const PRUnichar* aElementId)
    1556                 : {
    1557               0 :   if (mType != eStyleImageType_Null)
    1558               0 :     SetNull();
    1559                 : 
    1560               0 :   if (aElementId) {
    1561               0 :     mElementId = NS_strdup(aElementId);
    1562               0 :     mType = eStyleImageType_Element;
    1563                 :   }
    1564               0 : }
    1565                 : 
    1566                 : void
    1567               0 : nsStyleImage::SetCropRect(nsStyleSides* aCropRect)
    1568                 : {
    1569               0 :   if (aCropRect) {
    1570               0 :     mCropRect = new nsStyleSides(*aCropRect);
    1571                 :     // There is really not much we can do if 'new' fails
    1572                 :   } else {
    1573               0 :     mCropRect = nsnull;
    1574                 :   }
    1575               0 : }
    1576                 : 
    1577                 : static PRInt32
    1578               0 : ConvertToPixelCoord(const nsStyleCoord& aCoord, PRInt32 aPercentScale)
    1579                 : {
    1580                 :   double pixelValue;
    1581               0 :   switch (aCoord.GetUnit()) {
    1582                 :     case eStyleUnit_Percent:
    1583               0 :       pixelValue = aCoord.GetPercentValue() * aPercentScale;
    1584               0 :       break;
    1585                 :     case eStyleUnit_Factor:
    1586               0 :       pixelValue = aCoord.GetFactorValue();
    1587               0 :       break;
    1588                 :     default:
    1589               0 :       NS_NOTREACHED("unexpected unit for image crop rect");
    1590               0 :       return 0;
    1591                 :   }
    1592               0 :   NS_ABORT_IF_FALSE(pixelValue >= 0, "we ensured non-negative while parsing");
    1593               0 :   pixelValue = NS_MIN(pixelValue, double(PR_INT32_MAX)); // avoid overflow
    1594               0 :   return NS_lround(pixelValue);
    1595                 : }
    1596                 : 
    1597                 : bool
    1598               0 : nsStyleImage::ComputeActualCropRect(nsIntRect& aActualCropRect,
    1599                 :                                     bool* aIsEntireImage) const
    1600                 : {
    1601               0 :   if (mType != eStyleImageType_Image)
    1602               0 :     return false;
    1603                 : 
    1604               0 :   nsCOMPtr<imgIContainer> imageContainer;
    1605               0 :   mImage->GetImage(getter_AddRefs(imageContainer));
    1606               0 :   if (!imageContainer)
    1607               0 :     return false;
    1608                 : 
    1609               0 :   nsIntSize imageSize;
    1610               0 :   imageContainer->GetWidth(&imageSize.width);
    1611               0 :   imageContainer->GetHeight(&imageSize.height);
    1612               0 :   if (imageSize.width <= 0 || imageSize.height <= 0)
    1613               0 :     return false;
    1614                 : 
    1615               0 :   PRInt32 left   = ConvertToPixelCoord(mCropRect->GetLeft(),   imageSize.width);
    1616               0 :   PRInt32 top    = ConvertToPixelCoord(mCropRect->GetTop(),    imageSize.height);
    1617               0 :   PRInt32 right  = ConvertToPixelCoord(mCropRect->GetRight(),  imageSize.width);
    1618               0 :   PRInt32 bottom = ConvertToPixelCoord(mCropRect->GetBottom(), imageSize.height);
    1619                 : 
    1620                 :   // IntersectRect() returns an empty rect if we get negative width or height
    1621               0 :   nsIntRect cropRect(left, top, right - left, bottom - top);
    1622               0 :   nsIntRect imageRect(nsIntPoint(0, 0), imageSize);
    1623               0 :   aActualCropRect.IntersectRect(imageRect, cropRect);
    1624                 : 
    1625               0 :   if (aIsEntireImage)
    1626               0 :     *aIsEntireImage = aActualCropRect.IsEqualInterior(imageRect);
    1627               0 :   return true;
    1628                 : }
    1629                 : 
    1630                 : nsresult
    1631               0 : nsStyleImage::RequestDecode() const
    1632                 : {
    1633               0 :   if ((mType == eStyleImageType_Image) && mImage)
    1634               0 :     return mImage->RequestDecode();
    1635               0 :   return NS_OK;
    1636                 : }
    1637                 : 
    1638                 : bool
    1639               0 : nsStyleImage::IsOpaque() const
    1640                 : {
    1641               0 :   if (!IsComplete())
    1642               0 :     return false;
    1643                 : 
    1644               0 :   if (mType == eStyleImageType_Gradient)
    1645               0 :     return mGradient->IsOpaque();
    1646                 : 
    1647               0 :   if (mType == eStyleImageType_Element)
    1648               0 :     return false;
    1649                 : 
    1650               0 :   NS_ABORT_IF_FALSE(mType == eStyleImageType_Image, "unexpected image type");
    1651                 : 
    1652               0 :   nsCOMPtr<imgIContainer> imageContainer;
    1653               0 :   mImage->GetImage(getter_AddRefs(imageContainer));
    1654               0 :   NS_ABORT_IF_FALSE(imageContainer, "IsComplete() said image container is ready");
    1655                 : 
    1656                 :   // Check if the crop region of the current image frame is opaque
    1657                 :   bool isOpaque;
    1658               0 :   if (NS_SUCCEEDED(imageContainer->GetCurrentFrameIsOpaque(&isOpaque)) &&
    1659                 :       isOpaque) {
    1660               0 :     if (!mCropRect)
    1661               0 :       return true;
    1662                 : 
    1663                 :     // Must make sure if mCropRect contains at least a pixel.
    1664                 :     // XXX Is this optimization worth it? Maybe I should just return false.
    1665               0 :     nsIntRect actualCropRect;
    1666               0 :     bool rv = ComputeActualCropRect(actualCropRect);
    1667               0 :     NS_ASSERTION(rv, "ComputeActualCropRect() can not fail here");
    1668               0 :     return rv && !actualCropRect.IsEmpty();
    1669                 :   }
    1670                 : 
    1671               0 :   return false;
    1672                 : }
    1673                 : 
    1674                 : bool
    1675               0 : nsStyleImage::IsComplete() const
    1676                 : {
    1677               0 :   switch (mType) {
    1678                 :     case eStyleImageType_Null:
    1679               0 :       return false;
    1680                 :     case eStyleImageType_Gradient:
    1681                 :     case eStyleImageType_Element:
    1682               0 :       return true;
    1683                 :     case eStyleImageType_Image:
    1684                 :     {
    1685               0 :       PRUint32 status = imgIRequest::STATUS_ERROR;
    1686               0 :       return NS_SUCCEEDED(mImage->GetImageStatus(&status)) &&
    1687                 :              (status & imgIRequest::STATUS_SIZE_AVAILABLE) &&
    1688               0 :              (status & imgIRequest::STATUS_FRAME_COMPLETE);
    1689                 :     }
    1690                 :     default:
    1691               0 :       NS_NOTREACHED("unexpected image type");
    1692               0 :       return false;
    1693                 :   }
    1694                 : }
    1695                 : 
    1696                 : static inline bool
    1697               0 : EqualRects(const nsStyleSides* aRect1, const nsStyleSides* aRect2)
    1698                 : {
    1699                 :   return aRect1 == aRect2 || /* handles null== null, and optimize */
    1700               0 :          (aRect1 && aRect2 && *aRect1 == *aRect2);
    1701                 : }
    1702                 : 
    1703                 : bool
    1704               0 : nsStyleImage::operator==(const nsStyleImage& aOther) const
    1705                 : {
    1706               0 :   if (mType != aOther.mType)
    1707               0 :     return false;
    1708                 : 
    1709               0 :   if (!EqualRects(mCropRect, aOther.mCropRect))
    1710               0 :     return false;
    1711                 : 
    1712               0 :   if (mType == eStyleImageType_Image)
    1713               0 :     return EqualImages(mImage, aOther.mImage);
    1714                 : 
    1715               0 :   if (mType == eStyleImageType_Gradient)
    1716               0 :     return *mGradient == *aOther.mGradient;
    1717                 : 
    1718               0 :   if (mType == eStyleImageType_Element)
    1719               0 :     return NS_strcmp(mElementId, aOther.mElementId) == 0;
    1720                 : 
    1721               0 :   return true;
    1722                 : }
    1723                 : 
    1724                 : // --------------------
    1725                 : // nsStyleBackground
    1726                 : //
    1727                 : 
    1728               0 : nsStyleBackground::nsStyleBackground()
    1729                 :   : mAttachmentCount(1)
    1730                 :   , mClipCount(1)
    1731                 :   , mOriginCount(1)
    1732                 :   , mRepeatCount(1)
    1733                 :   , mPositionCount(1)
    1734                 :   , mImageCount(1)
    1735                 :   , mSizeCount(1)
    1736                 :   , mBackgroundColor(NS_RGBA(0, 0, 0, 0))
    1737               0 :   , mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS)
    1738                 : {
    1739               0 :   MOZ_COUNT_CTOR(nsStyleBackground);
    1740               0 :   Layer *onlyLayer = mLayers.AppendElement();
    1741               0 :   NS_ASSERTION(onlyLayer, "auto array must have room for 1 element");
    1742               0 :   onlyLayer->SetInitialValues();
    1743               0 : }
    1744                 : 
    1745               0 : nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
    1746                 :   : mAttachmentCount(aSource.mAttachmentCount)
    1747                 :   , mClipCount(aSource.mClipCount)
    1748                 :   , mOriginCount(aSource.mOriginCount)
    1749                 :   , mRepeatCount(aSource.mRepeatCount)
    1750                 :   , mPositionCount(aSource.mPositionCount)
    1751                 :   , mImageCount(aSource.mImageCount)
    1752                 :   , mSizeCount(aSource.mSizeCount)
    1753                 :   , mLayers(aSource.mLayers) // deep copy
    1754                 :   , mBackgroundColor(aSource.mBackgroundColor)
    1755               0 :   , mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy)
    1756                 : {
    1757               0 :   MOZ_COUNT_CTOR(nsStyleBackground);
    1758                 :   // If the deep copy of mLayers failed, truncate the counts.
    1759               0 :   PRUint32 count = mLayers.Length();
    1760               0 :   if (count != aSource.mLayers.Length()) {
    1761               0 :     NS_WARNING("truncating counts due to out-of-memory");
    1762               0 :     mAttachmentCount = NS_MAX(mAttachmentCount, count);
    1763               0 :     mClipCount = NS_MAX(mClipCount, count);
    1764               0 :     mOriginCount = NS_MAX(mOriginCount, count);
    1765               0 :     mRepeatCount = NS_MAX(mRepeatCount, count);
    1766               0 :     mPositionCount = NS_MAX(mPositionCount, count);
    1767               0 :     mImageCount = NS_MAX(mImageCount, count);
    1768               0 :     mSizeCount = NS_MAX(mSizeCount, count);
    1769                 :   }
    1770               0 : }
    1771                 : 
    1772               0 : nsStyleBackground::~nsStyleBackground()
    1773                 : {
    1774               0 :   MOZ_COUNT_DTOR(nsStyleBackground);
    1775               0 : }
    1776                 : 
    1777                 : void
    1778               0 : nsStyleBackground::Destroy(nsPresContext* aContext)
    1779                 : {
    1780                 :   // Untrack all the images stored in our layers
    1781               0 :   for (PRUint32 i = 0; i < mImageCount; ++i)
    1782               0 :     mLayers[i].UntrackImages(aContext);
    1783                 : 
    1784               0 :   this->~nsStyleBackground();
    1785               0 :   aContext->FreeToShell(sizeof(nsStyleBackground), this);
    1786               0 : }
    1787                 : 
    1788               0 : nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
    1789                 : {
    1790                 :   const nsStyleBackground* moreLayers =
    1791               0 :     mImageCount > aOther.mImageCount ? this : &aOther;
    1792                 :   const nsStyleBackground* lessLayers =
    1793               0 :     mImageCount > aOther.mImageCount ? &aOther : this;
    1794                 : 
    1795               0 :   bool hasVisualDifference = false;
    1796                 : 
    1797               0 :   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, moreLayers) {
    1798               0 :     if (i < lessLayers->mImageCount) {
    1799               0 :       if (moreLayers->mLayers[i] != lessLayers->mLayers[i]) {
    1800               0 :         if ((moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
    1801               0 :             (lessLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element))
    1802               0 :           return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
    1803               0 :         hasVisualDifference = true;
    1804                 :       }
    1805                 :     } else {
    1806               0 :       if (moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element)
    1807               0 :         return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
    1808               0 :       hasVisualDifference = true;
    1809                 :     }
    1810                 :   }
    1811                 : 
    1812               0 :   if (hasVisualDifference ||
    1813                 :       mBackgroundColor != aOther.mBackgroundColor ||
    1814                 :       mBackgroundInlinePolicy != aOther.mBackgroundInlinePolicy)
    1815               0 :     return NS_STYLE_HINT_VISUAL;
    1816                 : 
    1817               0 :   return NS_STYLE_HINT_NONE;
    1818                 : }
    1819                 : 
    1820                 : #ifdef DEBUG
    1821                 : /* static */
    1822               0 : nsChangeHint nsStyleBackground::MaxDifference()
    1823                 : {
    1824               0 :   return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
    1825                 : }
    1826                 : #endif
    1827                 : 
    1828               0 : bool nsStyleBackground::HasFixedBackground() const
    1829                 : {
    1830               0 :   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
    1831               0 :     const Layer &layer = mLayers[i];
    1832               0 :     if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
    1833               0 :         !layer.mImage.IsEmpty()) {
    1834               0 :       return true;
    1835                 :     }
    1836                 :   }
    1837               0 :   return false;
    1838                 : }
    1839                 : 
    1840               0 : bool nsStyleBackground::IsTransparent() const
    1841                 : {
    1842               0 :   return BottomLayer().mImage.IsEmpty() &&
    1843                 :          mImageCount == 1 &&
    1844               0 :          NS_GET_A(mBackgroundColor) == 0;
    1845                 : }
    1846                 : 
    1847                 : void
    1848               0 : nsStyleBackground::Position::SetInitialValues()
    1849                 : {
    1850                 :   // Initial value is "0% 0%"
    1851               0 :   mXPosition.mPercent = 0.0f;
    1852               0 :   mXPosition.mLength = 0;
    1853               0 :   mXPosition.mHasPercent = true;
    1854               0 :   mYPosition.mPercent = 0.0f;
    1855               0 :   mYPosition.mLength = 0;
    1856               0 :   mYPosition.mHasPercent = true;
    1857               0 : }
    1858                 : 
    1859                 : bool
    1860               0 : nsStyleBackground::Size::DependsOnFrameSize(const nsStyleImage& aImage) const
    1861                 : {
    1862               0 :   NS_ABORT_IF_FALSE(aImage.GetType() != eStyleImageType_Null,
    1863                 :                     "caller should have handled this");
    1864                 : 
    1865                 :   // If either dimension contains a non-zero percentage, rendering for that
    1866                 :   // dimension straightforwardly depends on frame size.
    1867               0 :   if ((mWidthType == eLengthPercentage && mWidth.mPercent != 0.0f) ||
    1868                 :       (mHeightType == eLengthPercentage && mHeight.mPercent != 0.0f)) {
    1869               0 :     return true;
    1870                 :   }
    1871                 : 
    1872                 :   // So too for contain and cover.
    1873               0 :   if (mWidthType == eContain || mWidthType == eCover) {
    1874               0 :     return true;
    1875                 :   }
    1876                 : 
    1877                 :   // If both dimensions are fixed lengths, there's no dependency.
    1878               0 :   if (mWidthType == eLengthPercentage && mHeightType == eLengthPercentage) {
    1879               0 :     return false;
    1880                 :   }
    1881                 : 
    1882               0 :   NS_ABORT_IF_FALSE((mWidthType == eLengthPercentage && mHeightType == eAuto) ||
    1883                 :                     (mWidthType == eAuto && mHeightType == eLengthPercentage) ||
    1884                 :                     (mWidthType == eAuto && mHeightType == eAuto),
    1885                 :                     "logic error");
    1886                 : 
    1887               0 :   nsStyleImageType type = aImage.GetType();
    1888                 : 
    1889                 :   // Gradient rendering depends on frame size when auto is involved because
    1890                 :   // gradients have no intrinsic ratio or dimensions, and therefore the relevant
    1891                 :   // dimension is "treat[ed] as 100%".
    1892               0 :   if (type == eStyleImageType_Gradient) {
    1893               0 :     return true;
    1894                 :   }
    1895                 : 
    1896                 :   // XXX Element rendering for auto or fixed length doesn't depend on frame size
    1897                 :   //     according to the spec.  However, we don't implement the spec yet, so
    1898                 :   //     for now we bail and say element() plus auto affects ultimate size.
    1899               0 :   if (type == eStyleImageType_Element) {
    1900               0 :     return true;
    1901                 :   }
    1902                 : 
    1903               0 :   if (type == eStyleImageType_Image) {
    1904               0 :     nsCOMPtr<imgIContainer> imgContainer;
    1905               0 :     aImage.GetImageData()->GetImage(getter_AddRefs(imgContainer));
    1906               0 :     if (imgContainer) {
    1907               0 :       nsIntSize imageSize;
    1908               0 :       nsSize imageRatio;
    1909                 :       bool hasWidth, hasHeight;
    1910                 :       nsLayoutUtils::ComputeSizeForDrawing(imgContainer, imageSize, imageRatio,
    1911               0 :                                            hasWidth, hasHeight);
    1912                 : 
    1913                 :       // If the image has a fixed width and height, rendering never depends on
    1914                 :       // the frame size.
    1915               0 :       if (hasWidth && hasHeight) {
    1916               0 :         return false;
    1917                 :       }
    1918                 : 
    1919                 :       // If the image has an intrinsic ratio, rendering will depend on frame
    1920                 :       // size when background-size is all auto.
    1921               0 :       if (imageRatio != nsSize(0, 0)) {
    1922               0 :         return mWidthType == mHeightType;
    1923                 :       }
    1924                 : 
    1925                 :       // Otherwise, rendering depends on frame size when the image dimensions
    1926                 :       // and background-size don't complement each other.
    1927               0 :       return !(hasWidth && mHeightType == eLengthPercentage) &&
    1928               0 :              !(hasHeight && mWidthType == eLengthPercentage);
    1929                 :     }
    1930                 :   } else {
    1931               0 :     NS_NOTREACHED("missed an enum value");
    1932                 :   }
    1933                 : 
    1934                 :   // Passed the gauntlet: no dependency.
    1935               0 :   return false;
    1936                 : }
    1937                 : 
    1938                 : void
    1939               0 : nsStyleBackground::Size::SetInitialValues()
    1940                 : {
    1941               0 :   mWidthType = mHeightType = eAuto;
    1942               0 : }
    1943                 : 
    1944                 : bool
    1945               0 : nsStyleBackground::Size::operator==(const Size& aOther) const
    1946                 : {
    1947               0 :   NS_ABORT_IF_FALSE(mWidthType < eDimensionType_COUNT,
    1948                 :                     "bad mWidthType for this");
    1949               0 :   NS_ABORT_IF_FALSE(mHeightType < eDimensionType_COUNT,
    1950                 :                     "bad mHeightType for this");
    1951               0 :   NS_ABORT_IF_FALSE(aOther.mWidthType < eDimensionType_COUNT,
    1952                 :                     "bad mWidthType for aOther");
    1953               0 :   NS_ABORT_IF_FALSE(aOther.mHeightType < eDimensionType_COUNT,
    1954                 :                     "bad mHeightType for aOther");
    1955                 : 
    1956                 :   return mWidthType == aOther.mWidthType &&
    1957                 :          mHeightType == aOther.mHeightType &&
    1958               0 :          (mWidthType != eLengthPercentage || mWidth == aOther.mWidth) &&
    1959               0 :          (mHeightType != eLengthPercentage || mHeight == aOther.mHeight);
    1960                 : }
    1961                 : 
    1962                 : void
    1963               0 : nsStyleBackground::Repeat::SetInitialValues() 
    1964                 : {
    1965               0 :   mXRepeat = NS_STYLE_BG_REPEAT_REPEAT;
    1966               0 :   mYRepeat = NS_STYLE_BG_REPEAT_REPEAT;
    1967               0 : }
    1968                 : 
    1969               0 : nsStyleBackground::Layer::Layer()
    1970                 : {
    1971               0 : }
    1972                 : 
    1973               0 : nsStyleBackground::Layer::~Layer()
    1974                 : {
    1975               0 : }
    1976                 : 
    1977                 : void
    1978               0 : nsStyleBackground::Layer::SetInitialValues()
    1979                 : {
    1980               0 :   mAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
    1981               0 :   mClip = NS_STYLE_BG_CLIP_BORDER;
    1982               0 :   mOrigin = NS_STYLE_BG_ORIGIN_PADDING;
    1983               0 :   mRepeat.SetInitialValues();
    1984               0 :   mPosition.SetInitialValues();
    1985               0 :   mSize.SetInitialValues();
    1986               0 :   mImage.SetNull();
    1987               0 : }
    1988                 : 
    1989                 : bool
    1990               0 : nsStyleBackground::Layer::RenderingMightDependOnFrameSize() const
    1991                 : {
    1992                 :   // Do we even have an image?
    1993               0 :   if (mImage.IsEmpty()) {
    1994               0 :     return false;
    1995                 :   }
    1996                 : 
    1997               0 :   return mPosition.DependsOnFrameSize() || mSize.DependsOnFrameSize(mImage);
    1998                 : }
    1999                 : 
    2000                 : bool
    2001               0 : nsStyleBackground::Layer::operator==(const Layer& aOther) const
    2002                 : {
    2003                 :   return mAttachment == aOther.mAttachment &&
    2004                 :          mClip == aOther.mClip &&
    2005                 :          mOrigin == aOther.mOrigin &&
    2006               0 :          mRepeat == aOther.mRepeat &&
    2007               0 :          mPosition == aOther.mPosition &&
    2008               0 :          mSize == aOther.mSize &&
    2009               0 :          mImage == aOther.mImage;
    2010                 : }
    2011                 : 
    2012                 : // --------------------
    2013                 : // nsStyleDisplay
    2014                 : //
    2015               0 : void nsTimingFunction::AssignFromKeyword(PRInt32 aTimingFunctionType)
    2016                 : {
    2017               0 :   switch (aTimingFunctionType) {
    2018                 :     case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START:
    2019               0 :       mType = StepStart;
    2020               0 :       mSteps = 1;
    2021               0 :       return;
    2022                 :     case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END:
    2023               0 :       mType = StepEnd;
    2024               0 :       mSteps = 1;
    2025               0 :       return;
    2026                 :     default:
    2027               0 :       mType = Function;
    2028                 :       break;
    2029                 :   }
    2030                 : 
    2031                 :   MOZ_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE == 0 &&
    2032                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR == 1 &&
    2033                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN == 2 &&
    2034                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT == 3 &&
    2035                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT == 4,
    2036                 :                     "transition timing function constants not as expected");
    2037                 : 
    2038                 :   static const float timingFunctionValues[5][4] = {
    2039                 :     { 0.25, 0.10, 0.25, 1.00 }, // ease
    2040                 :     { 0.00, 0.00, 1.00, 1.00 }, // linear
    2041                 :     { 0.42, 0.00, 1.00, 1.00 }, // ease-in
    2042                 :     { 0.00, 0.00, 0.58, 1.00 }, // ease-out
    2043                 :     { 0.42, 0.00, 0.58, 1.00 }  // ease-in-out
    2044                 :   };
    2045                 : 
    2046               0 :   NS_ABORT_IF_FALSE(0 <= aTimingFunctionType && aTimingFunctionType < 5,
    2047                 :                     "keyword out of range");
    2048               0 :   mFunc.mX1 = timingFunctionValues[aTimingFunctionType][0];
    2049               0 :   mFunc.mY1 = timingFunctionValues[aTimingFunctionType][1];
    2050               0 :   mFunc.mX2 = timingFunctionValues[aTimingFunctionType][2];
    2051               0 :   mFunc.mY2 = timingFunctionValues[aTimingFunctionType][3];
    2052                 : }
    2053                 : 
    2054               0 : nsTransition::nsTransition(const nsTransition& aCopy)
    2055                 :   : mTimingFunction(aCopy.mTimingFunction)
    2056                 :   , mDuration(aCopy.mDuration)
    2057                 :   , mDelay(aCopy.mDelay)
    2058                 :   , mProperty(aCopy.mProperty)
    2059               0 :   , mUnknownProperty(aCopy.mUnknownProperty)
    2060                 : {
    2061               0 : }
    2062                 : 
    2063               0 : void nsTransition::SetInitialValues()
    2064                 : {
    2065               0 :   mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE);
    2066               0 :   mDuration = 0.0;
    2067               0 :   mDelay = 0.0;
    2068               0 :   mProperty = eCSSPropertyExtra_all_properties;
    2069               0 : }
    2070                 : 
    2071               0 : void nsTransition::SetUnknownProperty(const nsAString& aUnknownProperty)
    2072                 : {
    2073               0 :   NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty) ==
    2074                 :                  eCSSProperty_UNKNOWN,
    2075                 :                "should be unknown property");
    2076               0 :   mProperty = eCSSProperty_UNKNOWN;
    2077               0 :   mUnknownProperty = do_GetAtom(aUnknownProperty);
    2078               0 : }
    2079                 : 
    2080               0 : nsAnimation::nsAnimation(const nsAnimation& aCopy)
    2081                 :   : mTimingFunction(aCopy.mTimingFunction)
    2082                 :   , mDuration(aCopy.mDuration)
    2083                 :   , mDelay(aCopy.mDelay)
    2084                 :   , mName(aCopy.mName)
    2085                 :   , mDirection(aCopy.mDirection)
    2086                 :   , mFillMode(aCopy.mFillMode)
    2087                 :   , mPlayState(aCopy.mPlayState)
    2088               0 :   , mIterationCount(aCopy.mIterationCount)
    2089                 : {
    2090               0 : }
    2091                 : 
    2092                 : void
    2093               0 : nsAnimation::SetInitialValues()
    2094                 : {
    2095               0 :   mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE);
    2096               0 :   mDuration = 0.0;
    2097               0 :   mDelay = 0.0;
    2098               0 :   mName = EmptyString();
    2099               0 :   mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
    2100               0 :   mFillMode = NS_STYLE_ANIMATION_FILL_MODE_NONE;
    2101               0 :   mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
    2102               0 :   mIterationCount = 1.0f;
    2103               0 : }
    2104                 : 
    2105               0 : nsStyleDisplay::nsStyleDisplay()
    2106                 : {
    2107               0 :   MOZ_COUNT_CTOR(nsStyleDisplay);
    2108               0 :   mAppearance = NS_THEME_NONE;
    2109               0 :   mDisplay = NS_STYLE_DISPLAY_INLINE;
    2110               0 :   mOriginalDisplay = mDisplay;
    2111               0 :   mPosition = NS_STYLE_POSITION_STATIC;
    2112               0 :   mFloats = NS_STYLE_FLOAT_NONE;
    2113               0 :   mOriginalFloats = mFloats;
    2114               0 :   mBreakType = NS_STYLE_CLEAR_NONE;
    2115               0 :   mBreakBefore = false;
    2116               0 :   mBreakAfter = false;
    2117               0 :   mOverflowX = NS_STYLE_OVERFLOW_VISIBLE;
    2118               0 :   mOverflowY = NS_STYLE_OVERFLOW_VISIBLE;
    2119               0 :   mResize = NS_STYLE_RESIZE_NONE;
    2120               0 :   mClipFlags = NS_STYLE_CLIP_AUTO;
    2121               0 :   mClip.SetRect(0,0,0,0);
    2122               0 :   mOpacity = 1.0f;
    2123               0 :   mSpecifiedTransform = nsnull;
    2124               0 :   mTransformOrigin[0].SetPercentValue(0.5f); // Transform is centered on origin
    2125               0 :   mTransformOrigin[1].SetPercentValue(0.5f);
    2126               0 :   mTransformOrigin[2].SetCoordValue(0);
    2127               0 :   mPerspectiveOrigin[0].SetPercentValue(0.5f);
    2128               0 :   mPerspectiveOrigin[1].SetPercentValue(0.5f);
    2129               0 :   mChildPerspective.SetCoordValue(0);
    2130               0 :   mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE;
    2131               0 :   mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT;
    2132               0 :   mOrient = NS_STYLE_ORIENT_HORIZONTAL;
    2133                 : 
    2134               0 :   mTransitions.AppendElement();
    2135               0 :   NS_ABORT_IF_FALSE(mTransitions.Length() == 1,
    2136                 :                     "appending within auto buffer should never fail");
    2137               0 :   mTransitions[0].SetInitialValues();
    2138               0 :   mTransitionTimingFunctionCount = 1;
    2139               0 :   mTransitionDurationCount = 1;
    2140               0 :   mTransitionDelayCount = 1;
    2141               0 :   mTransitionPropertyCount = 1;
    2142                 : 
    2143               0 :   mAnimations.AppendElement();
    2144               0 :   NS_ABORT_IF_FALSE(mAnimations.Length() == 1,
    2145                 :                     "appending within auto buffer should never fail");
    2146               0 :   mAnimations[0].SetInitialValues();
    2147               0 :   mAnimationTimingFunctionCount = 1;
    2148               0 :   mAnimationDurationCount = 1;
    2149               0 :   mAnimationDelayCount = 1;
    2150               0 :   mAnimationNameCount = 1;
    2151               0 :   mAnimationDirectionCount = 1;
    2152               0 :   mAnimationFillModeCount = 1;
    2153               0 :   mAnimationPlayStateCount = 1;
    2154               0 :   mAnimationIterationCountCount = 1;
    2155               0 : }
    2156                 : 
    2157               0 : nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
    2158                 :   : mTransitions(aSource.mTransitions)
    2159                 :   , mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount)
    2160                 :   , mTransitionDurationCount(aSource.mTransitionDurationCount)
    2161                 :   , mTransitionDelayCount(aSource.mTransitionDelayCount)
    2162                 :   , mTransitionPropertyCount(aSource.mTransitionPropertyCount)
    2163                 :   , mAnimations(aSource.mAnimations)
    2164                 :   , mAnimationTimingFunctionCount(aSource.mAnimationTimingFunctionCount)
    2165                 :   , mAnimationDurationCount(aSource.mAnimationDurationCount)
    2166                 :   , mAnimationDelayCount(aSource.mAnimationDelayCount)
    2167                 :   , mAnimationNameCount(aSource.mAnimationNameCount)
    2168                 :   , mAnimationDirectionCount(aSource.mAnimationDirectionCount)
    2169                 :   , mAnimationFillModeCount(aSource.mAnimationFillModeCount)
    2170                 :   , mAnimationPlayStateCount(aSource.mAnimationPlayStateCount)
    2171               0 :   , mAnimationIterationCountCount(aSource.mAnimationIterationCountCount)
    2172                 : {
    2173               0 :   MOZ_COUNT_CTOR(nsStyleDisplay);
    2174               0 :   mAppearance = aSource.mAppearance;
    2175               0 :   mDisplay = aSource.mDisplay;
    2176               0 :   mOriginalDisplay = aSource.mOriginalDisplay;
    2177               0 :   mOriginalFloats = aSource.mOriginalFloats;
    2178               0 :   mBinding = aSource.mBinding;
    2179               0 :   mPosition = aSource.mPosition;
    2180               0 :   mFloats = aSource.mFloats;
    2181               0 :   mBreakType = aSource.mBreakType;
    2182               0 :   mBreakBefore = aSource.mBreakBefore;
    2183               0 :   mBreakAfter = aSource.mBreakAfter;
    2184               0 :   mOverflowX = aSource.mOverflowX;
    2185               0 :   mOverflowY = aSource.mOverflowY;
    2186               0 :   mResize = aSource.mResize;
    2187               0 :   mClipFlags = aSource.mClipFlags;
    2188               0 :   mClip = aSource.mClip;
    2189               0 :   mOpacity = aSource.mOpacity;
    2190               0 :   mOrient = aSource.mOrient;
    2191                 : 
    2192                 :   /* Copy over the transformation information. */
    2193               0 :   mSpecifiedTransform = aSource.mSpecifiedTransform;
    2194                 :   
    2195                 :   /* Copy over transform origin. */
    2196               0 :   mTransformOrigin[0] = aSource.mTransformOrigin[0];
    2197               0 :   mTransformOrigin[1] = aSource.mTransformOrigin[1];
    2198               0 :   mTransformOrigin[2] = aSource.mTransformOrigin[2];
    2199               0 :   mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0];
    2200               0 :   mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1];
    2201               0 :   mChildPerspective = aSource.mChildPerspective;
    2202               0 :   mBackfaceVisibility = aSource.mBackfaceVisibility;
    2203               0 :   mTransformStyle = aSource.mTransformStyle;
    2204               0 : }
    2205                 : 
    2206               0 : nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
    2207                 : {
    2208               0 :   nsChangeHint hint = nsChangeHint(0);
    2209                 : 
    2210               0 :   if (!EqualURIs(mBinding, aOther.mBinding)
    2211                 :       || mPosition != aOther.mPosition
    2212                 :       || mDisplay != aOther.mDisplay
    2213                 :       || (mFloats == NS_STYLE_FLOAT_NONE) != (aOther.mFloats == NS_STYLE_FLOAT_NONE)
    2214                 :       || mOverflowX != aOther.mOverflowX
    2215                 :       || mOverflowY != aOther.mOverflowY
    2216                 :       || mResize != aOther.mResize)
    2217               0 :     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
    2218                 : 
    2219               0 :   if (mFloats != aOther.mFloats) {
    2220                 :     // Changing which side we float on doesn't affect descendants directly
    2221                 :     NS_UpdateHint(hint,
    2222                 :        NS_SubtractHint(nsChangeHint_ReflowFrame,
    2223                 :                        NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
    2224               0 :                                       nsChangeHint_NeedDirtyReflow)));
    2225                 :   }
    2226                 : 
    2227                 :   // XXX the following is conservative, for now: changing float breaking shouldn't
    2228                 :   // necessarily require a repaint, reflow should suffice.
    2229               0 :   if (mBreakType != aOther.mBreakType
    2230                 :       || mBreakBefore != aOther.mBreakBefore
    2231                 :       || mBreakAfter != aOther.mBreakAfter
    2232                 :       || mAppearance != aOther.mAppearance
    2233                 :       || mOrient != aOther.mOrient
    2234               0 :       || mClipFlags != aOther.mClipFlags || !mClip.IsEqualInterior(aOther.mClip))
    2235               0 :     NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame));
    2236                 : 
    2237               0 :   if (mOpacity != aOther.mOpacity) {
    2238               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateOpacityLayer);
    2239                 :   }
    2240                 : 
    2241                 :   /* If we've added or removed the transform property, we need to reconstruct the frame to add
    2242                 :    * or remove the view object, and also to handle abs-pos and fixed-pos containers.
    2243                 :    */
    2244               0 :   if (HasTransform() != aOther.HasTransform()) {
    2245               0 :     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
    2246                 :   }
    2247               0 :   else if (HasTransform()) {
    2248                 :     /* Otherwise, if we've kept the property lying around and we already had a
    2249                 :      * transform, we need to see whether or not we've changed the transform.
    2250                 :      * If so, we need to recompute its overflow rect (which probably changed
    2251                 :      * if the transform changed) and to redraw within the bounds of that new
    2252                 :      * overflow rect.
    2253                 :      */
    2254               0 :     if (!mSpecifiedTransform != !aOther.mSpecifiedTransform ||
    2255                 :         (mSpecifiedTransform &&
    2256               0 :          *mSpecifiedTransform != *aOther.mSpecifiedTransform)) {
    2257                 :       NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow,
    2258               0 :                                          nsChangeHint_UpdateTransformLayer));
    2259                 :     }
    2260                 : 
    2261                 :     const nsChangeHint kUpdateOverflowAndRepaintHint =
    2262               0 :       NS_CombineHint(nsChangeHint_UpdateOverflow, nsChangeHint_RepaintFrame);
    2263               0 :     for (PRUint8 index = 0; index < 3; ++index)
    2264               0 :       if (mTransformOrigin[index] != aOther.mTransformOrigin[index]) {
    2265               0 :         NS_UpdateHint(hint, kUpdateOverflowAndRepaintHint);
    2266               0 :         break;
    2267                 :       }
    2268                 :     
    2269               0 :     for (PRUint8 index = 0; index < 2; ++index)
    2270               0 :       if (mPerspectiveOrigin[index] != aOther.mPerspectiveOrigin[index]) {
    2271               0 :         NS_UpdateHint(hint, kUpdateOverflowAndRepaintHint);
    2272               0 :         break;
    2273                 :       }
    2274                 : 
    2275               0 :     if (mChildPerspective != aOther.mChildPerspective ||
    2276                 :         mTransformStyle != aOther.mTransformStyle)
    2277               0 :       NS_UpdateHint(hint, kUpdateOverflowAndRepaintHint);
    2278                 : 
    2279               0 :     if (mBackfaceVisibility != aOther.mBackfaceVisibility)
    2280               0 :       NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
    2281                 :   }
    2282                 : 
    2283                 :   // Note:  Our current behavior for handling changes to the
    2284                 :   // transition-duration, transition-delay, and transition-timing-function
    2285                 :   // properties is to do nothing.  In other words, the transition
    2286                 :   // property that matters is what it is when the transition begins, and
    2287                 :   // we don't stop a transition later because the transition property
    2288                 :   // changed.
    2289                 :   // We do handle changes to transition-property, but we don't need to
    2290                 :   // bother with anything here, since the transition manager is notified
    2291                 :   // of any style context change anyway.
    2292                 : 
    2293                 :   // Note: Likewise, for animation-*, the animation manager gets
    2294                 :   // notified about every new style context constructed, and it uses
    2295                 :   // that opportunity to handle dynamic changes appropriately.
    2296                 : 
    2297               0 :   return hint;
    2298                 : }
    2299                 : 
    2300                 : #ifdef DEBUG
    2301                 : /* static */
    2302               0 : nsChangeHint nsStyleDisplay::MaxDifference()
    2303                 : {
    2304                 :   // All the parts of FRAMECHANGE are present above in CalcDifference.
    2305                 :   return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
    2306                 :                       nsChangeHint_UpdateOpacityLayer |
    2307                 :                       nsChangeHint_UpdateTransformLayer |
    2308               0 :                       nsChangeHint_UpdateOverflow);
    2309                 : }
    2310                 : #endif
    2311                 : 
    2312                 : // --------------------
    2313                 : // nsStyleVisibility
    2314                 : //
    2315                 : 
    2316               0 : nsStyleVisibility::nsStyleVisibility(nsPresContext* aPresContext)
    2317                 : {
    2318               0 :   MOZ_COUNT_CTOR(nsStyleVisibility);
    2319               0 :   PRUint32 bidiOptions = aPresContext->GetBidi();
    2320               0 :   if (GET_BIDI_OPTION_DIRECTION(bidiOptions) == IBMBIDI_TEXTDIRECTION_RTL)
    2321               0 :     mDirection = NS_STYLE_DIRECTION_RTL;
    2322                 :   else
    2323               0 :     mDirection = NS_STYLE_DIRECTION_LTR;
    2324                 : 
    2325               0 :   mVisible = NS_STYLE_VISIBILITY_VISIBLE;
    2326               0 :   mPointerEvents = NS_STYLE_POINTER_EVENTS_AUTO;
    2327               0 : }
    2328                 : 
    2329               0 : nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
    2330                 : {
    2331               0 :   MOZ_COUNT_CTOR(nsStyleVisibility);
    2332               0 :   mDirection = aSource.mDirection;
    2333               0 :   mVisible = aSource.mVisible;
    2334               0 :   mPointerEvents = aSource.mPointerEvents;
    2335               0 : } 
    2336                 : 
    2337               0 : nsChangeHint nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const
    2338                 : {
    2339               0 :   nsChangeHint hint = nsChangeHint(0);
    2340                 : 
    2341               0 :   if (mDirection != aOther.mDirection) {
    2342               0 :     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
    2343               0 :   } else if (mVisible != aOther.mVisible) {
    2344               0 :     if ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
    2345                 :         (NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible)) {
    2346               0 :       NS_UpdateHint(hint, NS_STYLE_HINT_REFLOW);
    2347                 :     } else {
    2348               0 :       NS_UpdateHint(hint, NS_STYLE_HINT_VISUAL);
    2349                 :     }
    2350                 :   }
    2351               0 :   return hint;
    2352                 : }
    2353                 : 
    2354                 : #ifdef DEBUG
    2355                 : /* static */
    2356               0 : nsChangeHint nsStyleVisibility::MaxDifference()
    2357                 : {
    2358               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2359                 : }
    2360                 : #endif
    2361                 : 
    2362               0 : nsStyleContentData::~nsStyleContentData()
    2363                 : {
    2364               0 :   NS_ABORT_IF_FALSE(!mImageTracked,
    2365                 :                     "nsStyleContentData being destroyed while still tracking image!");
    2366               0 :   if (mType == eStyleContentType_Image) {
    2367               0 :     NS_IF_RELEASE(mContent.mImage);
    2368               0 :   } else if (mType == eStyleContentType_Counter ||
    2369                 :              mType == eStyleContentType_Counters) {
    2370               0 :     mContent.mCounters->Release();
    2371               0 :   } else if (mContent.mString) {
    2372               0 :     NS_Free(mContent.mString);
    2373                 :   }
    2374               0 : }
    2375                 : 
    2376               0 : nsStyleContentData& nsStyleContentData::operator=(const nsStyleContentData& aOther)
    2377                 : {
    2378               0 :   if (this == &aOther)
    2379               0 :     return *this;
    2380               0 :   this->~nsStyleContentData();
    2381               0 :   new (this) nsStyleContentData();
    2382                 : 
    2383               0 :   mType = aOther.mType;
    2384               0 :   if (mType == eStyleContentType_Image) {
    2385               0 :     mContent.mImage = aOther.mContent.mImage;
    2386               0 :     NS_IF_ADDREF(mContent.mImage);
    2387               0 :   } else if (mType == eStyleContentType_Counter ||
    2388                 :              mType == eStyleContentType_Counters) {
    2389               0 :     mContent.mCounters = aOther.mContent.mCounters;
    2390               0 :     mContent.mCounters->AddRef();
    2391               0 :   } else if (aOther.mContent.mString) {
    2392               0 :     mContent.mString = NS_strdup(aOther.mContent.mString);
    2393                 :   } else {
    2394               0 :     mContent.mString = nsnull;
    2395                 :   }
    2396               0 :   return *this;
    2397                 : }
    2398                 : 
    2399               0 : bool nsStyleContentData::operator==(const nsStyleContentData& aOther) const
    2400                 : {
    2401               0 :   if (mType != aOther.mType)
    2402               0 :     return false;
    2403               0 :   if (mType == eStyleContentType_Image) {
    2404               0 :     if (!mContent.mImage || !aOther.mContent.mImage)
    2405               0 :       return mContent.mImage == aOther.mContent.mImage;
    2406                 :     bool eq;
    2407               0 :     nsCOMPtr<nsIURI> thisURI, otherURI;
    2408               0 :     mContent.mImage->GetURI(getter_AddRefs(thisURI));
    2409               0 :     aOther.mContent.mImage->GetURI(getter_AddRefs(otherURI));
    2410               0 :     return thisURI == otherURI ||  // handles null==null
    2411               0 :            (thisURI && otherURI &&
    2412               0 :             NS_SUCCEEDED(thisURI->Equals(otherURI, &eq)) &&
    2413               0 :             eq);
    2414                 :   }
    2415               0 :   if (mType == eStyleContentType_Counter ||
    2416                 :       mType == eStyleContentType_Counters)
    2417               0 :     return *mContent.mCounters == *aOther.mContent.mCounters;
    2418               0 :   return safe_strcmp(mContent.mString, aOther.mContent.mString) == 0;
    2419                 : }
    2420                 : 
    2421                 : void
    2422               0 : nsStyleContentData::TrackImage(nsPresContext* aContext)
    2423                 : {
    2424                 :   // Sanity
    2425               0 :   NS_ABORT_IF_FALSE(!mImageTracked, "Already tracking image!");
    2426               0 :   NS_ABORT_IF_FALSE(mType == eStyleContentType_Image,
    2427                 :                     "Tryingto do image tracking on non-image!");
    2428               0 :   NS_ABORT_IF_FALSE(mContent.mImage,
    2429                 :                     "Can't track image when there isn't one!");
    2430                 : 
    2431                 :   // Register the image with the document
    2432               0 :   nsIDocument* doc = aContext->Document();
    2433               0 :   if (doc)
    2434               0 :     doc->AddImage(mContent.mImage);
    2435                 : 
    2436                 :   // Mark state
    2437                 : #ifdef DEBUG
    2438               0 :   mImageTracked = true;
    2439                 : #endif
    2440               0 : }
    2441                 : 
    2442                 : void
    2443               0 : nsStyleContentData::UntrackImage(nsPresContext* aContext)
    2444                 : {
    2445                 :   // Sanity
    2446               0 :   NS_ABORT_IF_FALSE(mImageTracked, "Image not tracked!");
    2447               0 :   NS_ABORT_IF_FALSE(mType == eStyleContentType_Image,
    2448                 :                     "Trying to do image tracking on non-image!");
    2449               0 :   NS_ABORT_IF_FALSE(mContent.mImage,
    2450                 :                     "Can't untrack image when there isn't one!");
    2451                 : 
    2452                 :   // Unregister the image with the document
    2453               0 :   nsIDocument* doc = aContext->Document();
    2454               0 :   if (doc)
    2455               0 :     doc->RemoveImage(mContent.mImage);
    2456                 : 
    2457                 :   // Mark state
    2458                 : #ifdef DEBUG
    2459               0 :   mImageTracked = false;
    2460                 : #endif
    2461               0 : }
    2462                 : 
    2463                 : 
    2464                 : //-----------------------
    2465                 : // nsStyleContent
    2466                 : //
    2467                 : 
    2468               0 : nsStyleContent::nsStyleContent(void)
    2469                 :   : mMarkerOffset(),
    2470                 :     mContents(nsnull),
    2471                 :     mIncrements(nsnull),
    2472                 :     mResets(nsnull),
    2473                 :     mContentCount(0),
    2474                 :     mIncrementCount(0),
    2475               0 :     mResetCount(0)
    2476                 : {
    2477               0 :   MOZ_COUNT_CTOR(nsStyleContent);
    2478               0 :   mMarkerOffset.SetAutoValue();
    2479               0 : }
    2480                 : 
    2481               0 : nsStyleContent::~nsStyleContent(void)
    2482                 : {
    2483               0 :   MOZ_COUNT_DTOR(nsStyleContent);
    2484               0 :   DELETE_ARRAY_IF(mContents);
    2485               0 :   DELETE_ARRAY_IF(mIncrements);
    2486               0 :   DELETE_ARRAY_IF(mResets);
    2487               0 : }
    2488                 : 
    2489                 : void 
    2490               0 : nsStyleContent::Destroy(nsPresContext* aContext)
    2491                 : {
    2492                 :   // Unregister any images we might have with the document.
    2493               0 :   for (PRUint32 i = 0; i < mContentCount; ++i) {
    2494               0 :     if ((mContents[i].mType == eStyleContentType_Image) &&
    2495               0 :         mContents[i].mContent.mImage) {
    2496               0 :       mContents[i].UntrackImage(aContext);
    2497                 :     }
    2498                 :   }
    2499                 : 
    2500               0 :   this->~nsStyleContent();
    2501               0 :   aContext->FreeToShell(sizeof(nsStyleContent), this);
    2502               0 : }
    2503                 : 
    2504               0 : nsStyleContent::nsStyleContent(const nsStyleContent& aSource)
    2505                 :    :mMarkerOffset(),
    2506                 :     mContents(nsnull),
    2507                 :     mIncrements(nsnull),
    2508                 :     mResets(nsnull),
    2509                 :     mContentCount(0),
    2510                 :     mIncrementCount(0),
    2511               0 :     mResetCount(0)
    2512                 : 
    2513                 : {
    2514               0 :   MOZ_COUNT_CTOR(nsStyleContent);
    2515               0 :   mMarkerOffset = aSource.mMarkerOffset;
    2516                 : 
    2517                 :   PRUint32 index;
    2518               0 :   if (NS_SUCCEEDED(AllocateContents(aSource.ContentCount()))) {
    2519               0 :     for (index = 0; index < mContentCount; index++) {
    2520               0 :       ContentAt(index) = aSource.ContentAt(index);
    2521                 :     }
    2522                 :   }
    2523                 : 
    2524               0 :   if (NS_SUCCEEDED(AllocateCounterIncrements(aSource.CounterIncrementCount()))) {
    2525               0 :     for (index = 0; index < mIncrementCount; index++) {
    2526               0 :       const nsStyleCounterData *data = aSource.GetCounterIncrementAt(index);
    2527               0 :       mIncrements[index].mCounter = data->mCounter;
    2528               0 :       mIncrements[index].mValue = data->mValue;
    2529                 :     }
    2530                 :   }
    2531                 : 
    2532               0 :   if (NS_SUCCEEDED(AllocateCounterResets(aSource.CounterResetCount()))) {
    2533               0 :     for (index = 0; index < mResetCount; index++) {
    2534               0 :       const nsStyleCounterData *data = aSource.GetCounterResetAt(index);
    2535               0 :       mResets[index].mCounter = data->mCounter;
    2536               0 :       mResets[index].mValue = data->mValue;
    2537                 :     }
    2538                 :   }
    2539               0 : }
    2540                 : 
    2541               0 : nsChangeHint nsStyleContent::CalcDifference(const nsStyleContent& aOther) const
    2542                 : {
    2543                 :   // In ReResolveStyleContext we assume that if there's no existing
    2544                 :   // ::before or ::after and we don't have to restyle children of the
    2545                 :   // node then we can't end up with a ::before or ::after due to the
    2546                 :   // restyle of the node itself.  That's not quite true, but the only
    2547                 :   // exception to the above is when the 'content' property of the node
    2548                 :   // changes and the pseudo-element inherits the changed value.  Since
    2549                 :   // the code here triggers a frame change on the node in that case,
    2550                 :   // the optimization in ReResolveStyleContext is ok.  But if we ever
    2551                 :   // change this code to not reconstruct frames on changes to the
    2552                 :   // 'content' property, then we will need to revisit the optimization
    2553                 :   // in ReResolveStyleContext.
    2554                 : 
    2555               0 :   if (mContentCount != aOther.mContentCount ||
    2556                 :       mIncrementCount != aOther.mIncrementCount || 
    2557                 :       mResetCount != aOther.mResetCount) {
    2558               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    2559                 :   }
    2560                 : 
    2561               0 :   PRUint32 ix = mContentCount;
    2562               0 :   while (0 < ix--) {
    2563               0 :     if (mContents[ix] != aOther.mContents[ix]) {
    2564                 :       // Unfortunately we need to reframe here; a simple reflow
    2565                 :       // will not pick up different text or different image URLs,
    2566                 :       // since we set all that up in the CSSFrameConstructor
    2567               0 :       return NS_STYLE_HINT_FRAMECHANGE;
    2568                 :     }
    2569                 :   }
    2570               0 :   ix = mIncrementCount;
    2571               0 :   while (0 < ix--) {
    2572               0 :     if ((mIncrements[ix].mValue != aOther.mIncrements[ix].mValue) || 
    2573               0 :         (mIncrements[ix].mCounter != aOther.mIncrements[ix].mCounter)) {
    2574               0 :       return NS_STYLE_HINT_FRAMECHANGE;
    2575                 :     }
    2576                 :   }
    2577               0 :   ix = mResetCount;
    2578               0 :   while (0 < ix--) {
    2579               0 :     if ((mResets[ix].mValue != aOther.mResets[ix].mValue) || 
    2580               0 :         (mResets[ix].mCounter != aOther.mResets[ix].mCounter)) {
    2581               0 :       return NS_STYLE_HINT_FRAMECHANGE;
    2582                 :     }
    2583                 :   }
    2584               0 :   if (mMarkerOffset != aOther.mMarkerOffset) {
    2585               0 :     return NS_STYLE_HINT_REFLOW;
    2586                 :   }
    2587               0 :   return NS_STYLE_HINT_NONE;
    2588                 : }
    2589                 : 
    2590                 : #ifdef DEBUG
    2591                 : /* static */
    2592               0 : nsChangeHint nsStyleContent::MaxDifference()
    2593                 : {
    2594               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2595                 : }
    2596                 : #endif
    2597                 : 
    2598               0 : nsresult nsStyleContent::AllocateContents(PRUint32 aCount)
    2599                 : {
    2600                 :   // We need to run the destructors of the elements of mContents, so we
    2601                 :   // delete and reallocate even if aCount == mContentCount.  (If
    2602                 :   // nsStyleContentData had its members private and managed their
    2603                 :   // ownership on setting, we wouldn't need this, but that seems
    2604                 :   // unnecessary at this point.)
    2605               0 :   DELETE_ARRAY_IF(mContents);
    2606               0 :   if (aCount) {
    2607               0 :     mContents = new nsStyleContentData[aCount];
    2608               0 :     if (! mContents) {
    2609               0 :       mContentCount = 0;
    2610               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2611                 :     }
    2612                 :   }
    2613               0 :   mContentCount = aCount;
    2614               0 :   return NS_OK;
    2615                 : }
    2616                 : 
    2617                 : // ---------------------
    2618                 : // nsStyleQuotes
    2619                 : //
    2620                 : 
    2621               0 : nsStyleQuotes::nsStyleQuotes(void)
    2622                 :   : mQuotesCount(0),
    2623               0 :     mQuotes(nsnull)
    2624                 : {
    2625               0 :   MOZ_COUNT_CTOR(nsStyleQuotes);
    2626               0 :   SetInitial();
    2627               0 : }
    2628                 : 
    2629               0 : nsStyleQuotes::~nsStyleQuotes(void)
    2630                 : {
    2631               0 :   MOZ_COUNT_DTOR(nsStyleQuotes);
    2632               0 :   DELETE_ARRAY_IF(mQuotes);
    2633               0 : }
    2634                 : 
    2635               0 : nsStyleQuotes::nsStyleQuotes(const nsStyleQuotes& aSource)
    2636                 :   : mQuotesCount(0),
    2637               0 :     mQuotes(nsnull)
    2638                 : {
    2639               0 :   MOZ_COUNT_CTOR(nsStyleQuotes);
    2640               0 :   CopyFrom(aSource);
    2641               0 : }
    2642                 : 
    2643                 : void
    2644               0 : nsStyleQuotes::SetInitial()
    2645                 : {
    2646                 :   // The initial value for quotes is the en-US typographic convention:
    2647                 :   // outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
    2648                 :   // with LEFT and RIGHT SINGLE QUOTATION MARK.
    2649                 :   static const PRUnichar initialQuotes[8] = {
    2650                 :     0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
    2651                 :   };
    2652                 :   
    2653               0 :   if (NS_SUCCEEDED(AllocateQuotes(2))) {
    2654                 :     SetQuotesAt(0,
    2655               0 :                 nsDependentString(&initialQuotes[0], 1),
    2656               0 :                 nsDependentString(&initialQuotes[2], 1));
    2657                 :     SetQuotesAt(1,
    2658               0 :                 nsDependentString(&initialQuotes[4], 1),
    2659               0 :                 nsDependentString(&initialQuotes[6], 1));
    2660                 :   }
    2661               0 : }
    2662                 : 
    2663                 : void
    2664               0 : nsStyleQuotes::CopyFrom(const nsStyleQuotes& aSource)
    2665                 : {
    2666               0 :   if (NS_SUCCEEDED(AllocateQuotes(aSource.QuotesCount()))) {
    2667               0 :     PRUint32 count = (mQuotesCount * 2);
    2668               0 :     for (PRUint32 index = 0; index < count; index += 2) {
    2669               0 :       aSource.GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]);
    2670                 :     }
    2671                 :   }
    2672               0 : }
    2673                 : 
    2674               0 : nsChangeHint nsStyleQuotes::CalcDifference(const nsStyleQuotes& aOther) const
    2675                 : {
    2676                 :   // If the quotes implementation is ever going to change we might not need
    2677                 :   // a framechange here and a reflow should be sufficient.  See bug 35768.
    2678               0 :   if (mQuotesCount == aOther.mQuotesCount) {
    2679               0 :     PRUint32 ix = (mQuotesCount * 2);
    2680               0 :     while (0 < ix--) {
    2681               0 :       if (mQuotes[ix] != aOther.mQuotes[ix]) {
    2682               0 :         return NS_STYLE_HINT_FRAMECHANGE;
    2683                 :       }
    2684                 :     }
    2685                 : 
    2686               0 :     return NS_STYLE_HINT_NONE;
    2687                 :   }
    2688               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2689                 : }
    2690                 : 
    2691                 : #ifdef DEBUG
    2692                 : /* static */
    2693               0 : nsChangeHint nsStyleQuotes::MaxDifference()
    2694                 : {
    2695               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2696                 : }
    2697                 : #endif
    2698                 : 
    2699                 : // --------------------
    2700                 : // nsStyleTextReset
    2701                 : //
    2702                 : 
    2703               0 : nsStyleTextReset::nsStyleTextReset(void) 
    2704                 : { 
    2705               0 :   MOZ_COUNT_CTOR(nsStyleTextReset);
    2706               0 :   mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated);
    2707               0 :   mTextBlink = NS_STYLE_TEXT_BLINK_NONE;
    2708               0 :   mTextDecorationLine = NS_STYLE_TEXT_DECORATION_LINE_NONE;
    2709               0 :   mTextDecorationColor = NS_RGB(0,0,0);
    2710                 :   mTextDecorationStyle =
    2711               0 :     NS_STYLE_TEXT_DECORATION_STYLE_SOLID | BORDER_COLOR_FOREGROUND;
    2712               0 :   mUnicodeBidi = NS_STYLE_UNICODE_BIDI_NORMAL;
    2713               0 : }
    2714                 : 
    2715               0 : nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset& aSource) 
    2716                 : { 
    2717               0 :   MOZ_COUNT_CTOR(nsStyleTextReset);
    2718               0 :   *this = aSource;
    2719               0 : }
    2720                 : 
    2721               0 : nsStyleTextReset::~nsStyleTextReset(void)
    2722                 : {
    2723               0 :   MOZ_COUNT_DTOR(nsStyleTextReset);
    2724               0 : }
    2725                 : 
    2726               0 : nsChangeHint nsStyleTextReset::CalcDifference(const nsStyleTextReset& aOther) const
    2727                 : {
    2728               0 :   if (mVerticalAlign == aOther.mVerticalAlign
    2729                 :       && mUnicodeBidi == aOther.mUnicodeBidi) {
    2730                 :     // Reflow for blink changes
    2731               0 :     if (mTextBlink != aOther.mTextBlink) {
    2732               0 :       return NS_STYLE_HINT_REFLOW;
    2733                 :     }
    2734                 : 
    2735               0 :     PRUint8 lineStyle = GetDecorationStyle();
    2736               0 :     PRUint8 otherLineStyle = aOther.GetDecorationStyle();
    2737               0 :     if (mTextDecorationLine != aOther.mTextDecorationLine ||
    2738                 :         lineStyle != otherLineStyle) {
    2739                 :       // Reflow for decoration line style changes only to or from double or
    2740                 :       // wave because that may cause overflow area changes
    2741               0 :       if (lineStyle == NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE ||
    2742                 :           lineStyle == NS_STYLE_TEXT_DECORATION_STYLE_WAVY ||
    2743                 :           otherLineStyle == NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE ||
    2744                 :           otherLineStyle == NS_STYLE_TEXT_DECORATION_STYLE_WAVY) {
    2745               0 :         return NS_STYLE_HINT_REFLOW;
    2746                 :       }
    2747                 :       // Repaint for other style decoration lines because they must be in
    2748                 :       // default overflow rect
    2749               0 :       return NS_STYLE_HINT_VISUAL;
    2750                 :     }
    2751                 : 
    2752                 :     // Repaint for decoration color changes
    2753                 :     nscolor decColor, otherDecColor;
    2754                 :     bool isFG, otherIsFG;
    2755               0 :     GetDecorationColor(decColor, isFG);
    2756               0 :     aOther.GetDecorationColor(otherDecColor, otherIsFG);
    2757               0 :     if (isFG != otherIsFG || (!isFG && decColor != otherDecColor)) {
    2758               0 :       return NS_STYLE_HINT_VISUAL;
    2759                 :     }
    2760                 : 
    2761               0 :     if (mTextOverflow != aOther.mTextOverflow) {
    2762               0 :       return NS_STYLE_HINT_VISUAL;
    2763                 :     }
    2764               0 :     return NS_STYLE_HINT_NONE;
    2765                 :   }
    2766               0 :   return NS_STYLE_HINT_REFLOW;
    2767                 : }
    2768                 : 
    2769                 : #ifdef DEBUG
    2770                 : /* static */
    2771               0 : nsChangeHint nsStyleTextReset::MaxDifference()
    2772                 : {
    2773               0 :   return NS_STYLE_HINT_REFLOW;
    2774                 : }
    2775                 : #endif
    2776                 : 
    2777                 : // Allowed to return one of NS_STYLE_HINT_NONE, NS_STYLE_HINT_REFLOW
    2778                 : // or NS_STYLE_HINT_VISUAL. Currently we just return NONE or REFLOW, though.
    2779                 : // XXXbz can this not return a more specific hint?  If that's ever
    2780                 : // changed, nsStyleBorder::CalcDifference will need changing too.
    2781                 : static nsChangeHint
    2782               0 : CalcShadowDifference(nsCSSShadowArray* lhs,
    2783                 :                      nsCSSShadowArray* rhs)
    2784                 : {
    2785               0 :   if (lhs == rhs)
    2786               0 :     return NS_STYLE_HINT_NONE;
    2787                 : 
    2788               0 :   if (!lhs || !rhs || lhs->Length() != rhs->Length())
    2789               0 :     return NS_STYLE_HINT_REFLOW;
    2790                 : 
    2791               0 :   for (PRUint32 i = 0; i < lhs->Length(); ++i) {
    2792               0 :     if (*lhs->ShadowAt(i) != *rhs->ShadowAt(i))
    2793               0 :       return NS_STYLE_HINT_REFLOW;
    2794                 :   }
    2795               0 :   return NS_STYLE_HINT_NONE;
    2796                 : }
    2797                 : 
    2798                 : // --------------------
    2799                 : // nsStyleText
    2800                 : //
    2801                 : 
    2802               0 : nsStyleText::nsStyleText(void)
    2803                 : { 
    2804               0 :   MOZ_COUNT_CTOR(nsStyleText);
    2805               0 :   mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
    2806               0 :   mTextAlignLast = NS_STYLE_TEXT_ALIGN_AUTO;
    2807               0 :   mTextTransform = NS_STYLE_TEXT_TRANSFORM_NONE;
    2808               0 :   mWhiteSpace = NS_STYLE_WHITESPACE_NORMAL;
    2809               0 :   mWordWrap = NS_STYLE_WORDWRAP_NORMAL;
    2810               0 :   mHyphens = NS_STYLE_HYPHENS_MANUAL;
    2811               0 :   mTextSizeAdjust = NS_STYLE_TEXT_SIZE_ADJUST_AUTO;
    2812                 : 
    2813               0 :   mLetterSpacing.SetNormalValue();
    2814               0 :   mLineHeight.SetNormalValue();
    2815               0 :   mTextIndent.SetCoordValue(0);
    2816               0 :   mWordSpacing = 0;
    2817                 : 
    2818               0 :   mTextShadow = nsnull;
    2819               0 :   mTabSize = NS_STYLE_TABSIZE_INITIAL;
    2820               0 : }
    2821                 : 
    2822               0 : nsStyleText::nsStyleText(const nsStyleText& aSource)
    2823                 :   : mTextAlign(aSource.mTextAlign),
    2824                 :     mTextAlignLast(aSource.mTextAlignLast),
    2825                 :     mTextTransform(aSource.mTextTransform),
    2826                 :     mWhiteSpace(aSource.mWhiteSpace),
    2827                 :     mWordWrap(aSource.mWordWrap),
    2828                 :     mHyphens(aSource.mHyphens),
    2829                 :     mTextSizeAdjust(aSource.mTextSizeAdjust),
    2830                 :     mTabSize(aSource.mTabSize),
    2831                 :     mLetterSpacing(aSource.mLetterSpacing),
    2832                 :     mLineHeight(aSource.mLineHeight),
    2833                 :     mTextIndent(aSource.mTextIndent),
    2834                 :     mWordSpacing(aSource.mWordSpacing),
    2835               0 :     mTextShadow(aSource.mTextShadow)
    2836                 : {
    2837               0 :   MOZ_COUNT_CTOR(nsStyleText);
    2838               0 : }
    2839                 : 
    2840               0 : nsStyleText::~nsStyleText(void)
    2841                 : {
    2842               0 :   MOZ_COUNT_DTOR(nsStyleText);
    2843               0 : }
    2844                 : 
    2845               0 : nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aOther) const
    2846                 : {
    2847               0 :   if (NewlineIsSignificant() != aOther.NewlineIsSignificant()) {
    2848                 :     // This may require construction of suppressed text frames
    2849               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    2850                 :   }
    2851                 : 
    2852               0 :   if ((mTextAlign != aOther.mTextAlign) ||
    2853                 :       (mTextAlignLast != aOther.mTextAlignLast) ||
    2854                 :       (mTextTransform != aOther.mTextTransform) ||
    2855                 :       (mWhiteSpace != aOther.mWhiteSpace) ||
    2856                 :       (mWordWrap != aOther.mWordWrap) ||
    2857                 :       (mHyphens != aOther.mHyphens) ||
    2858                 :       (mTextSizeAdjust != aOther.mTextSizeAdjust) ||
    2859               0 :       (mLetterSpacing != aOther.mLetterSpacing) ||
    2860               0 :       (mLineHeight != aOther.mLineHeight) ||
    2861               0 :       (mTextIndent != aOther.mTextIndent) ||
    2862                 :       (mWordSpacing != aOther.mWordSpacing) ||
    2863                 :       (mTabSize != aOther.mTabSize))
    2864               0 :     return NS_STYLE_HINT_REFLOW;
    2865                 : 
    2866               0 :   return CalcShadowDifference(mTextShadow, aOther.mTextShadow);
    2867                 : }
    2868                 : 
    2869                 : #ifdef DEBUG
    2870                 : /* static */
    2871               0 : nsChangeHint nsStyleText::MaxDifference()
    2872                 : {
    2873               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2874                 : }
    2875                 : #endif
    2876                 : 
    2877                 : //-----------------------
    2878                 : // nsStyleUserInterface
    2879                 : //
    2880                 : 
    2881               0 : nsCursorImage::nsCursorImage()
    2882                 :   : mHaveHotspot(false)
    2883                 :   , mHotspotX(0.0f)
    2884               0 :   , mHotspotY(0.0f)
    2885                 : {
    2886               0 : }
    2887                 : 
    2888               0 : nsCursorImage::nsCursorImage(const nsCursorImage& aOther)
    2889                 :   : mHaveHotspot(aOther.mHaveHotspot)
    2890                 :   , mHotspotX(aOther.mHotspotX)
    2891               0 :   , mHotspotY(aOther.mHotspotY)
    2892                 : {
    2893               0 :   SetImage(aOther.GetImage());
    2894               0 : }
    2895                 : 
    2896               0 : nsCursorImage::~nsCursorImage()
    2897                 : {
    2898               0 :   SetImage(nsnull);
    2899               0 : }
    2900                 : 
    2901                 : nsCursorImage&
    2902               0 : nsCursorImage::operator=(const nsCursorImage& aOther)
    2903                 : {
    2904               0 :   if (this != &aOther) {
    2905               0 :     mHaveHotspot = aOther.mHaveHotspot;
    2906               0 :     mHotspotX = aOther.mHotspotX;
    2907               0 :     mHotspotY = aOther.mHotspotY;
    2908               0 :     SetImage(aOther.GetImage());
    2909                 :   }
    2910                 : 
    2911               0 :   return *this;
    2912                 : }
    2913                 : 
    2914               0 : nsStyleUserInterface::nsStyleUserInterface(void) 
    2915                 : { 
    2916               0 :   MOZ_COUNT_CTOR(nsStyleUserInterface);
    2917               0 :   mUserInput = NS_STYLE_USER_INPUT_AUTO;
    2918               0 :   mUserModify = NS_STYLE_USER_MODIFY_READ_ONLY;
    2919               0 :   mUserFocus = NS_STYLE_USER_FOCUS_NONE;
    2920                 : 
    2921               0 :   mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113
    2922                 : 
    2923               0 :   mCursorArrayLength = 0;
    2924               0 :   mCursorArray = nsnull;
    2925               0 : }
    2926                 : 
    2927               0 : nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource) :
    2928                 :   mUserInput(aSource.mUserInput),
    2929                 :   mUserModify(aSource.mUserModify),
    2930                 :   mUserFocus(aSource.mUserFocus),
    2931               0 :   mCursor(aSource.mCursor)
    2932                 : { 
    2933               0 :   MOZ_COUNT_CTOR(nsStyleUserInterface);
    2934               0 :   CopyCursorArrayFrom(aSource);
    2935               0 : }
    2936                 : 
    2937               0 : nsStyleUserInterface::~nsStyleUserInterface(void) 
    2938                 : { 
    2939               0 :   MOZ_COUNT_DTOR(nsStyleUserInterface);
    2940               0 :   delete [] mCursorArray;
    2941               0 : }
    2942                 : 
    2943               0 : nsChangeHint nsStyleUserInterface::CalcDifference(const nsStyleUserInterface& aOther) const
    2944                 : {
    2945               0 :   nsChangeHint hint = nsChangeHint(0);
    2946               0 :   if (mCursor != aOther.mCursor)
    2947               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateCursor);
    2948                 : 
    2949                 :   // We could do better. But it wouldn't be worth it, URL-specified cursors are
    2950                 :   // rare.
    2951               0 :   if (mCursorArrayLength > 0 || aOther.mCursorArrayLength > 0)
    2952               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateCursor);
    2953                 : 
    2954               0 :   if (mUserModify != aOther.mUserModify)
    2955               0 :     NS_UpdateHint(hint, NS_STYLE_HINT_VISUAL);
    2956                 :   
    2957               0 :   if ((mUserInput != aOther.mUserInput) &&
    2958                 :       ((NS_STYLE_USER_INPUT_NONE == mUserInput) || 
    2959                 :        (NS_STYLE_USER_INPUT_NONE == aOther.mUserInput))) {
    2960               0 :     NS_UpdateHint(hint, NS_STYLE_HINT_FRAMECHANGE);
    2961                 :   }
    2962                 : 
    2963                 :   // ignore mUserFocus
    2964                 : 
    2965               0 :   return hint;
    2966                 : }
    2967                 : 
    2968                 : #ifdef DEBUG
    2969                 : /* static */
    2970               0 : nsChangeHint nsStyleUserInterface::MaxDifference()
    2971                 : {
    2972               0 :   return nsChangeHint(nsChangeHint_UpdateCursor | NS_STYLE_HINT_FRAMECHANGE);
    2973                 : }
    2974                 : #endif
    2975                 : 
    2976                 : void
    2977               0 : nsStyleUserInterface::CopyCursorArrayFrom(const nsStyleUserInterface& aSource)
    2978                 : {
    2979               0 :   mCursorArray = nsnull;
    2980               0 :   mCursorArrayLength = 0;
    2981               0 :   if (aSource.mCursorArrayLength) {
    2982               0 :     mCursorArray = new nsCursorImage[aSource.mCursorArrayLength];
    2983               0 :     if (mCursorArray) {
    2984               0 :       mCursorArrayLength = aSource.mCursorArrayLength;
    2985               0 :       for (PRUint32 i = 0; i < mCursorArrayLength; ++i)
    2986               0 :         mCursorArray[i] = aSource.mCursorArray[i];
    2987                 :     }
    2988                 :   }
    2989               0 : }
    2990                 : 
    2991                 : //-----------------------
    2992                 : // nsStyleUIReset
    2993                 : //
    2994                 : 
    2995               0 : nsStyleUIReset::nsStyleUIReset(void) 
    2996                 : { 
    2997               0 :   MOZ_COUNT_CTOR(nsStyleUIReset);
    2998               0 :   mUserSelect = NS_STYLE_USER_SELECT_AUTO;
    2999               0 :   mForceBrokenImageIcon = 0;
    3000               0 :   mIMEMode = NS_STYLE_IME_MODE_AUTO;
    3001               0 :   mWindowShadow = NS_STYLE_WINDOW_SHADOW_DEFAULT;
    3002               0 : }
    3003                 : 
    3004               0 : nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource) 
    3005                 : {
    3006               0 :   MOZ_COUNT_CTOR(nsStyleUIReset);
    3007               0 :   mUserSelect = aSource.mUserSelect;
    3008               0 :   mForceBrokenImageIcon = aSource.mForceBrokenImageIcon;
    3009               0 :   mIMEMode = aSource.mIMEMode;
    3010               0 :   mWindowShadow = aSource.mWindowShadow;
    3011               0 : }
    3012                 : 
    3013               0 : nsStyleUIReset::~nsStyleUIReset(void) 
    3014                 : { 
    3015               0 :   MOZ_COUNT_DTOR(nsStyleUIReset);
    3016               0 : }
    3017                 : 
    3018               0 : nsChangeHint nsStyleUIReset::CalcDifference(const nsStyleUIReset& aOther) const
    3019                 : {
    3020                 :   // ignore mIMEMode
    3021               0 :   if (mForceBrokenImageIcon != aOther.mForceBrokenImageIcon)
    3022               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    3023               0 :   if (mWindowShadow != aOther.mWindowShadow) {
    3024                 :     // We really need just an nsChangeHint_SyncFrameView, except
    3025                 :     // on an ancestor of the frame, so we get that by doing a
    3026                 :     // reflow.
    3027               0 :     return NS_STYLE_HINT_REFLOW;
    3028                 :   }
    3029               0 :   if (mUserSelect != aOther.mUserSelect)
    3030               0 :     return NS_STYLE_HINT_VISUAL;
    3031               0 :   return NS_STYLE_HINT_NONE;
    3032                 : }
    3033                 : 
    3034                 : #ifdef DEBUG
    3035                 : /* static */
    3036               0 : nsChangeHint nsStyleUIReset::MaxDifference()
    3037                 : {
    3038               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    3039                 : }
    3040                 : #endif
    3041                 : 

Generated by: LCOV version 1.7