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>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
42 * structs that contain the data provided by nsStyleContext, the
43 * internal API for computed style data for an element
46 #include "nsStyleStruct.h"
47 #include "nsStyleStructInlines.h"
48 #include "nsStyleConsts.h"
49 #include "nsThemeConstants.h"
51 #include "nsPresContext.h"
52 #include "nsIDeviceContext.h"
53 #include "nsIStyleRule.h"
57 #include "nsIPresShell.h"
59 #include "nsHTMLReflowState.h"
62 #include "nsBidiUtils.h"
64 #include "imgIRequest.h"
67 // Make sure we have enough bits in NS_STYLE_INHERIT_MASK.
68 PR_STATIC_ASSERT((((1 << nsStyleStructID_Length
) - 1) &
69 ~(NS_STYLE_INHERIT_MASK
)) == 0);
71 inline PRBool
IsFixedUnit(nsStyleUnit aUnit
, PRBool aEnumOK
)
73 return PRBool((aUnit
== eStyleUnit_Coord
) ||
74 (aEnumOK
&& (aUnit
== eStyleUnit_Enumerated
)));
77 static PRBool
EqualURIs(nsIURI
*aURI1
, nsIURI
*aURI2
)
80 return aURI1
== aURI2
|| // handle null==null, and optimize
82 NS_SUCCEEDED(aURI1
->Equals(aURI2
, &eq
)) && // not equal on fail
86 static PRBool
EqualURIs(nsCSSValue::URL
*aURI1
, nsCSSValue::URL
*aURI2
)
88 return aURI1
== aURI2
|| // handle null==null, and optimize
89 (aURI1
&& aURI2
&& aURI1
->URIEquals(*aURI2
));
92 static PRBool
EqualImages(imgIRequest
*aImage1
, imgIRequest
* aImage2
)
94 if (aImage1
== aImage2
) {
98 if (!aImage1
|| !aImage2
) {
102 nsCOMPtr
<nsIURI
> uri1
, uri2
;
103 aImage1
->GetURI(getter_AddRefs(uri1
));
104 aImage2
->GetURI(getter_AddRefs(uri2
));
105 return EqualURIs(uri1
, uri2
);
108 static nsChangeHint
CalcShadowDifference(nsCSSShadowArray
* lhs
,
109 nsCSSShadowArray
* rhs
);
111 // --------------------
114 nsStyleFont::nsStyleFont(const nsFont
& aFont
, nsPresContext
*aPresContext
)
116 mGenericID(kGenericFont_NONE
)
118 mSize
= mFont
.size
= nsStyleFont::ZoomText(aPresContext
, mFont
.size
);
120 mScriptUnconstrainedSize
= mSize
;
121 mScriptMinSize
= aPresContext
->TwipsToAppUnits(
122 NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT
));
124 mScriptSizeMultiplier
= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER
;
128 nsStyleFont::nsStyleFont(const nsStyleFont
& aSrc
)
131 , mGenericID(aSrc
.mGenericID
)
133 , mScriptLevel(aSrc
.mScriptLevel
)
134 , mScriptUnconstrainedSize(aSrc
.mScriptUnconstrainedSize
)
135 , mScriptMinSize(aSrc
.mScriptMinSize
)
136 , mScriptSizeMultiplier(aSrc
.mScriptSizeMultiplier
)
141 nsStyleFont::nsStyleFont(nsPresContext
* aPresContext
)
142 : mFont(*(aPresContext
->GetDefaultFont(kPresContext_DefaultVariableFont_ID
))),
143 mGenericID(kGenericFont_NONE
)
145 mSize
= mFont
.size
= nsStyleFont::ZoomText(aPresContext
, mFont
.size
);
147 mScriptUnconstrainedSize
= mSize
;
148 mScriptMinSize
= aPresContext
->TwipsToAppUnits(
149 NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT
));
151 mScriptSizeMultiplier
= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER
;
156 nsStyleFont::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
157 void* result
= aContext
->AllocateFromShell(sz
);
159 memset(result
, 0, sz
);
164 nsStyleFont::Destroy(nsPresContext
* aContext
) {
165 this->~nsStyleFont();
166 aContext
->FreeToShell(sizeof(nsStyleFont
), this);
169 nsChangeHint
nsStyleFont::CalcDifference(const nsStyleFont
& aOther
) const
171 if (mSize
== aOther
.mSize
) {
172 return CalcFontDifference(mFont
, aOther
.mFont
);
174 return NS_STYLE_HINT_REFLOW
;
179 nsChangeHint
nsStyleFont::MaxDifference()
181 return NS_STYLE_HINT_REFLOW
;
186 nsStyleFont::ZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
188 return nscoord(float(aSize
) * aPresContext
->TextZoom());
192 nsStyleFont::UnZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
194 return nscoord(float(aSize
) / aPresContext
->TextZoom());
197 nsChangeHint
nsStyleFont::CalcFontDifference(const nsFont
& aFont1
, const nsFont
& aFont2
)
199 if ((aFont1
.size
== aFont2
.size
) &&
200 (aFont1
.sizeAdjust
== aFont2
.sizeAdjust
) &&
201 (aFont1
.style
== aFont2
.style
) &&
202 (aFont1
.variant
== aFont2
.variant
) &&
203 (aFont1
.familyNameQuirks
== aFont2
.familyNameQuirks
) &&
204 (aFont1
.weight
== aFont2
.weight
) &&
205 (aFont1
.name
== aFont2
.name
)) {
206 if ((aFont1
.decorations
== aFont2
.decorations
)) {
207 return NS_STYLE_HINT_NONE
;
209 return NS_STYLE_HINT_VISUAL
;
211 return NS_STYLE_HINT_REFLOW
;
214 static PRBool
IsFixedData(const nsStyleSides
& aSides
, PRBool aEnumOK
)
216 NS_FOR_CSS_SIDES(side
) {
217 if (!IsFixedUnit(aSides
.GetUnit(side
), aEnumOK
))
223 static nscoord
CalcCoord(const nsStyleCoord
& aCoord
,
224 const nscoord
* aEnumTable
,
227 switch (aCoord
.GetUnit()) {
228 case eStyleUnit_Coord
:
229 return aCoord
.GetCoordValue();
230 case eStyleUnit_Enumerated
:
231 if (nsnull
!= aEnumTable
) {
232 PRInt32 value
= aCoord
.GetIntValue();
233 if ((0 <= value
) && (value
< aNumEnums
)) {
234 return aEnumTable
[aCoord
.GetIntValue()];
239 NS_ERROR("bad unit type");
245 nsStyleMargin::nsStyleMargin() {
246 nsStyleCoord
zero(0);
247 NS_FOR_CSS_SIDES(side
) {
248 mMargin
.Set(side
, zero
);
250 mHasCachedMargin
= PR_FALSE
;
253 nsStyleMargin::nsStyleMargin(const nsStyleMargin
& aSrc
) {
254 mMargin
= aSrc
.mMargin
;
255 mHasCachedMargin
= PR_FALSE
;
259 nsStyleMargin::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
260 void* result
= aContext
->AllocateFromShell(sz
);
262 memset(result
, 0, sz
);
267 nsStyleMargin::Destroy(nsPresContext
* aContext
) {
268 this->~nsStyleMargin();
269 aContext
->FreeToShell(sizeof(nsStyleMargin
), this);
273 void nsStyleMargin::RecalcData()
275 if (IsFixedData(mMargin
, PR_FALSE
)) {
276 NS_FOR_CSS_SIDES(side
) {
277 mCachedMargin
.side(side
) = CalcCoord(mMargin
.Get(side
), nsnull
, 0);
279 mHasCachedMargin
= PR_TRUE
;
282 mHasCachedMargin
= PR_FALSE
;
285 nsChangeHint
nsStyleMargin::CalcDifference(const nsStyleMargin
& aOther
) const
287 if (mMargin
== aOther
.mMargin
) {
288 return NS_STYLE_HINT_NONE
;
290 return NS_STYLE_HINT_REFLOW
;
295 nsChangeHint
nsStyleMargin::MaxDifference()
297 return NS_STYLE_HINT_REFLOW
;
301 nsStylePadding::nsStylePadding() {
302 nsStyleCoord
zero(0);
303 NS_FOR_CSS_SIDES(side
) {
304 mPadding
.Set(side
, zero
);
306 mHasCachedPadding
= PR_FALSE
;
309 nsStylePadding::nsStylePadding(const nsStylePadding
& aSrc
) {
310 mPadding
= aSrc
.mPadding
;
311 mHasCachedPadding
= PR_FALSE
;
315 nsStylePadding::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
316 void* result
= aContext
->AllocateFromShell(sz
);
318 memset(result
, 0, sz
);
323 nsStylePadding::Destroy(nsPresContext
* aContext
) {
324 this->~nsStylePadding();
325 aContext
->FreeToShell(sizeof(nsStylePadding
), this);
328 void nsStylePadding::RecalcData()
330 if (IsFixedData(mPadding
, PR_FALSE
)) {
331 NS_FOR_CSS_SIDES(side
) {
332 mCachedPadding
.side(side
) = CalcCoord(mPadding
.Get(side
), nsnull
, 0);
334 mHasCachedPadding
= PR_TRUE
;
337 mHasCachedPadding
= PR_FALSE
;
340 nsChangeHint
nsStylePadding::CalcDifference(const nsStylePadding
& aOther
) const
342 if (mPadding
== aOther
.mPadding
) {
343 return NS_STYLE_HINT_NONE
;
345 return NS_STYLE_HINT_REFLOW
;
350 nsChangeHint
nsStylePadding::MaxDifference()
352 return NS_STYLE_HINT_REFLOW
;
356 nsStyleBorder::nsStyleBorder(nsPresContext
* aPresContext
)
357 : mHaveBorderImageWidth(PR_FALSE
),
358 mComputedBorder(0, 0, 0, 0),
362 (aPresContext
->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM
];
363 NS_FOR_CSS_SIDES(side
) {
364 mBorder
.side(side
) = medium
;
365 mBorderStyle
[side
] = NS_STYLE_BORDER_STYLE_NONE
| BORDER_COLOR_FOREGROUND
;
366 mBorderColor
[side
] = NS_RGB(0, 0, 0);
368 NS_FOR_CSS_HALF_CORNERS(corner
) {
369 mBorderRadius
.Set(corner
, nsStyleCoord(0));
372 mBorderColors
= nsnull
;
375 mFloatEdge
= NS_STYLE_FLOAT_EDGE_CONTENT
;
377 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
380 nsBorderColors::~nsBorderColors()
382 NS_CSS_DELETE_LIST_MEMBER(nsBorderColors
, this, mNext
);
386 nsBorderColors::Clone(PRBool aDeep
) const
388 nsBorderColors
* result
= new nsBorderColors(mColor
);
389 if (NS_UNLIKELY(!result
))
392 NS_CSS_CLONE_LIST_MEMBER(nsBorderColors
, this, mNext
, result
, (PR_FALSE
));
396 nsStyleBorder::nsStyleBorder(const nsStyleBorder
& aSrc
)
397 : mBorderRadius(aSrc
.mBorderRadius
),
398 mBorderImageSplit(aSrc
.mBorderImageSplit
),
399 mFloatEdge(aSrc
.mFloatEdge
),
400 mBorderImageHFill(aSrc
.mBorderImageHFill
),
401 mBorderImageVFill(aSrc
.mBorderImageVFill
),
402 mBorderColors(nsnull
),
403 mBoxShadow(aSrc
.mBoxShadow
),
404 mHaveBorderImageWidth(aSrc
.mHaveBorderImageWidth
),
405 mBorderImageWidth(aSrc
.mBorderImageWidth
),
406 mComputedBorder(aSrc
.mComputedBorder
),
407 mBorder(aSrc
.mBorder
),
408 mBorderImage(aSrc
.mBorderImage
),
409 mTwipsPerPixel(aSrc
.mTwipsPerPixel
)
411 if (aSrc
.mBorderColors
) {
412 EnsureBorderColors();
413 for (PRInt32 i
= 0; i
< 4; i
++)
414 if (aSrc
.mBorderColors
[i
])
415 mBorderColors
[i
] = aSrc
.mBorderColors
[i
]->Clone();
417 mBorderColors
[i
] = nsnull
;
420 NS_FOR_CSS_SIDES(side
) {
421 mBorderStyle
[side
] = aSrc
.mBorderStyle
[side
];
422 mBorderColor
[side
] = aSrc
.mBorderColor
[side
];
424 NS_FOR_CSS_HALF_CORNERS(corner
) {
425 mBorderRadius
.Set(corner
, aSrc
.mBorderRadius
.Get(corner
));
429 nsStyleBorder::~nsStyleBorder()
432 for (PRInt32 i
= 0; i
< 4; i
++)
433 delete mBorderColors
[i
];
434 delete [] mBorderColors
;
439 nsStyleBorder::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
440 void* result
= aContext
->AllocateFromShell(sz
);
442 memset(result
, 0, sz
);
447 nsStyleBorder::Destroy(nsPresContext
* aContext
) {
448 this->~nsStyleBorder();
449 aContext
->FreeToShell(sizeof(nsStyleBorder
), this);
453 nsChangeHint
nsStyleBorder::CalcDifference(const nsStyleBorder
& aOther
) const
455 // Note that differences in mBorder don't affect rendering (which should only
456 // use mComputedBorder), so don't need to be tested for here.
457 if (mTwipsPerPixel
== aOther
.mTwipsPerPixel
&&
458 GetActualBorder() == aOther
.GetActualBorder() &&
459 mFloatEdge
== aOther
.mFloatEdge
) {
460 // Note that mBorderStyle stores not only the border style but also
461 // color-related flags. Given that we've already done an mComputedBorder
462 // comparison, border-style differences can only lead to a VISUAL hint. So
463 // it's OK to just compare the values directly -- if either the actual
464 // style or the color flags differ we want to repaint.
465 NS_FOR_CSS_SIDES(ix
) {
466 if (mBorderStyle
[ix
] != aOther
.mBorderStyle
[ix
] ||
467 mBorderColor
[ix
] != aOther
.mBorderColor
[ix
]) {
468 return NS_STYLE_HINT_VISUAL
;
472 if (mBorderRadius
!= aOther
.mBorderRadius
||
473 !mBorderColors
!= !aOther
.mBorderColors
) {
474 return NS_STYLE_HINT_VISUAL
;
477 if (IsBorderImageLoaded() || aOther
.IsBorderImageLoaded()) {
478 if (mBorderImage
!= aOther
.mBorderImage
||
479 mBorderImageHFill
!= aOther
.mBorderImageHFill
||
480 mBorderImageVFill
!= aOther
.mBorderImageVFill
||
481 mBorderImageSplit
!= aOther
.mBorderImageSplit
) {
482 return NS_STYLE_HINT_VISUAL
;
484 // The call to GetActualBorder above already considered
485 // mBorderImageWidth and mHaveBorderImageWidth.
488 // Note that at this point if mBorderColors is non-null so is
489 // aOther.mBorderColors
491 NS_FOR_CSS_SIDES(ix
) {
492 if (!nsBorderColors::Equal(mBorderColors
[ix
],
493 aOther
.mBorderColors
[ix
])) {
494 return NS_STYLE_HINT_VISUAL
;
499 // Decide what to do with regards to box-shadow
500 return CalcShadowDifference(mBoxShadow
, aOther
.mBoxShadow
);
502 return NS_STYLE_HINT_REFLOW
;
507 nsChangeHint
nsStyleBorder::MaxDifference()
509 return NS_STYLE_HINT_REFLOW
;
514 nsStyleBorder::ImageBorderDiffers() const
516 return mComputedBorder
!=
517 (mHaveBorderImageWidth
? mBorderImageWidth
: mBorder
);
521 nsStyleBorder::GetActualBorder() const
523 if (IsBorderImageLoaded())
524 if (mHaveBorderImageWidth
)
525 return mBorderImageWidth
;
529 return mComputedBorder
;
532 nsStyleOutline::nsStyleOutline(nsPresContext
* aPresContext
)
534 // spacing values not inherited
535 nsStyleCoord
zero(0);
536 NS_FOR_CSS_HALF_CORNERS(corner
) {
537 mOutlineRadius
.Set(corner
, zero
);
542 mOutlineWidth
= nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM
, eStyleUnit_Enumerated
);
543 mOutlineStyle
= NS_STYLE_BORDER_STYLE_NONE
;
544 mOutlineColor
= NS_RGB(0, 0, 0);
546 mHasCachedOutline
= PR_FALSE
;
547 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
550 nsStyleOutline::nsStyleOutline(const nsStyleOutline
& aSrc
) {
551 memcpy((nsStyleOutline
*)this, &aSrc
, sizeof(nsStyleOutline
));
555 nsStyleOutline::RecalcData(nsPresContext
* aContext
)
557 if (NS_STYLE_BORDER_STYLE_NONE
== GetOutlineStyle()) {
558 mCachedOutlineWidth
= 0;
559 mHasCachedOutline
= PR_TRUE
;
560 } else if (IsFixedUnit(mOutlineWidth
.GetUnit(), PR_TRUE
)) {
561 mCachedOutlineWidth
=
562 CalcCoord(mOutlineWidth
, aContext
->GetBorderWidthTable(), 3);
563 mCachedOutlineWidth
=
564 NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth
, mTwipsPerPixel
);
565 mHasCachedOutline
= PR_TRUE
;
568 mHasCachedOutline
= PR_FALSE
;
571 nsChangeHint
nsStyleOutline::CalcDifference(const nsStyleOutline
& aOther
) const
573 PRBool outlineWasVisible
=
574 mCachedOutlineWidth
> 0 && mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
575 PRBool outlineIsVisible
=
576 aOther
.mCachedOutlineWidth
> 0 && aOther
.mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
577 if (outlineWasVisible
!= outlineIsVisible
||
578 (outlineIsVisible
&& (mOutlineOffset
!= aOther
.mOutlineOffset
||
579 mOutlineWidth
!= aOther
.mOutlineWidth
||
580 mTwipsPerPixel
!= aOther
.mTwipsPerPixel
))) {
581 return NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
);
583 if ((mOutlineStyle
!= aOther
.mOutlineStyle
) ||
584 (mOutlineColor
!= aOther
.mOutlineColor
) ||
585 (mOutlineRadius
!= aOther
.mOutlineRadius
)) {
586 return nsChangeHint_RepaintFrame
;
588 return NS_STYLE_HINT_NONE
;
593 nsChangeHint
nsStyleOutline::MaxDifference()
595 return NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
);
599 // --------------------
602 nsStyleList::nsStyleList()
603 : mListStyleType(NS_STYLE_LIST_STYLE_DISC
),
604 mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE
)
608 nsStyleList::~nsStyleList()
612 nsStyleList::nsStyleList(const nsStyleList
& aSource
)
613 : mListStyleType(aSource
.mListStyleType
),
614 mListStylePosition(aSource
.mListStylePosition
),
615 mListStyleImage(aSource
.mListStyleImage
),
616 mImageRegion(aSource
.mImageRegion
)
620 nsChangeHint
nsStyleList::CalcDifference(const nsStyleList
& aOther
) const
622 if (mListStylePosition
!= aOther
.mListStylePosition
)
623 return NS_STYLE_HINT_FRAMECHANGE
;
624 if (EqualImages(mListStyleImage
, aOther
.mListStyleImage
) &&
625 mListStyleType
== aOther
.mListStyleType
) {
626 if (mImageRegion
== aOther
.mImageRegion
)
627 return NS_STYLE_HINT_NONE
;
628 if (mImageRegion
.width
== aOther
.mImageRegion
.width
&&
629 mImageRegion
.height
== aOther
.mImageRegion
.height
)
630 return NS_STYLE_HINT_VISUAL
;
632 return NS_STYLE_HINT_REFLOW
;
637 nsChangeHint
nsStyleList::MaxDifference()
639 return NS_STYLE_HINT_FRAMECHANGE
;
643 // --------------------
646 nsStyleXUL::nsStyleXUL()
648 mBoxAlign
= NS_STYLE_BOX_ALIGN_STRETCH
;
649 mBoxDirection
= NS_STYLE_BOX_DIRECTION_NORMAL
;
651 mBoxOrient
= NS_STYLE_BOX_ORIENT_HORIZONTAL
;
652 mBoxPack
= NS_STYLE_BOX_PACK_START
;
654 mStretchStack
= PR_TRUE
;
657 nsStyleXUL::~nsStyleXUL()
661 nsStyleXUL::nsStyleXUL(const nsStyleXUL
& aSource
)
663 memcpy((nsStyleXUL
*)this, &aSource
, sizeof(nsStyleXUL
));
666 nsChangeHint
nsStyleXUL::CalcDifference(const nsStyleXUL
& aOther
) const
668 if (mBoxAlign
== aOther
.mBoxAlign
&&
669 mBoxDirection
== aOther
.mBoxDirection
&&
670 mBoxFlex
== aOther
.mBoxFlex
&&
671 mBoxOrient
== aOther
.mBoxOrient
&&
672 mBoxPack
== aOther
.mBoxPack
&&
673 mBoxOrdinal
== aOther
.mBoxOrdinal
)
674 return NS_STYLE_HINT_NONE
;
675 if (mBoxOrdinal
!= aOther
.mBoxOrdinal
)
676 return NS_STYLE_HINT_FRAMECHANGE
;
677 return NS_STYLE_HINT_REFLOW
;
682 nsChangeHint
nsStyleXUL::MaxDifference()
684 return NS_STYLE_HINT_FRAMECHANGE
;
688 // --------------------
691 nsStyleColumn::nsStyleColumn(nsPresContext
* aPresContext
)
693 mColumnCount
= NS_STYLE_COLUMN_COUNT_AUTO
;
694 mColumnWidth
.SetAutoValue();
695 mColumnGap
.SetNormalValue();
697 mColumnRuleWidth
= (aPresContext
->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM
];
698 mColumnRuleStyle
= NS_STYLE_BORDER_STYLE_NONE
;
699 mColumnRuleColor
= NS_RGB(0, 0, 0);
700 mColumnRuleColorIsForeground
= PR_TRUE
;
702 mTwipsPerPixel
= aPresContext
->AppUnitsPerDevPixel();
705 nsStyleColumn::~nsStyleColumn()
709 nsStyleColumn::nsStyleColumn(const nsStyleColumn
& aSource
)
711 memcpy((nsStyleColumn
*)this, &aSource
, sizeof(nsStyleColumn
));
714 nsChangeHint
nsStyleColumn::CalcDifference(const nsStyleColumn
& aOther
) const
716 if ((mColumnWidth
.GetUnit() == eStyleUnit_Auto
)
717 != (aOther
.mColumnWidth
.GetUnit() == eStyleUnit_Auto
) ||
718 mColumnCount
!= aOther
.mColumnCount
)
719 // We force column count changes to do a reframe, because it's tricky to handle
720 // some edge cases where the column count gets smaller and content overflows.
722 return NS_STYLE_HINT_FRAMECHANGE
;
724 if (mColumnWidth
!= aOther
.mColumnWidth
||
725 mColumnGap
!= aOther
.mColumnGap
)
726 return NS_STYLE_HINT_REFLOW
;
728 if (GetComputedColumnRuleWidth() != aOther
.GetComputedColumnRuleWidth() ||
729 mColumnRuleStyle
!= aOther
.mColumnRuleStyle
||
730 mColumnRuleColor
!= aOther
.mColumnRuleColor
||
731 mColumnRuleColorIsForeground
!= aOther
.mColumnRuleColorIsForeground
)
732 return NS_STYLE_HINT_VISUAL
;
734 return NS_STYLE_HINT_NONE
;
739 nsChangeHint
nsStyleColumn::MaxDifference()
741 return NS_STYLE_HINT_FRAMECHANGE
;
746 // --------------------
749 nsStyleSVG::nsStyleSVG()
751 mFill
.mType
= eStyleSVGPaintType_Color
;
752 mFill
.mPaint
.mColor
= NS_RGB(0,0,0);
753 mFill
.mFallbackColor
= NS_RGB(0,0,0);
754 mStroke
.mType
= eStyleSVGPaintType_None
;
755 mStroke
.mPaint
.mColor
= NS_RGB(0,0,0);
756 mStroke
.mFallbackColor
= NS_RGB(0,0,0);
757 mStrokeDasharray
= nsnull
;
759 mStrokeDashoffset
.SetCoordValue(0);
760 mStrokeWidth
.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
763 mStrokeMiterlimit
= 4.0f
;
764 mStrokeOpacity
= 1.0f
;
766 mStrokeDasharrayLength
= 0;
767 mClipRule
= NS_STYLE_FILL_RULE_NONZERO
;
768 mColorInterpolation
= NS_STYLE_COLOR_INTERPOLATION_SRGB
;
769 mColorInterpolationFilters
= NS_STYLE_COLOR_INTERPOLATION_LINEARRGB
;
770 mFillRule
= NS_STYLE_FILL_RULE_NONZERO
;
771 mPointerEvents
= NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED
;
772 mShapeRendering
= NS_STYLE_SHAPE_RENDERING_AUTO
;
773 mStrokeLinecap
= NS_STYLE_STROKE_LINECAP_BUTT
;
774 mStrokeLinejoin
= NS_STYLE_STROKE_LINEJOIN_MITER
;
775 mTextAnchor
= NS_STYLE_TEXT_ANCHOR_START
;
776 mTextRendering
= NS_STYLE_TEXT_RENDERING_AUTO
;
779 nsStyleSVG::~nsStyleSVG()
781 delete [] mStrokeDasharray
;
784 nsStyleSVG::nsStyleSVG(const nsStyleSVG
& aSource
)
786 //memcpy((nsStyleSVG*)this, &aSource, sizeof(nsStyleSVG));
788 mFill
= aSource
.mFill
;
789 mStroke
= aSource
.mStroke
;
791 mMarkerEnd
= aSource
.mMarkerEnd
;
792 mMarkerMid
= aSource
.mMarkerMid
;
793 mMarkerStart
= aSource
.mMarkerStart
;
795 mStrokeDasharrayLength
= aSource
.mStrokeDasharrayLength
;
796 if (aSource
.mStrokeDasharray
) {
797 mStrokeDasharray
= new nsStyleCoord
[mStrokeDasharrayLength
];
798 if (mStrokeDasharray
)
799 memcpy(mStrokeDasharray
,
800 aSource
.mStrokeDasharray
,
801 mStrokeDasharrayLength
* sizeof(nsStyleCoord
));
803 mStrokeDasharrayLength
= 0;
805 mStrokeDasharray
= nsnull
;
808 mStrokeDashoffset
= aSource
.mStrokeDashoffset
;
809 mStrokeWidth
= aSource
.mStrokeWidth
;
811 mFillOpacity
= aSource
.mFillOpacity
;
812 mStrokeMiterlimit
= aSource
.mStrokeMiterlimit
;
813 mStrokeOpacity
= aSource
.mStrokeOpacity
;
815 mClipRule
= aSource
.mClipRule
;
816 mColorInterpolation
= aSource
.mColorInterpolation
;
817 mColorInterpolationFilters
= aSource
.mColorInterpolationFilters
;
818 mFillRule
= aSource
.mFillRule
;
819 mPointerEvents
= aSource
.mPointerEvents
;
820 mShapeRendering
= aSource
.mShapeRendering
;
821 mStrokeLinecap
= aSource
.mStrokeLinecap
;
822 mStrokeLinejoin
= aSource
.mStrokeLinejoin
;
823 mTextAnchor
= aSource
.mTextAnchor
;
824 mTextRendering
= aSource
.mTextRendering
;
827 static PRBool
PaintURIChanged(const nsStyleSVGPaint
& aPaint1
,
828 const nsStyleSVGPaint
& aPaint2
)
830 if (aPaint1
.mType
!= aPaint2
.mType
) {
831 return aPaint1
.mType
== eStyleSVGPaintType_Server
||
832 aPaint2
.mType
== eStyleSVGPaintType_Server
;
834 return aPaint1
.mType
== eStyleSVGPaintType_Server
&&
835 !EqualURIs(aPaint1
.mPaint
.mPaintServer
, aPaint2
.mPaint
.mPaintServer
);
838 nsChangeHint
nsStyleSVG::CalcDifference(const nsStyleSVG
& aOther
) const
840 nsChangeHint hint
= nsChangeHint(0);
842 if (mTextRendering
!= aOther
.mTextRendering
) {
843 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
844 // May be needed for non-svg frames
845 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
848 if (mFill
!= aOther
.mFill
||
849 mStroke
!= aOther
.mStroke
) {
850 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
851 if (PaintURIChanged(mFill
, aOther
.mFill
) ||
852 PaintURIChanged(mStroke
, aOther
.mStroke
)) {
853 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
855 // Nothing more to do, below we can only set "repaint"
859 if ( !EqualURIs(mMarkerEnd
, aOther
.mMarkerEnd
) ||
860 !EqualURIs(mMarkerMid
, aOther
.mMarkerMid
) ||
861 !EqualURIs(mMarkerStart
, aOther
.mMarkerStart
) ||
863 mStrokeDashoffset
!= aOther
.mStrokeDashoffset
||
864 mStrokeWidth
!= aOther
.mStrokeWidth
||
866 mFillOpacity
!= aOther
.mFillOpacity
||
867 mStrokeMiterlimit
!= aOther
.mStrokeMiterlimit
||
868 mStrokeOpacity
!= aOther
.mStrokeOpacity
||
870 mClipRule
!= aOther
.mClipRule
||
871 mColorInterpolation
!= aOther
.mColorInterpolation
||
872 mColorInterpolationFilters
!= aOther
.mColorInterpolationFilters
||
873 mFillRule
!= aOther
.mFillRule
||
874 mShapeRendering
!= aOther
.mShapeRendering
||
875 mStrokeDasharrayLength
!= aOther
.mStrokeDasharrayLength
||
876 mStrokeLinecap
!= aOther
.mStrokeLinecap
||
877 mStrokeLinejoin
!= aOther
.mStrokeLinejoin
||
878 mTextAnchor
!= aOther
.mTextAnchor
) {
879 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
883 // length of stroke dasharrays are the same (tested above) - check entries
884 for (PRUint32 i
=0; i
<mStrokeDasharrayLength
; i
++)
885 if (mStrokeDasharray
[i
] != aOther
.mStrokeDasharray
[i
]) {
886 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
895 nsChangeHint
nsStyleSVG::MaxDifference()
897 return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects
,
898 nsChangeHint_ReflowFrame
),
899 nsChangeHint_RepaintFrame
);
903 // --------------------
906 nsStyleSVGReset::nsStyleSVGReset()
908 mStopColor
= NS_RGB(0,0,0);
909 mFloodColor
= NS_RGB(0,0,0);
910 mLightingColor
= NS_RGB(255,255,255);
915 mFloodOpacity
= 1.0f
;
916 mDominantBaseline
= NS_STYLE_DOMINANT_BASELINE_AUTO
;
919 nsStyleSVGReset::~nsStyleSVGReset()
923 nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset
& aSource
)
925 mStopColor
= aSource
.mStopColor
;
926 mFloodColor
= aSource
.mFloodColor
;
927 mLightingColor
= aSource
.mLightingColor
;
928 mClipPath
= aSource
.mClipPath
;
929 mFilter
= aSource
.mFilter
;
930 mMask
= aSource
.mMask
;
931 mStopOpacity
= aSource
.mStopOpacity
;
932 mFloodOpacity
= aSource
.mFloodOpacity
;
933 mDominantBaseline
= aSource
.mDominantBaseline
;
936 nsChangeHint
nsStyleSVGReset::CalcDifference(const nsStyleSVGReset
& aOther
) const
938 nsChangeHint hint
= nsChangeHint(0);
940 if (!EqualURIs(mClipPath
, aOther
.mClipPath
) ||
941 !EqualURIs(mFilter
, aOther
.mFilter
) ||
942 !EqualURIs(mMask
, aOther
.mMask
)) {
943 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
944 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
945 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
946 } else if (mStopColor
!= aOther
.mStopColor
||
947 mFloodColor
!= aOther
.mFloodColor
||
948 mLightingColor
!= aOther
.mLightingColor
||
949 mStopOpacity
!= aOther
.mStopOpacity
||
950 mFloodOpacity
!= aOther
.mFloodOpacity
||
951 mDominantBaseline
!= aOther
.mDominantBaseline
)
952 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
959 nsChangeHint
nsStyleSVGReset::MaxDifference()
961 return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects
,
962 nsChangeHint_ReflowFrame
),
963 nsChangeHint_RepaintFrame
);
967 // nsStyleSVGPaint implementation
968 nsStyleSVGPaint::~nsStyleSVGPaint()
970 if (mType
== eStyleSVGPaintType_Server
) {
971 NS_IF_RELEASE(mPaint
.mPaintServer
);
976 nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType
)
978 if (mType
== eStyleSVGPaintType_Server
) {
979 this->~nsStyleSVGPaint();
980 new (this) nsStyleSVGPaint();
985 nsStyleSVGPaint
& nsStyleSVGPaint::operator=(const nsStyleSVGPaint
& aOther
)
990 SetType(aOther
.mType
);
992 mFallbackColor
= aOther
.mFallbackColor
;
993 if (mType
== eStyleSVGPaintType_Server
) {
994 mPaint
.mPaintServer
= aOther
.mPaint
.mPaintServer
;
995 NS_IF_ADDREF(mPaint
.mPaintServer
);
997 mPaint
.mColor
= aOther
.mPaint
.mColor
;
1002 PRBool
nsStyleSVGPaint::operator==(const nsStyleSVGPaint
& aOther
) const
1004 if (mType
!= aOther
.mType
)
1006 if (mType
== eStyleSVGPaintType_Server
)
1007 return EqualURIs(mPaint
.mPaintServer
, aOther
.mPaint
.mPaintServer
) &&
1008 mFallbackColor
== aOther
.mFallbackColor
;
1009 if (mType
== eStyleSVGPaintType_None
)
1011 return mPaint
.mColor
== aOther
.mPaint
.mColor
;
1017 // --------------------
1020 nsStylePosition::nsStylePosition(void)
1022 // positioning values not inherited
1023 nsStyleCoord
autoCoord(eStyleUnit_Auto
);
1024 mOffset
.SetLeft(autoCoord
);
1025 mOffset
.SetTop(autoCoord
);
1026 mOffset
.SetRight(autoCoord
);
1027 mOffset
.SetBottom(autoCoord
);
1028 mWidth
.SetAutoValue();
1029 mMinWidth
.SetCoordValue(0);
1030 mMaxWidth
.SetNoneValue();
1031 mHeight
.SetAutoValue();
1032 mMinHeight
.SetCoordValue(0);
1033 mMaxHeight
.SetNoneValue();
1034 mBoxSizing
= NS_STYLE_BOX_SIZING_CONTENT
;
1035 mZIndex
.SetAutoValue();
1038 nsStylePosition::~nsStylePosition(void)
1042 nsStylePosition::nsStylePosition(const nsStylePosition
& aSource
)
1044 memcpy((nsStylePosition
*)this, &aSource
, sizeof(nsStylePosition
));
1047 nsChangeHint
nsStylePosition::CalcDifference(const nsStylePosition
& aOther
) const
1049 if (mZIndex
!= aOther
.mZIndex
) {
1050 return NS_STYLE_HINT_REFLOW
;
1053 if ((mOffset
== aOther
.mOffset
) &&
1054 (mWidth
== aOther
.mWidth
) &&
1055 (mMinWidth
== aOther
.mMinWidth
) &&
1056 (mMaxWidth
== aOther
.mMaxWidth
) &&
1057 (mHeight
== aOther
.mHeight
) &&
1058 (mMinHeight
== aOther
.mMinHeight
) &&
1059 (mMaxHeight
== aOther
.mMaxHeight
) &&
1060 (mBoxSizing
== aOther
.mBoxSizing
))
1061 return NS_STYLE_HINT_NONE
;
1063 return nsChangeHint_ReflowFrame
;
1068 nsChangeHint
nsStylePosition::MaxDifference()
1070 return NS_STYLE_HINT_REFLOW
;
1074 // --------------------
1078 nsStyleTable::nsStyleTable()
1080 // values not inherited
1081 mLayoutStrategy
= NS_STYLE_TABLE_LAYOUT_AUTO
;
1082 mCols
= NS_STYLE_TABLE_COLS_NONE
;
1083 mFrame
= NS_STYLE_TABLE_FRAME_NONE
;
1084 mRules
= NS_STYLE_TABLE_RULES_NONE
;
1088 nsStyleTable::~nsStyleTable(void)
1092 nsStyleTable::nsStyleTable(const nsStyleTable
& aSource
)
1094 memcpy((nsStyleTable
*)this, &aSource
, sizeof(nsStyleTable
));
1097 nsChangeHint
nsStyleTable::CalcDifference(const nsStyleTable
& aOther
) const
1099 // Changes in mRules may require reframing (if border-collapse stuff changes, for example).
1100 if (mRules
!= aOther
.mRules
|| mSpan
!= aOther
.mSpan
||
1101 mLayoutStrategy
!= aOther
.mLayoutStrategy
)
1102 return NS_STYLE_HINT_FRAMECHANGE
;
1103 if (mFrame
!= aOther
.mFrame
|| mCols
!= aOther
.mCols
)
1104 return NS_STYLE_HINT_REFLOW
;
1105 return NS_STYLE_HINT_NONE
;
1110 nsChangeHint
nsStyleTable::MaxDifference()
1112 return NS_STYLE_HINT_FRAMECHANGE
;
1116 // -----------------------
1117 // nsStyleTableBorder
1119 nsStyleTableBorder::nsStyleTableBorder(nsPresContext
* aPresContext
)
1121 mBorderCollapse
= NS_STYLE_BORDER_SEPARATE
;
1123 nsCompatibility compatMode
= eCompatibility_FullStandards
;
1125 compatMode
= aPresContext
->CompatibilityMode();
1126 mEmptyCells
= (compatMode
== eCompatibility_NavQuirks
)
1127 ? NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND
1128 : NS_STYLE_TABLE_EMPTY_CELLS_SHOW
;
1129 mCaptionSide
= NS_STYLE_CAPTION_SIDE_TOP
;
1130 mBorderSpacingX
= 0;
1131 mBorderSpacingY
= 0;
1134 nsStyleTableBorder::~nsStyleTableBorder(void)
1138 nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder
& aSource
)
1140 memcpy((nsStyleTableBorder
*)this, &aSource
, sizeof(nsStyleTableBorder
));
1143 nsChangeHint
nsStyleTableBorder::CalcDifference(const nsStyleTableBorder
& aOther
) const
1145 // Border-collapse changes need a reframe, because we use a different frame
1146 // class for table cells in the collapsed border model. This is used to
1147 // conserve memory when using the separated border model (collapsed borders
1148 // require extra state to be stored).
1149 if (mBorderCollapse
!= aOther
.mBorderCollapse
) {
1150 return NS_STYLE_HINT_FRAMECHANGE
;
1153 if ((mCaptionSide
== aOther
.mCaptionSide
) &&
1154 (mBorderSpacingX
== aOther
.mBorderSpacingX
) &&
1155 (mBorderSpacingY
== aOther
.mBorderSpacingY
)) {
1156 if (mEmptyCells
== aOther
.mEmptyCells
)
1157 return NS_STYLE_HINT_NONE
;
1158 return NS_STYLE_HINT_VISUAL
;
1161 return NS_STYLE_HINT_REFLOW
;
1166 nsChangeHint
nsStyleTableBorder::MaxDifference()
1168 return NS_STYLE_HINT_FRAMECHANGE
;
1172 // --------------------
1176 nsStyleColor::nsStyleColor(nsPresContext
* aPresContext
)
1178 mColor
= aPresContext
->DefaultColor();
1181 nsStyleColor::nsStyleColor(const nsStyleColor
& aSource
)
1183 mColor
= aSource
.mColor
;
1186 nsChangeHint
nsStyleColor::CalcDifference(const nsStyleColor
& aOther
) const
1188 if (mColor
== aOther
.mColor
)
1189 return NS_STYLE_HINT_NONE
;
1190 return NS_STYLE_HINT_VISUAL
;
1195 nsChangeHint
nsStyleColor::MaxDifference()
1197 return NS_STYLE_HINT_VISUAL
;
1201 // --------------------
1202 // nsStyleBackground
1205 nsStyleBackground::nsStyleBackground()
1206 : mBackgroundFlags(NS_STYLE_BG_IMAGE_NONE
),
1207 mBackgroundAttachment(NS_STYLE_BG_ATTACHMENT_SCROLL
),
1208 mBackgroundClip(NS_STYLE_BG_CLIP_BORDER
),
1209 mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS
),
1210 mBackgroundOrigin(NS_STYLE_BG_ORIGIN_PADDING
),
1211 mBackgroundRepeat(NS_STYLE_BG_REPEAT_XY
),
1212 mBackgroundColor(NS_RGBA(0, 0, 0, 0))
1216 nsStyleBackground::nsStyleBackground(const nsStyleBackground
& aSource
)
1217 : mBackgroundFlags(aSource
.mBackgroundFlags
),
1218 mBackgroundAttachment(aSource
.mBackgroundAttachment
),
1219 mBackgroundClip(aSource
.mBackgroundClip
),
1220 mBackgroundInlinePolicy(aSource
.mBackgroundInlinePolicy
),
1221 mBackgroundOrigin(aSource
.mBackgroundOrigin
),
1222 mBackgroundRepeat(aSource
.mBackgroundRepeat
),
1223 mBackgroundXPosition(aSource
.mBackgroundXPosition
),
1224 mBackgroundYPosition(aSource
.mBackgroundYPosition
),
1225 mBackgroundColor(aSource
.mBackgroundColor
),
1226 mBackgroundImage(aSource
.mBackgroundImage
)
1230 nsStyleBackground::~nsStyleBackground()
1234 nsChangeHint
nsStyleBackground::CalcDifference(const nsStyleBackground
& aOther
) const
1236 if ((mBackgroundAttachment
== aOther
.mBackgroundAttachment
) &&
1237 (mBackgroundFlags
== aOther
.mBackgroundFlags
) &&
1238 (mBackgroundRepeat
== aOther
.mBackgroundRepeat
) &&
1239 (mBackgroundColor
== aOther
.mBackgroundColor
) &&
1240 (mBackgroundClip
== aOther
.mBackgroundClip
) &&
1241 (mBackgroundInlinePolicy
== aOther
.mBackgroundInlinePolicy
) &&
1242 (mBackgroundOrigin
== aOther
.mBackgroundOrigin
) &&
1243 EqualImages(mBackgroundImage
, aOther
.mBackgroundImage
) &&
1244 ((!(mBackgroundFlags
& NS_STYLE_BG_X_POSITION_PERCENT
) ||
1245 (mBackgroundXPosition
.mFloat
== aOther
.mBackgroundXPosition
.mFloat
)) &&
1246 (!(mBackgroundFlags
& NS_STYLE_BG_X_POSITION_LENGTH
) ||
1247 (mBackgroundXPosition
.mCoord
== aOther
.mBackgroundXPosition
.mCoord
))) &&
1248 ((!(mBackgroundFlags
& NS_STYLE_BG_Y_POSITION_PERCENT
) ||
1249 (mBackgroundYPosition
.mFloat
== aOther
.mBackgroundYPosition
.mFloat
)) &&
1250 (!(mBackgroundFlags
& NS_STYLE_BG_Y_POSITION_LENGTH
) ||
1251 (mBackgroundYPosition
.mCoord
== aOther
.mBackgroundYPosition
.mCoord
))))
1252 return NS_STYLE_HINT_NONE
;
1253 return NS_STYLE_HINT_VISUAL
;
1258 nsChangeHint
nsStyleBackground::MaxDifference()
1260 return NS_STYLE_HINT_VISUAL
;
1264 PRBool
nsStyleBackground::HasFixedBackground() const
1266 return mBackgroundAttachment
== NS_STYLE_BG_ATTACHMENT_FIXED
&&
1270 // --------------------
1274 nsStyleDisplay::nsStyleDisplay()
1276 mAppearance
= NS_THEME_NONE
;
1277 mDisplay
= NS_STYLE_DISPLAY_INLINE
;
1278 mOriginalDisplay
= NS_STYLE_DISPLAY_NONE
;
1279 mPosition
= NS_STYLE_POSITION_STATIC
;
1280 mFloats
= NS_STYLE_FLOAT_NONE
;
1281 mBreakType
= NS_STYLE_CLEAR_NONE
;
1282 mBreakBefore
= PR_FALSE
;
1283 mBreakAfter
= PR_FALSE
;
1284 mOverflowX
= NS_STYLE_OVERFLOW_VISIBLE
;
1285 mOverflowY
= NS_STYLE_OVERFLOW_VISIBLE
;
1286 mClipFlags
= NS_STYLE_CLIP_AUTO
;
1287 mClip
.SetRect(0,0,0,0);
1289 mTransformPresent
= PR_FALSE
; // No transform
1290 mTransformOrigin
[0].SetPercentValue(0.5f
); // Transform is centered on origin
1291 mTransformOrigin
[1].SetPercentValue(0.5f
);
1294 nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay
& aSource
)
1296 mAppearance
= aSource
.mAppearance
;
1297 mDisplay
= aSource
.mDisplay
;
1298 mOriginalDisplay
= aSource
.mOriginalDisplay
;
1299 mBinding
= aSource
.mBinding
;
1300 mPosition
= aSource
.mPosition
;
1301 mFloats
= aSource
.mFloats
;
1302 mBreakType
= aSource
.mBreakType
;
1303 mBreakBefore
= aSource
.mBreakBefore
;
1304 mBreakAfter
= aSource
.mBreakAfter
;
1305 mOverflowX
= aSource
.mOverflowX
;
1306 mOverflowY
= aSource
.mOverflowY
;
1307 mClipFlags
= aSource
.mClipFlags
;
1308 mClip
= aSource
.mClip
;
1309 mOpacity
= aSource
.mOpacity
;
1311 /* Copy over the transformation information. */
1312 mTransformPresent
= aSource
.mTransformPresent
;
1313 if (mTransformPresent
)
1314 mTransform
= aSource
.mTransform
;
1316 /* Copy over transform origin. */
1317 mTransformOrigin
[0] = aSource
.mTransformOrigin
[0];
1318 mTransformOrigin
[1] = aSource
.mTransformOrigin
[1];
1321 nsChangeHint
nsStyleDisplay::CalcDifference(const nsStyleDisplay
& aOther
) const
1323 nsChangeHint hint
= nsChangeHint(0);
1325 if (!EqualURIs(mBinding
, aOther
.mBinding
)
1326 || mPosition
!= aOther
.mPosition
1327 || mDisplay
!= aOther
.mDisplay
1328 || (mFloats
== NS_STYLE_FLOAT_NONE
) != (aOther
.mFloats
== NS_STYLE_FLOAT_NONE
)
1329 || mOverflowX
!= aOther
.mOverflowX
1330 || mOverflowY
!= aOther
.mOverflowY
)
1331 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
1333 if (mFloats
!= aOther
.mFloats
)
1334 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
1336 if (mClipFlags
!= aOther
.mClipFlags
|| mClip
!= aOther
.mClip
) {
1337 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
1339 // XXX the following is conservative, for now: changing float breaking shouldn't
1340 // necessarily require a repaint, reflow should suffice.
1341 if (mBreakType
!= aOther
.mBreakType
1342 || mBreakBefore
!= aOther
.mBreakBefore
1343 || mBreakAfter
!= aOther
.mBreakAfter
1344 || mAppearance
!= aOther
.mAppearance
)
1345 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
));
1347 if (mOpacity
!= aOther
.mOpacity
)
1348 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1350 /* If we've added or removed the transform property, we need to reconstruct the frame to add
1351 * or remove the view object, and also to handle abs-pos and fixed-pos containers.
1353 if (mTransformPresent
!= aOther
.mTransformPresent
) {
1354 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
1356 else if (mTransformPresent
) {
1357 /* Otherwise, if we've kept the property lying around and we already had a
1358 * transform, we need to see whether or not we've changed the transform.
1359 * If so, we need to do a reflow and a repaint. The reflow is to recompute
1360 * the overflow rect (which probably changed if the transform changed)
1361 * and to redraw within the bounds of that new overflow rect.
1363 if (mTransform
!= aOther
.mTransform
)
1364 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_ReflowFrame
,
1365 nsChangeHint_RepaintFrame
));
1367 for (PRUint8 index
= 0; index
< 2; ++index
)
1368 if (mTransformOrigin
[index
] != aOther
.mTransformOrigin
[index
]) {
1369 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_ReflowFrame
,
1370 nsChangeHint_RepaintFrame
));
1381 nsChangeHint
nsStyleDisplay::MaxDifference()
1383 // All the parts of FRAMECHANGE are present above in CalcDifference.
1384 return NS_STYLE_HINT_FRAMECHANGE
;
1388 // --------------------
1389 // nsStyleVisibility
1392 nsStyleVisibility::nsStyleVisibility(nsPresContext
* aPresContext
)
1394 PRUint32 bidiOptions
= aPresContext
->GetBidi();
1395 if (GET_BIDI_OPTION_DIRECTION(bidiOptions
) == IBMBIDI_TEXTDIRECTION_RTL
)
1396 mDirection
= NS_STYLE_DIRECTION_RTL
;
1398 mDirection
= NS_STYLE_DIRECTION_LTR
;
1400 mLangGroup
= aPresContext
->GetLangGroup();
1401 mVisible
= NS_STYLE_VISIBILITY_VISIBLE
;
1404 nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility
& aSource
)
1406 mDirection
= aSource
.mDirection
;
1407 mVisible
= aSource
.mVisible
;
1408 mLangGroup
= aSource
.mLangGroup
;
1411 nsChangeHint
nsStyleVisibility::CalcDifference(const nsStyleVisibility
& aOther
) const
1413 if ((mDirection
== aOther
.mDirection
) &&
1414 (mLangGroup
== aOther
.mLangGroup
)) {
1415 if ((mVisible
== aOther
.mVisible
)) {
1416 return NS_STYLE_HINT_NONE
;
1418 if ((NS_STYLE_VISIBILITY_COLLAPSE
== mVisible
) ||
1419 (NS_STYLE_VISIBILITY_COLLAPSE
== aOther
.mVisible
)) {
1420 return NS_STYLE_HINT_REFLOW
;
1422 return NS_STYLE_HINT_VISUAL
;
1424 return NS_STYLE_HINT_REFLOW
;
1429 nsChangeHint
nsStyleVisibility::MaxDifference()
1431 return NS_STYLE_HINT_REFLOW
;
1435 nsStyleContentData::~nsStyleContentData()
1437 if (mType
== eStyleContentType_Image
) {
1438 NS_IF_RELEASE(mContent
.mImage
);
1439 } else if (mType
== eStyleContentType_Counter
||
1440 mType
== eStyleContentType_Counters
) {
1441 mContent
.mCounters
->Release();
1442 } else if (mContent
.mString
) {
1443 NS_Free(mContent
.mString
);
1447 nsStyleContentData
& nsStyleContentData::operator=(const nsStyleContentData
& aOther
)
1449 if (this == &aOther
)
1451 this->~nsStyleContentData();
1452 new (this) nsStyleContentData();
1454 mType
= aOther
.mType
;
1455 if (mType
== eStyleContentType_Image
) {
1456 mContent
.mImage
= aOther
.mContent
.mImage
;
1457 NS_IF_ADDREF(mContent
.mImage
);
1458 } else if (mType
== eStyleContentType_Counter
||
1459 mType
== eStyleContentType_Counters
) {
1460 mContent
.mCounters
= aOther
.mContent
.mCounters
;
1461 mContent
.mCounters
->AddRef();
1462 } else if (aOther
.mContent
.mString
) {
1463 mContent
.mString
= NS_strdup(aOther
.mContent
.mString
);
1465 mContent
.mString
= nsnull
;
1470 PRBool
nsStyleContentData::operator==(const nsStyleContentData
& aOther
) const
1472 if (mType
!= aOther
.mType
)
1474 if (mType
== eStyleContentType_Image
) {
1475 if (!mContent
.mImage
|| !aOther
.mContent
.mImage
)
1476 return mContent
.mImage
== aOther
.mContent
.mImage
;
1478 nsCOMPtr
<nsIURI
> thisURI
, otherURI
;
1479 mContent
.mImage
->GetURI(getter_AddRefs(thisURI
));
1480 aOther
.mContent
.mImage
->GetURI(getter_AddRefs(otherURI
));
1481 return thisURI
== otherURI
|| // handles null==null
1482 (thisURI
&& otherURI
&&
1483 NS_SUCCEEDED(thisURI
->Equals(otherURI
, &eq
)) &&
1486 if (mType
== eStyleContentType_Counter
||
1487 mType
== eStyleContentType_Counters
)
1488 return *mContent
.mCounters
== *aOther
.mContent
.mCounters
;
1489 return nsCRT::strcmp(mContent
.mString
, aOther
.mContent
.mString
) == 0;
1492 //-----------------------
1496 nsStyleContent::nsStyleContent(void)
1501 mIncrements(nsnull
),
1505 mMarkerOffset
.SetAutoValue();
1508 nsStyleContent::~nsStyleContent(void)
1510 DELETE_ARRAY_IF(mContents
);
1511 DELETE_ARRAY_IF(mIncrements
);
1512 DELETE_ARRAY_IF(mResets
);
1515 nsStyleContent::nsStyleContent(const nsStyleContent
& aSource
)
1520 mIncrements(nsnull
),
1525 mMarkerOffset
= aSource
.mMarkerOffset
;
1528 if (NS_SUCCEEDED(AllocateContents(aSource
.ContentCount()))) {
1529 for (index
= 0; index
< mContentCount
; index
++) {
1530 ContentAt(index
) = aSource
.ContentAt(index
);
1534 if (NS_SUCCEEDED(AllocateCounterIncrements(aSource
.CounterIncrementCount()))) {
1535 for (index
= 0; index
< mIncrementCount
; index
++) {
1536 const nsStyleCounterData
*data
= aSource
.GetCounterIncrementAt(index
);
1537 mIncrements
[index
].mCounter
= data
->mCounter
;
1538 mIncrements
[index
].mValue
= data
->mValue
;
1542 if (NS_SUCCEEDED(AllocateCounterResets(aSource
.CounterResetCount()))) {
1543 for (index
= 0; index
< mResetCount
; index
++) {
1544 const nsStyleCounterData
*data
= aSource
.GetCounterResetAt(index
);
1545 mResets
[index
].mCounter
= data
->mCounter
;
1546 mResets
[index
].mValue
= data
->mValue
;
1551 nsChangeHint
nsStyleContent::CalcDifference(const nsStyleContent
& aOther
) const
1553 if (mContentCount
!= aOther
.mContentCount
||
1554 mIncrementCount
!= aOther
.mIncrementCount
||
1555 mResetCount
!= aOther
.mResetCount
) {
1556 return NS_STYLE_HINT_FRAMECHANGE
;
1559 PRUint32 ix
= mContentCount
;
1561 if (mContents
[ix
] != aOther
.mContents
[ix
]) {
1562 // Unfortunately we need to reframe here; a simple reflow
1563 // will not pick up different text or different image URLs,
1564 // since we set all that up in the CSSFrameConstructor
1565 return NS_STYLE_HINT_FRAMECHANGE
;
1568 ix
= mIncrementCount
;
1570 if ((mIncrements
[ix
].mValue
!= aOther
.mIncrements
[ix
].mValue
) ||
1571 (mIncrements
[ix
].mCounter
!= aOther
.mIncrements
[ix
].mCounter
)) {
1572 return NS_STYLE_HINT_FRAMECHANGE
;
1577 if ((mResets
[ix
].mValue
!= aOther
.mResets
[ix
].mValue
) ||
1578 (mResets
[ix
].mCounter
!= aOther
.mResets
[ix
].mCounter
)) {
1579 return NS_STYLE_HINT_FRAMECHANGE
;
1582 if (mMarkerOffset
!= aOther
.mMarkerOffset
) {
1583 return NS_STYLE_HINT_REFLOW
;
1585 return NS_STYLE_HINT_NONE
;
1590 nsChangeHint
nsStyleContent::MaxDifference()
1592 return NS_STYLE_HINT_FRAMECHANGE
;
1596 nsresult
nsStyleContent::AllocateContents(PRUint32 aCount
)
1598 // We need to run the destructors of the elements of mContents, so we
1599 // delete and reallocate even if aCount == mContentCount. (If
1600 // nsStyleContentData had its members private and managed their
1601 // ownership on setting, we wouldn't need this, but that seems
1602 // unnecessary at this point.)
1603 DELETE_ARRAY_IF(mContents
);
1605 mContents
= new nsStyleContentData
[aCount
];
1608 return NS_ERROR_OUT_OF_MEMORY
;
1611 mContentCount
= aCount
;
1615 // ---------------------
1619 nsStyleQuotes::nsStyleQuotes(void)
1626 nsStyleQuotes::~nsStyleQuotes(void)
1628 DELETE_ARRAY_IF(mQuotes
);
1631 nsStyleQuotes::nsStyleQuotes(const nsStyleQuotes
& aSource
)
1639 nsStyleQuotes::SetInitial()
1641 // The initial value for quotes is the en-US typographic convention:
1642 // outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
1643 // with LEFT and RIGHT SINGLE QUOTATION MARK.
1644 static const PRUnichar initialQuotes
[8] = {
1645 0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
1648 if (NS_SUCCEEDED(AllocateQuotes(2))) {
1650 nsDependentString(&initialQuotes
[0], 1),
1651 nsDependentString(&initialQuotes
[2], 1));
1653 nsDependentString(&initialQuotes
[4], 1),
1654 nsDependentString(&initialQuotes
[6], 1));
1659 nsStyleQuotes::CopyFrom(const nsStyleQuotes
& aSource
)
1661 if (NS_SUCCEEDED(AllocateQuotes(aSource
.QuotesCount()))) {
1662 PRUint32 count
= (mQuotesCount
* 2);
1663 for (PRUint32 index
= 0; index
< count
; index
+= 2) {
1664 aSource
.GetQuotesAt(index
, mQuotes
[index
], mQuotes
[index
+ 1]);
1669 nsChangeHint
nsStyleQuotes::CalcDifference(const nsStyleQuotes
& aOther
) const
1671 // If the quotes implementation is ever going to change we might not need
1672 // a framechange here and a reflow should be sufficient. See bug 35768.
1673 if (mQuotesCount
== aOther
.mQuotesCount
) {
1674 PRUint32 ix
= (mQuotesCount
* 2);
1676 if (mQuotes
[ix
] != aOther
.mQuotes
[ix
]) {
1677 return NS_STYLE_HINT_FRAMECHANGE
;
1681 return NS_STYLE_HINT_NONE
;
1683 return NS_STYLE_HINT_FRAMECHANGE
;
1688 nsChangeHint
nsStyleQuotes::MaxDifference()
1690 return NS_STYLE_HINT_FRAMECHANGE
;
1694 // --------------------
1698 nsStyleTextReset::nsStyleTextReset(void)
1700 mVerticalAlign
.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE
, eStyleUnit_Enumerated
);
1701 mTextDecoration
= NS_STYLE_TEXT_DECORATION_NONE
;
1702 mUnicodeBidi
= NS_STYLE_UNICODE_BIDI_NORMAL
;
1705 nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset
& aSource
)
1707 memcpy((nsStyleTextReset
*)this, &aSource
, sizeof(nsStyleTextReset
));
1710 nsStyleTextReset::~nsStyleTextReset(void) { }
1712 nsChangeHint
nsStyleTextReset::CalcDifference(const nsStyleTextReset
& aOther
) const
1714 if (mVerticalAlign
== aOther
.mVerticalAlign
1715 && mUnicodeBidi
== aOther
.mUnicodeBidi
) {
1716 if (mTextDecoration
!= aOther
.mTextDecoration
) {
1717 // Reflow for blink changes, repaint for others
1719 (mTextDecoration
& NS_STYLE_TEXT_DECORATION_BLINK
) ==
1720 (aOther
.mTextDecoration
& NS_STYLE_TEXT_DECORATION_BLINK
) ?
1721 NS_STYLE_HINT_VISUAL
: NS_STYLE_HINT_REFLOW
;
1724 return NS_STYLE_HINT_NONE
;
1726 return NS_STYLE_HINT_REFLOW
;
1731 nsChangeHint
nsStyleTextReset::MaxDifference()
1733 return NS_STYLE_HINT_REFLOW
;
1737 // --------------------
1743 nsCSSShadowArray::Release()
1754 CalcShadowDifference(nsCSSShadowArray
* lhs
,
1755 nsCSSShadowArray
* rhs
)
1758 return NS_STYLE_HINT_NONE
;
1760 if (!lhs
|| !rhs
|| lhs
->Length() != rhs
->Length())
1761 return NS_STYLE_HINT_REFLOW
;
1763 for (PRUint32 i
= 0; i
< lhs
->Length(); ++i
) {
1764 if (*lhs
->ShadowAt(i
) != *rhs
->ShadowAt(i
))
1765 return NS_STYLE_HINT_REFLOW
;
1767 return NS_STYLE_HINT_NONE
;
1770 // --------------------
1774 nsStyleText::nsStyleText(void)
1776 mTextAlign
= NS_STYLE_TEXT_ALIGN_DEFAULT
;
1777 mTextTransform
= NS_STYLE_TEXT_TRANSFORM_NONE
;
1778 mWhiteSpace
= NS_STYLE_WHITESPACE_NORMAL
;
1779 mWordWrap
= NS_STYLE_WORDWRAP_NORMAL
;
1781 mLetterSpacing
.SetNormalValue();
1782 mLineHeight
.SetNormalValue();
1783 mTextIndent
.SetCoordValue(0);
1784 mWordSpacing
.SetNormalValue();
1786 mTextShadow
= nsnull
;
1789 nsStyleText::nsStyleText(const nsStyleText
& aSource
)
1790 : mTextAlign(aSource
.mTextAlign
),
1791 mTextTransform(aSource
.mTextTransform
),
1792 mWhiteSpace(aSource
.mWhiteSpace
),
1793 mWordWrap(aSource
.mWordWrap
),
1794 mLetterSpacing(aSource
.mLetterSpacing
),
1795 mLineHeight(aSource
.mLineHeight
),
1796 mTextIndent(aSource
.mTextIndent
),
1797 mWordSpacing(aSource
.mWordSpacing
),
1798 mTextShadow(aSource
.mTextShadow
)
1801 nsStyleText::~nsStyleText(void) { }
1803 nsChangeHint
nsStyleText::CalcDifference(const nsStyleText
& aOther
) const
1805 if ((mTextAlign
!= aOther
.mTextAlign
) ||
1806 (mTextTransform
!= aOther
.mTextTransform
) ||
1807 (mWhiteSpace
!= aOther
.mWhiteSpace
) ||
1808 (mWordWrap
!= aOther
.mWordWrap
) ||
1809 (mLetterSpacing
!= aOther
.mLetterSpacing
) ||
1810 (mLineHeight
!= aOther
.mLineHeight
) ||
1811 (mTextIndent
!= aOther
.mTextIndent
) ||
1812 (mWordSpacing
!= aOther
.mWordSpacing
))
1813 return NS_STYLE_HINT_REFLOW
;
1815 return CalcShadowDifference(mTextShadow
, aOther
.mTextShadow
);
1820 nsChangeHint
nsStyleText::MaxDifference()
1822 return NS_STYLE_HINT_REFLOW
;
1826 //-----------------------
1827 // nsStyleUserInterface
1830 nsCursorImage::nsCursorImage()
1831 : mHaveHotspot(PR_FALSE
)
1837 nsStyleUserInterface::nsStyleUserInterface(void)
1839 mUserInput
= NS_STYLE_USER_INPUT_AUTO
;
1840 mUserModify
= NS_STYLE_USER_MODIFY_READ_ONLY
;
1841 mUserFocus
= NS_STYLE_USER_FOCUS_NONE
;
1843 mCursor
= NS_STYLE_CURSOR_AUTO
; // fix for bugzilla bug 51113
1845 mCursorArrayLength
= 0;
1846 mCursorArray
= nsnull
;
1849 nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface
& aSource
) :
1850 mUserInput(aSource
.mUserInput
),
1851 mUserModify(aSource
.mUserModify
),
1852 mUserFocus(aSource
.mUserFocus
),
1853 mCursor(aSource
.mCursor
)
1855 CopyCursorArrayFrom(aSource
);
1858 nsStyleUserInterface::~nsStyleUserInterface(void)
1860 delete [] mCursorArray
;
1863 nsChangeHint
nsStyleUserInterface::CalcDifference(const nsStyleUserInterface
& aOther
) const
1865 nsChangeHint hint
= nsChangeHint(0);
1866 if (mCursor
!= aOther
.mCursor
)
1867 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
1869 // We could do better. But it wouldn't be worth it, URL-specified cursors are
1871 if (mCursorArrayLength
> 0 || aOther
.mCursorArrayLength
> 0)
1872 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
1874 if (mUserModify
!= aOther
.mUserModify
)
1875 NS_UpdateHint(hint
, NS_STYLE_HINT_VISUAL
);
1877 if ((mUserInput
!= aOther
.mUserInput
) &&
1878 ((NS_STYLE_USER_INPUT_NONE
== mUserInput
) ||
1879 (NS_STYLE_USER_INPUT_NONE
== aOther
.mUserInput
))) {
1880 NS_UpdateHint(hint
, NS_STYLE_HINT_FRAMECHANGE
);
1883 // ignore mUserFocus
1890 nsChangeHint
nsStyleUserInterface::MaxDifference()
1892 return nsChangeHint(nsChangeHint_UpdateCursor
| NS_STYLE_HINT_FRAMECHANGE
);
1897 nsStyleUserInterface::CopyCursorArrayFrom(const nsStyleUserInterface
& aSource
)
1899 mCursorArray
= nsnull
;
1900 mCursorArrayLength
= 0;
1901 if (aSource
.mCursorArrayLength
) {
1902 mCursorArray
= new nsCursorImage
[aSource
.mCursorArrayLength
];
1904 mCursorArrayLength
= aSource
.mCursorArrayLength
;
1905 for (PRUint32 i
= 0; i
< mCursorArrayLength
; ++i
)
1906 mCursorArray
[i
] = aSource
.mCursorArray
[i
];
1911 //-----------------------
1915 nsStyleUIReset::nsStyleUIReset(void)
1917 mUserSelect
= NS_STYLE_USER_SELECT_AUTO
;
1918 mForceBrokenImageIcon
= 0;
1919 mIMEMode
= NS_STYLE_IME_MODE_AUTO
;
1920 mWindowShadow
= NS_STYLE_WINDOW_SHADOW_DEFAULT
;
1923 nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset
& aSource
)
1925 mUserSelect
= aSource
.mUserSelect
;
1926 mForceBrokenImageIcon
= aSource
.mForceBrokenImageIcon
;
1927 mIMEMode
= aSource
.mIMEMode
;
1928 mWindowShadow
= aSource
.mWindowShadow
;
1931 nsStyleUIReset::~nsStyleUIReset(void)
1935 nsChangeHint
nsStyleUIReset::CalcDifference(const nsStyleUIReset
& aOther
) const
1938 if (mForceBrokenImageIcon
!= aOther
.mForceBrokenImageIcon
)
1939 return NS_STYLE_HINT_FRAMECHANGE
;
1940 if (mWindowShadow
!= aOther
.mWindowShadow
) {
1941 // We really need just an nsChangeHint_SyncFrameView, except
1942 // on an ancestor of the frame, so we get that by doing a
1944 return NS_STYLE_HINT_REFLOW
;
1946 if (mUserSelect
!= aOther
.mUserSelect
)
1947 return NS_STYLE_HINT_VISUAL
;
1948 return NS_STYLE_HINT_NONE
;
1953 nsChangeHint
nsStyleUIReset::MaxDifference()
1955 return NS_STYLE_HINT_FRAMECHANGE
;