Huw Davies : winex11.drv: Use XRenderCompositeText instead of XRenderCompositeString.

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 25 14:43:45 CDT 2007


Module: wine
Branch: master
Commit: e0150c357d390c5f8edee9d6f5a55ff8939ee3a6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e0150c357d390c5f8edee9d6f5a55ff8939ee3a6

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu May 24 15:06:44 2007 +0100

winex11.drv: Use XRenderCompositeText instead of XRenderCompositeString.

---

 dlls/winex11.drv/xrender.c |   87 +++++++++++++++++++++++++++-----------------
 1 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index c8bd7ad..b11ed14 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -118,6 +118,7 @@ MAKE_FUNCPTR(XRenderComposite)
 MAKE_FUNCPTR(XRenderCompositeString8)
 MAKE_FUNCPTR(XRenderCompositeString16)
 MAKE_FUNCPTR(XRenderCompositeString32)
+MAKE_FUNCPTR(XRenderCompositeText16)
 MAKE_FUNCPTR(XRenderCreateGlyphSet)
 MAKE_FUNCPTR(XRenderCreatePicture)
 MAKE_FUNCPTR(XRenderFillRectangle)
@@ -181,6 +182,7 @@ LOAD_FUNCPTR(XRenderComposite)
 LOAD_FUNCPTR(XRenderCompositeString8)
 LOAD_FUNCPTR(XRenderCompositeString16)
 LOAD_FUNCPTR(XRenderCompositeString32)
+LOAD_FUNCPTR(XRenderCompositeText16)
 LOAD_FUNCPTR(XRenderCreateGlyphSet)
 LOAD_FUNCPTR(XRenderCreatePicture)
 LOAD_FUNCPTR(XRenderFillRectangle)
@@ -346,9 +348,9 @@ static void FreeEntry(int entry)
                     HeapFree(GetProcessHeap(), 0, formatEntry->bitmaps[i]);
                 HeapFree(GetProcessHeap(), 0, formatEntry->bitmaps);
                 formatEntry->bitmaps = NULL;
-                HeapFree(GetProcessHeap(), 0, formatEntry->gis);
-                formatEntry->gis = NULL;
             }
+            HeapFree(GetProcessHeap(), 0, formatEntry->gis);
+            formatEntry->gis = NULL;
             formatEntry->nrealized = 0;
         }
 
@@ -694,17 +696,16 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph, AA_Type format)
 	    formatEntry->bitmaps = HeapAlloc(GetProcessHeap(),
 				      HEAP_ZERO_MEMORY,
 				      formatEntry->nrealized * sizeof(formatEntry->bitmaps[0]));
-
-	  if (formatEntry->gis)
+        }
+        if (formatEntry->gis)
 	    formatEntry->gis = HeapReAlloc(GetProcessHeap(),
 				   HEAP_ZERO_MEMORY,
 				   formatEntry->gis,
 				   formatEntry->nrealized * sizeof(formatEntry->gis[0]));
-	  else
+        else
 	    formatEntry->gis = HeapAlloc(GetProcessHeap(),
 				   HEAP_ZERO_MEMORY,
-				   formatEntry->nrealized * sizeof(formatEntry->gis[0]));
-	}
+                                   formatEntry->nrealized * sizeof(formatEntry->gis[0]));
     }
 
 
@@ -790,6 +791,8 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph, AA_Type format)
 	}
     }
 
+    memcpy(&formatEntry->gis[glyph], &gi, sizeof(gi));
+
     if(formatEntry->glyphset) {
         if(format == AA_None && BitmapBitOrder(gdi_display) != MSBFirst) {
 	    unsigned char *byte = (unsigned char*) buf, c;
@@ -814,7 +817,6 @@ static BOOL UploadGlyph(X11DRV_PDEVICE *physDev, int glyph, AA_Type format)
 	HeapFree(GetProcessHeap(), 0, buf);
     } else {
         formatEntry->bitmaps[glyph] = buf;
-	memcpy(&formatEntry->gis[glyph], &gi, sizeof(gi));
     }
     return TRUE;
 }
@@ -1270,32 +1272,51 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
     TRACE("Writing %s at %d,%d\n", debugstr_wn(wstr,count),
           physDev->dc_rect.left + x, physDev->dc_rect.top + y);
 
-    if(X11DRV_XRender_Installed) {
-        wine_tsx11_lock();
-	if(!lpDx)
-	    pXRenderCompositeString16(gdi_display, render_op,
-				      physDev->xrender->tile_pict,
-				      physDev->xrender->pict,
-				      formatEntry->font_format, formatEntry->glyphset,
-				      0, 0, physDev->dc_rect.left + x, physDev->dc_rect.top + y,
-				      wstr, count);
-	else {
-	    INT offset = 0, xoff = 0, yoff = 0;
-	    for(idx = 0; idx < count; idx++) {
-	        pXRenderCompositeString16(gdi_display, render_op,
-					  physDev->xrender->tile_pict,
-					  physDev->xrender->pict,
-					  formatEntry->font_format, formatEntry->glyphset,
-					  0, 0, physDev->dc_rect.left + x + xoff,
-					  physDev->dc_rect.top + y + yoff,
-					  wstr + idx, 1);
-                offset += lpDx[idx];
-		xoff = offset * cosEsc;
-		yoff = offset * -sinEsc;
-	    }
-	}
-	wine_tsx11_unlock();
+    if(X11DRV_XRender_Installed)
+    {
+        XGlyphElt16 *elts = HeapAlloc(GetProcessHeap(), 0, sizeof(XGlyphElt16) * count);
+        INT offset = 0;
+        POINT desired, current;
 
+        /* There's a bug in XRenderCompositeText that ignores the xDst and yDst parameters.
+           So we pass zeros to the function and move to our starting position using the first
+           element of the elts array. */
+
+        desired.x = physDev->dc_rect.left + x;
+        desired.y = physDev->dc_rect.top + y;
+        current.x = current.y = 0;
+
+        for(idx = 0; idx < count; idx++)
+        {
+            elts[idx].glyphset = formatEntry->glyphset;
+            elts[idx].chars = wstr + idx;
+            elts[idx].nchars = 1;
+            elts[idx].xOff = desired.x - current.x;
+            elts[idx].yOff = desired.y - current.y;
+
+            current.x += (elts[idx].xOff + formatEntry->gis[wstr[idx]].xOff);
+            current.y += (elts[idx].yOff + formatEntry->gis[wstr[idx]].yOff);
+
+            if(!lpDx)
+            {
+                desired.x += formatEntry->gis[wstr[idx]].xOff;
+                desired.y += formatEntry->gis[wstr[idx]].yOff;
+            }
+            else
+            {
+                offset += lpDx[idx];
+                desired.x = physDev->dc_rect.left + x + offset * cosEsc;
+                desired.y = physDev->dc_rect.top  + y - offset * sinEsc;
+            }
+        }
+        wine_tsx11_lock();
+        pXRenderCompositeText16(gdi_display, render_op,
+                                physDev->xrender->tile_pict,
+                                physDev->xrender->pict,
+                                formatEntry->font_format,
+                                0, 0, 0, 0, elts, count);
+        wine_tsx11_unlock();
+        HeapFree(GetProcessHeap(), 0, elts);
     } else {
         INT offset = 0, xoff = 0, yoff = 0;
         wine_tsx11_lock();




More information about the wine-cvs mailing list