diff options
Diffstat (limited to 'gfx/thebes/gfxASurface.h')
-rw-r--r-- | gfx/thebes/gfxASurface.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/gfx/thebes/gfxASurface.h b/gfx/thebes/gfxASurface.h new file mode 100644 index 0000000000..d2e6daf771 --- /dev/null +++ b/gfx/thebes/gfxASurface.h @@ -0,0 +1,184 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_ASURFACE_H +#define GFX_ASURFACE_H + +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +#include "gfxPoint.h" +#include "gfxRect.h" +#include "gfxTypes.h" +#include "nscore.h" +#include "nsSize.h" +#include "mozilla/gfx/Rect.h" + +#include "nsStringFwd.h" + +class gfxImageSurface; + +template <typename T> +struct already_AddRefed; + +/** + * A surface is something you can draw on. Instantiate a subclass of this + * abstract class, and use gfxContext to draw on this surface. + */ +class gfxASurface { + public: +#ifdef MOZILLA_INTERNAL_API + nsrefcnt AddRef(void); + nsrefcnt Release(void); +#else + virtual nsrefcnt AddRef(void); + virtual nsrefcnt Release(void); +#endif + + public: + /** Wrap the given cairo surface and return a gfxASurface for it. + * This adds a reference to csurf (owned by the returned gfxASurface). + */ + static already_AddRefed<gfxASurface> Wrap( + cairo_surface_t* csurf, + const mozilla::gfx::IntSize& aSize = mozilla::gfx::IntSize(-1, -1)); + + /*** this DOES NOT addref the surface */ + cairo_surface_t* CairoSurface() { return mSurface; } + + gfxSurfaceType GetType() const; + + gfxContentType GetContentType() const; + + void SetDeviceOffset(const gfxPoint& offset); + gfxPoint GetDeviceOffset() const; + + void Flush() const; + void MarkDirty(); + void MarkDirty(const gfxRect& r); + + /* Printing backend functions */ + virtual nsresult BeginPrinting(const nsAString& aTitle, + const nsAString& aPrintToFileName); + virtual nsresult EndPrinting(); + virtual nsresult AbortPrinting(); + virtual nsresult BeginPage(); + virtual nsresult EndPage(); + + void SetData(const cairo_user_data_key_t* key, void* user_data, + thebes_destroy_func_t destroy); + void* GetData(const cairo_user_data_key_t* key); + + virtual void Finish(); + + /** + * Returns an image surface for this surface, or nullptr if not supported. + * This will not copy image data, just wraps an image surface around + * pixel data already available in memory. + */ + virtual already_AddRefed<gfxImageSurface> GetAsImageSurface(); + + /** + * Creates a new ARGB32 image surface with the same contents as this surface. + * Returns null on error. + */ + already_AddRefed<gfxImageSurface> CopyToARGB32ImageSurface(); + + int CairoStatus(); + + static gfxContentType ContentFromFormat(gfxImageFormat format); + + /** + * Record number of bytes for given surface type. Use positive bytes + * for allocations and negative bytes for deallocations. + */ + static void RecordMemoryUsedForSurfaceType(gfxSurfaceType aType, + int32_t aBytes); + + /** + * Same as above, but use current surface type as returned by GetType(). + * The bytes will be accumulated until RecordMemoryFreed is called, + * in which case the value that was recorded for this surface will + * be freed. + */ + void RecordMemoryUsed(int32_t aBytes); + void RecordMemoryFreed(); + + virtual int32_t KnownMemoryUsed() { return mBytesRecorded; } + + virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + // gfxASurface has many sub-classes. This method indicates if a sub-class + // is capable of measuring its own size accurately. If not, the caller + // must fall back to a computed size. (Note that gfxASurface can actually + // measure itself, but we must |return false| here because it serves as the + // (conservative) default for all the sub-classes. Therefore, this + // function should only be called on a |gfxASurface*| that actually points + // to a sub-class of gfxASurface.) + virtual bool SizeOfIsMeasured() const { return false; } + + static int32_t BytePerPixelFromFormat(gfxImageFormat format); + + virtual const mozilla::gfx::IntSize GetSize() const; + + virtual mozilla::gfx::SurfaceFormat GetSurfaceFormat() const; + + void SetOpaqueRect(const gfxRect& aRect); + + const gfxRect& GetOpaqueRect() { + if (!!mOpaqueRect) return *mOpaqueRect; + return GetEmptyOpaqueRect(); + } + + static uint8_t BytesPerPixel(gfxImageFormat aImageFormat); + + protected: + gfxASurface(); + + static gfxASurface* GetSurfaceWrapper(cairo_surface_t* csurf); + static void SetSurfaceWrapper(cairo_surface_t* csurf, gfxASurface* asurf); + + // NB: Init() *must* be called from within subclass's + // constructors. It's unsafe to call it after the ctor finishes; + // leaks and use-after-frees are possible. + void Init(cairo_surface_t* surface, bool existingSurface = false); + + // out-of-line helper to allow GetOpaqueRect() to be inlined + // without including gfxRect.h here + static const gfxRect& GetEmptyOpaqueRect(); + + virtual ~gfxASurface(); + + cairo_surface_t* mSurface; + mozilla::UniquePtr<gfxRect> mOpaqueRect; + + private: + static void SurfaceDestroyFunc(void* data); + + int32_t mFloatingRefs; + int32_t mBytesRecorded; + + protected: + bool mSurfaceValid; +}; + +/** + * An Unknown surface; used to wrap unknown cairo_surface_t returns from cairo + */ +class gfxUnknownSurface : public gfxASurface { + public: + gfxUnknownSurface(cairo_surface_t* surf, const mozilla::gfx::IntSize& aSize) + : mSize(aSize) { + Init(surf, true); + } + + virtual ~gfxUnknownSurface() = default; + const mozilla::gfx::IntSize GetSize() const override { return mSize; } + + private: + mozilla::gfx::IntSize mSize; +}; + +#endif /* GFX_ASURFACE_H */ |