| |
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| |
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
| |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
5 |
| |
6 // Main header first: |
| |
7 #include "nsSVGGFrame.h" |
| |
8 |
| |
9 // Keep others in (case-insensitive) order: |
| |
10 #include "nsGkAtoms.h" |
| |
11 #include "SVGTransformableElement.h" |
| |
12 #include "nsIFrame.h" |
| |
13 #include "SVGGraphicsElement.h" |
| |
14 #include "nsSVGIntegrationUtils.h" |
| |
15 #include "nsSVGUtils.h" |
| |
16 |
| |
17 using namespace mozilla::dom; |
| |
18 |
| |
19 //---------------------------------------------------------------------- |
| |
20 // Implementation |
| |
21 |
| |
22 nsIFrame* |
| |
23 NS_NewSVGGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) |
| |
24 { |
| |
25 return new (aPresShell) nsSVGGFrame(aContext); |
| |
26 } |
| |
27 |
| |
28 NS_IMPL_FRAMEARENA_HELPERS(nsSVGGFrame) |
| |
29 |
| |
30 #ifdef DEBUG |
| |
31 void |
| |
32 nsSVGGFrame::Init(nsIContent* aContent, |
| |
33 nsIFrame* aParent, |
| |
34 nsIFrame* aPrevInFlow) |
| |
35 { |
| |
36 NS_ASSERTION(aContent->IsSVG() && |
| |
37 static_cast<nsSVGElement*>(aContent)->IsTransformable(), |
| |
38 "The element doesn't support nsIDOMSVGTransformable"); |
| |
39 |
| |
40 nsSVGGFrameBase::Init(aContent, aParent, aPrevInFlow); |
| |
41 } |
| |
42 #endif /* DEBUG */ |
| |
43 |
| |
44 nsIAtom * |
| |
45 nsSVGGFrame::GetType() const |
| |
46 { |
| |
47 return nsGkAtoms::svgGFrame; |
| |
48 } |
| |
49 |
| |
50 //---------------------------------------------------------------------- |
| |
51 // nsISVGChildFrame methods |
| |
52 |
| |
53 void |
| |
54 nsSVGGFrame::NotifySVGChanged(uint32_t aFlags) |
| |
55 { |
| |
56 NS_ABORT_IF_FALSE(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED), |
| |
57 "Invalidation logic may need adjusting"); |
| |
58 |
| |
59 if (aFlags & TRANSFORM_CHANGED) { |
| |
60 // make sure our cached transform matrix gets (lazily) updated |
| |
61 mCanvasTM = nullptr; |
| |
62 } |
| |
63 |
| |
64 nsSVGGFrameBase::NotifySVGChanged(aFlags); |
| |
65 } |
| |
66 |
| |
67 gfxMatrix |
| |
68 nsSVGGFrame::GetCanvasTM(uint32_t aFor, nsIFrame* aTransformRoot) |
| |
69 { |
| |
70 if (!(GetStateBits() & NS_FRAME_IS_NONDISPLAY) && !aTransformRoot) { |
| |
71 if ((aFor == FOR_PAINTING && NS_SVGDisplayListPaintingEnabled()) || |
| |
72 (aFor == FOR_HIT_TESTING && NS_SVGDisplayListHitTestingEnabled())) { |
| |
73 return nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(this); |
| |
74 } |
| |
75 } |
| |
76 if (!mCanvasTM) { |
| |
77 NS_ASSERTION(mParent, "null parent"); |
| |
78 |
| |
79 nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent); |
| |
80 SVGGraphicsElement *content = static_cast<SVGGraphicsElement*>(mContent); |
| |
81 gfxMatrix tm = content->PrependLocalTransformsTo( |
| |
82 this == aTransformRoot ? gfxMatrix() : |
| |
83 parent->GetCanvasTM(aFor, aTransformRoot)); |
| |
84 |
| |
85 mCanvasTM = new gfxMatrix(tm); |
| |
86 } |
| |
87 return *mCanvasTM; |
| |
88 } |
| |
89 |
| |
90 nsresult |
| |
91 nsSVGGFrame::AttributeChanged(int32_t aNameSpaceID, |
| |
92 nsIAtom* aAttribute, |
| |
93 int32_t aModType) |
| |
94 { |
| |
95 if (aNameSpaceID == kNameSpaceID_None && |
| |
96 aAttribute == nsGkAtoms::transform) { |
| |
97 // We don't invalidate for transform changes (the layers code does that). |
| |
98 // Also note that SVGTransformableElement::GetAttributeChangeHint will |
| |
99 // return nsChangeHint_UpdateOverflow for "transform" attribute changes |
| |
100 // and cause DoApplyRenderingChangeToTree to make the SchedulePaint call. |
| |
101 NotifySVGChanged(TRANSFORM_CHANGED); |
| |
102 } |
| |
103 |
| |
104 return NS_OK; |
| |
105 } |