|
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 } |