From d92ed5bd079fc83ba30e17bb9776ad8db8c316a7 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 6 May 2010 14:05:39 +0100 Subject: [PATCH] gdi32: Add support for ETO_PDY and improve world transform support. --- dlls/gdi32/font.c | 135 ++++++++++++++++++++++++++++----------------- dlls/gdi32/path.c | 32 ++++------- dlls/wineps.drv/text.c | 17 +++--- dlls/winex11.drv/xrender.c | 105 ++++++++++++++++++++--------------- 4 files changed, 166 insertions(+), 123 deletions(-) diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index c21036d4f08..50f2c5703ac 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -1663,11 +1663,11 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, TEXTMETRICW tm; LOGFONTW lf; double cosEsc, sinEsc; - INT *deltas = NULL, char_extra; + INT char_extra; SIZE sz; RECT rc; BOOL done_extents = FALSE; - INT width = 0, xwidth = 0, ywidth = 0; + POINT *deltas = NULL, width = {0, 0}; DWORD type; DC * dc = get_dc_ptr( hdc ); INT breakRem; @@ -1677,9 +1677,9 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, 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; } 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; 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++) { - if(lpDx && (flags & ETO_PDY)) - deltas[i] = lpDx[i*2] + char_extra; - else if(lpDx) - deltas[i] = lpDx[i] + char_extra; + if(lpDx) + { + if(flags & ETO_PDY) + { + 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 { if(flags & ETO_GLYPH_INDEX) @@ -1807,21 +1819,37 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, else 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) { - deltas[i] = deltas[i] + dc->breakExtra; + deltas[i].x = deltas[i].x + dc->breakExtra; if (breakRem > 0) { breakRem--; - deltas[i]++; + deltas[i].x++; } } - deltas[i] = INTERNAL_XWSTODS(dc, deltas[i]); - width += deltas[i]; + total.x += deltas[i].x; + 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 { @@ -1833,10 +1861,9 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, GetTextExtentPointW(hdc, reordered_str, count, &sz); 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.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: if (align & TA_UPDATECP) { - pt.x = x + xwidth; - pt.y = y - ywidth; + pt.x = x + width.x; + pt.y = y - width.y; DPtoLP(hdc, &pt, 1); MoveToEx(hdc, pt.x, pt.y, NULL); } break; case TA_CENTER: - x -= xwidth / 2; - y += ywidth / 2; + x -= width.x / 2; + y += width.y / 2; break; case TA_RIGHT: - x -= xwidth; - y += ywidth; + x -= width.x; + y += width.y; if (align & TA_UPDATECP) { 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_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) { RECT rc; rc.left = x; - rc.right = x + width; + rc.right = x + width.x; rc.top = y - tm.tmAscent; rc.bottom = y + tm.tmDescent; 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; UINT glyph; - INT span = 0, *offsets = NULL; + INT span = 0; + POINT *offsets = NULL; unsigned int i; 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; offsets = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*deltas)); - offsets[0] = 0; + offsets[0].x = offsets[0].y = 0; + if(!deltas) { SIZE tmpsz; for(j = 1; j < count; j++) { 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 { 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 (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, - glyphs, span, deltas ? deltas + i - span : NULL); + glyphs, span, deltas ? (INT*)(deltas + (i - span)) : NULL); else - dc->funcs->pExtTextOut(dc->physDev, x + offsets[i - span] * cosEsc, y - offsets[i - span] * sinEsc, - (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, - glyphs, span, deltas ? deltas + i - span : NULL); + dc->funcs->pExtTextOut(dc->physDev, x + offsets[i - span].x, y + offsets[i - span].y, + (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, + glyphs, span, deltas ? (INT*)(deltas + (i - span)) : NULL); span = 0; } SelectObject(hdc, cur_font); @@ -1955,15 +1988,15 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, if(i == count - 1) { if (PATH_IsPathOpen(dc->path)) - ret = PATH_ExtTextOut(dc, x + (offsets ? offsets[count - span] * cosEsc : 0), - y - (offsets ? offsets[count - span] * sinEsc : 0), + ret = PATH_ExtTextOut(dc, x + (offsets ? offsets[count - span].x : 0), + y + (offsets ? offsets[count - span].y : 0), (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, - glyphs, span, deltas ? deltas + count - span : NULL); + glyphs, span, deltas ? (INT*)(deltas + (count - span)) : NULL); else - ret = dc->funcs->pExtTextOut(dc->physDev, x + (offsets ? offsets[count - span] * cosEsc : 0), - y - (offsets ? offsets[count - span] * sinEsc : 0), - (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, - glyphs, span, deltas ? deltas + count - span : NULL); + ret = dc->funcs->pExtTextOut(dc->physDev, x + (offsets ? offsets[count - span].x : 0), + y + (offsets ? offsets[count - span].y : 0), + (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, + glyphs, span, deltas ? (INT*)(deltas + (count - span)) : NULL); SelectObject(hdc, orig_font); HeapFree(GetProcessHeap(), 0, offsets); } @@ -1980,10 +2013,10 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, if (PATH_IsPathOpen(dc->path)) ret = PATH_ExtTextOut(dc, x, y, (flags & ~ETO_OPAQUE), &rc, - glyphs ? glyphs : reordered_str, count, deltas); + glyphs ? glyphs : reordered_str, count, (INT*)deltas); else 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: @@ -2033,8 +2066,8 @@ done: { pts[0].x = x - underlinePos * sinEsc; pts[0].y = y - underlinePos * cosEsc; - pts[1].x = x + xwidth - underlinePos * sinEsc; - pts[1].y = y - ywidth - underlinePos * cosEsc; + pts[1].x = x + width.x - underlinePos * sinEsc; + pts[1].y = y - width.y - underlinePos * cosEsc; pts[2].x = pts[1].x + underlineWidth * sinEsc; pts[2].y = pts[1].y + underlineWidth * cosEsc; pts[3].x = pts[0].x + underlineWidth * sinEsc; @@ -2049,8 +2082,8 @@ done: { pts[0].x = x - strikeoutPos * sinEsc; pts[0].y = y - strikeoutPos * cosEsc; - pts[1].x = x + xwidth - strikeoutPos * sinEsc; - pts[1].y = y - ywidth - strikeoutPos * cosEsc; + pts[1].x = x + width.x - strikeoutPos * sinEsc; + pts[1].y = y - width.y - strikeoutPos * cosEsc; pts[2].x = pts[1].x + strikeoutWidth * sinEsc; pts[2].y = pts[1].y + strikeoutWidth * cosEsc; pts[3].x = pts[0].x + strikeoutWidth * sinEsc; @@ -2076,8 +2109,8 @@ done: hpen = SelectObject(hdc, hpen); pts[0].x = x; pts[0].y = y; - pts[1].x = x + xwidth; - pts[1].y = y - ywidth; + pts[1].x = x + width.x; + pts[1].y = y - width.y; DPtoLP(hdc, pts, 2); 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); @@ -2091,8 +2124,8 @@ done: hpen = SelectObject(hdc, hpen); pts[0].x = x; pts[0].y = y; - pts[1].x = x + xwidth; - pts[1].y = y - ywidth; + pts[1].x = x + width.x; + pts[1].y = y - width.y; DPtoLP(hdc, pts, 2); 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); diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c index 4b035d74893..37339e891f7 100644 --- a/dlls/gdi32/path.c +++ b/dlls/gdi32/path.c @@ -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) { unsigned int idx; - double cosEsc, sinEsc; - LOGFONTW lf; 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, wine_dbgstr_rect(lprc), debugstr_wn(str, count), count, dx); 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++) { 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); - 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); } if (dx) { - offset += dx[idx]; - xoff = offset * cosEsc; - yoff = offset * -sinEsc; + if(flags & ETO_PDY) + { + offset.x += dx[idx * 2]; + offset.y += dx[idx * 2 + 1]; + } + else + offset.x += dx[idx]; } else { - xoff += gm.gmCellIncX; - yoff += gm.gmCellIncY; + offset.x += gm.gmCellIncX; + offset.y += gm.gmCellIncY; } } return TRUE; diff --git a/dlls/wineps.drv/text.c b/dlls/wineps.drv/text.c index 8ed788866e3..9b4bea63edc 100644 --- a/dlls/wineps.drv/text.c +++ b/dlls/wineps.drv/text.c @@ -112,18 +112,21 @@ static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR } else { UINT i; - float dx = 0.0, dy = 0.0; - float cos_theta = cos(physDev->font.escapement * M_PI / 1800.0); - float sin_theta = sin(physDev->font.escapement * M_PI / 1800.0); + POINT offset = {0, 0}; + for(i = 0; i < count-1; i++) { - TRACE("lpDx[%d] = %d\n", i, lpDx[i]); if(physDev->font.fontloc == Download) PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1); else PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1); - dx += lpDx[i] * cos_theta; - dy -= lpDx[i] * sin_theta; - PSDRV_WriteMoveTo(physDev, x + dx, y + dy); + if(flags & ETO_PDY) + { + 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) PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1); diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 0d4ef60de92..d9735b0a87c 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -1626,8 +1626,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag AA_Type aa_type = AA_None; DIBSECTION bmp; unsigned int idx; - double cosEsc, sinEsc; - LOGFONTW lf; const WineXRenderFormat *dst_format = get_xrender_format_from_color_shifts(physDev->depth, physDev->color_shifts); Picture tile_pict = 0; @@ -1678,16 +1676,6 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag 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) { HRGN clip_region; @@ -1731,7 +1719,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag if(X11DRV_XRender_Installed) { XGlyphElt16 *elts = HeapAlloc(GetProcessHeap(), 0, sizeof(XGlyphElt16) * count); - INT offset = 0; + POINT offset = {0, 0}; POINT desired, current; int render_op = PictOpOver; Picture pict = get_xrender_picture(physDev); @@ -1769,9 +1757,15 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag } else { - offset += lpDx[idx]; - desired.x = physDev->dc_rect.left + x + offset * cosEsc; - desired.y = physDev->dc_rect.top + y - offset * sinEsc; + if(flags & ETO_PDY) + { + 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(); @@ -1785,7 +1779,7 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag wine_tsx11_unlock(); HeapFree(GetProcessHeap(), 0, elts); } else { - INT offset = 0, xoff = 0, yoff = 0; + POINT offset = {0, 0}; wine_tsx11_lock(); 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; for(idx = 0; idx < count; idx++) { - sharp_glyph_fn(physDev, physDev->dc_rect.left + x + xoff, - physDev->dc_rect.top + y + yoff, + sharp_glyph_fn(physDev, + physDev->dc_rect.left + x + offset.x, + physDev->dc_rect.top + y + offset.y, formatEntry->bitmaps[wstr[idx]], &formatEntry->gis[wstr[idx]]); - if(lpDx) { - offset += lpDx[idx]; - xoff = offset * cosEsc; - yoff = offset * -sinEsc; - } else { - xoff += formatEntry->gis[wstr[idx]].xOff; - yoff += formatEntry->gis[wstr[idx]].yOff; + if(lpDx) + { + if(flags & ETO_PDY) + { + offset.x += lpDx[idx * 2]; + offset.y += lpDx[idx * 2 + 1]; + } + else + offset.x += lpDx[idx]; + } + else + { + offset.x += formatEntry->gis[wstr[idx]].xOff; + offset.y += formatEntry->gis[wstr[idx]].yOff; } } } 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; 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; - if(lpDx) { - offset += lpDx[idx]; - cur.x = offset * cosEsc; - cur.y = offset * -sinEsc; - } else { - cur.x += formatEntry->gis[wstr[idx]].xOff; - cur.y += formatEntry->gis[wstr[idx]].yOff; + + if(lpDx) + { + if(flags & ETO_PDY) + { + cur.x += lpDx[idx * 2]; + 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, @@ -1901,21 +1911,28 @@ BOOL X11DRV_XRender_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y, UINT flag image->green_mask = visual->green_mask; image->blue_mask = visual->blue_mask; - offset = xoff = yoff = 0; for(idx = 0; idx < count; idx++) { - SmoothGlyphGray(image, xoff + image_off_x - extents.left, - yoff + image_off_y - extents.top, + SmoothGlyphGray(image, + offset.x + image_off_x - extents.left, + offset.y + image_off_y - extents.top, formatEntry->bitmaps[wstr[idx]], &formatEntry->gis[wstr[idx]], physDev->textPixel); - if(lpDx) { - offset += lpDx[idx]; - xoff = offset * cosEsc; - yoff = offset * -sinEsc; - } else { - xoff += formatEntry->gis[wstr[idx]].xOff; - yoff += formatEntry->gis[wstr[idx]].yOff; - } + if(lpDx) + { + if(flags & ETO_PDY) + { + offset.x += lpDx[idx * 2]; + offset.y += lpDx[idx * 2 + 1]; + } + 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, image_x, image_y, image_w, image_h); -- 2.11.4.GIT