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/. */
6 
7 /*
8  * structs that contain the data provided by ComputedStyle, the
9  * internal API for computed style data for an element
10  */
11 
12 #ifndef nsStyleStruct_h___
13 #define nsStyleStruct_h___
14 
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"
34 
35 class nsIFrame;
36 class nsIURI;
37 class nsTextFrame;
38 struct nsStyleDisplay;
39 struct nsStyleVisibility;
40 namespace mozilla {
41 class ComputedStyle;
42 
43 }  // namespace mozilla
44 
45 namespace mozilla {
46 
47 using Position = StylePosition;
48 
49 template <>
HasPercent()50 inline bool StylePosition::HasPercent() const {
51   return horizontal.HasPercent() || vertical.HasPercent();
52 }
53 
54 /**
55  * True if the effective background image position described by this depends on
56  * the size of the corresponding frame.
57  */
58 template <>
DependsOnPositioningAreaSize()59 inline bool StylePosition::DependsOnPositioningAreaSize() const {
60   return HasPercent();
61 }
62 
63 template <>
FromPercentage(float aPercent)64 inline Position Position::FromPercentage(float aPercent) {
65   return {LengthPercentage::FromPercentage(aPercent),
66           LengthPercentage::FromPercentage(aPercent)};
67 }
68 
69 }  // namespace mozilla
70 
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;
76 
77   nsChangeHint CalcDifference(const nsStyleFont& aNewData) const;
78 
79   /**
80    * Return a given size multiplied by the current text zoom factor (in
81    * aPresContext).
82    *
83    * The size is allowed to be negative, but the caller is expected to deal with
84    * negative results.
85    */
86   static mozilla::Length ZoomText(const mozilla::dom::Document&,
87                                   mozilla::Length);
88 
89   nsFont mFont;
90 
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;
96 
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;
102 
103   // math-depth support (used for MathML scriptlevel)
104   int8_t mMathDepth;
105   // MathML  mathvariant support
106   mozilla::StyleMathVariant mMathVariant;
107   // math-style support (used for MathML displaystyle)
108   uint8_t mMathStyle;
109 
110   // allow different min font-size for certain cases
111   uint8_t mMinFontSizeRatio;  // percent * 100
112 
113   // was mLanguage set based on a lang attribute in the document?
114   bool mExplicitLanguage;
115 
116   // should calls to ZoomText() and UnZoomText() be made to the font
117   // size on this nsStyleFont? Also used to prevent SVG text from being
118   // affected by minimum font size pref.
119   bool mAllowZoomAndMinSize;
120 
121   // The value mSize would have had if scriptminsize had never been applied
122   mozilla::NonNegativeLength mScriptUnconstrainedSize;
123   mozilla::Length mScriptMinSize;
124   float mScriptSizeMultiplier;
125   RefPtr<nsAtom> mLanguage;
126 };
127 
128 // TODO(emilio, bug 1564526): Evaluate whether this is still needed.
129 struct CachedBorderImageData {
~CachedBorderImageDataCachedBorderImageData130   ~CachedBorderImageData() { PurgeCachedImages(); }
131 
132   // Caller are expected to ensure that the value of aSize is different from the
133   // cached one since the method won't do the check.
SetCachedSVGViewportSizeCachedBorderImageData134   void SetCachedSVGViewportSize(const mozilla::Maybe<nsSize>& aSize) {
135     mCachedSVGViewportSize = aSize;
136   }
137 
GetCachedSVGViewportSizeCachedBorderImageData138   const mozilla::Maybe<nsSize>& GetCachedSVGViewportSize() const {
139     return mCachedSVGViewportSize;
140   }
141 
142   void PurgeCachedImages();
143 
SetSubImageCachedBorderImageData144   void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) {
145     mSubImages.EnsureLengthAtLeast(aIndex + 1);
146     mSubImages[aIndex] = aSubImage;
147   }
GetSubImageCachedBorderImageData148   imgIContainer* GetSubImage(uint8_t aIndex) {
149     return mSubImages.SafeElementAt(aIndex);
150   }
151 
152   // These methods are used for the caller to caches the sub images created
153   // during a border-image paint operation
154   void PurgeCacheForViewportChange(
155       const mozilla::Maybe<nsSize>& aSVGViewportSize,
156       const bool aHasIntrinsicRatio);
157 
158  private:
159   // If this is a SVG border-image, we save the size of the SVG viewport that
160   // we used when rasterizing any cached border-image subimages. (The viewport
161   // size matters for percent-valued sizes & positions in inner SVG doc).
162   mozilla::Maybe<nsSize> mCachedSVGViewportSize;
163   nsTArray<RefPtr<imgIContainer>> mSubImages;
164 };
165 
166 struct nsStyleImageLayers {
167   enum class LayerType : uint8_t { Background = 0, Mask };
168 
169   explicit nsStyleImageLayers(LayerType aType);
170   nsStyleImageLayers(const nsStyleImageLayers& aSource);
171   MOZ_COUNTED_DTOR(nsStyleImageLayers)
172 
173   struct Repeat {
174     mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat;
175 
176     // Initialize nothing
177     Repeat() = default;
178 
IsInitialValuensStyleImageLayers::Repeat179     bool IsInitialValue() const {
180       return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat &&
181              mYRepeat == mozilla::StyleImageLayerRepeat::Repeat;
182     }
183 
DependsOnPositioningAreaSizensStyleImageLayers::Repeat184     bool DependsOnPositioningAreaSize() const {
185       return mXRepeat == mozilla::StyleImageLayerRepeat::Space ||
186              mYRepeat == mozilla::StyleImageLayerRepeat::Space;
187     }
188 
189     // Initialize to initial values
SetInitialValuesnsStyleImageLayers::Repeat190     void SetInitialValues() {
191       mXRepeat = mozilla::StyleImageLayerRepeat::Repeat;
192       mYRepeat = mozilla::StyleImageLayerRepeat::Repeat;
193     }
194 
195     bool operator==(const Repeat& aOther) const {
196       return mXRepeat == aOther.mXRepeat && mYRepeat == aOther.mYRepeat;
197     }
198     bool operator!=(const Repeat& aOther) const { return !(*this == aOther); }
199   };
200 
201   struct Layer {
202     typedef mozilla::StyleGeometryBox StyleGeometryBox;
203     typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment;
204     typedef mozilla::StyleBackgroundSize StyleBackgroundSize;
205 
206     mozilla::StyleImage mImage;
207     mozilla::Position mPosition;
208     StyleBackgroundSize mSize;
209     StyleGeometryBox mClip;
210     MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin;
211 
212     // This property is used for background layer only.
213     // For a mask layer, it should always be the initial value, which is
214     // StyleImageLayerAttachment::Scroll.
215     StyleImageLayerAttachment mAttachment;
216 
217     // This property is used for background layer only.
218     // For a mask layer, it should always be the initial value, which is
219     // StyleBlend::Normal.
220     mozilla::StyleBlend mBlendMode;
221 
222     // This property is used for mask layer only.
223     // For a background layer, it should always be the initial value, which is
224     // StyleMaskComposite::Add.
225     mozilla::StyleMaskComposite mComposite;
226 
227     // mask-only property. This property is used for mask layer only. For a
228     // background layer, it should always be the initial value, which is
229     // StyleMaskMode::MatchSource.
230     mozilla::StyleMaskMode mMaskMode;
231 
232     Repeat mRepeat;
233 
234     // This constructor does not initialize mRepeat or mOrigin and Initialize()
235     // must be called to do that.
236     Layer();
237     ~Layer();
238 
239     // Initialize mRepeat and mOrigin by specified layer type
240     void Initialize(LayerType aType);
241 
ResolveImagensStyleImageLayers::Layer242     void ResolveImage(mozilla::dom::Document& aDocument,
243                       const Layer* aOldLayer) {
244       mImage.ResolveImage(aDocument, aOldLayer ? &aOldLayer->mImage : nullptr);
245     }
246 
247     // True if the rendering of this layer might change when the size
248     // of the background positioning area changes.  This is true for any
249     // non-solid-color background whose position or size depends on
250     // the size of the positioning area.  It's also true for SVG images
251     // whose root <svg> node has a viewBox.
252     bool RenderingMightDependOnPositioningAreaSizeChange() const;
253 
254     // Compute the change hint required by changes in just this layer.
255     nsChangeHint CalcDifference(const Layer& aNewLayer) const;
256 
257     // An equality operator that compares the images using URL-equality
258     // rather than pointer-equality.
259     bool operator==(const Layer& aOther) const;
260     bool operator!=(const Layer& aOther) const { return !(*this == aOther); }
261   };
262 
263   // The (positive) number of computed values of each property, since
264   // the lengths of the lists are independent.
265   uint32_t mAttachmentCount;
266   uint32_t mClipCount;
267   uint32_t mOriginCount;
268   uint32_t mRepeatCount;
269   uint32_t mPositionXCount;
270   uint32_t mPositionYCount;
271   uint32_t mImageCount;
272   uint32_t mSizeCount;
273   uint32_t mMaskModeCount;
274   uint32_t mBlendModeCount;
275   uint32_t mCompositeCount;
276 
277   // Layers are stored in an array, matching the top-to-bottom order in
278   // which they are specified in CSS.  The number of layers to be used
279   // should come from the background-image property.  We create
280   // additional |Layer| objects for *any* property, not just
281   // background-image.  This means that the bottommost layer that
282   // callers in layout care about (which is also the one whose
283   // background-clip applies to the background-color) may not be last
284   // layer.  In layers below the bottom layer, properties will be
285   // uninitialized unless their count, above, indicates that they are
286   // present.
287   nsStyleAutoArray<Layer> mLayers;
288 
BottomLayernsStyleImageLayers289   const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
290 
ResolveImagesnsStyleImageLayers291   void ResolveImages(mozilla::dom::Document& aDocument,
292                      const nsStyleImageLayers* aOldLayers) {
293     for (uint32_t i = 0; i < mImageCount; ++i) {
294       const Layer* oldLayer = (aOldLayers && aOldLayers->mLayers.Length() > i)
295                                   ? &aOldLayers->mLayers[i]
296                                   : nullptr;
297       mLayers[i].ResolveImage(aDocument, oldLayer);
298     }
299   }
300 
301   // Fill unspecified layers by cycling through their values
302   // till they all are of length aMaxItemCount
303   void FillAllLayers(uint32_t aMaxItemCount);
304 
305   nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
306                               nsStyleImageLayers::LayerType aType) const;
307 
308   nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
309   nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther) = default;
310   bool operator==(const nsStyleImageLayers& aOther) const;
311 
312   static const nsCSSPropertyID kBackgroundLayerTable[];
313   static const nsCSSPropertyID kMaskLayerTable[];
314 
315 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
316   for (uint32_t var_ = (layers_).mImageCount; var_-- != 0;)
317 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_,  \
318                                                              start_, count_) \
319   NS_ASSERTION(                                                              \
320       (int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount,  \
321       "Invalid layer start!");                                               \
322   NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1,                     \
323                "Invalid layer range!");                                      \
324   for (uint32_t var_ = (start_) + 1;                                         \
325        var_-- != (uint32_t)((start_) + 1 - (count_));)
326 };
327 
328 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
329   explicit nsStyleBackground(const mozilla::dom::Document&);
330   nsStyleBackground(const nsStyleBackground& aOther);
331   ~nsStyleBackground();
332 
333   // Resolves and tracks the images in mImage.  Only called with a Servo-backed
334   // style system, where those images must be resolved later than the OMT
335   // nsStyleBackground constructor call.
336   void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBackground*);
337   static constexpr bool kHasTriggerImageLoads = true;
338 
339   nsChangeHint CalcDifference(const nsStyleBackground& aNewData) const;
340 
341   // Return the background color as nscolor.
342   nscolor BackgroundColor(const nsIFrame* aFrame) const;
343   nscolor BackgroundColor(const mozilla::ComputedStyle* aStyle) const;
344 
345   // True if this background is completely transparent.
346   bool IsTransparent(const nsIFrame* aFrame) const;
347   bool IsTransparent(mozilla::ComputedStyle* aStyle) const;
348 
349   // We have to take slower codepaths for fixed background attachment,
350   // but we don't want to do that when there's no image.
351   // Not inline because it uses an nsCOMPtr<imgIRequest>
352   // FIXME: Should be in nsStyleStructInlines.h.
353   bool HasFixedBackground(nsIFrame* aFrame) const;
354 
355   // Checks to see if this has a non-empty image with "local" attachment.
356   // This is defined in nsStyleStructInlines.h.
357   inline bool HasLocalBackground() const;
358 
BottomLayernsStyleBackground359   const nsStyleImageLayers::Layer& BottomLayer() const {
360     return mImage.BottomLayer();
361   }
362 
363   nsStyleImageLayers mImage;
364   mozilla::StyleColor mBackgroundColor;
365 };
366 
367 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
368   explicit nsStyleMargin(const mozilla::dom::Document&);
369   nsStyleMargin(const nsStyleMargin& aMargin);
370   MOZ_COUNTED_DTOR(nsStyleMargin)
371   static constexpr bool kHasTriggerImageLoads = false;
372 
373   nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const;
374 
GetMarginnsStyleMargin375   bool GetMargin(nsMargin& aMargin) const {
376     bool convertsToLength = mMargin.All(
377         [](const auto& aLength) { return aLength.ConvertsToLength(); });
378 
379     if (!convertsToLength) {
380       return false;
381     }
382 
383     for (const auto side : mozilla::AllPhysicalSides()) {
384       aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength();
385     }
386     return true;
387   }
388 
GetScrollMarginnsStyleMargin389   nsMargin GetScrollMargin() const {
390     return nsMargin(mScrollMargin.Get(mozilla::eSideTop).ToAppUnits(),
391                     mScrollMargin.Get(mozilla::eSideRight).ToAppUnits(),
392                     mScrollMargin.Get(mozilla::eSideBottom).ToAppUnits(),
393                     mScrollMargin.Get(mozilla::eSideLeft).ToAppUnits());
394   }
395 
396   // Return true if either the start or end side in the axis is 'auto'.
397   // (defined in WritingModes.h since we need the full WritingMode type)
398   inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const;
399   inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
400   inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode) const;
401 
402   mozilla::StyleRect<mozilla::LengthPercentageOrAuto> mMargin;
403   mozilla::StyleRect<mozilla::StyleLength> mScrollMargin;
404 };
405 
406 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding {
407   explicit nsStylePadding(const mozilla::dom::Document&);
408   nsStylePadding(const nsStylePadding& aPadding);
409   MOZ_COUNTED_DTOR(nsStylePadding)
410   static constexpr bool kHasTriggerImageLoads = false;
411 
412   nsChangeHint CalcDifference(const nsStylePadding& aNewData) const;
413 
414   mozilla::StyleRect<mozilla::NonNegativeLengthPercentage> mPadding;
415   mozilla::StyleRect<mozilla::NonNegativeLengthPercentageOrAuto> mScrollPadding;
416 
IsWidthDependentnsStylePadding417   inline bool IsWidthDependent() const {
418     return !mPadding.All(
419         [](const auto& aLength) { return aLength.ConvertsToLength(); });
420   }
421 
GetPaddingnsStylePadding422   bool GetPadding(nsMargin& aPadding) const {
423     if (IsWidthDependent()) {
424       return false;
425     }
426 
427     for (const auto side : mozilla::AllPhysicalSides()) {
428       // Clamp negative calc() to 0.
429       aPadding.Side(side) = std::max(mPadding.Get(side).ToLength(), 0);
430     }
431     return true;
432   }
433 };
434 
435 // Border widths are rounded to the nearest-below integer number of pixels,
436 // but values between zero and one device pixels are always rounded up to
437 // one device pixel.
438 #define NS_ROUND_BORDER_TO_PIXELS(l, tpp) \
439   ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
440 
441 // Returns if the given border style type is visible or not
IsVisibleBorderStyle(mozilla::StyleBorderStyle aStyle)442 static bool IsVisibleBorderStyle(mozilla::StyleBorderStyle aStyle) {
443   return (aStyle != mozilla::StyleBorderStyle::None &&
444           aStyle != mozilla::StyleBorderStyle::Hidden);
445 }
446 
447 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder {
448   explicit nsStyleBorder(const mozilla::dom::Document&);
449   nsStyleBorder(const nsStyleBorder& aBorder);
450   ~nsStyleBorder();
451 
452   // Resolves and tracks mBorderImageSource.  Only called with a Servo-backed
453   // style system, where those images must be resolved later than the OMT
454   // nsStyleBorder constructor call.
455   void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBorder*);
456   static constexpr bool kHasTriggerImageLoads = true;
457 
458   nsChangeHint CalcDifference(const nsStyleBorder& aNewData) const;
459 
460   // Return whether aStyle is a visible style.  Invisible styles cause
461   // the relevant computed border width to be 0.
462   // Note that this does *not* consider the effects of 'border-image':
463   // if border-style is none, but there is a loaded border image,
464   // HasVisibleStyle will be false even though there *is* a border.
HasVisibleStylensStyleBorder465   bool HasVisibleStyle(mozilla::Side aSide) const {
466     return IsVisibleBorderStyle(mBorderStyle[aSide]);
467   }
468 
469   // aBorderWidth is in twips
SetBorderWidthnsStyleBorder470   void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth) {
471     nscoord roundedWidth =
472         NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
473     mBorder.Side(aSide) = roundedWidth;
474     if (HasVisibleStyle(aSide)) {
475       mComputedBorder.Side(aSide) = roundedWidth;
476     }
477   }
478 
479   // Get the computed border (plus rounding).  This does consider the
480   // effects of 'border-style: none', but does not consider
481   // 'border-image'.
GetComputedBordernsStyleBorder482   const nsMargin& GetComputedBorder() const { return mComputedBorder; }
483 
HasBordernsStyleBorder484   bool HasBorder() const {
485     return mComputedBorder != nsMargin(0, 0, 0, 0) ||
486            !mBorderImageSource.IsNone();
487   }
488 
489   // Get the actual border width for a particular side, in appunits.  Note that
490   // this is zero if and only if there is no border to be painted for this
491   // side.  That is, this value takes into account the border style and the
492   // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
GetComputedBorderWidthnsStyleBorder493   nscoord GetComputedBorderWidth(mozilla::Side aSide) const {
494     return GetComputedBorder().Side(aSide);
495   }
496 
GetBorderStylensStyleBorder497   mozilla::StyleBorderStyle GetBorderStyle(mozilla::Side aSide) const {
498     NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
499     return mBorderStyle[aSide];
500   }
501 
SetBorderStylensStyleBorder502   void SetBorderStyle(mozilla::Side aSide, mozilla::StyleBorderStyle aStyle) {
503     NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
504     mBorderStyle[aSide] = aStyle;
505     mComputedBorder.Side(aSide) =
506         (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
507   }
508 
IsBorderImageSizeAvailablensStyleBorder509   inline bool IsBorderImageSizeAvailable() const {
510     return mBorderImageSource.IsSizeAvailable();
511   }
512 
513   nsMargin GetImageOutset() const;
514 
GetBorderImageRequestnsStyleBorder515   imgIRequest* GetBorderImageRequest() const {
516     return mBorderImageSource.GetImageRequest();
517   }
518 
519  public:
520   mozilla::StyleBorderRadius mBorderRadius;  // coord, percent
521   mozilla::StyleImage mBorderImageSource;
522   mozilla::StyleBorderImageWidth mBorderImageWidth;
523   mozilla::StyleNonNegativeLengthOrNumberRect mBorderImageOutset;
524   mozilla::StyleBorderImageSlice mBorderImageSlice;  // factor, percent
525   mozilla::StyleBorderImageRepeat mBorderImageRepeatH;
526   mozilla::StyleBorderImageRepeat mBorderImageRepeatV;
527   mozilla::StyleFloatEdge mFloatEdge;
528   mozilla::StyleBoxDecorationBreak mBoxDecorationBreak;
529 
530  protected:
531   mozilla::StyleBorderStyle mBorderStyle[4];  // StyleBorderStyle::*
532 
533  public:
534   // the colors to use for a simple border.
535   // not used for -moz-border-colors
536   mozilla::StyleColor mBorderTopColor;
537   mozilla::StyleColor mBorderRightColor;
538   mozilla::StyleColor mBorderBottomColor;
539   mozilla::StyleColor mBorderLeftColor;
540 
BorderColorFornsStyleBorder541   mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) {
542     switch (aSide) {
543       case mozilla::eSideTop:
544         return mBorderTopColor;
545       case mozilla::eSideRight:
546         return mBorderRightColor;
547       case mozilla::eSideBottom:
548         return mBorderBottomColor;
549       case mozilla::eSideLeft:
550         return mBorderLeftColor;
551     }
552     MOZ_ASSERT_UNREACHABLE("Unknown side");
553     return mBorderTopColor;
554   }
555 
BorderColorFornsStyleBorder556   const mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) const {
557     switch (aSide) {
558       case mozilla::eSideTop:
559         return mBorderTopColor;
560       case mozilla::eSideRight:
561         return mBorderRightColor;
562       case mozilla::eSideBottom:
563         return mBorderBottomColor;
564       case mozilla::eSideLeft:
565         return mBorderLeftColor;
566     }
567     MOZ_ASSERT_UNREACHABLE("Unknown side");
568     return mBorderTopColor;
569   }
570 
BorderColorFieldFornsStyleBorder571   static mozilla::StyleColor nsStyleBorder::*BorderColorFieldFor(
572       mozilla::Side aSide) {
573     switch (aSide) {
574       case mozilla::eSideTop:
575         return &nsStyleBorder::mBorderTopColor;
576       case mozilla::eSideRight:
577         return &nsStyleBorder::mBorderRightColor;
578       case mozilla::eSideBottom:
579         return &nsStyleBorder::mBorderBottomColor;
580       case mozilla::eSideLeft:
581         return &nsStyleBorder::mBorderLeftColor;
582     }
583     MOZ_ASSERT_UNREACHABLE("Unknown side");
584     return nullptr;
585   }
586 
587  protected:
588   // mComputedBorder holds the CSS2.1 computed border-width values.
589   // In particular, these widths take into account the border-style
590   // for the relevant side, and the values are rounded to the nearest
591   // device pixel (which is not part of the definition of computed
592   // values). The presence or absence of a border-image does not
593   // affect border-width values.
594   nsMargin mComputedBorder;
595 
596   // mBorder holds the nscoord values for the border widths as they
597   // would be if all the border-style values were visible (not hidden
598   // or none).  This member exists so that when we create structs
599   // using the copy constructor during style resolution the new
600   // structs will know what the specified values of the border were in
601   // case they have more specific rules setting the border style.
602   //
603   // Note that this isn't quite the CSS specified value, since this
604   // has had the enumerated border widths converted to lengths, and
605   // all lengths converted to twips.  But it's not quite the computed
606   // value either. The values are rounded to the nearest device pixel.
607   nsMargin mBorder;
608 
609  private:
610   nscoord mTwipsPerPixel;
611 
612   nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
613 };
614 
615 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline {
616   explicit nsStyleOutline(const mozilla::dom::Document&);
617   nsStyleOutline(const nsStyleOutline& aOutline);
618   MOZ_COUNTED_DTOR(nsStyleOutline)
619   static constexpr bool kHasTriggerImageLoads = false;
620 
621   nsChangeHint CalcDifference(const nsStyleOutline& aNewData) const;
622 
623   // This is the specified value of outline-width, but with length values
624   // computed to absolute.  mActualOutlineWidth stores the outline-width
625   // value used by layout.  (We must store mOutlineWidth for the same
626   // style struct resolution reasons that we do nsStyleBorder::mBorder;
627   // see that field's comment.)
628   nscoord mOutlineWidth;
629   mozilla::Length mOutlineOffset;
630   mozilla::StyleColor mOutlineColor;
631   mozilla::StyleOutlineStyle mOutlineStyle;
632 
GetOutlineWidthnsStyleOutline633   nscoord GetOutlineWidth() const { return mActualOutlineWidth; }
634 
ShouldPaintOutlinensStyleOutline635   bool ShouldPaintOutline() const {
636     if (mOutlineStyle.IsAuto()) {
637       return true;
638     }
639     if (GetOutlineWidth() > 0) {
640       MOZ_ASSERT(
641           mOutlineStyle.AsBorderStyle() != mozilla::StyleBorderStyle::None,
642           "outline-style: none implies outline-width of zero");
643       return true;
644     }
645     return false;
646   }
647 
648  protected:
649   // The actual value of outline-width is the computed value (an absolute
650   // length, forced to zero when outline-style is none) rounded to device
651   // pixels.  This is the value used by layout.
652   nscoord mActualOutlineWidth;
653   nscoord mTwipsPerPixel;
654 };
655 
656 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList {
657   explicit nsStyleList(const mozilla::dom::Document&);
658   nsStyleList(const nsStyleList& aStyleList);
659   ~nsStyleList();
660 
661  private:
662   nsStyleList& operator=(const nsStyleList& aOther) = delete;
663 
664  public:
665   void TriggerImageLoads(mozilla::dom::Document&, const nsStyleList*);
666   static constexpr bool kHasTriggerImageLoads = true;
667 
668   nsChangeHint CalcDifference(const nsStyleList& aNewData,
669                               const nsStyleDisplay& aOldDisplay) const;
670 
GetImageRegionnsStyleList671   nsRect GetImageRegion() const {
672     if (!mImageRegion.IsRect()) {
673       return nsRect();
674     }
675     return mImageRegion.AsRect().ToLayoutRect(0);
676   }
677 
678   already_AddRefed<nsIURI> GetListStyleImageURI() const;
679 
680   uint8_t mListStylePosition;
681 
682   mozilla::CounterStylePtr mCounterStyle;
683   mozilla::StyleQuotes mQuotes;
684   mozilla::StyleImage mListStyleImage;
685 
686   // the rect to use within an image.
687   mozilla::StyleClipRectOrAuto mImageRegion;
688 };
689 
690 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePage {
691   using StylePageSize = mozilla::StylePageSize;
692   using StylePageName = mozilla::StylePageName;
693   nsStylePage(const nsStylePage& aOther) = default;
694   nsStylePage& operator=(const nsStylePage& aOther) = default;
nsStylePagensStylePage695   explicit nsStylePage(const mozilla::dom::Document&)
696       : mSize(StylePageSize::Auto()), mPage(StylePageName::Auto()) {}
697 
698   static constexpr bool kHasTriggerImageLoads = false;
699   nsChangeHint CalcDifference(const nsStylePage& aNewData) const;
700 
701   // page-size property.
702   StylePageSize mSize;
703   // page-name property.
704   StylePageName mPage;
705 };
706 
707 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
708   using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto;
709   using Position = mozilla::Position;
710   template <typename T>
711   using StyleRect = mozilla::StyleRect<T>;
712   using StyleSize = mozilla::StyleSize;
713   using StyleMaxSize = mozilla::StyleMaxSize;
714   using WritingMode = mozilla::WritingMode;
715   using LogicalAxis = mozilla::LogicalAxis;
716   using StyleImplicitGridTracks = mozilla::StyleImplicitGridTracks;
717   using ComputedStyle = mozilla::ComputedStyle;
718   using StyleAlignSelf = mozilla::StyleAlignSelf;
719   using StyleJustifySelf = mozilla::StyleJustifySelf;
720 
721   explicit nsStylePosition(const mozilla::dom::Document&);
722   nsStylePosition(const nsStylePosition& aOther);
723   ~nsStylePosition();
724   static constexpr bool kHasTriggerImageLoads = false;
725 
726   nsChangeHint CalcDifference(
727       const nsStylePosition& aNewData,
728       const nsStyleVisibility& aOldStyleVisibility) const;
729 
730   // Returns whether we need to compute an hypothetical position if we were
731   // absolutely positioned.
NeedsHypotheticalPositionIfAbsPosnsStylePosition732   bool NeedsHypotheticalPositionIfAbsPos() const {
733     return (mOffset.Get(mozilla::eSideRight).IsAuto() &&
734             mOffset.Get(mozilla::eSideLeft).IsAuto()) ||
735            (mOffset.Get(mozilla::eSideTop).IsAuto() &&
736             mOffset.Get(mozilla::eSideBottom).IsAuto());
737   }
738 
739   /**
740    * Return the used value for 'align-self' given our parent ComputedStyle
741    * (or null for the root).
742    */
743   StyleAlignSelf UsedAlignSelf(const ComputedStyle*) const;
744 
745   /**
746    * Return the used value for 'justify-self' given our parent ComputedStyle
747    * aParent (or null for the root).
748    */
749   StyleJustifySelf UsedJustifySelf(const ComputedStyle*) const;
750 
751   /**
752    * Return the used value for 'justify/align-self' in aAxis given our parent
753    * ComputedStyle aParent (or null for the root).
754    * (defined in WritingModes.h since we need the full WritingMode type)
755    */
756   inline mozilla::StyleAlignFlags UsedSelfAlignment(
757       LogicalAxis aAxis, const mozilla::ComputedStyle* aParent) const;
758 
759   /**
760    * Return the used value for 'justify/align-content' in aAxis.
761    * (defined in WritingModes.h since we need the full WritingMode type)
762    */
763   inline mozilla::StyleContentDistribution UsedContentAlignment(
764       LogicalAxis aAxis) const;
765 
766   /**
767    * Return the used value for 'align-tracks'/'justify-tracks' for a track
768    * in the given axis.
769    * (defined in WritingModes.h since we need the full LogicalAxis type)
770    */
771   inline mozilla::StyleContentDistribution UsedTracksAlignment(
772       LogicalAxis aAxis, uint32_t aIndex) const;
773 
774   // Each entry has the same encoding as *-content, see below.
775   mozilla::StyleAlignTracks mAlignTracks;
776   mozilla::StyleJustifyTracks mJustifyTracks;
777 
778   Position mObjectPosition;
779   StyleRect<LengthPercentageOrAuto> mOffset;
780   StyleSize mWidth;
781   StyleSize mMinWidth;
782   StyleMaxSize mMaxWidth;
783   StyleSize mHeight;
784   StyleSize mMinHeight;
785   StyleMaxSize mMaxHeight;
786   mozilla::StyleFlexBasis mFlexBasis;
787   StyleImplicitGridTracks mGridAutoColumns;
788   StyleImplicitGridTracks mGridAutoRows;
789   mozilla::StyleAspectRatio mAspectRatio;
790   mozilla::StyleGridAutoFlow mGridAutoFlow;
791   uint8_t mMasonryAutoFlow;  // NS_STYLE_MASONRY_*
792 
793   mozilla::StyleAlignContent mAlignContent;
794   mozilla::StyleAlignItems mAlignItems;
795   mozilla::StyleAlignSelf mAlignSelf;
796   mozilla::StyleJustifyContent mJustifyContent;
797   mozilla::StyleComputedJustifyItems mJustifyItems;
798   mozilla::StyleJustifySelf mJustifySelf;
799   mozilla::StyleFlexDirection mFlexDirection;
800   mozilla::StyleFlexWrap mFlexWrap;
801   mozilla::StyleObjectFit mObjectFit;
802   mozilla::StyleBoxSizing mBoxSizing;
803   int32_t mOrder;
804   float mFlexGrow;
805   float mFlexShrink;
806   mozilla::StyleZIndex mZIndex;
807 
808   mozilla::StyleGridTemplateComponent mGridTemplateColumns;
809   mozilla::StyleGridTemplateComponent mGridTemplateRows;
810   mozilla::StyleGridTemplateAreas mGridTemplateAreas;
811 
812   mozilla::StyleGridLine mGridColumnStart;
813   mozilla::StyleGridLine mGridColumnEnd;
814   mozilla::StyleGridLine mGridRowStart;
815   mozilla::StyleGridLine mGridRowEnd;
816   mozilla::NonNegativeLengthPercentageOrNormal mColumnGap;
817   mozilla::NonNegativeLengthPercentageOrNormal mRowGap;
818 
819   // Logical-coordinate accessors for width and height properties,
820   // given a WritingMode value. The definitions of these methods are
821   // found in WritingModes.h (after the WritingMode class is fully
822   // declared).
823   inline const StyleSize& ISize(WritingMode) const;
824   inline const StyleSize& MinISize(WritingMode) const;
825   inline const StyleMaxSize& MaxISize(WritingMode) const;
826   inline const StyleSize& BSize(WritingMode) const;
827   inline const StyleSize& MinBSize(WritingMode) const;
828   inline const StyleMaxSize& MaxBSize(WritingMode) const;
829   inline const StyleSize& Size(LogicalAxis, WritingMode) const;
830   inline const StyleSize& MinSize(LogicalAxis, WritingMode) const;
831   inline const StyleMaxSize& MaxSize(LogicalAxis, WritingMode) const;
832   inline bool ISizeDependsOnContainer(WritingMode) const;
833   inline bool MinISizeDependsOnContainer(WritingMode) const;
834   inline bool MaxISizeDependsOnContainer(WritingMode) const;
835   inline bool BSizeDependsOnContainer(WritingMode) const;
836   inline bool MinBSizeDependsOnContainer(WritingMode) const;
837   inline bool MaxBSizeDependsOnContainer(WritingMode) const;
838 
839  private:
840   template <typename SizeOrMaxSize>
ISizeCoordDependsOnContainernsStylePosition841   static bool ISizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
842     if (aCoord.IsLengthPercentage()) {
843       return aCoord.AsLengthPercentage().HasPercent();
844     }
845     return aCoord.IsFitContent() || aCoord.IsMozAvailable();
846   }
847 
848   template <typename SizeOrMaxSize>
BSizeCoordDependsOnContainernsStylePosition849   static bool BSizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
850     return aCoord.IsLengthPercentage() &&
851            aCoord.AsLengthPercentage().HasPercent();
852   }
853 };
854 
855 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset {
856   explicit nsStyleTextReset(const mozilla::dom::Document&);
857   nsStyleTextReset(const nsStyleTextReset& aOther);
858   ~nsStyleTextReset();
859   static constexpr bool kHasTriggerImageLoads = false;
860 
861   // Note the difference between this and
862   // ComputedStyle::HasTextDecorationLines.
HasTextDecorationLinesnsStyleTextReset863   bool HasTextDecorationLines() const {
864     return mTextDecorationLine != mozilla::StyleTextDecorationLine::NONE &&
865            mTextDecorationLine !=
866                mozilla::StyleTextDecorationLine::COLOR_OVERRIDE;
867   }
868 
869   nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const;
870 
871   mozilla::StyleTextOverflow mTextOverflow;
872 
873   mozilla::StyleTextDecorationLine mTextDecorationLine;
874   uint8_t mTextDecorationStyle;  // NS_STYLE_TEXT_DECORATION_STYLE_*
875   uint8_t mUnicodeBidi;          // NS_STYLE_UNICODE_BIDI_*
876   nscoord mInitialLetterSink;    // 0 means normal
877   float mInitialLetterSize;      // 0.0f means normal
878   mozilla::StyleColor mTextDecorationColor;
879   mozilla::StyleTextDecorationLength mTextDecorationThickness;
880 };
881 
882 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText {
883   explicit nsStyleText(const mozilla::dom::Document&);
884   nsStyleText(const nsStyleText& aOther);
885   ~nsStyleText();
886   static constexpr bool kHasTriggerImageLoads = false;
887 
888   nsChangeHint CalcDifference(const nsStyleText& aNewData) const;
889 
890   mozilla::StyleRGBA mColor;
891   mozilla::StyleTextTransform mTextTransform;
892   mozilla::StyleTextAlign mTextAlign;
893   mozilla::StyleTextAlignLast mTextAlignLast;
894   mozilla::StyleTextJustify mTextJustify;
895   mozilla::StyleWhiteSpace mWhiteSpace;
896   mozilla::StyleLineBreak mLineBreak = mozilla::StyleLineBreak::Auto;
897 
898  private:
899   mozilla::StyleWordBreak mWordBreak = mozilla::StyleWordBreak::Normal;
900   mozilla::StyleOverflowWrap mOverflowWrap = mozilla::StyleOverflowWrap::Normal;
901 
902  public:
903   mozilla::StyleHyphens mHyphens;
904   mozilla::StyleRubyAlign mRubyAlign;
905   mozilla::StyleRubyPosition mRubyPosition;
906   mozilla::StyleTextSizeAdjust mTextSizeAdjust;
907   uint8_t mTextCombineUpright;  // NS_STYLE_TEXT_COMBINE_UPRIGHT_*
908   mozilla::StyleMozControlCharacterVisibility mMozControlCharacterVisibility;
909   uint8_t mTextEmphasisPosition;  // NS_STYLE_TEXT_EMPHASIS_POSITION_*
910   mozilla::StyleTextRendering mTextRendering;
911   mozilla::StyleColor mTextEmphasisColor;
912   mozilla::StyleColor mWebkitTextFillColor;
913   mozilla::StyleColor mWebkitTextStrokeColor;
914 
915   mozilla::StyleNonNegativeLengthOrNumber mTabSize;
916   mozilla::LengthPercentage mWordSpacing;
917   mozilla::StyleLetterSpacing mLetterSpacing;
918   mozilla::StyleLineHeight mLineHeight;
919   mozilla::LengthPercentage mTextIndent;
920 
921   mozilla::LengthPercentageOrAuto mTextUnderlineOffset;
922   mozilla::StyleTextDecorationSkipInk mTextDecorationSkipInk;
923   mozilla::StyleTextUnderlinePosition mTextUnderlinePosition;
924 
925   nscoord mWebkitTextStrokeWidth;  // coord
926 
927   mozilla::StyleArcSlice<mozilla::StyleSimpleShadow> mTextShadow;
928   mozilla::StyleTextEmphasisStyle mTextEmphasisStyle;
929 
930   mozilla::StyleHyphenateCharacter mHyphenateCharacter =
931       mozilla::StyleHyphenateCharacter::Auto();
932 
EffectiveWordBreaknsStyleText933   mozilla::StyleWordBreak EffectiveWordBreak() const {
934     if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
935       return mozilla::StyleWordBreak::Normal;
936     }
937     return mWordBreak;
938   }
939 
EffectiveOverflowWrapnsStyleText940   mozilla::StyleOverflowWrap EffectiveOverflowWrap() const {
941     if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
942       return mozilla::StyleOverflowWrap::Anywhere;
943     }
944     return mOverflowWrap;
945   }
946 
WhiteSpaceIsSignificantnsStyleText947   bool WhiteSpaceIsSignificant() const {
948     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
949            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
950            mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
951            mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
952   }
953 
WhiteSpaceCanHangOrVisuallyCollapsensStyleText954   bool WhiteSpaceCanHangOrVisuallyCollapse() const {
955     // This was originally expressed in nsTextFrame in terms of:
956     //   mWhiteSpace != StyleWhiteSpace::BreakSpaces &&
957     //       WhiteSpaceCanWrapStyle() &&
958     //       WhiteSpaceIsSignificant()
959     // which simplifies to:
960     return mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap;
961   }
962 
NewlineIsSignificantStylensStyleText963   bool NewlineIsSignificantStyle() const {
964     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
965            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
966            mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
967            mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
968   }
969 
WhiteSpaceOrNewlineIsSignificantnsStyleText970   bool WhiteSpaceOrNewlineIsSignificant() const {
971     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
972            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
973            mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
974            mWhiteSpace == mozilla::StyleWhiteSpace::PreLine ||
975            mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
976   }
977 
TabIsSignificantnsStyleText978   bool TabIsSignificant() const {
979     return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
980            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
981            mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces;
982   }
983 
WhiteSpaceCanWrapStylensStyleText984   bool WhiteSpaceCanWrapStyle() const {
985     return mWhiteSpace == mozilla::StyleWhiteSpace::Normal ||
986            mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
987            mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
988            mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
989   }
990 
WordCanWrapStylensStyleText991   bool WordCanWrapStyle() const {
992     if (!WhiteSpaceCanWrapStyle()) {
993       return false;
994     }
995     auto owrap = EffectiveOverflowWrap();
996     return owrap == mozilla::StyleOverflowWrap::BreakWord ||
997            owrap == mozilla::StyleOverflowWrap::Anywhere;
998   }
999 
HasEffectiveTextEmphasisnsStyleText1000   bool HasEffectiveTextEmphasis() const {
1001     if (mTextEmphasisStyle.IsNone()) {
1002       return false;
1003     }
1004     if (mTextEmphasisStyle.IsString() &&
1005         mTextEmphasisStyle.AsString().AsString().IsEmpty()) {
1006       return false;
1007     }
1008     return true;
1009   }
1010 
TextAlignForLastLinensStyleText1011   mozilla::StyleTextAlign TextAlignForLastLine() const {
1012     switch (mTextAlignLast) {
1013       case mozilla::StyleTextAlignLast::Auto:
1014         // 'text-align-last: auto' is equivalent to the value of the
1015         // 'text-align' property except when 'text-align' is set to 'justify',
1016         // in which case it is 'justify' when 'text-justify' is 'distribute' and
1017         // 'start' otherwise.
1018         //
1019         // XXX: the code below will have to change when we implement
1020         // text-justify
1021         if (mTextAlign == mozilla::StyleTextAlign::Justify) {
1022           return mozilla::StyleTextAlign::Start;
1023         }
1024         return mTextAlign;
1025       case mozilla::StyleTextAlignLast::Center:
1026         return mozilla::StyleTextAlign::Center;
1027       case mozilla::StyleTextAlignLast::Start:
1028         return mozilla::StyleTextAlign::Start;
1029       case mozilla::StyleTextAlignLast::End:
1030         return mozilla::StyleTextAlign::End;
1031       case mozilla::StyleTextAlignLast::Left:
1032         return mozilla::StyleTextAlign::Left;
1033       case mozilla::StyleTextAlignLast::Right:
1034         return mozilla::StyleTextAlign::Right;
1035       case mozilla::StyleTextAlignLast::Justify:
1036         return mozilla::StyleTextAlign::Justify;
1037     }
1038     return mozilla::StyleTextAlign::Start;
1039   }
1040 
HasWebkitTextStrokensStyleText1041   bool HasWebkitTextStroke() const { return mWebkitTextStrokeWidth > 0; }
1042 
HasTextShadownsStyleText1043   bool HasTextShadow() const { return !mTextShadow.IsEmpty(); }
1044 
1045   // The aContextFrame argument on each of these is the frame this
1046   // style struct is for.  If the frame is for SVG text or inside ruby,
1047   // the return value will be massaged to be something that makes sense
1048   // for those cases.
1049   inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const;
1050   inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
1051   inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
1052 
1053   mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const;
1054 };
1055 
1056 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility {
1057   explicit nsStyleVisibility(const mozilla::dom::Document&);
1058   nsStyleVisibility(const nsStyleVisibility& aVisibility);
1059   MOZ_COUNTED_DTOR(nsStyleVisibility)
1060   static constexpr bool kHasTriggerImageLoads = false;
1061 
1062   nsChangeHint CalcDifference(const nsStyleVisibility& aNewData) const;
1063 
1064   mozilla::StyleImageOrientation mImageOrientation;
1065   mozilla::StyleDirection mDirection;
1066   mozilla::StyleVisibility mVisible;
1067   mozilla::StyleImageRendering mImageRendering;
1068   mozilla::StyleWritingModeProperty mWritingMode;
1069   mozilla::StyleTextOrientation mTextOrientation;
1070   mozilla::StylePrintColorAdjust mPrintColorAdjust;
1071 
IsVisiblensStyleVisibility1072   bool IsVisible() const {
1073     return mVisible == mozilla::StyleVisibility::Visible;
1074   }
1075 
IsVisibleOrCollapsednsStyleVisibility1076   bool IsVisibleOrCollapsed() const {
1077     return mVisible == mozilla::StyleVisibility::Visible ||
1078            mVisible == mozilla::StyleVisibility::Collapse;
1079   }
1080 };
1081 
1082 namespace mozilla {
1083 
None()1084 inline StyleTextTransform StyleTextTransform::None() {
1085   return StyleTextTransform{StyleTextTransformCase::None,
1086                             StyleTextTransformOther()};
1087 }
1088 
IsNone()1089 inline bool StyleTextTransform::IsNone() const { return *this == None(); }
1090 
1091 // Note that IsAuto() does not exclude the possibility that `left` or `right`
1092 // is set; it refers only to behavior in horizontal typographic mode.
IsAuto()1093 inline bool StyleTextUnderlinePosition::IsAuto() const {
1094   return !(*this & (StyleTextUnderlinePosition::FROM_FONT |
1095                     StyleTextUnderlinePosition::UNDER));
1096 }
IsFromFont()1097 inline bool StyleTextUnderlinePosition::IsFromFont() const {
1098   return bool(*this & StyleTextUnderlinePosition::FROM_FONT);
1099 }
IsUnder()1100 inline bool StyleTextUnderlinePosition::IsUnder() const {
1101   return bool(*this & StyleTextUnderlinePosition::UNDER);
1102 }
IsLeft()1103 inline bool StyleTextUnderlinePosition::IsLeft() const {
1104   return bool(*this & StyleTextUnderlinePosition::LEFT);
1105 }
IsRight()1106 inline bool StyleTextUnderlinePosition::IsRight() const {
1107   return bool(*this & StyleTextUnderlinePosition::RIGHT);
1108 }
1109 
1110 struct StyleTransition {
StyleTransitionStyleTransition1111   StyleTransition() { /* leaves uninitialized; see also SetInitialValues */
1112   }
1113   explicit StyleTransition(const StyleTransition& aCopy);
1114 
1115   void SetInitialValues();
1116 
1117   // Delay and Duration are in milliseconds
1118 
GetTimingFunctionStyleTransition1119   const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
GetDelayStyleTransition1120   float GetDelay() const { return mDelay; }
GetDurationStyleTransition1121   float GetDuration() const { return mDuration; }
GetPropertyStyleTransition1122   nsCSSPropertyID GetProperty() const { return mProperty; }
GetUnknownPropertyStyleTransition1123   nsAtom* GetUnknownProperty() const { return mUnknownProperty; }
1124 
1125   bool operator==(const StyleTransition& aOther) const;
1126   bool operator!=(const StyleTransition& aOther) const {
1127     return !(*this == aOther);
1128   }
1129 
1130  private:
1131   nsTimingFunction mTimingFunction;
1132   float mDuration;
1133   float mDelay;
1134   nsCSSPropertyID mProperty;
1135   RefPtr<nsAtom> mUnknownProperty;  // used when mProperty is
1136                                     // eCSSProperty_UNKNOWN or
1137                                     // eCSSPropertyExtra_variable
1138 };
1139 
1140 struct StyleAnimation {
StyleAnimationStyleAnimation1141   StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */
1142   }
1143   explicit StyleAnimation(const StyleAnimation& aCopy);
1144 
1145   void SetInitialValues();
1146 
1147   // Delay and Duration are in milliseconds
1148 
GetTimingFunctionStyleAnimation1149   const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
GetDelayStyleAnimation1150   float GetDelay() const { return mDelay; }
GetDurationStyleAnimation1151   float GetDuration() const { return mDuration; }
GetNameStyleAnimation1152   nsAtom* GetName() const { return mName; }
GetDirectionStyleAnimation1153   dom::PlaybackDirection GetDirection() const { return mDirection; }
GetFillModeStyleAnimation1154   dom::FillMode GetFillMode() const { return mFillMode; }
GetPlayStateStyleAnimation1155   StyleAnimationPlayState GetPlayState() const { return mPlayState; }
GetIterationCountStyleAnimation1156   float GetIterationCount() const { return mIterationCount; }
GetTimelineStyleAnimation1157   const StyleAnimationTimeline& GetTimeline() const { return mTimeline; }
1158 
SetNameStyleAnimation1159   void SetName(already_AddRefed<nsAtom> aName) { mName = aName; }
SetNameStyleAnimation1160   void SetName(nsAtom* aName) { mName = aName; }
1161 
1162   bool operator==(const StyleAnimation& aOther) const;
1163   bool operator!=(const StyleAnimation& aOther) const {
1164     return !(*this == aOther);
1165   }
1166 
1167  private:
1168   nsTimingFunction mTimingFunction;
1169   float mDuration;
1170   float mDelay;
1171   RefPtr<nsAtom> mName;  // nsGkAtoms::_empty for 'none'
1172   dom::PlaybackDirection mDirection;
1173   dom::FillMode mFillMode;
1174   StyleAnimationPlayState mPlayState;
1175   float mIterationCount;  // mozilla::PositiveInfinity<float>() means infinite
1176   StyleAnimationTimeline mTimeline;
1177 };
1178 
1179 }  // namespace mozilla
1180 
1181 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
1182   typedef mozilla::StyleGeometryBox StyleGeometryBox;
1183 
1184   explicit nsStyleDisplay(const mozilla::dom::Document&);
1185   nsStyleDisplay(const nsStyleDisplay& aOther);
1186   ~nsStyleDisplay();
1187 
1188   void TriggerImageLoads(mozilla::dom::Document&, const nsStyleDisplay*);
1189   static constexpr bool kHasTriggerImageLoads = true;
1190 
1191   nsChangeHint CalcDifference(const nsStyleDisplay& aNewData,
1192                               const nsStylePosition& aOldPosition) const;
1193 
1194   nsChangeHint CalcTransformPropertyDifference(
1195       const nsStyleDisplay& aNewData) const;
1196 
1197   nsStyleAutoArray<mozilla::StyleTransition> mTransitions;
1198   // The number of elements in mTransitions that are not from repeating
1199   // a list due to another property being longer.
1200   uint32_t mTransitionTimingFunctionCount;
1201   uint32_t mTransitionDurationCount;
1202   uint32_t mTransitionDelayCount;
1203   uint32_t mTransitionPropertyCount;
1204   nsStyleAutoArray<mozilla::StyleAnimation> mAnimations;
1205   // The number of elements in mAnimations that are not from repeating
1206   // a list due to another property being longer.
1207   uint32_t mAnimationTimingFunctionCount;
1208   uint32_t mAnimationDurationCount;
1209   uint32_t mAnimationDelayCount;
1210   uint32_t mAnimationNameCount;
1211   uint32_t mAnimationDirectionCount;
1212   uint32_t mAnimationFillModeCount;
1213   uint32_t mAnimationPlayStateCount;
1214   uint32_t mAnimationIterationCountCount;
1215   uint32_t mAnimationTimelineCount;
1216 
1217   mozilla::StyleWillChange mWillChange;
1218   mozilla::StyleDisplay mDisplay;
1219   mozilla::StyleDisplay mOriginalDisplay;  // saved mDisplay for
1220                                            //         position:absolute/fixed
1221                                            //         and float:left/right;
1222                                            //         otherwise equal to
1223                                            //         mDisplay
1224   mozilla::StyleContain mContain;
1225 
1226  private:
1227   mozilla::StyleAppearance mAppearance;
1228 
1229  public:
1230   mozilla::StyleAppearance mDefaultAppearance;
1231   mozilla::StylePositionProperty mPosition;
1232 
1233   mozilla::StyleFloat mFloat;
1234   mozilla::StyleClear mBreakType;
1235   mozilla::StyleBreakWithin mBreakInside;
1236   mozilla::StyleBreakBetween mBreakBefore;
1237   mozilla::StyleBreakBetween mBreakAfter;
1238   mozilla::StyleOverflow mOverflowX;
1239   mozilla::StyleOverflow mOverflowY;
1240   mozilla::StyleOverflowClipBox mOverflowClipBoxBlock;
1241   mozilla::StyleOverflowClipBox mOverflowClipBoxInline;
1242   mozilla::StyleScrollbarGutter mScrollbarGutter;
1243   mozilla::StyleResize mResize;
1244   mozilla::StyleOrient mOrient;
1245   mozilla::StyleIsolation mIsolation;
1246   mozilla::StyleTopLayer mTopLayer;
1247 
1248   mozilla::StyleTouchAction mTouchAction;
1249   mozilla::StyleScrollBehavior mScrollBehavior;
1250   mozilla::StyleOverscrollBehavior mOverscrollBehaviorX;
1251   mozilla::StyleOverscrollBehavior mOverscrollBehaviorY;
1252   mozilla::StyleOverflowAnchor mOverflowAnchor;
1253   mozilla::StyleScrollSnapAlign mScrollSnapAlign;
1254   mozilla::StyleScrollSnapType mScrollSnapType;
1255   uint32_t mLineClamp;
1256 
1257   mozilla::StyleTransform mTransform;
1258   mozilla::StyleRotate mRotate;
1259   mozilla::StyleTranslate mTranslate;
1260   mozilla::StyleScale mScale;
1261 
1262   mozilla::StyleBackfaceVisibility mBackfaceVisibility;
1263   mozilla::StyleTransformStyle mTransformStyle;
1264   StyleGeometryBox mTransformBox;
1265 
1266   mozilla::StyleOffsetPath mOffsetPath;
1267   mozilla::LengthPercentage mOffsetDistance;
1268   mozilla::StyleOffsetRotate mOffsetRotate;
1269   mozilla::StylePositionOrAuto mOffsetAnchor;
1270 
1271   mozilla::StyleTransformOrigin mTransformOrigin;
1272   mozilla::StylePerspective mChildPerspective;
1273   mozilla::Position mPerspectiveOrigin;
1274 
1275   mozilla::StyleVerticalAlign mVerticalAlign;
1276 
GetTransitionPropertynsStyleDisplay1277   nsCSSPropertyID GetTransitionProperty(uint32_t aIndex) const {
1278     return mTransitions[aIndex % mTransitionPropertyCount].GetProperty();
1279   }
GetTransitionDelaynsStyleDisplay1280   float GetTransitionDelay(uint32_t aIndex) const {
1281     return mTransitions[aIndex % mTransitionDelayCount].GetDelay();
1282   }
GetTransitionDurationnsStyleDisplay1283   float GetTransitionDuration(uint32_t aIndex) const {
1284     return mTransitions[aIndex % mTransitionDurationCount].GetDuration();
1285   }
GetTransitionTimingFunctionnsStyleDisplay1286   const nsTimingFunction& GetTransitionTimingFunction(uint32_t aIndex) const {
1287     return mTransitions[aIndex % mTransitionTimingFunctionCount]
1288         .GetTimingFunction();
1289   }
GetTransitionCombinedDurationnsStyleDisplay1290   float GetTransitionCombinedDuration(uint32_t aIndex) const {
1291     // https://drafts.csswg.org/css-transitions/#transition-combined-duration
1292     return std::max(
1293                mTransitions[aIndex % mTransitionDurationCount].GetDuration(),
1294                0.0f) +
1295            mTransitions[aIndex % mTransitionDelayCount].GetDelay();
1296   }
1297 
GetAnimationNamensStyleDisplay1298   nsAtom* GetAnimationName(uint32_t aIndex) const {
1299     return mAnimations[aIndex % mAnimationNameCount].GetName();
1300   }
GetAnimationDelaynsStyleDisplay1301   float GetAnimationDelay(uint32_t aIndex) const {
1302     return mAnimations[aIndex % mAnimationDelayCount].GetDelay();
1303   }
GetAnimationDurationnsStyleDisplay1304   float GetAnimationDuration(uint32_t aIndex) const {
1305     return mAnimations[aIndex % mAnimationDurationCount].GetDuration();
1306   }
GetAnimationDirectionnsStyleDisplay1307   mozilla::dom::PlaybackDirection GetAnimationDirection(uint32_t aIndex) const {
1308     return mAnimations[aIndex % mAnimationDirectionCount].GetDirection();
1309   }
GetAnimationFillModensStyleDisplay1310   mozilla::dom::FillMode GetAnimationFillMode(uint32_t aIndex) const {
1311     return mAnimations[aIndex % mAnimationFillModeCount].GetFillMode();
1312   }
GetAnimationPlayStatensStyleDisplay1313   mozilla::StyleAnimationPlayState GetAnimationPlayState(
1314       uint32_t aIndex) const {
1315     return mAnimations[aIndex % mAnimationPlayStateCount].GetPlayState();
1316   }
GetAnimationIterationCountnsStyleDisplay1317   float GetAnimationIterationCount(uint32_t aIndex) const {
1318     return mAnimations[aIndex % mAnimationIterationCountCount]
1319         .GetIterationCount();
1320   }
GetAnimationTimingFunctionnsStyleDisplay1321   const nsTimingFunction& GetAnimationTimingFunction(uint32_t aIndex) const {
1322     return mAnimations[aIndex % mAnimationTimingFunctionCount]
1323         .GetTimingFunction();
1324   }
GetTimelinensStyleDisplay1325   const mozilla::StyleAnimationTimeline& GetTimeline(uint32_t aIndex) const {
1326     return mAnimations[aIndex % mAnimationTimelineCount].GetTimeline();
1327   }
1328 
1329   // The threshold used for extracting a shape from shape-outside: <image>.
1330   float mShapeImageThreshold = 0.0f;
1331 
1332   // The margin around a shape-outside: <image>.
1333   mozilla::NonNegativeLengthPercentage mShapeMargin;
1334 
1335   mozilla::StyleShapeOutside mShapeOutside;
1336 
HasAppearancensStyleDisplay1337   bool HasAppearance() const {
1338     return EffectiveAppearance() != mozilla::StyleAppearance::None;
1339   }
1340 
EffectiveAppearancensStyleDisplay1341   mozilla::StyleAppearance EffectiveAppearance() const {
1342     switch (mAppearance) {
1343       case mozilla::StyleAppearance::Auto:
1344       case mozilla::StyleAppearance::Button:
1345       case mozilla::StyleAppearance::Searchfield:
1346       case mozilla::StyleAppearance::Textarea:
1347       case mozilla::StyleAppearance::Checkbox:
1348       case mozilla::StyleAppearance::Radio:
1349       case mozilla::StyleAppearance::Menulist:
1350       case mozilla::StyleAppearance::Listbox:
1351       case mozilla::StyleAppearance::Meter:
1352       case mozilla::StyleAppearance::ProgressBar:
1353         // These are all the values that behave like `auto`.
1354         return mDefaultAppearance;
1355       case mozilla::StyleAppearance::Textfield:
1356         // `appearance: textfield` should behave like `auto` on all elements
1357         // except <input type=search> elements, which we identify using the
1358         // internal -moz-default-appearance property.  (In the browser chrome
1359         // we have some other elements that set `-moz-default-appearance:
1360         // searchfield`, but not in content documents.)
1361         if (mDefaultAppearance == mozilla::StyleAppearance::Searchfield) {
1362           return mAppearance;
1363         }
1364         // We also need to support `appearance: textfield` on <input
1365         // type=number>, since that is the only way in Gecko to disable the
1366         // spinners.
1367         if (mDefaultAppearance == mozilla::StyleAppearance::NumberInput) {
1368           return mAppearance;
1369         }
1370         return mDefaultAppearance;
1371       case mozilla::StyleAppearance::MenulistButton:
1372         // `appearance: menulist-button` should behave like `auto` on all
1373         // elements except for drop down selects, but since we have very little
1374         // difference between menulist and menulist-button handling, we don't
1375         // bother.
1376         return mDefaultAppearance;
1377       default:
1378         return mAppearance;
1379     }
1380   }
1381 
DisplayOutsidensStyleDisplay1382   static mozilla::StyleDisplayOutside DisplayOutside(
1383       mozilla::StyleDisplay aDisplay) {
1384     return mozilla::StyleDisplayOutside(
1385         (uint16_t(aDisplay) >> mozilla::STYLE_DISPLAY_INSIDE_BITS) &
1386         uint16_t(((1 << mozilla::STYLE_DISPLAY_OUTSIDE_BITS) - 1)));
1387   }
DisplayOutsidensStyleDisplay1388   mozilla::StyleDisplayOutside DisplayOutside() const {
1389     return DisplayOutside(mDisplay);
1390   }
1391 
DisplayInsidensStyleDisplay1392   static mozilla::StyleDisplayInside DisplayInside(
1393       mozilla::StyleDisplay aDisplay) {
1394     return mozilla::StyleDisplayInside(
1395         uint16_t(aDisplay) &
1396         uint16_t(((1 << mozilla::STYLE_DISPLAY_INSIDE_BITS) - 1)));
1397   }
DisplayInsidensStyleDisplay1398   mozilla::StyleDisplayInside DisplayInside() const {
1399     return DisplayInside(mDisplay);
1400   }
1401 
IsListItemnsStyleDisplay1402   static bool IsListItem(mozilla::StyleDisplay aDisplay) {
1403     return !!(uint16_t(aDisplay) & mozilla::STYLE_DISPLAY_LIST_ITEM_BIT);
1404   }
IsListItemnsStyleDisplay1405   bool IsListItem() const { return IsListItem(mDisplay); }
1406 
1407   // Whether display is `inline` or `inline list-item`.
IsInlineFlownsStyleDisplay1408   static bool IsInlineFlow(mozilla::StyleDisplay aDisplay) {
1409     return DisplayOutside(aDisplay) == mozilla::StyleDisplayOutside::Inline &&
1410            DisplayInside(aDisplay) == mozilla::StyleDisplayInside::Flow;
1411   }
1412 
IsInlineFlownsStyleDisplay1413   bool IsInlineFlow() const { return IsInlineFlow(mDisplay); }
1414 
IsInlineInsideStylensStyleDisplay1415   bool IsInlineInsideStyle() const {
1416     auto inside = DisplayInside();
1417     return IsInlineFlow() || inside == mozilla::StyleDisplayInside::Ruby ||
1418            inside == mozilla::StyleDisplayInside::RubyBase ||
1419            inside == mozilla::StyleDisplayInside::RubyBaseContainer ||
1420            inside == mozilla::StyleDisplayInside::RubyText ||
1421            inside == mozilla::StyleDisplayInside::RubyTextContainer;
1422   }
1423 
IsBlockOutsideStylensStyleDisplay1424   bool IsBlockOutsideStyle() const {
1425     return DisplayOutside() == mozilla::StyleDisplayOutside::Block;
1426   }
1427 
IsDisplayTypeInlineOutsidensStyleDisplay1428   static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) {
1429     auto outside = DisplayOutside(aDisplay);
1430     if (outside == mozilla::StyleDisplayOutside::Inline) {
1431       return true;
1432     }
1433     // just an optimization for the common case:
1434     if (outside == mozilla::StyleDisplayOutside::Block) {
1435       return false;
1436     }
1437     return mozilla::StyleDisplay::MozInlineBox == aDisplay ||
1438            mozilla::StyleDisplay::RubyBase == aDisplay ||
1439            mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
1440            mozilla::StyleDisplay::RubyText == aDisplay ||
1441            mozilla::StyleDisplay::RubyTextContainer == aDisplay;
1442   }
1443 
IsInlineOutsideStylensStyleDisplay1444   bool IsInlineOutsideStyle() const {
1445     return IsDisplayTypeInlineOutside(mDisplay);
1446   }
1447 
IsOriginalDisplayInlineOutsidensStyleDisplay1448   bool IsOriginalDisplayInlineOutside() const {
1449     return IsDisplayTypeInlineOutside(mOriginalDisplay);
1450   }
1451 
IsInnerTableStylensStyleDisplay1452   bool IsInnerTableStyle() const {
1453     return DisplayOutside() == mozilla::StyleDisplayOutside::InternalTable;
1454   }
1455 
IsInternalTableStyleExceptCellnsStyleDisplay1456   bool IsInternalTableStyleExceptCell() const {
1457     return IsInnerTableStyle() && mozilla::StyleDisplay::TableCell != mDisplay;
1458   }
1459 
IsXULDisplayStylensStyleDisplay1460   bool IsXULDisplayStyle() const {
1461     // -moz-{inline-}box is XUL, unless we're emulating it with flexbox.
1462     if (!mozilla::StaticPrefs::layout_css_emulate_moz_box_with_flex() &&
1463         DisplayInside() == mozilla::StyleDisplayInside::MozBox) {
1464       return true;
1465     }
1466 
1467     return DisplayOutside() == mozilla::StyleDisplayOutside::XUL;
1468   }
1469 
IsFloatingStylensStyleDisplay1470   bool IsFloatingStyle() const { return mozilla::StyleFloat::None != mFloat; }
1471 
IsPositionedStylensStyleDisplay1472   bool IsPositionedStyle() const {
1473     return mPosition != mozilla::StylePositionProperty::Static ||
1474            (mWillChange.bits & mozilla::StyleWillChangeBits::POSITION);
1475   }
1476 
IsAbsolutelyPositionedStylensStyleDisplay1477   bool IsAbsolutelyPositionedStyle() const {
1478     return mozilla::StylePositionProperty::Absolute == mPosition ||
1479            mozilla::StylePositionProperty::Fixed == mPosition;
1480   }
1481 
IsRelativelyOrStickyPositionedStylensStyleDisplay1482   bool IsRelativelyOrStickyPositionedStyle() const {
1483     return mozilla::StylePositionProperty::Relative == mPosition ||
1484            mozilla::StylePositionProperty::Sticky == mPosition;
1485   }
IsRelativelyPositionedStylensStyleDisplay1486   bool IsRelativelyPositionedStyle() const {
1487     return mozilla::StylePositionProperty::Relative == mPosition;
1488   }
IsStickyPositionedStylensStyleDisplay1489   bool IsStickyPositionedStyle() const {
1490     return mozilla::StylePositionProperty::Sticky == mPosition;
1491   }
IsPositionForcingStackingContextnsStyleDisplay1492   bool IsPositionForcingStackingContext() const {
1493     return mozilla::StylePositionProperty::Sticky == mPosition ||
1494            mozilla::StylePositionProperty::Fixed == mPosition;
1495   }
1496 
IsRubyDisplayTypensStyleDisplay1497   static bool IsRubyDisplayType(mozilla::StyleDisplay aDisplay) {
1498     return DisplayInside(aDisplay) == mozilla::StyleDisplayInside::Ruby ||
1499            IsInternalRubyDisplayType(aDisplay);
1500   }
1501 
IsInternalRubyDisplayTypensStyleDisplay1502   static bool IsInternalRubyDisplayType(mozilla::StyleDisplay aDisplay) {
1503     return mozilla::StyleDisplay::RubyBase == aDisplay ||
1504            mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
1505            mozilla::StyleDisplay::RubyText == aDisplay ||
1506            mozilla::StyleDisplay::RubyTextContainer == aDisplay;
1507   }
1508 
IsRubyDisplayTypensStyleDisplay1509   bool IsRubyDisplayType() const { return IsRubyDisplayType(mDisplay); }
1510 
IsInternalRubyDisplayTypensStyleDisplay1511   bool IsInternalRubyDisplayType() const {
1512     return IsInternalRubyDisplayType(mDisplay);
1513   }
1514 
IsOutOfFlowStylensStyleDisplay1515   bool IsOutOfFlowStyle() const {
1516     return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());
1517   }
1518 
IsScrollableOverflownsStyleDisplay1519   bool IsScrollableOverflow() const {
1520     // Visible and Clip can be combined but not with other values,
1521     // so checking mOverflowX is enough.
1522     return mOverflowX != mozilla::StyleOverflow::Visible &&
1523            mOverflowX != mozilla::StyleOverflow::Clip;
1524   }
1525 
OverflowIsVisibleInBothAxisnsStyleDisplay1526   bool OverflowIsVisibleInBothAxis() const {
1527     return mOverflowX == mozilla::StyleOverflow::Visible &&
1528            mOverflowY == mozilla::StyleOverflow::Visible;
1529   }
1530 
IsContainPaintnsStyleDisplay1531   bool IsContainPaint() const {
1532     return (mContain & mozilla::StyleContain::PAINT) &&
1533            !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
1534   }
1535 
IsContainLayoutnsStyleDisplay1536   bool IsContainLayout() const {
1537     // Note: The spec for layout containment says it should
1538     // have no effect on non-atomic, inline-level boxes. We
1539     // don't check for these here because we don't know
1540     // what type of element is involved. Callers are
1541     // responsible for checking if the box in question is
1542     // non-atomic and inline-level, and creating an
1543     // exemption as necessary.
1544     return (mContain & mozilla::StyleContain::LAYOUT) &&
1545            !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
1546   }
1547 
IsContainSizensStyleDisplay1548   bool IsContainSize() const {
1549     // Note: The spec for size containment says it should
1550     // have no effect on non-atomic, inline-level boxes. We
1551     // don't check for these here because we don't know
1552     // what type of element is involved. Callers are
1553     // responsible for checking if the box in question is
1554     // non-atomic and inline-level, and creating an
1555     // exemption as necessary.
1556     return (mContain & mozilla::StyleContain::SIZE) &&
1557            !IsInternalRubyDisplayType() &&
1558            DisplayInside() != mozilla::StyleDisplayInside::Table &&
1559            !IsInnerTableStyle();
1560   }
1561 
1562   /* Returns whether the element has the transform property or a related
1563    * property. */
HasTransformStylensStyleDisplay1564   bool HasTransformStyle() const {
1565     return HasTransformProperty() || HasIndividualTransform() ||
1566            mTransformStyle == mozilla::StyleTransformStyle::Preserve3d ||
1567            (mWillChange.bits & mozilla::StyleWillChangeBits::TRANSFORM) ||
1568            !mOffsetPath.IsNone();
1569   }
1570 
HasTransformPropertynsStyleDisplay1571   bool HasTransformProperty() const { return !mTransform._0.IsEmpty(); }
1572 
HasIndividualTransformnsStyleDisplay1573   bool HasIndividualTransform() const {
1574     return !mRotate.IsNone() || !mTranslate.IsNone() || !mScale.IsNone();
1575   }
1576 
HasPerspectiveStylensStyleDisplay1577   bool HasPerspectiveStyle() const { return !mChildPerspective.IsNone(); }
1578 
BackfaceIsHiddennsStyleDisplay1579   bool BackfaceIsHidden() const {
1580     return mBackfaceVisibility == mozilla::StyleBackfaceVisibility::Hidden;
1581   }
1582 
1583   // FIXME(emilio): This should be more fine-grained on each caller to
1584   // BreakBefore() / BreakAfter().
ShouldBreaknsStyleDisplay1585   static bool ShouldBreak(mozilla::StyleBreakBetween aBreak) {
1586     switch (aBreak) {
1587       case mozilla::StyleBreakBetween::Left:
1588       case mozilla::StyleBreakBetween::Right:
1589       case mozilla::StyleBreakBetween::Page:
1590       case mozilla::StyleBreakBetween::Always:
1591         return true;
1592       case mozilla::StyleBreakBetween::Auto:
1593       case mozilla::StyleBreakBetween::Avoid:
1594         return false;
1595       default:
1596         MOZ_ASSERT_UNREACHABLE("Unknown break kind");
1597         return false;
1598     }
1599   }
1600 
BreakBeforensStyleDisplay1601   bool BreakBefore() const { return ShouldBreak(mBreakBefore); }
1602 
BreakAfternsStyleDisplay1603   bool BreakAfter() const { return ShouldBreak(mBreakAfter); }
1604 
1605   // These are defined in nsStyleStructInlines.h.
1606 
1607   // The aContextFrame argument on each of these is the frame this
1608   // style struct is for.  If the frame is for SVG text, the return
1609   // value will be massaged to be something that makes sense for
1610   // SVG text.
1611   inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
1612   inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
1613   inline mozilla::StyleDisplay GetDisplay(const nsIFrame* aContextFrame) const;
1614   inline bool IsFloating(const nsIFrame* aContextFrame) const;
1615   inline bool IsRelativelyOrStickyPositioned(
1616       const nsIFrame* aContextFrame) const;
1617 
1618   // Note: In general, you'd want to call IsRelativelyOrStickyPositioned()
1619   // unless you want to deal with "position:relative" and "position:sticky"
1620   // differently.
1621   inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
1622   inline bool IsStickyPositioned(const nsIFrame* aContextFrame) const;
1623 
1624   inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
1625 
1626   // These methods are defined in nsStyleStructInlines.h.
1627 
1628   /**
1629    * Returns true when the element has the transform property
1630    * or a related property, and supports CSS transforms.
1631    * aContextFrame is the frame for which this is the nsStyleDisplay.
1632    */
1633   inline bool HasTransform(const nsIFrame* aContextFrame) const;
1634 
1635   /**
1636    * Returns true when the element has the perspective property,
1637    * and supports CSS transforms. aContextFrame is the frame for
1638    * which this is the nsStyleDisplay.
1639    */
1640   inline bool HasPerspective(const nsIFrame* aContextFrame) const;
1641 
1642   /**
1643    * Returns whether the element is a containing block for its
1644    * absolutely positioned descendants.
1645    * aContextFrame is the frame for which this is the nsStyleDisplay.
1646    */
1647   inline bool IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const;
1648 
1649   /**
1650    * Returns true when the element is a containing block for its fixed-pos
1651    * descendants.
1652    * aContextFrame is the frame for which this is the nsStyleDisplay.
1653    */
1654   inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const;
1655 
1656   /**
1657    * Tests for only the sub-parts of IsFixedPosContainingBlock that apply
1658    * to:
1659    *  - nearly all frames, except those that are SVG text frames.
1660    *  - frames that support CSS contain:layout and contain:paint and are not
1661    *    SVG text frames.
1662    *  - frames that support CSS transforms and are not SVG text frames.
1663    *
1664    * This should be used only when the caller has the style but not the
1665    * frame (i.e., when calculating style changes).
1666    */
1667   inline bool IsFixedPosContainingBlockForNonSVGTextFrames(
1668       const mozilla::ComputedStyle&) const;
1669   inline bool
1670   IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() const;
1671   inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const;
1672 
1673   void GenerateCombinedIndividualTransform();
1674 };
1675 
1676 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable {
1677   explicit nsStyleTable(const mozilla::dom::Document&);
1678   nsStyleTable(const nsStyleTable& aOther);
1679   ~nsStyleTable();
1680   static constexpr bool kHasTriggerImageLoads = false;
1681 
1682   nsChangeHint CalcDifference(const nsStyleTable& aNewData) const;
1683 
1684   mozilla::StyleTableLayout mLayoutStrategy;
1685   int32_t mXSpan;  // The number of columns spanned by a colgroup or col
1686 };
1687 
1688 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder {
1689   explicit nsStyleTableBorder(const mozilla::dom::Document&);
1690   nsStyleTableBorder(const nsStyleTableBorder& aOther);
1691   ~nsStyleTableBorder();
1692   static constexpr bool kHasTriggerImageLoads = false;
1693 
1694   nsChangeHint CalcDifference(const nsStyleTableBorder& aNewData) const;
1695 
1696   nscoord mBorderSpacingCol;
1697   nscoord mBorderSpacingRow;
1698   mozilla::StyleBorderCollapse mBorderCollapse;
1699   mozilla::StyleCaptionSide mCaptionSide;
1700   mozilla::StyleEmptyCells mEmptyCells;
1701 };
1702 
1703 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent {
1704   using CounterPair = mozilla::StyleGenericCounterPair<int32_t>;
1705 
1706   explicit nsStyleContent(const mozilla::dom::Document&);
1707   nsStyleContent(const nsStyleContent& aContent);
1708   ~nsStyleContent();
1709 
1710   void TriggerImageLoads(mozilla::dom::Document&, const nsStyleContent*);
1711   static constexpr bool kHasTriggerImageLoads = true;
1712 
ContentCountnsStyleContent1713   size_t ContentCount() const {
1714     return mContent.IsItems() ? mContent.AsItems().Length() : 0;
1715   }
1716 
ContentAtnsStyleContent1717   const mozilla::StyleContentItem& ContentAt(size_t aIndex) const {
1718     return mContent.AsItems().AsSpan()[aIndex];
1719   }
1720 
1721   nsChangeHint CalcDifference(const nsStyleContent& aNewData) const;
1722 
1723   mozilla::StyleContent mContent;
1724   mozilla::StyleCounterIncrement mCounterIncrement;
1725   mozilla::StyleCounterReset mCounterReset;
1726   mozilla::StyleCounterSet mCounterSet;
1727 };
1728 
1729 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
1730   explicit nsStyleUIReset(const mozilla::dom::Document&);
1731   nsStyleUIReset(const nsStyleUIReset& aOther);
1732   ~nsStyleUIReset();
1733   static constexpr bool kHasTriggerImageLoads = false;
1734 
1735   nsChangeHint CalcDifference(const nsStyleUIReset& aNewData) const;
1736 
1737  private:
1738   mozilla::StyleUserSelect mUserSelect;  // Use ComputedStyle::UserSelect()
1739   mozilla::StyleScrollbarWidth mScrollbarWidth;  // Use ScrollbarWidth()
1740 
1741  public:
ComputedUserSelectnsStyleUIReset1742   mozilla::StyleUserSelect ComputedUserSelect() const { return mUserSelect; }
1743 
ScrollbarWidthnsStyleUIReset1744   mozilla::StyleScrollbarWidth ScrollbarWidth() const {
1745     if (MOZ_UNLIKELY(
1746             mozilla::StaticPrefs::layout_css_scrollbar_width_thin_disabled())) {
1747       if (mScrollbarWidth == mozilla::StyleScrollbarWidth::Thin) {
1748         return mozilla::StyleScrollbarWidth::Auto;
1749       }
1750     }
1751     return mScrollbarWidth;
1752   }
1753 
1754   uint8_t mMozForceBrokenImageIcon;  // (0 if not forcing, otherwise forcing)
1755   mozilla::StyleImeMode mIMEMode;
1756   mozilla::StyleWindowDragging mWindowDragging;
1757   mozilla::StyleWindowShadow mWindowShadow;
1758   float mWindowOpacity;
1759   mozilla::StyleTransform mMozWindowTransform;
1760   mozilla::StyleTransformOrigin mWindowTransformOrigin;
1761 };
1762 
1763 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI {
1764   explicit nsStyleUI(const mozilla::dom::Document&);
1765   nsStyleUI(const nsStyleUI& aOther);
1766   ~nsStyleUI();
1767 
1768   void TriggerImageLoads(mozilla::dom::Document&, const nsStyleUI*);
1769   static constexpr bool kHasTriggerImageLoads = true;
1770 
1771   nsChangeHint CalcDifference(const nsStyleUI& aNewData) const;
1772 
1773   mozilla::StyleInert mInert;
1774 
1775  private:
1776   mozilla::StyleUserInput mUserInput;
1777   mozilla::StyleUserModify mUserModify;
1778   mozilla::StyleUserFocus mUserFocus;
1779   mozilla::StylePointerEvents mPointerEvents;
1780   mozilla::StyleCursor mCursor;
1781 
1782  public:
IsInertnsStyleUI1783   bool IsInert() const { return mInert == mozilla::StyleInert::Inert; }
1784 
UserInputnsStyleUI1785   mozilla::StyleUserInput UserInput() const {
1786     return IsInert() ? mozilla::StyleUserInput::None : mUserInput;
1787   }
1788 
UserModifynsStyleUI1789   mozilla::StyleUserModify UserModify() const {
1790     return IsInert() ? mozilla::StyleUserModify::ReadOnly : mUserModify;
1791   }
1792 
UserFocusnsStyleUI1793   mozilla::StyleUserFocus UserFocus() const {
1794     return IsInert() ? mozilla::StyleUserFocus::None : mUserFocus;
1795   }
1796 
1797   // This is likely not the getter you want (you probably want
1798   // ComputedStyle::PointerEvents().
ComputedPointerEventsnsStyleUI1799   mozilla::StylePointerEvents ComputedPointerEvents() const {
1800     return mPointerEvents;
1801   }
1802 
CursornsStyleUI1803   const mozilla::StyleCursor& Cursor() const {
1804     static mozilla::StyleCursor sAuto{{}, mozilla::StyleCursorKind::Auto};
1805     return IsInert() ? sAuto : mCursor;
1806   }
1807 
1808   mozilla::StyleColorOrAuto mAccentColor;
1809   mozilla::StyleCaretColor mCaretColor;
1810   mozilla::StyleScrollbarColor mScrollbarColor;
1811   mozilla::StyleColorScheme mColorScheme;
1812 
HasCustomScrollbarsnsStyleUI1813   bool HasCustomScrollbars() const { return !mScrollbarColor.IsAuto(); }
1814 };
1815 
1816 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL {
1817   explicit nsStyleXUL(const mozilla::dom::Document&);
1818   nsStyleXUL(const nsStyleXUL& aSource);
1819   ~nsStyleXUL();
1820   static constexpr bool kHasTriggerImageLoads = false;
1821 
1822   nsChangeHint CalcDifference(const nsStyleXUL& aNewData) const;
1823 
1824   float mBoxFlex;
1825   int32_t mBoxOrdinal;
1826   mozilla::StyleBoxAlign mBoxAlign;
1827   mozilla::StyleBoxDirection mBoxDirection;
1828   mozilla::StyleBoxOrient mBoxOrient;
1829   mozilla::StyleBoxPack mBoxPack;
1830 };
1831 
1832 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn {
1833   explicit nsStyleColumn(const mozilla::dom::Document&);
1834   nsStyleColumn(const nsStyleColumn& aSource);
1835   ~nsStyleColumn();
1836   static constexpr bool kHasTriggerImageLoads = false;
1837 
1838   nsChangeHint CalcDifference(const nsStyleColumn& aNewData) const;
1839 
1840   // This is the maximum number of columns we can process. It's used in
1841   // nsColumnSetFrame.
1842   static const uint32_t kMaxColumnCount = 1000;
1843 
1844   // This represents the value of column-count: auto.
1845   static const uint32_t kColumnCountAuto = 0;
1846 
1847   uint32_t mColumnCount = kColumnCountAuto;
1848   mozilla::NonNegativeLengthOrAuto mColumnWidth;
1849 
1850   mozilla::StyleColor mColumnRuleColor;
1851   mozilla::StyleBorderStyle mColumnRuleStyle;  // StyleborderStyle::*
1852   mozilla::StyleColumnFill mColumnFill = mozilla::StyleColumnFill::Balance;
1853   mozilla::StyleColumnSpan mColumnSpan = mozilla::StyleColumnSpan::None;
1854 
GetComputedColumnRuleWidthnsStyleColumn1855   nscoord GetComputedColumnRuleWidth() const {
1856     return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
1857   }
1858 
IsColumnContainerStylensStyleColumn1859   bool IsColumnContainerStyle() const {
1860     return mColumnCount != kColumnCountAuto || !mColumnWidth.IsAuto();
1861   }
1862 
IsColumnSpanStylensStyleColumn1863   bool IsColumnSpanStyle() const {
1864     return mColumnSpan == mozilla::StyleColumnSpan::All;
1865   }
1866 
1867  protected:
1868   nscoord mColumnRuleWidth;  // coord
1869   nscoord mTwipsPerPixel;
1870 };
1871 
1872 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG {
1873   explicit nsStyleSVG(const mozilla::dom::Document&);
1874   nsStyleSVG(const nsStyleSVG& aSource);
1875   ~nsStyleSVG();
1876   static constexpr bool kHasTriggerImageLoads = false;
1877 
1878   nsChangeHint CalcDifference(const nsStyleSVG& aNewData) const;
1879 
1880   mozilla::StyleSVGPaint mFill;
1881   mozilla::StyleSVGPaint mStroke;
1882   mozilla::StyleUrlOrNone mMarkerEnd;
1883   mozilla::StyleUrlOrNone mMarkerMid;
1884   mozilla::StyleUrlOrNone mMarkerStart;
1885   mozilla::StyleMozContextProperties mMozContextProperties;
1886 
1887   mozilla::StyleSVGStrokeDashArray mStrokeDasharray;
1888   mozilla::StyleSVGLength mStrokeDashoffset;
1889   mozilla::StyleSVGWidth mStrokeWidth;
1890 
1891   mozilla::StyleSVGOpacity mFillOpacity;
1892   float mStrokeMiterlimit;
1893   mozilla::StyleSVGOpacity mStrokeOpacity;
1894 
1895   mozilla::StyleFillRule mClipRule;
1896   mozilla::StyleColorInterpolation mColorInterpolation;
1897   mozilla::StyleColorInterpolation mColorInterpolationFilters;
1898   mozilla::StyleFillRule mFillRule;
1899   mozilla::StyleSVGPaintOrder mPaintOrder;
1900   mozilla::StyleShapeRendering mShapeRendering;
1901   mozilla::StyleStrokeLinecap mStrokeLinecap;
1902   mozilla::StyleStrokeLinejoin mStrokeLinejoin;
1903   mozilla::StyleDominantBaseline mDominantBaseline;
1904   mozilla::StyleTextAnchor mTextAnchor;
1905 
1906   /// Returns true if style has been set to expose the computed values of
1907   /// certain properties (such as 'fill') to the contents of any linked images.
ExposesContextPropertiesnsStyleSVG1908   bool ExposesContextProperties() const {
1909     return bool(mMozContextProperties.bits);
1910   }
1911 
HasMarkernsStyleSVG1912   bool HasMarker() const {
1913     return mMarkerStart.IsUrl() || mMarkerMid.IsUrl() || mMarkerEnd.IsUrl();
1914   }
1915 
1916   /**
1917    * Returns true if the stroke is not "none" and the stroke-opacity is greater
1918    * than zero (or a context-dependent value).
1919    *
1920    * This ignores stroke-widths as that depends on the context.
1921    */
HasStrokensStyleSVG1922   bool HasStroke() const {
1923     if (mStroke.kind.IsNone()) {
1924       return false;
1925     }
1926     return !mStrokeOpacity.IsOpacity() || mStrokeOpacity.AsOpacity() > 0;
1927   }
1928 
1929   /**
1930    * Returns true if the fill is not "none" and the fill-opacity is greater
1931    * than zero (or a context-dependent value).
1932    */
HasFillnsStyleSVG1933   bool HasFill() const {
1934     if (mFill.kind.IsNone()) {
1935       return false;
1936     }
1937     return !mFillOpacity.IsOpacity() || mFillOpacity.AsOpacity() > 0;
1938   }
1939 };
1940 
1941 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset {
1942   explicit nsStyleSVGReset(const mozilla::dom::Document&);
1943   nsStyleSVGReset(const nsStyleSVGReset& aSource);
1944   ~nsStyleSVGReset();
1945 
1946   // Resolves and tracks the images in mMask.  Only called with a Servo-backed
1947   // style system, where those images must be resolved later than the OMT
1948   // nsStyleSVGReset constructor call.
1949   void TriggerImageLoads(mozilla::dom::Document&, const nsStyleSVGReset*);
1950   static constexpr bool kHasTriggerImageLoads = true;
1951 
1952   nsChangeHint CalcDifference(const nsStyleSVGReset& aNewData) const;
1953 
HasClipPathnsStyleSVGReset1954   bool HasClipPath() const { return !mClipPath.IsNone(); }
1955 
1956   bool HasMask() const;
1957 
HasNonScalingStrokensStyleSVGReset1958   bool HasNonScalingStroke() const {
1959     return mVectorEffect == mozilla::StyleVectorEffect::NonScalingStroke;
1960   }
1961 
1962   // geometry properties
1963   mozilla::LengthPercentage mX;
1964   mozilla::LengthPercentage mY;
1965   mozilla::LengthPercentage mCx;
1966   mozilla::LengthPercentage mCy;
1967   mozilla::NonNegativeLengthPercentageOrAuto mRx;
1968   mozilla::NonNegativeLengthPercentageOrAuto mRy;
1969   mozilla::NonNegativeLengthPercentage mR;
1970 
1971   nsStyleImageLayers mMask;
1972   mozilla::StyleClipPath mClipPath;
1973   mozilla::StyleColor mStopColor;
1974   mozilla::StyleColor mFloodColor;
1975   mozilla::StyleColor mLightingColor;
1976 
1977   float mStopOpacity;
1978   float mFloodOpacity;
1979 
1980   mozilla::StyleVectorEffect mVectorEffect;
1981   mozilla::StyleMaskType mMaskType;
1982 
1983   mozilla::StyleDProperty mD;
1984 };
1985 
1986 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects {
1987   explicit nsStyleEffects(const mozilla::dom::Document&);
1988   nsStyleEffects(const nsStyleEffects& aSource);
1989   ~nsStyleEffects();
1990   static constexpr bool kHasTriggerImageLoads = false;
1991 
1992   nsChangeHint CalcDifference(const nsStyleEffects& aNewData) const;
1993 
HasFiltersnsStyleEffects1994   bool HasFilters() const { return !mFilters.IsEmpty(); }
1995 
HasBackdropFiltersnsStyleEffects1996   bool HasBackdropFilters() const { return !mBackdropFilters.IsEmpty(); }
1997 
HasBoxShadowWithInsetnsStyleEffects1998   bool HasBoxShadowWithInset(bool aInset) const {
1999     for (auto& shadow : mBoxShadow.AsSpan()) {
2000       if (shadow.inset == aInset) {
2001         return true;
2002       }
2003     }
2004     return false;
2005   }
2006 
HasMixBlendModensStyleEffects2007   bool HasMixBlendMode() const {
2008     return mMixBlendMode != mozilla::StyleBlend::Normal;
2009   }
2010 
2011   mozilla::StyleOwnedSlice<mozilla::StyleFilter> mFilters;
2012   mozilla::StyleOwnedSlice<mozilla::StyleBoxShadow> mBoxShadow;
2013   mozilla::StyleOwnedSlice<mozilla::StyleFilter> mBackdropFilters;
2014   mozilla::StyleClipRectOrAuto mClip;  // offsets from UL border edge
2015   float mOpacity;
2016   mozilla::StyleBlend mMixBlendMode;
2017 };
2018 
2019 #define STATIC_ASSERT_TYPE_LAYOUTS_MATCH(T1, T2)           \
2020   static_assert(sizeof(T1) == sizeof(T2),                  \
2021                 "Size mismatch between " #T1 " and " #T2); \
2022   static_assert(alignof(T1) == alignof(T2),                \
2023                 "Align mismatch between " #T1 " and " #T2);
2024 
2025 #define STATIC_ASSERT_FIELD_OFFSET_MATCHES(T1, T2, field)          \
2026   static_assert(offsetof(T1, field) == offsetof(T2, field),        \
2027                 "Field offset mismatch of " #field " between " #T1 \
2028                 " and " #T2);
2029 
2030 /**
2031  * These *_Simple types are used to map Gecko types to layout-equivalent but
2032  * simpler Rust types, to aid Rust binding generation.
2033  *
2034  * If something in this types or the assertions below needs to change, ask
2035  * bholley, heycam or emilio before!
2036  *
2037  * <div rustbindgen="true" replaces="nsPoint">
2038  */
2039 struct nsPoint_Simple {
2040   nscoord x, y;
2041 };
2042 
2043 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple);
2044 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x);
2045 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y);
2046 
2047 /**
2048  * <div rustbindgen="true" replaces="nsMargin">
2049  */
2050 struct nsMargin_Simple {
2051   nscoord top, right, bottom, left;
2052 };
2053 
2054 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple);
2055 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top);
2056 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right);
2057 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom);
2058 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left);
2059 
2060 /**
2061  * <div rustbindgen="true" replaces="nsRect">
2062  */
2063 struct nsRect_Simple {
2064   nscoord x, y, width, height;
2065 };
2066 
2067 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple);
2068 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x);
2069 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y);
2070 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width);
2071 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height);
2072 
2073 /**
2074  * <div rustbindgen="true" replaces="nsSize">
2075  */
2076 struct nsSize_Simple {
2077   nscoord width, height;
2078 };
2079 
2080 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple);
2081 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width);
2082 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height);
2083 
2084 /**
2085  * <div rustbindgen="true" replaces="mozilla::UniquePtr">
2086  *
2087  * TODO(Emilio): This is a workaround and we should be able to get rid of this
2088  * one.
2089  */
2090 template <typename T>
2091 struct UniquePtr_Simple {
2092   T* mPtr;
2093 };
2094 
2095 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(mozilla::UniquePtr<int>,
2096                                  UniquePtr_Simple<int>);
2097 
2098 /**
2099  * <div rustbindgen replaces="nsTArray"></div>
2100  */
2101 template <typename T>
2102 class nsTArray_Simple {
2103  protected:
2104   T* mBuffer;
2105 
2106  public:
~nsTArray_Simple()2107   ~nsTArray_Simple() {
2108     // The existence of a user-provided, and therefore non-trivial, destructor
2109     // here prevents bindgen from deriving the Clone trait via a simple memory
2110     // copy.
2111   }
2112 };
2113 
2114 /**
2115  * <div rustbindgen replaces="CopyableTArray"></div>
2116  */
2117 template <typename T>
2118 class CopyableTArray_Simple : public nsTArray_Simple<T> {};
2119 
2120 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<nsStyleImageLayers::Layer>,
2121                                  nsTArray_Simple<nsStyleImageLayers::Layer>);
2122 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleTransition>,
2123                                  nsTArray_Simple<mozilla::StyleTransition>);
2124 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleAnimation>,
2125                                  nsTArray_Simple<mozilla::StyleAnimation>);
2126 
2127 #endif /* nsStyleStruct_h___ */
2128