2004-03-09 20:19:53 +01:00
/*
* Unit tests for metafile functions
*
* Copyright ( c ) 2002 Dmitry Timoshkov
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2004-03-09 20:19:53 +01:00
*/
# include <assert.h>
2004-12-09 12:37:59 +01:00
# include <stdio.h>
2005-04-13 12:57:59 +02:00
# include <math.h>
2004-03-09 20:19:53 +01:00
# include "wine/test.h"
# include "winbase.h"
# include "wingdi.h"
# include "winuser.h"
# include "winerror.h"
static LOGFONTA orig_lf ;
static BOOL emr_processed = FALSE ;
2005-04-13 12:57:59 +02:00
/* Arbitrarily chosen values for the second co-ordinate of a metafile line */
# define LINE_X 55.0f
# define LINE_Y 15.0f
2005-10-26 12:05:07 +02:00
static INT ( WINAPI * pGetRelAbs ) ( HDC , DWORD ) ;
static INT ( WINAPI * pSetRelAbs ) ( HDC , INT ) ;
2011-03-10 20:22:22 +01:00
static COLORREF ( WINAPI * pSetDCBrushColor ) ( HDC , COLORREF ) ;
static COLORREF ( WINAPI * pSetDCPenColor ) ( HDC , COLORREF ) ;
2005-10-26 12:05:07 +02:00
# define GDI_GET_PROC(func) \
p # # func = ( void * ) GetProcAddress ( hGDI , # func ) ; \
if ( ! p # # func ) \
trace ( " GetProcAddress(hGDI, \" %s \" ) failed \n " , # func ) ; \
static void init_function_pointers ( void )
{
HMODULE hGDI ;
pGetRelAbs = NULL ;
pSetRelAbs = NULL ;
hGDI = GetModuleHandleA ( " gdi32.dll " ) ;
assert ( hGDI ) ;
GDI_GET_PROC ( GetRelAbs ) ;
GDI_GET_PROC ( SetRelAbs ) ;
2011-03-10 20:22:22 +01:00
GDI_GET_PROC ( SetDCBrushColor ) ;
GDI_GET_PROC ( SetDCPenColor ) ;
2005-10-26 12:05:07 +02:00
}
2005-10-31 11:05:52 +01:00
static int CALLBACK eto_emf_enum_proc ( HDC hdc , HANDLETABLE * handle_table ,
2004-03-09 20:19:53 +01:00
const ENHMETARECORD * emr , int n_objs , LPARAM param )
{
static int n_record ;
DWORD i ;
2004-11-30 22:38:57 +01:00
const INT * dx ;
INT * orig_dx = ( INT * ) param ;
2004-03-09 20:19:53 +01:00
LOGFONTA device_lf ;
2004-12-27 18:26:37 +01:00
INT ret ;
2004-03-09 20:19:53 +01:00
2005-03-29 20:56:35 +02:00
if ( ! hdc ) return 1 ;
2004-03-09 20:19:53 +01:00
PlayEnhMetaFileRecord ( hdc , handle_table , emr , n_objs ) ;
switch ( emr - > iType )
{
case EMR_HEADER :
2005-10-12 23:06:20 +02:00
ok ( GetTextAlign ( hdc ) = = 0 , " text align %08x \n " , GetTextAlign ( hdc ) ) ;
2006-10-12 22:56:45 +02:00
ok ( GetBkColor ( hdc ) = = RGB ( 0xff , 0xff , 0xff ) , " bk color %08x \n " , GetBkColor ( hdc ) ) ;
ok ( GetTextColor ( hdc ) = = RGB ( 0x0 , 0x0 , 0x0 ) , " text color %08x \n " , GetTextColor ( hdc ) ) ;
2005-10-12 23:06:20 +02:00
ok ( GetROP2 ( hdc ) = = R2_COPYPEN , " rop %d \n " , GetROP2 ( hdc ) ) ;
ok ( GetArcDirection ( hdc ) = = AD_COUNTERCLOCKWISE , " arc dir %d \n " , GetArcDirection ( hdc ) ) ;
ok ( GetPolyFillMode ( hdc ) = = ALTERNATE , " poly fill %d \n " , GetPolyFillMode ( hdc ) ) ;
ok ( GetStretchBltMode ( hdc ) = = BLACKONWHITE , " stretchblt mode %d \n " , GetStretchBltMode ( hdc ) ) ;
/* GetBkMode, GetRelAbs do not get reset to the default value */
ok ( GetBkMode ( hdc ) = = OPAQUE , " bk mode %d \n " , GetBkMode ( hdc ) ) ;
2005-10-26 12:05:07 +02:00
if ( pSetRelAbs & & pGetRelAbs )
ok ( pGetRelAbs ( hdc , 0 ) = = RELATIVE , " relabs %d \n " , pGetRelAbs ( hdc , 0 ) ) ;
2005-10-12 23:06:20 +02:00
2004-03-09 20:19:53 +01:00
n_record = 0 ;
break ;
case EMR_EXTTEXTOUTA :
{
2004-11-30 22:38:57 +01:00
const EMREXTTEXTOUTA * emr_ExtTextOutA = ( const EMREXTTEXTOUTA * ) emr ;
dx = ( const INT * ) ( ( const char * ) emr + emr_ExtTextOutA - > emrtext . offDx ) ;
2004-03-09 20:19:53 +01:00
2004-12-27 18:26:37 +01:00
ret = GetObjectA ( GetCurrentObject ( hdc , OBJ_FONT ) , sizeof ( device_lf ) , & device_lf ) ;
2006-10-12 22:56:45 +02:00
ok ( ret = = sizeof ( device_lf ) , " GetObjectA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
/* compare up to lfOutPrecision, other values are not interesting,
* and in fact sometimes arbitrary adapted by Win9x .
*/
ok ( ! memcmp ( & orig_lf , & device_lf , FIELD_OFFSET ( LOGFONTA , lfOutPrecision ) ) , " fonts don't match \n " ) ;
ok ( ! lstrcmpA ( orig_lf . lfFaceName , device_lf . lfFaceName ) , " font names don't match \n " ) ;
for ( i = 0 ; i < emr_ExtTextOutA - > emrtext . nChars ; i + + )
{
2006-10-12 22:56:45 +02:00
ok ( orig_dx [ i ] = = dx [ i ] , " pass %d: dx[%d] (%d) didn't match %d \n " ,
2004-03-09 20:19:53 +01:00
n_record , i , dx [ i ] , orig_dx [ i ] ) ;
}
n_record + + ;
emr_processed = TRUE ;
break ;
}
case EMR_EXTTEXTOUTW :
{
2004-11-30 22:38:57 +01:00
const EMREXTTEXTOUTW * emr_ExtTextOutW = ( const EMREXTTEXTOUTW * ) emr ;
dx = ( const INT * ) ( ( const char * ) emr + emr_ExtTextOutW - > emrtext . offDx ) ;
2004-03-09 20:19:53 +01:00
2008-12-09 13:42:08 +01:00
SetLastError ( 0xdeadbeef ) ;
2004-12-27 18:26:37 +01:00
ret = GetObjectA ( GetCurrentObject ( hdc , OBJ_FONT ) , sizeof ( device_lf ) , & device_lf ) ;
2008-12-09 13:42:08 +01:00
ok ( ret = = sizeof ( device_lf ) | |
broken ( ret = = ( sizeof ( device_lf ) - LF_FACESIZE + strlen ( device_lf . lfFaceName ) + 1 ) ) , /* NT4 */
" GetObjectA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
/* compare up to lfOutPrecision, other values are not interesting,
* and in fact sometimes arbitrary adapted by Win9x .
*/
ok ( ! memcmp ( & orig_lf , & device_lf , FIELD_OFFSET ( LOGFONTA , lfOutPrecision ) ) , " fonts don't match \n " ) ;
ok ( ! lstrcmpA ( orig_lf . lfFaceName , device_lf . lfFaceName ) , " font names don't match \n " ) ;
2016-04-28 18:47:14 +02:00
ok ( ! emr_ExtTextOutW - > rclBounds . left , " emr_ExtTextOutW->rclBounds.left = %d \n " ,
emr_ExtTextOutW - > rclBounds . left ) ;
ok ( emr_ExtTextOutW - > rclBounds . right ! = - 1 , " emr_ExtTextOutW->rclBounds.right = %d \n " ,
emr_ExtTextOutW - > rclBounds . right ) ;
ok ( emr_ExtTextOutW - > rclBounds . bottom ! = - 1 , " emr_ExtTextOutW->rclBounds.bottom = %d \n " ,
emr_ExtTextOutW - > rclBounds . bottom ) ;
2004-03-09 20:19:53 +01:00
for ( i = 0 ; i < emr_ExtTextOutW - > emrtext . nChars ; i + + )
{
2006-10-12 22:56:45 +02:00
ok ( orig_dx [ i ] = = dx [ i ] , " pass %d: dx[%d] (%d) didn't match %d \n " ,
2004-03-09 20:19:53 +01:00
n_record , i , dx [ i ] , orig_dx [ i ] ) ;
}
n_record + + ;
emr_processed = TRUE ;
break ;
}
default :
break ;
}
return 1 ;
}
static void test_ExtTextOut ( void )
{
HWND hwnd ;
HDC hdcDisplay , hdcMetafile ;
HENHMETAFILE hMetafile ;
HFONT hFont ;
static const char text [ ] = " Simple text to test ExtTextOut on metafiles " ;
INT i , len , dx [ 256 ] ;
static const RECT rc = { 0 , 0 , 100 , 100 } ;
2004-12-27 18:26:37 +01:00
BOOL ret ;
2004-03-09 20:19:53 +01:00
2018-06-25 21:46:41 +02:00
assert ( ARRAY_SIZE ( dx ) > = lstrlenA ( text ) ) ;
2004-03-09 20:19:53 +01:00
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA ( 0 , " static " , NULL , WS_POPUP | WS_VISIBLE ,
0 , 0 , 200 , 200 , 0 , 0 , 0 , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hwnd ! = 0 , " CreateWindowExA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
hdcDisplay = GetDC ( hwnd ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcDisplay ! = 0 , " GetDC error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
SetMapMode ( hdcDisplay , MM_TEXT ) ;
memset ( & orig_lf , 0 , sizeof ( orig_lf ) ) ;
orig_lf . lfCharSet = ANSI_CHARSET ;
orig_lf . lfClipPrecision = CLIP_DEFAULT_PRECIS ;
orig_lf . lfWeight = FW_DONTCARE ;
orig_lf . lfHeight = 7 ;
orig_lf . lfQuality = DEFAULT_QUALITY ;
lstrcpyA ( orig_lf . lfFaceName , " Arial " ) ;
hFont = CreateFontIndirectA ( & orig_lf ) ;
2006-10-12 22:56:45 +02:00
ok ( hFont ! = 0 , " CreateFontIndirectA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
hFont = SelectObject ( hdcDisplay , hFont ) ;
len = lstrlenA ( text ) ;
for ( i = 0 ; i < len ; i + + )
{
2004-12-27 18:26:37 +01:00
ret = GetCharWidthA ( hdcDisplay , text [ i ] , text [ i ] , & dx [ i ] ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " GetCharWidthA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
}
hFont = SelectObject ( hdcDisplay , hFont ) ;
hdcMetafile = CreateEnhMetaFileA ( hdcDisplay , NULL , NULL , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
ok ( GetDeviceCaps ( hdcMetafile , TECHNOLOGY ) = = DT_RASDISPLAY ,
" GetDeviceCaps(TECHNOLOGY) has to return DT_RASDISPLAY for a display based EMF \n " ) ;
hFont = SelectObject ( hdcMetafile , hFont ) ;
/* 1. pass NULL lpDx */
2004-12-27 18:26:37 +01:00
ret = ExtTextOutA ( hdcMetafile , 0 , 0 , 0 , & rc , text , lstrlenA ( text ) , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " ExtTextOutA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
/* 2. pass custom lpDx */
2004-12-27 18:26:37 +01:00
ret = ExtTextOutA ( hdcMetafile , 0 , 20 , 0 , & rc , text , lstrlenA ( text ) , dx ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " ExtTextOutA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
2016-04-28 18:47:14 +02:00
/* 3. pass NULL lprc */
ret = ExtTextOutA ( hdcMetafile , 0 , 40 , 0 , NULL , text , lstrlenA ( text ) , NULL ) ;
ok ( ret , " ExtTextOutA error %d \n " , GetLastError ( ) ) ;
2016-04-28 18:47:20 +02:00
/* 4. test with unmatched BeginPath/EndPath calls */
ret = BeginPath ( hdcMetafile ) ;
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
ret = BeginPath ( hdcMetafile ) ;
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
ret = EndPath ( hdcMetafile ) ;
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
ret = ExtTextOutA ( hdcMetafile , 0 , 60 , 0 , NULL , text , lstrlenA ( text ) , NULL ) ;
ok ( ret , " ExtTextOutA error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
hFont = SelectObject ( hdcMetafile , hFont ) ;
2004-12-27 18:26:37 +01:00
ret = DeleteObject ( hFont ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteObject error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
hMetafile = CloseEnhMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
ok ( ! GetObjectType ( hdcMetafile ) , " CloseEnhMetaFile has to destroy metafile hdc \n " ) ;
2004-12-27 18:26:37 +01:00
ret = PlayEnhMetaFile ( hdcDisplay , hMetafile , & rc ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " PlayEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
2005-10-12 23:06:20 +02:00
SetTextAlign ( hdcDisplay , TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING ) ;
SetBkColor ( hdcDisplay , RGB ( 0xff , 0 , 0 ) ) ;
SetTextColor ( hdcDisplay , RGB ( 0 , 0xff , 0 ) ) ;
SetROP2 ( hdcDisplay , R2_NOT ) ;
SetArcDirection ( hdcDisplay , AD_CLOCKWISE ) ;
SetPolyFillMode ( hdcDisplay , WINDING ) ;
SetStretchBltMode ( hdcDisplay , HALFTONE ) ;
2005-10-26 12:05:07 +02:00
if ( pSetRelAbs ) pSetRelAbs ( hdcDisplay , RELATIVE ) ;
2005-10-12 23:06:20 +02:00
SetBkMode ( hdcDisplay , OPAQUE ) ;
2005-10-31 11:05:52 +01:00
ret = EnumEnhMetaFile ( hdcDisplay , hMetafile , eto_emf_enum_proc , dx , & rc ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " EnumEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2004-03-09 20:19:53 +01:00
2005-10-12 23:06:20 +02:00
ok ( GetTextAlign ( hdcDisplay ) = = ( TA_UPDATECP | TA_CENTER | TA_BASELINE | TA_RTLREADING ) ,
" text align %08x \n " , GetTextAlign ( hdcDisplay ) ) ;
2006-10-12 22:56:45 +02:00
ok ( GetBkColor ( hdcDisplay ) = = RGB ( 0xff , 0 , 0 ) , " bk color %08x \n " , GetBkColor ( hdcDisplay ) ) ;
ok ( GetTextColor ( hdcDisplay ) = = RGB ( 0 , 0xff , 0 ) , " text color %08x \n " , GetTextColor ( hdcDisplay ) ) ;
2005-10-12 23:06:20 +02:00
ok ( GetROP2 ( hdcDisplay ) = = R2_NOT , " rop2 %d \n " , GetROP2 ( hdcDisplay ) ) ;
ok ( GetArcDirection ( hdcDisplay ) = = AD_CLOCKWISE , " arc dir %d \n " , GetArcDirection ( hdcDisplay ) ) ;
ok ( GetPolyFillMode ( hdcDisplay ) = = WINDING , " poly fill %d \n " , GetPolyFillMode ( hdcDisplay ) ) ;
ok ( GetStretchBltMode ( hdcDisplay ) = = HALFTONE , " stretchblt mode %d \n " , GetStretchBltMode ( hdcDisplay ) ) ;
2004-03-09 20:19:53 +01:00
ok ( emr_processed , " EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record \n " ) ;
2005-10-31 11:05:52 +01:00
ok ( ! EnumEnhMetaFile ( hdcDisplay , hMetafile , eto_emf_enum_proc , dx , NULL ) ,
2004-03-09 20:19:53 +01:00
" A valid hdc has to require a valid rc \n " ) ;
2005-03-29 20:56:35 +02:00
2005-10-31 11:05:52 +01:00
ok ( EnumEnhMetaFile ( NULL , hMetafile , eto_emf_enum_proc , dx , NULL ) ,
2005-03-29 20:56:35 +02:00
" A null hdc does not require a valid rc \n " ) ;
2004-03-09 20:19:53 +01:00
2004-12-27 18:26:37 +01:00
ret = DeleteEnhMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2004-12-27 18:26:37 +01:00
ret = ReleaseDC ( hwnd , hdcDisplay ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " ReleaseDC error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
DestroyWindow ( hwnd ) ;
}
2011-02-18 23:56:01 +01:00
struct eto_scale_test_record
{
INT graphics_mode ;
INT map_mode ;
double ex_scale ;
double ey_scale ;
BOOL processed ;
} ;
static int CALLBACK eto_scale_enum_proc ( HDC hdc , HANDLETABLE * handle_table ,
const ENHMETARECORD * emr , int n_objs , LPARAM param )
{
struct eto_scale_test_record * test = ( struct eto_scale_test_record * ) param ;
if ( emr - > iType = = EMR_EXTTEXTOUTW )
{
const EMREXTTEXTOUTW * pExtTextOutW = ( const EMREXTTEXTOUTW * ) emr ;
ok ( fabs ( test - > ex_scale - pExtTextOutW - > exScale ) < 0.001 ,
" Got exScale %f, expected %f \n " , pExtTextOutW - > exScale , test - > ex_scale ) ;
ok ( fabs ( test - > ey_scale - pExtTextOutW - > eyScale ) < 0.001 ,
" Got eyScale %f, expected %f \n " , pExtTextOutW - > eyScale , test - > ey_scale ) ;
test - > processed = TRUE ;
}
return 1 ;
}
static void test_ExtTextOutScale ( void )
{
const RECT rc = { 0 , 0 , 100 , 100 } ;
const WCHAR str [ ] = { ' a ' , 0 } ;
struct eto_scale_test_record test ;
HDC hdcDisplay , hdcMetafile ;
HENHMETAFILE hMetafile ;
HWND hwnd ;
SIZE wndext , vportext ;
int horzSize , vertSize , horzRes , vertRes ;
int ret ;
int i ;
hwnd = CreateWindowExA ( 0 , " static " , NULL , WS_POPUP | WS_VISIBLE ,
0 , 0 , 200 , 200 , 0 , 0 , 0 , NULL ) ;
ok ( hwnd ! = 0 , " CreateWindowExA failed \n " ) ;
hdcDisplay = GetDC ( hwnd ) ;
ok ( hdcDisplay ! = 0 , " GetDC failed \n " ) ;
horzSize = GetDeviceCaps ( hdcDisplay , HORZSIZE ) ;
horzRes = GetDeviceCaps ( hdcDisplay , HORZRES ) ;
vertSize = GetDeviceCaps ( hdcDisplay , VERTSIZE ) ;
vertRes = GetDeviceCaps ( hdcDisplay , VERTRES ) ;
ok ( horzSize & & horzRes & & vertSize & & vertRes , " GetDeviceCaps failed \n " ) ;
for ( i = 0 ; i < 16 ; i + + )
{
test . graphics_mode = i / 8 + 1 ;
test . map_mode = i % 8 + 1 ;
ret = SetGraphicsMode ( hdcDisplay , test . graphics_mode ) ;
ok ( ret , " SetGraphicsMode failed \n " ) ;
ret = SetMapMode ( hdcDisplay , test . map_mode ) ;
ok ( ret , " SetMapMode failed \n " ) ;
if ( ( test . map_mode = = MM_ISOTROPIC ) | | ( test . map_mode = = MM_ANISOTROPIC ) )
{
ret = SetWindowExtEx ( hdcDisplay , 1 , 1 , NULL ) ;
ok ( ret , " SetWindowExtEx failed \n " ) ;
ret = SetViewportExtEx ( hdcDisplay , - 20 , - 10 , NULL ) ;
ok ( ret , " SetViewportExtEx failed \n " ) ;
}
ret = GetViewportExtEx ( hdcDisplay , & vportext ) ;
ok ( ret , " GetViewportExtEx failed \n " ) ;
ret = GetWindowExtEx ( hdcDisplay , & wndext ) ;
ok ( ret , " GetWindowExtEx failed \n " ) ;
trace ( " gm %d, mm %d, wnd %d,%d, vp %d,%d horz %d,%d vert %d,%d \n " ,
test . graphics_mode , test . map_mode ,
wndext . cx , wndext . cy , vportext . cx , vportext . cy ,
horzSize , horzRes , vertSize , vertRes ) ;
if ( test . graphics_mode = = GM_COMPATIBLE )
{
test . ex_scale = 100.0 * ( ( FLOAT ) horzSize / ( FLOAT ) horzRes ) /
( ( FLOAT ) wndext . cx / ( FLOAT ) vportext . cx ) ;
test . ey_scale = 100.0 * ( ( FLOAT ) vertSize / ( FLOAT ) vertRes ) /
( ( FLOAT ) wndext . cy / ( FLOAT ) vportext . cy ) ;
}
else
{
test . ex_scale = 0.0 ;
test . ey_scale = 0.0 ;
}
hdcMetafile = CreateEnhMetaFileA ( hdcDisplay , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA failed \n " ) ;
ret = SetGraphicsMode ( hdcMetafile , test . graphics_mode ) ;
ok ( ret , " SetGraphicsMode failed \n " ) ;
ret = SetMapMode ( hdcMetafile , test . map_mode ) ;
ok ( ret , " SetMapMode failed \n " ) ;
if ( ( test . map_mode = = MM_ISOTROPIC ) | | ( test . map_mode = = MM_ANISOTROPIC ) )
{
ret = SetWindowExtEx ( hdcMetafile , 1 , 1 , NULL ) ;
ok ( ret , " SetWindowExtEx failed \n " ) ;
ret = SetViewportExtEx ( hdcMetafile , - 20 , - 10 , NULL ) ;
ok ( ret , " SetViewportExtEx failed \n " ) ;
}
ret = ExtTextOutW ( hdcMetafile , 0 , 0 , 0 , 0 , str , 1 , NULL ) ;
ok ( ret , " ExtTextOutW failed \n " ) ;
hMetafile = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hMetafile ! = 0 , " CloseEnhMetaFile failed \n " ) ;
test . processed = 0 ;
ret = EnumEnhMetaFile ( hdcDisplay , hMetafile , eto_scale_enum_proc , & test , & rc ) ;
ok ( ret , " EnumEnhMetaFile failed \n " ) ;
ok ( test . processed , " EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTW record \n " ) ;
ret = DeleteEnhMetaFile ( hMetafile ) ;
ok ( ret , " DeleteEnhMetaFile failed \n " ) ;
}
ret = ReleaseDC ( hwnd , hdcDisplay ) ;
ok ( ret , " ReleaseDC failed \n " ) ;
DestroyWindow ( hwnd ) ;
}
2008-04-28 09:02:31 +02:00
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 ) ;
}
2005-10-31 11:05:52 +01:00
static int CALLBACK savedc_emf_enum_proc ( HDC hdc , HANDLETABLE * handle_table ,
const ENHMETARECORD * emr , int n_objs , LPARAM param )
{
2008-04-28 09:02:31 +02:00
BOOL ret ;
XFORM xform ;
POINT pt ;
SIZE size ;
2005-10-31 11:05:52 +01:00
static int save_state ;
static int restore_no ;
2009-04-03 20:35:38 +02:00
static int select_no ;
2005-10-31 11:05:52 +01:00
2008-04-28 09:02:31 +02:00
trace ( " hdc %p, emr->iType %d, emr->nSize %d, param %p \n " ,
hdc , emr - > iType , emr - > nSize , ( void * ) param ) ;
SetLastError ( 0xdeadbeef ) ;
ret = GetWorldTransform ( hdc , & xform ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
2011-01-02 18:50:17 +01:00
ret = GetWindowOrgEx ( hdc , & pt ) ;
ok ( ret , " GetWindowOrgEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
trace ( " window org (%d,%d) \n " , pt . x , pt . y ) ;
2011-01-02 18:50:17 +01:00
ret = GetViewportOrgEx ( hdc , & pt ) ;
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
trace ( " vport org (%d,%d) \n " , pt . x , pt . y ) ;
2011-01-02 18:50:17 +01:00
ret = GetWindowExtEx ( hdc , & size ) ;
ok ( ret , " GetWindowExtEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
trace ( " window ext (%d,%d) \n " , size . cx , size . cy ) ;
2011-01-02 18:50:17 +01:00
ret = GetViewportExtEx ( hdc , & size ) ;
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
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 ) ;
2005-10-31 11:05:52 +01:00
switch ( emr - > iType )
{
case EMR_HEADER :
2008-04-28 09:02:31 +02:00
{
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 " ) ;
2005-10-31 11:05:52 +01:00
save_state = 0 ;
restore_no = 0 ;
2009-04-03 20:35:38 +02:00
select_no = 0 ;
2008-04-28 09:02:31 +02:00
check_dc_state ( hdc , restore_no , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 ) ;
2005-10-31 11:05:52 +01:00
break ;
2008-04-28 09:02:31 +02:00
}
2005-10-31 11:05:52 +01:00
2008-04-28 09:02:31 +02:00
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 ;
}
2005-10-31 11:05:52 +01:00
case EMR_SAVEDC :
save_state + + ;
2008-04-28 09:02:31 +02:00
trace ( " EMR_SAVEDC \n " ) ;
2005-10-31 11:05:52 +01:00
break ;
case EMR_RESTOREDC :
{
2006-12-09 19:03:09 +01:00
const EMRRESTOREDC * restoredc = ( const EMRRESTOREDC * ) emr ;
2008-04-28 09:02:31 +02:00
trace ( " EMR_RESTOREDC: %d \n " , restoredc - > iRelative ) ;
2005-10-31 11:05:52 +01:00
switch ( + + restore_no )
{
case 1 :
2006-10-12 22:56:45 +02:00
ok ( restoredc - > iRelative = = - 1 , " first restore %d \n " , restoredc - > iRelative ) ;
2008-04-28 09:02:31 +02:00
check_dc_state ( hdc , restore_no , - 2 , - 2 , 8192 , 8192 , 20 , 20 , 20479 , 20478 ) ;
2005-10-31 11:05:52 +01:00
break ;
case 2 :
2006-10-12 22:56:45 +02:00
ok ( restoredc - > iRelative = = - 3 , " second restore %d \n " , restoredc - > iRelative ) ;
2008-04-28 09:02:31 +02:00
check_dc_state ( hdc , restore_no , 0 , 0 , 16384 , 16384 , 0 , 0 , 17873 , 17872 ) ;
2005-10-31 11:05:52 +01:00
break ;
case 3 :
2006-10-12 22:56:45 +02:00
ok ( restoredc - > iRelative = = - 2 , " third restore %d \n " , restoredc - > iRelative ) ;
2008-04-28 09:02:31 +02:00
check_dc_state ( hdc , restore_no , - 4 , - 4 , 32767 , 32767 , 40 , 40 , 3276 , 3276 ) ;
2005-10-31 11:05:52 +01:00
break ;
}
ok ( restore_no < = 3 , " restore_no %d \n " , restore_no ) ;
save_state + = restoredc - > iRelative ;
break ;
}
2009-04-03 20:35:38 +02:00
case EMR_SELECTOBJECT :
{
const EMRSELECTOBJECT * selectobj = ( const EMRSELECTOBJECT * ) emr ;
trace ( " EMR_SELECTOBJECT: %x \n " , selectobj - > ihObject ) ;
select_no + + ;
break ;
}
2005-10-31 11:05:52 +01:00
case EMR_EOF :
ok ( save_state = = 0 , " EOF save_state %d \n " , save_state ) ;
2009-04-07 15:20:13 +02:00
ok ( select_no = = 3 , " Too many/few selects %i \n " , select_no ) ;
2005-10-31 11:05:52 +01:00
break ;
}
2008-04-28 09:02:31 +02:00
SetLastError ( 0xdeadbeef ) ;
ret = GetWorldTransform ( hdc , & xform ) ;
if ( ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED )
{
2011-01-02 18:50:17 +01:00
ret = GetWindowOrgEx ( hdc , & pt ) ;
ok ( ret , " GetWindowOrgEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
trace ( " window org (%d,%d) \n " , pt . x , pt . y ) ;
2011-01-02 18:50:17 +01:00
ret = GetViewportOrgEx ( hdc , & pt ) ;
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
trace ( " vport org (%d,%d) \n " , pt . x , pt . y ) ;
2011-01-02 18:50:17 +01:00
ret = GetWindowExtEx ( hdc , & size ) ;
ok ( ret , " GetWindowExtEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
trace ( " window ext (%d,%d) \n " , size . cx , size . cy ) ;
2011-01-02 18:50:17 +01:00
ret = GetViewportExtEx ( hdc , & size ) ;
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2008-04-28 09:02:31 +02:00
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 ) ;
}
2006-12-10 16:51:26 +01:00
return 1 ;
2005-10-31 11:05:52 +01:00
}
2006-12-10 16:51:26 +01:00
static void test_SaveDC ( void )
2005-10-31 11:05:52 +01:00
{
HDC hdcMetafile , hdcDisplay ;
HENHMETAFILE hMetafile ;
HWND hwnd ;
int ret ;
2009-04-03 20:35:38 +02:00
POINT pt ;
SIZE size ;
2009-04-07 15:20:13 +02:00
HFONT hFont , hFont2 , hFontOld , hFontCheck ;
2008-04-28 09:02:31 +02:00
static const RECT rc = { 0 , 0 , 150 , 150 } ;
2005-10-31 11:05:52 +01:00
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA ( 0 , " static " , NULL , WS_POPUP | WS_VISIBLE ,
0 , 0 , 200 , 200 , 0 , 0 , 0 , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hwnd ! = 0 , " CreateWindowExA error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
hdcDisplay = GetDC ( hwnd ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcDisplay ! = 0 , " GetDC error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
hdcMetafile = CreateEnhMetaFileA ( hdcDisplay , NULL , NULL , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
2008-04-28 09:02:31 +02:00
SetMapMode ( hdcMetafile , MM_ANISOTROPIC ) ;
2005-10-31 11:05:52 +01:00
/* Need to write something to the emf, otherwise Windows won't play it back */
2008-04-28 09:02:31 +02:00
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 ) ;
2005-10-31 11:05:52 +01:00
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( pt . x = = 0 , " Expecting ViewportOrg x of 0, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( size . cx = = 120 , " Expecting ViewportExt cx of 120, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
ret = SaveDC ( hdcMetafile ) ;
ok ( ret = = 1 , " ret = %d \n " , ret ) ;
2008-04-28 09:02:31 +02:00
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 ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( pt . x = = 10 , " Expecting ViewportOrg x of 10, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( size . cx = = 200 , " Expecting ViewportExt cx of 200, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
ret = SaveDC ( hdcMetafile ) ;
ok ( ret = = 2 , " ret = %d \n " , ret ) ;
2008-04-28 09:02:31 +02:00
SetWindowOrgEx ( hdcMetafile , - 2 , - 2 , NULL ) ;
SetViewportOrgEx ( hdcMetafile , 20 , 20 , NULL ) ;
SetWindowExtEx ( hdcMetafile , 120 , 120 , NULL ) ;
SetViewportExtEx ( hdcMetafile , 300 , 300 , NULL ) ;
2009-04-07 15:20:13 +02:00
SetPolyFillMode ( hdcMetafile , ALTERNATE ) ;
SetBkColor ( hdcMetafile , 0 ) ;
2008-04-28 09:02:31 +02:00
/* Force Win9x to update DC state */
SetPixelV ( hdcMetafile , 50 , 50 , 0 ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( pt . x = = 20 , " Expecting ViewportOrg x of 20, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( size . cx = = 300 , " Expecting ViewportExt cx of 300, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
ret = SaveDC ( hdcMetafile ) ;
ok ( ret = = 3 , " ret = %d \n " , ret ) ;
2008-04-28 09:02:31 +02:00
SetWindowOrgEx ( hdcMetafile , - 3 , - 3 , NULL ) ;
SetViewportOrgEx ( hdcMetafile , 30 , 30 , NULL ) ;
SetWindowExtEx ( hdcMetafile , 200 , 200 , NULL ) ;
SetViewportExtEx ( hdcMetafile , 400 , 400 , NULL ) ;
2009-04-07 15:20:13 +02:00
SetPolyFillMode ( hdcMetafile , WINDING ) ;
SetBkColor ( hdcMetafile , 0x123456 ) ;
ok ( GetPolyFillMode ( hdcMetafile ) = = WINDING , " PolyFillMode not restored \n " ) ;
ok ( GetBkColor ( hdcMetafile ) = = 0x123456 , " Background color not restored \n " ) ;
2008-04-28 09:02:31 +02:00
/* Force Win9x to update DC state */
SetPixelV ( hdcMetafile , 50 , 50 , 0 ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( pt . x = = 30 , " Expecting ViewportOrg x of 30, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( size . cx = = 400 , " Expecting ViewportExt cx of 400, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
ret = RestoreDC ( hdcMetafile , - 1 ) ;
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 20:41:41 +02:00
ok ( pt . x = = 20 , " Expecting ViewportOrg x of 20, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 20:41:41 +02:00
ok ( size . cx = = 300 , " Expecting ViewportExt cx of 300, got %i \n " , size . cx ) ;
ok ( GetPolyFillMode ( hdcMetafile ) = = ALTERNATE , " PolyFillMode not restored \n " ) ;
ok ( GetBkColor ( hdcMetafile ) = = 0 , " Background color not restored \n " ) ;
2005-10-31 11:05:52 +01:00
ret = SaveDC ( hdcMetafile ) ;
ok ( ret = = 3 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 20:41:41 +02:00
ok ( pt . x = = 20 , " Expecting ViewportOrg x of 20, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 20:41:41 +02:00
ok ( size . cx = = 300 , " Expecting ViewportExt cx of 300, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
ret = RestoreDC ( hdcMetafile , 1 ) ;
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 20:41:41 +02:00
ok ( pt . x = = 0 , " Expecting ViewportOrg x of 0, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 20:41:41 +02:00
ok ( size . cx = = 120 , " Expecting ViewportExt cx of 120, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
2008-04-28 09:02:31 +02:00
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 ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( pt . x = = 40 , " Expecting ViewportOrg x of 40, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( size . cx = = 50 , " Expecting ViewportExt cx of 50, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
ret = SaveDC ( hdcMetafile ) ;
ok ( ret = = 1 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( pt . x = = 40 , " Expecting ViewportOrg x of 40, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( size . cx = = 50 , " Expecting ViewportExt cx of 50, got %i \n " , size . cx ) ;
2005-10-31 11:05:52 +01:00
ret = SaveDC ( hdcMetafile ) ;
ok ( ret = = 2 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
memset ( & orig_lf , 0 , sizeof ( orig_lf ) ) ;
orig_lf . lfCharSet = ANSI_CHARSET ;
orig_lf . lfClipPrecision = CLIP_DEFAULT_PRECIS ;
orig_lf . lfWeight = FW_DONTCARE ;
orig_lf . lfHeight = 7 ;
orig_lf . lfQuality = DEFAULT_QUALITY ;
lstrcpyA ( orig_lf . lfFaceName , " Arial " ) ;
hFont = CreateFontIndirectA ( & orig_lf ) ;
ok ( hFont ! = 0 , " CreateFontIndirectA error %d \n " , GetLastError ( ) ) ;
hFontOld = SelectObject ( hdcMetafile , hFont ) ;
2009-04-07 15:20:13 +02:00
hFont2 = CreateFontIndirectA ( & orig_lf ) ;
ok ( hFont2 ! = 0 , " CreateFontIndirectA error %d \n " , GetLastError ( ) ) ;
hFontCheck = SelectObject ( hdcMetafile , hFont2 ) ;
ok ( hFontCheck = = hFont , " Font not selected \n " ) ;
2009-04-03 20:35:38 +02:00
/* Force Win9x to update DC state */
SetPixelV ( hdcMetafile , 50 , 50 , 0 ) ;
ret = RestoreDC ( hdcMetafile , 1 ) ;
ok ( ret , " ret = %d \n " , ret ) ;
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportOrgEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( pt . x = = 40 , " Expecting ViewportOrg x of 40, got %i \n " , pt . x ) ;
2009-04-03 20:35:38 +02:00
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
2011-02-09 22:44:13 +01:00
ok ( ret , " GetViewportExtEx error %u \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ok ( size . cx = = 50 , " Expecting ViewportExt cx of 50, got %i \n " , size . cx ) ;
2009-04-03 20:35:38 +02:00
hFontCheck = SelectObject ( hdcMetafile , hFontOld ) ;
2009-04-07 20:41:41 +02:00
ok ( hFontOld = = hFontCheck & & hFontCheck ! = hFont & & hFontCheck ! = hFont2 ,
" Font not reverted with DC Restore \n " ) ;
2009-04-03 20:35:38 +02:00
2009-04-07 20:32:58 +02:00
ret = RestoreDC ( hdcMetafile , - 20 ) ;
ok ( ! ret , " ret = %d \n " , ret ) ;
ret = RestoreDC ( hdcMetafile , 20 ) ;
ok ( ! ret , " ret = %d \n " , ret ) ;
2005-10-31 11:05:52 +01:00
hMetafile = CloseEnhMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
ret = EnumEnhMetaFile ( hdcDisplay , hMetafile , savedc_emf_enum_proc , 0 , & rc ) ;
ok ( ret = = 1 , " EnumEnhMetaFile rets %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = DeleteObject ( hFont ) ;
ok ( ret , " DeleteObject error %d \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ret = DeleteObject ( hFont2 ) ;
ok ( ret , " DeleteObject error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
ret = DeleteEnhMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
ret = ReleaseDC ( hwnd , hdcDisplay ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " ReleaseDC error %d \n " , GetLastError ( ) ) ;
2005-10-31 11:05:52 +01:00
DestroyWindow ( hwnd ) ;
2004-03-09 20:19:53 +01:00
}
2009-04-03 20:35:38 +02:00
static void test_mf_SaveDC ( void )
{
HDC hdcMetafile ;
HMETAFILE hMetafile ;
int ret ;
POINT pt ;
SIZE size ;
2009-04-07 15:20:13 +02:00
HFONT hFont , hFont2 , hFontOld , hFontCheck ;
2009-04-03 20:35:38 +02:00
hdcMetafile = CreateMetaFileA ( NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateMetaFileA error %d \n " , GetLastError ( ) ) ;
ret = SetMapMode ( hdcMetafile , MM_ANISOTROPIC ) ;
ok ( ret , " SetMapMode should not fail \n " ) ;
/* Need to write something to the emf, otherwise Windows won't play it back */
LineTo ( hdcMetafile , 150 , 150 ) ;
2011-03-09 16:21:45 +01:00
pt . x = pt . y = 5555 ;
SetWindowOrgEx ( hdcMetafile , 0 , 0 , & pt ) ;
ok ( pt . x = = 5555 & & pt . y = = 5555 , " wrong origin %d,%d \n " , pt . x , pt . y ) ;
pt . x = pt . y = 5555 ;
SetViewportOrgEx ( hdcMetafile , 0 , 0 , & pt ) ;
ok ( pt . x = = 5555 & & pt . y = = 5555 , " wrong origin %d,%d \n " , pt . x , pt . y ) ;
size . cx = size . cy = 5555 ;
SetWindowExtEx ( hdcMetafile , 110 , 110 , & size ) ;
ok ( size . cx = = 5555 & & size . cy = = 5555 , " wrong size %d,%d \n " , size . cx , size . cy ) ;
size . cx = size . cy = 5555 ;
SetViewportExtEx ( hdcMetafile , 120 , 120 , & size ) ;
ok ( size . cx = = 5555 & & size . cy = = 5555 , " wrong size %d,%d \n " , size . cx , size . cy ) ;
2009-04-03 20:35:38 +02:00
/* Force Win9x to update DC state */
SetPixelV ( hdcMetafile , 50 , 50 , 0 ) ;
ret = GetViewportOrgEx ( hdcMetafile , & pt ) ;
todo_wine ok ( ! ret , " GetViewportOrgEx should fail \n " ) ;
ret = GetViewportExtEx ( hdcMetafile , & size ) ;
todo_wine ok ( ! ret , " GetViewportExtEx should fail \n " ) ;
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 ) ;
2009-04-07 20:32:58 +02:00
ok ( ret = = 1 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
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 ) ;
2009-04-07 15:20:13 +02:00
SetPolyFillMode ( hdcMetafile , ALTERNATE ) ;
SetBkColor ( hdcMetafile , 0 ) ;
2009-04-03 20:35:38 +02:00
ret = SaveDC ( hdcMetafile ) ;
2009-04-07 20:32:58 +02:00
ok ( ret = = 1 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
SetWindowOrgEx ( hdcMetafile , - 3 , - 3 , NULL ) ;
SetViewportOrgEx ( hdcMetafile , 30 , 30 , NULL ) ;
SetWindowExtEx ( hdcMetafile , 200 , 200 , NULL ) ;
SetViewportExtEx ( hdcMetafile , 400 , 400 , NULL ) ;
2009-04-07 15:20:13 +02:00
SetPolyFillMode ( hdcMetafile , WINDING ) ;
SetBkColor ( hdcMetafile , 0x123456 ) ;
todo_wine ok ( ! GetPolyFillMode ( hdcMetafile ) , " GetPolyFillMode succeeded \n " ) ;
todo_wine ok ( GetBkColor ( hdcMetafile ) = = CLR_INVALID , " GetBkColor succeeded \n " ) ;
2009-04-03 20:35:38 +02:00
/* Force Win9x to update DC state */
SetPixelV ( hdcMetafile , 50 , 50 , 0 ) ;
ret = RestoreDC ( hdcMetafile , - 1 ) ;
2009-04-07 20:41:41 +02:00
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = SaveDC ( hdcMetafile ) ;
2009-04-07 20:32:58 +02:00
ok ( ret = = 1 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = RestoreDC ( hdcMetafile , 1 ) ;
2009-04-07 20:41:41 +02:00
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
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 ) ;
2009-04-07 20:32:58 +02:00
ok ( ret = = 1 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
ret = SaveDC ( hdcMetafile ) ;
2009-04-07 20:32:58 +02:00
ok ( ret = = 1 , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
memset ( & orig_lf , 0 , sizeof ( orig_lf ) ) ;
orig_lf . lfCharSet = ANSI_CHARSET ;
orig_lf . lfClipPrecision = CLIP_DEFAULT_PRECIS ;
orig_lf . lfWeight = FW_DONTCARE ;
orig_lf . lfHeight = 7 ;
orig_lf . lfQuality = DEFAULT_QUALITY ;
lstrcpyA ( orig_lf . lfFaceName , " Arial " ) ;
hFont = CreateFontIndirectA ( & orig_lf ) ;
ok ( hFont ! = 0 , " CreateFontIndirectA error %d \n " , GetLastError ( ) ) ;
hFontOld = SelectObject ( hdcMetafile , hFont ) ;
2009-04-07 15:20:13 +02:00
hFont2 = CreateFontIndirectA ( & orig_lf ) ;
ok ( hFont2 ! = 0 , " CreateFontIndirectA error %d \n " , GetLastError ( ) ) ;
hFontCheck = SelectObject ( hdcMetafile , hFont2 ) ;
ok ( hFontCheck = = hFont , " Font not selected \n " ) ;
2009-04-03 20:35:38 +02:00
/* Force Win9x to update DC state */
SetPixelV ( hdcMetafile , 50 , 50 , 0 ) ;
ret = RestoreDC ( hdcMetafile , 1 ) ;
2009-04-07 20:41:41 +02:00
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-03 20:35:38 +02:00
hFontCheck = SelectObject ( hdcMetafile , hFontOld ) ;
2009-04-07 15:20:13 +02:00
ok ( hFontOld ! = hFontCheck & & hFontCheck = = hFont2 , " Font incorrectly reverted with DC Restore \n " ) ;
2009-04-03 20:35:38 +02:00
2009-04-07 20:32:58 +02:00
/* restore level is ignored */
ret = RestoreDC ( hdcMetafile , - 20 ) ;
2009-04-07 20:41:41 +02:00
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-07 20:32:58 +02:00
ret = RestoreDC ( hdcMetafile , 20 ) ;
2009-04-07 20:41:41 +02:00
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-07 20:32:58 +02:00
ret = RestoreDC ( hdcMetafile , 0 ) ;
2009-04-07 20:41:41 +02:00
ok ( ret , " ret = %d \n " , ret ) ;
2009-04-07 20:32:58 +02:00
2009-04-03 20:35:38 +02:00
hMetafile = CloseMetaFile ( hdcMetafile ) ;
2019-11-21 16:10:21 +01:00
ok ( hMetafile ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
2009-04-03 20:35:38 +02:00
ret = DeleteMetaFile ( hMetafile ) ;
ok ( ret , " DeleteMetaFile error %d \n " , GetLastError ( ) ) ;
ret = DeleteObject ( hFont ) ;
ok ( ret , " DeleteObject error %d \n " , GetLastError ( ) ) ;
2009-04-07 15:20:13 +02:00
ret = DeleteObject ( hFont2 ) ;
ok ( ret , " DeleteObject error %d \n " , GetLastError ( ) ) ;
2009-04-03 20:35:38 +02:00
}
2004-12-09 12:37:59 +01:00
/* Win-format metafile (mfdrv) tests */
/* These tests compare the generated metafiles byte-by-byte */
/* with the nominal results. */
/* Maximum size of sample metafiles in bytes. */
2016-04-21 17:41:21 +02:00
# define MF_BUFSIZE 1024
2004-12-09 12:37:59 +01:00
/* 8x8 bitmap data for a pattern brush */
static const unsigned char SAMPLE_PATTERN_BRUSH [ ] = {
0x01 , 0x00 , 0x02 , 0x00 ,
0x03 , 0x00 , 0x04 , 0x00 ,
0x05 , 0x00 , 0x06 , 0x00 ,
0x07 , 0x00 , 0x08 , 0x00
} ;
/* Sample metafiles to be compared to the outputs of the
* test functions .
*/
static const unsigned char MF_BLANK_BITS [ ] = {
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x0c , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
} ;
static const unsigned char MF_GRAPHICS_BITS [ ] = {
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x22 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x07 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x14 , 0x02 ,
0x01 , 0x00 , 0x01 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x13 , 0x02 , 0x02 , 0x00 , 0x02 , 0x00 , 0x05 , 0x00 ,
0x00 , 0x00 , 0x14 , 0x02 , 0x01 , 0x00 , 0x01 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x00 , 0x18 , 0x04 , 0x02 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00
} ;
static const unsigned char MF_PATTERN_BRUSH_BITS [ ] = {
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x3d , 0x00 ,
0x00 , 0x00 , 0x01 , 0x00 , 0x2d , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x2d , 0x00 , 0x00 , 0x00 , 0x42 , 0x01 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x28 , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x00 , 0x06 , 0x00 , 0x00 , 0x00 ,
0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x2d , 0x01 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00
} ;
2011-03-10 20:22:22 +01:00
static const unsigned char MF_DCBRUSH_BITS [ ] =
{
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x2a , 0x00 ,
0x00 , 0x00 , 0x02 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x07 , 0x00 , 0x00 , 0x00 , 0xfc , 0x02 ,
0x00 , 0x00 , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x2d , 0x01 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0xfa , 0x02 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x2d , 0x01 , 0x01 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x00 , 0x1b , 0x04 , 0x14 , 0x00 ,
0x14 , 0x00 , 0x0a , 0x00 , 0x0a , 0x00 , 0x03 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00
} ;
2005-11-07 17:40:20 +01:00
static const unsigned char MF_TEXTOUT_ON_PATH_BITS [ ] =
{
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x19 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x0d , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x0d , 0x00 , 0x00 , 0x00 , 0x32 , 0x0a ,
0x16 , 0x00 , 0x0b , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x54 , 0x65 , 0x73 , 0x74 , 0x03 , 0x00 , 0x05 , 0x00 ,
0x08 , 0x00 , 0x0c , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00
} ;
static const unsigned char EMF_TEXTOUT_ON_PATH_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xe7 , 0xff , 0xff , 0xff , 0xe9 , 0xff , 0xff , 0xff ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0xf4 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x40 , 0x01 , 0x00 , 0x00 , 0xf0 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xe2 , 0x04 , 0x00 ,
0x80 , 0xa9 , 0x03 , 0x00 , 0x3b , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x54 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x01 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0xc8 , 0x41 , 0x00 , 0x80 , 0xbb , 0x41 ,
0x0b , 0x00 , 0x00 , 0x00 , 0x16 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x4c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x54 , 0x00 , 0x00 , 0x00 ,
0x54 , 0x00 , 0x65 , 0x00 , 0x73 , 0x00 , 0x74 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x3c , 0x00 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
} ;
2018-11-29 10:28:20 +01:00
static const unsigned char EMF_TEXTOUT_OUTLINE_ON_PATH_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xdd , 0xff , 0xff , 0xff , 0xdd , 0xff , 0xff , 0xff ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0x0c , 0x01 , 0x00 , 0x00 , 0x07 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x90 , 0x06 , 0x00 , 0x00 , 0x1a , 0x04 , 0x00 , 0x00 ,
0x51 , 0x02 , 0x00 , 0x00 , 0x72 , 0x01 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x1a , 0x0b , 0x09 , 0x00 ,
0xf0 , 0xa6 , 0x05 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x0d , 0x00 , 0x00 , 0x80 ,
0x3b , 0x00 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x54 , 0x00 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0x01 , 0x00 , 0x00 , 0x00 , 0xc3 , 0x30 , 0x0d , 0x42 ,
0xcf , 0xf3 , 0x0c , 0x42 , 0x0b , 0x00 , 0x00 , 0x00 ,
0x16 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x4c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0x54 , 0x00 , 0x00 , 0x00 , 0x54 , 0x00 , 0x65 , 0x00 ,
0x73 , 0x00 , 0x74 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x05 , 0x00 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x3c , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x0d , 0x00 , 0x00 , 0x80 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
} ;
2006-03-30 16:03:02 +02:00
static const unsigned char MF_LINETO_BITS [ ] = {
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x11 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x13 , 0x02 ,
0x0f , 0x00 , 0x37 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00
} ;
static const unsigned char EMF_LINETO_BITS [ ] = {
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x37 , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x61 , 0x06 , 0x00 , 0x00 , 0xb7 , 0x01 , 0x00 , 0x00 ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0x38 , 0x01 , 0x00 , 0x00 , 0x0b , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x7c , 0x01 , 0x00 , 0x00 , 0x2c , 0x01 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x60 , 0xcc , 0x05 , 0x00 ,
0xe0 , 0x93 , 0x04 , 0x00 , 0x46 , 0x00 , 0x00 , 0x00 ,
0x48 , 0x00 , 0x00 , 0x00 , 0x3a , 0x00 , 0x00 , 0x00 ,
0x47 , 0x44 , 0x49 , 0x43 , 0x01 , 0x00 , 0x00 , 0x80 ,
0x00 , 0x03 , 0x00 , 0x00 , 0x60 , 0xe5 , 0xf4 , 0x73 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x22 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x11 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x13 , 0x02 ,
0x0f , 0x00 , 0x37 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x11 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x0b , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x09 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x36 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x37 , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x25 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x80 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 ,
0x30 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x80 , 0x4b , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x05 , 0x00 , 0x00 , 0x00 , 0x0e , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00
} ;
static const unsigned char EMF_LINETO_MM_ANISOTROPIC_BITS [ ] = {
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x37 , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0x38 , 0x01 , 0x00 , 0x00 , 0x0b , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x7c , 0x01 , 0x00 , 0x00 , 0x2c , 0x01 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x60 , 0xcc , 0x05 , 0x00 ,
0xe0 , 0x93 , 0x04 , 0x00 , 0x46 , 0x00 , 0x00 , 0x00 ,
0x48 , 0x00 , 0x00 , 0x00 , 0x3a , 0x00 , 0x00 , 0x00 ,
0x47 , 0x44 , 0x49 , 0x43 , 0x01 , 0x00 , 0x00 , 0x80 ,
0x00 , 0x03 , 0x00 , 0x00 , 0xa4 , 0xfe , 0xf4 , 0x73 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x22 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x11 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x13 , 0x02 ,
0x0f , 0x00 , 0x37 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x11 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
0x0b , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x09 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x36 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x37 , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x25 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x80 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 ,
0x30 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x80 , 0x4b , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x05 , 0x00 , 0x00 , 0x00 , 0x0e , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00
} ;
static const unsigned char EMF_LINETO_MM_TEXT_BITS [ ] = {
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x37 , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x61 , 0x06 , 0x00 , 0x00 , 0xb7 , 0x01 , 0x00 , 0x00 ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0xe4 , 0x00 , 0x00 , 0x00 , 0x09 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x7c , 0x01 , 0x00 , 0x00 , 0x2c , 0x01 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x60 , 0xcc , 0x05 , 0x00 ,
0xe0 , 0x93 , 0x04 , 0x00 , 0x0b , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 ,
0x00 , 0x04 , 0x00 , 0x00 , 0x09 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 ,
0x00 , 0x04 , 0x00 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x37 , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x07 , 0x00 , 0x00 , 0x80 ,
0x25 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x80 , 0x30 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x80 ,
0x4b , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
} ;
2009-11-22 21:25:42 +01:00
static const unsigned char EMF_BITBLT [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2016-04-21 17:41:21 +02:00
0x4f , 0x00 , 0x00 , 0x00 , 0x4f , 0x00 , 0x00 , 0x00 ,
2009-11-22 21:25:42 +01:00
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
2016-04-21 17:41:21 +02:00
0x64 , 0x02 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
2009-11-22 21:25:42 +01:00
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2016-04-21 17:41:21 +02:00
0x80 , 0x07 , 0x00 , 0x00 , 0xb0 , 0x04 , 0x00 , 0x00 ,
0xfc , 0x01 , 0x00 , 0x00 , 0x3e , 0x01 , 0x00 , 0x00 ,
2009-11-22 21:25:42 +01:00
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2016-04-21 17:41:21 +02:00
0x00 , 0x00 , 0x00 , 0x00 , 0x60 , 0xc0 , 0x07 , 0x00 ,
0x30 , 0xda , 0x04 , 0x00 , 0x4c , 0x00 , 0x00 , 0x00 ,
2009-11-22 21:25:42 +01:00
0xbc , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x20 , 0x00 , 0xcc , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x80 , 0x3f , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 , 0x3f ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0x28 , 0x00 , 0x00 , 0x00 ,
0x8c , 0x00 , 0x00 , 0x00 , 0x30 , 0x00 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x18 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x30 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x4c , 0x00 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x62 , 0x00 , 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x80 , 0x3f ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x80 , 0x3f , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2016-04-21 17:41:21 +02:00
0x00 , 0x00 , 0x00 , 0x00 , 0x4d , 0x00 , 0x00 , 0x00 ,
0xc4 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x20 , 0x00 , 0xcc , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x0a , 0xd7 , 0xa3 , 0x3b , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x0a , 0xd7 , 0x23 , 0x3c ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x6c , 0x00 , 0x00 , 0x00 , 0x28 , 0x00 , 0x00 , 0x00 ,
0x94 , 0x00 , 0x00 , 0x00 , 0x30 , 0x00 , 0x00 , 0x00 ,
0x90 , 0x01 , 0x00 , 0x00 , 0x90 , 0x01 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x18 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x30 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
2009-11-22 21:25:42 +01:00
} ;
2011-03-10 20:22:22 +01:00
static const unsigned char EMF_DCBRUSH_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x13 , 0x00 , 0x00 , 0x00 , 0x13 , 0x00 , 0x00 , 0x00 ,
0x39 , 0x01 , 0x00 , 0x00 , 0x39 , 0x01 , 0x00 , 0x00 ,
0x52 , 0x02 , 0x00 , 0x00 , 0x52 , 0x02 , 0x00 , 0x00 ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0x44 , 0x01 , 0x00 , 0x00 , 0x0e , 0x00 , 0x00 , 0x00 ,
0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x04 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 ,
0x40 , 0x01 , 0x00 , 0x00 , 0xf0 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xe2 , 0x04 , 0x00 ,
0x80 , 0xa9 , 0x03 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x12 , 0x00 , 0x00 , 0x80 ,
0x25 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x13 , 0x00 , 0x00 , 0x80 , 0x27 , 0x00 , 0x00 , 0x00 ,
0x18 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x55 , 0x55 , 0x55 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x26 , 0x00 , 0x00 , 0x00 , 0x1c , 0x00 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x33 , 0x44 , 0x55 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x2b , 0x00 , 0x00 , 0x00 , 0x18 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x13 , 0x00 , 0x00 , 0x00 , 0x13 , 0x00 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x27 , 0x00 , 0x00 , 0x00 ,
0x18 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x12 , 0x34 , 0x56 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x0c , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x28 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
} ;
2009-11-22 21:25:42 +01:00
2012-01-17 04:38:15 +01:00
static const unsigned char EMF_BEZIER_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x80 , 0x00 , 0x00 , 0x01 , 0x80 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x1a , 0x2a , 0x0d , 0x00 , 0x1a , 0x2f , 0x0d , 0x00 ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0x44 , 0x01 , 0x00 , 0x00 , 0x06 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x51 , 0x01 , 0x00 , 0x00 , 0x0e , 0x01 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x68 , 0x24 , 0x05 , 0x00 ,
0xb0 , 0x1e , 0x04 , 0x00 , 0x58 , 0x00 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x0a , 0x00 , 0x14 , 0x00 , 0x14 , 0x00 ,
0x0f , 0x00 , 0x0f , 0x00 , 0x55 , 0x00 , 0x00 , 0x00 ,
0x2c , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x19 , 0x00 , 0x00 , 0x00 ,
0x19 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x0a , 0x00 , 0x14 , 0x00 , 0x14 , 0x00 ,
0x0f , 0x00 , 0x0f , 0x00 , 0x19 , 0x00 , 0x19 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x3c , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x01 , 0x80 , 0x00 , 0x00 , 0x01 , 0x80 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x01 , 0x80 , 0x00 , 0x00 ,
0x01 , 0x80 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x00 , 0x19 , 0x00 , 0x00 , 0x00 ,
0x19 , 0x00 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x34 , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x00 , 0x01 , 0x80 , 0x00 , 0x00 ,
0x01 , 0x80 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x80 , 0x00 , 0x00 , 0x01 , 0x80 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x0f , 0x00 , 0x00 , 0x00 , 0x0f , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
} ;
2016-03-09 12:17:05 +01:00
static const unsigned char EMF_POLYPOLYLINE_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x90 , 0x00 , 0x00 , 0xf4 , 0x01 , 0x00 , 0x00 ,
0x61 , 0x01 , 0x00 , 0x00 , 0xc2 , 0x02 , 0x00 , 0x00 ,
0x7a , 0xd4 , 0x13 , 0x00 , 0xe8 , 0x44 , 0x00 , 0x00 ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0x84 , 0x01 , 0x00 , 0x00 , 0x07 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xa1 , 0x05 , 0x00 , 0x00 , 0x47 , 0x03 , 0x00 , 0x00 ,
0xfc , 0x01 , 0x00 , 0x00 , 0x28 , 0x01 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xc0 , 0xc1 , 0x07 , 0x00 ,
0x2c , 0x84 , 0x04 , 0x00 , 0x5a , 0x00 , 0x00 , 0x00 ,
0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x5a , 0x00 , 0x00 , 0x00 ,
0x2c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x02 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x14 , 0x00 ,
0x5a , 0x00 , 0x00 , 0x00 , 0x30 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0x02 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x14 , 0x00 , 0x64 , 0x00 , 0xc8 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x00 , 0x40 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0x02 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0xc8 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x90 , 0x00 , 0x00 , 0x2c , 0x01 , 0x00 , 0x00 ,
0x07 , 0x00 , 0x00 , 0x00 , 0x48 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x90 , 0x00 , 0x00 , 0xf4 , 0x01 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0xc8 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x90 , 0x00 , 0x00 , 0x2c , 0x01 , 0x00 , 0x00 ,
0x90 , 0x01 , 0x00 , 0x00 , 0xf4 , 0x01 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
} ;
2016-04-08 12:40:56 +02:00
static const unsigned char EMF_GRADIENTFILL_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x2b , 0x01 , 0x00 , 0x00 , 0x35 , 0x01 , 0x00 , 0x00 ,
0x23 , 0x00 , 0x00 , 0x00 , 0x61 , 0x01 , 0x00 , 0x00 ,
0x31 , 0x29 , 0x00 , 0x00 , 0xa3 , 0x2a , 0x00 , 0x00 ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0x0c , 0x01 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x40 , 0x05 , 0x00 , 0x00 , 0x46 , 0x03 , 0x00 , 0x00 ,
0xda , 0x01 , 0x00 , 0x00 , 0x28 , 0x01 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x15 , 0x3c , 0x07 , 0x00 ,
0xcb , 0x82 , 0x04 , 0x00 , 0x76 , 0x00 , 0x00 , 0x00 ,
0x8c , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x2b , 0x01 , 0x00 , 0x00 ,
0x35 , 0x01 , 0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x00 , 0xff , 0x00 , 0x80 , 0x00 , 0x00 , 0x01 , 0x80 ,
0xc8 , 0x00 , 0x00 , 0x00 , 0xd2 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0x00 , 0xff ,
0xb4 , 0x00 , 0x00 , 0x00 , 0xbe , 0x00 , 0x00 , 0x00 ,
0x34 , 0x12 , 0x78 , 0x56 , 0xbc , 0x9a , 0xf0 , 0xde ,
0x2c , 0x01 , 0x00 , 0x00 , 0x36 , 0x01 , 0x00 , 0x00 ,
0x00 , 0xff , 0x00 , 0xff , 0x00 , 0xff , 0x00 , 0x00 ,
0x90 , 0x01 , 0x00 , 0x00 , 0x9a , 0x01 , 0x00 , 0x00 ,
0x00 , 0xff , 0x00 , 0xff , 0x00 , 0xff , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
} ;
2005-11-07 17:40:20 +01:00
/* For debugging or dumping the raw metafiles produced by
* new test functions .
*/
static INT CALLBACK mf_enum_proc ( HDC hdc , HANDLETABLE * ht , METARECORD * mr ,
INT nobj , LPARAM param )
{
2006-10-12 22:56:45 +02:00
trace ( " hdc %p, mr->rdFunction %04x, mr->rdSize %u, param %p \n " ,
2005-11-07 17:40:20 +01:00
hdc , mr - > rdFunction , mr - > rdSize , ( void * ) param ) ;
return TRUE ;
}
2004-12-09 12:37:59 +01:00
/* For debugging or dumping the raw metafiles produced by
* new test functions .
*/
static void dump_mf_bits ( const HMETAFILE mf , const char * desc )
{
2006-03-30 16:03:02 +02:00
BYTE buf [ MF_BUFSIZE ] ;
2005-02-14 22:04:45 +01:00
UINT mfsize , i ;
2004-12-09 12:37:59 +01:00
2006-03-31 21:03:41 +02:00
if ( ! winetest_debug ) return ;
2004-12-09 12:37:59 +01:00
mfsize = GetMetaFileBitsEx ( mf , MF_BUFSIZE , buf ) ;
ok ( mfsize > 0 , " %s: GetMetaFileBitsEx failed. \n " , desc ) ;
printf ( " MetaFile %s has bits: \n { \n " , desc ) ;
for ( i = 0 ; i < mfsize ; i + + )
{
2006-03-30 16:03:02 +02:00
printf ( " 0x%02x " , buf [ i ] ) ;
2004-12-09 12:37:59 +01:00
if ( i = = mfsize - 1 )
printf ( " \n " ) ;
else if ( i % 8 = = 7 )
printf ( " , \n " ) ;
else
printf ( " , " ) ;
}
printf ( " }; \n " ) ;
}
/* Compare the metafile produced by a test function with the
* expected raw metafile data in " bits " .
* Return value is 0 for a perfect match ,
* - 1 if lengths aren ' t equal ,
* otherwise returns the number of non - matching bytes .
*/
2005-08-08 17:03:42 +02:00
static int compare_mf_bits ( const HMETAFILE mf , const unsigned char * bits , UINT bsize ,
2004-12-09 12:37:59 +01:00
const char * desc )
{
2005-08-08 17:03:42 +02:00
unsigned char buf [ MF_BUFSIZE ] ;
2005-02-14 22:04:45 +01:00
UINT mfsize , i ;
int diff ;
2004-12-09 12:37:59 +01:00
mfsize = GetMetaFileBitsEx ( mf , MF_BUFSIZE , buf ) ;
ok ( mfsize > 0 , " %s: GetMetaFileBitsEx failed. \n " , desc ) ;
if ( mfsize < MF_BUFSIZE )
ok ( mfsize = = bsize , " %s: mfsize=%d, bsize=%d. \n " ,
desc , mfsize , bsize ) ;
else
ok ( bsize > = MF_BUFSIZE , " %s: mfsize > bufsize (%d bytes), bsize=%d. \n " ,
desc , mfsize , bsize ) ;
if ( mfsize ! = bsize )
return - 1 ;
diff = 0 ;
for ( i = 0 ; i < bsize ; i + + )
{
if ( buf [ i ] ! = bits [ i ] )
diff + + ;
}
ok ( diff = = 0 , " %s: mfsize=%d, bsize=%d, diff=%d \n " ,
desc , mfsize , bsize , diff ) ;
return diff ;
}
2005-10-18 12:35:14 +02:00
static int compare_mf_disk_bits ( LPCSTR name , const BYTE * bits , UINT bsize , const char * desc )
{
unsigned char buf [ MF_BUFSIZE ] ;
DWORD mfsize , rd_size , i ;
int diff ;
HANDLE hfile ;
BOOL ret ;
hfile = CreateFileA ( name , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , 0 , 0 ) ;
assert ( hfile ! = INVALID_HANDLE_VALUE ) ;
mfsize = GetFileSize ( hfile , NULL ) ;
assert ( mfsize < = MF_BUFSIZE ) ;
ret = ReadFile ( hfile , buf , sizeof ( buf ) , & rd_size , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( ret & & rd_size = = mfsize , " ReadFile: error %d \n " , GetLastError ( ) ) ;
2005-10-18 12:35:14 +02:00
CloseHandle ( hfile ) ;
2006-10-12 22:56:45 +02:00
ok ( mfsize = = bsize , " %s: mfsize=%d, bsize=%d. \n " , desc , mfsize , bsize ) ;
2005-10-18 12:35:14 +02:00
if ( mfsize ! = bsize )
return - 1 ;
diff = 0 ;
for ( i = 0 ; i < bsize ; i + + )
{
if ( buf [ i ] ! = bits [ i ] )
diff + + ;
}
2006-10-12 22:56:45 +02:00
ok ( diff = = 0 , " %s: mfsize=%d, bsize=%d, diff=%d \n " ,
2005-10-18 12:35:14 +02:00
desc , mfsize , bsize , diff ) ;
return diff ;
}
2005-11-07 17:40:20 +01:00
/* For debugging or dumping the raw EMFs produced by
* new test functions .
*/
static void dump_emf_bits ( const HENHMETAFILE mf , const char * desc )
{
BYTE buf [ MF_BUFSIZE ] ;
UINT mfsize , i ;
2006-03-31 21:03:41 +02:00
if ( ! winetest_debug ) return ;
2005-11-07 17:40:20 +01:00
mfsize = GetEnhMetaFileBits ( mf , MF_BUFSIZE , buf ) ;
ok ( mfsize > 0 , " %s: GetEnhMetaFileBits failed \n " , desc ) ;
printf ( " EMF %s has bits: \n { \n " , desc ) ;
for ( i = 0 ; i < mfsize ; i + + )
{
printf ( " 0x%02x " , buf [ i ] ) ;
if ( i = = mfsize - 1 )
printf ( " \n " ) ;
else if ( i % 8 = = 7 )
printf ( " , \n " ) ;
else
printf ( " , " ) ;
}
printf ( " }; \n " ) ;
}
static void dump_emf_records ( const HENHMETAFILE mf , const char * desc )
{
BYTE * emf ;
BYTE buf [ MF_BUFSIZE ] ;
UINT mfsize , offset ;
2006-03-31 21:03:41 +02:00
if ( ! winetest_debug ) return ;
2005-11-07 17:40:20 +01:00
mfsize = GetEnhMetaFileBits ( mf , MF_BUFSIZE , buf ) ;
2006-10-12 22:56:45 +02:00
ok ( mfsize > 0 , " %s: GetEnhMetaFileBits error %d \n " , desc , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
printf ( " EMF %s has records: \n " , desc ) ;
emf = buf ;
offset = 0 ;
while ( offset < mfsize )
{
EMR * emr = ( EMR * ) ( emf + offset ) ;
2006-10-12 22:56:45 +02:00
printf ( " emr->iType %d, emr->nSize %u \n " , emr - > iType , emr - > nSize ) ;
2005-11-07 17:40:20 +01:00
/*trace("emr->iType 0x%04lx, emr->nSize 0x%04lx\n", emr->iType, emr->nSize);*/
offset + = emr - > nSize ;
}
}
2008-05-07 13:34:36 +02:00
static void dump_emf_record ( const ENHMETARECORD * emr , const char * desc )
{
const BYTE * buf ;
DWORD i ;
if ( ! winetest_debug ) return ;
printf ( " %s: EMF record %u has bits: \n { \n " , desc , emr - > iType ) ;
buf = ( const BYTE * ) emr ;
for ( i = 0 ; i < emr - > nSize ; i + + )
{
printf ( " 0x%02x " , buf [ i ] ) ;
if ( i = = emr - > nSize - 1 )
printf ( " \n " ) ;
else if ( i % 8 = = 7 )
printf ( " , \n " ) ;
else
printf ( " , " ) ;
}
printf ( " }; \n " ) ;
}
2008-05-25 14:30:10 +02:00
static void dump_EMREXTTEXTOUT ( const EMREXTTEXTOUTW * eto )
{
trace ( " rclBounds %d,%d - %d,%d \n " , eto - > rclBounds . left , eto - > rclBounds . top ,
eto - > rclBounds . right , eto - > rclBounds . bottom ) ;
trace ( " iGraphicsMode %u \n " , eto - > iGraphicsMode ) ;
trace ( " exScale: %f \n " , eto - > exScale ) ;
trace ( " eyScale: %f \n " , eto - > eyScale ) ;
trace ( " emrtext.ptlReference %d,%d \n " , eto - > emrtext . ptlReference . x , eto - > emrtext . ptlReference . y ) ;
trace ( " emrtext.nChars %u \n " , eto - > emrtext . nChars ) ;
trace ( " emrtext.offString %#x \n " , eto - > emrtext . offString ) ;
trace ( " emrtext.fOptions %#x \n " , eto - > emrtext . fOptions ) ;
trace ( " emrtext.rcl %d,%d - %d,%d \n " , eto - > emrtext . rcl . left , eto - > emrtext . rcl . top ,
eto - > emrtext . rcl . right , eto - > emrtext . rcl . bottom ) ;
trace ( " emrtext.offDx %#x \n " , eto - > emrtext . offDx ) ;
}
2008-05-07 13:34:36 +02:00
static BOOL match_emf_record ( const ENHMETARECORD * emr1 , const ENHMETARECORD * emr2 ,
2008-12-10 17:27:30 +01:00
const char * desc , BOOL ignore_scaling )
2008-05-07 13:34:36 +02:00
{
int diff ;
2008-12-10 17:27:30 +01:00
ok ( emr1 - > iType = = emr2 - > iType , " %s: emr->iType %u != %u \n " ,
desc , emr1 - > iType , emr2 - > iType ) ;
2008-05-07 13:34:36 +02:00
2008-12-10 17:27:30 +01:00
ok ( emr1 - > nSize = = emr2 - > nSize , " %s: emr->nSize %u != %u \n " ,
desc , emr1 - > nSize , emr2 - > nSize ) ;
2008-05-07 13:34:36 +02:00
/* iType and nSize mismatches are fatal */
if ( emr1 - > iType ! = emr2 - > iType | | emr1 - > nSize ! = emr2 - > nSize ) return FALSE ;
/* contents of EMR_GDICOMMENT are not interesting */
if ( emr1 - > iType = = EMR_GDICOMMENT ) return TRUE ;
2008-05-21 14:54:29 +02:00
/* different Windows versions setup DC scaling differently when
* converting an old style metafile to an EMF .
*/
if ( ignore_scaling & & ( emr1 - > iType = = EMR_SETWINDOWEXTEX | |
emr1 - > iType = = EMR_SETVIEWPORTEXTEX ) )
return TRUE ;
2008-05-25 14:30:10 +02:00
if ( emr1 - > iType = = EMR_EXTTEXTOUTW | | emr1 - > iType = = EMR_EXTTEXTOUTA )
{
EMREXTTEXTOUTW * eto1 , * eto2 ;
eto1 = HeapAlloc ( GetProcessHeap ( ) , 0 , emr1 - > nSize ) ;
memcpy ( eto1 , emr1 , emr1 - > nSize ) ;
eto2 = HeapAlloc ( GetProcessHeap ( ) , 0 , emr2 - > nSize ) ;
memcpy ( eto2 , emr2 , emr2 - > nSize ) ;
/* different Windows versions setup DC scaling differently */
eto1 - > exScale = eto1 - > eyScale = 0.0 ;
eto2 - > exScale = eto2 - > eyScale = 0.0 ;
diff = memcmp ( eto1 , eto2 , emr1 - > nSize ) ;
if ( diff )
{
dump_EMREXTTEXTOUT ( eto1 ) ;
dump_EMREXTTEXTOUT ( eto2 ) ;
}
HeapFree ( GetProcessHeap ( ) , 0 , eto1 ) ;
HeapFree ( GetProcessHeap ( ) , 0 , eto2 ) ;
}
2009-06-16 11:35:38 +02:00
else if ( emr1 - > iType = = EMR_EXTSELECTCLIPRGN & & ! lstrcmpA ( desc , " emf_clipping " ) )
{
/* We have to take care of NT4 differences here */
diff = memcmp ( emr1 , emr2 , emr1 - > nSize ) ;
if ( diff )
{
ENHMETARECORD * emr_nt4 ;
emr_nt4 = HeapAlloc ( GetProcessHeap ( ) , 0 , emr2 - > nSize ) ;
memcpy ( emr_nt4 , emr2 , emr2 - > nSize ) ;
/* Correct the nRgnSize field */
emr_nt4 - > dParm [ 5 ] = sizeof ( RECT ) ;
diff = memcmp ( emr1 , emr_nt4 , emr1 - > nSize ) ;
if ( ! diff )
win_skip ( " Catered for NT4 differences \n " ) ;
HeapFree ( GetProcessHeap ( ) , 0 , emr_nt4 ) ;
}
}
2012-01-17 04:38:15 +01:00
else if ( emr1 - > iType = = EMR_POLYBEZIERTO16 | | emr1 - > iType = = EMR_POLYBEZIER16 )
{
EMRPOLYBEZIER16 * eto1 , * eto2 ;
eto1 = ( EMRPOLYBEZIER16 * ) emr1 ;
eto2 = ( EMRPOLYBEZIER16 * ) emr2 ;
2012-04-15 21:57:27 +02:00
diff = eto1 - > cpts ! = eto2 - > cpts ;
2012-01-17 04:38:15 +01:00
if ( ! diff )
diff = memcmp ( eto1 - > apts , eto2 - > apts , eto1 - > cpts * sizeof ( POINTS ) ) ;
}
else if ( emr1 - > iType = = EMR_POLYBEZIERTO | | emr1 - > iType = = EMR_POLYBEZIER )
{
EMRPOLYBEZIER * eto1 , * eto2 ;
eto1 = ( EMRPOLYBEZIER * ) emr1 ;
eto2 = ( EMRPOLYBEZIER * ) emr2 ;
2012-04-15 21:57:27 +02:00
diff = eto1 - > cptl ! = eto2 - > cptl ;
2012-01-17 04:38:15 +01:00
if ( ! diff )
diff = memcmp ( eto1 - > aptl , eto2 - > aptl , eto1 - > cptl * sizeof ( POINTL ) ) ;
}
2008-05-25 14:30:10 +02:00
else
diff = memcmp ( emr1 , emr2 , emr1 - > nSize ) ;
2008-12-10 17:27:30 +01:00
ok ( diff = = 0 , " %s: contents of record %u don't match \n " , desc , emr1 - > iType ) ;
2008-05-07 13:34:36 +02:00
if ( diff )
{
dump_emf_record ( emr1 , " expected bits " ) ;
dump_emf_record ( emr2 , " actual bits " ) ;
}
2008-12-10 17:27:30 +01:00
return diff = = 0 ; /* report all non-fatal record mismatches */
2008-05-07 13:34:36 +02:00
}
2005-11-07 17:40:20 +01:00
/* Compare the EMF produced by a test function with the
* expected raw EMF data in " bits " .
* Return value is 0 for a perfect match ,
* - 1 if lengths aren ' t equal ,
* otherwise returns the number of non - matching bytes .
*/
static int compare_emf_bits ( const HENHMETAFILE mf , const unsigned char * bits ,
2008-05-21 14:54:29 +02:00
UINT bsize , const char * desc ,
2008-12-10 17:27:30 +01:00
BOOL ignore_scaling )
2005-11-07 17:40:20 +01:00
{
unsigned char buf [ MF_BUFSIZE ] ;
2009-06-15 11:52:51 +02:00
UINT mfsize , offset1 , offset2 , diff_nt4 , diff_9x ;
2008-05-07 13:34:36 +02:00
const ENHMETAHEADER * emh1 , * emh2 ;
2005-11-07 17:40:20 +01:00
mfsize = GetEnhMetaFileBits ( mf , MF_BUFSIZE , buf ) ;
2006-10-12 22:56:45 +02:00
ok ( mfsize > 0 , " %s: GetEnhMetaFileBits error %d \n " , desc , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
2009-06-15 11:52:51 +02:00
/* ENHMETAHEADER size could differ, depending on platform */
diff_nt4 = sizeof ( SIZEL ) ;
diff_9x = sizeof ( SIZEL ) + 3 * sizeof ( DWORD ) ;
2005-11-07 17:40:20 +01:00
if ( mfsize < MF_BUFSIZE )
2006-03-30 16:03:02 +02:00
{
2009-06-15 11:52:51 +02:00
ok ( mfsize = = bsize | |
broken ( mfsize = = bsize - diff_nt4 ) | | /* NT4 */
broken ( mfsize = = bsize - diff_9x ) , /* Win9x/WinME */
" %s: mfsize=%d, bsize=%d \n " , desc , mfsize , bsize ) ;
2006-03-30 16:03:02 +02:00
}
2005-11-07 17:40:20 +01:00
else
ok ( bsize > = MF_BUFSIZE , " %s: mfsize > bufsize (%d bytes), bsize=%d \n " ,
desc , mfsize , bsize ) ;
2006-03-30 16:03:02 +02:00
2008-05-07 13:34:36 +02:00
/* basic things must match */
emh1 = ( const ENHMETAHEADER * ) bits ;
emh2 = ( const ENHMETAHEADER * ) buf ;
ok ( emh1 - > iType = = EMR_HEADER , " expected EMR_HEADER, got %u \n " , emh1 - > iType ) ;
ok ( emh1 - > nSize = = sizeof ( ENHMETAHEADER ) , " expected sizeof(ENHMETAHEADER), got %u \n " , emh1 - > nSize ) ;
ok ( emh2 - > nBytes = = mfsize , " expected emh->nBytes %u, got %u \n " , mfsize , emh2 - > nBytes ) ;
ok ( emh1 - > dSignature = = ENHMETA_SIGNATURE , " expected ENHMETA_SIGNATURE, got %u \n " , emh1 - > dSignature ) ;
ok ( emh1 - > iType = = emh2 - > iType , " expected EMR_HEADER, got %u \n " , emh2 - > iType ) ;
2009-06-15 11:52:51 +02:00
ok ( emh1 - > nSize = = emh2 - > nSize | |
broken ( emh1 - > nSize - diff_nt4 = = emh2 - > nSize ) | |
broken ( emh1 - > nSize - diff_9x = = emh2 - > nSize ) ,
" expected nSize %u, got %u \n " , emh1 - > nSize , emh2 - > nSize ) ;
2016-04-28 18:47:56 +02:00
ok ( emh1 - > rclBounds . left = = emh2 - > rclBounds . left , " %s: expected rclBounds.left = %d, got %d \n " ,
desc , emh1 - > rclBounds . left , emh2 - > rclBounds . left ) ;
ok ( emh1 - > rclBounds . top = = emh2 - > rclBounds . top , " %s: expected rclBounds.top = %d, got %d \n " ,
desc , emh1 - > rclBounds . top , emh2 - > rclBounds . top ) ;
ok ( emh1 - > rclBounds . right = = emh2 - > rclBounds . right , " %s: expected rclBounds.right = %d, got %d \n " ,
desc , emh1 - > rclBounds . right , emh2 - > rclBounds . right ) ;
ok ( emh1 - > rclBounds . bottom = = emh2 - > rclBounds . bottom , " %s: expected rclBounds.bottom = %d, got %d \n " ,
desc , emh1 - > rclBounds . bottom , emh2 - > rclBounds . bottom ) ;
2008-05-07 13:34:36 +02:00
ok ( emh1 - > dSignature = = emh2 - > dSignature , " expected dSignature %u, got %u \n " , emh1 - > dSignature , emh2 - > dSignature ) ;
2009-06-15 11:52:51 +02:00
ok ( emh1 - > nBytes = = emh2 - > nBytes | |
broken ( emh1 - > nBytes - diff_nt4 = = emh2 - > nBytes ) | |
broken ( emh1 - > nBytes - diff_9x = = emh2 - > nBytes ) ,
" expected nBytes %u, got %u \n " , emh1 - > nBytes , emh2 - > nBytes ) ;
ok ( emh1 - > nRecords = = emh2 - > nRecords , " expected nRecords %u, got %u \n " , emh1 - > nRecords , emh2 - > nRecords ) ;
offset1 = emh1 - > nSize ;
offset2 = emh2 - > nSize ; /* Needed for Win9x/WinME/NT4 */
while ( offset1 < emh1 - > nBytes )
2005-11-07 17:40:20 +01:00
{
2012-01-17 04:38:15 +01:00
const ENHMETARECORD * emr1 = ( const ENHMETARECORD * ) ( bits + offset1 ) ;
const ENHMETARECORD * emr2 = ( const ENHMETARECORD * ) ( buf + offset2 ) ;
2008-05-07 13:34:36 +02:00
2012-01-17 04:38:15 +01:00
trace ( " %s: EMF record %u, size %u/record %u, size %u \n " ,
2009-06-15 11:52:51 +02:00
desc , emr1 - > iType , emr1 - > nSize , emr2 - > iType , emr2 - > nSize ) ;
2008-05-07 13:34:36 +02:00
2008-12-10 17:27:30 +01:00
if ( ! match_emf_record ( emr1 , emr2 , desc , ignore_scaling ) ) return - 1 ;
2005-11-07 17:40:20 +01:00
2009-06-15 11:52:51 +02:00
/* We have already bailed out if iType or nSize don't match */
2012-01-17 04:38:15 +01:00
offset1 + = emr1 - > nSize ;
offset2 + = emr2 - > nSize ;
2005-11-07 17:40:20 +01:00
}
2008-05-07 13:34:36 +02:00
return 0 ;
2005-11-07 17:40:20 +01:00
}
2009-11-22 21:25:42 +01:00
/* tests blitting to an EMF */
static void test_emf_BitBlt ( void )
{
HDC hdcDisplay , hdcMetafile , hdcBitmap ;
HBITMAP hBitmap , hOldBitmap ;
HENHMETAFILE hMetafile ;
# define BMP_DIM 4
BITMAPINFOHEADER bmih =
{
sizeof ( BITMAPINFOHEADER ) ,
BMP_DIM , /* biWidth */
BMP_DIM , /* biHeight */
1 , /* biPlanes */
24 , /* biBitCount */
BI_RGB , /* biCompression */
0 , /* biXPelsPerMeter */
0 , /* biYPelsPerMeter */
0 , /* biClrUsed */
0 , /* biClrImportant */
} ;
void * bits ;
2016-04-21 17:41:21 +02:00
XFORM xform ;
2009-11-22 21:25:42 +01:00
BOOL ret ;
hdcDisplay = CreateDCA ( " DISPLAY " , NULL , NULL , NULL ) ;
ok ( hdcDisplay ! = 0 , " CreateDCA error %d \n " , GetLastError ( ) ) ;
hdcBitmap = CreateCompatibleDC ( hdcDisplay ) ;
ok ( hdcBitmap ! = 0 , " CreateCompatibleDC failed \n " ) ;
2016-04-21 17:41:21 +02:00
ok ( SetGraphicsMode ( hdcBitmap , GM_ADVANCED ) , " SetGraphicsMode failed \n " ) ;
2009-11-22 21:25:42 +01:00
bmih . biXPelsPerMeter = MulDiv ( GetDeviceCaps ( hdcDisplay , LOGPIXELSX ) , 100 , 3937 ) ;
bmih . biYPelsPerMeter = MulDiv ( GetDeviceCaps ( hdcDisplay , LOGPIXELSY ) , 100 , 3937 ) ;
hBitmap = CreateDIBSection ( hdcDisplay , ( const BITMAPINFO * ) & bmih ,
DIB_RGB_COLORS , & bits , NULL , 0 ) ;
hOldBitmap = SelectObject ( hdcBitmap , hBitmap ) ;
hdcMetafile = CreateEnhMetaFileA ( hdcBitmap , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA failed \n " ) ;
/* First fill the bitmap DC with something recognizable, like BLACKNESS */
ret = BitBlt ( hdcBitmap , 0 , 0 , BMP_DIM , BMP_DIM , 0 , 0 , 0 , BLACKNESS ) ;
ok ( ret , " BitBlt(BLACKNESS) failed \n " ) ;
ret = BitBlt ( hdcMetafile , 0 , 0 , BMP_DIM , BMP_DIM , hdcBitmap , 0 , 0 , SRCCOPY ) ;
ok ( ret , " BitBlt(SRCCOPY) failed \n " ) ;
ret = BitBlt ( hdcMetafile , 0 , 0 , BMP_DIM , BMP_DIM , 0 , 0 , 0 , WHITENESS ) ;
ok ( ret , " BitBlt(WHITENESS) failed \n " ) ;
2016-04-21 17:41:21 +02:00
ok ( SetMapMode ( hdcBitmap , MM_ANISOTROPIC ) , " SetMapMode failed \n " ) ;
ok ( SetWindowOrgEx ( hdcBitmap , 0 , 0 , NULL ) , " SetWindowOrgEx failed \n " ) ;
ok ( SetWindowExtEx ( hdcBitmap , 400 , 400 , NULL ) , " SetWindowExtEx failed \n " ) ;
ok ( SetViewportOrgEx ( hdcBitmap , 0 , 0 , NULL ) , " SetViewportOrgEx failed \n " ) ;
ok ( SetViewportExtEx ( hdcBitmap , BMP_DIM , BMP_DIM , NULL ) , " SetViewportExtEx failed \n " ) ;
memset ( & xform , 0 , sizeof ( xform ) ) ;
xform . eM11 = 0.5 ;
xform . eM22 = 1.0 ;
ok ( SetWorldTransform ( hdcBitmap , & xform ) , " SetWorldTransform failed \n " ) ;
ret = StretchBlt ( hdcMetafile , 0 , 0 , BMP_DIM , BMP_DIM , hdcBitmap , 0 , 0 , 400 , 400 , SRCCOPY ) ;
ok ( ret , " StretchBlt(SRCCOPY) failed \n " ) ;
2009-11-22 21:25:42 +01:00
hMetafile = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hMetafile ! = 0 , " CloseEnhMetaFile failed \n " ) ;
if ( compare_emf_bits ( hMetafile , EMF_BITBLT , sizeof ( EMF_BITBLT ) ,
" emf_BitBlt " , FALSE ) ! = 0 )
{
dump_emf_bits ( hMetafile , " emf_BitBlt " ) ;
dump_emf_records ( hMetafile , " emf_BitBlt " ) ;
}
SelectObject ( hdcBitmap , hOldBitmap ) ;
DeleteObject ( hBitmap ) ;
DeleteDC ( hdcBitmap ) ;
DeleteDC ( hdcDisplay ) ;
# undef BMP_DIM
}
2011-03-10 20:22:22 +01:00
static void test_emf_DCBrush ( void )
{
HDC hdcMetafile ;
HENHMETAFILE hMetafile ;
HBRUSH hBrush ;
HPEN hPen ;
BOOL ret ;
COLORREF color ;
if ( ! pSetDCBrushColor | | ! pSetDCPenColor )
{
win_skip ( " SetDCBrush/PenColor not supported \n " ) ;
return ;
}
hdcMetafile = CreateEnhMetaFileA ( GetDC ( 0 ) , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA failed \n " ) ;
hBrush = SelectObject ( hdcMetafile , GetStockObject ( DC_BRUSH ) ) ;
ok ( hBrush ! = 0 , " SelectObject error %d. \n " , GetLastError ( ) ) ;
hPen = SelectObject ( hdcMetafile , GetStockObject ( DC_PEN ) ) ;
ok ( hPen ! = 0 , " SelectObject error %d. \n " , GetLastError ( ) ) ;
color = pSetDCBrushColor ( hdcMetafile , RGB ( 0x55 , 0x55 , 0x55 ) ) ;
ok ( color = = 0xffffff , " SetDCBrushColor returned %x \n " , color ) ;
color = pSetDCPenColor ( hdcMetafile , RGB ( 0x33 , 0x44 , 0x55 ) ) ;
ok ( color = = 0 , " SetDCPenColor returned %x \n " , color ) ;
Rectangle ( hdcMetafile , 10 , 10 , 20 , 20 ) ;
color = pSetDCBrushColor ( hdcMetafile , RGB ( 0x12 , 0x34 , 0x56 ) ) ;
ok ( color = = 0x555555 , " SetDCBrushColor returned %x \n " , color ) ;
hMetafile = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hMetafile ! = 0 , " CloseEnhMetaFile failed \n " ) ;
if ( compare_emf_bits ( hMetafile , EMF_DCBRUSH_BITS , sizeof ( EMF_DCBRUSH_BITS ) ,
" emf_DC_Brush " , FALSE ) ! = 0 )
{
dump_emf_bits ( hMetafile , " emf_DC_Brush " ) ;
dump_emf_records ( hMetafile , " emf_DC_Brush " ) ;
}
ret = DeleteEnhMetaFile ( hMetafile ) ;
ok ( ret , " DeleteEnhMetaFile error %d \n " , GetLastError ( ) ) ;
ret = DeleteObject ( hBrush ) ;
ok ( ret , " DeleteObject(HBRUSH) error %d \n " , GetLastError ( ) ) ;
ret = DeleteObject ( hPen ) ;
ok ( ret , " DeleteObject(HPEN) error %d \n " , GetLastError ( ) ) ;
}
2004-12-09 12:37:59 +01:00
/* Test a blank metafile. May be used as a template for new tests. */
static void test_mf_Blank ( void )
{
HDC hdcMetafile ;
2005-10-19 20:28:14 +02:00
HMETAFILE hMetafile ;
2004-12-09 12:37:59 +01:00
INT caps ;
2004-12-27 18:26:37 +01:00
BOOL ret ;
2005-10-18 12:35:14 +02:00
INT type ;
2004-12-09 12:37:59 +01:00
hdcMetafile = CreateMetaFileA ( NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateMetaFileA(NULL) error %d \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
/* Tests on metafile initialization */
caps = GetDeviceCaps ( hdcMetafile , TECHNOLOGY ) ;
ok ( caps = = DT_METAFILE ,
" GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE. \n " , caps ) ;
hMetafile = CloseMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
2005-10-18 12:35:14 +02:00
type = GetObjectType ( hMetafile ) ;
ok ( type = = OBJ_METAFILE , " CloseMetaFile created object with type %d \n " , type ) ;
2019-11-21 16:08:46 +01:00
type = GetObjectType ( hdcMetafile ) ;
ok ( type = = 0 | | broken ( type = = OBJ_METADC ) /* win10 >=1607 */ ,
" CloseMetaFile has to destroy metafile hdc (%d) \n " , type ) ;
2004-12-09 12:37:59 +01:00
2005-10-19 20:28:14 +02:00
if ( compare_mf_bits ( hMetafile , MF_BLANK_BITS , sizeof ( MF_BLANK_BITS ) ,
" mf_blank " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
dump_mf_bits ( hMetafile , " mf_Blank " ) ;
EnumMetaFile ( 0 , hMetafile , mf_enum_proc , 0 ) ;
}
2005-10-19 20:28:14 +02:00
ret = DeleteMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hMetafile , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
}
static void test_CopyMetaFile ( void )
{
HDC hdcMetafile ;
HMETAFILE hMetafile , hmf_copy ;
BOOL ret ;
char temp_path [ MAX_PATH ] ;
char mf_name [ MAX_PATH ] ;
INT type ;
hdcMetafile = CreateMetaFileA ( NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateMetaFileA(NULL) error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
hMetafile = CloseMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
type = GetObjectType ( hMetafile ) ;
ok ( type = = OBJ_METAFILE , " CloseMetaFile created object with type %d \n " , type ) ;
2004-12-09 12:37:59 +01:00
if ( compare_mf_bits ( hMetafile , MF_BLANK_BITS , sizeof ( MF_BLANK_BITS ) ,
" mf_blank " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
dump_mf_bits ( hMetafile , " mf_Blank " ) ;
EnumMetaFile ( 0 , hMetafile , mf_enum_proc , 0 ) ;
}
2004-12-09 12:37:59 +01:00
2005-10-18 12:35:14 +02:00
GetTempPathA ( MAX_PATH , temp_path ) ;
GetTempFileNameA ( temp_path , " wmf " , 0 , mf_name ) ;
2005-10-19 20:28:14 +02:00
hmf_copy = CopyMetaFileA ( hMetafile , mf_name ) ;
2006-10-12 22:56:45 +02:00
ok ( hmf_copy ! = 0 , " CopyMetaFile error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
2005-10-18 12:35:14 +02:00
type = GetObjectType ( hmf_copy ) ;
ok ( type = = OBJ_METAFILE , " CopyMetaFile created object with type %d \n " , type ) ;
2004-12-27 18:26:37 +01:00
ret = DeleteMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hMetafile , GetLastError ( ) ) ;
2005-10-18 12:35:14 +02:00
if ( compare_mf_disk_bits ( mf_name , MF_BLANK_BITS , sizeof ( MF_BLANK_BITS ) , " mf_blank " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
2009-07-01 13:03:04 +02:00
dump_mf_bits ( hmf_copy , " mf_Blank " ) ;
EnumMetaFile ( 0 , hmf_copy , mf_enum_proc , 0 ) ;
2005-11-07 17:40:20 +01:00
}
2005-10-18 12:35:14 +02:00
ret = DeleteMetaFile ( hmf_copy ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hmf_copy , GetLastError ( ) ) ;
2005-10-18 12:35:14 +02:00
DeleteFileA ( mf_name ) ;
2004-12-09 12:37:59 +01:00
}
2005-10-19 20:28:14 +02:00
static void test_SetMetaFileBits ( void )
{
HMETAFILE hmf ;
INT type ;
BOOL ret ;
BYTE buf [ 256 ] ;
METAHEADER * mh ;
hmf = SetMetaFileBitsEx ( sizeof ( MF_GRAPHICS_BITS ) , MF_GRAPHICS_BITS ) ;
2006-10-12 22:56:45 +02:00
ok ( hmf ! = 0 , " SetMetaFileBitsEx error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
type = GetObjectType ( hmf ) ;
ok ( type = = OBJ_METAFILE , " SetMetaFileBitsEx created object with type %d \n " , type ) ;
if ( compare_mf_bits ( hmf , MF_GRAPHICS_BITS , sizeof ( MF_GRAPHICS_BITS ) , " mf_Graphics " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
2005-10-19 20:28:14 +02:00
dump_mf_bits ( hmf , " mf_Graphics " ) ;
2005-11-07 17:40:20 +01:00
EnumMetaFile ( 0 , hmf , mf_enum_proc , 0 ) ;
}
2005-10-19 20:28:14 +02:00
ret = DeleteMetaFile ( hmf ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hmf , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
/* NULL data crashes XP SP1 */
/*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/
2009-07-02 12:45:12 +02:00
/* Now with zero size */
2005-10-19 20:28:14 +02:00
SetLastError ( 0xdeadbeef ) ;
hmf = SetMetaFileBitsEx ( 0 , MF_GRAPHICS_BITS ) ;
ok ( ! hmf , " SetMetaFileBitsEx should fail \n " ) ;
2009-03-12 15:08:13 +01:00
ok ( GetLastError ( ) = = ERROR_INVALID_DATA | |
broken ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ) , /* Win9x */
" wrong error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
2009-07-02 12:45:12 +02:00
/* Now with odd size */
2005-10-19 20:28:14 +02:00
SetLastError ( 0xdeadbeef ) ;
hmf = SetMetaFileBitsEx ( sizeof ( MF_GRAPHICS_BITS ) - 1 , MF_GRAPHICS_BITS ) ;
ok ( ! hmf , " SetMetaFileBitsEx should fail \n " ) ;
2006-10-12 22:56:45 +02:00
ok ( GetLastError ( ) = = 0xdeadbeef /* XP SP1 */ , " wrong error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
2009-07-02 12:45:12 +02:00
/* Now with zeroed out header fields */
2005-10-19 20:28:14 +02:00
assert ( sizeof ( buf ) > = sizeof ( MF_GRAPHICS_BITS ) ) ;
memcpy ( buf , MF_GRAPHICS_BITS , sizeof ( MF_GRAPHICS_BITS ) ) ;
mh = ( METAHEADER * ) buf ;
/* corruption of any of the below fields leads to a failure */
mh - > mtType = 0 ;
mh - > mtVersion = 0 ;
mh - > mtHeaderSize = 0 ;
SetLastError ( 0xdeadbeef ) ;
hmf = SetMetaFileBitsEx ( sizeof ( MF_GRAPHICS_BITS ) , buf ) ;
ok ( ! hmf , " SetMetaFileBitsEx should fail \n " ) ;
2009-03-12 15:08:13 +01:00
ok ( GetLastError ( ) = = ERROR_INVALID_DATA | |
broken ( GetLastError ( ) = = ERROR_INVALID_PARAMETER ) , /* Win9x */
" wrong error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
/* Now with corrupted mtSize field */
memcpy ( buf , MF_GRAPHICS_BITS , sizeof ( MF_GRAPHICS_BITS ) ) ;
mh = ( METAHEADER * ) buf ;
/* corruption of mtSize doesn't lead to a failure */
mh - > mtSize * = 2 ;
hmf = SetMetaFileBitsEx ( sizeof ( MF_GRAPHICS_BITS ) , buf ) ;
2006-10-12 22:56:45 +02:00
ok ( hmf ! = 0 , " SetMetaFileBitsEx error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
if ( compare_mf_bits ( hmf , MF_GRAPHICS_BITS , sizeof ( MF_GRAPHICS_BITS ) , " mf_Graphics " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
2005-10-19 20:28:14 +02:00
dump_mf_bits ( hmf , " mf_Graphics " ) ;
2005-11-07 17:40:20 +01:00
EnumMetaFile ( 0 , hmf , mf_enum_proc , 0 ) ;
}
2005-10-19 20:28:14 +02:00
ret = DeleteMetaFile ( hmf ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hmf , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
2010-12-31 01:11:17 +01:00
# ifndef _WIN64 /* Generates access violation on XP x64 and Win2003 x64 */
2005-10-19 20:28:14 +02:00
/* Now with zeroed out mtSize field */
memcpy ( buf , MF_GRAPHICS_BITS , sizeof ( MF_GRAPHICS_BITS ) ) ;
mh = ( METAHEADER * ) buf ;
/* zeroing mtSize doesn't lead to a failure */
mh - > mtSize = 0 ;
hmf = SetMetaFileBitsEx ( sizeof ( MF_GRAPHICS_BITS ) , buf ) ;
2006-10-12 22:56:45 +02:00
ok ( hmf ! = 0 , " SetMetaFileBitsEx error %d \n " , GetLastError ( ) ) ;
2005-10-19 20:28:14 +02:00
if ( compare_mf_bits ( hmf , MF_GRAPHICS_BITS , sizeof ( MF_GRAPHICS_BITS ) , " mf_Graphics " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
2005-10-19 20:28:14 +02:00
dump_mf_bits ( hmf , " mf_Graphics " ) ;
2005-11-07 17:40:20 +01:00
EnumMetaFile ( 0 , hmf , mf_enum_proc , 0 ) ;
}
2005-10-19 20:28:14 +02:00
ret = DeleteMetaFile ( hmf ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hmf , GetLastError ( ) ) ;
2010-12-31 01:11:17 +01:00
# endif
2005-10-19 20:28:14 +02:00
}
2004-12-09 12:37:59 +01:00
/* Simple APIs from mfdrv/graphics.c
*/
2005-06-21 22:53:13 +02:00
static void test_mf_Graphics ( void )
2004-12-09 12:37:59 +01:00
{
HDC hdcMetafile ;
HMETAFILE hMetafile ;
POINT oldpoint ;
2019-11-21 16:08:46 +01:00
INT type ;
2004-12-27 18:26:37 +01:00
BOOL ret ;
2004-12-09 12:37:59 +01:00
hdcMetafile = CreateMetaFileA ( NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateMetaFileA(NULL) error %d \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
2004-12-27 18:26:37 +01:00
ret = MoveToEx ( hdcMetafile , 1 , 1 , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " MoveToEx error %d. \n " , GetLastError ( ) ) ;
2004-12-27 18:26:37 +01:00
ret = LineTo ( hdcMetafile , 2 , 2 ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
2004-12-27 18:26:37 +01:00
ret = MoveToEx ( hdcMetafile , 1 , 1 , & oldpoint ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " MoveToEx error %d. \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
/* oldpoint gets garbage under Win XP, so the following test would
* work under Wine but fails under Windows :
*
* ok ( ( oldpoint . x = = 2 ) & & ( oldpoint . y = = 2 ) ,
* " MoveToEx: (x, y) = (%ld, %ld), should be (2, 2). \n " ,
* oldpoint . x , oldpoint . y ) ;
*/
2004-12-27 18:26:37 +01:00
ret = Ellipse ( hdcMetafile , 0 , 0 , 2 , 2 ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " Ellipse error %d. \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
hMetafile = CloseMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
2019-11-21 16:08:46 +01:00
type = GetObjectType ( hdcMetafile ) ;
ok ( type = = 0 | | broken ( type = = OBJ_METADC ) /* win10 >=1607 */ ,
" CloseMetaFile has to destroy metafile hdc (%d) \n " , type ) ;
2004-12-09 12:37:59 +01:00
if ( compare_mf_bits ( hMetafile , MF_GRAPHICS_BITS , sizeof ( MF_GRAPHICS_BITS ) ,
" mf_Graphics " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
dump_mf_bits ( hMetafile , " mf_Graphics " ) ;
EnumMetaFile ( 0 , hMetafile , mf_enum_proc , 0 ) ;
}
2004-12-09 12:37:59 +01:00
2004-12-27 18:26:37 +01:00
ret = DeleteMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " ,
2004-12-09 12:37:59 +01:00
hMetafile , GetLastError ( ) ) ;
}
static void test_mf_PatternBrush ( void )
{
HDC hdcMetafile ;
HMETAFILE hMetafile ;
LOGBRUSH * orig_lb ;
HBRUSH hBrush ;
2004-12-27 18:26:37 +01:00
BOOL ret ;
2019-11-21 16:08:46 +01:00
INT type ;
2004-12-09 12:37:59 +01:00
orig_lb = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( LOGBRUSH ) ) ;
orig_lb - > lbStyle = BS_PATTERN ;
orig_lb - > lbColor = RGB ( 0 , 0 , 0 ) ;
2005-09-12 13:19:56 +02:00
orig_lb - > lbHatch = ( ULONG_PTR ) CreateBitmap ( 8 , 8 , 1 , 1 , SAMPLE_PATTERN_BRUSH ) ;
2006-10-12 22:56:45 +02:00
ok ( ( HBITMAP ) orig_lb - > lbHatch ! = NULL , " CreateBitmap error %d. \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
hBrush = CreateBrushIndirect ( orig_lb ) ;
2006-10-12 22:56:45 +02:00
ok ( hBrush ! = 0 , " CreateBrushIndirect error %d \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
hdcMetafile = CreateMetaFileA ( NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateMetaFileA error %d \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
hBrush = SelectObject ( hdcMetafile , hBrush ) ;
2006-10-12 22:56:45 +02:00
ok ( hBrush ! = 0 , " SelectObject error %d. \n " , GetLastError ( ) ) ;
2004-12-09 12:37:59 +01:00
hMetafile = CloseMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
2019-11-21 16:08:46 +01:00
type = GetObjectType ( hdcMetafile ) ;
ok ( type = = 0 | | broken ( type = = OBJ_METADC ) /* win10 >=1607 */ ,
" CloseMetaFile has to destroy metafile hdc (%d) \n " , type ) ;
2004-12-09 12:37:59 +01:00
if ( compare_mf_bits ( hMetafile , MF_PATTERN_BRUSH_BITS , sizeof ( MF_PATTERN_BRUSH_BITS ) ,
" mf_Pattern_Brush " ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
dump_mf_bits ( hMetafile , " mf_Pattern_Brush " ) ;
EnumMetaFile ( 0 , hMetafile , mf_enum_proc , 0 ) ;
}
2004-12-09 12:37:59 +01:00
2004-12-27 18:26:37 +01:00
ret = DeleteMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile error %d \n " , GetLastError ( ) ) ;
2004-12-27 18:26:37 +01:00
ret = DeleteObject ( hBrush ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteObject(HBRUSH) error %d \n " , GetLastError ( ) ) ;
2005-09-12 13:19:56 +02:00
ret = DeleteObject ( ( HBITMAP ) orig_lb - > lbHatch ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteObject(HBITMAP) error %d \n " ,
2004-12-09 12:37:59 +01:00
GetLastError ( ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , orig_lb ) ;
}
2011-03-10 20:22:22 +01:00
static void test_mf_DCBrush ( void )
{
HDC hdcMetafile ;
HMETAFILE hMetafile ;
HBRUSH hBrush ;
HPEN hPen ;
BOOL ret ;
COLORREF color ;
if ( ! pSetDCBrushColor | | ! pSetDCPenColor )
{
win_skip ( " SetDCBrush/PenColor not supported \n " ) ;
return ;
}
hdcMetafile = CreateMetaFileA ( NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateMetaFileA failed \n " ) ;
hBrush = SelectObject ( hdcMetafile , GetStockObject ( DC_BRUSH ) ) ;
ok ( hBrush ! = 0 , " SelectObject error %d. \n " , GetLastError ( ) ) ;
hPen = SelectObject ( hdcMetafile , GetStockObject ( DC_PEN ) ) ;
ok ( hPen ! = 0 , " SelectObject error %d. \n " , GetLastError ( ) ) ;
color = pSetDCBrushColor ( hdcMetafile , RGB ( 0x55 , 0x55 , 0x55 ) ) ;
ok ( color = = CLR_INVALID , " SetDCBrushColor returned %x \n " , color ) ;
color = pSetDCPenColor ( hdcMetafile , RGB ( 0x33 , 0x44 , 0x55 ) ) ;
ok ( color = = CLR_INVALID , " SetDCPenColor returned %x \n " , color ) ;
Rectangle ( hdcMetafile , 10 , 10 , 20 , 20 ) ;
color = pSetDCBrushColor ( hdcMetafile , RGB ( 0x12 , 0x34 , 0x56 ) ) ;
ok ( color = = CLR_INVALID , " SetDCBrushColor returned %x \n " , color ) ;
hMetafile = CloseMetaFile ( hdcMetafile ) ;
ok ( hMetafile ! = 0 , " CloseMetaFile failed \n " ) ;
if ( compare_mf_bits ( hMetafile , MF_DCBRUSH_BITS , sizeof ( MF_DCBRUSH_BITS ) , " mf_DCBrush " ) ! = 0 )
{
dump_mf_bits ( hMetafile , " mf_DCBrush " ) ;
EnumMetaFile ( 0 , hMetafile , mf_enum_proc , 0 ) ;
}
ret = DeleteMetaFile ( hMetafile ) ;
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hMetafile , GetLastError ( ) ) ;
}
2005-11-07 17:40:20 +01:00
static void test_mf_ExtTextOut_on_path ( void )
{
HDC hdcMetafile ;
HMETAFILE hMetafile ;
BOOL ret ;
static const INT dx [ 4 ] = { 3 , 5 , 8 , 12 } ;
hdcMetafile = CreateMetaFileA ( NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateMetaFileA(NULL) error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
ret = BeginPath ( hdcMetafile ) ;
ok ( ! ret , " BeginPath on metafile DC should fail \n " ) ;
ret = ExtTextOutA ( hdcMetafile , 11 , 22 , 0 , NULL , " Test " , 4 , dx ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " ExtTextOut error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
ret = EndPath ( hdcMetafile ) ;
ok ( ! ret , " EndPath on metafile DC should fail \n " ) ;
hMetafile = CloseMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
if ( compare_mf_bits ( hMetafile , MF_TEXTOUT_ON_PATH_BITS , sizeof ( MF_TEXTOUT_ON_PATH_BITS ) ,
" mf_TextOut_on_path " ) ! = 0 )
{
dump_mf_bits ( hMetafile , " mf_TextOut_on_path " ) ;
EnumMetaFile ( 0 , hMetafile , mf_enum_proc , 0 ) ;
}
ret = DeleteMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteMetaFile(%p) error %d \n " , hMetafile , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
}
static void test_emf_ExtTextOut_on_path ( void )
{
HWND hwnd ;
HDC hdcDisplay , hdcMetafile ;
HENHMETAFILE hMetafile ;
BOOL ret ;
2018-11-29 10:28:20 +01:00
LOGFONTA lf ;
HFONT hFont ;
2005-11-07 17:40:20 +01:00
static const INT dx [ 4 ] = { 3 , 5 , 8 , 12 } ;
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA ( 0 , " static " , NULL , WS_POPUP | WS_VISIBLE ,
0 , 0 , 200 , 200 , 0 , 0 , 0 , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hwnd ! = 0 , " CreateWindowExA error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
hdcDisplay = GetDC ( hwnd ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcDisplay ! = 0 , " GetDC error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
2018-11-29 10:28:20 +01:00
/* with default font */
ret = BeginPath ( hdcDisplay ) ;
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
ret = ExtTextOutA ( hdcDisplay , 11 , 22 , 0 , NULL , " Test " , 4 , dx ) ;
ok ( ret , " ExtTextOut error %d \n " , GetLastError ( ) ) ;
ret = EndPath ( hdcDisplay ) ;
ok ( ret , " EndPath error %d \n " , GetLastError ( ) ) ;
ret = GetPath ( hdcDisplay , NULL , NULL , 0 ) ;
ok ( ! ret , " expected 0, got %d \n " , ret ) ;
2005-11-07 17:40:20 +01:00
hdcMetafile = CreateEnhMetaFileA ( hdcDisplay , NULL , NULL , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
ret = BeginPath ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
ret = ExtTextOutA ( hdcMetafile , 11 , 22 , 0 , NULL , " Test " , 4 , dx ) ;
2018-11-29 10:28:24 +01:00
ok ( ret , " ExtTextOut error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
ret = EndPath ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " EndPath error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
2018-11-29 10:28:20 +01:00
ret = GetPath ( hdcMetafile , NULL , NULL , 0 ) ;
ok ( ! ret , " expected 0, got %d \n " , ret ) ;
2005-11-07 17:40:20 +01:00
hMetafile = CloseEnhMetaFile ( hdcMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( hMetafile ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
/* this doesn't succeed yet: EMF has correct size, all EMF records
* are there , but their contents don ' t match for different reasons .
*/
if ( compare_emf_bits ( hMetafile , EMF_TEXTOUT_ON_PATH_BITS , sizeof ( EMF_TEXTOUT_ON_PATH_BITS ) ,
2008-12-10 17:27:30 +01:00
" emf_TextOut_on_path " , FALSE ) ! = 0 )
2005-11-07 17:40:20 +01:00
{
dump_emf_bits ( hMetafile , " emf_TextOut_on_path " ) ;
dump_emf_records ( hMetafile , " emf_TextOut_on_path " ) ;
}
ret = DeleteEnhMetaFile ( hMetafile ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " DeleteEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2018-11-29 10:28:20 +01:00
/* with outline font */
memset ( & lf , 0 , sizeof ( lf ) ) ;
lf . lfCharSet = ANSI_CHARSET ;
lf . lfClipPrecision = CLIP_DEFAULT_PRECIS ;
lf . lfWeight = FW_DONTCARE ;
lf . lfHeight = 7 ;
lf . lfQuality = DEFAULT_QUALITY ;
lstrcpyA ( lf . lfFaceName , " Tahoma " ) ;
hFont = CreateFontIndirectA ( & lf ) ;
ok ( hFont ! = 0 , " CreateFontIndirectA error %d \n " , GetLastError ( ) ) ;
hFont = SelectObject ( hdcDisplay , hFont ) ;
ret = BeginPath ( hdcDisplay ) ;
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
ret = ExtTextOutA ( hdcDisplay , 11 , 22 , 0 , NULL , " Test " , 4 , dx ) ;
ok ( ret , " ExtTextOut error %d \n " , GetLastError ( ) ) ;
ret = EndPath ( hdcDisplay ) ;
ok ( ret , " EndPath error %d \n " , GetLastError ( ) ) ;
ret = GetPath ( hdcDisplay , NULL , NULL , 0 ) ;
ok ( ret ! = 0 , " expected != 0 \n " ) ;
SelectObject ( hdcDisplay , hFont ) ;
hdcMetafile = CreateEnhMetaFileA ( hdcDisplay , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
hFont = SelectObject ( hdcMetafile , hFont ) ;
ret = BeginPath ( hdcMetafile ) ;
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
ret = ExtTextOutA ( hdcMetafile , 11 , 22 , 0 , NULL , " Test " , 4 , dx ) ;
ok ( ret , " ExtTextOut error %d \n " , GetLastError ( ) ) ;
ret = EndPath ( hdcMetafile ) ;
ok ( ret , " EndPath error %d \n " , GetLastError ( ) ) ;
ret = GetPath ( hdcMetafile , NULL , NULL , 0 ) ;
ok ( ! ret , " expected 0, got %d \n " , ret ) ;
hFont = SelectObject ( hdcMetafile , hFont ) ;
DeleteObject ( hFont ) ;
hMetafile = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hMetafile ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_emf_bits ( hMetafile , EMF_TEXTOUT_OUTLINE_ON_PATH_BITS , sizeof ( EMF_TEXTOUT_OUTLINE_ON_PATH_BITS ) ,
2019-01-06 18:04:26 +01:00
" emf_TextOut_outline_on_path " , FALSE ) ! = 0 )
2018-11-29 10:28:20 +01:00
{
dump_emf_bits ( hMetafile , " emf_TextOut_outline_on_path " ) ;
dump_emf_records ( hMetafile , " emf_TextOut_outline_on_path " ) ;
}
ret = DeleteEnhMetaFile ( hMetafile ) ;
ok ( ret , " DeleteEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
ret = ReleaseDC ( hwnd , hdcDisplay ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " ReleaseDC error %d \n " , GetLastError ( ) ) ;
2005-11-07 17:40:20 +01:00
DestroyWindow ( hwnd ) ;
}
2008-04-21 12:38:03 +02:00
static const unsigned char EMF_CLIPPING [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2017-06-21 10:34:17 +02:00
0x1a , 0x00 , 0x00 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
2008-04-21 12:38:03 +02:00
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
2017-06-21 10:34:17 +02:00
0x04 , 0x01 , 0x00 , 0x00 , 0x08 , 0x00 , 0x00 , 0x00 ,
2008-04-21 12:38:03 +02:00
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2017-06-21 10:34:17 +02:00
0x80 , 0x07 , 0x00 , 0x00 , 0xb0 , 0x04 , 0x00 , 0x00 ,
0xfc , 0x01 , 0x00 , 0x00 , 0x3e , 0x01 , 0x00 , 0x00 ,
2008-04-21 12:38:03 +02:00
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2017-06-21 10:34:17 +02:00
0x00 , 0x00 , 0x00 , 0x00 , 0x60 , 0xc0 , 0x07 , 0x00 ,
0x30 , 0xda , 0x04 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 ,
2008-04-21 12:38:03 +02:00
0x10 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x4b , 0x00 , 0x00 , 0x00 ,
0x40 , 0x00 , 0x00 , 0x00 , 0x30 , 0x00 , 0x00 , 0x00 ,
0x05 , 0x00 , 0x00 , 0x00 , 0x20 , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
0x00 , 0x04 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 ,
2017-06-21 10:34:17 +02:00
0x00 , 0x04 , 0x00 , 0x00 , 0x3b , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x2b , 0x00 , 0x00 , 0x00 ,
0x18 , 0x00 , 0x00 , 0x00 , 0x64 , 0x00 , 0x00 , 0x00 ,
0x64 , 0x00 , 0x00 , 0x00 , 0xff , 0x03 , 0x00 , 0x00 ,
0xff , 0x03 , 0x00 , 0x00 , 0x3c , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x43 , 0x00 , 0x00 , 0x00 ,
0x0c , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 ,
0x0e , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00
2008-04-21 12:38:03 +02:00
} ;
static void translate ( POINT * pt , UINT count , const XFORM * xform )
{
while ( count - - )
{
FLOAT x = ( FLOAT ) pt - > x ;
FLOAT y = ( FLOAT ) pt - > y ;
pt - > x = ( LONG ) floor ( x * xform - > eM11 + y * xform - > eM21 + xform - > eDx + 0.5 ) ;
pt - > y = ( LONG ) floor ( x * xform - > eM12 + y * xform - > eM22 + xform - > eDy + 0.5 ) ;
pt + + ;
}
}
2008-05-21 14:54:29 +02:00
/* Compare rectangles allowing rounding errors */
static BOOL is_equal_rect ( const RECT * rc1 , const RECT * rc2 )
{
return abs ( rc1 - > left - rc2 - > left ) < = 1 & &
abs ( rc1 - > top - rc2 - > top ) < = 1 & &
abs ( rc1 - > right - rc2 - > right ) < = 1 & &
abs ( rc1 - > bottom - rc2 - > bottom ) < = 1 ;
}
2008-04-21 12:38:03 +02:00
static int CALLBACK clip_emf_enum_proc ( HDC hdc , HANDLETABLE * handle_table ,
const ENHMETARECORD * emr , int n_objs , LPARAM param )
{
if ( emr - > iType = = EMR_EXTSELECTCLIPRGN )
{
2012-01-17 04:38:15 +01:00
const EMREXTSELECTCLIPRGN * clip = ( const EMREXTSELECTCLIPRGN * ) emr ;
2008-04-21 12:38:03 +02:00
union _rgn
{
RGNDATA data ;
char buf [ sizeof ( RGNDATAHEADER ) + sizeof ( RECT ) ] ;
} ;
const union _rgn * rgn1 ;
union _rgn rgn2 ;
RECT rect , rc_transformed ;
const RECT * rc = ( const RECT * ) param ;
HRGN hrgn ;
XFORM xform ;
INT ret ;
BOOL is_win9x ;
trace ( " EMR_EXTSELECTCLIPRGN: cbRgnData %#x, iMode %u \n " ,
clip - > cbRgnData , clip - > iMode ) ;
ok ( clip - > iMode = = RGN_COPY , " expected RGN_COPY, got %u \n " , clip - > iMode ) ;
ok ( clip - > cbRgnData > = sizeof ( RGNDATAHEADER ) + sizeof ( RECT ) ,
" too small data block: %u bytes \n " , clip - > cbRgnData ) ;
if ( clip - > cbRgnData < sizeof ( RGNDATAHEADER ) + sizeof ( RECT ) )
return 0 ;
rgn1 = ( const union _rgn * ) clip - > RgnData ;
2016-06-20 11:56:26 +02:00
trace ( " size %u, type %u, count %u, rgn size %u, bound %s \n " ,
2008-04-21 12:38:03 +02:00
rgn1 - > data . rdh . dwSize , rgn1 - > data . rdh . iType ,
rgn1 - > data . rdh . nCount , rgn1 - > data . rdh . nRgnSize ,
2016-06-20 11:56:26 +02:00
wine_dbgstr_rect ( & rgn1 - > data . rdh . rcBound ) ) ;
2008-04-21 12:38:03 +02:00
ok ( EqualRect ( & rgn1 - > data . rdh . rcBound , rc ) , " rects don't match \n " ) ;
rect = * ( const RECT * ) rgn1 - > data . Buffer ;
2016-06-20 11:56:26 +02:00
trace ( " rect %s \n " , wine_dbgstr_rect ( & rect ) ) ;
2008-04-21 12:38:03 +02:00
ok ( EqualRect ( & rect , rc ) , " rects don't match \n " ) ;
2008-05-06 15:55:16 +02:00
ok ( rgn1 - > data . rdh . dwSize = = sizeof ( rgn1 - > data . rdh ) , " expected sizeof(rdh), got %u \n " , rgn1 - > data . rdh . dwSize ) ;
2008-04-21 12:38:03 +02:00
ok ( rgn1 - > data . rdh . iType = = RDH_RECTANGLES , " expected RDH_RECTANGLES, got %u \n " , rgn1 - > data . rdh . iType ) ;
ok ( rgn1 - > data . rdh . nCount = = 1 , " expected 1, got %u \n " , rgn1 - > data . rdh . nCount ) ;
2009-06-16 09:49:13 +02:00
ok ( rgn1 - > data . rdh . nRgnSize = = sizeof ( RECT ) | |
broken ( rgn1 - > data . rdh . nRgnSize = = 168 ) , /* NT4 */
" expected sizeof(RECT), got %u \n " , rgn1 - > data . rdh . nRgnSize ) ;
2008-04-21 12:38:03 +02:00
hrgn = CreateRectRgn ( 0 , 0 , 0 , 0 ) ;
memset ( & xform , 0 , sizeof ( xform ) ) ;
SetLastError ( 0xdeadbeef ) ;
ret = GetWorldTransform ( hdc , & xform ) ;
is_win9x = ! ret & & GetLastError ( ) = = ERROR_CALL_NOT_IMPLEMENTED ;
if ( ! is_win9x )
ok ( ret , " GetWorldTransform error %u \n " , GetLastError ( ) ) ;
trace ( " xform.eM11 %f, xform.eM22 %f \n " , xform . eM11 , xform . eM22 ) ;
ret = GetClipRgn ( hdc , hrgn ) ;
ok ( ret = = 0 , " GetClipRgn returned %d, expected 0 \n " , ret ) ;
PlayEnhMetaFileRecord ( hdc , handle_table , emr , n_objs ) ;
ret = GetClipRgn ( hdc , hrgn ) ;
2009-06-16 09:49:13 +02:00
ok ( ret = = 1 , " GetClipRgn returned %d, expected 1 \n " , ret ) ;
2008-04-21 12:38:03 +02:00
/* Win9x returns empty clipping region */
if ( is_win9x ) return 1 ;
ret = GetRegionData ( hrgn , 0 , NULL ) ;
ok ( ret = = sizeof ( rgn2 . data . rdh ) + sizeof ( RECT ) , " expected sizeof(rgn), got %u \n " , ret ) ;
ret = GetRegionData ( hrgn , sizeof ( rgn2 ) , & rgn2 . data ) ;
2011-02-09 22:44:13 +01:00
ok ( ret = = sizeof ( rgn2 ) , " expected sizeof(rgn2), got %u \n " , ret ) ;
2008-04-21 12:38:03 +02:00
2016-06-20 11:56:26 +02:00
trace ( " size %u, type %u, count %u, rgn size %u, bound %s \n " , rgn2 . data . rdh . dwSize ,
rgn2 . data . rdh . iType , rgn2 . data . rdh . nCount , rgn2 . data . rdh . nRgnSize ,
wine_dbgstr_rect ( & rgn2 . data . rdh . rcBound ) ) ;
2008-04-21 12:38:03 +02:00
rect = rgn2 . data . rdh . rcBound ;
rc_transformed = * rc ;
translate ( ( POINT * ) & rc_transformed , 2 , & xform ) ;
2016-06-20 11:56:26 +02:00
trace ( " transformed %s \n " , wine_dbgstr_rect ( & rc_transformed ) ) ;
2008-05-21 14:54:29 +02:00
ok ( is_equal_rect ( & rect , & rc_transformed ) , " rects don't match \n " ) ;
2008-04-21 12:38:03 +02:00
rect = * ( const RECT * ) rgn2 . data . Buffer ;
2016-06-20 11:56:26 +02:00
trace ( " rect %s \n " , wine_dbgstr_rect ( & rect ) ) ;
2008-04-21 12:38:03 +02:00
rc_transformed = * rc ;
translate ( ( POINT * ) & rc_transformed , 2 , & xform ) ;
2016-06-20 11:56:26 +02:00
trace ( " transformed %s \n " , wine_dbgstr_rect ( & rc_transformed ) ) ;
2008-05-21 14:54:29 +02:00
ok ( is_equal_rect ( & rect , & rc_transformed ) , " rects don't match \n " ) ;
2008-04-21 12:38:03 +02:00
2008-05-06 15:55:16 +02:00
ok ( rgn2 . data . rdh . dwSize = = sizeof ( rgn1 - > data . rdh ) , " expected sizeof(rdh), got %u \n " , rgn2 . data . rdh . dwSize ) ;
2008-04-21 12:38:03 +02:00
ok ( rgn2 . data . rdh . iType = = RDH_RECTANGLES , " expected RDH_RECTANGLES, got %u \n " , rgn2 . data . rdh . iType ) ;
ok ( rgn2 . data . rdh . nCount = = 1 , " expected 1, got %u \n " , rgn2 . data . rdh . nCount ) ;
2009-06-16 09:49:13 +02:00
ok ( rgn2 . data . rdh . nRgnSize = = sizeof ( RECT ) | |
broken ( rgn2 . data . rdh . nRgnSize = = 168 ) , /* NT4 */
" expected sizeof(RECT), got %u \n " , rgn2 . data . rdh . nRgnSize ) ;
2008-04-21 12:38:03 +02:00
DeleteObject ( hrgn ) ;
}
return 1 ;
}
static void test_emf_clipping ( void )
{
2020-01-06 16:59:26 +01:00
char buffer [ 100 ] ;
RGNDATA * rgndata = ( RGNDATA * ) buffer ;
2008-04-21 12:38:03 +02:00
static const RECT rc = { 0 , 0 , 100 , 100 } ;
RECT rc_clip = { 100 , 100 , 1024 , 1024 } ;
HWND hwnd ;
HDC hdc ;
HENHMETAFILE hemf ;
HRGN hrgn ;
INT ret ;
2009-09-07 08:57:55 +02:00
RECT rc_res , rc_sclip ;
2008-04-21 12:38:03 +02:00
SetLastError ( 0xdeadbeef ) ;
hdc = CreateEnhMetaFileA ( 0 , NULL , NULL , NULL ) ;
ok ( hdc ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
/* Need to write something to the emf, otherwise Windows won't play it back */
LineTo ( hdc , 1 , 1 ) ;
hrgn = CreateRectRgn ( rc_clip . left , rc_clip . top , rc_clip . right , rc_clip . bottom ) ;
ret = SelectClipRgn ( hdc , hrgn ) ;
ok ( ret = = SIMPLEREGION , " expected SIMPLEREGION, got %d \n " , ret ) ;
2017-06-21 10:34:17 +02:00
BeginPath ( hdc ) ;
Rectangle ( hdc , rc_clip . left , rc_clip . top , rc_clip . right , rc_clip . bottom ) ;
EndPath ( hdc ) ;
ret = SelectClipPath ( hdc , RGN_AND ) ;
ok ( ret , " SelectClipPath error %d \n " , GetLastError ( ) ) ;
2008-04-21 12:38:03 +02:00
SetLastError ( 0xdeadbeef ) ;
hemf = CloseEnhMetaFile ( hdc ) ;
ok ( hemf ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_emf_bits ( hemf , EMF_CLIPPING , sizeof ( EMF_CLIPPING ) ,
2008-12-10 17:27:30 +01:00
" emf_clipping " , FALSE ) ! = 0 )
2008-04-21 12:38:03 +02:00
{
dump_emf_bits ( hemf , " emf_clipping " ) ;
dump_emf_records ( hemf , " emf_clipping " ) ;
}
DeleteObject ( hrgn ) ;
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA ( 0 , " static " , NULL , WS_POPUP | WS_VISIBLE ,
0 , 0 , 200 , 200 , 0 , 0 , 0 , NULL ) ;
ok ( hwnd ! = 0 , " CreateWindowExA error %d \n " , GetLastError ( ) ) ;
hdc = GetDC ( hwnd ) ;
ret = EnumEnhMetaFile ( hdc , hemf , clip_emf_enum_proc , & rc_clip , & rc ) ;
ok ( ret , " EnumEnhMetaFile error %d \n " , GetLastError ( ) ) ;
DeleteEnhMetaFile ( hemf ) ;
ReleaseDC ( hwnd , hdc ) ;
DestroyWindow ( hwnd ) ;
2009-09-07 08:57:55 +02:00
hdc = CreateEnhMetaFileA ( 0 , NULL , NULL , NULL ) ;
SetRect ( & rc_sclip , 100 , 100 , GetSystemMetrics ( SM_CXSCREEN ) , GetSystemMetrics ( SM_CYSCREEN ) ) ;
hrgn = CreateRectRgn ( rc_sclip . left , rc_sclip . top , rc_sclip . right , rc_sclip . bottom ) ;
SelectClipRgn ( hdc , hrgn ) ;
2013-02-13 09:47:13 +01:00
SetRect ( & rc_res , - 1 , - 1 , - 1 , - 1 ) ;
2009-11-13 13:01:23 +01:00
ret = GetClipBox ( hdc , & rc_res ) ;
ok ( ret = = SIMPLEREGION , " got %d \n " , ret ) ;
2016-06-20 11:56:26 +02:00
ok ( EqualRect ( & rc_res , & rc_sclip ) , " expected %s, got %s \n " , wine_dbgstr_rect ( & rc_sclip ) ,
wine_dbgstr_rect ( & rc_res ) ) ;
2013-02-14 06:37:11 +01:00
OffsetRect ( & rc_sclip , - 100 , - 100 ) ;
ret = OffsetClipRgn ( hdc , - 100 , - 100 ) ;
ok ( ret = = SIMPLEREGION , " got %d \n " , ret ) ;
SetRect ( & rc_res , - 1 , - 1 , - 1 , - 1 ) ;
ret = GetClipBox ( hdc , & rc_res ) ;
ok ( ret = = SIMPLEREGION , " got %d \n " , ret ) ;
2016-06-20 11:56:26 +02:00
ok ( EqualRect ( & rc_res , & rc_sclip ) , " expected %s, got %s \n " , wine_dbgstr_rect ( & rc_sclip ) ,
wine_dbgstr_rect ( & rc_res ) ) ;
2013-02-14 06:37:11 +01:00
ret = IntersectClipRect ( hdc , 0 , 0 , 100 , 100 ) ;
2020-01-06 16:59:26 +01:00
/* all versions of Windows return COMPLEXREGION despite the region comprising one rectangle */
ok ( ret = = SIMPLEREGION | | broken ( ret = = COMPLEXREGION ) , " wrong region type %d \n " , ret ) ;
ret = GetClipRgn ( hdc , hrgn ) ;
ok ( ret = = 1 , " expected 1, got %d \n " , ret ) ;
ret = GetRegionData ( hrgn , sizeof ( buffer ) , rgndata ) ;
ok ( ret = = sizeof ( RGNDATAHEADER ) + sizeof ( RECT ) , " got %u \n " , ret ) ;
ok ( rgndata - > rdh . nCount = = 1 , " got %u rectangles \n " , rgndata - > rdh . nCount ) ;
ok ( EqualRect ( ( RECT * ) rgndata - > Buffer , & rc ) , " got rect %s \n " , wine_dbgstr_rect ( ( RECT * ) rgndata - > Buffer ) ) ;
2013-02-14 06:37:11 +01:00
SetRect ( & rc_res , - 1 , - 1 , - 1 , - 1 ) ;
ret = GetClipBox ( hdc , & rc_res ) ;
ok ( ret = = SIMPLEREGION , " got %d \n " , ret ) ;
2016-06-20 11:56:26 +02:00
ok ( EqualRect ( & rc_res , & rc ) , " expected %s, got %s \n " , wine_dbgstr_rect ( & rc ) ,
wine_dbgstr_rect ( & rc_res ) ) ;
2013-02-14 06:37:11 +01:00
SetRect ( & rc_sclip , 0 , 0 , 100 , 50 ) ;
ret = ExcludeClipRect ( hdc , 0 , 50 , 100 , 100 ) ;
2020-01-06 16:59:26 +01:00
/* all versions of Windows return COMPLEXREGION despite the region comprising one rectangle */
ok ( ret = = SIMPLEREGION | | broken ( ret = = COMPLEXREGION ) , " wrong region type %d \n " , ret ) ;
ret = GetClipRgn ( hdc , hrgn ) ;
ok ( ret = = 1 , " expected 1, got %d \n " , ret ) ;
ret = GetRegionData ( hrgn , sizeof ( buffer ) , rgndata ) ;
ok ( ret = = sizeof ( RGNDATAHEADER ) + sizeof ( RECT ) , " got %u \n " , ret ) ;
ok ( rgndata - > rdh . nCount = = 1 , " got %u rectangles \n " , rgndata - > rdh . nCount ) ;
ok ( EqualRect ( ( RECT * ) rgndata - > Buffer , & rc_sclip ) , " got rect %s \n " , wine_dbgstr_rect ( ( RECT * ) rgndata - > Buffer ) ) ;
2013-02-14 06:37:11 +01:00
SetRect ( & rc_res , - 1 , - 1 , - 1 , - 1 ) ;
ret = GetClipBox ( hdc , & rc_res ) ;
ok ( ret = = SIMPLEREGION , " got %d \n " , ret ) ;
2016-06-20 11:56:26 +02:00
ok ( EqualRect ( & rc_res , & rc_sclip ) , " expected %s, got %s \n " , wine_dbgstr_rect ( & rc_sclip ) ,
wine_dbgstr_rect ( & rc_res ) ) ;
2009-09-07 08:57:55 +02:00
hemf = CloseEnhMetaFile ( hdc ) ;
DeleteEnhMetaFile ( hemf ) ;
DeleteObject ( hrgn ) ;
2008-04-21 12:38:03 +02:00
}
2012-06-20 03:08:07 +02:00
static const unsigned char MF_CLIP_BITS [ ] = {
/* METAHEADER */
0x01 , 0x00 , /* mtType */
0x09 , 0x00 , /* mtHeaderSize */
0x00 , 0x03 , /* mtVersion */
0x32 , 0x00 , 0x00 , 0x00 , /* mtSize */
0x01 , 0x00 , /* mtNoObjects */
0x14 , 0x00 , 0x00 , 0x00 , /* mtMaxRecord (size in words of longest record) */
0x00 , 0x00 , /* reserved */
/* METARECORD for CreateRectRgn(0x11, 0x22, 0x33, 0x44) */
0x14 , 0x00 , 0x00 , 0x00 , /* rdSize in words */
0xff , 0x06 , /* META_CREATEREGION */
0x00 , 0x00 , 0x06 , 0x00 , 0xf6 , 0x02 , 0x00 , 0x00 ,
0x24 , 0x00 , 0x01 , 0x00 , 0x02 , 0x00 , 0x11 , 0x00 ,
0x22 , 0x00 , 0x33 , 0x00 , 0x44 , 0x00 , 0x02 , 0x00 ,
0x22 , 0x00 , 0x44 , 0x00 , 0x11 , 0x00 , 0x33 , 0x00 ,
0x02 , 0x00 ,
/* METARECORD for SelectObject */
0x04 , 0x00 , 0x00 , 0x00 ,
0x2d , 0x01 , /* META_SELECTOBJECT (not META_SELECTCLIPREGION?!) */
0x00 , 0x00 ,
/* METARECORD */
0x04 , 0x00 , 0x00 , 0x00 ,
0xf0 , 0x01 , /* META_DELETEOBJECT */
0x00 , 0x00 ,
/* METARECORD for MoveTo(1,0x30) */
0x05 , 0x00 , 0x00 , 0x00 , /* rdSize in words */
0x14 , 0x02 , /* META_MOVETO */
0x30 , 0x00 , /* y */
0x01 , 0x00 , /* x */
/* METARECORD for LineTo(0x20, 0x30) */
0x05 , 0x00 , 0x00 , 0x00 , /* rdSize in words */
0x13 , 0x02 , /* META_LINETO */
0x30 , 0x00 , /* y */
0x20 , 0x00 , /* x */
/* EOF */
0x03 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00
} ;
static int clip_mf_enum_proc_seen_selectclipregion ;
static int clip_mf_enum_proc_seen_selectobject ;
static int CALLBACK clip_mf_enum_proc ( HDC hdc , HANDLETABLE * handle_table ,
METARECORD * mr , int n_objs , LPARAM param )
{
switch ( mr - > rdFunction ) {
case META_SELECTCLIPREGION :
clip_mf_enum_proc_seen_selectclipregion + + ;
break ;
case META_SELECTOBJECT :
clip_mf_enum_proc_seen_selectobject + + ;
break ;
}
return 1 ;
}
static void test_mf_clipping ( void )
{
/* left top right bottom */
static RECT rc_clip = { 0x11 , 0x22 , 0x33 , 0x44 } ;
HWND hwnd ;
HDC hdc ;
HMETAFILE hmf ;
HRGN hrgn ;
INT ret ;
SetLastError ( 0xdeadbeef ) ;
hdc = CreateMetaFileA ( NULL ) ;
ok ( hdc ! = 0 , " CreateMetaFileA error %d \n " , GetLastError ( ) ) ;
hrgn = CreateRectRgn ( rc_clip . left , rc_clip . top , rc_clip . right , rc_clip . bottom ) ;
ret = SelectClipRgn ( hdc , hrgn ) ;
/* Seems like it should be SIMPLEREGION, but windows returns NULLREGION? */
ok ( ret = = NULLREGION , " expected NULLREGION, got %d \n " , ret ) ;
/* Draw a line that starts off left of the clip region and ends inside it */
MoveToEx ( hdc , 0x1 , 0x30 , NULL ) ;
LineTo ( hdc , 0x20 , 0x30 ) ;
SetLastError ( 0xdeadbeef ) ;
hmf = CloseMetaFile ( hdc ) ;
ok ( hmf ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_mf_bits ( hmf , MF_CLIP_BITS , sizeof ( MF_CLIP_BITS ) ,
" mf_clipping " ) ! = 0 )
{
dump_mf_bits ( hmf , " mf_clipping " ) ;
}
DeleteObject ( hrgn ) ;
hwnd = CreateWindowExA ( 0 , " static " , NULL , WS_POPUP | WS_VISIBLE ,
0 , 0 , 200 , 200 , 0 , 0 , 0 , NULL ) ;
ok ( hwnd ! = 0 , " CreateWindowExA error %d \n " , GetLastError ( ) ) ;
hdc = GetDC ( hwnd ) ;
ret = EnumMetaFile ( hdc , hmf , clip_mf_enum_proc , ( LPARAM ) & rc_clip ) ;
ok ( ret , " EnumMetaFile error %d \n " , GetLastError ( ) ) ;
/* Oddly, windows doesn't seem to use META_SELECTCLIPREGION */
ok ( clip_mf_enum_proc_seen_selectclipregion = = 0 ,
" expected 0 selectclipregion, saw %d \n " , clip_mf_enum_proc_seen_selectclipregion ) ;
ok ( clip_mf_enum_proc_seen_selectobject = = 1 ,
" expected 1 selectobject, saw %d \n " , clip_mf_enum_proc_seen_selectobject ) ;
DeleteMetaFile ( hmf ) ;
ReleaseDC ( hwnd , hdc ) ;
DestroyWindow ( hwnd ) ;
}
2016-02-23 08:16:49 +01:00
static const unsigned char MF_PATH_BITS [ ] =
{
0x01 , 0x00 , 0x09 , 0x00 , 0x00 , 0x03 , 0x2c , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x07 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x14 , 0x02 ,
0x32 , 0x00 , 0x32 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 ,
0x13 , 0x02 , 0x96 , 0x00 , 0x32 , 0x00 , 0x05 , 0x00 ,
0x00 , 0x00 , 0x13 , 0x02 , 0x96 , 0x00 , 0x96 , 0x00 ,
0x05 , 0x00 , 0x00 , 0x00 , 0x13 , 0x02 , 0x32 , 0x00 ,
0x96 , 0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x13 , 0x02 ,
0x32 , 0x00 , 0x32 , 0x00 , 0x07 , 0x00 , 0x00 , 0x00 ,
0x1b , 0x04 , 0x14 , 0x00 , 0x14 , 0x00 , 0x0a , 0x00 ,
0x0a , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
} ;
static void test_mf_GetPath ( void )
{
HDC hdc ;
HMETAFILE hmf ;
BOOL ret ;
int size ;
SetLastError ( 0xdeadbeef ) ;
hdc = CreateMetaFileA ( NULL ) ;
ok ( hdc ! = 0 , " CreateMetaFileA error %d \n " , GetLastError ( ) ) ;
2018-11-29 10:28:26 +01:00
ret = BeginPath ( hdc ) ;
ok ( ! ret , " BeginPath on metafile DC should fail \n " ) ;
2016-02-23 08:16:49 +01:00
ret = MoveToEx ( hdc , 50 , 50 , NULL ) ;
ok ( ret , " MoveToEx error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdc , 50 , 150 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdc , 150 , 150 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdc , 150 , 50 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdc , 50 , 50 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
Rectangle ( hdc , 10 , 10 , 20 , 20 ) ;
EndPath ( hdc ) ;
size = GetPath ( hdc , NULL , NULL , 0 ) ;
ok ( size = = - 1 , " GetPath returned %d. \n " , size ) ;
hmf = CloseMetaFile ( hdc ) ;
ok ( hmf ! = 0 , " CloseMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_mf_bits ( hmf , MF_PATH_BITS , sizeof ( MF_PATH_BITS ) , " mf_GetPath " ) ! = 0 )
{
dump_mf_bits ( hmf , " mf_GetPath " ) ;
EnumMetaFile ( 0 , hmf , mf_enum_proc , 0 ) ;
}
ret = DeleteMetaFile ( hmf ) ;
ok ( ret , " DeleteMetaFile error %d \n " , GetLastError ( ) ) ;
}
2005-07-15 11:55:33 +02:00
static INT CALLBACK EmfEnumProc ( HDC hdc , HANDLETABLE * lpHTable , const ENHMETARECORD * lpEMFR , INT nObj , LPARAM lpData )
2005-04-13 12:57:59 +02:00
{
2005-07-15 11:55:33 +02:00
LPMETAFILEPICT lpMFP = ( LPMETAFILEPICT ) lpData ;
2005-06-22 20:03:19 +02:00
POINT mapping [ 2 ] = { { 0 , 0 } , { 10 , 10 } } ;
2005-07-15 11:55:33 +02:00
/* When using MM_TEXT Win9x does not update the mapping mode
* until a record is played which actually outputs something */
2005-04-13 12:57:59 +02:00
PlayEnhMetaFileRecord ( hdc , lpHTable , lpEMFR , nObj ) ;
LPtoDP ( hdc , mapping , 2 ) ;
2008-05-07 13:34:36 +02:00
trace ( " EMF record: iType %d, nSize %d, (%d,%d)-(%d,%d) \n " ,
2006-03-30 16:03:02 +02:00
lpEMFR - > iType , lpEMFR - > nSize ,
mapping [ 0 ] . x , mapping [ 0 ] . y , mapping [ 1 ] . x , mapping [ 1 ] . y ) ;
2005-04-13 12:57:59 +02:00
if ( lpEMFR - > iType = = EMR_LINETO )
{
2005-07-15 11:55:33 +02:00
INT x0 , y0 , x1 , y1 ;
if ( ! lpMFP | | lpMFP - > mm = = MM_TEXT )
{
x0 = 0 ;
y0 = 0 ;
x1 = ( INT ) floor ( 10 * 100.0 / LINE_X + 0.5 ) ;
y1 = ( INT ) floor ( 10 * 100.0 / LINE_Y + 0.5 ) ;
}
else
{
2006-10-12 22:56:45 +02:00
ok ( lpMFP - > mm = = MM_ANISOTROPIC , " mm=%d \n " , lpMFP - > mm ) ;
2005-07-15 11:55:33 +02:00
x0 = MulDiv ( 0 , GetDeviceCaps ( hdc , HORZSIZE ) * 100 , GetDeviceCaps ( hdc , HORZRES ) ) ;
y0 = MulDiv ( 0 , GetDeviceCaps ( hdc , VERTSIZE ) * 100 , GetDeviceCaps ( hdc , VERTRES ) ) ;
x1 = MulDiv ( 10 , GetDeviceCaps ( hdc , HORZSIZE ) * 100 , GetDeviceCaps ( hdc , HORZRES ) ) ;
y1 = MulDiv ( 10 , GetDeviceCaps ( hdc , VERTSIZE ) * 100 , GetDeviceCaps ( hdc , VERTRES ) ) ;
}
2005-04-13 12:57:59 +02:00
ok ( mapping [ 0 ] . x = = x0 & & mapping [ 0 ] . y = = y0 & & mapping [ 1 ] . x = = x1 & & mapping [ 1 ] . y = = y1 ,
2006-10-12 22:56:45 +02:00
" (%d,%d)->(%d,%d), expected (%d,%d)->(%d,%d) \n " ,
2005-04-13 12:57:59 +02:00
mapping [ 0 ] . x , mapping [ 0 ] . y , mapping [ 1 ] . x , mapping [ 1 ] . y ,
x0 , y0 , x1 , y1 ) ;
}
return TRUE ;
}
static HENHMETAFILE create_converted_emf ( const METAFILEPICT * mfp )
{
HDC hdcMf ;
HMETAFILE hmf ;
2008-05-21 14:54:29 +02:00
HENHMETAFILE hemf ;
2005-04-13 12:57:59 +02:00
BOOL ret ;
UINT size ;
LPBYTE pBits ;
2013-10-16 07:31:44 +02:00
hdcMf = CreateMetaFileA ( NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( hdcMf ! = NULL , " CreateMetaFile failed with error %d \n " , GetLastError ( ) ) ;
2005-04-13 12:57:59 +02:00
ret = LineTo ( hdcMf , ( INT ) LINE_X , ( INT ) LINE_Y ) ;
2006-10-12 22:56:45 +02:00
ok ( ret , " LineTo failed with error %d \n " , GetLastError ( ) ) ;
2005-04-13 12:57:59 +02:00
hmf = CloseMetaFile ( hdcMf ) ;
2006-10-12 22:56:45 +02:00
ok ( hmf ! = NULL , " CloseMetaFile failed with error %d \n " , GetLastError ( ) ) ;
2006-03-30 16:03:02 +02:00
if ( compare_mf_bits ( hmf , MF_LINETO_BITS , sizeof ( MF_LINETO_BITS ) , " mf_LineTo " ) ! = 0 )
{
dump_mf_bits ( hmf , " mf_LineTo " ) ;
EnumMetaFile ( 0 , hmf , mf_enum_proc , 0 ) ;
}
2005-04-13 12:57:59 +02:00
size = GetMetaFileBitsEx ( hmf , 0 , NULL ) ;
2006-10-12 22:56:45 +02:00
ok ( size , " GetMetaFileBitsEx failed with error %d \n " , GetLastError ( ) ) ;
2005-04-13 12:57:59 +02:00
pBits = HeapAlloc ( GetProcessHeap ( ) , 0 , size ) ;
GetMetaFileBitsEx ( hmf , size , pBits ) ;
DeleteMetaFile ( hmf ) ;
2008-05-21 14:54:29 +02:00
hemf = SetWinMetaFileBits ( size , pBits , NULL , mfp ) ;
HeapFree ( GetProcessHeap ( ) , 0 , pBits ) ;
return hemf ;
2005-04-13 12:57:59 +02:00
}
2005-06-21 22:53:13 +02:00
static void test_mf_conversions ( void )
2005-04-13 12:57:59 +02:00
{
trace ( " Testing MF->EMF conversion (MM_ANISOTROPIC) \n " ) ;
{
HDC hdcOffscreen = CreateCompatibleDC ( NULL ) ;
HENHMETAFILE hemf ;
METAFILEPICT mfp ;
RECT rect = { 0 , 0 , 100 , 100 } ;
mfp . mm = MM_ANISOTROPIC ;
mfp . xExt = 100 ;
mfp . yExt = 100 ;
mfp . hMF = NULL ;
hemf = create_converted_emf ( & mfp ) ;
2006-03-30 16:03:02 +02:00
if ( compare_emf_bits ( hemf , EMF_LINETO_MM_ANISOTROPIC_BITS , sizeof ( EMF_LINETO_MM_ANISOTROPIC_BITS ) ,
2008-12-10 17:27:30 +01:00
" emf_LineTo MM_ANISOTROPIC " , TRUE ) ! = 0 )
2006-03-30 16:03:02 +02:00
{
dump_emf_bits ( hemf , " emf_LineTo MM_ANISOTROPIC " ) ;
dump_emf_records ( hemf , " emf_LineTo MM_ANISOTROPIC " ) ;
}
2005-07-15 11:55:33 +02:00
EnumEnhMetaFile ( hdcOffscreen , hemf , EmfEnumProc , & mfp , & rect ) ;
2006-03-30 16:03:02 +02:00
2005-04-13 12:57:59 +02:00
DeleteEnhMetaFile ( hemf ) ;
DeleteDC ( hdcOffscreen ) ;
}
trace ( " Testing MF->EMF conversion (MM_TEXT) \n " ) ;
{
HDC hdcOffscreen = CreateCompatibleDC ( NULL ) ;
HENHMETAFILE hemf ;
METAFILEPICT mfp ;
RECT rect = { 0 , 0 , 100 , 100 } ;
mfp . mm = MM_TEXT ;
mfp . xExt = 0 ;
mfp . yExt = 0 ;
mfp . hMF = NULL ;
hemf = create_converted_emf ( & mfp ) ;
2006-03-30 16:03:02 +02:00
if ( compare_emf_bits ( hemf , EMF_LINETO_MM_TEXT_BITS , sizeof ( EMF_LINETO_MM_TEXT_BITS ) ,
2008-12-10 17:27:30 +01:00
" emf_LineTo MM_TEXT " , TRUE ) ! = 0 )
2006-03-30 16:03:02 +02:00
{
dump_emf_bits ( hemf , " emf_LineTo MM_TEXT " ) ;
dump_emf_records ( hemf , " emf_LineTo MM_TEXT " ) ;
}
2005-07-15 11:55:33 +02:00
EnumEnhMetaFile ( hdcOffscreen , hemf , EmfEnumProc , & mfp , & rect ) ;
2006-03-30 16:03:02 +02:00
2005-04-13 12:57:59 +02:00
DeleteEnhMetaFile ( hemf ) ;
DeleteDC ( hdcOffscreen ) ;
}
trace ( " Testing MF->EMF conversion (NULL mfp) \n " ) ;
{
HDC hdcOffscreen = CreateCompatibleDC ( NULL ) ;
HENHMETAFILE hemf ;
RECT rect = { 0 , 0 , 100 , 100 } ;
hemf = create_converted_emf ( NULL ) ;
2006-03-30 16:03:02 +02:00
if ( compare_emf_bits ( hemf , EMF_LINETO_BITS , sizeof ( EMF_LINETO_BITS ) ,
2008-12-10 17:27:30 +01:00
" emf_LineTo NULL " , TRUE ) ! = 0 )
2006-03-30 16:03:02 +02:00
{
dump_emf_bits ( hemf , " emf_LineTo NULL " ) ;
dump_emf_records ( hemf , " emf_LineTo NULL " ) ;
}
2005-07-15 11:55:33 +02:00
EnumEnhMetaFile ( hdcOffscreen , hemf , EmfEnumProc , NULL , & rect ) ;
2006-03-30 16:03:02 +02:00
2005-04-13 12:57:59 +02:00
DeleteEnhMetaFile ( hemf ) ;
DeleteDC ( hdcOffscreen ) ;
}
}
2006-06-20 16:02:37 +02:00
static BOOL getConvertedFrameAndBounds ( UINT buffer_size , BYTE * buffer , BOOL mfpIsNull ,
LONG mm , LONG xExt , LONG yExt ,
RECTL * rclBounds , RECTL * rclFrame )
{
METAFILEPICT mfp ;
METAFILEPICT * mfpPtr = NULL ;
HENHMETAFILE emf ;
ENHMETAHEADER header ;
UINT res ;
if ( ! mfpIsNull )
{
mfp . mm = mm ;
mfp . xExt = xExt ;
mfp . yExt = yExt ;
mfpPtr = & mfp ;
}
emf = SetWinMetaFileBits ( buffer_size , buffer , NULL , mfpPtr ) ;
ok ( emf ! = NULL , " SetWinMetaFileBits failed \n " ) ;
if ( ! emf ) return FALSE ;
res = GetEnhMetaFileHeader ( emf , sizeof ( header ) , & header ) ;
ok ( res ! = 0 , " GetEnhMetaHeader failed \n " ) ;
DeleteEnhMetaFile ( emf ) ;
if ( ! res ) return FALSE ;
* rclBounds = header . rclBounds ;
* rclFrame = header . rclFrame ;
return TRUE ;
}
static void checkConvertedFrameAndBounds ( UINT buffer_size , BYTE * buffer , BOOL mfpIsNull ,
LONG mm , LONG xExt , LONG yExt ,
RECTL * rclBoundsExpected , RECTL * rclFrameExpected )
{
RECTL rclBounds , rclFrame ;
if ( getConvertedFrameAndBounds ( buffer_size , buffer , mfpIsNull , mm , xExt , yExt , & rclBounds , & rclFrame ) )
{
2006-06-24 16:01:31 +02:00
const char * msg ;
2006-06-20 16:02:37 +02:00
char buf [ 64 ] ;
if ( mfpIsNull )
{
msg = " mfp == NULL " ;
}
else
{
2006-06-24 16:01:31 +02:00
const char * mm_str ;
2006-06-20 16:02:37 +02:00
switch ( mm )
{
case MM_ANISOTROPIC : mm_str = " MM_ANISOTROPIC " ; break ;
case MM_ISOTROPIC : mm_str = " MM_ISOTROPIC " ; break ;
default : mm_str = " Unexpected " ;
}
2006-10-12 22:56:45 +02:00
sprintf ( buf , " mm=%s, xExt=%d, yExt=%d " , mm_str , xExt , yExt ) ;
2006-06-20 16:02:37 +02:00
msg = buf ;
}
2006-10-12 22:56:45 +02:00
ok ( rclBounds . left = = rclBoundsExpected - > left , " rclBounds.left: Expected %d, got %d (%s) \n " , rclBoundsExpected - > left , rclBounds . left , msg ) ;
ok ( rclBounds . top = = rclBoundsExpected - > top , " rclBounds.top: Expected %d, got %d (%s) \n " , rclBoundsExpected - > top , rclBounds . top , msg ) ;
ok ( rclBounds . right = = rclBoundsExpected - > right , " rclBounds.right: Expected %d, got %d (%s) \n " , rclBoundsExpected - > right , rclBounds . right , msg ) ;
ok ( rclBounds . bottom = = rclBoundsExpected - > bottom , " rclBounds.bottom: Expected %d, got %d (%s) \n " , rclBoundsExpected - > bottom , rclBounds . bottom , msg ) ;
ok ( rclFrame . left = = rclFrameExpected - > left , " rclFrame.left: Expected %d, got %d (%s) \n " , rclFrameExpected - > left , rclFrame . left , msg ) ;
ok ( rclFrame . top = = rclFrameExpected - > top , " rclFrame.top: Expected %d, got %d (%s) \n " , rclFrameExpected - > top , rclFrame . top , msg ) ;
ok ( rclFrame . right = = rclFrameExpected - > right , " rclFrame.right: Expected %d, got %d (%s) \n " , rclFrameExpected - > right , rclFrame . right , msg ) ;
ok ( rclFrame . bottom = = rclFrameExpected - > bottom , " rclFrame.bottom: Expected %d, got %d (%s) \n " , rclFrameExpected - > bottom , rclFrame . bottom , msg ) ;
2006-06-20 16:02:37 +02:00
}
}
static void test_SetWinMetaFileBits ( void )
{
HMETAFILE wmf ;
HDC wmfDC ;
BYTE * buffer ;
UINT buffer_size ;
RECT rect ;
UINT res ;
RECTL rclBoundsAnisotropic , rclFrameAnisotropic ;
RECTL rclBoundsIsotropic , rclFrameIsotropic ;
RECTL rclBounds , rclFrame ;
HDC dc ;
LONG diffx , diffy ;
2013-10-16 07:31:44 +02:00
wmfDC = CreateMetaFileA ( NULL ) ;
2006-06-20 16:02:37 +02:00
ok ( wmfDC ! = NULL , " CreateMetaFile failed \n " ) ;
if ( ! wmfDC ) return ;
SetWindowExtEx ( wmfDC , 100 , 100 , NULL ) ;
2016-06-21 14:13:43 +02:00
SetRect ( & rect , 0 , 0 , 50 , 50 ) ;
2006-06-20 16:02:37 +02:00
FillRect ( wmfDC , & rect , GetStockObject ( BLACK_BRUSH ) ) ;
wmf = CloseMetaFile ( wmfDC ) ;
ok ( wmf ! = NULL , " Metafile creation failed \n " ) ;
if ( ! wmf ) return ;
buffer_size = GetMetaFileBitsEx ( wmf , 0 , NULL ) ;
ok ( buffer_size ! = 0 , " GetMetaFileBitsEx failed \n " ) ;
if ( buffer_size = = 0 )
{
DeleteMetaFile ( wmf ) ;
return ;
}
2007-06-27 00:13:13 +02:00
buffer = HeapAlloc ( GetProcessHeap ( ) , 0 , buffer_size ) ;
2006-06-20 16:02:37 +02:00
ok ( buffer ! = NULL , " HeapAlloc failed \n " ) ;
if ( ! buffer )
{
DeleteMetaFile ( wmf ) ;
return ;
}
res = GetMetaFileBitsEx ( wmf , buffer_size , buffer ) ;
ok ( res = = buffer_size , " GetMetaFileBitsEx failed \n " ) ;
DeleteMetaFile ( wmf ) ;
if ( res ! = buffer_size )
{
HeapFree ( GetProcessHeap ( ) , 0 , buffer ) ;
return ;
}
/* Get the reference bounds and frame */
getConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , 0 , 0 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
getConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , 0 , 0 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
ok ( rclBoundsAnisotropic . left = = 0 & & rclBoundsAnisotropic . top = = 0 & &
rclBoundsIsotropic . left = = 0 & & rclBoundsIsotropic . top = = 0 ,
" SetWinMetaFileBits: Reference bounds: Left and top bound must be zero \n " ) ;
ok ( rclBoundsAnisotropic . right > = rclBoundsIsotropic . right , " SetWinMetaFileBits: Reference bounds: Invalid right bound \n " ) ;
ok ( rclBoundsAnisotropic . bottom > = rclBoundsIsotropic . bottom , " SetWinMetaFileBits: Reference bounds: Invalid bottom bound \n " ) ;
diffx = rclBoundsIsotropic . right - rclBoundsIsotropic . bottom ;
if ( diffx < 0 ) diffx = - diffx ;
ok ( diffx < = 1 , " SetWinMetaFileBits (MM_ISOTROPIC): Reference bounds are not isotropic \n " ) ;
dc = CreateCompatibleDC ( NULL ) ;
2008-05-21 14:54:29 +02:00
/* Allow 1 mm difference (rounding errors) */
diffx = rclBoundsAnisotropic . right - GetDeviceCaps ( dc , HORZRES ) / 2 ;
diffy = rclBoundsAnisotropic . bottom - GetDeviceCaps ( dc , VERTRES ) / 2 ;
if ( diffx < 0 ) diffx = - diffx ;
if ( diffy < 0 ) diffy = - diffy ;
2006-06-20 16:02:37 +02:00
todo_wine
{
2008-05-21 14:54:29 +02:00
ok ( diffx < = 1 & & diffy < = 1 ,
2006-10-12 22:56:45 +02:00
" SetWinMetaFileBits (MM_ANISOTROPIC): Reference bounds: The whole device surface must be used (%dx%d), but got (%dx%d) \n " ,
2008-05-21 14:54:29 +02:00
GetDeviceCaps ( dc , HORZRES ) / 2 , GetDeviceCaps ( dc , VERTRES ) / 2 , rclBoundsAnisotropic . right , rclBoundsAnisotropic . bottom ) ;
2006-06-20 16:02:37 +02:00
}
/* Allow 1 mm difference (rounding errors) */
diffx = rclFrameAnisotropic . right / 100 - GetDeviceCaps ( dc , HORZSIZE ) / 2 ;
diffy = rclFrameAnisotropic . bottom / 100 - GetDeviceCaps ( dc , VERTSIZE ) / 2 ;
if ( diffx < 0 ) diffx = - diffx ;
if ( diffy < 0 ) diffy = - diffy ;
todo_wine
{
ok ( diffx < = 1 & & diffy < = 1 ,
2006-10-12 22:56:45 +02:00
" SetWinMetaFileBits (MM_ANISOTROPIC): Reference frame: The whole device surface must be used (%dx%d), but got (%dx%d) \n " ,
2006-06-20 16:02:37 +02:00
GetDeviceCaps ( dc , HORZSIZE ) / 2 , GetDeviceCaps ( dc , VERTSIZE ) / 2 , rclFrameAnisotropic . right / 100 , rclFrameAnisotropic . bottom / 100 ) ;
}
DeleteDC ( dc ) ;
/* If the METAFILEPICT pointer is NULL, the MM_ANISOTROPIC mapping mode and the whole device surface are used */
checkConvertedFrameAndBounds ( buffer_size , buffer , TRUE , 0 , 0 , 0 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
/* If xExt or yExt is zero or negative, the whole device surface is used */
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , 10000 , 0 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , 10000 , 0 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , 0 , 10000 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , 0 , 10000 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , - 10000 , 0 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , - 10000 , 0 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , 0 , - 10000 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , 0 , - 10000 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , - 10000 , 10000 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , - 10000 , 10000 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , 10000 , - 10000 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , 10000 , - 10000 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
/* MSDN says that negative xExt and yExt values specify a ratio.
Check that this is wrong and the whole device surface is used */
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , - 1000 , - 100 , & rclBoundsAnisotropic , & rclFrameAnisotropic ) ;
checkConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , - 1000 , - 100 , & rclBoundsIsotropic , & rclFrameIsotropic ) ;
/* Ordinary conversions */
if ( getConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ANISOTROPIC , 30000 , 20000 , & rclBounds , & rclFrame ) )
{
ok ( rclFrame . left = = 0 & & rclFrame . top = = 0 & & rclFrame . right = = 30000 & & rclFrame . bottom = = 20000 ,
" SetWinMetaFileBits (MM_ANISOTROPIC): rclFrame contains invalid values \n " ) ;
ok ( rclBounds . left = = 0 & & rclBounds . top = = 0 & & rclBounds . right > rclBounds . bottom ,
" SetWinMetaFileBits (MM_ANISOTROPIC): rclBounds contains invalid values \n " ) ;
}
if ( getConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_ISOTROPIC , 30000 , 20000 , & rclBounds , & rclFrame ) )
{
ok ( rclFrame . left = = 0 & & rclFrame . top = = 0 & & rclFrame . right = = 30000 & & rclFrame . bottom = = 20000 ,
" SetWinMetaFileBits (MM_ISOTROPIC): rclFrame contains invalid values \n " ) ;
ok ( rclBounds . left = = 0 & & rclBounds . top = = 0 ,
" SetWinMetaFileBits (MM_ISOTROPIC): rclBounds contains invalid values \n " ) ;
/* Wine has a rounding error */
diffx = rclBounds . right - rclBounds . bottom ;
if ( diffx < 0 ) diffx = - diffx ;
ok ( diffx < = 1 , " SetWinMetaFileBits (MM_ISOTROPIC): rclBounds is not isotropic \n " ) ;
}
if ( getConvertedFrameAndBounds ( buffer_size , buffer , FALSE , MM_HIMETRIC , 30000 , 20000 , & rclBounds , & rclFrame ) )
{
ok ( rclFrame . right - rclFrame . left ! = 30000 & & rclFrame . bottom - rclFrame . top ! = 20000 ,
" SetWinMetaFileBits: xExt and yExt must be ignored for mapping modes other than MM_ANISOTROPIC and MM_ISOTROPIC \n " ) ;
}
HeapFree ( GetProcessHeap ( ) , 0 , buffer ) ;
}
2009-07-10 15:47:50 +02:00
static BOOL near_match ( int x , int y )
2009-07-07 12:32:41 +02:00
{
2009-07-10 15:47:50 +02:00
int epsilon = min ( abs ( x ) , abs ( y ) ) ;
2009-07-07 12:32:41 +02:00
2009-07-10 15:47:50 +02:00
epsilon = max ( epsilon / 100 , 2 ) ;
2009-07-07 12:32:41 +02:00
2009-07-10 15:47:50 +02:00
if ( x < y - epsilon | | x > y + epsilon ) return FALSE ;
return TRUE ;
2009-07-07 12:32:41 +02:00
}
static void getwinmetafilebits ( UINT mode , int scale , RECT * rc )
2009-06-30 12:47:59 +02:00
{
2016-06-08 12:00:46 +02:00
HENHMETAFILE emf , emf2 ;
2009-06-30 12:47:59 +02:00
HDC display_dc , emf_dc ;
2016-06-08 12:00:46 +02:00
ENHMETAHEADER * enh_header , * enh2_header ;
UINT size , emf_size , i , emf2_size ;
2009-06-30 12:47:59 +02:00
WORD check = 0 ;
DWORD rec_num = 0 ;
2009-07-08 16:20:25 +02:00
METAHEADER * mh = NULL ;
2009-06-30 12:47:59 +02:00
METARECORD * rec ;
2009-07-02 12:56:29 +02:00
INT horz_res , vert_res , horz_size , vert_size ;
2011-05-18 06:24:01 +02:00
INT curve_caps , line_caps , poly_caps ;
2016-06-08 12:00:46 +02:00
METAFILEPICT mfp ;
2009-06-30 12:47:59 +02:00
display_dc = GetDC ( NULL ) ;
2009-07-07 12:32:41 +02:00
ok ( display_dc ! = NULL , " display_dc is NULL \n " ) ;
2009-06-30 12:47:59 +02:00
2009-07-02 12:56:29 +02:00
horz_res = GetDeviceCaps ( display_dc , HORZRES ) ;
vert_res = GetDeviceCaps ( display_dc , VERTRES ) ;
horz_size = GetDeviceCaps ( display_dc , HORZSIZE ) ;
vert_size = GetDeviceCaps ( display_dc , VERTSIZE ) ;
2009-07-07 12:32:41 +02:00
emf_dc = CreateEnhMetaFileA ( display_dc , NULL , rc , NULL ) ;
ok ( emf_dc ! = NULL , " emf_dc is NULL \n " ) ;
2011-05-18 06:24:01 +02:00
curve_caps = GetDeviceCaps ( emf_dc , CURVECAPS ) ;
ok ( curve_caps = = 511 , " expect 511 got %d \n " , curve_caps ) ;
line_caps = GetDeviceCaps ( emf_dc , LINECAPS ) ;
ok ( line_caps = = 254 , " expect 254 got %d \n " , line_caps ) ;
poly_caps = GetDeviceCaps ( emf_dc , POLYGONALCAPS ) ;
ok ( poly_caps = = 255 , " expect 511 got %d \n " , poly_caps ) ;
2009-06-30 12:47:59 +02:00
for ( i = 0 ; i < 3000 ; i + + ) /* This is enough to take emf_size > 0xffff */
Rectangle ( emf_dc , 0 , 0 , 1000 , 20 ) ;
emf = CloseEnhMetaFile ( emf_dc ) ;
2009-07-07 12:32:41 +02:00
ok ( emf ! = NULL , " emf is NULL \n " ) ;
2009-06-30 12:47:59 +02:00
emf_size = GetEnhMetaFileBits ( emf , 0 , NULL ) ;
enh_header = HeapAlloc ( GetProcessHeap ( ) , 0 , emf_size ) ;
emf_size = GetEnhMetaFileBits ( emf , emf_size , ( BYTE * ) enh_header ) ;
2009-07-02 12:56:29 +02:00
DeleteEnhMetaFile ( emf ) ;
/* multiply szlDevice.cx by scale, when scale != 1 the recording and playback dcs
have different resolutions */
enh_header - > szlDevice . cx * = scale ;
emf = SetEnhMetaFileBits ( emf_size , ( BYTE * ) enh_header ) ;
2009-07-07 12:32:41 +02:00
ok ( emf ! = NULL , " emf is NULL \n " ) ;
ok ( EqualRect ( ( RECT * ) & enh_header - > rclFrame , rc ) , " Frame rectangles differ \n " ) ;
2009-06-30 12:47:59 +02:00
size = GetWinMetaFileBits ( emf , 0 , NULL , mode , display_dc ) ;
2009-07-17 11:57:03 +02:00
ok ( size | |
broken ( size = = 0 ) , /* some versions of winxp fail for some reason */
" GetWinMetaFileBits returns 0 \n " ) ;
2009-07-08 16:20:25 +02:00
if ( ! size ) goto end ;
2009-06-30 12:47:59 +02:00
mh = HeapAlloc ( GetProcessHeap ( ) , 0 , size ) ;
GetWinMetaFileBits ( emf , size , ( BYTE * ) mh , mode , display_dc ) ;
for ( i = 0 ; i < size / 2 ; i + + ) check + = ( ( WORD * ) mh ) [ i ] ;
ok ( check = = 0 , " check %04x \n " , check ) ;
rec = ( METARECORD * ) ( mh + 1 ) ;
while ( rec - > rdSize & & rec - > rdFunction )
{
const DWORD chunk_size = 0x2000 ;
DWORD mfcomment_chunks = ( emf_size + chunk_size - 1 ) / chunk_size ;
if ( rec_num < mfcomment_chunks )
{
DWORD this_chunk_size = chunk_size ;
if ( rec_num = = mfcomment_chunks - 1 )
this_chunk_size = emf_size - rec_num * chunk_size ;
2009-07-01 13:14:40 +02:00
ok ( rec - > rdSize = = ( this_chunk_size + 44 ) / 2 , " %04x: got %04x expected %04x \n " , rec_num , rec - > rdSize , ( this_chunk_size + 44 ) / 2 ) ;
ok ( rec - > rdFunction = = META_ESCAPE , " %04x: got %04x \n " , rec_num , rec - > rdFunction ) ;
if ( rec - > rdSize < ( this_chunk_size + 44 ) / 2 ) break ;
2009-06-30 12:47:59 +02:00
ok ( rec - > rdParm [ 0 ] = = MFCOMMENT , " got %04x \n " , rec - > rdParm [ 0 ] ) ;
ok ( rec - > rdParm [ 1 ] = = this_chunk_size + 34 , " got %04x %x \n " , rec - > rdParm [ 1 ] , emf_size + 34 ) ;
ok ( rec - > rdParm [ 2 ] = = 0x4d57 , " got %04x \n " , rec - > rdParm [ 2 ] ) ; /* WMFC */
ok ( rec - > rdParm [ 3 ] = = 0x4346 , " got %04x \n " , rec - > rdParm [ 3 ] ) ; /* " */
ok ( rec - > rdParm [ 4 ] = = 1 , " got %04x \n " , rec - > rdParm [ 4 ] ) ;
ok ( rec - > rdParm [ 5 ] = = 0 , " got %04x \n " , rec - > rdParm [ 5 ] ) ;
ok ( rec - > rdParm [ 6 ] = = 0 , " got %04x \n " , rec - > rdParm [ 6 ] ) ;
ok ( rec - > rdParm [ 7 ] = = 1 , " got %04x \n " , rec - > rdParm [ 7 ] ) ;
/* parm[8] is the checksum, tested above */
if ( rec_num > 0 ) ok ( rec - > rdParm [ 8 ] = = 0 , " got %04x \n " , rec - > rdParm [ 8 ] ) ;
ok ( rec - > rdParm [ 9 ] = = 0 , " got %04x \n " , rec - > rdParm [ 9 ] ) ;
ok ( rec - > rdParm [ 10 ] = = 0 , " got %04x \n " , rec - > rdParm [ 10 ] ) ;
ok ( rec - > rdParm [ 11 ] = = mfcomment_chunks , " got %04x \n " , rec - > rdParm [ 11 ] ) ; /* num chunks */
ok ( rec - > rdParm [ 12 ] = = 0 , " got %04x \n " , rec - > rdParm [ 12 ] ) ;
ok ( rec - > rdParm [ 13 ] = = this_chunk_size , " got %04x expected %04x \n " , rec - > rdParm [ 13 ] , this_chunk_size ) ;
ok ( rec - > rdParm [ 14 ] = = 0 , " got %04x \n " , rec - > rdParm [ 14 ] ) ;
ok ( * ( DWORD * ) ( rec - > rdParm + 15 ) = = emf_size - this_chunk_size - rec_num * chunk_size , " got %08x \n " , * ( DWORD * ) ( rec - > rdParm + 15 ) ) ; /* DWORD size remaining after current chunk */
ok ( * ( DWORD * ) ( rec - > rdParm + 17 ) = = emf_size , " got %08x emf_size %08x \n " , * ( DWORD * ) ( rec - > rdParm + 17 ) , emf_size ) ;
ok ( ! memcmp ( rec - > rdParm + 19 , ( char * ) enh_header + rec_num * chunk_size , this_chunk_size ) , " bits mismatch \n " ) ;
}
2009-07-02 12:56:29 +02:00
else if ( rec_num = = mfcomment_chunks )
{
ok ( rec - > rdFunction = = META_SETMAPMODE , " got %04x \n " , rec - > rdFunction ) ;
ok ( rec - > rdParm [ 0 ] = = mode , " got %04x \n " , rec - > rdParm [ 0 ] ) ;
}
else if ( rec_num = = mfcomment_chunks + 1 )
{
POINT pt ;
ok ( rec - > rdFunction = = META_SETWINDOWORG , " got %04x \n " , rec - > rdFunction ) ;
switch ( mode )
{
case MM_TEXT :
case MM_ISOTROPIC :
case MM_ANISOTROPIC :
2009-07-10 15:47:50 +02:00
pt . y = MulDiv ( rc - > top , vert_res , vert_size * 100 ) + 1 ;
pt . x = MulDiv ( rc - > left , horz_res , horz_size * 100 ) ;
2009-07-02 12:56:29 +02:00
break ;
case MM_LOMETRIC :
2009-07-10 15:47:50 +02:00
pt . y = MulDiv ( - rc - > top , 1 , 10 ) + 1 ;
pt . x = MulDiv ( rc - > left , 1 , 10 ) ;
2009-07-02 12:56:29 +02:00
break ;
case MM_HIMETRIC :
2009-07-07 12:32:41 +02:00
pt . y = - rc - > top + 1 ;
pt . x = ( rc - > left > = 0 ) ? rc - > left : rc - > left + 1 ; /* strange but true */
2009-07-02 12:56:29 +02:00
break ;
case MM_LOENGLISH :
2009-07-10 15:47:50 +02:00
pt . y = MulDiv ( - rc - > top , 10 , 254 ) + 1 ;
pt . x = MulDiv ( rc - > left , 10 , 254 ) ;
2009-07-02 12:56:29 +02:00
break ;
case MM_HIENGLISH :
2009-07-10 15:47:50 +02:00
pt . y = MulDiv ( - rc - > top , 100 , 254 ) + 1 ;
pt . x = MulDiv ( rc - > left , 100 , 254 ) ;
2009-07-02 12:56:29 +02:00
break ;
case MM_TWIPS :
2009-07-10 15:47:50 +02:00
pt . y = MulDiv ( - rc - > top , 72 * 20 , 2540 ) + 1 ;
pt . x = MulDiv ( rc - > left , 72 * 20 , 2540 ) ;
2009-07-02 12:56:29 +02:00
break ;
default :
pt . x = pt . y = 0 ;
}
2009-07-10 15:47:50 +02:00
ok ( near_match ( ( short ) rec - > rdParm [ 0 ] , pt . y ) , " got %d expect %d \n " , ( short ) rec - > rdParm [ 0 ] , pt . y ) ;
ok ( near_match ( ( short ) rec - > rdParm [ 1 ] , pt . x ) , " got %d expect %d \n " , ( short ) rec - > rdParm [ 1 ] , pt . x ) ;
2009-07-02 12:56:29 +02:00
}
if ( rec_num = = mfcomment_chunks + 2 )
{
ok ( rec - > rdFunction = = META_SETWINDOWEXT , " got %04x \n " , rec - > rdFunction ) ;
2009-07-10 15:47:50 +02:00
ok ( near_match ( ( short ) rec - > rdParm [ 0 ] , MulDiv ( rc - > bottom - rc - > top , vert_res , vert_size * 100 ) ) ,
" got %d \n " , ( short ) rec - > rdParm [ 0 ] ) ;
ok ( near_match ( ( short ) rec - > rdParm [ 1 ] , MulDiv ( rc - > right - rc - > left , horz_res , horz_size * 100 ) ) ,
" got %d \n " , ( short ) rec - > rdParm [ 1 ] ) ;
2009-07-02 12:56:29 +02:00
}
2009-06-30 12:47:59 +02:00
rec_num + + ;
rec = ( METARECORD * ) ( ( WORD * ) rec + rec - > rdSize ) ;
}
2016-06-08 12:00:46 +02:00
/* Show that we get the original back when we do the reverse conversion.
mfp is ignored in this case . */
mfp . mm = MM_ISOTROPIC ;
mfp . xExt = 0xcafe ;
mfp . yExt = 0xbeef ;
emf2 = SetWinMetaFileBits ( size , ( BYTE * ) mh , NULL , & mfp ) ;
ok ( ! ! emf2 , " got NULL \n " ) ;
emf2_size = GetEnhMetaFileBits ( emf2 , 0 , NULL ) ;
enh2_header = HeapAlloc ( GetProcessHeap ( ) , 0 , emf2_size ) ;
emf2_size = GetEnhMetaFileBits ( emf2 , emf2_size , ( BYTE * ) enh2_header ) ;
ok ( emf_size = = emf2_size , " %d %d \n " , emf_size , emf2_size ) ;
ok ( ! memcmp ( enh_header , enh2_header , emf_size ) , " mismatch \n " ) ;
HeapFree ( GetProcessHeap ( ) , 0 , enh2_header ) ;
DeleteEnhMetaFile ( emf2 ) ;
2009-07-08 16:20:25 +02:00
end :
2009-06-30 12:47:59 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , mh ) ;
HeapFree ( GetProcessHeap ( ) , 0 , enh_header ) ;
DeleteEnhMetaFile ( emf ) ;
ReleaseDC ( NULL , display_dc ) ;
}
2009-07-02 12:56:29 +02:00
static void test_GetWinMetaFileBits ( void )
{
UINT mode ;
2009-07-07 12:32:41 +02:00
RECT frames [ ] =
{
{ 1000 , 2000 , 3000 , 6000 } ,
{ - 1000 , 2000 , 3000 , 6000 } ,
{ 1000 , - 2000 , 3000 , 6000 } ,
{ 1005 , 2005 , 3000 , 6000 } ,
{ - 1005 , - 2005 , 3000 , 6000 } ,
{ - 1005 , - 2010 , 3000 , 6000 } ,
{ - 1005 , 2010 , 3000 , 6000 } ,
{ 0 , 0 , 1 , 1 } ,
{ - 1 , - 1 , 1 , 1 } ,
{ 0 , 0 , 0 , 0 }
} ;
2009-07-02 12:56:29 +02:00
for ( mode = MM_MIN ; mode < = MM_MAX ; mode + + )
{
2009-07-07 12:32:41 +02:00
RECT * rc ;
for ( rc = frames ; rc - > right - rc - > left > 0 ; rc + + )
{
getwinmetafilebits ( mode , 1 , rc ) ;
getwinmetafilebits ( mode , 2 , rc ) ;
}
2009-07-02 12:56:29 +02:00
}
}
2005-04-15 16:11:00 +02:00
static BOOL ( WINAPI * pGdiIsMetaPrintDC ) ( HDC ) ;
static BOOL ( WINAPI * pGdiIsMetaFileDC ) ( HDC ) ;
static BOOL ( WINAPI * pGdiIsPlayMetafileDC ) ( HDC ) ;
static void test_gdiis ( void )
{
RECT rect = { 0 , 0 , 100 , 100 } ;
HDC hdc , hemfDC , hmfDC ;
HENHMETAFILE hemf ;
HMODULE hgdi32 ;
/* resolve all the functions */
2013-10-16 07:31:44 +02:00
hgdi32 = GetModuleHandleA ( " gdi32.dll " ) ;
2005-04-15 16:11:00 +02:00
pGdiIsMetaPrintDC = ( void * ) GetProcAddress ( hgdi32 , " GdiIsMetaPrintDC " ) ;
pGdiIsMetaFileDC = ( void * ) GetProcAddress ( hgdi32 , " GdiIsMetaFileDC " ) ;
pGdiIsPlayMetafileDC = ( void * ) GetProcAddress ( hgdi32 , " GdiIsPlayMetafileDC " ) ;
2008-11-06 13:46:52 +01:00
if ( ! pGdiIsMetaPrintDC | | ! pGdiIsMetaFileDC | | ! pGdiIsPlayMetafileDC )
{
win_skip ( " Needed GdiIs* functions are not available \n " ) ;
2005-04-15 16:11:00 +02:00
return ;
2008-11-06 13:46:52 +01:00
}
2005-04-15 16:11:00 +02:00
/* try with nothing */
ok ( ! pGdiIsMetaPrintDC ( NULL ) , " ismetaprint with NULL parameter \n " ) ;
ok ( ! pGdiIsMetaFileDC ( NULL ) , " ismetafile with NULL parameter \n " ) ;
ok ( ! pGdiIsPlayMetafileDC ( NULL ) , " isplaymetafile with NULL parameter \n " ) ;
/* try with a metafile */
2013-10-16 07:31:44 +02:00
hmfDC = CreateMetaFileA ( NULL ) ;
2005-04-15 16:11:00 +02:00
ok ( ! pGdiIsMetaPrintDC ( hmfDC ) , " ismetaprint on metafile \n " ) ;
ok ( pGdiIsMetaFileDC ( hmfDC ) , " ismetafile on metafile \n " ) ;
ok ( ! pGdiIsPlayMetafileDC ( hmfDC ) , " isplaymetafile on metafile \n " ) ;
2007-05-28 09:21:58 +02:00
DeleteMetaFile ( CloseMetaFile ( hmfDC ) ) ;
2005-04-15 16:11:00 +02:00
/* try with an enhanced metafile */
hdc = GetDC ( NULL ) ;
hemfDC = CreateEnhMetaFileW ( hdc , NULL , & rect , NULL ) ;
ok ( hemfDC ! = NULL , " failed to create emf \n " ) ;
ok ( ! pGdiIsMetaPrintDC ( hemfDC ) , " ismetaprint on emf \n " ) ;
ok ( pGdiIsMetaFileDC ( hemfDC ) , " ismetafile on emf \n " ) ;
ok ( ! pGdiIsPlayMetafileDC ( hemfDC ) , " isplaymetafile on emf \n " ) ;
hemf = CloseEnhMetaFile ( hemfDC ) ;
ok ( hemf ! = NULL , " failed to close EMF \n " ) ;
2007-05-28 09:21:58 +02:00
DeleteEnhMetaFile ( hemf ) ;
2005-04-15 16:11:00 +02:00
ReleaseDC ( NULL , hdc ) ;
}
2007-05-28 09:21:58 +02:00
static void test_SetEnhMetaFileBits ( void )
{
BYTE data [ 256 ] ;
HENHMETAFILE hemf ;
ENHMETAHEADER * emh ;
memset ( data , 0xAA , sizeof ( data ) ) ;
SetLastError ( 0xdeadbeef ) ;
hemf = SetEnhMetaFileBits ( sizeof ( data ) , data ) ;
ok ( ! hemf , " SetEnhMetaFileBits should fail \n " ) ;
2008-11-13 14:41:34 +01:00
ok ( GetLastError ( ) = = ERROR_INVALID_DATA | |
GetLastError ( ) = = ERROR_INVALID_PARAMETER , /* Win9x, WinMe */
" expected ERROR_INVALID_DATA or ERROR_INVALID_PARAMETER, got %u \n " , GetLastError ( ) ) ;
2007-05-28 09:21:58 +02:00
emh = ( ENHMETAHEADER * ) data ;
memset ( emh , 0 , sizeof ( * emh ) ) ;
emh - > iType = EMR_HEADER ;
emh - > nSize = sizeof ( * emh ) ;
emh - > dSignature = ENHMETA_SIGNATURE ;
/* emh->nVersion = 0x10000; XP doesn't care about version */
emh - > nBytes = sizeof ( * emh ) ;
/* emh->nRecords = 1; XP doesn't care about records */
emh - > nHandles = 1 ; /* XP refuses to load a EMF if nHandles == 0 */
SetLastError ( 0xdeadbeef ) ;
hemf = SetEnhMetaFileBits ( emh - > nBytes , data ) ;
ok ( hemf ! = 0 , " SetEnhMetaFileBits error %u \n " , GetLastError ( ) ) ;
DeleteEnhMetaFile ( hemf ) ;
/* XP refuses to load unaligned EMF */
emh - > nBytes + + ;
SetLastError ( 0xdeadbeef ) ;
hemf = SetEnhMetaFileBits ( emh - > nBytes , data ) ;
2008-11-13 14:41:34 +01:00
ok ( ! hemf | |
broken ( hemf ! = NULL ) , /* Win9x, WinMe */
" SetEnhMetaFileBits should fail \n " ) ;
ok ( GetLastError ( ) = = 0xdeadbeef , " Expected deadbeef, got %u \n " , GetLastError ( ) ) ;
DeleteEnhMetaFile ( hemf ) ;
2007-05-28 09:21:58 +02:00
emh - > dSignature = 0 ;
emh - > nBytes - - ;
SetLastError ( 0xdeadbeef ) ;
hemf = SetEnhMetaFileBits ( emh - > nBytes , data ) ;
2008-11-13 14:41:34 +01:00
ok ( ! hemf | |
broken ( hemf ! = NULL ) , /* Win9x, WinMe */
" SetEnhMetaFileBits should fail \n " ) ;
ok ( GetLastError ( ) = = 0xdeadbeef , " Expected deadbeef, got %u \n " , GetLastError ( ) ) ;
DeleteEnhMetaFile ( hemf ) ;
2007-05-28 09:21:58 +02:00
}
2012-01-17 04:38:15 +01:00
static void test_emf_polybezier ( void )
{
HDC hdcMetafile ;
HENHMETAFILE hemf ;
POINT pts [ 4 ] ;
BOOL ret ;
SetLastError ( 0xdeadbeef ) ;
hdcMetafile = CreateEnhMetaFileA ( GetDC ( 0 ) , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
pts [ 0 ] . x = pts [ 0 ] . y = 10 ;
pts [ 1 ] . x = pts [ 1 ] . y = 20 ;
pts [ 2 ] . x = pts [ 2 ] . y = 15 ;
pts [ 3 ] . x = pts [ 3 ] . y = 25 ;
ret = PolyBezierTo ( hdcMetafile , pts , 3 ) ; /* EMR_POLYBEZIERTO16 */
ok ( ret , " PolyBezierTo failed \n " ) ;
ret = PolyBezier ( hdcMetafile , pts , 4 ) ; /* EMR_POLYBEZIER16 */
ok ( ret , " PolyBezier failed \n " ) ;
pts [ 0 ] . x = pts [ 0 ] . y = 32769 ;
ret = PolyBezier ( hdcMetafile , pts , 4 ) ; /* EMR_POLYBEZIER */
ok ( ret , " PolyBezier failed \n " ) ;
ret = PolyBezierTo ( hdcMetafile , pts , 3 ) ; /* EMR_POLYBEZIERTO */
ok ( ret , " PolyBezierTo failed \n " ) ;
hemf = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hemf ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_emf_bits ( hemf , EMF_BEZIER_BITS , sizeof ( EMF_BEZIER_BITS ) ,
" emf_Bezier " , FALSE ) ! = 0 )
{
dump_emf_bits ( hemf , " emf_Bezier " ) ;
dump_emf_records ( hemf , " emf_Bezier " ) ;
}
DeleteEnhMetaFile ( hemf ) ;
}
2016-02-18 07:54:09 +01:00
static const unsigned char EMF_PATH_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
2016-06-21 08:16:04 +02:00
0x0a , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x96 , 0x00 , 0x00 , 0x00 , 0x96 , 0x00 , 0x00 , 0x00 ,
0x90 , 0x01 , 0x00 , 0x00 , 0x90 , 0x01 , 0x00 , 0x00 ,
0x70 , 0x17 , 0x00 , 0x00 , 0x70 , 0x17 , 0x00 , 0x00 ,
2016-02-18 07:54:09 +01:00
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
2016-06-21 08:16:04 +02:00
0xf8 , 0x02 , 0x00 , 0x00 , 0x17 , 0x00 , 0x00 , 0x00 ,
2016-02-18 07:54:09 +01:00
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2016-06-17 06:51:05 +02:00
0x20 , 0x03 , 0x00 , 0x00 , 0x58 , 0x02 , 0x00 , 0x00 ,
2016-04-28 18:48:18 +02:00
0x40 , 0x01 , 0x00 , 0x00 , 0xf0 , 0x00 , 0x00 , 0x00 ,
2016-02-18 07:54:09 +01:00
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2016-04-28 18:48:18 +02:00
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xe2 , 0x04 , 0x00 ,
0x80 , 0xa9 , 0x03 , 0x00 , 0x3b , 0x00 , 0x00 , 0x00 ,
2016-02-18 07:54:09 +01:00
0x08 , 0x00 , 0x00 , 0x00 , 0x1b , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x32 , 0x00 , 0x00 , 0x00 ,
0x32 , 0x00 , 0x00 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x32 , 0x00 , 0x00 , 0x00 ,
0x96 , 0x00 , 0x00 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x96 , 0x00 , 0x00 , 0x00 ,
0x96 , 0x00 , 0x00 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x96 , 0x00 , 0x00 , 0x00 ,
0x32 , 0x00 , 0x00 , 0x00 , 0x36 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x32 , 0x00 , 0x00 , 0x00 ,
0x32 , 0x00 , 0x00 , 0x00 , 0x2b , 0x00 , 0x00 , 0x00 ,
0x18 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x13 , 0x00 , 0x00 , 0x00 ,
2016-04-28 18:48:18 +02:00
0x13 , 0x00 , 0x00 , 0x00 , 0x2d , 0x00 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x15 , 0x00 , 0x00 , 0x00 ,
0x15 , 0x00 , 0x00 , 0x00 , 0x26 , 0x00 , 0x00 , 0x00 ,
0x1c , 0x00 , 0x00 , 0x00 , 0x27 , 0x00 , 0x00 , 0x00 ,
0x1d , 0x00 , 0x00 , 0x00 , 0x15 , 0x00 , 0x00 , 0x00 ,
2016-06-17 06:51:05 +02:00
0x15 , 0x00 , 0x00 , 0x00 , 0x37 , 0x00 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x17 , 0x00 , 0x00 , 0x00 ,
0x17 , 0x00 , 0x00 , 0x00 , 0x24 , 0x00 , 0x00 , 0x00 ,
0x1a , 0x00 , 0x00 , 0x00 , 0x25 , 0x00 , 0x00 , 0x00 ,
0x1b , 0x00 , 0x00 , 0x00 , 0x17 , 0x00 , 0x00 , 0x00 ,
0x17 , 0x00 , 0x00 , 0x00 , 0x2e , 0x00 , 0x00 , 0x00 ,
2016-04-28 18:48:18 +02:00
0x28 , 0x00 , 0x00 , 0x00 , 0x15 , 0x00 , 0x00 , 0x00 ,
0x15 , 0x00 , 0x00 , 0x00 , 0x26 , 0x00 , 0x00 , 0x00 ,
0x1c , 0x00 , 0x00 , 0x00 , 0x27 , 0x00 , 0x00 , 0x00 ,
0x1d , 0x00 , 0x00 , 0x00 , 0x15 , 0x00 , 0x00 , 0x00 ,
0x15 , 0x00 , 0x00 , 0x00 , 0x2f , 0x00 , 0x00 , 0x00 ,
0x28 , 0x00 , 0x00 , 0x00 , 0x15 , 0x00 , 0x00 , 0x00 ,
0x15 , 0x00 , 0x00 , 0x00 , 0x26 , 0x00 , 0x00 , 0x00 ,
0x1c , 0x00 , 0x00 , 0x00 , 0x27 , 0x00 , 0x00 , 0x00 ,
0x1d , 0x00 , 0x00 , 0x00 , 0x15 , 0x00 , 0x00 , 0x00 ,
2016-04-28 18:48:32 +02:00
0x15 , 0x00 , 0x00 , 0x00 , 0x2a , 0x00 , 0x00 , 0x00 ,
0x18 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x13 , 0x00 , 0x00 , 0x00 ,
2016-04-28 18:48:46 +02:00
0x13 , 0x00 , 0x00 , 0x00 , 0x2c , 0x00 , 0x00 , 0x00 ,
0x20 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x13 , 0x00 , 0x00 , 0x00 ,
0x13 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ,
2016-04-28 18:48:58 +02:00
0x05 , 0x00 , 0x00 , 0x00 , 0x57 , 0x00 , 0x00 , 0x00 ,
0x2c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x04 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x0a , 0x00 , 0x14 , 0x00 , 0x0a , 0x00 ,
0x0a , 0x00 , 0x14 , 0x00 , 0x14 , 0x00 , 0x14 , 0x00 ,
2016-06-17 07:00:17 +02:00
0x59 , 0x00 , 0x00 , 0x00 , 0x2c , 0x00 , 0x00 , 0x00 ,
2016-04-28 18:49:07 +02:00
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
2016-06-17 07:00:17 +02:00
0x04 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x0a , 0x00 ,
0x14 , 0x00 , 0x0a , 0x00 , 0x0a , 0x00 , 0x14 , 0x00 ,
0x14 , 0x00 , 0x14 , 0x00 , 0x5a , 0x00 , 0x00 , 0x00 ,
0x38 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x02 , 0x00 , 0x00 , 0x00 ,
0x04 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 ,
0x02 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x0a , 0x00 ,
0x14 , 0x00 , 0x0a , 0x00 , 0x0a , 0x00 , 0x14 , 0x00 ,
2016-06-17 08:08:57 +02:00
0x14 , 0x00 , 0x14 , 0x00 , 0x5c , 0x00 , 0x00 , 0x00 ,
0x4c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x09 , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x0a , 0x00 , 0x14 , 0x00 , 0x0a , 0x00 ,
0x0a , 0x00 , 0x14 , 0x00 , 0x14 , 0x00 , 0x14 , 0x00 ,
0x1e , 0x00 , 0x1e , 0x00 , 0x28 , 0x00 , 0x14 , 0x00 ,
0x14 , 0x00 , 0x1e , 0x00 , 0x14 , 0x00 , 0x14 , 0x00 ,
0x14 , 0x00 , 0x0a , 0x00 , 0x06 , 0x02 , 0x04 , 0x04 ,
0x04 , 0x02 , 0x03 , 0x06 , 0x02 , 0x00 , 0x00 , 0x00 ,
2016-06-17 09:24:54 +02:00
0x29 , 0x00 , 0x00 , 0x00 , 0x1c , 0x00 , 0x00 , 0x00 ,
0x25 , 0x00 , 0x00 , 0x00 , 0x24 , 0x00 , 0x00 , 0x00 ,
0x17 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xb4 , 0x42 ,
0x00 , 0x00 , 0x34 , 0x43 , 0x3c , 0x00 , 0x00 , 0x00 ,
2016-06-21 08:16:04 +02:00
0x08 , 0x00 , 0x00 , 0x00 , 0x3f , 0x00 , 0x00 , 0x00 ,
0x18 , 0x00 , 0x00 , 0x00 , 0x0a , 0x00 , 0x00 , 0x00 ,
0x0a , 0x00 , 0x00 , 0x00 , 0x96 , 0x00 , 0x00 , 0x00 ,
0x96 , 0x00 , 0x00 , 0x00 , 0x3f , 0x00 , 0x00 , 0x00 ,
0x18 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0x0e , 0x00 , 0x00 , 0x00 ,
2016-06-17 09:24:54 +02:00
0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00
2016-02-18 07:54:09 +01:00
} ;
2016-06-21 07:38:19 +02:00
static const unsigned char EMF_EMPTY_PATH_BITS [ ] =
{
0x01 , 0x00 , 0x00 , 0x00 , 0x6c , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0xd8 , 0xff , 0xff , 0xff , 0xd8 , 0xff , 0xff , 0xff ,
0x20 , 0x45 , 0x4d , 0x46 , 0x00 , 0x00 , 0x01 , 0x00 ,
0xc8 , 0x00 , 0x00 , 0x00 , 0x0b , 0x00 , 0x00 , 0x00 ,
0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x20 , 0x03 , 0x00 , 0x00 , 0x58 , 0x02 , 0x00 , 0x00 ,
0x40 , 0x01 , 0x00 , 0x00 , 0xf0 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xe2 , 0x04 , 0x00 ,
0x80 , 0xa9 , 0x03 , 0x00 , 0x3b , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x3d , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x3b , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x3c , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x3c , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x3d , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x3b , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x44 , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x44 , 0x00 , 0x00 , 0x00 ,
0x08 , 0x00 , 0x00 , 0x00 , 0x0e , 0x00 , 0x00 , 0x00 ,
0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x10 , 0x00 , 0x00 , 0x00 , 0x14 , 0x00 , 0x00 , 0x00
} ;
static void test_emf_paths ( void )
2015-09-01 06:00:56 +02:00
{
2016-06-17 08:08:57 +02:00
POINT pts [ 9 ] = { { 10 , 10 } , { 20 , 10 } , { 10 , 20 } , { 20 , 20 } , { 30 , 30 } , { 40 , 20 } , { 20 , 30 } , { 20 , 20 } , { 20 , 10 } } ;
2016-04-28 18:49:07 +02:00
DWORD counts [ 2 ] = { 2 , 2 } ;
2016-06-17 08:08:57 +02:00
BYTE types [ 9 ] = { PT_MOVETO , PT_LINETO , PT_BEZIERTO , PT_BEZIERTO , PT_BEZIERTO , PT_LINETO ,
PT_LINETO | PT_CLOSEFIGURE , PT_MOVETO , PT_LINETO } ;
2015-09-01 06:00:56 +02:00
HDC hdcMetafile ;
HENHMETAFILE hemf ;
BOOL ret ;
int size ;
SetLastError ( 0xdeadbeef ) ;
hdcMetafile = CreateEnhMetaFileA ( GetDC ( 0 ) , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
2018-11-29 10:28:26 +01:00
ret = BeginPath ( hdcMetafile ) ;
ok ( ret , " BeginPath error %d \n " , GetLastError ( ) ) ;
2015-09-01 06:00:56 +02:00
ret = MoveToEx ( hdcMetafile , 50 , 50 , NULL ) ;
ok ( ret , " MoveToEx error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdcMetafile , 50 , 150 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdcMetafile , 150 , 150 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdcMetafile , 150 , 50 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
ret = LineTo ( hdcMetafile , 50 , 50 ) ;
ok ( ret , " LineTo error %d. \n " , GetLastError ( ) ) ;
2016-02-18 07:54:09 +01:00
Rectangle ( hdcMetafile , 10 , 10 , 20 , 20 ) ;
2016-04-28 18:48:18 +02:00
Arc ( hdcMetafile , 21 , 21 , 39 , 29 , 39 , 29 , 21 , 21 ) ;
2016-06-17 06:51:05 +02:00
ArcTo ( hdcMetafile , 23 , 23 , 37 , 27 , 37 , 27 , 23 , 23 ) ;
2016-04-28 18:48:18 +02:00
Chord ( hdcMetafile , 21 , 21 , 39 , 29 , 39 , 29 , 21 , 21 ) ;
Pie ( hdcMetafile , 21 , 21 , 39 , 29 , 39 , 29 , 21 , 21 ) ;
2016-04-28 18:48:32 +02:00
Ellipse ( hdcMetafile , 10 , 10 , 20 , 20 ) ;
2016-04-28 18:48:46 +02:00
RoundRect ( hdcMetafile , 10 , 10 , 20 , 20 , 3 , 5 ) ;
2016-04-28 18:48:58 +02:00
Polyline ( hdcMetafile , pts , 4 ) ;
2016-06-17 07:00:17 +02:00
PolylineTo ( hdcMetafile , pts , 4 ) ;
2016-04-28 18:49:07 +02:00
PolyPolyline ( hdcMetafile , pts , counts , 2 ) ;
2016-06-17 08:08:57 +02:00
PolyDraw ( hdcMetafile , pts , types , 9 ) ;
2016-06-17 09:24:54 +02:00
AngleArc ( hdcMetafile , 37 , 36 , 23 , 90 , 180 ) ;
2015-09-01 06:00:56 +02:00
EndPath ( hdcMetafile ) ;
size = GetPath ( hdcMetafile , NULL , NULL , 0 ) ;
2016-06-24 07:05:21 +02:00
ok ( size = = 112 , " GetPath returned %d. \n " , size ) ;
2015-09-01 06:00:56 +02:00
2016-06-21 08:16:04 +02:00
ret = StrokeAndFillPath ( hdcMetafile ) ;
ok ( ret , " StrokeAndFillPath failed err %d \n " , GetLastError ( ) ) ;
ret = StrokeAndFillPath ( hdcMetafile ) ;
ok ( ! ret , " StrokeAndFillPath succeeded \n " ) ;
2015-09-01 06:00:56 +02:00
hemf = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hemf ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
2016-06-21 07:38:19 +02:00
if ( compare_emf_bits ( hemf , EMF_PATH_BITS , sizeof ( EMF_PATH_BITS ) , " test_emf_paths " , FALSE ) ! = 0 )
{
dump_emf_bits ( hemf , " test_emf_paths " ) ;
dump_emf_records ( hemf , " test_emf_paths " ) ;
}
DeleteEnhMetaFile ( hemf ) ;
SetLastError ( 0xdeadbeef ) ;
hdcMetafile = CreateEnhMetaFileA ( GetDC ( 0 ) , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
ret = BeginPath ( hdcMetafile ) ;
ok ( ret , " BeginPath failed error %d \n " , GetLastError ( ) ) ;
ret = CloseFigure ( hdcMetafile ) ;
ok ( ret , " CloseFigure failed error %d \n " , GetLastError ( ) ) ;
ret = BeginPath ( hdcMetafile ) ;
ok ( ret , " BeginPath failed error %d \n " , GetLastError ( ) ) ;
ret = EndPath ( hdcMetafile ) ;
ok ( ret , " EndPath failed error %d \n " , GetLastError ( ) ) ;
ret = EndPath ( hdcMetafile ) ;
ok ( ! ret , " EndPath succeeded \n " ) ;
ret = CloseFigure ( hdcMetafile ) ;
ok ( ! ret , " CloseFigure succeeded \n " ) ;
ret = BeginPath ( hdcMetafile ) ;
ok ( ret , " BeginPath failed error %d \n " , GetLastError ( ) ) ;
ret = AbortPath ( hdcMetafile ) ;
ok ( ret , " AbortPath failed error %d \n " , GetLastError ( ) ) ;
ret = AbortPath ( hdcMetafile ) ;
ok ( ret , " AbortPath failed error %d \n " , GetLastError ( ) ) ;
hemf = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hemf ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_emf_bits ( hemf , EMF_EMPTY_PATH_BITS , sizeof ( EMF_EMPTY_PATH_BITS ) , " empty path " , FALSE ) ! = 0 )
2016-02-18 07:54:09 +01:00
{
2016-06-21 07:38:19 +02:00
dump_emf_bits ( hemf , " empty path " ) ;
dump_emf_records ( hemf , " empty path " ) ;
2016-02-18 07:54:09 +01:00
}
2015-09-01 06:00:56 +02:00
DeleteEnhMetaFile ( hemf ) ;
}
2016-03-09 12:17:05 +01:00
static void test_emf_PolyPolyline ( void )
{
HDC hdcMetafile ;
HENHMETAFILE hemf ;
POINT pts [ 4 ] = { { 10 , 20 } , { 100 , 200 } , { 0x9000 , 300 } , { 400 , 500 } } ;
DWORD counts [ 2 ] ;
BOOL ret ;
SetLastError ( 0xdeadbeef ) ;
hdcMetafile = CreateEnhMetaFileA ( GetDC ( 0 ) , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
ret = PolyPolyline ( hdcMetafile , NULL , NULL , 0 ) ;
ok ( ! ret , " PolyPolyline \n " ) ;
SetLastError ( 0xdeadbeef ) ;
counts [ 0 ] = 0 ;
counts [ 1 ] = 1 ;
ret = PolyPolyline ( hdcMetafile , pts , counts , 2 ) ;
ok ( ! ret , " PolyPolyline \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " gle %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
counts [ 0 ] = 1 ;
counts [ 1 ] = 1 ;
ret = PolyPolyline ( hdcMetafile , pts , counts , 2 ) ;
ok ( ! ret , " PolyPolyline \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " gle %d \n " , GetLastError ( ) ) ;
SetLastError ( 0xdeadbeef ) ;
counts [ 0 ] = 2 ;
counts [ 1 ] = 1 ;
ret = PolyPolyline ( hdcMetafile , pts , counts , 2 ) ;
ok ( ! ret , " PolyPolyline \n " ) ;
ok ( GetLastError ( ) = = ERROR_INVALID_PARAMETER , " gle %d \n " , GetLastError ( ) ) ;
counts [ 0 ] = 2 ;
counts [ 1 ] = 2 ;
ret = PolyPolyline ( hdcMetafile , pts , counts , 2 ) ;
ok ( ret , " PolyPolyline \n " ) ;
hemf = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hemf ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_emf_bits ( hemf , EMF_POLYPOLYLINE_BITS , sizeof ( EMF_POLYPOLYLINE_BITS ) ,
" emf_PolyPolyline " , FALSE ) ! = 0 )
{
dump_emf_bits ( hemf , " emf_PolyPolyline " ) ;
dump_emf_records ( hemf , " emf_PolyPolyline " ) ;
}
DeleteEnhMetaFile ( hemf ) ;
}
2016-04-08 12:40:56 +02:00
static void test_emf_GradientFill ( void )
{
HDC mf ;
HENHMETAFILE hemf ;
TRIVERTEX v [ ] =
{
{ 1 , 10 , 0xff00 , 0x8000 , 0x0000 , 0x8001 } ,
{ 200 , 210 , 0x0000 , 0x0000 , 0xff00 , 0xff00 } ,
{ 180 , 190 , 0x1234 , 0x5678 , 0x9abc , 0xdef0 } ,
{ 300 , 310 , 0xff00 , 0xff00 , 0xff00 , 0x0000 } ,
{ 400 , 410 , 0xff00 , 0xff00 , 0xff00 , 0x0000 }
} ;
GRADIENT_TRIANGLE tri [ ] = { { 0 , 1 , 2 } , { 3 , 1 , 0 } } ;
BOOL ret ;
mf = CreateEnhMetaFileA ( GetDC ( 0 ) , NULL , NULL , NULL ) ;
ok ( mf ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
/* Don't test the GRADIENT_FILL_RECT_ modes since a Windows bug
2016-04-19 06:12:52 +02:00
* means it allocates three mesh indices rather than two per
2016-04-08 12:40:56 +02:00
* rectangle . This results in uninitialised values being written
* to the EMF which is rather difficult to test against .
*
* Note also that the final vertex here is not required , yet it is
* written to the EMF , but is not considered in the bounds
* calculation .
*/
2018-06-25 21:46:41 +02:00
ret = GdiGradientFill ( mf , v , ARRAY_SIZE ( v ) , tri , ARRAY_SIZE ( tri ) , GRADIENT_FILL_TRIANGLE ) ;
2016-04-08 12:40:56 +02:00
ok ( ret , " GradientFill \n " ) ;
hemf = CloseEnhMetaFile ( mf ) ;
ok ( hemf ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
if ( compare_emf_bits ( hemf , EMF_GRADIENTFILL_BITS , sizeof ( EMF_GRADIENTFILL_BITS ) ,
" emf_GradientFill " , FALSE ) ! = 0 )
{
dump_emf_bits ( hemf , " emf_GradientFill " ) ;
dump_emf_records ( hemf , " emf_GradientFill " ) ;
}
DeleteEnhMetaFile ( hemf ) ;
}
2017-08-25 15:10:44 +02:00
static void set_rotation_xform ( XFORM * out , float rad , int dx , int dy )
{
out - > eM11 = cosf ( rad ) ;
out - > eM12 = - 1.f * sinf ( rad ) ;
out - > eM21 = sinf ( rad ) ;
out - > eM22 = cosf ( rad ) ;
out - > eDx = dx ;
out - > eDy = dy ;
}
struct emf_WorldTransform_test_data
{
const char * name ;
BOOL do_modify ;
BOOL do_playback ;
XFORM expected ;
XFORM scale ;
XFORM stored ; /* this is the "hidden" world transform used in PlayEnhMetaFileRecord */
} ;
static BOOL xform_eq ( const XFORM * a , const XFORM * b )
{
return fabs ( a - > eM11 - b - > eM11 ) < 0.001f & &
fabs ( a - > eM12 - b - > eM12 ) < 0.001f & &
fabs ( a - > eM21 - b - > eM21 ) < 0.001f & &
fabs ( a - > eM22 - b - > eM22 ) < 0.001f & &
fabs ( a - > eDx - b - > eDx ) < 0.001f & &
fabs ( a - > eDy - b - > eDy ) < 0.001f ;
}
static INT CALLBACK enum_emf_WorldTransform ( HDC hdc , HANDLETABLE * ht ,
const ENHMETARECORD * emr , INT nobj , LPARAM param )
{
XFORM xform = { 0 } ;
struct emf_WorldTransform_test_data * test_data = ( struct emf_WorldTransform_test_data * ) param ;
BOOL ret ;
switch ( emr - > iType )
{
case EMR_SETWORLDTRANSFORM :
{
const EMRSETWORLDTRANSFORM * lpXfrm = ( const EMRSETWORLDTRANSFORM * ) emr ;
/* get scale factors with an identity world transform */
GetWorldTransform ( hdc , & test_data - > scale ) ;
/* play back record */
ret = PlayEnhMetaFileRecord ( hdc , ht , emr , nobj ) ;
ok ( ret = = TRUE , " %s: PlayEnhMetaFileRecord failed \n " , test_data - > name ) ;
test_data - > stored = lpXfrm - > xform ;
CombineTransform ( & test_data - > expected , & test_data - > stored , & test_data - > scale ) ;
/* verify it is updated immediately */
ret = GetWorldTransform ( hdc , & xform ) ;
ok ( ret = = TRUE , " %s: GetWorldTransform failed \n " , test_data - > name ) ;
ok ( xform_eq ( & xform , & test_data - > expected ) ,
" %s: After SWT playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f \n " ,
test_data - > name ,
xform . eM11 , xform . eM12 ,
xform . eM21 , xform . eM22 ,
xform . eDx , xform . eDy ,
test_data - > expected . eM11 , test_data - > expected . eM12 ,
test_data - > expected . eM21 , test_data - > expected . eM22 ,
test_data - > expected . eDx , test_data - > expected . eDy ) ;
break ;
}
case EMR_MODIFYWORLDTRANSFORM :
{
const EMRMODIFYWORLDTRANSFORM * lpXfrm = ( const EMRMODIFYWORLDTRANSFORM * ) emr ;
/* transform persists across calls */
ret = GetWorldTransform ( hdc , & xform ) ;
ok ( ret = = TRUE , " %s: GetWorldTransform failed \n " , test_data - > name ) ;
ok ( xform_eq ( & xform , & test_data - > expected ) ,
" %s: On MWT entry, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f \n " ,
test_data - > name ,
xform . eM11 , xform . eM12 ,
xform . eM21 , xform . eM22 ,
xform . eDx , xform . eDy ,
test_data - > expected . eM11 , test_data - > expected . eM12 ,
test_data - > expected . eM21 , test_data - > expected . eM22 ,
test_data - > expected . eDx , test_data - > expected . eDy ) ;
if ( test_data - > do_playback )
{
/* play back record */
ret = PlayEnhMetaFileRecord ( hdc , ht , emr , nobj ) ;
ok ( ret = = TRUE , " %s: PlayEnhMetaFileRecord failed \n " , test_data - > name ) ;
if ( lpXfrm - > iMode = = MWT_LEFTMULTIPLY )
{
/* left multiply does not discard direct modifications */
CombineTransform ( & test_data - > expected , & lpXfrm - > xform , & test_data - > expected ) ;
/* and updates the stored matrix separately */
CombineTransform ( & test_data - > stored , & lpXfrm - > xform , & test_data - > stored ) ;
}
else if ( lpXfrm - > iMode = = MWT_RIGHTMULTIPLY )
{
/* but right multiply does discard */
CombineTransform ( & test_data - > stored , & test_data - > stored , & lpXfrm - > xform ) ;
CombineTransform ( & test_data - > expected , & test_data - > stored , & test_data - > scale ) ;
}
/* verify it is updated immediately */
ret = GetWorldTransform ( hdc , & xform ) ;
ok ( ret = = TRUE , " %s: GetWorldTransform failed \n " , test_data - > name ) ;
ok ( xform_eq ( & xform , & test_data - > expected ) ,
" %s: After MWT playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f \n " ,
test_data - > name ,
xform . eM11 , xform . eM12 ,
xform . eM21 , xform . eM22 ,
xform . eDx , xform . eDy ,
test_data - > expected . eM11 , test_data - > expected . eM12 ,
test_data - > expected . eM21 , test_data - > expected . eM22 ,
test_data - > expected . eDx , test_data - > expected . eDy ) ;
}
if ( test_data - > do_modify )
{
/* modify directly */
set_rotation_xform ( & xform , M_PI / 4.f , 1 , - 1 ) ;
ret = ModifyWorldTransform ( hdc , & xform , MWT_LEFTMULTIPLY ) ;
ok ( ret = = TRUE , " %s: ModifyWorldTransform failed \n " , test_data - > name ) ;
/* the modified transform persists across callback calls */
CombineTransform ( & test_data - > expected , & xform , & test_data - > expected ) ;
ret = GetWorldTransform ( hdc , & xform ) ;
ok ( ret = = TRUE , " %s: GetWorldTransform failed \n " , test_data - > name ) ;
ok ( xform_eq ( & xform , & test_data - > expected ) ,
" %s: After ModifyWT, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f \n " ,
test_data - > name ,
xform . eM11 , xform . eM12 ,
xform . eM21 , xform . eM22 ,
xform . eDx , xform . eDy ,
test_data - > expected . eM11 , test_data - > expected . eM12 ,
test_data - > expected . eM21 , test_data - > expected . eM22 ,
test_data - > expected . eDx , test_data - > expected . eDy ) ;
}
break ;
}
case EMR_LINETO :
ret = GetWorldTransform ( hdc , & xform ) ;
ok ( ret = = TRUE , " %s: GetWorldTransform failed \n " , test_data - > name ) ;
ok ( xform_eq ( & xform , & test_data - > expected ) ,
" %s: Before LINETO playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f \n " ,
test_data - > name ,
xform . eM11 , xform . eM12 ,
xform . eM21 , xform . eM22 ,
xform . eDx , xform . eDy ,
test_data - > expected . eM11 , test_data - > expected . eM12 ,
test_data - > expected . eM21 , test_data - > expected . eM22 ,
test_data - > expected . eDx , test_data - > expected . eDy ) ;
ret = PlayEnhMetaFileRecord ( hdc , ht , emr , nobj ) ;
ok ( ret = = TRUE , " %s: PlayEnhMetaFileRecord failed \n " , test_data - > name ) ;
/* transform doesn't change during LINETO playback */
ret = GetWorldTransform ( hdc , & xform ) ;
ok ( ret = = TRUE , " %s: GetWorldTransform failed \n " , test_data - > name ) ;
ok ( xform_eq ( & xform , & test_data - > expected ) ,
" %s: After LINETO playback, got wrong world transform: %f, %f; %f %f; %f %f; expected: %f, %f; %f %f; %f %f \n " ,
test_data - > name ,
xform . eM11 , xform . eM12 ,
xform . eM21 , xform . eM22 ,
xform . eDx , xform . eDy ,
test_data - > expected . eM11 , test_data - > expected . eM12 ,
test_data - > expected . eM21 , test_data - > expected . eM22 ,
test_data - > expected . eDx , test_data - > expected . eDy ) ;
break ;
default :
PlayEnhMetaFileRecord ( hdc , ht , emr , nobj ) ;
break ;
}
return 1 ;
}
static void test_emf_WorldTransform ( void )
{
HDC hdcMetafile , hdc ;
HWND hwnd ;
HENHMETAFILE hemf ;
XFORM xform ;
BOOL ret ;
RECT rect = { 0 , 0 , 100 , 100 } ;
int i ;
struct emf_WorldTransform_test_data test_data [ ] = {
{ " normal " , FALSE , TRUE } ,
{ " playback and modify " , TRUE , TRUE } ,
{ " manual modify " , TRUE , FALSE }
} ;
2018-06-25 21:46:41 +02:00
for ( i = 0 ; i < ARRAY_SIZE ( test_data ) ; + + i )
2017-08-25 15:10:44 +02:00
{
hdcMetafile = CreateEnhMetaFileA ( GetDC ( 0 ) , NULL , NULL , NULL ) ;
ok ( hdcMetafile ! = 0 , " CreateEnhMetaFileA error %d \n " , GetLastError ( ) ) ;
ret = SetGraphicsMode ( hdcMetafile , GM_ADVANCED ) ;
ok ( ret = = TRUE , " SetGraphicsMode failed \n " ) ;
set_rotation_xform ( & xform , M_PI / 4.f , 2 , 3 ) ;
ret = SetWorldTransform ( hdcMetafile , & xform ) ; /* EMR_SETWORLDTRANSFORM */
ok ( ret = = TRUE , " SetWorldTransform failed \n " ) ;
set_rotation_xform ( & xform , M_PI / 2.f , - 2 , - 3 ) ;
ret = ModifyWorldTransform ( hdcMetafile , & xform , MWT_LEFTMULTIPLY ) ; /* EMR_MODIFYWORLDTRANSFORM */
ok ( ret = = TRUE , " ModifyWorldTransform failed \n " ) ;
set_rotation_xform ( & xform , M_PI / 3.f , - 2 , 3 ) ;
ret = ModifyWorldTransform ( hdcMetafile , & xform , MWT_LEFTMULTIPLY ) ; /* EMR_MODIFYWORLDTRANSFORM */
ok ( ret = = TRUE , " ModifyWorldTransform failed \n " ) ;
set_rotation_xform ( & xform , M_PI , 2 , - 3 ) ;
ret = ModifyWorldTransform ( hdcMetafile , & xform , MWT_RIGHTMULTIPLY ) ; /* EMR_MODIFYWORLDTRANSFORM */
ok ( ret = = TRUE , " ModifyWorldTransform failed \n " ) ;
ret = LineTo ( hdcMetafile , 1 , 1 ) ;
ok ( ret = = TRUE , " LineTo failed \n " ) ;
hemf = CloseEnhMetaFile ( hdcMetafile ) ;
ok ( hemf ! = 0 , " CloseEnhMetaFile error %d \n " , GetLastError ( ) ) ;
hwnd = CreateWindowExA ( 0 , " static " , NULL , WS_POPUP | WS_VISIBLE ,
0 , 0 , 200 , 200 , 0 , 0 , 0 , NULL ) ;
ok ( hwnd ! = 0 , " CreateWindowExA error %d \n " , GetLastError ( ) ) ;
hdc = GetDC ( hwnd ) ;
ok ( hdc ! = 0 , " GetDC failed \n " ) ;
ret = EnumEnhMetaFile ( hdc , hemf , enum_emf_WorldTransform , & test_data [ i ] , & rect ) ;
ok ( ret = = TRUE , " EnumEnhMetaFile failed: %u \n " , GetLastError ( ) ) ;
ReleaseDC ( hwnd , hdc ) ;
DestroyWindow ( hwnd ) ;
DeleteEnhMetaFile ( hemf ) ;
}
}
2004-03-09 20:19:53 +01:00
START_TEST ( metafile )
{
2005-10-26 12:05:07 +02:00
init_function_pointers ( ) ;
2004-12-09 12:37:59 +01:00
/* For enhanced metafiles (enhmfdrv) */
2004-03-09 20:19:53 +01:00
test_ExtTextOut ( ) ;
2011-02-18 23:56:01 +01:00
test_ExtTextOutScale ( ) ;
2005-10-31 11:05:52 +01:00
test_SaveDC ( ) ;
2009-11-22 21:25:42 +01:00
test_emf_BitBlt ( ) ;
2011-03-10 20:22:22 +01:00
test_emf_DCBrush ( ) ;
2012-06-20 03:08:07 +02:00
test_emf_ExtTextOut_on_path ( ) ;
test_emf_clipping ( ) ;
test_emf_polybezier ( ) ;
2016-06-21 07:38:19 +02:00
test_emf_paths ( ) ;
2016-03-09 12:17:05 +01:00
test_emf_PolyPolyline ( ) ;
2016-04-08 12:40:56 +02:00
test_emf_GradientFill ( ) ;
2017-08-25 15:10:44 +02:00
test_emf_WorldTransform ( ) ;
2004-12-09 12:37:59 +01:00
/* For win-format metafiles (mfdrv) */
2009-04-03 20:35:38 +02:00
test_mf_SaveDC ( ) ;
2004-12-09 12:37:59 +01:00
test_mf_Blank ( ) ;
test_mf_Graphics ( ) ;
2005-01-14 16:12:59 +01:00
test_mf_PatternBrush ( ) ;
2011-03-10 20:22:22 +01:00
test_mf_DCBrush ( ) ;
2005-10-19 20:28:14 +02:00
test_CopyMetaFile ( ) ;
test_SetMetaFileBits ( ) ;
2005-11-07 17:40:20 +01:00
test_mf_ExtTextOut_on_path ( ) ;
2012-06-20 03:08:07 +02:00
test_mf_clipping ( ) ;
2016-02-23 08:16:49 +01:00
test_mf_GetPath ( ) ;
2005-04-13 12:57:59 +02:00
/* For metafile conversions */
test_mf_conversions ( ) ;
2006-06-20 16:02:37 +02:00
test_SetWinMetaFileBits ( ) ;
2009-06-30 12:47:59 +02:00
test_GetWinMetaFileBits ( ) ;
2005-04-15 16:11:00 +02:00
test_gdiis ( ) ;
2007-05-28 09:21:58 +02:00
test_SetEnhMetaFileBits ( ) ;
2004-03-09 20:19:53 +01:00
}