michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef _MOZILLA_GFX_DRAWTARGET_CAIRO_H_ michael@0: #define _MOZILLA_GFX_DRAWTARGET_CAIRO_H_ michael@0: michael@0: #include "2D.h" michael@0: #include "cairo.h" michael@0: #include "PathCairo.h" michael@0: michael@0: #include michael@0: michael@0: namespace mozilla { michael@0: namespace gfx { michael@0: michael@0: class SourceSurfaceCairo; michael@0: michael@0: class GradientStopsCairo : public GradientStops michael@0: { michael@0: public: michael@0: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsCairo) michael@0: GradientStopsCairo(GradientStop* aStops, uint32_t aNumStops, michael@0: ExtendMode aExtendMode) michael@0: : mExtendMode(aExtendMode) michael@0: { michael@0: for (uint32_t i = 0; i < aNumStops; ++i) { michael@0: mStops.push_back(aStops[i]); michael@0: } michael@0: } michael@0: michael@0: virtual ~GradientStopsCairo() {} michael@0: michael@0: const std::vector& GetStops() const michael@0: { michael@0: return mStops; michael@0: } michael@0: michael@0: ExtendMode GetExtendMode() const michael@0: { michael@0: return mExtendMode; michael@0: } michael@0: michael@0: virtual BackendType GetBackendType() const { return BackendType::CAIRO; } michael@0: michael@0: private: michael@0: std::vector mStops; michael@0: ExtendMode mExtendMode; michael@0: }; michael@0: michael@0: class DrawTargetCairo : public DrawTarget michael@0: { michael@0: public: michael@0: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCairo) michael@0: friend class BorrowedCairoContext; michael@0: michael@0: DrawTargetCairo(); michael@0: virtual ~DrawTargetCairo(); michael@0: michael@0: virtual BackendType GetType() const { return BackendType::CAIRO; } michael@0: virtual TemporaryRef Snapshot(); michael@0: virtual IntSize GetSize(); michael@0: michael@0: virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA); michael@0: michael@0: virtual bool LockBits(uint8_t** aData, IntSize* aSize, michael@0: int32_t* aStride, SurfaceFormat* aFormat); michael@0: virtual void ReleaseBits(uint8_t* aData); michael@0: michael@0: virtual void Flush(); michael@0: virtual void DrawSurface(SourceSurface *aSurface, michael@0: const Rect &aDest, michael@0: const Rect &aSource, michael@0: const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(), michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: virtual void DrawFilter(FilterNode *aNode, michael@0: const Rect &aSourceRect, michael@0: const Point &aDestPoint, michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: virtual void DrawSurfaceWithShadow(SourceSurface *aSurface, michael@0: const Point &aDest, michael@0: const Color &aColor, michael@0: const Point &aOffset, michael@0: Float aSigma, michael@0: CompositionOp aOperator); michael@0: michael@0: virtual void ClearRect(const Rect &aRect); michael@0: michael@0: virtual void CopySurface(SourceSurface *aSurface, michael@0: const IntRect &aSourceRect, michael@0: const IntPoint &aDestination); michael@0: virtual void CopyRect(const IntRect &aSourceRect, michael@0: const IntPoint &aDestination); michael@0: michael@0: virtual void FillRect(const Rect &aRect, michael@0: const Pattern &aPattern, michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: virtual void StrokeRect(const Rect &aRect, michael@0: const Pattern &aPattern, michael@0: const StrokeOptions &aStrokeOptions = StrokeOptions(), michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: virtual void StrokeLine(const Point &aStart, michael@0: const Point &aEnd, michael@0: const Pattern &aPattern, michael@0: const StrokeOptions &aStrokeOptions = StrokeOptions(), michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: michael@0: virtual void Stroke(const Path *aPath, michael@0: const Pattern &aPattern, michael@0: const StrokeOptions &aStrokeOptions = StrokeOptions(), michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: michael@0: virtual void Fill(const Path *aPath, michael@0: const Pattern &aPattern, michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: michael@0: virtual void FillGlyphs(ScaledFont *aFont, michael@0: const GlyphBuffer &aBuffer, michael@0: const Pattern &aPattern, michael@0: const DrawOptions &aOptions, michael@0: const GlyphRenderingOptions *aRenderingOptions = nullptr); michael@0: virtual void Mask(const Pattern &aSource, michael@0: const Pattern &aMask, michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: virtual void MaskSurface(const Pattern &aSource, michael@0: SourceSurface *aMask, michael@0: Point aOffset, michael@0: const DrawOptions &aOptions = DrawOptions()); michael@0: michael@0: virtual void PushClip(const Path *aPath); michael@0: virtual void PushClipRect(const Rect &aRect); michael@0: virtual void PopClip(); michael@0: michael@0: virtual TemporaryRef CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const; michael@0: michael@0: virtual TemporaryRef CreateSourceSurfaceFromData(unsigned char *aData, michael@0: const IntSize &aSize, michael@0: int32_t aStride, michael@0: SurfaceFormat aFormat) const; michael@0: virtual TemporaryRef OptimizeSourceSurface(SourceSurface *aSurface) const; michael@0: virtual TemporaryRef michael@0: CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const; michael@0: virtual TemporaryRef michael@0: CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const; michael@0: virtual TemporaryRef michael@0: CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat, michael@0: float aSigma) const; michael@0: michael@0: virtual TemporaryRef michael@0: CreateGradientStops(GradientStop *aStops, michael@0: uint32_t aNumStops, michael@0: ExtendMode aExtendMode = ExtendMode::CLAMP) const; michael@0: michael@0: virtual TemporaryRef CreateFilter(FilterType aType); michael@0: michael@0: virtual void *GetNativeSurface(NativeSurfaceType aType); michael@0: michael@0: bool Init(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr); michael@0: bool Init(const IntSize& aSize, SurfaceFormat aFormat); michael@0: bool Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat); michael@0: michael@0: virtual void SetTransform(const Matrix& aTransform); michael@0: michael@0: // Call to set up aContext for drawing (with the current transform, etc). michael@0: // Pass the path you're going to be using if you have one. michael@0: // Implicitly calls WillChange(aPath). michael@0: void PrepareForDrawing(cairo_t* aContext, const Path* aPath = nullptr); michael@0: michael@0: static cairo_surface_t *GetDummySurface(); michael@0: michael@0: private: // methods michael@0: // Init cairo surface without doing a cairo_surface_reference() call. michael@0: bool InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr); michael@0: enum DrawPatternType { DRAW_FILL, DRAW_STROKE }; michael@0: void DrawPattern(const Pattern& aPattern, michael@0: const StrokeOptions& aStrokeOptions, michael@0: const DrawOptions& aOptions, michael@0: DrawPatternType aDrawType, michael@0: bool aPathBoundsClip = false); michael@0: michael@0: void CopySurfaceInternal(cairo_surface_t* aSurface, michael@0: const IntRect& aSource, michael@0: const IntPoint& aDest); michael@0: michael@0: Rect GetUserSpaceClip(); michael@0: michael@0: // Call before you make any changes to the backing surface with which this michael@0: // context is associated. Pass the path you're going to be using if you have michael@0: // one. michael@0: void WillChange(const Path* aPath = nullptr); michael@0: michael@0: // Call if there is any reason to disassociate the snapshot from this draw michael@0: // target; for example, because we're going to be destroyed. michael@0: void MarkSnapshotIndependent(); michael@0: michael@0: // If the current operator is "source" then clear the destination before we michael@0: // draw into it, to simulate the effect of an unbounded source operator. michael@0: void ClearSurfaceForUnboundedSource(const CompositionOp &aOperator); michael@0: private: // data michael@0: cairo_t* mContext; michael@0: cairo_surface_t* mSurface; michael@0: IntSize mSize; michael@0: michael@0: uint8_t* mLockedBits; michael@0: michael@0: // The latest snapshot of this surface. This needs to be told when this michael@0: // target is modified. We keep it alive as a cache. michael@0: RefPtr mSnapshot; michael@0: static cairo_surface_t *mDummySurface; michael@0: }; michael@0: michael@0: } michael@0: } michael@0: michael@0: #endif // _MOZILLA_GFX_DRAWTARGET_CAIRO_H_