- Implemented GetEnhMetaFilePaletteEntries
- Added fixme stubs for SetMetaRgn and GetMetaRgn
- Added support for playing several enhanced metafile records
- Added beginnings of implementation for playing the rest of the
enhanced metafile records
diff --git a/objects/enhmetafile.c b/objects/enhmetafile.c
index 3960e4e..4bc2b43 100644
--- a/objects/enhmetafile.c
+++ b/objects/enhmetafile.c
@@ -8,8 +8,8 @@
*
* A header
* A table of handles to GDI objects
- * A private palette
* An array of metafile records
+ * A private palette
*
*
* The standard format consists of a header and an array of metafile records.
@@ -357,8 +357,12 @@
case EMR_EOF:
break;
case EMR_GDICOMMENT:
- /* application defined and processed */
- break;
+ {
+ PEMRGDICOMMENT lpGdiComment = (PEMRGDICOMMENT)mr;
+ /* In an enhanced metafile, there can be both public and private GDI comments */
+ GdiComment( hdc, lpGdiComment->cbData, lpGdiComment->Data );
+ break;
+ }
case EMR_SETMAPMODE:
{
DWORD mode = mr->dParm[0];
@@ -534,14 +538,16 @@
Polyline16(hdc, (POINT16 *)&mr->dParm[5], count);
break;
}
-
#if 0
case EMR_POLYPOLYGON16:
{
- INT polygons = mr->dParm[z];
- LPPOINT16 pts = (LPPOINT16) &mr->dParm[x];
- LPINT16 counts = (LPINT16) &mr->dParm[y];
- PolyPolygon16(hdc, pts, counts, polygons);
+ PEMRPOLYPOLYGON16 lpPolyPoly16 = (PEMRPOLYPOLYGON16)mr;
+
+ PolyPolygon16( hdc,
+ lpPolyPoly16->apts,
+ lpPolyPoly16->aPolyCounts,
+ lpPolyPoly16->nPolys );
+
break;
}
#endif
@@ -566,7 +572,7 @@
(const BITMAPINFO *)(((char *)mr)+offBmiSrc),
iUsageSrc,dwRop);
break;
- }
+ }
case EMR_EXTTEXTOUTW:
{
/* 0-3: ??? */
@@ -582,7 +588,119 @@
str, count, /* lpDx */ NULL);
break;
}
+
+ case EMR_CREATEPALETTE:
+ {
+ PEMRCREATEPALETTE lpCreatePal = (PEMRCREATEPALETTE)mr;
+ (handletable->objectHandle)[ lpCreatePal->ihPal ] =
+ CreatePalette( &lpCreatePal->lgpl );
+
+ break;
+ }
+
+ case EMR_SELECTPALETTE:
+ {
+ PEMRSELECTPALETTE lpSelectPal = (PEMRSELECTPALETTE)mr;
+
+ /* FIXME: Should this be forcing background mode? */
+ (handletable->objectHandle)[ lpSelectPal->ihPal ] =
+ SelectPalette( hdc, lpSelectPal->ihPal, FALSE );
+ break;
+ }
+
+ case EMR_REALIZEPALETTE:
+ {
+ RealizePalette( hdc );
+ break;
+ }
+
+#if 0
+ case EMR_EXTSELECTCLIPRGN:
+ {
+ PEMREXTSELECTCLIPRGN lpRgn = (PEMREXTSELECTCLIPRGN)mr;
+
+ /* Need to make a region out of the RGNDATA we have */
+ ExtSelectClipRgn( hdc, ..., (INT)(lpRgn->iMode) );
+
+ }
+#endif
+ case EMR_SETMETARGN:
+ {
+ SetMetaRgn( hdc );
+ break;
+ }
+ case EMR_SETWORLDTRANSFORM:
+ {
+ PEMRSETWORLDTRANSFORM lpXfrm = (PEMRSETWORLDTRANSFORM)mr;
+ SetWorldTransform( hdc, &lpXfrm->xform );
+ break;
+ }
+ case EMR_POLYBEZIER:
+ case EMR_POLYGON:
+ case EMR_POLYLINE:
+ case EMR_POLYBEZIERTO:
+ case EMR_POLYLINETO:
+ case EMR_POLYPOLYLINE:
+ case EMR_POLYPOLYGON:
+ case EMR_SETBRUSHORGEX:
+ case EMR_SETPIXELV:
+ case EMR_SETMAPPERFLAGS:
+ case EMR_SETCOLORADJUSTMENT:
+ case EMR_OFFSETCLIPRGN:
+ case EMR_EXCLUDECLIPRECT:
+ case EMR_SCALEVIEWPORTEXTEX:
+ case EMR_SCALEWINDOWEXTEX:
+ case EMR_MODIFYWORLDTRANSFORM:
+ case EMR_ANGLEARC:
+ case EMR_ROUNDRECT:
+ case EMR_ARC:
+ case EMR_CHORD:
+ case EMR_PIE:
+ case EMR_SETPALETTEENTRIES:
+ case EMR_RESIZEPALETTE:
+ case EMR_EXTFLOODFILL:
+ case EMR_ARCTO:
+ case EMR_POLYDRAW:
+ case EMR_SETARCDIRECTION:
+ case EMR_SETMITERLIMIT:
+ case EMR_BEGINPATH:
+ case EMR_ENDPATH:
+ case EMR_CLOSEFIGURE:
+ case EMR_FILLPATH:
+ case EMR_STROKEANDFILLPATH:
+ case EMR_STROKEPATH:
+ case EMR_FLATTENPATH:
+ case EMR_WIDENPATH:
+ case EMR_SELECTCLIPPATH:
+ case EMR_ABORTPATH:
+ case EMR_FILLRGN:
+ case EMR_FRAMERGN:
+ case EMR_INVERTRGN:
+ case EMR_PAINTRGN:
+ case EMR_BITBLT:
+ case EMR_STRETCHBLT:
+ case EMR_MASKBLT:
+ case EMR_PLGBLT:
+ case EMR_SETDIBITSTODEVICE:
+ case EMR_EXTTEXTOUTA:
+ case EMR_POLYBEZIER16:
+ case EMR_POLYBEZIERTO16:
+ case EMR_POLYLINETO16:
+ case EMR_POLYPOLYLINE16:
+ case EMR_POLYPOLYGON16:
+ case EMR_POLYDRAW16:
+ case EMR_CREATEMONOBRUSH:
+ case EMR_CREATEDIBPATTERNBRUSHPT:
+ case EMR_POLYTEXTOUTA:
+ case EMR_POLYTEXTOUTW:
+ case EMR_SETICMMODE:
+ case EMR_CREATECOLORSPACE:
+ case EMR_SETCOLORSPACE:
+ case EMR_DELETECOLORSPACE:
+ case EMR_GLSRECORD:
+ case EMR_GLSBOUNDEDRECORD:
+ case EMR_PIXELFORMAT:
default:
FIXME("type %d is unimplemented\n", type);
/* SetLastError(E_NOTIMPL); */
@@ -734,18 +852,109 @@
}
+/* Struct to be used to be passed in the LPVOID parameter for cbEnhPaletteCopy */
+typedef struct tagEMF_PaletteCopy
+{
+ UINT cEntries;
+ LPPALETTEENTRY lpPe;
+} EMF_PaletteCopy;
+
+/***************************************************************
+ * Find the EMR_EOF record and then use it to find the
+ * palette entries for this enhanced metafile.
+ * The lpData is actually a pointer to a EMF_PaletteCopy struct
+ * which contains the max number of elements to copy and where
+ * to copy them to.
+ *
+ * NOTE: To be used by GetEnhMetaFilePaletteEntries only!
+ */
+INT CALLBACK cbEnhPaletteCopy( HDC a,
+ LPHANDLETABLE b,
+ LPENHMETARECORD lpEMR,
+ INT c,
+ LPVOID lpData )
+{
+
+ if ( lpEMR->iType == EMR_EOF )
+ {
+ PEMREOF lpEof = (PEMREOF)lpEMR;
+ EMF_PaletteCopy* info = (EMF_PaletteCopy*)lpData;
+ DWORD dwNumPalToCopy = MIN( lpEof->nPalEntries, info->cEntries );
+
+ TRACE( "copying 0x%08lx palettes\n", dwNumPalToCopy );
+
+ memcpy( (LPVOID)info->lpPe,
+ (LPVOID)(((LPSTR)lpEof) + lpEof->offPalEntries),
+ sizeof( *(info->lpPe) ) * dwNumPalToCopy );
+
+ /* Update the passed data as a return code */
+ info->lpPe = NULL; /* Palettes were copied! */
+ info->cEntries = (UINT)dwNumPalToCopy;
+
+ return FALSE; /* That's all we need */
+ }
+
+ return TRUE;
+}
+
/*****************************************************************************
* GetEnhMetaFilePaletteEntries (GDI32.179)
*
* Copy the palette and report size
+ *
+ * BUGS: Error codes (SetLastError) are not set on failures
*/
-
-UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE hemf,
- UINT cEntries,
- LPPALETTEENTRY lppe)
+UINT WINAPI GetEnhMetaFilePaletteEntries( HENHMETAFILE hEmf,
+ UINT cEntries,
+ LPPALETTEENTRY lpPe )
{
- FIXME( "(%04x,%d,%p):stub\n", hemf, cEntries, lppe );
- return 0;
+ ENHMETAHEADER* enhHeader = EMF_GetEnhMetaHeader( hEmf );
+ UINT uReturnValue = GDI_ERROR;
+ EMF_PaletteCopy infoForCallBack;
+
+ TRACE( "(%04x,%d,%p)\n", hEmf, cEntries, lpPe );
+
+ /* First check if there are any palettes associated with
+ this metafile. */
+ if ( enhHeader->nPalEntries == 0 )
+ {
+ /* No palette associated with this enhanced metafile */
+ uReturnValue = 0;
+ goto done;
+ }
+
+ /* Is the user requesting the number of palettes? */
+ if ( lpPe == NULL )
+ {
+ uReturnValue = (UINT)enhHeader->nPalEntries;
+ goto done;
+ }
+
+ /* Copy cEntries worth of PALETTEENTRY structs into the buffer */
+ infoForCallBack.cEntries = cEntries;
+ infoForCallBack.lpPe = lpPe;
+
+ if ( !EnumEnhMetaFile( 0, hEmf, cbEnhPaletteCopy,
+ &infoForCallBack, NULL ) )
+ {
+ goto done;
+ }
+
+ /* Verify that the callback executed correctly */
+ if ( infoForCallBack.lpPe != NULL )
+ {
+ /* Callback proc had error! */
+ ERR( "cbEnhPaletteCopy didn't execute correctly\n" );
+ goto done;
+ }
+
+ uReturnValue = infoForCallBack.cEntries;
+
+done:
+
+ EMF_ReleaseEnhMetaHeader( hEmf );
+
+ return uReturnValue;
}
/******************************************************************
@@ -906,7 +1115,7 @@
EMF_ReAllocAndAdjustPointers(PEMRPOLYGON16,uRecord);
/* FIXME: This is mostly all wrong */
- lpRecord->emr.iType =
+ lpRecord->emr.iType = EMR_POLYGON16;
lpRecord->emr.nSize = sizeof( *lpRecord );
lpRecord->rclBounds.left = 0;