gfxASurface.h (5498B)
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef GFX_ASURFACE_H 7 #define GFX_ASURFACE_H 8 9 #include "mozilla/MemoryReporting.h" 10 #include "mozilla/UniquePtr.h" 11 12 #include "gfxPoint.h" 13 #include "gfxRect.h" 14 #include "gfxTypes.h" 15 #include "nscore.h" 16 #include "nsSize.h" 17 #include "mozilla/gfx/Rect.h" 18 19 #include "nsStringFwd.h" 20 21 class gfxImageSurface; 22 23 template <typename T> 24 struct already_AddRefed; 25 26 /** 27 * A surface is something you can draw on. Instantiate a subclass of this 28 * abstract class, and use gfxContext to draw on this surface. 29 */ 30 class gfxASurface { 31 public: 32 #ifdef MOZILLA_INTERNAL_API 33 nsrefcnt AddRef(void); 34 nsrefcnt Release(void); 35 #else 36 virtual nsrefcnt AddRef(void); 37 virtual nsrefcnt Release(void); 38 #endif 39 40 public: 41 /** Wrap the given cairo surface and return a gfxASurface for it. 42 * This adds a reference to csurf (owned by the returned gfxASurface). 43 */ 44 static already_AddRefed<gfxASurface> Wrap( 45 cairo_surface_t* csurf, 46 const mozilla::gfx::IntSize& aSize = mozilla::gfx::IntSize(-1, -1)); 47 48 /*** this DOES NOT addref the surface */ 49 cairo_surface_t* CairoSurface() { return mSurface; } 50 51 gfxSurfaceType GetType() const; 52 53 gfxContentType GetContentType() const; 54 55 void SetDeviceOffset(const gfxPoint& offset); 56 gfxPoint GetDeviceOffset() const; 57 58 void Flush() const; 59 void MarkDirty(); 60 void MarkDirty(const gfxRect& r); 61 62 /* Printing backend functions */ 63 virtual nsresult BeginPrinting(const nsAString& aTitle, 64 const nsAString& aPrintToFileName); 65 virtual nsresult EndPrinting(); 66 virtual nsresult AbortPrinting(); 67 virtual nsresult BeginPage(); 68 virtual nsresult EndPage(); 69 70 void SetData(const cairo_user_data_key_t* key, void* user_data, 71 thebes_destroy_func_t destroy); 72 void* GetData(const cairo_user_data_key_t* key); 73 74 virtual void Finish(); 75 76 /** 77 * Returns an image surface for this surface, or nullptr if not supported. 78 * This will not copy image data, just wraps an image surface around 79 * pixel data already available in memory. 80 */ 81 virtual already_AddRefed<gfxImageSurface> GetAsImageSurface(); 82 83 int CairoStatus(); 84 85 static gfxContentType ContentFromFormat(gfxImageFormat format); 86 87 /** 88 * Record number of bytes for given surface type. Use positive bytes 89 * for allocations and negative bytes for deallocations. 90 */ 91 static void RecordMemoryUsedForSurfaceType(gfxSurfaceType aType, 92 int32_t aBytes); 93 94 /** 95 * Same as above, but use current surface type as returned by GetType(). 96 * The bytes will be accumulated until RecordMemoryFreed is called, 97 * in which case the value that was recorded for this surface will 98 * be freed. 99 */ 100 void RecordMemoryUsed(int32_t aBytes); 101 void RecordMemoryFreed(); 102 103 virtual int32_t KnownMemoryUsed() { return mBytesRecorded; } 104 105 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 106 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 107 // gfxASurface has many sub-classes. This method indicates if a sub-class 108 // is capable of measuring its own size accurately. If not, the caller 109 // must fall back to a computed size. (Note that gfxASurface can actually 110 // measure itself, but we must |return false| here because it serves as the 111 // (conservative) default for all the sub-classes. Therefore, this 112 // function should only be called on a |gfxASurface*| that actually points 113 // to a sub-class of gfxASurface.) 114 virtual bool SizeOfIsMeasured() const { return false; } 115 116 static int32_t BytePerPixelFromFormat(gfxImageFormat format); 117 118 virtual const mozilla::gfx::IntSize GetSize() const; 119 120 virtual mozilla::gfx::SurfaceFormat GetSurfaceFormat() const; 121 122 void SetOpaqueRect(const gfxRect& aRect); 123 124 const gfxRect& GetOpaqueRect() { 125 if (!!mOpaqueRect) return *mOpaqueRect; 126 return GetEmptyOpaqueRect(); 127 } 128 129 static uint8_t BytesPerPixel(gfxImageFormat aImageFormat); 130 131 protected: 132 gfxASurface(); 133 134 static gfxASurface* GetSurfaceWrapper(cairo_surface_t* csurf); 135 static void SetSurfaceWrapper(cairo_surface_t* csurf, gfxASurface* asurf); 136 137 // NB: Init() *must* be called from within subclass's 138 // constructors. It's unsafe to call it after the ctor finishes; 139 // leaks and use-after-frees are possible. 140 void Init(cairo_surface_t* surface, bool existingSurface = false); 141 142 // out-of-line helper to allow GetOpaqueRect() to be inlined 143 // without including gfxRect.h here 144 static const gfxRect& GetEmptyOpaqueRect(); 145 146 virtual ~gfxASurface(); 147 148 cairo_surface_t* mSurface; 149 mozilla::UniquePtr<gfxRect> mOpaqueRect; 150 151 private: 152 static void SurfaceDestroyFunc(void* data); 153 154 int32_t mFloatingRefs; 155 int32_t mBytesRecorded; 156 157 protected: 158 bool mSurfaceValid; 159 }; 160 161 /** 162 * An Unknown surface; used to wrap unknown cairo_surface_t returns from cairo 163 */ 164 class gfxUnknownSurface : public gfxASurface { 165 public: 166 gfxUnknownSurface(cairo_surface_t* surf, const mozilla::gfx::IntSize& aSize) 167 : mSize(aSize) { 168 Init(surf, true); 169 } 170 171 virtual ~gfxUnknownSurface() = default; 172 const mozilla::gfx::IntSize GetSize() const override { return mSize; } 173 174 private: 175 mozilla::gfx::IntSize mSize; 176 }; 177 178 #endif /* GFX_ASURFACE_H */