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
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/
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
15 * The Original Code is mozilla.org code.
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.
23 * David Hyatt (hyatt@netscape.com)
24 * Mats Palmgren <mats.palmgren@bredband.net>
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
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.
41 * ***** END LICENSE BLOCK ***** */
44 * structs that contain the data provided by nsStyleContext, the
45 * internal API for computed style data for an element
48 #include "nsStyleStruct.h"
49 #include "nsStyleStructInlines.h"
50 #include "nsStyleConsts.h"
51 #include "nsThemeConstants.h"
53 #include "nsPresContext.h"
54 #include "nsIDeviceContext.h"
55 #include "nsIWidget.h"
56 #include "nsIStyleRule.h"
58 #include "nsCSSProps.h"
62 #include "nsHTMLReflowState.h"
65 #include "nsSVGUtils.h"
66 #include "nsBidiUtils.h"
68 #include "imgIRequest.h"
69 #include "imgIContainer.h"
72 // Make sure we have enough bits in NS_STYLE_INHERIT_MASK.
73 PR_STATIC_ASSERT((((1 << nsStyleStructID_Length
) - 1) &
74 ~(NS_STYLE_INHERIT_MASK
)) == 0);
76 inline PRBool
IsFixedUnit(const nsStyleCoord
& aCoord
, PRBool aEnumOK
)
78 return aCoord
.ConvertsToLength() ||
79 (aEnumOK
&& aCoord
.GetUnit() == eStyleUnit_Enumerated
);
82 static PRBool
EqualURIs(nsIURI
*aURI1
, nsIURI
*aURI2
)
85 return aURI1
== aURI2
|| // handle null==null, and optimize
87 NS_SUCCEEDED(aURI1
->Equals(aURI2
, &eq
)) && // not equal on fail
91 static PRBool
EqualURIs(nsCSSValue::URL
*aURI1
, nsCSSValue::URL
*aURI2
)
93 return aURI1
== aURI2
|| // handle null==null, and optimize
94 (aURI1
&& aURI2
&& aURI1
->URIEquals(*aURI2
));
97 static PRBool
EqualImages(imgIRequest
*aImage1
, imgIRequest
* aImage2
)
99 if (aImage1
== aImage2
) {
103 if (!aImage1
|| !aImage2
) {
107 nsCOMPtr
<nsIURI
> uri1
, uri2
;
108 aImage1
->GetURI(getter_AddRefs(uri1
));
109 aImage2
->GetURI(getter_AddRefs(uri2
));
110 return EqualURIs(uri1
, uri2
);
113 static nsChangeHint
CalcShadowDifference(nsCSSShadowArray
* lhs
,
114 nsCSSShadowArray
* rhs
);
116 // --------------------
119 nsStyleFont::nsStyleFont(const nsFont
& aFont
, nsPresContext
*aPresContext
)
121 mGenericID(kGenericFont_NONE
)
123 MOZ_COUNT_CTOR(nsStyleFont
);
124 mSize
= mFont
.size
= nsStyleFont::ZoomText(aPresContext
, mFont
.size
);
126 mScriptUnconstrainedSize
= mSize
;
127 mScriptMinSize
= aPresContext
->CSSTwipsToAppUnits(
128 NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT
));
130 mScriptSizeMultiplier
= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER
;
134 nsStyleFont::nsStyleFont(const nsStyleFont
& aSrc
)
137 , mGenericID(aSrc
.mGenericID
)
139 , mScriptLevel(aSrc
.mScriptLevel
)
140 , mScriptUnconstrainedSize(aSrc
.mScriptUnconstrainedSize
)
141 , mScriptMinSize(aSrc
.mScriptMinSize
)
142 , mScriptSizeMultiplier(aSrc
.mScriptSizeMultiplier
)
145 MOZ_COUNT_CTOR(nsStyleFont
);
148 nsStyleFont::nsStyleFont(nsPresContext
* aPresContext
)
149 : mFont(*(aPresContext
->GetDefaultFont(kPresContext_DefaultVariableFont_ID
))),
150 mGenericID(kGenericFont_NONE
)
152 MOZ_COUNT_CTOR(nsStyleFont
);
153 mSize
= mFont
.size
= nsStyleFont::ZoomText(aPresContext
, mFont
.size
);
155 mScriptUnconstrainedSize
= mSize
;
156 mScriptMinSize
= aPresContext
->CSSTwipsToAppUnits(
157 NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT
));
159 mScriptSizeMultiplier
= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER
;
164 nsStyleFont::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
165 void* result
= aContext
->AllocateFromShell(sz
);
167 memset(result
, 0, sz
);
172 nsStyleFont::Destroy(nsPresContext
* aContext
) {
173 this->~nsStyleFont();
174 aContext
->FreeToShell(sizeof(nsStyleFont
), this);
177 nsChangeHint
nsStyleFont::CalcDifference(const nsStyleFont
& aOther
) const
179 if (mSize
== aOther
.mSize
) {
180 return CalcFontDifference(mFont
, aOther
.mFont
);
182 return NS_STYLE_HINT_REFLOW
;
187 nsChangeHint
nsStyleFont::MaxDifference()
189 return NS_STYLE_HINT_REFLOW
;
194 nsStyleFont::ZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
196 return nscoord(float(aSize
) * aPresContext
->TextZoom());
200 nsStyleFont::UnZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
202 return nscoord(float(aSize
) / aPresContext
->TextZoom());
205 nsChangeHint
nsStyleFont::CalcFontDifference(const nsFont
& aFont1
, const nsFont
& aFont2
)
207 if ((aFont1
.size
== aFont2
.size
) &&
208 (aFont1
.sizeAdjust
== aFont2
.sizeAdjust
) &&
209 (aFont1
.style
== aFont2
.style
) &&
210 (aFont1
.variant
== aFont2
.variant
) &&
211 (aFont1
.familyNameQuirks
== aFont2
.familyNameQuirks
) &&
212 (aFont1
.weight
== aFont2
.weight
) &&
213 (aFont1
.stretch
== aFont2
.stretch
) &&
214 (aFont1
.name
== aFont2
.name
) &&
215 (aFont1
.featureSettings
== aFont2
.featureSettings
) &&
216 (aFont1
.languageOverride
== aFont2
.languageOverride
)) {
217 if ((aFont1
.decorations
== aFont2
.decorations
)) {
218 return NS_STYLE_HINT_NONE
;
220 return NS_STYLE_HINT_VISUAL
;
222 return NS_STYLE_HINT_REFLOW
;
225 static PRBool
IsFixedData(const nsStyleSides
& aSides
, PRBool aEnumOK
)
227 NS_FOR_CSS_SIDES(side
) {
228 if (!IsFixedUnit(aSides
.Get(side
), aEnumOK
))
234 static nscoord
CalcCoord(const nsStyleCoord
& aCoord
,
235 const nscoord
* aEnumTable
,
238 if (aCoord
.GetUnit() == eStyleUnit_Enumerated
) {
239 NS_ABORT_IF_FALSE(aEnumTable
, "must have enum table");
240 PRInt32 value
= aCoord
.GetIntValue();
241 if (0 <= value
&& value
< aNumEnums
) {
242 return aEnumTable
[aCoord
.GetIntValue()];
244 NS_NOTREACHED("unexpected enum value");
247 NS_ABORT_IF_FALSE(aCoord
.ConvertsToLength(), "unexpected unit");
248 return nsRuleNode::ComputeCoordPercentCalc(aCoord
, 0);
251 nsStyleMargin::nsStyleMargin() {
252 MOZ_COUNT_CTOR(nsStyleMargin
);
253 nsStyleCoord
zero(0, nsStyleCoord::CoordConstructor
);
254 NS_FOR_CSS_SIDES(side
) {
255 mMargin
.Set(side
, zero
);
257 mHasCachedMargin
= PR_FALSE
;
260 nsStyleMargin::nsStyleMargin(const nsStyleMargin
& aSrc
) {
261 MOZ_COUNT_CTOR(nsStyleMargin
);
262 mMargin
= aSrc
.mMargin
;
263 mHasCachedMargin
= PR_FALSE
;
267 nsStyleMargin::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
268 void* result
= aContext
->AllocateFromShell(sz
);
270 memset(result
, 0, sz
);
275 nsStyleMargin::Destroy(nsPresContext
* aContext
) {
276 this->~nsStyleMargin();
277 aContext
->FreeToShell(sizeof(nsStyleMargin
), this);
281 void nsStyleMargin::RecalcData()
283 if (IsFixedData(mMargin
, PR_FALSE
)) {
284 NS_FOR_CSS_SIDES(side
) {
285 mCachedMargin
.side(side
) = CalcCoord(mMargin
.Get(side
), nsnull
, 0);
287 mHasCachedMargin
= PR_TRUE
;
290 mHasCachedMargin
= PR_FALSE
;
293 nsChangeHint
nsStyleMargin::CalcDifference(const nsStyleMargin
& aOther
) const
295 if (mMargin
== aOther
.mMargin
) {
296 return NS_STYLE_HINT_NONE
;
298 // Margin differences can't affect descendant intrinsic sizes and
299 // don't need to force children to reflow.
300 return NS_SubtractHint(NS_STYLE_HINT_REFLOW
,
301 NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics
,
302 nsChangeHint_NeedDirtyReflow
));
307 nsChangeHint
nsStyleMargin::MaxDifference()
309 return NS_SubtractHint(NS_STYLE_HINT_REFLOW
,
310 NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics
,
311 nsChangeHint_NeedDirtyReflow
));
315 nsStylePadding::nsStylePadding() {
316 MOZ_COUNT_CTOR(nsStylePadding
);
317 nsStyleCoord
zero(0, nsStyleCoord::CoordConstructor
);
318 NS_FOR_CSS_SIDES(side
) {
319 mPadding
.Set(side
, zero
);
321 mHasCachedPadding
= PR_FALSE
;
324 nsStylePadding::nsStylePadding(const nsStylePadding
& aSrc
) {
325 MOZ_COUNT_CTOR(nsStylePadding
);
326 mPadding
= aSrc
.mPadding
;
327 mHasCachedPadding
= PR_FALSE
;
331 nsStylePadding::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
332 void* result
= aContext
->AllocateFromShell(sz
);
334 memset(result
, 0, sz
);
339 nsStylePadding::Destroy(nsPresContext
* aContext
) {
340 this->~nsStylePadding();
341 aContext
->FreeToShell(sizeof(nsStylePadding
), this);
344 void nsStylePadding::RecalcData()
346 if (IsFixedData(mPadding
, PR_FALSE
)) {
347 NS_FOR_CSS_SIDES(side
) {
348 // Clamp negative calc() to 0.
349 mCachedPadding
.side(side
) =
350 NS_MAX(CalcCoord(mPadding
.Get(side
), nsnull
, 0), 0);
352 mHasCachedPadding
= PR_TRUE
;
355 mHasCachedPadding
= PR_FALSE
;
358 nsChangeHint
nsStylePadding::CalcDifference(const nsStylePadding
& aOther
) const
360 if (mPadding
== aOther
.mPadding
) {
361 return NS_STYLE_HINT_NONE
;
363 // Padding differences can't affect descendant intrinsic sizes, but do need
364 // to force children to reflow so that we can reposition them, since their
365 // offsets are from our frame bounds but our content rect's position within
366 // those bounds is moving.
367 return NS_SubtractHint(NS_STYLE_HINT_REFLOW
,
368 nsChangeHint_ClearDescendantIntrinsics
);
373 nsChangeHint
nsStylePadding::MaxDifference()
375 return NS_SubtractHint(NS_STYLE_HINT_REFLOW
,
376 nsChangeHint_ClearDescendantIntrinsics
);
380 nsStyleBorder::nsStyleBorder(nsPresContext
* aPresContext
)
381 : mHaveBorderImageWidth(PR_FALSE
)
383 , mImageTracked(false)
385 , mComputedBorder(0, 0, 0, 0)
386 , mBorderImage(nsnull
)
388 MOZ_COUNT_CTOR(nsStyleBorder
);
390 (aPresContext
->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM
];
391 NS_FOR_CSS_SIDES(side
) {
392 mBorder
.side(side
) = medium
;
393 mBorderStyle
[side
] = NS_STYLE_BORDER_STYLE_NONE
| BORDER_COLOR_FOREGROUND
;
394 mBorderColor
[side
] = NS_RGB(0, 0, 0);
396 NS_FOR_CSS_HALF_CORNERS(corner
) {
397 mBorderRadius
.Set(corner
, nsStyleCoord(0, nsStyleCoord::CoordConstructor
));
400 mBorderColors
= nsnull
;
403 mFloatEdge
= NS_STYLE_FLOAT_EDGE_CONTENT
;
405 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
408 nsBorderColors::~nsBorderColors()
410 NS_CSS_DELETE_LIST_MEMBER(nsBorderColors
, this, mNext
);
414 nsBorderColors::Clone(PRBool aDeep
) const
416 nsBorderColors
* result
= new nsBorderColors(mColor
);
417 if (NS_UNLIKELY(!result
))
420 NS_CSS_CLONE_LIST_MEMBER(nsBorderColors
, this, mNext
, result
, (PR_FALSE
));
424 nsStyleBorder::nsStyleBorder(const nsStyleBorder
& aSrc
)
425 : mBorderRadius(aSrc
.mBorderRadius
),
426 mBorderImageSplit(aSrc
.mBorderImageSplit
),
427 mFloatEdge(aSrc
.mFloatEdge
),
428 mBorderImageHFill(aSrc
.mBorderImageHFill
),
429 mBorderImageVFill(aSrc
.mBorderImageVFill
),
430 mBorderColors(nsnull
),
431 mBoxShadow(aSrc
.mBoxShadow
),
432 mHaveBorderImageWidth(aSrc
.mHaveBorderImageWidth
),
433 mBorderImageWidth(aSrc
.mBorderImageWidth
),
434 mComputedBorder(aSrc
.mComputedBorder
),
435 mBorder(aSrc
.mBorder
),
436 mBorderImage(aSrc
.mBorderImage
),
437 mTwipsPerPixel(aSrc
.mTwipsPerPixel
)
439 MOZ_COUNT_CTOR(nsStyleBorder
);
440 if (aSrc
.mBorderColors
) {
441 EnsureBorderColors();
442 for (PRInt32 i
= 0; i
< 4; i
++)
443 if (aSrc
.mBorderColors
[i
])
444 mBorderColors
[i
] = aSrc
.mBorderColors
[i
]->Clone();
446 mBorderColors
[i
] = nsnull
;
449 NS_FOR_CSS_SIDES(side
) {
450 mBorderStyle
[side
] = aSrc
.mBorderStyle
[side
];
451 mBorderColor
[side
] = aSrc
.mBorderColor
[side
];
453 NS_FOR_CSS_HALF_CORNERS(corner
) {
454 mBorderRadius
.Set(corner
, aSrc
.mBorderRadius
.Get(corner
));
458 nsStyleBorder::~nsStyleBorder()
460 NS_ABORT_IF_FALSE(!mImageTracked
,
461 "nsStyleBorder being destroyed while still tracking image!");
462 MOZ_COUNT_DTOR(nsStyleBorder
);
464 for (PRInt32 i
= 0; i
< 4; i
++)
465 delete mBorderColors
[i
];
466 delete [] mBorderColors
;
471 nsStyleBorder::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
472 void* result
= aContext
->AllocateFromShell(sz
);
474 memset(result
, 0, sz
);
479 nsStyleBorder::Destroy(nsPresContext
* aContext
) {
481 UntrackImage(aContext
);
482 this->~nsStyleBorder();
483 aContext
->FreeToShell(sizeof(nsStyleBorder
), this);
487 nsChangeHint
nsStyleBorder::CalcDifference(const nsStyleBorder
& aOther
) const
489 nsChangeHint shadowDifference
=
490 CalcShadowDifference(mBoxShadow
, aOther
.mBoxShadow
);
492 // Note that differences in mBorder don't affect rendering (which should only
493 // use mComputedBorder), so don't need to be tested for here.
494 // XXXbz we should be able to return a more specific change hint for
495 // at least GetActualBorder() differences...
496 if (mTwipsPerPixel
!= aOther
.mTwipsPerPixel
||
497 GetActualBorder() != aOther
.GetActualBorder() ||
498 mFloatEdge
!= aOther
.mFloatEdge
||
499 (shadowDifference
& nsChangeHint_ReflowFrame
))
500 return NS_STYLE_HINT_REFLOW
;
502 // Note that mBorderStyle stores not only the border style but also
503 // color-related flags. Given that we've already done an mComputedBorder
504 // comparison, border-style differences can only lead to a VISUAL hint. So
505 // it's OK to just compare the values directly -- if either the actual
506 // style or the color flags differ we want to repaint.
507 NS_FOR_CSS_SIDES(ix
) {
508 if (mBorderStyle
[ix
] != aOther
.mBorderStyle
[ix
] ||
509 mBorderColor
[ix
] != aOther
.mBorderColor
[ix
])
510 return NS_STYLE_HINT_VISUAL
;
513 if (mBorderRadius
!= aOther
.mBorderRadius
||
514 !mBorderColors
!= !aOther
.mBorderColors
)
515 return NS_STYLE_HINT_VISUAL
;
517 if (IsBorderImageLoaded() || aOther
.IsBorderImageLoaded()) {
518 if (mBorderImage
!= aOther
.mBorderImage
||
519 mBorderImageHFill
!= aOther
.mBorderImageHFill
||
520 mBorderImageVFill
!= aOther
.mBorderImageVFill
||
521 mBorderImageSplit
!= aOther
.mBorderImageSplit
)
522 return NS_STYLE_HINT_VISUAL
;
523 // The call to GetActualBorder above already considered
524 // mBorderImageWidth and mHaveBorderImageWidth.
527 // Note that at this point if mBorderColors is non-null so is
528 // aOther.mBorderColors
530 NS_FOR_CSS_SIDES(ix
) {
531 if (!nsBorderColors::Equal(mBorderColors
[ix
],
532 aOther
.mBorderColors
[ix
]))
533 return NS_STYLE_HINT_VISUAL
;
537 return shadowDifference
;
542 nsChangeHint
nsStyleBorder::MaxDifference()
544 return NS_STYLE_HINT_REFLOW
;
549 nsStyleBorder::ImageBorderDiffers() const
551 return mComputedBorder
!=
552 (mHaveBorderImageWidth
? mBorderImageWidth
: mBorder
);
556 nsStyleBorder::GetActualBorder() const
558 if (IsBorderImageLoaded())
559 if (mHaveBorderImageWidth
)
560 return mBorderImageWidth
;
564 return mComputedBorder
;
568 nsStyleBorder::TrackImage(nsPresContext
* aContext
)
571 NS_ABORT_IF_FALSE(!mImageTracked
, "Already tracking image!");
572 NS_ABORT_IF_FALSE(mBorderImage
, "Can't track null image!");
574 // Register the image with the document
575 nsIDocument
* doc
= aContext
->Document();
577 doc
->AddImage(mBorderImage
);
581 mImageTracked
= true;
586 nsStyleBorder::UntrackImage(nsPresContext
* aContext
)
589 NS_ABORT_IF_FALSE(mImageTracked
, "Image not tracked!");
590 NS_ABORT_IF_FALSE(mBorderImage
, "Can't track null image!");
592 // Unregister the image with the document
593 nsIDocument
* doc
= aContext
->Document();
595 doc
->RemoveImage(mBorderImage
);
599 mImageTracked
= false;
603 nsStyleOutline::nsStyleOutline(nsPresContext
* aPresContext
)
605 MOZ_COUNT_CTOR(nsStyleOutline
);
606 // spacing values not inherited
607 nsStyleCoord
zero(0, nsStyleCoord::CoordConstructor
);
608 NS_FOR_CSS_HALF_CORNERS(corner
) {
609 mOutlineRadius
.Set(corner
, zero
);
614 mOutlineWidth
= nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM
, eStyleUnit_Enumerated
);
615 mOutlineStyle
= NS_STYLE_BORDER_STYLE_NONE
;
616 mOutlineColor
= NS_RGB(0, 0, 0);
618 mHasCachedOutline
= PR_FALSE
;
619 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
622 nsStyleOutline::nsStyleOutline(const nsStyleOutline
& aSrc
) {
623 MOZ_COUNT_CTOR(nsStyleOutline
);
624 memcpy((nsStyleOutline
*)this, &aSrc
, sizeof(nsStyleOutline
));
628 nsStyleOutline::RecalcData(nsPresContext
* aContext
)
630 if (NS_STYLE_BORDER_STYLE_NONE
== GetOutlineStyle()) {
631 mCachedOutlineWidth
= 0;
632 mHasCachedOutline
= PR_TRUE
;
633 } else if (IsFixedUnit(mOutlineWidth
, PR_TRUE
)) {
634 // Clamp negative calc() to 0.
635 mCachedOutlineWidth
=
636 NS_MAX(CalcCoord(mOutlineWidth
, aContext
->GetBorderWidthTable(), 3), 0);
637 mCachedOutlineWidth
=
638 NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth
, mTwipsPerPixel
);
639 mHasCachedOutline
= PR_TRUE
;
642 mHasCachedOutline
= PR_FALSE
;
645 nsChangeHint
nsStyleOutline::CalcDifference(const nsStyleOutline
& aOther
) const
647 PRBool outlineWasVisible
=
648 mCachedOutlineWidth
> 0 && mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
649 PRBool outlineIsVisible
=
650 aOther
.mCachedOutlineWidth
> 0 && aOther
.mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
651 if (outlineWasVisible
!= outlineIsVisible
||
652 (outlineIsVisible
&& (mOutlineOffset
!= aOther
.mOutlineOffset
||
653 mOutlineWidth
!= aOther
.mOutlineWidth
||
654 mTwipsPerPixel
!= aOther
.mTwipsPerPixel
))) {
655 return NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
);
657 if ((mOutlineStyle
!= aOther
.mOutlineStyle
) ||
658 (mOutlineColor
!= aOther
.mOutlineColor
) ||
659 (mOutlineRadius
!= aOther
.mOutlineRadius
)) {
660 return nsChangeHint_RepaintFrame
;
662 return NS_STYLE_HINT_NONE
;
667 nsChangeHint
nsStyleOutline::MaxDifference()
669 return NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
);
673 // --------------------
676 nsStyleList::nsStyleList()
677 : mListStyleType(NS_STYLE_LIST_STYLE_DISC
),
678 mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE
)
680 MOZ_COUNT_CTOR(nsStyleList
);
683 nsStyleList::~nsStyleList()
685 MOZ_COUNT_DTOR(nsStyleList
);
688 nsStyleList::nsStyleList(const nsStyleList
& aSource
)
689 : mListStyleType(aSource
.mListStyleType
),
690 mListStylePosition(aSource
.mListStylePosition
),
691 mImageRegion(aSource
.mImageRegion
)
693 SetListStyleImage(aSource
.GetListStyleImage());
694 MOZ_COUNT_CTOR(nsStyleList
);
697 nsChangeHint
nsStyleList::CalcDifference(const nsStyleList
& aOther
) const
699 if (mListStylePosition
!= aOther
.mListStylePosition
)
700 return NS_STYLE_HINT_FRAMECHANGE
;
701 if (EqualImages(mListStyleImage
, aOther
.mListStyleImage
) &&
702 mListStyleType
== aOther
.mListStyleType
) {
703 if (mImageRegion
== aOther
.mImageRegion
)
704 return NS_STYLE_HINT_NONE
;
705 if (mImageRegion
.width
== aOther
.mImageRegion
.width
&&
706 mImageRegion
.height
== aOther
.mImageRegion
.height
)
707 return NS_STYLE_HINT_VISUAL
;
709 return NS_STYLE_HINT_REFLOW
;
714 nsChangeHint
nsStyleList::MaxDifference()
716 return NS_STYLE_HINT_FRAMECHANGE
;
720 // --------------------
723 nsStyleXUL::nsStyleXUL()
725 MOZ_COUNT_CTOR(nsStyleXUL
);
726 mBoxAlign
= NS_STYLE_BOX_ALIGN_STRETCH
;
727 mBoxDirection
= NS_STYLE_BOX_DIRECTION_NORMAL
;
729 mBoxOrient
= NS_STYLE_BOX_ORIENT_HORIZONTAL
;
730 mBoxPack
= NS_STYLE_BOX_PACK_START
;
732 mStretchStack
= PR_TRUE
;
735 nsStyleXUL::~nsStyleXUL()
737 MOZ_COUNT_DTOR(nsStyleXUL
);
740 nsStyleXUL::nsStyleXUL(const nsStyleXUL
& aSource
)
742 MOZ_COUNT_CTOR(nsStyleXUL
);
743 memcpy((nsStyleXUL
*)this, &aSource
, sizeof(nsStyleXUL
));
746 nsChangeHint
nsStyleXUL::CalcDifference(const nsStyleXUL
& aOther
) const
748 if (mBoxAlign
== aOther
.mBoxAlign
&&
749 mBoxDirection
== aOther
.mBoxDirection
&&
750 mBoxFlex
== aOther
.mBoxFlex
&&
751 mBoxOrient
== aOther
.mBoxOrient
&&
752 mBoxPack
== aOther
.mBoxPack
&&
753 mBoxOrdinal
== aOther
.mBoxOrdinal
)
754 return NS_STYLE_HINT_NONE
;
755 if (mBoxOrdinal
!= aOther
.mBoxOrdinal
)
756 return NS_STYLE_HINT_FRAMECHANGE
;
757 return NS_STYLE_HINT_REFLOW
;
762 nsChangeHint
nsStyleXUL::MaxDifference()
764 return NS_STYLE_HINT_FRAMECHANGE
;
768 // --------------------
771 nsStyleColumn::nsStyleColumn(nsPresContext
* aPresContext
)
773 MOZ_COUNT_CTOR(nsStyleColumn
);
774 mColumnCount
= NS_STYLE_COLUMN_COUNT_AUTO
;
775 mColumnWidth
.SetAutoValue();
776 mColumnGap
.SetNormalValue();
778 mColumnRuleWidth
= (aPresContext
->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM
];
779 mColumnRuleStyle
= NS_STYLE_BORDER_STYLE_NONE
;
780 mColumnRuleColor
= NS_RGB(0, 0, 0);
781 mColumnRuleColorIsForeground
= PR_TRUE
;
783 mTwipsPerPixel
= aPresContext
->AppUnitsPerDevPixel();
786 nsStyleColumn::~nsStyleColumn()
788 MOZ_COUNT_DTOR(nsStyleColumn
);
791 nsStyleColumn::nsStyleColumn(const nsStyleColumn
& aSource
)
793 MOZ_COUNT_CTOR(nsStyleColumn
);
794 memcpy((nsStyleColumn
*)this, &aSource
, sizeof(nsStyleColumn
));
797 nsChangeHint
nsStyleColumn::CalcDifference(const nsStyleColumn
& aOther
) const
799 if ((mColumnWidth
.GetUnit() == eStyleUnit_Auto
)
800 != (aOther
.mColumnWidth
.GetUnit() == eStyleUnit_Auto
) ||
801 mColumnCount
!= aOther
.mColumnCount
)
802 // We force column count changes to do a reframe, because it's tricky to handle
803 // some edge cases where the column count gets smaller and content overflows.
805 return NS_STYLE_HINT_FRAMECHANGE
;
807 if (mColumnWidth
!= aOther
.mColumnWidth
||
808 mColumnGap
!= aOther
.mColumnGap
)
809 return NS_STYLE_HINT_REFLOW
;
811 if (GetComputedColumnRuleWidth() != aOther
.GetComputedColumnRuleWidth() ||
812 mColumnRuleStyle
!= aOther
.mColumnRuleStyle
||
813 mColumnRuleColor
!= aOther
.mColumnRuleColor
||
814 mColumnRuleColorIsForeground
!= aOther
.mColumnRuleColorIsForeground
)
815 return NS_STYLE_HINT_VISUAL
;
817 return NS_STYLE_HINT_NONE
;
822 nsChangeHint
nsStyleColumn::MaxDifference()
824 return NS_STYLE_HINT_FRAMECHANGE
;
828 // --------------------
831 nsStyleSVG::nsStyleSVG()
833 MOZ_COUNT_CTOR(nsStyleSVG
);
834 mFill
.mType
= eStyleSVGPaintType_Color
;
835 mFill
.mPaint
.mColor
= NS_RGB(0,0,0);
836 mFill
.mFallbackColor
= NS_RGB(0,0,0);
837 mStroke
.mType
= eStyleSVGPaintType_None
;
838 mStroke
.mPaint
.mColor
= NS_RGB(0,0,0);
839 mStroke
.mFallbackColor
= NS_RGB(0,0,0);
840 mStrokeDasharray
= nsnull
;
842 mStrokeDashoffset
.SetCoordValue(0);
843 mStrokeWidth
.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
846 mStrokeMiterlimit
= 4.0f
;
847 mStrokeOpacity
= 1.0f
;
849 mStrokeDasharrayLength
= 0;
850 mClipRule
= NS_STYLE_FILL_RULE_NONZERO
;
851 mColorInterpolation
= NS_STYLE_COLOR_INTERPOLATION_SRGB
;
852 mColorInterpolationFilters
= NS_STYLE_COLOR_INTERPOLATION_LINEARRGB
;
853 mFillRule
= NS_STYLE_FILL_RULE_NONZERO
;
854 mImageRendering
= NS_STYLE_IMAGE_RENDERING_AUTO
;
855 mShapeRendering
= NS_STYLE_SHAPE_RENDERING_AUTO
;
856 mStrokeLinecap
= NS_STYLE_STROKE_LINECAP_BUTT
;
857 mStrokeLinejoin
= NS_STYLE_STROKE_LINEJOIN_MITER
;
858 mTextAnchor
= NS_STYLE_TEXT_ANCHOR_START
;
859 mTextRendering
= NS_STYLE_TEXT_RENDERING_AUTO
;
862 nsStyleSVG::~nsStyleSVG()
864 MOZ_COUNT_DTOR(nsStyleSVG
);
865 delete [] mStrokeDasharray
;
868 nsStyleSVG::nsStyleSVG(const nsStyleSVG
& aSource
)
870 MOZ_COUNT_CTOR(nsStyleSVG
);
871 mFill
= aSource
.mFill
;
872 mStroke
= aSource
.mStroke
;
874 mMarkerEnd
= aSource
.mMarkerEnd
;
875 mMarkerMid
= aSource
.mMarkerMid
;
876 mMarkerStart
= aSource
.mMarkerStart
;
878 mStrokeDasharrayLength
= aSource
.mStrokeDasharrayLength
;
879 if (aSource
.mStrokeDasharray
) {
880 mStrokeDasharray
= new nsStyleCoord
[mStrokeDasharrayLength
];
881 if (mStrokeDasharray
)
882 memcpy(mStrokeDasharray
,
883 aSource
.mStrokeDasharray
,
884 mStrokeDasharrayLength
* sizeof(nsStyleCoord
));
886 mStrokeDasharrayLength
= 0;
888 mStrokeDasharray
= nsnull
;
891 mStrokeDashoffset
= aSource
.mStrokeDashoffset
;
892 mStrokeWidth
= aSource
.mStrokeWidth
;
894 mFillOpacity
= aSource
.mFillOpacity
;
895 mStrokeMiterlimit
= aSource
.mStrokeMiterlimit
;
896 mStrokeOpacity
= aSource
.mStrokeOpacity
;
898 mClipRule
= aSource
.mClipRule
;
899 mColorInterpolation
= aSource
.mColorInterpolation
;
900 mColorInterpolationFilters
= aSource
.mColorInterpolationFilters
;
901 mFillRule
= aSource
.mFillRule
;
902 mImageRendering
= aSource
.mImageRendering
;
903 mShapeRendering
= aSource
.mShapeRendering
;
904 mStrokeLinecap
= aSource
.mStrokeLinecap
;
905 mStrokeLinejoin
= aSource
.mStrokeLinejoin
;
906 mTextAnchor
= aSource
.mTextAnchor
;
907 mTextRendering
= aSource
.mTextRendering
;
910 static PRBool
PaintURIChanged(const nsStyleSVGPaint
& aPaint1
,
911 const nsStyleSVGPaint
& aPaint2
)
913 if (aPaint1
.mType
!= aPaint2
.mType
) {
914 return aPaint1
.mType
== eStyleSVGPaintType_Server
||
915 aPaint2
.mType
== eStyleSVGPaintType_Server
;
917 return aPaint1
.mType
== eStyleSVGPaintType_Server
&&
918 !EqualURIs(aPaint1
.mPaint
.mPaintServer
, aPaint2
.mPaint
.mPaintServer
);
921 nsChangeHint
nsStyleSVG::CalcDifference(const nsStyleSVG
& aOther
) const
923 nsChangeHint hint
= nsChangeHint(0);
925 if (mTextRendering
!= aOther
.mTextRendering
) {
926 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
927 // May be needed for non-svg frames
928 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
931 if (!EqualURIs(mMarkerEnd
, aOther
.mMarkerEnd
) ||
932 !EqualURIs(mMarkerMid
, aOther
.mMarkerMid
) ||
933 !EqualURIs(mMarkerStart
, aOther
.mMarkerStart
)) {
934 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
935 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
939 if (mFill
!= aOther
.mFill
||
940 mStroke
!= aOther
.mStroke
) {
941 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
942 if (PaintURIChanged(mFill
, aOther
.mFill
) ||
943 PaintURIChanged(mStroke
, aOther
.mStroke
)) {
944 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
946 // Nothing more to do, below we can only set "repaint"
950 if ( mStrokeDashoffset
!= aOther
.mStrokeDashoffset
||
951 mStrokeWidth
!= aOther
.mStrokeWidth
||
953 mFillOpacity
!= aOther
.mFillOpacity
||
954 mStrokeMiterlimit
!= aOther
.mStrokeMiterlimit
||
955 mStrokeOpacity
!= aOther
.mStrokeOpacity
||
957 mClipRule
!= aOther
.mClipRule
||
958 mColorInterpolation
!= aOther
.mColorInterpolation
||
959 mColorInterpolationFilters
!= aOther
.mColorInterpolationFilters
||
960 mFillRule
!= aOther
.mFillRule
||
961 mImageRendering
!= aOther
.mImageRendering
||
962 mShapeRendering
!= aOther
.mShapeRendering
||
963 mStrokeDasharrayLength
!= aOther
.mStrokeDasharrayLength
||
964 mStrokeLinecap
!= aOther
.mStrokeLinecap
||
965 mStrokeLinejoin
!= aOther
.mStrokeLinejoin
||
966 mTextAnchor
!= aOther
.mTextAnchor
) {
967 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
971 // length of stroke dasharrays are the same (tested above) - check entries
972 for (PRUint32 i
=0; i
<mStrokeDasharrayLength
; i
++)
973 if (mStrokeDasharray
[i
] != aOther
.mStrokeDasharray
[i
]) {
974 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
983 nsChangeHint
nsStyleSVG::MaxDifference()
985 return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects
,
986 nsChangeHint_ReflowFrame
),
987 nsChangeHint_RepaintFrame
);
991 // --------------------
994 nsStyleSVGReset::nsStyleSVGReset()
996 MOZ_COUNT_CTOR(nsStyleSVGReset
);
997 mStopColor
= NS_RGB(0,0,0);
998 mFloodColor
= NS_RGB(0,0,0);
999 mLightingColor
= NS_RGB(255,255,255);
1003 mStopOpacity
= 1.0f
;
1004 mFloodOpacity
= 1.0f
;
1005 mDominantBaseline
= NS_STYLE_DOMINANT_BASELINE_AUTO
;
1008 nsStyleSVGReset::~nsStyleSVGReset()
1010 MOZ_COUNT_DTOR(nsStyleSVGReset
);
1013 nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset
& aSource
)
1015 MOZ_COUNT_CTOR(nsStyleSVGReset
);
1016 mStopColor
= aSource
.mStopColor
;
1017 mFloodColor
= aSource
.mFloodColor
;
1018 mLightingColor
= aSource
.mLightingColor
;
1019 mClipPath
= aSource
.mClipPath
;
1020 mFilter
= aSource
.mFilter
;
1021 mMask
= aSource
.mMask
;
1022 mStopOpacity
= aSource
.mStopOpacity
;
1023 mFloodOpacity
= aSource
.mFloodOpacity
;
1024 mDominantBaseline
= aSource
.mDominantBaseline
;
1027 nsChangeHint
nsStyleSVGReset::CalcDifference(const nsStyleSVGReset
& aOther
) const
1029 nsChangeHint hint
= nsChangeHint(0);
1031 if (!EqualURIs(mClipPath
, aOther
.mClipPath
) ||
1032 !EqualURIs(mFilter
, aOther
.mFilter
) ||
1033 !EqualURIs(mMask
, aOther
.mMask
)) {
1034 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
1035 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
1036 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1037 } else if (mStopColor
!= aOther
.mStopColor
||
1038 mFloodColor
!= aOther
.mFloodColor
||
1039 mLightingColor
!= aOther
.mLightingColor
||
1040 mStopOpacity
!= aOther
.mStopOpacity
||
1041 mFloodOpacity
!= aOther
.mFloodOpacity
||
1042 mDominantBaseline
!= aOther
.mDominantBaseline
)
1043 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1050 nsChangeHint
nsStyleSVGReset::MaxDifference()
1052 return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects
,
1053 nsChangeHint_ReflowFrame
),
1054 nsChangeHint_RepaintFrame
);
1058 // nsStyleSVGPaint implementation
1059 nsStyleSVGPaint::~nsStyleSVGPaint()
1061 if (mType
== eStyleSVGPaintType_Server
) {
1062 NS_IF_RELEASE(mPaint
.mPaintServer
);
1067 nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType
)
1069 if (mType
== eStyleSVGPaintType_Server
) {
1070 this->~nsStyleSVGPaint();
1071 new (this) nsStyleSVGPaint();
1076 nsStyleSVGPaint
& nsStyleSVGPaint::operator=(const nsStyleSVGPaint
& aOther
)
1078 if (this == &aOther
)
1081 SetType(aOther
.mType
);
1083 mFallbackColor
= aOther
.mFallbackColor
;
1084 if (mType
== eStyleSVGPaintType_Server
) {
1085 mPaint
.mPaintServer
= aOther
.mPaint
.mPaintServer
;
1086 NS_IF_ADDREF(mPaint
.mPaintServer
);
1088 mPaint
.mColor
= aOther
.mPaint
.mColor
;
1093 PRBool
nsStyleSVGPaint::operator==(const nsStyleSVGPaint
& aOther
) const
1095 if (mType
!= aOther
.mType
)
1097 if (mType
== eStyleSVGPaintType_Server
)
1098 return EqualURIs(mPaint
.mPaintServer
, aOther
.mPaint
.mPaintServer
) &&
1099 mFallbackColor
== aOther
.mFallbackColor
;
1100 if (mType
== eStyleSVGPaintType_None
)
1102 return mPaint
.mColor
== aOther
.mPaint
.mColor
;
1106 // --------------------
1109 nsStylePosition::nsStylePosition(void)
1111 MOZ_COUNT_CTOR(nsStylePosition
);
1112 // positioning values not inherited
1113 nsStyleCoord
autoCoord(eStyleUnit_Auto
);
1114 mOffset
.SetLeft(autoCoord
);
1115 mOffset
.SetTop(autoCoord
);
1116 mOffset
.SetRight(autoCoord
);
1117 mOffset
.SetBottom(autoCoord
);
1118 mWidth
.SetAutoValue();
1119 mMinWidth
.SetCoordValue(0);
1120 mMaxWidth
.SetNoneValue();
1121 mHeight
.SetAutoValue();
1122 mMinHeight
.SetCoordValue(0);
1123 mMaxHeight
.SetNoneValue();
1124 mBoxSizing
= NS_STYLE_BOX_SIZING_CONTENT
;
1125 mZIndex
.SetAutoValue();
1128 nsStylePosition::~nsStylePosition(void)
1130 MOZ_COUNT_DTOR(nsStylePosition
);
1133 nsStylePosition::nsStylePosition(const nsStylePosition
& aSource
)
1135 MOZ_COUNT_CTOR(nsStylePosition
);
1136 memcpy((nsStylePosition
*)this, &aSource
, sizeof(nsStylePosition
));
1139 nsChangeHint
nsStylePosition::CalcDifference(const nsStylePosition
& aOther
) const
1142 (mZIndex
== aOther
.mZIndex
) ? NS_STYLE_HINT_NONE
: nsChangeHint_RepaintFrame
;
1144 if (mBoxSizing
!= aOther
.mBoxSizing
) {
1145 // Can affect both widths and heights; just a bad scene.
1146 return NS_CombineHint(hint
, nsChangeHint_ReflowFrame
);
1149 if (mHeight
!= aOther
.mHeight
||
1150 mMinHeight
!= aOther
.mMinHeight
||
1151 mMaxHeight
!= aOther
.mMaxHeight
) {
1152 // Height changes can affect descendant intrinsic sizes due to replaced
1153 // elements with percentage heights in descendants which also have
1154 // percentage heights. And due to our not-so-great computation of mVResize
1155 // in nsHTMLReflowState, they do need to force reflow of the whole subtree.
1156 // XXXbz due to XUL caching heights as well, height changes also need to
1157 // clear ancestor intrinsics!
1158 return NS_CombineHint(hint
, nsChangeHint_ReflowFrame
);
1161 if ((mWidth
== aOther
.mWidth
) &&
1162 (mMinWidth
== aOther
.mMinWidth
) &&
1163 (mMaxWidth
== aOther
.mMaxWidth
)) {
1164 if (mOffset
== aOther
.mOffset
) {
1167 // Offset changes only affect positioned content, and can't affect any
1168 // intrinsic widths. They also don't need to force reflow of
1170 return NS_CombineHint(hint
, nsChangeHint_NeedReflow
);
1174 // None of our width differences can affect descendant intrinsic
1175 // sizes and none of them need to force children to reflow.
1177 NS_CombineHint(hint
,
1178 NS_SubtractHint(nsChangeHint_ReflowFrame
,
1179 NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics
,
1180 nsChangeHint_NeedDirtyReflow
)));
1185 nsChangeHint
nsStylePosition::MaxDifference()
1187 return NS_STYLE_HINT_REFLOW
;
1192 nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord
&aCoord
)
1194 return aCoord
.GetUnit() == eStyleUnit_Auto
||
1195 aCoord
.HasPercent() ||
1196 (aCoord
.GetUnit() == eStyleUnit_Enumerated
&&
1197 (aCoord
.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT
||
1198 aCoord
.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE
));
1201 // --------------------
1205 nsStyleTable::nsStyleTable()
1207 MOZ_COUNT_CTOR(nsStyleTable
);
1208 // values not inherited
1209 mLayoutStrategy
= NS_STYLE_TABLE_LAYOUT_AUTO
;
1210 mCols
= NS_STYLE_TABLE_COLS_NONE
;
1211 mFrame
= NS_STYLE_TABLE_FRAME_NONE
;
1212 mRules
= NS_STYLE_TABLE_RULES_NONE
;
1216 nsStyleTable::~nsStyleTable(void)
1218 MOZ_COUNT_DTOR(nsStyleTable
);
1221 nsStyleTable::nsStyleTable(const nsStyleTable
& aSource
)
1223 MOZ_COUNT_CTOR(nsStyleTable
);
1224 memcpy((nsStyleTable
*)this, &aSource
, sizeof(nsStyleTable
));
1227 nsChangeHint
nsStyleTable::CalcDifference(const nsStyleTable
& aOther
) const
1229 // Changes in mRules may require reframing (if border-collapse stuff changes, for example).
1230 if (mRules
!= aOther
.mRules
|| mSpan
!= aOther
.mSpan
||
1231 mLayoutStrategy
!= aOther
.mLayoutStrategy
)
1232 return NS_STYLE_HINT_FRAMECHANGE
;
1233 if (mFrame
!= aOther
.mFrame
|| mCols
!= aOther
.mCols
)
1234 return NS_STYLE_HINT_REFLOW
;
1235 return NS_STYLE_HINT_NONE
;
1240 nsChangeHint
nsStyleTable::MaxDifference()
1242 return NS_STYLE_HINT_FRAMECHANGE
;
1246 // -----------------------
1247 // nsStyleTableBorder
1249 nsStyleTableBorder::nsStyleTableBorder(nsPresContext
* aPresContext
)
1251 MOZ_COUNT_CTOR(nsStyleTableBorder
);
1252 mBorderCollapse
= NS_STYLE_BORDER_SEPARATE
;
1254 nsCompatibility compatMode
= eCompatibility_FullStandards
;
1256 compatMode
= aPresContext
->CompatibilityMode();
1257 mEmptyCells
= (compatMode
== eCompatibility_NavQuirks
)
1258 ? NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND
1259 : NS_STYLE_TABLE_EMPTY_CELLS_SHOW
;
1260 mCaptionSide
= NS_STYLE_CAPTION_SIDE_TOP
;
1261 mBorderSpacingX
= 0;
1262 mBorderSpacingY
= 0;
1265 nsStyleTableBorder::~nsStyleTableBorder(void)
1267 MOZ_COUNT_DTOR(nsStyleTableBorder
);
1270 nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder
& aSource
)
1272 MOZ_COUNT_CTOR(nsStyleTableBorder
);
1273 memcpy((nsStyleTableBorder
*)this, &aSource
, sizeof(nsStyleTableBorder
));
1276 nsChangeHint
nsStyleTableBorder::CalcDifference(const nsStyleTableBorder
& aOther
) const
1278 // Border-collapse changes need a reframe, because we use a different frame
1279 // class for table cells in the collapsed border model. This is used to
1280 // conserve memory when using the separated border model (collapsed borders
1281 // require extra state to be stored).
1282 if (mBorderCollapse
!= aOther
.mBorderCollapse
) {
1283 return NS_STYLE_HINT_FRAMECHANGE
;
1286 if ((mCaptionSide
== aOther
.mCaptionSide
) &&
1287 (mBorderSpacingX
== aOther
.mBorderSpacingX
) &&
1288 (mBorderSpacingY
== aOther
.mBorderSpacingY
)) {
1289 if (mEmptyCells
== aOther
.mEmptyCells
)
1290 return NS_STYLE_HINT_NONE
;
1291 return NS_STYLE_HINT_VISUAL
;
1294 return NS_STYLE_HINT_REFLOW
;
1299 nsChangeHint
nsStyleTableBorder::MaxDifference()
1301 return NS_STYLE_HINT_FRAMECHANGE
;
1305 // --------------------
1309 nsStyleColor::nsStyleColor(nsPresContext
* aPresContext
)
1311 MOZ_COUNT_CTOR(nsStyleColor
);
1312 mColor
= aPresContext
->DefaultColor();
1315 nsStyleColor::nsStyleColor(const nsStyleColor
& aSource
)
1317 MOZ_COUNT_CTOR(nsStyleColor
);
1318 mColor
= aSource
.mColor
;
1321 nsChangeHint
nsStyleColor::CalcDifference(const nsStyleColor
& aOther
) const
1323 if (mColor
== aOther
.mColor
)
1324 return NS_STYLE_HINT_NONE
;
1325 return NS_STYLE_HINT_VISUAL
;
1330 nsChangeHint
nsStyleColor::MaxDifference()
1332 return NS_STYLE_HINT_VISUAL
;
1336 // --------------------
1340 nsStyleGradient::operator==(const nsStyleGradient
& aOther
) const
1342 NS_ABORT_IF_FALSE(mSize
== NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
||
1343 mShape
!= NS_STYLE_GRADIENT_SHAPE_LINEAR
,
1344 "incorrect combination of shape and size");
1345 NS_ABORT_IF_FALSE(aOther
.mSize
== NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
||
1346 aOther
.mShape
!= NS_STYLE_GRADIENT_SHAPE_LINEAR
,
1347 "incorrect combination of shape and size");
1349 if (mShape
!= aOther
.mShape
||
1350 mSize
!= aOther
.mSize
||
1351 mRepeating
!= aOther
.mRepeating
||
1352 mBgPosX
!= aOther
.mBgPosX
||
1353 mBgPosY
!= aOther
.mBgPosY
||
1354 mAngle
!= aOther
.mAngle
)
1357 if (mStops
.Length() != aOther
.mStops
.Length())
1360 for (PRUint32 i
= 0; i
< mStops
.Length(); i
++) {
1361 if (mStops
[i
].mLocation
!= aOther
.mStops
[i
].mLocation
||
1362 mStops
[i
].mColor
!= aOther
.mStops
[i
].mColor
)
1369 nsStyleGradient::nsStyleGradient(void)
1370 : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR
)
1371 , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
)
1372 , mRepeating(PR_FALSE
)
1377 nsStyleGradient::IsOpaque()
1379 for (PRUint32 i
= 0; i
< mStops
.Length(); i
++) {
1380 if (NS_GET_A(mStops
[i
].mColor
) < 255)
1386 // --------------------
1390 nsStyleImage::nsStyleImage()
1391 : mType(eStyleImageType_Null
)
1394 , mImageTracked(false)
1397 MOZ_COUNT_CTOR(nsStyleImage
);
1400 nsStyleImage::~nsStyleImage()
1402 MOZ_COUNT_DTOR(nsStyleImage
);
1403 if (mType
!= eStyleImageType_Null
)
1407 nsStyleImage::nsStyleImage(const nsStyleImage
& aOther
)
1408 : mType(eStyleImageType_Null
)
1411 , mImageTracked(false)
1414 // We need our own copy constructor because we don't want
1415 // to copy the reference count
1416 MOZ_COUNT_CTOR(nsStyleImage
);
1421 nsStyleImage::operator=(const nsStyleImage
& aOther
)
1423 if (this != &aOther
)
1430 nsStyleImage::DoCopy(const nsStyleImage
& aOther
)
1434 if (aOther
.mType
== eStyleImageType_Image
)
1435 SetImageData(aOther
.mImage
);
1436 else if (aOther
.mType
== eStyleImageType_Gradient
)
1437 SetGradientData(aOther
.mGradient
);
1438 else if (aOther
.mType
== eStyleImageType_Element
)
1439 SetElementId(aOther
.mElementId
);
1441 SetCropRect(aOther
.mCropRect
);
1445 nsStyleImage::SetNull()
1447 NS_ABORT_IF_FALSE(!mImageTracked
,
1448 "Calling SetNull() with image tracked!");
1450 if (mType
== eStyleImageType_Gradient
)
1451 mGradient
->Release();
1452 else if (mType
== eStyleImageType_Image
)
1454 else if (mType
== eStyleImageType_Element
)
1455 nsCRT::free(mElementId
);
1457 mType
= eStyleImageType_Null
;
1462 nsStyleImage::SetImageData(imgIRequest
* aImage
)
1464 NS_ABORT_IF_FALSE(!mImageTracked
,
1465 "Setting a new image without untracking the old one!");
1467 NS_IF_ADDREF(aImage
);
1469 if (mType
!= eStyleImageType_Null
)
1474 mType
= eStyleImageType_Image
;
1479 nsStyleImage::TrackImage(nsPresContext
* aContext
)
1482 NS_ABORT_IF_FALSE(!mImageTracked
, "Already tracking image!");
1483 NS_ABORT_IF_FALSE(mType
== eStyleImageType_Image
,
1484 "Can't track image when there isn't one!");
1486 // Register the image with the document
1487 nsIDocument
* doc
= aContext
->Document();
1489 doc
->AddImage(mImage
);
1493 mImageTracked
= true;
1498 nsStyleImage::UntrackImage(nsPresContext
* aContext
)
1501 NS_ABORT_IF_FALSE(mImageTracked
, "Image not tracked!");
1502 NS_ABORT_IF_FALSE(mType
== eStyleImageType_Image
,
1503 "Can't untrack image when there isn't one!");
1505 // Unregister the image with the document
1506 nsIDocument
* doc
= aContext
->Document();
1508 doc
->RemoveImage(mImage
);
1512 mImageTracked
= false;
1517 nsStyleImage::SetGradientData(nsStyleGradient
* aGradient
)
1520 aGradient
->AddRef();
1522 if (mType
!= eStyleImageType_Null
)
1526 mGradient
= aGradient
;
1527 mType
= eStyleImageType_Gradient
;
1532 nsStyleImage::SetElementId(const PRUnichar
* aElementId
)
1534 if (mType
!= eStyleImageType_Null
)
1538 mElementId
= nsCRT::strdup(aElementId
);
1539 mType
= eStyleImageType_Element
;
1544 nsStyleImage::SetCropRect(nsStyleSides
* aCropRect
)
1547 mCropRect
= new nsStyleSides(*aCropRect
);
1548 // There is really not much we can do if 'new' fails
1555 ConvertToPixelCoord(const nsStyleCoord
& aCoord
, PRInt32 aPercentScale
)
1558 switch (aCoord
.GetUnit()) {
1559 case eStyleUnit_Percent
:
1560 pixelValue
= aCoord
.GetPercentValue() * aPercentScale
;
1562 case eStyleUnit_Factor
:
1563 pixelValue
= aCoord
.GetFactorValue();
1566 NS_NOTREACHED("unexpected unit for image crop rect");
1569 NS_ABORT_IF_FALSE(pixelValue
>= 0, "we ensured non-negative while parsing");
1570 pixelValue
= NS_MIN(pixelValue
, double(PR_INT32_MAX
)); // avoid overflow
1571 return NS_lround(pixelValue
);
1575 nsStyleImage::ComputeActualCropRect(nsIntRect
& aActualCropRect
,
1576 PRBool
* aIsEntireImage
) const
1578 if (mType
!= eStyleImageType_Image
)
1581 nsCOMPtr
<imgIContainer
> imageContainer
;
1582 mImage
->GetImage(getter_AddRefs(imageContainer
));
1583 if (!imageContainer
)
1586 nsIntSize imageSize
;
1587 imageContainer
->GetWidth(&imageSize
.width
);
1588 imageContainer
->GetHeight(&imageSize
.height
);
1589 if (imageSize
.width
<= 0 || imageSize
.height
<= 0)
1592 PRInt32 left
= ConvertToPixelCoord(mCropRect
->GetLeft(), imageSize
.width
);
1593 PRInt32 top
= ConvertToPixelCoord(mCropRect
->GetTop(), imageSize
.height
);
1594 PRInt32 right
= ConvertToPixelCoord(mCropRect
->GetRight(), imageSize
.width
);
1595 PRInt32 bottom
= ConvertToPixelCoord(mCropRect
->GetBottom(), imageSize
.height
);
1597 // IntersectRect() returns an empty rect if we get negative width or height
1598 nsIntRect
cropRect(left
, top
, right
- left
, bottom
- top
);
1599 nsIntRect
imageRect(nsIntPoint(0, 0), imageSize
);
1600 aActualCropRect
.IntersectRect(imageRect
, cropRect
);
1603 *aIsEntireImage
= (aActualCropRect
== imageRect
);
1608 nsStyleImage::RequestDecode() const
1610 if ((mType
== eStyleImageType_Image
) && mImage
)
1611 return mImage
->RequestDecode();
1616 nsStyleImage::IsOpaque() const
1621 if (mType
== eStyleImageType_Gradient
)
1622 return mGradient
->IsOpaque();
1624 if (mType
== eStyleImageType_Element
)
1627 NS_ABORT_IF_FALSE(mType
== eStyleImageType_Image
, "unexpected image type");
1629 nsCOMPtr
<imgIContainer
> imageContainer
;
1630 mImage
->GetImage(getter_AddRefs(imageContainer
));
1631 NS_ABORT_IF_FALSE(imageContainer
, "IsComplete() said image container is ready");
1633 // Check if the crop region of the current image frame is opaque
1635 if (NS_SUCCEEDED(imageContainer
->GetCurrentFrameIsOpaque(&isOpaque
)) &&
1640 // Must make sure if mCropRect contains at least a pixel.
1641 // XXX Is this optimization worth it? Maybe I should just return PR_FALSE.
1642 nsIntRect actualCropRect
;
1643 PRBool rv
= ComputeActualCropRect(actualCropRect
);
1644 NS_ASSERTION(rv
, "ComputeActualCropRect() can not fail here");
1645 return rv
&& !actualCropRect
.IsEmpty();
1652 nsStyleImage::IsComplete() const
1655 case eStyleImageType_Null
:
1657 case eStyleImageType_Gradient
:
1658 case eStyleImageType_Element
:
1660 case eStyleImageType_Image
:
1662 PRUint32 status
= imgIRequest::STATUS_ERROR
;
1663 return NS_SUCCEEDED(mImage
->GetImageStatus(&status
)) &&
1664 (status
& imgIRequest::STATUS_SIZE_AVAILABLE
) &&
1665 (status
& imgIRequest::STATUS_FRAME_COMPLETE
);
1668 NS_NOTREACHED("unexpected image type");
1673 static inline PRBool
1674 EqualRects(const nsStyleSides
* aRect1
, const nsStyleSides
* aRect2
)
1676 return aRect1
== aRect2
|| /* handles null== null, and optimize */
1677 (aRect1
&& aRect2
&& *aRect1
== *aRect2
);
1681 nsStyleImage::operator==(const nsStyleImage
& aOther
) const
1683 if (mType
!= aOther
.mType
)
1686 if (!EqualRects(mCropRect
, aOther
.mCropRect
))
1689 if (mType
== eStyleImageType_Image
)
1690 return EqualImages(mImage
, aOther
.mImage
);
1692 if (mType
== eStyleImageType_Gradient
)
1693 return *mGradient
== *aOther
.mGradient
;
1695 if (mType
== eStyleImageType_Element
)
1696 return nsCRT::strcmp(mElementId
, aOther
.mElementId
) == 0;
1701 // --------------------
1702 // nsStyleBackground
1705 nsStyleBackground::nsStyleBackground()
1706 : mAttachmentCount(1)
1713 , mBackgroundColor(NS_RGBA(0, 0, 0, 0))
1714 , mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS
)
1716 MOZ_COUNT_CTOR(nsStyleBackground
);
1717 Layer
*onlyLayer
= mLayers
.AppendElement();
1718 NS_ASSERTION(onlyLayer
, "auto array must have room for 1 element");
1719 onlyLayer
->SetInitialValues();
1722 nsStyleBackground::nsStyleBackground(const nsStyleBackground
& aSource
)
1723 : mAttachmentCount(aSource
.mAttachmentCount
)
1724 , mClipCount(aSource
.mClipCount
)
1725 , mOriginCount(aSource
.mOriginCount
)
1726 , mRepeatCount(aSource
.mRepeatCount
)
1727 , mPositionCount(aSource
.mPositionCount
)
1728 , mImageCount(aSource
.mImageCount
)
1729 , mSizeCount(aSource
.mSizeCount
)
1730 , mLayers(aSource
.mLayers
) // deep copy
1731 , mBackgroundColor(aSource
.mBackgroundColor
)
1732 , mBackgroundInlinePolicy(aSource
.mBackgroundInlinePolicy
)
1734 MOZ_COUNT_CTOR(nsStyleBackground
);
1735 // If the deep copy of mLayers failed, truncate the counts.
1736 PRUint32 count
= mLayers
.Length();
1737 if (count
!= aSource
.mLayers
.Length()) {
1738 NS_WARNING("truncating counts due to out-of-memory");
1739 mAttachmentCount
= NS_MAX(mAttachmentCount
, count
);
1740 mClipCount
= NS_MAX(mClipCount
, count
);
1741 mOriginCount
= NS_MAX(mOriginCount
, count
);
1742 mRepeatCount
= NS_MAX(mRepeatCount
, count
);
1743 mPositionCount
= NS_MAX(mPositionCount
, count
);
1744 mImageCount
= NS_MAX(mImageCount
, count
);
1745 mSizeCount
= NS_MAX(mSizeCount
, count
);
1749 nsStyleBackground::~nsStyleBackground()
1751 MOZ_COUNT_DTOR(nsStyleBackground
);
1755 nsStyleBackground::Destroy(nsPresContext
* aContext
)
1757 // Untrack all the images stored in our layers
1758 for (PRUint32 i
= 0; i
< mImageCount
; ++i
)
1759 mLayers
[i
].UntrackImages(aContext
);
1761 this->~nsStyleBackground();
1762 aContext
->FreeToShell(sizeof(nsStyleBackground
), this);
1765 nsChangeHint
nsStyleBackground::CalcDifference(const nsStyleBackground
& aOther
) const
1767 const nsStyleBackground
* moreLayers
=
1768 mImageCount
> aOther
.mImageCount
? this : &aOther
;
1769 const nsStyleBackground
* lessLayers
=
1770 mImageCount
> aOther
.mImageCount
? &aOther
: this;
1772 bool hasVisualDifference
= false;
1774 NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i
, moreLayers
) {
1775 if (i
< lessLayers
->mImageCount
) {
1776 if (moreLayers
->mLayers
[i
] != lessLayers
->mLayers
[i
]) {
1777 if ((moreLayers
->mLayers
[i
].mImage
.GetType() == eStyleImageType_Element
) ||
1778 (lessLayers
->mLayers
[i
].mImage
.GetType() == eStyleImageType_Element
))
1779 return NS_CombineHint(nsChangeHint_UpdateEffects
, NS_STYLE_HINT_VISUAL
);
1780 hasVisualDifference
= true;
1783 if (moreLayers
->mLayers
[i
].mImage
.GetType() == eStyleImageType_Element
)
1784 return NS_CombineHint(nsChangeHint_UpdateEffects
, NS_STYLE_HINT_VISUAL
);
1785 hasVisualDifference
= true;
1789 if (hasVisualDifference
||
1790 mBackgroundColor
!= aOther
.mBackgroundColor
||
1791 mBackgroundInlinePolicy
!= aOther
.mBackgroundInlinePolicy
)
1792 return NS_STYLE_HINT_VISUAL
;
1794 return NS_STYLE_HINT_NONE
;
1799 nsChangeHint
nsStyleBackground::MaxDifference()
1801 return NS_CombineHint(nsChangeHint_UpdateEffects
, NS_STYLE_HINT_VISUAL
);
1805 PRBool
nsStyleBackground::HasFixedBackground() const
1807 NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i
, this) {
1808 const Layer
&layer
= mLayers
[i
];
1809 if (layer
.mAttachment
== NS_STYLE_BG_ATTACHMENT_FIXED
&&
1810 !layer
.mImage
.IsEmpty()) {
1817 PRBool
nsStyleBackground::IsTransparent() const
1819 return BottomLayer().mImage
.IsEmpty() &&
1821 NS_GET_A(mBackgroundColor
) == 0;
1825 nsStyleBackground::Position::SetInitialValues()
1827 mXPosition
.mPercent
= 0.0f
;
1828 mXPosition
.mLength
= 0;
1829 mYPosition
.mPercent
= 0.0f
;
1830 mYPosition
.mLength
= 0;
1834 nsStyleBackground::Size::SetInitialValues()
1836 mWidthType
= mHeightType
= eAuto
;
1840 nsStyleBackground::Size::operator==(const Size
& aOther
) const
1842 NS_ABORT_IF_FALSE(mWidthType
< eDimensionType_COUNT
,
1843 "bad mWidthType for this");
1844 NS_ABORT_IF_FALSE(mHeightType
< eDimensionType_COUNT
,
1845 "bad mHeightType for this");
1846 NS_ABORT_IF_FALSE(aOther
.mWidthType
< eDimensionType_COUNT
,
1847 "bad mWidthType for aOther");
1848 NS_ABORT_IF_FALSE(aOther
.mHeightType
< eDimensionType_COUNT
,
1849 "bad mHeightType for aOther");
1851 return mWidthType
== aOther
.mWidthType
&&
1852 mHeightType
== aOther
.mHeightType
&&
1853 (mWidthType
!= eLengthPercentage
|| mWidth
== aOther
.mWidth
) &&
1854 (mHeightType
!= eLengthPercentage
|| mHeight
== aOther
.mHeight
);
1857 nsStyleBackground::Layer::Layer()
1861 nsStyleBackground::Layer::~Layer()
1866 nsStyleBackground::Layer::SetInitialValues()
1868 mAttachment
= NS_STYLE_BG_ATTACHMENT_SCROLL
;
1869 mClip
= NS_STYLE_BG_CLIP_BORDER
;
1870 mOrigin
= NS_STYLE_BG_ORIGIN_PADDING
;
1871 mRepeat
= NS_STYLE_BG_REPEAT_XY
;
1872 mPosition
.SetInitialValues();
1873 mSize
.SetInitialValues();
1878 nsStyleBackground::Layer::RenderingMightDependOnFrameSize() const
1880 // Do we even have an image?
1881 if (mImage
.IsEmpty()) {
1885 // Does our position or size depend on frame size?
1886 if (mPosition
.DependsOnFrameSize() ||
1887 mSize
.DependsOnFrameSize(mImage
.GetType())) {
1891 // Are we an SVG image with a viewBox attribute?
1892 if (mImage
.GetType() == eStyleImageType_Image
) {
1893 nsCOMPtr
<imgIContainer
> imageContainer
;
1894 mImage
.GetImageData()->GetImage(getter_AddRefs(imageContainer
));
1895 if (imageContainer
&&
1896 imageContainer
->GetType() == imgIContainer::TYPE_VECTOR
) {
1897 nsIFrame
* rootFrame
= imageContainer
->GetRootLayoutFrame();
1899 nsSVGUtils::RootSVGElementHasViewbox(rootFrame
->GetContent())) {
1909 nsStyleBackground::Layer::operator==(const Layer
& aOther
) const
1911 return mAttachment
== aOther
.mAttachment
&&
1912 mClip
== aOther
.mClip
&&
1913 mOrigin
== aOther
.mOrigin
&&
1914 mRepeat
== aOther
.mRepeat
&&
1915 mPosition
== aOther
.mPosition
&&
1916 mSize
== aOther
.mSize
&&
1917 mImage
== aOther
.mImage
;
1920 // --------------------
1923 void nsTimingFunction::AssignFromKeyword(PRInt32 aTimingFunctionType
)
1925 PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE
== 0);
1926 PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR
== 1);
1927 PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN
== 2);
1928 PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT
== 3);
1929 PR_STATIC_ASSERT(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT
== 4);
1931 static const float timingFunctionValues
[5][4] = {
1932 { 0.25, 0.10, 0.25, 1.00 }, // ease
1933 { 0.00, 0.00, 1.00, 1.00 }, // linear
1934 { 0.42, 0.00, 1.00, 1.00 }, // ease-in
1935 { 0.00, 0.00, 0.58, 1.00 }, // ease-out
1936 { 0.42, 0.00, 0.58, 1.00 } // ease-in-out
1939 NS_ABORT_IF_FALSE(0 <= aTimingFunctionType
&& aTimingFunctionType
< 5,
1940 "keyword out of range");
1941 mX1
= timingFunctionValues
[aTimingFunctionType
][0];
1942 mY1
= timingFunctionValues
[aTimingFunctionType
][1];
1943 mX2
= timingFunctionValues
[aTimingFunctionType
][2];
1944 mY2
= timingFunctionValues
[aTimingFunctionType
][3];
1947 nsTransition::nsTransition(const nsTransition
& aCopy
)
1948 : mTimingFunction(aCopy
.mTimingFunction
)
1949 , mDuration(aCopy
.mDuration
)
1950 , mDelay(aCopy
.mDelay
)
1951 , mProperty(aCopy
.mProperty
)
1952 , mUnknownProperty(aCopy
.mUnknownProperty
)
1956 void nsTransition::SetInitialValues()
1958 mTimingFunction
= nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE
);
1961 mProperty
= eCSSPropertyExtra_all_properties
;
1964 void nsTransition::SetUnknownProperty(const nsAString
& aUnknownProperty
)
1966 NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty
) ==
1967 eCSSProperty_UNKNOWN
,
1968 "should be unknown property");
1969 mProperty
= eCSSProperty_UNKNOWN
;
1970 mUnknownProperty
= do_GetAtom(aUnknownProperty
);
1973 nsStyleDisplay::nsStyleDisplay()
1975 MOZ_COUNT_CTOR(nsStyleDisplay
);
1976 mAppearance
= NS_THEME_NONE
;
1977 mDisplay
= NS_STYLE_DISPLAY_INLINE
;
1978 mOriginalDisplay
= NS_STYLE_DISPLAY_NONE
;
1979 mPosition
= NS_STYLE_POSITION_STATIC
;
1980 mFloats
= NS_STYLE_FLOAT_NONE
;
1981 mBreakType
= NS_STYLE_CLEAR_NONE
;
1982 mBreakBefore
= PR_FALSE
;
1983 mBreakAfter
= PR_FALSE
;
1984 mOverflowX
= NS_STYLE_OVERFLOW_VISIBLE
;
1985 mOverflowY
= NS_STYLE_OVERFLOW_VISIBLE
;
1986 mResize
= NS_STYLE_RESIZE_NONE
;
1987 mClipFlags
= NS_STYLE_CLIP_AUTO
;
1988 mClip
.SetRect(0,0,0,0);
1990 mSpecifiedTransform
= nsnull
;
1991 mTransformOrigin
[0].SetPercentValue(0.5f
); // Transform is centered on origin
1992 mTransformOrigin
[1].SetPercentValue(0.5f
);
1993 mTransitions
.AppendElement();
1994 NS_ABORT_IF_FALSE(mTransitions
.Length() == 1,
1995 "appending within auto buffer should never fail");
1996 mTransitions
[0].SetInitialValues();
1997 mTransitionTimingFunctionCount
= 1;
1998 mTransitionDurationCount
= 1;
1999 mTransitionDelayCount
= 1;
2000 mTransitionPropertyCount
= 1;
2003 nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay
& aSource
)
2004 : mTransitions(aSource
.mTransitions
)
2005 , mTransitionTimingFunctionCount(aSource
.mTransitionTimingFunctionCount
)
2006 , mTransitionDurationCount(aSource
.mTransitionDurationCount
)
2007 , mTransitionDelayCount(aSource
.mTransitionDelayCount
)
2008 , mTransitionPropertyCount(aSource
.mTransitionPropertyCount
)
2010 MOZ_COUNT_CTOR(nsStyleDisplay
);
2011 mAppearance
= aSource
.mAppearance
;
2012 mDisplay
= aSource
.mDisplay
;
2013 mOriginalDisplay
= aSource
.mOriginalDisplay
;
2014 mBinding
= aSource
.mBinding
;
2015 mPosition
= aSource
.mPosition
;
2016 mFloats
= aSource
.mFloats
;
2017 mBreakType
= aSource
.mBreakType
;
2018 mBreakBefore
= aSource
.mBreakBefore
;
2019 mBreakAfter
= aSource
.mBreakAfter
;
2020 mOverflowX
= aSource
.mOverflowX
;
2021 mOverflowY
= aSource
.mOverflowY
;
2022 mResize
= aSource
.mResize
;
2023 mClipFlags
= aSource
.mClipFlags
;
2024 mClip
= aSource
.mClip
;
2025 mOpacity
= aSource
.mOpacity
;
2027 /* Copy over the transformation information. */
2028 mSpecifiedTransform
= aSource
.mSpecifiedTransform
;
2029 if (mSpecifiedTransform
)
2030 mTransform
= aSource
.mTransform
;
2032 /* Copy over transform origin. */
2033 mTransformOrigin
[0] = aSource
.mTransformOrigin
[0];
2034 mTransformOrigin
[1] = aSource
.mTransformOrigin
[1];
2037 nsChangeHint
nsStyleDisplay::CalcDifference(const nsStyleDisplay
& aOther
) const
2039 nsChangeHint hint
= nsChangeHint(0);
2041 if (!EqualURIs(mBinding
, aOther
.mBinding
)
2042 || mPosition
!= aOther
.mPosition
2043 || mDisplay
!= aOther
.mDisplay
2044 || (mFloats
== NS_STYLE_FLOAT_NONE
) != (aOther
.mFloats
== NS_STYLE_FLOAT_NONE
)
2045 || mOverflowX
!= aOther
.mOverflowX
2046 || mOverflowY
!= aOther
.mOverflowY
2047 || mResize
!= aOther
.mResize
)
2048 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
2050 if (mFloats
!= aOther
.mFloats
) {
2051 // Changing which side we float on doesn't affect descendants directly
2053 NS_SubtractHint(nsChangeHint_ReflowFrame
,
2054 NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics
,
2055 nsChangeHint_NeedDirtyReflow
)));
2058 // XXX the following is conservative, for now: changing float breaking shouldn't
2059 // necessarily require a repaint, reflow should suffice.
2060 if (mBreakType
!= aOther
.mBreakType
2061 || mBreakBefore
!= aOther
.mBreakBefore
2062 || mBreakAfter
!= aOther
.mBreakAfter
2063 || mAppearance
!= aOther
.mAppearance
2064 || mClipFlags
!= aOther
.mClipFlags
|| mClip
!= aOther
.mClip
)
2065 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
));
2067 if (mOpacity
!= aOther
.mOpacity
) {
2068 NS_UpdateHint(hint
, nsChangeHint_UpdateOpacityLayer
);
2071 /* If we've added or removed the transform property, we need to reconstruct the frame to add
2072 * or remove the view object, and also to handle abs-pos and fixed-pos containers.
2074 if (HasTransform() != aOther
.HasTransform()) {
2075 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
2077 else if (HasTransform()) {
2078 /* Otherwise, if we've kept the property lying around and we already had a
2079 * transform, we need to see whether or not we've changed the transform.
2080 * If so, we need to do a reflow and a repaint. The reflow is to recompute
2081 * the overflow rect (which probably changed if the transform changed)
2082 * and to redraw within the bounds of that new overflow rect.
2084 if (mTransform
!= aOther
.mTransform
)
2085 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_ReflowFrame
,
2086 nsChangeHint_UpdateTransformLayer
));
2088 for (PRUint8 index
= 0; index
< 2; ++index
)
2089 if (mTransformOrigin
[index
] != aOther
.mTransformOrigin
[index
]) {
2090 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_ReflowFrame
,
2091 nsChangeHint_RepaintFrame
));
2096 // Note: Our current behavior for handling changes to the
2097 // transition-duration, transition-delay, and transition-timing-function
2098 // properties is to do nothing. In other words, the transition
2099 // property that matters is what it is when the transition begins, and
2100 // we don't stop a transition later because the transition property
2102 // We do handle changes to transition-property, but we don't need to
2103 // bother with anything here, since the transition manager is notified
2104 // of any style context change anyway.
2111 nsChangeHint
nsStyleDisplay::MaxDifference()
2113 // All the parts of FRAMECHANGE are present above in CalcDifference.
2114 return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE
| nsChangeHint_UpdateOpacityLayer
|
2115 nsChangeHint_UpdateTransformLayer
);
2119 // --------------------
2120 // nsStyleVisibility
2123 nsStyleVisibility::nsStyleVisibility(nsPresContext
* aPresContext
)
2125 MOZ_COUNT_CTOR(nsStyleVisibility
);
2126 PRUint32 bidiOptions
= aPresContext
->GetBidi();
2127 if (GET_BIDI_OPTION_DIRECTION(bidiOptions
) == IBMBIDI_TEXTDIRECTION_RTL
)
2128 mDirection
= NS_STYLE_DIRECTION_RTL
;
2130 mDirection
= NS_STYLE_DIRECTION_LTR
;
2132 nsAutoString language
;
2133 aPresContext
->Document()->GetContentLanguage(language
);
2134 language
.StripWhitespace();
2136 // Content-Language may be a comma-separated list of language codes,
2137 // in which case the HTML5 spec says to treat it as unknown
2138 if (!language
.IsEmpty() &&
2139 language
.FindChar(PRUnichar(',')) == kNotFound
) {
2140 mLanguage
= do_GetAtom(language
);
2142 // we didn't find a (usable) Content-Language, so we fall back
2143 // to whatever the presContext guessed from the charset
2144 mLanguage
= aPresContext
->GetLanguageFromCharset();
2147 mVisible
= NS_STYLE_VISIBILITY_VISIBLE
;
2148 mPointerEvents
= NS_STYLE_POINTER_EVENTS_AUTO
;
2151 nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility
& aSource
)
2153 MOZ_COUNT_CTOR(nsStyleVisibility
);
2154 mDirection
= aSource
.mDirection
;
2155 mVisible
= aSource
.mVisible
;
2156 mLanguage
= aSource
.mLanguage
;
2157 mPointerEvents
= aSource
.mPointerEvents
;
2160 nsChangeHint
nsStyleVisibility::CalcDifference(const nsStyleVisibility
& aOther
) const
2162 nsChangeHint hint
= nsChangeHint(0);
2164 if (mDirection
!= aOther
.mDirection
) {
2165 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
2166 } else if (mLanguage
== aOther
.mLanguage
) {
2167 if (mVisible
!= aOther
.mVisible
) {
2168 if ((NS_STYLE_VISIBILITY_COLLAPSE
== mVisible
) ||
2169 (NS_STYLE_VISIBILITY_COLLAPSE
== aOther
.mVisible
)) {
2170 NS_UpdateHint(hint
, NS_STYLE_HINT_REFLOW
);
2172 NS_UpdateHint(hint
, NS_STYLE_HINT_VISUAL
);
2176 NS_UpdateHint(hint
, NS_STYLE_HINT_REFLOW
);
2183 nsChangeHint
nsStyleVisibility::MaxDifference()
2185 return NS_STYLE_HINT_FRAMECHANGE
;
2189 nsStyleContentData::~nsStyleContentData()
2191 NS_ABORT_IF_FALSE(!mImageTracked
,
2192 "nsStyleContentData being destroyed while still tracking image!");
2193 if (mType
== eStyleContentType_Image
) {
2194 NS_IF_RELEASE(mContent
.mImage
);
2195 } else if (mType
== eStyleContentType_Counter
||
2196 mType
== eStyleContentType_Counters
) {
2197 mContent
.mCounters
->Release();
2198 } else if (mContent
.mString
) {
2199 NS_Free(mContent
.mString
);
2203 nsStyleContentData
& nsStyleContentData::operator=(const nsStyleContentData
& aOther
)
2205 if (this == &aOther
)
2207 this->~nsStyleContentData();
2208 new (this) nsStyleContentData();
2210 mType
= aOther
.mType
;
2211 if (mType
== eStyleContentType_Image
) {
2212 mContent
.mImage
= aOther
.mContent
.mImage
;
2213 NS_IF_ADDREF(mContent
.mImage
);
2214 } else if (mType
== eStyleContentType_Counter
||
2215 mType
== eStyleContentType_Counters
) {
2216 mContent
.mCounters
= aOther
.mContent
.mCounters
;
2217 mContent
.mCounters
->AddRef();
2218 } else if (aOther
.mContent
.mString
) {
2219 mContent
.mString
= NS_strdup(aOther
.mContent
.mString
);
2221 mContent
.mString
= nsnull
;
2226 PRBool
nsStyleContentData::operator==(const nsStyleContentData
& aOther
) const
2228 if (mType
!= aOther
.mType
)
2230 if (mType
== eStyleContentType_Image
) {
2231 if (!mContent
.mImage
|| !aOther
.mContent
.mImage
)
2232 return mContent
.mImage
== aOther
.mContent
.mImage
;
2234 nsCOMPtr
<nsIURI
> thisURI
, otherURI
;
2235 mContent
.mImage
->GetURI(getter_AddRefs(thisURI
));
2236 aOther
.mContent
.mImage
->GetURI(getter_AddRefs(otherURI
));
2237 return thisURI
== otherURI
|| // handles null==null
2238 (thisURI
&& otherURI
&&
2239 NS_SUCCEEDED(thisURI
->Equals(otherURI
, &eq
)) &&
2242 if (mType
== eStyleContentType_Counter
||
2243 mType
== eStyleContentType_Counters
)
2244 return *mContent
.mCounters
== *aOther
.mContent
.mCounters
;
2245 return nsCRT::strcmp(mContent
.mString
, aOther
.mContent
.mString
) == 0;
2249 nsStyleContentData::TrackImage(nsPresContext
* aContext
)
2252 NS_ABORT_IF_FALSE(!mImageTracked
, "Already tracking image!");
2253 NS_ABORT_IF_FALSE(mType
== eStyleContentType_Image
,
2254 "Tryingto do image tracking on non-image!");
2255 NS_ABORT_IF_FALSE(mContent
.mImage
,
2256 "Can't track image when there isn't one!");
2258 // Register the image with the document
2259 nsIDocument
* doc
= aContext
->Document();
2261 doc
->AddImage(mContent
.mImage
);
2265 mImageTracked
= true;
2270 nsStyleContentData::UntrackImage(nsPresContext
* aContext
)
2273 NS_ABORT_IF_FALSE(mImageTracked
, "Image not tracked!");
2274 NS_ABORT_IF_FALSE(mType
== eStyleContentType_Image
,
2275 "Trying to do image tracking on non-image!");
2276 NS_ABORT_IF_FALSE(mContent
.mImage
,
2277 "Can't untrack image when there isn't one!");
2279 // Unregister the image with the document
2280 nsIDocument
* doc
= aContext
->Document();
2282 doc
->RemoveImage(mContent
.mImage
);
2286 mImageTracked
= false;
2291 //-----------------------
2295 nsStyleContent::nsStyleContent(void)
2298 mIncrements(nsnull
),
2304 MOZ_COUNT_CTOR(nsStyleContent
);
2305 mMarkerOffset
.SetAutoValue();
2308 nsStyleContent::~nsStyleContent(void)
2310 MOZ_COUNT_DTOR(nsStyleContent
);
2311 DELETE_ARRAY_IF(mContents
);
2312 DELETE_ARRAY_IF(mIncrements
);
2313 DELETE_ARRAY_IF(mResets
);
2317 nsStyleContent::Destroy(nsPresContext
* aContext
)
2319 // Unregister any images we might have with the document.
2320 for (PRUint32 i
= 0; i
< mContentCount
; ++i
) {
2321 if ((mContents
[i
].mType
== eStyleContentType_Image
) &&
2322 mContents
[i
].mContent
.mImage
) {
2323 mContents
[i
].UntrackImage(aContext
);
2327 this->~nsStyleContent();
2328 aContext
->FreeToShell(sizeof(nsStyleContent
), this);
2331 nsStyleContent::nsStyleContent(const nsStyleContent
& aSource
)
2334 mIncrements(nsnull
),
2341 MOZ_COUNT_CTOR(nsStyleContent
);
2342 mMarkerOffset
= aSource
.mMarkerOffset
;
2345 if (NS_SUCCEEDED(AllocateContents(aSource
.ContentCount()))) {
2346 for (index
= 0; index
< mContentCount
; index
++) {
2347 ContentAt(index
) = aSource
.ContentAt(index
);
2351 if (NS_SUCCEEDED(AllocateCounterIncrements(aSource
.CounterIncrementCount()))) {
2352 for (index
= 0; index
< mIncrementCount
; index
++) {
2353 const nsStyleCounterData
*data
= aSource
.GetCounterIncrementAt(index
);
2354 mIncrements
[index
].mCounter
= data
->mCounter
;
2355 mIncrements
[index
].mValue
= data
->mValue
;
2359 if (NS_SUCCEEDED(AllocateCounterResets(aSource
.CounterResetCount()))) {
2360 for (index
= 0; index
< mResetCount
; index
++) {
2361 const nsStyleCounterData
*data
= aSource
.GetCounterResetAt(index
);
2362 mResets
[index
].mCounter
= data
->mCounter
;
2363 mResets
[index
].mValue
= data
->mValue
;
2368 nsChangeHint
nsStyleContent::CalcDifference(const nsStyleContent
& aOther
) const
2370 // In ReResolveStyleContext we assume that if there's no existing
2371 // ::before or ::after and we don't have to restyle children of the
2372 // node then we can't end up with a ::before or ::after due to the
2373 // restyle of the node itself. That's not quite true, but the only
2374 // exception to the above is when the 'content' property of the node
2375 // changes and the pseudo-element inherits the changed value. Since
2376 // the code here triggers a frame change on the node in that case,
2377 // the optimization in ReResolveStyleContext is ok. But if we ever
2378 // change this code to not reconstruct frames on changes to the
2379 // 'content' property, then we will need to revisit the optimization
2380 // in ReResolveStyleContext.
2382 if (mContentCount
!= aOther
.mContentCount
||
2383 mIncrementCount
!= aOther
.mIncrementCount
||
2384 mResetCount
!= aOther
.mResetCount
) {
2385 return NS_STYLE_HINT_FRAMECHANGE
;
2388 PRUint32 ix
= mContentCount
;
2390 if (mContents
[ix
] != aOther
.mContents
[ix
]) {
2391 // Unfortunately we need to reframe here; a simple reflow
2392 // will not pick up different text or different image URLs,
2393 // since we set all that up in the CSSFrameConstructor
2394 return NS_STYLE_HINT_FRAMECHANGE
;
2397 ix
= mIncrementCount
;
2399 if ((mIncrements
[ix
].mValue
!= aOther
.mIncrements
[ix
].mValue
) ||
2400 (mIncrements
[ix
].mCounter
!= aOther
.mIncrements
[ix
].mCounter
)) {
2401 return NS_STYLE_HINT_FRAMECHANGE
;
2406 if ((mResets
[ix
].mValue
!= aOther
.mResets
[ix
].mValue
) ||
2407 (mResets
[ix
].mCounter
!= aOther
.mResets
[ix
].mCounter
)) {
2408 return NS_STYLE_HINT_FRAMECHANGE
;
2411 if (mMarkerOffset
!= aOther
.mMarkerOffset
) {
2412 return NS_STYLE_HINT_REFLOW
;
2414 return NS_STYLE_HINT_NONE
;
2419 nsChangeHint
nsStyleContent::MaxDifference()
2421 return NS_STYLE_HINT_FRAMECHANGE
;
2425 nsresult
nsStyleContent::AllocateContents(PRUint32 aCount
)
2427 // We need to run the destructors of the elements of mContents, so we
2428 // delete and reallocate even if aCount == mContentCount. (If
2429 // nsStyleContentData had its members private and managed their
2430 // ownership on setting, we wouldn't need this, but that seems
2431 // unnecessary at this point.)
2432 DELETE_ARRAY_IF(mContents
);
2434 mContents
= new nsStyleContentData
[aCount
];
2437 return NS_ERROR_OUT_OF_MEMORY
;
2440 mContentCount
= aCount
;
2444 // ---------------------
2448 nsStyleQuotes::nsStyleQuotes(void)
2452 MOZ_COUNT_CTOR(nsStyleQuotes
);
2456 nsStyleQuotes::~nsStyleQuotes(void)
2458 MOZ_COUNT_DTOR(nsStyleQuotes
);
2459 DELETE_ARRAY_IF(mQuotes
);
2462 nsStyleQuotes::nsStyleQuotes(const nsStyleQuotes
& aSource
)
2466 MOZ_COUNT_CTOR(nsStyleQuotes
);
2471 nsStyleQuotes::SetInitial()
2473 // The initial value for quotes is the en-US typographic convention:
2474 // outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
2475 // with LEFT and RIGHT SINGLE QUOTATION MARK.
2476 static const PRUnichar initialQuotes
[8] = {
2477 0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
2480 if (NS_SUCCEEDED(AllocateQuotes(2))) {
2482 nsDependentString(&initialQuotes
[0], 1),
2483 nsDependentString(&initialQuotes
[2], 1));
2485 nsDependentString(&initialQuotes
[4], 1),
2486 nsDependentString(&initialQuotes
[6], 1));
2491 nsStyleQuotes::CopyFrom(const nsStyleQuotes
& aSource
)
2493 if (NS_SUCCEEDED(AllocateQuotes(aSource
.QuotesCount()))) {
2494 PRUint32 count
= (mQuotesCount
* 2);
2495 for (PRUint32 index
= 0; index
< count
; index
+= 2) {
2496 aSource
.GetQuotesAt(index
, mQuotes
[index
], mQuotes
[index
+ 1]);
2501 nsChangeHint
nsStyleQuotes::CalcDifference(const nsStyleQuotes
& aOther
) const
2503 // If the quotes implementation is ever going to change we might not need
2504 // a framechange here and a reflow should be sufficient. See bug 35768.
2505 if (mQuotesCount
== aOther
.mQuotesCount
) {
2506 PRUint32 ix
= (mQuotesCount
* 2);
2508 if (mQuotes
[ix
] != aOther
.mQuotes
[ix
]) {
2509 return NS_STYLE_HINT_FRAMECHANGE
;
2513 return NS_STYLE_HINT_NONE
;
2515 return NS_STYLE_HINT_FRAMECHANGE
;
2520 nsChangeHint
nsStyleQuotes::MaxDifference()
2522 return NS_STYLE_HINT_FRAMECHANGE
;
2526 // --------------------
2530 nsStyleTextReset::nsStyleTextReset(void)
2532 MOZ_COUNT_CTOR(nsStyleTextReset
);
2533 mVerticalAlign
.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE
, eStyleUnit_Enumerated
);
2534 mTextDecoration
= NS_STYLE_TEXT_DECORATION_NONE
;
2535 mUnicodeBidi
= NS_STYLE_UNICODE_BIDI_NORMAL
;
2538 nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset
& aSource
)
2540 MOZ_COUNT_CTOR(nsStyleTextReset
);
2541 memcpy((nsStyleTextReset
*)this, &aSource
, sizeof(nsStyleTextReset
));
2544 nsStyleTextReset::~nsStyleTextReset(void)
2546 MOZ_COUNT_DTOR(nsStyleTextReset
);
2549 nsChangeHint
nsStyleTextReset::CalcDifference(const nsStyleTextReset
& aOther
) const
2551 if (mVerticalAlign
== aOther
.mVerticalAlign
2552 && mUnicodeBidi
== aOther
.mUnicodeBidi
) {
2553 if (mTextDecoration
!= aOther
.mTextDecoration
) {
2554 // Reflow for blink changes, repaint for others
2556 (mTextDecoration
& NS_STYLE_TEXT_DECORATION_BLINK
) ==
2557 (aOther
.mTextDecoration
& NS_STYLE_TEXT_DECORATION_BLINK
) ?
2558 NS_STYLE_HINT_VISUAL
: NS_STYLE_HINT_REFLOW
;
2561 return NS_STYLE_HINT_NONE
;
2563 return NS_STYLE_HINT_REFLOW
;
2568 nsChangeHint
nsStyleTextReset::MaxDifference()
2570 return NS_STYLE_HINT_REFLOW
;
2574 // Allowed to return one of NS_STYLE_HINT_NONE, NS_STYLE_HINT_REFLOW
2575 // or NS_STYLE_HINT_VISUAL. Currently we just return NONE or REFLOW, though.
2576 // XXXbz can this not return a more specific hint? If that's ever
2577 // changed, nsStyleBorder::CalcDifference will need changing too.
2579 CalcShadowDifference(nsCSSShadowArray
* lhs
,
2580 nsCSSShadowArray
* rhs
)
2583 return NS_STYLE_HINT_NONE
;
2585 if (!lhs
|| !rhs
|| lhs
->Length() != rhs
->Length())
2586 return NS_STYLE_HINT_REFLOW
;
2588 for (PRUint32 i
= 0; i
< lhs
->Length(); ++i
) {
2589 if (*lhs
->ShadowAt(i
) != *rhs
->ShadowAt(i
))
2590 return NS_STYLE_HINT_REFLOW
;
2592 return NS_STYLE_HINT_NONE
;
2595 // --------------------
2599 nsStyleText::nsStyleText(void)
2601 MOZ_COUNT_CTOR(nsStyleText
);
2602 mTextAlign
= NS_STYLE_TEXT_ALIGN_DEFAULT
;
2603 mTextTransform
= NS_STYLE_TEXT_TRANSFORM_NONE
;
2604 mWhiteSpace
= NS_STYLE_WHITESPACE_NORMAL
;
2605 mWordWrap
= NS_STYLE_WORDWRAP_NORMAL
;
2607 mLetterSpacing
.SetNormalValue();
2608 mLineHeight
.SetNormalValue();
2609 mTextIndent
.SetCoordValue(0);
2612 mTextShadow
= nsnull
;
2613 mTabSize
= NS_STYLE_TABSIZE_INITIAL
;
2616 nsStyleText::nsStyleText(const nsStyleText
& aSource
)
2617 : mTextAlign(aSource
.mTextAlign
),
2618 mTextTransform(aSource
.mTextTransform
),
2619 mWhiteSpace(aSource
.mWhiteSpace
),
2620 mWordWrap(aSource
.mWordWrap
),
2621 mTabSize(aSource
.mTabSize
),
2622 mLetterSpacing(aSource
.mLetterSpacing
),
2623 mLineHeight(aSource
.mLineHeight
),
2624 mTextIndent(aSource
.mTextIndent
),
2625 mWordSpacing(aSource
.mWordSpacing
),
2626 mTextShadow(aSource
.mTextShadow
)
2628 MOZ_COUNT_CTOR(nsStyleText
);
2631 nsStyleText::~nsStyleText(void)
2633 MOZ_COUNT_DTOR(nsStyleText
);
2636 nsChangeHint
nsStyleText::CalcDifference(const nsStyleText
& aOther
) const
2638 if (NewlineIsSignificant() != aOther
.NewlineIsSignificant()) {
2639 // This may require construction of suppressed text frames
2640 return NS_STYLE_HINT_FRAMECHANGE
;
2643 if ((mTextAlign
!= aOther
.mTextAlign
) ||
2644 (mTextTransform
!= aOther
.mTextTransform
) ||
2645 (mWhiteSpace
!= aOther
.mWhiteSpace
) ||
2646 (mWordWrap
!= aOther
.mWordWrap
) ||
2647 (mLetterSpacing
!= aOther
.mLetterSpacing
) ||
2648 (mLineHeight
!= aOther
.mLineHeight
) ||
2649 (mTextIndent
!= aOther
.mTextIndent
) ||
2650 (mWordSpacing
!= aOther
.mWordSpacing
) ||
2651 (mTabSize
!= aOther
.mTabSize
))
2652 return NS_STYLE_HINT_REFLOW
;
2654 return CalcShadowDifference(mTextShadow
, aOther
.mTextShadow
);
2659 nsChangeHint
nsStyleText::MaxDifference()
2661 return NS_STYLE_HINT_FRAMECHANGE
;
2665 //-----------------------
2666 // nsStyleUserInterface
2669 nsCursorImage::nsCursorImage()
2670 : mHaveHotspot(PR_FALSE
)
2676 nsCursorImage::nsCursorImage(const nsCursorImage
& aOther
)
2677 : mHaveHotspot(aOther
.mHaveHotspot
)
2678 , mHotspotX(aOther
.mHotspotX
)
2679 , mHotspotY(aOther
.mHotspotY
)
2681 SetImage(aOther
.GetImage());
2684 nsCursorImage::~nsCursorImage()
2690 nsCursorImage::operator=(const nsCursorImage
& aOther
)
2692 if (this != &aOther
) {
2693 mHaveHotspot
= aOther
.mHaveHotspot
;
2694 mHotspotX
= aOther
.mHotspotX
;
2695 mHotspotY
= aOther
.mHotspotY
;
2696 SetImage(aOther
.GetImage());
2702 nsStyleUserInterface::nsStyleUserInterface(void)
2704 MOZ_COUNT_CTOR(nsStyleUserInterface
);
2705 mUserInput
= NS_STYLE_USER_INPUT_AUTO
;
2706 mUserModify
= NS_STYLE_USER_MODIFY_READ_ONLY
;
2707 mUserFocus
= NS_STYLE_USER_FOCUS_NONE
;
2709 mCursor
= NS_STYLE_CURSOR_AUTO
; // fix for bugzilla bug 51113
2711 mCursorArrayLength
= 0;
2712 mCursorArray
= nsnull
;
2715 nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface
& aSource
) :
2716 mUserInput(aSource
.mUserInput
),
2717 mUserModify(aSource
.mUserModify
),
2718 mUserFocus(aSource
.mUserFocus
),
2719 mCursor(aSource
.mCursor
)
2721 MOZ_COUNT_CTOR(nsStyleUserInterface
);
2722 CopyCursorArrayFrom(aSource
);
2725 nsStyleUserInterface::~nsStyleUserInterface(void)
2727 MOZ_COUNT_DTOR(nsStyleUserInterface
);
2728 delete [] mCursorArray
;
2731 nsChangeHint
nsStyleUserInterface::CalcDifference(const nsStyleUserInterface
& aOther
) const
2733 nsChangeHint hint
= nsChangeHint(0);
2734 if (mCursor
!= aOther
.mCursor
)
2735 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
2737 // We could do better. But it wouldn't be worth it, URL-specified cursors are
2739 if (mCursorArrayLength
> 0 || aOther
.mCursorArrayLength
> 0)
2740 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
2742 if (mUserModify
!= aOther
.mUserModify
)
2743 NS_UpdateHint(hint
, NS_STYLE_HINT_VISUAL
);
2745 if ((mUserInput
!= aOther
.mUserInput
) &&
2746 ((NS_STYLE_USER_INPUT_NONE
== mUserInput
) ||
2747 (NS_STYLE_USER_INPUT_NONE
== aOther
.mUserInput
))) {
2748 NS_UpdateHint(hint
, NS_STYLE_HINT_FRAMECHANGE
);
2751 // ignore mUserFocus
2758 nsChangeHint
nsStyleUserInterface::MaxDifference()
2760 return nsChangeHint(nsChangeHint_UpdateCursor
| NS_STYLE_HINT_FRAMECHANGE
);
2765 nsStyleUserInterface::CopyCursorArrayFrom(const nsStyleUserInterface
& aSource
)
2767 mCursorArray
= nsnull
;
2768 mCursorArrayLength
= 0;
2769 if (aSource
.mCursorArrayLength
) {
2770 mCursorArray
= new nsCursorImage
[aSource
.mCursorArrayLength
];
2772 mCursorArrayLength
= aSource
.mCursorArrayLength
;
2773 for (PRUint32 i
= 0; i
< mCursorArrayLength
; ++i
)
2774 mCursorArray
[i
] = aSource
.mCursorArray
[i
];
2779 //-----------------------
2783 nsStyleUIReset::nsStyleUIReset(void)
2785 MOZ_COUNT_CTOR(nsStyleUIReset
);
2786 mUserSelect
= NS_STYLE_USER_SELECT_AUTO
;
2787 mForceBrokenImageIcon
= 0;
2788 mIMEMode
= NS_STYLE_IME_MODE_AUTO
;
2789 mWindowShadow
= NS_STYLE_WINDOW_SHADOW_DEFAULT
;
2792 nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset
& aSource
)
2794 MOZ_COUNT_CTOR(nsStyleUIReset
);
2795 mUserSelect
= aSource
.mUserSelect
;
2796 mForceBrokenImageIcon
= aSource
.mForceBrokenImageIcon
;
2797 mIMEMode
= aSource
.mIMEMode
;
2798 mWindowShadow
= aSource
.mWindowShadow
;
2801 nsStyleUIReset::~nsStyleUIReset(void)
2803 MOZ_COUNT_DTOR(nsStyleUIReset
);
2806 nsChangeHint
nsStyleUIReset::CalcDifference(const nsStyleUIReset
& aOther
) const
2809 if (mForceBrokenImageIcon
!= aOther
.mForceBrokenImageIcon
)
2810 return NS_STYLE_HINT_FRAMECHANGE
;
2811 if (mWindowShadow
!= aOther
.mWindowShadow
) {
2812 // We really need just an nsChangeHint_SyncFrameView, except
2813 // on an ancestor of the frame, so we get that by doing a
2815 return NS_STYLE_HINT_REFLOW
;
2817 if (mUserSelect
!= aOther
.mUserSelect
)
2818 return NS_STYLE_HINT_VISUAL
;
2819 return NS_STYLE_HINT_NONE
;
2824 nsChangeHint
nsStyleUIReset::MaxDifference()
2826 return NS_STYLE_HINT_FRAMECHANGE
;