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