From 08936ff97a18d0aefc159daa2118f0d5f345f0a5 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 24 Jan 2001 19:38:11 +0000 Subject: [PATCH] Partial implementation of world transform support. --- dlls/wineps/font.c | 7 ++- dlls/wineps/graphics.c | 31 +++++----- dlls/wineps/pen.c | 4 +- dlls/wineps/text.c | 29 ++++----- graphics/x11drv/graphics.c | 55 ++++++++++------- graphics/x11drv/pen.c | 4 +- graphics/x11drv/text.c | 54 +++++++++-------- graphics/x11drv/xfont.c | 11 +--- include/gdi.h | 121 +++++++++++++++++++++++++++++++++++++ 9 files changed, 223 insertions(+), 93 deletions(-) diff --git a/dlls/wineps/font.c b/dlls/wineps/font.c index 7ca351082ca..42f6423b566 100644 --- a/dlls/wineps/font.c +++ b/dlls/wineps/font.c @@ -109,7 +109,7 @@ HFONT16 PSDRV_FONT_SelectObject( DC * dc, HFONT16 hfont, afm = afmle->afm; physDev->font.afm = afm; - physDev->font.tm.tmHeight = YLSTODS(dc, lf->lfHeight); + physDev->font.tm.tmHeight = INTERNAL_YWSTODS(dc, lf->lfHeight); if(physDev->font.tm.tmHeight < 0) { physDev->font.tm.tmHeight *= - (afm->FullAscender - afm->Descender) / (afm->Ascender - afm->Descender); @@ -206,7 +206,6 @@ BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count, INT i; float width; - size->cy = YDSTOLS(dc, physDev->font.tm.tmHeight); width = 0.0; for(i = 0; i < count && str[i]; i++) { @@ -216,7 +215,9 @@ BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count, } width *= physDev->font.scale; TRACE("Width after scale (%f) is %f\n", physDev->font.scale, width); - size->cx = XDSTOLS(dc, width); + + size->cx = GDI_ROUND((FLOAT)width * dc->xformVport2World.eM11); + size->cy = GDI_ROUND((FLOAT)physDev->font.tm.tmHeight * dc->xformVport2World.eM22); return TRUE; } diff --git a/dlls/wineps/graphics.c b/dlls/wineps/graphics.c index 2849f224378..3e8ea03283d 100644 --- a/dlls/wineps/graphics.c +++ b/dlls/wineps/graphics.c @@ -28,9 +28,10 @@ BOOL PSDRV_LineTo(DC *dc, INT x, INT y) TRACE("%d %d\n", x, y); PSDRV_SetPen(dc); - PSDRV_WriteMoveTo(dc, XLPTODP(dc, dc->CursPosX), - YLPTODP(dc, dc->CursPosY)); - PSDRV_WriteLineTo(dc, XLPTODP(dc, x), YLPTODP(dc, y)); + PSDRV_WriteMoveTo(dc, INTERNAL_XWPTODP(dc, dc->CursPosX, dc->CursPosY), + INTERNAL_YWPTODP(dc, dc->CursPosX, dc->CursPosY)); + PSDRV_WriteLineTo(dc, INTERNAL_XWPTODP(dc, x, y), + INTERNAL_YWPTODP(dc, x, y)); PSDRV_DrawLine(dc); return TRUE; @@ -43,15 +44,15 @@ BOOL PSDRV_LineTo(DC *dc, INT x, INT y) BOOL PSDRV_Rectangle( DC *dc, INT left, INT top, INT right, INT bottom ) { - INT width = XLSTODS(dc, right - left); - INT height = YLSTODS(dc, bottom - top); - + INT width; + INT height; TRACE("%d %d - %d %d\n", left, top, right, bottom); - - PSDRV_WriteRectangle(dc, XLPTODP(dc, left), YLPTODP(dc, top), + width = INTERNAL_XWSTODS(dc, right - left); + height = INTERNAL_YWSTODS(dc, bottom - top); + PSDRV_WriteRectangle(dc, INTERNAL_XWPTODP(dc, left, top), + INTERNAL_YWPTODP(dc, left, top), width, height); - PSDRV_Brush(dc,0); PSDRV_SetPen(dc); PSDRV_DrawLine(dc); @@ -216,10 +217,10 @@ BOOL PSDRV_PolyPolyline( DC *dc, const POINT* pts, const DWORD* counts, pt = pts; for(polyline = 0; polyline < polylines; polyline++) { - PSDRV_WriteMoveTo(dc, XLPTODP(dc, pt->x), YLPTODP(dc, pt->y)); + PSDRV_WriteMoveTo(dc, INTERNAL_XWPTODP(dc, pt->x, pt->y), INTERNAL_YWPTODP(dc, pt->x, pt->y)); pt++; for(line = 1; line < counts[polyline]; line++) { - PSDRV_WriteLineTo(dc, XLPTODP(dc, pt->x), YLPTODP(dc, pt->y)); + PSDRV_WriteLineTo(dc, INTERNAL_XWPTODP(dc, pt->x, pt->y), INTERNAL_YWPTODP(dc, pt->x, pt->y)); pt++; } } @@ -250,10 +251,10 @@ BOOL PSDRV_PolyPolygon( DC *dc, const POINT* pts, const INT* counts, pt = pts; for(polygon = 0; polygon < polygons; polygon++) { - PSDRV_WriteMoveTo(dc, XLPTODP(dc, pt->x), YLPTODP(dc, pt->y)); + PSDRV_WriteMoveTo(dc, INTERNAL_XWPTODP(dc, pt->x, pt->y), INTERNAL_YWPTODP(dc, pt->x, pt->y)); pt++; for(line = 1; line < counts[polygon]; line++) { - PSDRV_WriteLineTo(dc, XLPTODP(dc, pt->x), YLPTODP(dc, pt->y)); + PSDRV_WriteLineTo(dc, INTERNAL_XWPTODP(dc, pt->x, pt->y), INTERNAL_YWPTODP(dc, pt->x, pt->y)); pt++; } PSDRV_WriteClosePath(dc); @@ -286,8 +287,8 @@ COLORREF PSDRV_SetPixel( DC *dc, INT x, INT y, COLORREF color ) PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev; PSCOLOR pscolor; - x = XLPTODP(dc, x); - y = YLPTODP(dc, y); + x = INTERNAL_XWPTODP(dc, x, y); + y = INTERNAL_YWPTODP(dc, x, y); PSDRV_WriteRectangle( dc, x, y, 0, 0 ); PSDRV_CreateColor( physDev, &pscolor, color ); diff --git a/dlls/wineps/pen.c b/dlls/wineps/pen.c index 45ffc2d8cb3..67106208430 100644 --- a/dlls/wineps/pen.c +++ b/dlls/wineps/pen.c @@ -28,7 +28,7 @@ extern HPEN PSDRV_PEN_SelectObject( DC * dc, HPEN hpen, PENOBJ * pen ) TRACE("hpen = %08x colour = %08lx\n", hpen, pen->logpen.lopnColor); dc->hPen = hpen; - physDev->pen.width = XLSTODS(dc, pen->logpen.lopnWidth.x); + physDev->pen.width = INTERNAL_XWSTODS(dc, pen->logpen.lopnWidth.x); if(physDev->pen.width < 0) physDev->pen.width = -physDev->pen.width; @@ -90,5 +90,3 @@ BOOL PSDRV_SetPen(DC *dc) return TRUE; } - - diff --git a/dlls/wineps/text.c b/dlls/wineps/text.c index 514b26b0da8..0c1fc4cf0e9 100644 --- a/dlls/wineps/text.c +++ b/dlls/wineps/text.c @@ -36,10 +36,10 @@ BOOL PSDRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags, /* set clipping and/or draw background */ if ((flags & (ETO_CLIPPED | ETO_OPAQUE)) && (lprect != NULL)) { - rect.left = XLPTODP(dc, lprect->left); - rect.right = XLPTODP(dc, lprect->right); - rect.top = YLPTODP(dc, lprect->top); - rect.bottom = YLPTODP(dc, lprect->bottom); + rect.left = INTERNAL_XWPTODP(dc, lprect->left, lprect->top); + rect.right = INTERNAL_XWPTODP(dc, lprect->right, lprect->bottom); + rect.top = INTERNAL_YWPTODP(dc, lprect->left, lprect->top); + rect.bottom = INTERNAL_YWPTODP(dc, lprect->right, lprect->bottom); PSDRV_WriteGSave(dc); PSDRV_WriteRectangle(dc, rect.left, rect.top, rect.right - rect.left, @@ -92,17 +92,17 @@ static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCWSTR str, UINT count, y = dc->CursPosY; } - x = XLPTODP(dc, x); - y = YLPTODP(dc, y); + x = INTERNAL_XWPTODP(dc, x, y); + y = INTERNAL_YWPTODP(dc, x, y); GetTextExtentPoint32W(dc->hSelf, str, count, &sz); - sz.cx = XLSTODS(dc, sz.cx); - sz.cy = YLSTODS(dc, sz.cy); - + sz.cx = INTERNAL_XWSTODS(dc, sz.cx); + sz.cy = INTERNAL_YWSTODS(dc, sz.cy); switch(dc->textAlign & (TA_LEFT | TA_CENTER | TA_RIGHT) ) { case TA_LEFT: - if(dc->textAlign & TA_UPDATECP) - dc->CursPosX = XDPTOLP(dc, x + sz.cx); + if(dc->textAlign & TA_UPDATECP) { + dc->CursPosX = INTERNAL_XDPTOWP(dc, x + sz.cx, y); + } break; case TA_CENTER: @@ -111,8 +111,9 @@ static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCWSTR str, UINT count, case TA_RIGHT: x -= sz.cx; - if(dc->textAlign & TA_UPDATECP) - dc->CursPosX = XDPTOLP(dc, x); + if(dc->textAlign & TA_UPDATECP) { + dc->CursPosX = INTERNAL_XDPTOWP(dc, x, y); + } break; } @@ -166,7 +167,7 @@ static BOOL PSDRV_Text(DC *dc, INT x, INT y, LPCWSTR str, UINT count, /* Get the width of the text */ PSDRV_GetTextExtentPoint(dc, strbuf, lstrlenW(strbuf), &size); - size.cx = XLSTODS(dc, size.cx); + size.cx = INTERNAL_XWSTODS(dc, size.cx); /* Do the underline */ diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c index a6455c4be07..1ebd62dda66 100644 --- a/graphics/x11drv/graphics.c +++ b/graphics/x11drv/graphics.c @@ -5,7 +5,7 @@ */ /* - * FIXME: none of these functions obey the GM_ADVANCED + * FIXME: only some of these functions obey the GM_ADVANCED * graphics mode */ @@ -291,15 +291,26 @@ BOOL X11DRV_LineTo( DC *dc, INT x, INT y ) { X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; + POINT start; + POINT end; if (X11DRV_SetupGCForPen( dc )) { /* Update the pixmap from the DIB section */ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE); - TSXDrawLine(display, physDev->drawable, physDev->gc, - dc->DCOrgX + XLPTODP( dc, dc->CursPosX ), - dc->DCOrgY + YLPTODP( dc, dc->CursPosY ), - dc->DCOrgX + XLPTODP( dc, x ), - dc->DCOrgY + YLPTODP( dc, y ) ); + + start.x = dc->CursPosX; + start.y = dc->CursPosY; + end.x = x; + end.y = y; + INTERNAL_LPTODP(dc,&start); + INTERNAL_LPTODP(dc,&end); + + TSXDrawLine(display, physDev->drawable, physDev->gc, + dc->DCOrgX + start.x, + dc->DCOrgY + start.y, + dc->DCOrgX + end.x, + dc->DCOrgY + end.y); + /* Update the DIBSection from the pixmap */ X11DRV_UnlockDIBSection(dc, TRUE); } @@ -581,10 +592,10 @@ X11DRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom) TRACE("(%d %d %d %d)\n", left, top, right, bottom); - left = XLPTODP( dc, left ); - top = YLPTODP( dc, top ); - right = XLPTODP( dc, right ); - bottom = YLPTODP( dc, bottom ); + left = INTERNAL_XWPTODP( dc, left, top ); + top = INTERNAL_YWPTODP( dc, left, top ); + right = INTERNAL_XWPTODP( dc, right, bottom ); + bottom = INTERNAL_YWPTODP( dc, right, bottom ); if ((left == right) || (top == bottom)) return TRUE; @@ -850,8 +861,8 @@ X11DRV_SetPixel( DC *dc, INT x, INT y, COLORREF color ) Pixel pixel; X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; - x = dc->DCOrgX + XLPTODP( dc, x ); - y = dc->DCOrgY + YLPTODP( dc, y ); + x = dc->DCOrgX + INTERNAL_XWPTODP( dc, x, y ); + y = dc->DCOrgY + INTERNAL_YWPTODP( dc, x, y ); pixel = X11DRV_PALETTE_ToPhysical( dc, color ); TSXSetForeground( display, physDev->gc, pixel ); @@ -877,8 +888,8 @@ X11DRV_GetPixel( DC *dc, INT x, INT y ) int pixel; X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; - x = dc->DCOrgX + XLPTODP( dc, x ); - y = dc->DCOrgY + YLPTODP( dc, y ); + x = dc->DCOrgX + INTERNAL_XWPTODP( dc, x, y ); + y = dc->DCOrgY + INTERNAL_YWPTODP( dc, x, y ); wine_tsx11_lock(); if (dc->flags & DC_MEMORY) { @@ -973,8 +984,8 @@ X11DRV_Polyline( DC *dc, const POINT* pt, INT count ) } for (i = 0; i < count; i++) { - points[i].x = dc->DCOrgX + XLPTODP( dc, pt[i].x ); - points[i].y = dc->DCOrgY + YLPTODP( dc, pt[i].y ); + points[i].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt[i].x, pt[i].y ); + points[i].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt[i].x, pt[i].y ); } if (X11DRV_SetupGCForPen ( dc )) @@ -1013,8 +1024,8 @@ X11DRV_Polygon( DC *dc, const POINT* pt, INT count ) } for (i = 0; i < count; i++) { - points[i].x = dc->DCOrgX + XLPTODP( dc, pt[i].x ); - points[i].y = dc->DCOrgY + YLPTODP( dc, pt[i].y ); + points[i].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt[i].x, pt[i].y ); + points[i].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt[i].x, pt[i].y ); } points[count] = points[0]; @@ -1078,8 +1089,8 @@ X11DRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons) { for (j = 0; j < counts[i]; j++) { - points[j].x = dc->DCOrgX + XLPTODP( dc, pt->x ); - points[j].y = dc->DCOrgY + YLPTODP( dc, pt->y ); + points[j].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt->x, pt->y ); + points[j].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt->x, pt->y ); pt++; } points[j] = points[0]; @@ -1122,8 +1133,8 @@ X11DRV_PolyPolyline( DC *dc, const POINT* pt, const DWORD* counts, DWORD polylin { for (j = 0; j < counts[i]; j++) { - points[j].x = dc->DCOrgX + XLPTODP( dc, pt->x ); - points[j].y = dc->DCOrgY + YLPTODP( dc, pt->y ); + points[j].x = dc->DCOrgX + INTERNAL_XWPTODP( dc, pt->x, pt->y ); + points[j].y = dc->DCOrgY + INTERNAL_YWPTODP( dc, pt->x, pt->y ); pt++; } TSXDrawLines( display, physDev->drawable, physDev->gc, diff --git a/graphics/x11drv/pen.c b/graphics/x11drv/pen.c index 7d789a62909..c037c93929d 100644 --- a/graphics/x11drv/pen.c +++ b/graphics/x11drv/pen.c @@ -33,8 +33,8 @@ HPEN X11DRV_PEN_SelectObject( DC * dc, HPEN hpen, PENOBJ * pen ) physDev->pen.endcap = pen->logpen.lopnStyle & PS_ENDCAP_MASK; physDev->pen.linejoin = pen->logpen.lopnStyle & PS_JOIN_MASK; - physDev->pen.width = (pen->logpen.lopnWidth.x * dc->vportExtX + - dc->wndExtX / 2) / dc->wndExtX; + physDev->pen.width = GDI_ROUND((FLOAT)pen->logpen.lopnWidth.x * + dc->xformWorld2Vport.eM11 * 0.5); if (physDev->pen.width < 0) physDev->pen.width = -physDev->pen.width; if (physDev->pen.width == 1) physDev->pen.width = 0; /* Faster */ physDev->pen.pixel = X11DRV_PALETTE_ToPhysical( dc, pen->logpen.lopnColor ); diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c index 98b01155d2a..be159f88108 100644 --- a/graphics/x11drv/text.c +++ b/graphics/x11drv/text.c @@ -87,24 +87,24 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags, return FALSE; if (!X11DRV_GetTextExtentPoint( dc, wstr, count, &sz )) return FALSE; - rect.left = XLPTODP( dc, x ); - rect.right = XLPTODP( dc, x+sz.cx ); - rect.top = YLPTODP( dc, y ); - rect.bottom = YLPTODP( dc, y+sz.cy ); + rect.left = INTERNAL_XWPTODP( dc, x, y ); + rect.right = INTERNAL_XWPTODP( dc, x+sz.cx, y+sz.cy ); + rect.top = INTERNAL_YWPTODP( dc, x, y ); + rect.bottom = INTERNAL_YWPTODP( dc, x+sz.cx, y+sz.cy ); } else { - rect.left = XLPTODP( dc, lprect->left ); - rect.right = XLPTODP( dc, lprect->right ); - rect.top = YLPTODP( dc, lprect->top ); - rect.bottom = YLPTODP( dc, lprect->bottom ); + rect.left = INTERNAL_XWPTODP( dc, lprect->left, lprect->top ); + rect.right = INTERNAL_XWPTODP( dc, lprect->right, lprect->bottom ); + rect.top = INTERNAL_YWPTODP( dc, lprect->left, lprect->top ); + rect.bottom = INTERNAL_YWPTODP( dc, lprect->right, lprect->bottom ); } if (rect.right < rect.left) SWAP_INT( rect.left, rect.right ); if (rect.bottom < rect.top) SWAP_INT( rect.top, rect.bottom ); } - x = XLPTODP( dc, x ); - y = YLPTODP( dc, y ); + x = INTERNAL_XWPTODP( dc, x, y ); + y = INTERNAL_YWPTODP( dc, x, y ); TRACE("\treal coord: x=%i, y=%i, rect=(%d,%d - %d,%d)\n", x, y, rect.left, rect.top, rect.right, rect.bottom); @@ -126,16 +126,15 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags, if (lpDx) /* have explicit character cell x offsets in logical coordinates */ { - int extra = dc->wndExtX / 2; for (i = width = 0; i < count; i++) width += lpDx[i]; - width = (width * dc->vportExtX + extra ) / dc->wndExtX; + width = INTERNAL_XWSTODS(dc, width); } else { SIZE sz; if (!X11DRV_GetTextExtentPoint( dc, wstr, count, &sz )) return FALSE; - width = XLSTODS(dc, sz.cx); + width = INTERNAL_XWSTODS(dc, sz.cx); } ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent; descent = pfo->lpX11Trans ? pfo->lpX11Trans->descent : font->descent; @@ -148,16 +147,16 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags, { case TA_LEFT: if (dc->textAlign & TA_UPDATECP) { - dc->CursPosX = XDPTOLP( dc, x + xwidth ); - dc->CursPosY = YDPTOLP( dc, y - ywidth ); + dc->CursPosX = INTERNAL_XDPTOWP( dc, x + xwidth, y - ywidth ); + dc->CursPosY = INTERNAL_YDPTOWP( dc, x + xwidth, y - ywidth ); } break; case TA_RIGHT: x -= xwidth; y += ywidth; if (dc->textAlign & TA_UPDATECP) { - dc->CursPosX = XDPTOLP( dc, x ); - dc->CursPosY = YDPTOLP( dc, y ); + dc->CursPosX = INTERNAL_XDPTOWP( dc, x, y ); + dc->CursPosY = INTERNAL_YDPTOWP( dc, x, y ); } break; case TA_CENTER: @@ -251,9 +250,11 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags, delta = i = 0; if( lpDx ) /* explicit character widths */ { - const long ve_we = dc->vportExtX*0x10000 / dc->wndExtX; + long ve_we; unsigned short err = 0; + ve_we = (LONG)(dc->xformWorld2Vport.eM11 * 0x10000); + while (i < count) { /* initialize text item with accumulated delta */ @@ -329,7 +330,9 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags, pfo, display, physDev->drawable, physDev->gc, x_i, y_i, &str2b[i], 1); if (lpDx) - offset += XLSTODS(dc, lpDx[i]); + { + offset += INTERNAL_XWSTODS(dc, lpDx[i]); + } else { offset += (double) (font->per_char ? @@ -408,10 +411,11 @@ BOOL X11DRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count, int info_width; X11DRV_cptable[pfo->fi->cptable].pTextExtents( pfo, p, count, &dir, &ascent, &descent, &info_width ); - size->cx = abs((info_width + dc->breakRem + count * - dc->charExtra) * dc->wndExtX / dc->vportExtX); - size->cy = abs((pfo->fs->ascent + pfo->fs->descent) * - dc->wndExtY / dc->vportExtY); + + size->cx = abs((info_width + dc->breakRem + count * + dc->charExtra) * (int)dc->xformWorld2Vport.eM11); + size->cy = abs((pfo->fs->ascent + pfo->fs->descent) * + (int)dc->xformWorld2Vport.eM22); } else { INT i; float x = 0.0, y = 0.0; @@ -426,8 +430,8 @@ BOOL X11DRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count, x *= pfo->lpX11Trans->pixelsize / 1000.0; y *= pfo->lpX11Trans->pixelsize / 1000.0; size->cx = fabs((x + dc->breakRem + count * dc->charExtra) * - dc->wndExtX / dc->vportExtX); - size->cy = fabs(y * dc->wndExtY / dc->vportExtY); + dc->xformVport2World.eM11); + size->cy = fabs(y * dc->xformVport2World.eM22); } size->cx *= pfo->rescale; size->cy *= pfo->rescale; diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c index 88acae127c3..3ab0e96aa44 100644 --- a/graphics/x11drv/xfont.c +++ b/graphics/x11drv/xfont.c @@ -3055,20 +3055,13 @@ HFONT X11DRV_FONT_SelectObject( DC* dc, HFONT hfont, FONTOBJ* font ) /* FIXME - check that the other drivers do this correctly */ if (lf.lfWidth) { - int vpt = abs(dc->vportExtX); - int wnd = abs(dc->wndExtX); - lf.lfWidth = (abs(lf.lfWidth) * vpt + (wnd>>1))/wnd; + lf.lfWidth = GDI_ROUND((FLOAT)lf.lfWidth * fabs(dc->xformWorld2Vport.eM11)); if (lf.lfWidth == 0) lf.lfWidth = 1; /* Minimum width */ } if (lf.lfHeight) { - int vpt = abs(dc->vportExtY); - int wnd = abs(dc->wndExtY); - if (lf.lfHeight > 0) - lf.lfHeight = (lf.lfHeight * vpt + (wnd>>1))/wnd; - else - lf.lfHeight = (lf.lfHeight * vpt - (wnd>>1))/wnd; + lf.lfHeight = GDI_ROUND((FLOAT)lf.lfHeight * fabs(dc->xformWorld2Vport.eM22)); if (lf.lfHeight == 0) lf.lfHeight = MIN_FONT_SIZE; diff --git a/include/gdi.h b/include/gdi.h index 6dbc8a7acfc..b0f6ccd6e90 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -413,6 +413,73 @@ static inline void WINE_UNUSED INTERNAL_LPTODP(DC *dc, LPPOINT point) point->y = GDI_ROUND(floatPoint.y); } + +/* Performs a world-to-viewport transformation on the specified point (which + * is in integer format). + */ +static inline INT WINE_UNUSED INTERNAL_XWPTODP(DC *dc, INT x, INT y) +{ + FLOAT_POINT floatPoint; + + /* Perform operation with floating point */ + floatPoint.x=(FLOAT)x; + floatPoint.y=(FLOAT)y; + INTERNAL_LPTODP_FLOAT(dc, &floatPoint); + + /* Round to integers */ + return GDI_ROUND(floatPoint.x); +} + +/* Performs a world-to-viewport transformation on the specified point (which + * is in integer format). + */ +static inline INT WINE_UNUSED INTERNAL_YWPTODP(DC *dc, INT x, INT y) +{ + FLOAT_POINT floatPoint; + + /* Perform operation with floating point */ + floatPoint.x=(FLOAT)x; + floatPoint.y=(FLOAT)y; + INTERNAL_LPTODP_FLOAT(dc, &floatPoint); + + /* Round to integers */ + return GDI_ROUND(floatPoint.y); +} + + +/* Performs a viewport-to-world transformation on the specified point (which + * is in integer format). + */ +static inline INT WINE_UNUSED INTERNAL_XDPTOWP(DC *dc, INT x, INT y) +{ + FLOAT_POINT floatPoint; + + /* Perform operation with floating point */ + floatPoint.x=(FLOAT)x; + floatPoint.y=(FLOAT)y; + INTERNAL_DPTOLP_FLOAT(dc, &floatPoint); + + /* Round to integers */ + return GDI_ROUND(floatPoint.x); +} + +/* Performs a viewport-to-world transformation on the specified point (which + * is in integer format). + */ +static inline INT WINE_UNUSED INTERNAL_YDPTOWP(DC *dc, INT x, INT y) +{ + FLOAT_POINT floatPoint; + + /* Perform operation with floating point */ + floatPoint.x=(FLOAT)x; + floatPoint.y=(FLOAT)y; + INTERNAL_DPTOLP_FLOAT(dc, &floatPoint); + + /* Round to integers */ + return GDI_ROUND(floatPoint.y); +} + + #define XDPTOLP(dc,x) \ (MulDiv(((x)-(dc)->vportOrgX), (dc)->wndExtX, (dc)->vportExtX) + (dc)->wndOrgX) #define YDPTOLP(dc,y) \ @@ -422,6 +489,60 @@ static inline void WINE_UNUSED INTERNAL_LPTODP(DC *dc, LPPOINT point) #define YLPTODP(dc,y) \ (MulDiv(((y)-(dc)->wndOrgY), (dc)->vportExtY, (dc)->wndExtY) + (dc)->vportOrgY) + + + /* World -> Device size conversion */ + +/* Performs a world-to-viewport transformation on the specified width (which + * is in floating point format). + */ +static inline void WINE_UNUSED INTERNAL_XWSTODS_FLOAT(DC *dc, FLOAT *width) +{ + /* Perform the transformation */ + *width = *width * dc->xformWorld2Vport.eM11; +} + +/* Performs a world-to-viewport transformation on the specified width (which + * is in integer format). + */ +static inline INT WINE_UNUSED INTERNAL_XWSTODS(DC *dc, INT width) +{ + FLOAT floatWidth; + + /* Perform operation with floating point */ + floatWidth = (FLOAT)width; + INTERNAL_XWSTODS_FLOAT(dc, &floatWidth); + + /* Round to integers */ + return GDI_ROUND(floatWidth); +} + + +/* Performs a world-to-viewport transformation on the specified size (which + * is in floating point format). + */ +static inline void WINE_UNUSED INTERNAL_YWSTODS_FLOAT(DC *dc, FLOAT *height) +{ + /* Perform the transformation */ + *height = *height * dc->xformWorld2Vport.eM22; +} + +/* Performs a world-to-viewport transformation on the specified size (which + * is in integer format). + */ +static inline INT WINE_UNUSED INTERNAL_YWSTODS(DC *dc, INT height) +{ + FLOAT floatHeight; + + /* Perform operation with floating point */ + floatHeight = (FLOAT)height; + INTERNAL_XWSTODS_FLOAT(dc, &floatHeight); + + /* Round to integers */ + return GDI_ROUND(floatHeight); +} + + /* Device <-> logical size conversion */ #define XDSTOLS(dc,x) \