Commit 59670ffb authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

gdi32: Introduce NtGdiCreateMetafileDC.

And use it in CreateEnhMetaFileW. Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 37f492ae
...@@ -282,6 +282,47 @@ static inline BOOL devcap_is_valid( int cap ) ...@@ -282,6 +282,47 @@ static inline BOOL devcap_is_valid( int cap )
} }
/********************************************************************** /**********************************************************************
* NtGdiCreateMetafileDC (win32u.@)
*/
HDC WINAPI NtGdiCreateMetafileDC( HDC hdc )
{
EMFDRV_PDEVICE *physDev;
HDC ref_dc, ret;
int cap;
DC *dc;
if (!(dc = alloc_dc_ptr( NTGDI_OBJ_ENHMETADC ))) return 0;
physDev = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev) );
if (!physDev)
{
free_dc_ptr( dc );
return 0;
}
dc->attr->emf = physDev;
push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver );
if (hdc) /* if no ref, use current display */
ref_dc = hdc;
else
ref_dc = CreateDCW( L"DISPLAY", NULL, NULL, NULL );
memset( physDev->dev_caps, 0, sizeof(physDev->dev_caps) );
for (cap = 0; cap < ARRAY_SIZE( physDev->dev_caps ); cap++)
if (devcap_is_valid( cap ))
physDev->dev_caps[cap] = NtGdiGetDeviceCaps( ref_dc, cap );
if (!hdc) NtGdiDeleteObjectApp( ref_dc );
NtGdiSetVirtualResolution( dc->hSelf, 0, 0, 0, 0 );
ret = dc->hSelf;
release_dc_ptr( dc );
return ret;
}
/**********************************************************************
* CreateEnhMetaFileW (GDI32.@) * CreateEnhMetaFileW (GDI32.@)
*/ */
HDC WINAPI CreateEnhMetaFileW( HDC WINAPI CreateEnhMetaFileW(
...@@ -291,23 +332,23 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -291,23 +332,23 @@ HDC WINAPI CreateEnhMetaFileW(
LPCWSTR description /* [in] optional description */ LPCWSTR description /* [in] optional description */
) )
{ {
HDC ret, ref_dc; HDC ret;
DC *dc; EMFDRV_PDEVICE *emf;
EMFDRV_PDEVICE *physDev; DC_ATTR *dc_attr;
HANDLE hFile; HANDLE hFile;
DWORD size = 0, length = 0; DWORD size = 0, length = 0;
int cap;
TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) ); TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) );
if (!(dc = alloc_dc_ptr( NTGDI_OBJ_ENHMETADC ))) return 0; if (!(ret = NtGdiCreateMetafileDC( hdc ))) return 0;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev)); if (!(dc_attr = get_dc_attr( ret )))
if (!physDev) { {
free_dc_ptr( dc ); DeleteDC( ret );
return 0; return 0;
} }
dc->attr->emf = physDev; emf = dc_attr->emf;
if(description) { /* App name\0Title\0\0 */ if(description) { /* App name\0Title\0\0 */
length = lstrlenW(description); length = lstrlenW(description);
length += lstrlenW(description + length + 1); length += lstrlenW(description + length + 1);
...@@ -316,93 +357,79 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -316,93 +357,79 @@ HDC WINAPI CreateEnhMetaFileW(
} }
size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4; size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) { if (!(emf->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size)))
HeapFree( GetProcessHeap(), 0, physDev ); {
free_dc_ptr( dc ); DeleteDC( ret );
return 0; return 0;
} }
push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver ); emf->handles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
HANDLE_LIST_INC * sizeof(emf->handles[0]) );
emf->handles_size = HANDLE_LIST_INC;
emf->cur_handles = 1;
emf->hFile = 0;
emf->dc_brush = 0;
emf->dc_pen = 0;
emf->path = FALSE;
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0])); emf->emh->iType = EMR_HEADER;
physDev->handles_size = HANDLE_LIST_INC; emf->emh->nSize = size;
physDev->cur_handles = 1;
physDev->hFile = 0;
physDev->dc_brush = 0;
physDev->dc_pen = 0;
physDev->path = FALSE;
if (hdc) /* if no ref, use current display */ emf->emh->rclBounds.left = emf->emh->rclBounds.top = 0;
ref_dc = hdc; emf->emh->rclBounds.right = emf->emh->rclBounds.bottom = -1;
else
ref_dc = CreateDCW( L"DISPLAY", NULL, NULL, NULL );
memset( physDev->dev_caps, 0, sizeof(physDev->dev_caps) ); if (rect)
for (cap = 0; cap < ARRAY_SIZE( physDev->dev_caps ); cap++) {
if (devcap_is_valid( cap )) emf->emh->rclFrame.left = rect->left;
physDev->dev_caps[cap] = GetDeviceCaps( ref_dc, cap ); emf->emh->rclFrame.top = rect->top;
emf->emh->rclFrame.right = rect->right;
if (!hdc) DeleteDC( ref_dc ); emf->emh->rclFrame.bottom = rect->bottom;
}
NtGdiSetVirtualResolution(physDev->dev.hdc, 0, 0, 0, 0); else
{
physDev->emh->iType = EMR_HEADER; /* Set this to {0,0 - -1,-1} and update it at the end */
physDev->emh->nSize = size; emf->emh->rclFrame.left = emf->emh->rclFrame.top = 0;
emf->emh->rclFrame.right = emf->emh->rclFrame.bottom = -1;
physDev->emh->rclBounds.left = physDev->emh->rclBounds.top = 0;
physDev->emh->rclBounds.right = physDev->emh->rclBounds.bottom = -1;
if(rect) {
physDev->emh->rclFrame.left = rect->left;
physDev->emh->rclFrame.top = rect->top;
physDev->emh->rclFrame.right = rect->right;
physDev->emh->rclFrame.bottom = rect->bottom;
} else { /* Set this to {0,0 - -1,-1} and update it at the end */
physDev->emh->rclFrame.left = physDev->emh->rclFrame.top = 0;
physDev->emh->rclFrame.right = physDev->emh->rclFrame.bottom = -1;
} }
physDev->emh->dSignature = ENHMETA_SIGNATURE; emf->emh->dSignature = ENHMETA_SIGNATURE;
physDev->emh->nVersion = 0x10000; emf->emh->nVersion = 0x10000;
physDev->emh->nBytes = physDev->emh->nSize; emf->emh->nBytes = emf->emh->nSize;
physDev->emh->nRecords = 1; emf->emh->nRecords = 1;
physDev->emh->nHandles = 1; emf->emh->nHandles = 1;
physDev->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */ emf->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
physDev->emh->nDescription = length / 2; emf->emh->nDescription = length / 2;
physDev->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0; emf->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */ emf->emh->nPalEntries = 0; /* I guess this should start at 0 */
/* Size in pixels */ /* Size in pixels */
physDev->emh->szlDevice.cx = physDev->dev_caps[HORZRES]; emf->emh->szlDevice.cx = GetDeviceCaps( ret, HORZRES );
physDev->emh->szlDevice.cy = physDev->dev_caps[VERTRES]; emf->emh->szlDevice.cy = GetDeviceCaps( ret, VERTRES );
/* Size in millimeters */ /* Size in millimeters */
physDev->emh->szlMillimeters.cx = physDev->dev_caps[HORZSIZE]; emf->emh->szlMillimeters.cx = GetDeviceCaps( ret, HORZSIZE );
physDev->emh->szlMillimeters.cy = physDev->dev_caps[VERTSIZE]; emf->emh->szlMillimeters.cy = GetDeviceCaps( ret, VERTSIZE );
/* Size in micrometers */ /* Size in micrometers */
physDev->emh->szlMicrometers.cx = physDev->emh->szlMillimeters.cx * 1000; emf->emh->szlMicrometers.cx = emf->emh->szlMillimeters.cx * 1000;
physDev->emh->szlMicrometers.cy = physDev->emh->szlMillimeters.cy * 1000; emf->emh->szlMicrometers.cy = emf->emh->szlMillimeters.cy * 1000;
memcpy((char *)physDev->emh + sizeof(ENHMETAHEADER), description, length); memcpy( (char *)emf->emh + sizeof(ENHMETAHEADER), description, length );
if (filename) /* disk based metafile */ if (filename) /* disk based metafile */
{ {
if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0, if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0,
NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) { NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
free_dc_ptr( dc ); DeleteDC( ret );
return 0; return 0;
} }
physDev->hFile = hFile; emf->hFile = hFile;
} }
TRACE("returning %p\n", physDev->dev.hdc); TRACE( "returning %p\n", ret );
ret = physDev->dev.hdc;
release_dc_ptr( dc );
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment