LCOV - app.info - layout/style/nsStyleStruct.cpp

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