michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 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 GFX_PATTERN_H michael@0: #define GFX_PATTERN_H michael@0: michael@0: #include "gfxTypes.h" michael@0: michael@0: #include "gfxMatrix.h" michael@0: #include "mozilla/Alignment.h" michael@0: #include "mozilla/gfx/2D.h" michael@0: #include "GraphicsFilter.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsTArray.h" michael@0: michael@0: class gfxContext; michael@0: class gfxASurface; michael@0: struct gfxRGBA; michael@0: typedef struct _cairo_pattern cairo_pattern_t; michael@0: michael@0: michael@0: class gfxPattern MOZ_FINAL{ michael@0: NS_INLINE_DECL_REFCOUNTING(gfxPattern) michael@0: michael@0: public: michael@0: gfxPattern(cairo_pattern_t *aPattern); michael@0: gfxPattern(const gfxRGBA& aColor); michael@0: gfxPattern(gfxASurface *surface); // from another surface michael@0: // linear michael@0: gfxPattern(gfxFloat x0, gfxFloat y0, gfxFloat x1, gfxFloat y1); // linear michael@0: gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0, michael@0: gfxFloat cx1, gfxFloat cy1, gfxFloat radius1); // radial michael@0: gfxPattern(mozilla::gfx::SourceSurface *aSurface, michael@0: const mozilla::gfx::Matrix &aTransform); // Azure michael@0: michael@0: cairo_pattern_t *CairoPattern(); michael@0: void AddColorStop(gfxFloat offset, const gfxRGBA& c); michael@0: void SetColorStops(mozilla::RefPtr aStops); michael@0: michael@0: // This should only be called on a cairo pattern that we want to use with michael@0: // Azure. We will read back the color stops from cairo and try to look michael@0: // them up in the cache. michael@0: void CacheColorStops(mozilla::gfx::DrawTarget *aDT); michael@0: michael@0: void SetMatrix(const gfxMatrix& matrix); michael@0: gfxMatrix GetMatrix() const; michael@0: gfxMatrix GetInverseMatrix() const; michael@0: michael@0: /* Get an Azure Pattern for the current Cairo pattern. aPattern transform michael@0: * specifies the transform that was set on the DrawTarget when the pattern michael@0: * was set. When this is nullptr it is assumed the transform is identical michael@0: * to the current transform. michael@0: */ michael@0: mozilla::gfx::Pattern *GetPattern(mozilla::gfx::DrawTarget *aTarget, michael@0: mozilla::gfx::Matrix *aPatternTransform = nullptr); michael@0: bool IsOpaque(); michael@0: michael@0: enum GraphicsExtend { michael@0: EXTEND_NONE, michael@0: EXTEND_REPEAT, michael@0: EXTEND_REFLECT, michael@0: EXTEND_PAD, michael@0: michael@0: // Our own private flag for setting either NONE or PAD, michael@0: // depending on what the platform does for NONE. This is only michael@0: // relevant for surface patterns; for all other patterns, it michael@0: // behaves identical to PAD. On MacOS X, this becomes "NONE", michael@0: // because Quartz does the thing that we want at image edges; michael@0: // similarily on the win32 printing surface, since michael@0: // everything's done with GDI there. On other platforms, it michael@0: // usually becomes PAD. michael@0: EXTEND_PAD_EDGE = 1000 michael@0: }; michael@0: michael@0: // none, repeat, reflect michael@0: void SetExtend(GraphicsExtend extend); michael@0: GraphicsExtend Extend() const; michael@0: michael@0: enum GraphicsPatternType { michael@0: PATTERN_SOLID, michael@0: PATTERN_SURFACE, michael@0: PATTERN_LINEAR, michael@0: PATTERN_RADIAL michael@0: }; michael@0: michael@0: GraphicsPatternType GetType() const; michael@0: michael@0: int CairoStatus(); michael@0: michael@0: void SetFilter(GraphicsFilter filter); michael@0: GraphicsFilter Filter() const; michael@0: michael@0: /* returns TRUE if it succeeded */ michael@0: bool GetSolidColor(gfxRGBA& aColor); michael@0: michael@0: already_AddRefed GetSurface(); michael@0: michael@0: bool IsAzure() { return !mPattern; } michael@0: michael@0: mozilla::TemporaryRef GetAzureSurface() { return mSourceSurface; } michael@0: michael@0: private: michael@0: // Private destructor, to discourage deletion outside of Release(): michael@0: ~gfxPattern(); michael@0: michael@0: cairo_pattern_t *mPattern; michael@0: michael@0: /** michael@0: * aPatternTransform is the cairo pattern transform --- from user space at michael@0: * the time the pattern was set, to pattern space. michael@0: * aCurrentTransform is the DrawTarget's CTM --- from user space to device michael@0: * space. michael@0: * aOriginalTransform, if non-null, is the DrawTarget's TM when michael@0: * aPatternTransform was set --- user space to device space. If null, then michael@0: * the DrawTarget's CTM is the same as the TM when aPatternTransfrom was set. michael@0: * This function sets aPatternTransform to the Azure pattern transform --- michael@0: * from pattern space to current DrawTarget user space. michael@0: */ michael@0: void AdjustTransformForPattern(mozilla::gfx::Matrix &aPatternTransform, michael@0: const mozilla::gfx::Matrix &aCurrentTransform, michael@0: const mozilla::gfx::Matrix *aOriginalTransform); michael@0: michael@0: union { michael@0: mozilla::AlignedStorage2 mColorPattern; michael@0: mozilla::AlignedStorage2 mLinearGradientPattern; michael@0: mozilla::AlignedStorage2 mRadialGradientPattern; michael@0: mozilla::AlignedStorage2 mSurfacePattern; michael@0: }; michael@0: michael@0: mozilla::gfx::Pattern *mGfxPattern; michael@0: michael@0: mozilla::RefPtr mSourceSurface; michael@0: mozilla::gfx::Matrix mTransform; michael@0: mozilla::RefPtr mStops; michael@0: GraphicsExtend mExtend; michael@0: mozilla::gfx::Filter mFilter; michael@0: }; michael@0: michael@0: #endif /* GFX_PATTERN_H */