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_SVGPATTERNFRAME_H_
8 #define LAYOUT_SVG_SVGPATTERNFRAME_H_
9 
10 #include "mozilla/Attributes.h"
11 #include "gfxMatrix.h"
12 #include "mozilla/gfx/2D.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/SVGPaintServerFrame.h"
15 #include "mozilla/UniquePtr.h"
16 
17 class nsIFrame;
18 
19 namespace mozilla {
20 class PresShell;
21 class SVGAnimatedLength;
22 class SVGAnimatedPreserveAspectRatio;
23 class SVGAnimatedTransformList;
24 class SVGAnimatedViewBox;
25 class SVGGeometryFrame;
26 }  // namespace mozilla
27 
28 nsIFrame* NS_NewSVGPatternFrame(mozilla::PresShell* aPresShell,
29                                 mozilla::ComputedStyle* aStyle);
30 
31 namespace mozilla {
32 
33 class SVGPatternFrame final : public SVGPaintServerFrame {
34   using SourceSurface = gfx::SourceSurface;
35 
36  public:
37   NS_DECL_FRAMEARENA_HELPERS(SVGPatternFrame)
38   NS_DECL_QUERYFRAME
39 
40   friend nsIFrame* ::NS_NewSVGPatternFrame(mozilla::PresShell* aPresShell,
41                                            ComputedStyle* aStyle);
42 
43   explicit SVGPatternFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
44 
45   // SVGPaintServerFrame methods:
46   virtual already_AddRefed<gfxPattern> GetPaintServerPattern(
47       nsIFrame* aSource, const DrawTarget* aDrawTarget,
48       const gfxMatrix& aContextMatrix, StyleSVGPaint nsStyleSVG::*aFillOrStroke,
49       float aGraphicOpacity, imgDrawingParams& aImgParams,
50       const gfxRect* aOverrideBounds) override;
51 
52  public:
53   // SVGContainerFrame methods:
54   virtual gfxMatrix GetCanvasTM() override;
55 
56   // nsIFrame interface:
57   virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
58                                     int32_t aModType) override;
59 
60 #ifdef DEBUG
61   virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
62                     nsIFrame* aPrevInFlow) override;
63 #endif
64 
65 #ifdef DEBUG_FRAME_DUMP
GetFrameName(nsAString & aResult)66   virtual nsresult GetFrameName(nsAString& aResult) const override {
67     return MakeFrameName(u"SVGPattern"_ns, aResult);
68   }
69 #endif  // DEBUG
70 
71  protected:
72   /**
73    * Parses this frame's href and - if it references another pattern - returns
74    * it.  It also makes this frame a rendering observer of the specified ID.
75    */
76   SVGPatternFrame* GetReferencedPattern();
77 
78   // Accessors to lookup pattern attributes
79   uint16_t GetEnumValue(uint32_t aIndex, nsIContent* aDefault);
GetEnumValue(uint32_t aIndex)80   uint16_t GetEnumValue(uint32_t aIndex) {
81     return GetEnumValue(aIndex, mContent);
82   }
83   SVGAnimatedTransformList* GetPatternTransformList(nsIContent* aDefault);
84   gfxMatrix GetPatternTransform();
85   const SVGAnimatedViewBox& GetViewBox(nsIContent* aDefault);
GetViewBox()86   const SVGAnimatedViewBox& GetViewBox() { return GetViewBox(mContent); }
87   const SVGAnimatedPreserveAspectRatio& GetPreserveAspectRatio(
88       nsIContent* aDefault);
GetPreserveAspectRatio()89   const SVGAnimatedPreserveAspectRatio& GetPreserveAspectRatio() {
90     return GetPreserveAspectRatio(mContent);
91   }
92   const SVGAnimatedLength* GetLengthValue(uint32_t aIndex,
93                                           nsIContent* aDefault);
GetLengthValue(uint32_t aIndex)94   const SVGAnimatedLength* GetLengthValue(uint32_t aIndex) {
95     return GetLengthValue(aIndex, mContent);
96   }
97 
98   already_AddRefed<SourceSurface> PaintPattern(
99       const DrawTarget* aDrawTarget, Matrix* patternMatrix,
100       const Matrix& aContextMatrix, nsIFrame* aSource,
101       StyleSVGPaint nsStyleSVG::*aFillOrStroke, float aGraphicOpacity,
102       const gfxRect* aOverrideBounds, imgDrawingParams& aImgParams);
103 
104   /**
105    * A <pattern> element may reference another <pattern> element using
106    * xlink:href and, if it doesn't have any child content of its own, then it
107    * will "inherit" the children of the referenced pattern (which may itself be
108    * inheriting its children if it references another <pattern>).  This
109    * function returns this SVGPatternFrame or the first pattern along the
110    * reference chain (if there is one) to have children.
111    */
112   SVGPatternFrame* GetPatternWithChildren();
113 
114   gfxRect GetPatternRect(uint16_t aPatternUnits, const gfxRect& bbox,
115                          const Matrix& aTargetCTM, nsIFrame* aTarget);
116   gfxMatrix ConstructCTM(const SVGAnimatedViewBox& aViewBox,
117                          uint16_t aPatternContentUnits, uint16_t aPatternUnits,
118                          const gfxRect& callerBBox, const Matrix& callerCTM,
119                          nsIFrame* aTarget);
120 
121  private:
122   // this is a *temporary* reference to the frame of the element currently
123   // referencing our pattern.  This must be temporary because different
124   // referencing frames will all reference this one frame
125   SVGGeometryFrame* mSource;
126   UniquePtr<gfxMatrix> mCTM;
127 
128  protected:
129   // This flag is used to detect loops in xlink:href processing
130   bool mLoopFlag;
131   bool mNoHRefURI;
132 };
133 
134 }  // namespace mozilla
135 
136 #endif  // LAYOUT_SVG_SVGPATTERNFRAME_H_
137