Fix round-off issues in font spacing calculations
Warren_Baird at cimmetry.com
Warren_Baird at cimmetry.com
Thu Feb 6 08:54:25 CST 2003
ChangeLog:
Fix round-off issue in font spacing calculation in ExtTextOut in XRender.
Description:
Using cummulative spacing offsets reduces round-off errors when
converting from logical to device coordinates. Without this fix, the
relative space between the last characters of a given input string varies
when the scaling factor between logical and device coordinates changes.
Warren Baird : Warren_Baird at cimmetry.com
Dave Belanger
diff -ur clean/wine/dlls/x11drv/xrender.c wine/dlls/x11drv/xrender.c
--- clean/wine/dlls/x11drv/xrender.c Wed Jan 29 15:30:55 2003
+++ wine/dlls/x11drv/xrender.c Thu Jan 30 11:10:40 2003
@@ -916,7 +916,7 @@
HDC hdc = physDev->hdc;
DC *dc = physDev->dc;
int textPixel, backgroundPixel;
- INT *deltas = NULL;
+ INT *offsets = NULL;
INT char_extra;
TRACE("%p, %d, %d, %08x, %p, %s, %d, %p)\n", hdc, x, y, flags,
@@ -1008,26 +1008,29 @@
TRACE("real x,y %d,%d\n", x, y);
- if((char_extra = GetTextCharacterExtra(physDev->hdc)) != 0) {
+ // Using cummulative spacing offsets reduces round-off errors when
+ // converting from logical to device coordinates.
+ if((char_extra = GetTextCharacterExtra(physDev->hdc)) != 0 || lpDx) {
INT i;
- SIZE tmpsz;
- deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
- for(i = 0; i < count; i++) {
- deltas[i] = char_extra;
- if(lpDx)
- deltas[i] += lpDx[i];
- else {
- GetTextExtentPointI(hdc, glyphs + i, 1, &tmpsz);
- deltas[i] += tmpsz.cx;
- }
- }
- } else if(lpDx)
- deltas = (INT*)lpDx;
-
- if(deltas) {
- width = 0;
- for(idx = 0; idx < count; idx++)
- width += deltas[idx];
+ long currentOffset = 0;
+ SIZE tmpsz;
+ offsets = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
+ for(i = 0; i < count; i++) {
+ currentOffset += char_extra;
+ if(lpDx) {
+ currentOffset += lpDx[i];
+ }
+ else {
+ GetTextExtentPointI(hdc, glyphs + i, 1, &tmpsz);
+ currentOffset += tmpsz.cx;
+ }
+ offsets[i] = currentOffset;
+ }
+ }
+
+ if(offsets) {
+ // Don't forget that offsets are cummulative.
+ width = offsets[count-1];
} else {
if(!done_extents) {[count-1];ets
GetTextExtentPointI(hdc, glyphs, count, &sz);
@@ -1113,11 +1116,14 @@
if ((data = X11DRV_GetRegionData( dc->hGCClipRgn, 0 )))
{
+ if (data->rdh.nCount)
+ {
wine_tsx11_lock();
pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
physDev->org.x, physDev->org.y,
(XRectangle *)data->Buffer, data->rdh.nCount );
wine_tsx11_unlock();
+ }
HeapFree( GetProcessHeap(), 0, data );
}
}
@@ -1200,7 +1206,7 @@
if(X11DRV_XRender_Installed) {
wine_tsx11_lock();
- if(!deltas)
+ if(!offsets)
pXRenderCompositeString16(gdi_display, render_op,
physDev->xrender->tile_pict,
physDev->xrender->pict,
@@ -1218,7 +1224,8 @@
0, 0, physDev->org.x + x + xoff,
physDev->org.y + y + yoff,
glyphs + idx, 1);
- offset += INTERNAL_XWSTODS(dc, deltas[idx]);
+ // Don't forget that offsets are cummulative.
+ offset = INTERNAL_XWSTODS(dc, offsets[idx]);
xoff = offset * cosEsc;
yoff = offset * -sinEsc;
}
@@ -1236,8 +1243,8 @@
physDev->org.y + y + yoff,
entry->bitmaps[glyphs[idx]],
&entry->gis[glyphs[idx]]);
- if(deltas) {
- offset += INTERNAL_XWSTODS(dc, deltas[idx]);
+ if(offsets) {
+ offset = INTERNAL_XWSTODS(dc, offsets[idx]);
xoff = offset * cosEsc;
yoff = offset * -sinEsc;
@@ -1252,8 +1259,8 @@
physDev->org.y + y + yoff,
entry->bitmaps[glyphs[idx]],
&entry->gis[glyphs[idx]]);
- if(deltas) {
- offset += INTERNAL_XWSTODS(dc, deltas[idx]);
+ if(offsets) {
+ offset = INTERNAL_XWSTODS(dc, offsets[idx]);
xoff = offset * cosEsc;
yoff = offset * -sinEsc;
@@ -1286,8 +1293,8 @@
extents.right = cur.x - entry->gis[glyphs[idx]].x +
entry->gis[glyphs[idx]].width;
if(extents.bottom < cur.y - entry->gis[glyphs[idx]].y +
entry->gis[glyphs[idx]].height)
extents.bottom = cur.y - entry->gis[glyphs[idx]].y +
entry->gis[glyphs[idx]].height;
- if(deltas) {
- offset += INTERNAL_XWSTODS(dc, deltas[idx]);
+ if(offsets) {
+ offset = INTERNAL_XWSTODS(dc, offsets[idx]);
cur.x = offset * cosEsc;
cur.y = offset * -sinEsc;
} else {
@@ -1363,8 +1370,8 @@
entry->bitmaps[glyphs[idx]],
&entry->gis[glyphs[idx]],
dc->textColor);
- if(deltas) {
- offset += INTERNAL_XWSTODS(dc, deltas[idx]);
+ if(offsets) {
+ offset = INTERNAL_XWSTODS(dc, offsets[idx]);
xoff = offset * cosEsc;
yoff = offset * -sinEsc;
} else {
@@ -1382,9 +1389,9 @@
}
LeaveCriticalSection(&xrender_cs);
- if(deltas && deltas != lpDx)
- HeapFree(GetProcessHeap(), 0, deltas);
-
+ if(offsets)
+ HeapFree(GetProcessHeap(), 0, offsets);
+
if (flags & ETO_CLIPPED)
RestoreVisRgn16( HDC_16(hdc) );
More information about the wine-patches
mailing list