Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c871d9a8
Commit
c871d9a8
authored
Apr 28, 2008
by
Dmitry Timoshkov
Committed by
Alexandre Julliard
Apr 28, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdi32: Save/restore internal EMF playing state on EMR_SAVEDC/EMR_RESTOREDC, add a test for this.
parent
d01438bd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
355 additions
and
99 deletions
+355
-99
enhmetafile.c
dlls/gdi32/enhmetafile.c
+148
-96
metafile.c
dlls/gdi32/tests/metafile.c
+207
-3
No files found.
dlls/gdi32/enhmetafile.c
View file @
c871d9a8
...
...
@@ -491,10 +491,9 @@ UINT WINAPI GetEnhMetaFileBits(
return
size
;
}
typedef
struct
enum_emh_data
typedef
struct
EMF_dc_state
{
INT
mode
;
XFORM
init_transform
;
XFORM
world_transform
;
INT
wndOrgX
;
INT
wndOrgY
;
...
...
@@ -504,6 +503,15 @@ typedef struct enum_emh_data
INT
vportOrgY
;
INT
vportExtX
;
INT
vportExtY
;
struct
EMF_dc_state
*
next
;
}
EMF_dc_state
;
typedef
struct
enum_emh_data
{
XFORM
init_transform
;
EMF_dc_state
state
;
INT
save_level
;
EMF_dc_state
*
saved_state
;
}
enum_emh_data
;
#define ENUM_GET_PRIVATE_DATA(ht) \
...
...
@@ -519,16 +527,16 @@ static void EMF_Update_MF_Xform(HDC hdc, const enum_emh_data *info)
XFORM
mapping_mode_trans
,
final_trans
;
FLOAT
scaleX
,
scaleY
;
scaleX
=
(
FLOAT
)
info
->
vportExtX
/
(
FLOAT
)
info
->
wndExtX
;
scaleY
=
(
FLOAT
)
info
->
vportExtY
/
(
FLOAT
)
info
->
wndExtY
;
scaleX
=
(
FLOAT
)
info
->
state
.
vportExtX
/
(
FLOAT
)
info
->
state
.
wndExtX
;
scaleY
=
(
FLOAT
)
info
->
state
.
vportExtY
/
(
FLOAT
)
info
->
state
.
wndExtY
;
mapping_mode_trans
.
eM11
=
scaleX
;
mapping_mode_trans
.
eM12
=
0
.
0
;
mapping_mode_trans
.
eM21
=
0
.
0
;
mapping_mode_trans
.
eM22
=
scaleY
;
mapping_mode_trans
.
eDx
=
(
FLOAT
)
info
->
vportOrgX
-
scaleX
*
(
FLOAT
)
info
->
wndOrgX
;
mapping_mode_trans
.
eDy
=
(
FLOAT
)
info
->
vportOrgY
-
scaleY
*
(
FLOAT
)
info
->
wndOrgY
;
mapping_mode_trans
.
eDx
=
(
FLOAT
)
info
->
state
.
vportOrgX
-
scaleX
*
(
FLOAT
)
info
->
state
.
wndOrgX
;
mapping_mode_trans
.
eDy
=
(
FLOAT
)
info
->
state
.
vportOrgY
-
scaleY
*
(
FLOAT
)
info
->
state
.
wndOrgY
;
CombineTransform
(
&
final_trans
,
&
info
->
world_transform
,
&
mapping_mode_trans
);
CombineTransform
(
&
final_trans
,
&
info
->
state
.
world_transform
,
&
mapping_mode_trans
);
CombineTransform
(
&
final_trans
,
&
final_trans
,
&
info
->
init_transform
);
if
(
!
SetWorldTransform
(
hdc
,
&
final_trans
))
...
...
@@ -537,6 +545,40 @@ static void EMF_Update_MF_Xform(HDC hdc, const enum_emh_data *info)
}
}
static
void
EMF_RestoreDC
(
enum_emh_data
*
info
,
INT
level
)
{
if
(
abs
(
level
)
>
info
->
save_level
||
level
==
0
)
return
;
if
(
level
<
0
)
level
=
info
->
save_level
+
level
+
1
;
while
(
info
->
save_level
>=
level
)
{
EMF_dc_state
*
state
=
info
->
saved_state
;
info
->
saved_state
=
state
->
next
;
state
->
next
=
NULL
;
if
(
--
info
->
save_level
<
level
)
{
EMF_dc_state
*
next
=
info
->
state
.
next
;
info
->
state
=
*
state
;
info
->
state
.
next
=
next
;
}
HeapFree
(
GetProcessHeap
(),
0
,
state
);
}
}
static
void
EMF_SaveDC
(
enum_emh_data
*
info
)
{
EMF_dc_state
*
state
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
state
));
if
(
state
)
{
*
state
=
info
->
state
;
state
->
next
=
info
->
saved_state
;
info
->
saved_state
=
state
;
info
->
save_level
++
;
TRACE
(
"save_level %d
\n
"
,
info
->
save_level
);
}
}
static
void
EMF_SetMapMode
(
HDC
hdc
,
enum_emh_data
*
info
)
{
INT
horzSize
=
GetDeviceCaps
(
hdc
,
HORZSIZE
);
...
...
@@ -544,46 +586,46 @@ static void EMF_SetMapMode(HDC hdc, enum_emh_data *info)
INT
horzRes
=
GetDeviceCaps
(
hdc
,
HORZRES
);
INT
vertRes
=
GetDeviceCaps
(
hdc
,
VERTRES
);
TRACE
(
"%d
\n
"
,
info
->
mode
);
TRACE
(
"%d
\n
"
,
info
->
state
.
mode
);
switch
(
info
->
mode
)
switch
(
info
->
state
.
mode
)
{
case
MM_TEXT
:
info
->
wndExtX
=
1
;
info
->
wndExtY
=
1
;
info
->
vportExtX
=
1
;
info
->
vportExtY
=
1
;
info
->
state
.
wndExtX
=
1
;
info
->
state
.
wndExtY
=
1
;
info
->
state
.
vportExtX
=
1
;
info
->
state
.
vportExtY
=
1
;
break
;
case
MM_LOMETRIC
:
case
MM_ISOTROPIC
:
info
->
wndExtX
=
horzSize
*
10
;
info
->
wndExtY
=
vertSize
*
10
;
info
->
vportExtX
=
horzRes
;
info
->
vportExtY
=
-
vertRes
;
info
->
state
.
wndExtX
=
horzSize
*
10
;
info
->
state
.
wndExtY
=
vertSize
*
10
;
info
->
state
.
vportExtX
=
horzRes
;
info
->
state
.
vportExtY
=
-
vertRes
;
break
;
case
MM_HIMETRIC
:
info
->
wndExtX
=
horzSize
*
100
;
info
->
wndExtY
=
vertSize
*
100
;
info
->
vportExtX
=
horzRes
;
info
->
vportExtY
=
-
vertRes
;
info
->
state
.
wndExtX
=
horzSize
*
100
;
info
->
state
.
wndExtY
=
vertSize
*
100
;
info
->
state
.
vportExtX
=
horzRes
;
info
->
state
.
vportExtY
=
-
vertRes
;
break
;
case
MM_LOENGLISH
:
info
->
wndExtX
=
MulDiv
(
1000
,
horzSize
,
254
);
info
->
wndExtY
=
MulDiv
(
1000
,
vertSize
,
254
);
info
->
vportExtX
=
horzRes
;
info
->
vportExtY
=
-
vertRes
;
info
->
state
.
wndExtX
=
MulDiv
(
1000
,
horzSize
,
254
);
info
->
state
.
wndExtY
=
MulDiv
(
1000
,
vertSize
,
254
);
info
->
state
.
vportExtX
=
horzRes
;
info
->
state
.
vportExtY
=
-
vertRes
;
break
;
case
MM_HIENGLISH
:
info
->
wndExtX
=
MulDiv
(
10000
,
horzSize
,
254
);
info
->
wndExtY
=
MulDiv
(
10000
,
vertSize
,
254
);
info
->
vportExtX
=
horzRes
;
info
->
vportExtY
=
-
vertRes
;
info
->
state
.
wndExtX
=
MulDiv
(
10000
,
horzSize
,
254
);
info
->
state
.
wndExtY
=
MulDiv
(
10000
,
vertSize
,
254
);
info
->
state
.
vportExtX
=
horzRes
;
info
->
state
.
vportExtY
=
-
vertRes
;
break
;
case
MM_TWIPS
:
info
->
wndExtX
=
MulDiv
(
14400
,
horzSize
,
254
);
info
->
wndExtY
=
MulDiv
(
14400
,
vertSize
,
254
);
info
->
vportExtX
=
horzRes
;
info
->
vportExtY
=
-
vertRes
;
info
->
state
.
wndExtX
=
MulDiv
(
14400
,
horzSize
,
254
);
info
->
state
.
wndExtY
=
MulDiv
(
14400
,
vertSize
,
254
);
info
->
state
.
vportExtX
=
horzRes
;
info
->
state
.
vportExtY
=
-
vertRes
;
break
;
case
MM_ANISOTROPIC
:
break
;
...
...
@@ -600,22 +642,22 @@ static void EMF_SetMapMode(HDC hdc, enum_emh_data *info)
static
void
EMF_FixIsotropic
(
HDC
hdc
,
enum_emh_data
*
info
)
{
double
xdim
=
fabs
((
double
)
info
->
vportExtX
*
GetDeviceCaps
(
hdc
,
HORZSIZE
)
/
(
GetDeviceCaps
(
hdc
,
HORZRES
)
*
info
->
wndExtX
));
double
ydim
=
fabs
((
double
)
info
->
vportExtY
*
GetDeviceCaps
(
hdc
,
VERTSIZE
)
/
(
GetDeviceCaps
(
hdc
,
VERTRES
)
*
info
->
wndExtY
));
double
xdim
=
fabs
((
double
)
info
->
state
.
vportExtX
*
GetDeviceCaps
(
hdc
,
HORZSIZE
)
/
(
GetDeviceCaps
(
hdc
,
HORZRES
)
*
info
->
state
.
wndExtX
));
double
ydim
=
fabs
((
double
)
info
->
state
.
vportExtY
*
GetDeviceCaps
(
hdc
,
VERTSIZE
)
/
(
GetDeviceCaps
(
hdc
,
VERTRES
)
*
info
->
state
.
wndExtY
));
if
(
xdim
>
ydim
)
{
INT
mincx
=
(
info
->
vportExtX
>=
0
)
?
1
:
-
1
;
info
->
vportExtX
=
floor
(
info
->
vportExtX
*
ydim
/
xdim
+
0
.
5
);
if
(
!
info
->
vportExtX
)
info
->
vportExtX
=
mincx
;
INT
mincx
=
(
info
->
state
.
vportExtX
>=
0
)
?
1
:
-
1
;
info
->
state
.
vportExtX
=
floor
(
info
->
state
.
vportExtX
*
ydim
/
xdim
+
0
.
5
);
if
(
!
info
->
state
.
vportExtX
)
info
->
state
.
vportExtX
=
mincx
;
}
else
{
INT
mincy
=
(
info
->
vportExtY
>=
0
)
?
1
:
-
1
;
info
->
vportExtY
=
floor
(
info
->
vportExtY
*
xdim
/
ydim
+
0
.
5
);
if
(
!
info
->
vportExtY
)
info
->
vportExtY
=
mincy
;
INT
mincy
=
(
info
->
state
.
vportExtY
>=
0
)
?
1
:
-
1
;
info
->
state
.
vportExtY
=
floor
(
info
->
state
.
vportExtY
*
xdim
/
ydim
+
0
.
5
);
if
(
!
info
->
state
.
vportExtY
)
info
->
state
.
vportExtY
=
mincy
;
}
}
...
...
@@ -740,9 +782,10 @@ BOOL WINAPI PlayEnhMetaFileRecord(
{
const
EMRSETMAPMODE
*
pSetMapMode
=
(
const
EMRSETMAPMODE
*
)
mr
;
if
(
info
->
mode
==
pSetMapMode
->
iMode
&&
(
info
->
mode
==
MM_ISOTROPIC
||
info
->
mode
==
MM_ANISOTROPIC
))
if
(
info
->
state
.
mode
==
pSetMapMode
->
iMode
&&
(
info
->
state
.
mode
==
MM_ISOTROPIC
||
info
->
state
.
mode
==
MM_ANISOTROPIC
))
break
;
info
->
mode
=
pSetMapMode
->
iMode
;
info
->
state
.
mode
=
pSetMapMode
->
iMode
;
EMF_SetMapMode
(
hdc
,
info
);
break
;
}
...
...
@@ -790,14 +833,16 @@ BOOL WINAPI PlayEnhMetaFileRecord(
}
case
EMR_SAVEDC
:
{
SaveDC
(
hdc
);
if
(
SaveDC
(
hdc
))
EMF_SaveDC
(
info
);
break
;
}
case
EMR_RESTOREDC
:
{
const
EMRRESTOREDC
*
pRestoreDC
=
(
const
EMRRESTOREDC
*
)
mr
;
TRACE
(
"EMR_RESTORE: %d
\n
"
,
pRestoreDC
->
iRelative
);
RestoreDC
(
hdc
,
pRestoreDC
->
iRelative
);
if
(
RestoreDC
(
hdc
,
pRestoreDC
->
iRelative
))
EMF_RestoreDC
(
info
,
pRestoreDC
->
iRelative
);
break
;
}
case
EMR_INTERSECTCLIPRECT
:
...
...
@@ -839,48 +884,46 @@ BOOL WINAPI PlayEnhMetaFileRecord(
{
const
EMRSETWINDOWORGEX
*
pSetWindowOrgEx
=
(
const
EMRSETWINDOWORGEX
*
)
mr
;
info
->
wndOrgX
=
pSetWindowOrgEx
->
ptlOrigin
.
x
;
info
->
wndOrgY
=
pSetWindowOrgEx
->
ptlOrigin
.
y
;
info
->
state
.
wndOrgX
=
pSetWindowOrgEx
->
ptlOrigin
.
x
;
info
->
state
.
wndOrgY
=
pSetWindowOrgEx
->
ptlOrigin
.
y
;
TRACE
(
"SetWindowOrgEx: %d,%d
\n
"
,
info
->
wndOrgX
,
info
->
wndOrgY
);
TRACE
(
"SetWindowOrgEx: %d,%d
\n
"
,
info
->
state
.
wndOrgX
,
info
->
state
.
wndOrgY
);
break
;
}
case
EMR_SETWINDOWEXTEX
:
{
const
EMRSETWINDOWEXTEX
*
pSetWindowExtEx
=
(
const
EMRSETWINDOWEXTEX
*
)
mr
;
if
(
info
->
mode
!=
MM_ISOTROPIC
&&
info
->
mode
!=
MM_ANISOTROPIC
)
if
(
info
->
state
.
mode
!=
MM_ISOTROPIC
&&
info
->
state
.
mode
!=
MM_ANISOTROPIC
)
break
;
info
->
wndExtX
=
pSetWindowExtEx
->
szlExtent
.
cx
;
info
->
wndExtY
=
pSetWindowExtEx
->
szlExtent
.
cy
;
if
(
info
->
mode
==
MM_ISOTROPIC
)
info
->
state
.
wndExtX
=
pSetWindowExtEx
->
szlExtent
.
cx
;
info
->
state
.
wndExtY
=
pSetWindowExtEx
->
szlExtent
.
cy
;
if
(
info
->
state
.
mode
==
MM_ISOTROPIC
)
EMF_FixIsotropic
(
hdc
,
info
);
TRACE
(
"SetWindowExtEx: %d,%d
\n
"
,
info
->
wndExtX
,
info
->
wndExtY
);
TRACE
(
"SetWindowExtEx: %d,%d
\n
"
,
info
->
state
.
wndExtX
,
info
->
state
.
wndExtY
);
break
;
}
case
EMR_SETVIEWPORTORGEX
:
{
const
EMRSETVIEWPORTORGEX
*
pSetViewportOrgEx
=
(
const
EMRSETVIEWPORTORGEX
*
)
mr
;
enum_emh_data
*
info
=
ENUM_GET_PRIVATE_DATA
(
handletable
);
info
->
vportOrgX
=
pSetViewportOrgEx
->
ptlOrigin
.
x
;
info
->
vportOrgY
=
pSetViewportOrgEx
->
ptlOrigin
.
y
;
TRACE
(
"SetViewportOrgEx: %d,%d
\n
"
,
info
->
vportOrgX
,
info
->
vportOrgY
);
info
->
state
.
vportOrgX
=
pSetViewportOrgEx
->
ptlOrigin
.
x
;
info
->
state
.
vportOrgY
=
pSetViewportOrgEx
->
ptlOrigin
.
y
;
TRACE
(
"SetViewportOrgEx: %d,%d
\n
"
,
info
->
state
.
vportOrgX
,
info
->
state
.
vportOrgY
);
break
;
}
case
EMR_SETVIEWPORTEXTEX
:
{
const
EMRSETVIEWPORTEXTEX
*
pSetViewportExtEx
=
(
const
EMRSETVIEWPORTEXTEX
*
)
mr
;
enum_emh_data
*
info
=
ENUM_GET_PRIVATE_DATA
(
handletable
);
if
(
info
->
mode
!=
MM_ISOTROPIC
&&
info
->
mode
!=
MM_ANISOTROPIC
)
if
(
info
->
state
.
mode
!=
MM_ISOTROPIC
&&
info
->
state
.
mode
!=
MM_ANISOTROPIC
)
break
;
info
->
vportExtX
=
pSetViewportExtEx
->
szlExtent
.
cx
;
info
->
vportExtY
=
pSetViewportExtEx
->
szlExtent
.
cy
;
if
(
info
->
mode
==
MM_ISOTROPIC
)
info
->
state
.
vportExtX
=
pSetViewportExtEx
->
szlExtent
.
cx
;
info
->
state
.
vportExtY
=
pSetViewportExtEx
->
szlExtent
.
cy
;
if
(
info
->
state
.
mode
==
MM_ISOTROPIC
)
EMF_FixIsotropic
(
hdc
,
info
);
TRACE
(
"SetViewportExtEx: %d,%d
\n
"
,
info
->
vportExtX
,
info
->
vportExtY
);
TRACE
(
"SetViewportExtEx: %d,%d
\n
"
,
info
->
state
.
vportExtX
,
info
->
state
.
vportExtY
);
break
;
}
case
EMR_CREATEPEN
:
...
...
@@ -1193,7 +1236,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
case
EMR_SETWORLDTRANSFORM
:
{
const
EMRSETWORLDTRANSFORM
*
lpXfrm
=
(
const
EMRSETWORLDTRANSFORM
*
)
mr
;
info
->
world_transform
=
lpXfrm
->
xform
;
info
->
state
.
world_transform
=
lpXfrm
->
xform
;
break
;
}
...
...
@@ -1331,18 +1374,18 @@ BOOL WINAPI PlayEnhMetaFileRecord(
{
const
EMRSCALEVIEWPORTEXTEX
*
lpScaleViewportExtEx
=
(
const
EMRSCALEVIEWPORTEXTEX
*
)
mr
;
if
((
info
->
mode
!=
MM_ISOTROPIC
)
&&
(
info
->
mode
!=
MM_ANISOTROPIC
))
if
((
info
->
state
.
mode
!=
MM_ISOTROPIC
)
&&
(
info
->
state
.
mode
!=
MM_ANISOTROPIC
))
break
;
if
(
!
lpScaleViewportExtEx
->
xNum
||
!
lpScaleViewportExtEx
->
xDenom
||
!
lpScaleViewportExtEx
->
yNum
||
!
lpScaleViewportExtEx
->
yDenom
)
break
;
info
->
vportExtX
=
MulDiv
(
info
->
vportExtX
,
lpScaleViewportExtEx
->
xNum
,
info
->
state
.
vportExtX
=
MulDiv
(
info
->
state
.
vportExtX
,
lpScaleViewportExtEx
->
xNum
,
lpScaleViewportExtEx
->
xDenom
);
info
->
vportExtY
=
MulDiv
(
info
->
vportExtY
,
lpScaleViewportExtEx
->
yNum
,
info
->
state
.
vportExtY
=
MulDiv
(
info
->
state
.
vportExtY
,
lpScaleViewportExtEx
->
yNum
,
lpScaleViewportExtEx
->
yDenom
);
if
(
info
->
vportExtX
==
0
)
info
->
vportExtX
=
1
;
if
(
info
->
vportExtY
==
0
)
info
->
vportExtY
=
1
;
if
(
info
->
mode
==
MM_ISOTROPIC
)
if
(
info
->
state
.
vportExtX
==
0
)
info
->
state
.
vportExtX
=
1
;
if
(
info
->
state
.
vportExtY
==
0
)
info
->
state
.
vportExtY
=
1
;
if
(
info
->
state
.
mode
==
MM_ISOTROPIC
)
EMF_FixIsotropic
(
hdc
,
info
);
TRACE
(
"EMRSCALEVIEWPORTEXTEX %d/%d %d/%d
\n
"
,
...
...
@@ -1356,18 +1399,18 @@ BOOL WINAPI PlayEnhMetaFileRecord(
{
const
EMRSCALEWINDOWEXTEX
*
lpScaleWindowExtEx
=
(
const
EMRSCALEWINDOWEXTEX
*
)
mr
;
if
((
info
->
mode
!=
MM_ISOTROPIC
)
&&
(
info
->
mode
!=
MM_ANISOTROPIC
))
if
((
info
->
state
.
mode
!=
MM_ISOTROPIC
)
&&
(
info
->
state
.
mode
!=
MM_ANISOTROPIC
))
break
;
if
(
!
lpScaleWindowExtEx
->
xNum
||
!
lpScaleWindowExtEx
->
xDenom
||
!
lpScaleWindowExtEx
->
xNum
||
!
lpScaleWindowExtEx
->
yDenom
)
break
;
info
->
wndExtX
=
MulDiv
(
info
->
wndExtX
,
lpScaleWindowExtEx
->
xNum
,
info
->
state
.
wndExtX
=
MulDiv
(
info
->
state
.
wndExtX
,
lpScaleWindowExtEx
->
xNum
,
lpScaleWindowExtEx
->
xDenom
);
info
->
wndExtY
=
MulDiv
(
info
->
wndExtY
,
lpScaleWindowExtEx
->
yNum
,
info
->
state
.
wndExtY
=
MulDiv
(
info
->
state
.
wndExtY
,
lpScaleWindowExtEx
->
yNum
,
lpScaleWindowExtEx
->
yDenom
);
if
(
info
->
wndExtX
==
0
)
info
->
wndExtX
=
1
;
if
(
info
->
wndExtY
==
0
)
info
->
wndExtY
=
1
;
if
(
info
->
mode
==
MM_ISOTROPIC
)
if
(
info
->
state
.
wndExtX
==
0
)
info
->
state
.
wndExtX
=
1
;
if
(
info
->
state
.
wndExtY
==
0
)
info
->
state
.
wndExtY
=
1
;
if
(
info
->
state
.
mode
==
MM_ISOTROPIC
)
EMF_FixIsotropic
(
hdc
,
info
);
TRACE
(
"EMRSCALEWINDOWEXTEX %d/%d %d/%d
\n
"
,
...
...
@@ -1383,16 +1426,16 @@ BOOL WINAPI PlayEnhMetaFileRecord(
switch
(
lpModifyWorldTrans
->
iMode
)
{
case
MWT_IDENTITY
:
info
->
world_transform
.
eM11
=
info
->
world_transform
.
eM22
=
1
;
info
->
world_transform
.
eM12
=
info
->
world_transform
.
eM21
=
0
;
info
->
world_transform
.
eDx
=
info
->
world_transform
.
eDy
=
0
;
info
->
state
.
world_transform
.
eM11
=
info
->
state
.
world_transform
.
eM22
=
1
;
info
->
state
.
world_transform
.
eM12
=
info
->
state
.
world_transform
.
eM21
=
0
;
info
->
state
.
world_transform
.
eDx
=
info
->
state
.
world_transform
.
eDy
=
0
;
break
;
case
MWT_LEFTMULTIPLY
:
CombineTransform
(
&
info
->
world_transform
,
&
lpModifyWorldTrans
->
xform
,
&
info
->
world_transform
);
CombineTransform
(
&
info
->
state
.
world_transform
,
&
lpModifyWorldTrans
->
xform
,
&
info
->
state
.
world_transform
);
break
;
case
MWT_RIGHTMULTIPLY
:
CombineTransform
(
&
info
->
world_transform
,
&
info
->
world_transform
,
CombineTransform
(
&
info
->
state
.
world_transform
,
&
info
->
state
.
world_transform
,
&
lpModifyWorldTrans
->
xform
);
break
;
default:
...
...
@@ -2243,17 +2286,20 @@ BOOL WINAPI EnumEnhMetaFile(
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
info
->
wndOrgX
=
0
;
info
->
wndOrgY
=
0
;
info
->
wndExtX
=
1
;
info
->
wndExtY
=
1
;
info
->
vportOrgX
=
0
;
info
->
vportOrgY
=
0
;
info
->
vportExtX
=
1
;
info
->
vportExtY
=
1
;
info
->
world_transform
.
eM11
=
info
->
world_transform
.
eM22
=
1
;
info
->
world_transform
.
eM12
=
info
->
world_transform
.
eM21
=
0
;
info
->
world_transform
.
eDx
=
info
->
world_transform
.
eDy
=
0
;
info
->
state
.
wndOrgX
=
0
;
info
->
state
.
wndOrgY
=
0
;
info
->
state
.
wndExtX
=
1
;
info
->
state
.
wndExtY
=
1
;
info
->
state
.
vportOrgX
=
0
;
info
->
state
.
vportOrgY
=
0
;
info
->
state
.
vportExtX
=
1
;
info
->
state
.
vportExtY
=
1
;
info
->
state
.
world_transform
.
eM11
=
info
->
state
.
world_transform
.
eM22
=
1
;
info
->
state
.
world_transform
.
eM12
=
info
->
state
.
world_transform
.
eM21
=
0
;
info
->
state
.
world_transform
.
eDx
=
info
->
state
.
world_transform
.
eDy
=
0
;
info
->
save_level
=
0
;
info
->
saved_state
=
NULL
;
ht
=
(
HANDLETABLE
*
)
&
info
[
1
];
ht
->
objectHandle
[
0
]
=
hmf
;
...
...
@@ -2282,7 +2328,7 @@ BOOL WINAPI EnumEnhMetaFile(
old_stretchblt
=
SetStretchBltMode
(
hdc
,
BLACKONWHITE
);
}
info
->
mode
=
MM_TEXT
;
info
->
state
.
mode
=
MM_TEXT
;
if
(
IS_WIN9X
()
)
{
...
...
@@ -2386,6 +2432,12 @@ BOOL WINAPI EnumEnhMetaFile(
if
(
(
ht
->
objectHandle
)[
i
]
)
DeleteObject
(
(
ht
->
objectHandle
)[
i
]
);
while
(
info
->
saved_state
)
{
EMF_dc_state
*
state
=
info
->
saved_state
;
info
->
saved_state
=
info
->
saved_state
->
next
;
HeapFree
(
GetProcessHeap
(),
0
,
state
);
}
HeapFree
(
GetProcessHeap
(),
0
,
info
);
return
ret
;
}
...
...
dlls/gdi32/tests/metafile.c
View file @
c871d9a8
...
...
@@ -261,37 +261,174 @@ static void test_ExtTextOut(void)
DestroyWindow
(
hwnd
);
}
static
void
check_dc_state
(
HDC
hdc
,
int
restore_no
,
int
wnd_org_x
,
int
wnd_org_y
,
int
wnd_ext_x
,
int
wnd_ext_y
,
int
vp_org_x
,
int
vp_org_y
,
int
vp_ext_x
,
int
vp_ext_y
)
{
BOOL
ret
;
XFORM
xform
;
POINT
vp_org
,
win_org
;
SIZE
vp_size
,
win_size
;
FLOAT
xscale
,
yscale
,
edx
,
edy
;
SetLastError
(
0xdeadbeef
);
ret
=
GetWorldTransform
(
hdc
,
&
xform
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_CALL_NOT_IMPLEMENTED
)
goto
win9x_here
;
ok
(
ret
,
"GetWorldTransform error %u
\n
"
,
GetLastError
());
trace
(
"%d: eM11 %f, eM22 %f, eDx %f, eDy %f
\n
"
,
restore_no
,
xform
.
eM11
,
xform
.
eM22
,
xform
.
eDx
,
xform
.
eDy
);
ok
(
xform
.
eM12
==
0
.
0
,
"%d: expected eM12 0.0, got %f
\n
"
,
restore_no
,
xform
.
eM12
);
ok
(
xform
.
eM21
==
0
.
0
,
"%d: expected eM21 0.0, got %f
\n
"
,
restore_no
,
xform
.
eM21
);
xscale
=
(
FLOAT
)
vp_ext_x
/
(
FLOAT
)
wnd_ext_x
;
trace
(
"x scale %f
\n
"
,
xscale
);
ok
(
fabs
(
xscale
-
xform
.
eM11
)
<
0
.
01
,
"%d: vp_ext_x %d, wnd_ext_cx %d, eM11 %f
\n
"
,
restore_no
,
vp_ext_x
,
wnd_ext_x
,
xform
.
eM11
);
yscale
=
(
FLOAT
)
vp_ext_y
/
(
FLOAT
)
wnd_ext_y
;
trace
(
"y scale %f
\n
"
,
yscale
);
ok
(
fabs
(
yscale
-
xform
.
eM22
)
<
0
.
01
,
"%d: vp_ext_y %d, wnd_ext_y %d, eM22 %f
\n
"
,
restore_no
,
vp_ext_y
,
wnd_ext_y
,
xform
.
eM22
);
edx
=
(
FLOAT
)
vp_org_x
-
xform
.
eM11
*
(
FLOAT
)
wnd_org_x
;
ok
(
fabs
(
edx
-
xform
.
eDx
)
<
0
.
01
,
"%d: edx %f != eDx %f
\n
"
,
restore_no
,
edx
,
xform
.
eDx
);
edy
=
(
FLOAT
)
vp_org_y
-
xform
.
eM22
*
(
FLOAT
)
wnd_org_y
;
ok
(
fabs
(
edy
-
xform
.
eDy
)
<
0
.
01
,
"%d: edy %f != eDy %f
\n
"
,
restore_no
,
edy
,
xform
.
eDy
);
return
;
win9x_here:
GetWindowOrgEx
(
hdc
,
&
win_org
);
GetViewportOrgEx
(
hdc
,
&
vp_org
);
GetWindowExtEx
(
hdc
,
&
win_size
);
GetViewportExtEx
(
hdc
,
&
vp_size
);
ok
(
wnd_org_x
==
win_org
.
x
,
"%d: wnd_org_x: %d != %d
\n
"
,
restore_no
,
wnd_org_x
,
win_org
.
x
);
ok
(
wnd_org_y
==
win_org
.
y
,
"%d: wnd_org_y: %d != %d
\n
"
,
restore_no
,
wnd_org_y
,
win_org
.
y
);
ok
(
vp_org_x
==
vp_org
.
x
,
"%d: vport_org_x: %d != %d
\n
"
,
restore_no
,
vp_org_x
,
vp_org
.
x
);
ok
(
vp_org_y
==
vp_org
.
y
,
"%d: vport_org_y: %d != %d
\n
"
,
restore_no
,
vp_org_y
,
vp_org
.
y
);
ok
(
wnd_ext_x
==
win_size
.
cx
,
"%d: wnd_ext_x: %d != %d
\n
"
,
restore_no
,
wnd_ext_x
,
win_size
.
cx
);
ok
(
wnd_ext_y
==
win_size
.
cy
,
"%d: wnd_ext_y: %d != %d
\n
"
,
restore_no
,
wnd_ext_y
,
win_size
.
cy
);
ok
(
vp_ext_x
==
vp_size
.
cx
,
"%d: vport_ext_x: %d != %d
\n
"
,
restore_no
,
vp_ext_x
,
vp_size
.
cx
);
ok
(
vp_ext_y
==
vp_size
.
cy
,
"%d: vport_ext_y: %d != %d
\n
"
,
restore_no
,
vp_ext_y
,
vp_size
.
cy
);
}
static
int
CALLBACK
savedc_emf_enum_proc
(
HDC
hdc
,
HANDLETABLE
*
handle_table
,
const
ENHMETARECORD
*
emr
,
int
n_objs
,
LPARAM
param
)
{
BOOL
ret
;
XFORM
xform
;
POINT
pt
;
SIZE
size
;
static
int
save_state
;
static
int
restore_no
;
trace
(
"hdc %p, emr->iType %d, emr->nSize %d, param %p
\n
"
,
hdc
,
emr
->
iType
,
emr
->
nSize
,
(
void
*
)
param
);
trace
(
"BEFORE:
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
GetWorldTransform
(
hdc
,
&
xform
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_CALL_NOT_IMPLEMENTED
)
{
ok
(
GetWindowOrgEx
(
hdc
,
&
pt
),
"GetWindowOrgEx error %u
\n
"
,
GetLastError
());
trace
(
"window org (%d,%d)
\n
"
,
pt
.
x
,
pt
.
y
);
ok
(
GetViewportOrgEx
(
hdc
,
&
pt
),
"GetViewportOrgEx error %u
\n
"
,
GetLastError
());
trace
(
"vport org (%d,%d)
\n
"
,
pt
.
x
,
pt
.
y
);
ok
(
GetWindowExtEx
(
hdc
,
&
size
),
"GetWindowExtEx error %u
\n
"
,
GetLastError
());
trace
(
"window ext (%d,%d)
\n
"
,
size
.
cx
,
size
.
cy
);
ok
(
GetViewportExtEx
(
hdc
,
&
size
),
"GetViewportExtEx error %u
\n
"
,
GetLastError
());
trace
(
"vport ext (%d,%d)
\n
"
,
size
.
cx
,
size
.
cy
);
}
else
{
ok
(
ret
,
"GetWorldTransform error %u
\n
"
,
GetLastError
());
trace
(
"eM11 %f, eM22 %f, eDx %f, eDy %f
\n
"
,
xform
.
eM11
,
xform
.
eM22
,
xform
.
eDx
,
xform
.
eDy
);
}
PlayEnhMetaFileRecord
(
hdc
,
handle_table
,
emr
,
n_objs
);
switch
(
emr
->
iType
)
{
case
EMR_HEADER
:
{
static
RECT
exp_bounds
=
{
0
,
0
,
150
,
150
};
RECT
bounds
;
const
ENHMETAHEADER
*
emf
=
(
const
ENHMETAHEADER
*
)
emr
;
trace
(
"bounds %d,%d-%d,%d, frame %d,%d-%d,%d
\n
"
,
emf
->
rclBounds
.
left
,
emf
->
rclBounds
.
top
,
emf
->
rclBounds
.
right
,
emf
->
rclBounds
.
bottom
,
emf
->
rclFrame
.
left
,
emf
->
rclFrame
.
top
,
emf
->
rclFrame
.
right
,
emf
->
rclFrame
.
bottom
);
trace
(
"mm %d x %d, device %d x %d
\n
"
,
emf
->
szlMillimeters
.
cx
,
emf
->
szlMillimeters
.
cy
,
emf
->
szlDevice
.
cx
,
emf
->
szlDevice
.
cy
);
SetRect
(
&
bounds
,
emf
->
rclBounds
.
left
,
emf
->
rclBounds
.
top
,
emf
->
rclBounds
.
right
,
emf
->
rclBounds
.
bottom
);
ok
(
EqualRect
(
&
bounds
,
&
exp_bounds
),
"wrong bounds
\n
"
);
save_state
=
0
;
restore_no
=
0
;
check_dc_state
(
hdc
,
restore_no
,
0
,
0
,
1
,
1
,
0
,
0
,
1
,
1
);
break
;
}
case
EMR_LINETO
:
{
const
EMRLINETO
*
line
=
(
const
EMRLINETO
*
)
emr
;
trace
(
"EMR_LINETO %d,%d
\n
"
,
line
->
ptl
.
x
,
line
->
ptl
.
x
);
break
;
}
case
EMR_SETWINDOWORGEX
:
{
const
EMRSETWINDOWORGEX
*
org
=
(
const
EMRSETWINDOWORGEX
*
)
emr
;
trace
(
"EMR_SETWINDOWORGEX: %d,%d
\n
"
,
org
->
ptlOrigin
.
x
,
org
->
ptlOrigin
.
y
);
break
;
}
case
EMR_SETWINDOWEXTEX
:
{
const
EMRSETWINDOWEXTEX
*
ext
=
(
const
EMRSETWINDOWEXTEX
*
)
emr
;
trace
(
"EMR_SETWINDOWEXTEX: %d,%d
\n
"
,
ext
->
szlExtent
.
cx
,
ext
->
szlExtent
.
cy
);
break
;
}
case
EMR_SETVIEWPORTORGEX
:
{
const
EMRSETVIEWPORTORGEX
*
org
=
(
const
EMRSETVIEWPORTORGEX
*
)
emr
;
trace
(
"EMR_SETVIEWPORTORGEX: %d,%d
\n
"
,
org
->
ptlOrigin
.
x
,
org
->
ptlOrigin
.
y
);
break
;
}
case
EMR_SETVIEWPORTEXTEX
:
{
const
EMRSETVIEWPORTEXTEX
*
ext
=
(
const
EMRSETVIEWPORTEXTEX
*
)
emr
;
trace
(
"EMR_SETVIEWPORTEXTEX: %d,%d
\n
"
,
ext
->
szlExtent
.
cx
,
ext
->
szlExtent
.
cy
);
break
;
}
case
EMR_SAVEDC
:
save_state
++
;
trace
(
"EMR_SAVEDC
\n
"
);
break
;
case
EMR_RESTOREDC
:
{
const
EMRRESTOREDC
*
restoredc
=
(
const
EMRRESTOREDC
*
)
emr
;
trace
(
"EMR_RESTOREDC: %d
\n
"
,
restoredc
->
iRelative
);
switch
(
++
restore_no
)
{
case
1
:
ok
(
restoredc
->
iRelative
==
-
1
,
"first restore %d
\n
"
,
restoredc
->
iRelative
);
check_dc_state
(
hdc
,
restore_no
,
-
2
,
-
2
,
8192
,
8192
,
20
,
20
,
20479
,
20478
);
break
;
case
2
:
ok
(
restoredc
->
iRelative
==
-
3
,
"second restore %d
\n
"
,
restoredc
->
iRelative
);
check_dc_state
(
hdc
,
restore_no
,
0
,
0
,
16384
,
16384
,
0
,
0
,
17873
,
17872
);
break
;
case
3
:
ok
(
restoredc
->
iRelative
==
-
2
,
"third restore %d
\n
"
,
restoredc
->
iRelative
);
check_dc_state
(
hdc
,
restore_no
,
-
4
,
-
4
,
32767
,
32767
,
40
,
40
,
3276
,
3276
);
break
;
}
ok
(
restore_no
<=
3
,
"restore_no %d
\n
"
,
restore_no
);
...
...
@@ -302,6 +439,27 @@ static int CALLBACK savedc_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
ok
(
save_state
==
0
,
"EOF save_state %d
\n
"
,
save_state
);
break
;
}
trace
(
"AFTER:
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
GetWorldTransform
(
hdc
,
&
xform
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_CALL_NOT_IMPLEMENTED
)
{
ok
(
GetWindowOrgEx
(
hdc
,
&
pt
),
"GetWindowOrgEx error %u
\n
"
,
GetLastError
());
trace
(
"window org (%d,%d)
\n
"
,
pt
.
x
,
pt
.
y
);
ok
(
GetViewportOrgEx
(
hdc
,
&
pt
),
"GetViewportOrgEx error %u
\n
"
,
GetLastError
());
trace
(
"vport org (%d,%d)
\n
"
,
pt
.
x
,
pt
.
y
);
ok
(
GetWindowExtEx
(
hdc
,
&
size
),
"GetWindowExtEx error %u
\n
"
,
GetLastError
());
trace
(
"window ext (%d,%d)
\n
"
,
size
.
cx
,
size
.
cy
);
ok
(
GetViewportExtEx
(
hdc
,
&
size
),
"GetViewportExtEx error %u
\n
"
,
GetLastError
());
trace
(
"vport ext (%d,%d)
\n
"
,
size
.
cx
,
size
.
cy
);
}
else
{
ok
(
ret
,
"GetWorldTransform error %u
\n
"
,
GetLastError
());
trace
(
"eM11 %f, eM22 %f, eDx %f, eDy %f
\n
"
,
xform
.
eM11
,
xform
.
eM22
,
xform
.
eDx
,
xform
.
eDy
);
}
return
1
;
}
...
...
@@ -311,7 +469,7 @@ static void test_SaveDC(void)
HENHMETAFILE
hMetafile
;
HWND
hwnd
;
int
ret
;
static
const
RECT
rc
=
{
0
,
0
,
1
00
,
10
0
};
static
const
RECT
rc
=
{
0
,
0
,
1
50
,
15
0
};
/* Win9x doesn't play EMFs on invisible windows */
hwnd
=
CreateWindowExA
(
0
,
"static"
,
NULL
,
WS_POPUP
|
WS_VISIBLE
,
...
...
@@ -324,18 +482,52 @@ static void test_SaveDC(void)
hdcMetafile
=
CreateEnhMetaFileA
(
hdcDisplay
,
NULL
,
NULL
,
NULL
);
ok
(
hdcMetafile
!=
0
,
"CreateEnhMetaFileA error %d
\n
"
,
GetLastError
());
SetMapMode
(
hdcMetafile
,
MM_ANISOTROPIC
);
/* Need to write something to the emf, otherwise Windows won't play it back */
LineTo
(
hdcMetafile
,
100
,
100
);
LineTo
(
hdcMetafile
,
150
,
150
);
SetWindowOrgEx
(
hdcMetafile
,
0
,
0
,
NULL
);
SetViewportOrgEx
(
hdcMetafile
,
0
,
0
,
NULL
);
SetWindowExtEx
(
hdcMetafile
,
110
,
110
,
NULL
);
SetViewportExtEx
(
hdcMetafile
,
120
,
120
,
NULL
);
/* Force Win9x to update DC state */
SetPixelV
(
hdcMetafile
,
50
,
50
,
0
);
ret
=
SaveDC
(
hdcMetafile
);
ok
(
ret
==
1
,
"ret = %d
\n
"
,
ret
);
SetWindowOrgEx
(
hdcMetafile
,
-
1
,
-
1
,
NULL
);
SetViewportOrgEx
(
hdcMetafile
,
10
,
10
,
NULL
);
SetWindowExtEx
(
hdcMetafile
,
150
,
150
,
NULL
);
SetViewportExtEx
(
hdcMetafile
,
200
,
200
,
NULL
);
/* Force Win9x to update DC state */
SetPixelV
(
hdcMetafile
,
50
,
50
,
0
);
ret
=
SaveDC
(
hdcMetafile
);
ok
(
ret
==
2
,
"ret = %d
\n
"
,
ret
);
SetWindowOrgEx
(
hdcMetafile
,
-
2
,
-
2
,
NULL
);
SetViewportOrgEx
(
hdcMetafile
,
20
,
20
,
NULL
);
SetWindowExtEx
(
hdcMetafile
,
120
,
120
,
NULL
);
SetViewportExtEx
(
hdcMetafile
,
300
,
300
,
NULL
);
/* Force Win9x to update DC state */
SetPixelV
(
hdcMetafile
,
50
,
50
,
0
);
ret
=
SaveDC
(
hdcMetafile
);
ok
(
ret
==
3
,
"ret = %d
\n
"
,
ret
);
SetWindowOrgEx
(
hdcMetafile
,
-
3
,
-
3
,
NULL
);
SetViewportOrgEx
(
hdcMetafile
,
30
,
30
,
NULL
);
SetWindowExtEx
(
hdcMetafile
,
200
,
200
,
NULL
);
SetViewportExtEx
(
hdcMetafile
,
400
,
400
,
NULL
);
/* Force Win9x to update DC state */
SetPixelV
(
hdcMetafile
,
50
,
50
,
0
);
ret
=
RestoreDC
(
hdcMetafile
,
-
1
);
ok
(
ret
,
"ret = %d
\n
"
,
ret
);
...
...
@@ -345,6 +537,14 @@ static void test_SaveDC(void)
ret
=
RestoreDC
(
hdcMetafile
,
1
);
ok
(
ret
,
"ret = %d
\n
"
,
ret
);
SetWindowOrgEx
(
hdcMetafile
,
-
4
,
-
4
,
NULL
);
SetViewportOrgEx
(
hdcMetafile
,
40
,
40
,
NULL
);
SetWindowExtEx
(
hdcMetafile
,
500
,
500
,
NULL
);
SetViewportExtEx
(
hdcMetafile
,
50
,
50
,
NULL
);
/* Force Win9x to update DC state */
SetPixelV
(
hdcMetafile
,
50
,
50
,
0
);
ret
=
SaveDC
(
hdcMetafile
);
ok
(
ret
==
1
,
"ret = %d
\n
"
,
ret
);
...
...
@@ -1282,12 +1482,16 @@ static int CALLBACK clip_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
rect
=
rgn2
.
data
.
rdh
.
rcBound
;
rc_transformed
=
*
rc
;
translate
((
POINT
*
)
&
rc_transformed
,
2
,
&
xform
);
trace
(
"transformed (%d,%d-%d,%d)
\n
"
,
rc_transformed
.
left
,
rc_transformed
.
top
,
rc_transformed
.
right
,
rc_transformed
.
bottom
);
ok
(
EqualRect
(
&
rect
,
&
rc_transformed
),
"rects don't match
\n
"
);
rect
=
*
(
const
RECT
*
)
rgn2
.
data
.
Buffer
;
trace
(
"rect (%d,%d-%d,%d)
\n
"
,
rect
.
left
,
rect
.
top
,
rect
.
right
,
rect
.
bottom
);
rc_transformed
=
*
rc
;
translate
((
POINT
*
)
&
rc_transformed
,
2
,
&
xform
);
trace
(
"transformed (%d,%d-%d,%d)
\n
"
,
rc_transformed
.
left
,
rc_transformed
.
top
,
rc_transformed
.
right
,
rc_transformed
.
bottom
);
ok
(
EqualRect
(
&
rect
,
&
rc_transformed
),
"rects don't match
\n
"
);
ok
(
rgn2
.
data
.
rdh
.
dwSize
==
sizeof
(
rgn1
->
data
.
rdh
),
"expected sizeof(rdh), got %u"
,
rgn2
.
data
.
rdh
.
dwSize
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment