gdiplus: Reimplement GdipCreateMetafileFromEmf without using IPicture.
This commit is contained in:
parent
d8a855305f
commit
91a3e5fc10
|
@ -58,6 +58,7 @@ extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **r
|
|||
extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc) DECLSPEC_HIDDEN;
|
||||
extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
|
||||
extern MetafileType METAFILE_GetEmfType(HENHMETAFILE hemf) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
|
||||
REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN;
|
||||
|
@ -280,6 +281,7 @@ struct GpMetafile{
|
|||
GpUnit unit;
|
||||
MetafileType metafile_type;
|
||||
HENHMETAFILE hemf;
|
||||
int preserve_hemf; /* if true, hemf belongs to the app and should not be deleted */
|
||||
|
||||
/* recording */
|
||||
HDC record_dc;
|
||||
|
|
|
@ -2350,62 +2350,43 @@ GpStatus WINGDIPAPI GdipCreateFromHWNDICM(HWND hwnd, GpGraphics **graphics)
|
|||
GpStatus WINGDIPAPI GdipCreateMetafileFromEmf(HENHMETAFILE hemf, BOOL delete,
|
||||
GpMetafile **metafile)
|
||||
{
|
||||
IStream *stream = NULL;
|
||||
UINT read;
|
||||
ENHMETAHEADER *copy;
|
||||
GpStatus retval = Ok;
|
||||
ENHMETAHEADER header;
|
||||
MetafileType metafile_type;
|
||||
|
||||
TRACE("(%p,%i,%p)\n", hemf, delete, metafile);
|
||||
|
||||
if(!hemf || !metafile)
|
||||
return InvalidParameter;
|
||||
|
||||
read = GetEnhMetaFileBits(hemf, 0, NULL);
|
||||
copy = GdipAlloc(read);
|
||||
GetEnhMetaFileBits(hemf, read, (BYTE *)copy);
|
||||
if (GetEnhMetaFileHeader(hemf, sizeof(header), &header) == 0)
|
||||
return GenericError;
|
||||
|
||||
if(CreateStreamOnHGlobal(copy, TRUE, &stream) != S_OK){
|
||||
ERR("could not make stream\n");
|
||||
GdipFree(copy);
|
||||
retval = GenericError;
|
||||
goto err;
|
||||
}
|
||||
metafile_type = METAFILE_GetEmfType(hemf);
|
||||
|
||||
if (metafile_type == MetafileTypeInvalid)
|
||||
return GenericError;
|
||||
|
||||
*metafile = GdipAlloc(sizeof(GpMetafile));
|
||||
if(!*metafile){
|
||||
retval = OutOfMemory;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture,
|
||||
(LPVOID*) &((*metafile)->image.picture)) != S_OK)
|
||||
{
|
||||
retval = GenericError;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!*metafile)
|
||||
return OutOfMemory;
|
||||
|
||||
(*metafile)->image.type = ImageTypeMetafile;
|
||||
memcpy(&(*metafile)->image.format, &ImageFormatWMF, sizeof(GUID));
|
||||
(*metafile)->image.palette = NULL;
|
||||
(*metafile)->image.xres = (REAL)copy->szlDevice.cx;
|
||||
(*metafile)->image.yres = (REAL)copy->szlDevice.cy;
|
||||
(*metafile)->bounds.X = (REAL)copy->rclBounds.left;
|
||||
(*metafile)->bounds.Y = (REAL)copy->rclBounds.top;
|
||||
(*metafile)->bounds.Width = (REAL)(copy->rclBounds.right - copy->rclBounds.left);
|
||||
(*metafile)->bounds.Height = (REAL)(copy->rclBounds.bottom - copy->rclBounds.top);
|
||||
(*metafile)->image.format = ImageFormatEMF;
|
||||
(*metafile)->image.frame_count = 1;
|
||||
(*metafile)->image.xres = (REAL)header.szlDevice.cx;
|
||||
(*metafile)->image.yres = (REAL)header.szlDevice.cy;
|
||||
(*metafile)->bounds.X = (REAL)header.rclBounds.left;
|
||||
(*metafile)->bounds.Y = (REAL)header.rclBounds.top;
|
||||
(*metafile)->bounds.Width = (REAL)(header.rclBounds.right - header.rclBounds.left);
|
||||
(*metafile)->bounds.Height = (REAL)(header.rclBounds.bottom - header.rclBounds.top);
|
||||
(*metafile)->unit = UnitPixel;
|
||||
|
||||
if(delete)
|
||||
DeleteEnhMetaFile(hemf);
|
||||
(*metafile)->metafile_type = metafile_type;
|
||||
(*metafile)->hemf = hemf;
|
||||
(*metafile)->preserve_hemf = !delete;
|
||||
|
||||
TRACE("<-- %p\n", *metafile);
|
||||
|
||||
err:
|
||||
if (retval != Ok)
|
||||
GdipFree(*metafile);
|
||||
IStream_Release(stream);
|
||||
return retval;
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete,
|
||||
|
@ -2431,7 +2412,8 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete,
|
|||
hemf = SetWinMetaFileBits(read, copy, NULL, NULL);
|
||||
GdipFree(copy);
|
||||
|
||||
retval = GdipCreateMetafileFromEmf(hemf, FALSE, metafile);
|
||||
/* FIXME: We should store and use hwmf instead of converting to hemf */
|
||||
retval = GdipCreateMetafileFromEmf(hemf, TRUE, metafile);
|
||||
|
||||
if (retval == Ok)
|
||||
{
|
||||
|
@ -2443,9 +2425,13 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete,
|
|||
placeable->BoundingBox.Left);
|
||||
(*metafile)->bounds.Height = (REAL)(placeable->BoundingBox.Bottom -
|
||||
placeable->BoundingBox.Top);
|
||||
(*metafile)->metafile_type = MetafileTypeWmfPlaceable;
|
||||
(*metafile)->image.format = ImageFormatWMF;
|
||||
|
||||
if (delete) DeleteMetaFile(hwmf);
|
||||
}
|
||||
else
|
||||
DeleteEnhMetaFile(hemf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -2189,7 +2189,8 @@ static GpStatus free_image_data(GpImage *image)
|
|||
GpMetafile *metafile = (GpMetafile*)image;
|
||||
GdipFree(metafile->comment_data);
|
||||
DeleteEnhMetaFile(CloseEnhMetaFile(metafile->record_dc));
|
||||
DeleteEnhMetaFile(metafile->hemf);
|
||||
if (!metafile->preserve_hemf)
|
||||
DeleteEnhMetaFile(metafile->hemf);
|
||||
if (metafile->record_graphics)
|
||||
{
|
||||
WARN("metafile closed while recording\n");
|
||||
|
|
|
@ -548,3 +548,41 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
|
|||
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int CALLBACK get_metafile_type_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
|
||||
int nObj, LPARAM lpData)
|
||||
{
|
||||
MetafileType *result = (MetafileType*)lpData;
|
||||
|
||||
if (lpEMFR->iType == EMR_GDICOMMENT)
|
||||
{
|
||||
const EMRGDICOMMENT *comment = (const EMRGDICOMMENT*)lpEMFR;
|
||||
|
||||
if (comment->cbData >= 4 && memcmp(comment->Data, "EMF+", 4) == 0)
|
||||
{
|
||||
const EmfPlusRecordHeader *header = (const EmfPlusRecordHeader*)&comment->Data[4];
|
||||
|
||||
if (4 + sizeof(EmfPlusRecordHeader) <= comment->cbData &&
|
||||
header->Type == EmfPlusRecordTypeHeader)
|
||||
{
|
||||
if ((header->Flags & 1) == 1)
|
||||
*result = MetafileTypeEmfPlusDual;
|
||||
else
|
||||
*result = MetafileTypeEmfPlusOnly;
|
||||
}
|
||||
}
|
||||
else
|
||||
*result = MetafileTypeEmf;
|
||||
}
|
||||
else
|
||||
*result = MetafileTypeEmf;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MetafileType METAFILE_GetEmfType(HENHMETAFILE hemf)
|
||||
{
|
||||
MetafileType result = MetafileTypeInvalid;
|
||||
EnumEnhMetaFile(NULL, hemf, get_metafile_type_proc, &result, NULL);
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue