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