gdi32: Add support for ETO_PDY and improve world transform support.

This commit is contained in:
Huw Davies 2010-05-06 14:05:39 +01:00 committed by Alexandre Julliard
parent 4733bd8162
commit d92ed5bd07
4 changed files with 166 additions and 123 deletions

View File

@ -1663,11 +1663,11 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
TEXTMETRICW tm; TEXTMETRICW tm;
LOGFONTW lf; LOGFONTW lf;
double cosEsc, sinEsc; double cosEsc, sinEsc;
INT *deltas = NULL, char_extra; INT char_extra;
SIZE sz; SIZE sz;
RECT rc; RECT rc;
BOOL done_extents = FALSE; BOOL done_extents = FALSE;
INT width = 0, xwidth = 0, ywidth = 0; POINT *deltas = NULL, width = {0, 0};
DWORD type; DWORD type;
DC * dc = get_dc_ptr( hdc ); DC * dc = get_dc_ptr( hdc );
INT breakRem; INT breakRem;
@ -1677,9 +1677,9 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
breakRem = dc->breakRem; breakRem = dc->breakRem;
if (quietfixme == 0 && flags & (ETO_NUMERICSLOCAL | ETO_NUMERICSLATIN | ETO_PDY)) if (quietfixme == 0 && flags & (ETO_NUMERICSLOCAL | ETO_NUMERICSLATIN))
{ {
FIXME("flags ETO_NUMERICSLOCAL | ETO_NUMERICSLATIN | ETO_PDY unimplemented\n"); FIXME("flags ETO_NUMERICSLOCAL | ETO_NUMERICSLATIN unimplemented\n");
quietfixme = 1; quietfixme = 1;
} }
if (!dc->funcs->pExtTextOut && !PATH_IsPathOpen(dc->path)) if (!dc->funcs->pExtTextOut && !PATH_IsPathOpen(dc->path))
@ -1793,13 +1793,25 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
{ {
UINT i; UINT i;
SIZE tmpsz; SIZE tmpsz;
deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT)); POINT total = {0, 0}, desired[2];
deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*deltas));
for(i = 0; i < count; i++) for(i = 0; i < count; i++)
{ {
if(lpDx && (flags & ETO_PDY)) if(lpDx)
deltas[i] = lpDx[i*2] + char_extra; {
else if(lpDx) if(flags & ETO_PDY)
deltas[i] = lpDx[i] + char_extra; {
deltas[i].x = lpDx[i * 2] + char_extra;
deltas[i].y = -lpDx[i * 2 + 1];
}
else
{
deltas[i].x = lpDx[i] + char_extra;
deltas[i].y = 0;
}
}
else else
{ {
if(flags & ETO_GLYPH_INDEX) if(flags & ETO_GLYPH_INDEX)
@ -1807,21 +1819,37 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
else else
GetTextExtentPointW(hdc, reordered_str + i, 1, &tmpsz); GetTextExtentPointW(hdc, reordered_str + i, 1, &tmpsz);
deltas[i] = tmpsz.cx; deltas[i].x = tmpsz.cx;
deltas[i].y = 0;
} }
if (!(flags & ETO_GLYPH_INDEX) && (dc->breakExtra || breakRem) && reordered_str[i] == tm.tmBreakChar) if (!(flags & ETO_GLYPH_INDEX) && (dc->breakExtra || breakRem) && reordered_str[i] == tm.tmBreakChar)
{ {
deltas[i] = deltas[i] + dc->breakExtra; deltas[i].x = deltas[i].x + dc->breakExtra;
if (breakRem > 0) if (breakRem > 0)
{ {
breakRem--; breakRem--;
deltas[i]++; deltas[i].x++;
} }
} }
deltas[i] = INTERNAL_XWSTODS(dc, deltas[i]); total.x += deltas[i].x;
width += deltas[i]; total.y += deltas[i].y;
desired[0].x = desired[0].y = 0;
desired[1].x = cosEsc * total.x + sinEsc * total.y;
desired[1].y = -sinEsc * total.x + cosEsc * total.y;
LPtoDP(hdc, desired, 2);
desired[1].x -= desired[0].x;
desired[1].y -= desired[0].y;
deltas[i].x = desired[1].x - width.x;
deltas[i].y = desired[1].y - width.y;
width = desired[1];
} }
flags |= ETO_PDY;
} }
else else
{ {
@ -1833,10 +1861,9 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
GetTextExtentPointW(hdc, reordered_str, count, &sz); GetTextExtentPointW(hdc, reordered_str, count, &sz);
done_extents = TRUE; done_extents = TRUE;
} }
width = INTERNAL_XWSTODS(dc, sz.cx); width.x = INTERNAL_XWSTODS(dc, sz.cx);
width.y = 0;
} }
xwidth = width * cosEsc;
ywidth = width * sinEsc;
tm.tmAscent = abs(INTERNAL_YWSTODS(dc, tm.tmAscent)); tm.tmAscent = abs(INTERNAL_YWSTODS(dc, tm.tmAscent));
tm.tmDescent = abs(INTERNAL_YWSTODS(dc, tm.tmDescent)); tm.tmDescent = abs(INTERNAL_YWSTODS(dc, tm.tmDescent));
@ -1845,21 +1872,21 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
case TA_LEFT: case TA_LEFT:
if (align & TA_UPDATECP) if (align & TA_UPDATECP)
{ {
pt.x = x + xwidth; pt.x = x + width.x;
pt.y = y - ywidth; pt.y = y - width.y;
DPtoLP(hdc, &pt, 1); DPtoLP(hdc, &pt, 1);
MoveToEx(hdc, pt.x, pt.y, NULL); MoveToEx(hdc, pt.x, pt.y, NULL);
} }
break; break;
case TA_CENTER: case TA_CENTER:
x -= xwidth / 2; x -= width.x / 2;
y += ywidth / 2; y += width.y / 2;
break; break;
case TA_RIGHT: case TA_RIGHT:
x -= xwidth; x -= width.x;
y += ywidth; y += width.y;
if (align & TA_UPDATECP) if (align & TA_UPDATECP)
{ {
pt.x = x; pt.x = x;
@ -1890,12 +1917,12 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
{ {
if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE))) if(!((flags & ETO_CLIPPED) && (flags & ETO_OPAQUE)))
{ {
if(!(flags & ETO_OPAQUE) || x < rc.left || x + width >= rc.right || if(!(flags & ETO_OPAQUE) || x < rc.left || x + width.x >= rc.right ||
y - tm.tmAscent < rc.top || y + tm.tmDescent >= rc.bottom) y - tm.tmAscent < rc.top || y + tm.tmDescent >= rc.bottom)
{ {
RECT rc; RECT rc;
rc.left = x; rc.left = x;
rc.right = x + width; rc.right = x + width.x;
rc.top = y - tm.tmAscent; rc.top = y - tm.tmAscent;
rc.bottom = y + tm.tmDescent; rc.bottom = y + tm.tmDescent;
dc->funcs->pExtTextOut(dc->physDev, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL); dc->funcs->pExtTextOut(dc->physDev, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
@ -1907,7 +1934,8 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
{ {
HFONT orig_font = dc->hFont, cur_font; HFONT orig_font = dc->hFont, cur_font;
UINT glyph; UINT glyph;
INT span = 0, *offsets = NULL; INT span = 0;
POINT *offsets = NULL;
unsigned int i; unsigned int i;
glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD)); glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD));
@ -1920,32 +1948,37 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
{ {
unsigned int j; unsigned int j;
offsets = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*deltas)); offsets = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*deltas));
offsets[0] = 0; offsets[0].x = offsets[0].y = 0;
if(!deltas) if(!deltas)
{ {
SIZE tmpsz; SIZE tmpsz;
for(j = 1; j < count; j++) for(j = 1; j < count; j++)
{ {
GetTextExtentPointW(hdc, reordered_str + j - 1, 1, &tmpsz); GetTextExtentPointW(hdc, reordered_str + j - 1, 1, &tmpsz);
offsets[j] = offsets[j-1] + INTERNAL_XWSTODS(dc, tmpsz.cx); offsets[j].x = offsets[j - 1].x + INTERNAL_XWSTODS(dc, tmpsz.cx);
offsets[j].y = 0;
} }
} }
else else
{ {
for(j = 1; j < count; j++) for(j = 1; j < count; j++)
offsets[j] = offsets[j-1] + deltas[j]; {
offsets[j].x = offsets[j - 1].x + deltas[j].x;
offsets[j].y = offsets[j - 1].y + deltas[j].y;
}
} }
} }
if(span) if(span)
{ {
if (PATH_IsPathOpen(dc->path)) if (PATH_IsPathOpen(dc->path))
ret = PATH_ExtTextOut(dc, x + offsets[i - span] * cosEsc, y - offsets[i - span] * sinEsc, ret = PATH_ExtTextOut(dc, x + offsets[i - span].x, y + offsets[i - span].y,
(flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc,
glyphs, span, deltas ? deltas + i - span : NULL); glyphs, span, deltas ? (INT*)(deltas + (i - span)) : NULL);
else else
dc->funcs->pExtTextOut(dc->physDev, x + offsets[i - span] * cosEsc, y - offsets[i - span] * sinEsc, dc->funcs->pExtTextOut(dc->physDev, x + offsets[i - span].x, y + offsets[i - span].y,
(flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc,
glyphs, span, deltas ? deltas + i - span : NULL); glyphs, span, deltas ? (INT*)(deltas + (i - span)) : NULL);
span = 0; span = 0;
} }
SelectObject(hdc, cur_font); SelectObject(hdc, cur_font);
@ -1955,15 +1988,15 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
if(i == count - 1) if(i == count - 1)
{ {
if (PATH_IsPathOpen(dc->path)) if (PATH_IsPathOpen(dc->path))
ret = PATH_ExtTextOut(dc, x + (offsets ? offsets[count - span] * cosEsc : 0), ret = PATH_ExtTextOut(dc, x + (offsets ? offsets[count - span].x : 0),
y - (offsets ? offsets[count - span] * sinEsc : 0), y + (offsets ? offsets[count - span].y : 0),
(flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc,
glyphs, span, deltas ? deltas + count - span : NULL); glyphs, span, deltas ? (INT*)(deltas + (count - span)) : NULL);
else else
ret = dc->funcs->pExtTextOut(dc->physDev, x + (offsets ? offsets[count - span] * cosEsc : 0), ret = dc->funcs->pExtTextOut(dc->physDev, x + (offsets ? offsets[count - span].x : 0),
y - (offsets ? offsets[count - span] * sinEsc : 0), y + (offsets ? offsets[count - span].y : 0),
(flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc,
glyphs, span, deltas ? deltas + count - span : NULL); glyphs, span, deltas ? (INT*)(deltas + (count - span)) : NULL);
SelectObject(hdc, orig_font); SelectObject(hdc, orig_font);
HeapFree(GetProcessHeap(), 0, offsets); HeapFree(GetProcessHeap(), 0, offsets);
} }
@ -1980,10 +2013,10 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
if (PATH_IsPathOpen(dc->path)) if (PATH_IsPathOpen(dc->path))
ret = PATH_ExtTextOut(dc, x, y, (flags & ~ETO_OPAQUE), &rc, ret = PATH_ExtTextOut(dc, x, y, (flags & ~ETO_OPAQUE), &rc,
glyphs ? glyphs : reordered_str, count, deltas); glyphs ? glyphs : reordered_str, count, (INT*)deltas);
else else
ret = dc->funcs->pExtTextOut(dc->physDev, x, y, (flags & ~ETO_OPAQUE), &rc, ret = dc->funcs->pExtTextOut(dc->physDev, x, y, (flags & ~ETO_OPAQUE), &rc,
glyphs ? glyphs : reordered_str, count, deltas); glyphs ? glyphs : reordered_str, count, (INT*)deltas);
} }
done: done:
@ -2033,8 +2066,8 @@ done:
{ {
pts[0].x = x - underlinePos * sinEsc; pts[0].x = x - underlinePos * sinEsc;
pts[0].y = y - underlinePos * cosEsc; pts[0].y = y - underlinePos * cosEsc;
pts[1].x = x + xwidth - underlinePos * sinEsc; pts[1].x = x + width.x - underlinePos * sinEsc;
pts[1].y = y - ywidth - underlinePos * cosEsc; pts[1].y = y - width.y - underlinePos * cosEsc;
pts[2].x = pts[1].x + underlineWidth * sinEsc; pts[2].x = pts[1].x + underlineWidth * sinEsc;
pts[2].y = pts[1].y + underlineWidth * cosEsc; pts[2].y = pts[1].y + underlineWidth * cosEsc;
pts[3].x = pts[0].x + underlineWidth * sinEsc; pts[3].x = pts[0].x + underlineWidth * sinEsc;
@ -2049,8 +2082,8 @@ done:
{ {
pts[0].x = x - strikeoutPos * sinEsc; pts[0].x = x - strikeoutPos * sinEsc;
pts[0].y = y - strikeoutPos * cosEsc; pts[0].y = y - strikeoutPos * cosEsc;
pts[1].x = x + xwidth - strikeoutPos * sinEsc; pts[1].x = x + width.x - strikeoutPos * sinEsc;
pts[1].y = y - ywidth - strikeoutPos * cosEsc; pts[1].y = y - width.y - strikeoutPos * cosEsc;
pts[2].x = pts[1].x + strikeoutWidth * sinEsc; pts[2].x = pts[1].x + strikeoutWidth * sinEsc;
pts[2].y = pts[1].y + strikeoutWidth * cosEsc; pts[2].y = pts[1].y + strikeoutWidth * cosEsc;
pts[3].x = pts[0].x + strikeoutWidth * sinEsc; pts[3].x = pts[0].x + strikeoutWidth * sinEsc;
@ -2076,8 +2109,8 @@ done:
hpen = SelectObject(hdc, hpen); hpen = SelectObject(hdc, hpen);
pts[0].x = x; pts[0].x = x;
pts[0].y = y; pts[0].y = y;
pts[1].x = x + xwidth; pts[1].x = x + width.x;
pts[1].y = y - ywidth; pts[1].y = y - width.y;
DPtoLP(hdc, pts, 2); DPtoLP(hdc, pts, 2);
MoveToEx(hdc, pts[0].x - underlinePos * sinEsc, pts[0].y - underlinePos * cosEsc, &oldpt); MoveToEx(hdc, pts[0].x - underlinePos * sinEsc, pts[0].y - underlinePos * cosEsc, &oldpt);
LineTo(hdc, pts[1].x - underlinePos * sinEsc, pts[1].y - underlinePos * cosEsc); LineTo(hdc, pts[1].x - underlinePos * sinEsc, pts[1].y - underlinePos * cosEsc);
@ -2091,8 +2124,8 @@ done:
hpen = SelectObject(hdc, hpen); hpen = SelectObject(hdc, hpen);
pts[0].x = x; pts[0].x = x;
pts[0].y = y; pts[0].y = y;
pts[1].x = x + xwidth; pts[1].x = x + width.x;
pts[1].y = y - ywidth; pts[1].y = y - width.y;
DPtoLP(hdc, pts, 2); DPtoLP(hdc, pts, 2);
MoveToEx(hdc, pts[0].x - strikeoutPos * sinEsc, pts[0].y - strikeoutPos * cosEsc, &oldpt); MoveToEx(hdc, pts[0].x - strikeoutPos * sinEsc, pts[0].y - strikeoutPos * cosEsc, &oldpt);
LineTo(hdc, pts[1].x - strikeoutPos * sinEsc, pts[1].y - strikeoutPos * cosEsc); LineTo(hdc, pts[1].x - strikeoutPos * sinEsc, pts[1].y - strikeoutPos * cosEsc);

View File

@ -1423,28 +1423,14 @@ BOOL PATH_ExtTextOut(DC *dc, INT x, INT y, UINT flags, const RECT *lprc,
LPCWSTR str, UINT count, const INT *dx) LPCWSTR str, UINT count, const INT *dx)
{ {
unsigned int idx; unsigned int idx;
double cosEsc, sinEsc;
LOGFONTW lf;
HDC hdc = dc->hSelf; HDC hdc = dc->hSelf;
INT offset = 0, xoff = 0, yoff = 0; POINT offset = {0, 0};
TRACE("%p, %d, %d, %08x, %s, %s, %d, %p)\n", hdc, x, y, flags, TRACE("%p, %d, %d, %08x, %s, %s, %d, %p)\n", hdc, x, y, flags,
wine_dbgstr_rect(lprc), debugstr_wn(str, count), count, dx); wine_dbgstr_rect(lprc), debugstr_wn(str, count), count, dx);
if (!count) return TRUE; if (!count) return TRUE;
GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
if (lf.lfEscapement != 0)
{
cosEsc = cos(lf.lfEscapement * M_PI / 1800);
sinEsc = sin(lf.lfEscapement * M_PI / 1800);
} else
{
cosEsc = 1;
sinEsc = 0;
}
for (idx = 0; idx < count; idx++) for (idx = 0; idx < count; idx++)
{ {
static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} }; static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
@ -1463,21 +1449,25 @@ BOOL PATH_ExtTextOut(DC *dc, INT x, INT y, UINT flags, const RECT *lprc,
GetGlyphOutlineW(hdc, str[idx], GGO_GLYPH_INDEX | GGO_NATIVE, &gm, dwSize, outline, &identity); GetGlyphOutlineW(hdc, str[idx], GGO_GLYPH_INDEX | GGO_NATIVE, &gm, dwSize, outline, &identity);
PATH_add_outline(dc, x + xoff, y + yoff, outline, dwSize); PATH_add_outline(dc, x + offset.x, y + offset.y, outline, dwSize);
HeapFree(GetProcessHeap(), 0, outline); HeapFree(GetProcessHeap(), 0, outline);
} }
if (dx) if (dx)
{ {
offset += dx[idx]; if(flags & ETO_PDY)
xoff = offset * cosEsc; {
yoff = offset * -sinEsc; offset.x += dx[idx * 2];
offset.y += dx[idx * 2 + 1];
}
else
offset.x += dx[idx];
} }
else else
{ {
xoff += gm.gmCellIncX; offset.x += gm.gmCellIncX;
yoff += gm.gmCellIncY; offset.y += gm.gmCellIncY;
} }
} }
return TRUE; return TRUE;

View File

@ -112,18 +112,21 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR
} }
else { else {
UINT i; UINT i;
float dx = 0.0, dy = 0.0; POINT offset = {0, 0};
float cos_theta = cos(physDev->font.escapement * M_PI / 1800.0);
float sin_theta = sin(physDev->font.escapement * M_PI / 1800.0);
for(i = 0; i < count-1; i++) { for(i = 0; i < count-1; i++) {
TRACE("lpDx[%d] = %d\n", i, lpDx[i]);
if(physDev->font.fontloc == Download) if(physDev->font.fontloc == Download)
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1); PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
else else
PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1); PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
dx += lpDx[i] * cos_theta; if(flags & ETO_PDY)
dy -= lpDx[i] * sin_theta; {
PSDRV_WriteMoveTo(physDev, x + dx, y + dy); offset.x += lpDx[i * 2];
offset.y += lpDx[i * 2 + 1];
}
else
offset.x += lpDx[i];
PSDRV_WriteMoveTo(physDev, x + offset.x, y + offset.y);
} }
if(physDev->font.fontloc == Download) if(physDev->font.fontloc == Download)
PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1); PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);

View File

@ -1626,8 +1626,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
AA_Type aa_type = AA_None; AA_Type aa_type = AA_None;
DIBSECTION bmp; DIBSECTION bmp;
unsigned int idx; unsigned int idx;
double cosEsc, sinEsc;
LOGFONTW lf;
const WineXRenderFormat *dst_format = get_xrender_format_from_color_shifts(physDev->depth, physDev->color_shifts); const WineXRenderFormat *dst_format = get_xrender_format_from_color_shifts(physDev->depth, physDev->color_shifts);
Picture tile_pict = 0; Picture tile_pict = 0;
@ -1678,16 +1676,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
goto done_unlock; goto done_unlock;
} }
GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
if(lf.lfEscapement != 0) {
cosEsc = cos(lf.lfEscapement * M_PI / 1800);
sinEsc = sin(lf.lfEscapement * M_PI / 1800);
} else {
cosEsc = 1;
sinEsc = 0;
}
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ {
HRGN clip_region; HRGN clip_region;
@ -1731,7 +1719,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
if(X11DRV_XRender_Installed) if(X11DRV_XRender_Installed)
{ {
XGlyphElt16 *elts = HeapAlloc(GetProcessHeap(), 0, sizeof(XGlyphElt16) * count); XGlyphElt16 *elts = HeapAlloc(GetProcessHeap(), 0, sizeof(XGlyphElt16) * count);
INT offset = 0; POINT offset = {0, 0};
POINT desired, current; POINT desired, current;
int render_op = PictOpOver; int render_op = PictOpOver;
Picture pict = get_xrender_picture(physDev); Picture pict = get_xrender_picture(physDev);
@ -1769,9 +1757,15 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
} }
else else
{ {
offset += lpDx[idx]; if(flags & ETO_PDY)
desired.x = physDev->dc_rect.left + x + offset * cosEsc; {
desired.y = physDev->dc_rect.top + y - offset * sinEsc; offset.x += lpDx[idx * 2];
offset.y += lpDx[idx * 2 + 1];
}
else
offset.x += lpDx[idx];
desired.x = physDev->dc_rect.left + x + offset.x;
desired.y = physDev->dc_rect.top + y + offset.y;
} }
} }
wine_tsx11_lock(); wine_tsx11_lock();
@ -1785,7 +1779,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
wine_tsx11_unlock(); wine_tsx11_unlock();
HeapFree(GetProcessHeap(), 0, elts); HeapFree(GetProcessHeap(), 0, elts);
} else { } else {
INT offset = 0, xoff = 0, yoff = 0; POINT offset = {0, 0};
wine_tsx11_lock(); wine_tsx11_lock();
XSetForeground( gdi_display, physDev->gc, textPixel ); XSetForeground( gdi_display, physDev->gc, textPixel );
@ -1799,17 +1793,25 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
sharp_glyph_fn = SharpGlyphGray; sharp_glyph_fn = SharpGlyphGray;
for(idx = 0; idx < count; idx++) { for(idx = 0; idx < count; idx++) {
sharp_glyph_fn(physDev, physDev->dc_rect.left + x + xoff, sharp_glyph_fn(physDev,
physDev->dc_rect.top + y + yoff, physDev->dc_rect.left + x + offset.x,
physDev->dc_rect.top + y + offset.y,
formatEntry->bitmaps[wstr[idx]], formatEntry->bitmaps[wstr[idx]],
&formatEntry->gis[wstr[idx]]); &formatEntry->gis[wstr[idx]]);
if(lpDx) { if(lpDx)
offset += lpDx[idx]; {
xoff = offset * cosEsc; if(flags & ETO_PDY)
yoff = offset * -sinEsc; {
} else { offset.x += lpDx[idx * 2];
xoff += formatEntry->gis[wstr[idx]].xOff; offset.y += lpDx[idx * 2 + 1];
yoff += formatEntry->gis[wstr[idx]].yOff; }
else
offset.x += lpDx[idx];
}
else
{
offset.x += formatEntry->gis[wstr[idx]].xOff;
offset.y += formatEntry->gis[wstr[idx]].yOff;
} }
} }
} else { } else {
@ -1831,13 +1833,21 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
extents.right = cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width; extents.right = cur.x - formatEntry->gis[wstr[idx]].x + formatEntry->gis[wstr[idx]].width;
if(extents.bottom < cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height) if(extents.bottom < cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height)
extents.bottom = cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height; extents.bottom = cur.y - formatEntry->gis[wstr[idx]].y + formatEntry->gis[wstr[idx]].height;
if(lpDx) {
offset += lpDx[idx]; if(lpDx)
cur.x = offset * cosEsc; {
cur.y = offset * -sinEsc; if(flags & ETO_PDY)
} else { {
cur.x += formatEntry->gis[wstr[idx]].xOff; cur.x += lpDx[idx * 2];
cur.y += formatEntry->gis[wstr[idx]].yOff; cur.y += lpDx[idx * 2 + 1];
}
else
cur.x += lpDx[idx];
}
else
{
cur.x += formatEntry->gis[wstr[idx]].xOff;
cur.y += formatEntry->gis[wstr[idx]].yOff;
} }
} }
TRACE("glyph extents %d,%d - %d,%d drawable x,y %d,%d\n", extents.left, extents.top, TRACE("glyph extents %d,%d - %d,%d drawable x,y %d,%d\n", extents.left, extents.top,
@ -1901,21 +1911,28 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag
image->green_mask = visual->green_mask; image->green_mask = visual->green_mask;
image->blue_mask = visual->blue_mask; image->blue_mask = visual->blue_mask;
offset = xoff = yoff = 0;
for(idx = 0; idx < count; idx++) { for(idx = 0; idx < count; idx++) {
SmoothGlyphGray(image, xoff + image_off_x - extents.left, SmoothGlyphGray(image,
yoff + image_off_y - extents.top, offset.x + image_off_x - extents.left,
offset.y + image_off_y - extents.top,
formatEntry->bitmaps[wstr[idx]], formatEntry->bitmaps[wstr[idx]],
&formatEntry->gis[wstr[idx]], &formatEntry->gis[wstr[idx]],
physDev->textPixel); physDev->textPixel);
if(lpDx) { if(lpDx)
offset += lpDx[idx]; {
xoff = offset * cosEsc; if(flags & ETO_PDY)
yoff = offset * -sinEsc; {
} else { offset.x += lpDx[idx * 2];
xoff += formatEntry->gis[wstr[idx]].xOff; offset.y += lpDx[idx * 2 + 1];
yoff += formatEntry->gis[wstr[idx]].yOff; }
} else
offset.x += lpDx[idx];
}
else
{
offset.x += formatEntry->gis[wstr[idx]].xOff;
offset.y += formatEntry->gis[wstr[idx]].yOff;
}
} }
XPutImage(gdi_display, physDev->drawable, physDev->gc, image, 0, 0, XPutImage(gdi_display, physDev->drawable, physDev->gc, image, 0, 0,
image_x, image_y, image_w, image_h); image_x, image_y, image_w, image_h);