Coverage Report

Created: 2018-09-25 14:53

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