gdi32: Introduce NtGdiCreateMetafileDC.
And use it in CreateEnhMetaFileW. Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
37f492ae55
commit
59670ffb2d
|
@ -282,56 +282,27 @@ static inline BOOL devcap_is_valid( int cap )
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* CreateEnhMetaFileW (GDI32.@)
|
* NtGdiCreateMetafileDC (win32u.@)
|
||||||
*/
|
*/
|
||||||
HDC WINAPI CreateEnhMetaFileW(
|
HDC WINAPI NtGdiCreateMetafileDC( HDC hdc )
|
||||||
HDC hdc, /* [in] optional reference DC */
|
|
||||||
LPCWSTR filename, /* [in] optional filename for disk metafiles */
|
|
||||||
const RECT* rect, /* [in] optional bounding rectangle */
|
|
||||||
LPCWSTR description /* [in] optional description */
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
HDC ret, ref_dc;
|
|
||||||
DC *dc;
|
|
||||||
EMFDRV_PDEVICE *physDev;
|
EMFDRV_PDEVICE *physDev;
|
||||||
HANDLE hFile;
|
HDC ref_dc, ret;
|
||||||
DWORD size = 0, length = 0;
|
|
||||||
int cap;
|
int cap;
|
||||||
|
DC *dc;
|
||||||
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 (!(dc = alloc_dc_ptr( NTGDI_OBJ_ENHMETADC ))) return 0;
|
||||||
|
|
||||||
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
|
physDev = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev) );
|
||||||
if (!physDev) {
|
if (!physDev)
|
||||||
|
{
|
||||||
free_dc_ptr( dc );
|
free_dc_ptr( dc );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dc->attr->emf = physDev;
|
dc->attr->emf = physDev;
|
||||||
if(description) { /* App name\0Title\0\0 */
|
|
||||||
length = lstrlenW(description);
|
|
||||||
length += lstrlenW(description + length + 1);
|
|
||||||
length += 3;
|
|
||||||
length *= 2;
|
|
||||||
}
|
|
||||||
size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
|
|
||||||
|
|
||||||
if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
|
|
||||||
HeapFree( GetProcessHeap(), 0, physDev );
|
|
||||||
free_dc_ptr( dc );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver );
|
push_dc_driver( &dc->physDev, &physDev->dev, &emfdrv_driver );
|
||||||
|
|
||||||
physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
|
|
||||||
physDev->handles_size = HANDLE_LIST_INC;
|
|
||||||
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 */
|
if (hdc) /* if no ref, use current display */
|
||||||
ref_dc = hdc;
|
ref_dc = hdc;
|
||||||
else
|
else
|
||||||
|
@ -340,69 +311,125 @@ HDC WINAPI CreateEnhMetaFileW(
|
||||||
memset( physDev->dev_caps, 0, sizeof(physDev->dev_caps) );
|
memset( physDev->dev_caps, 0, sizeof(physDev->dev_caps) );
|
||||||
for (cap = 0; cap < ARRAY_SIZE( physDev->dev_caps ); cap++)
|
for (cap = 0; cap < ARRAY_SIZE( physDev->dev_caps ); cap++)
|
||||||
if (devcap_is_valid( cap ))
|
if (devcap_is_valid( cap ))
|
||||||
physDev->dev_caps[cap] = GetDeviceCaps( ref_dc, cap );
|
physDev->dev_caps[cap] = NtGdiGetDeviceCaps( ref_dc, cap );
|
||||||
|
|
||||||
if (!hdc) DeleteDC( ref_dc );
|
if (!hdc) NtGdiDeleteObjectApp( ref_dc );
|
||||||
|
|
||||||
NtGdiSetVirtualResolution(physDev->dev.hdc, 0, 0, 0, 0);
|
NtGdiSetVirtualResolution( dc->hSelf, 0, 0, 0, 0 );
|
||||||
|
|
||||||
physDev->emh->iType = EMR_HEADER;
|
ret = dc->hSelf;
|
||||||
physDev->emh->nSize = size;
|
release_dc_ptr( dc );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
physDev->emh->rclBounds.left = physDev->emh->rclBounds.top = 0;
|
/**********************************************************************
|
||||||
physDev->emh->rclBounds.right = physDev->emh->rclBounds.bottom = -1;
|
* CreateEnhMetaFileW (GDI32.@)
|
||||||
|
*/
|
||||||
|
HDC WINAPI CreateEnhMetaFileW(
|
||||||
|
HDC hdc, /* [in] optional reference DC */
|
||||||
|
LPCWSTR filename, /* [in] optional filename for disk metafiles */
|
||||||
|
const RECT* rect, /* [in] optional bounding rectangle */
|
||||||
|
LPCWSTR description /* [in] optional description */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HDC ret;
|
||||||
|
EMFDRV_PDEVICE *emf;
|
||||||
|
DC_ATTR *dc_attr;
|
||||||
|
HANDLE hFile;
|
||||||
|
DWORD size = 0, length = 0;
|
||||||
|
|
||||||
if(rect) {
|
TRACE("(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect), debugstr_w(description) );
|
||||||
physDev->emh->rclFrame.left = rect->left;
|
|
||||||
physDev->emh->rclFrame.top = rect->top;
|
if (!(ret = NtGdiCreateMetafileDC( hdc ))) return 0;
|
||||||
physDev->emh->rclFrame.right = rect->right;
|
|
||||||
physDev->emh->rclFrame.bottom = rect->bottom;
|
if (!(dc_attr = get_dc_attr( ret )))
|
||||||
} else { /* Set this to {0,0 - -1,-1} and update it at the end */
|
{
|
||||||
physDev->emh->rclFrame.left = physDev->emh->rclFrame.top = 0;
|
DeleteDC( ret );
|
||||||
physDev->emh->rclFrame.right = physDev->emh->rclFrame.bottom = -1;
|
return 0;
|
||||||
|
}
|
||||||
|
emf = dc_attr->emf;
|
||||||
|
|
||||||
|
if(description) { /* App name\0Title\0\0 */
|
||||||
|
length = lstrlenW(description);
|
||||||
|
length += lstrlenW(description + length + 1);
|
||||||
|
length += 3;
|
||||||
|
length *= 2;
|
||||||
|
}
|
||||||
|
size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
|
||||||
|
|
||||||
|
if (!(emf->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size)))
|
||||||
|
{
|
||||||
|
DeleteDC( ret );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
physDev->emh->dSignature = ENHMETA_SIGNATURE;
|
emf->handles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
physDev->emh->nVersion = 0x10000;
|
HANDLE_LIST_INC * sizeof(emf->handles[0]) );
|
||||||
physDev->emh->nBytes = physDev->emh->nSize;
|
emf->handles_size = HANDLE_LIST_INC;
|
||||||
physDev->emh->nRecords = 1;
|
emf->cur_handles = 1;
|
||||||
physDev->emh->nHandles = 1;
|
emf->hFile = 0;
|
||||||
|
emf->dc_brush = 0;
|
||||||
|
emf->dc_pen = 0;
|
||||||
|
emf->path = FALSE;
|
||||||
|
|
||||||
physDev->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
|
emf->emh->iType = EMR_HEADER;
|
||||||
physDev->emh->nDescription = length / 2;
|
emf->emh->nSize = size;
|
||||||
|
|
||||||
physDev->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
|
emf->emh->rclBounds.left = emf->emh->rclBounds.top = 0;
|
||||||
|
emf->emh->rclBounds.right = emf->emh->rclBounds.bottom = -1;
|
||||||
|
|
||||||
physDev->emh->nPalEntries = 0; /* I guess this should start at 0 */
|
if (rect)
|
||||||
|
{
|
||||||
|
emf->emh->rclFrame.left = rect->left;
|
||||||
|
emf->emh->rclFrame.top = rect->top;
|
||||||
|
emf->emh->rclFrame.right = rect->right;
|
||||||
|
emf->emh->rclFrame.bottom = rect->bottom;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Set this to {0,0 - -1,-1} and update it at the end */
|
||||||
|
emf->emh->rclFrame.left = emf->emh->rclFrame.top = 0;
|
||||||
|
emf->emh->rclFrame.right = emf->emh->rclFrame.bottom = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
emf->emh->dSignature = ENHMETA_SIGNATURE;
|
||||||
|
emf->emh->nVersion = 0x10000;
|
||||||
|
emf->emh->nBytes = emf->emh->nSize;
|
||||||
|
emf->emh->nRecords = 1;
|
||||||
|
emf->emh->nHandles = 1;
|
||||||
|
|
||||||
|
emf->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
|
||||||
|
emf->emh->nDescription = length / 2;
|
||||||
|
|
||||||
|
emf->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue