LCOV - code coverage report
Current view: directory - layout/style - nsStyleStruct.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1483 0 0.0 %
Date: 2012-06-02 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               0 :   mColumnFill = NS_STYLE_COLUMN_FILL_BALANCE;
     799                 : 
     800               0 :   mColumnRuleWidth = (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
     801               0 :   mColumnRuleStyle = NS_STYLE_BORDER_STYLE_NONE;
     802               0 :   mColumnRuleColor = NS_RGB(0, 0, 0);
     803               0 :   mColumnRuleColorIsForeground = true;
     804                 : 
     805               0 :   mTwipsPerPixel = aPresContext->AppUnitsPerDevPixel();
     806               0 : }
     807                 : 
     808               0 : nsStyleColumn::~nsStyleColumn() 
     809                 : {
     810               0 :   MOZ_COUNT_DTOR(nsStyleColumn);
     811               0 : }
     812                 : 
     813               0 : nsStyleColumn::nsStyleColumn(const nsStyleColumn& aSource)
     814                 : {
     815               0 :   MOZ_COUNT_CTOR(nsStyleColumn);
     816               0 :   memcpy((nsStyleColumn*)this, &aSource, sizeof(nsStyleColumn));
     817               0 : }
     818                 : 
     819               0 : nsChangeHint nsStyleColumn::CalcDifference(const nsStyleColumn& aOther) const
     820                 : {
     821               0 :   if ((mColumnWidth.GetUnit() == eStyleUnit_Auto)
     822               0 :       != (aOther.mColumnWidth.GetUnit() == eStyleUnit_Auto) ||
     823                 :       mColumnCount != aOther.mColumnCount)
     824                 :     // We force column count changes to do a reframe, because it's tricky to handle
     825                 :     // some edge cases where the column count gets smaller and content overflows.
     826                 :     // XXX not ideal
     827               0 :     return NS_STYLE_HINT_FRAMECHANGE;
     828                 : 
     829               0 :   if (mColumnWidth != aOther.mColumnWidth ||
     830               0 :       mColumnGap != aOther.mColumnGap ||
     831                 :       mColumnFill != aOther.mColumnFill)
     832               0 :     return NS_STYLE_HINT_REFLOW;
     833                 : 
     834               0 :   if (GetComputedColumnRuleWidth() != aOther.GetComputedColumnRuleWidth() ||
     835                 :       mColumnRuleStyle != aOther.mColumnRuleStyle ||
     836                 :       mColumnRuleColor != aOther.mColumnRuleColor ||
     837                 :       mColumnRuleColorIsForeground != aOther.mColumnRuleColorIsForeground)
     838               0 :     return NS_STYLE_HINT_VISUAL;
     839                 : 
     840               0 :   return NS_STYLE_HINT_NONE;
     841                 : }
     842                 : 
     843                 : #ifdef DEBUG
     844                 : /* static */
     845               0 : nsChangeHint nsStyleColumn::MaxDifference()
     846                 : {
     847               0 :   return NS_STYLE_HINT_FRAMECHANGE;
     848                 : }
     849                 : #endif
     850                 : 
     851                 : // --------------------
     852                 : // nsStyleSVG
     853                 : //
     854               0 : nsStyleSVG::nsStyleSVG() 
     855                 : {
     856               0 :     MOZ_COUNT_CTOR(nsStyleSVG);
     857               0 :     mFill.mType              = eStyleSVGPaintType_Color;
     858               0 :     mFill.mPaint.mColor      = NS_RGB(0,0,0);
     859               0 :     mFill.mFallbackColor     = NS_RGB(0,0,0);
     860               0 :     mStroke.mType            = eStyleSVGPaintType_None;
     861               0 :     mStroke.mPaint.mColor    = NS_RGB(0,0,0);
     862               0 :     mStroke.mFallbackColor   = NS_RGB(0,0,0);
     863               0 :     mStrokeDasharray         = nsnull;
     864                 : 
     865               0 :     mStrokeDashoffset.SetCoordValue(0);
     866               0 :     mStrokeWidth.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
     867                 : 
     868               0 :     mFillOpacity             = 1.0f;
     869               0 :     mStrokeMiterlimit        = 4.0f;
     870               0 :     mStrokeOpacity           = 1.0f;
     871                 : 
     872               0 :     mStrokeDasharrayLength   = 0;
     873               0 :     mClipRule                = NS_STYLE_FILL_RULE_NONZERO;
     874               0 :     mColorInterpolation      = NS_STYLE_COLOR_INTERPOLATION_SRGB;
     875               0 :     mColorInterpolationFilters = NS_STYLE_COLOR_INTERPOLATION_LINEARRGB;
     876               0 :     mFillRule                = NS_STYLE_FILL_RULE_NONZERO;
     877               0 :     mImageRendering          = NS_STYLE_IMAGE_RENDERING_AUTO;
     878               0 :     mShapeRendering          = NS_STYLE_SHAPE_RENDERING_AUTO;
     879               0 :     mStrokeLinecap           = NS_STYLE_STROKE_LINECAP_BUTT;
     880               0 :     mStrokeLinejoin          = NS_STYLE_STROKE_LINEJOIN_MITER;
     881               0 :     mTextAnchor              = NS_STYLE_TEXT_ANCHOR_START;
     882               0 :     mTextRendering           = NS_STYLE_TEXT_RENDERING_AUTO;
     883               0 : }
     884                 : 
     885               0 : nsStyleSVG::~nsStyleSVG() 
     886                 : {
     887               0 :   MOZ_COUNT_DTOR(nsStyleSVG);
     888               0 :   delete [] mStrokeDasharray;
     889               0 : }
     890                 : 
     891               0 : nsStyleSVG::nsStyleSVG(const nsStyleSVG& aSource)
     892                 : {
     893               0 :   MOZ_COUNT_CTOR(nsStyleSVG);
     894               0 :   mFill = aSource.mFill;
     895               0 :   mStroke = aSource.mStroke;
     896                 : 
     897               0 :   mMarkerEnd = aSource.mMarkerEnd;
     898               0 :   mMarkerMid = aSource.mMarkerMid;
     899               0 :   mMarkerStart = aSource.mMarkerStart;
     900                 : 
     901               0 :   mStrokeDasharrayLength = aSource.mStrokeDasharrayLength;
     902               0 :   if (aSource.mStrokeDasharray) {
     903               0 :     mStrokeDasharray = new nsStyleCoord[mStrokeDasharrayLength];
     904               0 :     if (mStrokeDasharray)
     905                 :       memcpy(mStrokeDasharray,
     906                 :              aSource.mStrokeDasharray,
     907               0 :              mStrokeDasharrayLength * sizeof(nsStyleCoord));
     908                 :     else
     909               0 :       mStrokeDasharrayLength = 0;
     910                 :   } else {
     911               0 :     mStrokeDasharray = nsnull;
     912                 :   }
     913                 : 
     914               0 :   mStrokeDashoffset = aSource.mStrokeDashoffset;
     915               0 :   mStrokeWidth = aSource.mStrokeWidth;
     916                 : 
     917               0 :   mFillOpacity = aSource.mFillOpacity;
     918               0 :   mStrokeMiterlimit = aSource.mStrokeMiterlimit;
     919               0 :   mStrokeOpacity = aSource.mStrokeOpacity;
     920                 : 
     921               0 :   mClipRule = aSource.mClipRule;
     922               0 :   mColorInterpolation = aSource.mColorInterpolation;
     923               0 :   mColorInterpolationFilters = aSource.mColorInterpolationFilters;
     924               0 :   mFillRule = aSource.mFillRule;
     925               0 :   mImageRendering = aSource.mImageRendering;
     926               0 :   mShapeRendering = aSource.mShapeRendering;
     927               0 :   mStrokeLinecap = aSource.mStrokeLinecap;
     928               0 :   mStrokeLinejoin = aSource.mStrokeLinejoin;
     929               0 :   mTextAnchor = aSource.mTextAnchor;
     930               0 :   mTextRendering = aSource.mTextRendering;
     931               0 : }
     932                 : 
     933               0 : static bool PaintURIChanged(const nsStyleSVGPaint& aPaint1,
     934                 :                               const nsStyleSVGPaint& aPaint2)
     935                 : {
     936               0 :   if (aPaint1.mType != aPaint2.mType) {
     937                 :     return aPaint1.mType == eStyleSVGPaintType_Server ||
     938               0 :            aPaint2.mType == eStyleSVGPaintType_Server;
     939                 :   }
     940                 :   return aPaint1.mType == eStyleSVGPaintType_Server &&
     941               0 :     !EqualURIs(aPaint1.mPaint.mPaintServer, aPaint2.mPaint.mPaintServer);
     942                 : }
     943                 : 
     944               0 : nsChangeHint nsStyleSVG::CalcDifference(const nsStyleSVG& aOther) const
     945                 : {
     946               0 :   nsChangeHint hint = nsChangeHint(0);
     947                 : 
     948               0 :   if (mTextRendering != aOther.mTextRendering) {
     949               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     950                 :     // May be needed for non-svg frames
     951               0 :     NS_UpdateHint(hint, nsChangeHint_ReflowFrame);
     952                 :   }
     953                 : 
     954               0 :   if (!EqualURIs(mMarkerEnd, aOther.mMarkerEnd) ||
     955               0 :       !EqualURIs(mMarkerMid, aOther.mMarkerMid) ||
     956               0 :       !EqualURIs(mMarkerStart, aOther.mMarkerStart)) {
     957               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     958               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateEffects);
     959               0 :     return hint;
     960                 :   }
     961                 : 
     962               0 :   if (mFill != aOther.mFill ||
     963               0 :       mStroke != aOther.mStroke) {
     964               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     965               0 :     if (PaintURIChanged(mFill, aOther.mFill) ||
     966               0 :         PaintURIChanged(mStroke, aOther.mStroke)) {
     967               0 :       NS_UpdateHint(hint, nsChangeHint_UpdateEffects);
     968                 :     }
     969                 :     // Nothing more to do, below we can only set "repaint"
     970               0 :     return hint;
     971                 :   }
     972                 : 
     973               0 :   if ( mStrokeDashoffset      != aOther.mStrokeDashoffset      ||
     974               0 :        mStrokeWidth           != aOther.mStrokeWidth           ||
     975                 : 
     976                 :        mFillOpacity           != aOther.mFillOpacity           ||
     977                 :        mStrokeMiterlimit      != aOther.mStrokeMiterlimit      ||
     978                 :        mStrokeOpacity         != aOther.mStrokeOpacity         ||
     979                 : 
     980                 :        mClipRule              != aOther.mClipRule              ||
     981                 :        mColorInterpolation    != aOther.mColorInterpolation    ||
     982                 :        mColorInterpolationFilters != aOther.mColorInterpolationFilters ||
     983                 :        mFillRule              != aOther.mFillRule              ||
     984                 :        mImageRendering        != aOther.mImageRendering        ||
     985                 :        mShapeRendering        != aOther.mShapeRendering        ||
     986                 :        mStrokeDasharrayLength != aOther.mStrokeDasharrayLength ||
     987                 :        mStrokeLinecap         != aOther.mStrokeLinecap         ||
     988                 :        mStrokeLinejoin        != aOther.mStrokeLinejoin        ||
     989                 :        mTextAnchor            != aOther.mTextAnchor) {
     990               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     991               0 :     return hint;
     992                 :   }
     993                 : 
     994                 :   // length of stroke dasharrays are the same (tested above) - check entries
     995               0 :   for (PRUint32 i=0; i<mStrokeDasharrayLength; i++)
     996               0 :     if (mStrokeDasharray[i] != aOther.mStrokeDasharray[i]) {
     997               0 :       NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     998               0 :       return hint;
     999                 :     }
    1000                 : 
    1001               0 :   return hint;
    1002                 : }
    1003                 : 
    1004                 : #ifdef DEBUG
    1005                 : /* static */
    1006               0 : nsChangeHint nsStyleSVG::MaxDifference()
    1007                 : {
    1008                 :   return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects,
    1009                 :                                        nsChangeHint_ReflowFrame),
    1010               0 :                                        nsChangeHint_RepaintFrame);
    1011                 : }
    1012                 : #endif
    1013                 : 
    1014                 : // --------------------
    1015                 : // nsStyleSVGReset
    1016                 : //
    1017               0 : nsStyleSVGReset::nsStyleSVGReset() 
    1018                 : {
    1019               0 :     MOZ_COUNT_CTOR(nsStyleSVGReset);
    1020               0 :     mStopColor               = NS_RGB(0,0,0);
    1021               0 :     mFloodColor              = NS_RGB(0,0,0);
    1022               0 :     mLightingColor           = NS_RGB(255,255,255);
    1023               0 :     mClipPath                = nsnull;
    1024               0 :     mFilter                  = nsnull;
    1025               0 :     mMask                    = nsnull;
    1026               0 :     mStopOpacity             = 1.0f;
    1027               0 :     mFloodOpacity            = 1.0f;
    1028               0 :     mDominantBaseline        = NS_STYLE_DOMINANT_BASELINE_AUTO;
    1029               0 : }
    1030                 : 
    1031               0 : nsStyleSVGReset::~nsStyleSVGReset() 
    1032                 : {
    1033               0 :   MOZ_COUNT_DTOR(nsStyleSVGReset);
    1034               0 : }
    1035                 : 
    1036               0 : nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
    1037                 : {
    1038               0 :   MOZ_COUNT_CTOR(nsStyleSVGReset);
    1039               0 :   mStopColor = aSource.mStopColor;
    1040               0 :   mFloodColor = aSource.mFloodColor;
    1041               0 :   mLightingColor = aSource.mLightingColor;
    1042               0 :   mClipPath = aSource.mClipPath;
    1043               0 :   mFilter = aSource.mFilter;
    1044               0 :   mMask = aSource.mMask;
    1045               0 :   mStopOpacity = aSource.mStopOpacity;
    1046               0 :   mFloodOpacity = aSource.mFloodOpacity;
    1047               0 :   mDominantBaseline = aSource.mDominantBaseline;
    1048               0 : }
    1049                 : 
    1050               0 : nsChangeHint nsStyleSVGReset::CalcDifference(const nsStyleSVGReset& aOther) const
    1051                 : {
    1052               0 :   nsChangeHint hint = nsChangeHint(0);
    1053                 : 
    1054               0 :   if (!EqualURIs(mClipPath, aOther.mClipPath) ||
    1055               0 :       !EqualURIs(mFilter, aOther.mFilter)     ||
    1056               0 :       !EqualURIs(mMask, aOther.mMask)) {
    1057               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateEffects);
    1058               0 :     NS_UpdateHint(hint, nsChangeHint_ReflowFrame);
    1059               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
    1060               0 :   } else if (mStopColor        != aOther.mStopColor     ||
    1061                 :              mFloodColor       != aOther.mFloodColor    ||
    1062                 :              mLightingColor    != aOther.mLightingColor ||
    1063                 :              mStopOpacity      != aOther.mStopOpacity   ||
    1064                 :              mFloodOpacity     != aOther.mFloodOpacity  ||
    1065                 :              mDominantBaseline != aOther.mDominantBaseline)
    1066               0 :     NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
    1067                 : 
    1068               0 :   return hint;
    1069                 : }
    1070                 : 
    1071                 : #ifdef DEBUG
    1072                 : /* static */
    1073               0 : nsChangeHint nsStyleSVGReset::MaxDifference()
    1074                 : {
    1075                 :   return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects,
    1076                 :                                        nsChangeHint_ReflowFrame),
    1077               0 :                                        nsChangeHint_RepaintFrame);
    1078                 : }
    1079                 : #endif
    1080                 : 
    1081                 : // nsStyleSVGPaint implementation
    1082               0 : nsStyleSVGPaint::~nsStyleSVGPaint()
    1083                 : {
    1084               0 :   if (mType == eStyleSVGPaintType_Server) {
    1085               0 :     NS_IF_RELEASE(mPaint.mPaintServer);
    1086                 :   }
    1087               0 : }
    1088                 : 
    1089                 : void
    1090               0 : nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType)
    1091                 : {
    1092               0 :   if (mType == eStyleSVGPaintType_Server) {
    1093               0 :     this->~nsStyleSVGPaint();
    1094               0 :     new (this) nsStyleSVGPaint();
    1095                 :   }
    1096               0 :   mType = aType;
    1097               0 : }
    1098                 : 
    1099               0 : nsStyleSVGPaint& nsStyleSVGPaint::operator=(const nsStyleSVGPaint& aOther) 
    1100                 : {
    1101               0 :   if (this == &aOther)
    1102               0 :     return *this;
    1103                 : 
    1104               0 :   SetType(aOther.mType);
    1105                 : 
    1106               0 :   mFallbackColor = aOther.mFallbackColor;
    1107               0 :   if (mType == eStyleSVGPaintType_Server) {
    1108               0 :     mPaint.mPaintServer = aOther.mPaint.mPaintServer;
    1109               0 :     NS_IF_ADDREF(mPaint.mPaintServer);
    1110                 :   } else {
    1111               0 :     mPaint.mColor = aOther.mPaint.mColor;
    1112                 :   }
    1113               0 :   return *this;
    1114                 : }
    1115                 : 
    1116               0 : bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const
    1117                 : {
    1118               0 :   if (mType != aOther.mType)
    1119               0 :     return false;
    1120               0 :   if (mType == eStyleSVGPaintType_Server)
    1121               0 :     return EqualURIs(mPaint.mPaintServer, aOther.mPaint.mPaintServer) &&
    1122               0 :            mFallbackColor == aOther.mFallbackColor;
    1123               0 :   if (mType == eStyleSVGPaintType_None)
    1124               0 :     return true;
    1125               0 :   return mPaint.mColor == aOther.mPaint.mColor;
    1126                 : }
    1127                 : 
    1128                 : 
    1129                 : // --------------------
    1130                 : // nsStylePosition
    1131                 : //
    1132               0 : nsStylePosition::nsStylePosition(void) 
    1133                 : { 
    1134               0 :   MOZ_COUNT_CTOR(nsStylePosition);
    1135                 :   // positioning values not inherited
    1136               0 :   nsStyleCoord  autoCoord(eStyleUnit_Auto);
    1137               0 :   mOffset.SetLeft(autoCoord);
    1138               0 :   mOffset.SetTop(autoCoord);
    1139               0 :   mOffset.SetRight(autoCoord);
    1140               0 :   mOffset.SetBottom(autoCoord);
    1141               0 :   mWidth.SetAutoValue();
    1142               0 :   mMinWidth.SetCoordValue(0);
    1143               0 :   mMaxWidth.SetNoneValue();
    1144               0 :   mHeight.SetAutoValue();
    1145               0 :   mMinHeight.SetCoordValue(0);
    1146               0 :   mMaxHeight.SetNoneValue();
    1147               0 :   mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
    1148               0 :   mZIndex.SetAutoValue();
    1149               0 : }
    1150                 : 
    1151               0 : nsStylePosition::~nsStylePosition(void) 
    1152                 : { 
    1153               0 :   MOZ_COUNT_DTOR(nsStylePosition);
    1154               0 : }
    1155                 : 
    1156               0 : nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
    1157                 : {
    1158               0 :   MOZ_COUNT_CTOR(nsStylePosition);
    1159               0 :   memcpy((nsStylePosition*)this, &aSource, sizeof(nsStylePosition));
    1160               0 : }
    1161                 : 
    1162               0 : nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) const
    1163                 : {
    1164                 :   nsChangeHint hint =
    1165               0 :     (mZIndex == aOther.mZIndex) ? NS_STYLE_HINT_NONE : nsChangeHint_RepaintFrame;
    1166                 : 
    1167               0 :   if (mBoxSizing != aOther.mBoxSizing) {
    1168                 :     // Can affect both widths and heights; just a bad scene.
    1169               0 :     return NS_CombineHint(hint, nsChangeHint_ReflowFrame);
    1170                 :   }
    1171                 : 
    1172               0 :   if (mHeight != aOther.mHeight ||
    1173               0 :       mMinHeight != aOther.mMinHeight ||
    1174               0 :       mMaxHeight != aOther.mMaxHeight) {
    1175                 :     // Height changes can affect descendant intrinsic sizes due to replaced
    1176                 :     // elements with percentage heights in descendants which also have
    1177                 :     // percentage heights.  And due to our not-so-great computation of mVResize
    1178                 :     // in nsHTMLReflowState, they do need to force reflow of the whole subtree.
    1179                 :     // XXXbz due to XUL caching heights as well, height changes also need to
    1180                 :     // clear ancestor intrinsics!
    1181               0 :     return NS_CombineHint(hint, nsChangeHint_ReflowFrame);
    1182                 :   }
    1183                 : 
    1184               0 :   if ((mWidth == aOther.mWidth) &&
    1185               0 :       (mMinWidth == aOther.mMinWidth) &&
    1186               0 :       (mMaxWidth == aOther.mMaxWidth)) {
    1187               0 :     if (mOffset == aOther.mOffset) {
    1188               0 :       return hint;
    1189                 :     } else {
    1190                 :       // Offset changes only affect positioned content, and can't affect any
    1191                 :       // intrinsic widths.  They also don't need to force reflow of
    1192                 :       // descendants.
    1193               0 :       return NS_CombineHint(hint, nsChangeHint_NeedReflow);
    1194                 :     }
    1195                 :   }
    1196                 : 
    1197                 :   // None of our width differences can affect descendant intrinsic
    1198                 :   // sizes and none of them need to force children to reflow.
    1199                 :   return
    1200                 :     NS_CombineHint(hint,
    1201                 :                    NS_SubtractHint(nsChangeHint_ReflowFrame,
    1202                 :                                    NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
    1203               0 :                                                   nsChangeHint_NeedDirtyReflow)));
    1204                 : }
    1205                 : 
    1206                 : #ifdef DEBUG
    1207                 : /* static */
    1208               0 : nsChangeHint nsStylePosition::MaxDifference()
    1209                 : {
    1210               0 :   return NS_STYLE_HINT_REFLOW;
    1211                 : }
    1212                 : #endif
    1213                 : 
    1214                 : /* static */ bool
    1215               0 : nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord &aCoord)
    1216                 : {
    1217               0 :   return aCoord.GetUnit() == eStyleUnit_Auto ||
    1218               0 :          aCoord.HasPercent() ||
    1219               0 :          (aCoord.GetUnit() == eStyleUnit_Enumerated &&
    1220               0 :           (aCoord.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT ||
    1221               0 :            aCoord.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE));
    1222                 : }
    1223                 : 
    1224                 : // --------------------
    1225                 : // nsStyleTable
    1226                 : //
    1227                 : 
    1228               0 : nsStyleTable::nsStyleTable() 
    1229                 : { 
    1230               0 :   MOZ_COUNT_CTOR(nsStyleTable);
    1231                 :   // values not inherited
    1232               0 :   mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
    1233               0 :   mCols  = NS_STYLE_TABLE_COLS_NONE;
    1234               0 :   mFrame = NS_STYLE_TABLE_FRAME_NONE;
    1235               0 :   mRules = NS_STYLE_TABLE_RULES_NONE;
    1236               0 :   mSpan = 1;
    1237               0 : }
    1238                 : 
    1239               0 : nsStyleTable::~nsStyleTable(void) 
    1240                 : {
    1241               0 :   MOZ_COUNT_DTOR(nsStyleTable);
    1242               0 : }
    1243                 : 
    1244               0 : nsStyleTable::nsStyleTable(const nsStyleTable& aSource)
    1245                 : {
    1246               0 :   MOZ_COUNT_CTOR(nsStyleTable);
    1247               0 :   memcpy((nsStyleTable*)this, &aSource, sizeof(nsStyleTable));
    1248               0 : }
    1249                 : 
    1250               0 : nsChangeHint nsStyleTable::CalcDifference(const nsStyleTable& aOther) const
    1251                 : {
    1252                 :   // Changes in mRules may require reframing (if border-collapse stuff changes, for example).
    1253               0 :   if (mRules != aOther.mRules || mSpan != aOther.mSpan ||
    1254                 :       mLayoutStrategy != aOther.mLayoutStrategy)
    1255               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    1256               0 :   if (mFrame != aOther.mFrame || mCols != aOther.mCols)
    1257               0 :     return NS_STYLE_HINT_REFLOW;
    1258               0 :   return NS_STYLE_HINT_NONE;
    1259                 : }
    1260                 : 
    1261                 : #ifdef DEBUG
    1262                 : /* static */
    1263               0 : nsChangeHint nsStyleTable::MaxDifference()
    1264                 : {
    1265               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    1266                 : }
    1267                 : #endif
    1268                 : 
    1269                 : // -----------------------
    1270                 : // nsStyleTableBorder
    1271                 : 
    1272               0 : nsStyleTableBorder::nsStyleTableBorder(nsPresContext* aPresContext) 
    1273                 : { 
    1274               0 :   MOZ_COUNT_CTOR(nsStyleTableBorder);
    1275               0 :   mBorderCollapse = NS_STYLE_BORDER_SEPARATE;
    1276                 : 
    1277               0 :   nsCompatibility compatMode = eCompatibility_FullStandards;
    1278               0 :   if (aPresContext)
    1279               0 :     compatMode = aPresContext->CompatibilityMode();
    1280                 :   mEmptyCells = (compatMode == eCompatibility_NavQuirks)
    1281                 :                   ? NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND     
    1282               0 :                   : NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
    1283               0 :   mCaptionSide = NS_STYLE_CAPTION_SIDE_TOP;
    1284               0 :   mBorderSpacingX = 0;
    1285               0 :   mBorderSpacingY = 0;
    1286               0 : }
    1287                 : 
    1288               0 : nsStyleTableBorder::~nsStyleTableBorder(void) 
    1289                 : {
    1290               0 :   MOZ_COUNT_DTOR(nsStyleTableBorder);
    1291               0 : }
    1292                 : 
    1293               0 : nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder& aSource)
    1294                 : {
    1295               0 :   MOZ_COUNT_CTOR(nsStyleTableBorder);
    1296               0 :   memcpy((nsStyleTableBorder*)this, &aSource, sizeof(nsStyleTableBorder));
    1297               0 : }
    1298                 : 
    1299               0 : nsChangeHint nsStyleTableBorder::CalcDifference(const nsStyleTableBorder& aOther) const
    1300                 : {
    1301                 :   // Border-collapse changes need a reframe, because we use a different frame
    1302                 :   // class for table cells in the collapsed border model.  This is used to
    1303                 :   // conserve memory when using the separated border model (collapsed borders
    1304                 :   // require extra state to be stored).
    1305               0 :   if (mBorderCollapse != aOther.mBorderCollapse) {
    1306               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    1307                 :   }
    1308                 :   
    1309               0 :   if ((mCaptionSide == aOther.mCaptionSide) &&
    1310                 :       (mBorderSpacingX == aOther.mBorderSpacingX) &&
    1311                 :       (mBorderSpacingY == aOther.mBorderSpacingY)) {
    1312               0 :     if (mEmptyCells == aOther.mEmptyCells)
    1313               0 :       return NS_STYLE_HINT_NONE;
    1314               0 :     return NS_STYLE_HINT_VISUAL;
    1315                 :   }
    1316                 :   else
    1317               0 :     return NS_STYLE_HINT_REFLOW;
    1318                 : }
    1319                 : 
    1320                 : #ifdef DEBUG
    1321                 : /* static */
    1322               0 : nsChangeHint nsStyleTableBorder::MaxDifference()
    1323                 : {
    1324               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    1325                 : }
    1326                 : #endif
    1327                 : 
    1328                 : // --------------------
    1329                 : // nsStyleColor
    1330                 : //
    1331                 : 
    1332               0 : nsStyleColor::nsStyleColor(nsPresContext* aPresContext)
    1333                 : {
    1334               0 :   MOZ_COUNT_CTOR(nsStyleColor);
    1335               0 :   mColor = aPresContext->DefaultColor();
    1336               0 : }
    1337                 : 
    1338               0 : nsStyleColor::nsStyleColor(const nsStyleColor& aSource)
    1339                 : {
    1340               0 :   MOZ_COUNT_CTOR(nsStyleColor);
    1341               0 :   mColor = aSource.mColor;
    1342               0 : }
    1343                 : 
    1344               0 : nsChangeHint nsStyleColor::CalcDifference(const nsStyleColor& aOther) const
    1345                 : {
    1346               0 :   if (mColor == aOther.mColor)
    1347               0 :     return NS_STYLE_HINT_NONE;
    1348               0 :   return NS_STYLE_HINT_VISUAL;
    1349                 : }
    1350                 : 
    1351                 : #ifdef DEBUG
    1352                 : /* static */
    1353               0 : nsChangeHint nsStyleColor::MaxDifference()
    1354                 : {
    1355               0 :   return NS_STYLE_HINT_VISUAL;
    1356                 : }
    1357                 : #endif
    1358                 : 
    1359                 : // --------------------
    1360                 : // nsStyleGradient
    1361                 : //
    1362                 : bool
    1363               0 : nsStyleGradient::operator==(const nsStyleGradient& aOther) const
    1364                 : {
    1365               0 :   NS_ABORT_IF_FALSE(mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
    1366                 :                     mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
    1367                 :                     "incorrect combination of shape and size");
    1368               0 :   NS_ABORT_IF_FALSE(aOther.mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
    1369                 :                     aOther.mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
    1370                 :                     "incorrect combination of shape and size");
    1371                 : 
    1372               0 :   if (mShape != aOther.mShape ||
    1373                 :       mSize != aOther.mSize ||
    1374                 :       mRepeating != aOther.mRepeating ||
    1375                 :       mToCorner != aOther.mToCorner ||
    1376               0 :       mBgPosX != aOther.mBgPosX ||
    1377               0 :       mBgPosY != aOther.mBgPosY ||
    1378               0 :       mAngle != aOther.mAngle)
    1379               0 :     return false;
    1380                 : 
    1381               0 :   if (mStops.Length() != aOther.mStops.Length())
    1382               0 :     return false;
    1383                 : 
    1384               0 :   for (PRUint32 i = 0; i < mStops.Length(); i++) {
    1385               0 :     if (mStops[i].mLocation != aOther.mStops[i].mLocation ||
    1386               0 :         mStops[i].mColor != aOther.mStops[i].mColor)
    1387               0 :       return false;
    1388                 :   }
    1389                 : 
    1390               0 :   return true;
    1391                 : }
    1392                 : 
    1393               0 : nsStyleGradient::nsStyleGradient(void)
    1394                 :   : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR)
    1395                 :   , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)
    1396                 :   , mRepeating(false)
    1397               0 :   , mToCorner(false)
    1398                 : {
    1399               0 : }
    1400                 : 
    1401                 : bool
    1402               0 : nsStyleGradient::IsOpaque()
    1403                 : {
    1404               0 :   for (PRUint32 i = 0; i < mStops.Length(); i++) {
    1405               0 :     if (NS_GET_A(mStops[i].mColor) < 255)
    1406               0 :       return false;
    1407                 :   }
    1408               0 :   return true;
    1409                 : }
    1410                 : 
    1411                 : // --------------------
    1412                 : // nsStyleImage
    1413                 : //
    1414                 : 
    1415               0 : nsStyleImage::nsStyleImage()
    1416                 :   : mType(eStyleImageType_Null)
    1417                 :   , mCropRect(nsnull)
    1418                 : #ifdef DEBUG
    1419               0 :   , mImageTracked(false)
    1420                 : #endif
    1421                 : {
    1422               0 :   MOZ_COUNT_CTOR(nsStyleImage);
    1423               0 : }
    1424                 : 
    1425               0 : nsStyleImage::~nsStyleImage()
    1426                 : {
    1427               0 :   MOZ_COUNT_DTOR(nsStyleImage);
    1428               0 :   if (mType != eStyleImageType_Null)
    1429               0 :     SetNull();
    1430               0 : }
    1431                 : 
    1432               0 : nsStyleImage::nsStyleImage(const nsStyleImage& aOther)
    1433                 :   : mType(eStyleImageType_Null)
    1434                 :   , mCropRect(nsnull)
    1435                 : #ifdef DEBUG
    1436               0 :   , mImageTracked(false)
    1437                 : #endif
    1438                 : {
    1439                 :   // We need our own copy constructor because we don't want
    1440                 :   // to copy the reference count
    1441               0 :   MOZ_COUNT_CTOR(nsStyleImage);
    1442               0 :   DoCopy(aOther);
    1443               0 : }
    1444                 : 
    1445                 : nsStyleImage&
    1446               0 : nsStyleImage::operator=(const nsStyleImage& aOther)
    1447                 : {
    1448               0 :   if (this != &aOther)
    1449               0 :     DoCopy(aOther);
    1450                 : 
    1451               0 :   return *this;
    1452                 : }
    1453                 : 
    1454                 : void
    1455               0 : nsStyleImage::DoCopy(const nsStyleImage& aOther)
    1456                 : {
    1457               0 :   SetNull();
    1458                 : 
    1459               0 :   if (aOther.mType == eStyleImageType_Image)
    1460               0 :     SetImageData(aOther.mImage);
    1461               0 :   else if (aOther.mType == eStyleImageType_Gradient)
    1462               0 :     SetGradientData(aOther.mGradient);
    1463               0 :   else if (aOther.mType == eStyleImageType_Element)
    1464               0 :     SetElementId(aOther.mElementId);
    1465                 : 
    1466               0 :   SetCropRect(aOther.mCropRect);
    1467               0 : }
    1468                 : 
    1469                 : void
    1470               0 : nsStyleImage::SetNull()
    1471                 : {
    1472               0 :   NS_ABORT_IF_FALSE(!mImageTracked,
    1473                 :                     "Calling SetNull() with image tracked!");
    1474                 : 
    1475               0 :   if (mType == eStyleImageType_Gradient)
    1476               0 :     mGradient->Release();
    1477               0 :   else if (mType == eStyleImageType_Image)
    1478               0 :     NS_RELEASE(mImage);
    1479               0 :   else if (mType == eStyleImageType_Element)
    1480               0 :     NS_Free(mElementId);
    1481                 : 
    1482               0 :   mType = eStyleImageType_Null;
    1483               0 :   mCropRect = nsnull;
    1484               0 : }
    1485                 : 
    1486                 : void
    1487               0 : nsStyleImage::SetImageData(imgIRequest* aImage)
    1488                 : {
    1489               0 :   NS_ABORT_IF_FALSE(!mImageTracked,
    1490                 :                     "Setting a new image without untracking the old one!");
    1491                 : 
    1492               0 :   NS_IF_ADDREF(aImage);
    1493                 : 
    1494               0 :   if (mType != eStyleImageType_Null)
    1495               0 :     SetNull();
    1496                 : 
    1497               0 :   if (aImage) {
    1498               0 :     mImage = aImage;
    1499               0 :     mType = eStyleImageType_Image;
    1500                 :   }
    1501               0 : }
    1502                 : 
    1503                 : void
    1504               0 : nsStyleImage::TrackImage(nsPresContext* aContext)
    1505                 : {
    1506                 :   // Sanity
    1507               0 :   NS_ABORT_IF_FALSE(!mImageTracked, "Already tracking image!");
    1508               0 :   NS_ABORT_IF_FALSE(mType == eStyleImageType_Image,
    1509                 :                     "Can't track image when there isn't one!");
    1510                 : 
    1511                 :   // Register the image with the document
    1512               0 :   nsIDocument* doc = aContext->Document();
    1513               0 :   if (doc)
    1514               0 :     doc->AddImage(mImage);
    1515                 : 
    1516                 :   // Mark state
    1517                 : #ifdef DEBUG
    1518               0 :   mImageTracked = true;
    1519                 : #endif
    1520               0 : }
    1521                 : 
    1522                 : void
    1523               0 : nsStyleImage::UntrackImage(nsPresContext* aContext)
    1524                 : {
    1525                 :   // Sanity
    1526               0 :   NS_ABORT_IF_FALSE(mImageTracked, "Image not tracked!");
    1527               0 :   NS_ABORT_IF_FALSE(mType == eStyleImageType_Image,
    1528                 :                     "Can't untrack image when there isn't one!");
    1529                 : 
    1530                 :   // Unregister the image with the document
    1531               0 :   nsIDocument* doc = aContext->Document();
    1532               0 :   if (doc)
    1533               0 :     doc->RemoveImage(mImage);
    1534                 : 
    1535                 :   // Mark state
    1536                 : #ifdef DEBUG
    1537               0 :   mImageTracked = false;
    1538                 : #endif
    1539               0 : }
    1540                 : 
    1541                 : void
    1542               0 : nsStyleImage::SetGradientData(nsStyleGradient* aGradient)
    1543                 : {
    1544               0 :   if (aGradient)
    1545               0 :     aGradient->AddRef();
    1546                 : 
    1547               0 :   if (mType != eStyleImageType_Null)
    1548               0 :     SetNull();
    1549                 : 
    1550               0 :   if (aGradient) {
    1551               0 :     mGradient = aGradient;
    1552               0 :     mType = eStyleImageType_Gradient;
    1553                 :   }
    1554               0 : }
    1555                 : 
    1556                 : void
    1557               0 : nsStyleImage::SetElementId(const PRUnichar* aElementId)
    1558                 : {
    1559               0 :   if (mType != eStyleImageType_Null)
    1560               0 :     SetNull();
    1561                 : 
    1562               0 :   if (aElementId) {
    1563               0 :     mElementId = NS_strdup(aElementId);
    1564               0 :     mType = eStyleImageType_Element;
    1565                 :   }
    1566               0 : }
    1567                 : 
    1568                 : void
    1569               0 : nsStyleImage::SetCropRect(nsStyleSides* aCropRect)
    1570                 : {
    1571               0 :   if (aCropRect) {
    1572               0 :     mCropRect = new nsStyleSides(*aCropRect);
    1573                 :     // There is really not much we can do if 'new' fails
    1574                 :   } else {
    1575               0 :     mCropRect = nsnull;
    1576                 :   }
    1577               0 : }
    1578                 : 
    1579                 : static PRInt32
    1580               0 : ConvertToPixelCoord(const nsStyleCoord& aCoord, PRInt32 aPercentScale)
    1581                 : {
    1582                 :   double pixelValue;
    1583               0 :   switch (aCoord.GetUnit()) {
    1584                 :     case eStyleUnit_Percent:
    1585               0 :       pixelValue = aCoord.GetPercentValue() * aPercentScale;
    1586               0 :       break;
    1587                 :     case eStyleUnit_Factor:
    1588               0 :       pixelValue = aCoord.GetFactorValue();
    1589               0 :       break;
    1590                 :     default:
    1591               0 :       NS_NOTREACHED("unexpected unit for image crop rect");
    1592               0 :       return 0;
    1593                 :   }
    1594               0 :   NS_ABORT_IF_FALSE(pixelValue >= 0, "we ensured non-negative while parsing");
    1595               0 :   pixelValue = NS_MIN(pixelValue, double(PR_INT32_MAX)); // avoid overflow
    1596               0 :   return NS_lround(pixelValue);
    1597                 : }
    1598                 : 
    1599                 : bool
    1600               0 : nsStyleImage::ComputeActualCropRect(nsIntRect& aActualCropRect,
    1601                 :                                     bool* aIsEntireImage) const
    1602                 : {
    1603               0 :   if (mType != eStyleImageType_Image)
    1604               0 :     return false;
    1605                 : 
    1606               0 :   nsCOMPtr<imgIContainer> imageContainer;
    1607               0 :   mImage->GetImage(getter_AddRefs(imageContainer));
    1608               0 :   if (!imageContainer)
    1609               0 :     return false;
    1610                 : 
    1611               0 :   nsIntSize imageSize;
    1612               0 :   imageContainer->GetWidth(&imageSize.width);
    1613               0 :   imageContainer->GetHeight(&imageSize.height);
    1614               0 :   if (imageSize.width <= 0 || imageSize.height <= 0)
    1615               0 :     return false;
    1616                 : 
    1617               0 :   PRInt32 left   = ConvertToPixelCoord(mCropRect->GetLeft(),   imageSize.width);
    1618               0 :   PRInt32 top    = ConvertToPixelCoord(mCropRect->GetTop(),    imageSize.height);
    1619               0 :   PRInt32 right  = ConvertToPixelCoord(mCropRect->GetRight(),  imageSize.width);
    1620               0 :   PRInt32 bottom = ConvertToPixelCoord(mCropRect->GetBottom(), imageSize.height);
    1621                 : 
    1622                 :   // IntersectRect() returns an empty rect if we get negative width or height
    1623               0 :   nsIntRect cropRect(left, top, right - left, bottom - top);
    1624               0 :   nsIntRect imageRect(nsIntPoint(0, 0), imageSize);
    1625               0 :   aActualCropRect.IntersectRect(imageRect, cropRect);
    1626                 : 
    1627               0 :   if (aIsEntireImage)
    1628               0 :     *aIsEntireImage = aActualCropRect.IsEqualInterior(imageRect);
    1629               0 :   return true;
    1630                 : }
    1631                 : 
    1632                 : nsresult
    1633               0 : nsStyleImage::RequestDecode() const
    1634                 : {
    1635               0 :   if ((mType == eStyleImageType_Image) && mImage)
    1636               0 :     return mImage->RequestDecode();
    1637               0 :   return NS_OK;
    1638                 : }
    1639                 : 
    1640                 : bool
    1641               0 : nsStyleImage::IsOpaque() const
    1642                 : {
    1643               0 :   if (!IsComplete())
    1644               0 :     return false;
    1645                 : 
    1646               0 :   if (mType == eStyleImageType_Gradient)
    1647               0 :     return mGradient->IsOpaque();
    1648                 : 
    1649               0 :   if (mType == eStyleImageType_Element)
    1650               0 :     return false;
    1651                 : 
    1652               0 :   NS_ABORT_IF_FALSE(mType == eStyleImageType_Image, "unexpected image type");
    1653                 : 
    1654               0 :   nsCOMPtr<imgIContainer> imageContainer;
    1655               0 :   mImage->GetImage(getter_AddRefs(imageContainer));
    1656               0 :   NS_ABORT_IF_FALSE(imageContainer, "IsComplete() said image container is ready");
    1657                 : 
    1658                 :   // Check if the crop region of the current image frame is opaque
    1659                 :   bool isOpaque;
    1660               0 :   if (NS_SUCCEEDED(imageContainer->GetCurrentFrameIsOpaque(&isOpaque)) &&
    1661                 :       isOpaque) {
    1662               0 :     if (!mCropRect)
    1663               0 :       return true;
    1664                 : 
    1665                 :     // Must make sure if mCropRect contains at least a pixel.
    1666                 :     // XXX Is this optimization worth it? Maybe I should just return false.
    1667               0 :     nsIntRect actualCropRect;
    1668               0 :     bool rv = ComputeActualCropRect(actualCropRect);
    1669               0 :     NS_ASSERTION(rv, "ComputeActualCropRect() can not fail here");
    1670               0 :     return rv && !actualCropRect.IsEmpty();
    1671                 :   }
    1672                 : 
    1673               0 :   return false;
    1674                 : }
    1675                 : 
    1676                 : bool
    1677               0 : nsStyleImage::IsComplete() const
    1678                 : {
    1679               0 :   switch (mType) {
    1680                 :     case eStyleImageType_Null:
    1681               0 :       return false;
    1682                 :     case eStyleImageType_Gradient:
    1683                 :     case eStyleImageType_Element:
    1684               0 :       return true;
    1685                 :     case eStyleImageType_Image:
    1686                 :     {
    1687               0 :       PRUint32 status = imgIRequest::STATUS_ERROR;
    1688               0 :       return NS_SUCCEEDED(mImage->GetImageStatus(&status)) &&
    1689                 :              (status & imgIRequest::STATUS_SIZE_AVAILABLE) &&
    1690               0 :              (status & imgIRequest::STATUS_FRAME_COMPLETE);
    1691                 :     }
    1692                 :     default:
    1693               0 :       NS_NOTREACHED("unexpected image type");
    1694               0 :       return false;
    1695                 :   }
    1696                 : }
    1697                 : 
    1698                 : static inline bool
    1699               0 : EqualRects(const nsStyleSides* aRect1, const nsStyleSides* aRect2)
    1700                 : {
    1701                 :   return aRect1 == aRect2 || /* handles null== null, and optimize */
    1702               0 :          (aRect1 && aRect2 && *aRect1 == *aRect2);
    1703                 : }
    1704                 : 
    1705                 : bool
    1706               0 : nsStyleImage::operator==(const nsStyleImage& aOther) const
    1707                 : {
    1708               0 :   if (mType != aOther.mType)
    1709               0 :     return false;
    1710                 : 
    1711               0 :   if (!EqualRects(mCropRect, aOther.mCropRect))
    1712               0 :     return false;
    1713                 : 
    1714               0 :   if (mType == eStyleImageType_Image)
    1715               0 :     return EqualImages(mImage, aOther.mImage);
    1716                 : 
    1717               0 :   if (mType == eStyleImageType_Gradient)
    1718               0 :     return *mGradient == *aOther.mGradient;
    1719                 : 
    1720               0 :   if (mType == eStyleImageType_Element)
    1721               0 :     return NS_strcmp(mElementId, aOther.mElementId) == 0;
    1722                 : 
    1723               0 :   return true;
    1724                 : }
    1725                 : 
    1726                 : // --------------------
    1727                 : // nsStyleBackground
    1728                 : //
    1729                 : 
    1730               0 : nsStyleBackground::nsStyleBackground()
    1731                 :   : mAttachmentCount(1)
    1732                 :   , mClipCount(1)
    1733                 :   , mOriginCount(1)
    1734                 :   , mRepeatCount(1)
    1735                 :   , mPositionCount(1)
    1736                 :   , mImageCount(1)
    1737                 :   , mSizeCount(1)
    1738                 :   , mBackgroundColor(NS_RGBA(0, 0, 0, 0))
    1739               0 :   , mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS)
    1740                 : {
    1741               0 :   MOZ_COUNT_CTOR(nsStyleBackground);
    1742               0 :   Layer *onlyLayer = mLayers.AppendElement();
    1743               0 :   NS_ASSERTION(onlyLayer, "auto array must have room for 1 element");
    1744               0 :   onlyLayer->SetInitialValues();
    1745               0 : }
    1746                 : 
    1747               0 : nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
    1748                 :   : mAttachmentCount(aSource.mAttachmentCount)
    1749                 :   , mClipCount(aSource.mClipCount)
    1750                 :   , mOriginCount(aSource.mOriginCount)
    1751                 :   , mRepeatCount(aSource.mRepeatCount)
    1752                 :   , mPositionCount(aSource.mPositionCount)
    1753                 :   , mImageCount(aSource.mImageCount)
    1754                 :   , mSizeCount(aSource.mSizeCount)
    1755                 :   , mLayers(aSource.mLayers) // deep copy
    1756                 :   , mBackgroundColor(aSource.mBackgroundColor)
    1757               0 :   , mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy)
    1758                 : {
    1759               0 :   MOZ_COUNT_CTOR(nsStyleBackground);
    1760                 :   // If the deep copy of mLayers failed, truncate the counts.
    1761               0 :   PRUint32 count = mLayers.Length();
    1762               0 :   if (count != aSource.mLayers.Length()) {
    1763               0 :     NS_WARNING("truncating counts due to out-of-memory");
    1764               0 :     mAttachmentCount = NS_MAX(mAttachmentCount, count);
    1765               0 :     mClipCount = NS_MAX(mClipCount, count);
    1766               0 :     mOriginCount = NS_MAX(mOriginCount, count);
    1767               0 :     mRepeatCount = NS_MAX(mRepeatCount, count);
    1768               0 :     mPositionCount = NS_MAX(mPositionCount, count);
    1769               0 :     mImageCount = NS_MAX(mImageCount, count);
    1770               0 :     mSizeCount = NS_MAX(mSizeCount, count);
    1771                 :   }
    1772               0 : }
    1773                 : 
    1774               0 : nsStyleBackground::~nsStyleBackground()
    1775                 : {
    1776               0 :   MOZ_COUNT_DTOR(nsStyleBackground);
    1777               0 : }
    1778                 : 
    1779                 : void
    1780               0 : nsStyleBackground::Destroy(nsPresContext* aContext)
    1781                 : {
    1782                 :   // Untrack all the images stored in our layers
    1783               0 :   for (PRUint32 i = 0; i < mImageCount; ++i)
    1784               0 :     mLayers[i].UntrackImages(aContext);
    1785                 : 
    1786               0 :   this->~nsStyleBackground();
    1787               0 :   aContext->FreeToShell(sizeof(nsStyleBackground), this);
    1788               0 : }
    1789                 : 
    1790               0 : nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
    1791                 : {
    1792                 :   const nsStyleBackground* moreLayers =
    1793               0 :     mImageCount > aOther.mImageCount ? this : &aOther;
    1794                 :   const nsStyleBackground* lessLayers =
    1795               0 :     mImageCount > aOther.mImageCount ? &aOther : this;
    1796                 : 
    1797               0 :   bool hasVisualDifference = false;
    1798                 : 
    1799               0 :   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, moreLayers) {
    1800               0 :     if (i < lessLayers->mImageCount) {
    1801               0 :       if (moreLayers->mLayers[i] != lessLayers->mLayers[i]) {
    1802               0 :         if ((moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
    1803               0 :             (lessLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element))
    1804               0 :           return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
    1805               0 :         hasVisualDifference = true;
    1806                 :       }
    1807                 :     } else {
    1808               0 :       if (moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element)
    1809               0 :         return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
    1810               0 :       hasVisualDifference = true;
    1811                 :     }
    1812                 :   }
    1813                 : 
    1814               0 :   if (hasVisualDifference ||
    1815                 :       mBackgroundColor != aOther.mBackgroundColor ||
    1816                 :       mBackgroundInlinePolicy != aOther.mBackgroundInlinePolicy)
    1817               0 :     return NS_STYLE_HINT_VISUAL;
    1818                 : 
    1819               0 :   return NS_STYLE_HINT_NONE;
    1820                 : }
    1821                 : 
    1822                 : #ifdef DEBUG
    1823                 : /* static */
    1824               0 : nsChangeHint nsStyleBackground::MaxDifference()
    1825                 : {
    1826               0 :   return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
    1827                 : }
    1828                 : #endif
    1829                 : 
    1830               0 : bool nsStyleBackground::HasFixedBackground() const
    1831                 : {
    1832               0 :   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
    1833               0 :     const Layer &layer = mLayers[i];
    1834               0 :     if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
    1835               0 :         !layer.mImage.IsEmpty()) {
    1836               0 :       return true;
    1837                 :     }
    1838                 :   }
    1839               0 :   return false;
    1840                 : }
    1841                 : 
    1842               0 : bool nsStyleBackground::IsTransparent() const
    1843                 : {
    1844               0 :   return BottomLayer().mImage.IsEmpty() &&
    1845                 :          mImageCount == 1 &&
    1846               0 :          NS_GET_A(mBackgroundColor) == 0;
    1847                 : }
    1848                 : 
    1849                 : void
    1850               0 : nsStyleBackground::Position::SetInitialValues()
    1851                 : {
    1852                 :   // Initial value is "0% 0%"
    1853               0 :   mXPosition.mPercent = 0.0f;
    1854               0 :   mXPosition.mLength = 0;
    1855               0 :   mXPosition.mHasPercent = true;
    1856               0 :   mYPosition.mPercent = 0.0f;
    1857               0 :   mYPosition.mLength = 0;
    1858               0 :   mYPosition.mHasPercent = true;
    1859               0 : }
    1860                 : 
    1861                 : bool
    1862               0 : nsStyleBackground::Size::DependsOnFrameSize(const nsStyleImage& aImage) const
    1863                 : {
    1864               0 :   NS_ABORT_IF_FALSE(aImage.GetType() != eStyleImageType_Null,
    1865                 :                     "caller should have handled this");
    1866                 : 
    1867                 :   // If either dimension contains a non-zero percentage, rendering for that
    1868                 :   // dimension straightforwardly depends on frame size.
    1869               0 :   if ((mWidthType == eLengthPercentage && mWidth.mPercent != 0.0f) ||
    1870                 :       (mHeightType == eLengthPercentage && mHeight.mPercent != 0.0f)) {
    1871               0 :     return true;
    1872                 :   }
    1873                 : 
    1874                 :   // So too for contain and cover.
    1875               0 :   if (mWidthType == eContain || mWidthType == eCover) {
    1876               0 :     return true;
    1877                 :   }
    1878                 : 
    1879                 :   // If both dimensions are fixed lengths, there's no dependency.
    1880               0 :   if (mWidthType == eLengthPercentage && mHeightType == eLengthPercentage) {
    1881               0 :     return false;
    1882                 :   }
    1883                 : 
    1884               0 :   NS_ABORT_IF_FALSE((mWidthType == eLengthPercentage && mHeightType == eAuto) ||
    1885                 :                     (mWidthType == eAuto && mHeightType == eLengthPercentage) ||
    1886                 :                     (mWidthType == eAuto && mHeightType == eAuto),
    1887                 :                     "logic error");
    1888                 : 
    1889               0 :   nsStyleImageType type = aImage.GetType();
    1890                 : 
    1891                 :   // Gradient rendering depends on frame size when auto is involved because
    1892                 :   // gradients have no intrinsic ratio or dimensions, and therefore the relevant
    1893                 :   // dimension is "treat[ed] as 100%".
    1894               0 :   if (type == eStyleImageType_Gradient) {
    1895               0 :     return true;
    1896                 :   }
    1897                 : 
    1898                 :   // XXX Element rendering for auto or fixed length doesn't depend on frame size
    1899                 :   //     according to the spec.  However, we don't implement the spec yet, so
    1900                 :   //     for now we bail and say element() plus auto affects ultimate size.
    1901               0 :   if (type == eStyleImageType_Element) {
    1902               0 :     return true;
    1903                 :   }
    1904                 : 
    1905               0 :   if (type == eStyleImageType_Image) {
    1906               0 :     nsCOMPtr<imgIContainer> imgContainer;
    1907               0 :     aImage.GetImageData()->GetImage(getter_AddRefs(imgContainer));
    1908               0 :     if (imgContainer) {
    1909               0 :       nsIntSize imageSize;
    1910               0 :       nsSize imageRatio;
    1911                 :       bool hasWidth, hasHeight;
    1912                 :       nsLayoutUtils::ComputeSizeForDrawing(imgContainer, imageSize, imageRatio,
    1913               0 :                                            hasWidth, hasHeight);
    1914                 : 
    1915                 :       // If the image has a fixed width and height, rendering never depends on
    1916                 :       // the frame size.
    1917               0 :       if (hasWidth && hasHeight) {
    1918               0 :         return false;
    1919                 :       }
    1920                 : 
    1921                 :       // If the image has an intrinsic ratio, rendering will depend on frame
    1922                 :       // size when background-size is all auto.
    1923               0 :       if (imageRatio != nsSize(0, 0)) {
    1924               0 :         return mWidthType == mHeightType;
    1925                 :       }
    1926                 : 
    1927                 :       // Otherwise, rendering depends on frame size when the image dimensions
    1928                 :       // and background-size don't complement each other.
    1929               0 :       return !(hasWidth && mHeightType == eLengthPercentage) &&
    1930               0 :              !(hasHeight && mWidthType == eLengthPercentage);
    1931                 :     }
    1932                 :   } else {
    1933               0 :     NS_NOTREACHED("missed an enum value");
    1934                 :   }
    1935                 : 
    1936                 :   // Passed the gauntlet: no dependency.
    1937               0 :   return false;
    1938                 : }
    1939                 : 
    1940                 : void
    1941               0 : nsStyleBackground::Size::SetInitialValues()
    1942                 : {
    1943               0 :   mWidthType = mHeightType = eAuto;
    1944               0 : }
    1945                 : 
    1946                 : bool
    1947               0 : nsStyleBackground::Size::operator==(const Size& aOther) const
    1948                 : {
    1949               0 :   NS_ABORT_IF_FALSE(mWidthType < eDimensionType_COUNT,
    1950                 :                     "bad mWidthType for this");
    1951               0 :   NS_ABORT_IF_FALSE(mHeightType < eDimensionType_COUNT,
    1952                 :                     "bad mHeightType for this");
    1953               0 :   NS_ABORT_IF_FALSE(aOther.mWidthType < eDimensionType_COUNT,
    1954                 :                     "bad mWidthType for aOther");
    1955               0 :   NS_ABORT_IF_FALSE(aOther.mHeightType < eDimensionType_COUNT,
    1956                 :                     "bad mHeightType for aOther");
    1957                 : 
    1958                 :   return mWidthType == aOther.mWidthType &&
    1959                 :          mHeightType == aOther.mHeightType &&
    1960               0 :          (mWidthType != eLengthPercentage || mWidth == aOther.mWidth) &&
    1961               0 :          (mHeightType != eLengthPercentage || mHeight == aOther.mHeight);
    1962                 : }
    1963                 : 
    1964                 : void
    1965               0 : nsStyleBackground::Repeat::SetInitialValues() 
    1966                 : {
    1967               0 :   mXRepeat = NS_STYLE_BG_REPEAT_REPEAT;
    1968               0 :   mYRepeat = NS_STYLE_BG_REPEAT_REPEAT;
    1969               0 : }
    1970                 : 
    1971               0 : nsStyleBackground::Layer::Layer()
    1972                 : {
    1973               0 : }
    1974                 : 
    1975               0 : nsStyleBackground::Layer::~Layer()
    1976                 : {
    1977               0 : }
    1978                 : 
    1979                 : void
    1980               0 : nsStyleBackground::Layer::SetInitialValues()
    1981                 : {
    1982               0 :   mAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
    1983               0 :   mClip = NS_STYLE_BG_CLIP_BORDER;
    1984               0 :   mOrigin = NS_STYLE_BG_ORIGIN_PADDING;
    1985               0 :   mRepeat.SetInitialValues();
    1986               0 :   mPosition.SetInitialValues();
    1987               0 :   mSize.SetInitialValues();
    1988               0 :   mImage.SetNull();
    1989               0 : }
    1990                 : 
    1991                 : bool
    1992               0 : nsStyleBackground::Layer::RenderingMightDependOnFrameSize() const
    1993                 : {
    1994                 :   // Do we even have an image?
    1995               0 :   if (mImage.IsEmpty()) {
    1996               0 :     return false;
    1997                 :   }
    1998                 : 
    1999               0 :   return mPosition.DependsOnFrameSize() || mSize.DependsOnFrameSize(mImage);
    2000                 : }
    2001                 : 
    2002                 : bool
    2003               0 : nsStyleBackground::Layer::operator==(const Layer& aOther) const
    2004                 : {
    2005                 :   return mAttachment == aOther.mAttachment &&
    2006                 :          mClip == aOther.mClip &&
    2007                 :          mOrigin == aOther.mOrigin &&
    2008               0 :          mRepeat == aOther.mRepeat &&
    2009               0 :          mPosition == aOther.mPosition &&
    2010               0 :          mSize == aOther.mSize &&
    2011               0 :          mImage == aOther.mImage;
    2012                 : }
    2013                 : 
    2014                 : // --------------------
    2015                 : // nsStyleDisplay
    2016                 : //
    2017               0 : void nsTimingFunction::AssignFromKeyword(PRInt32 aTimingFunctionType)
    2018                 : {
    2019               0 :   switch (aTimingFunctionType) {
    2020                 :     case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START:
    2021               0 :       mType = StepStart;
    2022               0 :       mSteps = 1;
    2023               0 :       return;
    2024                 :     case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END:
    2025               0 :       mType = StepEnd;
    2026               0 :       mSteps = 1;
    2027               0 :       return;
    2028                 :     default:
    2029               0 :       mType = Function;
    2030                 :       break;
    2031                 :   }
    2032                 : 
    2033                 :   MOZ_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE == 0 &&
    2034                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR == 1 &&
    2035                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN == 2 &&
    2036                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT == 3 &&
    2037                 :                     NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT == 4,
    2038                 :                     "transition timing function constants not as expected");
    2039                 : 
    2040                 :   static const float timingFunctionValues[5][4] = {
    2041                 :     { 0.25, 0.10, 0.25, 1.00 }, // ease
    2042                 :     { 0.00, 0.00, 1.00, 1.00 }, // linear
    2043                 :     { 0.42, 0.00, 1.00, 1.00 }, // ease-in
    2044                 :     { 0.00, 0.00, 0.58, 1.00 }, // ease-out
    2045                 :     { 0.42, 0.00, 0.58, 1.00 }  // ease-in-out
    2046                 :   };
    2047                 : 
    2048               0 :   NS_ABORT_IF_FALSE(0 <= aTimingFunctionType && aTimingFunctionType < 5,
    2049                 :                     "keyword out of range");
    2050               0 :   mFunc.mX1 = timingFunctionValues[aTimingFunctionType][0];
    2051               0 :   mFunc.mY1 = timingFunctionValues[aTimingFunctionType][1];
    2052               0 :   mFunc.mX2 = timingFunctionValues[aTimingFunctionType][2];
    2053               0 :   mFunc.mY2 = timingFunctionValues[aTimingFunctionType][3];
    2054                 : }
    2055                 : 
    2056               0 : nsTransition::nsTransition(const nsTransition& aCopy)
    2057                 :   : mTimingFunction(aCopy.mTimingFunction)
    2058                 :   , mDuration(aCopy.mDuration)
    2059                 :   , mDelay(aCopy.mDelay)
    2060                 :   , mProperty(aCopy.mProperty)
    2061               0 :   , mUnknownProperty(aCopy.mUnknownProperty)
    2062                 : {
    2063               0 : }
    2064                 : 
    2065               0 : void nsTransition::SetInitialValues()
    2066                 : {
    2067               0 :   mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE);
    2068               0 :   mDuration = 0.0;
    2069               0 :   mDelay = 0.0;
    2070               0 :   mProperty = eCSSPropertyExtra_all_properties;
    2071               0 : }
    2072                 : 
    2073               0 : void nsTransition::SetUnknownProperty(const nsAString& aUnknownProperty)
    2074                 : {
    2075               0 :   NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty) ==
    2076                 :                  eCSSProperty_UNKNOWN,
    2077                 :                "should be unknown property");
    2078               0 :   mProperty = eCSSProperty_UNKNOWN;
    2079               0 :   mUnknownProperty = do_GetAtom(aUnknownProperty);
    2080               0 : }
    2081                 : 
    2082               0 : nsAnimation::nsAnimation(const nsAnimation& aCopy)
    2083                 :   : mTimingFunction(aCopy.mTimingFunction)
    2084                 :   , mDuration(aCopy.mDuration)
    2085                 :   , mDelay(aCopy.mDelay)
    2086                 :   , mName(aCopy.mName)
    2087                 :   , mDirection(aCopy.mDirection)
    2088                 :   , mFillMode(aCopy.mFillMode)
    2089                 :   , mPlayState(aCopy.mPlayState)
    2090               0 :   , mIterationCount(aCopy.mIterationCount)
    2091                 : {
    2092               0 : }
    2093                 : 
    2094                 : void
    2095               0 : nsAnimation::SetInitialValues()
    2096                 : {
    2097               0 :   mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE);
    2098               0 :   mDuration = 0.0;
    2099               0 :   mDelay = 0.0;
    2100               0 :   mName = EmptyString();
    2101               0 :   mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL;
    2102               0 :   mFillMode = NS_STYLE_ANIMATION_FILL_MODE_NONE;
    2103               0 :   mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING;
    2104               0 :   mIterationCount = 1.0f;
    2105               0 : }
    2106                 : 
    2107               0 : nsStyleDisplay::nsStyleDisplay()
    2108                 : {
    2109               0 :   MOZ_COUNT_CTOR(nsStyleDisplay);
    2110               0 :   mAppearance = NS_THEME_NONE;
    2111               0 :   mDisplay = NS_STYLE_DISPLAY_INLINE;
    2112               0 :   mOriginalDisplay = mDisplay;
    2113               0 :   mPosition = NS_STYLE_POSITION_STATIC;
    2114               0 :   mFloats = NS_STYLE_FLOAT_NONE;
    2115               0 :   mOriginalFloats = mFloats;
    2116               0 :   mBreakType = NS_STYLE_CLEAR_NONE;
    2117               0 :   mBreakBefore = false;
    2118               0 :   mBreakAfter = false;
    2119               0 :   mOverflowX = NS_STYLE_OVERFLOW_VISIBLE;
    2120               0 :   mOverflowY = NS_STYLE_OVERFLOW_VISIBLE;
    2121               0 :   mResize = NS_STYLE_RESIZE_NONE;
    2122               0 :   mClipFlags = NS_STYLE_CLIP_AUTO;
    2123               0 :   mClip.SetRect(0,0,0,0);
    2124               0 :   mOpacity = 1.0f;
    2125               0 :   mSpecifiedTransform = nsnull;
    2126               0 :   mTransformOrigin[0].SetPercentValue(0.5f); // Transform is centered on origin
    2127               0 :   mTransformOrigin[1].SetPercentValue(0.5f);
    2128               0 :   mTransformOrigin[2].SetCoordValue(0);
    2129               0 :   mPerspectiveOrigin[0].SetPercentValue(0.5f);
    2130               0 :   mPerspectiveOrigin[1].SetPercentValue(0.5f);
    2131               0 :   mChildPerspective.SetCoordValue(0);
    2132               0 :   mBackfaceVisibility = NS_STYLE_BACKFACE_VISIBILITY_VISIBLE;
    2133               0 :   mTransformStyle = NS_STYLE_TRANSFORM_STYLE_FLAT;
    2134               0 :   mOrient = NS_STYLE_ORIENT_HORIZONTAL;
    2135                 : 
    2136               0 :   mTransitions.AppendElement();
    2137               0 :   NS_ABORT_IF_FALSE(mTransitions.Length() == 1,
    2138                 :                     "appending within auto buffer should never fail");
    2139               0 :   mTransitions[0].SetInitialValues();
    2140               0 :   mTransitionTimingFunctionCount = 1;
    2141               0 :   mTransitionDurationCount = 1;
    2142               0 :   mTransitionDelayCount = 1;
    2143               0 :   mTransitionPropertyCount = 1;
    2144                 : 
    2145               0 :   mAnimations.AppendElement();
    2146               0 :   NS_ABORT_IF_FALSE(mAnimations.Length() == 1,
    2147                 :                     "appending within auto buffer should never fail");
    2148               0 :   mAnimations[0].SetInitialValues();
    2149               0 :   mAnimationTimingFunctionCount = 1;
    2150               0 :   mAnimationDurationCount = 1;
    2151               0 :   mAnimationDelayCount = 1;
    2152               0 :   mAnimationNameCount = 1;
    2153               0 :   mAnimationDirectionCount = 1;
    2154               0 :   mAnimationFillModeCount = 1;
    2155               0 :   mAnimationPlayStateCount = 1;
    2156               0 :   mAnimationIterationCountCount = 1;
    2157               0 : }
    2158                 : 
    2159               0 : nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
    2160                 :   : mTransitions(aSource.mTransitions)
    2161                 :   , mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount)
    2162                 :   , mTransitionDurationCount(aSource.mTransitionDurationCount)
    2163                 :   , mTransitionDelayCount(aSource.mTransitionDelayCount)
    2164                 :   , mTransitionPropertyCount(aSource.mTransitionPropertyCount)
    2165                 :   , mAnimations(aSource.mAnimations)
    2166                 :   , mAnimationTimingFunctionCount(aSource.mAnimationTimingFunctionCount)
    2167                 :   , mAnimationDurationCount(aSource.mAnimationDurationCount)
    2168                 :   , mAnimationDelayCount(aSource.mAnimationDelayCount)
    2169                 :   , mAnimationNameCount(aSource.mAnimationNameCount)
    2170                 :   , mAnimationDirectionCount(aSource.mAnimationDirectionCount)
    2171                 :   , mAnimationFillModeCount(aSource.mAnimationFillModeCount)
    2172                 :   , mAnimationPlayStateCount(aSource.mAnimationPlayStateCount)
    2173               0 :   , mAnimationIterationCountCount(aSource.mAnimationIterationCountCount)
    2174                 : {
    2175               0 :   MOZ_COUNT_CTOR(nsStyleDisplay);
    2176               0 :   mAppearance = aSource.mAppearance;
    2177               0 :   mDisplay = aSource.mDisplay;
    2178               0 :   mOriginalDisplay = aSource.mOriginalDisplay;
    2179               0 :   mOriginalFloats = aSource.mOriginalFloats;
    2180               0 :   mBinding = aSource.mBinding;
    2181               0 :   mPosition = aSource.mPosition;
    2182               0 :   mFloats = aSource.mFloats;
    2183               0 :   mBreakType = aSource.mBreakType;
    2184               0 :   mBreakBefore = aSource.mBreakBefore;
    2185               0 :   mBreakAfter = aSource.mBreakAfter;
    2186               0 :   mOverflowX = aSource.mOverflowX;
    2187               0 :   mOverflowY = aSource.mOverflowY;
    2188               0 :   mResize = aSource.mResize;
    2189               0 :   mClipFlags = aSource.mClipFlags;
    2190               0 :   mClip = aSource.mClip;
    2191               0 :   mOpacity = aSource.mOpacity;
    2192               0 :   mOrient = aSource.mOrient;
    2193                 : 
    2194                 :   /* Copy over the transformation information. */
    2195               0 :   mSpecifiedTransform = aSource.mSpecifiedTransform;
    2196                 :   
    2197                 :   /* Copy over transform origin. */
    2198               0 :   mTransformOrigin[0] = aSource.mTransformOrigin[0];
    2199               0 :   mTransformOrigin[1] = aSource.mTransformOrigin[1];
    2200               0 :   mTransformOrigin[2] = aSource.mTransformOrigin[2];
    2201               0 :   mPerspectiveOrigin[0] = aSource.mPerspectiveOrigin[0];
    2202               0 :   mPerspectiveOrigin[1] = aSource.mPerspectiveOrigin[1];
    2203               0 :   mChildPerspective = aSource.mChildPerspective;
    2204               0 :   mBackfaceVisibility = aSource.mBackfaceVisibility;
    2205               0 :   mTransformStyle = aSource.mTransformStyle;
    2206               0 : }
    2207                 : 
    2208               0 : nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
    2209                 : {
    2210               0 :   nsChangeHint hint = nsChangeHint(0);
    2211                 : 
    2212               0 :   if (!EqualURIs(mBinding, aOther.mBinding)
    2213                 :       || mPosition != aOther.mPosition
    2214                 :       || mDisplay != aOther.mDisplay
    2215                 :       || (mFloats == NS_STYLE_FLOAT_NONE) != (aOther.mFloats == NS_STYLE_FLOAT_NONE)
    2216                 :       || mOverflowX != aOther.mOverflowX
    2217                 :       || mOverflowY != aOther.mOverflowY
    2218                 :       || mResize != aOther.mResize)
    2219               0 :     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
    2220                 : 
    2221               0 :   if (mFloats != aOther.mFloats) {
    2222                 :     // Changing which side we float on doesn't affect descendants directly
    2223                 :     NS_UpdateHint(hint,
    2224                 :        NS_SubtractHint(nsChangeHint_ReflowFrame,
    2225                 :                        NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
    2226               0 :                                       nsChangeHint_NeedDirtyReflow)));
    2227                 :   }
    2228                 : 
    2229                 :   // XXX the following is conservative, for now: changing float breaking shouldn't
    2230                 :   // necessarily require a repaint, reflow should suffice.
    2231               0 :   if (mBreakType != aOther.mBreakType
    2232                 :       || mBreakBefore != aOther.mBreakBefore
    2233                 :       || mBreakAfter != aOther.mBreakAfter
    2234                 :       || mAppearance != aOther.mAppearance
    2235                 :       || mOrient != aOther.mOrient
    2236               0 :       || mClipFlags != aOther.mClipFlags || !mClip.IsEqualInterior(aOther.mClip))
    2237               0 :     NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame));
    2238                 : 
    2239               0 :   if (mOpacity != aOther.mOpacity) {
    2240               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateOpacityLayer);
    2241                 :   }
    2242                 : 
    2243                 :   /* If we've added or removed the transform property, we need to reconstruct the frame to add
    2244                 :    * or remove the view object, and also to handle abs-pos and fixed-pos containers.
    2245                 :    */
    2246               0 :   if (HasTransform() != aOther.HasTransform()) {
    2247               0 :     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
    2248                 :   }
    2249               0 :   else if (HasTransform()) {
    2250                 :     /* Otherwise, if we've kept the property lying around and we already had a
    2251                 :      * transform, we need to see whether or not we've changed the transform.
    2252                 :      * If so, we need to recompute its overflow rect (which probably changed
    2253                 :      * if the transform changed) and to redraw within the bounds of that new
    2254                 :      * overflow rect.
    2255                 :      */
    2256               0 :     if (!mSpecifiedTransform != !aOther.mSpecifiedTransform ||
    2257                 :         (mSpecifiedTransform &&
    2258               0 :          *mSpecifiedTransform != *aOther.mSpecifiedTransform)) {
    2259                 :       NS_UpdateHint(hint, NS_CombineHint(nsChangeHint_UpdateOverflow,
    2260               0 :                                          nsChangeHint_UpdateTransformLayer));
    2261                 :     }
    2262                 : 
    2263                 :     const nsChangeHint kUpdateOverflowAndRepaintHint =
    2264               0 :       NS_CombineHint(nsChangeHint_UpdateOverflow, nsChangeHint_RepaintFrame);
    2265               0 :     for (PRUint8 index = 0; index < 3; ++index)
    2266               0 :       if (mTransformOrigin[index] != aOther.mTransformOrigin[index]) {
    2267               0 :         NS_UpdateHint(hint, kUpdateOverflowAndRepaintHint);
    2268               0 :         break;
    2269                 :       }
    2270                 :     
    2271               0 :     for (PRUint8 index = 0; index < 2; ++index)
    2272               0 :       if (mPerspectiveOrigin[index] != aOther.mPerspectiveOrigin[index]) {
    2273               0 :         NS_UpdateHint(hint, kUpdateOverflowAndRepaintHint);
    2274               0 :         break;
    2275                 :       }
    2276                 : 
    2277               0 :     if (mChildPerspective != aOther.mChildPerspective ||
    2278                 :         mTransformStyle != aOther.mTransformStyle)
    2279               0 :       NS_UpdateHint(hint, kUpdateOverflowAndRepaintHint);
    2280                 : 
    2281               0 :     if (mBackfaceVisibility != aOther.mBackfaceVisibility)
    2282               0 :       NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
    2283                 :   }
    2284                 : 
    2285                 :   // Note:  Our current behavior for handling changes to the
    2286                 :   // transition-duration, transition-delay, and transition-timing-function
    2287                 :   // properties is to do nothing.  In other words, the transition
    2288                 :   // property that matters is what it is when the transition begins, and
    2289                 :   // we don't stop a transition later because the transition property
    2290                 :   // changed.
    2291                 :   // We do handle changes to transition-property, but we don't need to
    2292                 :   // bother with anything here, since the transition manager is notified
    2293                 :   // of any style context change anyway.
    2294                 : 
    2295                 :   // Note: Likewise, for animation-*, the animation manager gets
    2296                 :   // notified about every new style context constructed, and it uses
    2297                 :   // that opportunity to handle dynamic changes appropriately.
    2298                 : 
    2299               0 :   return hint;
    2300                 : }
    2301                 : 
    2302                 : #ifdef DEBUG
    2303                 : /* static */
    2304               0 : nsChangeHint nsStyleDisplay::MaxDifference()
    2305                 : {
    2306                 :   // All the parts of FRAMECHANGE are present above in CalcDifference.
    2307                 :   return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
    2308                 :                       nsChangeHint_UpdateOpacityLayer |
    2309                 :                       nsChangeHint_UpdateTransformLayer |
    2310               0 :                       nsChangeHint_UpdateOverflow);
    2311                 : }
    2312                 : #endif
    2313                 : 
    2314                 : // --------------------
    2315                 : // nsStyleVisibility
    2316                 : //
    2317                 : 
    2318               0 : nsStyleVisibility::nsStyleVisibility(nsPresContext* aPresContext)
    2319                 : {
    2320               0 :   MOZ_COUNT_CTOR(nsStyleVisibility);
    2321               0 :   PRUint32 bidiOptions = aPresContext->GetBidi();
    2322               0 :   if (GET_BIDI_OPTION_DIRECTION(bidiOptions) == IBMBIDI_TEXTDIRECTION_RTL)
    2323               0 :     mDirection = NS_STYLE_DIRECTION_RTL;
    2324                 :   else
    2325               0 :     mDirection = NS_STYLE_DIRECTION_LTR;
    2326                 : 
    2327               0 :   mVisible = NS_STYLE_VISIBILITY_VISIBLE;
    2328               0 :   mPointerEvents = NS_STYLE_POINTER_EVENTS_AUTO;
    2329               0 : }
    2330                 : 
    2331               0 : nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
    2332                 : {
    2333               0 :   MOZ_COUNT_CTOR(nsStyleVisibility);
    2334               0 :   mDirection = aSource.mDirection;
    2335               0 :   mVisible = aSource.mVisible;
    2336               0 :   mPointerEvents = aSource.mPointerEvents;
    2337               0 : } 
    2338                 : 
    2339               0 : nsChangeHint nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const
    2340                 : {
    2341               0 :   nsChangeHint hint = nsChangeHint(0);
    2342                 : 
    2343               0 :   if (mDirection != aOther.mDirection) {
    2344               0 :     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
    2345               0 :   } else if (mVisible != aOther.mVisible) {
    2346               0 :     if ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
    2347                 :         (NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible)) {
    2348               0 :       NS_UpdateHint(hint, NS_STYLE_HINT_REFLOW);
    2349                 :     } else {
    2350               0 :       NS_UpdateHint(hint, NS_STYLE_HINT_VISUAL);
    2351                 :     }
    2352                 :   }
    2353               0 :   return hint;
    2354                 : }
    2355                 : 
    2356                 : #ifdef DEBUG
    2357                 : /* static */
    2358               0 : nsChangeHint nsStyleVisibility::MaxDifference()
    2359                 : {
    2360               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2361                 : }
    2362                 : #endif
    2363                 : 
    2364               0 : nsStyleContentData::~nsStyleContentData()
    2365                 : {
    2366               0 :   NS_ABORT_IF_FALSE(!mImageTracked,
    2367                 :                     "nsStyleContentData being destroyed while still tracking image!");
    2368               0 :   if (mType == eStyleContentType_Image) {
    2369               0 :     NS_IF_RELEASE(mContent.mImage);
    2370               0 :   } else if (mType == eStyleContentType_Counter ||
    2371                 :              mType == eStyleContentType_Counters) {
    2372               0 :     mContent.mCounters->Release();
    2373               0 :   } else if (mContent.mString) {
    2374               0 :     NS_Free(mContent.mString);
    2375                 :   }
    2376               0 : }
    2377                 : 
    2378               0 : nsStyleContentData& nsStyleContentData::operator=(const nsStyleContentData& aOther)
    2379                 : {
    2380               0 :   if (this == &aOther)
    2381               0 :     return *this;
    2382               0 :   this->~nsStyleContentData();
    2383               0 :   new (this) nsStyleContentData();
    2384                 : 
    2385               0 :   mType = aOther.mType;
    2386               0 :   if (mType == eStyleContentType_Image) {
    2387               0 :     mContent.mImage = aOther.mContent.mImage;
    2388               0 :     NS_IF_ADDREF(mContent.mImage);
    2389               0 :   } else if (mType == eStyleContentType_Counter ||
    2390                 :              mType == eStyleContentType_Counters) {
    2391               0 :     mContent.mCounters = aOther.mContent.mCounters;
    2392               0 :     mContent.mCounters->AddRef();
    2393               0 :   } else if (aOther.mContent.mString) {
    2394               0 :     mContent.mString = NS_strdup(aOther.mContent.mString);
    2395                 :   } else {
    2396               0 :     mContent.mString = nsnull;
    2397                 :   }
    2398               0 :   return *this;
    2399                 : }
    2400                 : 
    2401               0 : bool nsStyleContentData::operator==(const nsStyleContentData& aOther) const
    2402                 : {
    2403               0 :   if (mType != aOther.mType)
    2404               0 :     return false;
    2405               0 :   if (mType == eStyleContentType_Image) {
    2406               0 :     if (!mContent.mImage || !aOther.mContent.mImage)
    2407               0 :       return mContent.mImage == aOther.mContent.mImage;
    2408                 :     bool eq;
    2409               0 :     nsCOMPtr<nsIURI> thisURI, otherURI;
    2410               0 :     mContent.mImage->GetURI(getter_AddRefs(thisURI));
    2411               0 :     aOther.mContent.mImage->GetURI(getter_AddRefs(otherURI));
    2412               0 :     return thisURI == otherURI ||  // handles null==null
    2413               0 :            (thisURI && otherURI &&
    2414               0 :             NS_SUCCEEDED(thisURI->Equals(otherURI, &eq)) &&
    2415               0 :             eq);
    2416                 :   }
    2417               0 :   if (mType == eStyleContentType_Counter ||
    2418                 :       mType == eStyleContentType_Counters)
    2419               0 :     return *mContent.mCounters == *aOther.mContent.mCounters;
    2420               0 :   return safe_strcmp(mContent.mString, aOther.mContent.mString) == 0;
    2421                 : }
    2422                 : 
    2423                 : void
    2424               0 : nsStyleContentData::TrackImage(nsPresContext* aContext)
    2425                 : {
    2426                 :   // Sanity
    2427               0 :   NS_ABORT_IF_FALSE(!mImageTracked, "Already tracking image!");
    2428               0 :   NS_ABORT_IF_FALSE(mType == eStyleContentType_Image,
    2429                 :                     "Tryingto do image tracking on non-image!");
    2430               0 :   NS_ABORT_IF_FALSE(mContent.mImage,
    2431                 :                     "Can't track image when there isn't one!");
    2432                 : 
    2433                 :   // Register the image with the document
    2434               0 :   nsIDocument* doc = aContext->Document();
    2435               0 :   if (doc)
    2436               0 :     doc->AddImage(mContent.mImage);
    2437                 : 
    2438                 :   // Mark state
    2439                 : #ifdef DEBUG
    2440               0 :   mImageTracked = true;
    2441                 : #endif
    2442               0 : }
    2443                 : 
    2444                 : void
    2445               0 : nsStyleContentData::UntrackImage(nsPresContext* aContext)
    2446                 : {
    2447                 :   // Sanity
    2448               0 :   NS_ABORT_IF_FALSE(mImageTracked, "Image not tracked!");
    2449               0 :   NS_ABORT_IF_FALSE(mType == eStyleContentType_Image,
    2450                 :                     "Trying to do image tracking on non-image!");
    2451               0 :   NS_ABORT_IF_FALSE(mContent.mImage,
    2452                 :                     "Can't untrack image when there isn't one!");
    2453                 : 
    2454                 :   // Unregister the image with the document
    2455               0 :   nsIDocument* doc = aContext->Document();
    2456               0 :   if (doc)
    2457               0 :     doc->RemoveImage(mContent.mImage);
    2458                 : 
    2459                 :   // Mark state
    2460                 : #ifdef DEBUG
    2461               0 :   mImageTracked = false;
    2462                 : #endif
    2463               0 : }
    2464                 : 
    2465                 : 
    2466                 : //-----------------------
    2467                 : // nsStyleContent
    2468                 : //
    2469                 : 
    2470               0 : nsStyleContent::nsStyleContent(void)
    2471                 :   : mMarkerOffset(),
    2472                 :     mContents(nsnull),
    2473                 :     mIncrements(nsnull),
    2474                 :     mResets(nsnull),
    2475                 :     mContentCount(0),
    2476                 :     mIncrementCount(0),
    2477               0 :     mResetCount(0)
    2478                 : {
    2479               0 :   MOZ_COUNT_CTOR(nsStyleContent);
    2480               0 :   mMarkerOffset.SetAutoValue();
    2481               0 : }
    2482                 : 
    2483               0 : nsStyleContent::~nsStyleContent(void)
    2484                 : {
    2485               0 :   MOZ_COUNT_DTOR(nsStyleContent);
    2486               0 :   DELETE_ARRAY_IF(mContents);
    2487               0 :   DELETE_ARRAY_IF(mIncrements);
    2488               0 :   DELETE_ARRAY_IF(mResets);
    2489               0 : }
    2490                 : 
    2491                 : void 
    2492               0 : nsStyleContent::Destroy(nsPresContext* aContext)
    2493                 : {
    2494                 :   // Unregister any images we might have with the document.
    2495               0 :   for (PRUint32 i = 0; i < mContentCount; ++i) {
    2496               0 :     if ((mContents[i].mType == eStyleContentType_Image) &&
    2497               0 :         mContents[i].mContent.mImage) {
    2498               0 :       mContents[i].UntrackImage(aContext);
    2499                 :     }
    2500                 :   }
    2501                 : 
    2502               0 :   this->~nsStyleContent();
    2503               0 :   aContext->FreeToShell(sizeof(nsStyleContent), this);
    2504               0 : }
    2505                 : 
    2506               0 : nsStyleContent::nsStyleContent(const nsStyleContent& aSource)
    2507                 :    :mMarkerOffset(),
    2508                 :     mContents(nsnull),
    2509                 :     mIncrements(nsnull),
    2510                 :     mResets(nsnull),
    2511                 :     mContentCount(0),
    2512                 :     mIncrementCount(0),
    2513               0 :     mResetCount(0)
    2514                 : 
    2515                 : {
    2516               0 :   MOZ_COUNT_CTOR(nsStyleContent);
    2517               0 :   mMarkerOffset = aSource.mMarkerOffset;
    2518                 : 
    2519                 :   PRUint32 index;
    2520               0 :   if (NS_SUCCEEDED(AllocateContents(aSource.ContentCount()))) {
    2521               0 :     for (index = 0; index < mContentCount; index++) {
    2522               0 :       ContentAt(index) = aSource.ContentAt(index);
    2523                 :     }
    2524                 :   }
    2525                 : 
    2526               0 :   if (NS_SUCCEEDED(AllocateCounterIncrements(aSource.CounterIncrementCount()))) {
    2527               0 :     for (index = 0; index < mIncrementCount; index++) {
    2528               0 :       const nsStyleCounterData *data = aSource.GetCounterIncrementAt(index);
    2529               0 :       mIncrements[index].mCounter = data->mCounter;
    2530               0 :       mIncrements[index].mValue = data->mValue;
    2531                 :     }
    2532                 :   }
    2533                 : 
    2534               0 :   if (NS_SUCCEEDED(AllocateCounterResets(aSource.CounterResetCount()))) {
    2535               0 :     for (index = 0; index < mResetCount; index++) {
    2536               0 :       const nsStyleCounterData *data = aSource.GetCounterResetAt(index);
    2537               0 :       mResets[index].mCounter = data->mCounter;
    2538               0 :       mResets[index].mValue = data->mValue;
    2539                 :     }
    2540                 :   }
    2541               0 : }
    2542                 : 
    2543               0 : nsChangeHint nsStyleContent::CalcDifference(const nsStyleContent& aOther) const
    2544                 : {
    2545                 :   // In ReResolveStyleContext we assume that if there's no existing
    2546                 :   // ::before or ::after and we don't have to restyle children of the
    2547                 :   // node then we can't end up with a ::before or ::after due to the
    2548                 :   // restyle of the node itself.  That's not quite true, but the only
    2549                 :   // exception to the above is when the 'content' property of the node
    2550                 :   // changes and the pseudo-element inherits the changed value.  Since
    2551                 :   // the code here triggers a frame change on the node in that case,
    2552                 :   // the optimization in ReResolveStyleContext is ok.  But if we ever
    2553                 :   // change this code to not reconstruct frames on changes to the
    2554                 :   // 'content' property, then we will need to revisit the optimization
    2555                 :   // in ReResolveStyleContext.
    2556                 : 
    2557               0 :   if (mContentCount != aOther.mContentCount ||
    2558                 :       mIncrementCount != aOther.mIncrementCount || 
    2559                 :       mResetCount != aOther.mResetCount) {
    2560               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    2561                 :   }
    2562                 : 
    2563               0 :   PRUint32 ix = mContentCount;
    2564               0 :   while (0 < ix--) {
    2565               0 :     if (mContents[ix] != aOther.mContents[ix]) {
    2566                 :       // Unfortunately we need to reframe here; a simple reflow
    2567                 :       // will not pick up different text or different image URLs,
    2568                 :       // since we set all that up in the CSSFrameConstructor
    2569               0 :       return NS_STYLE_HINT_FRAMECHANGE;
    2570                 :     }
    2571                 :   }
    2572               0 :   ix = mIncrementCount;
    2573               0 :   while (0 < ix--) {
    2574               0 :     if ((mIncrements[ix].mValue != aOther.mIncrements[ix].mValue) || 
    2575               0 :         (mIncrements[ix].mCounter != aOther.mIncrements[ix].mCounter)) {
    2576               0 :       return NS_STYLE_HINT_FRAMECHANGE;
    2577                 :     }
    2578                 :   }
    2579               0 :   ix = mResetCount;
    2580               0 :   while (0 < ix--) {
    2581               0 :     if ((mResets[ix].mValue != aOther.mResets[ix].mValue) || 
    2582               0 :         (mResets[ix].mCounter != aOther.mResets[ix].mCounter)) {
    2583               0 :       return NS_STYLE_HINT_FRAMECHANGE;
    2584                 :     }
    2585                 :   }
    2586               0 :   if (mMarkerOffset != aOther.mMarkerOffset) {
    2587               0 :     return NS_STYLE_HINT_REFLOW;
    2588                 :   }
    2589               0 :   return NS_STYLE_HINT_NONE;
    2590                 : }
    2591                 : 
    2592                 : #ifdef DEBUG
    2593                 : /* static */
    2594               0 : nsChangeHint nsStyleContent::MaxDifference()
    2595                 : {
    2596               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2597                 : }
    2598                 : #endif
    2599                 : 
    2600               0 : nsresult nsStyleContent::AllocateContents(PRUint32 aCount)
    2601                 : {
    2602                 :   // We need to run the destructors of the elements of mContents, so we
    2603                 :   // delete and reallocate even if aCount == mContentCount.  (If
    2604                 :   // nsStyleContentData had its members private and managed their
    2605                 :   // ownership on setting, we wouldn't need this, but that seems
    2606                 :   // unnecessary at this point.)
    2607               0 :   DELETE_ARRAY_IF(mContents);
    2608               0 :   if (aCount) {
    2609               0 :     mContents = new nsStyleContentData[aCount];
    2610               0 :     if (! mContents) {
    2611               0 :       mContentCount = 0;
    2612               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2613                 :     }
    2614                 :   }
    2615               0 :   mContentCount = aCount;
    2616               0 :   return NS_OK;
    2617                 : }
    2618                 : 
    2619                 : // ---------------------
    2620                 : // nsStyleQuotes
    2621                 : //
    2622                 : 
    2623               0 : nsStyleQuotes::nsStyleQuotes(void)
    2624                 :   : mQuotesCount(0),
    2625               0 :     mQuotes(nsnull)
    2626                 : {
    2627               0 :   MOZ_COUNT_CTOR(nsStyleQuotes);
    2628               0 :   SetInitial();
    2629               0 : }
    2630                 : 
    2631               0 : nsStyleQuotes::~nsStyleQuotes(void)
    2632                 : {
    2633               0 :   MOZ_COUNT_DTOR(nsStyleQuotes);
    2634               0 :   DELETE_ARRAY_IF(mQuotes);
    2635               0 : }
    2636                 : 
    2637               0 : nsStyleQuotes::nsStyleQuotes(const nsStyleQuotes& aSource)
    2638                 :   : mQuotesCount(0),
    2639               0 :     mQuotes(nsnull)
    2640                 : {
    2641               0 :   MOZ_COUNT_CTOR(nsStyleQuotes);
    2642               0 :   CopyFrom(aSource);
    2643               0 : }
    2644                 : 
    2645                 : void
    2646               0 : nsStyleQuotes::SetInitial()
    2647                 : {
    2648                 :   // The initial value for quotes is the en-US typographic convention:
    2649                 :   // outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
    2650                 :   // with LEFT and RIGHT SINGLE QUOTATION MARK.
    2651                 :   static const PRUnichar initialQuotes[8] = {
    2652                 :     0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
    2653                 :   };
    2654                 :   
    2655               0 :   if (NS_SUCCEEDED(AllocateQuotes(2))) {
    2656                 :     SetQuotesAt(0,
    2657               0 :                 nsDependentString(&initialQuotes[0], 1),
    2658               0 :                 nsDependentString(&initialQuotes[2], 1));
    2659                 :     SetQuotesAt(1,
    2660               0 :                 nsDependentString(&initialQuotes[4], 1),
    2661               0 :                 nsDependentString(&initialQuotes[6], 1));
    2662                 :   }
    2663               0 : }
    2664                 : 
    2665                 : void
    2666               0 : nsStyleQuotes::CopyFrom(const nsStyleQuotes& aSource)
    2667                 : {
    2668               0 :   if (NS_SUCCEEDED(AllocateQuotes(aSource.QuotesCount()))) {
    2669               0 :     PRUint32 count = (mQuotesCount * 2);
    2670               0 :     for (PRUint32 index = 0; index < count; index += 2) {
    2671               0 :       aSource.GetQuotesAt(index, mQuotes[index], mQuotes[index + 1]);
    2672                 :     }
    2673                 :   }
    2674               0 : }
    2675                 : 
    2676               0 : nsChangeHint nsStyleQuotes::CalcDifference(const nsStyleQuotes& aOther) const
    2677                 : {
    2678                 :   // If the quotes implementation is ever going to change we might not need
    2679                 :   // a framechange here and a reflow should be sufficient.  See bug 35768.
    2680               0 :   if (mQuotesCount == aOther.mQuotesCount) {
    2681               0 :     PRUint32 ix = (mQuotesCount * 2);
    2682               0 :     while (0 < ix--) {
    2683               0 :       if (mQuotes[ix] != aOther.mQuotes[ix]) {
    2684               0 :         return NS_STYLE_HINT_FRAMECHANGE;
    2685                 :       }
    2686                 :     }
    2687                 : 
    2688               0 :     return NS_STYLE_HINT_NONE;
    2689                 :   }
    2690               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2691                 : }
    2692                 : 
    2693                 : #ifdef DEBUG
    2694                 : /* static */
    2695               0 : nsChangeHint nsStyleQuotes::MaxDifference()
    2696                 : {
    2697               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2698                 : }
    2699                 : #endif
    2700                 : 
    2701                 : // --------------------
    2702                 : // nsStyleTextReset
    2703                 : //
    2704                 : 
    2705               0 : nsStyleTextReset::nsStyleTextReset(void) 
    2706                 : { 
    2707               0 :   MOZ_COUNT_CTOR(nsStyleTextReset);
    2708               0 :   mVerticalAlign.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE, eStyleUnit_Enumerated);
    2709               0 :   mTextBlink = NS_STYLE_TEXT_BLINK_NONE;
    2710               0 :   mTextDecorationLine = NS_STYLE_TEXT_DECORATION_LINE_NONE;
    2711               0 :   mTextDecorationColor = NS_RGB(0,0,0);
    2712                 :   mTextDecorationStyle =
    2713               0 :     NS_STYLE_TEXT_DECORATION_STYLE_SOLID | BORDER_COLOR_FOREGROUND;
    2714               0 :   mUnicodeBidi = NS_STYLE_UNICODE_BIDI_NORMAL;
    2715               0 : }
    2716                 : 
    2717               0 : nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset& aSource) 
    2718                 : { 
    2719               0 :   MOZ_COUNT_CTOR(nsStyleTextReset);
    2720               0 :   *this = aSource;
    2721               0 : }
    2722                 : 
    2723               0 : nsStyleTextReset::~nsStyleTextReset(void)
    2724                 : {
    2725               0 :   MOZ_COUNT_DTOR(nsStyleTextReset);
    2726               0 : }
    2727                 : 
    2728               0 : nsChangeHint nsStyleTextReset::CalcDifference(const nsStyleTextReset& aOther) const
    2729                 : {
    2730               0 :   if (mVerticalAlign == aOther.mVerticalAlign
    2731                 :       && mUnicodeBidi == aOther.mUnicodeBidi) {
    2732                 :     // Reflow for blink changes
    2733               0 :     if (mTextBlink != aOther.mTextBlink) {
    2734               0 :       return NS_STYLE_HINT_REFLOW;
    2735                 :     }
    2736                 : 
    2737               0 :     PRUint8 lineStyle = GetDecorationStyle();
    2738               0 :     PRUint8 otherLineStyle = aOther.GetDecorationStyle();
    2739               0 :     if (mTextDecorationLine != aOther.mTextDecorationLine ||
    2740                 :         lineStyle != otherLineStyle) {
    2741                 :       // Reflow for decoration line style changes only to or from double or
    2742                 :       // wave because that may cause overflow area changes
    2743               0 :       if (lineStyle == NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE ||
    2744                 :           lineStyle == NS_STYLE_TEXT_DECORATION_STYLE_WAVY ||
    2745                 :           otherLineStyle == NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE ||
    2746                 :           otherLineStyle == NS_STYLE_TEXT_DECORATION_STYLE_WAVY) {
    2747               0 :         return NS_STYLE_HINT_REFLOW;
    2748                 :       }
    2749                 :       // Repaint for other style decoration lines because they must be in
    2750                 :       // default overflow rect
    2751               0 :       return NS_STYLE_HINT_VISUAL;
    2752                 :     }
    2753                 : 
    2754                 :     // Repaint for decoration color changes
    2755                 :     nscolor decColor, otherDecColor;
    2756                 :     bool isFG, otherIsFG;
    2757               0 :     GetDecorationColor(decColor, isFG);
    2758               0 :     aOther.GetDecorationColor(otherDecColor, otherIsFG);
    2759               0 :     if (isFG != otherIsFG || (!isFG && decColor != otherDecColor)) {
    2760               0 :       return NS_STYLE_HINT_VISUAL;
    2761                 :     }
    2762                 : 
    2763               0 :     if (mTextOverflow != aOther.mTextOverflow) {
    2764               0 :       return NS_STYLE_HINT_VISUAL;
    2765                 :     }
    2766               0 :     return NS_STYLE_HINT_NONE;
    2767                 :   }
    2768               0 :   return NS_STYLE_HINT_REFLOW;
    2769                 : }
    2770                 : 
    2771                 : #ifdef DEBUG
    2772                 : /* static */
    2773               0 : nsChangeHint nsStyleTextReset::MaxDifference()
    2774                 : {
    2775               0 :   return NS_STYLE_HINT_REFLOW;
    2776                 : }
    2777                 : #endif
    2778                 : 
    2779                 : // Allowed to return one of NS_STYLE_HINT_NONE, NS_STYLE_HINT_REFLOW
    2780                 : // or NS_STYLE_HINT_VISUAL. Currently we just return NONE or REFLOW, though.
    2781                 : // XXXbz can this not return a more specific hint?  If that's ever
    2782                 : // changed, nsStyleBorder::CalcDifference will need changing too.
    2783                 : static nsChangeHint
    2784               0 : CalcShadowDifference(nsCSSShadowArray* lhs,
    2785                 :                      nsCSSShadowArray* rhs)
    2786                 : {
    2787               0 :   if (lhs == rhs)
    2788               0 :     return NS_STYLE_HINT_NONE;
    2789                 : 
    2790               0 :   if (!lhs || !rhs || lhs->Length() != rhs->Length())
    2791               0 :     return NS_STYLE_HINT_REFLOW;
    2792                 : 
    2793               0 :   for (PRUint32 i = 0; i < lhs->Length(); ++i) {
    2794               0 :     if (*lhs->ShadowAt(i) != *rhs->ShadowAt(i))
    2795               0 :       return NS_STYLE_HINT_REFLOW;
    2796                 :   }
    2797               0 :   return NS_STYLE_HINT_NONE;
    2798                 : }
    2799                 : 
    2800                 : // --------------------
    2801                 : // nsStyleText
    2802                 : //
    2803                 : 
    2804               0 : nsStyleText::nsStyleText(void)
    2805                 : { 
    2806               0 :   MOZ_COUNT_CTOR(nsStyleText);
    2807               0 :   mTextAlign = NS_STYLE_TEXT_ALIGN_DEFAULT;
    2808               0 :   mTextAlignLast = NS_STYLE_TEXT_ALIGN_AUTO;
    2809               0 :   mTextTransform = NS_STYLE_TEXT_TRANSFORM_NONE;
    2810               0 :   mWhiteSpace = NS_STYLE_WHITESPACE_NORMAL;
    2811               0 :   mWordWrap = NS_STYLE_WORDWRAP_NORMAL;
    2812               0 :   mHyphens = NS_STYLE_HYPHENS_MANUAL;
    2813               0 :   mTextSizeAdjust = NS_STYLE_TEXT_SIZE_ADJUST_AUTO;
    2814                 : 
    2815               0 :   mLetterSpacing.SetNormalValue();
    2816               0 :   mLineHeight.SetNormalValue();
    2817               0 :   mTextIndent.SetCoordValue(0);
    2818               0 :   mWordSpacing = 0;
    2819                 : 
    2820               0 :   mTextShadow = nsnull;
    2821               0 :   mTabSize = NS_STYLE_TABSIZE_INITIAL;
    2822               0 : }
    2823                 : 
    2824               0 : nsStyleText::nsStyleText(const nsStyleText& aSource)
    2825                 :   : mTextAlign(aSource.mTextAlign),
    2826                 :     mTextAlignLast(aSource.mTextAlignLast),
    2827                 :     mTextTransform(aSource.mTextTransform),
    2828                 :     mWhiteSpace(aSource.mWhiteSpace),
    2829                 :     mWordWrap(aSource.mWordWrap),
    2830                 :     mHyphens(aSource.mHyphens),
    2831                 :     mTextSizeAdjust(aSource.mTextSizeAdjust),
    2832                 :     mTabSize(aSource.mTabSize),
    2833                 :     mLetterSpacing(aSource.mLetterSpacing),
    2834                 :     mLineHeight(aSource.mLineHeight),
    2835                 :     mTextIndent(aSource.mTextIndent),
    2836                 :     mWordSpacing(aSource.mWordSpacing),
    2837               0 :     mTextShadow(aSource.mTextShadow)
    2838                 : {
    2839               0 :   MOZ_COUNT_CTOR(nsStyleText);
    2840               0 : }
    2841                 : 
    2842               0 : nsStyleText::~nsStyleText(void)
    2843                 : {
    2844               0 :   MOZ_COUNT_DTOR(nsStyleText);
    2845               0 : }
    2846                 : 
    2847               0 : nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aOther) const
    2848                 : {
    2849               0 :   if (NewlineIsSignificant() != aOther.NewlineIsSignificant()) {
    2850                 :     // This may require construction of suppressed text frames
    2851               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    2852                 :   }
    2853                 : 
    2854               0 :   if ((mTextAlign != aOther.mTextAlign) ||
    2855                 :       (mTextAlignLast != aOther.mTextAlignLast) ||
    2856                 :       (mTextTransform != aOther.mTextTransform) ||
    2857                 :       (mWhiteSpace != aOther.mWhiteSpace) ||
    2858                 :       (mWordWrap != aOther.mWordWrap) ||
    2859                 :       (mHyphens != aOther.mHyphens) ||
    2860                 :       (mTextSizeAdjust != aOther.mTextSizeAdjust) ||
    2861               0 :       (mLetterSpacing != aOther.mLetterSpacing) ||
    2862               0 :       (mLineHeight != aOther.mLineHeight) ||
    2863               0 :       (mTextIndent != aOther.mTextIndent) ||
    2864                 :       (mWordSpacing != aOther.mWordSpacing) ||
    2865                 :       (mTabSize != aOther.mTabSize))
    2866               0 :     return NS_STYLE_HINT_REFLOW;
    2867                 : 
    2868               0 :   return CalcShadowDifference(mTextShadow, aOther.mTextShadow);
    2869                 : }
    2870                 : 
    2871                 : #ifdef DEBUG
    2872                 : /* static */
    2873               0 : nsChangeHint nsStyleText::MaxDifference()
    2874                 : {
    2875               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    2876                 : }
    2877                 : #endif
    2878                 : 
    2879                 : //-----------------------
    2880                 : // nsStyleUserInterface
    2881                 : //
    2882                 : 
    2883               0 : nsCursorImage::nsCursorImage()
    2884                 :   : mHaveHotspot(false)
    2885                 :   , mHotspotX(0.0f)
    2886               0 :   , mHotspotY(0.0f)
    2887                 : {
    2888               0 : }
    2889                 : 
    2890               0 : nsCursorImage::nsCursorImage(const nsCursorImage& aOther)
    2891                 :   : mHaveHotspot(aOther.mHaveHotspot)
    2892                 :   , mHotspotX(aOther.mHotspotX)
    2893               0 :   , mHotspotY(aOther.mHotspotY)
    2894                 : {
    2895               0 :   SetImage(aOther.GetImage());
    2896               0 : }
    2897                 : 
    2898               0 : nsCursorImage::~nsCursorImage()
    2899                 : {
    2900               0 :   SetImage(nsnull);
    2901               0 : }
    2902                 : 
    2903                 : nsCursorImage&
    2904               0 : nsCursorImage::operator=(const nsCursorImage& aOther)
    2905                 : {
    2906               0 :   if (this != &aOther) {
    2907               0 :     mHaveHotspot = aOther.mHaveHotspot;
    2908               0 :     mHotspotX = aOther.mHotspotX;
    2909               0 :     mHotspotY = aOther.mHotspotY;
    2910               0 :     SetImage(aOther.GetImage());
    2911                 :   }
    2912                 : 
    2913               0 :   return *this;
    2914                 : }
    2915                 : 
    2916               0 : nsStyleUserInterface::nsStyleUserInterface(void) 
    2917                 : { 
    2918               0 :   MOZ_COUNT_CTOR(nsStyleUserInterface);
    2919               0 :   mUserInput = NS_STYLE_USER_INPUT_AUTO;
    2920               0 :   mUserModify = NS_STYLE_USER_MODIFY_READ_ONLY;
    2921               0 :   mUserFocus = NS_STYLE_USER_FOCUS_NONE;
    2922                 : 
    2923               0 :   mCursor = NS_STYLE_CURSOR_AUTO; // fix for bugzilla bug 51113
    2924                 : 
    2925               0 :   mCursorArrayLength = 0;
    2926               0 :   mCursorArray = nsnull;
    2927               0 : }
    2928                 : 
    2929               0 : nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource) :
    2930                 :   mUserInput(aSource.mUserInput),
    2931                 :   mUserModify(aSource.mUserModify),
    2932                 :   mUserFocus(aSource.mUserFocus),
    2933               0 :   mCursor(aSource.mCursor)
    2934                 : { 
    2935               0 :   MOZ_COUNT_CTOR(nsStyleUserInterface);
    2936               0 :   CopyCursorArrayFrom(aSource);
    2937               0 : }
    2938                 : 
    2939               0 : nsStyleUserInterface::~nsStyleUserInterface(void) 
    2940                 : { 
    2941               0 :   MOZ_COUNT_DTOR(nsStyleUserInterface);
    2942               0 :   delete [] mCursorArray;
    2943               0 : }
    2944                 : 
    2945               0 : nsChangeHint nsStyleUserInterface::CalcDifference(const nsStyleUserInterface& aOther) const
    2946                 : {
    2947               0 :   nsChangeHint hint = nsChangeHint(0);
    2948               0 :   if (mCursor != aOther.mCursor)
    2949               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateCursor);
    2950                 : 
    2951                 :   // We could do better. But it wouldn't be worth it, URL-specified cursors are
    2952                 :   // rare.
    2953               0 :   if (mCursorArrayLength > 0 || aOther.mCursorArrayLength > 0)
    2954               0 :     NS_UpdateHint(hint, nsChangeHint_UpdateCursor);
    2955                 : 
    2956               0 :   if (mUserModify != aOther.mUserModify)
    2957               0 :     NS_UpdateHint(hint, NS_STYLE_HINT_VISUAL);
    2958                 :   
    2959               0 :   if ((mUserInput != aOther.mUserInput) &&
    2960                 :       ((NS_STYLE_USER_INPUT_NONE == mUserInput) || 
    2961                 :        (NS_STYLE_USER_INPUT_NONE == aOther.mUserInput))) {
    2962               0 :     NS_UpdateHint(hint, NS_STYLE_HINT_FRAMECHANGE);
    2963                 :   }
    2964                 : 
    2965                 :   // ignore mUserFocus
    2966                 : 
    2967               0 :   return hint;
    2968                 : }
    2969                 : 
    2970                 : #ifdef DEBUG
    2971                 : /* static */
    2972               0 : nsChangeHint nsStyleUserInterface::MaxDifference()
    2973                 : {
    2974               0 :   return nsChangeHint(nsChangeHint_UpdateCursor | NS_STYLE_HINT_FRAMECHANGE);
    2975                 : }
    2976                 : #endif
    2977                 : 
    2978                 : void
    2979               0 : nsStyleUserInterface::CopyCursorArrayFrom(const nsStyleUserInterface& aSource)
    2980                 : {
    2981               0 :   mCursorArray = nsnull;
    2982               0 :   mCursorArrayLength = 0;
    2983               0 :   if (aSource.mCursorArrayLength) {
    2984               0 :     mCursorArray = new nsCursorImage[aSource.mCursorArrayLength];
    2985               0 :     if (mCursorArray) {
    2986               0 :       mCursorArrayLength = aSource.mCursorArrayLength;
    2987               0 :       for (PRUint32 i = 0; i < mCursorArrayLength; ++i)
    2988               0 :         mCursorArray[i] = aSource.mCursorArray[i];
    2989                 :     }
    2990                 :   }
    2991               0 : }
    2992                 : 
    2993                 : //-----------------------
    2994                 : // nsStyleUIReset
    2995                 : //
    2996                 : 
    2997               0 : nsStyleUIReset::nsStyleUIReset(void) 
    2998                 : { 
    2999               0 :   MOZ_COUNT_CTOR(nsStyleUIReset);
    3000               0 :   mUserSelect = NS_STYLE_USER_SELECT_AUTO;
    3001               0 :   mForceBrokenImageIcon = 0;
    3002               0 :   mIMEMode = NS_STYLE_IME_MODE_AUTO;
    3003               0 :   mWindowShadow = NS_STYLE_WINDOW_SHADOW_DEFAULT;
    3004               0 : }
    3005                 : 
    3006               0 : nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource) 
    3007                 : {
    3008               0 :   MOZ_COUNT_CTOR(nsStyleUIReset);
    3009               0 :   mUserSelect = aSource.mUserSelect;
    3010               0 :   mForceBrokenImageIcon = aSource.mForceBrokenImageIcon;
    3011               0 :   mIMEMode = aSource.mIMEMode;
    3012               0 :   mWindowShadow = aSource.mWindowShadow;
    3013               0 : }
    3014                 : 
    3015               0 : nsStyleUIReset::~nsStyleUIReset(void) 
    3016                 : { 
    3017               0 :   MOZ_COUNT_DTOR(nsStyleUIReset);
    3018               0 : }
    3019                 : 
    3020               0 : nsChangeHint nsStyleUIReset::CalcDifference(const nsStyleUIReset& aOther) const
    3021                 : {
    3022                 :   // ignore mIMEMode
    3023               0 :   if (mForceBrokenImageIcon != aOther.mForceBrokenImageIcon)
    3024               0 :     return NS_STYLE_HINT_FRAMECHANGE;
    3025               0 :   if (mWindowShadow != aOther.mWindowShadow) {
    3026                 :     // We really need just an nsChangeHint_SyncFrameView, except
    3027                 :     // on an ancestor of the frame, so we get that by doing a
    3028                 :     // reflow.
    3029               0 :     return NS_STYLE_HINT_REFLOW;
    3030                 :   }
    3031               0 :   if (mUserSelect != aOther.mUserSelect)
    3032               0 :     return NS_STYLE_HINT_VISUAL;
    3033               0 :   return NS_STYLE_HINT_NONE;
    3034                 : }
    3035                 : 
    3036                 : #ifdef DEBUG
    3037                 : /* static */
    3038               0 : nsChangeHint nsStyleUIReset::MaxDifference()
    3039                 : {
    3040               0 :   return NS_STYLE_HINT_FRAMECHANGE;
    3041                 : }
    3042                 : #endif
    3043                 : 

Generated by: LCOV version 1.7