tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGGradientFrame.h (7112B)


      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 #ifndef LAYOUT_SVG_SVGGRADIENTFRAME_H_
      8 #define LAYOUT_SVG_SVGGRADIENTFRAME_H_
      9 
     10 #include "gfxMatrix.h"
     11 #include "gfxRect.h"
     12 #include "mozilla/SVGPaintServerFrame.h"
     13 #include "nsCOMPtr.h"
     14 #include "nsCSSRenderingGradients.h"
     15 #include "nsIFrame.h"
     16 #include "nsLiteralString.h"
     17 
     18 class gfxPattern;
     19 class nsAtom;
     20 class nsIContent;
     21 
     22 namespace mozilla {
     23 class PresShell;
     24 class SVGAnimatedTransformList;
     25 
     26 namespace dom {
     27 class SVGLinearGradientElement;
     28 class SVGRadialGradientElement;
     29 }  // namespace dom
     30 }  // namespace mozilla
     31 
     32 nsIFrame* NS_NewSVGLinearGradientFrame(mozilla::PresShell* aPresShell,
     33                                       mozilla::ComputedStyle* aStyle);
     34 nsIFrame* NS_NewSVGRadialGradientFrame(mozilla::PresShell* aPresShell,
     35                                       mozilla::ComputedStyle* aStyle);
     36 
     37 namespace mozilla {
     38 
     39 class SVGGradientFrame : public SVGPaintServerFrame {
     40  using ExtendMode = gfx::ExtendMode;
     41 
     42 protected:
     43  SVGGradientFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
     44                   ClassID aID);
     45 
     46 public:
     47  NS_DECL_ABSTRACT_FRAME(SVGGradientFrame)
     48  NS_DECL_QUERYFRAME
     49  NS_DECL_QUERYFRAME_TARGET(SVGGradientFrame)
     50 
     51  // SVGPaintServerFrame methods:
     52  already_AddRefed<gfxPattern> GetPaintServerPattern(
     53      nsIFrame* aSource, const DrawTarget* aDrawTarget,
     54      const gfxMatrix& aContextMatrix,
     55      StyleSVGPaint nsStyleSVG::* aFillOrStroke, float aGraphicOpacity,
     56      imgDrawingParams& aImgParams, const gfxRect* aOverrideBounds) override;
     57 
     58  // nsIFrame interface:
     59  nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
     60                            AttrModType aModType) override;
     61 
     62 #ifdef DEBUG_FRAME_DUMP
     63  nsresult GetFrameName(nsAString& aResult) const override {
     64    return MakeFrameName(u"SVGGradient"_ns, aResult);
     65  }
     66 #endif  // DEBUG
     67 
     68 private:
     69  /**
     70   * Parses this frame's href and - if it references another gradient - returns
     71   * it.  It also makes this frame a rendering observer of the specified ID.
     72   */
     73  SVGGradientFrame* GetReferencedGradient();
     74 
     75  void GetStops(nsTArray<ColorStop>* aStops, float aGraphicOpacity);
     76 
     77  SVGGradientFrame* GetGradientTransformFrame(SVGGradientFrame* aDefault);
     78  // Will be singular for gradientUnits="objectBoundingBox" with an empty bbox.
     79  gfxMatrix GetGradientTransform(nsIFrame* aSource,
     80                                 const gfxRect* aOverrideBounds);
     81 
     82 protected:
     83  virtual bool GradientVectorLengthIsZero() = 0;
     84  virtual already_AddRefed<gfxPattern> CreateGradient() = 0;
     85 
     86  // Accessors to lookup gradient attributes
     87  uint16_t GetEnumValue(uint32_t aIndex, nsIContent* aDefault);
     88  uint16_t GetEnumValue(uint32_t aIndex) {
     89    return GetEnumValue(aIndex, mContent);
     90  }
     91  uint16_t GetGradientUnits();
     92  uint16_t GetSpreadMethod();
     93  float GetLengthValue(const SVGAnimatedLength& aLength);
     94 
     95  // Gradient-type-specific lookups since the length values differ between
     96  // linear and radial gradients
     97  virtual dom::SVGLinearGradientElement* GetLinearGradientWithLength(
     98      uint32_t aIndex, dom::SVGLinearGradientElement* aDefault);
     99  virtual dom::SVGRadialGradientElement* GetRadialGradientWithLength(
    100      uint32_t aIndex, dom::SVGRadialGradientElement* aDefault);
    101 
    102  // The frame our gradient is (currently) being applied to
    103  nsIFrame* mSource;
    104 
    105 private:
    106  // Flag to mark this frame as "in use" during recursive calls along our
    107  // gradient's reference chain so we can detect reference loops. See:
    108  // http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute
    109  bool mLoopFlag;
    110  // Gradients often don't reference other gradients, so here we cache
    111  // the fact that that isn't happening.
    112  bool mNoHRefURI;
    113 };
    114 
    115 // -------------------------------------------------------------------------
    116 // Linear Gradients
    117 // -------------------------------------------------------------------------
    118 
    119 class SVGLinearGradientFrame final : public SVGGradientFrame {
    120  friend nsIFrame* ::NS_NewSVGLinearGradientFrame(
    121      mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
    122 
    123 protected:
    124  explicit SVGLinearGradientFrame(ComputedStyle* aStyle,
    125                                  nsPresContext* aPresContext)
    126      : SVGGradientFrame(aStyle, aPresContext, kClassID) {}
    127 
    128 public:
    129  NS_DECL_QUERYFRAME
    130  NS_DECL_FRAMEARENA_HELPERS(SVGLinearGradientFrame)
    131 
    132  // nsIFrame interface:
    133 #ifdef DEBUG
    134  void Init(nsIContent* aContent, nsContainerFrame* aParent,
    135            nsIFrame* aPrevInFlow) override;
    136 #endif
    137 
    138  nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
    139                            AttrModType aModType) override;
    140 
    141 #ifdef DEBUG_FRAME_DUMP
    142  nsresult GetFrameName(nsAString& aResult) const override {
    143    return MakeFrameName(u"SVGLinearGradient"_ns, aResult);
    144  }
    145 #endif  // DEBUG
    146 
    147 protected:
    148  using SVGGradientFrame::GetLengthValue;
    149  float GetLengthValue(uint32_t aIndex);
    150  mozilla::dom::SVGLinearGradientElement* GetLinearGradientWithLength(
    151      uint32_t aIndex,
    152      mozilla::dom::SVGLinearGradientElement* aDefault) override;
    153  bool GradientVectorLengthIsZero() override;
    154  already_AddRefed<gfxPattern> CreateGradient() override;
    155 };
    156 
    157 // -------------------------------------------------------------------------
    158 // Radial Gradients
    159 // -------------------------------------------------------------------------
    160 
    161 class SVGRadialGradientFrame final : public SVGGradientFrame {
    162  friend nsIFrame* ::NS_NewSVGRadialGradientFrame(
    163      mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
    164 
    165 protected:
    166  explicit SVGRadialGradientFrame(ComputedStyle* aStyle,
    167                                  nsPresContext* aPresContext)
    168      : SVGGradientFrame(aStyle, aPresContext, kClassID) {}
    169 
    170 public:
    171  NS_DECL_QUERYFRAME
    172  NS_DECL_FRAMEARENA_HELPERS(SVGRadialGradientFrame)
    173 
    174  // nsIFrame interface:
    175 #ifdef DEBUG
    176  void Init(nsIContent* aContent, nsContainerFrame* aParent,
    177            nsIFrame* aPrevInFlow) override;
    178 #endif
    179 
    180  nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
    181                            AttrModType aModType) override;
    182 
    183 #ifdef DEBUG_FRAME_DUMP
    184  nsresult GetFrameName(nsAString& aResult) const override {
    185    return MakeFrameName(u"SVGRadialGradient"_ns, aResult);
    186  }
    187 #endif  // DEBUG
    188 
    189 protected:
    190  using SVGGradientFrame::GetLengthValue;
    191  float GetLengthValue(uint32_t aIndex, Maybe<float> aDefaultValue = Nothing());
    192  float GetLengthValue(uint32_t aIndex, float aDefaultValue) {
    193    return GetLengthValue(aIndex, Some(aDefaultValue));
    194  }
    195  mozilla::dom::SVGRadialGradientElement* GetRadialGradientWithLength(
    196      uint32_t aIndex,
    197      mozilla::dom::SVGRadialGradientElement* aDefault) override;
    198  bool GradientVectorLengthIsZero() override;
    199  already_AddRefed<gfxPattern> CreateGradient() override;
    200 };
    201 
    202 }  // namespace mozilla
    203 
    204 #endif  // LAYOUT_SVG_SVGGRADIENTFRAME_H_