Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; 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 : #ifndef _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
7 : #define _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
8 :
9 : #include "2D.h"
10 : #include "cairo.h"
11 : #include "PathCairo.h"
12 :
13 : #include <vector>
14 :
15 : namespace mozilla {
16 : namespace gfx {
17 :
18 : class SourceSurfaceCairo;
19 :
20 : class GradientStopsCairo : public GradientStops
21 : {
22 : public:
23 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsCairo)
24 0 : GradientStopsCairo(GradientStop* aStops, uint32_t aNumStops,
25 : ExtendMode aExtendMode)
26 0 : : mExtendMode(aExtendMode)
27 : {
28 0 : for (uint32_t i = 0; i < aNumStops; ++i) {
29 0 : mStops.push_back(aStops[i]);
30 : }
31 0 : }
32 :
33 0 : virtual ~GradientStopsCairo() {}
34 :
35 0 : const std::vector<GradientStop>& GetStops() const
36 : {
37 0 : return mStops;
38 : }
39 :
40 0 : ExtendMode GetExtendMode() const
41 : {
42 0 : return mExtendMode;
43 : }
44 :
45 0 : virtual BackendType GetBackendType() const { return BackendType::CAIRO; }
46 :
47 : private:
48 : std::vector<GradientStop> mStops;
49 : ExtendMode mExtendMode;
50 : };
51 :
52 : class DrawTargetCairo final : public DrawTarget
53 : {
54 : public:
55 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCairo, override)
56 : friend class BorrowedCairoContext;
57 : friend class BorrowedXlibDrawable;
58 :
59 : DrawTargetCairo();
60 : virtual ~DrawTargetCairo();
61 :
62 : virtual bool IsValid() const override;
63 : virtual DrawTargetType GetType() const override;
64 0 : virtual BackendType GetBackendType() const override { return BackendType::CAIRO; }
65 : virtual already_AddRefed<SourceSurface> Snapshot() override;
66 : virtual IntSize GetSize() override;
67 :
68 : virtual bool IsCurrentGroupOpaque() override;
69 :
70 : virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
71 :
72 : virtual bool LockBits(uint8_t** aData, IntSize* aSize,
73 : int32_t* aStride, SurfaceFormat* aFormat,
74 : IntPoint* aOrigin = nullptr) override;
75 : virtual void ReleaseBits(uint8_t* aData) override;
76 :
77 : virtual void Flush() override;
78 : virtual void DrawSurface(SourceSurface *aSurface,
79 : const Rect &aDest,
80 : const Rect &aSource,
81 : const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
82 : const DrawOptions &aOptions = DrawOptions()) override;
83 : virtual void DrawFilter(FilterNode *aNode,
84 : const Rect &aSourceRect,
85 : const Point &aDestPoint,
86 : const DrawOptions &aOptions = DrawOptions()) override;
87 : virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
88 : const Point &aDest,
89 : const Color &aColor,
90 : const Point &aOffset,
91 : Float aSigma,
92 : CompositionOp aOperator) override;
93 :
94 : virtual void ClearRect(const Rect &aRect) override;
95 :
96 : virtual void CopySurface(SourceSurface *aSurface,
97 : const IntRect &aSourceRect,
98 : const IntPoint &aDestination) override;
99 : virtual void CopyRect(const IntRect &aSourceRect,
100 : const IntPoint &aDestination) override;
101 :
102 : virtual void FillRect(const Rect &aRect,
103 : const Pattern &aPattern,
104 : const DrawOptions &aOptions = DrawOptions()) override;
105 : virtual void StrokeRect(const Rect &aRect,
106 : const Pattern &aPattern,
107 : const StrokeOptions &aStrokeOptions = StrokeOptions(),
108 : const DrawOptions &aOptions = DrawOptions()) override;
109 : virtual void StrokeLine(const Point &aStart,
110 : const Point &aEnd,
111 : const Pattern &aPattern,
112 : const StrokeOptions &aStrokeOptions = StrokeOptions(),
113 : const DrawOptions &aOptions = DrawOptions()) override;
114 :
115 : virtual void Stroke(const Path *aPath,
116 : const Pattern &aPattern,
117 : const StrokeOptions &aStrokeOptions = StrokeOptions(),
118 : const DrawOptions &aOptions = DrawOptions()) override;
119 :
120 : virtual void Fill(const Path *aPath,
121 : const Pattern &aPattern,
122 : const DrawOptions &aOptions = DrawOptions()) override;
123 :
124 : virtual void FillGlyphs(ScaledFont *aFont,
125 : const GlyphBuffer &aBuffer,
126 : const Pattern &aPattern,
127 : const DrawOptions &aOptions,
128 : const GlyphRenderingOptions *aRenderingOptions = nullptr) override;
129 : virtual void Mask(const Pattern &aSource,
130 : const Pattern &aMask,
131 : const DrawOptions &aOptions = DrawOptions()) override;
132 : virtual void MaskSurface(const Pattern &aSource,
133 : SourceSurface *aMask,
134 : Point aOffset,
135 : const DrawOptions &aOptions = DrawOptions()) override;
136 :
137 : virtual bool Draw3DTransformedSurface(SourceSurface* aSurface,
138 : const Matrix4x4& aMatrix) override;
139 :
140 : virtual void PushClip(const Path *aPath) override;
141 : virtual void PushClipRect(const Rect &aRect) override;
142 : virtual void PopClip() override;
143 : virtual void PushLayer(bool aOpaque, Float aOpacity,
144 : SourceSurface* aMask,
145 : const Matrix& aMaskTransform,
146 : const IntRect& aBounds = IntRect(),
147 : bool aCopyBackground = false) override;
148 : virtual void PopLayer() override;
149 :
150 : virtual already_AddRefed<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const override;
151 :
152 : virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
153 : const IntSize &aSize,
154 : int32_t aStride,
155 : SurfaceFormat aFormat) const override;
156 : virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const override;
157 : virtual already_AddRefed<SourceSurface>
158 : CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const override;
159 : virtual already_AddRefed<DrawTarget>
160 : CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const override;
161 : virtual already_AddRefed<DrawTarget>
162 : CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat,
163 : float aSigma) const override;
164 :
165 : virtual already_AddRefed<GradientStops>
166 : CreateGradientStops(GradientStop *aStops,
167 : uint32_t aNumStops,
168 : ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
169 :
170 : virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
171 :
172 : virtual void GetGlyphRasterizationMetrics(ScaledFont *aScaledFont, const uint16_t* aGlyphIndices,
173 : uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics) override;
174 :
175 : virtual void *GetNativeSurface(NativeSurfaceType aType) override;
176 :
177 : bool Init(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
178 : bool Init(const IntSize& aSize, SurfaceFormat aFormat);
179 : bool Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
180 :
181 : virtual void SetTransform(const Matrix& aTransform) override;
182 :
183 0 : virtual void DetachAllSnapshots() override { MarkSnapshotIndependent(); }
184 :
185 : // Call to set up aContext for drawing (with the current transform, etc).
186 : // Pass the path you're going to be using if you have one.
187 : // Implicitly calls WillChange(aPath).
188 : void PrepareForDrawing(cairo_t* aContext, const Path* aPath = nullptr);
189 :
190 : static cairo_surface_t *GetDummySurface();
191 :
192 : // Cairo hardcodes this as its maximum surface size.
193 0 : static size_t GetMaxSurfaceSize() {
194 0 : return 32767;
195 : }
196 :
197 : private: // methods
198 : // Init cairo surface without doing a cairo_surface_reference() call.
199 : bool InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
200 : enum DrawPatternType { DRAW_FILL, DRAW_STROKE };
201 : void DrawPattern(const Pattern& aPattern,
202 : const StrokeOptions& aStrokeOptions,
203 : const DrawOptions& aOptions,
204 : DrawPatternType aDrawType,
205 : bool aPathBoundsClip = false);
206 :
207 : void CopySurfaceInternal(cairo_surface_t* aSurface,
208 : const IntRect& aSource,
209 : const IntPoint& aDest);
210 :
211 : Rect GetUserSpaceClip();
212 :
213 : // Call before you make any changes to the backing surface with which this
214 : // context is associated. Pass the path you're going to be using if you have
215 : // one.
216 : void WillChange(const Path* aPath = nullptr);
217 :
218 : // Call if there is any reason to disassociate the snapshot from this draw
219 : // target; for example, because we're going to be destroyed.
220 : void MarkSnapshotIndependent();
221 :
222 : // If the current operator is "source" then clear the destination before we
223 : // draw into it, to simulate the effect of an unbounded source operator.
224 : void ClearSurfaceForUnboundedSource(const CompositionOp &aOperator);
225 :
226 : // Set the Cairo context font options according to the current draw target
227 : // font state.
228 : void SetFontOptions();
229 :
230 : private: // data
231 : cairo_t* mContext;
232 : cairo_surface_t* mSurface;
233 : IntSize mSize;
234 : bool mTransformSingular;
235 :
236 : uint8_t* mLockedBits;
237 :
238 : cairo_font_options_t* mFontOptions;
239 :
240 : struct PushedLayer
241 : {
242 0 : PushedLayer(Float aOpacity, bool aWasPermittingSubpixelAA)
243 0 : : mOpacity(aOpacity)
244 : , mMaskPattern(nullptr)
245 0 : , mWasPermittingSubpixelAA(aWasPermittingSubpixelAA)
246 0 : {}
247 : Float mOpacity;
248 : cairo_pattern_t* mMaskPattern;
249 : bool mWasPermittingSubpixelAA;
250 : };
251 : std::vector<PushedLayer> mPushedLayers;
252 :
253 : // The latest snapshot of this surface. This needs to be told when this
254 : // target is modified. We keep it alive as a cache.
255 : RefPtr<SourceSurfaceCairo> mSnapshot;
256 : static cairo_surface_t *mDummySurface;
257 : };
258 :
259 : } // namespace gfx
260 : } // namespace mozilla
261 :
262 : #endif // _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
|