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

Generated by: LCOV version 1.7