1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 * structs that contain the data provided by nsStyleContext, the
8 * internal API for computed style data for an element
11 #include "nsStyleStruct.h"
12 #include "nsStyleStructInlines.h"
13 #include "nsStyleConsts.h"
14 #include "nsThemeConstants.h"
16 #include "nsPresContext.h"
17 #include "nsIWidget.h"
18 #include "nsCRTGlue.h"
19 #include "nsCSSProps.h"
23 #include "nsBidiUtils.h"
24 #include "nsLayoutUtils.h"
26 #include "imgIRequest.h"
27 #include "imgIContainer.h"
28 #include "CounterStyleManager.h"
30 #include "mozilla/Likely.h"
32 #include "nsIDocument.h"
35 static_assert((((1 << nsStyleStructID_Length
) - 1) &
36 ~(NS_STYLE_INHERIT_MASK
)) == 0,
37 "Not enough bits in NS_STYLE_INHERIT_MASK");
39 inline bool IsFixedUnit(const nsStyleCoord
& aCoord
, bool aEnumOK
)
41 return aCoord
.ConvertsToLength() ||
42 (aEnumOK
&& aCoord
.GetUnit() == eStyleUnit_Enumerated
);
45 static bool EqualURIs(nsIURI
*aURI1
, nsIURI
*aURI2
)
48 return aURI1
== aURI2
|| // handle null==null, and optimize
50 NS_SUCCEEDED(aURI1
->Equals(aURI2
, &eq
)) && // not equal on fail
54 static bool EqualURIs(mozilla::css::URLValue
*aURI1
, mozilla::css::URLValue
*aURI2
)
56 return aURI1
== aURI2
|| // handle null==null, and optimize
57 (aURI1
&& aURI2
&& aURI1
->URIEquals(*aURI2
));
60 static bool EqualImages(imgIRequest
*aImage1
, imgIRequest
* aImage2
)
62 if (aImage1
== aImage2
) {
66 if (!aImage1
|| !aImage2
) {
70 nsCOMPtr
<nsIURI
> uri1
, uri2
;
71 aImage1
->GetURI(getter_AddRefs(uri1
));
72 aImage2
->GetURI(getter_AddRefs(uri2
));
73 return EqualURIs(uri1
, uri2
);
76 // A nullsafe wrapper for strcmp. We depend on null-safety.
77 static int safe_strcmp(const char16_t
* a
, const char16_t
* b
)
82 return NS_strcmp(a
, b
);
85 static nsChangeHint
CalcShadowDifference(nsCSSShadowArray
* lhs
,
86 nsCSSShadowArray
* rhs
);
88 // --------------------
91 nsStyleFont::nsStyleFont(const nsFont
& aFont
, nsPresContext
*aPresContext
)
93 , mGenericID(kGenericFont_NONE
)
94 , mExplicitLanguage(false)
96 MOZ_COUNT_CTOR(nsStyleFont
);
100 nsStyleFont::nsStyleFont(const nsStyleFont
& aSrc
)
103 , mGenericID(aSrc
.mGenericID
)
104 , mScriptLevel(aSrc
.mScriptLevel
)
105 , mMathVariant(aSrc
.mMathVariant
)
106 , mMathDisplay(aSrc
.mMathDisplay
)
107 , mExplicitLanguage(aSrc
.mExplicitLanguage
)
108 , mAllowZoom(aSrc
.mAllowZoom
)
109 , mScriptUnconstrainedSize(aSrc
.mScriptUnconstrainedSize
)
110 , mScriptMinSize(aSrc
.mScriptMinSize
)
111 , mScriptSizeMultiplier(aSrc
.mScriptSizeMultiplier
)
112 , mLanguage(aSrc
.mLanguage
)
114 MOZ_COUNT_CTOR(nsStyleFont
);
117 nsStyleFont::nsStyleFont(nsPresContext
* aPresContext
)
118 // passing nullptr to GetDefaultFont make it use the doc language
119 : mFont(*(aPresContext
->GetDefaultFont(kPresContext_DefaultVariableFont_ID
,
121 , mGenericID(kGenericFont_NONE
)
122 , mExplicitLanguage(false)
124 MOZ_COUNT_CTOR(nsStyleFont
);
129 nsStyleFont::Init(nsPresContext
* aPresContext
)
131 mSize
= mFont
.size
= nsStyleFont::ZoomText(aPresContext
, mFont
.size
);
132 mScriptUnconstrainedSize
= mSize
;
133 mScriptMinSize
= aPresContext
->CSSTwipsToAppUnits(
134 NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT
));
136 mScriptSizeMultiplier
= NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER
;
137 mMathVariant
= NS_MATHML_MATHVARIANT_NONE
;
138 mMathDisplay
= NS_MATHML_DISPLAYSTYLE_INLINE
;
141 nsAutoString language
;
142 aPresContext
->Document()->GetContentLanguage(language
);
143 language
.StripWhitespace();
145 // Content-Language may be a comma-separated list of language codes,
146 // in which case the HTML5 spec says to treat it as unknown
147 if (!language
.IsEmpty() &&
148 language
.FindChar(char16_t(',')) == kNotFound
) {
149 mLanguage
= do_GetAtom(language
);
150 // NOTE: This does *not* count as an explicit language; in other
151 // words, it doesn't trigger language-specific hyphenation.
153 // we didn't find a (usable) Content-Language, so we fall back
154 // to whatever the presContext guessed from the charset
155 mLanguage
= aPresContext
->GetLanguageFromCharset();
160 nsStyleFont::Destroy(nsPresContext
* aContext
) {
161 this->~nsStyleFont();
162 aContext
->PresShell()->
163 FreeByObjectID(nsPresArena::nsStyleFont_id
, this);
167 nsStyleFont::EnableZoom(nsPresContext
* aContext
, bool aEnable
)
169 if (mAllowZoom
== aEnable
) {
172 mAllowZoom
= aEnable
;
174 mSize
= nsStyleFont::ZoomText(aContext
, mSize
);
175 mFont
.size
= nsStyleFont::ZoomText(aContext
, mFont
.size
);
176 mScriptUnconstrainedSize
=
177 nsStyleFont::ZoomText(aContext
, mScriptUnconstrainedSize
);
179 mSize
= nsStyleFont::UnZoomText(aContext
, mSize
);
180 mFont
.size
= nsStyleFont::UnZoomText(aContext
, mFont
.size
);
181 mScriptUnconstrainedSize
=
182 nsStyleFont::UnZoomText(aContext
, mScriptUnconstrainedSize
);
186 nsChangeHint
nsStyleFont::CalcDifference(const nsStyleFont
& aOther
) const
188 MOZ_ASSERT(mAllowZoom
== aOther
.mAllowZoom
,
189 "expected mAllowZoom to be the same on both nsStyleFonts");
190 if (mSize
!= aOther
.mSize
||
191 mLanguage
!= aOther
.mLanguage
||
192 mExplicitLanguage
!= aOther
.mExplicitLanguage
||
193 mMathVariant
!= aOther
.mMathVariant
||
194 mMathDisplay
!= aOther
.mMathDisplay
) {
195 return NS_STYLE_HINT_REFLOW
;
198 nsChangeHint hint
= CalcFontDifference(mFont
, aOther
.mFont
);
203 // XXX Should any of these cause a non-nsChangeHint_NeutralChange change?
204 if (mGenericID
!= aOther
.mGenericID
||
205 mScriptLevel
!= aOther
.mScriptLevel
||
206 mScriptUnconstrainedSize
!= aOther
.mScriptUnconstrainedSize
||
207 mScriptMinSize
!= aOther
.mScriptMinSize
||
208 mScriptSizeMultiplier
!= aOther
.mScriptSizeMultiplier
) {
209 return nsChangeHint_NeutralChange
;
212 return NS_STYLE_HINT_NONE
;
216 nsStyleFont::ZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
218 return nscoord(float(aSize
) * aPresContext
->TextZoom());
222 nsStyleFont::UnZoomText(nsPresContext
*aPresContext
, nscoord aSize
)
224 return nscoord(float(aSize
) / aPresContext
->TextZoom());
227 nsChangeHint
nsStyleFont::CalcFontDifference(const nsFont
& aFont1
, const nsFont
& aFont2
)
229 if ((aFont1
.size
== aFont2
.size
) &&
230 (aFont1
.sizeAdjust
== aFont2
.sizeAdjust
) &&
231 (aFont1
.style
== aFont2
.style
) &&
232 (aFont1
.weight
== aFont2
.weight
) &&
233 (aFont1
.stretch
== aFont2
.stretch
) &&
234 (aFont1
.smoothing
== aFont2
.smoothing
) &&
235 (aFont1
.fontlist
== aFont2
.fontlist
) &&
236 (aFont1
.kerning
== aFont2
.kerning
) &&
237 (aFont1
.synthesis
== aFont2
.synthesis
) &&
238 (aFont1
.variantAlternates
== aFont2
.variantAlternates
) &&
239 (aFont1
.alternateValues
== aFont2
.alternateValues
) &&
240 (aFont1
.featureValueLookup
== aFont2
.featureValueLookup
) &&
241 (aFont1
.variantCaps
== aFont2
.variantCaps
) &&
242 (aFont1
.variantEastAsian
== aFont2
.variantEastAsian
) &&
243 (aFont1
.variantLigatures
== aFont2
.variantLigatures
) &&
244 (aFont1
.variantNumeric
== aFont2
.variantNumeric
) &&
245 (aFont1
.variantPosition
== aFont2
.variantPosition
) &&
246 (aFont1
.fontFeatureSettings
== aFont2
.fontFeatureSettings
) &&
247 (aFont1
.languageOverride
== aFont2
.languageOverride
) &&
248 (aFont1
.systemFont
== aFont2
.systemFont
)) {
249 if ((aFont1
.decorations
== aFont2
.decorations
)) {
250 return NS_STYLE_HINT_NONE
;
252 return NS_STYLE_HINT_VISUAL
;
254 return NS_STYLE_HINT_REFLOW
;
257 static bool IsFixedData(const nsStyleSides
& aSides
, bool aEnumOK
)
259 NS_FOR_CSS_SIDES(side
) {
260 if (!IsFixedUnit(aSides
.Get(side
), aEnumOK
))
266 static nscoord
CalcCoord(const nsStyleCoord
& aCoord
,
267 const nscoord
* aEnumTable
,
270 if (aCoord
.GetUnit() == eStyleUnit_Enumerated
) {
271 NS_ABORT_IF_FALSE(aEnumTable
, "must have enum table");
272 int32_t value
= aCoord
.GetIntValue();
273 if (0 <= value
&& value
< aNumEnums
) {
274 return aEnumTable
[aCoord
.GetIntValue()];
276 NS_NOTREACHED("unexpected enum value");
279 NS_ABORT_IF_FALSE(aCoord
.ConvertsToLength(), "unexpected unit");
280 return nsRuleNode::ComputeCoordPercentCalc(aCoord
, 0);
283 nsStyleMargin::nsStyleMargin()
284 : mHasCachedMargin(false)
285 , mCachedMargin(0, 0, 0, 0)
287 MOZ_COUNT_CTOR(nsStyleMargin
);
288 nsStyleCoord
zero(0, nsStyleCoord::CoordConstructor
);
289 NS_FOR_CSS_SIDES(side
) {
290 mMargin
.Set(side
, zero
);
294 nsStyleMargin::nsStyleMargin(const nsStyleMargin
& aSrc
)
295 : mMargin(aSrc
.mMargin
)
296 , mHasCachedMargin(false)
297 , mCachedMargin(0, 0, 0, 0)
299 MOZ_COUNT_CTOR(nsStyleMargin
);
303 nsStyleMargin::Destroy(nsPresContext
* aContext
) {
304 this->~nsStyleMargin();
305 aContext
->PresShell()->
306 FreeByObjectID(nsPresArena::nsStyleMargin_id
, this);
310 void nsStyleMargin::RecalcData()
312 if (IsFixedData(mMargin
, false)) {
313 NS_FOR_CSS_SIDES(side
) {
314 mCachedMargin
.Side(side
) = CalcCoord(mMargin
.Get(side
), nullptr, 0);
316 mHasCachedMargin
= true;
319 mHasCachedMargin
= false;
322 nsChangeHint
nsStyleMargin::CalcDifference(const nsStyleMargin
& aOther
) const
324 if (mMargin
== aOther
.mMargin
) {
325 return NS_STYLE_HINT_NONE
;
327 // Margin differences can't affect descendant intrinsic sizes and
328 // don't need to force children to reflow.
329 return NS_CombineHint(nsChangeHint_NeedReflow
,
330 nsChangeHint_ClearAncestorIntrinsics
);
333 nsStylePadding::nsStylePadding()
334 : mHasCachedPadding(false)
335 , mCachedPadding(0, 0, 0, 0)
337 MOZ_COUNT_CTOR(nsStylePadding
);
338 nsStyleCoord
zero(0, nsStyleCoord::CoordConstructor
);
339 NS_FOR_CSS_SIDES(side
) {
340 mPadding
.Set(side
, zero
);
344 nsStylePadding::nsStylePadding(const nsStylePadding
& aSrc
)
345 : mPadding(aSrc
.mPadding
)
346 , mHasCachedPadding(false)
347 , mCachedPadding(0, 0, 0, 0)
349 MOZ_COUNT_CTOR(nsStylePadding
);
353 nsStylePadding::Destroy(nsPresContext
* aContext
) {
354 this->~nsStylePadding();
355 aContext
->PresShell()->
356 FreeByObjectID(nsPresArena::nsStylePadding_id
, this);
359 void nsStylePadding::RecalcData()
361 if (IsFixedData(mPadding
, false)) {
362 NS_FOR_CSS_SIDES(side
) {
363 // Clamp negative calc() to 0.
364 mCachedPadding
.Side(side
) =
365 std::max(CalcCoord(mPadding
.Get(side
), nullptr, 0), 0);
367 mHasCachedPadding
= true;
370 mHasCachedPadding
= false;
373 nsChangeHint
nsStylePadding::CalcDifference(const nsStylePadding
& aOther
) const
375 if (mPadding
== aOther
.mPadding
) {
376 return NS_STYLE_HINT_NONE
;
378 // Padding differences can't affect descendant intrinsic sizes, but do need
379 // to force children to reflow so that we can reposition them, since their
380 // offsets are from our frame bounds but our content rect's position within
381 // those bounds is moving.
382 return NS_SubtractHint(NS_STYLE_HINT_REFLOW
,
383 nsChangeHint_ClearDescendantIntrinsics
);
386 nsStyleBorder::nsStyleBorder(nsPresContext
* aPresContext
)
387 : mBorderColors(nullptr),
389 mBorderImageFill(NS_STYLE_BORDER_IMAGE_SLICE_NOFILL
),
390 mBorderImageRepeatH(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH
),
391 mBorderImageRepeatV(NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH
),
392 mFloatEdge(NS_STYLE_FLOAT_EDGE_CONTENT
),
393 mBoxDecorationBreak(NS_STYLE_BOX_DECORATION_BREAK_SLICE
),
394 mComputedBorder(0, 0, 0, 0)
396 MOZ_COUNT_CTOR(nsStyleBorder
);
398 NS_FOR_CSS_HALF_CORNERS (corner
) {
399 mBorderRadius
.Set(corner
, nsStyleCoord(0, nsStyleCoord::CoordConstructor
));
403 (aPresContext
->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM
];
404 NS_FOR_CSS_SIDES(side
) {
405 mBorderImageSlice
.Set(side
, nsStyleCoord(1.0f
, eStyleUnit_Percent
));
406 mBorderImageWidth
.Set(side
, nsStyleCoord(1.0f
, eStyleUnit_Factor
));
407 mBorderImageOutset
.Set(side
, nsStyleCoord(0.0f
, eStyleUnit_Factor
));
409 mBorder
.Side(side
) = medium
;
410 mBorderStyle
[side
] = NS_STYLE_BORDER_STYLE_NONE
| BORDER_COLOR_FOREGROUND
;
411 mBorderColor
[side
] = NS_RGB(0, 0, 0);
414 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
417 nsBorderColors::~nsBorderColors()
419 NS_CSS_DELETE_LIST_MEMBER(nsBorderColors
, this, mNext
);
423 nsBorderColors::Clone(bool aDeep
) const
425 nsBorderColors
* result
= new nsBorderColors(mColor
);
426 if (MOZ_UNLIKELY(!result
))
429 NS_CSS_CLONE_LIST_MEMBER(nsBorderColors
, this, mNext
, result
, (false));
433 nsStyleBorder::nsStyleBorder(const nsStyleBorder
& aSrc
)
434 : mBorderColors(nullptr),
435 mBoxShadow(aSrc
.mBoxShadow
),
436 mBorderRadius(aSrc
.mBorderRadius
),
437 mBorderImageSource(aSrc
.mBorderImageSource
),
438 mBorderImageSlice(aSrc
.mBorderImageSlice
),
439 mBorderImageWidth(aSrc
.mBorderImageWidth
),
440 mBorderImageOutset(aSrc
.mBorderImageOutset
),
441 mBorderImageFill(aSrc
.mBorderImageFill
),
442 mBorderImageRepeatH(aSrc
.mBorderImageRepeatH
),
443 mBorderImageRepeatV(aSrc
.mBorderImageRepeatV
),
444 mFloatEdge(aSrc
.mFloatEdge
),
445 mBoxDecorationBreak(aSrc
.mBoxDecorationBreak
),
446 mComputedBorder(aSrc
.mComputedBorder
),
447 mBorder(aSrc
.mBorder
),
448 mTwipsPerPixel(aSrc
.mTwipsPerPixel
)
450 MOZ_COUNT_CTOR(nsStyleBorder
);
451 if (aSrc
.mBorderColors
) {
452 EnsureBorderColors();
453 for (int32_t i
= 0; i
< 4; i
++)
454 if (aSrc
.mBorderColors
[i
])
455 mBorderColors
[i
] = aSrc
.mBorderColors
[i
]->Clone();
457 mBorderColors
[i
] = nullptr;
460 NS_FOR_CSS_SIDES(side
) {
461 mBorderStyle
[side
] = aSrc
.mBorderStyle
[side
];
462 mBorderColor
[side
] = aSrc
.mBorderColor
[side
];
466 nsStyleBorder::~nsStyleBorder()
468 MOZ_COUNT_DTOR(nsStyleBorder
);
470 for (int32_t i
= 0; i
< 4; i
++)
471 delete mBorderColors
[i
];
472 delete [] mBorderColors
;
477 nsStyleBorder::GetImageOutset() const
479 // We don't check whether there is a border-image (which is OK since
480 // the initial values yields 0 outset) so that we don't have to
481 // reflow to update overflow areas when an image loads.
483 NS_FOR_CSS_SIDES(s
) {
484 nsStyleCoord coord
= mBorderImageOutset
.Get(s
);
486 switch (coord
.GetUnit()) {
487 case eStyleUnit_Coord
:
488 value
= coord
.GetCoordValue();
490 case eStyleUnit_Factor
:
491 value
= coord
.GetFactorValue() * mComputedBorder
.Side(s
);
494 NS_NOTREACHED("unexpected CSS unit for image outset");
498 outset
.Side(s
) = value
;
504 nsStyleBorder::Destroy(nsPresContext
* aContext
) {
505 UntrackImage(aContext
);
506 this->~nsStyleBorder();
507 aContext
->PresShell()->
508 FreeByObjectID(nsPresArena::nsStyleBorder_id
, this);
511 nsChangeHint
nsStyleBorder::CalcDifference(const nsStyleBorder
& aOther
) const
513 nsChangeHint shadowDifference
=
514 CalcShadowDifference(mBoxShadow
, aOther
.mBoxShadow
);
515 NS_ABORT_IF_FALSE(shadowDifference
== unsigned(NS_STYLE_HINT_REFLOW
) ||
516 shadowDifference
== unsigned(NS_STYLE_HINT_VISUAL
) ||
517 shadowDifference
== unsigned(NS_STYLE_HINT_NONE
),
518 "should do more with shadowDifference");
520 // XXXbz we should be able to return a more specific change hint for
521 // at least GetComputedBorder() differences...
522 if (mTwipsPerPixel
!= aOther
.mTwipsPerPixel
||
523 GetComputedBorder() != aOther
.GetComputedBorder() ||
524 mFloatEdge
!= aOther
.mFloatEdge
||
525 mBorderImageOutset
!= aOther
.mBorderImageOutset
||
526 (shadowDifference
& nsChangeHint_NeedReflow
) ||
527 mBoxDecorationBreak
!= aOther
.mBoxDecorationBreak
)
528 return NS_STYLE_HINT_REFLOW
;
530 NS_FOR_CSS_SIDES(ix
) {
531 // See the explanation in nsChangeHint.h of
532 // nsChangeHint_BorderStyleNoneChange .
533 // Furthermore, even though we know *this* side is 0 width, just
534 // assume a visual hint for some other change rather than bother
535 // tracking this result through the rest of the function.
536 if (HasVisibleStyle(ix
) != aOther
.HasVisibleStyle(ix
)) {
537 return NS_CombineHint(NS_STYLE_HINT_VISUAL
,
538 nsChangeHint_BorderStyleNoneChange
);
542 // Note that mBorderStyle stores not only the border style but also
543 // color-related flags. Given that we've already done an mComputedBorder
544 // comparison, border-style differences can only lead to a VISUAL hint. So
545 // it's OK to just compare the values directly -- if either the actual
546 // style or the color flags differ we want to repaint.
547 NS_FOR_CSS_SIDES(ix
) {
548 if (mBorderStyle
[ix
] != aOther
.mBorderStyle
[ix
] ||
549 mBorderColor
[ix
] != aOther
.mBorderColor
[ix
])
550 return NS_STYLE_HINT_VISUAL
;
553 if (mBorderRadius
!= aOther
.mBorderRadius
||
554 !mBorderColors
!= !aOther
.mBorderColors
)
555 return NS_STYLE_HINT_VISUAL
;
557 if (IsBorderImageLoaded() || aOther
.IsBorderImageLoaded()) {
558 if (mBorderImageSource
!= aOther
.mBorderImageSource
||
559 mBorderImageRepeatH
!= aOther
.mBorderImageRepeatH
||
560 mBorderImageRepeatV
!= aOther
.mBorderImageRepeatV
||
561 mBorderImageSlice
!= aOther
.mBorderImageSlice
||
562 mBorderImageFill
!= aOther
.mBorderImageFill
||
563 mBorderImageWidth
!= aOther
.mBorderImageWidth
||
564 mBorderImageOutset
!= aOther
.mBorderImageOutset
)
565 return NS_STYLE_HINT_VISUAL
;
568 // Note that at this point if mBorderColors is non-null so is
569 // aOther.mBorderColors
571 NS_FOR_CSS_SIDES(ix
) {
572 if (!nsBorderColors::Equal(mBorderColors
[ix
],
573 aOther
.mBorderColors
[ix
]))
574 return NS_STYLE_HINT_VISUAL
;
578 if (shadowDifference
) {
579 return shadowDifference
;
582 // mBorder is the specified border value. Changes to this don't
583 // need any change processing, since we operate on the computed
584 // border values instead.
585 if (mBorder
!= aOther
.mBorder
) {
586 return nsChangeHint_NeutralChange
;
589 return NS_STYLE_HINT_NONE
;
592 nsStyleOutline::nsStyleOutline(nsPresContext
* aPresContext
)
594 MOZ_COUNT_CTOR(nsStyleOutline
);
595 // spacing values not inherited
596 nsStyleCoord
zero(0, nsStyleCoord::CoordConstructor
);
597 NS_FOR_CSS_HALF_CORNERS(corner
) {
598 mOutlineRadius
.Set(corner
, zero
);
603 mOutlineWidth
= nsStyleCoord(NS_STYLE_BORDER_WIDTH_MEDIUM
, eStyleUnit_Enumerated
);
604 mOutlineStyle
= NS_STYLE_BORDER_STYLE_NONE
;
605 mOutlineColor
= NS_RGB(0, 0, 0);
607 mHasCachedOutline
= false;
608 mTwipsPerPixel
= aPresContext
->DevPixelsToAppUnits(1);
611 nsStyleOutline::nsStyleOutline(const nsStyleOutline
& aSrc
)
612 : mOutlineRadius(aSrc
.mOutlineRadius
)
613 , mOutlineWidth(aSrc
.mOutlineWidth
)
614 , mOutlineOffset(aSrc
.mOutlineOffset
)
615 , mCachedOutlineWidth(aSrc
.mCachedOutlineWidth
)
616 , mOutlineColor(aSrc
.mOutlineColor
)
617 , mHasCachedOutline(aSrc
.mHasCachedOutline
)
618 , mOutlineStyle(aSrc
.mOutlineStyle
)
619 , mTwipsPerPixel(aSrc
.mTwipsPerPixel
)
621 MOZ_COUNT_CTOR(nsStyleOutline
);
625 nsStyleOutline::RecalcData(nsPresContext
* aContext
)
627 if (NS_STYLE_BORDER_STYLE_NONE
== GetOutlineStyle()) {
628 mCachedOutlineWidth
= 0;
629 mHasCachedOutline
= true;
630 } else if (IsFixedUnit(mOutlineWidth
, true)) {
631 // Clamp negative calc() to 0.
632 mCachedOutlineWidth
=
633 std::max(CalcCoord(mOutlineWidth
, aContext
->GetBorderWidthTable(), 3), 0);
634 mCachedOutlineWidth
=
635 NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth
, mTwipsPerPixel
);
636 mHasCachedOutline
= true;
639 mHasCachedOutline
= false;
642 nsChangeHint
nsStyleOutline::CalcDifference(const nsStyleOutline
& aOther
) const
644 bool outlineWasVisible
=
645 mCachedOutlineWidth
> 0 && mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
646 bool outlineIsVisible
=
647 aOther
.mCachedOutlineWidth
> 0 && aOther
.mOutlineStyle
!= NS_STYLE_BORDER_STYLE_NONE
;
648 if (outlineWasVisible
!= outlineIsVisible
||
649 (outlineIsVisible
&& (mOutlineOffset
!= aOther
.mOutlineOffset
||
650 mOutlineWidth
!= aOther
.mOutlineWidth
||
651 mTwipsPerPixel
!= aOther
.mTwipsPerPixel
))) {
652 return NS_CombineHint(nsChangeHint_AllReflowHints
,
653 nsChangeHint_RepaintFrame
);
656 if ((mOutlineStyle
!= aOther
.mOutlineStyle
) ||
657 (mOutlineColor
!= aOther
.mOutlineColor
) ||
658 (mOutlineRadius
!= aOther
.mOutlineRadius
)) {
659 return nsChangeHint_RepaintFrame
;
662 // XXX Not exactly sure if we need to check the cached outline values.
663 if (mOutlineWidth
!= aOther
.mOutlineWidth
||
664 mOutlineOffset
!= aOther
.mOutlineOffset
||
665 mTwipsPerPixel
!= aOther
.mTwipsPerPixel
||
666 mHasCachedOutline
!= aOther
.mHasCachedOutline
||
667 (mHasCachedOutline
&&
668 (mCachedOutlineWidth
!= aOther
.mCachedOutlineWidth
))) {
669 return nsChangeHint_NeutralChange
;
672 return NS_STYLE_HINT_NONE
;
675 // --------------------
678 nsStyleList::nsStyleList(nsPresContext
* aPresContext
)
679 : mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE
),
680 mListStyleType(NS_LITERAL_STRING("disc")),
681 mCounterStyle(aPresContext
->CounterStyleManager()->
682 BuildCounterStyle(mListStyleType
))
684 MOZ_COUNT_CTOR(nsStyleList
);
687 nsStyleList::~nsStyleList()
689 MOZ_COUNT_DTOR(nsStyleList
);
692 nsStyleList::nsStyleList(const nsStyleList
& aSource
)
693 : mListStylePosition(aSource
.mListStylePosition
),
694 mListStyleType(aSource
.mListStyleType
),
695 mCounterStyle(aSource
.mCounterStyle
),
696 mImageRegion(aSource
.mImageRegion
)
698 SetListStyleImage(aSource
.GetListStyleImage());
699 MOZ_COUNT_CTOR(nsStyleList
);
702 nsChangeHint
nsStyleList::CalcDifference(const nsStyleList
& aOther
) const
704 if (mListStylePosition
!= aOther
.mListStylePosition
)
705 return NS_STYLE_HINT_FRAMECHANGE
;
706 if (EqualImages(mListStyleImage
, aOther
.mListStyleImage
) &&
707 mCounterStyle
== aOther
.mCounterStyle
) {
708 if (mImageRegion
.IsEqualInterior(aOther
.mImageRegion
)) {
709 if (mListStyleType
!= aOther
.mListStyleType
)
710 return nsChangeHint_NeutralChange
;
711 return NS_STYLE_HINT_NONE
;
713 if (mImageRegion
.width
== aOther
.mImageRegion
.width
&&
714 mImageRegion
.height
== aOther
.mImageRegion
.height
)
715 return NS_STYLE_HINT_VISUAL
;
717 return NS_STYLE_HINT_REFLOW
;
720 // --------------------
723 nsStyleXUL::nsStyleXUL()
725 MOZ_COUNT_CTOR(nsStyleXUL
);
726 mBoxAlign
= NS_STYLE_BOX_ALIGN_STRETCH
;
727 mBoxDirection
= NS_STYLE_BOX_DIRECTION_NORMAL
;
729 mBoxOrient
= NS_STYLE_BOX_ORIENT_HORIZONTAL
;
730 mBoxPack
= NS_STYLE_BOX_PACK_START
;
732 mStretchStack
= true;
735 nsStyleXUL::~nsStyleXUL()
737 MOZ_COUNT_DTOR(nsStyleXUL
);
740 nsStyleXUL::nsStyleXUL(const nsStyleXUL
& aSource
)
741 : mBoxFlex(aSource
.mBoxFlex
)
742 , mBoxOrdinal(aSource
.mBoxOrdinal
)
743 , mBoxAlign(aSource
.mBoxAlign
)
744 , mBoxDirection(aSource
.mBoxDirection
)
745 , mBoxOrient(aSource
.mBoxOrient
)
746 , mBoxPack(aSource
.mBoxPack
)
747 , mStretchStack(aSource
.mStretchStack
)
749 MOZ_COUNT_CTOR(nsStyleXUL
);
752 nsChangeHint
nsStyleXUL::CalcDifference(const nsStyleXUL
& aOther
) const
754 if (mBoxAlign
== aOther
.mBoxAlign
&&
755 mBoxDirection
== aOther
.mBoxDirection
&&
756 mBoxFlex
== aOther
.mBoxFlex
&&
757 mBoxOrient
== aOther
.mBoxOrient
&&
758 mBoxPack
== aOther
.mBoxPack
&&
759 mBoxOrdinal
== aOther
.mBoxOrdinal
&&
760 mStretchStack
== aOther
.mStretchStack
)
761 return NS_STYLE_HINT_NONE
;
762 if (mBoxOrdinal
!= aOther
.mBoxOrdinal
)
763 return NS_STYLE_HINT_FRAMECHANGE
;
764 return NS_STYLE_HINT_REFLOW
;
767 // --------------------
770 /* static */ const uint32_t nsStyleColumn::kMaxColumnCount
= 1000;
772 nsStyleColumn::nsStyleColumn(nsPresContext
* aPresContext
)
774 MOZ_COUNT_CTOR(nsStyleColumn
);
775 mColumnCount
= NS_STYLE_COLUMN_COUNT_AUTO
;
776 mColumnWidth
.SetAutoValue();
777 mColumnGap
.SetNormalValue();
778 mColumnFill
= NS_STYLE_COLUMN_FILL_BALANCE
;
780 mColumnRuleWidth
= (aPresContext
->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM
];
781 mColumnRuleStyle
= NS_STYLE_BORDER_STYLE_NONE
;
782 mColumnRuleColor
= NS_RGB(0, 0, 0);
783 mColumnRuleColorIsForeground
= true;
785 mTwipsPerPixel
= aPresContext
->AppUnitsPerDevPixel();
788 nsStyleColumn::~nsStyleColumn()
790 MOZ_COUNT_DTOR(nsStyleColumn
);
793 nsStyleColumn::nsStyleColumn(const nsStyleColumn
& aSource
)
794 : mColumnCount(aSource
.mColumnCount
)
795 , mColumnWidth(aSource
.mColumnWidth
)
796 , mColumnGap(aSource
.mColumnGap
)
797 , mColumnRuleColor(aSource
.mColumnRuleColor
)
798 , mColumnRuleStyle(aSource
.mColumnRuleStyle
)
799 , mColumnFill(aSource
.mColumnFill
)
800 , mColumnRuleColorIsForeground(aSource
.mColumnRuleColorIsForeground
)
801 , mColumnRuleWidth(aSource
.mColumnRuleWidth
)
802 , mTwipsPerPixel(aSource
.mTwipsPerPixel
)
804 MOZ_COUNT_CTOR(nsStyleColumn
);
807 nsChangeHint
nsStyleColumn::CalcDifference(const nsStyleColumn
& aOther
) const
809 if ((mColumnWidth
.GetUnit() == eStyleUnit_Auto
)
810 != (aOther
.mColumnWidth
.GetUnit() == eStyleUnit_Auto
) ||
811 mColumnCount
!= aOther
.mColumnCount
)
812 // We force column count changes to do a reframe, because it's tricky to handle
813 // some edge cases where the column count gets smaller and content overflows.
815 return NS_STYLE_HINT_FRAMECHANGE
;
817 if (mColumnWidth
!= aOther
.mColumnWidth
||
818 mColumnGap
!= aOther
.mColumnGap
||
819 mColumnFill
!= aOther
.mColumnFill
)
820 return NS_STYLE_HINT_REFLOW
;
822 if (GetComputedColumnRuleWidth() != aOther
.GetComputedColumnRuleWidth() ||
823 mColumnRuleStyle
!= aOther
.mColumnRuleStyle
||
824 mColumnRuleColor
!= aOther
.mColumnRuleColor
||
825 mColumnRuleColorIsForeground
!= aOther
.mColumnRuleColorIsForeground
)
826 return NS_STYLE_HINT_VISUAL
;
828 // XXX Is it right that we never check mTwipsPerPixel to return a
829 // non-nsChangeHint_NeutralChange hint?
830 if (mColumnRuleWidth
!= aOther
.mColumnRuleWidth
||
831 mTwipsPerPixel
!= aOther
.mTwipsPerPixel
) {
832 return nsChangeHint_NeutralChange
;
835 return NS_STYLE_HINT_NONE
;
838 // --------------------
841 nsStyleSVG::nsStyleSVG()
843 MOZ_COUNT_CTOR(nsStyleSVG
);
844 mFill
.mType
= eStyleSVGPaintType_Color
;
845 mFill
.mPaint
.mColor
= NS_RGB(0,0,0);
846 mFill
.mFallbackColor
= NS_RGB(0,0,0);
847 mStroke
.mType
= eStyleSVGPaintType_None
;
848 mStroke
.mPaint
.mColor
= NS_RGB(0,0,0);
849 mStroke
.mFallbackColor
= NS_RGB(0,0,0);
850 mStrokeDasharray
= nullptr;
852 mStrokeDashoffset
.SetCoordValue(0);
853 mStrokeWidth
.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
856 mStrokeMiterlimit
= 4.0f
;
857 mStrokeOpacity
= 1.0f
;
859 mStrokeDasharrayLength
= 0;
860 mClipRule
= NS_STYLE_FILL_RULE_NONZERO
;
861 mColorInterpolation
= NS_STYLE_COLOR_INTERPOLATION_SRGB
;
862 mColorInterpolationFilters
= NS_STYLE_COLOR_INTERPOLATION_LINEARRGB
;
863 mFillRule
= NS_STYLE_FILL_RULE_NONZERO
;
864 mImageRendering
= NS_STYLE_IMAGE_RENDERING_AUTO
;
865 mPaintOrder
= NS_STYLE_PAINT_ORDER_NORMAL
;
866 mShapeRendering
= NS_STYLE_SHAPE_RENDERING_AUTO
;
867 mStrokeLinecap
= NS_STYLE_STROKE_LINECAP_BUTT
;
868 mStrokeLinejoin
= NS_STYLE_STROKE_LINEJOIN_MITER
;
869 mTextAnchor
= NS_STYLE_TEXT_ANCHOR_START
;
870 mTextRendering
= NS_STYLE_TEXT_RENDERING_AUTO
;
871 mFillOpacitySource
= eStyleSVGOpacitySource_Normal
;
872 mStrokeOpacitySource
= eStyleSVGOpacitySource_Normal
;
873 mStrokeDasharrayFromObject
= false;
874 mStrokeDashoffsetFromObject
= false;
875 mStrokeWidthFromObject
= false;
878 nsStyleSVG::~nsStyleSVG()
880 MOZ_COUNT_DTOR(nsStyleSVG
);
881 delete [] mStrokeDasharray
;
884 nsStyleSVG::nsStyleSVG(const nsStyleSVG
& aSource
)
886 MOZ_COUNT_CTOR(nsStyleSVG
);
887 mFill
= aSource
.mFill
;
888 mStroke
= aSource
.mStroke
;
890 mMarkerEnd
= aSource
.mMarkerEnd
;
891 mMarkerMid
= aSource
.mMarkerMid
;
892 mMarkerStart
= aSource
.mMarkerStart
;
894 mStrokeDasharrayLength
= aSource
.mStrokeDasharrayLength
;
895 if (aSource
.mStrokeDasharray
) {
896 mStrokeDasharray
= new nsStyleCoord
[mStrokeDasharrayLength
];
897 if (mStrokeDasharray
) {
898 for (size_t i
= 0; i
< mStrokeDasharrayLength
; i
++) {
899 mStrokeDasharray
[i
] = aSource
.mStrokeDasharray
[i
];
902 mStrokeDasharrayLength
= 0;
905 mStrokeDasharray
= nullptr;
908 mStrokeDashoffset
= aSource
.mStrokeDashoffset
;
909 mStrokeWidth
= aSource
.mStrokeWidth
;
911 mFillOpacity
= aSource
.mFillOpacity
;
912 mStrokeMiterlimit
= aSource
.mStrokeMiterlimit
;
913 mStrokeOpacity
= aSource
.mStrokeOpacity
;
915 mClipRule
= aSource
.mClipRule
;
916 mColorInterpolation
= aSource
.mColorInterpolation
;
917 mColorInterpolationFilters
= aSource
.mColorInterpolationFilters
;
918 mFillRule
= aSource
.mFillRule
;
919 mImageRendering
= aSource
.mImageRendering
;
920 mPaintOrder
= aSource
.mPaintOrder
;
921 mShapeRendering
= aSource
.mShapeRendering
;
922 mStrokeLinecap
= aSource
.mStrokeLinecap
;
923 mStrokeLinejoin
= aSource
.mStrokeLinejoin
;
924 mTextAnchor
= aSource
.mTextAnchor
;
925 mTextRendering
= aSource
.mTextRendering
;
926 mFillOpacitySource
= aSource
.mFillOpacitySource
;
927 mStrokeOpacitySource
= aSource
.mStrokeOpacitySource
;
928 mStrokeDasharrayFromObject
= aSource
.mStrokeDasharrayFromObject
;
929 mStrokeDashoffsetFromObject
= aSource
.mStrokeDashoffsetFromObject
;
930 mStrokeWidthFromObject
= aSource
.mStrokeWidthFromObject
;
933 static bool PaintURIChanged(const nsStyleSVGPaint
& aPaint1
,
934 const nsStyleSVGPaint
& aPaint2
)
936 if (aPaint1
.mType
!= aPaint2
.mType
) {
937 return aPaint1
.mType
== eStyleSVGPaintType_Server
||
938 aPaint2
.mType
== eStyleSVGPaintType_Server
;
940 return aPaint1
.mType
== eStyleSVGPaintType_Server
&&
941 !EqualURIs(aPaint1
.mPaint
.mPaintServer
, aPaint2
.mPaint
.mPaintServer
);
944 nsChangeHint
nsStyleSVG::CalcDifference(const nsStyleSVG
& aOther
) const
946 nsChangeHint hint
= nsChangeHint(0);
948 if (!EqualURIs(mMarkerEnd
, aOther
.mMarkerEnd
) ||
949 !EqualURIs(mMarkerMid
, aOther
.mMarkerMid
) ||
950 !EqualURIs(mMarkerStart
, aOther
.mMarkerStart
)) {
951 // Markers currently contribute to nsSVGPathGeometryFrame::mRect,
952 // so we need a reflow as well as a repaint. No intrinsic sizes need
953 // to change, so nsChangeHint_NeedReflow is sufficient.
954 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
955 NS_UpdateHint(hint
, nsChangeHint_NeedReflow
);
956 NS_UpdateHint(hint
, nsChangeHint_NeedDirtyReflow
); // XXX remove me: bug 876085
957 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
961 if (mFill
!= aOther
.mFill
||
962 mStroke
!= aOther
.mStroke
||
963 mFillOpacity
!= aOther
.mFillOpacity
||
964 mStrokeOpacity
!= aOther
.mStrokeOpacity
) {
965 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
966 if (HasStroke() != aOther
.HasStroke() ||
967 (!HasStroke() && HasFill() != aOther
.HasFill())) {
968 // Frame bounds and overflow rects depend on whether we "have" fill or
969 // stroke. Whether we have stroke or not just changed, or else we have no
970 // stroke (in which case whether we have fill or not is significant to frame
971 // bounds) and whether we have fill or not just changed. In either case we
972 // need to reflow so the frame rect is updated.
973 // XXXperf this is a waste on non nsSVGPathGeometryFrames.
974 NS_UpdateHint(hint
, nsChangeHint_NeedReflow
);
975 NS_UpdateHint(hint
, nsChangeHint_NeedDirtyReflow
); // XXX remove me: bug 876085
977 if (PaintURIChanged(mFill
, aOther
.mFill
) ||
978 PaintURIChanged(mStroke
, aOther
.mStroke
)) {
979 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
983 // Stroke currently contributes to nsSVGPathGeometryFrame::mRect, so
984 // we need a reflow here. No intrinsic sizes need to change, so
985 // nsChangeHint_NeedReflow is sufficient.
986 // Note that stroke-dashoffset does not affect nsSVGPathGeometryFrame::mRect.
987 // text-anchor and text-rendering changes also require a reflow since they
988 // change frames' rects.
989 if (mStrokeWidth
!= aOther
.mStrokeWidth
||
990 mStrokeMiterlimit
!= aOther
.mStrokeMiterlimit
||
991 mStrokeLinecap
!= aOther
.mStrokeLinecap
||
992 mStrokeLinejoin
!= aOther
.mStrokeLinejoin
||
993 mTextAnchor
!= aOther
.mTextAnchor
||
994 mTextRendering
!= aOther
.mTextRendering
) {
995 NS_UpdateHint(hint
, nsChangeHint_NeedReflow
);
996 NS_UpdateHint(hint
, nsChangeHint_NeedDirtyReflow
); // XXX remove me: bug 876085
997 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1001 if (hint
& nsChangeHint_RepaintFrame
) {
1002 return hint
; // we don't add anything else below
1005 if ( mStrokeDashoffset
!= aOther
.mStrokeDashoffset
||
1006 mClipRule
!= aOther
.mClipRule
||
1007 mColorInterpolation
!= aOther
.mColorInterpolation
||
1008 mColorInterpolationFilters
!= aOther
.mColorInterpolationFilters
||
1009 mFillRule
!= aOther
.mFillRule
||
1010 mImageRendering
!= aOther
.mImageRendering
||
1011 mPaintOrder
!= aOther
.mPaintOrder
||
1012 mShapeRendering
!= aOther
.mShapeRendering
||
1013 mStrokeDasharrayLength
!= aOther
.mStrokeDasharrayLength
||
1014 mFillOpacitySource
!= aOther
.mFillOpacitySource
||
1015 mStrokeOpacitySource
!= aOther
.mStrokeOpacitySource
||
1016 mStrokeDasharrayFromObject
!= aOther
.mStrokeDasharrayFromObject
||
1017 mStrokeDashoffsetFromObject
!= aOther
.mStrokeDashoffsetFromObject
||
1018 mStrokeWidthFromObject
!= aOther
.mStrokeWidthFromObject
) {
1019 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1023 // length of stroke dasharrays are the same (tested above) - check entries
1024 for (uint32_t i
=0; i
<mStrokeDasharrayLength
; i
++)
1025 if (mStrokeDasharray
[i
] != aOther
.mStrokeDasharray
[i
]) {
1026 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1033 // --------------------
1036 nsStyleClipPath::nsStyleClipPath()
1037 : mType(NS_STYLE_CLIP_PATH_NONE
)
1039 , mSizingBox(NS_STYLE_CLIP_SHAPE_SIZING_NOBOX
)
1043 nsStyleClipPath::nsStyleClipPath(const nsStyleClipPath
& aSource
)
1044 : mType(NS_STYLE_CLIP_PATH_NONE
)
1046 , mSizingBox(NS_STYLE_CLIP_SHAPE_SIZING_NOBOX
)
1048 if (aSource
.mType
== NS_STYLE_CLIP_PATH_URL
) {
1049 SetURL(aSource
.mURL
);
1050 } else if (aSource
.mType
== NS_STYLE_CLIP_PATH_SHAPE
) {
1051 SetBasicShape(aSource
.mBasicShape
, aSource
.mSizingBox
);
1052 } else if (aSource
.mType
== NS_STYLE_CLIP_PATH_SHAPE
) {
1053 SetSizingBox(aSource
.mSizingBox
);
1057 nsStyleClipPath::~nsStyleClipPath()
1063 nsStyleClipPath::operator=(const nsStyleClipPath
& aOther
)
1065 if (this == &aOther
) {
1071 if (aOther
.mType
== NS_STYLE_CLIP_PATH_URL
) {
1072 SetURL(aOther
.mURL
);
1073 } else if (aOther
.mType
== NS_STYLE_CLIP_PATH_SHAPE
) {
1074 SetBasicShape(aOther
.mBasicShape
, aOther
.mSizingBox
);
1075 } else if (aOther
.mType
== NS_STYLE_CLIP_PATH_BOX
) {
1076 SetSizingBox(aOther
.mSizingBox
);
1078 mSizingBox
= NS_STYLE_CLIP_SHAPE_SIZING_NOBOX
;
1079 mType
= NS_STYLE_CLIP_PATH_NONE
;
1086 nsStyleClipPath::operator==(const nsStyleClipPath
& aOther
) const
1088 if (mType
!= aOther
.mType
) {
1092 if (mType
== NS_STYLE_CLIP_PATH_URL
) {
1093 return EqualURIs(mURL
, aOther
.mURL
);
1094 } else if (mType
== NS_STYLE_CLIP_PATH_SHAPE
) {
1095 return *mBasicShape
== *aOther
.mBasicShape
&&
1096 mSizingBox
== aOther
.mSizingBox
;
1097 } else if (mType
== NS_STYLE_CLIP_PATH_BOX
) {
1098 return mSizingBox
== aOther
.mSizingBox
;
1105 nsStyleClipPath::ReleaseRef()
1107 if (mType
== NS_STYLE_CLIP_PATH_SHAPE
) {
1108 NS_ASSERTION(mBasicShape
, "expected pointer");
1109 mBasicShape
->Release();
1110 } else if (mType
== NS_STYLE_CLIP_PATH_URL
) {
1111 NS_ASSERTION(mURL
, "expected pointer");
1118 nsStyleClipPath::SetURL(nsIURI
* aURL
)
1120 NS_ASSERTION(aURL
, "expected pointer");
1124 mType
= NS_STYLE_CLIP_PATH_URL
;
1128 nsStyleClipPath::SetBasicShape(nsStyleBasicShape
* aBasicShape
, uint8_t aSizingBox
)
1130 NS_ASSERTION(aBasicShape
, "expected pointer");
1132 mBasicShape
= aBasicShape
;
1133 mBasicShape
->AddRef();
1134 mSizingBox
= aSizingBox
;
1135 mType
= NS_STYLE_CLIP_PATH_SHAPE
;
1139 nsStyleClipPath::SetSizingBox(uint8_t aSizingBox
)
1142 mSizingBox
= aSizingBox
;
1143 mType
= NS_STYLE_CLIP_PATH_BOX
;
1146 // --------------------
1149 nsStyleFilter::nsStyleFilter()
1150 : mType(NS_STYLE_FILTER_NONE
)
1151 , mDropShadow(nullptr)
1153 MOZ_COUNT_CTOR(nsStyleFilter
);
1156 nsStyleFilter::nsStyleFilter(const nsStyleFilter
& aSource
)
1157 : mType(NS_STYLE_FILTER_NONE
)
1158 , mDropShadow(nullptr)
1160 MOZ_COUNT_CTOR(nsStyleFilter
);
1161 if (aSource
.mType
== NS_STYLE_FILTER_URL
) {
1162 SetURL(aSource
.mURL
);
1163 } else if (aSource
.mType
== NS_STYLE_FILTER_DROP_SHADOW
) {
1164 SetDropShadow(aSource
.mDropShadow
);
1165 } else if (aSource
.mType
!= NS_STYLE_FILTER_NONE
) {
1166 SetFilterParameter(aSource
.mFilterParameter
, aSource
.mType
);
1170 nsStyleFilter::~nsStyleFilter()
1173 MOZ_COUNT_DTOR(nsStyleFilter
);
1177 nsStyleFilter::operator=(const nsStyleFilter
& aOther
)
1179 if (this == &aOther
)
1182 if (aOther
.mType
== NS_STYLE_FILTER_URL
) {
1183 SetURL(aOther
.mURL
);
1184 } else if (aOther
.mType
== NS_STYLE_FILTER_DROP_SHADOW
) {
1185 SetDropShadow(aOther
.mDropShadow
);
1186 } else if (aOther
.mType
!= NS_STYLE_FILTER_NONE
) {
1187 SetFilterParameter(aOther
.mFilterParameter
, aOther
.mType
);
1194 nsStyleFilter::operator==(const nsStyleFilter
& aOther
) const
1196 if (mType
!= aOther
.mType
) {
1200 if (mType
== NS_STYLE_FILTER_URL
) {
1201 return EqualURIs(mURL
, aOther
.mURL
);
1202 } else if (mType
== NS_STYLE_FILTER_DROP_SHADOW
) {
1203 return *mDropShadow
== *aOther
.mDropShadow
;
1204 } else if (mType
!= NS_STYLE_FILTER_NONE
) {
1205 return mFilterParameter
== aOther
.mFilterParameter
;
1212 nsStyleFilter::ReleaseRef()
1214 if (mType
== NS_STYLE_FILTER_DROP_SHADOW
) {
1215 NS_ASSERTION(mDropShadow
, "expected pointer");
1216 mDropShadow
->Release();
1217 } else if (mType
== NS_STYLE_FILTER_URL
) {
1218 NS_ASSERTION(mURL
, "expected pointer");
1224 nsStyleFilter::SetFilterParameter(const nsStyleCoord
& aFilterParameter
,
1228 mFilterParameter
= aFilterParameter
;
1233 nsStyleFilter::SetURL(nsIURI
* aURL
)
1235 NS_ASSERTION(aURL
, "expected pointer");
1239 mType
= NS_STYLE_FILTER_URL
;
1243 nsStyleFilter::SetDropShadow(nsCSSShadowArray
* aDropShadow
)
1245 NS_ASSERTION(aDropShadow
, "expected pointer");
1247 mDropShadow
= aDropShadow
;
1248 mDropShadow
->AddRef();
1249 mType
= NS_STYLE_FILTER_DROP_SHADOW
;
1252 // --------------------
1255 nsStyleSVGReset::nsStyleSVGReset()
1257 MOZ_COUNT_CTOR(nsStyleSVGReset
);
1258 mStopColor
= NS_RGB(0,0,0);
1259 mFloodColor
= NS_RGB(0,0,0);
1260 mLightingColor
= NS_RGB(255,255,255);
1262 mStopOpacity
= 1.0f
;
1263 mFloodOpacity
= 1.0f
;
1264 mDominantBaseline
= NS_STYLE_DOMINANT_BASELINE_AUTO
;
1265 mVectorEffect
= NS_STYLE_VECTOR_EFFECT_NONE
;
1266 mMaskType
= NS_STYLE_MASK_TYPE_LUMINANCE
;
1269 nsStyleSVGReset::~nsStyleSVGReset()
1271 MOZ_COUNT_DTOR(nsStyleSVGReset
);
1274 nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset
& aSource
)
1276 MOZ_COUNT_CTOR(nsStyleSVGReset
);
1277 mStopColor
= aSource
.mStopColor
;
1278 mFloodColor
= aSource
.mFloodColor
;
1279 mLightingColor
= aSource
.mLightingColor
;
1280 mClipPath
= aSource
.mClipPath
;
1281 mFilters
= aSource
.mFilters
;
1282 mMask
= aSource
.mMask
;
1283 mStopOpacity
= aSource
.mStopOpacity
;
1284 mFloodOpacity
= aSource
.mFloodOpacity
;
1285 mDominantBaseline
= aSource
.mDominantBaseline
;
1286 mVectorEffect
= aSource
.mVectorEffect
;
1287 mMaskType
= aSource
.mMaskType
;
1290 nsChangeHint
nsStyleSVGReset::CalcDifference(const nsStyleSVGReset
& aOther
) const
1292 nsChangeHint hint
= nsChangeHint(0);
1294 if (mClipPath
!= aOther
.mClipPath
||
1295 !EqualURIs(mMask
, aOther
.mMask
) ||
1296 mFilters
!= aOther
.mFilters
) {
1297 NS_UpdateHint(hint
, nsChangeHint_UpdateEffects
);
1298 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1299 // We only actually need to update the overflow area for filter
1300 // changes. However, mask and clip-path changes require that we
1301 // update the PreEffectsBBoxProperty, which is done during overflow
1303 NS_UpdateHint(hint
, nsChangeHint_UpdateOverflow
);
1306 if (mDominantBaseline
!= aOther
.mDominantBaseline
) {
1307 // XXXjwatt: why NS_STYLE_HINT_REFLOW? Isn't that excessive?
1308 NS_UpdateHint(hint
, NS_STYLE_HINT_REFLOW
);
1309 } else if (mVectorEffect
!= aOther
.mVectorEffect
) {
1310 // Stroke currently affects nsSVGPathGeometryFrame::mRect, and
1311 // vector-effect affect stroke. As a result we need to reflow if
1312 // vector-effect changes in order to have nsSVGPathGeometryFrame::
1313 // ReflowSVG called to update its mRect. No intrinsic sizes need
1314 // to change so nsChangeHint_NeedReflow is sufficient.
1315 NS_UpdateHint(hint
, nsChangeHint_NeedReflow
);
1316 NS_UpdateHint(hint
, nsChangeHint_NeedDirtyReflow
); // XXX remove me: bug 876085
1317 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1318 } else if (mStopColor
!= aOther
.mStopColor
||
1319 mFloodColor
!= aOther
.mFloodColor
||
1320 mLightingColor
!= aOther
.mLightingColor
||
1321 mStopOpacity
!= aOther
.mStopOpacity
||
1322 mFloodOpacity
!= aOther
.mFloodOpacity
||
1323 mMaskType
!= aOther
.mMaskType
) {
1324 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1330 // nsStyleSVGPaint implementation
1331 nsStyleSVGPaint::~nsStyleSVGPaint()
1333 if (mType
== eStyleSVGPaintType_Server
) {
1334 NS_IF_RELEASE(mPaint
.mPaintServer
);
1339 nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType
)
1341 if (mType
== eStyleSVGPaintType_Server
) {
1342 this->~nsStyleSVGPaint();
1343 new (this) nsStyleSVGPaint();
1348 nsStyleSVGPaint
& nsStyleSVGPaint::operator=(const nsStyleSVGPaint
& aOther
)
1350 if (this == &aOther
)
1353 SetType(aOther
.mType
);
1355 mFallbackColor
= aOther
.mFallbackColor
;
1356 if (mType
== eStyleSVGPaintType_Server
) {
1357 mPaint
.mPaintServer
= aOther
.mPaint
.mPaintServer
;
1358 NS_IF_ADDREF(mPaint
.mPaintServer
);
1360 mPaint
.mColor
= aOther
.mPaint
.mColor
;
1365 bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint
& aOther
) const
1367 if (mType
!= aOther
.mType
)
1369 if (mType
== eStyleSVGPaintType_Server
)
1370 return EqualURIs(mPaint
.mPaintServer
, aOther
.mPaint
.mPaintServer
) &&
1371 mFallbackColor
== aOther
.mFallbackColor
;
1372 if (mType
== eStyleSVGPaintType_Color
)
1373 return mPaint
.mColor
== aOther
.mPaint
.mColor
;
1378 // --------------------
1381 nsStylePosition::nsStylePosition(void)
1383 MOZ_COUNT_CTOR(nsStylePosition
);
1385 // positioning values not inherited
1387 mObjectPosition
.SetInitialPercentValues(0.5f
);
1389 nsStyleCoord
autoCoord(eStyleUnit_Auto
);
1390 mOffset
.SetLeft(autoCoord
);
1391 mOffset
.SetTop(autoCoord
);
1392 mOffset
.SetRight(autoCoord
);
1393 mOffset
.SetBottom(autoCoord
);
1394 mWidth
.SetAutoValue();
1395 mMinWidth
.SetAutoValue();
1396 mMaxWidth
.SetNoneValue();
1397 mHeight
.SetAutoValue();
1398 mMinHeight
.SetAutoValue();
1399 mMaxHeight
.SetNoneValue();
1400 mFlexBasis
.SetAutoValue();
1402 // The initial value of grid-auto-columns and grid-auto-rows is 'auto',
1403 // which computes to 'minmax(min-content, max-content)'.
1404 mGridAutoColumnsMin
.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT
,
1405 eStyleUnit_Enumerated
);
1406 mGridAutoColumnsMax
.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT
,
1407 eStyleUnit_Enumerated
);
1408 mGridAutoRowsMin
.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT
,
1409 eStyleUnit_Enumerated
);
1410 mGridAutoRowsMax
.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT
,
1411 eStyleUnit_Enumerated
);
1413 mGridAutoFlow
= NS_STYLE_GRID_AUTO_FLOW_ROW
;
1414 mBoxSizing
= NS_STYLE_BOX_SIZING_CONTENT
;
1415 mAlignContent
= NS_STYLE_ALIGN_CONTENT_STRETCH
;
1416 mAlignItems
= NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE
;
1417 mAlignSelf
= NS_STYLE_ALIGN_SELF_AUTO
;
1418 mFlexDirection
= NS_STYLE_FLEX_DIRECTION_ROW
;
1419 mFlexWrap
= NS_STYLE_FLEX_WRAP_NOWRAP
;
1420 mJustifyContent
= NS_STYLE_JUSTIFY_CONTENT_FLEX_START
;
1421 mObjectFit
= NS_STYLE_OBJECT_FIT_FILL
;
1422 mOrder
= NS_STYLE_ORDER_INITIAL
;
1425 mZIndex
.SetAutoValue();
1426 // Other members get their default constructors
1427 // which initialize them to representations of their respective initial value.
1428 // mGridTemplateAreas: nullptr for 'none'
1429 // mGridTemplate{Rows,Columns}: false and empty arrays for 'none'
1430 // mGrid{Column,Row}{Start,End}: false/0/empty values for 'auto'
1433 nsStylePosition::~nsStylePosition(void)
1435 MOZ_COUNT_DTOR(nsStylePosition
);
1438 nsStylePosition::nsStylePosition(const nsStylePosition
& aSource
)
1439 : mObjectPosition(aSource
.mObjectPosition
)
1440 , mOffset(aSource
.mOffset
)
1441 , mWidth(aSource
.mWidth
)
1442 , mMinWidth(aSource
.mMinWidth
)
1443 , mMaxWidth(aSource
.mMaxWidth
)
1444 , mHeight(aSource
.mHeight
)
1445 , mMinHeight(aSource
.mMinHeight
)
1446 , mMaxHeight(aSource
.mMaxHeight
)
1447 , mFlexBasis(aSource
.mFlexBasis
)
1448 , mGridAutoColumnsMin(aSource
.mGridAutoColumnsMin
)
1449 , mGridAutoColumnsMax(aSource
.mGridAutoColumnsMax
)
1450 , mGridAutoRowsMin(aSource
.mGridAutoRowsMin
)
1451 , mGridAutoRowsMax(aSource
.mGridAutoRowsMax
)
1452 , mGridAutoFlow(aSource
.mGridAutoFlow
)
1453 , mBoxSizing(aSource
.mBoxSizing
)
1454 , mAlignContent(aSource
.mAlignContent
)
1455 , mAlignItems(aSource
.mAlignItems
)
1456 , mAlignSelf(aSource
.mAlignSelf
)
1457 , mFlexDirection(aSource
.mFlexDirection
)
1458 , mFlexWrap(aSource
.mFlexWrap
)
1459 , mJustifyContent(aSource
.mJustifyContent
)
1460 , mObjectFit(aSource
.mObjectFit
)
1461 , mOrder(aSource
.mOrder
)
1462 , mFlexGrow(aSource
.mFlexGrow
)
1463 , mFlexShrink(aSource
.mFlexShrink
)
1464 , mZIndex(aSource
.mZIndex
)
1465 , mGridTemplateColumns(aSource
.mGridTemplateColumns
)
1466 , mGridTemplateRows(aSource
.mGridTemplateRows
)
1467 , mGridTemplateAreas(aSource
.mGridTemplateAreas
)
1468 , mGridColumnStart(aSource
.mGridColumnStart
)
1469 , mGridColumnEnd(aSource
.mGridColumnEnd
)
1470 , mGridRowStart(aSource
.mGridRowStart
)
1471 , mGridRowEnd(aSource
.mGridRowEnd
)
1473 MOZ_COUNT_CTOR(nsStylePosition
);
1477 IsAutonessEqual(const nsStyleSides
& aSides1
, const nsStyleSides
& aSides2
)
1479 NS_FOR_CSS_SIDES(side
) {
1480 if ((aSides1
.GetUnit(side
) == eStyleUnit_Auto
) !=
1481 (aSides2
.GetUnit(side
) == eStyleUnit_Auto
)) {
1488 nsChangeHint
nsStylePosition::CalcDifference(const nsStylePosition
& aOther
) const
1490 nsChangeHint hint
= nsChangeHint(0);
1492 // Changes to "z-index" require a repaint.
1493 if (mZIndex
!= aOther
.mZIndex
) {
1494 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
1497 // Changes to "object-fit" & "object-position" require a repaint. They
1498 // may also require a reflow, if we have a nsSubDocumentFrame, so that we
1499 // can adjust the size & position of the subdocument.
1500 if (mObjectFit
!= aOther
.mObjectFit
||
1501 mObjectPosition
!= aOther
.mObjectPosition
) {
1502 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_RepaintFrame
,
1503 nsChangeHint_NeedReflow
));
1506 if (mOrder
!= aOther
.mOrder
) {
1507 // "order" impacts both layout order and stacking order, so we need both a
1508 // reflow and a repaint when it changes. (Technically, we only need a
1509 // reflow if we're in a multi-line flexbox (which we can't be sure about,
1510 // since that's determined by styling on our parent) -- there, "order" can
1511 // affect which flex line we end up on, & hence can affect our sizing by
1512 // changing the group of flex items we're competing with for space.)
1513 return NS_CombineHint(hint
, NS_CombineHint(nsChangeHint_RepaintFrame
,
1514 nsChangeHint_AllReflowHints
));
1517 if (mBoxSizing
!= aOther
.mBoxSizing
) {
1518 // Can affect both widths and heights; just a bad scene.
1519 return NS_CombineHint(hint
, nsChangeHint_AllReflowHints
);
1522 // Properties that apply to flex items:
1523 // XXXdholbert These should probably be more targeted (bug 819536)
1524 if (mAlignSelf
!= aOther
.mAlignSelf
||
1525 mFlexBasis
!= aOther
.mFlexBasis
||
1526 mFlexGrow
!= aOther
.mFlexGrow
||
1527 mFlexShrink
!= aOther
.mFlexShrink
) {
1528 return NS_CombineHint(hint
, nsChangeHint_AllReflowHints
);
1531 // Properties that apply to flex containers:
1532 // - flex-direction can swap a flex container between vertical & horizontal.
1533 // - align-items can change the sizing of a flex container & the positioning
1535 // - flex-wrap changes whether a flex container's children are wrapped, which
1536 // impacts their sizing/positioning and hence impacts the container's size.
1537 if (mAlignItems
!= aOther
.mAlignItems
||
1538 mFlexDirection
!= aOther
.mFlexDirection
||
1539 mFlexWrap
!= aOther
.mFlexWrap
) {
1540 return NS_CombineHint(hint
, nsChangeHint_AllReflowHints
);
1543 // Properties that apply to grid containers:
1544 // FIXME: only for grid containers
1545 // (ie. 'display: grid' or 'display: inline-grid')
1546 if (mGridTemplateColumns
!= aOther
.mGridTemplateColumns
||
1547 mGridTemplateRows
!= aOther
.mGridTemplateRows
||
1548 mGridTemplateAreas
!= aOther
.mGridTemplateAreas
||
1549 mGridAutoColumnsMin
!= aOther
.mGridAutoColumnsMin
||
1550 mGridAutoColumnsMax
!= aOther
.mGridAutoColumnsMax
||
1551 mGridAutoRowsMin
!= aOther
.mGridAutoRowsMin
||
1552 mGridAutoRowsMax
!= aOther
.mGridAutoRowsMax
||
1553 mGridAutoFlow
!= aOther
.mGridAutoFlow
) {
1554 return NS_CombineHint(hint
, nsChangeHint_AllReflowHints
);
1557 // Properties that apply to grid items:
1558 // FIXME: only for grid items
1559 // (ie. parent frame is 'display: grid' or 'display: inline-grid')
1560 if (mGridColumnStart
!= aOther
.mGridColumnStart
||
1561 mGridColumnEnd
!= aOther
.mGridColumnEnd
||
1562 mGridRowStart
!= aOther
.mGridRowStart
||
1563 mGridRowEnd
!= aOther
.mGridRowEnd
) {
1564 return NS_CombineHint(hint
, nsChangeHint_AllReflowHints
);
1567 // Changing justify-content on a flexbox might affect the positioning of its
1568 // children, but it won't affect any sizing.
1569 if (mJustifyContent
!= aOther
.mJustifyContent
) {
1570 NS_UpdateHint(hint
, nsChangeHint_NeedReflow
);
1573 // Properties that apply only to multi-line flex containers:
1574 // 'align-content' can change the positioning & sizing of a multi-line flex
1575 // container's children when there's extra space in the cross axis, but it
1576 // shouldn't affect the container's own sizing.
1578 // NOTE: If we get here, we know that mFlexWrap == aOther.mFlexWrap
1579 // (otherwise, we would've returned earlier). So it doesn't matter which one
1580 // of those we check to see if we're multi-line.
1581 if (mFlexWrap
!= NS_STYLE_FLEX_WRAP_NOWRAP
&&
1582 mAlignContent
!= aOther
.mAlignContent
) {
1583 NS_UpdateHint(hint
, nsChangeHint_NeedReflow
);
1586 if (mHeight
!= aOther
.mHeight
||
1587 mMinHeight
!= aOther
.mMinHeight
||
1588 mMaxHeight
!= aOther
.mMaxHeight
) {
1589 // Height changes can affect descendant intrinsic sizes due to replaced
1590 // elements with percentage heights in descendants which also have
1591 // percentage heights. And due to our not-so-great computation of mVResize
1592 // in nsHTMLReflowState, they do need to force reflow of the whole subtree.
1593 // XXXbz due to XUL caching heights as well, height changes also need to
1594 // clear ancestor intrinsics!
1595 return NS_CombineHint(hint
, nsChangeHint_AllReflowHints
);
1598 if (mWidth
!= aOther
.mWidth
||
1599 mMinWidth
!= aOther
.mMinWidth
||
1600 mMaxWidth
!= aOther
.mMaxWidth
) {
1601 // None of our width differences can affect descendant intrinsic
1602 // sizes and none of them need to force children to reflow.
1604 NS_CombineHint(hint
,
1605 NS_SubtractHint(nsChangeHint_AllReflowHints
,
1606 NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics
,
1607 nsChangeHint_NeedDirtyReflow
)));
1610 // If width and height have not changed, but any of the offsets have changed,
1611 // then return the respective hints so that we would hopefully be able to
1613 // Note that it is possible that we'll need to reflow when processing
1614 // restyles, but we don't have enough information to make a good decision
1616 // Don't try to handle changes between "auto" and non-auto efficiently;
1617 // that's tricky to do and will hardly ever be able to avoid a reflow.
1618 if (mOffset
!= aOther
.mOffset
) {
1619 if (IsAutonessEqual(mOffset
, aOther
.mOffset
)) {
1620 NS_UpdateHint(hint
, nsChangeHint(nsChangeHint_RecomputePosition
|
1621 nsChangeHint_UpdateOverflow
));
1623 return NS_CombineHint(hint
, nsChangeHint_AllReflowHints
);
1630 nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord
&aCoord
)
1632 return aCoord
.HasPercent() ||
1633 (aCoord
.GetUnit() == eStyleUnit_Enumerated
&&
1634 (aCoord
.GetIntValue() == NS_STYLE_WIDTH_FIT_CONTENT
||
1635 aCoord
.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE
));
1638 // --------------------
1642 nsStyleTable::nsStyleTable()
1644 MOZ_COUNT_CTOR(nsStyleTable
);
1645 // values not inherited
1646 mLayoutStrategy
= NS_STYLE_TABLE_LAYOUT_AUTO
;
1650 nsStyleTable::~nsStyleTable(void)
1652 MOZ_COUNT_DTOR(nsStyleTable
);
1655 nsStyleTable::nsStyleTable(const nsStyleTable
& aSource
)
1656 : mLayoutStrategy(aSource
.mLayoutStrategy
)
1657 , mSpan(aSource
.mSpan
)
1659 MOZ_COUNT_CTOR(nsStyleTable
);
1662 nsChangeHint
nsStyleTable::CalcDifference(const nsStyleTable
& aOther
) const
1664 if (mSpan
!= aOther
.mSpan
||
1665 mLayoutStrategy
!= aOther
.mLayoutStrategy
)
1666 return NS_STYLE_HINT_FRAMECHANGE
;
1667 return NS_STYLE_HINT_NONE
;
1670 // -----------------------
1671 // nsStyleTableBorder
1673 nsStyleTableBorder::nsStyleTableBorder()
1675 MOZ_COUNT_CTOR(nsStyleTableBorder
);
1676 mBorderCollapse
= NS_STYLE_BORDER_SEPARATE
;
1678 mEmptyCells
= NS_STYLE_TABLE_EMPTY_CELLS_SHOW
;
1679 mCaptionSide
= NS_STYLE_CAPTION_SIDE_TOP
;
1680 mBorderSpacingX
= 0;
1681 mBorderSpacingY
= 0;
1684 nsStyleTableBorder::~nsStyleTableBorder(void)
1686 MOZ_COUNT_DTOR(nsStyleTableBorder
);
1689 nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder
& aSource
)
1690 : mBorderSpacingX(aSource
.mBorderSpacingX
)
1691 , mBorderSpacingY(aSource
.mBorderSpacingY
)
1692 , mBorderCollapse(aSource
.mBorderCollapse
)
1693 , mCaptionSide(aSource
.mCaptionSide
)
1694 , mEmptyCells(aSource
.mEmptyCells
)
1696 MOZ_COUNT_CTOR(nsStyleTableBorder
);
1699 nsChangeHint
nsStyleTableBorder::CalcDifference(const nsStyleTableBorder
& aOther
) const
1701 // Border-collapse changes need a reframe, because we use a different frame
1702 // class for table cells in the collapsed border model. This is used to
1703 // conserve memory when using the separated border model (collapsed borders
1704 // require extra state to be stored).
1705 if (mBorderCollapse
!= aOther
.mBorderCollapse
) {
1706 return NS_STYLE_HINT_FRAMECHANGE
;
1709 if ((mCaptionSide
== aOther
.mCaptionSide
) &&
1710 (mBorderSpacingX
== aOther
.mBorderSpacingX
) &&
1711 (mBorderSpacingY
== aOther
.mBorderSpacingY
)) {
1712 if (mEmptyCells
== aOther
.mEmptyCells
)
1713 return NS_STYLE_HINT_NONE
;
1714 return NS_STYLE_HINT_VISUAL
;
1717 return NS_STYLE_HINT_REFLOW
;
1720 // --------------------
1724 nsStyleColor::nsStyleColor(nsPresContext
* aPresContext
)
1726 MOZ_COUNT_CTOR(nsStyleColor
);
1727 mColor
= aPresContext
->DefaultColor();
1730 nsStyleColor::nsStyleColor(const nsStyleColor
& aSource
)
1732 MOZ_COUNT_CTOR(nsStyleColor
);
1733 mColor
= aSource
.mColor
;
1736 nsChangeHint
nsStyleColor::CalcDifference(const nsStyleColor
& aOther
) const
1738 if (mColor
== aOther
.mColor
)
1739 return NS_STYLE_HINT_NONE
;
1740 return NS_STYLE_HINT_VISUAL
;
1743 // --------------------
1747 nsStyleGradient::operator==(const nsStyleGradient
& aOther
) const
1749 NS_ABORT_IF_FALSE(mSize
== NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
||
1750 mShape
!= NS_STYLE_GRADIENT_SHAPE_LINEAR
,
1751 "incorrect combination of shape and size");
1752 NS_ABORT_IF_FALSE(aOther
.mSize
== NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
||
1753 aOther
.mShape
!= NS_STYLE_GRADIENT_SHAPE_LINEAR
,
1754 "incorrect combination of shape and size");
1756 if (mShape
!= aOther
.mShape
||
1757 mSize
!= aOther
.mSize
||
1758 mRepeating
!= aOther
.mRepeating
||
1759 mLegacySyntax
!= aOther
.mLegacySyntax
||
1760 mBgPosX
!= aOther
.mBgPosX
||
1761 mBgPosY
!= aOther
.mBgPosY
||
1762 mAngle
!= aOther
.mAngle
||
1763 mRadiusX
!= aOther
.mRadiusX
||
1764 mRadiusY
!= aOther
.mRadiusY
)
1767 if (mStops
.Length() != aOther
.mStops
.Length())
1770 for (uint32_t i
= 0; i
< mStops
.Length(); i
++) {
1771 const auto& stop1
= mStops
[i
];
1772 const auto& stop2
= aOther
.mStops
[i
];
1773 if (stop1
.mLocation
!= stop2
.mLocation
||
1774 stop1
.mIsInterpolationHint
!= stop2
.mIsInterpolationHint
||
1775 (!stop1
.mIsInterpolationHint
&& stop1
.mColor
!= stop2
.mColor
))
1782 nsStyleGradient::nsStyleGradient(void)
1783 : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR
)
1784 , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
)
1786 , mLegacySyntax(false)
1791 nsStyleGradient::IsOpaque()
1793 for (uint32_t i
= 0; i
< mStops
.Length(); i
++) {
1794 if (NS_GET_A(mStops
[i
].mColor
) < 255)
1801 nsStyleGradient::HasCalc()
1803 for (uint32_t i
= 0; i
< mStops
.Length(); i
++) {
1804 if (mStops
[i
].mLocation
.IsCalcUnit())
1807 return mBgPosX
.IsCalcUnit() || mBgPosY
.IsCalcUnit() || mAngle
.IsCalcUnit() ||
1808 mRadiusX
.IsCalcUnit() || mRadiusY
.IsCalcUnit();
1811 // --------------------
1815 nsStyleImage::nsStyleImage()
1816 : mType(eStyleImageType_Null
)
1817 , mCropRect(nullptr)
1819 , mImageTracked(false)
1822 MOZ_COUNT_CTOR(nsStyleImage
);
1825 nsStyleImage::~nsStyleImage()
1827 MOZ_COUNT_DTOR(nsStyleImage
);
1828 if (mType
!= eStyleImageType_Null
)
1832 nsStyleImage::nsStyleImage(const nsStyleImage
& aOther
)
1833 : mType(eStyleImageType_Null
)
1834 , mCropRect(nullptr)
1836 , mImageTracked(false)
1839 // We need our own copy constructor because we don't want
1840 // to copy the reference count
1841 MOZ_COUNT_CTOR(nsStyleImage
);
1846 nsStyleImage::operator=(const nsStyleImage
& aOther
)
1848 if (this != &aOther
)
1855 nsStyleImage::DoCopy(const nsStyleImage
& aOther
)
1859 if (aOther
.mType
== eStyleImageType_Image
)
1860 SetImageData(aOther
.mImage
);
1861 else if (aOther
.mType
== eStyleImageType_Gradient
)
1862 SetGradientData(aOther
.mGradient
);
1863 else if (aOther
.mType
== eStyleImageType_Element
)
1864 SetElementId(aOther
.mElementId
);
1866 SetCropRect(aOther
.mCropRect
);
1870 nsStyleImage::SetNull()
1872 NS_ABORT_IF_FALSE(!mImageTracked
,
1873 "Calling SetNull() with image tracked!");
1875 if (mType
== eStyleImageType_Gradient
)
1876 mGradient
->Release();
1877 else if (mType
== eStyleImageType_Image
)
1879 else if (mType
== eStyleImageType_Element
)
1880 NS_Free(mElementId
);
1882 mType
= eStyleImageType_Null
;
1883 mCropRect
= nullptr;
1887 nsStyleImage::SetImageData(imgRequestProxy
* aImage
)
1889 NS_ABORT_IF_FALSE(!mImageTracked
,
1890 "Setting a new image without untracking the old one!");
1892 NS_IF_ADDREF(aImage
);
1894 if (mType
!= eStyleImageType_Null
)
1899 mType
= eStyleImageType_Image
;
1905 nsStyleImage::TrackImage(nsPresContext
* aContext
)
1908 NS_ABORT_IF_FALSE(!mImageTracked
, "Already tracking image!");
1909 NS_ABORT_IF_FALSE(mType
== eStyleImageType_Image
,
1910 "Can't track image when there isn't one!");
1912 // Register the image with the document
1913 nsIDocument
* doc
= aContext
->Document();
1915 doc
->AddImage(mImage
);
1919 mImageTracked
= true;
1924 nsStyleImage::UntrackImage(nsPresContext
* aContext
)
1927 NS_ABORT_IF_FALSE(mImageTracked
, "Image not tracked!");
1928 NS_ABORT_IF_FALSE(mType
== eStyleImageType_Image
,
1929 "Can't untrack image when there isn't one!");
1931 // Unregister the image with the document
1932 nsIDocument
* doc
= aContext
->Document();
1934 doc
->RemoveImage(mImage
, nsIDocument::REQUEST_DISCARD
);
1938 mImageTracked
= false;
1943 nsStyleImage::SetGradientData(nsStyleGradient
* aGradient
)
1946 aGradient
->AddRef();
1948 if (mType
!= eStyleImageType_Null
)
1952 mGradient
= aGradient
;
1953 mType
= eStyleImageType_Gradient
;
1958 nsStyleImage::SetElementId(const char16_t
* aElementId
)
1960 if (mType
!= eStyleImageType_Null
)
1964 mElementId
= NS_strdup(aElementId
);
1965 mType
= eStyleImageType_Element
;
1970 nsStyleImage::SetCropRect(nsStyleSides
* aCropRect
)
1973 mCropRect
= new nsStyleSides(*aCropRect
);
1974 // There is really not much we can do if 'new' fails
1976 mCropRect
= nullptr;
1981 ConvertToPixelCoord(const nsStyleCoord
& aCoord
, int32_t aPercentScale
)
1984 switch (aCoord
.GetUnit()) {
1985 case eStyleUnit_Percent
:
1986 pixelValue
= aCoord
.GetPercentValue() * aPercentScale
;
1988 case eStyleUnit_Factor
:
1989 pixelValue
= aCoord
.GetFactorValue();
1992 NS_NOTREACHED("unexpected unit for image crop rect");
1995 NS_ABORT_IF_FALSE(pixelValue
>= 0, "we ensured non-negative while parsing");
1996 pixelValue
= std::min(pixelValue
, double(INT32_MAX
)); // avoid overflow
1997 return NS_lround(pixelValue
);
2001 nsStyleImage::ComputeActualCropRect(nsIntRect
& aActualCropRect
,
2002 bool* aIsEntireImage
) const
2004 if (mType
!= eStyleImageType_Image
)
2007 nsCOMPtr
<imgIContainer
> imageContainer
;
2008 mImage
->GetImage(getter_AddRefs(imageContainer
));
2009 if (!imageContainer
)
2012 nsIntSize imageSize
;
2013 imageContainer
->GetWidth(&imageSize
.width
);
2014 imageContainer
->GetHeight(&imageSize
.height
);
2015 if (imageSize
.width
<= 0 || imageSize
.height
<= 0)
2018 int32_t left
= ConvertToPixelCoord(mCropRect
->GetLeft(), imageSize
.width
);
2019 int32_t top
= ConvertToPixelCoord(mCropRect
->GetTop(), imageSize
.height
);
2020 int32_t right
= ConvertToPixelCoord(mCropRect
->GetRight(), imageSize
.width
);
2021 int32_t bottom
= ConvertToPixelCoord(mCropRect
->GetBottom(), imageSize
.height
);
2023 // IntersectRect() returns an empty rect if we get negative width or height
2024 nsIntRect
cropRect(left
, top
, right
- left
, bottom
- top
);
2025 nsIntRect
imageRect(nsIntPoint(0, 0), imageSize
);
2026 aActualCropRect
.IntersectRect(imageRect
, cropRect
);
2029 *aIsEntireImage
= aActualCropRect
.IsEqualInterior(imageRect
);
2034 nsStyleImage::StartDecoding() const
2036 if ((mType
== eStyleImageType_Image
) && mImage
)
2037 return mImage
->StartDecoding();
2042 nsStyleImage::IsOpaque() const
2047 if (mType
== eStyleImageType_Gradient
)
2048 return mGradient
->IsOpaque();
2050 if (mType
== eStyleImageType_Element
)
2053 NS_ABORT_IF_FALSE(mType
== eStyleImageType_Image
, "unexpected image type");
2055 nsCOMPtr
<imgIContainer
> imageContainer
;
2056 mImage
->GetImage(getter_AddRefs(imageContainer
));
2057 NS_ABORT_IF_FALSE(imageContainer
, "IsComplete() said image container is ready");
2059 // Check if the crop region of the image is opaque.
2060 if (imageContainer
->IsOpaque()) {
2064 // Must make sure if mCropRect contains at least a pixel.
2065 // XXX Is this optimization worth it? Maybe I should just return false.
2066 nsIntRect actualCropRect
;
2067 bool rv
= ComputeActualCropRect(actualCropRect
);
2068 NS_ASSERTION(rv
, "ComputeActualCropRect() can not fail here");
2069 return rv
&& !actualCropRect
.IsEmpty();
2076 nsStyleImage::IsComplete() const
2079 case eStyleImageType_Null
:
2081 case eStyleImageType_Gradient
:
2082 case eStyleImageType_Element
:
2084 case eStyleImageType_Image
:
2086 uint32_t status
= imgIRequest::STATUS_ERROR
;
2087 return NS_SUCCEEDED(mImage
->GetImageStatus(&status
)) &&
2088 (status
& imgIRequest::STATUS_SIZE_AVAILABLE
) &&
2089 (status
& imgIRequest::STATUS_FRAME_COMPLETE
);
2092 NS_NOTREACHED("unexpected image type");
2098 nsStyleImage::IsLoaded() const
2101 case eStyleImageType_Null
:
2103 case eStyleImageType_Gradient
:
2104 case eStyleImageType_Element
:
2106 case eStyleImageType_Image
:
2108 uint32_t status
= imgIRequest::STATUS_ERROR
;
2109 return NS_SUCCEEDED(mImage
->GetImageStatus(&status
)) &&
2110 !(status
& imgIRequest::STATUS_ERROR
) &&
2111 (status
& imgIRequest::STATUS_LOAD_COMPLETE
);
2114 NS_NOTREACHED("unexpected image type");
2120 EqualRects(const nsStyleSides
* aRect1
, const nsStyleSides
* aRect2
)
2122 return aRect1
== aRect2
|| /* handles null== null, and optimize */
2123 (aRect1
&& aRect2
&& *aRect1
== *aRect2
);
2127 nsStyleImage::operator==(const nsStyleImage
& aOther
) const
2129 if (mType
!= aOther
.mType
)
2132 if (!EqualRects(mCropRect
, aOther
.mCropRect
))
2135 if (mType
== eStyleImageType_Image
)
2136 return EqualImages(mImage
, aOther
.mImage
);
2138 if (mType
== eStyleImageType_Gradient
)
2139 return *mGradient
== *aOther
.mGradient
;
2141 if (mType
== eStyleImageType_Element
)
2142 return NS_strcmp(mElementId
, aOther
.mElementId
) == 0;
2147 // --------------------
2148 // nsStyleBackground
2151 nsStyleBackground::nsStyleBackground()
2152 : mAttachmentCount(1)
2159 , mBlendModeCount(1)
2160 , mBackgroundColor(NS_RGBA(0, 0, 0, 0))
2162 MOZ_COUNT_CTOR(nsStyleBackground
);
2163 Layer
*onlyLayer
= mLayers
.AppendElement();
2164 NS_ASSERTION(onlyLayer
, "auto array must have room for 1 element");
2165 onlyLayer
->SetInitialValues();
2168 nsStyleBackground::nsStyleBackground(const nsStyleBackground
& aSource
)
2169 : mAttachmentCount(aSource
.mAttachmentCount
)
2170 , mClipCount(aSource
.mClipCount
)
2171 , mOriginCount(aSource
.mOriginCount
)
2172 , mRepeatCount(aSource
.mRepeatCount
)
2173 , mPositionCount(aSource
.mPositionCount
)
2174 , mImageCount(aSource
.mImageCount
)
2175 , mSizeCount(aSource
.mSizeCount
)
2176 , mBlendModeCount(aSource
.mBlendModeCount
)
2177 , mLayers(aSource
.mLayers
) // deep copy
2178 , mBackgroundColor(aSource
.mBackgroundColor
)
2180 MOZ_COUNT_CTOR(nsStyleBackground
);
2181 // If the deep copy of mLayers failed, truncate the counts.
2182 uint32_t count
= mLayers
.Length();
2183 if (count
!= aSource
.mLayers
.Length()) {
2184 NS_WARNING("truncating counts due to out-of-memory");
2185 mAttachmentCount
= std::max(mAttachmentCount
, count
);
2186 mClipCount
= std::max(mClipCount
, count
);
2187 mOriginCount
= std::max(mOriginCount
, count
);
2188 mRepeatCount
= std::max(mRepeatCount
, count
);
2189 mPositionCount
= std::max(mPositionCount
, count
);
2190 mImageCount
= std::max(mImageCount
, count
);
2191 mSizeCount
= std::max(mSizeCount
, count
);
2192 mBlendModeCount
= std::max(mSizeCount
, count
);
2196 nsStyleBackground::~nsStyleBackground()
2198 MOZ_COUNT_DTOR(nsStyleBackground
);
2202 nsStyleBackground::Destroy(nsPresContext
* aContext
)
2204 // Untrack all the images stored in our layers
2205 for (uint32_t i
= 0; i
< mImageCount
; ++i
)
2206 mLayers
[i
].UntrackImages(aContext
);
2208 this->~nsStyleBackground();
2209 aContext
->PresShell()->
2210 FreeByObjectID(nsPresArena::nsStyleBackground_id
, this);
2213 nsChangeHint
nsStyleBackground::CalcDifference(const nsStyleBackground
& aOther
) const
2215 const nsStyleBackground
* moreLayers
=
2216 mImageCount
> aOther
.mImageCount
? this : &aOther
;
2217 const nsStyleBackground
* lessLayers
=
2218 mImageCount
> aOther
.mImageCount
? &aOther
: this;
2220 bool hasVisualDifference
= false;
2222 NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i
, moreLayers
) {
2223 if (i
< lessLayers
->mImageCount
) {
2224 if (moreLayers
->mLayers
[i
] != lessLayers
->mLayers
[i
]) {
2225 if ((moreLayers
->mLayers
[i
].mImage
.GetType() == eStyleImageType_Element
) ||
2226 (lessLayers
->mLayers
[i
].mImage
.GetType() == eStyleImageType_Element
))
2227 return NS_CombineHint(nsChangeHint_UpdateEffects
, NS_STYLE_HINT_VISUAL
);
2228 hasVisualDifference
= true;
2231 if (moreLayers
->mLayers
[i
].mImage
.GetType() == eStyleImageType_Element
)
2232 return NS_CombineHint(nsChangeHint_UpdateEffects
, NS_STYLE_HINT_VISUAL
);
2233 hasVisualDifference
= true;
2237 if (hasVisualDifference
|| mBackgroundColor
!= aOther
.mBackgroundColor
)
2238 return NS_STYLE_HINT_VISUAL
;
2240 if (mAttachmentCount
!= aOther
.mAttachmentCount
||
2241 mClipCount
!= aOther
.mClipCount
||
2242 mOriginCount
!= aOther
.mOriginCount
||
2243 mRepeatCount
!= aOther
.mRepeatCount
||
2244 mPositionCount
!= aOther
.mPositionCount
||
2245 mSizeCount
!= aOther
.mSizeCount
) {
2246 return nsChangeHint_NeutralChange
;
2249 return NS_STYLE_HINT_NONE
;
2252 bool nsStyleBackground::HasFixedBackground() const
2254 NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i
, this) {
2255 const Layer
&layer
= mLayers
[i
];
2256 if (layer
.mAttachment
== NS_STYLE_BG_ATTACHMENT_FIXED
&&
2257 !layer
.mImage
.IsEmpty()) {
2264 bool nsStyleBackground::IsTransparent() const
2266 return BottomLayer().mImage
.IsEmpty() &&
2268 NS_GET_A(mBackgroundColor
) == 0;
2272 nsStyleBackground::Position::SetInitialPercentValues(float aPercentVal
)
2274 mXPosition
.mPercent
= aPercentVal
;
2275 mXPosition
.mLength
= 0;
2276 mXPosition
.mHasPercent
= true;
2277 mYPosition
.mPercent
= aPercentVal
;
2278 mYPosition
.mLength
= 0;
2279 mYPosition
.mHasPercent
= true;
2283 nsStyleBackground::Size::DependsOnPositioningAreaSize(const nsStyleImage
& aImage
) const
2285 NS_ABORT_IF_FALSE(aImage
.GetType() != eStyleImageType_Null
,
2286 "caller should have handled this");
2288 // If either dimension contains a non-zero percentage, rendering for that
2289 // dimension straightforwardly depends on frame size.
2290 if ((mWidthType
== eLengthPercentage
&& mWidth
.mPercent
!= 0.0f
) ||
2291 (mHeightType
== eLengthPercentage
&& mHeight
.mPercent
!= 0.0f
)) {
2295 // So too for contain and cover.
2296 if (mWidthType
== eContain
|| mWidthType
== eCover
) {
2300 // If both dimensions are fixed lengths, there's no dependency.
2301 if (mWidthType
== eLengthPercentage
&& mHeightType
== eLengthPercentage
) {
2305 NS_ABORT_IF_FALSE((mWidthType
== eLengthPercentage
&& mHeightType
== eAuto
) ||
2306 (mWidthType
== eAuto
&& mHeightType
== eLengthPercentage
) ||
2307 (mWidthType
== eAuto
&& mHeightType
== eAuto
),
2310 nsStyleImageType type
= aImage
.GetType();
2312 // Gradient rendering depends on frame size when auto is involved because
2313 // gradients have no intrinsic ratio or dimensions, and therefore the relevant
2314 // dimension is "treat[ed] as 100%".
2315 if (type
== eStyleImageType_Gradient
) {
2319 // XXX Element rendering for auto or fixed length doesn't depend on frame size
2320 // according to the spec. However, we don't implement the spec yet, so
2321 // for now we bail and say element() plus auto affects ultimate size.
2322 if (type
== eStyleImageType_Element
) {
2326 if (type
== eStyleImageType_Image
) {
2327 nsCOMPtr
<imgIContainer
> imgContainer
;
2328 aImage
.GetImageData()->GetImage(getter_AddRefs(imgContainer
));
2330 nsIntSize imageSize
;
2332 bool hasWidth
, hasHeight
;
2333 nsLayoutUtils::ComputeSizeForDrawing(imgContainer
, imageSize
, imageRatio
,
2334 hasWidth
, hasHeight
);
2336 // If the image has a fixed width and height, rendering never depends on
2338 if (hasWidth
&& hasHeight
) {
2342 // If the image has an intrinsic ratio, rendering will depend on frame
2343 // size when background-size is all auto.
2344 if (imageRatio
!= nsSize(0, 0)) {
2345 return mWidthType
== mHeightType
;
2348 // Otherwise, rendering depends on frame size when the image dimensions
2349 // and background-size don't complement each other.
2350 return !(hasWidth
&& mHeightType
== eLengthPercentage
) &&
2351 !(hasHeight
&& mWidthType
== eLengthPercentage
);
2354 NS_NOTREACHED("missed an enum value");
2357 // Passed the gauntlet: no dependency.
2362 nsStyleBackground::Size::SetInitialValues()
2364 mWidthType
= mHeightType
= eAuto
;
2368 nsStyleBackground::Size::operator==(const Size
& aOther
) const
2370 NS_ABORT_IF_FALSE(mWidthType
< eDimensionType_COUNT
,
2371 "bad mWidthType for this");
2372 NS_ABORT_IF_FALSE(mHeightType
< eDimensionType_COUNT
,
2373 "bad mHeightType for this");
2374 NS_ABORT_IF_FALSE(aOther
.mWidthType
< eDimensionType_COUNT
,
2375 "bad mWidthType for aOther");
2376 NS_ABORT_IF_FALSE(aOther
.mHeightType
< eDimensionType_COUNT
,
2377 "bad mHeightType for aOther");
2379 return mWidthType
== aOther
.mWidthType
&&
2380 mHeightType
== aOther
.mHeightType
&&
2381 (mWidthType
!= eLengthPercentage
|| mWidth
== aOther
.mWidth
) &&
2382 (mHeightType
!= eLengthPercentage
|| mHeight
== aOther
.mHeight
);
2386 nsStyleBackground::Repeat::SetInitialValues()
2388 mXRepeat
= NS_STYLE_BG_REPEAT_REPEAT
;
2389 mYRepeat
= NS_STYLE_BG_REPEAT_REPEAT
;
2392 nsStyleBackground::Layer::Layer()
2396 nsStyleBackground::Layer::~Layer()
2401 nsStyleBackground::Layer::SetInitialValues()
2403 mAttachment
= NS_STYLE_BG_ATTACHMENT_SCROLL
;
2404 mClip
= NS_STYLE_BG_CLIP_BORDER
;
2405 mOrigin
= NS_STYLE_BG_ORIGIN_PADDING
;
2406 mRepeat
.SetInitialValues();
2407 mBlendMode
= NS_STYLE_BLEND_NORMAL
;
2408 mPosition
.SetInitialPercentValues(0.0f
); // Initial value is "0% 0%"
2409 mSize
.SetInitialValues();
2414 nsStyleBackground::Layer::RenderingMightDependOnPositioningAreaSizeChange() const
2416 // Do we even have an image?
2417 if (mImage
.IsEmpty()) {
2421 return mPosition
.DependsOnPositioningAreaSize() ||
2422 mSize
.DependsOnPositioningAreaSize(mImage
);
2426 nsStyleBackground::Layer::operator==(const Layer
& aOther
) const
2428 return mAttachment
== aOther
.mAttachment
&&
2429 mClip
== aOther
.mClip
&&
2430 mOrigin
== aOther
.mOrigin
&&
2431 mRepeat
== aOther
.mRepeat
&&
2432 mBlendMode
== aOther
.mBlendMode
&&
2433 mPosition
== aOther
.mPosition
&&
2434 mSize
== aOther
.mSize
&&
2435 mImage
== aOther
.mImage
;
2438 // --------------------
2441 void nsTimingFunction::AssignFromKeyword(int32_t aTimingFunctionType
)
2443 switch (aTimingFunctionType
) {
2444 case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START
:
2448 case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END
:
2457 static_assert(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE
== 0 &&
2458 NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR
== 1 &&
2459 NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN
== 2 &&
2460 NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_OUT
== 3 &&
2461 NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE_IN_OUT
== 4,
2462 "transition timing function constants not as expected");
2464 static const float timingFunctionValues
[5][4] = {
2465 { 0.25f
, 0.10f
, 0.25f
, 1.00f
}, // ease
2466 { 0.00f
, 0.00f
, 1.00f
, 1.00f
}, // linear
2467 { 0.42f
, 0.00f
, 1.00f
, 1.00f
}, // ease-in
2468 { 0.00f
, 0.00f
, 0.58f
, 1.00f
}, // ease-out
2469 { 0.42f
, 0.00f
, 0.58f
, 1.00f
} // ease-in-out
2472 NS_ABORT_IF_FALSE(0 <= aTimingFunctionType
&& aTimingFunctionType
< 5,
2473 "keyword out of range");
2474 mFunc
.mX1
= timingFunctionValues
[aTimingFunctionType
][0];
2475 mFunc
.mY1
= timingFunctionValues
[aTimingFunctionType
][1];
2476 mFunc
.mX2
= timingFunctionValues
[aTimingFunctionType
][2];
2477 mFunc
.mY2
= timingFunctionValues
[aTimingFunctionType
][3];
2480 mozilla::StyleTransition::StyleTransition(const StyleTransition
& aCopy
)
2481 : mTimingFunction(aCopy
.mTimingFunction
)
2482 , mDuration(aCopy
.mDuration
)
2483 , mDelay(aCopy
.mDelay
)
2484 , mProperty(aCopy
.mProperty
)
2485 , mUnknownProperty(aCopy
.mUnknownProperty
)
2490 mozilla::StyleTransition::SetInitialValues()
2492 mTimingFunction
= nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE
);
2495 mProperty
= eCSSPropertyExtra_all_properties
;
2499 mozilla::StyleTransition::SetUnknownProperty(const nsAString
& aUnknownProperty
)
2501 NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty
,
2502 nsCSSProps::eEnabledForAllContent
) ==
2503 eCSSProperty_UNKNOWN
,
2504 "should be unknown property");
2505 mProperty
= eCSSProperty_UNKNOWN
;
2506 mUnknownProperty
= do_GetAtom(aUnknownProperty
);
2510 mozilla::StyleTransition::operator==(const mozilla::StyleTransition
& aOther
) const
2512 return mTimingFunction
== aOther
.mTimingFunction
&&
2513 mDuration
== aOther
.mDuration
&&
2514 mDelay
== aOther
.mDelay
&&
2515 mProperty
== aOther
.mProperty
&&
2516 (mProperty
!= eCSSProperty_UNKNOWN
||
2517 mUnknownProperty
== aOther
.mUnknownProperty
);
2520 mozilla::StyleAnimation::StyleAnimation(const mozilla::StyleAnimation
& aCopy
)
2521 : mTimingFunction(aCopy
.mTimingFunction
)
2522 , mDuration(aCopy
.mDuration
)
2523 , mDelay(aCopy
.mDelay
)
2524 , mName(aCopy
.mName
)
2525 , mDirection(aCopy
.mDirection
)
2526 , mFillMode(aCopy
.mFillMode
)
2527 , mPlayState(aCopy
.mPlayState
)
2528 , mIterationCount(aCopy
.mIterationCount
)
2533 mozilla::StyleAnimation::SetInitialValues()
2535 mTimingFunction
= nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE
);
2538 mName
= EmptyString();
2539 mDirection
= NS_STYLE_ANIMATION_DIRECTION_NORMAL
;
2540 mFillMode
= NS_STYLE_ANIMATION_FILL_MODE_NONE
;
2541 mPlayState
= NS_STYLE_ANIMATION_PLAY_STATE_RUNNING
;
2542 mIterationCount
= 1.0f
;
2546 mozilla::StyleAnimation::operator==(const mozilla::StyleAnimation
& aOther
) const
2548 return mTimingFunction
== aOther
.mTimingFunction
&&
2549 mDuration
== aOther
.mDuration
&&
2550 mDelay
== aOther
.mDelay
&&
2551 mName
== aOther
.mName
&&
2552 mDirection
== aOther
.mDirection
&&
2553 mFillMode
== aOther
.mFillMode
&&
2554 mPlayState
== aOther
.mPlayState
&&
2555 mIterationCount
== aOther
.mIterationCount
;
2558 nsStyleDisplay::nsStyleDisplay()
2559 : mWillChangeBitField(0)
2561 MOZ_COUNT_CTOR(nsStyleDisplay
);
2562 mAppearance
= NS_THEME_NONE
;
2563 mDisplay
= NS_STYLE_DISPLAY_INLINE
;
2564 mOriginalDisplay
= mDisplay
;
2565 mPosition
= NS_STYLE_POSITION_STATIC
;
2566 mFloats
= NS_STYLE_FLOAT_NONE
;
2567 mOriginalFloats
= mFloats
;
2568 mBreakType
= NS_STYLE_CLEAR_NONE
;
2569 mBreakInside
= NS_STYLE_PAGE_BREAK_AUTO
;
2570 mBreakBefore
= false;
2571 mBreakAfter
= false;
2572 mOverflowX
= NS_STYLE_OVERFLOW_VISIBLE
;
2573 mOverflowY
= NS_STYLE_OVERFLOW_VISIBLE
;
2574 mOverflowClipBox
= NS_STYLE_OVERFLOW_CLIP_BOX_PADDING_BOX
;
2575 mResize
= NS_STYLE_RESIZE_NONE
;
2576 mClipFlags
= NS_STYLE_CLIP_AUTO
;
2577 mClip
.SetRect(0,0,0,0);
2579 mSpecifiedTransform
= nullptr;
2580 mTransformOrigin
[0].SetPercentValue(0.5f
); // Transform is centered on origin
2581 mTransformOrigin
[1].SetPercentValue(0.5f
);
2582 mTransformOrigin
[2].SetCoordValue(0);
2583 mPerspectiveOrigin
[0].SetPercentValue(0.5f
);
2584 mPerspectiveOrigin
[1].SetPercentValue(0.5f
);
2585 mChildPerspective
.SetNoneValue();
2586 mBackfaceVisibility
= NS_STYLE_BACKFACE_VISIBILITY_VISIBLE
;
2587 mTransformStyle
= NS_STYLE_TRANSFORM_STYLE_FLAT
;
2588 mOrient
= NS_STYLE_ORIENT_AUTO
;
2589 mMixBlendMode
= NS_STYLE_BLEND_NORMAL
;
2590 mIsolation
= NS_STYLE_ISOLATION_AUTO
;
2591 mTouchAction
= NS_STYLE_TOUCH_ACTION_AUTO
;
2592 mScrollBehavior
= NS_STYLE_SCROLL_BEHAVIOR_AUTO
;
2594 mTransitions
.AppendElement();
2595 NS_ABORT_IF_FALSE(mTransitions
.Length() == 1,
2596 "appending within auto buffer should never fail");
2597 mTransitions
[0].SetInitialValues();
2598 mTransitionTimingFunctionCount
= 1;
2599 mTransitionDurationCount
= 1;
2600 mTransitionDelayCount
= 1;
2601 mTransitionPropertyCount
= 1;
2603 mAnimations
.AppendElement();
2604 NS_ABORT_IF_FALSE(mAnimations
.Length() == 1,
2605 "appending within auto buffer should never fail");
2606 mAnimations
[0].SetInitialValues();
2607 mAnimationTimingFunctionCount
= 1;
2608 mAnimationDurationCount
= 1;
2609 mAnimationDelayCount
= 1;
2610 mAnimationNameCount
= 1;
2611 mAnimationDirectionCount
= 1;
2612 mAnimationFillModeCount
= 1;
2613 mAnimationPlayStateCount
= 1;
2614 mAnimationIterationCountCount
= 1;
2617 nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay
& aSource
)
2618 : mBinding(aSource
.mBinding
)
2619 , mClip(aSource
.mClip
)
2620 , mOpacity(aSource
.mOpacity
)
2621 , mDisplay(aSource
.mDisplay
)
2622 , mOriginalDisplay(aSource
.mOriginalDisplay
)
2623 , mAppearance(aSource
.mAppearance
)
2624 , mPosition(aSource
.mPosition
)
2625 , mFloats(aSource
.mFloats
)
2626 , mOriginalFloats(aSource
.mOriginalFloats
)
2627 , mBreakType(aSource
.mBreakType
)
2628 , mBreakInside(aSource
.mBreakInside
)
2629 , mBreakBefore(aSource
.mBreakBefore
)
2630 , mBreakAfter(aSource
.mBreakAfter
)
2631 , mOverflowX(aSource
.mOverflowX
)
2632 , mOverflowY(aSource
.mOverflowY
)
2633 , mOverflowClipBox(aSource
.mOverflowClipBox
)
2634 , mResize(aSource
.mResize
)
2635 , mClipFlags(aSource
.mClipFlags
)
2636 , mOrient(aSource
.mOrient
)
2637 , mMixBlendMode(aSource
.mMixBlendMode
)
2638 , mIsolation(aSource
.mIsolation
)
2639 , mWillChangeBitField(aSource
.mWillChangeBitField
)
2640 , mWillChange(aSource
.mWillChange
)
2641 , mTouchAction(aSource
.mTouchAction
)
2642 , mScrollBehavior(aSource
.mScrollBehavior
)
2643 , mBackfaceVisibility(aSource
.mBackfaceVisibility
)
2644 , mTransformStyle(aSource
.mTransformStyle
)
2645 , mSpecifiedTransform(aSource
.mSpecifiedTransform
)
2646 , mChildPerspective(aSource
.mChildPerspective
)
2647 , mTransitions(aSource
.mTransitions
)
2648 , mTransitionTimingFunctionCount(aSource
.mTransitionTimingFunctionCount
)
2649 , mTransitionDurationCount(aSource
.mTransitionDurationCount
)
2650 , mTransitionDelayCount(aSource
.mTransitionDelayCount
)
2651 , mTransitionPropertyCount(aSource
.mTransitionPropertyCount
)
2652 , mAnimations(aSource
.mAnimations
)
2653 , mAnimationTimingFunctionCount(aSource
.mAnimationTimingFunctionCount
)
2654 , mAnimationDurationCount(aSource
.mAnimationDurationCount
)
2655 , mAnimationDelayCount(aSource
.mAnimationDelayCount
)
2656 , mAnimationNameCount(aSource
.mAnimationNameCount
)
2657 , mAnimationDirectionCount(aSource
.mAnimationDirectionCount
)
2658 , mAnimationFillModeCount(aSource
.mAnimationFillModeCount
)
2659 , mAnimationPlayStateCount(aSource
.mAnimationPlayStateCount
)
2660 , mAnimationIterationCountCount(aSource
.mAnimationIterationCountCount
)
2662 MOZ_COUNT_CTOR(nsStyleDisplay
);
2664 /* Copy over transform origin. */
2665 mTransformOrigin
[0] = aSource
.mTransformOrigin
[0];
2666 mTransformOrigin
[1] = aSource
.mTransformOrigin
[1];
2667 mTransformOrigin
[2] = aSource
.mTransformOrigin
[2];
2668 mPerspectiveOrigin
[0] = aSource
.mPerspectiveOrigin
[0];
2669 mPerspectiveOrigin
[1] = aSource
.mPerspectiveOrigin
[1];
2672 nsChangeHint
nsStyleDisplay::CalcDifference(const nsStyleDisplay
& aOther
) const
2674 nsChangeHint hint
= nsChangeHint(0);
2676 if (!EqualURIs(mBinding
, aOther
.mBinding
)
2677 || mPosition
!= aOther
.mPosition
2678 || mDisplay
!= aOther
.mDisplay
2679 || (mFloats
== NS_STYLE_FLOAT_NONE
) != (aOther
.mFloats
== NS_STYLE_FLOAT_NONE
)
2680 || mOverflowX
!= aOther
.mOverflowX
2681 || mOverflowY
!= aOther
.mOverflowY
2682 || mScrollBehavior
!= aOther
.mScrollBehavior
2683 || mResize
!= aOther
.mResize
)
2684 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
2686 /* Note: When mScrollBehavior is changed, the nsChangeHint_NeutralChange is
2687 * not sufficient to enter nsCSSFrameConstructor::PropagateScrollToViewport.
2688 * By using the same hint as used when the overflow css property changes,
2689 * nsChangeHint_ReconstructFrame, PropagateScrollToViewport will be called.
2691 * The scroll-behavior css property is not expected to change often (the
2692 * CSSOM-View DOM methods are likely to be used in those cases); however,
2693 * if this does become common perhaps a faster-path might be worth while.
2696 if ((mAppearance
== NS_THEME_TEXTFIELD
&&
2697 aOther
.mAppearance
!= NS_THEME_TEXTFIELD
) ||
2698 (mAppearance
!= NS_THEME_TEXTFIELD
&&
2699 aOther
.mAppearance
== NS_THEME_TEXTFIELD
)) {
2700 // This is for <input type=number> where we allow authors to specify a
2701 // |-moz-appearance:textfield| to get a control without a spinner. (The
2702 // spinner is present for |-moz-appearance:number-input| but also other
2703 // values such as 'none'.) We need to reframe since we want to use
2704 // nsTextControlFrame instead of nsNumberControlFrame if the author
2705 // specifies 'textfield'.
2706 return nsChangeHint_ReconstructFrame
;
2709 if (mFloats
!= aOther
.mFloats
) {
2710 // Changing which side we float on doesn't affect descendants directly
2712 NS_SubtractHint(nsChangeHint_AllReflowHints
,
2713 NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics
,
2714 nsChangeHint_NeedDirtyReflow
)));
2717 // XXX the following is conservative, for now: changing float breaking shouldn't
2718 // necessarily require a repaint, reflow should suffice.
2719 if (mBreakType
!= aOther
.mBreakType
2720 || mBreakInside
!= aOther
.mBreakInside
2721 || mBreakBefore
!= aOther
.mBreakBefore
2722 || mBreakAfter
!= aOther
.mBreakAfter
2723 || mAppearance
!= aOther
.mAppearance
2724 || mOrient
!= aOther
.mOrient
2725 || mOverflowClipBox
!= aOther
.mOverflowClipBox
2726 || mClipFlags
!= aOther
.mClipFlags
)
2727 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_AllReflowHints
,
2728 nsChangeHint_RepaintFrame
));
2730 if (!mClip
.IsEqualInterior(aOther
.mClip
)) {
2731 // If the clip has changed, we just need to update overflow areas. DLBI
2732 // will handle the invalidation.
2733 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_UpdateOverflow
,
2734 nsChangeHint_SchedulePaint
));
2737 if (mOpacity
!= aOther
.mOpacity
) {
2738 // If we're going from the optimized >=0.99 opacity value to 1.0 or back, then
2739 // repaint the frame because DLBI will not catch the invalidation. Otherwise,
2740 // just update the opacity layer.
2741 if ((mOpacity
>= 0.99f
&& mOpacity
< 1.0f
&& aOther
.mOpacity
== 1.0f
) ||
2742 (aOther
.mOpacity
>= 0.99f
&& aOther
.mOpacity
< 1.0f
&& mOpacity
== 1.0f
)) {
2743 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
2745 NS_UpdateHint(hint
, nsChangeHint_UpdateOpacityLayer
);
2749 if (mMixBlendMode
!= aOther
.mMixBlendMode
2750 || mIsolation
!= aOther
.mIsolation
) {
2751 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
2754 /* If we've added or removed the transform property, we need to reconstruct the frame to add
2755 * or remove the view object, and also to handle abs-pos and fixed-pos containers.
2757 if (HasTransformStyle() != aOther
.HasTransformStyle()) {
2758 // We do not need to apply nsChangeHint_UpdateTransformLayer since
2759 // nsChangeHint_RepaintFrame will forcibly invalidate the frame area and
2760 // ensure layers are rebuilt (or removed).
2761 NS_UpdateHint(hint
, NS_CombineHint(nsChangeHint_AddOrRemoveTransform
,
2762 NS_CombineHint(nsChangeHint_UpdateOverflow
,
2763 nsChangeHint_RepaintFrame
)));
2765 /* Otherwise, if we've kept the property lying around and we already had a
2766 * transform, we need to see whether or not we've changed the transform.
2767 * If so, we need to recompute its overflow rect (which probably changed
2768 * if the transform changed) and to redraw within the bounds of that new
2771 * If the property isn't present in either style struct, we still do the
2772 * comparisons but turn all the resulting change hints into
2773 * nsChangeHint_NeutralChange.
2775 nsChangeHint transformHint
= nsChangeHint(0);
2777 if (!mSpecifiedTransform
!= !aOther
.mSpecifiedTransform
||
2778 (mSpecifiedTransform
&&
2779 *mSpecifiedTransform
!= *aOther
.mSpecifiedTransform
)) {
2780 NS_UpdateHint(transformHint
, nsChangeHint_UpdateTransformLayer
);
2782 if (mSpecifiedTransform
&&
2783 aOther
.mSpecifiedTransform
) {
2784 NS_UpdateHint(transformHint
, nsChangeHint_UpdatePostTransformOverflow
);
2786 NS_UpdateHint(transformHint
, nsChangeHint_UpdateOverflow
);
2790 const nsChangeHint kUpdateOverflowAndRepaintHint
=
2791 NS_CombineHint(nsChangeHint_UpdateOverflow
, nsChangeHint_RepaintFrame
);
2792 for (uint8_t index
= 0; index
< 3; ++index
)
2793 if (mTransformOrigin
[index
] != aOther
.mTransformOrigin
[index
]) {
2794 NS_UpdateHint(transformHint
, kUpdateOverflowAndRepaintHint
);
2798 for (uint8_t index
= 0; index
< 2; ++index
)
2799 if (mPerspectiveOrigin
[index
] != aOther
.mPerspectiveOrigin
[index
]) {
2800 NS_UpdateHint(transformHint
, kUpdateOverflowAndRepaintHint
);
2804 if (mChildPerspective
!= aOther
.mChildPerspective
||
2805 mTransformStyle
!= aOther
.mTransformStyle
)
2806 NS_UpdateHint(transformHint
, kUpdateOverflowAndRepaintHint
);
2808 if (mBackfaceVisibility
!= aOther
.mBackfaceVisibility
)
2809 NS_UpdateHint(transformHint
, nsChangeHint_RepaintFrame
);
2811 if (transformHint
) {
2812 if (HasTransformStyle()) {
2813 NS_UpdateHint(hint
, transformHint
);
2815 NS_UpdateHint(hint
, nsChangeHint_NeutralChange
);
2820 // Note that the HasTransformStyle() != aOther.HasTransformStyle()
2821 // test above handles relevant changes in the
2822 // NS_STYLE_WILL_CHANGE_TRANSFORM bit, which in turn handles frame
2823 // reconstruction for changes in the containing block of
2824 // fixed-positioned elements. Other than that, all changes to
2825 // 'will-change' can be handled by a repaint.
2826 uint8_t willChangeBitsChanged
=
2827 mWillChangeBitField
^ aOther
.mWillChangeBitField
;
2828 if (willChangeBitsChanged
) {
2829 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
2832 // Note: Our current behavior for handling changes to the
2833 // transition-duration, transition-delay, and transition-timing-function
2834 // properties is to do nothing. In other words, the transition
2835 // property that matters is what it is when the transition begins, and
2836 // we don't stop a transition later because the transition property
2838 // We do handle changes to transition-property, but we don't need to
2839 // bother with anything here, since the transition manager is notified
2840 // of any style context change anyway.
2842 // Note: Likewise, for animation-*, the animation manager gets
2843 // notified about every new style context constructed, and it uses
2844 // that opportunity to handle dynamic changes appropriately.
2846 // But we still need to return nsChangeHint_NeutralChange for these
2847 // properties, since some data did change in the style struct.
2850 (!mClip
.IsEqualEdges(aOther
.mClip
) ||
2851 mOriginalDisplay
!= aOther
.mOriginalDisplay
||
2852 mOriginalFloats
!= aOther
.mOriginalFloats
||
2853 mTransitions
!= aOther
.mTransitions
||
2854 mTransitionTimingFunctionCount
!=
2855 aOther
.mTransitionTimingFunctionCount
||
2856 mTransitionDurationCount
!= aOther
.mTransitionDurationCount
||
2857 mTransitionDelayCount
!= aOther
.mTransitionDelayCount
||
2858 mTransitionPropertyCount
!= aOther
.mTransitionPropertyCount
||
2859 mAnimations
!= aOther
.mAnimations
||
2860 mAnimationTimingFunctionCount
!= aOther
.mAnimationTimingFunctionCount
||
2861 mAnimationDurationCount
!= aOther
.mAnimationDurationCount
||
2862 mAnimationDelayCount
!= aOther
.mAnimationDelayCount
||
2863 mAnimationNameCount
!= aOther
.mAnimationNameCount
||
2864 mAnimationDirectionCount
!= aOther
.mAnimationDirectionCount
||
2865 mAnimationFillModeCount
!= aOther
.mAnimationFillModeCount
||
2866 mAnimationPlayStateCount
!= aOther
.mAnimationPlayStateCount
||
2867 mAnimationIterationCountCount
!= aOther
.mAnimationIterationCountCount
)) {
2868 NS_UpdateHint(hint
, nsChangeHint_NeutralChange
);
2874 // --------------------
2875 // nsStyleVisibility
2878 nsStyleVisibility::nsStyleVisibility(nsPresContext
* aPresContext
)
2880 MOZ_COUNT_CTOR(nsStyleVisibility
);
2881 uint32_t bidiOptions
= aPresContext
->GetBidi();
2882 if (GET_BIDI_OPTION_DIRECTION(bidiOptions
) == IBMBIDI_TEXTDIRECTION_RTL
)
2883 mDirection
= NS_STYLE_DIRECTION_RTL
;
2885 mDirection
= NS_STYLE_DIRECTION_LTR
;
2887 mVisible
= NS_STYLE_VISIBILITY_VISIBLE
;
2888 mPointerEvents
= NS_STYLE_POINTER_EVENTS_AUTO
;
2889 mWritingMode
= NS_STYLE_WRITING_MODE_HORIZONTAL_TB
;
2890 mTextOrientation
= NS_STYLE_TEXT_ORIENTATION_MIXED
;
2893 nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility
& aSource
)
2895 MOZ_COUNT_CTOR(nsStyleVisibility
);
2896 mImageOrientation
= aSource
.mImageOrientation
;
2897 mDirection
= aSource
.mDirection
;
2898 mVisible
= aSource
.mVisible
;
2899 mPointerEvents
= aSource
.mPointerEvents
;
2900 mWritingMode
= aSource
.mWritingMode
;
2901 mTextOrientation
= aSource
.mTextOrientation
;
2904 nsChangeHint
nsStyleVisibility::CalcDifference(const nsStyleVisibility
& aOther
) const
2906 nsChangeHint hint
= nsChangeHint(0);
2908 if (mDirection
!= aOther
.mDirection
|| mWritingMode
!= aOther
.mWritingMode
) {
2909 NS_UpdateHint(hint
, nsChangeHint_ReconstructFrame
);
2911 if ((mImageOrientation
!= aOther
.mImageOrientation
)) {
2912 NS_UpdateHint(hint
, nsChangeHint_AllReflowHints
);
2913 NS_UpdateHint(hint
, nsChangeHint_RepaintFrame
);
2915 if (mVisible
!= aOther
.mVisible
) {
2916 if ((NS_STYLE_VISIBILITY_COLLAPSE
== mVisible
) ||
2917 (NS_STYLE_VISIBILITY_COLLAPSE
== aOther
.mVisible
)) {
2918 NS_UpdateHint(hint
, NS_STYLE_HINT_REFLOW
);
2920 NS_UpdateHint(hint
, NS_STYLE_HINT_VISUAL
);
2923 if (mTextOrientation
!= aOther
.mTextOrientation
) {
2924 NS_UpdateHint(hint
, NS_STYLE_HINT_REFLOW
);
2926 if (mPointerEvents
!= aOther
.mPointerEvents
) {
2927 // nsSVGPathGeometryFrame's mRect depends on stroke _and_ on the value
2928 // of pointer-events. See nsSVGPathGeometryFrame::ReflowSVG's use of
2929 // GetHitTestFlags. (Only a reflow, no visual change.)
2930 NS_UpdateHint(hint
, nsChangeHint_NeedReflow
);
2931 NS_UpdateHint(hint
, nsChangeHint_NeedDirtyReflow
); // XXX remove me: bug 876085
2937 nsStyleContentData::~nsStyleContentData()
2939 NS_ABORT_IF_FALSE(!mImageTracked
,
2940 "nsStyleContentData being destroyed while still tracking image!");
2941 if (mType
== eStyleContentType_Image
) {
2942 NS_IF_RELEASE(mContent
.mImage
);
2943 } else if (mType
== eStyleContentType_Counter
||
2944 mType
== eStyleContentType_Counters
) {
2945 mContent
.mCounters
->Release();
2946 } else if (mContent
.mString
) {
2947 NS_Free(mContent
.mString
);
2951 nsStyleContentData
& nsStyleContentData::operator=(const nsStyleContentData
& aOther
)
2953 if (this == &aOther
)
2955 this->~nsStyleContentData();
2956 new (this) nsStyleContentData();
2958 mType
= aOther
.mType
;
2959 if (mType
== eStyleContentType_Image
) {
2960 mContent
.mImage
= aOther
.mContent
.mImage
;
2961 NS_IF_ADDREF(mContent
.mImage
);
2962 } else if (mType
== eStyleContentType_Counter
||
2963 mType
== eStyleContentType_Counters
) {
2964 mContent
.mCounters
= aOther
.mContent
.mCounters
;
2965 mContent
.mCounters
->AddRef();
2966 } else if (aOther
.mContent
.mString
) {
2967 mContent
.mString
= NS_strdup(aOther
.mContent
.mString
);
2969 mContent
.mString
= nullptr;
2974 bool nsStyleContentData::operator==(const nsStyleContentData
& aOther
) const
2976 if (mType
!= aOther
.mType
)
2978 if (mType
== eStyleContentType_Image
) {
2979 if (!mContent
.mImage
|| !aOther
.mContent
.mImage
)
2980 return mContent
.mImage
== aOther
.mContent
.mImage
;
2982 nsCOMPtr
<nsIURI
> thisURI
, otherURI
;
2983 mContent
.mImage
->GetURI(getter_AddRefs(thisURI
));
2984 aOther
.mContent
.mImage
->GetURI(getter_AddRefs(otherURI
));
2985 return thisURI
== otherURI
|| // handles null==null
2986 (thisURI
&& otherURI
&&
2987 NS_SUCCEEDED(thisURI
->Equals(otherURI
, &eq
)) &&
2990 if (mType
== eStyleContentType_Counter
||
2991 mType
== eStyleContentType_Counters
)
2992 return *mContent
.mCounters
== *aOther
.mContent
.mCounters
;
2993 return safe_strcmp(mContent
.mString
, aOther
.mContent
.mString
) == 0;
2997 nsStyleContentData::TrackImage(nsPresContext
* aContext
)
3000 NS_ABORT_IF_FALSE(!mImageTracked
, "Already tracking image!");
3001 NS_ABORT_IF_FALSE(mType
== eStyleContentType_Image
,
3002 "Trying to do image tracking on non-image!");
3003 NS_ABORT_IF_FALSE(mContent
.mImage
,
3004 "Can't track image when there isn't one!");
3006 // Register the image with the document
3007 nsIDocument
* doc
= aContext
->Document();
3009 doc
->AddImage(mContent
.mImage
);
3013 mImageTracked
= true;
3018 nsStyleContentData::UntrackImage(nsPresContext
* aContext
)
3021 NS_ABORT_IF_FALSE(mImageTracked
, "Image not tracked!");
3022 NS_ABORT_IF_FALSE(mType
== eStyleContentType_Image
,
3023 "Trying to do image tracking on non-image!");
3024 NS_ABORT_IF_FALSE(mContent
.mImage
,
3025 "Can't untrack image when there isn't one!");
3027 // Unregister the image with the document
3028 nsIDocument
* doc
= aContext
->Document();
3030 doc
->RemoveImage(mContent
.mImage
, nsIDocument::REQUEST_DISCARD
);
3034 mImageTracked
= false;
3039 //-----------------------
3043 nsStyleContent::nsStyleContent(void)
3046 mIncrements(nullptr),
3052 MOZ_COUNT_CTOR(nsStyleContent
);
3053 mMarkerOffset
.SetAutoValue();
3056 nsStyleContent::~nsStyleContent(void)
3058 MOZ_COUNT_DTOR(nsStyleContent
);
3059 DELETE_ARRAY_IF(mContents
);
3060 DELETE_ARRAY_IF(mIncrements
);
3061 DELETE_ARRAY_IF(mResets
);
3065 nsStyleContent::Destroy(nsPresContext
* aContext
)
3067 // Unregister any images we might have with the document.
3068 for (uint32_t i
= 0; i
< mContentCount
; ++i
) {
3069 if ((mContents
[i
].mType
== eStyleContentType_Image
) &&
3070 mContents
[i
].mContent
.mImage
) {
3071 mContents
[i
].UntrackImage(aContext
);
3075 this->~nsStyleContent();
3076 aContext
->PresShell()->
3077 FreeByObjectID(nsPresArena::nsStyleContent_id
, this);
3080 nsStyleContent::nsStyleContent(const nsStyleContent
& aSource
)
3083 mIncrements(nullptr),
3090 MOZ_COUNT_CTOR(nsStyleContent
);
3091 mMarkerOffset
= aSource
.mMarkerOffset
;
3094 if (NS_SUCCEEDED(AllocateContents(aSource
.ContentCount()))) {
3095 for (index
= 0; index
< mContentCount
; index
++) {
3096 ContentAt(index
) = aSource
.ContentAt(index
);
3100 if (NS_SUCCEEDED(AllocateCounterIncrements(aSource
.CounterIncrementCount()))) {
3101 for (index
= 0; index
< mIncrementCount
; index
++) {
3102 const nsStyleCounterData
*data
= aSource
.GetCounterIncrementAt(index
);
3103 mIncrements
[index
].mCounter
= data
->mCounter
;
3104 mIncrements
[index
].mValue
= data
->mValue
;
3108 if (NS_SUCCEEDED(AllocateCounterResets(aSource
.CounterResetCount()))) {
3109 for (index
= 0; index
< mResetCount
; index
++) {
3110 const nsStyleCounterData
*data
= aSource
.GetCounterResetAt(index
);
3111 mResets
[index
].mCounter
= data
->mCounter
;
3112 mResets
[index
].mValue
= data
->mValue
;
3117 nsChangeHint
nsStyleContent::CalcDifference(const nsStyleContent
& aOther
) const
3119 // In ReResolveStyleContext we assume that if there's no existing
3120 // ::before or ::after and we don't have to restyle children of the
3121 // node then we can't end up with a ::before or ::after due to the
3122 // restyle of the node itself. That's not quite true, but the only
3123 // exception to the above is when the 'content' property of the node
3124 // changes and the pseudo-element inherits the changed value. Since
3125 // the code here triggers a frame change on the node in that case,
3126 // the optimization in ReResolveStyleContext is ok. But if we ever
3127 // change this code to not reconstruct frames on changes to the
3128 // 'content' property, then we will need to revisit the optimization
3129 // in ReResolveStyleContext.
3131 if (mContentCount
!= aOther
.mContentCount
||
3132 mIncrementCount
!= aOther
.mIncrementCount
||
3133 mResetCount
!= aOther
.mResetCount
) {
3134 return NS_STYLE_HINT_FRAMECHANGE
;
3137 uint32_t ix
= mContentCount
;
3139 if (mContents
[ix
] != aOther
.mContents
[ix
]) {
3140 // Unfortunately we need to reframe here; a simple reflow
3141 // will not pick up different text or different image URLs,
3142 // since we set all that up in the CSSFrameConstructor
3143 return NS_STYLE_HINT_FRAMECHANGE
;
3146 ix
= mIncrementCount
;
3148 if ((mIncrements
[ix
].mValue
!= aOther
.mIncrements
[ix
].mValue
) ||
3149 (mIncrements
[ix
].mCounter
!= aOther
.mIncrements
[ix
].mCounter
)) {
3150 return NS_STYLE_HINT_FRAMECHANGE
;
3155 if ((mResets
[ix
].mValue
!= aOther
.mResets
[ix
].mValue
) ||
3156 (mResets
[ix
].mCounter
!= aOther
.mResets
[ix
].mCounter
)) {
3157 return NS_STYLE_HINT_FRAMECHANGE
;
3160 if (mMarkerOffset
!= aOther
.mMarkerOffset
) {
3161 return NS_STYLE_HINT_REFLOW
;
3163 return NS_STYLE_HINT_NONE
;
3166 nsresult
nsStyleContent::AllocateContents(uint32_t aCount
)
3168 // We need to run the destructors of the elements of mContents, so we
3169 // delete and reallocate even if aCount == mContentCount. (If
3170 // nsStyleContentData had its members private and managed their
3171 // ownership on setting, we wouldn't need this, but that seems
3172 // unnecessary at this point.)
3173 DELETE_ARRAY_IF(mContents
);
3175 mContents
= new nsStyleContentData
[aCount
];
3178 return NS_ERROR_OUT_OF_MEMORY
;
3181 mContentCount
= aCount
;
3185 // ---------------------
3189 nsStyleQuotes::nsStyleQuotes(void)
3193 MOZ_COUNT_CTOR(nsStyleQuotes
);
3197 nsStyleQuotes::~nsStyleQuotes(void)
3199 MOZ_COUNT_DTOR(nsStyleQuotes
);
3200 DELETE_ARRAY_IF(mQuotes
);
3203 nsStyleQuotes::nsStyleQuotes(const nsStyleQuotes
& aSource
)
3207 MOZ_COUNT_CTOR(nsStyleQuotes
);
3212 nsStyleQuotes::SetInitial()
3214 // The initial value for quotes is the en-US typographic convention:
3215 // outermost are LEFT and RIGHT DOUBLE QUOTATION MARK, alternating
3216 // with LEFT and RIGHT SINGLE QUOTATION MARK.
3217 static const char16_t initialQuotes
[8] = {
3218 0x201C, 0, 0x201D, 0, 0x2018, 0, 0x2019, 0
3221 if (NS_SUCCEEDED(AllocateQuotes(2))) {
3223 nsDependentString(&initialQuotes
[0], 1),
3224 nsDependentString(&initialQuotes
[2], 1));
3226 nsDependentString(&initialQuotes
[4], 1),
3227 nsDependentString(&initialQuotes
[6], 1));
3232 nsStyleQuotes::CopyFrom(const nsStyleQuotes
& aSource
)
3234 if (NS_SUCCEEDED(AllocateQuotes(aSource
.QuotesCount()))) {
3235 uint32_t count
= (mQuotesCount
* 2);
3236 for (uint32_t index
= 0; index
< count
; index
+= 2) {
3237 aSource
.GetQuotesAt(index
, mQuotes
[index
], mQuotes
[index
+ 1]);
3242 nsChangeHint
nsStyleQuotes::CalcDifference(const nsStyleQuotes
& aOther
) const
3244 // If the quotes implementation is ever going to change we might not need
3245 // a framechange here and a reflow should be sufficient. See bug 35768.
3246 if (mQuotesCount
== aOther
.mQuotesCount
) {
3247 uint32_t ix
= (mQuotesCount
* 2);
3249 if (mQuotes
[ix
] != aOther
.mQuotes
[ix
]) {
3250 return NS_STYLE_HINT_FRAMECHANGE
;
3254 return NS_STYLE_HINT_NONE
;
3256 return NS_STYLE_HINT_FRAMECHANGE
;
3259 // --------------------
3263 nsStyleTextReset::nsStyleTextReset(void)
3265 MOZ_COUNT_CTOR(nsStyleTextReset
);
3266 mVerticalAlign
.SetIntValue(NS_STYLE_VERTICAL_ALIGN_BASELINE
, eStyleUnit_Enumerated
);
3267 mTextDecorationLine
= NS_STYLE_TEXT_DECORATION_LINE_NONE
;
3268 mTextDecorationColor
= NS_RGB(0,0,0);
3269 mTextDecorationStyle
=
3270 NS_STYLE_TEXT_DECORATION_STYLE_SOLID
| BORDER_COLOR_FOREGROUND
;
3271 mUnicodeBidi
= NS_STYLE_UNICODE_BIDI_NORMAL
;
3274 nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset
& aSource
)
3276 MOZ_COUNT_CTOR(nsStyleTextReset
);
3280 nsStyleTextReset::~nsStyleTextReset(void)
3282 MOZ_COUNT_DTOR(nsStyleTextReset
);
3285 nsChangeHint
nsStyleTextReset::CalcDifference(const nsStyleTextReset
& aOther
) const
3287 if (mVerticalAlign
== aOther
.mVerticalAlign
3288 && mUnicodeBidi
== aOther
.mUnicodeBidi
) {
3289 uint8_t lineStyle
= GetDecorationStyle();
3290 uint8_t otherLineStyle
= aOther
.GetDecorationStyle();
3291 if (mTextDecorationLine
!= aOther
.mTextDecorationLine
||
3292 lineStyle
!= otherLineStyle
) {
3293 // Repaint for other style decoration lines because they must be in
3294 // default overflow rect
3295 nsChangeHint hint
= NS_STYLE_HINT_VISUAL
;
3296 NS_UpdateHint(hint
, nsChangeHint_UpdateSubtreeOverflow
);
3300 // Repaint for decoration color changes
3301 nscolor decColor
, otherDecColor
;
3302 bool isFG
, otherIsFG
;
3303 GetDecorationColor(decColor
, isFG
);
3304 aOther
.GetDecorationColor(otherDecColor
, otherIsFG
);
3305 if (isFG
!= otherIsFG
|| (!isFG
&& decColor
!= otherDecColor
)) {
3306 return NS_STYLE_HINT_VISUAL
;
3309 if (mTextOverflow
!= aOther
.mTextOverflow
) {
3310 return NS_STYLE_HINT_VISUAL
;
3312 return NS_STYLE_HINT_NONE
;
3314 return NS_STYLE_HINT_REFLOW
;
3317 // Allowed to return one of NS_STYLE_HINT_NONE, NS_STYLE_HINT_REFLOW
3318 // or NS_STYLE_HINT_VISUAL. Currently we just return NONE or REFLOW, though.
3319 // XXXbz can this not return a more specific hint? If that's ever
3320 // changed, nsStyleBorder::CalcDifference will need changing too.
3322 CalcShadowDifference(nsCSSShadowArray
* lhs
,
3323 nsCSSShadowArray
* rhs
)
3326 return NS_STYLE_HINT_NONE
;
3328 if (!lhs
|| !rhs
|| lhs
->Length() != rhs
->Length())
3329 return NS_STYLE_HINT_REFLOW
;
3331 for (uint32_t i
= 0; i
< lhs
->Length(); ++i
) {
3332 if (*lhs
->ShadowAt(i
) != *rhs
->ShadowAt(i
))
3333 return NS_STYLE_HINT_REFLOW
;
3335 return NS_STYLE_HINT_NONE
;
3338 // --------------------
3342 nsStyleText::nsStyleText(void)
3344 MOZ_COUNT_CTOR(nsStyleText
);
3345 mTextAlign
= NS_STYLE_TEXT_ALIGN_DEFAULT
;
3346 mTextAlignLast
= NS_STYLE_TEXT_ALIGN_AUTO
;
3347 mTextAlignTrue
= false;
3348 mTextAlignLastTrue
= false;
3349 mTextTransform
= NS_STYLE_TEXT_TRANSFORM_NONE
;
3350 mWhiteSpace
= NS_STYLE_WHITESPACE_NORMAL
;
3351 mWordBreak
= NS_STYLE_WORDBREAK_NORMAL
;
3352 mWordWrap
= NS_STYLE_WORDWRAP_NORMAL
;
3353 mHyphens
= NS_STYLE_HYPHENS_MANUAL
;
3354 mRubyPosition
= NS_STYLE_RUBY_POSITION_INITIAL
;
3355 mTextSizeAdjust
= NS_STYLE_TEXT_SIZE_ADJUST_AUTO
;
3356 mTextCombineUpright
= NS_STYLE_TEXT_COMBINE_UPRIGHT_NONE
;
3357 mControlCharacterVisibility
= NS_STYLE_CONTROL_CHARACTER_VISIBILITY_HIDDEN
;
3359 mLetterSpacing
.SetNormalValue();
3360 mLineHeight
.SetNormalValue();
3361 mTextIndent
.SetCoordValue(0);
3364 mTextShadow
= nullptr;
3365 mTabSize
= NS_STYLE_TABSIZE_INITIAL
;
3368 nsStyleText::nsStyleText(const nsStyleText
& aSource
)
3369 : mTextAlign(aSource
.mTextAlign
),
3370 mTextAlignLast(aSource
.mTextAlignLast
),
3371 mTextAlignTrue(false),
3372 mTextAlignLastTrue(false),
3373 mTextTransform(aSource
.mTextTransform
),
3374 mWhiteSpace(aSource
.mWhiteSpace
),
3375 mWordBreak(aSource
.mWordBreak
),
3376 mWordWrap(aSource
.mWordWrap
),
3377 mHyphens(aSource
.mHyphens
),
3378 mRubyPosition(aSource
.mRubyPosition
),
3379 mTextSizeAdjust(aSource
.mTextSizeAdjust
),
3380 mTextCombineUpright(aSource
.mTextCombineUpright
),
3381 mControlCharacterVisibility(aSource
.mControlCharacterVisibility
),
3382 mTabSize(aSource
.mTabSize
),
3383 mWordSpacing(aSource
.mWordSpacing
),
3384 mLetterSpacing(aSource
.mLetterSpacing
),
3385 mLineHeight(aSource
.mLineHeight
),
3386 mTextIndent(aSource
.mTextIndent
),
3387 mTextShadow(aSource
.mTextShadow
)
3389 MOZ_COUNT_CTOR(nsStyleText
);
3392 nsStyleText::~nsStyleText(void)
3394 MOZ_COUNT_DTOR(nsStyleText
);
3397 nsChangeHint
nsStyleText::CalcDifference(const nsStyleText
& aOther
) const
3399 if (WhiteSpaceOrNewlineIsSignificant() !=
3400 aOther
.WhiteSpaceOrNewlineIsSignificant()) {
3401 // This may require construction of suppressed text frames
3402 return NS_STYLE_HINT_FRAMECHANGE
;
3405 if (mTextCombineUpright
!= aOther
.mTextCombineUpright
||
3406 mControlCharacterVisibility
!= aOther
.mControlCharacterVisibility
) {
3407 return nsChangeHint_ReconstructFrame
;
3410 if ((mTextAlign
!= aOther
.mTextAlign
) ||
3411 (mTextAlignLast
!= aOther
.mTextAlignLast
) ||
3412 (mTextAlignTrue
!= aOther
.mTextAlignTrue
) ||
3413 (mTextAlignLastTrue
!= aOther
.mTextAlignLastTrue
) ||
3414 (mTextTransform
!= aOther
.mTextTransform
) ||
3415 (mWhiteSpace
!= aOther
.mWhiteSpace
) ||
3416 (mWordBreak
!= aOther
.mWordBreak
) ||
3417 (mWordWrap
!= aOther
.mWordWrap
) ||
3418 (mHyphens
!= aOther
.mHyphens
) ||
3419 (mRubyPosition
!= aOther
.mRubyPosition
) ||
3420 (mTextSizeAdjust
!= aOther
.mTextSizeAdjust
) ||
3421 (mLetterSpacing
!= aOther
.mLetterSpacing
) ||
3422 (mLineHeight
!= aOther
.mLineHeight
) ||
3423 (mTextIndent
!= aOther
.mTextIndent
) ||
3424 (mWordSpacing
!= aOther
.mWordSpacing
) ||
3425 (mTabSize
!= aOther
.mTabSize
))
3426 return NS_STYLE_HINT_REFLOW
;
3428 return CalcShadowDifference(mTextShadow
, aOther
.mTextShadow
);
3431 //-----------------------
3432 // nsStyleUserInterface
3435 nsCursorImage::nsCursorImage()
3436 : mHaveHotspot(false)
3442 nsCursorImage::nsCursorImage(const nsCursorImage
& aOther
)
3443 : mHaveHotspot(aOther
.mHaveHotspot
)
3444 , mHotspotX(aOther
.mHotspotX
)
3445 , mHotspotY(aOther
.mHotspotY
)
3447 SetImage(aOther
.GetImage());
3450 nsCursorImage::~nsCursorImage()
3456 nsCursorImage::operator=(const nsCursorImage
& aOther
)
3458 if (this != &aOther
) {
3459 mHaveHotspot
= aOther
.mHaveHotspot
;
3460 mHotspotX
= aOther
.mHotspotX
;
3461 mHotspotY
= aOther
.mHotspotY
;
3462 SetImage(aOther
.GetImage());
3468 nsStyleUserInterface::nsStyleUserInterface(void)
3470 MOZ_COUNT_CTOR(nsStyleUserInterface
);
3471 mUserInput
= NS_STYLE_USER_INPUT_AUTO
;
3472 mUserModify
= NS_STYLE_USER_MODIFY_READ_ONLY
;
3473 mUserFocus
= NS_STYLE_USER_FOCUS_NONE
;
3474 mWindowDragging
= NS_STYLE_WINDOW_DRAGGING_NO_DRAG
;
3476 mCursor
= NS_STYLE_CURSOR_AUTO
; // fix for bugzilla bug 51113
3478 mCursorArrayLength
= 0;
3479 mCursorArray
= nullptr;
3482 nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface
& aSource
) :
3483 mUserInput(aSource
.mUserInput
),
3484 mUserModify(aSource
.mUserModify
),
3485 mUserFocus(aSource
.mUserFocus
),
3486 mWindowDragging(aSource
.mWindowDragging
),
3487 mCursor(aSource
.mCursor
)
3489 MOZ_COUNT_CTOR(nsStyleUserInterface
);
3490 CopyCursorArrayFrom(aSource
);
3493 nsStyleUserInterface::~nsStyleUserInterface(void)
3495 MOZ_COUNT_DTOR(nsStyleUserInterface
);
3496 delete [] mCursorArray
;
3499 nsChangeHint
nsStyleUserInterface::CalcDifference(const nsStyleUserInterface
& aOther
) const
3501 nsChangeHint hint
= nsChangeHint(0);
3502 if (mCursor
!= aOther
.mCursor
)
3503 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
3505 // We could do better. But it wouldn't be worth it, URL-specified cursors are
3507 if (mCursorArrayLength
> 0 || aOther
.mCursorArrayLength
> 0)
3508 NS_UpdateHint(hint
, nsChangeHint_UpdateCursor
);
3510 if (mUserModify
!= aOther
.mUserModify
)
3511 NS_UpdateHint(hint
, NS_STYLE_HINT_VISUAL
);
3513 if (mUserInput
!= aOther
.mUserInput
) {
3514 if (NS_STYLE_USER_INPUT_NONE
== mUserInput
||
3515 NS_STYLE_USER_INPUT_NONE
== aOther
.mUserInput
) {
3516 NS_UpdateHint(hint
, NS_STYLE_HINT_FRAMECHANGE
);
3518 NS_UpdateHint(hint
, nsChangeHint_NeutralChange
);
3522 if (mUserFocus
!= aOther
.mUserFocus
) {
3523 NS_UpdateHint(hint
, nsChangeHint_NeutralChange
);
3526 if (mWindowDragging
!= aOther
.mWindowDragging
) {
3527 NS_UpdateHint(hint
, nsChangeHint_SchedulePaint
);
3534 nsStyleUserInterface::CopyCursorArrayFrom(const nsStyleUserInterface
& aSource
)
3536 mCursorArray
= nullptr;
3537 mCursorArrayLength
= 0;
3538 if (aSource
.mCursorArrayLength
) {
3539 mCursorArray
= new nsCursorImage
[aSource
.mCursorArrayLength
];
3541 mCursorArrayLength
= aSource
.mCursorArrayLength
;
3542 for (uint32_t i
= 0; i
< mCursorArrayLength
; ++i
)
3543 mCursorArray
[i
] = aSource
.mCursorArray
[i
];
3548 //-----------------------
3552 nsStyleUIReset::nsStyleUIReset(void)
3554 MOZ_COUNT_CTOR(nsStyleUIReset
);
3555 mUserSelect
= NS_STYLE_USER_SELECT_AUTO
;
3556 mForceBrokenImageIcon
= 0;
3557 mIMEMode
= NS_STYLE_IME_MODE_AUTO
;
3558 mWindowShadow
= NS_STYLE_WINDOW_SHADOW_DEFAULT
;
3561 nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset
& aSource
)
3563 MOZ_COUNT_CTOR(nsStyleUIReset
);
3564 mUserSelect
= aSource
.mUserSelect
;
3565 mForceBrokenImageIcon
= aSource
.mForceBrokenImageIcon
;
3566 mIMEMode
= aSource
.mIMEMode
;
3567 mWindowShadow
= aSource
.mWindowShadow
;
3570 nsStyleUIReset::~nsStyleUIReset(void)
3572 MOZ_COUNT_DTOR(nsStyleUIReset
);
3575 nsChangeHint
nsStyleUIReset::CalcDifference(const nsStyleUIReset
& aOther
) const
3578 if (mForceBrokenImageIcon
!= aOther
.mForceBrokenImageIcon
)
3579 return NS_STYLE_HINT_FRAMECHANGE
;
3580 if (mWindowShadow
!= aOther
.mWindowShadow
) {
3581 // We really need just an nsChangeHint_SyncFrameView, except
3582 // on an ancestor of the frame, so we get that by doing a
3584 return NS_STYLE_HINT_REFLOW
;
3586 if (mUserSelect
!= aOther
.mUserSelect
)
3587 return NS_STYLE_HINT_VISUAL
;
3588 return NS_STYLE_HINT_NONE
;
3591 //-----------------------
3595 nsStyleVariables::nsStyleVariables()
3597 MOZ_COUNT_CTOR(nsStyleVariables
);
3600 nsStyleVariables::nsStyleVariables(const nsStyleVariables
& aSource
)
3602 MOZ_COUNT_CTOR(nsStyleVariables
);
3605 nsStyleVariables::~nsStyleVariables(void)
3607 MOZ_COUNT_DTOR(nsStyleVariables
);
3611 nsStyleVariables::CalcDifference(const nsStyleVariables
& aOther
) const
3613 return nsChangeHint(0);