Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
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 :
42 : /** Wrap the given cairo surface and return a gfxASurface for it.
43 : * This adds a reference to csurf (owned by the returned gfxASurface).
44 : */
45 : static already_AddRefed<gfxASurface> Wrap(cairo_surface_t *csurf, const mozilla::gfx::IntSize& aSize = mozilla::gfx::IntSize(-1, -1));
46 :
47 : /*** this DOES NOT addref the surface */
48 2 : cairo_surface_t *CairoSurface() {
49 2 : return mSurface;
50 : }
51 :
52 : gfxSurfaceType GetType() const;
53 :
54 : gfxContentType GetContentType() const;
55 :
56 : void SetDeviceOffset(const gfxPoint& offset);
57 : gfxPoint GetDeviceOffset() const;
58 :
59 : void Flush() const;
60 : void MarkDirty();
61 : void MarkDirty(const gfxRect& r);
62 :
63 : /* Printing backend functions */
64 : virtual nsresult BeginPrinting(const nsAString& aTitle, 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,
71 : void *user_data,
72 : thebes_destroy_func_t destroy);
73 : void *GetData(const cairo_user_data_key_t *key);
74 :
75 : virtual void Finish();
76 :
77 : /**
78 : * Create an offscreen surface that can be efficiently copied into
79 : * this surface (at least if tiling is not involved).
80 : * Returns null on error.
81 : */
82 : virtual already_AddRefed<gfxASurface> CreateSimilarSurface(gfxContentType aType,
83 : const mozilla::gfx::IntSize& aSize);
84 :
85 : /**
86 : * Returns an image surface for this surface, or nullptr if not supported.
87 : * This will not copy image data, just wraps an image surface around
88 : * pixel data already available in memory.
89 : */
90 : virtual already_AddRefed<gfxImageSurface> GetAsImageSurface();
91 :
92 : /**
93 : * Creates a new ARGB32 image surface with the same contents as this surface.
94 : * Returns null on error.
95 : */
96 : already_AddRefed<gfxImageSurface> CopyToARGB32ImageSurface();
97 :
98 : int CairoStatus();
99 :
100 : static gfxContentType ContentFromFormat(gfxImageFormat format);
101 :
102 : /**
103 : * Record number of bytes for given surface type. Use positive bytes
104 : * for allocations and negative bytes for deallocations.
105 : */
106 : static void RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
107 : int32_t aBytes);
108 :
109 : /**
110 : * Same as above, but use current surface type as returned by GetType().
111 : * The bytes will be accumulated until RecordMemoryFreed is called,
112 : * in which case the value that was recorded for this surface will
113 : * be freed.
114 : */
115 : void RecordMemoryUsed(int32_t aBytes);
116 : void RecordMemoryFreed();
117 :
118 0 : virtual int32_t KnownMemoryUsed() { return mBytesRecorded; }
119 :
120 : virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
121 : virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
122 : // gfxASurface has many sub-classes. This method indicates if a sub-class
123 : // is capable of measuring its own size accurately. If not, the caller
124 : // must fall back to a computed size. (Note that gfxASurface can actually
125 : // measure itself, but we must |return false| here because it serves as the
126 : // (conservative) default for all the sub-classes. Therefore, this
127 : // function should only be called on a |gfxASurface*| that actually points
128 : // to a sub-class of gfxASurface.)
129 0 : virtual bool SizeOfIsMeasured() const { return false; }
130 :
131 : static int32_t BytePerPixelFromFormat(gfxImageFormat format);
132 :
133 : virtual const mozilla::gfx::IntSize GetSize() const;
134 :
135 : virtual mozilla::gfx::SurfaceFormat GetSurfaceFormat() const;
136 :
137 : void SetOpaqueRect(const gfxRect& aRect);
138 :
139 0 : const gfxRect& GetOpaqueRect() {
140 0 : if (!!mOpaqueRect)
141 0 : return *mOpaqueRect;
142 0 : return GetEmptyOpaqueRect();
143 : }
144 :
145 : static uint8_t BytesPerPixel(gfxImageFormat aImageFormat);
146 :
147 : protected:
148 : gfxASurface();
149 :
150 : static gfxASurface* GetSurfaceWrapper(cairo_surface_t *csurf);
151 : static void SetSurfaceWrapper(cairo_surface_t *csurf, gfxASurface *asurf);
152 :
153 : // NB: Init() *must* be called from within subclass's
154 : // constructors. It's unsafe to call it after the ctor finishes;
155 : // leaks and use-after-frees are possible.
156 : void Init(cairo_surface_t *surface, bool existingSurface = false);
157 :
158 : // out-of-line helper to allow GetOpaqueRect() to be inlined
159 : // without including gfxRect.h here
160 : static const gfxRect& GetEmptyOpaqueRect();
161 :
162 : virtual ~gfxASurface();
163 :
164 : cairo_surface_t *mSurface;
165 : mozilla::UniquePtr<gfxRect> mOpaqueRect;
166 :
167 : private:
168 : static void SurfaceDestroyFunc(void *data);
169 :
170 : int32_t mFloatingRefs;
171 : int32_t mBytesRecorded;
172 :
173 : protected:
174 : bool mSurfaceValid;
175 : };
176 :
177 : /**
178 : * An Unknown surface; used to wrap unknown cairo_surface_t returns from cairo
179 : */
180 : class gfxUnknownSurface : public gfxASurface {
181 : public:
182 0 : gfxUnknownSurface(cairo_surface_t *surf, const mozilla::gfx::IntSize& aSize)
183 0 : : mSize(aSize)
184 : {
185 0 : Init(surf, true);
186 0 : }
187 :
188 0 : virtual ~gfxUnknownSurface() { }
189 0 : virtual const mozilla::gfx::IntSize GetSize() const override { return mSize; }
190 :
191 : private:
192 : mozilla::gfx::IntSize mSize;
193 : };
194 :
195 : #endif /* GFX_ASURFACE_H */
|