Implement Get/Set EMFTransform
Warren_Baird at cimmetry.com
Warren_Baird at cimmetry.com
Thu Feb 6 08:52:49 CST 2003
ChangeLog:
1. Implementation of GetEMFTransform and SetEMFTransform Windows API
functions.
2. Fix EnumEnhMetaFile so it renders properly inside the limits
of the given rectangle input parameter.
Description:
1. GetEMFTransform and SetEMFTransform have been implemented by storing an
additional XFORM inside the DC structure to map an EMF to a destination
rectangle.
2. Fixing EnumEnhMetaFile relies on the previous GetEMFTransform and
SetEMFTransform functions. The EMF mapping transformation is combined
to the Wnd2VPort transformation.
Warren Baird : Warren_Baird at cimmetry.com
Xavier Servettaz
diff -ur clean/wine/include/wingdi.h wine/include/wingdi.h
--- clean/wine/include/wingdi.h Wed Jan 29 15:31:07 2003
+++ wine/include/wingdi.h Mon Feb 3 18:54:12 2003
@@ -3255,6 +3255,7 @@
COLORREF WINAPI GetDCPenColor(HDC);
UINT WINAPI GetDIBColorTable(HDC,UINT,UINT,RGBQUAD*);
INT WINAPI GetDIBits(HDC,HBITMAP,UINT,UINT,LPVOID,LPBITMAPINFO,UINT);
+BOOL WINAPI GetEMFTransform(HDC, LPXFORM);
HENHMETAFILE WINAPI GetEnhMetaFileA(LPCSTR);
HENHMETAFILE WINAPI GetEnhMetaFileW(LPCWSTR);
#define GetEnhMetaFile WINELIB_NAME_AW(GetEnhMetaFile)
@@ -3413,6 +3414,7 @@
INT WINAPI SetDIBits(HDC,HBITMAP,UINT,UINT,LPCVOID,const
BITMAPINFO*,UINT);
INT WINAPI SetDIBitsToDevice(HDC,INT,INT,DWORD,DWORD,INT,
INT,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT);
+BOOL WINAPI SetEMFTransform(HDC, const XFORM *);
HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT,const BYTE *);
INT WINAPI SetGraphicsMode(HDC,INT);
INT WINAPI SetICMMode(HDC,INT);
diff -ur clean/wine/include/gdi.h wine/include/gdi.h
--- clean/wine/include/gdi.h Wed Jan 29 15:31:05 2003
+++ wine/include/gdi.h Mon Feb 3 10:55:03 2003
@@ -159,6 +159,7 @@
XFORM xformWorld2Wnd; /* World-to-window transformation */
XFORM xformWorld2Vport; /* World-to-viewport transformation */
XFORM xformVport2World; /* Inverse of the above transformation */
+ XFORM xformEMFmapping; /* Map an EMF to destination rectangle*/
BOOL vport2WorldValid; /* Is xformVport2World valid? */
} DC;
diff -ur clean/wine/objects/dc.c wine/objects/dc.c
--- clean/wine/objects/dc.c Wed Jan 29 15:31:13 2003
+++ wine/objects/dc.c Mon Feb 3 10:33:17 2003
@@ -119,6 +119,7 @@
dc->xformWorld2Wnd.eDy = 0.0f;
dc->xformWorld2Vport = dc->xformWorld2Wnd;
dc->xformVport2World = dc->xformWorld2Wnd;
+ dc->xformEMFmapping = dc->xformWorld2Wnd;
dc->vport2WorldValid = TRUE;
PATH_InitGdiPath(&dc->path);
return dc;
@@ -256,9 +257,14 @@
xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY -
scaleY * (FLOAT)dc->wndOrgY;
+ XFORM additionalTransform;
/* Combine with the world transformation */
- CombineTransform( &dc->xformWorld2Vport, &dc->xformWorld2Wnd,
- &xformWnd2Vport );
+ CombineTransform(&additionalTransform,
+ &dc->xformWorld2Wnd,
+ &xformWnd2Vport );
+ CombineTransform(&dc->xformWorld2Vport,
+ &additionalTransform,
+ &dc->xformEMFmapping );
/* Create inverse of world-to-viewport transformation */
dc->vport2WorldValid = DC_InvertXform( &dc->xformWorld2Vport,
@@ -314,6 +320,7 @@
newdc->xformWorld2Wnd = dc->xformWorld2Wnd;
newdc->xformWorld2Vport = dc->xformWorld2Vport;
newdc->xformVport2World = dc->xformVport2World;
+ newdc->xformEMFmapping = dc->xformEMFmapping;
newdc->vport2WorldValid = dc->vport2WorldValid;
newdc->wndOrgX = dc->wndOrgX;
newdc->wndOrgY = dc->wndOrgY;
@@ -402,6 +409,7 @@
dc->xformWorld2Wnd = dcs->xformWorld2Wnd;
dc->xformWorld2Vport = dcs->xformWorld2Vport;
dc->xformVport2World = dcs->xformVport2World;
+ dc->xformEMFmapping = dcs->xformEMFmapping;
dc->vport2WorldValid = dcs->vport2WorldValid;
dc->wndOrgX = dcs->wndOrgX;
@@ -976,6 +984,35 @@
return nOldDirection;
}
+/***********************************************************************
+ * GetEMFTransform (GDI32.@)
+ */
+BOOL WINAPI GetEMFTransform( HDC hdc, LPXFORM xform )
+{
+ DC * dc;
+ if (!xform) return FALSE;
+ if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
+ *xform = dc->xformEMFmapping;
+ GDI_ReleaseObj( hdc );
+ return TRUE;
+}
+
+/***********************************************************************
+ * SetEMFTransform (GDI32.@)
+ */
+BOOL WINAPI SetEMFTransform( HDC hdc, const XFORM *xform )
+{
+ BOOL ret = FALSE;
+ DC *dc = DC_GetDCPtr( hdc );
+ if (!dc) { return FALSE;}
+ if (xform) {
+ dc->xformEMFmapping = *xform;
+ DC_UpdateXforms( dc );
+ ret = TRUE;
+ }
+ GDI_ReleaseObj( hdc );
+ return ret;
+}
/***********************************************************************
* GetWorldTransform (GDI32.@)
diff -ur clean/wine/objects/enhmetafile.c wine/objects/enhmetafile.c
--- clean/wine/objects/enhmetafile.c Mon Feb 3 19:07:49 2003
+++ wine/objects/enhmetafile.c Mon Feb 3 19:15:45 2003
@@ -418,18 +418,12 @@
}
case EMR_SETWINDOWORGEX:
{
- XFORM xform;
- PEMRSETWINDOWORGEX pSetWindowOrgEx = (PEMRSETWINDOWORGEX) mr;
-
- xform.eM11 = 1;
- xform.eM12 = 0;
- xform.eM21 = 0;
- xform.eM22 = 1;
- xform.eDx = -pSetWindowOrgEx->ptlOrigin.x;
- xform.eDy = -pSetWindowOrgEx->ptlOrigin.y;
-
- ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
- break;
+ PEMRSETWINDOWORGEX pSetWindowOrgEx = (PEMRSETWINDOWORGEX) mr;
+ SetWindowOrgEx(hdc,
+ pSetWindowOrgEx->ptlOrigin.x,
+ pSetWindowOrgEx->ptlOrigin.y,
+ NULL);
+ break;
}
case EMR_SETWINDOWEXTEX:
{
@@ -1608,11 +1602,15 @@
HANDLETABLE *ht;
INT savedMode = 0;
FLOAT xSrcPixSize, ySrcPixSize, xscale, yscale;
- XFORM savedXform, xform;
+ XFORM savedXform, xform, savedEMFXform;
HPEN hPen = NULL;
HBRUSH hBrush = NULL;
HFONT hFont = NULL;
POINT pt[2];
+ INT oldvportExtX = 0;
+ INT oldvportExtY = 0;
+ INT oldvportOrgX = 0;
+ INT oldvportOrgY = 0;
if(!lpRect)
{
@@ -1660,10 +1658,59 @@
savedMode = SetGraphicsMode(hdc, GM_ADVANCED);
GetWorldTransform(hdc, &savedXform);
+ GetEMFTransform(hdc, &savedEMFXform);
- if (!ModifyWorldTransform(hdc, &xform, MWT_RIGHTMULTIPLY)) {
- ERR("World transform failed!\n");
+ /* here we combine "out-of-EMF" Wnd2Vport transformation with
+ the one mapping to the selected output rectangle.
+ Since they both will be included in the additionalTransform, we ensure
+ Identity is set to xformWnd2Vport before playing the EMF
+
+ rem: "out-of-EMF" means any transform that is already set for this DC.
+ */
+
+ DC *dc = DC_GetDCPtr (hdc);
+ if (!dc) {
+ FIXME ("ERROR failed to get DC ptr while playing enhmetafile!/n");
+ return FALSE;
}
+
+ XFORM xformWnd2Vport;
+ XFORM additionalTransform;
+ FLOAT scaleX, scaleY;
+
+ /* Construct a transformation to do the window-to-viewport conversion */
+ scaleX = (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX;
+ scaleY = (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY;
+ xformWnd2Vport.eM11 = scaleX;
+ xformWnd2Vport.eM12 = 0.0;
+ xformWnd2Vport.eM21 = 0.0;
+ xformWnd2Vport.eM22 = scaleY;
+ xformWnd2Vport.eDx = (FLOAT)dc->vportOrgX -
+ scaleX * (FLOAT)dc->wndOrgX;
+ xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY -
+ scaleY * (FLOAT)dc->wndOrgY;
+
+ /* save old values */
+ oldvportExtX = dc->vportExtX;
+ oldvportExtY = dc->vportExtY;
+ oldvportOrgX = dc->vportOrgX;
+ oldvportOrgY = dc->vportOrgY;
+
+ /* set identity */
+ dc->vportExtX = dc->wndExtX;
+ dc->vportExtY = dc->wndExtY;
+ dc->vportOrgX = dc->wndOrgX;
+ dc->vportOrgY = dc->wndOrgY;
+
+ /* release DC */
+ GDI_ReleaseObj(hdc);
+
+ /* combine transformations */
+ CombineTransform(&additionalTransform,
+ &xform,
+ &xformWnd2Vport);
+
+ SetEMFTransform(hdc, &additionalTransform);
/* save the current pen, brush and font */
hPen = GetCurrentObject(hdc, OBJ_PEN);
@@ -1696,7 +1743,22 @@
SelectObject(hdc, hPen);
SelectObject(hdc, hFont);
+ /* reset vport values */
+ DC *dc = DC_GetDCPtr (hdc);
+ if (!dc) {
+ FIXME ("ERROR failed to get DC ptr while playing enhmetafile!/n");
+ return FALSE;
+ }
+ dc->vportExtX = oldvportExtX;
+ dc->vportExtY = oldvportExtY;
+ dc->vportOrgX = oldvportOrgX;
+ dc->vportOrgY = oldvportOrgY;
+ /* release DC */
+ GDI_ReleaseObj(hdc);
+
SetWorldTransform(hdc, &savedXform);
+ SetEMFTransform(hdc, &savedEMFXform);
+
if (savedMode)
SetGraphicsMode(hdc, savedMode);
}
More information about the wine-patches
mailing list