Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /*
8 : * structs that contain the data provided by ComputedStyle, the
9 : * internal API for computed style data for an element
10 : */
11 :
12 : #ifndef nsStyleStruct_h___
13 : #define nsStyleStruct_h___
14 :
15 : #include "mozilla/Attributes.h"
16 : #include "mozilla/Maybe.h"
17 : #include "mozilla/SheetType.h"
18 : #include "mozilla/StaticPtr.h"
19 : #include "mozilla/StyleComplexColor.h"
20 : #include "mozilla/UniquePtr.h"
21 : #include "nsColor.h"
22 : #include "nsCoord.h"
23 : #include "nsMargin.h"
24 : #include "nsFont.h"
25 : #include "nsStyleAutoArray.h"
26 : #include "nsStyleCoord.h"
27 : #include "nsStyleConsts.h"
28 : #include "nsChangeHint.h"
29 : #include "nsTimingFunction.h"
30 : #include "nsCOMPtr.h"
31 : #include "nsCOMArray.h"
32 : #include "nsTArray.h"
33 : #include "nsCSSValue.h"
34 : #include "imgRequestProxy.h"
35 : #include "Orientation.h"
36 : #include "CounterStyleManager.h"
37 : #include <cstddef> // offsetof()
38 : #include <utility>
39 : #include "X11UndefineNone.h"
40 :
41 : class nsIFrame;
42 : class nsIURI;
43 : class nsTextFrame;
44 : class imgIContainer;
45 : class nsPresContext;
46 : struct nsStyleDisplay;
47 : struct nsStyleVisibility;
48 : namespace mozilla {
49 : class ComputedStyle;
50 : namespace dom {
51 : class ImageTracker;
52 : } // namespace dom
53 : } // namespace mozilla
54 :
55 : namespace mozilla {
56 :
57 : struct Position {
58 : using Coord = nsStyleCoord::CalcValue;
59 :
60 : Coord mXPosition, mYPosition;
61 :
62 : // Initialize nothing
63 840 : Position() {}
64 :
65 : // Sets both mXPosition and mYPosition to the given percent value for the
66 : // initial property-value (e.g. 0.0f for "0% 0%", or 0.5f for "50% 50%")
67 : void SetInitialPercentValues(float aPercentVal);
68 :
69 : // Sets both mXPosition and mYPosition to 0 (app units) for the
70 : // initial property-value as a length with no percentage component.
71 : void SetInitialZeroValues();
72 :
73 : // True if the effective background image position described by this depends
74 : // on the size of the corresponding frame.
75 0 : bool DependsOnPositioningAreaSize() const {
76 0 : return mXPosition.mPercent != 0.0f || mYPosition.mPercent != 0.0f;
77 : }
78 :
79 180 : bool operator==(const Position& aOther) const {
80 360 : return mXPosition == aOther.mXPosition &&
81 360 : mYPosition == aOther.mYPosition;
82 : }
83 180 : bool operator!=(const Position& aOther) const {
84 180 : return !(*this == aOther);
85 : }
86 : };
87 :
88 : } // namespace mozilla
89 :
90 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont
91 : {
92 : nsStyleFont(const nsFont& aFont, const nsPresContext* aContext);
93 : nsStyleFont(const nsStyleFont& aStyleFont);
94 : explicit nsStyleFont(const nsPresContext* aContext);
95 352 : ~nsStyleFont() {
96 176 : MOZ_COUNT_DTOR(nsStyleFont);
97 176 : }
98 : void FinishStyle(nsPresContext*, const nsStyleFont*) {}
99 : const static bool kHasFinishStyle = false;
100 :
101 : nsChangeHint CalcDifference(const nsStyleFont& aNewData) const;
102 :
103 : /**
104 : * Return aSize multiplied by the current text zoom factor (in aPresContext).
105 : * aSize is allowed to be negative, but the caller is expected to deal with
106 : * negative results. The result is clamped to nscoord_MIN .. nscoord_MAX.
107 : */
108 : static nscoord ZoomText(const nsPresContext* aPresContext, nscoord aSize);
109 : /**
110 : * Return aSize divided by the current text zoom factor (in aPresContext).
111 : * aSize is allowed to be negative, but the caller is expected to deal with
112 : * negative results. The result is clamped to nscoord_MIN .. nscoord_MAX.
113 : */
114 : static nscoord UnZoomText(nsPresContext* aPresContext, nscoord aSize);
115 : static already_AddRefed<nsAtom> GetLanguage(const nsPresContext* aPresContext);
116 :
117 : void EnableZoom(nsPresContext* aContext, bool aEnable);
118 :
119 : nsFont mFont; // [inherited]
120 : nscoord mSize; // [inherited] Our "computed size". Can be different
121 : // from mFont.size which is our "actual size" and is
122 : // enforced to be >= the user's preferred min-size.
123 : // mFont.size should be used for display purposes
124 : // while mSize is the value to return in
125 : // getComputedStyle() for example.
126 :
127 : // In stylo these three track whether the size is keyword-derived
128 : // and if so if it has been modified by a factor/offset
129 : float mFontSizeFactor;
130 : nscoord mFontSizeOffset;
131 : uint8_t mFontSizeKeyword; // NS_STYLE_FONT_SIZE_*, is NS_STYLE_FONT_SIZE_NO_KEYWORD
132 : // when not keyword-derived
133 :
134 : uint8_t mGenericID; // [inherited] generic CSS font family, if any;
135 : // value is a kGenericFont_* constant, see nsFont.h.
136 :
137 : // MathML scriptlevel support
138 : int8_t mScriptLevel; // [inherited]
139 : // MathML mathvariant support
140 : uint8_t mMathVariant; // [inherited]
141 : // MathML displaystyle support
142 : uint8_t mMathDisplay; // [inherited]
143 :
144 : // allow different min font-size for certain cases
145 : uint8_t mMinFontSizeRatio; // [inherited] percent * 100
146 :
147 : // was mLanguage set based on a lang attribute in the document?
148 : bool mExplicitLanguage; // [inherited]
149 :
150 : // should calls to ZoomText() and UnZoomText() be made to the font
151 : // size on this nsStyleFont?
152 : bool mAllowZoom; // [inherited]
153 :
154 : // The value mSize would have had if scriptminsize had never been applied
155 : nscoord mScriptUnconstrainedSize;
156 : nscoord mScriptMinSize; // [inherited] length
157 : float mScriptSizeMultiplier; // [inherited]
158 : RefPtr<nsAtom> mLanguage; // [inherited]
159 : };
160 :
161 574 : struct nsStyleGradientStop
162 : {
163 : nsStyleCoord mLocation; // percent, coord, calc, none
164 : mozilla::StyleComplexColor mColor;
165 : bool mIsInterpolationHint;
166 :
167 : // Use ==/!= on nsStyleGradient instead of on the gradient stop.
168 : bool operator==(const nsStyleGradientStop&) const = delete;
169 : bool operator!=(const nsStyleGradientStop&) const = delete;
170 : };
171 :
172 : class nsStyleGradient final
173 : {
174 : public:
175 : nsStyleGradient();
176 : uint8_t mShape; // NS_STYLE_GRADIENT_SHAPE_*
177 : uint8_t mSize; // NS_STYLE_GRADIENT_SIZE_*;
178 : // not used (must be FARTHEST_CORNER) for linear shape
179 : bool mRepeating;
180 : bool mLegacySyntax; // If true, serialization should use a vendor prefix.
181 : // XXXdholbert This will hopefully be going away soon, if bug 1337655 sticks:
182 : bool mMozLegacySyntax; // (Only makes sense when mLegacySyntax is true.)
183 : // If true, serialization should use -moz prefix.
184 : // Else, serialization should use -webkit prefix.
185 :
186 : nsStyleCoord mBgPosX; // percent, coord, calc, none
187 : nsStyleCoord mBgPosY; // percent, coord, calc, none
188 : nsStyleCoord mAngle; // none, angle
189 :
190 : nsStyleCoord mRadiusX; // percent, coord, calc, none
191 : nsStyleCoord mRadiusY; // percent, coord, calc, none
192 :
193 : // stops are in the order specified in the stylesheet
194 : nsTArray<nsStyleGradientStop> mStops;
195 :
196 : bool operator==(const nsStyleGradient& aOther) const;
197 : bool operator!=(const nsStyleGradient& aOther) const {
198 : return !(*this == aOther);
199 : }
200 :
201 : bool IsOpaque();
202 : bool HasCalc();
203 : uint32_t Hash(PLDHashNumber aHash);
204 :
205 592 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleGradient)
206 :
207 : private:
208 : // Private destructor, to discourage deletion outside of Release():
209 364 : ~nsStyleGradient() {}
210 :
211 : nsStyleGradient(const nsStyleGradient& aOther) = delete;
212 : nsStyleGradient& operator=(const nsStyleGradient& aOther) = delete;
213 : };
214 :
215 : /**
216 : * A wrapper for an imgRequestProxy that supports off-main-thread creation
217 : * and equality comparison.
218 : *
219 : * An nsStyleImageRequest can be created using the constructor that takes the
220 : * URL, base URI, referrer and principal that can be used to initiate an image
221 : * load and produce an imgRequestProxy later.
222 : *
223 : * This can be called from any thread. The nsStyleImageRequest is not
224 : * considered "resolved" at this point, and the Resolve() method must be called
225 : * later to initiate the image load and make calls to get() valid.
226 : *
227 : * Calls to TrackImage(), UntrackImage(), LockImage(), UnlockImage() and
228 : * RequestDiscard() are made to the imgRequestProxy and ImageTracker as
229 : * appropriate, according to the mode flags passed in to the constructor.
230 : *
231 : * The constructor receives a css::ImageValue to represent the url()
232 : * information, which is held on to for the comparisons done in
233 : * DefinitelyEquals().
234 : */
235 : class nsStyleImageRequest
236 : {
237 : public:
238 : typedef mozilla::css::URLValueData URLValueData;
239 :
240 : // Flags describing whether the imgRequestProxy must be tracked in the
241 : // ImageTracker, whether LockImage/UnlockImage calls will be made
242 : // when obtaining and releasing the imgRequestProxy, and whether
243 : // RequestDiscard will be called on release.
244 : enum class Mode : uint8_t {
245 : // The imgRequestProxy will be added to the ImageTracker when resolved
246 : // Without this flag, the nsStyleImageRequest itself will call LockImage/
247 : // UnlockImage on the imgRequestProxy, rather than leaving locking to the
248 : // ImageTracker to manage.
249 : //
250 : // This flag is currently used by all nsStyleImageRequests except
251 : // those for list-style-image and cursor.
252 : Track = 0x1,
253 :
254 : // The imgRequestProxy will have its RequestDiscard method called when
255 : // the nsStyleImageRequest is going away.
256 : //
257 : // This is currently used only for cursor images.
258 : Discard = 0x2,
259 : };
260 :
261 : // Can be called from any thread, but Resolve() must be called later
262 : // on the main thread before get() can be used.
263 : nsStyleImageRequest(Mode aModeFlags, mozilla::css::ImageValue* aImageValue);
264 :
265 : bool Resolve(nsPresContext*, const nsStyleImageRequest* aOldImageRequest);
266 : bool IsResolved() const { return mResolved; }
267 :
268 60 : imgRequestProxy* get() {
269 60 : MOZ_ASSERT(IsResolved(), "Resolve() must be called first");
270 60 : MOZ_ASSERT(NS_IsMainThread());
271 120 : return mRequestProxy.get();
272 : }
273 : const imgRequestProxy* get() const {
274 : return const_cast<nsStyleImageRequest*>(this)->get();
275 : }
276 :
277 : // Returns whether the ImageValue objects in the two nsStyleImageRequests
278 : // return true from URLValueData::DefinitelyEqualURIs.
279 : bool DefinitelyEquals(const nsStyleImageRequest& aOther) const;
280 :
281 120 : mozilla::css::ImageValue* GetImageValue() const { return mImageValue; }
282 :
283 : already_AddRefed<nsIURI> GetImageURI() const;
284 890 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleImageRequest);
285 :
286 : private:
287 : ~nsStyleImageRequest();
288 : nsStyleImageRequest& operator=(const nsStyleImageRequest& aOther) = delete;
289 :
290 : void MaybeTrackAndLock();
291 :
292 : RefPtr<imgRequestProxy> mRequestProxy;
293 : RefPtr<mozilla::css::ImageValue> mImageValue;
294 : RefPtr<mozilla::dom::ImageTracker> mImageTracker;
295 :
296 : // Cache DocGroup for dispatching events in the destructor.
297 : RefPtr<mozilla::dom::DocGroup> mDocGroup;
298 :
299 : Mode mModeFlags;
300 : bool mResolved;
301 : };
302 :
303 240 : MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsStyleImageRequest::Mode)
304 :
305 : enum nsStyleImageType {
306 : eStyleImageType_Null,
307 : eStyleImageType_Image,
308 : eStyleImageType_Gradient,
309 : eStyleImageType_Element,
310 : eStyleImageType_URL
311 : };
312 :
313 0 : struct CachedBorderImageData
314 : {
315 0 : ~CachedBorderImageData() {
316 0 : PurgeCachedImages();
317 0 : }
318 :
319 : // Caller are expected to ensure that the value of aSVGViewportSize is
320 : // different from the cached one since the method won't do the check.
321 : void SetCachedSVGViewportSize(const mozilla::Maybe<nsSize>& aSVGViewportSize);
322 : const mozilla::Maybe<nsSize>& GetCachedSVGViewportSize();
323 : void PurgeCachedImages();
324 : void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage);
325 : imgIContainer* GetSubImage(uint8_t aIndex);
326 :
327 : private:
328 : // If this is a SVG border-image, we save the size of the SVG viewport that
329 : // we used when rasterizing any cached border-image subimages. (The viewport
330 : // size matters for percent-valued sizes & positions in inner SVG doc).
331 : mozilla::Maybe<nsSize> mCachedSVGViewportSize;
332 : nsCOMArray<imgIContainer> mSubImages;
333 : };
334 :
335 : /**
336 : * Represents a paintable image of one of the following types.
337 : * (1) A real image loaded from an external source.
338 : * (2) A CSS linear or radial gradient.
339 : * (3) An element within a document, or an <img>, <video>, or <canvas> element
340 : * not in a document.
341 : * (*) Optionally a crop rect can be set to paint a partial (rectangular)
342 : * region of an image. (Currently, this feature is only supported with an
343 : * image of type (1)).
344 : */
345 : struct nsStyleImage
346 : {
347 : typedef mozilla::css::URLValue URLValue;
348 : typedef mozilla::css::URLValueData URLValueData;
349 :
350 : nsStyleImage();
351 : ~nsStyleImage();
352 : nsStyleImage(const nsStyleImage& aOther);
353 : nsStyleImage& operator=(const nsStyleImage& aOther);
354 :
355 : void SetNull();
356 : void SetImageRequest(already_AddRefed<nsStyleImageRequest> aImage);
357 : void SetGradientData(nsStyleGradient* aGradient);
358 : void SetElementId(already_AddRefed<nsAtom> aElementId);
359 : void SetCropRect(mozilla::UniquePtr<nsStyleSides> aCropRect);
360 : void SetURLValue(already_AddRefed<URLValue> aData);
361 :
362 1514 : void ResolveImage(nsPresContext* aContext, const nsStyleImage* aOldImage) {
363 1514 : MOZ_ASSERT(mType != eStyleImageType_Image || mImage);
364 1514 : if (mType == eStyleImageType_Image && !mImage->IsResolved()) {
365 : const nsStyleImageRequest* oldRequest =
366 0 : (aOldImage && aOldImage->GetType() == eStyleImageType_Image)
367 4 : ? aOldImage->ImageRequest() : nullptr;
368 4 : mImage->Resolve(aContext, oldRequest);
369 : }
370 1514 : }
371 :
372 : nsStyleImageType GetType() const {
373 : return mType;
374 : }
375 8 : nsStyleImageRequest* ImageRequest() const {
376 8 : MOZ_ASSERT(mType == eStyleImageType_Image, "Data is not an image!");
377 8 : MOZ_ASSERT(mImage);
378 8 : return mImage;
379 : }
380 4 : imgRequestProxy* GetImageData() const {
381 4 : return ImageRequest()->get();
382 : }
383 68 : nsStyleGradient* GetGradientData() const {
384 68 : NS_ASSERTION(mType == eStyleImageType_Gradient, "Data is not a gradient!");
385 68 : return mGradient;
386 : }
387 4 : bool IsResolved() const {
388 4 : return mType != eStyleImageType_Image || ImageRequest()->IsResolved();
389 : }
390 0 : const nsAtom* GetElementId() const {
391 0 : NS_ASSERTION(mType == eStyleImageType_Element, "Data is not an element!");
392 0 : return mElementId;
393 : }
394 0 : const mozilla::UniquePtr<nsStyleSides>& GetCropRect() const {
395 0 : NS_ASSERTION(mType == eStyleImageType_Image,
396 : "Only image data can have a crop rect");
397 0 : return mCropRect;
398 : }
399 :
400 : already_AddRefed<nsIURI> GetImageURI() const;
401 :
402 : URLValueData* GetURLValue() const;
403 :
404 : /**
405 : * Compute the actual crop rect in pixels, using the source image bounds.
406 : * The computation involves converting percentage unit to pixel unit and
407 : * clamping each side value to fit in the source image bounds.
408 : * @param aActualCropRect the computed actual crop rect.
409 : * @param aIsEntireImage true iff |aActualCropRect| is identical to the
410 : * source image bounds.
411 : * @return true iff |aActualCropRect| holds a meaningful value.
412 : */
413 : bool ComputeActualCropRect(nsIntRect& aActualCropRect,
414 : bool* aIsEntireImage = nullptr) const;
415 :
416 : /**
417 : * Starts the decoding of a image. Returns true if the current frame of the
418 : * image is complete. The return value is intended to be used instead of
419 : * IsComplete because IsComplete may not be up to date if notifications
420 : * from decoding are pending because they are being sent async.
421 : */
422 : bool StartDecoding() const;
423 : /**
424 : * @return true if the item is definitely opaque --- i.e., paints every
425 : * pixel within its bounds opaquely, and the bounds contains at least a pixel.
426 : */
427 : bool IsOpaque() const;
428 : /**
429 : * @return true if this image is fully loaded, and its size is calculated;
430 : * always returns true if |mType| is |eStyleImageType_Gradient| or
431 : * |eStyleImageType_Element|.
432 : */
433 : bool IsComplete() const;
434 : /**
435 : * @return true if this image is loaded without error;
436 : * always returns true if |mType| is |eStyleImageType_Gradient| or
437 : * |eStyleImageType_Element|.
438 : */
439 : bool IsLoaded() const;
440 : /**
441 : * @return true if it is 100% confident that this image contains no pixel
442 : * to draw.
443 : */
444 : bool IsEmpty() const {
445 : // There are some other cases when the image will be empty, for example
446 : // when the crop rect is empty. However, checking the emptiness of crop
447 : // rect is non-trivial since each side value can be specified with
448 : // percentage unit, which can not be evaluated until the source image size
449 : // is available. Therefore, we currently postpone the evaluation of crop
450 : // rect until the actual rendering time --- alternatively until GetOpaqueRegion()
451 : // is called.
452 : return mType == eStyleImageType_Null;
453 : }
454 :
455 : bool operator==(const nsStyleImage& aOther) const;
456 18 : bool operator!=(const nsStyleImage& aOther) const {
457 18 : return !(*this == aOther);
458 : }
459 :
460 0 : bool ImageDataEquals(const nsStyleImage& aOther) const
461 : {
462 0 : return GetType() == eStyleImageType_Image &&
463 0 : aOther.GetType() == eStyleImageType_Image &&
464 0 : GetImageData() == aOther.GetImageData();
465 : }
466 :
467 : // These methods are used for the caller to caches the sub images created
468 : // during a border-image paint operation
469 : inline void SetSubImage(uint8_t aIndex, imgIContainer* aSubImage) const;
470 : inline imgIContainer* GetSubImage(uint8_t aIndex) const;
471 : void PurgeCacheForViewportChange(
472 : const mozilla::Maybe<nsSize>& aSVGViewportSize,
473 : const bool aHasIntrinsicRatio) const;
474 :
475 : private:
476 : void DoCopy(const nsStyleImage& aOther);
477 : void EnsureCachedBIData() const;
478 :
479 : // This variable keeps some cache data for border image and is lazily
480 : // allocated since it is only used in border image case.
481 : mozilla::UniquePtr<CachedBorderImageData> mCachedBIData;
482 :
483 : nsStyleImageType mType;
484 : union {
485 : nsStyleImageRequest* mImage;
486 : nsStyleGradient* mGradient;
487 : URLValue* mURLValue; // See the comment in SetStyleImage's 'case
488 : // eCSSUnit_URL' section to know why we need to
489 : // store URLValues separately from mImage.
490 : nsAtom* mElementId;
491 : };
492 :
493 : // This is _currently_ used only in conjunction with eStyleImageType_Image.
494 : mozilla::UniquePtr<nsStyleSides> mCropRect;
495 : };
496 :
497 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColor
498 : {
499 : explicit nsStyleColor(const nsPresContext* aContext);
500 : nsStyleColor(const nsStyleColor& aOther);
501 740 : ~nsStyleColor() {
502 370 : MOZ_COUNT_DTOR(nsStyleColor);
503 370 : }
504 : void FinishStyle(nsPresContext*, const nsStyleColor*) {}
505 : const static bool kHasFinishStyle = false;
506 :
507 : nsChangeHint CalcDifference(const nsStyleColor& aNewData) const;
508 :
509 : // Don't add ANY members to this struct! We can achieve caching in the rule
510 : // tree (rather than the style tree) by letting color stay by itself! -dwh
511 : nscolor mColor; // [inherited]
512 : };
513 :
514 : struct nsStyleImageLayers {
515 : // Indices into kBackgroundLayerTable and kMaskLayerTable
516 : enum {
517 : shorthand = 0,
518 : color,
519 : image,
520 : repeat,
521 : positionX,
522 : positionY,
523 : clip,
524 : origin,
525 : size,
526 : attachment,
527 : maskMode,
528 : composite
529 : };
530 :
531 : enum class LayerType : uint8_t {
532 : Background = 0,
533 : Mask
534 : };
535 :
536 : explicit nsStyleImageLayers(LayerType aType);
537 : nsStyleImageLayers(const nsStyleImageLayers &aSource);
538 880 : ~nsStyleImageLayers() {
539 440 : MOZ_COUNT_DTOR(nsStyleImageLayers);
540 440 : }
541 :
542 : static bool IsInitialPositionForLayerType(mozilla::Position aPosition, LayerType aType);
543 :
544 : struct Size {
545 : struct Dimension : public nsStyleCoord::CalcValue {
546 0 : nscoord ResolveLengthPercentage(nscoord aAvailable) const {
547 0 : double d = double(mPercent) * double(aAvailable) + double(mLength);
548 0 : if (d < 0.0) {
549 : return 0;
550 : }
551 0 : return NSToCoordRoundWithClamp(float(d));
552 : }
553 : };
554 : Dimension mWidth, mHeight;
555 :
556 : bool IsInitialValue() const {
557 0 : return mWidthType == eAuto && mHeightType == eAuto;
558 : }
559 :
560 0 : nscoord ResolveWidthLengthPercentage(const nsSize& aBgPositioningArea) const {
561 0 : MOZ_ASSERT(mWidthType == eLengthPercentage,
562 : "resolving non-length/percent dimension!");
563 0 : return mWidth.ResolveLengthPercentage(aBgPositioningArea.width);
564 : }
565 :
566 0 : nscoord ResolveHeightLengthPercentage(const nsSize& aBgPositioningArea) const {
567 0 : MOZ_ASSERT(mHeightType == eLengthPercentage,
568 : "resolving non-length/percent dimension!");
569 0 : return mHeight.ResolveLengthPercentage(aBgPositioningArea.height);
570 : }
571 :
572 : // Except for eLengthPercentage, Dimension types which might change
573 : // how a layer is painted when the corresponding frame's dimensions
574 : // change *must* precede all dimension types which are agnostic to
575 : // frame size; see DependsOnDependsOnPositioningAreaSizeSize.
576 : enum DimensionType {
577 : // If one of mWidth and mHeight is eContain or eCover, then both are.
578 : // NOTE: eContain and eCover *must* be equal to NS_STYLE_BG_SIZE_CONTAIN
579 : // and NS_STYLE_BG_SIZE_COVER (in kBackgroundSizeKTable).
580 : eContain, eCover,
581 :
582 : eAuto,
583 : eLengthPercentage,
584 : eDimensionType_COUNT
585 : };
586 : uint8_t mWidthType, mHeightType;
587 :
588 : // True if the effective image size described by this depends on the size of
589 : // the corresponding frame, when aImage (which must not have null type) is
590 : // the background image.
591 : bool DependsOnPositioningAreaSize(const nsStyleImage& aImage) const;
592 :
593 : // Initialize nothing
594 700 : Size() {}
595 :
596 : // Initialize to initial values
597 : void SetInitialValues();
598 :
599 : bool operator==(const Size& aOther) const;
600 6 : bool operator!=(const Size& aOther) const {
601 6 : return !(*this == aOther);
602 : }
603 : };
604 :
605 : struct Repeat {
606 : mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat;
607 :
608 : // Initialize nothing
609 700 : Repeat() {}
610 :
611 0 : bool IsInitialValue() const {
612 0 : return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat &&
613 0 : mYRepeat == mozilla::StyleImageLayerRepeat::Repeat;
614 : }
615 :
616 0 : bool DependsOnPositioningAreaSize() const {
617 0 : return mXRepeat == mozilla::StyleImageLayerRepeat::Space ||
618 0 : mYRepeat == mozilla::StyleImageLayerRepeat::Space;
619 : }
620 :
621 : // Initialize to initial values
622 : void SetInitialValues() {
623 140 : mXRepeat = mozilla::StyleImageLayerRepeat::Repeat;
624 140 : mYRepeat = mozilla::StyleImageLayerRepeat::Repeat;
625 : }
626 :
627 6 : bool operator==(const Repeat& aOther) const {
628 12 : return mXRepeat == aOther.mXRepeat &&
629 12 : mYRepeat == aOther.mYRepeat;
630 : }
631 6 : bool operator!=(const Repeat& aOther) const {
632 6 : return !(*this == aOther);
633 : }
634 : };
635 :
636 560 : struct Layer {
637 : typedef mozilla::StyleGeometryBox StyleGeometryBox;
638 : typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment;
639 :
640 : nsStyleImage mImage; // [reset]
641 : mozilla::Position mPosition; // [reset]
642 : Size mSize; // [reset]
643 : StyleGeometryBox mClip; // [reset] See nsStyleConsts.h
644 : MOZ_INIT_OUTSIDE_CTOR
645 : StyleGeometryBox mOrigin; // [reset] See nsStyleConsts.h
646 : StyleImageLayerAttachment mAttachment;
647 : // [reset] See nsStyleConsts.h
648 : // background-only property
649 : // This property is used for background layer
650 : // only. For a mask layer, it should always
651 : // be the initial value, which is
652 : // StyleImageLayerAttachment::Scroll.
653 : uint8_t mBlendMode; // [reset] See nsStyleConsts.h
654 : // background-only property
655 : // This property is used for background layer
656 : // only. For a mask layer, it should always
657 : // be the initial value, which is
658 : // NS_STYLE_BLEND_NORMAL.
659 : uint8_t mComposite; // [reset] See nsStyleConsts.h
660 : // mask-only property
661 : // This property is used for mask layer only.
662 : // For a background layer, it should always
663 : // be the initial value, which is
664 : // NS_STYLE_COMPOSITE_MODE_ADD.
665 : uint8_t mMaskMode; // [reset] See nsStyleConsts.h
666 : // mask-only property
667 : // This property is used for mask layer only.
668 : // For a background layer, it should always
669 : // be the initial value, which is
670 : // NS_STYLE_MASK_MODE_MATCH_SOURCE.
671 : Repeat mRepeat; // [reset] See nsStyleConsts.h
672 :
673 : // This constructor does not initialize mRepeat or mOrigin and Initialize()
674 : // must be called to do that.
675 : Layer();
676 : ~Layer();
677 :
678 : // Initialize mRepeat and mOrigin by specified layer type
679 : void Initialize(LayerType aType);
680 :
681 738 : void ResolveImage(nsPresContext* aContext, const Layer* aOldLayer) {
682 738 : mImage.ResolveImage(aContext, aOldLayer ? &aOldLayer->mImage : nullptr);
683 738 : }
684 :
685 : // True if the rendering of this layer might change when the size
686 : // of the background positioning area changes. This is true for any
687 : // non-solid-color background whose position or size depends on
688 : // the size of the positioning area. It's also true for SVG images
689 : // whose root <svg> node has a viewBox.
690 : bool RenderingMightDependOnPositioningAreaSizeChange() const;
691 :
692 : // Compute the change hint required by changes in just this layer.
693 : nsChangeHint CalcDifference(const Layer& aNewLayer) const;
694 :
695 : // An equality operator that compares the images using URL-equality
696 : // rather than pointer-equality.
697 : bool operator==(const Layer& aOther) const;
698 : bool operator!=(const Layer& aOther) const {
699 : return !(*this == aOther);
700 : }
701 : };
702 :
703 : // The (positive) number of computed values of each property, since
704 : // the lengths of the lists are independent.
705 : uint32_t mAttachmentCount,
706 : mClipCount,
707 : mOriginCount,
708 : mRepeatCount,
709 : mPositionXCount,
710 : mPositionYCount,
711 : mImageCount,
712 : mSizeCount,
713 : mMaskModeCount,
714 : mBlendModeCount,
715 : mCompositeCount;
716 :
717 : // Layers are stored in an array, matching the top-to-bottom order in
718 : // which they are specified in CSS. The number of layers to be used
719 : // should come from the background-image property. We create
720 : // additional |Layer| objects for *any* property, not just
721 : // background-image. This means that the bottommost layer that
722 : // callers in layout care about (which is also the one whose
723 : // background-clip applies to the background-color) may not be last
724 : // layer. In layers below the bottom layer, properties will be
725 : // uninitialized unless their count, above, indicates that they are
726 : // present.
727 : nsStyleAutoArray<Layer> mLayers;
728 :
729 1484 : const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
730 :
731 738 : void ResolveImages(nsPresContext* aContext, const nsStyleImageLayers* aOldLayers) {
732 1476 : for (uint32_t i = 0; i < mImageCount; ++i) {
733 : const Layer* oldLayer =
734 92 : (aOldLayers && aOldLayers->mLayers.Length() > i)
735 784 : ? &aOldLayers->mLayers[i]
736 738 : : nullptr;
737 738 : mLayers[i].ResolveImage(aContext, oldLayer);
738 : }
739 738 : }
740 :
741 : // Fill unspecified layers by cycling through their values
742 : // till they all are of length aMaxItemCount
743 : void FillAllLayers(uint32_t aMaxItemCount);
744 :
745 : nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
746 : nsStyleImageLayers::LayerType aType) const;
747 :
748 : nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
749 : nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther);
750 : bool operator==(const nsStyleImageLayers& aOther) const;
751 :
752 : static const nsCSSPropertyID kBackgroundLayerTable[];
753 : static const nsCSSPropertyID kMaskLayerTable[];
754 :
755 : #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
756 : for (uint32_t var_ = (layers_).mImageCount; var_-- != 0; )
757 : #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, start_, count_) \
758 : NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, "Invalid layer start!"); \
759 : NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
760 : for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
761 : };
762 :
763 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
764 : explicit nsStyleBackground(const nsPresContext* aContext);
765 : nsStyleBackground(const nsStyleBackground& aOther);
766 : ~nsStyleBackground();
767 :
768 : // Resolves and tracks the images in mImage. Only called with a Servo-backed
769 : // style system, where those images must be resolved later than the OMT
770 : // nsStyleBackground constructor call.
771 : void FinishStyle(nsPresContext*, const nsStyleBackground*);
772 : const static bool kHasFinishStyle = true;
773 :
774 : nsChangeHint CalcDifference(const nsStyleBackground& aNewData) const;
775 :
776 : // Return the background color as nscolor.
777 : nscolor BackgroundColor(const nsIFrame* aFrame) const;
778 : nscolor BackgroundColor(mozilla::ComputedStyle* aStyle) const;
779 :
780 : // True if this background is completely transparent.
781 : bool IsTransparent(const nsIFrame* aFrame) const;
782 : bool IsTransparent(mozilla::ComputedStyle* aStyle) const;
783 :
784 : // We have to take slower codepaths for fixed background attachment,
785 : // but we don't want to do that when there's no image.
786 : // Not inline because it uses an nsCOMPtr<imgIRequest>
787 : // FIXME: Should be in nsStyleStructInlines.h.
788 : bool HasFixedBackground(nsIFrame* aFrame) const;
789 :
790 : // Checks to see if this has a non-empty image with "local" attachment.
791 : // This is defined in nsStyleStructInlines.h.
792 : inline bool HasLocalBackground() const;
793 :
794 1484 : const nsStyleImageLayers::Layer& BottomLayer() const { return mImage.BottomLayer(); }
795 :
796 : nsStyleImageLayers mImage;
797 : mozilla::StyleComplexColor mBackgroundColor; // [reset]
798 : };
799 :
800 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin
801 : {
802 : explicit nsStyleMargin(const nsPresContext* aContext);
803 : nsStyleMargin(const nsStyleMargin& aMargin);
804 612 : ~nsStyleMargin() {
805 306 : MOZ_COUNT_DTOR(nsStyleMargin);
806 306 : }
807 : void FinishStyle(nsPresContext*, const nsStyleMargin*) {}
808 : const static bool kHasFinishStyle = false;
809 :
810 : nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const;
811 :
812 6724 : bool GetMargin(nsMargin& aMargin) const
813 : {
814 6724 : if (!mMargin.ConvertsToLength()) {
815 : return false;
816 : }
817 :
818 60498 : NS_FOR_CSS_SIDES(side) {
819 53776 : aMargin.Side(side) = mMargin.ToLength(side);
820 : }
821 : return true;
822 : }
823 :
824 : // Return true if either the start or end side in the axis is 'auto'.
825 : // (defined in WritingModes.h since we need the full WritingMode type)
826 : inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const;
827 : inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const;
828 :
829 : nsStyleSides mMargin; // [reset] coord, percent, calc, auto
830 : };
831 :
832 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding
833 : {
834 : explicit nsStylePadding(const nsPresContext* aContext);
835 : nsStylePadding(const nsStylePadding& aPadding);
836 736 : ~nsStylePadding() {
837 368 : MOZ_COUNT_DTOR(nsStylePadding);
838 368 : }
839 : void FinishStyle(nsPresContext*, const nsStylePadding*) {}
840 : const static bool kHasFinishStyle = false;
841 :
842 : nsChangeHint CalcDifference(const nsStylePadding& aNewData) const;
843 :
844 : nsStyleSides mPadding; // [reset] coord, percent, calc
845 :
846 306 : bool IsWidthDependent() const {
847 306 : return !mPadding.ConvertsToLength();
848 : }
849 :
850 5630 : bool GetPadding(nsMargin& aPadding) const
851 : {
852 5630 : if (!mPadding.ConvertsToLength()) {
853 : return false;
854 : }
855 :
856 50670 : NS_FOR_CSS_SIDES(side) {
857 : // Clamp negative calc() to 0.
858 67560 : aPadding.Side(side) = std::max(mPadding.ToLength(side), 0);
859 : }
860 : return true;
861 : }
862 : };
863 :
864 : struct nsCSSShadowItem
865 : {
866 : nscoord mXOffset;
867 : nscoord mYOffset;
868 : nscoord mRadius;
869 : nscoord mSpread;
870 :
871 : nscolor mColor;
872 : bool mHasColor; // Whether mColor should be used
873 : bool mInset;
874 :
875 86 : nsCSSShadowItem()
876 86 : : mXOffset(0)
877 86 : , mYOffset(0)
878 128 : , mRadius(0)
879 64 : , mSpread(0)
880 64 : , mColor(NS_RGB(0, 0, 0))
881 : , mHasColor(false)
882 0 : , mInset(false)
883 0 : {
884 0 : MOZ_COUNT_CTOR(nsCSSShadowItem);
885 0 : }
886 0 : ~nsCSSShadowItem() {
887 0 : MOZ_COUNT_DTOR(nsCSSShadowItem);
888 0 : }
889 0 :
890 : bool operator==(const nsCSSShadowItem& aOther) const {
891 0 : return (mXOffset == aOther.mXOffset &&
892 0 : mYOffset == aOther.mYOffset &&
893 : mRadius == aOther.mRadius &&
894 : mHasColor == aOther.mHasColor &&
895 : mSpread == aOther.mSpread &&
896 : mInset == aOther.mInset &&
897 : (!mHasColor || mColor == aOther.mColor));
898 : }
899 74 : bool operator!=(const nsCSSShadowItem& aOther) const {
900 : return !(*this == aOther);
901 : }
902 : };
903 :
904 : class nsCSSShadowArray final
905 74 : {
906 148 : public:
907 : void* operator new(size_t aBaseSize, uint32_t aArrayLen) {
908 : // We can allocate both this nsCSSShadowArray and the
909 62 : // actual array in one allocation. The amount of memory to
910 : // allocate is equal to the class's size + the number of bytes for all
911 74 : // but the first array item (because aBaseSize includes one
912 148 : // item, see the private declarations)
913 : return ::operator new(aBaseSize +
914 98 : (aArrayLen - 1) * sizeof(nsCSSShadowItem));
915 : }
916 :
917 12 : void operator delete(void* aPtr) { ::operator delete(aPtr); }
918 :
919 74 : explicit nsCSSShadowArray(uint32_t aArrayLen) :
920 : mLength(aArrayLen)
921 : {
922 : for (uint32_t i = 1; i < mLength; ++i) {
923 124 : // Make sure we call the constructors of each nsCSSShadowItem
924 64 : // (the first one is called for us because we declared it under private)
925 2 : new (&mArray[i]) nsCSSShadowItem();
926 : }
927 62 : }
928 :
929 : private:
930 : // Private destructor, to discourage deletion outside of Release():
931 50 : ~nsCSSShadowArray() {
932 50 : for (uint32_t i = 1; i < mLength; ++i) {
933 50 : mArray[i].~nsCSSShadowItem();
934 : }
935 0 : }
936 0 :
937 0 : public:
938 : uint32_t Length() const { return mLength; }
939 : nsCSSShadowItem* ShadowAt(uint32_t i) {
940 84 : MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
941 140 : return &mArray[i];
942 84 : }
943 : const nsCSSShadowItem* ShadowAt(uint32_t i) const {
944 : MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
945 : return &mArray[i];
946 : }
947 :
948 : bool HasShadowWithInset(bool aInset) {
949 0 : for (uint32_t i = 0; i < mLength; ++i) {
950 0 : if (mArray[i].mInset == aInset) {
951 : return true;
952 : }
953 : }
954 0 : return false;
955 0 : }
956 :
957 : bool operator==(const nsCSSShadowArray& aOther) const {
958 : if (mLength != aOther.Length()) {
959 : return false;
960 : }
961 :
962 : for (uint32_t i = 0; i < mLength; ++i) {
963 334 : if (ShadowAt(i) != aOther.ShadowAt(i)) {
964 : return false;
965 : }
966 : }
967 :
968 : return true;
969 : }
970 :
971 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSShadowArray)
972 :
973 : private:
974 : uint32_t mLength;
975 : nsCSSShadowItem mArray[1]; // This MUST be the last item
976 : };
977 :
978 : // Border widths are rounded to the nearest-below integer number of pixels,
979 : // but values between zero and one device pixels are always rounded up to
980 : // one device pixel.
981 : #define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \
982 : ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
983 : // Outline offset is rounded to the nearest integer number of pixels, but values
984 : // between zero and one device pixels are always rounded up to one device pixel.
985 : // Note that the offset can be negative.
986 100 : #define NS_ROUND_OFFSET_TO_PIXELS(l,tpp) \
987 100 : (((l) == 0) ? 0 : \
988 : ((l) > 0) ? std::max( (tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) : \
989 : std::min(-(tpp), ((l) - ((tpp) / 2)) / (tpp) * (tpp)))
990 :
991 : // Returns if the given border style type is visible or not
992 : static bool IsVisibleBorderStyle(uint8_t aStyle)
993 : {
994 : return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
995 : aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
996 : }
997 :
998 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
999 : {
1000 : explicit nsStyleBorder(const nsPresContext* aContext);
1001 : nsStyleBorder(const nsStyleBorder& aBorder);
1002 : ~nsStyleBorder();
1003 :
1004 : // Resolves and tracks mBorderImageSource. Only called with a Servo-backed
1005 : // style system, where those images must be resolved later than the OMT
1006 : // nsStyleBorder constructor call.
1007 : void FinishStyle(nsPresContext*, const nsStyleBorder*);
1008 : const static bool kHasFinishStyle = true;
1009 :
1010 : nsChangeHint CalcDifference(const nsStyleBorder& aNewData) const;
1011 192 :
1012 : // Return whether aStyle is a visible style. Invisible styles cause
1013 : // the relevant computed border width to be 0.
1014 : // Note that this does *not* consider the effects of 'border-image':
1015 0 : // if border-style is none, but there is a loaded border image,
1016 : // HasVisibleStyle will be false even though there *is* a border.
1017 : bool HasVisibleStyle(mozilla::Side aSide) const
1018 0 : {
1019 0 : return IsVisibleBorderStyle(mBorderStyle[aSide]);
1020 0 : }
1021 0 :
1022 : // aBorderWidth is in twips
1023 0 : void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth)
1024 : {
1025 : nscoord roundedWidth =
1026 : NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
1027 : mBorder.Side(aSide) = roundedWidth;
1028 : if (HasVisibleStyle(aSide)) {
1029 : mComputedBorder.Side(aSide) = roundedWidth;
1030 16 : }
1031 : }
1032 :
1033 1144 : // Get the computed border (plus rounding). This does consider the
1034 : // effects of 'border-style: none', but does not consider
1035 2288 : // 'border-image'.
1036 : const nsMargin& GetComputedBorder() const
1037 : {
1038 : return mComputedBorder;
1039 : }
1040 :
1041 : bool HasBorder() const
1042 : {
1043 : return mComputedBorder != nsMargin(0,0,0,0) || !mBorderImageSource.IsEmpty();
1044 88 : }
1045 :
1046 : // Get the actual border width for a particular side, in appunits. Note that
1047 172 : // this is zero if and only if there is no border to be painted for this
1048 : // side. That is, this value takes into account the border style and the
1049 172 : // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
1050 172 : nscoord GetComputedBorderWidth(mozilla::Side aSide) const
1051 : {
1052 : return GetComputedBorder().Side(aSide);
1053 0 : }
1054 :
1055 0 : uint8_t GetBorderStyle(mozilla::Side aSide) const
1056 0 : {
1057 0 : NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
1058 0 : return mBorderStyle[aSide];
1059 0 : }
1060 :
1061 : void SetBorderStyle(mozilla::Side aSide, uint8_t aStyle)
1062 : {
1063 2 : NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
1064 : mBorderStyle[aSide] = aStyle;
1065 : mComputedBorder.Side(aSide) =
1066 : (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0);
1067 : }
1068 876 :
1069 : inline bool IsBorderImageLoaded() const
1070 876 : {
1071 0 : return mBorderImageSource.IsLoaded();
1072 : }
1073 :
1074 : nsMargin GetImageOutset() const;
1075 :
1076 : imgIRequest* GetBorderImageRequest() const
1077 : {
1078 : if (mBorderImageSource.GetType() == eStyleImageType_Image) {
1079 : return mBorderImageSource.GetImageData();
1080 : }
1081 : return nullptr;
1082 : }
1083 :
1084 : public:
1085 : nsStyleCorners mBorderRadius; // [reset] coord, percent
1086 : nsStyleImage mBorderImageSource; // [reset]
1087 : nsStyleSides mBorderImageSlice; // [reset] factor, percent
1088 : nsStyleSides mBorderImageWidth; // [reset] length, factor, percent, auto
1089 : nsStyleSides mBorderImageOutset; // [reset] length, factor
1090 :
1091 : uint8_t mBorderImageFill; // [reset]
1092 : mozilla::StyleBorderImageRepeat mBorderImageRepeatH; // [reset]
1093 : mozilla::StyleBorderImageRepeat mBorderImageRepeatV; // [reset]
1094 : mozilla::StyleFloatEdge mFloatEdge; // [reset]
1095 : mozilla::StyleBoxDecorationBreak mBoxDecorationBreak; // [reset]
1096 :
1097 : protected:
1098 : uint8_t mBorderStyle[4]; // [reset] See nsStyleConsts.h
1099 :
1100 : public:
1101 0 : // [reset] the colors to use for a simple border.
1102 0 : // not used for -moz-border-colors
1103 0 : mozilla::StyleComplexColor mBorderTopColor;
1104 0 : mozilla::StyleComplexColor mBorderRightColor;
1105 0 : mozilla::StyleComplexColor mBorderBottomColor;
1106 0 : mozilla::StyleComplexColor mBorderLeftColor;
1107 :
1108 0 : mozilla::StyleComplexColor&
1109 : BorderColorFor(mozilla::Side aSide) {
1110 : switch (aSide) {
1111 : case mozilla::eSideTop: return mBorderTopColor;
1112 : case mozilla::eSideRight: return mBorderRightColor;
1113 268 : case mozilla::eSideBottom: return mBorderBottomColor;
1114 268 : case mozilla::eSideLeft: return mBorderLeftColor;
1115 88 : }
1116 60 : MOZ_ASSERT_UNREACHABLE("Unknown side");
1117 60 : return mBorderTopColor;
1118 60 : }
1119 :
1120 0 : const mozilla::StyleComplexColor&
1121 : BorderColorFor(mozilla::Side aSide) const {
1122 : switch (aSide) {
1123 : case mozilla::eSideTop: return mBorderTopColor;
1124 : case mozilla::eSideRight: return mBorderRightColor;
1125 0 : case mozilla::eSideBottom: return mBorderBottomColor;
1126 0 : case mozilla::eSideLeft: return mBorderLeftColor;
1127 : }
1128 : MOZ_ASSERT_UNREACHABLE("Unknown side");
1129 : return mBorderTopColor;
1130 0 : }
1131 :
1132 0 : static mozilla::StyleComplexColor nsStyleBorder::*
1133 : BorderColorFieldFor(mozilla::Side aSide) {
1134 0 : switch (aSide) {
1135 : case mozilla::eSideTop:
1136 0 : return &nsStyleBorder::mBorderTopColor;
1137 : case mozilla::eSideRight:
1138 : return &nsStyleBorder::mBorderRightColor;
1139 : case mozilla::eSideBottom:
1140 : return &nsStyleBorder::mBorderBottomColor;
1141 : case mozilla::eSideLeft:
1142 : return &nsStyleBorder::mBorderLeftColor;
1143 : }
1144 : MOZ_ASSERT_UNREACHABLE("Unknown side");
1145 : return nullptr;
1146 : }
1147 :
1148 : protected:
1149 : // mComputedBorder holds the CSS2.1 computed border-width values.
1150 : // In particular, these widths take into account the border-style
1151 : // for the relevant side, and the values are rounded to the nearest
1152 : // device pixel (which is not part of the definition of computed
1153 : // values). The presence or absence of a border-image does not
1154 : // affect border-width values.
1155 : nsMargin mComputedBorder;
1156 :
1157 : // mBorder holds the nscoord values for the border widths as they
1158 : // would be if all the border-style values were visible (not hidden
1159 : // or none). This member exists so that when we create structs
1160 : // using the copy constructor during style resolution the new
1161 : // structs will know what the specified values of the border were in
1162 : // case they have more specific rules setting the border style.
1163 : //
1164 : // Note that this isn't quite the CSS specified value, since this
1165 : // has had the enumerated border widths converted to lengths, and
1166 : // all lengths converted to twips. But it's not quite the computed
1167 : // value either. The values are rounded to the nearest device pixel.
1168 : nsMargin mBorder;
1169 :
1170 : private:
1171 : nscoord mTwipsPerPixel;
1172 64 :
1173 32 : nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
1174 32 : };
1175 :
1176 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline
1177 : {
1178 : explicit nsStyleOutline(const nsPresContext* aContext);
1179 : nsStyleOutline(const nsStyleOutline& aOutline);
1180 : ~nsStyleOutline() {
1181 : MOZ_COUNT_DTOR(nsStyleOutline);
1182 : }
1183 : void FinishStyle(nsPresContext*, const nsStyleOutline*) {}
1184 : const static bool kHasFinishStyle = false;
1185 :
1186 : void RecalcData();
1187 : nsChangeHint CalcDifference(const nsStyleOutline& aNewData) const;
1188 :
1189 : nsStyleCorners mOutlineRadius; // [reset] coord, percent, calc
1190 :
1191 : // This is the specified value of outline-width, but with length values
1192 : // computed to absolute. mActualOutlineWidth stores the outline-width
1193 : // value used by layout. (We must store mOutlineWidth for the same
1194 : // style struct resolution reasons that we do nsStyleBorder::mBorder;
1195 : // see that field's comment.)
1196 : nscoord mOutlineWidth; // [reset] coord, enum (see nsStyleConsts.h)
1197 : nscoord mOutlineOffset; // [reset]
1198 2498 : mozilla::StyleComplexColor mOutlineColor; // [reset]
1199 : uint8_t mOutlineStyle; // [reset] See nsStyleConsts.h
1200 4996 :
1201 2498 : nscoord GetOutlineWidth() const
1202 2498 : {
1203 : return mActualOutlineWidth;
1204 : }
1205 :
1206 : bool ShouldPaintOutline() const
1207 : {
1208 : return mOutlineStyle == NS_STYLE_BORDER_STYLE_AUTO ||
1209 : (GetOutlineWidth() > 0 &&
1210 : mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE);
1211 : }
1212 :
1213 : protected:
1214 : // The actual value of outline-width is the computed value (an absolute
1215 : // length, forced to zero when outline-style is none) rounded to device
1216 : // pixels. This is the value used by layout.
1217 : nscoord mActualOutlineWidth;
1218 : nscoord mTwipsPerPixel;
1219 6 : };
1220 :
1221 :
1222 : /**
1223 1028 : * An object that allows sharing of arrays that store 'quotes' property
1224 : * values. This is particularly important for inheritance, where we want
1225 : * to share the same 'quotes' value with a parent ComputedStyle.
1226 : */
1227 0 : class nsStyleQuoteValues
1228 : {
1229 : public:
1230 : typedef nsTArray<std::pair<nsString, nsString>> QuotePairArray;
1231 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsStyleQuoteValues);
1232 : QuotePairArray mQuotePairs;
1233 :
1234 : private:
1235 : ~nsStyleQuoteValues() {}
1236 : };
1237 :
1238 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList
1239 : {
1240 : explicit nsStyleList(const nsPresContext* aContext);
1241 : nsStyleList(const nsStyleList& aStyleList);
1242 0 : ~nsStyleList();
1243 0 :
1244 0 : void FinishStyle(nsPresContext*, const nsStyleList*);
1245 0 : const static bool kHasFinishStyle = true;
1246 :
1247 68 : nsChangeHint CalcDifference(const nsStyleList& aNewData,
1248 : const nsStyleDisplay* aOldDisplay) const;
1249 136 :
1250 : static void Shutdown() {
1251 : sInitialQuotes = nullptr;
1252 : sNoneQuotes = nullptr;
1253 : }
1254 :
1255 : imgRequestProxy* GetListStyleImage() const
1256 : {
1257 : return mListStyleImage ? mListStyleImage->get() : nullptr;
1258 : }
1259 :
1260 : already_AddRefed<nsIURI> GetListStyleImageURI() const;
1261 :
1262 : const nsStyleQuoteValues::QuotePairArray& GetQuotePairs() const;
1263 :
1264 : void SetQuotesInherit(const nsStyleList* aOther);
1265 : void SetQuotesInitial();
1266 : void SetQuotesNone();
1267 : void SetQuotes(nsStyleQuoteValues::QuotePairArray&& aValues);
1268 :
1269 : uint8_t mListStylePosition; // [inherited]
1270 : RefPtr<nsStyleImageRequest> mListStyleImage; // [inherited]
1271 :
1272 : mozilla::CounterStylePtr mCounterStyle; // [inherited]
1273 :
1274 : private:
1275 : RefPtr<nsStyleQuoteValues> mQuotes; // [inherited]
1276 : nsStyleList& operator=(const nsStyleList& aOther) = delete;
1277 : public:
1278 8352 : nsRect mImageRegion; // [inherited] the rect to use within an image
1279 :
1280 : private:
1281 : // nsStyleQuoteValues objects representing two common values, for sharing.
1282 : static mozilla::StaticRefPtr<nsStyleQuoteValues> sInitialQuotes;
1283 : static mozilla::StaticRefPtr<nsStyleQuoteValues> sNoneQuotes;
1284 : };
1285 :
1286 : struct nsStyleGridLine
1287 : {
1288 : // http://dev.w3.org/csswg/css-grid/#typedef-grid-line
1289 : // XXXmats we could optimize memory size here
1290 : bool mHasSpan;
1291 : int32_t mInteger; // 0 means not provided
1292 280 : nsString mLineName; // Empty string means not provided.
1293 280 :
1294 280 : // These are the limits that we choose to clamp grid line numbers to.
1295 : // http://dev.w3.org/csswg/css-grid/#overlarge-grids
1296 : // mInteger is clamped to this range:
1297 280 : static const int32_t kMinLine = -10000;
1298 : static const int32_t kMaxLine = 10000;
1299 7400 :
1300 7400 : nsStyleGridLine()
1301 7400 : : mHasSpan(false)
1302 7400 : , mInteger(0)
1303 : // mLineName get its default constructor, the empty string
1304 7400 : {
1305 : }
1306 7400 :
1307 7400 : nsStyleGridLine(const nsStyleGridLine& aOther)
1308 14800 : {
1309 7400 : (*this) = aOther;
1310 : }
1311 368 :
1312 : void operator=(const nsStyleGridLine& aOther)
1313 368 : {
1314 736 : mHasSpan = aOther.mHasSpan;
1315 736 : mInteger = aOther.mInteger;
1316 : mLineName = aOther.mLineName;
1317 : }
1318 :
1319 : bool operator!=(const nsStyleGridLine& aOther) const
1320 : {
1321 : return mHasSpan != aOther.mHasSpan ||
1322 : mInteger != aOther.mInteger ||
1323 : mLineName != aOther.mLineName;
1324 : }
1325 :
1326 : void SetToInteger(uint32_t value)
1327 : {
1328 : mHasSpan = false;
1329 : mInteger = value;
1330 : mLineName.Truncate();
1331 : }
1332 0 :
1333 : void SetAuto()
1334 0 : {
1335 0 : mHasSpan = false;
1336 : mInteger = 0;
1337 : mLineName.Truncate();
1338 0 : }
1339 :
1340 : bool IsAuto() const
1341 : {
1342 : bool haveInitialValues = mInteger == 0 && mLineName.IsEmpty();
1343 : MOZ_ASSERT(!(haveInitialValues && mHasSpan),
1344 : "should not have 'span' when other components are "
1345 : "at their initial values");
1346 : return haveInitialValues;
1347 : }
1348 : };
1349 :
1350 : // Computed value of the grid-template-columns or grid-template-rows property
1351 : // (but *not* grid-template-areas.)
1352 : // http://dev.w3.org/csswg/css-grid/#track-sizing
1353 : //
1354 : // This represents either:
1355 : // * none:
1356 : // mIsSubgrid is false, all three arrays are empty
1357 : // * <track-list>:
1358 : // mIsSubgrid is false,
1359 : // mMinTrackSizingFunctions and mMaxTrackSizingFunctions
1360 : // are of identical non-zero size,
1361 : // and mLineNameLists is one element longer than that.
1362 : // (Delimiting N columns requires N+1 lines:
1363 : // one before each track, plus one at the very end.)
1364 : //
1365 : // An omitted <line-names> is still represented in mLineNameLists,
1366 : // as an empty sub-array.
1367 : //
1368 : // A <track-size> specified as a single <track-breadth> is represented
1369 : // as identical min and max sizing functions.
1370 : // A 'fit-content(size)' <track-size> is represented as eStyleUnit_None
1371 : // in the min sizing function and 'size' in the max sizing function.
1372 : //
1373 : // The units for nsStyleCoord are:
1374 : // * eStyleUnit_Percent represents a <percentage>
1375 : // * eStyleUnit_FlexFraction represents a <flex> flexible fraction
1376 : // * eStyleUnit_Coord represents a <length>
1377 : // * eStyleUnit_Enumerated represents min-content or max-content
1378 : // * subgrid <line-name-list>?:
1379 : // mIsSubgrid is true,
1380 : // mLineNameLists may or may not be empty,
1381 : // mMinTrackSizingFunctions and mMaxTrackSizingFunctions are empty.
1382 0 : //
1383 : // If mRepeatAutoIndex != -1 then that index is an <auto-repeat> and
1384 : // mIsAutoFill == true means it's an 'auto-fill', otherwise 'auto-fit'.
1385 : // mRepeatAutoLineNameListBefore is the list of line names before the track
1386 : // size, mRepeatAutoLineNameListAfter the names after. (They are empty
1387 : // when there is no <auto-repeat> track, i.e. when mRepeatAutoIndex == -1).
1388 : // When mIsSubgrid is true, mRepeatAutoLineNameListBefore contains the line
1389 : // names and mRepeatAutoLineNameListAfter is empty.
1390 : struct nsStyleGridTemplate
1391 : {
1392 : nsTArray<nsTArray<nsString>> mLineNameLists;
1393 0 : nsTArray<nsStyleCoord> mMinTrackSizingFunctions;
1394 0 : nsTArray<nsStyleCoord> mMaxTrackSizingFunctions;
1395 : nsTArray<nsString> mRepeatAutoLineNameListBefore;
1396 0 : nsTArray<nsString> mRepeatAutoLineNameListAfter;
1397 : int16_t mRepeatAutoIndex; // -1 or the track index for an auto-fill/fit track
1398 0 : bool mIsAutoFill : 1;
1399 : bool mIsSubgrid : 1;
1400 0 :
1401 : nsStyleGridTemplate()
1402 0 : : mRepeatAutoIndex(-1)
1403 0 : , mIsAutoFill(false)
1404 0 : , mIsSubgrid(false)
1405 0 : {
1406 0 : }
1407 0 :
1408 0 : inline bool operator==(const nsStyleGridTemplate& aOther) const {
1409 0 : return
1410 : mIsSubgrid == aOther.mIsSubgrid &&
1411 : mLineNameLists == aOther.mLineNameLists &&
1412 : mMinTrackSizingFunctions == aOther.mMinTrackSizingFunctions &&
1413 0 : mMaxTrackSizingFunctions == aOther.mMaxTrackSizingFunctions &&
1414 : mIsAutoFill == aOther.mIsAutoFill &&
1415 : mRepeatAutoIndex == aOther.mRepeatAutoIndex &&
1416 0 : mRepeatAutoLineNameListBefore == aOther.mRepeatAutoLineNameListBefore &&
1417 0 : mRepeatAutoLineNameListAfter == aOther.mRepeatAutoLineNameListAfter;
1418 0 : }
1419 :
1420 : bool HasRepeatAuto() const {
1421 : return mRepeatAutoIndex != -1;
1422 : }
1423 :
1424 : bool IsRepeatAutoIndex(uint32_t aIndex) const {
1425 : MOZ_ASSERT(aIndex < uint32_t(2*nsStyleGridLine::kMaxLine));
1426 : return int32_t(aIndex) == mRepeatAutoIndex;
1427 : }
1428 : };
1429 :
1430 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition
1431 : {
1432 : explicit nsStylePosition(const nsPresContext* aContext);
1433 : nsStylePosition(const nsStylePosition& aOther);
1434 : ~nsStylePosition();
1435 : void FinishStyle(nsPresContext*, const nsStylePosition*) {}
1436 : const static bool kHasFinishStyle = false;
1437 :
1438 : nsChangeHint CalcDifference(const nsStylePosition& aNewData,
1439 : const nsStyleVisibility* aOldStyleVisibility) const;
1440 :
1441 : /**
1442 : * Return the used value for 'align-self' given our parent ComputedStyle
1443 : * aParent (or null for the root).
1444 : */
1445 : uint8_t UsedAlignSelf(mozilla::ComputedStyle* aParent) const;
1446 :
1447 : /**
1448 : * Return the used value for 'justify-self' given our parent ComputedStyle
1449 : * aParent (or null for the root).
1450 : */
1451 : uint8_t UsedJustifySelf(mozilla::ComputedStyle* aParent) const;
1452 :
1453 : mozilla::Position mObjectPosition; // [reset]
1454 : nsStyleSides mOffset; // [reset] coord, percent, calc, auto
1455 : nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto
1456 : nsStyleCoord mMinWidth; // [reset] coord, percent, enum, calc
1457 : nsStyleCoord mMaxWidth; // [reset] coord, percent, enum, calc, none
1458 : nsStyleCoord mHeight; // [reset] coord, percent, calc, auto
1459 : nsStyleCoord mMinHeight; // [reset] coord, percent, calc
1460 : nsStyleCoord mMaxHeight; // [reset] coord, percent, calc, none
1461 : nsStyleCoord mFlexBasis; // [reset] coord, percent, enum, calc, auto
1462 : nsStyleCoord mGridAutoColumnsMin; // [reset] coord, percent, enum, calc, flex
1463 : nsStyleCoord mGridAutoColumnsMax; // [reset] coord, percent, enum, calc, flex
1464 : nsStyleCoord mGridAutoRowsMin; // [reset] coord, percent, enum, calc, flex
1465 : nsStyleCoord mGridAutoRowsMax; // [reset] coord, percent, enum, calc, flex
1466 : uint8_t mGridAutoFlow; // [reset] enumerated. See nsStyleConsts.h
1467 : mozilla::StyleBoxSizing mBoxSizing; // [reset] see nsStyleConsts.h
1468 :
1469 : uint16_t mAlignContent; // [reset] fallback value in the high byte
1470 : uint8_t mAlignItems; // [reset] see nsStyleConsts.h
1471 : uint8_t mAlignSelf; // [reset] see nsStyleConsts.h
1472 : uint16_t mJustifyContent; // [reset] fallback value in the high byte
1473 : // We cascade mSpecifiedJustifyItems, to handle the auto value, but store the
1474 : // computed value in mJustifyItems.
1475 : //
1476 : // They're effectively only different in this regard: mJustifyItems is set to
1477 : // mSpecifiedJustifyItems, except when the latter is AUTO -- in that case,
1478 : // mJustifyItems is set to NORMAL, or to the parent ComputedStyle's
1479 : // mJustifyItems if it has the legacy flag.
1480 : //
1481 : // This last part happens in ComputedStyle::ApplyStyleFixups.
1482 : uint8_t mSpecifiedJustifyItems; // [reset] see nsStyleConsts.h
1483 : uint8_t mJustifyItems; // [reset] see nsStyleConsts.h
1484 : uint8_t mJustifySelf; // [reset] see nsStyleConsts.h
1485 : uint8_t mFlexDirection; // [reset] see nsStyleConsts.h
1486 : uint8_t mFlexWrap; // [reset] see nsStyleConsts.h
1487 : uint8_t mObjectFit; // [reset] see nsStyleConsts.h
1488 : int32_t mOrder; // [reset] integer
1489 : float mFlexGrow; // [reset] float
1490 : float mFlexShrink; // [reset] float
1491 : nsStyleCoord mZIndex; // [reset] integer, auto
1492 : mozilla::UniquePtr<nsStyleGridTemplate> mGridTemplateColumns;
1493 : mozilla::UniquePtr<nsStyleGridTemplate> mGridTemplateRows;
1494 :
1495 : // nullptr for 'none'
1496 : RefPtr<mozilla::css::GridTemplateAreasValue> mGridTemplateAreas;
1497 :
1498 : nsStyleGridLine mGridColumnStart;
1499 : nsStyleGridLine mGridColumnEnd;
1500 : nsStyleGridLine mGridRowStart;
1501 : nsStyleGridLine mGridRowEnd;
1502 24 : nsStyleCoord mColumnGap; // [reset] normal, coord, percent, calc
1503 : nsStyleCoord mRowGap; // [reset] normal, coord, percent, calc
1504 26 :
1505 26 : // FIXME: Logical-coordinate equivalents to these WidthDepends... and
1506 : // HeightDepends... methods have been introduced (see below); we probably
1507 : // want to work towards removing the physical methods, and using the logical
1508 : // ones in all cases.
1509 :
1510 : bool WidthDependsOnContainer() const
1511 : {
1512 : return mWidth.GetUnit() == eStyleUnit_Auto ||
1513 : WidthCoordDependsOnContainer(mWidth);
1514 : }
1515 :
1516 : // NOTE: For a flex item, "min-width:auto" is supposed to behave like
1517 22 : // "min-content", which does depend on the container, so you might think we'd
1518 : // need a special case for "flex item && min-width:auto" here. However,
1519 22 : // we don't actually need that special-case code, because flex items are
1520 : // explicitly supposed to *ignore* their min-width (i.e. behave like it's 0)
1521 : // until the flex container explicitly considers it. So -- since the flex
1522 : // container doesn't rely on this method, we don't need to worry about
1523 : // special behavior for flex items' "min-width:auto" values here.
1524 : bool MinWidthDependsOnContainer() const
1525 : { return WidthCoordDependsOnContainer(mMinWidth); }
1526 : bool MaxWidthDependsOnContainer() const
1527 : { return WidthCoordDependsOnContainer(mMaxWidth); }
1528 960 :
1529 : // Note that these functions count 'auto' as depending on the
1530 1034 : // container since that's the case for absolutely positioned elements.
1531 1108 : // However, some callers do not care about this case and should check
1532 : // for it, since it is the most common case.
1533 : // FIXME: We should probably change the assumption to be the other way
1534 : // around.
1535 : // Consider this as part of moving to the logical-coordinate APIs.
1536 : bool HeightDependsOnContainer() const
1537 1916 : {
1538 : return mHeight.GetUnit() == eStyleUnit_Auto || // CSS 2.1, 10.6.4, item (5)
1539 1916 : HeightCoordDependsOnContainer(mHeight);
1540 : }
1541 1002 :
1542 : // NOTE: The comment above MinWidthDependsOnContainer about flex items
1543 3006 : // applies here, too.
1544 : bool MinHeightDependsOnContainer() const
1545 : { return HeightCoordDependsOnContainer(mMinHeight); }
1546 : bool MaxHeightDependsOnContainer() const
1547 : { return HeightCoordDependsOnContainer(mMaxHeight); }
1548 :
1549 : bool OffsetHasPercent(mozilla::Side aSide) const
1550 : {
1551 : return mOffset.Get(aSide).HasPercent();
1552 : }
1553 :
1554 : // Logical-coordinate accessors for width and height properties,
1555 : // given a WritingMode value. The definitions of these methods are
1556 : // found in WritingModes.h (after the WritingMode class is fully
1557 : // declared).
1558 : inline nsStyleCoord& ISize(mozilla::WritingMode aWM);
1559 : inline nsStyleCoord& MinISize(mozilla::WritingMode aWM);
1560 : inline nsStyleCoord& MaxISize(mozilla::WritingMode aWM);
1561 : inline nsStyleCoord& BSize(mozilla::WritingMode aWM);
1562 : inline nsStyleCoord& MinBSize(mozilla::WritingMode aWM);
1563 : inline nsStyleCoord& MaxBSize(mozilla::WritingMode aWM);
1564 : inline const nsStyleCoord& ISize(mozilla::WritingMode aWM) const;
1565 : inline const nsStyleCoord& MinISize(mozilla::WritingMode aWM) const;
1566 : inline const nsStyleCoord& MaxISize(mozilla::WritingMode aWM) const;
1567 : inline const nsStyleCoord& BSize(mozilla::WritingMode aWM) const;
1568 : inline const nsStyleCoord& MinBSize(mozilla::WritingMode aWM) const;
1569 : inline const nsStyleCoord& MaxBSize(mozilla::WritingMode aWM) const;
1570 : inline bool ISizeDependsOnContainer(mozilla::WritingMode aWM) const;
1571 : inline bool MinISizeDependsOnContainer(mozilla::WritingMode aWM) const;
1572 : inline bool MaxISizeDependsOnContainer(mozilla::WritingMode aWM) const;
1573 : inline bool BSizeDependsOnContainer(mozilla::WritingMode aWM) const;
1574 : inline bool MinBSizeDependsOnContainer(mozilla::WritingMode aWM) const;
1575 1990 : inline bool MaxBSizeDependsOnContainer(mozilla::WritingMode aWM) const;
1576 :
1577 : const nsStyleGridTemplate& GridTemplateColumns() const;
1578 400 : const nsStyleGridTemplate& GridTemplateRows() const;
1579 :
1580 140 : private:
1581 : static bool WidthCoordDependsOnContainer(const nsStyleCoord &aCoord);
1582 4 : static bool HeightCoordDependsOnContainer(const nsStyleCoord &aCoord)
1583 4 : { return aCoord.HasPercent(); }
1584 0 : };
1585 4 :
1586 : struct nsStyleTextOverflowSide
1587 : {
1588 : nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
1589 :
1590 : bool operator==(const nsStyleTextOverflowSide& aOther) const {
1591 : return mType == aOther.mType &&
1592 : (mType != NS_STYLE_TEXT_OVERFLOW_STRING ||
1593 : mString == aOther.mString);
1594 : }
1595 256 : bool operator!=(const nsStyleTextOverflowSide& aOther) const {
1596 : return !(*this == aOther);
1597 70 : }
1598 2 :
1599 2 : nsString mString;
1600 : uint8_t mType;
1601 2 : };
1602 2 :
1603 : struct nsStyleTextOverflow
1604 : {
1605 : nsStyleTextOverflow() : mLogicalDirections(true) {}
1606 0 : bool operator==(const nsStyleTextOverflow& aOther) const {
1607 0 : return mLeft == aOther.mLeft && mRight == aOther.mRight;
1608 : }
1609 0 : bool operator!=(const nsStyleTextOverflow& aOther) const {
1610 0 : return !(*this == aOther);
1611 : }
1612 :
1613 : // Returns the value to apply on the left side.
1614 0 : const nsStyleTextOverflowSide& GetLeft(uint8_t aDirection) const {
1615 0 : NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
1616 : aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
1617 0 : return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
1618 0 : mLeft : mRight;
1619 : }
1620 :
1621 : // Returns the value to apply on the right side.
1622 : const nsStyleTextOverflowSide& GetRight(uint8_t aDirection) const {
1623 0 : NS_ASSERTION(aDirection == NS_STYLE_DIRECTION_LTR ||
1624 : aDirection == NS_STYLE_DIRECTION_RTL, "bad direction");
1625 : return !mLogicalDirections || aDirection == NS_STYLE_DIRECTION_LTR ?
1626 : mRight : mLeft;
1627 : }
1628 0 :
1629 : // Returns the first value that was specified.
1630 : const nsStyleTextOverflowSide* GetFirstValue() const {
1631 : return mLogicalDirections ? &mRight : &mLeft;
1632 : }
1633 :
1634 : // Returns the second value, or null if there was only one value specified.
1635 : const nsStyleTextOverflowSide* GetSecondValue() const {
1636 : return mLogicalDirections ? nullptr : &mRight;
1637 : }
1638 :
1639 : nsStyleTextOverflowSide mLeft; // start side when mLogicalDirections is true
1640 : nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
1641 : bool mLogicalDirections; // true when only one value was specified
1642 : };
1643 :
1644 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset
1645 : {
1646 : explicit nsStyleTextReset(const nsPresContext* aContext);
1647 : nsStyleTextReset(const nsStyleTextReset& aOther);
1648 : ~nsStyleTextReset();
1649 : void FinishStyle(nsPresContext*, const nsStyleTextReset*) {}
1650 : const static bool kHasFinishStyle = false;
1651 :
1652 : // Note the difference between this and
1653 : // ComputedStyle::HasTextDecorationLines.
1654 : bool HasTextDecorationLines() const {
1655 : return mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_NONE &&
1656 : mTextDecorationLine != NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
1657 : }
1658 :
1659 : nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const;
1660 :
1661 : nsStyleTextOverflow mTextOverflow; // [reset] enum, string
1662 :
1663 : uint8_t mTextDecorationLine; // [reset] see nsStyleConsts.h
1664 : uint8_t mTextDecorationStyle; // [reset] see nsStyleConsts.h
1665 : uint8_t mUnicodeBidi; // [reset] see nsStyleConsts.h
1666 : nscoord mInitialLetterSink; // [reset] 0 means normal
1667 : float mInitialLetterSize; // [reset] 0.0f means normal
1668 : mozilla::StyleComplexColor mTextDecorationColor; // [reset]
1669 : };
1670 :
1671 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText
1672 : {
1673 : explicit nsStyleText(const nsPresContext* aContext);
1674 : nsStyleText(const nsStyleText& aOther);
1675 : ~nsStyleText();
1676 : void FinishStyle(nsPresContext*, const nsStyleText*) {}
1677 : const static bool kHasFinishStyle = false;
1678 :
1679 : nsChangeHint CalcDifference(const nsStyleText& aNewData) const;
1680 :
1681 : uint8_t mTextAlign; // [inherited] see nsStyleConsts.h
1682 : uint8_t mTextAlignLast; // [inherited] see nsStyleConsts.h
1683 : bool mTextAlignTrue : 1; // [inherited] see nsStyleConsts.h
1684 : bool mTextAlignLastTrue : 1; // [inherited] see nsStyleConsts.h
1685 : mozilla::StyleTextJustify mTextJustify; // [inherited]
1686 : uint8_t mTextTransform; // [inherited] see nsStyleConsts.h
1687 : mozilla::StyleWhiteSpace mWhiteSpace; // [inherited] see nsStyleConsts.h
1688 : uint8_t mWordBreak; // [inherited] see nsStyleConsts.h
1689 : uint8_t mOverflowWrap; // [inherited] see nsStyleConsts.h
1690 : mozilla::StyleHyphens mHyphens; // [inherited] see nsStyleConsts.h
1691 : uint8_t mRubyAlign; // [inherited] see nsStyleConsts.h
1692 : uint8_t mRubyPosition; // [inherited] see nsStyleConsts.h
1693 : uint8_t mTextSizeAdjust; // [inherited] see nsStyleConsts.h
1694 : uint8_t mTextCombineUpright; // [inherited] see nsStyleConsts.h
1695 : uint8_t mControlCharacterVisibility; // [inherited] see nsStyleConsts.h
1696 : uint8_t mTextEmphasisPosition; // [inherited] see nsStyleConsts.h
1697 : uint8_t mTextEmphasisStyle; // [inherited] see nsStyleConsts.h
1698 : uint8_t mTextRendering; // [inherited] see nsStyleConsts.h
1699 : mozilla::StyleComplexColor mTextEmphasisColor; // [inherited]
1700 : mozilla::StyleComplexColor mWebkitTextFillColor; // [inherited]
1701 : mozilla::StyleComplexColor mWebkitTextStrokeColor; // [inherited]
1702 :
1703 : nsStyleCoord mTabSize; // [inherited] coord, factor, calc
1704 : nsStyleCoord mWordSpacing; // [inherited] coord, percent, calc
1705 : nsStyleCoord mLetterSpacing; // [inherited] coord, normal
1706 172 : nsStyleCoord mLineHeight; // [inherited] coord, factor, normal
1707 172 : nsStyleCoord mTextIndent; // [inherited] coord, percent, calc
1708 172 : nscoord mWebkitTextStrokeWidth; // [inherited] coord
1709 172 :
1710 : RefPtr<nsCSSShadowArray> mTextShadow; // [inherited] nullptr in case of a zero-length
1711 :
1712 30 : nsString mTextEmphasisStyleString; // [inherited]
1713 30 :
1714 30 : bool WhiteSpaceIsSignificant() const {
1715 30 : return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
1716 : mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
1717 : mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
1718 26 : }
1719 26 :
1720 22 : bool NewlineIsSignificantStyle() const {
1721 48 : return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
1722 26 : mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
1723 : mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
1724 : }
1725 :
1726 8 : bool WhiteSpaceOrNewlineIsSignificant() const {
1727 8 : return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
1728 : mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
1729 : mWhiteSpace == mozilla::StyleWhiteSpace::PreLine ||
1730 88 : mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
1731 88 : }
1732 88 :
1733 88 : bool TabIsSignificant() const {
1734 : return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
1735 : mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap;
1736 10 : }
1737 10 :
1738 10 : bool WhiteSpaceCanWrapStyle() const {
1739 : return mWhiteSpace == mozilla::StyleWhiteSpace::Normal ||
1740 : mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
1741 : mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
1742 88 : }
1743 :
1744 : bool WordCanWrapStyle() const {
1745 : return WhiteSpaceCanWrapStyle() &&
1746 : mOverflowWrap == NS_STYLE_OVERFLOWWRAP_BREAK_WORD;
1747 : }
1748 :
1749 : bool HasTextEmphasis() const {
1750 : return !mTextEmphasisStyleString.IsEmpty();
1751 : }
1752 :
1753 : bool HasWebkitTextStroke() const {
1754 : return mWebkitTextStrokeWidth > 0;
1755 : }
1756 :
1757 : // These are defined in nsStyleStructInlines.h.
1758 : inline bool HasTextShadow() const;
1759 : inline nsCSSShadowArray* GetTextShadow() const;
1760 :
1761 : // The aContextFrame argument on each of these is the frame this
1762 : // style struct is for. If the frame is for SVG text or inside ruby,
1763 : // the return value will be massaged to be something that makes sense
1764 : // for those cases.
1765 : inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const;
1766 : inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
1767 : inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
1768 :
1769 : mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const;
1770 : };
1771 :
1772 : struct nsStyleImageOrientation
1773 : {
1774 : static nsStyleImageOrientation CreateAsAngleAndFlip(double aRadians,
1775 : bool aFlip) {
1776 : uint8_t orientation(0);
1777 :
1778 : // Compute the final angle value, rounding to the closest quarter turn.
1779 : double roundedAngle = fmod(aRadians, 2 * M_PI);
1780 : if (roundedAngle < 0) {
1781 : roundedAngle = roundedAngle + 2 * M_PI;
1782 : }
1783 : if (roundedAngle < 0.25 * M_PI) { orientation = ANGLE_0; }
1784 : else if (roundedAngle < 0.75 * M_PI) { orientation = ANGLE_90; }
1785 : else if (roundedAngle < 1.25 * M_PI) { orientation = ANGLE_180;}
1786 : else if (roundedAngle < 1.75 * M_PI) { orientation = ANGLE_270;}
1787 : else { orientation = ANGLE_0; }
1788 :
1789 0 : // Add a bit for 'flip' if needed.
1790 : if (aFlip) {
1791 0 : orientation |= FLIP_MASK;
1792 0 : }
1793 0 :
1794 : return nsStyleImageOrientation(orientation);
1795 0 : }
1796 :
1797 : static nsStyleImageOrientation CreateAsOrientationAndFlip(uint8_t aOrientation,
1798 : bool aFlip) {
1799 : MOZ_ASSERT(aOrientation <= ANGLE_270);
1800 : if (aFlip) {
1801 : aOrientation |= FLIP_MASK;
1802 : }
1803 0 : return nsStyleImageOrientation(aOrientation);
1804 : }
1805 :
1806 : static nsStyleImageOrientation CreateAsFlip() {
1807 70 : return nsStyleImageOrientation(FLIP_MASK);
1808 : }
1809 :
1810 0 : static nsStyleImageOrientation CreateAsFromImage() {
1811 0 : return nsStyleImageOrientation(FROM_IMAGE_MASK);
1812 : }
1813 :
1814 : // The default constructor yields 0 degrees of rotation and no flip.
1815 : nsStyleImageOrientation() : mOrientation(0) { }
1816 :
1817 0 : bool IsDefault() const { return mOrientation == 0; }
1818 0 : bool IsFlipped() const { return mOrientation & FLIP_MASK; }
1819 : bool IsFromImage() const { return mOrientation & FROM_IMAGE_MASK; }
1820 0 : bool SwapsWidthAndHeight() const {
1821 0 : uint8_t angle = mOrientation & ORIENTATION_MASK;
1822 0 : return (angle == ANGLE_90) || (angle == ANGLE_270);
1823 : }
1824 0 :
1825 0 : mozilla::image::Angle Angle() const {
1826 : switch (mOrientation & ORIENTATION_MASK) {
1827 : case ANGLE_0: return mozilla::image::Angle::D0;
1828 : case ANGLE_90: return mozilla::image::Angle::D90;
1829 0 : case ANGLE_180: return mozilla::image::Angle::D180;
1830 0 : case ANGLE_270: return mozilla::image::Angle::D270;
1831 0 : default:
1832 0 : NS_NOTREACHED("Unexpected angle");
1833 0 : return mozilla::image::Angle::D0;
1834 0 : }
1835 : }
1836 0 :
1837 0 : nsStyleCoord AngleAsCoord() const {
1838 : switch (mOrientation & ORIENTATION_MASK) {
1839 : case ANGLE_0: return nsStyleCoord(0.0f, eStyleUnit_Degree);
1840 : case ANGLE_90: return nsStyleCoord(90.0f, eStyleUnit_Degree);
1841 : case ANGLE_180: return nsStyleCoord(180.0f, eStyleUnit_Degree);
1842 60 : case ANGLE_270: return nsStyleCoord(270.0f, eStyleUnit_Degree);
1843 : default:
1844 : NS_NOTREACHED("Unexpected angle");
1845 : return nsStyleCoord();
1846 60 : }
1847 : }
1848 :
1849 : bool operator==(const nsStyleImageOrientation& aOther) const {
1850 : return aOther.mOrientation == mOrientation;
1851 : }
1852 :
1853 : bool operator!=(const nsStyleImageOrientation& aOther) const {
1854 : return !(*this == aOther);
1855 : }
1856 :
1857 : protected:
1858 : enum Bits {
1859 : ORIENTATION_MASK = 0x1 | 0x2, // The bottom two bits are the angle.
1860 : FLIP_MASK = 0x4, // Whether the image should be flipped.
1861 : FROM_IMAGE_MASK = 0x8, // Whether the image's inherent orientation
1862 : }; // should be used.
1863 :
1864 : enum Angles {
1865 : ANGLE_0 = 0,
1866 : ANGLE_90 = 1,
1867 : ANGLE_180 = 2,
1868 : ANGLE_270 = 3,
1869 : };
1870 :
1871 : explicit nsStyleImageOrientation(uint8_t aOrientation)
1872 : : mOrientation(aOrientation)
1873 : { }
1874 172 :
1875 86 : uint8_t mOrientation;
1876 86 : };
1877 :
1878 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility
1879 : {
1880 : explicit nsStyleVisibility(const nsPresContext* aContext);
1881 : nsStyleVisibility(const nsStyleVisibility& aVisibility);
1882 : ~nsStyleVisibility() {
1883 : MOZ_COUNT_DTOR(nsStyleVisibility);
1884 : }
1885 : void FinishStyle(nsPresContext*, const nsStyleVisibility*) {}
1886 : const static bool kHasFinishStyle = false;
1887 :
1888 : nsChangeHint CalcDifference(const nsStyleVisibility& aNewData) const;
1889 :
1890 : nsStyleImageOrientation mImageOrientation; // [inherited]
1891 0 : uint8_t mDirection; // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
1892 : uint8_t mVisible; // [inherited]
1893 : uint8_t mImageRendering; // [inherited] see nsStyleConsts.h
1894 : uint8_t mWritingMode; // [inherited] see nsStyleConsts.h
1895 0 : uint8_t mTextOrientation; // [inherited] see nsStyleConsts.h
1896 : uint8_t mColorAdjust; // [inherited] see nsStyleConsts.h
1897 :
1898 : bool IsVisible() const {
1899 : return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
1900 : }
1901 :
1902 3236 : bool IsVisibleOrCollapsed() const {
1903 : return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
1904 6594 : (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
1905 : }
1906 : };
1907 :
1908 : namespace mozilla {
1909 :
1910 : struct StyleTransition
1911 4 : {
1912 : StyleTransition() { /* leaves uninitialized; see also SetInitialValues */ }
1913 : explicit StyleTransition(const StyleTransition& aCopy);
1914 :
1915 0 : void SetInitialValues();
1916 :
1917 : // Delay and Duration are in milliseconds
1918 :
1919 : const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
1920 : float GetDelay() const { return mDelay; }
1921 : float GetDuration() const { return mDuration; }
1922 : nsCSSPropertyID GetProperty() const { return mProperty; }
1923 : nsAtom* GetUnknownProperty() const { return mUnknownProperty; }
1924 :
1925 : void SetTimingFunction(const nsTimingFunction& aTimingFunction)
1926 : { mTimingFunction = aTimingFunction; }
1927 : void SetDelay(float aDelay) { mDelay = aDelay; }
1928 : void SetDuration(float aDuration) { mDuration = aDuration; }
1929 :
1930 : nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
1931 :
1932 : bool operator==(const StyleTransition& aOther) const;
1933 : bool operator!=(const StyleTransition& aOther) const
1934 : { return !(*this == aOther); }
1935 :
1936 : private:
1937 : nsTimingFunction mTimingFunction;
1938 3234 : float mDuration;
1939 : float mDelay;
1940 6570 : nsCSSPropertyID mProperty;
1941 : RefPtr<nsAtom> mUnknownProperty; // used when mProperty is
1942 : // eCSSProperty_UNKNOWN or
1943 : // eCSSPropertyExtra_variable
1944 : };
1945 :
1946 : struct StyleAnimation
1947 0 : {
1948 : StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
1949 : explicit StyleAnimation(const StyleAnimation& aCopy);
1950 0 :
1951 : void SetInitialValues();
1952 :
1953 : // Delay and Duration are in milliseconds
1954 :
1955 : const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; }
1956 : float GetDelay() const { return mDelay; }
1957 : float GetDuration() const { return mDuration; }
1958 : nsAtom* GetName() const { return mName; }
1959 : dom::PlaybackDirection GetDirection() const { return mDirection; }
1960 2 : dom::FillMode GetFillMode() const { return mFillMode; }
1961 0 : uint8_t GetPlayState() const { return mPlayState; }
1962 : float GetIterationCount() const { return mIterationCount; }
1963 :
1964 : void SetTimingFunction(const nsTimingFunction& aTimingFunction)
1965 : { mTimingFunction = aTimingFunction; }
1966 : void SetDelay(float aDelay) { mDelay = aDelay; }
1967 : void SetDuration(float aDuration) { mDuration = aDuration; }
1968 : void SetName(already_AddRefed<nsAtom> aName) { mName = aName; }
1969 : void SetName(nsAtom* aName) { mName = aName; }
1970 : void SetDirection(dom::PlaybackDirection aDirection) { mDirection = aDirection; }
1971 : void SetFillMode(dom::FillMode aFillMode) { mFillMode = aFillMode; }
1972 : void SetPlayState(uint8_t aPlayState) { mPlayState = aPlayState; }
1973 : void SetIterationCount(float aIterationCount)
1974 : { mIterationCount = aIterationCount; }
1975 :
1976 : nsTimingFunction& TimingFunctionSlot() { return mTimingFunction; }
1977 :
1978 : bool operator==(const StyleAnimation& aOther) const;
1979 : bool operator!=(const StyleAnimation& aOther) const
1980 : { return !(*this == aOther); }
1981 :
1982 : private:
1983 : nsTimingFunction mTimingFunction;
1984 : float mDuration;
1985 0 : float mDelay;
1986 : RefPtr<nsAtom> mName; // nsGkAtoms::_empty for 'none'
1987 : dom::PlaybackDirection mDirection;
1988 0 : dom::FillMode mFillMode;
1989 0 : uint8_t mPlayState;
1990 0 : float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
1991 : };
1992 0 :
1993 0 : class StyleBasicShape final
1994 : {
1995 : public:
1996 : explicit StyleBasicShape(StyleBasicShapeType type)
1997 : : mType(type),
1998 : mFillRule(StyleFillRule::Nonzero)
1999 : {
2000 : mPosition.SetInitialPercentValues(0.5f);
2001 : }
2002 :
2003 : StyleBasicShapeType GetShapeType() const { return mType; }
2004 : nsCSSKeyword GetShapeTypeName() const;
2005 0 :
2006 0 : StyleFillRule GetFillRule() const { return mFillRule; }
2007 : void SetFillRule(StyleFillRule aFillRule)
2008 : {
2009 0 : MOZ_ASSERT(mType == StyleBasicShapeType::Polygon, "expected polygon");
2010 : mFillRule = aFillRule;
2011 : }
2012 :
2013 : mozilla::Position& GetPosition() {
2014 : MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
2015 : mType == StyleBasicShapeType::Ellipse,
2016 : "expected circle or ellipse");
2017 : return mPosition;
2018 0 : }
2019 0 : const mozilla::Position& GetPosition() const {
2020 0 : MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
2021 0 : mType == StyleBasicShapeType::Ellipse,
2022 0 : "expected circle or ellipse");
2023 0 : return mPosition;
2024 : }
2025 :
2026 : bool HasRadius() const {
2027 : MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
2028 : nsStyleCoord zero;
2029 0 : zero.SetCoordValue(0);
2030 0 : NS_FOR_CSS_HALF_CORNERS(corner) {
2031 0 : if (mRadius.Get(corner) != zero) {
2032 : return true;
2033 : }
2034 : }
2035 : return false;
2036 : }
2037 : nsStyleCorners& GetRadius() {
2038 : MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
2039 : return mRadius;
2040 : }
2041 : const nsStyleCorners& GetRadius() const {
2042 0 : MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
2043 : return mRadius;
2044 : }
2045 :
2046 : // mCoordinates has coordinates for polygon or radii for
2047 : // ellipse and circle.
2048 : nsTArray<nsStyleCoord>& Coordinates()
2049 : {
2050 0 : return mCoordinates;
2051 : }
2052 0 :
2053 0 : const nsTArray<nsStyleCoord>& Coordinates() const
2054 0 : {
2055 0 : return mCoordinates;
2056 0 : }
2057 :
2058 : bool operator==(const StyleBasicShape& aOther) const
2059 : {
2060 : return mType == aOther.mType &&
2061 : mFillRule == aOther.mFillRule &&
2062 : mCoordinates == aOther.mCoordinates &&
2063 : mPosition == aOther.mPosition &&
2064 : mRadius == aOther.mRadius;
2065 : }
2066 : bool operator!=(const StyleBasicShape& aOther) const {
2067 : return !(*this == aOther);
2068 : }
2069 :
2070 : private:
2071 : StyleBasicShapeType mType;
2072 : StyleFillRule mFillRule;
2073 :
2074 : // mCoordinates has coordinates for polygon or radii for
2075 : // ellipse and circle.
2076 : // (top, right, bottom, left) for inset
2077 : nsTArray<nsStyleCoord> mCoordinates;
2078 420 : // position of center for ellipse or circle
2079 : mozilla::Position mPosition;
2080 : // corner radii for inset (0 if not set)
2081 : nsStyleCorners mRadius;
2082 1146 : };
2083 1146 :
2084 1146 : struct StyleShapeSource final
2085 : {
2086 : StyleShapeSource() = default;
2087 :
2088 : StyleShapeSource(const StyleShapeSource& aSource);
2089 :
2090 78 : ~StyleShapeSource()
2091 : {
2092 78 : }
2093 :
2094 : StyleShapeSource& operator=(const StyleShapeSource& aOther);
2095 :
2096 : bool operator==(const StyleShapeSource& aOther) const;
2097 :
2098 : bool operator!=(const StyleShapeSource& aOther) const
2099 : {
2100 0 : return !(*this == aOther);
2101 : }
2102 0 :
2103 : StyleShapeSourceType GetType() const
2104 0 : {
2105 0 : return mType;
2106 : }
2107 :
2108 : css::URLValue* GetURL() const
2109 : {
2110 0 : MOZ_ASSERT(mType == StyleShapeSourceType::URL, "Wrong shape source type!");
2111 : return mShapeImage
2112 0 : ? static_cast<css::URLValue*>(mShapeImage->GetURLValue())
2113 0 : : nullptr;
2114 : }
2115 :
2116 : void SetURL(css::URLValue* aValue);
2117 :
2118 : const UniquePtr<nsStyleImage>& GetShapeImage() const
2119 : {
2120 : MOZ_ASSERT(mType == StyleShapeSourceType::Image, "Wrong shape source type!");
2121 : return mShapeImage;
2122 : }
2123 0 :
2124 : // Iff we have "shape-outside:<image>" with an image URI (not a gradient),
2125 0 : // this method returns the corresponding imgIRequest*. Else, returns
2126 0 : // null.
2127 : imgIRequest* GetShapeImageData() const;
2128 :
2129 : void SetShapeImage(UniquePtr<nsStyleImage> aShapeImage);
2130 :
2131 : const UniquePtr<StyleBasicShape>& GetBasicShape() const
2132 0 : {
2133 : MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
2134 0 : return mBasicShape;
2135 : }
2136 :
2137 0 : void SetBasicShape(UniquePtr<StyleBasicShape> aBasicShape,
2138 : StyleGeometryBox aReferenceBox);
2139 :
2140 : StyleGeometryBox GetReferenceBox() const
2141 : {
2142 : MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
2143 : mType == StyleShapeSourceType::Shape,
2144 : "Wrong shape source type!");
2145 : return mReferenceBox;
2146 : }
2147 :
2148 : void SetReferenceBox(StyleGeometryBox aReferenceBox);
2149 :
2150 : private:
2151 : void* operator new(size_t) = delete;
2152 :
2153 : void DoCopy(const StyleShapeSource& aOther);
2154 :
2155 : mozilla::UniquePtr<StyleBasicShape> mBasicShape;
2156 : mozilla::UniquePtr<nsStyleImage> mShapeImage;
2157 : StyleShapeSourceType mType = StyleShapeSourceType::None;
2158 : StyleGeometryBox mReferenceBox = StyleGeometryBox::NoBox;
2159 : };
2160 :
2161 : } // namespace mozilla
2162 :
2163 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
2164 : {
2165 : typedef mozilla::StyleGeometryBox StyleGeometryBox;
2166 :
2167 : explicit nsStyleDisplay(const nsPresContext* aContext);
2168 : nsStyleDisplay(const nsStyleDisplay& aOther);
2169 : ~nsStyleDisplay();
2170 :
2171 : void FinishStyle(nsPresContext*, const nsStyleDisplay*);
2172 : const static bool kHasFinishStyle = true;
2173 :
2174 : nsChangeHint CalcDifference(const nsStyleDisplay& aNewData) const;
2175 :
2176 : // We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
2177 : // mBinding->mOriginPrincipal.
2178 : RefPtr<mozilla::css::URLValue> mBinding; // [reset]
2179 : mozilla::StyleDisplay mDisplay; // [reset] see nsStyleConsts.h StyleDisplay
2180 : mozilla::StyleDisplay mOriginalDisplay; // [reset] saved mDisplay for
2181 : // position:absolute/fixed
2182 : // and float:left/right;
2183 : // otherwise equal to
2184 : // mDisplay
2185 : uint8_t mContain; // [reset] see nsStyleConsts.h NS_STYLE_CONTAIN_*
2186 : uint8_t mAppearance; // [reset]
2187 : uint8_t mPosition; // [reset] see nsStyleConsts.h
2188 :
2189 : // [reset] See StyleFloat in nsStyleConsts.h.
2190 : mozilla::StyleFloat mFloat;
2191 : // [reset] Save mFloat for position:absolute/fixed; otherwise equal to mFloat.
2192 : mozilla::StyleFloat mOriginalFloat;
2193 :
2194 : mozilla::StyleClear mBreakType; // [reset]
2195 : uint8_t mBreakInside; // [reset] NS_STYLE_PAGE_BREAK_AUTO/AVOID
2196 : bool mBreakBefore; // [reset]
2197 : bool mBreakAfter; // [reset]
2198 : uint8_t mOverflowX; // [reset] see nsStyleConsts.h
2199 : uint8_t mOverflowY; // [reset] see nsStyleConsts.h
2200 : uint8_t mOverflowClipBoxBlock; // [reset] see nsStyleConsts.h
2201 : uint8_t mOverflowClipBoxInline; // [reset] see nsStyleConsts.h
2202 : uint8_t mResize; // [reset] see nsStyleConsts.h
2203 : mozilla::StyleOrient mOrient; // [reset] see nsStyleConsts.h
2204 : uint8_t mIsolation; // [reset] see nsStyleConsts.h
2205 : uint8_t mTopLayer; // [reset] see nsStyleConsts.h
2206 : uint8_t mWillChangeBitField; // [reset] see nsStyleConsts.h. Stores a
2207 : // bitfield representation of the properties
2208 : // that are frequently queried. This should
2209 : // match mWillChange. Also tracks if any of the
2210 : // properties in the will-change list require
2211 : // a stacking context.
2212 : nsTArray<RefPtr<nsAtom>> mWillChange;
2213 :
2214 : uint8_t mTouchAction; // [reset] see nsStyleConsts.h
2215 : uint8_t mScrollBehavior; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_*
2216 : mozilla::StyleOverscrollBehavior mOverscrollBehaviorX; // [reset] see nsStyleConsts.h
2217 : mozilla::StyleOverscrollBehavior mOverscrollBehaviorY; // [reset] see nsStyleConsts.h
2218 : uint8_t mScrollSnapTypeX; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
2219 : uint8_t mScrollSnapTypeY; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_SNAP_TYPE_*
2220 : nsStyleCoord mScrollSnapPointsX; // [reset]
2221 : nsStyleCoord mScrollSnapPointsY; // [reset]
2222 : mozilla::Position mScrollSnapDestination; // [reset]
2223 : nsTArray<mozilla::Position> mScrollSnapCoordinate; // [reset]
2224 :
2225 : // mSpecifiedTransform is the list of transform functions as
2226 : // specified, or null to indicate there is no transform. (inherit or
2227 : // initial are replaced by an actual list of transform functions, or
2228 : // null, as appropriate.)
2229 : uint8_t mBackfaceVisibility;
2230 : uint8_t mTransformStyle;
2231 : StyleGeometryBox mTransformBox; // [reset] see nsStyleConsts.h
2232 : RefPtr<nsCSSValueSharedList> mSpecifiedTransform; // [reset]
2233 : RefPtr<nsCSSValueSharedList> mSpecifiedRotate; // [reset]
2234 : RefPtr<nsCSSValueSharedList> mSpecifiedTranslate; // [reset]
2235 : RefPtr<nsCSSValueSharedList> mSpecifiedScale; // [reset]
2236 :
2237 : // Used to store the final combination of mSpecifiedTranslate,
2238 : // mSpecifiedRotate, mSpecifiedScale and mSpecifiedTransform.
2239 : // Use GetCombinedTransform() to get the final transform, instead of
2240 : // accessing mCombinedTransform directly.
2241 : RefPtr<nsCSSValueSharedList> mCombinedTransform;
2242 :
2243 : nsStyleCoord mTransformOrigin[3]; // [reset] percent, coord, calc, 3rd param is coord, calc only
2244 : nsStyleCoord mChildPerspective; // [reset] none, coord
2245 : nsStyleCoord mPerspectiveOrigin[2]; // [reset] percent, coord, calc
2246 :
2247 : nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
2248 :
2249 : nsStyleAutoArray<mozilla::StyleTransition> mTransitions; // [reset]
2250 12 :
2251 : // The number of elements in mTransitions that are not from repeating
2252 12 : // a list due to another property being longer.
2253 : uint32_t mTransitionTimingFunctionCount,
2254 4 : mTransitionDurationCount,
2255 : mTransitionDelayCount,
2256 4 : mTransitionPropertyCount;
2257 :
2258 4 : nsCSSPropertyID GetTransitionProperty(uint32_t aIndex) const
2259 : {
2260 4 : return mTransitions[aIndex % mTransitionPropertyCount].GetProperty();
2261 : }
2262 4 : float GetTransitionDelay(uint32_t aIndex) const
2263 : {
2264 8 : return mTransitions[aIndex % mTransitionDelayCount].GetDelay();
2265 : }
2266 4 : float GetTransitionDuration(uint32_t aIndex) const
2267 : {
2268 : return mTransitions[aIndex % mTransitionDurationCount].GetDuration();
2269 : }
2270 12 : const nsTimingFunction& GetTransitionTimingFunction(uint32_t aIndex) const
2271 12 : {
2272 8 : return mTransitions[aIndex % mTransitionTimingFunctionCount].GetTimingFunction();
2273 : }
2274 : float GetTransitionCombinedDuration(uint32_t aIndex) const
2275 : {
2276 : // https://drafts.csswg.org/css-transitions/#transition-combined-duration
2277 : return
2278 : std::max(mTransitions[aIndex % mTransitionDurationCount].GetDuration(),
2279 : 0.0f)
2280 : + mTransitions[aIndex % mTransitionDelayCount].GetDelay();
2281 : }
2282 :
2283 : nsStyleAutoArray<mozilla::StyleAnimation> mAnimations; // [reset]
2284 :
2285 : // The number of elements in mAnimations that are not from repeating
2286 : // a list due to another property being longer.
2287 : uint32_t mAnimationTimingFunctionCount,
2288 0 : mAnimationDurationCount,
2289 : mAnimationDelayCount,
2290 0 : mAnimationNameCount,
2291 : mAnimationDirectionCount,
2292 0 : mAnimationFillModeCount,
2293 : mAnimationPlayStateCount,
2294 0 : mAnimationIterationCountCount;
2295 :
2296 0 : nsAtom* GetAnimationName(uint32_t aIndex) const
2297 : {
2298 0 : return mAnimations[aIndex % mAnimationNameCount].GetName();
2299 : }
2300 0 : float GetAnimationDelay(uint32_t aIndex) const
2301 : {
2302 0 : return mAnimations[aIndex % mAnimationDelayCount].GetDelay();
2303 : }
2304 0 : float GetAnimationDuration(uint32_t aIndex) const
2305 : {
2306 0 : return mAnimations[aIndex % mAnimationDurationCount].GetDuration();
2307 : }
2308 0 : mozilla::dom::PlaybackDirection GetAnimationDirection(uint32_t aIndex) const
2309 : {
2310 0 : return mAnimations[aIndex % mAnimationDirectionCount].GetDirection();
2311 : }
2312 0 : mozilla::dom::FillMode GetAnimationFillMode(uint32_t aIndex) const
2313 : {
2314 0 : return mAnimations[aIndex % mAnimationFillModeCount].GetFillMode();
2315 : }
2316 0 : uint8_t GetAnimationPlayState(uint32_t aIndex) const
2317 : {
2318 0 : return mAnimations[aIndex % mAnimationPlayStateCount].GetPlayState();
2319 : }
2320 : float GetAnimationIterationCount(uint32_t aIndex) const
2321 : {
2322 : return mAnimations[aIndex % mAnimationIterationCountCount].GetIterationCount();
2323 : }
2324 : const nsTimingFunction& GetAnimationTimingFunction(uint32_t aIndex) const
2325 : {
2326 : return mAnimations[aIndex % mAnimationTimingFunctionCount].GetTimingFunction();
2327 : }
2328 :
2329 20 : // The threshold used for extracting a shape from shape-outside: <image>.
2330 20 : float mShapeImageThreshold = 0.0f; // [reset]
2331 4 :
2332 0 : // The margin around a shape-outside: <image>.
2333 20 : nsStyleCoord mShapeMargin;
2334 20 :
2335 : mozilla::StyleShapeSource mShapeOutside; // [reset]
2336 :
2337 : bool IsBlockInsideStyle() const {
2338 : return mozilla::StyleDisplay::Block == mDisplay ||
2339 : mozilla::StyleDisplay::ListItem == mDisplay ||
2340 2 : mozilla::StyleDisplay::InlineBlock == mDisplay ||
2341 2 : mozilla::StyleDisplay::TableCaption == mDisplay ||
2342 2 : mozilla::StyleDisplay::FlowRoot == mDisplay;
2343 2 : // Should TABLE_CELL be included here? They have
2344 2 : // block frames nested inside of them.
2345 2 : // (But please audit all callers before changing.)
2346 2 : }
2347 2 :
2348 : bool IsBlockOutsideStyle() const {
2349 : return mozilla::StyleDisplay::Block == mDisplay ||
2350 570 : mozilla::StyleDisplay::Flex == mDisplay ||
2351 570 : mozilla::StyleDisplay::WebkitBox == mDisplay ||
2352 570 : mozilla::StyleDisplay::Grid == mDisplay ||
2353 570 : mozilla::StyleDisplay::ListItem == mDisplay ||
2354 980 : mozilla::StyleDisplay::Table == mDisplay ||
2355 490 : mozilla::StyleDisplay::FlowRoot == mDisplay;
2356 980 : }
2357 490 :
2358 980 : static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) {
2359 490 : return mozilla::StyleDisplay::Inline == aDisplay ||
2360 490 : mozilla::StyleDisplay::InlineBlock == aDisplay ||
2361 : mozilla::StyleDisplay::InlineTable == aDisplay ||
2362 490 : mozilla::StyleDisplay::MozInlineBox == aDisplay ||
2363 : mozilla::StyleDisplay::InlineFlex == aDisplay ||
2364 1060 : mozilla::StyleDisplay::WebkitInlineBox == aDisplay ||
2365 570 : mozilla::StyleDisplay::InlineGrid == aDisplay ||
2366 : mozilla::StyleDisplay::MozInlineGrid == aDisplay ||
2367 : mozilla::StyleDisplay::MozInlineStack == aDisplay ||
2368 : mozilla::StyleDisplay::Ruby == aDisplay ||
2369 544 : mozilla::StyleDisplay::RubyBase == aDisplay ||
2370 : mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
2371 : mozilla::StyleDisplay::RubyText == aDisplay ||
2372 : mozilla::StyleDisplay::RubyTextContainer == aDisplay ||
2373 26 : mozilla::StyleDisplay::Contents == aDisplay;
2374 : }
2375 :
2376 946 : bool IsInlineOutsideStyle() const {
2377 946 : return IsDisplayTypeInlineOutside(mDisplay);
2378 : }
2379 946 :
2380 946 : bool IsOriginalDisplayInlineOutsideStyle() const {
2381 946 : return IsDisplayTypeInlineOutside(mOriginalDisplay);
2382 946 : }
2383 1892 :
2384 946 : bool IsInnerTableStyle() const {
2385 : return mozilla::StyleDisplay::TableCaption == mDisplay ||
2386 : mozilla::StyleDisplay::TableCell == mDisplay ||
2387 : IsInternalTableStyleExceptCell();
2388 1196 : }
2389 :
2390 : bool IsInternalTableStyleExceptCell() const {
2391 : return mozilla::StyleDisplay::TableRow == mDisplay ||
2392 4630 : mozilla::StyleDisplay::TableRowGroup == mDisplay ||
2393 1196 : mozilla::StyleDisplay::TableHeaderGroup == mDisplay ||
2394 : mozilla::StyleDisplay::TableFooterGroup == mDisplay ||
2395 : mozilla::StyleDisplay::TableColumn == mDisplay ||
2396 : mozilla::StyleDisplay::TableColumnGroup == mDisplay;
2397 2172 : }
2398 2172 :
2399 : bool IsFloatingStyle() const {
2400 : return mozilla::StyleFloat::None != mFloat;
2401 92 : }
2402 :
2403 : bool IsAbsolutelyPositionedStyle() const {
2404 : return NS_STYLE_POSITION_ABSOLUTE == mPosition ||
2405 : NS_STYLE_POSITION_FIXED == mPosition;
2406 : }
2407 :
2408 : bool IsRelativelyPositionedStyle() const {
2409 0 : return NS_STYLE_POSITION_RELATIVE == mPosition ||
2410 0 : NS_STYLE_POSITION_STICKY == mPosition;
2411 : }
2412 : bool IsPositionForcingStackingContext() const {
2413 : return NS_STYLE_POSITION_STICKY == mPosition ||
2414 0 : NS_STYLE_POSITION_FIXED == mPosition;
2415 : }
2416 :
2417 : static bool IsRubyDisplayType(mozilla::StyleDisplay aDisplay) {
2418 : return mozilla::StyleDisplay::Ruby == aDisplay ||
2419 : IsInternalRubyDisplayType(aDisplay);
2420 : }
2421 :
2422 : static bool IsInternalRubyDisplayType(mozilla::StyleDisplay aDisplay) {
2423 : return mozilla::StyleDisplay::RubyBase == aDisplay ||
2424 256 : mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
2425 256 : mozilla::StyleDisplay::RubyText == aDisplay ||
2426 : mozilla::StyleDisplay::RubyTextContainer == aDisplay;
2427 : }
2428 :
2429 : bool IsRubyDisplayType() const {
2430 : return IsRubyDisplayType(mDisplay);
2431 : }
2432 :
2433 : bool IsInternalRubyDisplayType() const {
2434 4048 : return IsInternalRubyDisplayType(mDisplay);
2435 23672 : }
2436 11682 :
2437 11836 : bool IsOutOfFlowStyle() const {
2438 7942 : return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());
2439 : }
2440 :
2441 0 : bool IsScrollableOverflow() const {
2442 0 : // mOverflowX and mOverflowY always match when one of them is
2443 : // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
2444 : return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
2445 3982 : mOverflowX != NS_STYLE_OVERFLOW_CLIP;
2446 3982 : }
2447 :
2448 : bool IsContainPaint() const {
2449 : return (NS_STYLE_CONTAIN_PAINT & mContain) &&
2450 0 : !IsInternalRubyDisplayType() &&
2451 : !IsInternalTableStyleExceptCell();
2452 : }
2453 :
2454 : /* Returns whether the element has the -moz-transform property
2455 : * or a related property. */
2456 : bool HasTransformStyle() const {
2457 : return mSpecifiedTransform || mSpecifiedRotate || mSpecifiedTranslate ||
2458 : mSpecifiedScale ||
2459 : mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
2460 : (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM);
2461 : }
2462 :
2463 : bool HasIndividualTransform() const {
2464 : return mSpecifiedRotate || mSpecifiedTranslate || mSpecifiedScale;
2465 : }
2466 :
2467 : bool HasPerspectiveStyle() const {
2468 : return mChildPerspective.GetUnit() == eStyleUnit_Coord;
2469 : }
2470 :
2471 : bool BackfaceIsHidden() const {
2472 : return mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
2473 : }
2474 :
2475 : // These are defined in nsStyleStructInlines.h.
2476 :
2477 : // The aContextFrame argument on each of these is the frame this
2478 : // style struct is for. If the frame is for SVG text, the return
2479 : // value will be massaged to be something that makes sense for
2480 : // SVG text.
2481 : inline bool IsBlockInside(const nsIFrame* aContextFrame) const;
2482 : inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
2483 : inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
2484 : inline bool IsOriginalDisplayInlineOutside(const nsIFrame* aContextFrame) const;
2485 : inline mozilla::StyleDisplay GetDisplay(const nsIFrame* aContextFrame) const;
2486 : inline bool IsFloating(const nsIFrame* aContextFrame) const;
2487 : inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
2488 : inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
2489 :
2490 : // These methods are defined in nsStyleStructInlines.h.
2491 :
2492 : /**
2493 : * Returns whether the element is a containing block for its
2494 : * absolutely positioned descendants.
2495 : * aContextFrame is the frame for which this is the nsStyleDisplay.
2496 : */
2497 : inline bool IsAbsPosContainingBlock(const nsIFrame* aContextFrame) const;
2498 :
2499 : /**
2500 : * The same as IsAbsPosContainingBlock, except skipping the tests that
2501 : * are based on the frame rather than the ComputedStyle (thus
2502 : * potentially returning a false positive).
2503 : */
2504 : inline bool IsAbsPosContainingBlockForAppropriateFrame(
2505 : mozilla::ComputedStyle&) const;
2506 :
2507 : /**
2508 : * Returns true when the element has the transform property
2509 : * or a related property, and supports CSS transforms.
2510 : * aContextFrame is the frame for which this is the nsStyleDisplay.
2511 : */
2512 : inline bool HasTransform(const nsIFrame* aContextFrame) const;
2513 :
2514 : /**
2515 : * Returns true when the element has the perspective property,
2516 : * and supports CSS transforms. aContextFrame is the frame for
2517 : * which this is the nsStyleDisplay.
2518 : */
2519 : inline bool HasPerspective(const nsIFrame* aContextFrame) const;
2520 :
2521 : /**
2522 : * Returns true when the element is a containing block for its fixed-pos
2523 : * descendants.
2524 : * aContextFrame is the frame for which this is the nsStyleDisplay.
2525 : */
2526 : inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const;
2527 :
2528 : /**
2529 : * The same as IsFixedPosContainingBlock, except skipping the tests that
2530 : * are based on the frame rather than the ComputedStyle (thus
2531 : * potentially returning a false positive).
2532 : */
2533 : inline bool IsFixedPosContainingBlockForAppropriateFrame(
2534 : mozilla::ComputedStyle&) const;
2535 :
2536 : /**
2537 : * Returns the final combined transform.
2538 : **/
2539 : already_AddRefed<nsCSSValueSharedList> GetCombinedTransform() const {
2540 : if (mCombinedTransform) {
2541 : return do_AddRef(mCombinedTransform);
2542 : }
2543 :
2544 : // backward compatible to gecko-backed style system.
2545 : return mSpecifiedTransform ? do_AddRef(mSpecifiedTransform) : nullptr;
2546 : }
2547 :
2548 : private:
2549 : // Helpers for above functions, which do some but not all of the tests
2550 : // for them (since transform must be tested separately for each).
2551 : inline bool HasAbsPosContainingBlockStyleInternal() const;
2552 : inline bool HasFixedPosContainingBlockStyleInternal(
2553 : mozilla::ComputedStyle&) const;
2554 : void GenerateCombinedTransform();
2555 : public:
2556 : // Return the 'float' and 'clear' properties, with inline-{start,end} values
2557 : // resolved to {left,right} according to the given writing mode. These are
2558 : // defined in WritingModes.h.
2559 : inline mozilla::StyleFloat PhysicalFloats(mozilla::WritingMode aWM) const;
2560 : inline mozilla::StyleClear PhysicalBreakType(mozilla::WritingMode aWM) const;
2561 : };
2562 :
2563 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable
2564 : {
2565 : explicit nsStyleTable(const nsPresContext* aContext);
2566 : nsStyleTable(const nsStyleTable& aOther);
2567 : ~nsStyleTable();
2568 : void FinishStyle(nsPresContext*, const nsStyleTable*) {}
2569 : const static bool kHasFinishStyle = false;
2570 :
2571 : nsChangeHint CalcDifference(const nsStyleTable& aNewData) const;
2572 :
2573 : uint8_t mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
2574 : int32_t mSpan; // [reset] the number of columns spanned by a colgroup or col
2575 : };
2576 :
2577 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder
2578 : {
2579 : explicit nsStyleTableBorder(const nsPresContext* aContext);
2580 : nsStyleTableBorder(const nsStyleTableBorder& aOther);
2581 : ~nsStyleTableBorder();
2582 : void FinishStyle(nsPresContext*, const nsStyleTableBorder*) {}
2583 : const static bool kHasFinishStyle = false;
2584 :
2585 : nsChangeHint CalcDifference(const nsStyleTableBorder& aNewData) const;
2586 :
2587 : nscoord mBorderSpacingCol;// [inherited]
2588 : nscoord mBorderSpacingRow;// [inherited]
2589 : uint8_t mBorderCollapse;// [inherited]
2590 : uint8_t mCaptionSide; // [inherited]
2591 : uint8_t mEmptyCells; // [inherited]
2592 : };
2593 :
2594 : enum nsStyleContentType {
2595 : eStyleContentType_String = 1,
2596 : eStyleContentType_Image = 10,
2597 : eStyleContentType_Attr = 20,
2598 : eStyleContentType_Counter = 30,
2599 : eStyleContentType_Counters = 31,
2600 : eStyleContentType_OpenQuote = 40,
2601 : eStyleContentType_CloseQuote = 41,
2602 : eStyleContentType_NoOpenQuote = 42,
2603 : eStyleContentType_NoCloseQuote = 43,
2604 : eStyleContentType_AltContent = 50,
2605 : eStyleContentType_Uninitialized
2606 : };
2607 :
2608 : struct nsStyleContentAttr {
2609 : RefPtr<nsAtom> mName; // Non-null.
2610 : RefPtr<nsAtom> mNamespaceURL; // May be null.
2611 :
2612 : bool operator==(const nsStyleContentAttr& aOther) const
2613 : {
2614 : return mName == aOther.mName && mNamespaceURL == aOther.mNamespaceURL;
2615 : }
2616 : };
2617 :
2618 : class nsStyleContentData
2619 : {
2620 : public:
2621 : nsStyleContentData()
2622 : : mType(eStyleContentType_Uninitialized)
2623 : {
2624 : MOZ_COUNT_CTOR(nsStyleContentData);
2625 : mContent.mString = nullptr;
2626 : }
2627 : nsStyleContentData(const nsStyleContentData&);
2628 :
2629 : ~nsStyleContentData();
2630 : nsStyleContentData& operator=(const nsStyleContentData& aOther);
2631 : bool operator==(const nsStyleContentData& aOther) const;
2632 :
2633 : bool operator!=(const nsStyleContentData& aOther) const {
2634 : return !(*this == aOther);
2635 : }
2636 :
2637 : nsStyleContentType GetType() const { return mType; }
2638 :
2639 : char16_t* GetString() const
2640 : {
2641 : MOZ_ASSERT(mType == eStyleContentType_String);
2642 : return mContent.mString;
2643 : }
2644 :
2645 : const nsStyleContentAttr* GetAttr() const {
2646 : MOZ_ASSERT(mType == eStyleContentType_Attr);
2647 : MOZ_ASSERT(mContent.mAttr);
2648 : return mContent.mAttr;
2649 : }
2650 :
2651 : struct CounterFunction
2652 : {
2653 : nsString mIdent;
2654 : // This is only used when it is a counters() function.
2655 : nsString mSeparator;
2656 : mozilla::CounterStylePtr mCounterStyle;
2657 :
2658 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CounterFunction)
2659 :
2660 : bool operator==(const CounterFunction& aOther) const;
2661 : bool operator!=(const CounterFunction& aOther) const {
2662 : return !(*this == aOther);
2663 : }
2664 : private:
2665 : ~CounterFunction() {}
2666 : };
2667 :
2668 : CounterFunction* GetCounters() const
2669 : {
2670 : MOZ_ASSERT(mType == eStyleContentType_Counter ||
2671 : mType == eStyleContentType_Counters);
2672 : MOZ_ASSERT(mContent.mCounters->mCounterStyle.IsResolved(),
2673 : "Counter style should have been resolved");
2674 : return mContent.mCounters;
2675 : }
2676 :
2677 : nsStyleImageRequest* ImageRequest() const
2678 : {
2679 : MOZ_ASSERT(mType == eStyleContentType_Image);
2680 : MOZ_ASSERT(mContent.mImage);
2681 : return mContent.mImage;
2682 : }
2683 :
2684 : imgRequestProxy* GetImage() const
2685 : {
2686 : return ImageRequest()->get();
2687 : }
2688 :
2689 : void SetKeyword(nsStyleContentType aType)
2690 : {
2691 : MOZ_ASSERT(aType == eStyleContentType_OpenQuote ||
2692 : aType == eStyleContentType_CloseQuote ||
2693 : aType == eStyleContentType_NoOpenQuote ||
2694 : aType == eStyleContentType_NoCloseQuote ||
2695 : aType == eStyleContentType_AltContent);
2696 : MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
2697 : "should only initialize nsStyleContentData once");
2698 : mType = aType;
2699 : }
2700 :
2701 : void SetString(nsStyleContentType aType, const char16_t* aString)
2702 : {
2703 : MOZ_ASSERT(aType == eStyleContentType_String);
2704 : MOZ_ASSERT(aString);
2705 : MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
2706 : "should only initialize nsStyleContentData once");
2707 : mType = aType;
2708 : mContent.mString = NS_strdup(aString);
2709 : }
2710 :
2711 : void SetCounters(nsStyleContentType aType,
2712 : already_AddRefed<CounterFunction> aCounterFunction)
2713 : {
2714 : MOZ_ASSERT(aType == eStyleContentType_Counter ||
2715 : aType == eStyleContentType_Counters);
2716 : MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
2717 : "should only initialize nsStyleContentData once");
2718 : mType = aType;
2719 : mContent.mCounters = aCounterFunction.take();
2720 : MOZ_ASSERT(mContent.mCounters);
2721 : }
2722 :
2723 : void SetImageRequest(already_AddRefed<nsStyleImageRequest> aRequest)
2724 : {
2725 : MOZ_ASSERT(mType == eStyleContentType_Uninitialized,
2726 : "should only initialize nsStyleContentData once");
2727 : mType = eStyleContentType_Image;
2728 : mContent.mImage = aRequest.take();
2729 : MOZ_ASSERT(mContent.mImage);
2730 : }
2731 :
2732 : void Resolve(nsPresContext*, const nsStyleContentData*);
2733 :
2734 : private:
2735 : nsStyleContentType mType;
2736 : union {
2737 : char16_t *mString;
2738 : nsStyleContentAttr* mAttr;
2739 : nsStyleImageRequest* mImage;
2740 : CounterFunction* mCounters;
2741 : } mContent;
2742 : };
2743 :
2744 : struct nsStyleCounterData
2745 : {
2746 : nsString mCounter;
2747 : int32_t mValue;
2748 :
2749 : bool operator==(const nsStyleCounterData& aOther) const {
2750 : return mValue == aOther.mValue && mCounter == aOther.mCounter;
2751 : }
2752 :
2753 : bool operator!=(const nsStyleCounterData& aOther) const {
2754 : return !(*this == aOther);
2755 : }
2756 : };
2757 :
2758 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent
2759 : {
2760 : explicit nsStyleContent(const nsPresContext* aContext);
2761 : nsStyleContent(const nsStyleContent& aContent);
2762 : ~nsStyleContent();
2763 : void FinishStyle(nsPresContext*, const nsStyleContent*);
2764 : const static bool kHasFinishStyle = true;
2765 :
2766 : nsChangeHint CalcDifference(const nsStyleContent& aNewData) const;
2767 :
2768 : uint32_t ContentCount() const { return mContents.Length(); } // [reset]
2769 :
2770 : const nsStyleContentData& ContentAt(uint32_t aIndex) const {
2771 : return mContents[aIndex];
2772 : }
2773 :
2774 : nsStyleContentData& ContentAt(uint32_t aIndex) { return mContents[aIndex]; }
2775 :
2776 : void AllocateContents(uint32_t aCount) {
2777 : // We need to run the destructors of the elements of mContents, so we
2778 : // delete and reallocate even if aCount == mContentCount. (If
2779 : // nsStyleContentData had its members private and managed their
2780 : // ownership on setting, we wouldn't need this, but that seems
2781 : // unnecessary at this point.)
2782 : mContents.Clear();
2783 : mContents.SetLength(aCount);
2784 : }
2785 :
2786 : uint32_t CounterIncrementCount() const { return mIncrements.Length(); } // [reset]
2787 : const nsStyleCounterData& CounterIncrementAt(uint32_t aIndex) const {
2788 : return mIncrements[aIndex];
2789 : }
2790 :
2791 : void AllocateCounterIncrements(uint32_t aCount) {
2792 : mIncrements.Clear();
2793 : mIncrements.SetLength(aCount);
2794 : }
2795 :
2796 : void SetCounterIncrementAt(uint32_t aIndex, const nsString& aCounter, int32_t aIncrement) {
2797 : mIncrements[aIndex].mCounter = aCounter;
2798 : mIncrements[aIndex].mValue = aIncrement;
2799 : }
2800 :
2801 : uint32_t CounterResetCount() const { return mResets.Length(); } // [reset]
2802 : const nsStyleCounterData& CounterResetAt(uint32_t aIndex) const {
2803 : return mResets[aIndex];
2804 : }
2805 :
2806 : void AllocateCounterResets(uint32_t aCount) {
2807 : mResets.Clear();
2808 : mResets.SetLength(aCount);
2809 : }
2810 :
2811 : void SetCounterResetAt(uint32_t aIndex, const nsString& aCounter, int32_t aValue) {
2812 : mResets[aIndex].mCounter = aCounter;
2813 : mResets[aIndex].mValue = aValue;
2814 : }
2815 :
2816 : protected:
2817 : nsTArray<nsStyleContentData> mContents;
2818 : nsTArray<nsStyleCounterData> mIncrements;
2819 : nsTArray<nsStyleCounterData> mResets;
2820 : };
2821 :
2822 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset
2823 : {
2824 : explicit nsStyleUIReset(const nsPresContext* aContext);
2825 : nsStyleUIReset(const nsStyleUIReset& aOther);
2826 : ~nsStyleUIReset();
2827 : void FinishStyle(nsPresContext*, const nsStyleUIReset*) {}
2828 : const static bool kHasFinishStyle = false;
2829 :
2830 : nsChangeHint CalcDifference(const nsStyleUIReset& aNewData) const;
2831 :
2832 : mozilla::StyleUserSelect mUserSelect; // [reset](selection-style)
2833 : uint8_t mForceBrokenImageIcon; // [reset] (0 if not forcing, otherwise forcing)
2834 : uint8_t mIMEMode; // [reset]
2835 : mozilla::StyleWindowDragging mWindowDragging; // [reset]
2836 : uint8_t mWindowShadow; // [reset]
2837 : float mWindowOpacity; // [reset]
2838 : RefPtr<nsCSSValueSharedList> mSpecifiedWindowTransform; // [reset]
2839 : nsStyleCoord mWindowTransformOrigin[2]; // [reset] percent, coord, calc
2840 : };
2841 :
2842 : struct nsCursorImage
2843 : {
2844 : bool mHaveHotspot;
2845 : float mHotspotX, mHotspotY;
2846 : RefPtr<nsStyleImageRequest> mImage;
2847 :
2848 : nsCursorImage();
2849 : nsCursorImage(const nsCursorImage& aOther);
2850 :
2851 : nsCursorImage& operator=(const nsCursorImage& aOther);
2852 :
2853 : bool operator==(const nsCursorImage& aOther) const;
2854 : bool operator!=(const nsCursorImage& aOther) const
2855 : {
2856 : return !(*this == aOther);
2857 : }
2858 :
2859 : imgRequestProxy* GetImage() const {
2860 : return mImage->get();
2861 : }
2862 : };
2863 :
2864 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUserInterface
2865 : {
2866 : explicit nsStyleUserInterface(const nsPresContext* aContext);
2867 : nsStyleUserInterface(const nsStyleUserInterface& aOther);
2868 : ~nsStyleUserInterface();
2869 :
2870 : void FinishStyle(nsPresContext*, const nsStyleUserInterface*);
2871 : const static bool kHasFinishStyle = true;
2872 :
2873 : nsChangeHint CalcDifference(const nsStyleUserInterface& aNewData) const;
2874 :
2875 : mozilla::StyleUserInput mUserInput; // [inherited]
2876 : mozilla::StyleUserModify mUserModify; // [inherited] (modify-content)
2877 : mozilla::StyleUserFocus mUserFocus; // [inherited] (auto-select)
2878 : uint8_t mPointerEvents; // [inherited] see nsStyleConsts.h
2879 :
2880 : uint8_t mCursor; // [inherited] See nsStyleConsts.h
2881 : nsTArray<nsCursorImage> mCursorImages; // [inherited] images and coords
2882 : mozilla::StyleComplexColor mCaretColor; // [inherited]
2883 :
2884 : mozilla::StyleComplexColor mScrollbarFaceColor; // [inherited]
2885 : mozilla::StyleComplexColor mScrollbarTrackColor; // [inherited]
2886 :
2887 : inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
2888 :
2889 : bool HasCustomScrollbars() const
2890 : {
2891 : return !mScrollbarFaceColor.IsAuto() || !mScrollbarTrackColor.IsAuto();
2892 : }
2893 : };
2894 :
2895 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL
2896 : {
2897 : explicit nsStyleXUL(const nsPresContext* aContext);
2898 : nsStyleXUL(const nsStyleXUL& aSource);
2899 : ~nsStyleXUL();
2900 : void FinishStyle(nsPresContext*, const nsStyleXUL*) {}
2901 : const static bool kHasFinishStyle = false;
2902 :
2903 : nsChangeHint CalcDifference(const nsStyleXUL& aNewData) const;
2904 :
2905 : float mBoxFlex; // [reset] see nsStyleConsts.h
2906 : uint32_t mBoxOrdinal; // [reset] see nsStyleConsts.h
2907 : mozilla::StyleBoxAlign mBoxAlign; // [reset]
2908 : mozilla::StyleBoxDirection mBoxDirection; // [reset]
2909 : mozilla::StyleBoxOrient mBoxOrient; // [reset]
2910 : mozilla::StyleBoxPack mBoxPack; // [reset]
2911 : mozilla::StyleStackSizing mStackSizing; // [reset] see nsStyleConsts.h
2912 : };
2913 :
2914 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn
2915 : {
2916 : explicit nsStyleColumn(const nsPresContext* aContext);
2917 : nsStyleColumn(const nsStyleColumn& aSource);
2918 : ~nsStyleColumn();
2919 : void FinishStyle(nsPresContext*, const nsStyleColumn*) {}
2920 : const static bool kHasFinishStyle = false;
2921 :
2922 : nsChangeHint CalcDifference(const nsStyleColumn& aNewData) const;
2923 :
2924 : /**
2925 : * This is the maximum number of columns we can process. It's used in both
2926 : * nsColumnSetFrame and nsRuleNode.
2927 : */
2928 : static const uint32_t kMaxColumnCount = 1000;
2929 :
2930 : uint32_t mColumnCount; // [reset] see nsStyleConsts.h
2931 : nsStyleCoord mColumnWidth; // [reset] coord, auto
2932 :
2933 : mozilla::StyleComplexColor mColumnRuleColor; // [reset]
2934 : uint8_t mColumnRuleStyle; // [reset]
2935 : uint8_t mColumnFill; // [reset] see nsStyleConsts.h
2936 : uint8_t mColumnSpan; // [reset] see nsStyleConsts.h
2937 :
2938 : void SetColumnRuleWidth(nscoord aWidth) {
2939 : mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
2940 : }
2941 :
2942 : nscoord GetComputedColumnRuleWidth() const {
2943 : return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
2944 : }
2945 :
2946 : protected:
2947 : nscoord mColumnRuleWidth; // [reset] coord
2948 : nscoord mTwipsPerPixel;
2949 : };
2950 :
2951 : enum nsStyleSVGPaintType : uint8_t {
2952 : eStyleSVGPaintType_None = 1,
2953 : eStyleSVGPaintType_Color,
2954 : eStyleSVGPaintType_Server,
2955 : eStyleSVGPaintType_ContextFill,
2956 : eStyleSVGPaintType_ContextStroke
2957 : };
2958 :
2959 : enum nsStyleSVGFallbackType : uint8_t {
2960 : eStyleSVGFallbackType_NotSet,
2961 : eStyleSVGFallbackType_None,
2962 : eStyleSVGFallbackType_Color,
2963 : };
2964 :
2965 : enum nsStyleSVGOpacitySource : uint8_t {
2966 : eStyleSVGOpacitySource_Normal,
2967 : eStyleSVGOpacitySource_ContextFillOpacity,
2968 : eStyleSVGOpacitySource_ContextStrokeOpacity
2969 : };
2970 :
2971 : class nsStyleSVGPaint
2972 : {
2973 : public:
2974 : explicit nsStyleSVGPaint(nsStyleSVGPaintType aType = nsStyleSVGPaintType(0));
2975 : nsStyleSVGPaint(const nsStyleSVGPaint& aSource);
2976 : ~nsStyleSVGPaint();
2977 :
2978 : nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
2979 :
2980 : nsStyleSVGPaintType Type() const { return mType; }
2981 :
2982 : void SetNone();
2983 : void SetColor(nscolor aColor);
2984 : void SetPaintServer(mozilla::css::URLValue* aPaintServer,
2985 : nsStyleSVGFallbackType aFallbackType,
2986 : nscolor aFallbackColor);
2987 : void SetPaintServer(mozilla::css::URLValue* aPaintServer) {
2988 : SetPaintServer(aPaintServer, eStyleSVGFallbackType_NotSet,
2989 : NS_RGB(0, 0, 0));
2990 : }
2991 : void SetContextValue(nsStyleSVGPaintType aType,
2992 : nsStyleSVGFallbackType aFallbackType,
2993 : nscolor aFallbackColor);
2994 : void SetContextValue(nsStyleSVGPaintType aType) {
2995 : SetContextValue(aType, eStyleSVGFallbackType_NotSet, NS_RGB(0, 0, 0));
2996 : }
2997 :
2998 : nscolor GetColor() const {
2999 : MOZ_ASSERT(mType == eStyleSVGPaintType_Color);
3000 : return mPaint.mColor;
3001 : }
3002 :
3003 : mozilla::css::URLValue* GetPaintServer() const {
3004 : MOZ_ASSERT(mType == eStyleSVGPaintType_Server);
3005 : return mPaint.mPaintServer;
3006 : }
3007 :
3008 : nsStyleSVGFallbackType GetFallbackType() const {
3009 : return mFallbackType;
3010 : }
3011 :
3012 : nscolor GetFallbackColor() const {
3013 : MOZ_ASSERT(mType == eStyleSVGPaintType_Server ||
3014 : mType == eStyleSVGPaintType_ContextFill ||
3015 : mType == eStyleSVGPaintType_ContextStroke);
3016 : return mFallbackColor;
3017 : }
3018 :
3019 : bool operator==(const nsStyleSVGPaint& aOther) const;
3020 : bool operator!=(const nsStyleSVGPaint& aOther) const {
3021 : return !(*this == aOther);
3022 : }
3023 :
3024 : private:
3025 : void Reset();
3026 : void Assign(const nsStyleSVGPaint& aOther);
3027 :
3028 : union {
3029 : nscolor mColor;
3030 : mozilla::css::URLValue* mPaintServer;
3031 : } mPaint;
3032 : nsStyleSVGPaintType mType;
3033 : nsStyleSVGFallbackType mFallbackType;
3034 : nscolor mFallbackColor;
3035 : };
3036 :
3037 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG
3038 : {
3039 : explicit nsStyleSVG(const nsPresContext* aContext);
3040 : nsStyleSVG(const nsStyleSVG& aSource);
3041 : ~nsStyleSVG();
3042 : void FinishStyle(nsPresContext*, const nsStyleSVG*) {}
3043 : const static bool kHasFinishStyle = false;
3044 :
3045 : nsChangeHint CalcDifference(const nsStyleSVG& aNewData) const;
3046 :
3047 : nsStyleSVGPaint mFill; // [inherited]
3048 : nsStyleSVGPaint mStroke; // [inherited]
3049 : RefPtr<mozilla::css::URLValue> mMarkerEnd; // [inherited]
3050 : RefPtr<mozilla::css::URLValue> mMarkerMid; // [inherited]
3051 : RefPtr<mozilla::css::URLValue> mMarkerStart; // [inherited]
3052 : nsTArray<nsStyleCoord> mStrokeDasharray; // [inherited] coord, percent, factor
3053 : nsTArray<RefPtr<nsAtom>> mContextProps;
3054 :
3055 : nsStyleCoord mStrokeDashoffset; // [inherited] coord, percent, factor
3056 : nsStyleCoord mStrokeWidth; // [inherited] coord, percent, factor
3057 :
3058 : float mFillOpacity; // [inherited]
3059 : float mStrokeMiterlimit; // [inherited]
3060 : float mStrokeOpacity; // [inherited]
3061 :
3062 : mozilla::StyleFillRule mClipRule; // [inherited]
3063 : uint8_t mColorInterpolation; // [inherited] see nsStyleConsts.h
3064 : uint8_t mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
3065 : mozilla::StyleFillRule mFillRule; // [inherited] see nsStyleConsts.h
3066 : uint8_t mPaintOrder; // [inherited] see nsStyleConsts.h
3067 : uint8_t mShapeRendering; // [inherited] see nsStyleConsts.h
3068 : uint8_t mStrokeLinecap; // [inherited] see nsStyleConsts.h
3069 : uint8_t mStrokeLinejoin; // [inherited] see nsStyleConsts.h
3070 : uint8_t mTextAnchor; // [inherited] see nsStyleConsts.h
3071 : uint8_t mContextPropsBits; // [inherited] see nsStyleConsts.h.
3072 : // Stores a bitfield representation of
3073 : // the specified properties.
3074 :
3075 : /// Returns true if style has been set to expose the computed values of
3076 : /// certain properties (such as 'fill') to the contents of any linked images.
3077 : bool ExposesContextProperties() const {
3078 : return bool(mContextPropsBits);
3079 : }
3080 :
3081 : nsStyleSVGOpacitySource FillOpacitySource() const {
3082 : uint8_t value = (mContextFlags & FILL_OPACITY_SOURCE_MASK) >>
3083 : FILL_OPACITY_SOURCE_SHIFT;
3084 : return nsStyleSVGOpacitySource(value);
3085 : }
3086 : nsStyleSVGOpacitySource StrokeOpacitySource() const {
3087 : uint8_t value = (mContextFlags & STROKE_OPACITY_SOURCE_MASK) >>
3088 : STROKE_OPACITY_SOURCE_SHIFT;
3089 : return nsStyleSVGOpacitySource(value);
3090 : }
3091 : bool StrokeDasharrayFromObject() const {
3092 : return mContextFlags & STROKE_DASHARRAY_CONTEXT;
3093 : }
3094 : bool StrokeDashoffsetFromObject() const {
3095 : return mContextFlags & STROKE_DASHOFFSET_CONTEXT;
3096 : }
3097 : bool StrokeWidthFromObject() const {
3098 : return mContextFlags & STROKE_WIDTH_CONTEXT;
3099 : }
3100 :
3101 : void SetFillOpacitySource(nsStyleSVGOpacitySource aValue) {
3102 : mContextFlags = (mContextFlags & ~FILL_OPACITY_SOURCE_MASK) |
3103 : (aValue << FILL_OPACITY_SOURCE_SHIFT);
3104 : }
3105 : void SetStrokeOpacitySource(nsStyleSVGOpacitySource aValue) {
3106 : mContextFlags = (mContextFlags & ~STROKE_OPACITY_SOURCE_MASK) |
3107 : (aValue << STROKE_OPACITY_SOURCE_SHIFT);
3108 : }
3109 : void SetStrokeDasharrayFromObject(bool aValue) {
3110 : mContextFlags = (mContextFlags & ~STROKE_DASHARRAY_CONTEXT) |
3111 : (aValue ? STROKE_DASHARRAY_CONTEXT : 0);
3112 : }
3113 : void SetStrokeDashoffsetFromObject(bool aValue) {
3114 : mContextFlags = (mContextFlags & ~STROKE_DASHOFFSET_CONTEXT) |
3115 : (aValue ? STROKE_DASHOFFSET_CONTEXT : 0);
3116 : }
3117 : void SetStrokeWidthFromObject(bool aValue) {
3118 : mContextFlags = (mContextFlags & ~STROKE_WIDTH_CONTEXT) |
3119 : (aValue ? STROKE_WIDTH_CONTEXT : 0);
3120 : }
3121 :
3122 : bool HasMarker() const {
3123 : return mMarkerStart || mMarkerMid || mMarkerEnd;
3124 : }
3125 :
3126 : /**
3127 : * Returns true if the stroke is not "none" and the stroke-opacity is greater
3128 : * than zero. This ignores stroke-widths as that depends on the context.
3129 : */
3130 : bool HasStroke() const {
3131 : return mStroke.Type() != eStyleSVGPaintType_None && mStrokeOpacity > 0;
3132 : }
3133 :
3134 : /**
3135 : * Returns true if the fill is not "none" and the fill-opacity is greater
3136 : * than zero.
3137 : */
3138 : bool HasFill() const {
3139 : return mFill.Type() != eStyleSVGPaintType_None && mFillOpacity > 0;
3140 : }
3141 :
3142 : private:
3143 : // Flags to represent the use of context-fill and context-stroke
3144 : // for fill-opacity or stroke-opacity, and context-value for stroke-dasharray,
3145 : // stroke-dashoffset and stroke-width.
3146 :
3147 : // fill-opacity: context-{fill,stroke}
3148 : static const uint8_t FILL_OPACITY_SOURCE_MASK = 0x03;
3149 : // stroke-opacity: context-{fill,stroke}
3150 : static const uint8_t STROKE_OPACITY_SOURCE_MASK = 0x0C;
3151 : // stroke-dasharray: context-value
3152 : static const uint8_t STROKE_DASHARRAY_CONTEXT = 0x10;
3153 : // stroke-dashoffset: context-value
3154 : static const uint8_t STROKE_DASHOFFSET_CONTEXT = 0x20;
3155 : // stroke-width: context-value
3156 : static const uint8_t STROKE_WIDTH_CONTEXT = 0x40;
3157 : static const uint8_t FILL_OPACITY_SOURCE_SHIFT = 0;
3158 : static const uint8_t STROKE_OPACITY_SOURCE_SHIFT = 2;
3159 :
3160 : uint8_t mContextFlags; // [inherited]
3161 : };
3162 :
3163 : struct nsStyleFilter
3164 : {
3165 : nsStyleFilter();
3166 : nsStyleFilter(const nsStyleFilter& aSource);
3167 : ~nsStyleFilter();
3168 : void FinishStyle(nsPresContext*, const nsStyleFilter*) {}
3169 : const static bool kHasFinishStyle = false;
3170 :
3171 : nsStyleFilter& operator=(const nsStyleFilter& aOther);
3172 :
3173 : bool operator==(const nsStyleFilter& aOther) const;
3174 : bool operator!=(const nsStyleFilter& aOther) const {
3175 : return !(*this == aOther);
3176 : }
3177 :
3178 : uint32_t GetType() const {
3179 : return mType;
3180 : }
3181 :
3182 : const nsStyleCoord& GetFilterParameter() const {
3183 : NS_ASSERTION(mType != NS_STYLE_FILTER_DROP_SHADOW &&
3184 : mType != NS_STYLE_FILTER_URL &&
3185 : mType != NS_STYLE_FILTER_NONE, "wrong filter type");
3186 : return mFilterParameter;
3187 : }
3188 : void SetFilterParameter(const nsStyleCoord& aFilterParameter,
3189 : int32_t aType);
3190 :
3191 : mozilla::css::URLValue* GetURL() const {
3192 : MOZ_ASSERT(mType == NS_STYLE_FILTER_URL, "wrong filter type");
3193 : return mURL;
3194 : }
3195 :
3196 : bool SetURL(mozilla::css::URLValue* aValue);
3197 :
3198 : nsCSSShadowArray* GetDropShadow() const {
3199 : NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type");
3200 : return mDropShadow;
3201 : }
3202 : void SetDropShadow(nsCSSShadowArray* aDropShadow);
3203 :
3204 : private:
3205 : void ReleaseRef();
3206 :
3207 : uint32_t mType; // see NS_STYLE_FILTER_* constants in nsStyleConsts.h
3208 : nsStyleCoord mFilterParameter; // coord, percent, factor, angle
3209 : union {
3210 : mozilla::css::URLValue* mURL;
3211 : nsCSSShadowArray* mDropShadow;
3212 : };
3213 : };
3214 :
3215 : template<>
3216 : struct nsTArray_CopyChooser<nsStyleFilter>
3217 : {
3218 : typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
3219 : };
3220 :
3221 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset
3222 : {
3223 : explicit nsStyleSVGReset(const nsPresContext* aContext);
3224 : nsStyleSVGReset(const nsStyleSVGReset& aSource);
3225 : ~nsStyleSVGReset();
3226 :
3227 : // Resolves and tracks the images in mMask. Only called with a Servo-backed
3228 : // style system, where those images must be resolved later than the OMT
3229 : // nsStyleSVGReset constructor call.
3230 : void FinishStyle(nsPresContext*, const nsStyleSVGReset*);
3231 : const static bool kHasFinishStyle = true;
3232 :
3233 : nsChangeHint CalcDifference(const nsStyleSVGReset& aNewData) const;
3234 :
3235 : bool HasClipPath() const {
3236 : return mClipPath.GetType() != mozilla::StyleShapeSourceType::None;
3237 : }
3238 :
3239 : bool HasMask() const;
3240 :
3241 : bool HasNonScalingStroke() const {
3242 : return mVectorEffect == NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE;
3243 : }
3244 :
3245 : nsStyleImageLayers mMask;
3246 : mozilla::StyleShapeSource mClipPath;// [reset]
3247 : mozilla::StyleComplexColor mStopColor; // [reset]
3248 : mozilla::StyleComplexColor mFloodColor; // [reset]
3249 : mozilla::StyleComplexColor mLightingColor; // [reset]
3250 :
3251 : float mStopOpacity; // [reset]
3252 : float mFloodOpacity; // [reset]
3253 :
3254 : uint8_t mDominantBaseline; // [reset] see nsStyleConsts.h
3255 : uint8_t mVectorEffect; // [reset] see nsStyleConsts.h
3256 : uint8_t mMaskType; // [reset] see nsStyleConsts.h
3257 : };
3258 :
3259 : struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects
3260 : {
3261 : explicit nsStyleEffects(const nsPresContext* aContext);
3262 : nsStyleEffects(const nsStyleEffects& aSource);
3263 : ~nsStyleEffects();
3264 : void FinishStyle(nsPresContext*, const nsStyleEffects*) {}
3265 : const static bool kHasFinishStyle = false;
3266 :
3267 : nsChangeHint CalcDifference(const nsStyleEffects& aNewData) const;
3268 :
3269 : bool HasFilters() const {
3270 : return !mFilters.IsEmpty();
3271 : }
3272 :
3273 : nsTArray<nsStyleFilter> mFilters; // [reset]
3274 : RefPtr<nsCSSShadowArray> mBoxShadow; // [reset] nullptr for 'none'
3275 : nsRect mClip; // [reset] offsets from UL border edge
3276 : float mOpacity; // [reset]
3277 : uint8_t mClipFlags; // [reset] see nsStyleConsts.h
3278 : uint8_t mMixBlendMode; // [reset] see nsStyleConsts.h
3279 : };
3280 :
3281 : #define STATIC_ASSERT_TYPE_LAYOUTS_MATCH(T1, T2) \
3282 : static_assert(sizeof(T1) == sizeof(T2), \
3283 : "Size mismatch between " #T1 " and " #T2); \
3284 : static_assert(alignof(T1) == alignof(T2), \
3285 : "Align mismatch between " #T1 " and " #T2); \
3286 :
3287 : #define STATIC_ASSERT_FIELD_OFFSET_MATCHES(T1, T2, field) \
3288 : static_assert(offsetof(T1, field) == offsetof(T2, field), \
3289 : "Field offset mismatch of " #field " between " #T1 " and " #T2); \
3290 :
3291 : /**
3292 : * These *_Simple types are used to map Gecko types to layout-equivalent but
3293 : * simpler Rust types, to aid Rust binding generation.
3294 : *
3295 : * If something in this types or the assertions below needs to change, ask
3296 : * bholley, heycam or emilio before!
3297 : *
3298 : * <div rustbindgen="true" replaces="nsPoint">
3299 : */
3300 : struct nsPoint_Simple {
3301 : nscoord x, y;
3302 : };
3303 :
3304 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple);
3305 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x);
3306 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y);
3307 :
3308 : /**
3309 : * <div rustbindgen="true" replaces="nsMargin">
3310 : */
3311 : struct nsMargin_Simple {
3312 : nscoord top, right, bottom, left;
3313 : };
3314 :
3315 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple);
3316 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top);
3317 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right);
3318 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom);
3319 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left);
3320 :
3321 : /**
3322 : * <div rustbindgen="true" replaces="nsRect">
3323 : */
3324 : struct nsRect_Simple {
3325 : nscoord x, y, width, height;
3326 : };
3327 :
3328 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple);
3329 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x);
3330 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y);
3331 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width);
3332 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height);
3333 :
3334 : /**
3335 : * <div rustbindgen="true" replaces="nsSize">
3336 : */
3337 : struct nsSize_Simple {
3338 : nscoord width, height;
3339 : };
3340 :
3341 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple);
3342 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width);
3343 : STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height);
3344 :
3345 : /**
3346 : * <div rustbindgen="true" replaces="mozilla::UniquePtr">
3347 : *
3348 : * TODO(Emilio): This is a workaround and we should be able to get rid of this
3349 : * one.
3350 : */
3351 : template<typename T>
3352 : struct UniquePtr_Simple {
3353 : T* mPtr;
3354 : };
3355 :
3356 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(mozilla::UniquePtr<int>, UniquePtr_Simple<int>);
3357 :
3358 : /**
3359 : * <div rustbindgen replaces="nsTArray"></div>
3360 : */
3361 : template<typename T>
3362 : class nsTArray_Simple {
3363 : T* mBuffer;
3364 : public:
3365 : // The existence of a destructor here prevents bindgen from deriving the Clone
3366 : // trait via a simple memory copy.
3367 : ~nsTArray_Simple() {};
3368 : };
3369 :
3370 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<nsStyleImageLayers::Layer>,
3371 : nsTArray_Simple<nsStyleImageLayers::Layer>);
3372 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleTransition>,
3373 : nsTArray_Simple<mozilla::StyleTransition>);
3374 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleAnimation>,
3375 : nsTArray_Simple<mozilla::StyleAnimation>);
3376 :
3377 : /**
3378 : * <div rustbindgen replaces="nsCOMArray"></div>
3379 : *
3380 : * mozilla::ArrayIterator doesn't work well with bindgen.
3381 : */
3382 : template<typename T>
3383 : class nsCOMArray_Simple {
3384 : nsTArray<nsISupports*> mBuffer;
3385 : };
3386 :
3387 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsCOMArray<nsIContent>,
3388 : nsCOMArray_Simple<nsIContent>);
3389 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsCOMArray<nsINode>,
3390 : nsCOMArray_Simple<nsINode>);
3391 : STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsCOMArray<imgIContainer>,
3392 : nsCOMArray_Simple<imgIContainer>);
3393 :
3394 : #endif /* nsStyleStruct_h___ */
|