1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Corporation code.
16 : *
17 : * The Initial Developer of the Original Code is Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2011
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 2 or later (the "GPL"), or
25 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #ifndef MOZILLA_GFX_PATH_CAIRO_H_
38 : #define MOZILLA_GFX_PATH_CAIRO_H_
39 :
40 : #include "2D.h"
41 : #include "cairo.h"
42 :
43 : namespace mozilla {
44 : namespace gfx {
45 :
46 : class DrawTargetCairo;
47 :
48 : // A reference to a cairo context that can maintain and set a path.
49 : //
50 : // This class exists to make it possible for us to not construct paths manually
51 : // using cairo_path_t, which in the common case is a speed and memory
52 : // optimization (as the cairo_t maintains the path for us, and we don't have to
53 : // use cairo_append_path). Instead, we can share a cairo_t with a DrawTarget,
54 : // and have it inform us when we need to make a copy of the path.
55 : //
56 : // Exactly one Path* object represents the current path on a given DrawTarget's
57 : // context. That Path* object registers its CairoPathContext with the
58 : // DrawTarget it's associated with. If that DrawTarget is going to change its
59 : // path, it has to tell the CairoPathContext beforehand so the path can be
60 : // saved off.
61 : // The path ownership is transferred to every new instance of CairoPathContext
62 : // in the constructor. We inform the draw target of the new context object,
63 : // which causes us to save off a copy of the path, as we're not going to be
64 : // informed upon changes any more.
65 : // Any transformation on aCtx is not applied to this path, though a path can be
66 : // transformed separately from its context by passing a matrix to the
67 : // constructor.
68 : class CairoPathContext : public RefCounted<CairoPathContext>
69 : {
70 : public:
71 : // Construct a CairoPathContext and set it to be the path observer of
72 : // aDrawTarget. Optionally, this path can be transformed by aMatrix.
73 : CairoPathContext(cairo_t* aCtx, DrawTargetCairo* aDrawTarget,
74 : FillRule aFillRule,
75 : const Matrix& aMatrix = Matrix());
76 : ~CairoPathContext();
77 :
78 : // Copy the path on mContext to be the path on aToContext, if they aren't the
79 : // same.
80 : void CopyPathTo(cairo_t* aToContext);
81 :
82 : // This method must be called by the draw target before it changes the path
83 : // currently on the cairo context.
84 : void PathWillChange();
85 :
86 : // This method must be called by the draw target whenever it is going to
87 : // change the current transformation on mContext.
88 : void MatrixWillChange(const Matrix& aMatrix);
89 :
90 : // This method must be called as the draw target is dying. In this case, we
91 : // forget our reference to the draw target, and become the only reference to
92 : // our context.
93 : void ForgetDrawTarget();
94 :
95 : // Create a duplicate context, and copy this path to that context. Optionally,
96 : // the new context can be transformed.
97 : void DuplicateContextAndPath(const Matrix& aMatrix = Matrix());
98 :
99 : // Returns true if this CairoPathContext represents path.
100 : bool ContainsPath(const Path* path);
101 :
102 0 : cairo_t* GetContext() const { return mContext; }
103 0 : DrawTargetCairo* GetDrawTarget() const { return mDrawTarget; }
104 0 : Matrix GetTransform() const { return mTransform; }
105 0 : FillRule GetFillRule() const { return mFillRule; }
106 :
107 0 : operator cairo_t* () const { return mContext; }
108 :
109 : private: // methods
110 : CairoPathContext(const CairoPathContext&) MOZ_DELETE;
111 :
112 : private: // data
113 : Matrix mTransform;
114 : cairo_t* mContext;
115 : // Not a RefPtr to avoid cycles.
116 : DrawTargetCairo* mDrawTarget;
117 : FillRule mFillRule;
118 : };
119 :
120 : class PathBuilderCairo : public PathBuilder
121 0 : {
122 : public:
123 : // This constructor implicitly takes ownership of aCtx by calling
124 : // aDrawTarget->SetPathObserver(). Therefore, if the draw target has a path
125 : // observer, this constructor will cause it to copy out its path.
126 : // The path currently set on aCtx is not changed.
127 : PathBuilderCairo(cairo_t* aCtx, DrawTargetCairo* aDrawTarget, FillRule aFillRule);
128 :
129 : // This constructor, called with a CairoPathContext*, implicitly takes
130 : // ownership of the path, and therefore makes aPathContext copy out its path
131 : // regardless of whether it has a pointer to a DrawTargetCairo.
132 : // The path currently set on aPathContext is not changed.
133 : explicit PathBuilderCairo(CairoPathContext* aPathContext,
134 : const Matrix& aTransform = Matrix());
135 :
136 : virtual void MoveTo(const Point &aPoint);
137 : virtual void LineTo(const Point &aPoint);
138 : virtual void BezierTo(const Point &aCP1,
139 : const Point &aCP2,
140 : const Point &aCP3);
141 : virtual void QuadraticBezierTo(const Point &aCP1,
142 : const Point &aCP2);
143 : virtual void Close();
144 : virtual void Arc(const Point &aOrigin, float aRadius, float aStartAngle,
145 : float aEndAngle, bool aAntiClockwise = false);
146 : virtual Point CurrentPoint() const;
147 : virtual TemporaryRef<Path> Finish();
148 :
149 : TemporaryRef<CairoPathContext> GetPathContext();
150 :
151 : private: // methods
152 : void SetFillRule(FillRule aFillRule);
153 :
154 : private: // data
155 : RefPtr<CairoPathContext> mPathContext;
156 : FillRule mFillRule;
157 : };
158 :
159 : class PathCairo : public Path
160 0 : {
161 : public:
162 : PathCairo(cairo_t* aCtx, DrawTargetCairo* aDrawTarget, FillRule aFillRule, const Matrix& aTransform);
163 :
164 0 : virtual BackendType GetBackendType() const { return BACKEND_CAIRO; }
165 :
166 : virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FILL_WINDING) const;
167 : virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
168 : FillRule aFillRule = FILL_WINDING) const;
169 :
170 : virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const;
171 :
172 : virtual Rect GetBounds(const Matrix &aTransform = Matrix()) const;
173 :
174 : virtual Rect GetStrokedBounds(const StrokeOptions &aStrokeOptions,
175 : const Matrix &aTransform = Matrix()) const;
176 :
177 0 : virtual FillRule GetFillRule() const { return mFillRule; }
178 :
179 : TemporaryRef<CairoPathContext> GetPathContext();
180 :
181 : // Set this path to be the current path for aContext (if it's not already
182 : // aContext's path). You must pass the draw target associated with the
183 : // context as aDrawTarget.
184 : void CopyPathTo(cairo_t* aContext, DrawTargetCairo* aDrawTarget);
185 :
186 : private:
187 : RefPtr<CairoPathContext> mPathContext;
188 : FillRule mFillRule;
189 : };
190 :
191 : }
192 : }
193 :
194 : #endif /* MOZILLA_GFX_PATH_CAIRO_H_ */
|