nsStyleStruct.h (87694B)
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 <cstddef> // offsetof() 16 17 #include "CounterStyleManager.h" 18 #include "UniqueOrNonOwningPtr.h" 19 #include "X11UndefineNone.h" 20 #include "imgIContainer.h" 21 #include "imgRequestProxy.h" 22 #include "mozilla/Assertions.h" 23 #include "mozilla/Attributes.h" 24 #include "mozilla/Likely.h" 25 #include "mozilla/Maybe.h" 26 #include "mozilla/WindowButtonType.h" 27 #include "nsChangeHint.h" 28 #include "nsColor.h" 29 #include "nsCoord.h" 30 #include "nsFont.h" 31 #include "nsMargin.h" 32 #include "nsStyleAutoArray.h" 33 #include "nsStyleConsts.h" 34 #include "nsTArray.h" 35 36 class nsIFrame; 37 class nsIURI; 38 class nsTextFrame; 39 struct nsStyleDisplay; 40 struct nsStyleVisibility; 41 class nsComputedDOMStyle; 42 namespace mozilla { 43 class ComputedStyle; 44 struct AnchorPosResolutionCache; 45 class AnchorPosReferenceData; 46 struct IntrinsicSize; 47 struct SizeComputationInput; 48 49 } // namespace mozilla 50 51 namespace mozilla::dom { 52 enum class CompositeOperation : uint8_t; 53 } // namespace mozilla::dom 54 55 namespace mozilla { 56 57 using Position = StylePosition; 58 59 template <> 60 inline bool StylePosition::HasPercent() const { 61 return horizontal.HasPercent() || vertical.HasPercent(); 62 } 63 64 /** 65 * True if the effective background image position described by this depends on 66 * the size of the corresponding frame. 67 */ 68 template <> 69 inline bool StylePosition::DependsOnPositioningAreaSize() const { 70 return HasPercent(); 71 } 72 73 template <> 74 inline Position Position::FromPercentage(float aPercent) { 75 return {LengthPercentage::FromPercentage(aPercent), 76 LengthPercentage::FromPercentage(aPercent)}; 77 } 78 79 /** 80 * Convenience struct for querying if a given box has size-containment in 81 * either axis. 82 */ 83 struct ContainSizeAxes { 84 ContainSizeAxes(bool aIContained, bool aBContained) 85 : mIContained(aIContained), mBContained(aBContained) {} 86 87 bool IsBoth() const { return mIContained && mBContained; } 88 bool IsAny() const { return mIContained || mBContained; } 89 90 bool operator==(const ContainSizeAxes&) const = default; 91 92 /** 93 * Return a contained size from an uncontained size. 94 */ 95 nsSize ContainSize(const nsSize& aUncontainedSize, 96 const nsIFrame& aFrame) const; 97 IntrinsicSize ContainIntrinsicSize(const IntrinsicSize& aUncontainedSize, 98 const nsIFrame& aFrame) const; 99 Maybe<nscoord> ContainIntrinsicBSize(const nsIFrame& aFrame, 100 nscoord aNoneValue = 0) const; 101 Maybe<nscoord> ContainIntrinsicISize(const nsIFrame& aFrame, 102 nscoord aNoneValue = 0) const; 103 104 const bool mIContained; 105 const bool mBContained; 106 }; 107 108 // Used value for the CSS 'float' property (logical 'inline-*' in the computed 109 // value will have been resolved to 'left' or 'right'). 110 enum class UsedFloat : uint8_t { 111 None, 112 Left, 113 Right, 114 }; 115 116 // Used value for the CSS 'clear' property (logical 'inline-*' in the computed 117 // value will have been resolved to 'left' or 'right'). 118 enum class UsedClear : uint8_t { 119 None, 120 Left, 121 Right, 122 Both, 123 }; 124 125 } // namespace mozilla 126 127 #define STYLE_STRUCT(name_) \ 128 name_(const name_&); \ 129 MOZ_COUNTED_DTOR(name_); \ 130 void MarkLeaked() const { MOZ_COUNT_DTOR(name_); } \ 131 nsChangeHint CalcDifference(const name_&) const; 132 133 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont { 134 STYLE_STRUCT(nsStyleFont) 135 explicit nsStyleFont(const mozilla::dom::Document&); 136 137 /** 138 * Return a given size multiplied by the current text zoom factor (in 139 * aPresContext). 140 * 141 * The size is allowed to be negative, but the caller is expected to deal with 142 * negative results. 143 */ 144 static mozilla::Length ZoomText(const mozilla::dom::Document&, 145 mozilla::Length); 146 147 nsAtom* GetFontPaletteAtom() const { return mFontPalette._0.AsAtom(); } 148 149 nsFont mFont; 150 151 // Our "computed size". Can be different from mFont.size which is our "actual 152 // size" and is enforced to be >= the user's preferred min-size. mFont.size 153 // should be used for display purposes while mSize is the value to return in 154 // getComputedStyle() for example. 155 mozilla::NonNegativeLength mSize; 156 157 // In stylo these three track whether the size is keyword-derived 158 // and if so if it has been modified by a factor/offset 159 float mFontSizeFactor; 160 mozilla::Length mFontSizeOffset; 161 mozilla::StyleFontSizeKeyword mFontSizeKeyword; 162 mozilla::StyleFontPalette mFontPalette; 163 // math-depth support (used for MathML scriptlevel) 164 int8_t mMathDepth; 165 mozilla::StyleLineHeight mLineHeight; 166 // allow different min font-size for certain cases 167 mozilla::StylePercentage mMinFontSizeRatio{1.0f}; 168 // MathML mathvariant support 169 mozilla::StyleMathVariant mMathVariant; 170 // math-style support (used for MathML displaystyle) 171 mozilla::StyleMathStyle mMathStyle; 172 // math-shift support (used for MathML cramped mode) 173 mozilla::StyleMathShift mMathShift; 174 175 // Was mLanguage set based on a lang attribute in the document? 176 bool mExplicitLanguage = false; 177 178 mozilla::StyleXTextScale mXTextScale; 179 180 bool MinFontSizeEnabled() const { 181 return mXTextScale == mozilla::StyleXTextScale::All; 182 } 183 184 // The value mSize would have had if scriptminsize had never been applied 185 mozilla::NonNegativeLength mScriptUnconstrainedSize; 186 mozilla::Length mScriptMinSize; 187 RefPtr<nsAtom> mLanguage; 188 }; 189 190 struct nsStyleImageLayers { 191 enum class LayerType : uint8_t { Background = 0, Mask }; 192 193 explicit nsStyleImageLayers(LayerType aType); 194 nsStyleImageLayers(const nsStyleImageLayers& aSource); 195 196 struct Repeat { 197 mozilla::StyleImageLayerRepeat mXRepeat = 198 mozilla::StyleImageLayerRepeat::Repeat; 199 mozilla::StyleImageLayerRepeat mYRepeat = 200 mozilla::StyleImageLayerRepeat::Repeat; 201 202 // Initialize nothing 203 Repeat() = default; 204 205 bool IsInitialValue() const { 206 return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat && 207 mYRepeat == mozilla::StyleImageLayerRepeat::Repeat; 208 } 209 210 bool DependsOnPositioningAreaSize() const { 211 return mXRepeat == mozilla::StyleImageLayerRepeat::Space || 212 mYRepeat == mozilla::StyleImageLayerRepeat::Space; 213 } 214 215 bool operator==(const Repeat& aOther) const = default; 216 bool operator!=(const Repeat& aOther) const = default; 217 }; 218 219 struct Layer { 220 using StyleGeometryBox = mozilla::StyleGeometryBox; 221 using StyleImageLayerAttachment = mozilla::StyleImageLayerAttachment; 222 using StyleBackgroundSize = mozilla::StyleBackgroundSize; 223 224 mozilla::StyleImage mImage; 225 mozilla::Position mPosition; 226 StyleBackgroundSize mSize; 227 StyleGeometryBox mClip; 228 MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin; 229 230 // This property is used for background layer only. 231 // For a mask layer, it should always be the initial value, which is 232 // StyleImageLayerAttachment::Scroll. 233 StyleImageLayerAttachment mAttachment; 234 235 // This property is used for background layer only. 236 // For a mask layer, it should always be the initial value, which is 237 // StyleBlend::Normal. 238 mozilla::StyleBlend mBlendMode; 239 240 // This property is used for mask layer only. 241 // For a background layer, it should always be the initial value, which is 242 // StyleMaskComposite::Add. 243 mozilla::StyleMaskComposite mComposite; 244 245 // mask-only property. This property is used for mask layer only. For a 246 // background layer, it should always be the initial value, which is 247 // StyleMaskMode::MatchSource. 248 mozilla::StyleMaskMode mMaskMode; 249 250 Repeat mRepeat; 251 252 // This constructor does not initialize mRepeat or mOrigin and Initialize() 253 // must be called to do that. 254 Layer(); 255 ~Layer(); 256 257 // Initialize mRepeat and mOrigin by specified layer type 258 void Initialize(LayerType aType); 259 260 void ResolveImage(mozilla::dom::Document& aDocument, 261 const Layer* aOldLayer) { 262 mImage.ResolveImage(aDocument, aOldLayer ? &aOldLayer->mImage : nullptr); 263 } 264 265 // True if the rendering of this layer might change when the size 266 // of the background positioning area changes. This is true for any 267 // non-solid-color background whose position or size depends on 268 // the size of the positioning area. It's also true for SVG images 269 // whose root <svg> node has a viewBox. 270 bool RenderingMightDependOnPositioningAreaSizeChange() const; 271 272 // Compute the change hint required by changes in just this layer. 273 nsChangeHint CalcDifference(const Layer& aNewLayer) const; 274 275 // An equality operator that compares the images using URL-equality 276 // rather than pointer-equality. 277 bool operator==(const Layer& aOther) const; 278 bool operator!=(const Layer& aOther) const = default; 279 }; 280 281 // The (positive) number of computed values of each property, since 282 // the lengths of the lists are independent. 283 uint32_t mAttachmentCount; 284 uint32_t mClipCount; 285 uint32_t mOriginCount; 286 uint32_t mRepeatCount; 287 uint32_t mPositionXCount; 288 uint32_t mPositionYCount; 289 uint32_t mImageCount; 290 uint32_t mSizeCount; 291 uint32_t mMaskModeCount; 292 uint32_t mBlendModeCount; 293 uint32_t mCompositeCount; 294 295 // Layers are stored in an array, matching the top-to-bottom order in 296 // which they are specified in CSS. The number of layers to be used 297 // should come from the background-image property. We create 298 // additional |Layer| objects for *any* property, not just 299 // background-image. This means that the bottommost layer that 300 // callers in layout care about (which is also the one whose 301 // background-clip applies to the background-color) may not be last 302 // layer. In layers below the bottom layer, properties will be 303 // uninitialized unless their count, above, indicates that they are 304 // present. 305 nsStyleAutoArray<Layer> mLayers; 306 307 const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; } 308 309 void ResolveImages(mozilla::dom::Document& aDocument, 310 const nsStyleImageLayers* aOldLayers) { 311 for (uint32_t i = 0; i < mImageCount; ++i) { 312 const Layer* oldLayer = (aOldLayers && aOldLayers->mLayers.Length() > i) 313 ? &aOldLayers->mLayers[i] 314 : nullptr; 315 mLayers[i].ResolveImage(aDocument, oldLayer); 316 } 317 } 318 319 // Fill unspecified layers by cycling through their values 320 // till they all are of length aMaxItemCount 321 void FillAllLayers(uint32_t aMaxItemCount); 322 323 nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers, 324 nsStyleImageLayers::LayerType aType) const; 325 326 nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther); 327 nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther) = default; 328 bool operator==(const nsStyleImageLayers& aOther) const; 329 330 static const NonCustomCSSPropertyId kBackgroundLayerTable[]; 331 static const NonCustomCSSPropertyId kMaskLayerTable[]; 332 333 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \ 334 for (uint32_t var_ = (layers_).mImageCount; (var_)-- != 0;) 335 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, \ 336 start_, count_) \ 337 NS_ASSERTION( \ 338 (int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, \ 339 "Invalid layer start!"); \ 340 NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, \ 341 "Invalid layer range!"); \ 342 for (uint32_t var_ = (start_) + 1; \ 343 (var_)-- != (uint32_t)((start_) + 1 - (count_));) 344 }; 345 346 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground { 347 STYLE_STRUCT(nsStyleBackground) 348 nsStyleBackground(); 349 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBackground*); 350 351 // Return the background color as nscolor. 352 nscolor BackgroundColor(const nsIFrame* aFrame) const; 353 nscolor BackgroundColor(const mozilla::ComputedStyle* aStyle) const; 354 355 // True if this background is completely transparent. 356 bool IsTransparent(const nsIFrame* aFrame) const; 357 bool IsTransparent(const mozilla::ComputedStyle* aStyle) const; 358 359 // We have to take slower codepaths for fixed background attachment, 360 // but we don't want to do that when there's no image. 361 // Not inline because it uses an nsCOMPtr<imgIRequest> 362 // FIXME: Should be in nsStyleStructInlines.h. 363 bool HasFixedBackground(nsIFrame* aFrame) const; 364 365 // Checks to see if this has a non-empty image with "local" attachment. 366 // This is defined in nsStyleStructInlines.h. 367 inline bool HasLocalBackground() const; 368 369 const nsStyleImageLayers::Layer& BottomLayer() const { 370 return mImage.BottomLayer(); 371 } 372 373 nsStyleImageLayers mImage; 374 mozilla::StyleColor mBackgroundColor; 375 }; 376 377 using AnchorResolvedMargin = 378 mozilla::UniqueOrNonOwningPtr<const mozilla::StyleMargin>; 379 380 // Base set of parameters required to resolve a reference to an anchor. 381 struct AnchorPosResolutionParams { 382 struct AutoResolutionOverrideParams { 383 // Whether anchor-center is being used on the horizontal axis. 384 bool mHAnchorCenter = false; 385 // Whether anchor-center is being used on the vertical axis. 386 bool mVAnchorCenter = false; 387 // Whether position-area is being used. 388 bool mPositionAreaInUse = false; 389 390 AutoResolutionOverrideParams() = default; 391 AutoResolutionOverrideParams( 392 const nsIFrame* aFrame, 393 const mozilla::AnchorPosResolutionCache* aCache); 394 explicit AutoResolutionOverrideParams(const nsIFrame* aFrame); 395 396 bool OverriddenToZero(mozilla::StylePhysicalAxis aAxis) const; 397 }; 398 // Frame of the anchor positioned element. 399 // If nullptr, skips anchor lookup and returns invalid, resolving fallbacks. 400 const nsIFrame* mFrame; 401 // Position property of the element in question. 402 mozilla::StylePositionProperty mPosition; 403 // Cache data used for anchor resolution. 404 mozilla::AnchorPosResolutionCache* const mCache; 405 // Set of parameters that override `auto` values to 0, if the default 406 // anchor is valid. 407 AutoResolutionOverrideParams mAutoResolutionOverrideParams; 408 409 // Helper functions for creating anchor resolution parameters. 410 // Defined in corresponding header files. 411 static inline AnchorPosResolutionParams From( 412 const nsIFrame* aFrame, 413 mozilla::AnchorPosResolutionCache* aAnchorPosResolutionCache = nullptr); 414 static AnchorPosResolutionParams From( 415 const mozilla::SizeComputationInput* aSizingInput, 416 bool aIgnorePositionArea = false); 417 static inline AnchorPosResolutionParams From( 418 const nsComputedDOMStyle* aComputedDOMStyle); 419 }; 420 421 struct AnchorResolvedMarginHelper { 422 static const mozilla::StyleMargin& ZeroValue() { 423 static const auto value = mozilla::StyleMargin::LengthPercentage( 424 mozilla::StyleLengthPercentage::Zero()); 425 return value; 426 } 427 428 static AnchorResolvedMargin FromUnresolved( 429 const mozilla::StyleMargin& aValue, mozilla::StylePhysicalAxis aAxis, 430 const AnchorPosResolutionParams& aParams) { 431 auto resolved = [&]() { 432 if (aValue.HasAnchorPositioningFunction()) { 433 return ResolveAnchor(aValue, aAxis, aParams); 434 } 435 return AnchorResolvedMargin::NonOwning(&aValue); 436 }(); 437 if (resolved->IsAuto() && 438 aParams.mAutoResolutionOverrideParams.OverriddenToZero(aAxis)) { 439 return Zero(); 440 } 441 return resolved; 442 } 443 444 private: 445 static AnchorResolvedMargin Zero() { 446 return AnchorResolvedMargin::NonOwning(&ZeroValue()); 447 } 448 449 static AnchorResolvedMargin ResolveAnchor( 450 const mozilla::StyleMargin& aValue, mozilla::StylePhysicalAxis aAxis, 451 const AnchorPosResolutionParams& aParams); 452 }; 453 454 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin { 455 STYLE_STRUCT(nsStyleMargin) 456 nsStyleMargin(); 457 458 // Returns false if any margin is layout-dependent in any way. 459 // Percentage values and/or `anchor-size()` will do this. 460 bool GetMargin(nsMargin& aMargin) const { 461 bool convertsToLength = mMargin.All( 462 [](const auto& aLength) { return aLength.ConvertsToLength(); }); 463 464 if (!convertsToLength) { 465 return false; 466 } 467 468 for (const auto side : mozilla::AllPhysicalSides()) { 469 aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength(); 470 } 471 return true; 472 } 473 474 nsMargin GetScrollMargin() const { 475 return nsMargin(mScrollMargin.Get(mozilla::eSideTop).ToAppUnits(), 476 mScrollMargin.Get(mozilla::eSideRight).ToAppUnits(), 477 mScrollMargin.Get(mozilla::eSideBottom).ToAppUnits(), 478 mScrollMargin.Get(mozilla::eSideLeft).ToAppUnits()); 479 } 480 481 // Return true if either the start or end side in the axis is 'auto'. 482 // (defined in WritingModes.h since we need the full WritingMode type) 483 inline bool HasBlockAxisAuto(mozilla::WritingMode aWM, 484 const AnchorPosResolutionParams& aParams) const; 485 inline bool HasInlineAxisAuto(mozilla::WritingMode aWM, 486 const AnchorPosResolutionParams& aParams) const; 487 inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode, 488 const AnchorPosResolutionParams& aParams) const; 489 490 // Attempt to return the resolved margin, resolving anchor functions, and 491 // using a dummy percentage basis. If the resulting value returns true for 492 // `HasPercent`, percentage value needs to be resolved with a proper basis at 493 // a later point. 494 AnchorResolvedMargin GetMargin( 495 mozilla::Side aSide, const AnchorPosResolutionParams& aParams) const { 496 return AnchorResolvedMarginHelper::FromUnresolved( 497 mMargin.Get(aSide), mozilla::ToStylePhysicalAxis(aSide), aParams); 498 } 499 500 bool MarginEquals(const nsStyleMargin& aOther) const { 501 for (const auto side : mozilla::AllPhysicalSides()) { 502 if (mMargin.Get(side) != aOther.mMargin.Get(side)) { 503 return false; 504 } 505 } 506 return true; 507 } 508 509 // As with other logical-coordinate accessors, definitions for these 510 // are found in WritingModes.h. 511 inline AnchorResolvedMargin GetMargin( 512 mozilla::LogicalSide aSide, mozilla::WritingMode aWM, 513 const AnchorPosResolutionParams& aParams) const; 514 515 mozilla::StyleRect<mozilla::StyleMargin> mMargin; 516 mozilla::StyleRect<mozilla::StyleLength> mScrollMargin; 517 // TODO: Add support per-axis/side clipping, see 518 // https://github.com/w3c/csswg-drafts/issues/7245 519 mozilla::StyleOverflowClipMargin mOverflowClipMargin; 520 }; 521 522 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding { 523 STYLE_STRUCT(nsStylePadding) 524 nsStylePadding(); 525 526 mozilla::StyleRect<mozilla::NonNegativeLengthPercentage> mPadding; 527 mozilla::StyleRect<mozilla::NonNegativeLengthPercentageOrAuto> mScrollPadding; 528 529 inline bool IsWidthDependent() const { 530 return !mPadding.All( 531 [](const auto& aLength) { return aLength.ConvertsToLength(); }); 532 } 533 534 bool GetPadding(nsMargin& aPadding) const { 535 if (IsWidthDependent()) { 536 return false; 537 } 538 539 for (const auto side : mozilla::AllPhysicalSides()) { 540 // Clamp negative calc() to 0. 541 aPadding.Side(side) = std::max(mPadding.Get(side).ToLength(), 0); 542 } 543 return true; 544 } 545 }; 546 547 // Border widths are rounded to the nearest-below integer number of pixels, 548 // but values between zero and one device pixels are always rounded up to 549 // one device pixel. 550 #define NS_ROUND_BORDER_TO_PIXELS(l, tpp) \ 551 ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp)) 552 553 // Returns if the given border style type is visible or not 554 static inline bool IsVisibleBorderStyle(mozilla::StyleBorderStyle aStyle) { 555 return aStyle != mozilla::StyleBorderStyle::None && 556 aStyle != mozilla::StyleBorderStyle::Hidden; 557 } 558 559 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder { 560 STYLE_STRUCT(nsStyleBorder) 561 nsStyleBorder(); 562 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBorder*); 563 564 // Return whether aStyle is a visible style. Invisible styles cause 565 // the relevant computed border width to be 0. 566 // Note that this does *not* consider the effects of 'border-image': 567 // if border-style is none, but there is a loaded border image, 568 // HasVisibleStyle will be false even though there *is* a border. 569 bool HasVisibleStyle(mozilla::Side aSide) const { 570 return IsVisibleBorderStyle(mBorderStyle.Get(aSide)); 571 } 572 573 // aBorderWidth is in twips 574 void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth, 575 nscoord aAppUnitsPerDevPixel) { 576 mBorder.Get(aSide) = 577 NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, aAppUnitsPerDevPixel); 578 } 579 580 // Get the computed border (plus rounding). 581 nsMargin GetComputedBorder() const { 582 nsMargin border(mBorder._0, mBorder._1, mBorder._2, mBorder._3); 583 for (auto side : mozilla::AllPhysicalSides()) { 584 if (!HasVisibleStyle(side)) { 585 border.Side(side) = 0; 586 } 587 } 588 return border; 589 } 590 591 bool HasBorder() const { 592 for (auto side : mozilla::AllPhysicalSides()) { 593 if (mBorder.Get(side) && HasVisibleStyle(side)) { 594 return true; 595 } 596 } 597 return !mBorderImageSource.IsNone(); 598 } 599 600 // Get the actual border width for a particular side, in appunits. Note that 601 // this is zero if and only if there is no border to be painted for this 602 // side. That is, this value takes into account the border style and the 603 // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS. 604 nscoord GetComputedBorderWidth(mozilla::Side aSide) const { 605 if (!HasVisibleStyle(aSide)) { 606 return 0; 607 } 608 return mBorder.Get(aSide); 609 } 610 611 mozilla::StyleBorderStyle GetBorderStyle(mozilla::Side aSide) const { 612 NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side"); 613 return mBorderStyle.Get(aSide); 614 } 615 616 void SetBorderStyle(mozilla::Side aSide, mozilla::StyleBorderStyle aStyle) { 617 NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side"); 618 mBorderStyle.Get(aSide) = aStyle; 619 } 620 621 inline bool IsBorderImageSizeAvailable() const { 622 return mBorderImageSource.IsSizeAvailable(); 623 } 624 625 nsMargin GetImageOutset() const; 626 627 imgIRequest* GetBorderImageRequest() const { 628 return mBorderImageSource.GetImageRequest(); 629 } 630 631 public: 632 mozilla::StyleBorderRadius mBorderRadius; // coord, percent 633 mozilla::StyleImage mBorderImageSource; 634 mozilla::StyleBorderImageWidth mBorderImageWidth; 635 mozilla::StyleNonNegativeLengthOrNumberRect mBorderImageOutset; 636 mozilla::StyleBorderImageSlice mBorderImageSlice; // factor, percent 637 mozilla::StyleBorderImageRepeat mBorderImageRepeat; 638 mozilla::StyleFloatEdge mFloatEdge; 639 mozilla::StyleBoxDecorationBreak mBoxDecorationBreak; 640 641 protected: 642 mozilla::StyleRect<mozilla::StyleBorderStyle> mBorderStyle; 643 mozilla::StyleRect<mozilla::StyleBorderSideWidth> mBorder; 644 645 public: 646 // the colors to use for a simple border. 647 // not used for -moz-border-colors 648 mozilla::StyleColor mBorderTopColor; 649 mozilla::StyleColor mBorderRightColor; 650 mozilla::StyleColor mBorderBottomColor; 651 mozilla::StyleColor mBorderLeftColor; 652 653 mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) { 654 switch (aSide) { 655 case mozilla::eSideTop: 656 return mBorderTopColor; 657 case mozilla::eSideRight: 658 return mBorderRightColor; 659 case mozilla::eSideBottom: 660 return mBorderBottomColor; 661 case mozilla::eSideLeft: 662 return mBorderLeftColor; 663 } 664 MOZ_ASSERT_UNREACHABLE("Unknown side"); 665 return mBorderTopColor; 666 } 667 668 const mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) const { 669 switch (aSide) { 670 case mozilla::eSideTop: 671 return mBorderTopColor; 672 case mozilla::eSideRight: 673 return mBorderRightColor; 674 case mozilla::eSideBottom: 675 return mBorderBottomColor; 676 case mozilla::eSideLeft: 677 return mBorderLeftColor; 678 } 679 MOZ_ASSERT_UNREACHABLE("Unknown side"); 680 return mBorderTopColor; 681 } 682 683 static mozilla::StyleColor nsStyleBorder::* BorderColorFieldFor( 684 mozilla::Side aSide) { 685 switch (aSide) { 686 case mozilla::eSideTop: 687 return &nsStyleBorder::mBorderTopColor; 688 case mozilla::eSideRight: 689 return &nsStyleBorder::mBorderRightColor; 690 case mozilla::eSideBottom: 691 return &nsStyleBorder::mBorderBottomColor; 692 case mozilla::eSideLeft: 693 return &nsStyleBorder::mBorderLeftColor; 694 } 695 MOZ_ASSERT_UNREACHABLE("Unknown side"); 696 return nullptr; 697 } 698 699 nsStyleBorder& operator=(const nsStyleBorder&) = delete; 700 }; 701 702 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline { 703 STYLE_STRUCT(nsStyleOutline) 704 nsStyleOutline(); 705 706 mozilla::StyleBorderSideWidth mOutlineWidth; 707 mozilla::StyleAu mOutlineOffset; 708 mozilla::StyleColor mOutlineColor; 709 mozilla::StyleOutlineStyle mOutlineStyle; 710 711 bool ShouldPaintOutline() const { 712 if (mOutlineStyle.IsAuto()) { 713 return true; 714 } 715 if (!IsVisibleBorderStyle(mOutlineStyle.AsBorderStyle())) { 716 return false; 717 } 718 return mOutlineWidth > 0; 719 } 720 721 nsSize EffectiveOffsetFor(const nsRect& aRect) const; 722 }; 723 724 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList { 725 STYLE_STRUCT(nsStyleList) 726 nsStyleList(); 727 728 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleList*); 729 730 nsStyleList& operator=(const nsStyleList& aOther) = delete; 731 nsChangeHint CalcDifference(const nsStyleList& aNewData, 732 const mozilla::ComputedStyle& aOldStyle) const; 733 734 mozilla::StyleListStylePosition mListStylePosition; 735 736 mozilla::StyleListStyleType mListStyleType; 737 mozilla::StyleQuotes mQuotes; 738 mozilla::StyleImage mListStyleImage; 739 }; 740 741 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePage { 742 STYLE_STRUCT(nsStylePage) 743 MOZ_COUNTED_DEFAULT_CTOR(nsStylePage) 744 745 using StylePageOrientation = mozilla::StylePageOrientation; 746 using StylePageSize = mozilla::StylePageSize; 747 using StylePageName = mozilla::StylePageName; 748 749 // page-size property. 750 StylePageSize mSize = StylePageSize::Auto(); 751 // page-name property. 752 StylePageName mPage = StylePageName::Auto(); 753 // page-orientation property. 754 StylePageOrientation mPageOrientation = StylePageOrientation::Upright; 755 }; 756 757 using AnchorResolvedInset = 758 mozilla::UniqueOrNonOwningPtr<const mozilla::StyleInset>; 759 760 // Set of parameters required to resolve the anchor's position offset in a 761 // containing block. 762 struct AnchorPosOffsetResolutionParams { 763 // Size of the containing block for the anchor positioned element. 764 // This needs to be set only if all of the following conditions are true: 765 // 766 // * The resolution is happening during reflow (i.e. Containing block 767 // doesn't have its rect set) 768 // * The caller needs the correct size, not just its type (e.g. Just 769 // checking `HasPercent()` of the inset resolved value) 770 const mozilla::LogicalSize* mCBSize; 771 AnchorPosResolutionParams mBaseParams; 772 773 static AnchorPosOffsetResolutionParams UseCBFrameSize( 774 const AnchorPosResolutionParams& aBaseParams) { 775 return {aBaseParams, nullptr}; 776 } 777 778 static AnchorPosOffsetResolutionParams ExplicitCBFrameSize( 779 const AnchorPosResolutionParams& aBaseParams, 780 const mozilla::LogicalSize* aCBSize) { 781 return {aBaseParams, aCBSize}; 782 } 783 784 private: 785 AnchorPosOffsetResolutionParams(const AnchorPosResolutionParams& aBaseParams, 786 const mozilla::LogicalSize* aCBSize) 787 : mCBSize{aCBSize}, mBaseParams{aBaseParams} {} 788 }; 789 790 struct AnchorResolvedInsetHelper { 791 static const mozilla::StyleInset& AutoValue() { 792 static const auto value = mozilla::StyleInset::Auto(); 793 return value; 794 } 795 796 static const mozilla::StyleInset& ZeroValue() { 797 static const auto value = mozilla::StyleInset::LengthPercentage( 798 mozilla::StyleLengthPercentage::Zero()); 799 return value; 800 } 801 802 static AnchorResolvedInset FromUnresolved( 803 const mozilla::StyleInset& aValue, mozilla::Side aSide, 804 const AnchorPosOffsetResolutionParams& aParams) { 805 auto resolved = [&]() { 806 if (aValue.HasAnchorPositioningFunction()) { 807 return ResolveAnchor(aValue, mozilla::ToStylePhysicalSide(aSide), 808 aParams); 809 } 810 return AnchorResolvedInset::NonOwning(&aValue); 811 }(); 812 if (resolved->IsAuto() && 813 aParams.mBaseParams.mAutoResolutionOverrideParams.OverriddenToZero( 814 mozilla::ToStylePhysicalAxis(aSide))) { 815 return AnchorResolvedInset::NonOwning(&ZeroValue()); 816 } 817 return resolved; 818 } 819 820 private: 821 static AnchorResolvedInset Auto() { 822 return AnchorResolvedInset::NonOwning(&AutoValue()); 823 } 824 825 static AnchorResolvedInset ResolveAnchor( 826 const mozilla::StyleInset& aValue, mozilla::StylePhysicalSide aSide, 827 const AnchorPosOffsetResolutionParams& aParams); 828 }; 829 830 using AnchorResolvedSize = 831 mozilla::UniqueOrNonOwningPtr<const mozilla::StyleSize>; 832 833 struct AnchorResolvedSizeHelper { 834 static const mozilla::StyleSize& ZeroValue() { 835 static const auto value = mozilla::StyleSize::LengthPercentage( 836 mozilla::StyleLengthPercentage::Zero()); 837 return value; 838 } 839 840 static const mozilla::StyleSize& MinContentValue() { 841 static const auto value = mozilla::StyleSize::MinContent(); 842 return value; 843 } 844 845 static const mozilla::StyleSize& AutoValue() { 846 static const auto value = mozilla::StyleSize::Auto(); 847 return value; 848 } 849 850 static AnchorResolvedSize FromUnresolved( 851 const mozilla::StyleSize& aValue, mozilla::StylePhysicalAxis aAxis, 852 const AnchorPosResolutionParams& aParams) { 853 if (aValue.HasAnchorPositioningFunction()) { 854 return ResolveAnchor(aValue, aAxis, aParams); 855 } 856 return AnchorResolvedSize::NonOwning(&aValue); 857 } 858 859 static AnchorResolvedSize Overridden(const mozilla::StyleSize& aSize) { 860 return AnchorResolvedSize::NonOwning(&aSize); 861 } 862 863 static AnchorResolvedSize Zero() { 864 return AnchorResolvedSize::NonOwning(&ZeroValue()); 865 } 866 867 static AnchorResolvedSize MinContent() { 868 return AnchorResolvedSize::NonOwning(&MinContentValue()); 869 } 870 871 static AnchorResolvedSize Auto() { 872 return AnchorResolvedSize::NonOwning(&AutoValue()); 873 } 874 875 static AnchorResolvedSize LengthPercentage( 876 const mozilla::StyleLengthPercentage& aLP) { 877 return mozilla::MakeUniqueOfUniqueOrNonOwning<const mozilla::StyleSize>( 878 aLP); 879 } 880 881 private: 882 static AnchorResolvedSize ResolveAnchor( 883 const mozilla::StyleSize& aValue, mozilla::StylePhysicalAxis aAxis, 884 const AnchorPosResolutionParams& aParams); 885 }; 886 887 using AnchorResolvedMaxSize = 888 mozilla::UniqueOrNonOwningPtr<const mozilla::StyleMaxSize>; 889 890 struct AnchorResolvedMaxSizeHelper { 891 static const mozilla::StyleMaxSize& MaxContentValue() { 892 static const auto value = mozilla::StyleMaxSize::MaxContent(); 893 return value; 894 } 895 static const mozilla::StyleMaxSize& NoneValue() { 896 static const auto value = mozilla::StyleMaxSize::None(); 897 return value; 898 } 899 900 static AnchorResolvedMaxSize FromUnresolved( 901 const mozilla::StyleMaxSize& aValue, mozilla::StylePhysicalAxis aAxis, 902 const AnchorPosResolutionParams& aParams) { 903 if (aValue.HasAnchorPositioningFunction()) { 904 return ResolveAnchor(aValue, aAxis, aParams); 905 } 906 return AnchorResolvedMaxSize::NonOwning(&aValue); 907 } 908 static AnchorResolvedMaxSize MaxContent() { 909 return AnchorResolvedMaxSize::NonOwning(&MaxContentValue()); 910 } 911 912 static AnchorResolvedMaxSize None() { 913 return AnchorResolvedMaxSize::NonOwning(&NoneValue()); 914 } 915 916 private: 917 static AnchorResolvedMaxSize ResolveAnchor( 918 const mozilla::StyleMaxSize& aValue, mozilla::StylePhysicalAxis aAxis, 919 const AnchorPosResolutionParams& aParams); 920 }; 921 922 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition { 923 STYLE_STRUCT(nsStylePosition) 924 nsStylePosition(); 925 926 using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto; 927 using Position = mozilla::Position; 928 template <typename T> 929 using StyleRect = mozilla::StyleRect<T>; 930 using StyleSize = mozilla::StyleSize; 931 using StyleMaxSize = mozilla::StyleMaxSize; 932 using WritingMode = mozilla::WritingMode; 933 using LogicalAxis = mozilla::LogicalAxis; 934 using StyleImplicitGridTracks = mozilla::StyleImplicitGridTracks; 935 using ComputedStyle = mozilla::ComputedStyle; 936 using StyleSelfAlignment = mozilla::StyleSelfAlignment; 937 938 nsChangeHint CalcDifference(const nsStylePosition& aNewData, 939 const ComputedStyle& aOldStyle) const; 940 941 // Returns whether we need to compute an hypothetical position if we were 942 // absolutely positioned. 943 bool NeedsHypotheticalPositionIfAbsPos() const { 944 // NOTE(dshin): By passing in nullptr for frames, we're guaranteeing that 945 // no anchor is found, instead considering fallbacks or anchor-invalid 946 // values. Since anchor resolved value can never be auto, this is 947 // guaranteed to be correct, if not pessimistic. 948 // TODO(dshin): Probably nicer if we try to resolve. Two tricky parts: 949 // * `CalcDifference`: Need to pass in the changing frame somehow. 950 // * Reflow cases where containing block is not yet set (Mainly when 951 // `nsBlockFrame` is about to run another reflow for clearance) 952 const auto anchorResolutionParams = 953 AnchorPosOffsetResolutionParams::UseCBFrameSize( 954 {nullptr, mozilla::StylePositionProperty::Absolute}); 955 return (GetAnchorResolvedInset(mozilla::eSideRight, anchorResolutionParams) 956 ->IsAuto() && 957 GetAnchorResolvedInset(mozilla::eSideLeft, anchorResolutionParams) 958 ->IsAuto()) || 959 (GetAnchorResolvedInset(mozilla::eSideTop, anchorResolutionParams) 960 ->IsAuto() && 961 GetAnchorResolvedInset(mozilla::eSideBottom, anchorResolutionParams) 962 ->IsAuto()); 963 } 964 965 const mozilla::StyleContainIntrinsicSize& ContainIntrinsicBSize( 966 const WritingMode& aWM) const; 967 const mozilla::StyleContainIntrinsicSize& ContainIntrinsicISize( 968 const WritingMode& aWM) const; 969 970 /** 971 * Return the used value for 'align-self' given our parent ComputedStyle 972 * (or null for the root). 973 */ 974 StyleSelfAlignment UsedAlignSelf(const ComputedStyle*) const; 975 976 /** 977 * Return the used value for 'justify-self' given our parent ComputedStyle 978 * aParent (or null for the root). 979 */ 980 StyleSelfAlignment UsedJustifySelf(const ComputedStyle*) const; 981 982 /** 983 * Return the used value for 'justify/align-self' for the axis in the 984 * alignment container's writing mode. 985 * 986 * @param aAlignContainerStyle the computed style of the alignment container, 987 * or null for the root. 988 * 989 * (defined in WritingModes.h since we need the full WritingMode type) 990 */ 991 inline mozilla::StyleAlignFlags UsedSelfAlignment( 992 LogicalAxis aAlignContainerAxis, 993 const mozilla::ComputedStyle* aAlignContainerStyle) const; 994 995 /** 996 * Return the used value for 'justify/align-self' for the axis in the 997 * alignment subject's writing mode. 998 * 999 * @param aAlignSubjectAxis the axis in aAlignSubjectWM. 1000 * @param aAlignContainerStyle the computed style of the alignment container, 1001 * or null for the root. 1002 * 1003 * (defined in WritingModes.h since we need the full WritingMode type) 1004 */ 1005 inline mozilla::StyleAlignFlags UsedSelfAlignment( 1006 WritingMode aAlignSubjectWM, LogicalAxis aAlignSubjectAxis, 1007 WritingMode aAlignContainerWM, 1008 const ComputedStyle* aAlignContainerStyle) const; 1009 1010 /** 1011 * Return the used value for 'justify/align-content' in aAxis. 1012 * (defined in WritingModes.h since we need the full WritingMode type) 1013 */ 1014 inline mozilla::StyleContentDistribution UsedContentAlignment( 1015 LogicalAxis aAxis) const; 1016 1017 Position mObjectPosition; 1018 StyleRect<mozilla::StyleInset> mOffset; 1019 StyleSize mWidth; 1020 StyleSize mMinWidth; 1021 StyleMaxSize mMaxWidth; 1022 StyleSize mHeight; 1023 StyleSize mMinHeight; 1024 StyleMaxSize mMaxHeight; 1025 1026 // 'auto' or a `<dashed-ident>` referencing an anchor positioning anchor 1027 // element. 1028 mozilla::StylePositionAnchor mPositionAnchor; 1029 mozilla::StylePositionArea mPositionArea; 1030 mozilla::StylePositionVisibility mPositionVisibility; 1031 mozilla::StylePositionTryFallbacks mPositionTryFallbacks; 1032 mozilla::StylePositionTryOrder mPositionTryOrder; 1033 1034 mozilla::StyleFlexBasis mFlexBasis; 1035 StyleImplicitGridTracks mGridAutoColumns; 1036 StyleImplicitGridTracks mGridAutoRows; 1037 mozilla::StyleAspectRatio mAspectRatio; 1038 mozilla::StyleGridAutoFlow mGridAutoFlow; 1039 mozilla::StyleMasonryAutoFlow mMasonryAutoFlow; 1040 1041 mozilla::StyleContentDistribution mAlignContent; 1042 mozilla::StyleItemPlacement mAlignItems; 1043 mozilla::StyleSelfAlignment mAlignSelf; 1044 mozilla::StyleContentDistribution mJustifyContent; 1045 mozilla::StyleComputedJustifyItems mJustifyItems; 1046 mozilla::StyleSelfAlignment mJustifySelf; 1047 mozilla::StyleFlexDirection mFlexDirection; 1048 mozilla::StyleFlexWrap mFlexWrap; 1049 mozilla::StyleObjectFit mObjectFit; 1050 mozilla::StyleBoxSizing mBoxSizing; 1051 int32_t mOrder; 1052 float mFlexGrow; 1053 float mFlexShrink; 1054 mozilla::StyleZIndex mZIndex; 1055 1056 mozilla::StyleGridTemplateComponent mGridTemplateColumns; 1057 mozilla::StyleGridTemplateComponent mGridTemplateRows; 1058 mozilla::StyleGridTemplateAreas mGridTemplateAreas; 1059 1060 mozilla::StyleGridLine mGridColumnStart; 1061 mozilla::StyleGridLine mGridColumnEnd; 1062 mozilla::StyleGridLine mGridRowStart; 1063 mozilla::StyleGridLine mGridRowEnd; 1064 mozilla::NonNegativeLengthPercentageOrNormal mColumnGap; 1065 mozilla::NonNegativeLengthPercentageOrNormal mRowGap; 1066 1067 mozilla::StyleContainIntrinsicSize mContainIntrinsicWidth; 1068 mozilla::StyleContainIntrinsicSize mContainIntrinsicHeight; 1069 1070 // Logical-coordinate accessors for width and height properties, 1071 // given a WritingMode value. The definitions of these methods are 1072 // found in WritingModes.h (after the WritingMode class is fully 1073 // declared). 1074 inline AnchorResolvedSize ISize(WritingMode, 1075 const AnchorPosResolutionParams&) const; 1076 inline AnchorResolvedSize MinISize(WritingMode, 1077 const AnchorPosResolutionParams&) const; 1078 inline AnchorResolvedMaxSize MaxISize(WritingMode, 1079 const AnchorPosResolutionParams&) const; 1080 inline AnchorResolvedSize BSize(WritingMode, 1081 const AnchorPosResolutionParams&) const; 1082 inline AnchorResolvedSize MinBSize(WritingMode, 1083 const AnchorPosResolutionParams&) const; 1084 inline AnchorResolvedMaxSize MaxBSize(WritingMode, 1085 const AnchorPosResolutionParams&) const; 1086 inline AnchorResolvedSize Size(LogicalAxis, WritingMode, 1087 const AnchorPosResolutionParams&) const; 1088 inline AnchorResolvedSize MinSize(LogicalAxis, WritingMode, 1089 const AnchorPosResolutionParams&) const; 1090 inline AnchorResolvedMaxSize MaxSize(LogicalAxis, WritingMode, 1091 const AnchorPosResolutionParams&) const; 1092 static inline bool ISizeDependsOnContainer(const AnchorResolvedSize&); 1093 static inline bool MinISizeDependsOnContainer(const AnchorResolvedSize&); 1094 static inline bool MaxISizeDependsOnContainer(const AnchorResolvedMaxSize&); 1095 static inline bool BSizeDependsOnContainer(const AnchorResolvedSize&); 1096 static inline bool MinBSizeDependsOnContainer(const AnchorResolvedSize&); 1097 static inline bool MaxBSizeDependsOnContainer(const AnchorResolvedMaxSize&); 1098 1099 // TODO(dshin): These inset getters are to be removed when 1100 // interleaving computation is implemented. 1101 AnchorResolvedInset GetAnchorResolvedInset( 1102 mozilla::Side aSide, 1103 const AnchorPosOffsetResolutionParams& aParams) const { 1104 return AnchorResolvedInsetHelper::FromUnresolved(mOffset.Get(aSide), aSide, 1105 aParams); 1106 } 1107 1108 inline AnchorResolvedInset GetAnchorResolvedInset( 1109 mozilla::LogicalSide aSide, WritingMode aWM, 1110 const AnchorPosOffsetResolutionParams& aParams) const; 1111 1112 // Returns the side with an auto inset if exactly one inset in the given 1113 // physical axis is auto. Otherwise returns Nothing(). 1114 mozilla::Maybe<mozilla::Side> GetSingleAutoInsetInAxis( 1115 mozilla::StylePhysicalAxis aAxis, 1116 const AnchorPosOffsetResolutionParams& aParams) const { 1117 const mozilla::Side startSide = 1118 aAxis == mozilla::StylePhysicalAxis::Horizontal ? mozilla::eSideLeft 1119 : mozilla::eSideTop; 1120 const mozilla::Side endSide = 1121 aAxis == mozilla::StylePhysicalAxis::Horizontal ? mozilla::eSideRight 1122 : mozilla::eSideBottom; 1123 1124 const bool startInsetIsAuto = 1125 AnchorResolvedInsetHelper::FromUnresolved(mOffset.Get(startSide), 1126 startSide, aParams) 1127 ->IsAuto(); 1128 const bool endInsetIsAuto = AnchorResolvedInsetHelper::FromUnresolved( 1129 mOffset.Get(endSide), endSide, aParams) 1130 ->IsAuto(); 1131 1132 if (startInsetIsAuto && !endInsetIsAuto) { 1133 return mozilla::Some(startSide); 1134 } 1135 if (!startInsetIsAuto && endInsetIsAuto) { 1136 return mozilla::Some(endSide); 1137 } 1138 return mozilla::Nothing(); 1139 } 1140 1141 // Logical-axis version, defined in WritingModes.h 1142 inline mozilla::Maybe<mozilla::Side> GetSingleAutoInsetInAxis( 1143 LogicalAxis aAxis, WritingMode aWM, 1144 const AnchorPosOffsetResolutionParams& aParams) const; 1145 1146 AnchorResolvedSize GetWidth(const AnchorPosResolutionParams& aParams) const { 1147 return AnchorResolvedSizeHelper::FromUnresolved( 1148 mWidth, mozilla::StylePhysicalAxis::Horizontal, aParams); 1149 } 1150 1151 AnchorResolvedSize GetHeight(const AnchorPosResolutionParams& aParams) const { 1152 return AnchorResolvedSizeHelper::FromUnresolved( 1153 mHeight, mozilla::StylePhysicalAxis::Vertical, aParams); 1154 } 1155 1156 AnchorResolvedSize GetMinWidth( 1157 const AnchorPosResolutionParams& aParams) const { 1158 return AnchorResolvedSizeHelper::FromUnresolved( 1159 mMinWidth, mozilla::StylePhysicalAxis::Horizontal, aParams); 1160 } 1161 1162 AnchorResolvedSize GetMinHeight( 1163 const AnchorPosResolutionParams& aParams) const { 1164 return AnchorResolvedSizeHelper::FromUnresolved( 1165 mMinHeight, mozilla::StylePhysicalAxis::Vertical, aParams); 1166 } 1167 1168 AnchorResolvedMaxSize GetMaxWidth( 1169 const AnchorPosResolutionParams& aParams) const { 1170 return AnchorResolvedMaxSizeHelper::FromUnresolved( 1171 mMaxWidth, mozilla::StylePhysicalAxis::Horizontal, aParams); 1172 } 1173 1174 AnchorResolvedMaxSize GetMaxHeight( 1175 const AnchorPosResolutionParams& aParams) const { 1176 return AnchorResolvedMaxSizeHelper::FromUnresolved( 1177 mMaxHeight, mozilla::StylePhysicalAxis::Vertical, aParams); 1178 } 1179 1180 private: 1181 template <typename SizeOrMaxSize> 1182 static bool ISizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) { 1183 if (aCoord.IsLengthPercentage()) { 1184 return aCoord.AsLengthPercentage().HasPercent(); 1185 } 1186 return aCoord.IsFitContent() || aCoord.BehavesLikeStretchOnInlineAxis(); 1187 } 1188 1189 template <typename SizeOrMaxSize> 1190 static bool BSizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) { 1191 if (aCoord.IsLengthPercentage()) { 1192 return aCoord.AsLengthPercentage().HasPercent(); 1193 } 1194 return aCoord.BehavesLikeStretchOnBlockAxis(); 1195 } 1196 }; 1197 1198 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset { 1199 STYLE_STRUCT(nsStyleTextReset) 1200 nsStyleTextReset(); 1201 1202 // Note the difference between this and 1203 // ComputedStyle::HasTextDecorationLines. 1204 bool HasTextDecorationLines() const { 1205 return mTextDecorationLine != mozilla::StyleTextDecorationLine::NONE && 1206 mTextDecorationLine != 1207 mozilla::StyleTextDecorationLine::COLOR_OVERRIDE; 1208 } 1209 1210 mozilla::StyleTextOverflow mTextOverflow; 1211 1212 mozilla::StyleTextDecorationLine mTextDecorationLine; 1213 mozilla::StyleTextDecorationStyle mTextDecorationStyle; 1214 mozilla::StyleUnicodeBidi mUnicodeBidi; 1215 mozilla::StyleInitialLetter mInitialLetter; 1216 mozilla::StyleColor mTextDecorationColor; 1217 mozilla::StyleTextDecorationLength mTextDecorationThickness; 1218 mozilla::StyleTextDecorationInset mTextDecorationInset; 1219 }; 1220 1221 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText { 1222 STYLE_STRUCT(nsStyleText) 1223 explicit nsStyleText(const mozilla::dom::Document&); 1224 1225 mozilla::StyleAbsoluteColor mColor; 1226 mozilla::StyleForcedColorAdjust mForcedColorAdjust; 1227 mozilla::StyleTextTransform mTextTransform; 1228 mozilla::StyleTextAlign mTextAlign; 1229 mozilla::StyleTextAlignLast mTextAlignLast; 1230 mozilla::StyleTextJustify mTextJustify; 1231 mozilla::StyleWhiteSpaceCollapse mWhiteSpaceCollapse = 1232 mozilla::StyleWhiteSpaceCollapse::Collapse; 1233 mozilla::StyleTextWrapMode mTextWrapMode = mozilla::StyleTextWrapMode::Wrap; 1234 mozilla::StyleLineBreak mLineBreak = mozilla::StyleLineBreak::Auto; 1235 1236 private: 1237 mozilla::StyleWordBreak mWordBreak = mozilla::StyleWordBreak::Normal; 1238 mozilla::StyleOverflowWrap mOverflowWrap = mozilla::StyleOverflowWrap::Normal; 1239 mozilla::StyleTextAutospace mTextAutospace = 1240 mozilla::StyleTextAutospace::NO_AUTOSPACE; 1241 1242 public: 1243 mozilla::StyleHyphens mHyphens; 1244 mozilla::StyleRubyAlign mRubyAlign; 1245 mozilla::StyleRubyPosition mRubyPosition; 1246 mozilla::StyleTextSizeAdjust mTextSizeAdjust; 1247 mozilla::StyleTextCombineUpright mTextCombineUpright; 1248 mozilla::StyleMozControlCharacterVisibility mMozControlCharacterVisibility; 1249 mozilla::StyleTextEmphasisPosition mTextEmphasisPosition; 1250 mozilla::StyleTextRendering mTextRendering; 1251 mozilla::StyleColor mTextEmphasisColor; 1252 mozilla::StyleColor mWebkitTextFillColor; 1253 mozilla::StyleColor mWebkitTextStrokeColor; 1254 1255 mozilla::StyleNonNegativeLengthOrNumber mTabSize; 1256 mozilla::LengthPercentage mWordSpacing; 1257 mozilla::StyleLetterSpacing mLetterSpacing; 1258 mozilla::StyleTextIndent mTextIndent; 1259 1260 mozilla::LengthPercentageOrAuto mTextUnderlineOffset; 1261 mozilla::StyleTextDecorationSkipInk mTextDecorationSkipInk; 1262 mozilla::StyleTextUnderlinePosition mTextUnderlinePosition; 1263 1264 mozilla::StyleAu mWebkitTextStrokeWidth; 1265 1266 mozilla::StyleArcSlice<mozilla::StyleSimpleShadow> mTextShadow; 1267 mozilla::StyleTextEmphasisStyle mTextEmphasisStyle; 1268 1269 mozilla::StyleHyphenateCharacter mHyphenateCharacter = 1270 mozilla::StyleHyphenateCharacter::Auto(); 1271 mozilla::StyleHyphenateLimitChars mHyphenateLimitChars = 1272 mozilla::StyleHyphenateLimitChars::Auto(); 1273 1274 mozilla::StyleTextSecurity mWebkitTextSecurity = 1275 mozilla::StyleTextSecurity::None; 1276 1277 mozilla::StyleTextWrapStyle mTextWrapStyle = 1278 mozilla::StyleTextWrapStyle::Auto; 1279 1280 char16_t TextSecurityMaskChar() const { 1281 switch (mWebkitTextSecurity) { 1282 case mozilla::StyleTextSecurity::None: 1283 return 0; 1284 case mozilla::StyleTextSecurity::Circle: 1285 return 0x25E6; 1286 case mozilla::StyleTextSecurity::Disc: 1287 return 0x2022; 1288 case mozilla::StyleTextSecurity::Square: 1289 return 0x25A0; 1290 default: 1291 MOZ_ASSERT_UNREACHABLE("unknown StyleTextSecurity value!"); 1292 return 0; 1293 } 1294 } 1295 1296 mozilla::StyleWordBreak EffectiveWordBreak() const { 1297 if (mWordBreak == mozilla::StyleWordBreak::BreakWord) { 1298 return mozilla::StyleWordBreak::Normal; 1299 } 1300 return mWordBreak; 1301 } 1302 1303 mozilla::StyleOverflowWrap EffectiveOverflowWrap() const { 1304 if (mWordBreak == mozilla::StyleWordBreak::BreakWord) { 1305 return mozilla::StyleOverflowWrap::Anywhere; 1306 } 1307 return mOverflowWrap; 1308 } 1309 1310 mozilla::StyleTextAutospace EffectiveTextAutospace() const { 1311 if (!mozilla::StaticPrefs::layout_css_text_autospace_enabled()) { 1312 return mozilla::StyleTextAutospace::NO_AUTOSPACE; 1313 } 1314 return mTextAutospace; 1315 } 1316 1317 bool WhiteSpaceIsSignificant() const { 1318 return mWhiteSpaceCollapse != mozilla::StyleWhiteSpaceCollapse::Collapse && 1319 mWhiteSpaceCollapse != 1320 mozilla::StyleWhiteSpaceCollapse::PreserveBreaks; 1321 } 1322 1323 bool WhiteSpaceCanHangOrVisuallyCollapse() const { 1324 // This was originally expressed in nsTextFrame in terms of: 1325 // mWhiteSpace != StyleWhiteSpace::BreakSpaces && 1326 // WhiteSpaceCanWrapStyle() && 1327 // WhiteSpaceIsSignificant() 1328 // which simplifies to: 1329 return mTextWrapMode == mozilla::StyleTextWrapMode::Wrap && 1330 mWhiteSpaceCollapse != mozilla::StyleWhiteSpaceCollapse::BreakSpaces; 1331 } 1332 1333 bool NewlineIsSignificantStyle() const { 1334 return mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::Preserve || 1335 mWhiteSpaceCollapse == 1336 mozilla::StyleWhiteSpaceCollapse::PreserveBreaks || 1337 mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::BreakSpaces; 1338 } 1339 1340 bool WhiteSpaceOrNewlineIsSignificant() const { 1341 return NewlineIsSignificantStyle() || WhiteSpaceIsSignificant(); 1342 } 1343 1344 bool TabIsSignificant() const { 1345 return mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::Preserve || 1346 mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::BreakSpaces; 1347 } 1348 1349 bool WhiteSpaceCanWrapStyle() const { 1350 return mTextWrapMode == mozilla::StyleTextWrapMode::Wrap; 1351 } 1352 1353 bool WordCanWrapStyle() const { 1354 if (!WhiteSpaceCanWrapStyle()) { 1355 return false; 1356 } 1357 auto owrap = EffectiveOverflowWrap(); 1358 return owrap == mozilla::StyleOverflowWrap::BreakWord || 1359 owrap == mozilla::StyleOverflowWrap::Anywhere; 1360 } 1361 1362 bool HasEffectiveTextEmphasis() const { 1363 if (mTextEmphasisStyle.IsNone()) { 1364 return false; 1365 } 1366 if (mTextEmphasisStyle.IsString() && 1367 mTextEmphasisStyle.AsString().AsString().IsEmpty()) { 1368 return false; 1369 } 1370 return true; 1371 } 1372 1373 mozilla::StyleTextAlign TextAlignForLastLine() const { 1374 switch (mTextAlignLast) { 1375 case mozilla::StyleTextAlignLast::Auto: 1376 // 'text-align-last: auto' is equivalent to the value of the 1377 // 'text-align' property except when 'text-align' is set to 'justify', 1378 // in which case it is 'justify' when 'text-justify' is 'distribute' and 1379 // 'start' otherwise. 1380 // 1381 // XXX: the code below will have to change when we implement 1382 // text-justify 1383 if (mTextAlign == mozilla::StyleTextAlign::Justify) { 1384 return mozilla::StyleTextAlign::Start; 1385 } 1386 return mTextAlign; 1387 case mozilla::StyleTextAlignLast::Center: 1388 return mozilla::StyleTextAlign::Center; 1389 case mozilla::StyleTextAlignLast::Start: 1390 return mozilla::StyleTextAlign::Start; 1391 case mozilla::StyleTextAlignLast::End: 1392 return mozilla::StyleTextAlign::End; 1393 case mozilla::StyleTextAlignLast::Left: 1394 return mozilla::StyleTextAlign::Left; 1395 case mozilla::StyleTextAlignLast::Right: 1396 return mozilla::StyleTextAlign::Right; 1397 case mozilla::StyleTextAlignLast::Justify: 1398 return mozilla::StyleTextAlign::Justify; 1399 } 1400 return mozilla::StyleTextAlign::Start; 1401 } 1402 1403 bool HasWebkitTextStroke() const { return mWebkitTextStrokeWidth > 0; } 1404 1405 bool HasTextShadow() const { return !mTextShadow.IsEmpty(); } 1406 1407 // The aContextFrame argument on each of these is the frame this 1408 // style struct is for. If the frame is for SVG text or inside ruby, 1409 // the return value will be massaged to be something that makes sense 1410 // for those cases. 1411 inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const; 1412 inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const; 1413 inline bool WordCanWrap(const nsIFrame* aContextFrame) const; 1414 1415 mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM, 1416 const nsAtom* aLanguage) const; 1417 }; 1418 1419 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility { 1420 STYLE_STRUCT(nsStyleVisibility) 1421 explicit nsStyleVisibility(const mozilla::dom::Document&); 1422 1423 bool IsVisible() const { 1424 return mVisible == mozilla::StyleVisibility::Visible; 1425 } 1426 1427 bool IsCollapse() const { 1428 return mVisible == mozilla::StyleVisibility::Collapse; 1429 } 1430 1431 bool IsVisibleOrCollapsed() const { 1432 return mVisible == mozilla::StyleVisibility::Visible || 1433 mVisible == mozilla::StyleVisibility::Collapse; 1434 } 1435 1436 bool UseLegacyCollapseBehavior() const { 1437 return mMozBoxCollapse == mozilla::StyleMozBoxCollapse::Legacy; 1438 } 1439 1440 /** 1441 * Given an image request, returns the orientation that should be used 1442 * on the image. The returned orientation may differ from the style 1443 * struct's orientation member value, if the image request is not of the 1444 * same origin. 1445 * 1446 * @param aRequest The image request used to determine if same origin. 1447 */ 1448 mozilla::StyleImageOrientation UsedImageOrientation( 1449 imgIRequest* aRequest) const { 1450 return UsedImageOrientation(aRequest, mImageOrientation); 1451 } 1452 1453 /** 1454 * Given an image request and an orientation, returns the orientation 1455 * that should be used on the image. The returned orientation may differ 1456 * from the input orientation if the image request is not of the same 1457 * origin. 1458 * 1459 * @param aRequest The image request used to determine if same origin. 1460 * @param aOrientation The input orientation. 1461 */ 1462 static mozilla::StyleImageOrientation UsedImageOrientation( 1463 imgIRequest* aRequest, mozilla::StyleImageOrientation aOrientation); 1464 1465 mozilla::StyleDirection mDirection; 1466 mozilla::StyleVisibility mVisible; 1467 mozilla::StyleImageRendering mImageRendering; 1468 mozilla::StyleWritingModeProperty mWritingMode; 1469 mozilla::StyleTextOrientation mTextOrientation; 1470 mozilla::StyleMozBoxCollapse mMozBoxCollapse; 1471 mozilla::StylePrintColorAdjust mPrintColorAdjust; 1472 1473 private: 1474 mozilla::StyleImageOrientation mImageOrientation; 1475 }; 1476 1477 namespace mozilla { 1478 1479 // Note that IsAuto() does not exclude the possibility that `left` or `right` 1480 // is set; it refers only to behavior in horizontal typographic mode. 1481 inline bool StyleTextUnderlinePosition::IsAuto() const { 1482 return !(*this & (StyleTextUnderlinePosition::FROM_FONT | 1483 StyleTextUnderlinePosition::UNDER)); 1484 } 1485 inline bool StyleTextUnderlinePosition::IsFromFont() const { 1486 return bool(*this & StyleTextUnderlinePosition::FROM_FONT); 1487 } 1488 inline bool StyleTextUnderlinePosition::IsUnder() const { 1489 return bool(*this & StyleTextUnderlinePosition::UNDER); 1490 } 1491 inline bool StyleTextUnderlinePosition::IsLeft() const { 1492 return bool(*this & StyleTextUnderlinePosition::LEFT); 1493 } 1494 inline bool StyleTextUnderlinePosition::IsRight() const { 1495 return bool(*this & StyleTextUnderlinePosition::RIGHT); 1496 } 1497 1498 struct StyleTransition { 1499 StyleTransition() = default; 1500 explicit StyleTransition(const StyleTransition& aCopy); 1501 const StyleComputedTimingFunction& GetTimingFunction() const { 1502 return mTimingFunction; 1503 } 1504 const StyleTime& GetDelay() const { return mDelay; } 1505 const StyleTime& GetDuration() const { return mDuration; } 1506 const StyleTransitionProperty& GetProperty() const { return mProperty; } 1507 StyleTransitionBehavior GetBehavior() const { return mBehavior; } 1508 1509 bool operator==(const StyleTransition& aOther) const; 1510 bool operator!=(const StyleTransition&) const = default; 1511 1512 private: 1513 StyleComputedTimingFunction mTimingFunction{ 1514 StyleComputedTimingFunction::Keyword(StyleTimingKeyword::Ease)}; 1515 StyleTime mDuration{0.0}; 1516 StyleTime mDelay{0.0}; 1517 StyleTransitionProperty mProperty{StyleTransitionProperty::NonCustom( 1518 StyleNonCustomPropertyId{uint16_t(eCSSProperty_all)})}; 1519 StyleTransitionBehavior mBehavior = StyleTransitionBehavior::Normal; 1520 }; 1521 1522 struct StyleAnimation { 1523 StyleAnimation() = default; 1524 explicit StyleAnimation(const StyleAnimation& aCopy); 1525 1526 const StyleComputedTimingFunction& GetTimingFunction() const { 1527 return mTimingFunction; 1528 } 1529 const StyleTime& GetDelay() const { return mDelay; } 1530 const StyleAnimationDuration& GetDuration() const { return mDuration; } 1531 nsAtom* GetName() const { return mName._0.AsAtom(); } 1532 StyleAnimationDirection GetDirection() const { return mDirection; } 1533 StyleAnimationFillMode GetFillMode() const { return mFillMode; } 1534 StyleAnimationPlayState GetPlayState() const { return mPlayState; } 1535 float GetIterationCount() const { return mIterationCount._0; } 1536 StyleAnimationComposition GetComposition() const { return mComposition; } 1537 const StyleAnimationTimeline& GetTimeline() const { return mTimeline; } 1538 1539 bool operator==(const StyleAnimation& aOther) const; 1540 bool operator!=(const StyleAnimation&) const = default; 1541 1542 private: 1543 StyleComputedTimingFunction mTimingFunction{ 1544 StyleComputedTimingFunction::Keyword(StyleTimingKeyword::Ease)}; 1545 StyleAnimationDuration mDuration = StyleAnimationDuration::Auto(); 1546 StyleTime mDelay{0.0f}; 1547 StyleAnimationName mName; 1548 StyleAnimationDirection mDirection = StyleAnimationDirection::Normal; 1549 StyleAnimationFillMode mFillMode = StyleAnimationFillMode::None; 1550 StyleAnimationPlayState mPlayState = StyleAnimationPlayState::Running; 1551 StyleAnimationIterationCount mIterationCount{1.0f}; 1552 StyleAnimationComposition mComposition = StyleAnimationComposition::Replace; 1553 StyleAnimationTimeline mTimeline = StyleAnimationTimeline::Auto(); 1554 }; 1555 1556 struct StyleScrollTimeline { 1557 StyleScrollTimeline() = default; 1558 explicit StyleScrollTimeline(const StyleScrollTimeline& aCopy) = default; 1559 1560 nsAtom* GetName() const { return mName.AsAtom(); } 1561 StyleScrollAxis GetAxis() const { return mAxis; } 1562 1563 bool operator==(const StyleScrollTimeline&) const = default; 1564 bool operator!=(const StyleScrollTimeline&) const = default; 1565 1566 private: 1567 StyleTimelineName mName; 1568 StyleScrollAxis mAxis = StyleScrollAxis::Block; 1569 }; 1570 1571 struct StyleViewTimeline { 1572 StyleViewTimeline() = default; 1573 explicit StyleViewTimeline(const StyleViewTimeline& aCopy) = default; 1574 1575 nsAtom* GetName() const { return mName.AsAtom(); } 1576 StyleScrollAxis GetAxis() const { return mAxis; } 1577 const StyleViewTimelineInset& GetInset() const { return mInset; } 1578 1579 bool operator==(const StyleViewTimeline&) const = default; 1580 bool operator!=(const StyleViewTimeline&) const = default; 1581 1582 private: 1583 StyleTimelineName mName; 1584 StyleScrollAxis mAxis = StyleScrollAxis::Block; 1585 StyleViewTimelineInset mInset; 1586 }; 1587 1588 } // namespace mozilla 1589 1590 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay { 1591 STYLE_STRUCT(nsStyleDisplay) 1592 nsStyleDisplay(); 1593 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleDisplay*); 1594 1595 using StyleContain = mozilla::StyleContain; 1596 using StyleContentVisibility = mozilla::StyleContentVisibility; 1597 1598 nsChangeHint CalcDifference(const nsStyleDisplay& aNewData, 1599 const mozilla::ComputedStyle& aOldStyle) const; 1600 1601 nsChangeHint CalcTransformPropertyDifference( 1602 const nsStyleDisplay& aNewData) const; 1603 1604 mozilla::StyleDisplay mDisplay; 1605 // Saved mDisplay for position:absolute/fixed and float:left/right; otherwise 1606 // equal to mDisplay. 1607 mozilla::StyleDisplay mOriginalDisplay; 1608 // Equal to mContain plus any implicit containment from mContentVisibility and 1609 // mContainerType. 1610 mozilla::StyleContentVisibility mContentVisibility; 1611 mozilla::StyleContainerType mContainerType; 1612 1613 bool IsQueryContainer() const { 1614 return mContainerType != mozilla::StyleContainerType::NORMAL; 1615 } 1616 1617 // See WritingModes.h for the implementations. 1618 inline mozilla::UsedFloat UsedFloat(mozilla::WritingMode aWM) const; 1619 inline mozilla::UsedClear UsedClear(mozilla::WritingMode aWM) const; 1620 1621 private: 1622 mozilla::StyleAppearance mAppearance; 1623 mozilla::StyleContain mContain; 1624 // Equal to mContain plus any implicit containment from mContentVisibility and 1625 // mContainerType. 1626 mozilla::StyleContain mEffectiveContainment; 1627 1628 public: 1629 mozilla::StyleAppearance mDefaultAppearance; 1630 mozilla::StylePositionProperty mPosition; 1631 1632 mozilla::StyleFloat mFloat; 1633 mozilla::StyleClear mClear; 1634 mozilla::StyleBreakWithin mBreakInside; 1635 mozilla::StyleBreakBetween mBreakBefore; 1636 mozilla::StyleBreakBetween mBreakAfter; 1637 mozilla::StyleOverflow mOverflowX; 1638 mozilla::StyleOverflow mOverflowY; 1639 mozilla::StyleScrollbarGutter mScrollbarGutter; 1640 mozilla::StyleResize mResize; 1641 mozilla::StyleOrient mOrient; 1642 mozilla::StyleIsolation mIsolation; 1643 mozilla::StyleTopLayer mTopLayer; 1644 1645 mozilla::StyleTouchAction mTouchAction; 1646 mozilla::StyleScrollBehavior mScrollBehavior; 1647 mozilla::StyleOverscrollBehavior mOverscrollBehaviorX; 1648 mozilla::StyleOverscrollBehavior mOverscrollBehaviorY; 1649 mozilla::StyleOverflowAnchor mOverflowAnchor; 1650 mozilla::StyleScrollSnapAlign mScrollSnapAlign; 1651 mozilla::StyleScrollSnapStop mScrollSnapStop; 1652 mozilla::StyleScrollSnapType mScrollSnapType; 1653 1654 mozilla::StyleBackfaceVisibility mBackfaceVisibility; 1655 mozilla::StyleTransformStyle mTransformStyle; 1656 mozilla::StyleTransformBox mTransformBox; 1657 1658 mozilla::StyleTransform mTransform; 1659 mozilla::StyleRotate mRotate; 1660 1661 mozilla::StyleTranslate mTranslate; 1662 mozilla::StyleScale mScale; 1663 1664 mozilla::StyleContainerName mContainerName; 1665 mozilla::StyleWillChange mWillChange; 1666 1667 mozilla::StyleOffsetPath mOffsetPath; 1668 mozilla::LengthPercentage mOffsetDistance; 1669 mozilla::StyleOffsetRotate mOffsetRotate; 1670 mozilla::StylePositionOrAuto mOffsetAnchor; 1671 mozilla::StyleOffsetPosition mOffsetPosition; 1672 1673 mozilla::StyleTransformOrigin mTransformOrigin; 1674 mozilla::StylePerspective mChildPerspective; 1675 mozilla::Position mPerspectiveOrigin; 1676 1677 mozilla::StyleVerticalAlign mVerticalAlign; 1678 mozilla::StyleBaselineSource mBaselineSource; 1679 1680 mozilla::StyleLineClamp mWebkitLineClamp; 1681 1682 // The threshold used for extracting a shape from shape-outside: <image>. 1683 float mShapeImageThreshold = 0.0f; 1684 1685 mozilla::StyleZoom mZoom = mozilla::StyleZoom::ONE; 1686 1687 // The margin around a shape-outside: <image>. 1688 mozilla::NonNegativeLengthPercentage mShapeMargin; 1689 1690 mozilla::StyleShapeOutside mShapeOutside; 1691 1692 // 'none', 'all', or a list of one or more `<dashed-ident>` identifiers that 1693 // anchor positioned elements may reference. 1694 mozilla::StyleAnchorName mAnchorName; 1695 1696 // 'none', 'all', or a list of one or more `<dashed-ident>` identifiers that 1697 // may identify anchor positioning anchor elements. 1698 mozilla::StyleAnchorScope mAnchorScope; 1699 1700 mozilla::Maybe<mozilla::WindowButtonType> GetWindowButtonType() const { 1701 if (MOZ_LIKELY(mDefaultAppearance == mozilla::StyleAppearance::None)) { 1702 return mozilla::Nothing(); 1703 } 1704 switch (mDefaultAppearance) { 1705 case mozilla::StyleAppearance::MozWindowButtonMaximize: 1706 case mozilla::StyleAppearance::MozWindowButtonRestore: 1707 return Some(mozilla::WindowButtonType::Maximize); 1708 case mozilla::StyleAppearance::MozWindowButtonMinimize: 1709 return Some(mozilla::WindowButtonType::Minimize); 1710 case mozilla::StyleAppearance::MozWindowButtonClose: 1711 return Some(mozilla::WindowButtonType::Close); 1712 default: 1713 return mozilla::Nothing(); 1714 } 1715 } 1716 1717 bool HasAppearance() const { 1718 return EffectiveAppearance() != mozilla::StyleAppearance::None; 1719 } 1720 1721 mozilla::StyleAppearance EffectiveAppearance() const { 1722 if (MOZ_LIKELY(mAppearance == mozilla::StyleAppearance::None)) { 1723 return mAppearance; 1724 } 1725 switch (mAppearance) { 1726 case mozilla::StyleAppearance::Auto: 1727 case mozilla::StyleAppearance::Button: 1728 case mozilla::StyleAppearance::Searchfield: 1729 case mozilla::StyleAppearance::Textarea: 1730 case mozilla::StyleAppearance::Checkbox: 1731 case mozilla::StyleAppearance::Radio: 1732 case mozilla::StyleAppearance::Menulist: 1733 case mozilla::StyleAppearance::Listbox: 1734 case mozilla::StyleAppearance::Meter: 1735 case mozilla::StyleAppearance::ProgressBar: 1736 // These are all the values that behave like `auto`. 1737 return mDefaultAppearance; 1738 case mozilla::StyleAppearance::Textfield: 1739 // `appearance: textfield` should behave like `auto` on all elements 1740 // except <input type=search/number/password> elements, which we 1741 // identify using the internal -moz-default-appearance property. 1742 if (mDefaultAppearance == mozilla::StyleAppearance::NumberInput || 1743 mDefaultAppearance == mozilla::StyleAppearance::PasswordInput) { 1744 return mAppearance; 1745 } 1746 return mDefaultAppearance; 1747 case mozilla::StyleAppearance::MenulistButton: 1748 // `appearance: menulist-button` should behave like `auto` on all 1749 // elements except for drop down selects. 1750 if (mDefaultAppearance == mozilla::StyleAppearance::Menulist) { 1751 return mAppearance; 1752 } 1753 return mDefaultAppearance; 1754 default: 1755 return mAppearance; 1756 } 1757 } 1758 1759 mozilla::StyleDisplayOutside DisplayOutside() const { 1760 return mDisplay.Outside(); 1761 } 1762 mozilla::StyleDisplayInside DisplayInside() const { 1763 return mDisplay.Inside(); 1764 } 1765 bool IsListItem() const { return mDisplay.IsListItem(); } 1766 bool IsInlineFlow() const { return mDisplay.IsInlineFlow(); } 1767 1768 bool IsInlineInsideStyle() const { return mDisplay.IsInlineInside(); } 1769 1770 bool IsBlockOutsideStyle() const { 1771 return DisplayOutside() == mozilla::StyleDisplayOutside::Block; 1772 } 1773 1774 bool IsInlineOutsideStyle() const { return mDisplay.IsInlineOutside(); } 1775 1776 bool IsOriginalDisplayInlineOutside() const { 1777 return mOriginalDisplay.IsInlineOutside(); 1778 } 1779 1780 bool IsInnerTableStyle() const { return mDisplay.IsInternalTable(); } 1781 1782 bool IsInternalTableStyleExceptCell() const { 1783 return mDisplay.IsInternalTableExceptCell(); 1784 } 1785 1786 bool IsFloatingStyle() const { return mozilla::StyleFloat::None != mFloat; } 1787 1788 bool IsPositionedStyle() const { 1789 return mPosition != mozilla::StylePositionProperty::Static || 1790 (mWillChange.bits & mozilla::StyleWillChangeBits::POSITION); 1791 } 1792 1793 bool IsAbsolutelyPositionedStyle() const { 1794 return mozilla::StylePositionProperty::Absolute == mPosition || 1795 mozilla::StylePositionProperty::Fixed == mPosition; 1796 } 1797 1798 bool IsRelativelyOrStickyPositionedStyle() const { 1799 return mozilla::StylePositionProperty::Relative == mPosition || 1800 mozilla::StylePositionProperty::Sticky == mPosition; 1801 } 1802 bool IsRelativelyPositionedStyle() const { 1803 return mozilla::StylePositionProperty::Relative == mPosition; 1804 } 1805 bool IsStickyPositionedStyle() const { 1806 return mozilla::StylePositionProperty::Sticky == mPosition; 1807 } 1808 bool IsPositionForcingStackingContext() const { 1809 return mozilla::StylePositionProperty::Sticky == mPosition || 1810 mozilla::StylePositionProperty::Fixed == mPosition; 1811 } 1812 1813 bool HasAnchorName() const { return !mAnchorName.IsEmpty(); } 1814 1815 bool IsRubyDisplayType() const { return mDisplay.IsRuby(); } 1816 1817 bool IsInternalRubyDisplayType() const { return mDisplay.IsInternalRuby(); } 1818 1819 bool IsOutOfFlowStyle() const { 1820 return (IsAbsolutelyPositionedStyle() || IsFloatingStyle()); 1821 } 1822 1823 bool IsScrollableOverflow() const { 1824 // Visible and Clip can be combined but not with other values, 1825 // so checking mOverflowX is enough. 1826 return mOverflowX != mozilla::StyleOverflow::Visible && 1827 mOverflowX != mozilla::StyleOverflow::Clip; 1828 } 1829 1830 bool OverflowIsVisibleInBothAxis() const { 1831 return mOverflowX == mozilla::StyleOverflow::Visible && 1832 mOverflowY == mozilla::StyleOverflow::Visible; 1833 } 1834 1835 bool IsContainPaint() const { 1836 // Short circuit for no containment whatsoever 1837 if (!mEffectiveContainment) { 1838 return false; 1839 } 1840 return (mEffectiveContainment & StyleContain::PAINT) && 1841 !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell(); 1842 } 1843 1844 bool IsContainLayout() const { 1845 // Short circuit for no containment whatsoever 1846 if (!mEffectiveContainment) { 1847 return false; 1848 } 1849 // Note: The spec for layout containment says it should 1850 // have no effect on non-atomic, inline-level boxes. We 1851 // don't check for these here because we don't know 1852 // what type of element is involved. Callers are 1853 // responsible for checking if the box in question is 1854 // non-atomic and inline-level, and creating an 1855 // exemption as necessary. 1856 return (mEffectiveContainment & StyleContain::LAYOUT) && 1857 !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell(); 1858 } 1859 1860 bool IsContainStyle() const { 1861 return !!(mEffectiveContainment & StyleContain::STYLE); 1862 } 1863 1864 bool IsContainAny() const { return !!mEffectiveContainment; } 1865 1866 // This is similar to PrecludesSizeContainmentOrContentVisibility, but also 1867 // takes into account whether or not the given frame is a non-atomic, 1868 // inline-level box. 1869 bool PrecludesSizeContainmentOrContentVisibilityWithFrame( 1870 const nsIFrame&) const; 1871 1872 StyleContentVisibility ContentVisibility(const nsIFrame&) const; 1873 1874 /* Returns whether the element has the transform property or a related 1875 * property. */ 1876 bool HasTransformStyle() const { 1877 return HasTransformProperty() || HasIndividualTransform() || 1878 mTransformStyle == mozilla::StyleTransformStyle::Preserve3d || 1879 (mWillChange.bits & mozilla::StyleWillChangeBits::TRANSFORM) || 1880 !mOffsetPath.IsNone(); 1881 } 1882 1883 bool HasTransformProperty() const { return !mTransform._0.IsEmpty(); } 1884 1885 bool HasIndividualTransform() const { 1886 return !mRotate.IsNone() || !mTranslate.IsNone() || !mScale.IsNone(); 1887 } 1888 1889 bool HasPerspectiveStyle() const { return !mChildPerspective.IsNone(); } 1890 1891 bool BackfaceIsHidden() const { 1892 return mBackfaceVisibility == mozilla::StyleBackfaceVisibility::Hidden; 1893 } 1894 1895 // FIXME(emilio): This should be more fine-grained on each caller to 1896 // BreakBefore() / BreakAfter(). 1897 static bool ShouldBreak(mozilla::StyleBreakBetween aBreak) { 1898 switch (aBreak) { 1899 case mozilla::StyleBreakBetween::Left: 1900 case mozilla::StyleBreakBetween::Right: 1901 case mozilla::StyleBreakBetween::Page: 1902 case mozilla::StyleBreakBetween::Always: 1903 return true; 1904 case mozilla::StyleBreakBetween::Auto: 1905 case mozilla::StyleBreakBetween::Avoid: 1906 return false; 1907 default: 1908 MOZ_ASSERT_UNREACHABLE("Unknown break kind"); 1909 return false; 1910 } 1911 } 1912 1913 // These two methods are deprecated since they do not differentiate paginated 1914 // context and multi-column context. Use nsIFrame::ShouldBreakBefore() / 1915 // nsIFrame::ShouldBreakAfter() instead. 1916 bool BreakBefore() const { return ShouldBreak(mBreakBefore); } 1917 bool BreakAfter() const { return ShouldBreak(mBreakAfter); } 1918 1919 // These are defined in nsStyleStructInlines.h. 1920 1921 // The aContextFrame argument on each of these is the frame this 1922 // style struct is for. If the frame is for SVG text, the return 1923 // value will be massaged to be something that makes sense for 1924 // SVG text. 1925 inline bool IsBlockOutside(const nsIFrame* aContextFrame) const; 1926 inline bool IsInlineOutside(const nsIFrame* aContextFrame) const; 1927 inline mozilla::StyleDisplay GetDisplay(const nsIFrame* aContextFrame) const; 1928 inline bool IsFloating(const nsIFrame* aContextFrame) const; 1929 inline bool IsRelativelyOrStickyPositioned( 1930 const nsIFrame* aContextFrame) const; 1931 1932 // Note: In general, you'd want to call IsRelativelyOrStickyPositioned() 1933 // unless you want to deal with "position:relative" and "position:sticky" 1934 // differently. 1935 inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const; 1936 inline bool IsStickyPositioned(const nsIFrame* aContextFrame) const; 1937 1938 inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const; 1939 1940 // These methods are defined in nsStyleStructInlines.h. 1941 1942 /** 1943 * Returns true when the element has the transform property 1944 * or a related property, and supports CSS transforms. 1945 * aContextFrame is the frame for which this is the nsStyleDisplay. 1946 */ 1947 inline bool HasTransform(const nsIFrame* aContextFrame) const; 1948 1949 /** 1950 * Returns true when the element has the perspective property, 1951 * and supports CSS transforms. aContextFrame is the frame for 1952 * which this is the nsStyleDisplay. 1953 */ 1954 inline bool HasPerspective(const nsIFrame* aContextFrame) const; 1955 1956 inline bool 1957 IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() const; 1958 inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const; 1959 1960 mozilla::ContainSizeAxes GetContainSizeAxes(const nsIFrame& aFrame) const; 1961 }; 1962 1963 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable { 1964 STYLE_STRUCT(nsStyleTable) 1965 nsStyleTable(); 1966 1967 mozilla::StyleTableLayout mLayoutStrategy; 1968 int32_t mXSpan; // The number of columns spanned by a colgroup or col 1969 }; 1970 1971 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder { 1972 STYLE_STRUCT(nsStyleTableBorder) 1973 nsStyleTableBorder(); 1974 1975 mozilla::StyleBorderSpacing mBorderSpacing; 1976 mozilla::StyleBorderCollapse mBorderCollapse; 1977 mozilla::StyleCaptionSide mCaptionSide; 1978 mozilla::StyleEmptyCells mEmptyCells; 1979 }; 1980 1981 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent { 1982 STYLE_STRUCT(nsStyleContent) 1983 nsStyleContent(); 1984 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleContent*); 1985 1986 using CounterPair = mozilla::StyleGenericCounterPair<int32_t>; 1987 1988 /// Returns the content items that aren't alternative content. 1989 mozilla::Span<const mozilla::StyleContentItem> NonAltContentItems() const { 1990 if (!mContent.IsItems()) { 1991 return {}; 1992 } 1993 const auto& items = mContent.AsItems(); 1994 return mozilla::Span(items.items).To(items.alt_start); 1995 } 1996 1997 /// Returns the content items that /are/ alternative content. 1998 mozilla::Span<const mozilla::StyleContentItem> AltContentItems() const { 1999 if (!mContent.IsItems()) { 2000 return {}; 2001 } 2002 const auto& items = mContent.AsItems(); 2003 return mozilla::Span(items.items).From(items.alt_start); 2004 } 2005 2006 mozilla::StyleContent mContent; 2007 mozilla::StyleCounterIncrement mCounterIncrement; 2008 mozilla::StyleCounterReset mCounterReset; 2009 mozilla::StyleCounterSet mCounterSet; 2010 }; 2011 2012 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset { 2013 STYLE_STRUCT(nsStyleUIReset) 2014 nsStyleUIReset(); 2015 2016 private: 2017 mozilla::StyleUserSelect mUserSelect; // Use ComputedStyle::UserSelect() 2018 mozilla::StyleScrollbarWidth mScrollbarWidth; // Use ScrollbarWidth() 2019 2020 public: 2021 mozilla::StyleUserSelect ComputedUserSelect() const { return mUserSelect; } 2022 2023 mozilla::StyleScrollbarWidth ScrollbarWidth() const; 2024 2025 const mozilla::StyleTransitionProperty& GetTransitionProperty( 2026 uint32_t aIndex) const { 2027 return mTransitions[aIndex % mTransitionPropertyCount].GetProperty(); 2028 } 2029 const mozilla::StyleTime& GetTransitionDelay(uint32_t aIndex) const { 2030 return mTransitions[aIndex % mTransitionDelayCount].GetDelay(); 2031 } 2032 const mozilla::StyleTime& GetTransitionDuration(uint32_t aIndex) const { 2033 return mTransitions[aIndex % mTransitionDurationCount].GetDuration(); 2034 } 2035 const mozilla::StyleComputedTimingFunction& GetTransitionTimingFunction( 2036 uint32_t aIndex) const { 2037 return mTransitions[aIndex % mTransitionTimingFunctionCount] 2038 .GetTimingFunction(); 2039 } 2040 mozilla::StyleTransitionBehavior GetTransitionBehavior( 2041 uint32_t aIndex) const { 2042 return mTransitions[aIndex % mTransitionBehaviorCount].GetBehavior(); 2043 } 2044 mozilla::StyleTime GetTransitionCombinedDuration(uint32_t aIndex) const { 2045 // https://drafts.csswg.org/css-transitions/#transition-combined-duration 2046 return {std::max(GetTransitionDuration(aIndex).seconds, 0.0f) + 2047 GetTransitionDelay(aIndex).seconds}; 2048 } 2049 2050 nsAtom* GetAnimationName(uint32_t aIndex) const { 2051 return mAnimations[aIndex % mAnimationNameCount].GetName(); 2052 } 2053 const mozilla::StyleTime& GetAnimationDelay(uint32_t aIndex) const { 2054 return mAnimations[aIndex % mAnimationDelayCount].GetDelay(); 2055 } 2056 const mozilla::StyleAnimationDuration& GetAnimationDuration( 2057 uint32_t aIndex) const { 2058 return mAnimations[aIndex % mAnimationDurationCount].GetDuration(); 2059 } 2060 mozilla::StyleAnimationDirection GetAnimationDirection( 2061 uint32_t aIndex) const { 2062 return mAnimations[aIndex % mAnimationDirectionCount].GetDirection(); 2063 } 2064 mozilla::StyleAnimationFillMode GetAnimationFillMode(uint32_t aIndex) const { 2065 return mAnimations[aIndex % mAnimationFillModeCount].GetFillMode(); 2066 } 2067 mozilla::StyleAnimationPlayState GetAnimationPlayState( 2068 uint32_t aIndex) const { 2069 return mAnimations[aIndex % mAnimationPlayStateCount].GetPlayState(); 2070 } 2071 float GetAnimationIterationCount(uint32_t aIndex) const { 2072 return mAnimations[aIndex % mAnimationIterationCountCount] 2073 .GetIterationCount(); 2074 } 2075 const mozilla::StyleComputedTimingFunction& GetAnimationTimingFunction( 2076 uint32_t aIndex) const { 2077 return mAnimations[aIndex % mAnimationTimingFunctionCount] 2078 .GetTimingFunction(); 2079 } 2080 mozilla::StyleAnimationComposition GetAnimationComposition( 2081 uint32_t aIndex) const { 2082 return mAnimations[aIndex % mAnimationCompositionCount].GetComposition(); 2083 } 2084 const mozilla::StyleAnimationTimeline& GetTimeline(uint32_t aIndex) const { 2085 return mAnimations[aIndex % mAnimationTimelineCount].GetTimeline(); 2086 } 2087 2088 mozilla::StyleBoolInteger mMozForceBrokenImageIcon; 2089 mozilla::StyleBoolInteger mMozSubtreeHiddenOnlyVisually; 2090 mozilla::StyleImeMode mIMEMode; 2091 mozilla::StyleWindowDragging mWindowDragging; 2092 mozilla::StyleWindowShadow mWindowShadow; 2093 float mWindowOpacity; 2094 // The margin of the window region that should be transparent to events. 2095 mozilla::StyleLength mMozWindowInputRegionMargin; 2096 mozilla::StyleTransform mMozWindowTransform; 2097 2098 nsStyleAutoArray<mozilla::StyleTransition> mTransitions; 2099 // The number of elements in mTransitions that are not from repeating 2100 // a list due to another property being longer. 2101 uint32_t mTransitionTimingFunctionCount; 2102 uint32_t mTransitionDurationCount; 2103 uint32_t mTransitionDelayCount; 2104 uint32_t mTransitionPropertyCount; 2105 uint32_t mTransitionBehaviorCount; 2106 nsStyleAutoArray<mozilla::StyleAnimation> mAnimations; 2107 // The number of elements in mAnimations that are not from repeating 2108 // a list due to another property being longer. 2109 uint32_t mAnimationTimingFunctionCount; 2110 uint32_t mAnimationDurationCount; 2111 uint32_t mAnimationDelayCount; 2112 uint32_t mAnimationNameCount; 2113 uint32_t mAnimationDirectionCount; 2114 uint32_t mAnimationFillModeCount; 2115 uint32_t mAnimationPlayStateCount; 2116 uint32_t mAnimationIterationCountCount; 2117 uint32_t mAnimationCompositionCount; 2118 uint32_t mAnimationTimelineCount; 2119 2120 nsStyleAutoArray<mozilla::StyleScrollTimeline> mScrollTimelines; 2121 uint32_t mScrollTimelineNameCount; 2122 uint32_t mScrollTimelineAxisCount; 2123 2124 nsStyleAutoArray<mozilla::StyleViewTimeline> mViewTimelines; 2125 uint32_t mViewTimelineNameCount; 2126 uint32_t mViewTimelineAxisCount; 2127 uint32_t mViewTimelineInsetCount; 2128 2129 mozilla::StyleFieldSizing mFieldSizing; 2130 2131 bool HasViewTransitionName() const { return !mViewTransitionName.IsNone(); } 2132 2133 mozilla::StyleViewTransitionName mViewTransitionName; 2134 mozilla::StyleViewTransitionClass mViewTransitionClass; 2135 }; 2136 2137 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI { 2138 STYLE_STRUCT(nsStyleUI) 2139 nsStyleUI(); 2140 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleUI*); 2141 2142 mozilla::StyleInert mInert; 2143 mozilla::StyleMozTheme mMozTheme; 2144 2145 private: 2146 mozilla::StyleUserFocus mUserFocus; 2147 mozilla::StylePointerEvents mPointerEvents; 2148 mozilla::StyleCursor mCursor; 2149 2150 public: 2151 bool IsInert() const { return mInert == mozilla::StyleInert::Inert; } 2152 2153 mozilla::StyleUserFocus UserFocus() const { 2154 return IsInert() ? mozilla::StyleUserFocus::None : mUserFocus; 2155 } 2156 2157 // This is likely not the getter you want (you probably want 2158 // ComputedStyle::PointerEvents(). 2159 mozilla::StylePointerEvents ComputedPointerEvents() const { 2160 return mPointerEvents; 2161 } 2162 2163 const mozilla::StyleCursor& Cursor() const { 2164 static mozilla::StyleCursor sAuto{{}, mozilla::StyleCursorKind::Auto}; 2165 return IsInert() ? sAuto : mCursor; 2166 } 2167 2168 mozilla::StyleColorOrAuto mAccentColor; 2169 mozilla::StyleCaretColor mCaretColor; 2170 mozilla::StyleScrollbarColor mScrollbarColor; 2171 mozilla::StyleColorScheme mColorScheme; 2172 2173 bool HasCustomScrollbars() const { return !mScrollbarColor.IsAuto(); } 2174 }; 2175 2176 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL { 2177 STYLE_STRUCT(nsStyleXUL) 2178 nsStyleXUL(); 2179 2180 float mBoxFlex; 2181 int32_t mBoxOrdinal; 2182 mozilla::StyleBoxAlign mBoxAlign; 2183 mozilla::StyleBoxDirection mBoxDirection; 2184 mozilla::StyleBoxOrient mBoxOrient; 2185 mozilla::StyleBoxPack mBoxPack; 2186 }; 2187 2188 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn { 2189 STYLE_STRUCT(nsStyleColumn) 2190 nsStyleColumn(); 2191 2192 mozilla::StyleColumnCount mColumnCount = mozilla::StyleColumnCount::Auto(); 2193 mozilla::NonNegativeLengthOrAuto mColumnWidth; 2194 2195 mozilla::StyleColor mColumnRuleColor; 2196 mozilla::StyleBorderStyle mColumnRuleStyle; 2197 mozilla::StyleColumnFill mColumnFill = mozilla::StyleColumnFill::Balance; 2198 mozilla::StyleColumnSpan mColumnSpan = mozilla::StyleColumnSpan::None; 2199 2200 nscoord GetColumnRuleWidth() const { 2201 if (!IsVisibleBorderStyle(mColumnRuleStyle)) { 2202 return 0; 2203 } 2204 return mColumnRuleWidth; 2205 } 2206 2207 bool IsColumnContainerStyle() const { 2208 return !mColumnCount.IsAuto() || !mColumnWidth.IsAuto(); 2209 } 2210 2211 bool IsColumnSpanStyle() const { 2212 return mColumnSpan == mozilla::StyleColumnSpan::All; 2213 } 2214 2215 protected: 2216 mozilla::StyleBorderSideWidth mColumnRuleWidth; 2217 }; 2218 2219 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG { 2220 STYLE_STRUCT(nsStyleSVG) 2221 nsStyleSVG(); 2222 2223 mozilla::StyleSVGPaint mFill; 2224 mozilla::StyleSVGPaint mStroke; 2225 mozilla::StyleUrlOrNone mMarkerEnd; 2226 mozilla::StyleUrlOrNone mMarkerMid; 2227 mozilla::StyleUrlOrNone mMarkerStart; 2228 mozilla::StyleMozContextProperties mMozContextProperties; 2229 2230 mozilla::StyleSVGStrokeDashArray mStrokeDasharray; 2231 mozilla::StyleSVGLength mStrokeDashoffset; 2232 mozilla::StyleSVGWidth mStrokeWidth; 2233 2234 mozilla::StyleSVGOpacity mFillOpacity; 2235 float mStrokeMiterlimit; 2236 mozilla::StyleSVGOpacity mStrokeOpacity; 2237 2238 mozilla::StyleFillRule mClipRule; 2239 mozilla::StyleColorInterpolation mColorInterpolation; 2240 mozilla::StyleColorInterpolation mColorInterpolationFilters; 2241 mozilla::StyleFillRule mFillRule; 2242 mozilla::StyleSVGPaintOrder mPaintOrder; 2243 mozilla::StyleShapeRendering mShapeRendering; 2244 mozilla::StyleStrokeLinecap mStrokeLinecap; 2245 mozilla::StyleStrokeLinejoin mStrokeLinejoin; 2246 mozilla::StyleDominantBaseline mDominantBaseline; 2247 mozilla::StyleTextAnchor mTextAnchor; 2248 2249 /// Returns true if style has been set to expose the computed values of 2250 /// certain properties (such as 'fill') to the contents of any linked images. 2251 bool ExposesContextProperties() const { 2252 return bool(mMozContextProperties.bits); 2253 } 2254 2255 bool HasMarker() const { 2256 return mMarkerStart.IsUrl() || mMarkerMid.IsUrl() || mMarkerEnd.IsUrl(); 2257 } 2258 2259 /** 2260 * Returns true if the stroke is not "none" and the stroke-opacity is greater 2261 * than zero (or a context-dependent value). 2262 * 2263 * This ignores stroke-widths as that depends on the context. 2264 */ 2265 bool HasStroke() const { 2266 if (mStroke.kind.IsNone()) { 2267 return false; 2268 } 2269 return !mStrokeOpacity.IsOpacity() || mStrokeOpacity.AsOpacity() > 0; 2270 } 2271 2272 /** 2273 * Returns true if the fill is not "none" and the fill-opacity is greater 2274 * than zero (or a context-dependent value). 2275 */ 2276 bool HasFill() const { 2277 if (mFill.kind.IsNone()) { 2278 return false; 2279 } 2280 return !mFillOpacity.IsOpacity() || mFillOpacity.AsOpacity() > 0; 2281 } 2282 }; 2283 2284 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset { 2285 STYLE_STRUCT(nsStyleSVGReset) 2286 nsStyleSVGReset(); 2287 void TriggerImageLoads(mozilla::dom::Document&, const nsStyleSVGReset*); 2288 2289 bool HasClipPath() const { return !mClipPath.IsNone(); } 2290 2291 bool HasMask() const; 2292 2293 bool HasNonScalingStroke() const { 2294 return mVectorEffect.HasNonScalingStroke(); 2295 } 2296 2297 // geometry properties 2298 mozilla::LengthPercentage mX; 2299 mozilla::LengthPercentage mY; 2300 mozilla::LengthPercentage mCx; 2301 mozilla::LengthPercentage mCy; 2302 mozilla::NonNegativeLengthPercentageOrAuto mRx; 2303 mozilla::NonNegativeLengthPercentageOrAuto mRy; 2304 mozilla::NonNegativeLengthPercentage mR; 2305 2306 nsStyleImageLayers mMask; 2307 mozilla::StyleClipPath mClipPath; 2308 mozilla::StyleColor mStopColor; 2309 mozilla::StyleColor mFloodColor; 2310 mozilla::StyleColor mLightingColor; 2311 2312 float mStopOpacity; 2313 float mFloodOpacity; 2314 2315 mozilla::StyleVectorEffect mVectorEffect; 2316 mozilla::StyleMaskType mMaskType; 2317 2318 mozilla::StyleDProperty mD; 2319 }; 2320 2321 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects { 2322 STYLE_STRUCT(nsStyleEffects) 2323 nsStyleEffects(); 2324 2325 bool HasFilters() const { return !mFilters.IsEmpty(); } 2326 2327 bool HasBackdropFilters() const { return !mBackdropFilters.IsEmpty(); } 2328 2329 bool HasBoxShadowWithInset(bool aInset) const { 2330 for (const auto& shadow : mBoxShadow.AsSpan()) { 2331 if (shadow.inset == aInset) { 2332 return true; 2333 } 2334 } 2335 return false; 2336 } 2337 2338 bool HasMixBlendMode() const { 2339 return mMixBlendMode != mozilla::StyleBlend::Normal; 2340 } 2341 2342 bool IsOpaque() const { return mOpacity >= 1.0f; } 2343 2344 bool IsTransparent() const { return mOpacity == 0.0f; } 2345 2346 mozilla::StyleOwnedSlice<mozilla::StyleFilter> mFilters; 2347 mozilla::StyleOwnedSlice<mozilla::StyleBoxShadow> mBoxShadow; 2348 mozilla::StyleOwnedSlice<mozilla::StyleFilter> mBackdropFilters; 2349 mozilla::StyleClipRectOrAuto mClip; // offsets from UL border edge 2350 float mOpacity; 2351 mozilla::StyleBlend mMixBlendMode; 2352 }; 2353 2354 #undef STYLE_STRUCT 2355 2356 #define STATIC_ASSERT_TYPE_LAYOUTS_MATCH(T1, T2) \ 2357 static_assert(sizeof(T1) == sizeof(T2), \ 2358 "Size mismatch between " #T1 " and " #T2); \ 2359 static_assert(alignof(T1) == alignof(T2), \ 2360 "Align mismatch between " #T1 " and " #T2); 2361 2362 #define STATIC_ASSERT_FIELD_OFFSET_MATCHES(T1, T2, field) \ 2363 static_assert(offsetof(T1, field) == offsetof(T2, field), \ 2364 "Field offset mismatch of " #field " between " #T1 \ 2365 " and " #T2); 2366 2367 /** 2368 * These *_Simple types are used to map Gecko types to layout-equivalent but 2369 * simpler Rust types, to aid Rust binding generation. 2370 * 2371 * If something in this types or the assertions below needs to change, ask 2372 * bholley, heycam or emilio before! 2373 * 2374 * <div rustbindgen="true" replaces="nsPoint"> 2375 */ 2376 struct nsPoint_Simple { 2377 nscoord x, y; 2378 }; 2379 2380 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple); 2381 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x); 2382 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y); 2383 2384 /** 2385 * <div rustbindgen="true" replaces="nsMargin"> 2386 */ 2387 struct nsMargin_Simple { 2388 nscoord top, right, bottom, left; 2389 }; 2390 2391 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple); 2392 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top); 2393 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right); 2394 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom); 2395 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left); 2396 2397 /** 2398 * <div rustbindgen="true" replaces="nsRect"> 2399 */ 2400 struct nsRect_Simple { 2401 nscoord x, y, width, height; 2402 }; 2403 2404 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple); 2405 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x); 2406 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y); 2407 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width); 2408 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height); 2409 2410 /** 2411 * <div rustbindgen="true" replaces="nsSize"> 2412 */ 2413 struct nsSize_Simple { 2414 nscoord width, height; 2415 }; 2416 2417 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple); 2418 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width); 2419 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height); 2420 2421 #endif /* nsStyleStruct_h___ */