Bug 1698786: part 2) Change some compile-time dependent `printf`s to `MOZ_LOG` in...
[gecko.git] / layout / style / nsStyleStruct.h
blob3d5ab8e32bc5f4fa1bbc61a774a0ee5bbafea30b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /*
8 * structs that contain the data provided by ComputedStyle, the
9 * internal API for computed style data for an element
12 #ifndef nsStyleStruct_h___
13 #define nsStyleStruct_h___
15 #include "mozilla/Attributes.h"
16 #include "mozilla/Maybe.h"
17 #include "mozilla/ServoStyleConstsInlines.h"
18 #include "mozilla/StaticPrefs_layout.h"
19 #include "mozilla/UniquePtr.h"
20 #include "nsColor.h"
21 #include "nsCoord.h"
22 #include "nsMargin.h"
23 #include "nsFont.h"
24 #include "nsStyleAutoArray.h"
25 #include "nsStyleConsts.h"
26 #include "nsChangeHint.h"
27 #include "nsTimingFunction.h"
28 #include "nsTArray.h"
29 #include "imgIContainer.h"
30 #include "imgRequestProxy.h"
31 #include "CounterStyleManager.h"
32 #include <cstddef> // offsetof()
33 #include "X11UndefineNone.h"
35 class nsIFrame;
36 class nsIURI;
37 class nsTextFrame;
38 struct nsStyleDisplay;
39 struct nsStyleVisibility;
40 namespace mozilla {
41 class ComputedStyle;
43 } // namespace mozilla
45 namespace mozilla {
47 using Position = StylePosition;
49 template <>
50 inline bool StylePosition::HasPercent() const {
51 return horizontal.HasPercent() || vertical.HasPercent();
54 /**
55 * True if the effective background image position described by this depends on
56 * the size of the corresponding frame.
58 template <>
59 inline bool StylePosition::DependsOnPositioningAreaSize() const {
60 return HasPercent();
63 template <>
64 inline Position Position::FromPercentage(float aPercent) {
65 return {LengthPercentage::FromPercentage(aPercent),
66 LengthPercentage::FromPercentage(aPercent)};
69 } // namespace mozilla
71 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont {
72 nsStyleFont(const nsStyleFont& aStyleFont);
73 explicit nsStyleFont(const mozilla::dom::Document&);
74 MOZ_COUNTED_DTOR(nsStyleFont)
75 static constexpr bool kHasTriggerImageLoads = false;
77 nsChangeHint CalcDifference(const nsStyleFont& aNewData) const;
79 /**
80 * Return a given size multiplied by the current text zoom factor (in
81 * aPresContext).
83 * The size is allowed to be negative, but the caller is expected to deal with
84 * negative results.
86 static mozilla::Length ZoomText(const mozilla::dom::Document&,
87 mozilla::Length);
89 nsFont mFont;
91 // Our "computed size". Can be different from mFont.size which is our "actual
92 // size" and is enforced to be >= the user's preferred min-size. mFont.size
93 // should be used for display purposes while mSize is the value to return in
94 // getComputedStyle() for example.
95 mozilla::NonNegativeLength mSize;
97 // In stylo these three track whether the size is keyword-derived
98 // and if so if it has been modified by a factor/offset
99 float mFontSizeFactor;
100 mozilla::Length mFontSizeOffset;
101 mozilla::StyleFontSizeKeyword mFontSizeKeyword;
103 mozilla::StyleGenericFontFamily mGenericID;
105 // math-depth support (used for MathML scriptlevel)
106 int8_t mMathDepth;
107 // MathML mathvariant support
108 uint8_t mMathVariant;
109 // math-style support (used for MathML displaystyle)
110 uint8_t mMathStyle;
112 // allow different min font-size for certain cases
113 uint8_t mMinFontSizeRatio; // percent * 100
115 // was mLanguage set based on a lang attribute in the document?
116 bool mExplicitLanguage;
118 // should calls to ZoomText() and UnZoomText() be made to the font
119 // size on this nsStyleFont? Also used to prevent SVG text from being
120 // affected by minimum font size pref.
121 bool mAllowZoomAndMinSize;
123 // The value mSize would have had if scriptminsize had never been applied
124 mozilla::NonNegativeLength mScriptUnconstrainedSize;
125 mozilla::Length mScriptMinSize;
126 float mScriptSizeMultiplier;
127 RefPtr<nsAtom> mLanguage;
130 // TODO(emilio, bug 1564526): Evaluate whether this is still needed.
131 struct CachedBorderImageData {
132 ~CachedBorderImageData() { PurgeCachedImages(); }
134 // Caller are expected to ensure that the value of aSize is different from the
135 // cached one since the method won't do the check.
136 void SetCachedSVGViewportSize(const mozilla::Maybe<nsSize>& aSize) {
137 mCachedSVGViewportSize = aSize;
140 const mozilla::Maybe<nsSize>& GetCachedSVGViewportSize() const {
141 return mCachedSVGViewportSize;
144 void PurgeCachedImages();
146 void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) {
147 mSubImages.EnsureLengthAtLeast(aIndex + 1);
148 mSubImages[aIndex] = aSubImage;
150 imgIContainer* GetSubImage(uint8_t aIndex) {
151 return mSubImages.SafeElementAt(aIndex);
154 // These methods are used for the caller to caches the sub images created
155 // during a border-image paint operation
156 void PurgeCacheForViewportChange(
157 const mozilla::Maybe<nsSize>& aSVGViewportSize,
158 const bool aHasIntrinsicRatio);
160 private:
161 // If this is a SVG border-image, we save the size of the SVG viewport that
162 // we used when rasterizing any cached border-image subimages. (The viewport
163 // size matters for percent-valued sizes & positions in inner SVG doc).
164 mozilla::Maybe<nsSize> mCachedSVGViewportSize;
165 nsTArray<RefPtr<imgIContainer>> mSubImages;
168 struct nsStyleImageLayers {
169 enum class LayerType : uint8_t { Background = 0, Mask };
171 explicit nsStyleImageLayers(LayerType aType);
172 nsStyleImageLayers(const nsStyleImageLayers& aSource);
173 MOZ_COUNTED_DTOR(nsStyleImageLayers)
175 struct Repeat {
176 mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat;
178 // Initialize nothing
179 Repeat() = default;
181 bool IsInitialValue() const {
182 return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat &&
183 mYRepeat == mozilla::StyleImageLayerRepeat::Repeat;
186 bool DependsOnPositioningAreaSize() const {
187 return mXRepeat == mozilla::StyleImageLayerRepeat::Space ||
188 mYRepeat == mozilla::StyleImageLayerRepeat::Space;
191 // Initialize to initial values
192 void SetInitialValues() {
193 mXRepeat = mozilla::StyleImageLayerRepeat::Repeat;
194 mYRepeat = mozilla::StyleImageLayerRepeat::Repeat;
197 bool operator==(const Repeat& aOther) const {
198 return mXRepeat == aOther.mXRepeat && mYRepeat == aOther.mYRepeat;
200 bool operator!=(const Repeat& aOther) const { return !(*this == aOther); }
203 struct Layer {
204 typedef mozilla::StyleGeometryBox StyleGeometryBox;
205 typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment;
206 typedef mozilla::StyleBackgroundSize StyleBackgroundSize;
208 mozilla::StyleImage mImage;
209 mozilla::Position mPosition;
210 StyleBackgroundSize mSize;
211 StyleGeometryBox mClip;
212 MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin;
214 // This property is used for background layer only.
215 // For a mask layer, it should always be the initial value, which is
216 // StyleImageLayerAttachment::Scroll.
217 StyleImageLayerAttachment mAttachment;
219 // This property is used for background layer only.
220 // For a mask layer, it should always be the initial value, which is
221 // StyleBlend::Normal.
222 mozilla::StyleBlend mBlendMode;
224 // This property is used for mask layer only.
225 // For a background layer, it should always be the initial value, which is
226 // StyleMaskComposite::Add.
227 mozilla::StyleMaskComposite mComposite;
229 // mask-only property. This property is used for mask layer only. For a
230 // background layer, it should always be the initial value, which is
231 // StyleMaskMode::MatchSource.
232 mozilla::StyleMaskMode mMaskMode;
234 Repeat mRepeat;
236 // This constructor does not initialize mRepeat or mOrigin and Initialize()
237 // must be called to do that.
238 Layer();
239 ~Layer();
241 // Initialize mRepeat and mOrigin by specified layer type
242 void Initialize(LayerType aType);
244 void ResolveImage(mozilla::dom::Document& aDocument,
245 const Layer* aOldLayer) {
246 mImage.ResolveImage(aDocument, aOldLayer ? &aOldLayer->mImage : nullptr);
249 // True if the rendering of this layer might change when the size
250 // of the background positioning area changes. This is true for any
251 // non-solid-color background whose position or size depends on
252 // the size of the positioning area. It's also true for SVG images
253 // whose root <svg> node has a viewBox.
254 bool RenderingMightDependOnPositioningAreaSizeChange() const;
256 // Compute the change hint required by changes in just this layer.
257 nsChangeHint CalcDifference(const Layer& aNewLayer) const;
259 // An equality operator that compares the images using URL-equality
260 // rather than pointer-equality.
261 bool operator==(const Layer& aOther) const;
262 bool operator!=(const Layer& aOther) const { return !(*this == aOther); }
265 // The (positive) number of computed values of each property, since
266 // the lengths of the lists are independent.
267 uint32_t mAttachmentCount;
268 uint32_t mClipCount;
269 uint32_t mOriginCount;
270 uint32_t mRepeatCount;
271 uint32_t mPositionXCount;
272 uint32_t mPositionYCount;
273 uint32_t mImageCount;
274 uint32_t mSizeCount;
275 uint32_t mMaskModeCount;
276 uint32_t mBlendModeCount;
277 uint32_t mCompositeCount;
279 // Layers are stored in an array, matching the top-to-bottom order in
280 // which they are specified in CSS. The number of layers to be used
281 // should come from the background-image property. We create
282 // additional |Layer| objects for *any* property, not just
283 // background-image. This means that the bottommost layer that
284 // callers in layout care about (which is also the one whose
285 // background-clip applies to the background-color) may not be last
286 // layer. In layers below the bottom layer, properties will be
287 // uninitialized unless their count, above, indicates that they are
288 // present.
289 nsStyleAutoArray<Layer> mLayers;
291 const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
293 void ResolveImages(mozilla::dom::Document& aDocument,
294 const nsStyleImageLayers* aOldLayers) {
295 for (uint32_t i = 0; i < mImageCount; ++i) {
296 const Layer* oldLayer = (aOldLayers && aOldLayers->mLayers.Length() > i)
297 ? &aOldLayers->mLayers[i]
298 : nullptr;
299 mLayers[i].ResolveImage(aDocument, oldLayer);
303 // Fill unspecified layers by cycling through their values
304 // till they all are of length aMaxItemCount
305 void FillAllLayers(uint32_t aMaxItemCount);
307 nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
308 nsStyleImageLayers::LayerType aType) const;
310 nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
311 nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther) = default;
312 bool operator==(const nsStyleImageLayers& aOther) const;
314 static const nsCSSPropertyID kBackgroundLayerTable[];
315 static const nsCSSPropertyID kMaskLayerTable[];
317 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
318 for (uint32_t var_ = (layers_).mImageCount; var_-- != 0;)
319 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, \
320 start_, count_) \
321 NS_ASSERTION( \
322 (int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, \
323 "Invalid layer start!"); \
324 NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, \
325 "Invalid layer range!"); \
326 for (uint32_t var_ = (start_) + 1; \
327 var_-- != (uint32_t)((start_) + 1 - (count_));)
330 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
331 explicit nsStyleBackground(const mozilla::dom::Document&);
332 nsStyleBackground(const nsStyleBackground& aOther);
333 ~nsStyleBackground();
335 // Resolves and tracks the images in mImage. Only called with a Servo-backed
336 // style system, where those images must be resolved later than the OMT
337 // nsStyleBackground constructor call.
338 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBackground*);
339 static constexpr bool kHasTriggerImageLoads = true;
341 nsChangeHint CalcDifference(const nsStyleBackground& aNewData) const;
343 // Return the background color as nscolor.
344 nscolor BackgroundColor(const nsIFrame* aFrame) const;
345 nscolor BackgroundColor(const mozilla::ComputedStyle* aStyle) const;
347 // True if this background is completely transparent.
348 bool IsTransparent(const nsIFrame* aFrame) const;
349 bool IsTransparent(mozilla::ComputedStyle* aStyle) const;
351 // We have to take slower codepaths for fixed background attachment,
352 // but we don't want to do that when there's no image.
353 // Not inline because it uses an nsCOMPtr<imgIRequest>
354 // FIXME: Should be in nsStyleStructInlines.h.
355 bool HasFixedBackground(nsIFrame* aFrame) const;
357 // Checks to see if this has a non-empty image with "local" attachment.
358 // This is defined in nsStyleStructInlines.h.
359 inline bool HasLocalBackground() const;
361 const nsStyleImageLayers::Layer& BottomLayer() const {
362 return mImage.BottomLayer();
365 nsStyleImageLayers mImage;
366 mozilla::StyleColor mBackgroundColor;
369 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
370 explicit nsStyleMargin(const mozilla::dom::Document&);
371 nsStyleMargin(const nsStyleMargin& aMargin);
372 MOZ_COUNTED_DTOR(nsStyleMargin)
373 static constexpr bool kHasTriggerImageLoads = false;
375 nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const;
377 bool GetMargin(nsMargin& aMargin) const {
378 bool convertsToLength = mMargin.All(
379 [](const auto& aLength) { return aLength.ConvertsToLength(); });
381 if (!convertsToLength) {
382 return false;
385 for (const auto side : mozilla::AllPhysicalSides()) {
386 aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength();
388 return true;
391 nsMargin GetScrollMargin() const {
392 return nsMargin(mScrollMargin.Get(mozilla::eSideTop).ToAppUnits(),
393 mScrollMargin.Get(mozilla::eSideRight).ToAppUnits(),
394 mScrollMargin.Get(mozilla::eSideBottom).ToAppUnits(),
395 mScrollMargin.Get(mozilla::eSideLeft).ToAppUnits());
398 // Return true if either the start or end side in the axis is 'auto'.
399 // (defined in WritingModes.h since we need the full WritingMode type)
400 inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const;
401 inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
402 inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode) const;
404 mozilla::StyleRect<mozilla::LengthPercentageOrAuto> mMargin;
405 mozilla::StyleRect<mozilla::StyleLength> mScrollMargin;
408 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding {
409 explicit nsStylePadding(const mozilla::dom::Document&);
410 nsStylePadding(const nsStylePadding& aPadding);
411 MOZ_COUNTED_DTOR(nsStylePadding)
412 static constexpr bool kHasTriggerImageLoads = false;
414 nsChangeHint CalcDifference(const nsStylePadding& aNewData) const;
416 mozilla::StyleRect<mozilla::NonNegativeLengthPercentage> mPadding;
417 mozilla::StyleRect<mozilla::NonNegativeLengthPercentageOrAuto> mScrollPadding;
419 inline bool IsWidthDependent() const {
420 return !mPadding.All(
421 [](const auto& aLength) { return aLength.ConvertsToLength(); });
424 bool GetPadding(nsMargin& aPadding) const {
425 if (IsWidthDependent()) {
426 return false;
429 for (const auto side : mozilla::AllPhysicalSides()) {
430 // Clamp negative calc() to 0.
431 aPadding.Side(side) = std::max(mPadding.Get(side).ToLength(), 0);
433 return true;
437 // Border widths are rounded to the nearest-below integer number of pixels,
438 // but values between zero and one device pixels are always rounded up to
439 // one device pixel.
440 #define NS_ROUND_BORDER_TO_PIXELS(l, tpp) \
441 ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
443 // Returns if the given border style type is visible or not
444 static bool IsVisibleBorderStyle(mozilla::StyleBorderStyle aStyle) {
445 return (aStyle != mozilla::StyleBorderStyle::None &&
446 aStyle != mozilla::StyleBorderStyle::Hidden);
449 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder {
450 explicit nsStyleBorder(const mozilla::dom::Document&);
451 nsStyleBorder(const nsStyleBorder& aBorder);
452 ~nsStyleBorder();
454 // Resolves and tracks mBorderImageSource. Only called with a Servo-backed
455 // style system, where those images must be resolved later than the OMT
456 // nsStyleBorder constructor call.
457 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBorder*);
458 static constexpr bool kHasTriggerImageLoads = true;
460 nsChangeHint CalcDifference(const nsStyleBorder& aNewData) const;
462 // Return whether aStyle is a visible style. Invisible styles cause
463 // the relevant computed border width to be 0.
464 // Note that this does *not* consider the effects of 'border-image':
465 // if border-style is none, but there is a loaded border image,
466 // HasVisibleStyle will be false even though there *is* a border.
467 bool HasVisibleStyle(mozilla::Side aSide) const {
468 return IsVisibleBorderStyle(mBorderStyle[aSide]);
471 // aBorderWidth is in twips
472 void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth) {
473 nscoord roundedWidth =
474 NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
475 mBorder.Side(aSide) = roundedWidth;
476 if (HasVisibleStyle(aSide)) {
477 mComputedBorder.Side(aSide) = roundedWidth;
481 // Get the computed border (plus rounding). This does consider the
482 // effects of 'border-style: none', but does not consider
483 // 'border-image'.
484 const nsMargin& GetComputedBorder() const { return mComputedBorder; }
486 bool HasBorder() const {
487 return mComputedBorder != nsMargin(0, 0, 0, 0) ||
488 !mBorderImageSource.IsNone();
491 // Get the actual border width for a particular side, in appunits. Note that
492 // this is zero if and only if there is no border to be painted for this
493 // side. That is, this value takes into account the border style and the
494 // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
495 nscoord GetComputedBorderWidth(mozilla::Side aSide) const {
496 return GetComputedBorder().Side(aSide);
499 mozilla::StyleBorderStyle GetBorderStyle(mozilla::Side aSide) const {
500 NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
501 return mBorderStyle[aSide];
504 void SetBorderStyle(mozilla::Side aSide, mozilla::StyleBorderStyle aStyle) {
505 NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
506 mBorderStyle[aSide] = aStyle;
507 mComputedBorder.Side(aSide) =
508 (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
511 inline bool IsBorderImageSizeAvailable() const {
512 return mBorderImageSource.IsSizeAvailable();
515 nsMargin GetImageOutset() const;
517 imgIRequest* GetBorderImageRequest() const {
518 return mBorderImageSource.GetImageRequest();
521 public:
522 mozilla::StyleBorderRadius mBorderRadius; // coord, percent
523 mozilla::StyleImage mBorderImageSource;
524 mozilla::StyleBorderImageWidth mBorderImageWidth;
525 mozilla::StyleNonNegativeLengthOrNumberRect mBorderImageOutset;
526 mozilla::StyleBorderImageSlice mBorderImageSlice; // factor, percent
527 mozilla::StyleBorderImageRepeat mBorderImageRepeatH;
528 mozilla::StyleBorderImageRepeat mBorderImageRepeatV;
529 mozilla::StyleFloatEdge mFloatEdge;
530 mozilla::StyleBoxDecorationBreak mBoxDecorationBreak;
532 protected:
533 mozilla::StyleBorderStyle mBorderStyle[4]; // StyleBorderStyle::*
535 public:
536 // the colors to use for a simple border.
537 // not used for -moz-border-colors
538 mozilla::StyleColor mBorderTopColor;
539 mozilla::StyleColor mBorderRightColor;
540 mozilla::StyleColor mBorderBottomColor;
541 mozilla::StyleColor mBorderLeftColor;
543 mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) {
544 switch (aSide) {
545 case mozilla::eSideTop:
546 return mBorderTopColor;
547 case mozilla::eSideRight:
548 return mBorderRightColor;
549 case mozilla::eSideBottom:
550 return mBorderBottomColor;
551 case mozilla::eSideLeft:
552 return mBorderLeftColor;
554 MOZ_ASSERT_UNREACHABLE("Unknown side");
555 return mBorderTopColor;
558 const mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) const {
559 switch (aSide) {
560 case mozilla::eSideTop:
561 return mBorderTopColor;
562 case mozilla::eSideRight:
563 return mBorderRightColor;
564 case mozilla::eSideBottom:
565 return mBorderBottomColor;
566 case mozilla::eSideLeft:
567 return mBorderLeftColor;
569 MOZ_ASSERT_UNREACHABLE("Unknown side");
570 return mBorderTopColor;
573 static mozilla::StyleColor nsStyleBorder::*BorderColorFieldFor(
574 mozilla::Side aSide) {
575 switch (aSide) {
576 case mozilla::eSideTop:
577 return &nsStyleBorder::mBorderTopColor;
578 case mozilla::eSideRight:
579 return &nsStyleBorder::mBorderRightColor;
580 case mozilla::eSideBottom:
581 return &nsStyleBorder::mBorderBottomColor;
582 case mozilla::eSideLeft:
583 return &nsStyleBorder::mBorderLeftColor;
585 MOZ_ASSERT_UNREACHABLE("Unknown side");
586 return nullptr;
589 protected:
590 // mComputedBorder holds the CSS2.1 computed border-width values.
591 // In particular, these widths take into account the border-style
592 // for the relevant side, and the values are rounded to the nearest
593 // device pixel (which is not part of the definition of computed
594 // values). The presence or absence of a border-image does not
595 // affect border-width values.
596 nsMargin mComputedBorder;
598 // mBorder holds the nscoord values for the border widths as they
599 // would be if all the border-style values were visible (not hidden
600 // or none). This member exists so that when we create structs
601 // using the copy constructor during style resolution the new
602 // structs will know what the specified values of the border were in
603 // case they have more specific rules setting the border style.
605 // Note that this isn't quite the CSS specified value, since this
606 // has had the enumerated border widths converted to lengths, and
607 // all lengths converted to twips. But it's not quite the computed
608 // value either. The values are rounded to the nearest device pixel.
609 nsMargin mBorder;
611 private:
612 nscoord mTwipsPerPixel;
614 nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
617 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline {
618 explicit nsStyleOutline(const mozilla::dom::Document&);
619 nsStyleOutline(const nsStyleOutline& aOutline);
620 MOZ_COUNTED_DTOR(nsStyleOutline)
621 static constexpr bool kHasTriggerImageLoads = false;
623 nsChangeHint CalcDifference(const nsStyleOutline& aNewData) const;
625 mozilla::StyleBorderRadius mOutlineRadius;
627 // This is the specified value of outline-width, but with length values
628 // computed to absolute. mActualOutlineWidth stores the outline-width
629 // value used by layout. (We must store mOutlineWidth for the same
630 // style struct resolution reasons that we do nsStyleBorder::mBorder;
631 // see that field's comment.)
632 nscoord mOutlineWidth;
633 mozilla::Length mOutlineOffset;
634 mozilla::StyleColor mOutlineColor;
635 mozilla::StyleOutlineStyle mOutlineStyle;
637 nscoord GetOutlineWidth() const { return mActualOutlineWidth; }
639 bool ShouldPaintOutline() const {
640 if (mOutlineStyle.IsAuto()) {
641 return true;
643 if (GetOutlineWidth() > 0) {
644 MOZ_ASSERT(
645 mOutlineStyle.AsBorderStyle() != mozilla::StyleBorderStyle::None,
646 "outline-style: none implies outline-width of zero");
647 return true;
649 return false;
652 protected:
653 // The actual value of outline-width is the computed value (an absolute
654 // length, forced to zero when outline-style is none) rounded to device
655 // pixels. This is the value used by layout.
656 nscoord mActualOutlineWidth;
657 nscoord mTwipsPerPixel;
660 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList {
661 explicit nsStyleList(const mozilla::dom::Document&);
662 nsStyleList(const nsStyleList& aStyleList);
663 ~nsStyleList();
665 private:
666 nsStyleList& operator=(const nsStyleList& aOther) = delete;
668 public:
669 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleList*);
670 static constexpr bool kHasTriggerImageLoads = true;
672 nsChangeHint CalcDifference(const nsStyleList& aNewData,
673 const nsStyleDisplay& aOldDisplay) const;
675 nsRect GetImageRegion() const {
676 if (!mImageRegion.IsRect()) {
677 return nsRect();
679 return mImageRegion.AsRect().ToLayoutRect(0);
682 already_AddRefed<nsIURI> GetListStyleImageURI() const;
684 uint8_t mListStylePosition;
686 mozilla::CounterStylePtr mCounterStyle;
687 mozilla::StyleQuotes mQuotes;
688 mozilla::StyleImage mListStyleImage;
690 // the rect to use within an image.
691 mozilla::StyleClipRectOrAuto mImageRegion;
692 // true in an <ol reversed> scope.
693 mozilla::StyleMozListReversed mMozListReversed;
696 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
697 using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto;
698 using Position = mozilla::Position;
699 template <typename T>
700 using StyleRect = mozilla::StyleRect<T>;
701 using StyleSize = mozilla::StyleSize;
702 using StyleMaxSize = mozilla::StyleMaxSize;
703 using WritingMode = mozilla::WritingMode;
704 using LogicalAxis = mozilla::LogicalAxis;
705 using StyleImplicitGridTracks = mozilla::StyleImplicitGridTracks;
706 using ComputedStyle = mozilla::ComputedStyle;
707 using StyleAlignSelf = mozilla::StyleAlignSelf;
708 using StyleJustifySelf = mozilla::StyleJustifySelf;
710 explicit nsStylePosition(const mozilla::dom::Document&);
711 nsStylePosition(const nsStylePosition& aOther);
712 ~nsStylePosition();
713 static constexpr bool kHasTriggerImageLoads = false;
715 nsChangeHint CalcDifference(
716 const nsStylePosition& aNewData,
717 const nsStyleVisibility& aOldStyleVisibility) const;
719 // Returns whether we need to compute an hypothetical position if we were
720 // absolutely positioned.
721 bool NeedsHypotheticalPositionIfAbsPos() const {
722 return (mOffset.Get(mozilla::eSideRight).IsAuto() &&
723 mOffset.Get(mozilla::eSideLeft).IsAuto()) ||
724 (mOffset.Get(mozilla::eSideTop).IsAuto() &&
725 mOffset.Get(mozilla::eSideBottom).IsAuto());
729 * Return the used value for 'align-self' given our parent ComputedStyle
730 * (or null for the root).
732 StyleAlignSelf UsedAlignSelf(const ComputedStyle*) const;
735 * Return the used value for 'justify-self' given our parent ComputedStyle
736 * aParent (or null for the root).
738 StyleJustifySelf UsedJustifySelf(const ComputedStyle*) const;
741 * Return the used value for 'justify/align-self' in aAxis given our parent
742 * ComputedStyle aParent (or null for the root).
743 * (defined in WritingModes.h since we need the full WritingMode type)
745 inline mozilla::StyleAlignFlags UsedSelfAlignment(
746 LogicalAxis aAxis, const mozilla::ComputedStyle* aParent) const;
749 * Return the used value for 'justify/align-content' in aAxis.
750 * (defined in WritingModes.h since we need the full WritingMode type)
752 inline mozilla::StyleContentDistribution UsedContentAlignment(
753 LogicalAxis aAxis) const;
756 * Return the used value for 'align-tracks'/'justify-tracks' for a track
757 * in the given axis.
758 * (defined in WritingModes.h since we need the full LogicalAxis type)
760 inline mozilla::StyleContentDistribution UsedTracksAlignment(
761 LogicalAxis aAxis, uint32_t aIndex) const;
763 // Each entry has the same encoding as *-content, see below.
764 mozilla::StyleAlignTracks mAlignTracks;
765 mozilla::StyleJustifyTracks mJustifyTracks;
767 Position mObjectPosition;
768 StyleRect<LengthPercentageOrAuto> mOffset;
769 StyleSize mWidth;
770 StyleSize mMinWidth;
771 StyleMaxSize mMaxWidth;
772 StyleSize mHeight;
773 StyleSize mMinHeight;
774 StyleMaxSize mMaxHeight;
775 mozilla::StyleFlexBasis mFlexBasis;
776 StyleImplicitGridTracks mGridAutoColumns;
777 StyleImplicitGridTracks mGridAutoRows;
778 mozilla::StyleAspectRatio mAspectRatio;
779 mozilla::StyleGridAutoFlow mGridAutoFlow;
780 uint8_t mMasonryAutoFlow; // NS_STYLE_MASONRY_*
782 mozilla::StyleAlignContent mAlignContent;
783 mozilla::StyleAlignItems mAlignItems;
784 mozilla::StyleAlignSelf mAlignSelf;
785 mozilla::StyleJustifyContent mJustifyContent;
786 mozilla::StyleComputedJustifyItems mJustifyItems;
787 mozilla::StyleJustifySelf mJustifySelf;
788 mozilla::StyleFlexDirection mFlexDirection;
789 mozilla::StyleFlexWrap mFlexWrap;
790 mozilla::StyleObjectFit mObjectFit;
791 mozilla::StyleBoxSizing mBoxSizing;
792 int32_t mOrder;
793 float mFlexGrow;
794 float mFlexShrink;
795 mozilla::StyleZIndex mZIndex;
797 mozilla::StyleGridTemplateComponent mGridTemplateColumns;
798 mozilla::StyleGridTemplateComponent mGridTemplateRows;
799 mozilla::StyleGridTemplateAreas mGridTemplateAreas;
801 mozilla::StyleGridLine mGridColumnStart;
802 mozilla::StyleGridLine mGridColumnEnd;
803 mozilla::StyleGridLine mGridRowStart;
804 mozilla::StyleGridLine mGridRowEnd;
805 mozilla::NonNegativeLengthPercentageOrNormal mColumnGap;
806 mozilla::NonNegativeLengthPercentageOrNormal mRowGap;
808 // Logical-coordinate accessors for width and height properties,
809 // given a WritingMode value. The definitions of these methods are
810 // found in WritingModes.h (after the WritingMode class is fully
811 // declared).
812 inline const StyleSize& ISize(WritingMode) const;
813 inline const StyleSize& MinISize(WritingMode) const;
814 inline const StyleMaxSize& MaxISize(WritingMode) const;
815 inline const StyleSize& BSize(WritingMode) const;
816 inline const StyleSize& MinBSize(WritingMode) const;
817 inline const StyleMaxSize& MaxBSize(WritingMode) const;
818 inline const StyleSize& Size(LogicalAxis, WritingMode) const;
819 inline const StyleSize& MinSize(LogicalAxis, WritingMode) const;
820 inline const StyleMaxSize& MaxSize(LogicalAxis, WritingMode) const;
821 inline bool ISizeDependsOnContainer(WritingMode) const;
822 inline bool MinISizeDependsOnContainer(WritingMode) const;
823 inline bool MaxISizeDependsOnContainer(WritingMode) const;
824 inline bool BSizeDependsOnContainer(WritingMode) const;
825 inline bool MinBSizeDependsOnContainer(WritingMode) const;
826 inline bool MaxBSizeDependsOnContainer(WritingMode) const;
828 private:
829 template <typename SizeOrMaxSize>
830 static bool ISizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
831 if (aCoord.IsLengthPercentage()) {
832 return aCoord.AsLengthPercentage().HasPercent();
834 return aCoord.IsMozFitContent() || aCoord.IsMozAvailable();
837 template <typename SizeOrMaxSize>
838 static bool BSizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
839 return aCoord.IsLengthPercentage() &&
840 aCoord.AsLengthPercentage().HasPercent();
844 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset {
845 explicit nsStyleTextReset(const mozilla::dom::Document&);
846 nsStyleTextReset(const nsStyleTextReset& aOther);
847 ~nsStyleTextReset();
848 static constexpr bool kHasTriggerImageLoads = false;
850 // Note the difference between this and
851 // ComputedStyle::HasTextDecorationLines.
852 bool HasTextDecorationLines() const {
853 return mTextDecorationLine != mozilla::StyleTextDecorationLine::NONE &&
854 mTextDecorationLine !=
855 mozilla::StyleTextDecorationLine::COLOR_OVERRIDE;
858 nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const;
860 mozilla::StyleTextOverflow mTextOverflow;
862 mozilla::StyleTextDecorationLine mTextDecorationLine;
863 uint8_t mTextDecorationStyle; // NS_STYLE_TEXT_DECORATION_STYLE_*
864 uint8_t mUnicodeBidi; // NS_STYLE_UNICODE_BIDI_*
865 nscoord mInitialLetterSink; // 0 means normal
866 float mInitialLetterSize; // 0.0f means normal
867 mozilla::StyleColor mTextDecorationColor;
868 mozilla::StyleTextDecorationLength mTextDecorationThickness;
871 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText {
872 explicit nsStyleText(const mozilla::dom::Document&);
873 nsStyleText(const nsStyleText& aOther);
874 ~nsStyleText();
875 static constexpr bool kHasTriggerImageLoads = false;
877 nsChangeHint CalcDifference(const nsStyleText& aNewData) const;
879 mozilla::StyleRGBA mColor;
880 mozilla::StyleTextTransform mTextTransform;
881 mozilla::StyleTextAlign mTextAlign;
882 mozilla::StyleTextAlignLast mTextAlignLast;
883 mozilla::StyleTextJustify mTextJustify;
884 mozilla::StyleWhiteSpace mWhiteSpace;
885 mozilla::StyleLineBreak mLineBreak = mozilla::StyleLineBreak::Auto;
887 private:
888 mozilla::StyleWordBreak mWordBreak = mozilla::StyleWordBreak::Normal;
889 mozilla::StyleOverflowWrap mOverflowWrap = mozilla::StyleOverflowWrap::Normal;
891 public:
892 mozilla::StyleHyphens mHyphens;
893 mozilla::StyleRubyAlign mRubyAlign;
894 mozilla::StyleRubyPosition mRubyPosition;
895 mozilla::StyleTextSizeAdjust mTextSizeAdjust;
896 uint8_t mTextCombineUpright; // NS_STYLE_TEXT_COMBINE_UPRIGHT_*
897 mozilla::StyleControlCharacterVisibility mControlCharacterVisibility;
898 uint8_t mTextEmphasisPosition; // NS_STYLE_TEXT_EMPHASIS_POSITION_*
899 mozilla::StyleTextRendering mTextRendering;
900 mozilla::StyleColor mTextEmphasisColor;
901 mozilla::StyleColor mWebkitTextFillColor;
902 mozilla::StyleColor mWebkitTextStrokeColor;
904 mozilla::StyleNonNegativeLengthOrNumber mMozTabSize;
905 mozilla::LengthPercentage mWordSpacing;
906 mozilla::StyleLetterSpacing mLetterSpacing;
907 mozilla::StyleLineHeight mLineHeight;
908 mozilla::LengthPercentage mTextIndent;
910 mozilla::LengthPercentageOrAuto mTextUnderlineOffset;
911 mozilla::StyleTextDecorationSkipInk mTextDecorationSkipInk;
912 mozilla::StyleTextUnderlinePosition mTextUnderlinePosition;
914 nscoord mWebkitTextStrokeWidth; // coord
916 mozilla::StyleArcSlice<mozilla::StyleSimpleShadow> mTextShadow;
917 mozilla::StyleTextEmphasisStyle mTextEmphasisStyle;
919 mozilla::StyleWordBreak EffectiveWordBreak() const {
920 if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
921 return mozilla::StyleWordBreak::Normal;
923 return mWordBreak;
926 mozilla::StyleOverflowWrap EffectiveOverflowWrap() const {
927 if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
928 return mozilla::StyleOverflowWrap::Anywhere;
930 return mOverflowWrap;
933 bool WhiteSpaceIsSignificant() const {
934 return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
935 mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
936 mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
937 mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
940 bool WhiteSpaceCanHangOrVisuallyCollapse() const {
941 // This was originally expressed in nsTextFrame in terms of:
942 // mWhiteSpace != StyleWhiteSpace::BreakSpaces &&
943 // WhiteSpaceCanWrapStyle() &&
944 // WhiteSpaceIsSignificant()
945 // which simplifies to:
946 return mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap;
949 bool NewlineIsSignificantStyle() const {
950 return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
951 mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
952 mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
953 mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
956 bool WhiteSpaceOrNewlineIsSignificant() const {
957 return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
958 mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
959 mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
960 mWhiteSpace == mozilla::StyleWhiteSpace::PreLine ||
961 mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
964 bool TabIsSignificant() const {
965 return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
966 mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
967 mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces;
970 bool WhiteSpaceCanWrapStyle() const {
971 return mWhiteSpace == mozilla::StyleWhiteSpace::Normal ||
972 mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
973 mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
974 mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
977 bool WordCanWrapStyle() const {
978 if (!WhiteSpaceCanWrapStyle()) {
979 return false;
981 auto owrap = EffectiveOverflowWrap();
982 return owrap == mozilla::StyleOverflowWrap::BreakWord ||
983 owrap == mozilla::StyleOverflowWrap::Anywhere;
986 bool HasEffectiveTextEmphasis() const {
987 if (mTextEmphasisStyle.IsNone()) {
988 return false;
990 if (mTextEmphasisStyle.IsString() &&
991 mTextEmphasisStyle.AsString().AsString().IsEmpty()) {
992 return false;
994 return true;
997 mozilla::StyleTextAlign TextAlignForLastLine() const {
998 switch (mTextAlignLast) {
999 case mozilla::StyleTextAlignLast::Auto:
1000 // 'text-align-last: auto' is equivalent to the value of the
1001 // 'text-align' property except when 'text-align' is set to 'justify',
1002 // in which case it is 'justify' when 'text-justify' is 'distribute' and
1003 // 'start' otherwise.
1005 // XXX: the code below will have to change when we implement
1006 // text-justify
1007 if (mTextAlign == mozilla::StyleTextAlign::Justify) {
1008 return mozilla::StyleTextAlign::Start;
1010 return mTextAlign;
1011 case mozilla::StyleTextAlignLast::Center:
1012 return mozilla::StyleTextAlign::Center;
1013 case mozilla::StyleTextAlignLast::Start:
1014 return mozilla::StyleTextAlign::Start;
1015 case mozilla::StyleTextAlignLast::End:
1016 return mozilla::StyleTextAlign::End;
1017 case mozilla::StyleTextAlignLast::Left:
1018 return mozilla::StyleTextAlign::Left;
1019 case mozilla::StyleTextAlignLast::Right:
1020 return mozilla::StyleTextAlign::Right;
1021 case mozilla::StyleTextAlignLast::Justify:
1022 return mozilla::StyleTextAlign::Justify;
1024 return mozilla::StyleTextAlign::Start;
1027 bool HasWebkitTextStroke() const { return mWebkitTextStrokeWidth > 0; }
1029 bool HasTextShadow() const { return !mTextShadow.IsEmpty(); }
1031 // The aContextFrame argument on each of these is the frame this
1032 // style struct is for. If the frame is for SVG text or inside ruby,
1033 // the return value will be massaged to be something that makes sense
1034 // for those cases.
1035 inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const;
1036 inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
1037 inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
1039 mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const;
1042 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility {
1043 explicit nsStyleVisibility(const mozilla::dom::Document&);
1044 nsStyleVisibility(const nsStyleVisibility& aVisibility);
1045 MOZ_COUNTED_DTOR(nsStyleVisibility)
1046 static constexpr bool kHasTriggerImageLoads = false;
1048 nsChangeHint CalcDifference(const nsStyleVisibility& aNewData) const;
1050 mozilla::StyleImageOrientation mImageOrientation;
1051 mozilla::StyleDirection mDirection;
1052 mozilla::StyleVisibility mVisible;
1053 mozilla::StyleImageRendering mImageRendering;
1054 mozilla::StyleWritingModeProperty mWritingMode;
1055 mozilla::StyleTextOrientation mTextOrientation;
1056 mozilla::StyleColorAdjust mColorAdjust;
1058 bool IsVisible() const {
1059 return mVisible == mozilla::StyleVisibility::Visible;
1062 bool IsVisibleOrCollapsed() const {
1063 return mVisible == mozilla::StyleVisibility::Visible ||
1064 mVisible == mozilla::StyleVisibility::Collapse;
1068 namespace mozilla {
1070 inline StyleTextTransform StyleTextTransform::None() {
1071 return StyleTextTransform{StyleTextTransformCase::None,
1072 StyleTextTransformOther()};
1075 inline bool StyleTextTransform::IsNone() const { return *this == None(); }
1077 // Note that IsAuto() does not exclude the possibility that `left` or `right`
1078 // is set; it refers only to behavior in horizontal typographic mode.
1079 inline bool StyleTextUnderlinePosition::IsAuto() const {
1080 return !(*this & (StyleTextUnderlinePosition::FROM_FONT |
1081 StyleTextUnderlinePosition::UNDER));
1083 inline bool StyleTextUnderlinePosition::IsFromFont() const {
1084 return bool(*this & StyleTextUnderlinePosition::FROM_FONT);
1086 inline bool StyleTextUnderlinePosition::IsUnder() const {
1087 return bool(*this & StyleTextUnderlinePosition::UNDER);
1089 inline bool StyleTextUnderlinePosition::IsLeft() const {
1090 return bool(*this & StyleTextUnderlinePosition::LEFT);
1092 inline bool StyleTextUnderlinePosition::IsRight() const {
1093 return bool(*this & StyleTextUnderlinePosition::RIGHT);
1096 struct StyleTransition {
1097 StyleTransition() { /* leaves uninitialized; see also SetInitialValues */
1099 explicit StyleTransition(const StyleTransition& aCopy);
1101 void SetInitialValues();
1103 // Delay and Duration are in milliseconds
1105 const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
1106 float GetDelay() const { return mDelay; }
1107 float GetDuration() const { return mDuration; }
1108 nsCSSPropertyID GetProperty() const { return mProperty; }
1109 nsAtom* GetUnknownProperty() const { return mUnknownProperty; }
1111 bool operator==(const StyleTransition& aOther) const;
1112 bool operator!=(const StyleTransition& aOther) const {
1113 return !(*this == aOther);
1116 private:
1117 nsTimingFunction mTimingFunction;
1118 float mDuration;
1119 float mDelay;
1120 nsCSSPropertyID mProperty;
1121 RefPtr<nsAtom> mUnknownProperty; // used when mProperty is
1122 // eCSSProperty_UNKNOWN or
1123 // eCSSPropertyExtra_variable
1126 struct StyleAnimation {
1127 StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */
1129 explicit StyleAnimation(const StyleAnimation& aCopy);
1131 void SetInitialValues();
1133 // Delay and Duration are in milliseconds
1135 const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
1136 float GetDelay() const { return mDelay; }
1137 float GetDuration() const { return mDuration; }
1138 nsAtom* GetName() const { return mName; }
1139 dom::PlaybackDirection GetDirection() const { return mDirection; }
1140 dom::FillMode GetFillMode() const { return mFillMode; }
1141 StyleAnimationPlayState GetPlayState() const { return mPlayState; }
1142 float GetIterationCount() const { return mIterationCount; }
1144 void SetName(already_AddRefed<nsAtom> aName) { mName = aName; }
1145 void SetName(nsAtom* aName) { mName = aName; }
1147 bool operator==(const StyleAnimation& aOther) const;
1148 bool operator!=(const StyleAnimation& aOther) const {
1149 return !(*this == aOther);
1152 private:
1153 nsTimingFunction mTimingFunction;
1154 float mDuration;
1155 float mDelay;
1156 RefPtr<nsAtom> mName; // nsGkAtoms::_empty for 'none'
1157 dom::PlaybackDirection mDirection;
1158 dom::FillMode mFillMode;
1159 StyleAnimationPlayState mPlayState;
1160 float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
1163 } // namespace mozilla
1165 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
1166 typedef mozilla::StyleGeometryBox StyleGeometryBox;
1168 explicit nsStyleDisplay(const mozilla::dom::Document&);
1169 nsStyleDisplay(const nsStyleDisplay& aOther);
1170 ~nsStyleDisplay();
1172 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleDisplay*);
1173 static constexpr bool kHasTriggerImageLoads = true;
1175 nsChangeHint CalcDifference(const nsStyleDisplay& aNewData,
1176 const nsStylePosition& aOldPosition) const;
1178 nsStyleAutoArray<mozilla::StyleTransition> mTransitions;
1179 // The number of elements in mTransitions that are not from repeating
1180 // a list due to another property being longer.
1181 uint32_t mTransitionTimingFunctionCount;
1182 uint32_t mTransitionDurationCount;
1183 uint32_t mTransitionDelayCount;
1184 uint32_t mTransitionPropertyCount;
1185 nsStyleAutoArray<mozilla::StyleAnimation> mAnimations;
1186 // The number of elements in mAnimations that are not from repeating
1187 // a list due to another property being longer.
1188 uint32_t mAnimationTimingFunctionCount;
1189 uint32_t mAnimationDurationCount;
1190 uint32_t mAnimationDelayCount;
1191 uint32_t mAnimationNameCount;
1192 uint32_t mAnimationDirectionCount;
1193 uint32_t mAnimationFillModeCount;
1194 uint32_t mAnimationPlayStateCount;
1195 uint32_t mAnimationIterationCountCount;
1197 mozilla::StyleWillChange mWillChange;
1198 mozilla::StyleDisplay mDisplay;
1199 mozilla::StyleDisplay mOriginalDisplay; // saved mDisplay for
1200 // position:absolute/fixed
1201 // and float:left/right;
1202 // otherwise equal to
1203 // mDisplay
1204 mozilla::StyleContain mContain;
1206 private:
1207 mozilla::StyleAppearance mAppearance;
1209 public:
1210 mozilla::StyleAppearance mDefaultAppearance;
1211 mozilla::StylePositionProperty mPosition;
1213 mozilla::StyleFloat mFloat;
1214 mozilla::StyleClear mBreakType;
1215 mozilla::StyleBreakWithin mBreakInside;
1216 mozilla::StyleBreakBetween mBreakBefore;
1217 mozilla::StyleBreakBetween mBreakAfter;
1218 mozilla::StyleOverflow mOverflowX;
1219 mozilla::StyleOverflow mOverflowY;
1220 mozilla::StyleOverflowClipBox mOverflowClipBoxBlock;
1221 mozilla::StyleOverflowClipBox mOverflowClipBoxInline;
1222 mozilla::StyleResize mResize;
1223 mozilla::StyleOrient mOrient;
1224 mozilla::StyleIsolation mIsolation;
1225 mozilla::StyleTopLayer mTopLayer;
1227 mozilla::StyleTouchAction mTouchAction;
1228 mozilla::StyleScrollBehavior mScrollBehavior;
1229 mozilla::StyleOverscrollBehavior mOverscrollBehaviorX;
1230 mozilla::StyleOverscrollBehavior mOverscrollBehaviorY;
1231 mozilla::StyleOverflowAnchor mOverflowAnchor;
1232 mozilla::StyleScrollSnapAlign mScrollSnapAlign;
1233 mozilla::StyleScrollSnapType mScrollSnapType;
1234 uint32_t mLineClamp;
1236 mozilla::StyleTransform mTransform;
1237 mozilla::StyleRotate mRotate;
1238 mozilla::StyleTranslate mTranslate;
1239 mozilla::StyleScale mScale;
1241 mozilla::StyleBackfaceVisibility mBackfaceVisibility;
1242 mozilla::StyleTransformStyle mTransformStyle;
1243 StyleGeometryBox mTransformBox;
1245 mozilla::StyleOffsetPath mOffsetPath;
1246 mozilla::LengthPercentage mOffsetDistance;
1247 mozilla::StyleOffsetRotate mOffsetRotate;
1248 mozilla::StylePositionOrAuto mOffsetAnchor;
1250 mozilla::StyleTransformOrigin mTransformOrigin;
1251 mozilla::StylePerspective mChildPerspective;
1252 mozilla::Position mPerspectiveOrigin;
1254 mozilla::StyleVerticalAlign mVerticalAlign;
1256 nsCSSPropertyID GetTransitionProperty(uint32_t aIndex) const {
1257 return mTransitions[aIndex % mTransitionPropertyCount].GetProperty();
1259 float GetTransitionDelay(uint32_t aIndex) const {
1260 return mTransitions[aIndex % mTransitionDelayCount].GetDelay();
1262 float GetTransitionDuration(uint32_t aIndex) const {
1263 return mTransitions[aIndex % mTransitionDurationCount].GetDuration();
1265 const nsTimingFunction& GetTransitionTimingFunction(uint32_t aIndex) const {
1266 return mTransitions[aIndex % mTransitionTimingFunctionCount]
1267 .GetTimingFunction();
1269 float GetTransitionCombinedDuration(uint32_t aIndex) const {
1270 // https://drafts.csswg.org/css-transitions/#transition-combined-duration
1271 return std::max(
1272 mTransitions[aIndex % mTransitionDurationCount].GetDuration(),
1273 0.0f) +
1274 mTransitions[aIndex % mTransitionDelayCount].GetDelay();
1277 nsAtom* GetAnimationName(uint32_t aIndex) const {
1278 return mAnimations[aIndex % mAnimationNameCount].GetName();
1280 float GetAnimationDelay(uint32_t aIndex) const {
1281 return mAnimations[aIndex % mAnimationDelayCount].GetDelay();
1283 float GetAnimationDuration(uint32_t aIndex) const {
1284 return mAnimations[aIndex % mAnimationDurationCount].GetDuration();
1286 mozilla::dom::PlaybackDirection GetAnimationDirection(uint32_t aIndex) const {
1287 return mAnimations[aIndex % mAnimationDirectionCount].GetDirection();
1289 mozilla::dom::FillMode GetAnimationFillMode(uint32_t aIndex) const {
1290 return mAnimations[aIndex % mAnimationFillModeCount].GetFillMode();
1292 mozilla::StyleAnimationPlayState GetAnimationPlayState(
1293 uint32_t aIndex) const {
1294 return mAnimations[aIndex % mAnimationPlayStateCount].GetPlayState();
1296 float GetAnimationIterationCount(uint32_t aIndex) const {
1297 return mAnimations[aIndex % mAnimationIterationCountCount]
1298 .GetIterationCount();
1300 const nsTimingFunction& GetAnimationTimingFunction(uint32_t aIndex) const {
1301 return mAnimations[aIndex % mAnimationTimingFunctionCount]
1302 .GetTimingFunction();
1305 // The threshold used for extracting a shape from shape-outside: <image>.
1306 float mShapeImageThreshold = 0.0f;
1308 // The margin around a shape-outside: <image>.
1309 mozilla::NonNegativeLengthPercentage mShapeMargin;
1311 mozilla::StyleShapeOutside mShapeOutside;
1313 bool HasAppearance() const {
1314 return EffectiveAppearance() != mozilla::StyleAppearance::None;
1317 mozilla::StyleAppearance EffectiveAppearance() const {
1318 switch (mAppearance) {
1319 case mozilla::StyleAppearance::Auto:
1320 case mozilla::StyleAppearance::Button:
1321 case mozilla::StyleAppearance::Searchfield:
1322 case mozilla::StyleAppearance::Textarea:
1323 case mozilla::StyleAppearance::Checkbox:
1324 case mozilla::StyleAppearance::Radio:
1325 case mozilla::StyleAppearance::Menulist:
1326 case mozilla::StyleAppearance::Listbox:
1327 case mozilla::StyleAppearance::Meter:
1328 case mozilla::StyleAppearance::ProgressBar:
1329 // These are all the values that behave like `auto`.
1330 return mDefaultAppearance;
1331 case mozilla::StyleAppearance::Textfield:
1332 // `appearance: textfield` should behave like `auto` on all elements
1333 // except <input type=search> elements, which we identify using the
1334 // internal -moz-default-appearance property. (In the browser chrome
1335 // we have some other elements that set `-moz-default-appearance:
1336 // searchfield`, but not in content documents.)
1337 if (mDefaultAppearance == mozilla::StyleAppearance::Searchfield) {
1338 return mAppearance;
1340 // We also need to support `appearance: textfield` on <input
1341 // type=number>, since that is the only way in Gecko to disable the
1342 // spinners.
1343 if (mDefaultAppearance == mozilla::StyleAppearance::NumberInput) {
1344 return mAppearance;
1346 return mDefaultAppearance;
1347 case mozilla::StyleAppearance::MenulistButton:
1348 // `appearance: menulist-button` should behave like `auto` on all
1349 // elements except for drop down selects, but since we have very little
1350 // difference between menulist and menulist-button handling, we don't
1351 // bother.
1352 return mDefaultAppearance;
1353 default:
1354 return mAppearance;
1358 static mozilla::StyleDisplayOutside DisplayOutside(
1359 mozilla::StyleDisplay aDisplay) {
1360 return mozilla::StyleDisplayOutside(
1361 (uint16_t(aDisplay) >> mozilla::STYLE_DISPLAY_INSIDE_BITS) &
1362 uint16_t(((1 << mozilla::STYLE_DISPLAY_OUTSIDE_BITS) - 1)));
1364 mozilla::StyleDisplayOutside DisplayOutside() const {
1365 return DisplayOutside(mDisplay);
1368 static mozilla::StyleDisplayInside DisplayInside(
1369 mozilla::StyleDisplay aDisplay) {
1370 return mozilla::StyleDisplayInside(
1371 uint16_t(aDisplay) &
1372 uint16_t(((1 << mozilla::STYLE_DISPLAY_INSIDE_BITS) - 1)));
1374 mozilla::StyleDisplayInside DisplayInside() const {
1375 return DisplayInside(mDisplay);
1378 static bool IsListItem(mozilla::StyleDisplay aDisplay) {
1379 return !!(uint16_t(aDisplay) & mozilla::STYLE_DISPLAY_LIST_ITEM_BIT);
1381 bool IsListItem() const { return IsListItem(mDisplay); }
1383 // Whether display is `inline` or `inline list-item`.
1384 static bool IsInlineFlow(mozilla::StyleDisplay aDisplay) {
1385 return DisplayOutside(aDisplay) == mozilla::StyleDisplayOutside::Inline &&
1386 DisplayInside(aDisplay) == mozilla::StyleDisplayInside::Flow;
1389 bool IsInlineFlow() const { return IsInlineFlow(mDisplay); }
1391 bool IsInlineInsideStyle() const {
1392 auto inside = DisplayInside();
1393 return IsInlineFlow() || inside == mozilla::StyleDisplayInside::Ruby ||
1394 inside == mozilla::StyleDisplayInside::RubyBase ||
1395 inside == mozilla::StyleDisplayInside::RubyBaseContainer ||
1396 inside == mozilla::StyleDisplayInside::RubyText ||
1397 inside == mozilla::StyleDisplayInside::RubyTextContainer;
1400 bool IsBlockOutsideStyle() const {
1401 return DisplayOutside() == mozilla::StyleDisplayOutside::Block;
1404 static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) {
1405 auto outside = DisplayOutside(aDisplay);
1406 if (outside == mozilla::StyleDisplayOutside::Inline) {
1407 return true;
1409 // just an optimization for the common case:
1410 if (outside == mozilla::StyleDisplayOutside::Block) {
1411 return false;
1413 return mozilla::StyleDisplay::MozInlineBox == aDisplay ||
1414 mozilla::StyleDisplay::RubyBase == aDisplay ||
1415 mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
1416 mozilla::StyleDisplay::RubyText == aDisplay ||
1417 mozilla::StyleDisplay::RubyTextContainer == aDisplay;
1420 bool IsInlineOutsideStyle() const {
1421 return IsDisplayTypeInlineOutside(mDisplay);
1424 bool IsOriginalDisplayInlineOutside() const {
1425 return IsDisplayTypeInlineOutside(mOriginalDisplay);
1428 bool IsInnerTableStyle() const {
1429 return DisplayOutside() == mozilla::StyleDisplayOutside::InternalTable;
1432 bool IsInternalTableStyleExceptCell() const {
1433 return IsInnerTableStyle() && mozilla::StyleDisplay::TableCell != mDisplay;
1436 bool IsXULDisplayStyle() const {
1437 // -moz-{inline-}box is XUL, unless we're emulating it with flexbox.
1438 if (!mozilla::StaticPrefs::layout_css_emulate_moz_box_with_flex() &&
1439 DisplayInside() == mozilla::StyleDisplayInside::MozBox) {
1440 return true;
1443 #ifdef MOZ_XUL
1444 return DisplayOutside() == mozilla::StyleDisplayOutside::XUL;
1445 #else
1446 return false;
1447 #endif
1450 bool IsFloatingStyle() const { return mozilla::StyleFloat::None != mFloat; }
1452 bool IsPositionedStyle() const {
1453 return mPosition != mozilla::StylePositionProperty::Static ||
1454 (mWillChange.bits & mozilla::StyleWillChangeBits::ABSPOS_CB);
1457 bool IsAbsolutelyPositionedStyle() const {
1458 return mozilla::StylePositionProperty::Absolute == mPosition ||
1459 mozilla::StylePositionProperty::Fixed == mPosition;
1462 bool IsRelativelyPositionedStyle() const {
1463 return mozilla::StylePositionProperty::Relative == mPosition ||
1464 mozilla::StylePositionProperty::Sticky == mPosition;
1466 bool IsStickyPositionedStyle() const {
1467 return mozilla::StylePositionProperty::Sticky == mPosition;
1469 bool IsPositionForcingStackingContext() const {
1470 return mozilla::StylePositionProperty::Sticky == mPosition ||
1471 mozilla::StylePositionProperty::Fixed == mPosition;
1474 static bool IsRubyDisplayType(mozilla::StyleDisplay aDisplay) {
1475 return DisplayInside(aDisplay) == mozilla::StyleDisplayInside::Ruby ||
1476 IsInternalRubyDisplayType(aDisplay);
1479 static bool IsInternalRubyDisplayType(mozilla::StyleDisplay aDisplay) {
1480 return mozilla::StyleDisplay::RubyBase == aDisplay ||
1481 mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
1482 mozilla::StyleDisplay::RubyText == aDisplay ||
1483 mozilla::StyleDisplay::RubyTextContainer == aDisplay;
1486 bool IsRubyDisplayType() const { return IsRubyDisplayType(mDisplay); }
1488 bool IsInternalRubyDisplayType() const {
1489 return IsInternalRubyDisplayType(mDisplay);
1492 bool IsOutOfFlowStyle() const {
1493 return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());
1496 bool IsScrollableOverflow() const {
1497 // Visible and Clip can be combined but not with other values,
1498 // so checking mOverflowX is enough.
1499 return mOverflowX != mozilla::StyleOverflow::Visible &&
1500 mOverflowX != mozilla::StyleOverflow::Clip;
1503 bool OverflowIsVisibleInBothAxis() const {
1504 return mOverflowX == mozilla::StyleOverflow::Visible &&
1505 mOverflowY == mozilla::StyleOverflow::Visible;
1508 bool IsContainPaint() const {
1509 return (mContain & mozilla::StyleContain::PAINT) &&
1510 !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
1513 bool IsContainLayout() const {
1514 // Note: The spec for layout containment says it should
1515 // have no effect on non-atomic, inline-level boxes. We
1516 // don't check for these here because we don't know
1517 // what type of element is involved. Callers are
1518 // responsible for checking if the box in question is
1519 // non-atomic and inline-level, and creating an
1520 // exemption as necessary.
1521 return (mContain & mozilla::StyleContain::LAYOUT) &&
1522 !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
1525 bool IsContainSize() const {
1526 // Note: The spec for size containment says it should
1527 // have no effect on non-atomic, inline-level boxes. We
1528 // don't check for these here because we don't know
1529 // what type of element is involved. Callers are
1530 // responsible for checking if the box in question is
1531 // non-atomic and inline-level, and creating an
1532 // exemption as necessary.
1533 return (mContain & mozilla::StyleContain::SIZE) &&
1534 !IsInternalRubyDisplayType() &&
1535 DisplayInside() != mozilla::StyleDisplayInside::Table &&
1536 !IsInnerTableStyle();
1539 /* Returns whether the element has the transform property or a related
1540 * property. */
1541 bool HasTransformStyle() const {
1542 return HasTransformProperty() || HasIndividualTransform() ||
1543 mTransformStyle == mozilla::StyleTransformStyle::Preserve3d ||
1544 (mWillChange.bits & mozilla::StyleWillChangeBits::TRANSFORM) ||
1545 !mOffsetPath.IsNone();
1548 bool HasTransformProperty() const { return !mTransform._0.IsEmpty(); }
1550 bool HasIndividualTransform() const {
1551 return !mRotate.IsNone() || !mTranslate.IsNone() || !mScale.IsNone();
1554 bool HasPerspectiveStyle() const { return !mChildPerspective.IsNone(); }
1556 bool BackfaceIsHidden() const {
1557 return mBackfaceVisibility == mozilla::StyleBackfaceVisibility::Hidden;
1560 // FIXME(emilio): This should be more fine-grained on each caller to
1561 // BreakBefore() / BreakAfter().
1562 static bool ShouldBreak(mozilla::StyleBreakBetween aBreak) {
1563 switch (aBreak) {
1564 case mozilla::StyleBreakBetween::Left:
1565 case mozilla::StyleBreakBetween::Right:
1566 case mozilla::StyleBreakBetween::Page:
1567 case mozilla::StyleBreakBetween::Always:
1568 return true;
1569 case mozilla::StyleBreakBetween::Auto:
1570 case mozilla::StyleBreakBetween::Avoid:
1571 return false;
1572 default:
1573 MOZ_ASSERT_UNREACHABLE("Unknown break kind");
1574 return false;
1578 bool BreakBefore() const { return ShouldBreak(mBreakBefore); }
1580 bool BreakAfter() const { return ShouldBreak(mBreakAfter); }
1582 // These are defined in nsStyleStructInlines.h.
1584 // The aContextFrame argument on each of these is the frame this
1585 // style struct is for. If the frame is for SVG text, the return
1586 // value will be massaged to be something that makes sense for
1587 // SVG text.
1588 inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
1589 inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
1590 inline mozilla::StyleDisplay GetDisplay(const nsIFrame* aContextFrame) const;
1591 inline bool IsFloating(const nsIFrame* aContextFrame) const;
1592 inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
1593 inline bool IsStickyPositioned(const nsIFrame* aContextFrame) const;
1594 inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
1596 // These methods are defined in nsStyleStructInlines.h.
1599 * Returns true when the element has the transform property
1600 * or a related property, and supports CSS transforms.
1601 * aContextFrame is the frame for which this is the nsStyleDisplay.
1603 inline bool HasTransform(const nsIFrame* aContextFrame) const;
1606 * Returns true when the element has the perspective property,
1607 * and supports CSS transforms. aContextFrame is the frame for
1608 * which this is the nsStyleDisplay.
1610 inline bool HasPerspective(const nsIFrame* aContextFrame) const;
1613 * Returns whether the element is a containing block for its
1614 * absolutely positioned descendants.
1615 * aContextFrame is the frame for which this is the nsStyleDisplay.
1617 inline bool IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const;
1620 * Returns true when the element is a containing block for its fixed-pos
1621 * descendants.
1622 * aContextFrame is the frame for which this is the nsStyleDisplay.
1624 inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const;
1627 * Tests for only the sub-parts of IsFixedPosContainingBlock that apply
1628 * to:
1629 * - nearly all frames, except those that are SVG text frames.
1630 * - frames that support CSS contain:layout and contain:paint and are not
1631 * SVG text frames.
1632 * - frames that support CSS transforms and are not SVG text frames.
1634 * This should be used only when the caller has the style but not the
1635 * frame (i.e., when calculating style changes).
1637 inline bool IsFixedPosContainingBlockForNonSVGTextFrames(
1638 const mozilla::ComputedStyle&) const;
1639 inline bool
1640 IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() const;
1641 inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const;
1643 void GenerateCombinedIndividualTransform();
1646 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable {
1647 explicit nsStyleTable(const mozilla::dom::Document&);
1648 nsStyleTable(const nsStyleTable& aOther);
1649 ~nsStyleTable();
1650 static constexpr bool kHasTriggerImageLoads = false;
1652 nsChangeHint CalcDifference(const nsStyleTable& aNewData) const;
1654 mozilla::StyleTableLayout mLayoutStrategy;
1655 int32_t mXSpan; // The number of columns spanned by a colgroup or col
1658 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder {
1659 explicit nsStyleTableBorder(const mozilla::dom::Document&);
1660 nsStyleTableBorder(const nsStyleTableBorder& aOther);
1661 ~nsStyleTableBorder();
1662 static constexpr bool kHasTriggerImageLoads = false;
1664 nsChangeHint CalcDifference(const nsStyleTableBorder& aNewData) const;
1666 nscoord mBorderSpacingCol;
1667 nscoord mBorderSpacingRow;
1668 mozilla::StyleBorderCollapse mBorderCollapse;
1669 mozilla::StyleCaptionSide mCaptionSide;
1670 mozilla::StyleEmptyCells mEmptyCells;
1673 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent {
1674 using CounterPair = mozilla::StyleGenericCounterPair<int32_t>;
1676 explicit nsStyleContent(const mozilla::dom::Document&);
1677 nsStyleContent(const nsStyleContent& aContent);
1678 ~nsStyleContent();
1680 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleContent*);
1681 static constexpr bool kHasTriggerImageLoads = true;
1683 size_t ContentCount() const {
1684 return mContent.IsItems() ? mContent.AsItems().Length() : 0;
1687 const mozilla::StyleContentItem& ContentAt(size_t aIndex) const {
1688 return mContent.AsItems().AsSpan()[aIndex];
1691 nsChangeHint CalcDifference(const nsStyleContent& aNewData) const;
1693 mozilla::StyleContent mContent;
1694 mozilla::StyleCounterIncrement mCounterIncrement;
1695 mozilla::StyleCounterSetOrReset mCounterReset;
1696 mozilla::StyleCounterSetOrReset mCounterSet;
1699 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
1700 explicit nsStyleUIReset(const mozilla::dom::Document&);
1701 nsStyleUIReset(const nsStyleUIReset& aOther);
1702 ~nsStyleUIReset();
1703 static constexpr bool kHasTriggerImageLoads = false;
1705 nsChangeHint CalcDifference(const nsStyleUIReset& aNewData) const;
1707 mozilla::StyleUserSelect mUserSelect; // [reset](selection-style)
1708 mozilla::StyleScrollbarWidth mScrollbarWidth;
1709 uint8_t mMozForceBrokenImageIcon; // (0 if not forcing, otherwise forcing)
1710 mozilla::StyleImeMode mIMEMode;
1711 mozilla::StyleWindowDragging mWindowDragging;
1712 mozilla::StyleWindowShadow mWindowShadow;
1713 float mWindowOpacity;
1714 mozilla::StyleTransform mMozWindowTransform;
1715 mozilla::StyleTransformOrigin mWindowTransformOrigin;
1718 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI {
1719 explicit nsStyleUI(const mozilla::dom::Document&);
1720 nsStyleUI(const nsStyleUI& aOther);
1721 ~nsStyleUI();
1723 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleUI*);
1724 static constexpr bool kHasTriggerImageLoads = true;
1726 nsChangeHint CalcDifference(const nsStyleUI& aNewData) const;
1728 mozilla::StyleInert mInert;
1729 mozilla::StyleUserInput mUserInput;
1730 mozilla::StyleUserModify mUserModify; // (modify-content)
1731 mozilla::StyleUserFocus mUserFocus; // (auto-select)
1732 mozilla::StylePointerEvents mPointerEvents;
1734 mozilla::StyleCursor mCursor;
1736 mozilla::StyleColorOrAuto mCaretColor;
1737 mozilla::StyleScrollbarColor mScrollbarColor;
1739 inline mozilla::StylePointerEvents GetEffectivePointerEvents(
1740 nsIFrame* aFrame) const;
1742 bool HasCustomScrollbars() const { return !mScrollbarColor.IsAuto(); }
1745 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL {
1746 explicit nsStyleXUL(const mozilla::dom::Document&);
1747 nsStyleXUL(const nsStyleXUL& aSource);
1748 ~nsStyleXUL();
1749 static constexpr bool kHasTriggerImageLoads = false;
1751 nsChangeHint CalcDifference(const nsStyleXUL& aNewData) const;
1753 float mBoxFlex;
1754 int32_t mBoxOrdinal;
1755 mozilla::StyleBoxAlign mBoxAlign;
1756 mozilla::StyleBoxDirection mBoxDirection;
1757 mozilla::StyleBoxOrient mBoxOrient;
1758 mozilla::StyleBoxPack mBoxPack;
1761 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn {
1762 explicit nsStyleColumn(const mozilla::dom::Document&);
1763 nsStyleColumn(const nsStyleColumn& aSource);
1764 ~nsStyleColumn();
1765 static constexpr bool kHasTriggerImageLoads = false;
1767 nsChangeHint CalcDifference(const nsStyleColumn& aNewData) const;
1769 // This is the maximum number of columns we can process. It's used in
1770 // nsColumnSetFrame.
1771 static const uint32_t kMaxColumnCount = 1000;
1773 // This represents the value of column-count: auto.
1774 static const uint32_t kColumnCountAuto = 0;
1776 uint32_t mColumnCount = kColumnCountAuto;
1777 mozilla::NonNegativeLengthOrAuto mColumnWidth;
1779 mozilla::StyleColor mColumnRuleColor;
1780 mozilla::StyleBorderStyle mColumnRuleStyle; // StyleborderStyle::*
1781 mozilla::StyleColumnFill mColumnFill = mozilla::StyleColumnFill::Balance;
1782 mozilla::StyleColumnSpan mColumnSpan = mozilla::StyleColumnSpan::None;
1784 nscoord GetComputedColumnRuleWidth() const {
1785 return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
1788 bool IsColumnContainerStyle() const {
1789 return mColumnCount != kColumnCountAuto || !mColumnWidth.IsAuto();
1792 bool IsColumnSpanStyle() const {
1793 return mColumnSpan == mozilla::StyleColumnSpan::All;
1796 protected:
1797 nscoord mColumnRuleWidth; // coord
1798 nscoord mTwipsPerPixel;
1801 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG {
1802 explicit nsStyleSVG(const mozilla::dom::Document&);
1803 nsStyleSVG(const nsStyleSVG& aSource);
1804 ~nsStyleSVG();
1805 static constexpr bool kHasTriggerImageLoads = false;
1807 nsChangeHint CalcDifference(const nsStyleSVG& aNewData) const;
1809 mozilla::StyleSVGPaint mFill;
1810 mozilla::StyleSVGPaint mStroke;
1811 mozilla::StyleUrlOrNone mMarkerEnd;
1812 mozilla::StyleUrlOrNone mMarkerMid;
1813 mozilla::StyleUrlOrNone mMarkerStart;
1814 mozilla::StyleMozContextProperties mMozContextProperties;
1816 mozilla::StyleSVGStrokeDashArray mStrokeDasharray;
1817 mozilla::StyleSVGLength mStrokeDashoffset;
1818 mozilla::StyleSVGWidth mStrokeWidth;
1820 mozilla::StyleSVGOpacity mFillOpacity;
1821 float mStrokeMiterlimit;
1822 mozilla::StyleSVGOpacity mStrokeOpacity;
1824 mozilla::StyleFillRule mClipRule;
1825 mozilla::StyleColorInterpolation mColorInterpolation;
1826 mozilla::StyleColorInterpolation mColorInterpolationFilters;
1827 mozilla::StyleFillRule mFillRule;
1828 mozilla::StyleSVGPaintOrder mPaintOrder;
1829 mozilla::StyleShapeRendering mShapeRendering;
1830 mozilla::StyleStrokeLinecap mStrokeLinecap;
1831 mozilla::StyleStrokeLinejoin mStrokeLinejoin;
1832 mozilla::StyleDominantBaseline mDominantBaseline;
1833 mozilla::StyleTextAnchor mTextAnchor;
1835 /// Returns true if style has been set to expose the computed values of
1836 /// certain properties (such as 'fill') to the contents of any linked images.
1837 bool ExposesContextProperties() const {
1838 return bool(mMozContextProperties.bits);
1841 bool HasMarker() const {
1842 return mMarkerStart.IsUrl() || mMarkerMid.IsUrl() || mMarkerEnd.IsUrl();
1846 * Returns true if the stroke is not "none" and the stroke-opacity is greater
1847 * than zero (or a context-dependent value).
1849 * This ignores stroke-widths as that depends on the context.
1851 bool HasStroke() const {
1852 if (mStroke.kind.IsNone()) {
1853 return false;
1855 return !mStrokeOpacity.IsOpacity() || mStrokeOpacity.AsOpacity() > 0;
1859 * Returns true if the fill is not "none" and the fill-opacity is greater
1860 * than zero (or a context-dependent value).
1862 bool HasFill() const {
1863 if (mFill.kind.IsNone()) {
1864 return false;
1866 return !mFillOpacity.IsOpacity() || mFillOpacity.AsOpacity() > 0;
1870 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset {
1871 explicit nsStyleSVGReset(const mozilla::dom::Document&);
1872 nsStyleSVGReset(const nsStyleSVGReset& aSource);
1873 ~nsStyleSVGReset();
1875 // Resolves and tracks the images in mMask. Only called with a Servo-backed
1876 // style system, where those images must be resolved later than the OMT
1877 // nsStyleSVGReset constructor call.
1878 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleSVGReset*);
1879 static constexpr bool kHasTriggerImageLoads = true;
1881 nsChangeHint CalcDifference(const nsStyleSVGReset& aNewData) const;
1883 bool HasClipPath() const { return !mClipPath.IsNone(); }
1885 bool HasMask() const;
1887 bool HasNonScalingStroke() const {
1888 return mVectorEffect == mozilla::StyleVectorEffect::NonScalingStroke;
1891 // geometry properties
1892 mozilla::LengthPercentage mX;
1893 mozilla::LengthPercentage mY;
1894 mozilla::LengthPercentage mCx;
1895 mozilla::LengthPercentage mCy;
1896 mozilla::NonNegativeLengthPercentageOrAuto mRx;
1897 mozilla::NonNegativeLengthPercentageOrAuto mRy;
1898 mozilla::NonNegativeLengthPercentage mR;
1900 nsStyleImageLayers mMask;
1901 mozilla::StyleClipPath mClipPath;
1902 mozilla::StyleColor mStopColor;
1903 mozilla::StyleColor mFloodColor;
1904 mozilla::StyleColor mLightingColor;
1906 float mStopOpacity;
1907 float mFloodOpacity;
1909 mozilla::StyleVectorEffect mVectorEffect;
1910 mozilla::StyleMaskType mMaskType;
1913 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects {
1914 explicit nsStyleEffects(const mozilla::dom::Document&);
1915 nsStyleEffects(const nsStyleEffects& aSource);
1916 ~nsStyleEffects();
1917 static constexpr bool kHasTriggerImageLoads = false;
1919 nsChangeHint CalcDifference(const nsStyleEffects& aNewData) const;
1921 bool HasFilters() const { return !mFilters.IsEmpty(); }
1923 bool HasBackdropFilters() const { return !mBackdropFilters.IsEmpty(); }
1925 bool HasBoxShadowWithInset(bool aInset) const {
1926 for (auto& shadow : mBoxShadow.AsSpan()) {
1927 if (shadow.inset == aInset) {
1928 return true;
1931 return false;
1934 bool HasMixBlendMode() const {
1935 return mMixBlendMode != mozilla::StyleBlend::Normal;
1938 mozilla::StyleOwnedSlice<mozilla::StyleFilter> mFilters;
1939 mozilla::StyleOwnedSlice<mozilla::StyleBoxShadow> mBoxShadow;
1940 mozilla::StyleOwnedSlice<mozilla::StyleFilter> mBackdropFilters;
1941 mozilla::StyleClipRectOrAuto mClip; // offsets from UL border edge
1942 float mOpacity;
1943 mozilla::StyleBlend mMixBlendMode;
1946 #define STATIC_ASSERT_TYPE_LAYOUTS_MATCH(T1, T2) \
1947 static_assert(sizeof(T1) == sizeof(T2), \
1948 "Size mismatch between " #T1 " and " #T2); \
1949 static_assert(alignof(T1) == alignof(T2), \
1950 "Align mismatch between " #T1 " and " #T2);
1952 #define STATIC_ASSERT_FIELD_OFFSET_MATCHES(T1, T2, field) \
1953 static_assert(offsetof(T1, field) == offsetof(T2, field), \
1954 "Field offset mismatch of " #field " between " #T1 \
1955 " and " #T2);
1958 * These *_Simple types are used to map Gecko types to layout-equivalent but
1959 * simpler Rust types, to aid Rust binding generation.
1961 * If something in this types or the assertions below needs to change, ask
1962 * bholley, heycam or emilio before!
1964 * <div rustbindgen="true" replaces="nsPoint">
1966 struct nsPoint_Simple {
1967 nscoord x, y;
1970 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple);
1971 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x);
1972 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y);
1975 * <div rustbindgen="true" replaces="nsMargin">
1977 struct nsMargin_Simple {
1978 nscoord top, right, bottom, left;
1981 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple);
1982 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top);
1983 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right);
1984 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom);
1985 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left);
1988 * <div rustbindgen="true" replaces="nsRect">
1990 struct nsRect_Simple {
1991 nscoord x, y, width, height;
1994 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple);
1995 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x);
1996 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y);
1997 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width);
1998 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height);
2001 * <div rustbindgen="true" replaces="nsSize">
2003 struct nsSize_Simple {
2004 nscoord width, height;
2007 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple);
2008 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width);
2009 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height);
2012 * <div rustbindgen="true" replaces="mozilla::UniquePtr">
2014 * TODO(Emilio): This is a workaround and we should be able to get rid of this
2015 * one.
2017 template <typename T>
2018 struct UniquePtr_Simple {
2019 T* mPtr;
2022 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(mozilla::UniquePtr<int>,
2023 UniquePtr_Simple<int>);
2026 * <div rustbindgen replaces="nsTArray"></div>
2028 template <typename T>
2029 class nsTArray_Simple {
2030 protected:
2031 T* mBuffer;
2033 public:
2034 ~nsTArray_Simple() {
2035 // The existence of a user-provided, and therefore non-trivial, destructor
2036 // here prevents bindgen from deriving the Clone trait via a simple memory
2037 // copy.
2042 * <div rustbindgen replaces="CopyableTArray"></div>
2044 template <typename T>
2045 class CopyableTArray_Simple : public nsTArray_Simple<T> {};
2047 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<nsStyleImageLayers::Layer>,
2048 nsTArray_Simple<nsStyleImageLayers::Layer>);
2049 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleTransition>,
2050 nsTArray_Simple<mozilla::StyleTransition>);
2051 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleAnimation>,
2052 nsTArray_Simple<mozilla::StyleAnimation>);
2054 #endif /* nsStyleStruct_h___ */