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>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * structs that contain the data provided by nsStyleContext, the
42 * internal API for computed style data for an element
45 #include "nsStyleStruct.h"
46 #include "nsStyleConsts.h"
47 #include "nsThemeConstants.h"
49 #include "nsPresContext.h"
50 #include "nsIDeviceContext.h"
51 #include "nsIStyleRule.h"
55 #include "nsIPresShell.h"
57 #include "nsHTMLReflowState.h"
60 #include "nsBidiUtils.h"
62 #include "imgIRequest.h"
65 // Make sure we have enough bits in NS_STYLE_INHERIT_MASK.
66 PR_STATIC_ASSERT((((1 << nsStyleStructID_Length
) - 1) &
67 ~(NS_STYLE_INHERIT_MASK
)) == 0);
69 inline PRBool
IsFixedUnit(nsStyleUnit aUnit
, PRBool aEnumOK
)
71 return PRBool((aUnit
== eStyleUnit_Coord
) ||
72 (aEnumOK
&& (aUnit
== eStyleUnit_Enumerated
)));
75 static PRBool
EqualURIs(nsIURI
*aURI1
, nsIURI
*aURI2
)
78 return aURI1
== aURI2
|| // handle null==null, and optimize
80 NS_SUCCEEDED(aURI1
->Equals(aURI2
, &eq
)) && // not equal on fail
84 static PRBool
EqualURIs(nsCSSValue::URL
*aURI1
, nsCSSValue::URL
*aURI2
)
86 return aURI1
== aURI2
|| // handle null==null, and optimize
87 (aURI1
&& aURI2
&& aURI1
->URIEquals(*aURI2
));
90 static PRBool
EqualImages(imgIRequest
*aImage1
, imgIRequest
* aImage2
)
92 if (aImage1
== aImage2
) {
96 if (!aImage1
|| !aImage2
) {
100 nsCOMPtr
<nsIURI
> uri1
, uri2
;
101 aImage1
->GetURI(getter_AddRefs(uri1
));
102 aImage2
->GetURI(getter_AddRefs(uri2
));
103 return EqualURIs(uri1
, uri2
);
106 // --------------------
109 nsStyleFont::nsStyleFont(const nsFont
& aFont
, nsPresContext
*aPresContext
)
111 mFlags(NS_STYLE_FONT_DEFAULT
)
113 mSize
= mFont
.size
= nsStyleFont::ZoomText(aPresContext
, mFont
.size
);
115 mScriptUnconstrainedSize
= mSize
;
116 mScriptMinSize
= aPresContext
->TwipsToAppUnits(
117 NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT
));
119 mScriptSizeMultiplier
= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER
;
123 nsStyleFont::nsStyleFont(const nsStyleFont
& aSrc
)
126 , mFlags(aSrc
.mFlags
)
128 , mScriptLevel(aSrc
.mScriptLevel
)
129 , mScriptUnconstrainedSize(aSrc
.mScriptUnconstrainedSize
)
130 , mScriptMinSize(aSrc
.mScriptMinSize
)
131 , mScriptSizeMultiplier(aSrc
.mScriptSizeMultiplier
)
136 nsStyleFont::nsStyleFont(nsPresContext
* aPresContext
)
137 : mFont(*(aPresContext
->GetDefaultFont(kPresContext_DefaultVariableFont_ID
))),
138 mFlags(NS_STYLE_FONT_DEFAULT
)
140 mSize
= mFont
.size
= nsStyleFont::ZoomText(aPresContext
, mFont
.size
);
142 mScriptUnconstrainedSize
= mSize
;
143 mScriptMinSize
= aPresContext
->TwipsToAppUnits(
144 NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT
));
146 mScriptSizeMultiplier
= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER
;
151 nsStyleFont::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
152 void* result
= aContext
->AllocateFromShell(sz
);
154 memset(result
, 0, sz
);
159 nsStyleFont::Destroy(nsPresContext
* aContext
) {
160 this->~nsStyleFont();
161 aContext
->FreeToShell(sizeof(nsStyleFont
), this);
164 nsChangeHint
nsStyleFont::CalcDifference(const nsStyleFont
& aOther
) const
166 if (mSize
== aOther
.mSize
) {
167 return CalcFontDifference(mFont
, aOther
.mFont
);
169 return NS_STYLE_HINT_REFLOW
;
174 nsChangeHint
nsStyleFont::MaxDifference()
176 return NS_STYLE_HINT_REFLOW
;
181 nsStyleFont::ZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
183 return nscoord(float(aSize
) * aPresContext
->TextZoom());
187 nsStyleFont::UnZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
189 return nscoord(float(aSize
) / aPresContext
->TextZoom());
192 nsChangeHint
nsStyleFont::CalcFontDifference(const nsFont
& aFont1
, const nsFont
& aFont2
)
194 if ((aFont1
.size
== aFont2
.size
) &&
195 (aFont1
.sizeAdjust
== aFont2
.sizeAdjust
) &&
196 (aFont1
.style
== aFont2
.style
) &&
197 (aFont1
.variant
== aFont2
.variant
) &&
198 (aFont1
.familyNameQuirks
== aFont2
.familyNameQuirks
) &&
199 (aFont1
.weight
== aFont2
.weight
) &&
200 (aFont1
.name
== aFont2
.name
)) {
201 if ((aFont1
.decorations
== aFont2
.decorations
)) {
202 return NS_STYLE_HINT_NONE
;
204 return NS_STYLE_HINT_VISUAL
;
206 return NS_STYLE_HINT_REFLOW
;
209 static PRBool
IsFixedData(const nsStyleSides
& aSides
, PRBool aEnumOK
)
211 NS_FOR_CSS_SIDES(side
) {
212 if (!IsFixedUnit(aSides
.GetUnit(side
), aEnumOK
))
218 static nscoord
CalcCoord(const nsStyleCoord
& aCoord
,
219 const nscoord
* aEnumTable
,
222 switch (aCoord
.GetUnit()) {
223 case eStyleUnit_Coord
:
224 return aCoord
.GetCoordValue();
225 case eStyleUnit_Enumerated
:
226 if (nsnull
!= aEnumTable
) {
227 PRInt32 value
= aCoord
.GetIntValue();
228 if ((0 <= value
) && (value
< aNumEnums
)) {
229 return aEnumTable
[aCoord
.GetIntValue()];
233 case eStyleUnit_Chars
:
234 // XXX we need a frame and a rendering context to calculate this, bug 281972, bug 282126.
235 NS_NOTYETIMPLEMENTED("CalcCoord: eStyleUnit_Chars");
238 NS_ERROR("bad unit type");
244 nsStyleMargin::nsStyleMargin() {
245 nsStyleCoord
zero(0);
246 NS_FOR_CSS_SIDES(side
) {
247 mMargin
.Set(side
, zero
);
249 mHasCachedMargin
= PR_FALSE
;
252 nsStyleMargin::nsStyleMargin(const nsStyleMargin
& aSrc
) {
253 mMargin
= aSrc
.mMargin
;
254 mHasCachedMargin
= PR_FALSE
;
258 nsStyleMargin::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
259 void* result
= aContext
->AllocateFromShell(sz
);
261 memset(result
, 0, sz
);
266 nsStyleMargin::Destroy(nsPresContext
* aContext
) {
267 this->~nsStyleMargin();
268 aContext
->FreeToShell(sizeof(nsStyleMargin
), this);
272 void nsStyleMargin::RecalcData()
274 if (IsFixedData(mMargin
, PR_FALSE
)) {
275 NS_FOR_CSS_SIDES(side
) {
276 mCachedMargin
.side(side
) = CalcCoord(mMargin
.Get(side
), nsnull
, 0);
278 mHasCachedMargin
= PR_TRUE
;
281 mHasCachedMargin
= PR_FALSE
;
284 nsChangeHint
nsStyleMargin::CalcDifference(const nsStyleMargin
& aOther
) const
286 if (mMargin
== aOther
.mMargin
) {
287 return NS_STYLE_HINT_NONE
;
289 return NS_STYLE_HINT_REFLOW
;
294 nsChangeHint
nsStyleMargin::MaxDifference()
296 return NS_STYLE_HINT_REFLOW
;
300 nsStylePadding::nsStylePadding() {
301 nsStyleCoord
zero(0);
302 NS_FOR_CSS_SIDES(side
) {
303 mPadding
.Set(side
, zero
);
305 mHasCachedPadding
= PR_FALSE
;
308 nsStylePadding::nsStylePadding(const nsStylePadding
& aSrc
) {
309 mPadding
= aSrc
.mPadding
;
310 mHasCachedPadding
= PR_FALSE
;
314 nsStylePadding::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
315 void* result
= aContext
->AllocateFromShell(sz
);
317 memset(result
, 0, sz
);
322 nsStylePadding::Destroy(nsPresContext
* aContext
) {
323 this->~nsStylePadding();
324 aContext
->FreeToShell(sizeof(nsStylePadding
), this);
327 void nsStylePadding::RecalcData()
329 if (IsFixedData(mPadding
, PR_FALSE
)) {
330 NS_FOR_CSS_SIDES(side
) {
331 mCachedPadding
.side(side
) = CalcCoord(mPadding
.Get(side
), nsnull
, 0);
333 mHasCachedPadding
= PR_TRUE
;
336 mHasCachedPadding
= PR_FALSE
;
339 nsChangeHint
nsStylePadding::CalcDifference(const nsStylePadding
& aOther
) const
341 if (mPadding
== aOther
.mPadding
) {
342 return NS_STYLE_HINT_NONE
;
344 return NS_STYLE_HINT_REFLOW
;
349 nsChangeHint
nsStylePadding::MaxDifference()
351 return NS_STYLE_HINT_REFLOW
;
355 nsStyleBorder::nsStyleBorder(nsPresContext
* aPresContext
)
356 : mActualBorder(0, 0, 0, 0)
359 (aPresContext
->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM
];
360 NS_FOR_CSS_SIDES(side
) {
361 mBorder
.side(side
) = medium
;
362 mBorderStyle
[side
] = NS_STYLE_BORDER_STYLE_NONE
| BORDER_COLOR_FOREGROUND
;
363 mBorderColor
[side
] = NS_RGB(0, 0, 0);
364 mBorderRadius
.Set(side
, nsStyleCoord(0));
367 mBorderColors
= nsnull
;
369 mFloatEdge
= NS_STYLE_FLOAT_EDGE_CONTENT
;
371 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
374 nsStyleBorder::nsStyleBorder(const nsStyleBorder
& aSrc
)
376 memcpy((nsStyleBorder
*)this, &aSrc
, sizeof(nsStyleBorder
));
377 mBorderColors
= nsnull
;
378 if (aSrc
.mBorderColors
) {
379 EnsureBorderColors();
380 for (PRInt32 i
= 0; i
< 4; i
++)
381 if (aSrc
.mBorderColors
[i
])
382 mBorderColors
[i
] = aSrc
.mBorderColors
[i
]->CopyColors();
384 mBorderColors
[i
] = nsnull
;
389 nsStyleBorder::operator new(size_t sz
, nsPresContext
* aContext
) CPP_THROW_NEW
{
390 void* result
= aContext
->AllocateFromShell(sz
);
392 memset(result
, 0, sz
);
397 nsStyleBorder::Destroy(nsPresContext
* aContext
) {
398 this->~nsStyleBorder();
399 aContext
->FreeToShell(sizeof(nsStyleBorder
), this);
403 nsChangeHint
nsStyleBorder::CalcDifference(const nsStyleBorder
& aOther
) const
405 // Note that differences in mBorder don't affect rendering (which should only
406 // use mComputedBorder), so don't need to be tested for here.
407 if (mTwipsPerPixel
== aOther
.mTwipsPerPixel
&&
408 mActualBorder
== aOther
.mActualBorder
&&
409 mFloatEdge
== aOther
.mFloatEdge
) {
410 // Note that mBorderStyle stores not only the border style but also
411 // color-related flags. Given that we've already done an mComputedBorder
412 // comparison, border-style differences can only lead to a VISUAL hint. So
413 // it's OK to just compare the values directly -- if either the actual
414 // style or the color flags differ we want to repaint.
415 NS_FOR_CSS_SIDES(ix
) {
416 if (mBorderStyle
[ix
] != aOther
.mBorderStyle
[ix
] ||
417 mBorderColor
[ix
] != aOther
.mBorderColor
[ix
]) {
418 return NS_STYLE_HINT_VISUAL
;
422 if (mBorderRadius
!= aOther
.mBorderRadius
||
423 !mBorderColors
!= !aOther
.mBorderColors
) {
424 return NS_STYLE_HINT_VISUAL
;
427 // Note that at this point if mBorderColors is non-null so is
428 // aOther.mBorderColors
430 NS_FOR_CSS_SIDES(ix
) {
431 if (!mBorderColors
[ix
] != !aOther
.mBorderColors
[ix
]) {
432 return NS_STYLE_HINT_VISUAL
;
433 } else if (mBorderColors
[ix
] && aOther
.mBorderColors
[ix
]) {
434 if (!mBorderColors
[ix
]->Equals(aOther
.mBorderColors
[ix
]))
435 return NS_STYLE_HINT_VISUAL
;
441 return NS_STYLE_HINT_NONE
;
443 return NS_STYLE_HINT_REFLOW
;
448 nsChangeHint
nsStyleBorder::MaxDifference()
450 return NS_STYLE_HINT_REFLOW
;
454 nsStyleOutline::nsStyleOutline(nsPresContext
* aPresContext
)
456 // spacing values not inherited
457 nsStyleCoord
zero(0);
458 NS_FOR_CSS_SIDES(side
) {
459 mOutlineRadius
.Set(side
, zero
);
462 mOutlineOffset
.SetCoordValue(0);
464 mOutlineWidth
= nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM
, eStyleUnit_Enumerated
);
465 mOutlineStyle
= NS_STYLE_BORDER_STYLE_NONE
;
466 mOutlineColor
= NS_RGB(0, 0, 0);
468 mHasCachedOutline
= PR_FALSE
;
469 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
472 nsStyleOutline::nsStyleOutline(const nsStyleOutline
& aSrc
) {
473 memcpy((nsStyleOutline
*)this, &aSrc
, sizeof(nsStyleOutline
));
477 nsStyleOutline::RecalcData(nsPresContext
* aContext
)
479 if (NS_STYLE_BORDER_STYLE_NONE
== GetOutlineStyle()) {
480 mCachedOutlineWidth
= 0;
481 mHasCachedOutline
= PR_TRUE
;
482 } else if (IsFixedUnit(mOutlineWidth
.GetUnit(), PR_TRUE
)) {
483 mCachedOutlineWidth
=
484 CalcCoord(mOutlineWidth
, aContext
->GetBorderWidthTable(), 3);
485 mCachedOutlineWidth
=
486 NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth
, mTwipsPerPixel
);
487 mHasCachedOutline
= PR_TRUE
;
490 mHasCachedOutline
= PR_FALSE
;
493 nsChangeHint
nsStyleOutline::CalcDifference(const nsStyleOutline
& aOther
) const
495 PRBool outlineWasVisible
=
496 mCachedOutlineWidth
> 0 && mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
497 PRBool outlineIsVisible
=
498 aOther
.mCachedOutlineWidth
> 0 && aOther
.mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
499 if (outlineWasVisible
!= outlineIsVisible
||
500 (outlineIsVisible
&& (mOutlineOffset
!= aOther
.mOutlineOffset
||
501 mOutlineWidth
!= aOther
.mOutlineWidth
||
502 mTwipsPerPixel
!= aOther
.mTwipsPerPixel
))) {
503 return NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
);
505 if ((mOutlineStyle
!= aOther
.mOutlineStyle
) ||
506 (mOutlineColor
!= aOther
.mOutlineColor
) ||
507 (mOutlineRadius
!= aOther
.mOutlineRadius
)) {
508 return nsChangeHint_RepaintFrame
;
510 return NS_STYLE_HINT_NONE
;
515 nsChangeHint
nsStyleOutline::MaxDifference()
517 return NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
);
521 // --------------------
524 nsStyleList::nsStyleList()
525 : mListStyleType(NS_STYLE_LIST_STYLE_DISC
),
526 mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE
)
530 nsStyleList::~nsStyleList()
534 nsStyleList::nsStyleList(const nsStyleList
& aSource
)
535 : mListStyleType(aSource
.mListStyleType
),
536 mListStylePosition(aSource
.mListStylePosition
),
537 mListStyleImage(aSource
.mListStyleImage
),
538 mImageRegion(aSource
.mImageRegion
)
542 nsChangeHint
nsStyleList::CalcDifference(const nsStyleList
& aOther
) const
544 if (mListStylePosition
!= aOther
.mListStylePosition
)
545 return NS_STYLE_HINT_FRAMECHANGE
;
546 if (EqualImages(mListStyleImage
, aOther
.mListStyleImage
) &&
547 mListStyleType
== aOther
.mListStyleType
) {
548 if (mImageRegion
== aOther
.mImageRegion
)
549 return NS_STYLE_HINT_NONE
;
550 if (mImageRegion
.width
== aOther
.mImageRegion
.width
&&
551 mImageRegion
.height
== aOther
.mImageRegion
.height
)
552 return NS_STYLE_HINT_VISUAL
;
554 return NS_STYLE_HINT_REFLOW
;
559 nsChangeHint
nsStyleList::MaxDifference()
561 return NS_STYLE_HINT_FRAMECHANGE
;
565 // --------------------
568 nsStyleXUL::nsStyleXUL()
570 mBoxAlign
= NS_STYLE_BOX_ALIGN_STRETCH
;
571 mBoxDirection
= NS_STYLE_BOX_DIRECTION_NORMAL
;
573 mBoxOrient
= NS_STYLE_BOX_ORIENT_HORIZONTAL
;
574 mBoxPack
= NS_STYLE_BOX_PACK_START
;
578 nsStyleXUL::~nsStyleXUL()
582 nsStyleXUL::nsStyleXUL(const nsStyleXUL
& aSource
)
584 memcpy((nsStyleXUL
*)this, &aSource
, sizeof(nsStyleXUL
));
587 nsChangeHint
nsStyleXUL::CalcDifference(const nsStyleXUL
& aOther
) const
589 if (mBoxAlign
== aOther
.mBoxAlign
&&
590 mBoxDirection
== aOther
.mBoxDirection
&&
591 mBoxFlex
== aOther
.mBoxFlex
&&
592 mBoxOrient
== aOther
.mBoxOrient
&&
593 mBoxPack
== aOther
.mBoxPack
&&
594 mBoxOrdinal
== aOther
.mBoxOrdinal
)
595 return NS_STYLE_HINT_NONE
;
596 if (mBoxOrdinal
!= aOther
.mBoxOrdinal
)
597 return NS_STYLE_HINT_FRAMECHANGE
;
598 return NS_STYLE_HINT_REFLOW
;
603 nsChangeHint
nsStyleXUL::MaxDifference()
605 return NS_STYLE_HINT_FRAMECHANGE
;
609 // --------------------
612 nsStyleColumn::nsStyleColumn()
614 mColumnCount
= NS_STYLE_COLUMN_COUNT_AUTO
;
615 mColumnWidth
.SetAutoValue();
616 mColumnGap
.SetNormalValue();
619 nsStyleColumn::~nsStyleColumn()
623 nsStyleColumn::nsStyleColumn(const nsStyleColumn
& aSource
)
625 memcpy((nsStyleColumn
*)this, &aSource
, sizeof(nsStyleColumn
));
628 nsChangeHint
nsStyleColumn::CalcDifference(const nsStyleColumn
& aOther
) const
630 if ((mColumnWidth
.GetUnit() == eStyleUnit_Auto
)
631 != (aOther
.mColumnWidth
.GetUnit() == eStyleUnit_Auto
) ||
632 mColumnCount
!= aOther
.mColumnCount
)
633 // We force column count changes to do a reframe, because it's tricky to handle
634 // some edge cases where the column count gets smaller and content overflows.
636 return nsChangeHint_ReconstructFrame
;
638 if (mColumnWidth
!= aOther
.mColumnWidth
||
639 mColumnGap
!= aOther
.mColumnGap
)
640 return nsChangeHint_ReflowFrame
;
642 return NS_STYLE_HINT_NONE
;
647 nsChangeHint
nsStyleColumn::MaxDifference()
649 return NS_CombineHint(nsChangeHint_ReconstructFrame
,
650 nsChangeHint_ReflowFrame
);
655 // --------------------
658 nsStyleSVG::nsStyleSVG()
660 mFill
.mType
= eStyleSVGPaintType_Color
;
661 mFill
.mPaint
.mColor
= NS_RGB(0,0,0);
662 mFill
.mFallbackColor
= NS_RGB(0,0,0);
663 mStroke
.mType
= eStyleSVGPaintType_None
;
664 mStroke
.mPaint
.mColor
= NS_RGB(0,0,0);
665 mStroke
.mFallbackColor
= NS_RGB(0,0,0);
666 mStrokeDasharray
= nsnull
;
668 mStrokeDashoffset
.SetCoordValue(0);
669 mStrokeWidth
.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
672 mStrokeMiterlimit
= 4.0f
;
673 mStrokeOpacity
= 1.0f
;
675 mStrokeDasharrayLength
= 0;
676 mClipRule
= NS_STYLE_FILL_RULE_NONZERO
;
677 mColorInterpolation
= NS_STYLE_COLOR_INTERPOLATION_SRGB
;
678 mColorInterpolationFilters
= NS_STYLE_COLOR_INTERPOLATION_LINEARRGB
;
679 mFillRule
= NS_STYLE_FILL_RULE_NONZERO
;
680 mPointerEvents
= NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED
;
681 mShapeRendering
= NS_STYLE_SHAPE_RENDERING_AUTO
;
682 mStrokeLinecap
= NS_STYLE_STROKE_LINECAP_BUTT
;
683 mStrokeLinejoin
= NS_STYLE_STROKE_LINEJOIN_MITER
;
684 mTextAnchor
= NS_STYLE_TEXT_ANCHOR_START
;
685 mTextRendering
= NS_STYLE_TEXT_RENDERING_AUTO
;
688 nsStyleSVG::~nsStyleSVG()
690 delete [] mStrokeDasharray
;
693 nsStyleSVG::nsStyleSVG(const nsStyleSVG
& aSource
)
695 //memcpy((nsStyleSVG*)this, &aSource, sizeof(nsStyleSVG));
697 mFill
= aSource
.mFill
;
698 mStroke
= aSource
.mStroke
;
700 mMarkerEnd
= aSource
.mMarkerEnd
;
701 mMarkerMid
= aSource
.mMarkerMid
;
702 mMarkerStart
= aSource
.mMarkerStart
;
704 mStrokeDasharrayLength
= aSource
.mStrokeDasharrayLength
;
705 if (aSource
.mStrokeDasharray
) {
706 mStrokeDasharray
= new nsStyleCoord
[mStrokeDasharrayLength
];
707 if (mStrokeDasharray
)
708 memcpy(mStrokeDasharray
,
709 aSource
.mStrokeDasharray
,
710 mStrokeDasharrayLength
* sizeof(nsStyleCoord
));
712 mStrokeDasharrayLength
= 0;
714 mStrokeDasharray
= nsnull
;
717 mStrokeDashoffset
= aSource
.mStrokeDashoffset
;
718 mStrokeWidth
= aSource
.mStrokeWidth
;
720 mFillOpacity
= aSource
.mFillOpacity
;
721 mStrokeMiterlimit
= aSource
.mStrokeMiterlimit
;
722 mStrokeOpacity
= aSource
.mStrokeOpacity
;
724 mClipRule
= aSource
.mClipRule
;
725 mColorInterpolation
= aSource
.mColorInterpolation
;
726 mColorInterpolationFilters
= aSource
.mColorInterpolationFilters
;
727 mFillRule
= aSource
.mFillRule
;
728 mPointerEvents
= aSource
.mPointerEvents
;
729 mShapeRendering
= aSource
.mShapeRendering
;
730 mStrokeLinecap
= aSource
.mStrokeLinecap
;
731 mStrokeLinejoin
= aSource
.mStrokeLinejoin
;
732 mTextAnchor
= aSource
.mTextAnchor
;
733 mTextRendering
= aSource
.mTextRendering
;
736 nsChangeHint
nsStyleSVG::CalcDifference(const nsStyleSVG
& aOther
) const
738 if ( mFill
!= aOther
.mFill
||
739 mStroke
!= aOther
.mStroke
||
741 !EqualURIs(mMarkerEnd
, aOther
.mMarkerEnd
) ||
742 !EqualURIs(mMarkerMid
, aOther
.mMarkerMid
) ||
743 !EqualURIs(mMarkerStart
, aOther
.mMarkerStart
) ||
745 mStrokeDashoffset
!= aOther
.mStrokeDashoffset
||
746 mStrokeWidth
!= aOther
.mStrokeWidth
||
748 mFillOpacity
!= aOther
.mFillOpacity
||
749 mStrokeMiterlimit
!= aOther
.mStrokeMiterlimit
||
750 mStrokeOpacity
!= aOther
.mStrokeOpacity
||
752 mClipRule
!= aOther
.mClipRule
||
753 mColorInterpolation
!= aOther
.mColorInterpolation
||
754 mColorInterpolationFilters
!= aOther
.mColorInterpolationFilters
||
755 mFillRule
!= aOther
.mFillRule
||
756 mPointerEvents
!= aOther
.mPointerEvents
||
757 mShapeRendering
!= aOther
.mShapeRendering
||
758 mStrokeDasharrayLength
!= aOther
.mStrokeDasharrayLength
||
759 mStrokeLinecap
!= aOther
.mStrokeLinecap
||
760 mStrokeLinejoin
!= aOther
.mStrokeLinejoin
||
761 mTextAnchor
!= aOther
.mTextAnchor
||
762 mTextRendering
!= aOther
.mTextRendering
)
763 return NS_STYLE_HINT_VISUAL
;
765 // length of stroke dasharrays are the same (tested above) - check entries
766 for (PRUint32 i
=0; i
<mStrokeDasharrayLength
; i
++)
767 if (mStrokeDasharray
[i
] != aOther
.mStrokeDasharray
[i
])
768 return NS_STYLE_HINT_VISUAL
;
770 return NS_STYLE_HINT_NONE
;
775 nsChangeHint
nsStyleSVG::MaxDifference()
777 return NS_STYLE_HINT_VISUAL
;
781 // --------------------
784 nsStyleSVGReset::nsStyleSVGReset()
786 mStopColor
= NS_RGB(0,0,0);
787 mFloodColor
= NS_RGB(0,0,0);
788 mLightingColor
= NS_RGB(255,255,255);
793 mFloodOpacity
= 1.0f
;
794 mDominantBaseline
= NS_STYLE_DOMINANT_BASELINE_AUTO
;
797 nsStyleSVGReset::~nsStyleSVGReset()
801 nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset
& aSource
)
803 mStopColor
= aSource
.mStopColor
;
804 mFloodColor
= aSource
.mFloodColor
;
805 mLightingColor
= aSource
.mLightingColor
;
806 mClipPath
= aSource
.mClipPath
;
807 mFilter
= aSource
.mFilter
;
808 mMask
= aSource
.mMask
;
809 mStopOpacity
= aSource
.mStopOpacity
;
810 mFloodOpacity
= aSource
.mFloodOpacity
;
811 mDominantBaseline
= aSource
.mDominantBaseline
;
814 nsChangeHint
nsStyleSVGReset::CalcDifference(const nsStyleSVGReset
& aOther
) const
816 if (mStopColor
!= aOther
.mStopColor
||
817 mFloodColor
!= aOther
.mFloodColor
||
818 mLightingColor
!= aOther
.mLightingColor
||
819 !EqualURIs(mClipPath
, aOther
.mClipPath
) ||
820 !EqualURIs(mFilter
, aOther
.mFilter
) ||
821 !EqualURIs(mMask
, aOther
.mMask
) ||
822 mStopOpacity
!= aOther
.mStopOpacity
||
823 mFloodOpacity
!= aOther
.mFloodOpacity
||
824 mDominantBaseline
!= aOther
.mDominantBaseline
)
825 return NS_STYLE_HINT_VISUAL
;
827 return NS_STYLE_HINT_NONE
;
832 nsChangeHint
nsStyleSVGReset::MaxDifference()
834 return NS_STYLE_HINT_VISUAL
;
838 // nsStyleSVGPaint implementation
839 nsStyleSVGPaint::~nsStyleSVGPaint()
841 if (mType
== eStyleSVGPaintType_Server
) {
842 NS_IF_RELEASE(mPaint
.mPaintServer
);
847 nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType
)
849 if (mType
== eStyleSVGPaintType_Server
) {
850 this->~nsStyleSVGPaint();
851 new (this) nsStyleSVGPaint();
856 nsStyleSVGPaint
& nsStyleSVGPaint::operator=(const nsStyleSVGPaint
& aOther
)
861 SetType(aOther
.mType
);
863 mFallbackColor
= aOther
.mFallbackColor
;
864 if (mType
== eStyleSVGPaintType_Server
) {
865 mPaint
.mPaintServer
= aOther
.mPaint
.mPaintServer
;
866 NS_IF_ADDREF(mPaint
.mPaintServer
);
868 mPaint
.mColor
= aOther
.mPaint
.mColor
;
873 PRBool
nsStyleSVGPaint::operator==(const nsStyleSVGPaint
& aOther
) const
875 if (mType
!= aOther
.mType
)
877 if (mType
== eStyleSVGPaintType_Server
)
878 return EqualURIs(mPaint
.mPaintServer
, aOther
.mPaint
.mPaintServer
) &&
879 mFallbackColor
== aOther
.mFallbackColor
;
880 if (mType
== eStyleSVGPaintType_None
)
882 return mPaint
.mColor
== aOther
.mPaint
.mColor
;
888 // --------------------
891 nsStylePosition::nsStylePosition(void)
893 // positioning values not inherited
894 nsStyleCoord
autoCoord(eStyleUnit_Auto
);
895 mOffset
.SetLeft(autoCoord
);
896 mOffset
.SetTop(autoCoord
);
897 mOffset
.SetRight(autoCoord
);
898 mOffset
.SetBottom(autoCoord
);
899 mWidth
.SetAutoValue();
900 mMinWidth
.SetCoordValue(0);
901 mMaxWidth
.SetNoneValue();
902 mHeight
.SetAutoValue();
903 mMinHeight
.SetCoordValue(0);
904 mMaxHeight
.SetNoneValue();
905 mBoxSizing
= NS_STYLE_BOX_SIZING_CONTENT
;
906 mZIndex
.SetAutoValue();
909 nsStylePosition::~nsStylePosition(void)
913 nsStylePosition::nsStylePosition(const nsStylePosition
& aSource
)
915 memcpy((nsStylePosition
*)this, &aSource
, sizeof(nsStylePosition
));
918 nsChangeHint
nsStylePosition::CalcDifference(const nsStylePosition
& aOther
) const
920 if (mZIndex
!= aOther
.mZIndex
) {
921 return NS_STYLE_HINT_REFLOW
;
924 if ((mOffset
== aOther
.mOffset
) &&
925 (mWidth
== aOther
.mWidth
) &&
926 (mMinWidth
== aOther
.mMinWidth
) &&
927 (mMaxWidth
== aOther
.mMaxWidth
) &&
928 (mHeight
== aOther
.mHeight
) &&
929 (mMinHeight
== aOther
.mMinHeight
) &&
930 (mMaxHeight
== aOther
.mMaxHeight
) &&
931 (mBoxSizing
== aOther
.mBoxSizing
))
932 return NS_STYLE_HINT_NONE
;
934 return nsChangeHint_ReflowFrame
;
939 nsChangeHint
nsStylePosition::MaxDifference()
941 return NS_STYLE_HINT_REFLOW
;
945 // --------------------
949 nsStyleTable::nsStyleTable()
951 // values not inherited
952 mLayoutStrategy
= NS_STYLE_TABLE_LAYOUT_AUTO
;
953 mCols
= NS_STYLE_TABLE_COLS_NONE
;
954 mFrame
= NS_STYLE_TABLE_FRAME_NONE
;
955 mRules
= NS_STYLE_TABLE_RULES_NONE
;
959 nsStyleTable::~nsStyleTable(void)
963 nsStyleTable::nsStyleTable(const nsStyleTable
& aSource
)
965 memcpy((nsStyleTable
*)this, &aSource
, sizeof(nsStyleTable
));
968 nsChangeHint
nsStyleTable::CalcDifference(const nsStyleTable
& aOther
) const
970 // Changes in mRules may require reframing (if border-collapse stuff changes, for example).
971 if (mRules
!= aOther
.mRules
|| mSpan
!= aOther
.mSpan
||
972 mLayoutStrategy
!= aOther
.mLayoutStrategy
)
973 return NS_STYLE_HINT_FRAMECHANGE
;
974 if (mFrame
!= aOther
.mFrame
|| mCols
!= aOther
.mCols
)
975 return NS_STYLE_HINT_REFLOW
;
976 return NS_STYLE_HINT_NONE
;
981 nsChangeHint
nsStyleTable::MaxDifference()
983 return NS_STYLE_HINT_FRAMECHANGE
;
987 // -----------------------
988 // nsStyleTableBorder
990 nsStyleTableBorder::nsStyleTableBorder(nsPresContext
* aPresContext
)
992 mBorderCollapse
= NS_STYLE_BORDER_SEPARATE
;
994 nsCompatibility compatMode
= eCompatibility_FullStandards
;
996 compatMode
= aPresContext
->CompatibilityMode();
997 mEmptyCells
= (compatMode
== eCompatibility_NavQuirks
)
998 ? NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND
999 : NS_STYLE_TABLE_EMPTY_CELLS_SHOW
;
1000 mCaptionSide
= NS_STYLE_CAPTION_SIDE_TOP
;
1001 mBorderSpacingX
.SetCoordValue(0);
1002 mBorderSpacingY
.SetCoordValue(0);
1005 nsStyleTableBorder::~nsStyleTableBorder(void)
1009 nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder
& aSource
)
1011 memcpy((nsStyleTableBorder
*)this, &aSource
, sizeof(nsStyleTableBorder
));
1014 nsChangeHint
nsStyleTableBorder::CalcDifference(const nsStyleTableBorder
& aOther
) const
1016 // Border-collapse changes need a reframe, because we use a different frame
1017 // class for table cells in the collapsed border model. This is used to
1018 // conserve memory when using the separated border model (collapsed borders
1019 // require extra state to be stored).
1020 if (mBorderCollapse
!= aOther
.mBorderCollapse
) {
1021 return NS_STYLE_HINT_FRAMECHANGE
;
1024 if ((mCaptionSide
== aOther
.mCaptionSide
) &&
1025 (mBorderSpacingX
== aOther
.mBorderSpacingX
) &&
1026 (mBorderSpacingY
== aOther
.mBorderSpacingY
)) {
1027 if (mEmptyCells
== aOther
.mEmptyCells
)
1028 return NS_STYLE_HINT_NONE
;
1029 return NS_STYLE_HINT_VISUAL
;
1032 return NS_STYLE_HINT_REFLOW
;
1037 nsChangeHint
nsStyleTableBorder::MaxDifference()
1039 return NS_STYLE_HINT_FRAMECHANGE
;
1043 // --------------------
1047 nsStyleColor::nsStyleColor(nsPresContext
* aPresContext
)
1049 mColor
= aPresContext
->DefaultColor();
1052 nsStyleColor::nsStyleColor(const nsStyleColor
& aSource
)
1054 mColor
= aSource
.mColor
;
1057 nsChangeHint
nsStyleColor::CalcDifference(const nsStyleColor
& aOther
) const
1059 if (mColor
== aOther
.mColor
)
1060 return NS_STYLE_HINT_NONE
;
1061 return NS_STYLE_HINT_VISUAL
;
1066 nsChangeHint
nsStyleColor::MaxDifference()
1068 return NS_STYLE_HINT_VISUAL
;
1072 // --------------------
1073 // nsStyleBackground
1076 nsStyleBackground::nsStyleBackground(nsPresContext
* aPresContext
)
1077 : mBackgroundFlags(NS_STYLE_BG_COLOR_TRANSPARENT
| NS_STYLE_BG_IMAGE_NONE
),
1078 mBackgroundAttachment(NS_STYLE_BG_ATTACHMENT_SCROLL
),
1079 mBackgroundClip(NS_STYLE_BG_CLIP_BORDER
),
1080 mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS
),
1081 mBackgroundOrigin(NS_STYLE_BG_ORIGIN_PADDING
),
1082 mBackgroundRepeat(NS_STYLE_BG_REPEAT_XY
)
1084 mBackgroundColor
= aPresContext
->DefaultBackgroundColor();
1087 nsStyleBackground::nsStyleBackground(const nsStyleBackground
& aSource
)
1088 : mBackgroundFlags(aSource
.mBackgroundFlags
),
1089 mBackgroundAttachment(aSource
.mBackgroundAttachment
),
1090 mBackgroundClip(aSource
.mBackgroundClip
),
1091 mBackgroundInlinePolicy(aSource
.mBackgroundInlinePolicy
),
1092 mBackgroundOrigin(aSource
.mBackgroundOrigin
),
1093 mBackgroundRepeat(aSource
.mBackgroundRepeat
),
1094 mBackgroundXPosition(aSource
.mBackgroundXPosition
),
1095 mBackgroundYPosition(aSource
.mBackgroundYPosition
),
1096 mBackgroundColor(aSource
.mBackgroundColor
),
1097 mBackgroundImage(aSource
.mBackgroundImage
)
1101 nsStyleBackground::~nsStyleBackground()
1105 nsChangeHint
nsStyleBackground::CalcDifference(const nsStyleBackground
& aOther
) const
1107 if ((mBackgroundAttachment
== aOther
.mBackgroundAttachment
) &&
1108 (mBackgroundFlags
== aOther
.mBackgroundFlags
) &&
1109 (mBackgroundRepeat
== aOther
.mBackgroundRepeat
) &&
1110 (mBackgroundColor
== aOther
.mBackgroundColor
) &&
1111 (mBackgroundClip
== aOther
.mBackgroundClip
) &&
1112 (mBackgroundInlinePolicy
== aOther
.mBackgroundInlinePolicy
) &&
1113 (mBackgroundOrigin
== aOther
.mBackgroundOrigin
) &&
1114 EqualImages(mBackgroundImage
, aOther
.mBackgroundImage
) &&
1115 ((!(mBackgroundFlags
& NS_STYLE_BG_X_POSITION_PERCENT
) ||
1116 (mBackgroundXPosition
.mFloat
== aOther
.mBackgroundXPosition
.mFloat
)) &&
1117 (!(mBackgroundFlags
& NS_STYLE_BG_X_POSITION_LENGTH
) ||
1118 (mBackgroundXPosition
.mCoord
== aOther
.mBackgroundXPosition
.mCoord
))) &&
1119 ((!(mBackgroundFlags
& NS_STYLE_BG_Y_POSITION_PERCENT
) ||
1120 (mBackgroundYPosition
.mFloat
== aOther
.mBackgroundYPosition
.mFloat
)) &&
1121 (!(mBackgroundFlags
& NS_STYLE_BG_Y_POSITION_LENGTH
) ||
1122 (mBackgroundYPosition
.mCoord
== aOther
.mBackgroundYPosition
.mCoord
))))
1123 return NS_STYLE_HINT_NONE
;
1124 return NS_STYLE_HINT_VISUAL
;
1129 nsChangeHint
nsStyleBackground::MaxDifference()
1131 return NS_STYLE_HINT_VISUAL
;
1135 PRBool
nsStyleBackground::HasFixedBackground() const
1137 return mBackgroundAttachment
== NS_STYLE_BG_ATTACHMENT_FIXED
&&
1141 // --------------------
1145 nsStyleDisplay::nsStyleDisplay()
1147 mAppearance
= NS_THEME_NONE
;
1148 mDisplay
= NS_STYLE_DISPLAY_INLINE
;
1149 mOriginalDisplay
= NS_STYLE_DISPLAY_NONE
;
1150 mPosition
= NS_STYLE_POSITION_STATIC
;
1151 mFloats
= NS_STYLE_FLOAT_NONE
;
1152 mBreakType
= NS_STYLE_CLEAR_NONE
;
1153 mBreakBefore
= PR_FALSE
;
1154 mBreakAfter
= PR_FALSE
;
1155 mOverflowX
= NS_STYLE_OVERFLOW_VISIBLE
;
1156 mOverflowY
= NS_STYLE_OVERFLOW_VISIBLE
;
1157 mClipFlags
= NS_STYLE_CLIP_AUTO
;
1158 mClip
.SetRect(0,0,0,0);
1162 nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay
& aSource
)
1164 mAppearance
= aSource
.mAppearance
;
1165 mDisplay
= aSource
.mDisplay
;
1166 mOriginalDisplay
= aSource
.mOriginalDisplay
;
1167 mBinding
= aSource
.mBinding
;
1168 mPosition
= aSource
.mPosition
;
1169 mFloats
= aSource
.mFloats
;
1170 mBreakType
= aSource
.mBreakType
;
1171 mBreakBefore
= aSource
.mBreakBefore
;
1172 mBreakAfter
= aSource
.mBreakAfter
;
1173 mOverflowX
= aSource
.mOverflowX
;
1174 mOverflowY
= aSource
.mOverflowY
;
1175 mClipFlags
= aSource
.mClipFlags
;
1176 mClip
= aSource
.mClip
;
1177 mOpacity
= aSource
.mOpacity
;
1180 nsChangeHint
nsStyleDisplay::CalcDifference(const nsStyleDisplay
& aOther
) const
1182 nsChangeHint hint
= nsChangeHint(0);
1184 if (!EqualURIs(mBinding
, aOther
.mBinding
)
1185 || mPosition
!= aOther
.mPosition
1186 || mDisplay
!= aOther
.mDisplay
1187 || (mFloats
== NS_STYLE_FLOAT_NONE
) != (aOther
.mFloats
== NS_STYLE_FLOAT_NONE
)
1188 || mOverflowX
!= aOther
.mOverflowX
1189 || mOverflowY
!= aOther
.mOverflowY
)
1190 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
1192 if (mFloats
!= aOther
.mFloats
)
1193 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
1195 if (mClipFlags
!= aOther
.mClipFlags
|| mClip
!= aOther
.mClip
) {
1196 NS_UpdateHint(hint
, nsChangeHint_ReflowFrame
);
1198 // XXX the following is conservative, for now: changing float breaking shouldn't
1199 // necessarily require a repaint, reflow should suffice.
1200 if (mBreakType
!= aOther
.mBreakType
1201 || mBreakBefore
!= aOther
.mBreakBefore
1202 || mBreakAfter
!= aOther
.mBreakAfter
1203 || mAppearance
!= aOther
.mAppearance
)
1204 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_ReflowFrame
, nsChangeHint_RepaintFrame
));
1206 if (mOpacity
!= aOther
.mOpacity
)
1207 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1214 nsChangeHint
nsStyleDisplay::MaxDifference()
1216 // All the parts of FRAMECHANGE are present above in CalcDifference.
1217 return NS_STYLE_HINT_FRAMECHANGE
;
1221 // --------------------
1222 // nsStyleVisibility
1225 nsStyleVisibility::nsStyleVisibility(nsPresContext
* aPresContext
)
1227 PRUint32 bidiOptions
= aPresContext
->GetBidi();
1228 if (GET_BIDI_OPTION_DIRECTION(bidiOptions
) == IBMBIDI_TEXTDIRECTION_RTL
)
1229 mDirection
= NS_STYLE_DIRECTION_RTL
;
1231 mDirection
= NS_STYLE_DIRECTION_LTR
;
1233 mLangGroup
= aPresContext
->GetLangGroup();
1234 mVisible
= NS_STYLE_VISIBILITY_VISIBLE
;
1237 nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility
& aSource
)
1239 mDirection
= aSource
.mDirection
;
1240 mVisible
= aSource
.mVisible
;
1241 mLangGroup
= aSource
.mLangGroup
;
1244 nsChangeHint
nsStyleVisibility::CalcDifference(const nsStyleVisibility
& aOther
) const
1246 if ((mDirection
== aOther
.mDirection
) &&
1247 (mLangGroup
== aOther
.mLangGroup
)) {
1248 if ((mVisible
== aOther
.mVisible
)) {
1249 return NS_STYLE_HINT_NONE
;
1251 if ((NS_STYLE_VISIBILITY_COLLAPSE
== mVisible
) ||
1252 (NS_STYLE_VISIBILITY_COLLAPSE
== aOther
.mVisible
)) {
1253 return NS_STYLE_HINT_REFLOW
;
1255 return NS_STYLE_HINT_VISUAL
;
1257 return NS_STYLE_HINT_REFLOW
;
1262 nsChangeHint
nsStyleVisibility::MaxDifference()
1264 return NS_STYLE_HINT_REFLOW
;
1268 nsStyleContentData::~nsStyleContentData()
1270 if (mType
== eStyleContentType_Image
) {
1271 NS_IF_RELEASE(mContent
.mImage
);
1272 } else if (mType
== eStyleContentType_Counter
||
1273 mType
== eStyleContentType_Counters
) {
1274 mContent
.mCounters
->Release();
1275 } else if (mContent
.mString
) {
1276 NS_Free(mContent
.mString
);
1280 nsStyleContentData
& nsStyleContentData::operator=(const nsStyleContentData
& aOther
)
1282 if (this == &aOther
)
1284 this->~nsStyleContentData();
1285 new (this) nsStyleContentData();
1287 mType
= aOther
.mType
;
1288 if (mType
== eStyleContentType_Image
) {
1289 mContent
.mImage
= aOther
.mContent
.mImage
;
1290 NS_IF_ADDREF(mContent
.mImage
);
1291 } else if (mType
== eStyleContentType_Counter
||
1292 mType
== eStyleContentType_Counters
) {
1293 mContent
.mCounters
= aOther
.mContent
.mCounters
;
1294 mContent
.mCounters
->AddRef();
1295 } else if (aOther
.mContent
.mString
) {
1296 mContent
.mString
= NS_strdup(aOther
.mContent
.mString
);
1298 mContent
.mString
= nsnull
;
1303 PRBool
nsStyleContentData::operator==(const nsStyleContentData
& aOther
) const
1305 if (mType
!= aOther
.mType
)
1307 if (mType
== eStyleContentType_Image
) {
1308 if (!mContent
.mImage
|| !aOther
.mContent
.mImage
)
1309 return mContent
.mImage
== aOther
.mContent
.mImage
;
1311 nsCOMPtr
<nsIURI
> thisURI
, otherURI
;
1312 mContent
.mImage
->GetURI(getter_AddRefs(thisURI
));
1313 aOther
.mContent
.mImage
->GetURI(getter_AddRefs(otherURI
));
1314 return thisURI
== otherURI
|| // handles null==null
1315 (thisURI
&& otherURI
&&
1316 NS_SUCCEEDED(thisURI
->Equals(otherURI
, &eq
)) &&
1319 if (mType
== eStyleContentType_Counter
||
1320 mType
== eStyleContentType_Counters
)
1321 return *mContent
.mCounters
== *aOther
.mContent
.mCounters
;
1322 return nsCRT::strcmp(mContent
.mString
, aOther
.mContent
.mString
) == 0;
1325 //-----------------------
1329 nsStyleContent::nsStyleContent(void)
1334 mIncrements(nsnull
),
1338 mMarkerOffset
.SetAutoValue();
1341 nsStyleContent::~nsStyleContent(void)
1343 DELETE_ARRAY_IF(mContents
);
1344 DELETE_ARRAY_IF(mIncrements
);
1345 DELETE_ARRAY_IF(mResets
);
1348 nsStyleContent::nsStyleContent(const nsStyleContent
& aSource
)
1353 mIncrements(nsnull
),
1358 mMarkerOffset
= aSource
.mMarkerOffset
;
1361 if (NS_SUCCEEDED(AllocateContents(aSource
.ContentCount()))) {
1362 for (index
= 0; index
< mContentCount
; index
++) {
1363 ContentAt(index
) = aSource
.ContentAt(index
);
1367 if (NS_SUCCEEDED(AllocateCounterIncrements(aSource
.CounterIncrementCount()))) {
1368 for (index
= 0; index
< mIncrementCount
; index
++) {
1369 const nsStyleCounterData
*data
= aSource
.GetCounterIncrementAt(index
);
1370 mIncrements
[index
].mCounter
= data
->mCounter
;
1371 mIncrements
[index
].mValue
= data
->mValue
;
1375 if (NS_SUCCEEDED(AllocateCounterResets(aSource
.CounterResetCount()))) {
1376 for (index
= 0; index
< mResetCount
; index
++) {
1377 const nsStyleCounterData
*data
= aSource
.GetCounterResetAt(index
);
1378 mResets
[index
].mCounter
= data
->mCounter
;
1379 mResets
[index
].mValue
= data
->mValue
;
1384 nsChangeHint
nsStyleContent::CalcDifference(const nsStyleContent
& aOther
) const
1386 if (mContentCount
!= aOther
.mContentCount
||
1387 mIncrementCount
!= aOther
.mIncrementCount
||
1388 mResetCount
!= aOther
.mResetCount
) {
1389 return NS_STYLE_HINT_FRAMECHANGE
;
1392 PRUint32 ix
= mContentCount
;
1394 if (mContents
[ix
] != aOther
.mContents
[ix
]) {
1395 // Unfortunately we need to reframe here; a simple reflow
1396 // will not pick up different text or different image URLs,
1397 // since we set all that up in the CSSFrameConstructor
1398 return NS_STYLE_HINT_FRAMECHANGE
;
1401 ix
= mIncrementCount
;
1403 if ((mIncrements
[ix
].mValue
!= aOther
.mIncrements
[ix
].mValue
) ||
1404 (mIncrements
[ix
].mCounter
!= aOther
.mIncrements
[ix
].mCounter
)) {
1405 return NS_STYLE_HINT_FRAMECHANGE
;
1410 if ((mResets
[ix
].mValue
!= aOther
.mResets
[ix
].mValue
) ||
1411 (mResets
[ix
].mCounter
!= aOther
.mResets
[ix
].mCounter
)) {
1412 return NS_STYLE_HINT_FRAMECHANGE
;
1415 if (mMarkerOffset
!= aOther
.mMarkerOffset
) {
1416 return NS_STYLE_HINT_REFLOW
;
1418 return NS_STYLE_HINT_NONE
;
1423 nsChangeHint
nsStyleContent::MaxDifference()
1425 return NS_STYLE_HINT_FRAMECHANGE
;
1429 nsresult
nsStyleContent::AllocateContents(PRUint32 aCount
)
1431 // We need to run the destructors of the elements of mContents, so we
1432 // delete and reallocate even if aCount == mContentCount. (If
1433 // nsStyleContentData had its members private and managed their
1434 // ownership on setting, we wouldn't need this, but that seems
1435 // unnecessary at this point.)
1436 DELETE_ARRAY_IF(mContents
);
1438 mContents
= new nsStyleContentData
[aCount
];
1441 return NS_ERROR_OUT_OF_MEMORY
;
1444 mContentCount
= aCount
;
1448 // ---------------------
1452 nsStyleQuotes::nsStyleQuotes(void)
1458 nsStyleQuotes::~nsStyleQuotes(void)
1460 DELETE_ARRAY_IF(mQuotes
);
1463 nsStyleQuotes::nsStyleQuotes(const nsStyleQuotes
& aSource
)
1467 if (NS_SUCCEEDED(AllocateQuotes(aSource
.QuotesCount()))) {
1468 PRUint32 count
= (mQuotesCount
* 2);
1469 for (PRUint32 index
= 0; index
< count
; index
+= 2) {
1470 aSource
.GetQuotesAt(index
, mQuotes
[index
], mQuotes
[index
+ 1]);
1475 nsChangeHint
nsStyleQuotes::CalcDifference(const nsStyleQuotes
& aOther
) const
1477 // If the quotes implementation is ever going to change we might not need
1478 // a framechange here and a reflow should be sufficient. See bug 35768.
1479 if (mQuotesCount
== aOther
.mQuotesCount
) {
1480 PRUint32 ix
= (mQuotesCount
* 2);
1482 if (mQuotes
[ix
] != aOther
.mQuotes
[ix
]) {
1483 return NS_STYLE_HINT_FRAMECHANGE
;
1487 return NS_STYLE_HINT_NONE
;
1489 return NS_STYLE_HINT_FRAMECHANGE
;
1494 nsChangeHint
nsStyleQuotes::MaxDifference()
1496 return NS_STYLE_HINT_FRAMECHANGE
;
1500 // --------------------
1504 nsStyleTextReset::nsStyleTextReset(void)
1506 mVerticalAlign
.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE
, eStyleUnit_Enumerated
);
1507 mTextDecoration
= NS_STYLE_TEXT_DECORATION_NONE
;
1508 mUnicodeBidi
= NS_STYLE_UNICODE_BIDI_NORMAL
;
1511 nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset
& aSource
)
1513 memcpy((nsStyleTextReset
*)this, &aSource
, sizeof(nsStyleTextReset
));
1516 nsStyleTextReset::~nsStyleTextReset(void) { }
1518 nsChangeHint
nsStyleTextReset::CalcDifference(const nsStyleTextReset
& aOther
) const
1520 if (mVerticalAlign
== aOther
.mVerticalAlign
1521 && mUnicodeBidi
== aOther
.mUnicodeBidi
) {
1522 if (mTextDecoration
!= aOther
.mTextDecoration
) {
1523 // Reflow for blink changes, repaint for others
1525 (mTextDecoration
& NS_STYLE_TEXT_DECORATION_BLINK
) ==
1526 (aOther
.mTextDecoration
& NS_STYLE_TEXT_DECORATION_BLINK
) ?
1527 NS_STYLE_HINT_VISUAL
: NS_STYLE_HINT_REFLOW
;
1530 return NS_STYLE_HINT_NONE
;
1532 return NS_STYLE_HINT_REFLOW
;
1537 nsChangeHint
nsStyleTextReset::MaxDifference()
1539 return NS_STYLE_HINT_REFLOW
;
1543 // --------------------
1547 nsStyleText::nsStyleText(void)
1549 mTextAlign
= NS_STYLE_TEXT_ALIGN_DEFAULT
;
1550 mTextTransform
= NS_STYLE_TEXT_TRANSFORM_NONE
;
1551 mWhiteSpace
= NS_STYLE_WHITESPACE_NORMAL
;
1553 mLetterSpacing
.SetNormalValue();
1554 mLineHeight
.SetNormalValue();
1555 mTextIndent
.SetCoordValue(0);
1556 mWordSpacing
.SetNormalValue();
1559 nsStyleText::nsStyleText(const nsStyleText
& aSource
)
1561 memcpy((nsStyleText
*)this, &aSource
, sizeof(nsStyleText
));
1564 nsStyleText::~nsStyleText(void) { }
1566 nsChangeHint
nsStyleText::CalcDifference(const nsStyleText
& aOther
) const
1568 if ((mTextAlign
== aOther
.mTextAlign
) &&
1569 (mTextTransform
== aOther
.mTextTransform
) &&
1570 (mWhiteSpace
== aOther
.mWhiteSpace
) &&
1571 (mLetterSpacing
== aOther
.mLetterSpacing
) &&
1572 (mLineHeight
== aOther
.mLineHeight
) &&
1573 (mTextIndent
== aOther
.mTextIndent
) &&
1574 (mWordSpacing
== aOther
.mWordSpacing
))
1575 return NS_STYLE_HINT_NONE
;
1576 return NS_STYLE_HINT_REFLOW
;
1581 nsChangeHint
nsStyleText::MaxDifference()
1583 return NS_STYLE_HINT_REFLOW
;
1587 //-----------------------
1588 // nsStyleUserInterface
1591 nsCursorImage::nsCursorImage()
1592 : mHaveHotspot(PR_FALSE
)
1598 nsStyleUserInterface::nsStyleUserInterface(void)
1600 mUserInput
= NS_STYLE_USER_INPUT_AUTO
;
1601 mUserModify
= NS_STYLE_USER_MODIFY_READ_ONLY
;
1602 mUserFocus
= NS_STYLE_USER_FOCUS_NONE
;
1604 mCursor
= NS_STYLE_CURSOR_AUTO
; // fix for bugzilla bug 51113
1606 mCursorArrayLength
= 0;
1607 mCursorArray
= nsnull
;
1610 nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface
& aSource
) :
1611 mUserInput(aSource
.mUserInput
),
1612 mUserModify(aSource
.mUserModify
),
1613 mUserFocus(aSource
.mUserFocus
),
1614 mCursor(aSource
.mCursor
)
1616 CopyCursorArrayFrom(aSource
);
1619 nsStyleUserInterface::~nsStyleUserInterface(void)
1621 delete [] mCursorArray
;
1624 nsChangeHint
nsStyleUserInterface::CalcDifference(const nsStyleUserInterface
& aOther
) const
1626 nsChangeHint hint
= nsChangeHint(0);
1627 if (mCursor
!= aOther
.mCursor
)
1628 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
1630 // We could do better. But it wouldn't be worth it, URL-specified cursors are
1632 if (mCursorArrayLength
> 0 || aOther
.mCursorArrayLength
> 0)
1633 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
1635 if (mUserModify
!= aOther
.mUserModify
)
1636 NS_UpdateHint(hint
, NS_STYLE_HINT_VISUAL
);
1638 if ((mUserInput
!= aOther
.mUserInput
) &&
1639 ((NS_STYLE_USER_INPUT_NONE
== mUserInput
) ||
1640 (NS_STYLE_USER_INPUT_NONE
== aOther
.mUserInput
))) {
1641 NS_UpdateHint(hint
, NS_STYLE_HINT_FRAMECHANGE
);
1644 // ignore mUserFocus
1651 nsChangeHint
nsStyleUserInterface::MaxDifference()
1653 return nsChangeHint(nsChangeHint_UpdateCursor
| NS_STYLE_HINT_FRAMECHANGE
);
1658 nsStyleUserInterface::CopyCursorArrayFrom(const nsStyleUserInterface
& aSource
)
1660 mCursorArray
= nsnull
;
1661 mCursorArrayLength
= 0;
1662 if (aSource
.mCursorArrayLength
) {
1663 mCursorArray
= new nsCursorImage
[aSource
.mCursorArrayLength
];
1665 mCursorArrayLength
= aSource
.mCursorArrayLength
;
1666 for (PRUint32 i
= 0; i
< mCursorArrayLength
; ++i
)
1667 mCursorArray
[i
] = aSource
.mCursorArray
[i
];
1672 //-----------------------
1676 nsStyleUIReset::nsStyleUIReset(void)
1678 mUserSelect
= NS_STYLE_USER_SELECT_AUTO
;
1679 mForceBrokenImageIcon
= 0;
1680 mIMEMode
= NS_STYLE_IME_MODE_AUTO
;
1683 nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset
& aSource
)
1685 mUserSelect
= aSource
.mUserSelect
;
1686 mForceBrokenImageIcon
= aSource
.mForceBrokenImageIcon
;
1687 mIMEMode
= aSource
.mIMEMode
;
1690 nsStyleUIReset::~nsStyleUIReset(void)
1694 nsChangeHint
nsStyleUIReset::CalcDifference(const nsStyleUIReset
& aOther
) const
1697 if (mForceBrokenImageIcon
== aOther
.mForceBrokenImageIcon
) {
1698 if (mUserSelect
== aOther
.mUserSelect
) {
1699 return NS_STYLE_HINT_NONE
;
1701 return NS_STYLE_HINT_VISUAL
;
1703 return NS_STYLE_HINT_FRAMECHANGE
;
1708 nsChangeHint
nsStyleUIReset::MaxDifference()
1710 return NS_STYLE_HINT_FRAMECHANGE
;