adding windows gfxPlatform support

This commit is contained in:
pavlov%pavlov.net 2006-02-01 02:35:38 +00:00
parent bcf3cb7d0d
commit 07cb0c3299
15 changed files with 245 additions and 133 deletions

View File

@ -41,9 +41,7 @@
#include "nsMemory.h"
#if defined(MOZ_ENABLE_GTK2)
#include "gfxPlatform.h"
#endif
#include "gfxImageSurface.h"
@ -51,13 +49,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "gfxXlibSurface.h"
# ifdef MOZ_ENABLE_GLITZ
# include "gfxGlitzSurface.h"
# include "glitz-glx.h"
# endif
#elif XP_WIN
#include "gfxWindowsSurface.h"
#endif
#include <stdlib.h>
@ -65,9 +57,6 @@ NS_IMPL_ISUPPORTS1(nsThebesDrawingSurface, nsIDrawingSurface)
nsThebesDrawingSurface::nsThebesDrawingSurface()
{
#ifdef XP_WIN
mWidget = nsnull;
#endif
}
nsThebesDrawingSurface::~nsThebesDrawingSurface()
@ -87,7 +76,6 @@ nsThebesDrawingSurface::Init(nsThebesDeviceContext *aDC, gfxASurface *aSurface)
mWidth = 0;
mHeight = 0;
mNativeWidget = nsnull;
return NS_OK;
}
@ -102,30 +90,11 @@ nsThebesDrawingSurface::Init(nsThebesDeviceContext *aDC, PRUint32 aWidth, PRUint
mWidth = aWidth;
mHeight = aHeight;
mDC = aDC;
mNativeWidget = nsnull;
#if defined(MOZ_ENABLE_GTK2)
// XXX Performance Problem
// because we don't pass aDC->GetWidget() (a HWND on Windows) to this function,
// we get DIBs instead of DDBs.
mSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(aWidth, aHeight, gfxImageSurface::ImageFormatARGB32);
#elif XP_WIN
if (aFastAccess) {
mSurface = new gfxImageSurface(gfxImageSurface::ImageFormatARGB32, aWidth, aHeight);
} else {
// this may or may not be null. this is currently only called from a spot
// where this will be a hwnd
nsNativeWidget widget = aDC->GetWidget();
HDC dc = nsnull;
if (widget)
dc = GetDC((HWND)widget);
mSurface = new gfxWindowsSurface(dc, aWidth, aHeight);
if (widget)
ReleaseDC((HWND)widget, dc);
}
#else
#error Write me!
#endif
return NS_OK;
}

View File

@ -91,17 +91,12 @@ public:
/* utility functions */
gfxASurface *GetThebesSurface(void) { return mSurface; }
PRInt32 GetDepth() { /* XXX */ return 24; }
nsNativeWidget GetNativeWidget(void) { return mNativeWidget; }
nsresult PushFilter(const nsIntRect& aRect, PRBool aAreaIsOpaque, float aOpacity);
void PopFilter();
private:
nsRefPtr<gfxASurface> mSurface;
nsThebesDeviceContext *mDC;
nsNativeWidget mNativeWidget;
#ifdef XP_WIN
nsIWidget *mWidget;
#endif
PRUint32 mWidth, mHeight;
};

View File

@ -750,8 +750,6 @@ nsThebesRenderingContext::GetNativeGraphicData(GraphicDataType aType)
{
if (mWidget && mDrawingSurface == mLocalDrawingSurface)
return mWidget->GetNativeData(NS_NATIVE_WIDGET);
else if (mDrawingSurface != mLocalDrawingSurface)
return mDrawingSurface->GetNativeWidget();
}
if (aType == NATIVE_THEBES_CONTEXT)
return mThebes;

View File

@ -32,6 +32,7 @@ endif
ifeq ($(MOZ_GFX_TOOLKIT),windows)
EXPORTS += gfxWindowsFonts.h \
gfxWindowsPlatform.h \
gfxWindowsSurface.h
ifdef MOZ_ENABLE_GLITZ

View File

@ -71,8 +71,7 @@ public:
*/
virtual gfxASurface *CreateOffscreenSurface(PRUint32 width,
PRUint32 height,
gfxASurface::gfxImageFormat imageFormat,
PRBool fastPixelAccess = PR_FALSE) = 0;
gfxASurface::gfxImageFormat imageFormat) = 0;
/*
* Font bits

View File

@ -52,8 +52,7 @@ public:
gfxASurface *CreateOffscreenSurface(PRUint32 width,
PRUint32 height,
gfxASurface::gfxImageFormat imageFormat,
PRBool fastPixelAccess);
gfxASurface::gfxImageFormat imageFormat);
GdkDrawable *GetSurfaceGdkDrawable(gfxASurface *aSurf);

View File

@ -54,6 +54,7 @@ public:
cairo_font_face_t *CairoFontFace() { return mFontFace; }
cairo_scaled_font_t *CairoScaledFont() { return mScaledFont; }
void UpdateFonts(cairo_t *cr);
protected:
cairo_font_face_t *MakeCairoFontFace();

View File

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Foundation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@pavlov.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_WINDOWS_PLATFORM_H
#define GFX_WINDOWS_PLATFORM_H
#include "gfxPlatform.h"
class NS_EXPORT gfxWindowsPlatform : public gfxPlatform {
public:
gfxWindowsPlatform();
static gfxWindowsPlatform *GetPlatform() {
return (gfxWindowsPlatform*) gfxPlatform::GetPlatform();
}
gfxASurface *CreateOffscreenSurface(PRUint32 width,
PRUint32 height,
gfxASurface::gfxImageFormat imageFormat);
nsresult GetFontList(const nsACString& aLangGroup,
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts);
};
#endif /* GFX_WINDOWS_PLATFORM_H */

View File

@ -57,9 +57,6 @@ private:
HDC mDC;
HWND mWnd;
HBITMAP mOrigBitmap;
PRInt32 mWidth;
PRInt32 mHeight;
};
#endif /* GFX_WINDOWSSURFACE_H */

View File

@ -39,8 +39,9 @@ EXTRA_DSO_LDOPTS += \
ifeq ($(MOZ_GFX_TOOLKIT),windows)
CPPSRCS += gfxWindowsSurface.cpp \
gfxWindowsFonts.cpp \
CPPSRCS += gfxWindowsFonts.cpp \
gfxWindowsPlatform.cpp \
gfxWindowsSurface.cpp \
$(NULL)
_OS_LIBS = usp10

View File

@ -38,7 +38,7 @@
#include "gfxPlatform.h"
#if defined(XP_WIN)
//#include "gfxPlatformWindows.h"
#include "gfxWindowsPlatform.h"
#elif defined(XP_MACOSX)
#include "gfxPlatformMac.h"
#elif defined(MOZ_WIDGET_GTK2)
@ -57,8 +57,7 @@ gfxPlatform::GetPlatform()
{
if (!gPlatform) {
#if defined(XP_WIN)
// gPlatform = new gfxPlatformWindows;
return nsnull;
gPlatform = new gfxWindowsPlatform;
#elif defined(XP_MACOSX)
gPlatform = new gfxPlatformMac;
#elif defined(MOZ_WIDGET_GTK2)

View File

@ -71,84 +71,79 @@ gfxPlatformGtk::gfxPlatformGtk()
}
gfxASurface*
gfxPlatformGtk::CreateOffscreenSurface (PRUint32 width,
PRUint32 height,
gfxASurface::gfxImageFormat imageFormat,
PRBool fastPixelAccess)
gfxPlatformGtk::CreateOffscreenSurface(PRUint32 width,
PRUint32 height,
gfxASurface::gfxImageFormat imageFormat)
{
gfxASurface *newSurface = nsnull;
if (fastPixelAccess) {
newSurface = new gfxImageSurface(imageFormat, width, height);
int bpp, glitzf;
int bestbpp = gdk_visual_get_best_depth();
switch (imageFormat) {
case gfxASurface::ImageFormatARGB32:
bpp = 32;
glitzf = 0; // GLITZ_STANDARD_ARGB32;
break;
case gfxASurface::ImageFormatRGB24:
bpp = 24;
glitzf = 1; // GLITZ_STANDARD_RGB24;
break;
case gfxASurface::ImageFormatA8:
bpp = 8;
glitzf = 2; // GLITZ_STANDARD_A8;
case gfxASurface::ImageFormatA1:
bpp = 1;
glitzf = 3; // GLITZ_STANDARD_A1;
break;
default:
return nsnull;
}
if (bestbpp < bpp)
bpp = bestbpp;
if (!UseGlitz()) {
GdkPixmap *pixmap = ::gdk_pixmap_new(nsnull, width, height, bpp);
gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), gdk_rgb_get_colormap());
newSurface = new gfxXlibSurface(GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(pixmap)),
GDK_WINDOW_XWINDOW(GDK_DRAWABLE(pixmap)),
GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(GDK_DRAWABLE(pixmap))),
width, height);
// set up the surface to auto-unref the gdk pixmap when the surface
// is released
cairo_surface_set_user_data(newSurface->CairoSurface(),
&cairo_gdk_pixmap_key,
pixmap,
do_gdk_pixmap_unref);
} else {
int bpp, glitzf;
int bestbpp = gdk_visual_get_best_depth();
switch (imageFormat) {
case gfxASurface::ImageFormatARGB32:
bpp = 32;
glitzf = 0; // GLITZ_STANDARD_ARGB32;
break;
case gfxASurface::ImageFormatRGB24:
bpp = 24;
glitzf = 1; // GLITZ_STANDARD_RGB24;
break;
case gfxASurface::ImageFormatA8:
bpp = 8;
glitzf = 2; // GLITZ_STANDARD_A8;
case gfxASurface::ImageFormatA1:
bpp = 1;
glitzf = 3; // GLITZ_STANDARD_A1;
break;
default:
return nsnull;
}
if (bestbpp < bpp)
bpp = bestbpp;
if (!UseGlitz()) {
GdkPixmap *pixmap = ::gdk_pixmap_new(nsnull, width, height, bpp);
gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), gdk_rgb_get_colormap());
newSurface = new gfxXlibSurface(GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(pixmap)),
GDK_WINDOW_XWINDOW(GDK_DRAWABLE(pixmap)),
GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(GDK_DRAWABLE(pixmap))),
width, height);
// set up the surface to auto-unref the gdk pixmap when the surface
// is released
cairo_surface_set_user_data (newSurface->CairoSurface(),
&cairo_gdk_pixmap_key,
pixmap,
do_gdk_pixmap_unref);
} else {
#ifdef MOZ_ENABLE_GLITZ
glitz_drawable_format_t *gdformat = glitz_glx_find_pbuffer_format
(GDK_DISPLAY(),
gdk_x11_get_default_screen(),
0, NULL, 0);
glitz_drawable_format_t *gdformat = glitz_glx_find_pbuffer_format
(GDK_DISPLAY(),
gdk_x11_get_default_screen(),
0, NULL, 0);
glitz_drawable_t *gdraw =
glitz_glx_create_pbuffer_drawable (GDK_DISPLAY(),
DefaultScreen(GDK_DISPLAY()),
gdformat,
width,
height);
glitz_format_t *gformat =
glitz_find_standard_format (gdraw, (glitz_format_name_t) glitzf);
glitz_drawable_t *gdraw =
glitz_glx_create_pbuffer_drawable(GDK_DISPLAY(),
DefaultScreen(GDK_DISPLAY()),
gdformat,
width,
height);
glitz_format_t *gformat =
glitz_find_standard_format(gdraw, (glitz_format_name_t)glitzf);
glitz_surface_t *gsurf =
glitz_surface_create (gdraw,
gformat,
width,
height,
0,
NULL);
glitz_surface_t *gsurf =
glitz_surface_create(gdraw,
gformat,
width,
height,
0,
NULL);
glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
newSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE);
glitz_surface_attach(gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
newSurface = new gfxGlitzSurface(gdraw, gsurf, PR_TRUE);
#endif
}
}
return newSurface;
@ -173,10 +168,10 @@ void
gfxPlatformGtk::SetSurfaceGdkWindow(gfxASurface *aSurf,
GdkWindow *win)
{
cairo_surface_set_user_data (aSurf->CairoSurface(),
&cairo_gdk_window_key,
win,
nsnull);
cairo_surface_set_user_data(aSurf->CairoSurface(),
&cairo_gdk_window_key,
win,
nsnull);
}
// this is in nsFontConfigUtils.h

View File

@ -80,6 +80,17 @@ gfxWindowsFont::~gfxWindowsFont()
cairo_scaled_font_destroy(mScaledFont);
}
void
gfxWindowsFont::UpdateFonts(cairo_t *cr)
{
cairo_font_face_destroy(mFontFace);
cairo_scaled_font_destroy(mScaledFont);
mFontFace = MakeCairoFontFace();
NS_ASSERTION(mFontFace, "Failed to make font face");
mScaledFont = MakeCairoScaledFont(nsnull);
NS_ASSERTION(mScaledFont, "Failed to make scaled font");
}
cairo_font_face_t *
gfxWindowsFont::MakeCairoFontFace()
@ -96,8 +107,6 @@ gfxWindowsFont::MakeCairoFontFace()
cairo_scaled_font_t *
gfxWindowsFont::MakeCairoScaledFont(cairo_t *cr)
{
// cairo_win32_set_global_font_dc(mDC);
cairo_scaled_font_t *font = nsnull;
cairo_matrix_t sizeMatrix, ctm;
@ -352,6 +361,7 @@ TRY_AGAIN_SAME_SCRIPT:
SaveDC(aDC);
gfxWindowsFont *currentFont = static_cast<gfxWindowsFont*>(mGroup->mFonts[fontIndex]);
currentFont->UpdateFonts(cr);
fontFace = currentFont->CairoFontFace();
scaledFont = currentFont->CairoScaledFont();

View File

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Foundation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "gfxWindowsPlatform.h"
#include "gfxImageSurface.h"
#include "gfxWindowsSurface.h"
gfxWindowsPlatform::gfxWindowsPlatform()
{
}
gfxASurface*
gfxWindowsPlatform::CreateOffscreenSurface(PRUint32 width,
PRUint32 height,
gfxASurface::gfxImageFormat imageFormat)
{
return new gfxWindowsSurface(nsnull, width, height);
}
nsresult
gfxWindowsPlatform::GetFontList(const nsACString& aLangGroup,
const nsACString& aGenericFamily,
nsStringArray& aListOfFonts)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -53,9 +53,10 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, PRBool deleteDC) :
}
gfxWindowsSurface::gfxWindowsSurface(HDC dc, unsigned long width, unsigned long height) :
mOwnsDC(PR_TRUE), mWnd(nsnull), mWidth(width), mHeight(height)
mOwnsDC(PR_TRUE), mWnd(nsnull)
{
mDC = ::CreateCompatibleDC(dc);
// set the clip region on it so that cairo knows the surface
// dimensions
HRGN clipRegion = ::CreateRectRgn(0, 0, width, height);
@ -64,11 +65,36 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, unsigned long width, unsigned long
}
::DeleteObject(clipRegion);
// Creating with width or height of 0 will create a
// 1x1 monotone bitmap, which isn't what we want
HBITMAP tbits = ::CreateCompatibleBitmap(dc, PR_MAX(2, width), PR_MAX(2, height));
HBITMAP bmp = nsnull;
if (dc) {
// Create a DDB if we can -- this is faster.
mOrigBitmap = (HBITMAP)::SelectObject(mDC, tbits);
// Creating with width or height of 0 will create a
// 1x1 monotone bitmap, which isn't what we want
bmp = ::CreateCompatibleBitmap(dc, PR_MAX(2, width), PR_MAX(2, height));
} else {
// Otherwise, create a DIB -- this is slower.
BITMAPINFO bmpInfo;
unsigned char *bits = NULL;
/* initialize the bitmapinfoheader */
memset(&bmpInfo.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = width;
bmpInfo.bmiHeader.biHeight = -(long)height;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biCompression = BI_RGB;
/* create a DIBSection */
bmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
/* Flush GDI to make sure the DIBSection is actually created */
GdiFlush();
}
/* Select the bitmap in to the DC */
mOrigBitmap = (HBITMAP)::SelectObject(mDC, bmp);
Init(cairo_win32_surface_create(mDC));
}