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 NS_SVGCONTAINERFRAME_H
8 #define NS_SVGCONTAINERFRAME_H
9 
10 #include "mozilla/Attributes.h"
11 #include "nsContainerFrame.h"
12 #include "nsFrame.h"
13 #include "nsIFrame.h"
14 #include "nsSVGDisplayableFrame.h"
15 #include "nsQueryFrame.h"
16 #include "nsRect.h"
17 #include "nsSVGUtils.h"
18 
19 class gfxContext;
20 class nsFrameList;
21 class nsIContent;
22 class nsIPresShell;
23 class nsStyleContext;
24 
25 struct nsRect;
26 
27 /**
28  * Base class for SVG container frames. Frame sub-classes that do not
29  * display their contents directly (such as the frames for <marker> or
30  * <pattern>) just inherit this class. Frame sub-classes that do or can
31  * display their contents directly (such as the frames for inner-<svg> or
32  * <g>) inherit our nsDisplayContainerFrame sub-class.
33  *
34  *                               *** WARNING ***
35  *
36  * Do *not* blindly cast to SVG element types in this class's methods (see the
37  * warning comment for nsSVGDisplayContainerFrame below).
38  */
39 class nsSVGContainerFrame : public nsContainerFrame {
40   friend nsIFrame* NS_NewSVGContainerFrame(nsIPresShell* aPresShell,
41                                            nsStyleContext* aContext);
42 
43  protected:
nsSVGContainerFrame(nsStyleContext * aContext,ClassID aID)44   nsSVGContainerFrame(nsStyleContext* aContext, ClassID aID)
45       : nsContainerFrame(aContext, aID) {
46     AddStateBits(NS_FRAME_SVG_LAYOUT);
47   }
48 
49  public:
50   NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(nsSVGContainerFrame)51   NS_DECL_FRAMEARENA_HELPERS(nsSVGContainerFrame)
52 
53   // Returns the transform to our gfxContext (to device pixels, not CSS px)
54   virtual gfxMatrix GetCanvasTM() { return gfxMatrix(); }
55 
56   /**
57    * Returns true if the frame's content has a transform that applies only to
58    * its children, and not to the frame itself. For example, an implicit
59    * transform introduced by a 'viewBox' attribute, or an explicit transform
60    * due to a root-<svg> having its currentScale/currentTransform properties
61    * set. If aTransform is non-null, then it will be set to the transform.
62    */
HasChildrenOnlyTransform(Matrix * aTransform)63   virtual bool HasChildrenOnlyTransform(Matrix* aTransform) const {
64     return false;
65   }
66 
67   // nsIFrame:
68   virtual void AppendFrames(ChildListID aListID,
69                             nsFrameList& aFrameList) override;
70   virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
71                             nsFrameList& aFrameList) override;
72   virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
73 
IsFrameOfType(uint32_t aFlags)74   virtual bool IsFrameOfType(uint32_t aFlags) const override {
75     return nsContainerFrame::IsFrameOfType(
76         aFlags & ~(nsIFrame::eSVG | nsIFrame::eSVGContainer));
77   }
78 
BuildDisplayList(nsDisplayListBuilder * aBuilder,const nsDisplayListSet & aLists)79   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
80                                 const nsDisplayListSet& aLists) override {}
81 
82   virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
83 
84  protected:
85   /**
86    * Traverses a frame tree, marking any SVGTextFrame frames as dirty
87    * and calling InvalidateRenderingObservers() on it.
88    */
89   static void ReflowSVGNonDisplayText(nsIFrame* aContainer);
90 };
91 
92 /**
93  * Frame class or base-class for SVG containers that can or do display their
94  * contents directly.
95  *
96  *                               *** WARNING ***
97  *
98  * This class's methods can *not* assume that mContent points to an instance of
99  * an SVG element class since this class is inherited by
100  * nsSVGGenericContainerFrame which is used for unrecognized elements in the
101  * SVG namespace. Do *not* blindly cast to SVG element types.
102  */
103 class nsSVGDisplayContainerFrame : public nsSVGContainerFrame,
104                                    public nsSVGDisplayableFrame {
105  protected:
nsSVGDisplayContainerFrame(nsStyleContext * aContext,nsIFrame::ClassID aID)106   nsSVGDisplayContainerFrame(nsStyleContext* aContext, nsIFrame::ClassID aID)
107       : nsSVGContainerFrame(aContext, aID) {
108     AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
109   }
110 
111  public:
112   NS_DECL_QUERYFRAME
113   NS_DECL_QUERYFRAME_TARGET(nsSVGDisplayContainerFrame)
114   NS_DECL_ABSTRACT_FRAME(nsSVGDisplayContainerFrame)
115 
116   // nsIFrame:
117   virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
118                             nsFrameList& aFrameList) override;
119   virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
120   virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
121                     nsIFrame* aPrevInFlow) override;
122 
123   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
124                                 const nsDisplayListSet& aLists) override;
125 
126   virtual bool IsSVGTransformed(
127       Matrix* aOwnTransform = nullptr,
128       Matrix* aFromParentTransform = nullptr) const override;
129 
130   // nsSVGDisplayableFrame interface:
131   virtual void PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform,
132                         imgDrawingParams& aImgParams,
133                         const nsIntRect* aDirtyRect = nullptr) override;
134   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
135   virtual void ReflowSVG() override;
136   virtual void NotifySVGChanged(uint32_t aFlags) override;
137   virtual SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace,
138                                       uint32_t aFlags) override;
IsDisplayContainer()139   virtual bool IsDisplayContainer() override { return true; }
140   virtual gfxMatrix GetCanvasTM() override;
141 
142  protected:
143   /**
144    * Cached canvasTM value.
145    */
146   nsAutoPtr<gfxMatrix> mCanvasTM;
147 };
148 
149 #endif
150