diff --git a/gfx/cairo/libpixman/src/pixman-remap.h b/gfx/cairo/libpixman/src/pixman-remap.h index 5c2c2003a31..103de496ebc 100644 --- a/gfx/cairo/libpixman/src/pixman-remap.h +++ b/gfx/cairo/libpixman/src/pixman-remap.h @@ -1,9 +1,7 @@ #define pixman_add_trapezoids _cairo_pixman_add_trapezoids -#define INT_pixman_color_to_pixel _cairo_pixman_color_to_pixel #define pixman_color_to_pixel _cairo_pixman_color_to_pixel #define composeFunctions _cairo_pixman_compose_functions #define fbComposeSetupMMX _cairo_pixman_compose_setup_mmx -#define INT_pixman_composite _cairo_pixman_composite #define pixman_composite _cairo_pixman_composite #define fbCompositeCopyAreammx _cairo_pixman_composite_copy_area_mmx #define fbCompositeSolidMask_nx8888x0565Cmmx _cairo_pixman_composite_solid_mask_nx8888x0565Cmmx diff --git a/gfx/public/nsIRenderingContext.h b/gfx/public/nsIRenderingContext.h index 6ba0103e3e2..3ce59a9ee50 100644 --- a/gfx/public/nsIRenderingContext.h +++ b/gfx/public/nsIRenderingContext.h @@ -65,6 +65,10 @@ struct nsTextDimensions; struct nsBoundingMetrics; #endif +#ifdef MOZ_CAIRO_GFX +class gfxASurface; +#endif + /* gfx2 */ class imgIContainer; @@ -125,6 +129,16 @@ public: */ NS_IMETHOD Init(nsIDeviceContext* aContext, nsIDrawingSurface* aSurface) = 0; +#ifdef MOZ_CAIRO_GFX + /** + * Initialize the RenderingContext + * @param aContext the device context to use for the drawing. + * @param aThebesSurface the Thebes gfxASurface to which to draw + * @result The result of the initialization, NS_Ok if no errors + */ + NS_IMETHOD Init(nsIDeviceContext* aContext, gfxASurface* aThebesSurface) = 0; +#endif + /** * Reset the rendering context */ diff --git a/gfx/src/ps/nsRenderingContextPS.h b/gfx/src/ps/nsRenderingContextPS.h index 04af6db5174..e69de29bb2d 100644 --- a/gfx/src/ps/nsRenderingContextPS.h +++ b/gfx/src/ps/nsRenderingContextPS.h @@ -1,305 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** 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.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Roland Mainz - * - * Alternatively, the contents of this file may be used under the terms of - * either of 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 nsRenderingContextPS_h___ -#define nsRenderingContextPS_h___ - -#include "nsIRenderingContext.h" -#include "nsRenderingContextImpl.h" -#include "nsUnitConversion.h" -#include "nsFont.h" -#include "nsFontMetricsPS.h" -#include "nsPoint.h" -#include "nsString.h" -#include "nsCRT.h" -#include "nsTransform2D.h" -#include "nsIViewManager.h" -#include "nsIWidget.h" -#include "nsRect.h" -#include "nsDeviceContextPS.h" -#include "nsVoidArray.h" - -class nsPostScriptObj; -class PS_State; - -class nsRenderingContextPS : public nsRenderingContextImpl -{ -public: - nsRenderingContextPS(); - virtual ~nsRenderingContextPS(); - - NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW - - NS_DECL_ISUPPORTS - -public: - // nsIRenderingContext - NS_IMETHOD Init(nsIDeviceContext* aContext); - NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWidget) {return NS_ERROR_NOT_IMPLEMENTED;} - NS_IMETHOD Init(nsIDeviceContext* aContext, nsIDrawingSurface* aSurface) {return NS_ERROR_NOT_IMPLEMENTED;} - - NS_IMETHOD Reset(void); - - NS_IMETHOD GetDeviceContext(nsIDeviceContext *&aContext); - - NS_IMETHOD LockDrawingSurface(PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight, - void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes, - PRUint32 aFlags); - NS_IMETHOD UnlockDrawingSurface(void); - - NS_IMETHOD SelectOffScreenDrawingSurface(nsIDrawingSurface* aSurface); - NS_IMETHOD GetDrawingSurface(nsIDrawingSurface* *aSurface); - NS_IMETHOD GetHints(PRUint32& aResult); - - NS_IMETHOD PushState(void); - NS_IMETHOD PopState(void); - - NS_IMETHOD IsVisibleRect(const nsRect& aRect, PRBool &aClipState); - - NS_IMETHOD SetClipRect(const nsRect& aRect, nsClipCombine aCombine); - NS_IMETHOD GetClipRect(nsRect &aRect, PRBool &aClipState); - NS_IMETHOD SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine); - NS_IMETHOD CopyClipRegion(nsIRegion &aRegion); - NS_IMETHOD GetClipRegion(nsIRegion **aRegion); - - NS_IMETHOD SetLineStyle(nsLineStyle aLineStyle); - NS_IMETHOD GetLineStyle(nsLineStyle &aLineStyle); - - NS_IMETHOD SetColor(nscolor aColor); - NS_IMETHOD GetColor(nscolor &aColor) const; - - NS_IMETHOD SetFont(const nsFont& aFont, nsIAtom* aLangGroup); - NS_IMETHOD SetFont(nsIFontMetrics *aFontMetrics); - - NS_IMETHOD GetFontMetrics(nsIFontMetrics *&aFontMetrics); - - NS_IMETHOD Translate(nscoord aX, nscoord aY); - NS_IMETHOD Scale(float aSx, float aSy); - NS_IMETHOD GetCurrentTransform(nsTransform2D *&aTransform); - - NS_IMETHOD CreateDrawingSurface(const nsRect& aBounds, PRUint32 aSurfFlags, nsIDrawingSurface* &aSurface); - NS_IMETHOD DestroyDrawingSurface(nsIDrawingSurface* aDS); - - NS_IMETHOD DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1); - NS_IMETHOD DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints); - - NS_IMETHOD DrawRect(const nsRect& aRect); - NS_IMETHOD DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD FillRect(const nsRect& aRect); - NS_IMETHOD FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD InvertRect(const nsRect& aRect); - NS_IMETHOD InvertRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD DrawPolygon(const nsPoint aPoints[], PRInt32 aNumPoints); - NS_IMETHOD FillPolygon(const nsPoint aPoints[], PRInt32 aNumPoints); - - NS_IMETHOD DrawEllipse(const nsRect& aRect); - NS_IMETHOD DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - NS_IMETHOD FillEllipse(const nsRect& aRect); - NS_IMETHOD FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight); - - NS_IMETHOD DrawArc(const nsRect& aRect, - float aStartAngle, float aEndAngle); - NS_IMETHOD DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, - float aStartAngle, float aEndAngle); - NS_IMETHOD FillArc(const nsRect& aRect, - float aStartAngle, float aEndAngle); - NS_IMETHOD FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, - float aStartAngle, float aEndAngle); - - NS_IMETHOD GetWidth(char aC, nscoord& aWidth); - NS_IMETHOD GetWidth(PRUnichar aC, nscoord& aWidth, - PRInt32 *aFontID); - NS_IMETHOD GetWidth(const nsString& aString, nscoord& aWidth, - PRInt32 *aFontID); - NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth); - NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth); - NS_IMETHOD GetWidth(const PRUnichar* aString, PRUint32 aLength, - nscoord& aWidth, PRInt32 *aFontID); - - NS_IMETHOD DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing); - NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); - NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); -protected: - PRInt32 DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, nsFontPS* aFontPS, - const nscoord* aSpacing); - PRInt32 DrawString(const char *aString, PRUint32 aLength, - nscoord &aX, nscoord &aY, nsFontPS* aFontPS, - const nscoord* aSpacing); -public: - - NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions); - NS_IMETHOD GetTextDimensions(const PRUnichar *aString, PRUint32 aLength, - nsTextDimensions& aDimensions, PRInt32 *aFontID); - NS_IMETHOD GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID = nsnull); - NS_IMETHOD GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID = nsnull); - - /** - * Draw a portion of an image, scaling it to fit a specified rect. - * @param aImage The image to draw - * @param aSrcRect The rect (in twips) of the image to draw. - * [x,y] denotes the top left corner of the region. - * @param aDestRect The device context rect (in twips) that the image - * portion should occupy. [x,y] denotes the top left corner. - * [height,width] denotes the desired image size. - */ - NS_IMETHOD DrawImage(imgIContainer *aImage, - const nsRect & aSrcRect, const nsRect & aDestRect); - - /* - * Tiles an image over an area - * @param aImage Image to tile - * @param aXImageStart x location where the origin (0,0) of the image starts - * @param aYImageStart y location where the origin (0,0) of the image starts - * @param aTargetRect area to draw to - * - */ - NS_IMETHOD DrawTile(imgIContainer *aImage, - nscoord aXImageStart, nscoord aYImageStart, const nsRect *aTargetRect); - - NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, - const nsRect &aDestBounds, PRUint32 aCopyFlags); - - // Postscript utilities - /** --------------------------------------------------- - * Set the current postscript font - * @update 12/21/98 dwc - */ - void PostscriptFont(nscoord aHeight, PRUint8 aStyle, - PRUint8 aVariant, PRUint16 aWeight, PRUint8 decorations); - - inline nsPostScriptObj* GetPostScriptObj() { return mPSObj; }; - -#ifdef XP_WIN -// this define is here only so the postscript can be compiled -// and tested on the windows platform. - NS_IMETHOD GetWidth(const char *aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nscoord& aWidth, - PRInt32& aNumCharsFit, - PRInt32* aFontID = nsnull) {return NS_OK;} - - NS_IMETHOD GetWidth(const PRUnichar *aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nscoord& aWidth, - PRInt32& aNumCharsFit, - PRInt32* aFontID = nsnull) {return NS_OK;} - -#endif - - -#ifdef MOZ_MATHML - /** - * Returns metrics (in app units) of an 8-bit character string - */ - NS_IMETHOD GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); - - /** - * Returns metrics (in app units) of a Unicode character string - */ - NS_IMETHOD GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID = nsnull); -#endif /* MOZ_MATHML */ - - /** --------------------------------------------------- - * Output an encapsulated postscript file to the print job. See - * documentation in gfx/public/nsIRenderingContext.h. - * @update 3/6/2004 kherron - * @param aRect Rectangle in which to render the EPS - * @param aDataFile - data stored in a file - * @return NS_OK or a suitable error code. - */ - NS_IMETHOD RenderEPS(const nsRect& aRect, FILE *aDataFile); - -private: - nsresult CommonInit(void); - void PushClipState(void); - -protected: - nsCOMPtr mContext; - nsCOMPtr mFontMetrics; - nsLineStyle mCurrLineStyle; - PS_State *mStates; - nsVoidArray *mStateCache; - float mP2T; - nscolor mCurrentColor; - - //state management - PRUint8 *mGammaTable; - nsPostScriptObj *mPSObj; -}; - - -#endif /* !nsRenderingContextPS_h___ */ diff --git a/gfx/src/thebes/nsThebesDeviceContext.cpp b/gfx/src/thebes/nsThebesDeviceContext.cpp index 9a3b2450c4f..584a6b1fbd6 100644 --- a/gfx/src/thebes/nsThebesDeviceContext.cpp +++ b/gfx/src/thebes/nsThebesDeviceContext.cpp @@ -284,7 +284,7 @@ nsThebesDeviceContext::CreateRenderingContext(nsIWidget *aWidget, nsCOMPtr pContext; rv = CreateRenderingContextInstance(*getter_AddRefs(pContext)); if (NS_SUCCEEDED(rv)) { - rv = pContext->Init(this, aWidget); + rv = pContext->Init(this, aWidget->GetThebesSurface()); if (NS_SUCCEEDED(rv)) { aContext = pContext; NS_ADDREF(aContext); @@ -479,54 +479,10 @@ nsThebesDeviceContext::GetClientRect(nsRect &aRect) return rv; } -#if defined(MOZ_ENABLE_GLITZ) -void* -nsThebesDeviceContext::GetGlitzDrawableFormat() -{ - glitz_drawable_format_t* format = nsnull; -#ifdef MOZ_ENABLE_GTK2 - glitz_drawable_format_t templ; - memset(&templ, 0, sizeof(templ)); - templ.samples = 1; // change this to change FSAA? - - int defaultScreen = gdk_x11_get_default_screen(); - unsigned long mask = GLITZ_FORMAT_SAMPLES_MASK; - - format = glitz_glx_find_window_format (GDK_DISPLAY(), defaultScreen, mask, &templ, 0); -#endif - return format; -} -#endif - -#if defined(MOZ_ENABLE_GLITZ) && defined(MOZ_ENABLE_GTK2) -void* -nsThebesDeviceContext::GetDesiredVisual() -{ - Display* dpy = GDK_DISPLAY(); - int defaultScreen = gdk_x11_get_default_screen(); - glitz_drawable_format_t* format = (glitz_drawable_format_t*) GetGlitzDrawableFormat(); - if (format) { - XVisualInfo* vinfo = glitz_glx_get_visual_info_from_format(dpy, defaultScreen, format); - GdkScreen* screen = gdk_display_get_screen(gdk_x11_lookup_xdisplay(dpy), defaultScreen); - GdkVisual* vis = gdk_x11_screen_lookup_visual(screen, vinfo->visualid); - return vis; - } else { - // GL/GLX not available, force glitz off - nsThebesDrawingSurface::mGlitzMode = 0; - } - - return nsnull; -} -#endif - NS_IMETHODIMP nsThebesDeviceContext::PrepareNativeWidget(nsIWidget* aWidget, void** aOut) { -#if defined(MOZ_ENABLE_GLITZ) && defined(MOZ_ENABLE_GTK2) - *aOut = GetDesiredVisual(); -#else *aOut = nsnull; -#endif return NS_OK; } diff --git a/gfx/src/thebes/nsThebesDeviceContext.h b/gfx/src/thebes/nsThebesDeviceContext.h index 01d5e10081b..fd2b71b744d 100644 --- a/gfx/src/thebes/nsThebesDeviceContext.h +++ b/gfx/src/thebes/nsThebesDeviceContext.h @@ -90,14 +90,6 @@ public: NS_IMETHOD GetRect(nsRect &aRect); NS_IMETHOD GetClientRect(nsRect &aRect); -#ifdef MOZ_ENABLE_GLITZ - /* glitz_drawable_format_t */ void* GetGlitzDrawableFormat(); - -#ifdef MOZ_ENABLE_GTK2 - /* GdkVisual */ void* GetDesiredVisual(); -#endif -#endif - /* printing goop */ NS_IMETHOD GetDeviceContextFor(nsIDeviceContextSpec *aDevice, nsIDeviceContext *&aContext); diff --git a/gfx/src/thebes/nsThebesDrawingSurface.cpp b/gfx/src/thebes/nsThebesDrawingSurface.cpp index 6eb675836d0..376b00c4a25 100644 --- a/gfx/src/thebes/nsThebesDrawingSurface.cpp +++ b/gfx/src/thebes/nsThebesDrawingSurface.cpp @@ -41,6 +41,8 @@ #include "nsMemory.h" +#include "gfxPlatform.h" + #include "gfxImageSurface.h" #ifdef MOZ_ENABLE_GTK2 @@ -77,16 +79,22 @@ nsThebesDrawingSurface::~nsThebesDrawingSurface() } #ifdef MOZ_ENABLE_GTK2 -static cairo_user_data_key_t cairo_gtk_pixmap_unref_key; -static void do_gtk_pixmap_unref (void *data) -{ - GdkPixmap *pmap = (GdkPixmap*)data; - guint rc = ((GObject*)pmap)->ref_count; - //fprintf (stderr, "do_gtk_pixmap_unref: %p refcnt %d\n", pmap, rc); - gdk_pixmap_unref (pmap); -} #endif +nsresult +nsThebesDrawingSurface::Init(nsThebesDeviceContext *aDC, gfxASurface *aSurface) +{ + mDC = aDC; + mSurface = aSurface; + + // don't know + mWidth = 0; + mHeight = 0; + + mNativeWidget = nsnull; + return NS_OK; +} + nsresult nsThebesDrawingSurface::Init(nsThebesDeviceContext *aDC, PRUint32 aWidth, PRUint32 aHeight, PRBool aFastAccess) { @@ -101,54 +109,7 @@ nsThebesDrawingSurface::Init(nsThebesDeviceContext *aDC, PRUint32 aWidth, PRUint mNativeWidget = nsnull; #if defined(MOZ_ENABLE_GTK2) - if (aFastAccess) { - //fprintf (stderr, "## nsThebesDrawingSurface::Init gfxImageSurface %d %d\n", aWidth, aHeight); - mSurface = new gfxImageSurface(gfxImageSurface::ImageFormatARGB32, aWidth, aHeight); - } else { - if (!UseGlitz()) { - mNativeWidget = ::gdk_pixmap_new(nsnull, mWidth, mHeight, 24); - { - guint rc = ((GObject*)mNativeWidget)->ref_count; - //fprintf (stderr, "do_gtk_pixmap_new: %p refcnt %d\n", mNativeWidget, rc); - } - gdk_drawable_set_colormap(GDK_DRAWABLE(mNativeWidget), gdk_rgb_get_colormap()); - - mSurface = new gfxXlibSurface(GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(mNativeWidget)), - GDK_WINDOW_XWINDOW(GDK_DRAWABLE(mNativeWidget)), - GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(GDK_DRAWABLE(mNativeWidget)))); - - // we need some thebes wrappers for surface destructor hooks - cairo_surface_set_user_data (mSurface->CairoSurface(), - &cairo_gtk_pixmap_unref_key, - mNativeWidget, - do_gtk_pixmap_unref); - - //mSurface = new gfxXlibSurface(GDK_DISPLAY(), GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()), aWidth, aHeight); - } else { -# if defined(MOZ_ENABLE_GLITZ) - glitz_drawable_format_t *gdformat = (glitz_drawable_format_t*) aDC->GetGlitzDrawableFormat(); - glitz_drawable_t *gdraw = - glitz_glx_create_pbuffer_drawable (GDK_DISPLAY(), - DefaultScreen(GDK_DISPLAY()), - gdformat, - aWidth, - aHeight); - glitz_format_t *gformat = - glitz_find_standard_format (gdraw, GLITZ_STANDARD_ARGB32); - glitz_surface_t *gsurf = - glitz_surface_create (gdraw, - gformat, - aWidth, - aHeight, - 0, - NULL); - glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR); - - //fprintf (stderr, "## nsThebesDrawingSurface::Init Glitz PBUFFER %d %d\n", aWidth, aHeight); - mSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE); -# endif - } - } + mSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(aWidth, aHeight, gfxImageSurface::ImageFormatARGB32); #elif XP_WIN if (aFastAccess) { mSurface = new gfxImageSurface(gfxImageSurface::ImageFormatARGB32, aWidth, aHeight); @@ -201,58 +162,7 @@ nsThebesDrawingSurface::Init (nsThebesDeviceContext *aDC, nsNativeWidget aWidget mHeight = 0; #ifdef MOZ_ENABLE_GTK2 - NS_ASSERTION (GDK_IS_WINDOW(aWidget), "unsupported native widget type!"); - - if (!UseGlitz()) { - mSurface = new gfxXlibSurface(GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(aWidget)), - GDK_WINDOW_XWINDOW(GDK_DRAWABLE(aWidget)), - GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(GDK_DRAWABLE(aWidget)))); - } else { -# if defined(MOZ_ENABLE_GLITZ) - glitz_surface_t *gsurf; - glitz_drawable_t *gdraw; - - glitz_drawable_format_t *gdformat = (glitz_drawable_format_t*) aDC->GetGlitzDrawableFormat(); - - Display* dpy = GDK_WINDOW_XDISPLAY(GDK_DRAWABLE(aWidget)); - Window wnd = GDK_WINDOW_XWINDOW(GDK_DRAWABLE(aWidget)); - - Window root_ignore; - int x_ignore, y_ignore; - unsigned int bwidth_ignore, width, height, depth; - - XGetGeometry(dpy, - wnd, - &root_ignore, &x_ignore, &y_ignore, - &width, &height, - &bwidth_ignore, &depth); - - gdraw = - glitz_glx_create_drawable_for_window (dpy, - DefaultScreen(dpy), - gdformat, - wnd, - width, - height); - glitz_format_t *gformat = - glitz_find_standard_format (gdraw, GLITZ_STANDARD_ARGB32); - gsurf = - glitz_surface_create (gdraw, - gformat, - width, - height, - 0, - NULL); - glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR); - - - //fprintf (stderr, "## nsThebesDrawingSurface::Init Glitz DRAWABLE %p (DC: %p)\n", aWidget, aDC); - mSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE); - - mWidth = width; - mHeight = height; -# endif - } + NS_ERROR("Should never be called."); #elif XP_WIN HDC nativeDC = (HDC)aWidget; mSurface = new gfxWindowsSurface(nativeDC); @@ -329,6 +239,8 @@ nsThebesDrawingSurface::Unlock (void) NS_IMETHODIMP nsThebesDrawingSurface::GetDimensions (PRUint32 *aWidth, PRUint32 *aHeight) { + if (mWidth == 0 && mHeight == 0) + NS_ERROR("nsThebesDrawingSurface::GetDimensions on a surface for which we don't know width/height!"); *aWidth = mWidth; *aHeight = mHeight; return NS_OK; diff --git a/gfx/src/thebes/nsThebesDrawingSurface.h b/gfx/src/thebes/nsThebesDrawingSurface.h index adc9ae6e348..f84ef6fdbfc 100644 --- a/gfx/src/thebes/nsThebesDrawingSurface.h +++ b/gfx/src/thebes/nsThebesDrawingSurface.h @@ -60,6 +60,9 @@ public: // a fast server pixmap nsresult Init (nsThebesDeviceContext *aDC, PRUint32 aWidth, PRUint32 aHeight, PRBool aFastAccess); + // wrap a gfxASurface with a nsThebesDrawingSurface + nsresult Init (nsThebesDeviceContext *aDC, gfxASurface *aSurface); + // create a fast drawing surface for a native widget nsresult Init (nsThebesDeviceContext *aDC, nsIWidget *aWidget); diff --git a/gfx/src/thebes/nsThebesFontMetrics.cpp b/gfx/src/thebes/nsThebesFontMetrics.cpp index 01e6b78f7d9..1d0e0b24661 100644 --- a/gfx/src/thebes/nsThebesFontMetrics.cpp +++ b/gfx/src/thebes/nsThebesFontMetrics.cpp @@ -281,7 +281,9 @@ nsThebesFontMetrics::GetWidth(const PRUnichar* aString, PRUint32 aLength, nscoord& aWidth, PRInt32 *aFontID, nsThebesRenderingContext *aContext) { - aWidth = ROUND_TO_TWIPS(mFontGroup->MeasureText(aContext->Thebes(), nsDependentSubstring(aString, aString+aLength))); + nsRefPtr textrun = mFontGroup->MakeTextRun(nsDependentSubstring(aString, aString+aLength)); + + aWidth = ROUND_TO_TWIPS(textrun->MeasureString(aContext->Thebes())); return NS_OK; @@ -345,7 +347,9 @@ nsThebesFontMetrics::DrawString(const PRUnichar* aString, PRUint32 aLength, { float app2dev = mDeviceContext->AppUnitsToDevUnits(); - mFontGroup->DrawString(aContext->Thebes(), nsDependentSubstring(aString, aString+aLength), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev))); + nsRefPtr textrun = mFontGroup->MakeTextRun(nsDependentSubstring(aString, aString+aLength)); + + textrun->DrawString(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev))); return NS_OK; } diff --git a/gfx/src/thebes/nsThebesImage.cpp b/gfx/src/thebes/nsThebesImage.cpp index de07762a73c..5e3324f20ad 100644 --- a/gfx/src/thebes/nsThebesImage.cpp +++ b/gfx/src/thebes/nsThebesImage.cpp @@ -215,7 +215,9 @@ nsThebesImage::Optimize(nsIDeviceContext* aContext) # ifdef MOZ_ENABLE_GLITZ // glitz nsThebesDeviceContext *tdc = NS_STATIC_CAST(nsThebesDeviceContext*, aContext); - glitz_drawable_format_t *gdf = (glitz_drawable_format_t*) tdc->GetGlitzDrawableFormat(); + glitz_drawable_format_t *gdf = 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()), gdf, diff --git a/gfx/src/thebes/nsThebesRenderingContext.cpp b/gfx/src/thebes/nsThebesRenderingContext.cpp index fd25d2bf4c5..66c2ee9adc7 100644 --- a/gfx/src/thebes/nsThebesRenderingContext.cpp +++ b/gfx/src/thebes/nsThebesRenderingContext.cpp @@ -90,10 +90,28 @@ nsThebesRenderingContext::~nsThebesRenderingContext() ////////////////////////////////////////////////////////////////////// //// nsIRenderingContext +NS_IMETHODIMP +nsThebesRenderingContext::Init(nsIDeviceContext* aContext, gfxASurface *aThebesSurface) +{ + PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsTRC::Init ctx %p thebesSurface %p\n", this, aContext, aThebesSurface)); + + nsThebesDeviceContext *thebesDC = NS_STATIC_CAST(nsThebesDeviceContext*, aContext); + + mDeviceContext = aContext; + mWidget = nsnull; + + mLocalDrawingSurface = new nsThebesDrawingSurface(); + mLocalDrawingSurface->Init(thebesDC, aThebesSurface); + mDrawingSurface = mLocalDrawingSurface; + + mThebes = new gfxContext(aThebesSurface); + + return (CommonInit()); +} + NS_IMETHODIMP nsThebesRenderingContext::Init(nsIDeviceContext* aContext, nsIWidget *aWidget) { - PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsTRC::Init ctx %p widget %p\n", this, aContext, aWidget)); nsThebesDeviceContext *thebesDC = NS_STATIC_CAST(nsThebesDeviceContext*, aContext); diff --git a/gfx/src/thebes/nsThebesRenderingContext.h b/gfx/src/thebes/nsThebesRenderingContext.h index 165d8406276..699e4f5a302 100644 --- a/gfx/src/thebes/nsThebesRenderingContext.h +++ b/gfx/src/thebes/nsThebesRenderingContext.h @@ -69,6 +69,8 @@ public: NS_DECL_ISUPPORTS + NS_IMETHOD Init(nsIDeviceContext* aContext, gfxASurface* aThebesSurface); + NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWidget); NS_IMETHOD Init(nsIDeviceContext* aContext, nsIDrawingSurface *aSurface); NS_IMETHOD CommonInit(void); diff --git a/gfx/thebes/public/Makefile.in b/gfx/thebes/public/Makefile.in index 3f150933438..0efafd3e789 100644 --- a/gfx/thebes/public/Makefile.in +++ b/gfx/thebes/public/Makefile.in @@ -18,10 +18,10 @@ EXPORTS = gfxASurface.h \ gfxImageSurface.h \ gfxMatrix.h \ gfxPattern.h \ + gfxPlatform.h \ gfxPoint.h \ gfxRect.h \ gfxRegion.h \ - gfxTextRun.h \ gfxTypes.h \ $(NULL) @@ -40,7 +40,7 @@ endif endif ifeq ($(MOZ_GFX_TOOLKIT),gtk2) -EXPORTS += gfxXlibSurface.h gfxPangoFonts.h +EXPORTS += gfxXlibSurface.h gfxPangoFonts.h gfxPlatformGtk.h ifdef MOZ_ENABLE_GLITZ REQUIRES += glitzglx diff --git a/gfx/thebes/public/gfxASurface.h b/gfx/thebes/public/gfxASurface.h index 4f3c660e8c2..3876b963eea 100644 --- a/gfx/thebes/public/gfxASurface.h +++ b/gfx/thebes/public/gfxASurface.h @@ -65,6 +65,11 @@ public: /*** this DOES NOT addref the surface */ cairo_surface_t* CairoSurface() { return mSurface; } + void SetDeviceOffset (gfxFloat xOff, gfxFloat yOff) { + cairo_surface_set_device_offset(mSurface, + xOff, yOff); + } + void Flush() { cairo_surface_flush(mSurface); } void MarkDirty() { cairo_surface_mark_dirty(mSurface); } void MarkDirty(const gfxRect& r) { diff --git a/gfx/thebes/public/gfxContext.h b/gfx/thebes/public/gfxContext.h index befbef7189f..76236df201c 100644 --- a/gfx/thebes/public/gfxContext.h +++ b/gfx/thebes/public/gfxContext.h @@ -190,17 +190,14 @@ public: /** * Add the text outline to the current path. */ - void AddStringToPath(gfxTextRun& text, int pos, int len); + // specify this in a sane way. + //void AddStringToPath(gfxTextRun& text); /** - * Draw a substring of the text run at the current point. + * Draw the text run at the current point. + * XXX support drawing subsections of the text run */ - void DrawText(gfxTextRun& text, int pos, int len); - - /** - * Draw the string at some point (XXX need docs) - */ - void DrawText(const nsAString& aString, gfxPoint pt, gfxFontGroup &aFontGroup); + void DrawText(gfxTextRun& text); /** ** Transformation Matrix manipulation diff --git a/gfx/thebes/public/gfxFont.h b/gfx/thebes/public/gfxFont.h index 0b0647db1e4..925a9223fd8 100644 --- a/gfx/thebes/public/gfxFont.h +++ b/gfx/thebes/public/gfxFont.h @@ -45,6 +45,7 @@ #include class gfxContext; +class gfxTextRun; #define FONT_STYLE_NORMAL 0 #define FONT_STYLE_ITALIC 1 @@ -147,6 +148,8 @@ protected: const gfxFontStyle *mStyle; }; +typedef std::vector gfxFontVector; + class NS_EXPORT gfxFontGroup { public: gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle) @@ -158,13 +161,10 @@ public: delete *it; } - std::vector &GetFontList() { return mFonts; } // XXX this should really be const.. + gfxFontVector &GetFontList() { return mFonts; } // XXX this should really be const.. const gfxFontStyle *GetStyle() const { return &mStyle; } - virtual void DrawString(gfxContext *aContext, const nsAString& aString, gfxPoint pt) = 0; - virtual gfxFloat MeasureText(gfxContext *aContext, const nsAString& aString) = 0; // returns length in pixels - // need something here for "text dimensions" similar to what we had before - // XXX need to handle spacing... + virtual gfxTextRun *MakeTextRun(const nsAString& aString) = 0; protected: /* data gets passed in to the font when it is created */ @@ -174,7 +174,6 @@ protected: PRBool FillFontArray(); nsString mFamilies; gfxFontStyle mStyle; - typedef std::vector gfxFontVector; gfxFontVector mFonts; PRBool mIsRTL; @@ -183,5 +182,16 @@ protected: }; +// these do not copy the text +class NS_EXPORT gfxTextRun { + THEBES_DECL_REFCOUNTING_ABSTRACT + +public: + virtual void DrawString(gfxContext *aContext, + gfxPoint pt) = 0; + + // returns length in pixels + virtual gfxFloat MeasureString(gfxContext *aContext) = 0; +}; #endif diff --git a/gfx/thebes/public/gfxPangoFonts.h b/gfx/thebes/public/gfxPangoFonts.h index 0fb021e9fc9..0db6f1bddd4 100644 --- a/gfx/thebes/public/gfxPangoFonts.h +++ b/gfx/thebes/public/gfxPangoFonts.h @@ -51,11 +51,8 @@ public: virtual const gfxFont::Metrics& GetMetrics(); - // private, but for use by gfxPangoFontGroup - void UpdateContext(gfxContext *ctx); - PangoContext *GetContext() { RealizeFont(); return mPangoCtx; } - void GetSize(const char *aString, PRUint32 aLength, gfxSize& inkSize, gfxSize& logSize); - void DrawString(gfxContext *ctx, const char *aString, PRUint32 aLength, gfxPoint pt); + PangoFontDescription* GetPangoFontDescription() { RealizeFont(); return mPangoFontDesc; } + PangoContext* GetPangoContext() { RealizeFont(); return mPangoCtx; } protected: nsString mName; @@ -69,6 +66,7 @@ protected: Metrics mMetrics; void RealizeFont(PRBool force = PR_FALSE); + void GetSize(const char *aString, PRUint32 aLength, gfxSize& inkSize, gfxSize& logSize); }; class NS_EXPORT gfxPangoFontGroup : public gfxFontGroup { @@ -77,15 +75,29 @@ public: const gfxFontStyle *aStyle); virtual ~gfxPangoFontGroup (); - virtual void DrawString (gfxContext *aContext, - const nsAString& aString, - gfxPoint pt); - - virtual gfxFloat MeasureText (gfxContext *aContext, - const nsAString& aString); + virtual gfxTextRun *MakeTextRun(const nsAString& aString); protected: virtual gfxFont* MakeFont(const nsAString& aName); }; +class NS_EXPORT gfxPangoTextRun : public gfxTextRun { + THEBES_DECL_ISUPPORTS_INHERITED +public: + gfxPangoTextRun(const nsAString& aString, gfxPangoFontGroup *aFontGroup); + ~gfxPangoTextRun(); + + virtual void DrawString(gfxContext *aContext, gfxPoint pt); + virtual gfxFloat MeasureString(gfxContext *aContext); + +private: + nsString mString; + gfxPangoFontGroup *mGroup; + + PangoLayout *mPangoLayout; + int mWidth, mHeight; + + void EnsurePangoLayout(gfxContext *aContext = nsnull); +}; + #endif /* GFX_PANGOFONTS_H */ diff --git a/gfx/thebes/public/gfxWindowsFonts.h b/gfx/thebes/public/gfxWindowsFonts.h index 2ff81782e1c..9b46655963e 100644 --- a/gfx/thebes/public/gfxWindowsFonts.h +++ b/gfx/thebes/public/gfxWindowsFonts.h @@ -78,18 +78,37 @@ class NS_EXPORT gfxWindowsFontGroup : public gfxFontGroup { public: gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFontStyle* aStyle, HWND hwnd); virtual ~gfxWindowsFontGroup(); - void DrawString(gfxContext *aContext, const nsAString& aString, gfxPoint pt); - gfxFloat MeasureText(gfxContext *aContext, const nsAString& aString); + + virtual gfxTextRun *MakeTextRun(const nsAString& aString); protected: virtual gfxFont *MakeFont(const nsAString& aName); +private: + HWND mWnd; + + friend class gfxWindowsTextRun; +}; + + +class NS_EXPORT gfxWindowsTextRun : public gfxTextRun { + THEBES_DECL_ISUPPORTS_INHERITED + +public: + gfxWindowsTextRun(const nsAString& aString, gfxWindowsFontGroup *aFontGroup); + ~gfxWindowsTextRun(); + + virtual void DrawString(gfxContext *aContext, gfxPoint pt); + virtual gfxFloat MeasureString(gfxContext *aContext); + private: PRInt32 MeasureOrDrawUniscribe(gfxContext *aContext, const PRUnichar *aString, PRUint32 aLength, PRBool aDraw, PRInt32 aX, PRInt32 aY, const PRInt32 *aSpacing); - HWND mWnd; + + nsString mString; + gfxWindowsFontGroup *mGroup; }; #endif /* GFX_WINDOWSFONTS_H */ diff --git a/gfx/thebes/src/Makefile.in b/gfx/thebes/src/Makefile.in index db6725d5e3f..80238a26817 100644 --- a/gfx/thebes/src/Makefile.in +++ b/gfx/thebes/src/Makefile.in @@ -23,6 +23,7 @@ CPPSRCS = \ gfxImageSurface.cpp \ gfxPattern.cpp \ gfxFont.cpp \ + gfxPlatform.cpp \ $(NULL) @@ -47,7 +48,7 @@ OS_LIBS += $(call EXPAND_LIBNAME,$(_OS_LIBS)) endif ifeq ($(MOZ_GFX_TOOLKIT),gtk2) -CPPSRCS += gfxXlibSurface.cpp gfxPangoFonts.cpp +CPPSRCS += gfxXlibSurface.cpp gfxPangoFonts.cpp gfxPlatformGtk.cpp EXTRA_DSO_LDOPTS += $(MOZ_PANGO_LIBS) endif @@ -62,9 +63,14 @@ REQUIRES += glitzglx SHARED_LIBRARY_LIBS += $(DIST)/lib/$(LIB_PREFIX)mozglitzglx.$(LIB_SUFFIX) endif endif + +EXTRA_DSO_LDOPTS += $(TK_LIBS) + + include $(topsrcdir)/config/rules.mk -CXXFLAGS += $(MOZ_CAIRO_CFLAGS) + +CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS) ifeq ($(MOZ_GFX_TOOLKIT),gtk2) CXXFLAGS += $(MOZ_PANGO_CFLAGS) diff --git a/gfx/thebes/src/gfxContext.cpp b/gfx/thebes/src/gfxContext.cpp index 57db3623b2d..054b9ce97f1 100644 --- a/gfx/thebes/src/gfxContext.cpp +++ b/gfx/thebes/src/gfxContext.cpp @@ -487,16 +487,11 @@ void gfxContext::Mask(gfxASurface *surface, gfxPoint offset) } // fonts? -void gfxContext::DrawText(gfxTextRun& text, int pos, int len) +void gfxContext::DrawText(gfxTextRun& text) { } -void gfxContext::DrawText(const nsAString& aString, gfxPoint pt, gfxFontGroup &aFontGroup) -{ - // aFontGroup.DrawText(aString, pt); -} - void gfxContext::Paint(gfxFloat alpha) { cairo_paint_with_alpha(mCairo, alpha); diff --git a/gfx/thebes/src/gfxPangoFonts.cpp b/gfx/thebes/src/gfxPangoFonts.cpp index 6b4bc7f7ce3..c4bb5ee6ff4 100644 --- a/gfx/thebes/src/gfxPangoFonts.cpp +++ b/gfx/thebes/src/gfxPangoFonts.cpp @@ -47,6 +47,10 @@ static PangoLanguage *GetPangoLanguage(const nsACString& aLangGroup); +/** + ** gfxPangoFont + **/ + gfxPangoFont::gfxPangoFont(const nsAString &aName, const gfxFontGroup *aFontGroup) : mName(aName), mFontGroup(aFontGroup) { @@ -158,13 +162,6 @@ gfxPangoFont::RealizeFont(PRBool force) mHasMetrics = PR_FALSE; } -void -gfxPangoFont::UpdateContext(gfxContext *ctx) -{ - RealizeFont(); - pango_cairo_update_context (ctx->GetCairo(), mPangoCtx); -} - void gfxPangoFont::GetSize(const char *aCharString, PRUint32 aLength, gfxSize& inkSize, gfxSize& logSize) { @@ -196,35 +193,6 @@ gfxPangoFont::GetSize(const char *aCharString, PRUint32 aLength, gfxSize& inkSiz g_list_free(items); } -void -gfxPangoFont::DrawString(gfxContext *ctx, const char *aString, PRUint32 aLength, gfxPoint pt) -{ - //fprintf (stderr, "DrawString: '%s'\n", aString); - gfxMatrix mat = ctx->CurrentMatrix(); - - PangoLayout *layout = pango_layout_new (mPangoCtx); - pango_layout_set_text (layout, aString, aLength); - - if (pango_layout_get_line_count(layout) == 1) { - // we draw only the first layout line, because - // we can then position by baseline (which is what pt is at); - // using show_layout expects top-left point. - ctx->MoveTo(pt); - UpdateContext(ctx); - PangoLayoutLine *line = pango_layout_get_line(layout, 0); - pango_cairo_show_layout_line (ctx->GetCairo(), line); - } else { - //printf("**** gfxPangoFonts: more than one line in layout!\n"); - // we really should never hit this - ctx->MoveTo(gfxPoint(pt.x, pt.y - mMetrics.height)); - UpdateContext(ctx); - pango_cairo_show_layout (ctx->GetCairo(), layout); - } - g_object_unref (layout); - - ctx->SetMatrix(mat); -} - const gfxFont::Metrics& gfxPangoFont::GetMetrics() { @@ -302,6 +270,10 @@ gfxPangoFont::GetMetrics() return mMetrics; } +/** + ** gfxPangoFontGroup + **/ + gfxPangoFontGroup::gfxPangoFontGroup (const nsAString& families, const gfxFontStyle *aStyle) : gfxFontGroup(families, aStyle) @@ -314,42 +286,92 @@ gfxPangoFontGroup::~gfxPangoFontGroup() { } -void -gfxPangoFontGroup::DrawString (gfxContext *aContext, - const nsAString& aString, - gfxPoint pt) -{ - gfxPangoFont *pf = ((gfxPangoFont*) mFonts[0]); - NS_ConvertUTF16toUTF8 u8str(aString); - pf->DrawString(aContext, u8str.Data(), u8str.Length(), pt); -} - -gfxFloat -gfxPangoFontGroup::MeasureText (gfxContext *aContext, - const nsAString& aString) -{ - gfxPangoFont *pf = ((gfxPangoFont*) mFonts[0]); - NS_ConvertUTF16toUTF8 u8str(aString); - int pw, ph; - - //fprintf (stderr, "SizeString: '%s'\n", u8str.Data()); - - pf->UpdateContext(aContext); - PangoLayout *layout = pango_layout_new (pf->GetContext()); - pango_layout_set_text (layout, u8str.Data(), u8str.Length()); - pango_layout_get_size(layout, &pw, &ph); - g_object_unref (layout); - - return pw/PANGO_SCALE; -} - gfxFont* gfxPangoFontGroup::MakeFont(const nsAString& aName) { return nsnull; } -/** language group helpers **/ +gfxTextRun* +gfxPangoFontGroup::MakeTextRun(const nsAString& aString) +{ + return new gfxPangoTextRun(aString, this); +} + + +/** + ** gfxPangoTextRun + **/ + +THEBES_IMPL_REFCOUNTING(gfxPangoTextRun) + +gfxPangoTextRun::gfxPangoTextRun(const nsAString& aString, gfxPangoFontGroup *aGroup) + : mString(aString), mGroup(aGroup), mPangoLayout(nsnull), mWidth(-1), mHeight(-1) +{ +} + +gfxPangoTextRun::~gfxPangoTextRun() +{ + if (mPangoLayout) { + g_object_unref (mPangoLayout); + mPangoLayout = nsnull; + } +} + +void +gfxPangoTextRun::EnsurePangoLayout(gfxContext *aContext) +{ + gfxPangoFont *pf = ((gfxPangoFont*) mGroup->GetFontList()[0]); + + if (mPangoLayout == nsnull) { + NS_ConvertUTF16toUTF8 u8str(mString); + + mPangoLayout = pango_layout_new (pf->GetPangoContext()); + pango_layout_set_text (mPangoLayout, u8str.Data(), u8str.Length()); + + if (pango_layout_get_line_count(mPangoLayout) != 1) { + NS_WARNING("gfxPangoFonts: more than one line in layout!\n"); + } + } + + if (aContext) { + pango_cairo_update_context (aContext->GetCairo(), pf->GetPangoContext()); + } +} + +void +gfxPangoTextRun::DrawString (gfxContext *aContext, gfxPoint pt) +{ + gfxMatrix mat = aContext->CurrentMatrix(); + + aContext->MoveTo(pt); + + // we draw only the first layout line, because + // we can then position by baseline (which is what pt is at); + // using show_layout expects top-left point. + EnsurePangoLayout(aContext); + PangoLayoutLine *line = pango_layout_get_line(mPangoLayout, 0); + pango_cairo_show_layout_line (aContext->GetCairo(), line); + + aContext->SetMatrix(mat); +} + +gfxFloat +gfxPangoTextRun::MeasureString (gfxContext *aContext) +{ + if (mWidth == -1) { + EnsurePangoLayout(aContext); + pango_layout_get_size (mPangoLayout, &mWidth, &mHeight); + } + + return mWidth/PANGO_SCALE; +} + + +/** + ** language group helpers + **/ + struct MozPangoLangGroup { const char *mozLangGroup; const char *PangoLang; diff --git a/gfx/thebes/src/gfxWindowsFonts.cpp b/gfx/thebes/src/gfxWindowsFonts.cpp index 8d25f1655eb..6127903ce05 100644 --- a/gfx/thebes/src/gfxWindowsFonts.cpp +++ b/gfx/thebes/src/gfxWindowsFonts.cpp @@ -253,23 +253,43 @@ gfxWindowsFontGroup::~gfxWindowsFontGroup() } -void -gfxWindowsFontGroup::DrawString(gfxContext *aContext, const nsAString& aString, gfxPoint pt) +gfxTextRun * +gfxWindowsFontGroup::MakeTextRun(const nsAString& aString) { - MeasureOrDrawUniscribe(aContext, PromiseFlatString(aString).get(), aString.Length(), PR_TRUE, pt.x, pt.y, nsnull); + return new gfxWindowsTextRun(aString, this); +} + + + + +THEBES_IMPL_REFCOUNTING(gfxWindowsTextRun) + +gfxWindowsTextRun::gfxWindowsTextRun(const nsAString& aString, gfxWindowsFontGroup *aFontGroup) + : mString(aString), mGroup(aFontGroup) +{ +} + +gfxWindowsTextRun::~gfxWindowsTextRun() +{ +} + +void +gfxWindowsTextRun::DrawString(gfxContext *aContext, gfxPoint pt) +{ + MeasureOrDrawUniscribe(aContext, mString.get(), mString.Length(), PR_TRUE, pt.x, pt.y, nsnull); } gfxFloat -gfxWindowsFontGroup::MeasureText(gfxContext *aContext, const nsAString& aString) +gfxWindowsTextRun::MeasureString(gfxContext *aContext) { - return MeasureOrDrawUniscribe(aContext, PromiseFlatString(aString).get(), aString.Length(), PR_FALSE, 0, 0, nsnull); + return MeasureOrDrawUniscribe(aContext, mString.get(), mString.Length(), PR_FALSE, 0, 0, nsnull); } PRInt32 -gfxWindowsFontGroup::MeasureOrDrawUniscribe(gfxContext *aContext, - const PRUnichar *aString, PRUint32 aLength, - PRBool aDraw, PRInt32 aX, PRInt32 aY, const PRInt32 *aSpacing) +gfxWindowsTextRun::MeasureOrDrawUniscribe(gfxContext *aContext, + const PRUnichar *aString, PRUint32 aLength, + PRBool aDraw, PRInt32 aX, PRInt32 aY, const PRInt32 *aSpacing) { HDC aDC = static_cast(aContext->CurrentSurface())->GetDC(); @@ -323,15 +343,15 @@ TRY_AGAIN_SAME_SCRIPT: loops++; SaveDC(aDC); - gfxWindowsFont *currentFont = static_cast(mFonts[fontIndex]); + gfxWindowsFont *currentFont = static_cast(mGroup->mFonts[fontIndex]); fontFace = currentFont->CairoFontFace(); scaledFont = currentFont->CairoScaledFont(); cairo_set_font_face(cr, fontFace); - cairo_set_font_size(cr, mStyle.size); + cairo_set_font_size(cr, mGroup->mStyle.size); cairo_win32_scaled_font_select_font(scaledFont, aDC); const double cairofontfactor = cairo_win32_scaled_font_get_metrics_factor(scaledFont); - const double cairoToPixels = cairofontfactor * mStyle.size; + const double cairoToPixels = cairofontfactor * mGroup->mStyle.size; if (!isComplex) items[i].a.eScript = SCRIPT_UNDEFINED; @@ -346,7 +366,7 @@ TRY_AGAIN_SAME_SCRIPT: } if (rv == USP_E_SCRIPT_NOT_IN_FONT) { - if (fontIndex < mFonts.size() - 1) { + if (fontIndex < mGroup->mFonts.size() - 1) { fontIndex++; cairo_win32_scaled_font_done_font(scaledFont); RestoreDC(aDC, -1); @@ -361,13 +381,14 @@ TRY_AGAIN_SAME_SCRIPT: } if (numGlyphs > 0 && glyphs[0] == 0) { - if (fontIndex < mFonts.size() - 1) { + if (fontIndex < mGroup->mFonts.size() - 1) { fontIndex++; cairo_win32_scaled_font_done_font(scaledFont); RestoreDC(aDC, -1); goto TRY_AGAIN_SAME_SCRIPT; } // otherwise we fail to draw the characters so give up and continue on. + printf("failed to render glyphs :(\n"); } if (rv == 0) { diff --git a/widget/public/nsIWidget.h b/widget/public/nsIWidget.h index 20a6831e641..94b0de8bd1d 100644 --- a/widget/public/nsIWidget.h +++ b/widget/public/nsIWidget.h @@ -66,6 +66,10 @@ class nsGUIEvent; struct nsColorMap; class imgIContainer; +#ifdef MOZ_CAIRO_GFX +class gfxASurface; +#endif + /** * Callback function that processes events. * The argument is actually a subtype (subclass) of nsEvent which carries @@ -851,6 +855,10 @@ class nsIWidget : public nsISupports { virtual nsIRenderingContext* GetRenderingContext() = 0; virtual nsIDeviceContext* GetDeviceContext() = 0; virtual nsIAppShell *GetAppShell() = 0; + +#ifdef MOZ_CAIRO_GFX + virtual gfxASurface *GetThebesSurface() = 0; +#endif //@} /** diff --git a/widget/src/gtk2/Makefile.in b/widget/src/gtk2/Makefile.in index 9ad6e274c1b..af1be4794f5 100644 --- a/widget/src/gtk2/Makefile.in +++ b/widget/src/gtk2/Makefile.in @@ -73,6 +73,10 @@ REQUIRES = xpcom \ ifeq ($(MOZ_ENABLE_CAIRO_GFX),1) REQUIRES += thebes cairo + +ifeq ($(MOZ_ENABLE_GLITZ),1) +REQUIRES += glitz glitzglx +endif endif CSRCS = \ diff --git a/widget/src/gtk2/nsNativeThemeGTK.cpp b/widget/src/gtk2/nsNativeThemeGTK.cpp index 3754790e5cc..0b407d9d88b 100644 --- a/widget/src/gtk2/nsNativeThemeGTK.cpp +++ b/widget/src/gtk2/nsNativeThemeGTK.cpp @@ -63,6 +63,7 @@ #ifdef MOZ_CAIRO_GFX #include "gfxContext.h" +#include "gfxPlatformGtk.h" #endif NS_IMPL_ISUPPORTS2(nsNativeThemeGTK, nsITheme, nsIObserver) @@ -490,7 +491,8 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext, aClipRect.width * t2p, aClipRect.height * t2p }; - GdkWindow *gdkwin = (GdkWindow*) aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_GDK_DRAWABLE); + + GdkWindow* gdkwin = (GdkWindow*) gfxPlatformGtk::GetPlatform()->GetSurfaceGdkDrawable(ctx->CurrentSurface()); GdkDrawable *target_drawable = nsnull; PRBool needs_thebes_composite = PR_FALSE; diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp index d09678a6277..cc1ae33fe87 100644 --- a/widget/src/gtk2/nsWindow.cpp +++ b/widget/src/gtk2/nsWindow.cpp @@ -95,6 +95,16 @@ static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility" #include "nsIInterfaceRequestorUtils.h" #include "nsAutoPtr.h" +#ifdef MOZ_CAIRO_GFX +#include "gfxPlatformGtk.h" +#include "gfxXlibSurface.h" + +#ifdef MOZ_ENABLE_GLITZ +#include "gfxGlitzSurface.h" +#include "glitz-glx.h" +#endif +#endif + /* For PrepareNativeWidget */ static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID); @@ -2308,14 +2318,29 @@ nsWindow::NativeCreate(nsIWidget *aParent, } GdkVisual* visual = nsnull; - if (!aContext) { - nsCOMPtr dc = do_CreateInstance(kDeviceContextCID); - // no parent widget to initialize with - dc->Init(nsnull); - dc->PrepareNativeWidget(this, (void**)&visual); - } else { - aContext->PrepareNativeWidget(this, (void**)&visual); +#ifdef MOZ_ENABLE_GLITZ + if (gfxPlatform::UseGlitz()) { + nsCOMPtr dc = aContext; + if (!dc) { + nsCOMPtr dc = do_CreateInstance(kDeviceContextCID); + // no parent widget to initialize with + dc->Init(nsnull); + } + + Display* dpy = GDK_DISPLAY(); + int defaultScreen = gdk_x11_get_default_screen(); + glitz_drawable_format_t* format = glitz_glx_find_window_format (dpy, defaultScreen, + 0, NULL, 0); + if (format) { + XVisualInfo* vinfo = glitz_glx_get_visual_info_from_format(dpy, defaultScreen, format); + GdkScreen* screen = gdk_display_get_screen(gdk_x11_lookup_xdisplay(dpy), defaultScreen); + visual = gdk_x11_screen_lookup_visual(screen, vinfo->visualid); + } else { + // couldn't find a GLX visual; force Glitz off + gfxPlatform::SetUseGlitz(PR_FALSE); + } } +#endif // ok, create our windows switch (mWindowType) { @@ -4808,3 +4833,75 @@ IM_get_input_context(MozDrawingarea *aArea) } #endif + +#ifdef MOZ_CAIRO_GFX +// return the gfxASurface for rendering to this widget +gfxASurface* +nsWindow::GetThebesSurface() +{ + // XXXvlad always create a new thebes surface for now, + // because the old clip doesn't get cleared otherwise. + // we should fix this at some point, and just reset + // the clip. + mThebesSurface = nsnull; + + if (!mThebesSurface) { + GdkDrawable* d = GDK_DRAWABLE(mDrawingarea->inner_window); + if (!gfxPlatform::UseGlitz()) { + mThebesSurface = new gfxXlibSurface + (GDK_WINDOW_XDISPLAY(d), + GDK_WINDOW_XWINDOW(d), + GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(d))); + gfxPlatformGtk::GetPlatform()->SetSurfaceGdkWindow(mThebesSurface, GDK_WINDOW(d)); + } else { +#ifdef MOZ_ENABLE_GLITZ + glitz_surface_t *gsurf; + glitz_drawable_t *gdraw; + + glitz_drawable_format_t *gdformat = glitz_glx_find_window_format (GDK_DISPLAY(), + gdk_x11_get_default_screen(), + 0, NULL, 0); + if (!gdformat) + NS_ERROR("Failed to find glitz drawable format"); + + Display* dpy = GDK_WINDOW_XDISPLAY(d); + Window wnd = GDK_WINDOW_XWINDOW(d); + + Window root_ignore; + int x_ignore, y_ignore; + unsigned int bwidth_ignore, width, height, depth; + + XGetGeometry(dpy, + wnd, + &root_ignore, &x_ignore, &y_ignore, + &width, &height, + &bwidth_ignore, &depth); + + gdraw = + glitz_glx_create_drawable_for_window (dpy, + DefaultScreen(dpy), + gdformat, + wnd, + width, + height); + glitz_format_t *gformat = + glitz_find_standard_format (gdraw, GLITZ_STANDARD_RGB24); + gsurf = + glitz_surface_create (gdraw, + gformat, + width, + height, + 0, + NULL); + glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR); + + + //fprintf (stderr, "## nsThebesDrawingSurface::Init Glitz DRAWABLE %p (DC: %p)\n", aWidget, aDC); + mThebesSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE); +#endif + } + } + + return mThebesSurface; +} +#endif diff --git a/widget/src/gtk2/nsWindow.h b/widget/src/gtk2/nsWindow.h index 1b04c9ccfe7..a0f90afb598 100644 --- a/widget/src/gtk2/nsWindow.h +++ b/widget/src/gtk2/nsWindow.h @@ -38,6 +38,8 @@ #ifndef __nsWindow_h__ +#include "nsAutoPtr.h" + #include "nsCommonWidget.h" #include "mozcontainer.h" @@ -285,6 +287,10 @@ public: NS_IMETHOD UpdateTranslucentWindowAlpha(const nsRect& aRect, PRUint8* aAlphas); #endif +#ifdef MOZ_CAIRO_GFX + gfxASurface *GetThebesSurface(); +#endif + private: void GetToplevelWidget(GtkWidget **aWidget); void GetContainerWindow(nsWindow **aWindow); @@ -310,6 +316,10 @@ private: PRInt32 mSizeState; PluginType mPluginType; +#ifdef MOZ_CAIRO_GFX + nsRefPtr mThebesSurface; +#endif + #ifdef ACCESSIBILITY nsCOMPtr mRootAccessible; void CreateRootAccessible(); diff --git a/widget/src/xpwidgets/Makefile.in b/widget/src/xpwidgets/Makefile.in index 8d2e2dd984c..6db222b8810 100644 --- a/widget/src/xpwidgets/Makefile.in +++ b/widget/src/xpwidgets/Makefile.in @@ -61,6 +61,10 @@ REQUIRES = xpcom \ view \ $(NULL) +ifeq ($(MOZ_ENABLE_CAIRO_GFX),1) +REQUIRES += thebes cairo +endif + DEFINES += -D_IMPL_NS_WIDGET -DUSE_TLS_FOR_TOOLKIT CPPSRCS = \ diff --git a/widget/src/xpwidgets/nsBaseWidget.cpp b/widget/src/xpwidgets/nsBaseWidget.cpp index 61e0d0f6837..a25d26e0bad 100644 --- a/widget/src/xpwidgets/nsBaseWidget.cpp +++ b/widget/src/xpwidgets/nsBaseWidget.cpp @@ -48,6 +48,11 @@ #include "nsIScreenManager.h" #include "nsAppDirectoryServiceDefs.h" +#ifdef MOZ_CAIRO_GFX +#include +#include "gfxPlatform.h" +#endif + #ifdef DEBUG #include "nsIServiceManager.h" #include "nsIPref.h" @@ -612,7 +617,11 @@ nsIRenderingContext* nsBaseWidget::GetRenderingContext() rv = mContext->CreateRenderingContextInstance(*getter_AddRefs(renderingCtx)); if (NS_SUCCEEDED(rv)) { +#ifndef MOZ_CAIRO_GFX rv = renderingCtx->Init(mContext, this); +#else + rv = renderingCtx->Init(mContext, GetThebesSurface()); +#endif if (NS_SUCCEEDED(rv)) { nsIRenderingContext *ret = renderingCtx; /* Increment object refcount that the |ret| object is still a valid one @@ -668,6 +677,24 @@ nsIAppShell *nsBaseWidget::GetAppShell() } +#ifdef MOZ_CAIRO_GFX +//------------------------------------------------------------------------- +// +// Get the thebes surface +// +//------------------------------------------------------------------------- +gfxASurface *nsBaseWidget::GetThebesSurface() +{ + nsIWidget *parent = GetParent(); + if (!parent) + return nsnull; + + // in theory we should get our parent's surface, + // clone it, and set a device offset before returning + return nsnull; +} +#endif + //------------------------------------------------------------------------- // // Destroy the window diff --git a/widget/src/xpwidgets/nsBaseWidget.h b/widget/src/xpwidgets/nsBaseWidget.h index 3bf2e9cc982..7f4eaf8b4c0 100644 --- a/widget/src/xpwidgets/nsBaseWidget.h +++ b/widget/src/xpwidgets/nsBaseWidget.h @@ -110,6 +110,9 @@ public: virtual nsIDeviceContext* GetDeviceContext(); virtual nsIAppShell * GetAppShell(); virtual nsIToolkit* GetToolkit(); +#ifdef MOZ_CAIRO_GFX + virtual gfxASurface* GetThebesSurface(); +#endif NS_IMETHOD SetModal(PRBool aModal); NS_IMETHOD ModalEventFilter(PRBool aRealEvent, void *aEvent, PRBool *aForWindow);