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