GetTextExtentExPointW Speedup

Dan Hipschman dsh at linux.ucla.edu
Tue Jul 11 19:58:35 CDT 2006


Hi,

This is a patch to implement GetTextExtentPoint in terms of
GetTextExtentExPoint.  The current implementation does it the other way
around, but uses an order N^2 algorithm to ensure consistency.  To make
this patch work I had to add the Ex-version functionality to the GDI and
driver code (X11 and PS).  I tried not to change any existing code, but
only add a few lines where needed to calculate the partial extents and
number of characters that fit.  The one place I did have to change some
code in the X11 driver (X11DRV_TextExtents_normal), I derived the changes
from an existing implementation (X11DRV_TextExtents_dbcs_2fonts).

ChangeLog:
* Implement GetTextExtentPoint in terms of GetTextExtentExPoint (not vice
  versa) for efficiency (required adding the Ex functionality to drivers)
---
 dlls/gdi/driver.c                 |    2 -
 dlls/gdi/enhmfdrv/init.c          |    2 -
 dlls/gdi/font.c                   |  108 +++++++++++++++++++++----------------
 dlls/gdi/freetype.c               |   27 +++++++--
 dlls/gdi/gdi_private.h            |    4 +
 dlls/gdi/mfdrv/init.c             |    2 -
 dlls/wineps.drv/builtin.c         |   19 ++++++-
 dlls/wineps.drv/psdrv.h           |    4 +
 dlls/wineps.drv/wineps.drv.spec   |    2 -
 dlls/winex11.drv/codepage.c       |   32 ++++++++++-
 dlls/winex11.drv/text.c           |   18 +++++-
 dlls/winex11.drv/winex11.drv.spec |    2 -
 dlls/winex11.drv/x11font.h        |    3 +
 13 files changed, 151 insertions(+), 74 deletions(-)

diff --git a/dlls/gdi/driver.c b/dlls/gdi/driver.c
index 8d50e8c..76657a7 100644
--- a/dlls/gdi/driver.c
+++ b/dlls/gdi/driver.c
@@ -121,7 +121,7 @@ #define GET_FUNC(name) driver->funcs.p##
         GET_FUNC(GetPixel);
         GET_FUNC(GetPixelFormat);
         GET_FUNC(GetSystemPaletteEntries);
-        GET_FUNC(GetTextExtentPoint);
+        GET_FUNC(GetTextExtentExPoint);
         GET_FUNC(GetTextMetrics);
         GET_FUNC(IntersectClipRect);
         GET_FUNC(InvertRgn);
diff --git a/dlls/gdi/enhmfdrv/init.c b/dlls/gdi/enhmfdrv/init.c
index 82f0222..c3677b0 100644
--- a/dlls/gdi/enhmfdrv/init.c
+++ b/dlls/gdi/enhmfdrv/init.c
@@ -80,7 +80,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     NULL,                            /* pGetPixel */
     NULL,                            /* pGetPixelFormat */
     NULL,                            /* pGetSystemPaletteEntries */
-    NULL,                            /* pGetTextExtentPoint */
+    NULL,                            /* pGetTextExtentExPoint */
     NULL,                            /* pGetTextMetrics */
     EMFDRV_IntersectClipRect,        /* pIntersectClipRect */
     EMFDRV_InvertRgn,                /* pInvertRgn */
diff --git a/dlls/gdi/font.c b/dlls/gdi/font.c
index 33a03f6..a1bb3e6 100644
--- a/dlls/gdi/font.c
+++ b/dlls/gdi/font.c
@@ -1053,27 +1053,7 @@ BOOL WINAPI GetTextExtentPoint32W(
     INT count,   /* [in]  Number of characters in string */
     LPSIZE size) /* [out] Address of structure for string size */
 {
-    BOOL ret = FALSE;
-    DC * dc = DC_GetDCPtr( hdc );
-    if (!dc) return FALSE;
-
-    if(dc->gdiFont)
-        ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
-    else if(dc->funcs->pGetTextExtentPoint)
-        ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
-
-    if (ret)
-    {
-	size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
-	size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
-        size->cx += count * dc->charExtra + dc->breakRem;
-    }
-
-    GDI_ReleaseObj( hdc );
-
-    TRACE("(%p %s %d %p): returning %ld x %ld\n",
-          hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
-    return ret;
+    return GetTextExtentExPointW(hdc, str, count, 0, NULL, NULL, size);
 }
 
 /***********************************************************************
@@ -1101,9 +1081,10 @@ BOOL WINAPI GetTextExtentPointI(
 	size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
         size->cx += count * dc->charExtra;
     }
-    else if(dc->funcs->pGetTextExtentPoint) {
-        FIXME("calling GetTextExtentPoint\n");
-        ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
+    else if(dc->funcs->pGetTextExtentExPoint) {
+        FIXME("calling GetTextExtentExPoint\n");
+        ret = dc->funcs->pGetTextExtentExPoint( dc->physDev, (LPCWSTR)indices,
+                                                count, 0, NULL, NULL, size );
     }
 
     GDI_ReleaseObj( hdc );
@@ -1205,36 +1186,71 @@ BOOL WINAPI GetTextExtentExPointW( HDC h
 				   INT maxExt, LPINT lpnFit,
 				   LPINT alpDx, LPSIZE size )
 {
-    int index, nFit, extent;
-    SIZE tSize;
+    INT nFit = 0;
+    LPINT dxs = NULL;
+    HANDLE heap = NULL;
+    DC *dc;
     BOOL ret = FALSE;
 
     TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
 
-    size->cx = size->cy = nFit = extent = 0;
-    for(index = 0; index < count; index++)
+    dc = DC_GetDCPtr(hdc);
+    if (! dc)
+        return FALSE;
+
+    /* If we need to calculate nFit, then we need the partial extents even if
+       the user hasn't provided us with an array.  */
+    if (lpnFit)
     {
- 	if(!GetTextExtentPoint32W( hdc, str, index + 1, &tSize )) goto done;
-        /* GetTextExtentPoint includes intercharacter spacing. */
-        /* FIXME - justification needs doing yet.  Remember that the base
-         * data will not be in logical coordinates.
-         */
-	extent = tSize.cx;
-	if( !lpnFit || extent <= maxExt )
-        /* It is allowed to be equal. */
-        {
-	    nFit++;
-	    if( alpDx ) alpDx[index] = extent;
-        }
-	if( tSize.cy > size->cy ) size->cy = tSize.cy;
+	heap = GetProcessHeap();
+	dxs = alpDx ? alpDx : HeapAlloc(heap, 0, count * sizeof alpDx[0]);
+	if (! dxs)
+	{
+	    GDI_ReleaseObj(hdc);
+	    SetLastError(ERROR_OUTOFMEMORY);
+	    return FALSE;
+	}
     }
-    size->cx = extent;
-    if(lpnFit) *lpnFit = nFit;
-    ret = TRUE;
+    else
+	dxs = alpDx;
 
-    TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
+    if (dc->gdiFont)
+	ret = WineEngGetTextExtentExPoint(dc->gdiFont, str, count,
+					  0, NULL, dxs, size);
+    else if (dc->funcs->pGetTextExtentExPoint)
+	ret = dc->funcs->pGetTextExtentExPoint(dc->physDev, str, count,
+					       0, NULL, dxs, size);
 
-done:
+    /* Perform device size to world size transformations.  */
+    if (ret)
+    {
+	INT extra = dc->charExtra, breakRem = dc->breakRem;
+
+	if (dxs)
+	{
+	    INT i;
+	    for (i = 0; i < count; ++i)
+	    {
+		dxs[i] = abs(INTERNAL_XDSTOWS(dc, dxs[i]));
+		dxs[i] += (i+1) * extra + breakRem;
+		if (dxs[i] <= maxExt)
+		    ++nFit;
+	    }
+	}
+	size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
+	size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
+	size->cx += count * extra + breakRem;
+    }
+
+    if (lpnFit)
+	*lpnFit = nFit;
+
+    if (dxs && ! alpDx)
+	HeapFree(heap, 0, dxs);
+
+    GDI_ReleaseObj( hdc );
+
+    TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
     return ret;
 }
 
diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c
index 9f52e60..7fb62bd 100644
--- a/dlls/gdi/freetype.c
+++ b/dlls/gdi/freetype.c
@@ -3849,20 +3849,21 @@ BOOL WineEngGetCharABCWidthsI(GdiFont fo
 }
 
 /*************************************************************
- * WineEngGetTextExtentPoint
+ * WineEngGetTextExtentExPoint
  *
  */
-BOOL WineEngGetTextExtentPoint(GdiFont font, LPCWSTR wstr, INT count,
-			       LPSIZE size)
+BOOL WineEngGetTextExtentExPoint(GdiFont font, LPCWSTR wstr, INT count,
+                                 INT max_ext, LPINT pnfit, LPINT dxs, LPSIZE size)
 {
     INT idx;
+    INT nfit = 0, ext;
     GLYPHMETRICS gm;
     TEXTMETRICW tm;
     FT_UInt glyph_index;
     GdiFont linked_font;
 
-    TRACE("%p, %s, %d, %p\n", font, debugstr_wn(wstr, count), count,
-	  size);
+    TRACE("%p, %s, %d, %d, %p\n", font, debugstr_wn(wstr, count), count,
+	  max_ext, size);
 
     size->cx = 0;
     WineEngGetTextMetrics(font, &tm);
@@ -3873,8 +3874,18 @@ BOOL WineEngGetTextExtentPoint(GdiFont f
         WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
                                &gm, 0, NULL, NULL);
 	size->cx += linked_font->gm[glyph_index].adv;
+        ext = size->cx;
+        if (! pnfit || ext <= max_ext) {
+            ++nfit;
+            if (dxs)
+                dxs[idx] = ext;
+        }
     }
-    TRACE("return %ld,%ld\n", size->cx, size->cy);
+
+    if (pnfit)
+        *pnfit = nfit;
+
+    TRACE("return %ld, %ld, %d\n", size->cx, size->cy, nfit);
     return TRUE;
 }
 
@@ -4149,8 +4160,8 @@ BOOL WineEngGetCharABCWidthsI(GdiFont fo
     return FALSE;
 }
 
-BOOL WineEngGetTextExtentPoint(GdiFont font, LPCWSTR wstr, INT count,
-			       LPSIZE size)
+BOOL WineEngGetTextExtentExPoint(GdiFont font, LPCWSTR wstr, INT count,
+                                 INT max_ext, LPINT nfit, LPINT dx, LPSIZE size)
 {
     ERR("called but we don't have FreeType\n");
     return FALSE;
diff --git a/dlls/gdi/gdi_private.h b/dlls/gdi/gdi_private.h
index 610babb..a0de444 100644
--- a/dlls/gdi/gdi_private.h
+++ b/dlls/gdi/gdi_private.h
@@ -107,7 +107,7 @@ typedef struct tagDC_FUNCS
     COLORREF (*pGetPixel)(PHYSDEV,INT,INT);
     INT      (*pGetPixelFormat)(PHYSDEV);
     UINT     (*pGetSystemPaletteEntries)(PHYSDEV,UINT,UINT,LPPALETTEENTRY);
-    BOOL     (*pGetTextExtentPoint)(PHYSDEV,LPCWSTR,INT,LPSIZE);
+    BOOL     (*pGetTextExtentExPoint)(PHYSDEV,LPCWSTR,INT,INT,LPINT,LPINT,LPSIZE);
     BOOL     (*pGetTextMetrics)(PHYSDEV,TEXTMETRICW*);
     INT      (*pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
     BOOL     (*pInvertRgn)(PHYSDEV,HRGN);
@@ -379,7 +379,7 @@ extern DWORD WineEngGetGlyphOutline(GdiF
 extern BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph);
 extern UINT WineEngGetOutlineTextMetrics(GdiFont, UINT, LPOUTLINETEXTMETRICW);
 extern UINT WineEngGetTextCharsetInfo(GdiFont font, LPFONTSIGNATURE fs, DWORD flags);
-extern BOOL WineEngGetTextExtentPoint(GdiFont, LPCWSTR, INT, LPSIZE);
+extern BOOL WineEngGetTextExtentExPoint(GdiFont, LPCWSTR, INT, INT, LPINT, LPINT, LPSIZE);
 extern BOOL WineEngGetTextExtentPointI(GdiFont, const WORD *, INT, LPSIZE);
 extern INT  WineEngGetTextFace(GdiFont, INT, LPWSTR);
 extern BOOL WineEngGetTextMetrics(GdiFont, LPTEXTMETRICW);
diff --git a/dlls/gdi/mfdrv/init.c b/dlls/gdi/mfdrv/init.c
index bf964a7..c85501a 100644
--- a/dlls/gdi/mfdrv/init.c
+++ b/dlls/gdi/mfdrv/init.c
@@ -80,7 +80,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     NULL,                            /* pGetPixel */
     NULL,                            /* pGetPixelFormat */
     NULL,                            /* pGetSystemPaletteEntries */
-    NULL,                            /* pGetTextExtentPoint */
+    NULL,                            /* pGetTextExtentExPoint */
     NULL,                            /* pGetTextMetrics */
     MFDRV_IntersectClipRect,         /* pIntersectClipRect */
     MFDRV_InvertRgn,                 /* pInvertRgn */
diff --git a/dlls/wineps.drv/builtin.c b/dlls/wineps.drv/builtin.c
index 7c4cd8c..fe436da 100644
--- a/dlls/wineps.drv/builtin.c
+++ b/dlls/wineps.drv/builtin.c
@@ -304,23 +304,38 @@ const AFMMETRICS *PSDRV_UVMetrics(LONG U
 }
 
 /***********************************************************************
- *           PSDRV_GetTextExtentPoint
+ *           PSDRV_GetTextExtentExPoint
  */
-BOOL PSDRV_GetTextExtentPoint(PSDRV_PDEVICE *physDev, LPCWSTR str, INT count, LPSIZE size)
+BOOL PSDRV_GetTextExtentExPoint(PSDRV_PDEVICE *physDev, LPCWSTR str, INT count,
+                                INT maxExt, LPINT lpnFit, LPINT alpDx, LPSIZE size)
 {
+    int     	    nfit = 0;
     int     	    i;
     float   	    width = 0.0;
+    float   	    scale;
 
     assert(physDev->font.fontloc == Builtin);
 
     TRACE("%s %i\n", debugstr_wn(str, count), count);
 
+    scale = physDev->font.fontinfo.Builtin.scale;
     for (i = 0; i < count && str[i] != '\0'; ++i)
+    {
+	float scaled_width;
 	width += PSDRV_UVMetrics(str[i], physDev->font.fontinfo.Builtin.afm)->WX;
+	scaled_width = width * scale;
+	if (alpDx)
+	    alpDx[i] = scaled_width;
+	if (scaled_width <= maxExt)
+	    ++nfit;
+    }
 
     size->cx = width * physDev->font.fontinfo.Builtin.scale;
     size->cy = physDev->font.fontinfo.Builtin.tm.tmHeight;
 
+    if (lpnFit)
+	*lpnFit = nfit;
+
     TRACE("cx=%li cy=%li\n", size->cx, size->cy);
 
     return TRUE;
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index 94dbb0b..f60731d 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -480,8 +480,8 @@ extern BOOL PSDRV_ExtTextOut( PSDRV_PDEV
 				const INT *lpDx );
 extern BOOL PSDRV_GetCharWidth( PSDRV_PDEVICE *physDev, UINT firstChar, UINT lastChar,
 				  LPINT buffer );
-extern BOOL PSDRV_GetTextExtentPoint( PSDRV_PDEVICE *physDev, LPCWSTR str, INT count,
-					LPSIZE size );
+extern BOOL PSDRV_GetTextExtentExPoint( PSDRV_PDEVICE *physDev, LPCWSTR str, INT count,
+					INT maxExt, LPINT lpnFit, LPINT alpDx, LPSIZE size );
 extern BOOL PSDRV_GetTextMetrics( PSDRV_PDEVICE *physDev, TEXTMETRICW *metrics );
 extern BOOL PSDRV_LineTo( PSDRV_PDEVICE *physDev, INT x, INT y );
 extern BOOL PSDRV_PatBlt( PSDRV_PDEVICE *physDev, INT x, INT y, INT width, INT height, DWORD
diff --git a/dlls/wineps.drv/wineps.drv.spec b/dlls/wineps.drv/wineps.drv.spec
index 79082d4..1d3f20c 100644
--- a/dlls/wineps.drv/wineps.drv.spec
+++ b/dlls/wineps.drv/wineps.drv.spec
@@ -14,7 +14,7 @@ # GDI driver
 @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) PSDRV_ExtTextOut
 @ cdecl GetCharWidth(ptr long long ptr) PSDRV_GetCharWidth
 @ cdecl GetDeviceCaps(ptr long) PSDRV_GetDeviceCaps
-@ cdecl GetTextExtentPoint(ptr ptr long ptr) PSDRV_GetTextExtentPoint
+@ cdecl GetTextExtentExPoint(ptr ptr long long ptr ptr ptr) PSDRV_GetTextExtentExPoint
 @ cdecl GetTextMetrics(ptr ptr) PSDRV_GetTextMetrics
 @ cdecl LineTo(ptr long long) PSDRV_LineTo
 @ cdecl PaintRgn(ptr long) PSDRV_PaintRgn
diff --git a/dlls/winex11.drv/codepage.c b/dlls/winex11.drv/codepage.c
index 86201da..697b648 100644
--- a/dlls/winex11.drv/codepage.c
+++ b/dlls/winex11.drv/codepage.c
@@ -432,14 +432,32 @@ static void X11DRV_DrawText_normal( font
 
 static void X11DRV_TextExtents_normal( fontObject* pfo, XChar2b* pstr, int count,
                                        int* pdir, int* pascent, int* pdescent,
-                                       int* pwidth )
+                                       int* pwidth, int max_extent, int* pfit,
+                                       int* partial_extents )
 {
     XCharStruct info;
+    int ascent, descent, width;
+    int i, fit;
 
+    width = 0;
+    fit = 0;
+    *pascent = 0;
+    *pdescent = 0;
     wine_tsx11_lock();
-    XTextExtents16( pfo->fs, pstr, count, pdir, pascent, pdescent, &info );
+    for ( i = 0; i < count; i++ )
+    {
+	XTextExtents16( pfo->fs, pstr, 1, pdir, &ascent, &descent, &info );
+	if ( *pascent < ascent ) *pascent = ascent;
+	if ( *pdescent < descent ) *pdescent = descent;
+	width += info.width;
+	if ( partial_extents ) partial_extents[i] = width;
+	if ( width < max_extent ) fit++;
+
+	pstr++;
+    }
     wine_tsx11_unlock();
-    *pwidth = info.width;
+    *pwidth = width;
+    if ( pfit ) *pfit = fit;
 }
 
 static void X11DRV_GetTextMetricsW_normal( fontObject* pfo, LPTEXTMETRICW pTM )
@@ -594,11 +612,13 @@ void X11DRV_DrawText_dbcs_2fonts( fontOb
 static
 void X11DRV_TextExtents_dbcs_2fonts( fontObject* pfo, XChar2b* pstr, int count,
                                      int* pdir, int* pascent, int* pdescent,
-                                     int* pwidth )
+                                     int* pwidth, int max_extent, int* pfit,
+                                     int* partial_extents )
 {
     XCharStruct info;
     int ascent, descent, width;
     int i;
+    int fit;
     int curfont;
     fontObject* pfos[X11FONT_REFOBJS_MAX+1];
 
@@ -607,6 +627,7 @@ void X11DRV_TextExtents_dbcs_2fonts( fon
     if ( pfos[0] == NULL ) pfos[0] = pfo;
 
     width = 0;
+    fit = 0;
     *pascent = 0;
     *pdescent = 0;
     wine_tsx11_lock();
@@ -617,11 +638,14 @@ void X11DRV_TextExtents_dbcs_2fonts( fon
 	if ( *pascent < ascent ) *pascent = ascent;
 	if ( *pdescent < descent ) *pdescent = descent;
 	width += info.width;
+	if ( partial_extents ) partial_extents[i] = width;
+	if ( width <= max_extent ) fit++;
 
 	pstr ++;
     }
     wine_tsx11_unlock();
     *pwidth = width;
+    if ( pfit ) *pfit = fit;
 }
 
 static void X11DRV_GetTextMetricsW_cp932( fontObject* pfo, LPTEXTMETRICW pTM )
diff --git a/dlls/winex11.drv/text.c b/dlls/winex11.drv/text.c
index 0ec9bbc..8efd27a 100644
--- a/dlls/winex11.drv/text.c
+++ b/dlls/winex11.drv/text.c
@@ -201,10 +201,10 @@ END:
 
 
 /***********************************************************************
- *           X11DRV_GetTextExtentPoint
+ *           X11DRV_GetTextExtentExPoint
  */
-BOOL X11DRV_GetTextExtentPoint( X11DRV_PDEVICE *physDev, LPCWSTR str, INT count,
-                                  LPSIZE size )
+BOOL X11DRV_GetTextExtentExPoint( X11DRV_PDEVICE *physDev, LPCWSTR str, INT count,
+                                  INT maxExt, LPINT lpnFit, LPINT alpDx, LPSIZE size )
 {
     fontObject* pfo = XFONT_GetFontObject( physDev->font );
 
@@ -216,23 +216,33 @@ BOOL X11DRV_GetTextExtentPoint( X11DRV_P
 	    int dir, ascent, descent;
 	    int info_width;
 	    X11DRV_cptable[pfo->fi->cptable].pTextExtents( pfo, p,
-				count, &dir, &ascent, &descent, &info_width );
+				count, &dir, &ascent, &descent, &info_width,
+				maxExt, lpnFit, alpDx );
 
           size->cx = info_width;
           size->cy = pfo->fs->ascent + pfo->fs->descent;
 	} else {
 	    INT i;
+	    INT nfit = 0;
 	    float x = 0.0, y = 0.0;
+	    float scaled_x = 0.0, pixsize = pfo->lpX11Trans->pixelsize;
 	    /* FIXME: Deal with *_char_or_byte2 != 0 situations */
 	    for(i = 0; i < count; i++) {
 	        x += pfo->fs->per_char ?
 	   pfo->fs->per_char[p[i].byte2 - pfo->fs->min_char_or_byte2].attributes :
 	   pfo->fs->min_bounds.attributes;
+	        scaled_x = x * pixsize / 1000.0;
+	        if (alpDx)
+	            alpDx[i] = scaled_x;
+	        if (scaled_x <= maxExt)
+	            ++nfit;
 	    }
 	    y = pfo->lpX11Trans->RAW_ASCENT + pfo->lpX11Trans->RAW_DESCENT;
 	    TRACE("x = %f y = %f\n", x, y);
 	    size->cx = x * pfo->lpX11Trans->pixelsize / 1000.0;
 	    size->cy = y * pfo->lpX11Trans->pixelsize / 1000.0;
+	    if (lpnFit)
+	        *lpnFit = nfit;
 	}
 	size->cx *= pfo->rescale;
 	size->cy *= pfo->rescale;
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 687aabd..072295d 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -27,7 +27,7 @@ # GDI driver
 @ cdecl GetPixel(ptr long long) X11DRV_GetPixel
 @ cdecl GetPixelFormat(ptr) X11DRV_GetPixelFormat
 @ cdecl GetSystemPaletteEntries(ptr long long ptr) X11DRV_GetSystemPaletteEntries
-@ cdecl GetTextExtentPoint(ptr ptr long ptr) X11DRV_GetTextExtentPoint
+@ cdecl GetTextExtentExPoint(ptr ptr long long ptr ptr ptr) X11DRV_GetTextExtentExPoint
 @ cdecl GetTextMetrics(ptr ptr) X11DRV_GetTextMetrics
 @ cdecl LineTo(ptr long long) X11DRV_LineTo
 @ cdecl PaintRgn(ptr long) X11DRV_PaintRgn
diff --git a/dlls/winex11.drv/x11font.h b/dlls/winex11.drv/x11font.h
index c3c77e4..27eb82e 100644
--- a/dlls/winex11.drv/x11font.h
+++ b/dlls/winex11.drv/x11font.h
@@ -240,7 +240,8 @@ typedef struct tagX11DRV_CP
                        int x, int y, XTextItem16* pitems, int count );
     void (*pTextExtents)( fontObject* pfo, XChar2b* pstr, int count,
                           int* pdir, int* pascent, int* pdescent,
-                          int* pwidth );
+                          int* pwidth, int max_extent, int *pfit,
+                          int* partial_extents );
     void (*pGetTextMetricsW)( fontObject* pfo, LPTEXTMETRICW pTM );
 } X11DRV_CP;
 



More information about the wine-patches mailing list