From e0150c357d390c5f8edee9d6f5a55ff8939ee3a6 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 24 May 2007 15:06:44 +0100 Subject: [PATCH] winex11.drv: Use XRenderCompositeText instead of XRenderCompositeString. --- dlls/winex11.drv/xrender.c | 87 ++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index c8bd7ad46b5..b11ed14d61c 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(); -- 2.11.4.GIT