[OS/2]
Bug 395301: Move offscreen surface creation from gfxOS2Platform to gfxOS2Surface
--- a/gfx/thebes/public/gfxOS2Platform.h
+++ b/gfx/thebes/public/gfxOS2Platform.h
@@ -66,16 +66,11 @@ public:
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, PRBool& aAborted);
gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
const gfxFontStyle *aStyle);
protected:
static gfxFontconfigUtils *sFontconfigUtils;
-
-private:
- HDC mDC;
- HPS mPS;
- HBITMAP mBitmap;
};
#endif /* GFX_OS2_PLATFORM_H */
--- a/gfx/thebes/public/gfxOS2Surface.h
+++ b/gfx/thebes/public/gfxOS2Surface.h
@@ -35,28 +35,37 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_OS2_SURFACE_H
#define GFX_OS2_SURFACE_H
#include "gfxASurface.h"
+#define INCL_GPIBITMAPS
#include <os2.h>
#include <cairo-os2.h>
class THEBES_API gfxOS2Surface : public gfxASurface {
public:
+ // constructor to create a cairo surface using an existing PS
gfxOS2Surface(HPS aPS, const gfxIntSize& aSize);
+ // constructor used to create a memory surface of given size
+ gfxOS2Surface(const gfxIntSize& aSize,
+ gfxASurface::gfxImageFormat aImageFormat);
+ // constructor for surface connected to an onscreen window
gfxOS2Surface(HWND aWnd);
virtual ~gfxOS2Surface();
HPS GetPS() { return mPS; }
gfxIntSize GetSize() { return mSize; }
private:
PRBool mOwnsPS;
- HPS mPS;
- gfxIntSize mSize;
+ PRBool mHasWnd; // indicates if created through the HWND constructor
+ HDC mDC; // memory device context
+ HPS mPS; // presentation space connected to window or memory device
+ HBITMAP mBitmap; // bitmap for initialization of memory surface
+ gfxIntSize mSize; // current size of the surface
};
#endif /* GFX_OS2_SURFACE_H */
--- a/gfx/thebes/src/gfxOS2Platform.cpp
+++ b/gfx/thebes/src/gfxOS2Platform.cpp
@@ -46,17 +46,16 @@
//#include <fontconfig/fontconfig.h>
/**********************************************************************
* class gfxOS2Platform
**********************************************************************/
gfxFontconfigUtils *gfxOS2Platform::sFontconfigUtils = nsnull;
gfxOS2Platform::gfxOS2Platform()
- : mDC(NULL), mPS(NULL), mBitmap(NULL)
{
#ifdef DEBUG_thebes
printf("gfxOS2Platform::gfxOS2Platform()\n");
#endif
// this seems to be reasonably early in the process and only once,
// so it's a good place to initialize OS/2 cairo stuff
cairo_os2_init();
#ifdef DEBUG_thebes
@@ -70,26 +69,16 @@ gfxOS2Platform::gfxOS2Platform()
gfxOS2Platform::~gfxOS2Platform()
{
#ifdef DEBUG_thebes
printf("gfxOS2Platform::~gfxOS2Platform()\n");
#endif
gfxFontconfigUtils::Shutdown();
sFontconfigUtils = nsnull;
- if (mBitmap) {
- GpiSetBitmap(mPS, NULL);
- GpiDeleteBitmap(mBitmap);
- }
- if (mPS) {
- GpiDestroyPS(mPS);
- }
- if (mDC) {
- DevCloseDC(mDC);
- }
// clean up OS/2 cairo stuff
cairo_os2_fini();
#ifdef DEBUG_thebes
printf(" cairo_os2_fini() was called\n");
#endif
}
already_AddRefed<gfxASurface>
@@ -97,51 +86,22 @@ gfxOS2Platform::CreateOffscreenSurface(c
gfxASurface::gfxImageFormat aImageFormat)
{
#ifdef DEBUG_thebes_2
printf("gfxOS2Platform::CreateOffscreenSurface(%d/%d, %d)\n",
aSize.width, aSize.height, aImageFormat);
#endif
gfxASurface *newSurface = nsnull;
- // XXX we only ever seem to get aImageFormat=0 or ImageFormatARGB32 but
+ // we only ever seem to get aImageFormat=0 or ImageFormatARGB32 but
// I don't really know if we need to differ between ARGB32 and RGB24 here
if (aImageFormat == gfxASurface::ImageFormatARGB32 ||
aImageFormat == gfxASurface::ImageFormatRGB24)
{
- // create a PS, partly taken from nsOffscreenSurface::Init(), i.e. nsDrawingSurfaceOS2.cpp
- DEVOPENSTRUC dop = { 0, 0, 0, 0, 0 };
- SIZEL sizel = { 0, 0 }; /* use same page size as device */
- mDC = DevOpenDC(0, OD_MEMORY, "*", 5, (PDEVOPENDATA)&dop, NULLHANDLE);
- if (mDC != DEV_ERROR) {
- mPS = GpiCreatePS(0, mDC, &sizel, PU_PELS | GPIT_MICRO | GPIA_ASSOC);
- if (mPS != GPI_ERROR) {
- // XXX: nsPaletteOS2::SelectGlobalPalette(mPS);
- // perhaps implement the palette stuff at some point?!
-
- // now create a bitmap of the right size
- BITMAPINFOHEADER2 hdr = { 0 };
- hdr.cbFix = sizeof(BITMAPINFOHEADER2);
- hdr.cx = aSize.width;
- hdr.cy = aSize.height;
- hdr.cPlanes = 1;
-
- // find bit depth, XXX this may not work here, use the aImageFormat instead?!
- LONG lBitCount = 0;
- DevQueryCaps(mDC, CAPS_COLOR_BITCOUNT, 1, &lBitCount);
- hdr.cBitCount = (USHORT)lBitCount;
-
- mBitmap = GpiCreateBitmap(mPS, &hdr, 0, 0, 0);
- if (mBitmap != GPI_ERROR) {
- // set final stats & select bitmap into ps
- GpiSetBitmap(mPS, mBitmap);
- }
- } /* if mPS */
- } /* if mDC */
- newSurface = new gfxOS2Surface(mPS, aSize);
+ newSurface = new gfxOS2Surface(aSize, aImageFormat);
} else if (aImageFormat == gfxASurface::ImageFormatA8 ||
aImageFormat == gfxASurface::ImageFormatA1) {
newSurface = new gfxImageSurface(aSize, aImageFormat);
} else {
return nsnull;
}
NS_IF_ADDREF(newSurface);
--- a/gfx/thebes/src/gfxOS2Surface.cpp
+++ b/gfx/thebes/src/gfxOS2Surface.cpp
@@ -39,61 +39,129 @@
#include <stdio.h>
/**********************************************************************
* class gfxOS2Surface
**********************************************************************/
gfxOS2Surface::gfxOS2Surface(HPS aPS, const gfxIntSize& aSize)
- : mOwnsPS(PR_FALSE), mPS(aPS), mSize(aSize)
+ : mOwnsPS(PR_FALSE), mHasWnd(PR_FALSE), mDC(nsnull), mPS(aPS), mBitmap(nsnull), mSize(aSize)
+{
+#ifdef DEBUG_thebes_2
+ printf("gfxOS2Surface[%#x]::gfxOS2Surface(HPS=%#x, Size=%dx%d)\n", (unsigned int)this,
+ (unsigned int)mPS, aSize.width, aSize.height);
+#endif
+
+ // create the cairo surface on the passed PS
+ cairo_surface_t *surf = cairo_os2_surface_create(mPS, mSize.width, mSize.height);
+#ifdef DEBUG_thebes_2
+ printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
+ cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height);
+#endif
+ // XXX for now uncomment the mark_dirty function, see bug 371505
+ //cairo_surface_mark_dirty(surf);
+ Init(surf);
+}
+
+gfxOS2Surface::gfxOS2Surface(const gfxIntSize& aSize,
+ gfxASurface::gfxImageFormat aImageFormat)
+ : mOwnsPS(PR_TRUE), mHasWnd(PR_FALSE), mSize(aSize)
{
#ifdef DEBUG_thebes_2
- printf("gfxOS2Surface[%#x]::gfxOS2Surface(HPS=%#x, ...)\n",
- (unsigned int)this, (unsigned int)aPS);
+ printf("gfxOS2Surface[%#x]::gfxOS2Surface(Size=%dx%d, %d)\n", (unsigned int)this,
+ aSize.width, aSize.height, aImageFormat);
#endif
+ // in this case we don't have a window, so we create a memory presentation
+ // space to construct the cairo surface on
+ // create a PS, partly taken from nsOffscreenSurface::Init(), i.e. nsDrawingSurfaceOS2.cpp
+ DEVOPENSTRUC dop = { 0, 0, 0, 0, 0 };
+ SIZEL sizel = { 0, 0 }; // use same page size as device
+ mDC = DevOpenDC(0, OD_MEMORY, (PSZ)"*", 5, (PDEVOPENDATA)&dop, NULLHANDLE);
+ NS_ASSERTION(mDC != DEV_ERROR, "Could not create memory DC");
+
+ mPS = GpiCreatePS(0, mDC, &sizel, PU_PELS | GPIT_MICRO | GPIA_ASSOC);
+ NS_ASSERTION(mPS != GPI_ERROR, "Could not create PS on memory DC!");
+
+ // now create a bitmap of the right size
+ BITMAPINFOHEADER2 hdr = { 0 };
+ hdr.cbFix = sizeof(BITMAPINFOHEADER2);
+ hdr.cx = mSize.width;
+ hdr.cy = mSize.height;
+ hdr.cPlanes = 1;
+
+ // find bit depth
+ LONG lBitCount = 0;
+ DevQueryCaps(mDC, CAPS_COLOR_BITCOUNT, 1, &lBitCount);
+ hdr.cBitCount = (USHORT)lBitCount;
+
+ mBitmap = GpiCreateBitmap(mPS, &hdr, 0, 0, 0);
+ NS_ASSERTION(mBitmap != GPI_ERROR, "Could not create bitmap in memory!");
+ // set final stats & select bitmap into PS
+ GpiSetBitmap(mPS, mBitmap);
+
+ // now we can finally create the cairo surface on the in-memory PS
cairo_surface_t *surf = cairo_os2_surface_create(mPS, mSize.width, mSize.height);
#ifdef DEBUG_thebes_2
- printf(" type(%#x)=%d (own=%d, ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
- cairo_surface_get_type(surf), mOwnsPS, (unsigned int)mPS, mSize.width, mSize.height);
+ printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
+ cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height);
#endif
// XXX for now uncomment the mark_dirty function, see bug 371505
//cairo_surface_mark_dirty(surf);
Init(surf);
}
gfxOS2Surface::gfxOS2Surface(HWND aWnd)
- : mOwnsPS(PR_TRUE)
+ : mOwnsPS(PR_TRUE), mHasWnd(PR_TRUE), mDC(nsnull), mBitmap(nsnull)
{
#ifdef DEBUG_thebes_2
- printf("gfxOS2Surface[%#x]::gfxOS2Surface(HWND=%#x)\n",
- (unsigned int)this, (unsigned int)aWnd);
+ printf("gfxOS2Surface[%#x]::gfxOS2Surface(HWND=%#x)\n", (unsigned int)this,
+ (unsigned int)aWnd);
#endif
mPS = WinGetPS(aWnd);
RECTL rectl;
WinQueryWindowRect(aWnd, &rectl);
mSize.width = rectl.xRight - rectl.xLeft;
mSize.height = rectl.yTop - rectl.yBottom;
if (mSize.width == 0) mSize.width = 1; // fake a minimal surface area to let
if (mSize.height == 0) mSize.height = 1; // cairo_os2_surface_create() return something
cairo_surface_t *surf = cairo_os2_surface_create(mPS, mSize.width, mSize.height);
#ifdef DEBUG_thebes_2
- printf(" type(%#x)=%d (own=%d, ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
- cairo_surface_get_type(surf), mOwnsPS, (unsigned int)mPS, mSize.width, mSize.height);
+ printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf,
+ cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height);
#endif
- cairo_os2_surface_set_hwnd(surf, aWnd); // XXX is this needed here??
+ // record the window handle in the cairo surface, so that refresh works
+ cairo_os2_surface_set_hwnd(surf, aWnd);
// XXX for now uncomment the mark_dirty function, see bug 371505
//cairo_surface_mark_dirty(surf);
Init(surf);
}
gfxOS2Surface::~gfxOS2Surface()
{
#ifdef DEBUG_thebes_2
printf("gfxOS2Surface[%#x]::~gfxOS2Surface()\n", (unsigned int)this);
#endif
- if (mOwnsPS)
- WinReleasePS(mPS);
+ // Surfaces connected to a window were created using WinGetPS so we should
+ // release it again with WinReleasePS. Memory surfaces on the other
+ // hand were created on memory device contexts with the GPI functions, so
+ // use those to clean up stuff.
+ if (mHasWnd) {
+ if (mOwnsPS && mPS) {
+ WinReleasePS(mPS);
+ }
+ } else {
+ if (mBitmap) {
+ GpiSetBitmap(mPS, NULL);
+ GpiDeleteBitmap(mBitmap);
+ }
+ if (mOwnsPS && mPS) {
+ GpiDestroyPS(mPS);
+ }
+ if (mDC) {
+ DevCloseDC(mDC);
+ }
+ }
}