-
Notifications
You must be signed in to change notification settings - Fork 0
/
nsStyleStruct.h
2209 lines (1844 loc) · 78.4 KB
/
nsStyleStruct.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* structs that contain the data provided by ComputedStyle, the
* internal API for computed style data for an element
*/
#ifndef nsStyleStruct_h___
#define nsStyleStruct_h___
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/ServoStyleConstsInlines.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/UniquePtr.h"
#include "nsColor.h"
#include "nsCoord.h"
#include "nsMargin.h"
#include "nsFont.h"
#include "nsStyleAutoArray.h"
#include "nsStyleConsts.h"
#include "nsChangeHint.h"
#include "nsTimingFunction.h"
#include "nsTArray.h"
#include "imgIContainer.h"
#include "imgRequestProxy.h"
#include "CounterStyleManager.h"
#include <cstddef> // offsetof()
#include "X11UndefineNone.h"
class nsIFrame;
class nsIURI;
class nsTextFrame;
struct nsStyleDisplay;
struct nsStyleVisibility;
namespace mozilla {
class ComputedStyle;
struct IntrinsicSize;
} // namespace mozilla
namespace mozilla {
using Position = StylePosition;
template <>
inline bool StylePosition::HasPercent() const {
return horizontal.HasPercent() || vertical.HasPercent();
}
/**
* True if the effective background image position described by this depends on
* the size of the corresponding frame.
*/
template <>
inline bool StylePosition::DependsOnPositioningAreaSize() const {
return HasPercent();
}
template <>
inline Position Position::FromPercentage(float aPercent) {
return {LengthPercentage::FromPercentage(aPercent),
LengthPercentage::FromPercentage(aPercent)};
}
/**
* Convenience struct for querying if a given box has size-containment in
* either axis.
*/
struct ContainSizeAxes {
ContainSizeAxes(bool aIContained, bool aBContained)
: mIContained(aIContained), mBContained(aBContained) {}
bool IsBoth() const { return mIContained && mBContained; }
bool IsAny() const { return mIContained || mBContained; }
/**
* Return a contained size from an uncontained size.
*/
nsSize ContainSize(const nsSize& aUncontainedSize,
const WritingMode& aWM) const;
IntrinsicSize ContainIntrinsicSize(const IntrinsicSize& aUncontainedSize,
const WritingMode& aWM) const;
const bool mIContained;
const bool mBContained;
};
} // namespace mozilla
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont {
nsStyleFont(const nsStyleFont& aStyleFont);
explicit nsStyleFont(const mozilla::dom::Document&);
MOZ_COUNTED_DTOR(nsStyleFont)
static constexpr bool kHasTriggerImageLoads = false;
nsChangeHint CalcDifference(const nsStyleFont& aNewData) const;
/**
* Return a given size multiplied by the current text zoom factor (in
* aPresContext).
*
* The size is allowed to be negative, but the caller is expected to deal with
* negative results.
*/
static mozilla::Length ZoomText(const mozilla::dom::Document&,
mozilla::Length);
nsFont mFont;
// Our "computed size". Can be different from mFont.size which is our "actual
// size" and is enforced to be >= the user's preferred min-size. mFont.size
// should be used for display purposes while mSize is the value to return in
// getComputedStyle() for example.
mozilla::NonNegativeLength mSize;
// In stylo these three track whether the size is keyword-derived
// and if so if it has been modified by a factor/offset
float mFontSizeFactor;
mozilla::Length mFontSizeOffset;
mozilla::StyleFontSizeKeyword mFontSizeKeyword;
// math-depth support (used for MathML scriptlevel)
int8_t mMathDepth;
// MathML mathvariant support
mozilla::StyleMathVariant mMathVariant;
// math-style support (used for MathML displaystyle)
uint8_t mMathStyle;
// allow different min font-size for certain cases
uint8_t mMinFontSizeRatio; // percent * 100
// was mLanguage set based on a lang attribute in the document?
bool mExplicitLanguage;
// should calls to ZoomText() and UnZoomText() be made to the font
// size on this nsStyleFont? Also used to prevent SVG text from being
// affected by minimum font size pref.
bool mAllowZoomAndMinSize;
// The value mSize would have had if scriptminsize had never been applied
mozilla::NonNegativeLength mScriptUnconstrainedSize;
mozilla::Length mScriptMinSize;
float mScriptSizeMultiplier;
RefPtr<nsAtom> mLanguage;
};
// TODO(emilio, bug 1564526): Evaluate whether this is still needed.
struct CachedBorderImageData {
~CachedBorderImageData() { PurgeCachedImages(); }
// Caller are expected to ensure that the value of aSize is different from the
// cached one since the method won't do the check.
void SetCachedSVGViewportSize(const mozilla::Maybe<nsSize>& aSize) {
mCachedSVGViewportSize = aSize;
}
const mozilla::Maybe<nsSize>& GetCachedSVGViewportSize() const {
return mCachedSVGViewportSize;
}
void PurgeCachedImages();
void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) {
mSubImages.EnsureLengthAtLeast(aIndex + 1);
mSubImages[aIndex] = aSubImage;
}
imgIContainer* GetSubImage(uint8_t aIndex) {
return mSubImages.SafeElementAt(aIndex);
}
// These methods are used for the caller to caches the sub images created
// during a border-image paint operation
void PurgeCacheForViewportChange(
const mozilla::Maybe<nsSize>& aSVGViewportSize,
const bool aHasIntrinsicRatio);
private:
// If this is a SVG border-image, we save the size of the SVG viewport that
// we used when rasterizing any cached border-image subimages. (The viewport
// size matters for percent-valued sizes & positions in inner SVG doc).
mozilla::Maybe<nsSize> mCachedSVGViewportSize;
nsTArray<RefPtr<imgIContainer>> mSubImages;
};
struct nsStyleImageLayers {
enum class LayerType : uint8_t { Background = 0, Mask };
explicit nsStyleImageLayers(LayerType aType);
nsStyleImageLayers(const nsStyleImageLayers& aSource);
MOZ_COUNTED_DTOR(nsStyleImageLayers)
struct Repeat {
mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat;
// Initialize nothing
Repeat() = default;
bool IsInitialValue() const {
return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat &&
mYRepeat == mozilla::StyleImageLayerRepeat::Repeat;
}
bool DependsOnPositioningAreaSize() const {
return mXRepeat == mozilla::StyleImageLayerRepeat::Space ||
mYRepeat == mozilla::StyleImageLayerRepeat::Space;
}
// Initialize to initial values
void SetInitialValues() {
mXRepeat = mozilla::StyleImageLayerRepeat::Repeat;
mYRepeat = mozilla::StyleImageLayerRepeat::Repeat;
}
bool operator==(const Repeat& aOther) const {
return mXRepeat == aOther.mXRepeat && mYRepeat == aOther.mYRepeat;
}
bool operator!=(const Repeat& aOther) const { return !(*this == aOther); }
};
struct Layer {
typedef mozilla::StyleGeometryBox StyleGeometryBox;
typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment;
typedef mozilla::StyleBackgroundSize StyleBackgroundSize;
mozilla::StyleImage mImage;
mozilla::Position mPosition;
StyleBackgroundSize mSize;
StyleGeometryBox mClip;
MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin;
// This property is used for background layer only.
// For a mask layer, it should always be the initial value, which is
// StyleImageLayerAttachment::Scroll.
StyleImageLayerAttachment mAttachment;
// This property is used for background layer only.
// For a mask layer, it should always be the initial value, which is
// StyleBlend::Normal.
mozilla::StyleBlend mBlendMode;
// This property is used for mask layer only.
// For a background layer, it should always be the initial value, which is
// StyleMaskComposite::Add.
mozilla::StyleMaskComposite mComposite;
// mask-only property. This property is used for mask layer only. For a
// background layer, it should always be the initial value, which is
// StyleMaskMode::MatchSource.
mozilla::StyleMaskMode mMaskMode;
Repeat mRepeat;
// This constructor does not initialize mRepeat or mOrigin and Initialize()
// must be called to do that.
Layer();
~Layer();
// Initialize mRepeat and mOrigin by specified layer type
void Initialize(LayerType aType);
void ResolveImage(mozilla::dom::Document& aDocument,
const Layer* aOldLayer) {
mImage.ResolveImage(aDocument, aOldLayer ? &aOldLayer->mImage : nullptr);
}
// True if the rendering of this layer might change when the size
// of the background positioning area changes. This is true for any
// non-solid-color background whose position or size depends on
// the size of the positioning area. It's also true for SVG images
// whose root <svg> node has a viewBox.
bool RenderingMightDependOnPositioningAreaSizeChange() const;
// Compute the change hint required by changes in just this layer.
nsChangeHint CalcDifference(const Layer& aNewLayer) const;
// An equality operator that compares the images using URL-equality
// rather than pointer-equality.
bool operator==(const Layer& aOther) const;
bool operator!=(const Layer& aOther) const { return !(*this == aOther); }
};
// The (positive) number of computed values of each property, since
// the lengths of the lists are independent.
uint32_t mAttachmentCount;
uint32_t mClipCount;
uint32_t mOriginCount;
uint32_t mRepeatCount;
uint32_t mPositionXCount;
uint32_t mPositionYCount;
uint32_t mImageCount;
uint32_t mSizeCount;
uint32_t mMaskModeCount;
uint32_t mBlendModeCount;
uint32_t mCompositeCount;
// Layers are stored in an array, matching the top-to-bottom order in
// which they are specified in CSS. The number of layers to be used
// should come from the background-image property. We create
// additional |Layer| objects for *any* property, not just
// background-image. This means that the bottommost layer that
// callers in layout care about (which is also the one whose
// background-clip applies to the background-color) may not be last
// layer. In layers below the bottom layer, properties will be
// uninitialized unless their count, above, indicates that they are
// present.
nsStyleAutoArray<Layer> mLayers;
const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
void ResolveImages(mozilla::dom::Document& aDocument,
const nsStyleImageLayers* aOldLayers) {
for (uint32_t i = 0; i < mImageCount; ++i) {
const Layer* oldLayer = (aOldLayers && aOldLayers->mLayers.Length() > i)
? &aOldLayers->mLayers[i]
: nullptr;
mLayers[i].ResolveImage(aDocument, oldLayer);
}
}
// Fill unspecified layers by cycling through their values
// till they all are of length aMaxItemCount
void FillAllLayers(uint32_t aMaxItemCount);
nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
nsStyleImageLayers::LayerType aType) const;
nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther) = default;
bool operator==(const nsStyleImageLayers& aOther) const;
static const nsCSSPropertyID kBackgroundLayerTable[];
static const nsCSSPropertyID kMaskLayerTable[];
#define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
for (uint32_t var_ = (layers_).mImageCount; var_-- != 0;)
#define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, \
start_, count_) \
NS_ASSERTION( \
(int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, \
"Invalid layer start!"); \
NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, \
"Invalid layer range!"); \
for (uint32_t var_ = (start_) + 1; \
var_-- != (uint32_t)((start_) + 1 - (count_));)
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
explicit nsStyleBackground(const mozilla::dom::Document&);
nsStyleBackground(const nsStyleBackground& aOther);
~nsStyleBackground();
// Resolves and tracks the images in mImage. Only called with a Servo-backed
// style system, where those images must be resolved later than the OMT
// nsStyleBackground constructor call.
void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBackground*);
static constexpr bool kHasTriggerImageLoads = true;
nsChangeHint CalcDifference(const nsStyleBackground& aNewData) const;
// Return the background color as nscolor.
nscolor BackgroundColor(const nsIFrame* aFrame) const;
nscolor BackgroundColor(const mozilla::ComputedStyle* aStyle) const;
// True if this background is completely transparent.
bool IsTransparent(const nsIFrame* aFrame) const;
bool IsTransparent(mozilla::ComputedStyle* aStyle) const;
// We have to take slower codepaths for fixed background attachment,
// but we don't want to do that when there's no image.
// Not inline because it uses an nsCOMPtr<imgIRequest>
// FIXME: Should be in nsStyleStructInlines.h.
bool HasFixedBackground(nsIFrame* aFrame) const;
// Checks to see if this has a non-empty image with "local" attachment.
// This is defined in nsStyleStructInlines.h.
inline bool HasLocalBackground() const;
const nsStyleImageLayers::Layer& BottomLayer() const {
return mImage.BottomLayer();
}
nsStyleImageLayers mImage;
mozilla::StyleColor mBackgroundColor;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
explicit nsStyleMargin(const mozilla::dom::Document&);
nsStyleMargin(const nsStyleMargin& aMargin);
MOZ_COUNTED_DTOR(nsStyleMargin)
static constexpr bool kHasTriggerImageLoads = false;
nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const;
bool GetMargin(nsMargin& aMargin) const {
bool convertsToLength = mMargin.All(
[](const auto& aLength) { return aLength.ConvertsToLength(); });
if (!convertsToLength) {
return false;
}
for (const auto side : mozilla::AllPhysicalSides()) {
aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength();
}
return true;
}
nsMargin GetScrollMargin() const {
return nsMargin(mScrollMargin.Get(mozilla::eSideTop).ToAppUnits(),
mScrollMargin.Get(mozilla::eSideRight).ToAppUnits(),
mScrollMargin.Get(mozilla::eSideBottom).ToAppUnits(),
mScrollMargin.Get(mozilla::eSideLeft).ToAppUnits());
}
// Return true if either the start or end side in the axis is 'auto'.
// (defined in WritingModes.h since we need the full WritingMode type)
inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const;
inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode) const;
mozilla::StyleRect<mozilla::LengthPercentageOrAuto> mMargin;
mozilla::StyleRect<mozilla::StyleLength> mScrollMargin;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding {
explicit nsStylePadding(const mozilla::dom::Document&);
nsStylePadding(const nsStylePadding& aPadding);
MOZ_COUNTED_DTOR(nsStylePadding)
static constexpr bool kHasTriggerImageLoads = false;
nsChangeHint CalcDifference(const nsStylePadding& aNewData) const;
mozilla::StyleRect<mozilla::NonNegativeLengthPercentage> mPadding;
mozilla::StyleRect<mozilla::NonNegativeLengthPercentageOrAuto> mScrollPadding;
inline bool IsWidthDependent() const {
return !mPadding.All(
[](const auto& aLength) { return aLength.ConvertsToLength(); });
}
bool GetPadding(nsMargin& aPadding) const {
if (IsWidthDependent()) {
return false;
}
for (const auto side : mozilla::AllPhysicalSides()) {
// Clamp negative calc() to 0.
aPadding.Side(side) = std::max(mPadding.Get(side).ToLength(), 0);
}
return true;
}
};
// Border widths are rounded to the nearest-below integer number of pixels,
// but values between zero and one device pixels are always rounded up to
// one device pixel.
#define NS_ROUND_BORDER_TO_PIXELS(l, tpp) \
((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
// Returns if the given border style type is visible or not
static bool IsVisibleBorderStyle(mozilla::StyleBorderStyle aStyle) {
return (aStyle != mozilla::StyleBorderStyle::None &&
aStyle != mozilla::StyleBorderStyle::Hidden);
}
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder {
explicit nsStyleBorder(const mozilla::dom::Document&);
nsStyleBorder(const nsStyleBorder& aBorder);
~nsStyleBorder();
// Resolves and tracks mBorderImageSource. Only called with a Servo-backed
// style system, where those images must be resolved later than the OMT
// nsStyleBorder constructor call.
void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBorder*);
static constexpr bool kHasTriggerImageLoads = true;
nsChangeHint CalcDifference(const nsStyleBorder& aNewData) const;
// Return whether aStyle is a visible style. Invisible styles cause
// the relevant computed border width to be 0.
// Note that this does *not* consider the effects of 'border-image':
// if border-style is none, but there is a loaded border image,
// HasVisibleStyle will be false even though there *is* a border.
bool HasVisibleStyle(mozilla::Side aSide) const {
return IsVisibleBorderStyle(mBorderStyle[aSide]);
}
// aBorderWidth is in twips
void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth) {
nscoord roundedWidth =
NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
mBorder.Side(aSide) = roundedWidth;
if (HasVisibleStyle(aSide)) {
mComputedBorder.Side(aSide) = roundedWidth;
}
}
// Get the computed border (plus rounding). This does consider the
// effects of 'border-style: none', but does not consider
// 'border-image'.
const nsMargin& GetComputedBorder() const { return mComputedBorder; }
bool HasBorder() const {
return mComputedBorder != nsMargin(0, 0, 0, 0) ||
!mBorderImageSource.IsNone();
}
// Get the actual border width for a particular side, in appunits. Note that
// this is zero if and only if there is no border to be painted for this
// side. That is, this value takes into account the border style and the
// value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
nscoord GetComputedBorderWidth(mozilla::Side aSide) const {
return GetComputedBorder().Side(aSide);
}
mozilla::StyleBorderStyle GetBorderStyle(mozilla::Side aSide) const {
NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
return mBorderStyle[aSide];
}
void SetBorderStyle(mozilla::Side aSide, mozilla::StyleBorderStyle aStyle) {
NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
mBorderStyle[aSide] = aStyle;
mComputedBorder.Side(aSide) =
(HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
}
inline bool IsBorderImageSizeAvailable() const {
return mBorderImageSource.IsSizeAvailable();
}
nsMargin GetImageOutset() const;
imgIRequest* GetBorderImageRequest() const {
return mBorderImageSource.GetImageRequest();
}
public:
mozilla::StyleBorderRadius mBorderRadius; // coord, percent
mozilla::StyleImage mBorderImageSource;
mozilla::StyleBorderImageWidth mBorderImageWidth;
mozilla::StyleNonNegativeLengthOrNumberRect mBorderImageOutset;
mozilla::StyleBorderImageSlice mBorderImageSlice; // factor, percent
mozilla::StyleBorderImageRepeat mBorderImageRepeatH;
mozilla::StyleBorderImageRepeat mBorderImageRepeatV;
mozilla::StyleFloatEdge mFloatEdge;
mozilla::StyleBoxDecorationBreak mBoxDecorationBreak;
protected:
mozilla::StyleBorderStyle mBorderStyle[4]; // StyleBorderStyle::*
public:
// the colors to use for a simple border.
// not used for -moz-border-colors
mozilla::StyleColor mBorderTopColor;
mozilla::StyleColor mBorderRightColor;
mozilla::StyleColor mBorderBottomColor;
mozilla::StyleColor mBorderLeftColor;
mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) {
switch (aSide) {
case mozilla::eSideTop:
return mBorderTopColor;
case mozilla::eSideRight:
return mBorderRightColor;
case mozilla::eSideBottom:
return mBorderBottomColor;
case mozilla::eSideLeft:
return mBorderLeftColor;
}
MOZ_ASSERT_UNREACHABLE("Unknown side");
return mBorderTopColor;
}
const mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) const {
switch (aSide) {
case mozilla::eSideTop:
return mBorderTopColor;
case mozilla::eSideRight:
return mBorderRightColor;
case mozilla::eSideBottom:
return mBorderBottomColor;
case mozilla::eSideLeft:
return mBorderLeftColor;
}
MOZ_ASSERT_UNREACHABLE("Unknown side");
return mBorderTopColor;
}
static mozilla::StyleColor nsStyleBorder::*BorderColorFieldFor(
mozilla::Side aSide) {
switch (aSide) {
case mozilla::eSideTop:
return &nsStyleBorder::mBorderTopColor;
case mozilla::eSideRight:
return &nsStyleBorder::mBorderRightColor;
case mozilla::eSideBottom:
return &nsStyleBorder::mBorderBottomColor;
case mozilla::eSideLeft:
return &nsStyleBorder::mBorderLeftColor;
}
MOZ_ASSERT_UNREACHABLE("Unknown side");
return nullptr;
}
protected:
// mComputedBorder holds the CSS2.1 computed border-width values.
// In particular, these widths take into account the border-style
// for the relevant side, and the values are rounded to the nearest
// device pixel (which is not part of the definition of computed
// values). The presence or absence of a border-image does not
// affect border-width values.
nsMargin mComputedBorder;
// mBorder holds the nscoord values for the border widths as they
// would be if all the border-style values were visible (not hidden
// or none). This member exists so that when we create structs
// using the copy constructor during style resolution the new
// structs will know what the specified values of the border were in
// case they have more specific rules setting the border style.
//
// Note that this isn't quite the CSS specified value, since this
// has had the enumerated border widths converted to lengths, and
// all lengths converted to twips. But it's not quite the computed
// value either. The values are rounded to the nearest device pixel.
nsMargin mBorder;
private:
nscoord mTwipsPerPixel;
nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline {
explicit nsStyleOutline(const mozilla::dom::Document&);
nsStyleOutline(const nsStyleOutline& aOutline);
MOZ_COUNTED_DTOR(nsStyleOutline)
static constexpr bool kHasTriggerImageLoads = false;
nsChangeHint CalcDifference(const nsStyleOutline& aNewData) const;
// This is the specified value of outline-width, but with length values
// computed to absolute. mActualOutlineWidth stores the outline-width
// value used by layout. (We must store mOutlineWidth for the same
// style struct resolution reasons that we do nsStyleBorder::mBorder;
// see that field's comment.)
nscoord mOutlineWidth;
mozilla::Length mOutlineOffset;
mozilla::StyleColor mOutlineColor;
mozilla::StyleOutlineStyle mOutlineStyle;
nscoord GetOutlineWidth() const { return mActualOutlineWidth; }
bool ShouldPaintOutline() const {
if (mOutlineStyle.IsAuto()) {
return true;
}
if (GetOutlineWidth() > 0) {
MOZ_ASSERT(
mOutlineStyle.AsBorderStyle() != mozilla::StyleBorderStyle::None,
"outline-style: none implies outline-width of zero");
return true;
}
return false;
}
protected:
// The actual value of outline-width is the computed value (an absolute
// length, forced to zero when outline-style is none) rounded to device
// pixels. This is the value used by layout.
nscoord mActualOutlineWidth;
nscoord mTwipsPerPixel;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList {
explicit nsStyleList(const mozilla::dom::Document&);
nsStyleList(const nsStyleList& aStyleList);
~nsStyleList();
private:
nsStyleList& operator=(const nsStyleList& aOther) = delete;
public:
void TriggerImageLoads(mozilla::dom::Document&, const nsStyleList*);
static constexpr bool kHasTriggerImageLoads = true;
nsChangeHint CalcDifference(const nsStyleList& aNewData,
const nsStyleDisplay& aOldDisplay) const;
nsRect GetImageRegion() const {
if (!mImageRegion.IsRect()) {
return nsRect();
}
return mImageRegion.AsRect().ToLayoutRect(0);
}
already_AddRefed<nsIURI> GetListStyleImageURI() const;
uint8_t mListStylePosition;
mozilla::CounterStylePtr mCounterStyle;
mozilla::StyleQuotes mQuotes;
mozilla::StyleImage mListStyleImage;
// the rect to use within an image.
mozilla::StyleClipRectOrAuto mImageRegion;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePage {
using StylePageSize = mozilla::StylePageSize;
using StylePageName = mozilla::StylePageName;
nsStylePage(const nsStylePage& aOther) = default;
nsStylePage& operator=(const nsStylePage& aOther) = default;
explicit nsStylePage(const mozilla::dom::Document&)
: mSize(StylePageSize::Auto()), mPage(StylePageName::Auto()) {}
static constexpr bool kHasTriggerImageLoads = false;
nsChangeHint CalcDifference(const nsStylePage& aNewData) const;
// page-size property.
StylePageSize mSize;
// page-name property.
StylePageName mPage;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto;
using Position = mozilla::Position;
template <typename T>
using StyleRect = mozilla::StyleRect<T>;
using StyleSize = mozilla::StyleSize;
using StyleMaxSize = mozilla::StyleMaxSize;
using WritingMode = mozilla::WritingMode;
using LogicalAxis = mozilla::LogicalAxis;
using StyleImplicitGridTracks = mozilla::StyleImplicitGridTracks;
using ComputedStyle = mozilla::ComputedStyle;
using StyleAlignSelf = mozilla::StyleAlignSelf;
using StyleJustifySelf = mozilla::StyleJustifySelf;
explicit nsStylePosition(const mozilla::dom::Document&);
nsStylePosition(const nsStylePosition& aOther);
~nsStylePosition();
static constexpr bool kHasTriggerImageLoads = false;
nsChangeHint CalcDifference(
const nsStylePosition& aNewData,
const nsStyleVisibility& aOldStyleVisibility) const;
// Returns whether we need to compute an hypothetical position if we were
// absolutely positioned.
bool NeedsHypotheticalPositionIfAbsPos() const {
return (mOffset.Get(mozilla::eSideRight).IsAuto() &&
mOffset.Get(mozilla::eSideLeft).IsAuto()) ||
(mOffset.Get(mozilla::eSideTop).IsAuto() &&
mOffset.Get(mozilla::eSideBottom).IsAuto());
}
/**
* Return the used value for 'align-self' given our parent ComputedStyle
* (or null for the root).
*/
StyleAlignSelf UsedAlignSelf(const ComputedStyle*) const;
/**
* Return the used value for 'justify-self' given our parent ComputedStyle
* aParent (or null for the root).
*/
StyleJustifySelf UsedJustifySelf(const ComputedStyle*) const;
/**
* Return the used value for 'justify/align-self' in aAxis given our parent
* ComputedStyle aParent (or null for the root).
* (defined in WritingModes.h since we need the full WritingMode type)
*/
inline mozilla::StyleAlignFlags UsedSelfAlignment(
LogicalAxis aAxis, const mozilla::ComputedStyle* aParent) const;
/**
* Return the used value for 'justify/align-content' in aAxis.
* (defined in WritingModes.h since we need the full WritingMode type)
*/
inline mozilla::StyleContentDistribution UsedContentAlignment(
LogicalAxis aAxis) const;
/**
* Return the used value for 'align-tracks'/'justify-tracks' for a track
* in the given axis.
* (defined in WritingModes.h since we need the full LogicalAxis type)
*/
inline mozilla::StyleContentDistribution UsedTracksAlignment(
LogicalAxis aAxis, uint32_t aIndex) const;
// Each entry has the same encoding as *-content, see below.
mozilla::StyleAlignTracks mAlignTracks;
mozilla::StyleJustifyTracks mJustifyTracks;
Position mObjectPosition;
StyleRect<LengthPercentageOrAuto> mOffset;
StyleSize mWidth;
StyleSize mMinWidth;
StyleMaxSize mMaxWidth;
StyleSize mHeight;
StyleSize mMinHeight;
StyleMaxSize mMaxHeight;
mozilla::StyleFlexBasis mFlexBasis;
StyleImplicitGridTracks mGridAutoColumns;
StyleImplicitGridTracks mGridAutoRows;
mozilla::StyleAspectRatio mAspectRatio;
mozilla::StyleGridAutoFlow mGridAutoFlow;
uint8_t mMasonryAutoFlow; // NS_STYLE_MASONRY_*
mozilla::StyleAlignContent mAlignContent;
mozilla::StyleAlignItems mAlignItems;
mozilla::StyleAlignSelf mAlignSelf;
mozilla::StyleJustifyContent mJustifyContent;
mozilla::StyleComputedJustifyItems mJustifyItems;
mozilla::StyleJustifySelf mJustifySelf;
mozilla::StyleFlexDirection mFlexDirection;
mozilla::StyleFlexWrap mFlexWrap;
mozilla::StyleObjectFit mObjectFit;
mozilla::StyleBoxSizing mBoxSizing;
int32_t mOrder;
float mFlexGrow;
float mFlexShrink;
mozilla::StyleZIndex mZIndex;
mozilla::StyleGridTemplateComponent mGridTemplateColumns;
mozilla::StyleGridTemplateComponent mGridTemplateRows;
mozilla::StyleGridTemplateAreas mGridTemplateAreas;
mozilla::StyleGridLine mGridColumnStart;
mozilla::StyleGridLine mGridColumnEnd;
mozilla::StyleGridLine mGridRowStart;
mozilla::StyleGridLine mGridRowEnd;
mozilla::NonNegativeLengthPercentageOrNormal mColumnGap;
mozilla::NonNegativeLengthPercentageOrNormal mRowGap;
// Logical-coordinate accessors for width and height properties,
// given a WritingMode value. The definitions of these methods are
// found in WritingModes.h (after the WritingMode class is fully
// declared).
inline const StyleSize& ISize(WritingMode) const;
inline const StyleSize& MinISize(WritingMode) const;
inline const StyleMaxSize& MaxISize(WritingMode) const;
inline const StyleSize& BSize(WritingMode) const;
inline const StyleSize& MinBSize(WritingMode) const;
inline const StyleMaxSize& MaxBSize(WritingMode) const;
inline const StyleSize& Size(LogicalAxis, WritingMode) const;
inline const StyleSize& MinSize(LogicalAxis, WritingMode) const;
inline const StyleMaxSize& MaxSize(LogicalAxis, WritingMode) const;
inline bool ISizeDependsOnContainer(WritingMode) const;
inline bool MinISizeDependsOnContainer(WritingMode) const;
inline bool MaxISizeDependsOnContainer(WritingMode) const;
inline bool BSizeDependsOnContainer(WritingMode) const;
inline bool MinBSizeDependsOnContainer(WritingMode) const;
inline bool MaxBSizeDependsOnContainer(WritingMode) const;
private:
template <typename SizeOrMaxSize>
static bool ISizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
if (aCoord.IsLengthPercentage()) {
return aCoord.AsLengthPercentage().HasPercent();
}
return aCoord.IsFitContent() || aCoord.IsMozAvailable();
}
template <typename SizeOrMaxSize>
static bool BSizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
return aCoord.IsLengthPercentage() &&
aCoord.AsLengthPercentage().HasPercent();
}
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset {
explicit nsStyleTextReset(const mozilla::dom::Document&);
nsStyleTextReset(const nsStyleTextReset& aOther);
~nsStyleTextReset();
static constexpr bool kHasTriggerImageLoads = false;
// Note the difference between this and
// ComputedStyle::HasTextDecorationLines.
bool HasTextDecorationLines() const {
return mTextDecorationLine != mozilla::StyleTextDecorationLine::NONE &&
mTextDecorationLine !=
mozilla::StyleTextDecorationLine::COLOR_OVERRIDE;
}
nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const;
mozilla::StyleTextOverflow mTextOverflow;
mozilla::StyleTextDecorationLine mTextDecorationLine;
uint8_t mTextDecorationStyle; // NS_STYLE_TEXT_DECORATION_STYLE_*
uint8_t mUnicodeBidi; // NS_STYLE_UNICODE_BIDI_*
nscoord mInitialLetterSink; // 0 means normal
float mInitialLetterSize; // 0.0f means normal
mozilla::StyleColor mTextDecorationColor;
mozilla::StyleTextDecorationLength mTextDecorationThickness;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText {
explicit nsStyleText(const mozilla::dom::Document&);
nsStyleText(const nsStyleText& aOther);
~nsStyleText();
static constexpr bool kHasTriggerImageLoads = false;
nsChangeHint CalcDifference(const nsStyleText& aNewData) const;
mozilla::StyleRGBA mColor;
mozilla::StyleTextTransform mTextTransform;
mozilla::StyleTextAlign mTextAlign;
mozilla::StyleTextAlignLast mTextAlignLast;
mozilla::StyleTextJustify mTextJustify;
mozilla::StyleWhiteSpace mWhiteSpace;
mozilla::StyleLineBreak mLineBreak = mozilla::StyleLineBreak::Auto;
private:
mozilla::StyleWordBreak mWordBreak = mozilla::StyleWordBreak::Normal;
mozilla::StyleOverflowWrap mOverflowWrap = mozilla::StyleOverflowWrap::Normal;
public:
mozilla::StyleHyphens mHyphens;
mozilla::StyleRubyAlign mRubyAlign;
mozilla::StyleRubyPosition mRubyPosition;
mozilla::StyleTextSizeAdjust mTextSizeAdjust;
uint8_t mTextCombineUpright; // NS_STYLE_TEXT_COMBINE_UPRIGHT_*
mozilla::StyleMozControlCharacterVisibility mMozControlCharacterVisibility;
uint8_t mTextEmphasisPosition; // NS_STYLE_TEXT_EMPHASIS_POSITION_*
mozilla::StyleTextRendering mTextRendering;
mozilla::StyleColor mTextEmphasisColor;
mozilla::StyleColor mWebkitTextFillColor;
mozilla::StyleColor mWebkitTextStrokeColor;
mozilla::StyleNonNegativeLengthOrNumber mTabSize;
mozilla::LengthPercentage mWordSpacing;
mozilla::StyleLetterSpacing mLetterSpacing;
mozilla::StyleLineHeight mLineHeight;
mozilla::LengthPercentage mTextIndent;
mozilla::LengthPercentageOrAuto mTextUnderlineOffset;
mozilla::StyleTextDecorationSkipInk mTextDecorationSkipInk;
mozilla::StyleTextUnderlinePosition mTextUnderlinePosition;
nscoord mWebkitTextStrokeWidth; // coord
mozilla::StyleArcSlice<mozilla::StyleSimpleShadow> mTextShadow;
mozilla::StyleTextEmphasisStyle mTextEmphasisStyle;
mozilla::StyleHyphenateCharacter mHyphenateCharacter =
mozilla::StyleHyphenateCharacter::Auto();
mozilla::StyleWordBreak EffectiveWordBreak() const {
if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
return mozilla::StyleWordBreak::Normal;
}
return mWordBreak;
}
mozilla::StyleOverflowWrap EffectiveOverflowWrap() const {
if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
return mozilla::StyleOverflowWrap::Anywhere;
}
return mOverflowWrap;
}
bool WhiteSpaceIsSignificant() const {
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
}
bool WhiteSpaceCanHangOrVisuallyCollapse() const {
// This was originally expressed in nsTextFrame in terms of:
// mWhiteSpace != StyleWhiteSpace::BreakSpaces &&
// WhiteSpaceCanWrapStyle() &&
// WhiteSpaceIsSignificant()
// which simplifies to:
return mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap;
}
bool NewlineIsSignificantStyle() const {
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
}
bool WhiteSpaceOrNewlineIsSignificant() const {
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine ||
mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;