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_IMAGESURFACE_H
7 #define GFX_IMAGESURFACE_H
8 
9 #include "mozilla/MemoryReporting.h"
10 #include "mozilla/RefPtr.h"
11 #include "gfxASurface.h"
12 #include "nsSize.h"
13 
14 // ARGB -- raw buffer.. wont be changed.. good for storing data.
15 
16 class gfxSubimageSurface;
17 
18 namespace mozilla {
19 namespace gfx {
20 class DataSourceSurface;
21 class SourceSurface;
22 }  // namespace gfx
23 }  // namespace mozilla
24 
25 /**
26  * A raw image buffer. The format can be set in the constructor. Its main
27  * purpose is for storing read-only images and using it as a source surface,
28  * but it can also be drawn to.
29  */
30 class gfxImageSurface : public gfxASurface {
31  public:
32   /**
33    * Construct an image surface around an existing buffer of image data.
34    * @param aData A buffer containing the image data
35    * @param aSize The size of the buffer
36    * @param aStride The stride of the buffer
37    * @param format Format of the data
38    *
39    * @see gfxImageFormat
40    */
41   gfxImageSurface(unsigned char* aData, const mozilla::gfx::IntSize& aSize,
42                   long aStride, gfxImageFormat aFormat);
43 
44   /**
45    * Construct an image surface.
46    * @param aSize The size of the buffer
47    * @param format Format of the data
48    *
49    * @see gfxImageFormat
50    */
51   gfxImageSurface(const mozilla::gfx::IntSize& size, gfxImageFormat format,
52                   bool aClear = true);
53 
54   /**
55    * Construct an image surface, with a specified stride and allowing the
56    * allocation of more memory than required for the storage of the surface
57    * itself.  When aStride and aMinimalAllocation are <=0, this constructor
58    * is the equivalent of the preceeding one.
59    *
60    * @param format Format of the data
61    * @param aSize The size of the buffer
62    * @param aStride The stride of the buffer - if <=0, use ComputeStride()
63    * @param aMinimalAllocation Allocate at least this many bytes.  If smaller
64    *        than width * stride, or width*stride <=0, this value is ignored.
65    * @param aClear
66    *
67    * @see gfxImageFormat
68    */
69   gfxImageSurface(const mozilla::gfx::IntSize& aSize, gfxImageFormat aFormat,
70                   long aStride, int32_t aMinimalAllocation, bool aClear);
71 
72   explicit gfxImageSurface(cairo_surface_t* csurf);
73 
74   virtual ~gfxImageSurface();
75 
76   // ImageSurface methods
Format()77   gfxImageFormat Format() const { return mFormat; }
78 
GetSize()79   virtual const mozilla::gfx::IntSize GetSize() const override { return mSize; }
Width()80   int32_t Width() const {
81     if (mSize.width < 0) {
82       return 0;
83     }
84     return mSize.width;
85   }
Height()86   int32_t Height() const {
87     if (mSize.height < 0) {
88       return 0;
89     }
90     return mSize.height;
91   }
92 
93   /**
94    * Distance in bytes between the start of a line and the start of the
95    * next line.
96    */
Stride()97   int32_t Stride() const { return mStride; }
98   /**
99    * Returns a pointer for the image data. Users of this function can
100    * write to it, but must not attempt to free the buffer.
101    */
Data()102   unsigned char* Data() const {
103     return mData;
104   }  // delete this data under us and die.
105   /**
106    * Returns the total size of the image data.
107    */
GetDataSize()108   int32_t GetDataSize() const {
109     if (mStride < 0 || mSize.height < 0) {
110       return 0;
111     }
112     return mStride * mSize.height;
113   }
114 
115   /* Fast copy from another image surface; returns TRUE if successful, FALSE
116    * otherwise */
117   bool CopyFrom(gfxImageSurface* other);
118 
119   /**
120    * Fast copy from a source surface; returns TRUE if successful, FALSE
121    * otherwise Assumes that the format of this surface is compatable with
122    * aSurface
123    */
124   bool CopyFrom(mozilla::gfx::SourceSurface* aSurface);
125 
126   /**
127    * Fast copy to a source surface; returns TRUE if successful, FALSE otherwise
128    * Assumes that the format of this surface is compatible with aSurface
129    */
130   bool CopyTo(mozilla::gfx::SourceSurface* aSurface);
131 
132   /**
133    * Copy to a Moz2D DataSourceSurface.
134    * Marked as virtual so that browsercomps can access this method.
135    */
136   virtual already_AddRefed<mozilla::gfx::DataSourceSurface>
137   CopyToB8G8R8A8DataSourceSurface();
138 
139   /* return new Subimage with pointing to original image starting from aRect.pos
140    * and size of aRect.size. New subimage keeping current image reference
141    */
142   already_AddRefed<gfxSubimageSurface> GetSubimage(const gfxRect& aRect);
143 
144   virtual already_AddRefed<gfxImageSurface> GetAsImageSurface() override;
145 
146   /** See gfxASurface.h. */
147   static long ComputeStride(const mozilla::gfx::IntSize&, gfxImageFormat);
148 
149   virtual size_t SizeOfExcludingThis(
150       mozilla::MallocSizeOf aMallocSizeOf) const override;
151   virtual size_t SizeOfIncludingThis(
152       mozilla::MallocSizeOf aMallocSizeOf) const override;
153   virtual bool SizeOfIsMeasured() const override;
154 
155  protected:
156   gfxImageSurface();
157   void InitWithData(unsigned char* aData, const mozilla::gfx::IntSize& aSize,
158                     long aStride, gfxImageFormat aFormat);
159   /**
160    * See the parameters to the matching constructor.  This should only
161    * be called once, in the constructor, which has already set mSize
162    * and mFormat.
163    */
164   void AllocateAndInit(long aStride, int32_t aMinimalAllocation, bool aClear);
165   void InitFromSurface(cairo_surface_t* csurf);
166 
ComputeStride()167   long ComputeStride() const {
168     if (mSize.height < 0 || mSize.width < 0) {
169       return 0;
170     }
171     return ComputeStride(mSize, mFormat);
172   }
173 
174   void MakeInvalid();
175 
176   mozilla::gfx::IntSize mSize;
177   bool mOwnsData;
178   unsigned char* mData;
179   gfxImageFormat mFormat;
180   long mStride;
181 };
182 
183 class gfxSubimageSurface : public gfxImageSurface {
184  protected:
185   friend class gfxImageSurface;
186   gfxSubimageSurface(gfxImageSurface* aParent, unsigned char* aData,
187                      const mozilla::gfx::IntSize& aSize,
188                      gfxImageFormat aFormat);
189 
190  private:
191   RefPtr<gfxImageSurface> mParent;
192 };
193 
194 #endif /* GFX_IMAGESURFACE_H */
195