|
|
/*****************************************************************************
* * parser.cxx - Parser for the Win32 to Win16 metafile converter. * * Date: 8/13/91 * Author: Jeffrey Newman (c-jeffn) * * Copyright 1991 Microsoft Corp *****************************************************************************/
#include "precomp.h"
#pragma hdrstop
#define EMR_LAST_MF3216_SUPPORTED 97
BOOL bGetNextRecord(PLOCALDC pLocalDC, PENHMETARECORD *pemr) ;
// Call table for the translation entry points.
PDOFN pdofnDrawingOrders[] = { (PDOFN) NULL, bHandleHeader, // EMR_HEADER 1
bHandlePolyBezier, // EMR_POLYBEZIER 2
bHandlePolygon, // EMR_POLYGON 3
bHandlePolyline, // EMR_POLYLINE 4
bHandlePolyBezierTo, // EMR_POLYBEZIERTO 5
bHandlePolylineTo, // EMR_POLYLINETO 6
bHandlePolyPolyline, // EMR_POLYPOLYLINE 7
bHandlePolyPolygon, // EMR_POLYPOLYGON 8
bHandleSetWindowExt, // EMR_SETWINDOWEXTEX 9
bHandleSetWindowOrg, // EMR_SETWINDOWORGEX 10
bHandleSetViewportExt, // EMR_SETVIEWPORTEXTEX 11
bHandleSetViewportOrg, // EMR_SETVIEWPORTORGEX 12
bHandleNotImplemented, // EMR_SETBRUSHORGEX 13
bHandleEOF, // EMR_EOF 14
bHandleSetPixel, // EMR_SETPIXELV 15
bHandleSetMapperFlags, // EMR_SETMAPPERFLAGS 16
bHandleSetMapMode, // EMR_SETMAPMODE 17
bHandleSetBkMode, // EMR_SETBKMODE 18
bHandleSetPolyFillMode, // EMR_SETPOLYFILLMODE 19
bHandleSetRop2, // EMR_SETROP2 20
bHandleSetStretchBltMode, // EMR_SETSTRETCHBLTMODE 21
bHandleSetTextAlign, // EMR_SETTEXTALIGN 22
bHandleNotImplemented, // EMR_SETCOLORADJUSTMENT 23
bHandleSetTextColor, // EMR_SETTEXTCOLOR 24
bHandleSetBkColor, // EMR_SETBKCOLOR 25
bHandleOffsetClipRgn, // EMR_OFFSETCLIPRGN 26
bHandleMoveTo, // EMR_MOVETOEX 27
bHandleSetMetaRgn, // EMR_SETMETARGN 28
bHandleExcludeClipRect, // EMR_EXCLUDECLIPRECT 29
bHandleIntersectClipRect, // EMR_INTERSECTCLIPRECT 30
bHandleScaleViewportExt, // EMR_SCALEVIEWPORTEXTEX 31
bHandleScaleWindowExt, // EMR_SCALEWINDOWEXTEX 32
bHandleSaveDC, // EMR_SAVEDC 33
bHandleRestoreDC, // EMR_RESTOREDC 34
bHandleSetWorldTransform, // EMR_SETWORLDTRANSFORM 35
bHandleModifyWorldTransform, // EMR_MODIFYWORLDTRANSFORM 36
bHandleSelectObject, // EMR_SELECTOBJECT 37
bHandleCreatePen, // EMR_CREATEPEN 38
bHandleCreateBrushIndirect, // EMR_CREATEBRUSHINDIRECT 39
bHandleDeleteObject, // EMR_DELETEOBJECT 40
bHandleAngleArc, // EMR_ANGLEARC 41
bHandleEllipse, // EMR_ELLIPSE 42
bHandleRectangle, // EMR_RECTANGLE 43
bHandleRoundRect, // EMR_ROUNDRECT 44
bHandleArc, // EMR_ARC 45
bHandleChord, // EMR_CHORD 46
bHandlePie, // EMR_PIE 47
bHandleSelectPalette, // EMR_SELECTPALETTE 48
bHandleCreatePalette, // EMR_CREATEPALETTE 49
bHandleSetPaletteEntries, // EMR_SETPALETTEENTRIES 50
bHandleResizePalette, // EMR_RESIZEPALETTE 51
bHandleRealizePalette, // EMR_REALIZEPALETTE 52
bHandleExtFloodFill, // EMR_EXTFLOODFILL 53
bHandleLineTo, // EMR_LINETO 54
bHandleArcTo, // EMR_ARCTO 55
bHandlePolyDraw, // EMR_POLYDRAW 56
bHandleSetArcDirection, // EMR_SETARCDIRECTION 57
bHandleNotImplemented, // EMR_SETMITERLIMIT 58
bHandleBeginPath, // EMR_BEGINPATH 59
bHandleEndPath, // EMR_ENDPATH 60
bHandleCloseFigure, // EMR_CLOSEFIGURE 61
bHandleFillPath, // EMR_FILLPATH 62
bHandleStrokeAndFillPath, // EMR_STROKEANDFILLPATH 63
bHandleStrokePath, // EMR_STROKEPATH 64
bHandleFlattenPath, // EMR_FLATTENPATH 65
bHandleWidenPath, // EMR_WIDENPATH 66
bHandleSelectClipPath, // EMR_SELECTCLIPPATH 67
bHandleAbortPath, // EMR_ABORTPATH 68
bHandleNotImplemented, // 69
bHandleGdiComment, // EMR_GDICOMMENT 70
bHandleFillRgn, // EMR_FILLRGN 71
bHandleFrameRgn, // EMR_FRAMERGN 72
bHandleInvertRgn, // EMR_INVERTRGN 73
bHandlePaintRgn, // EMR_PAINTRGN 74
bHandleExtSelectClipRgn, // EMR_EXTSELECTCLIPRGN 75
bHandleBitBlt, // EMR_BITBLT 76
bHandleStretchBlt, // EMR_STRETCHBLT 77
bHandleMaskBlt, // EMR_MASKBLT 78
bHandlePlgBlt, // EMR_PLGBLT 79
bHandleSetDIBitsToDevice, // EMR_SETDIBITSTODEVICE 80
bHandleStretchDIBits, // EMR_STRETCHDIBITS 81
bHandleExtCreateFont, // EMR_EXTCREATEFONTINDIRECTW 82
bHandleExtTextOut, // EMR_EXTTEXTOUTA 83
bHandleExtTextOut, // EMR_EXTTEXTOUTW 84
bHandlePoly16, // EMR_POLYBEZIER16 85
bHandlePoly16, // EMR_POLYGON16 86
bHandlePoly16, // EMR_POLYLINE16 87
bHandlePoly16, // EMR_POLYBEZIERTO16 88
bHandlePoly16, // EMR_POLYLINETO16 89
bHandlePolyPoly16, // EMR_POLYPOLYLINE16 90
bHandlePolyPoly16, // EMR_POLYPOLYGON16 91
bHandlePoly16, // EMR_POLYDRAW16 92
bHandleCreateMonoBrush, // EMR_CREATEMONOBRUSH 93
bHandleCreateDIBPatternBrush, // EMR_CREATEDIBPATTERNBRUSHPT 94
bHandleExtCreatePen, // EMR_EXTCREATEPEN 95
bHandlePolyTextOut, // EMR_POLYTEXTOUTA 96
bHandlePolyTextOut, // EMR_POLYTEXTOUTW 97
bHandleNotImplemented, // EMR_SETICMMODE 98
bHandleNotImplemented, // EMR_CREATECOLORSPACE 99
bHandleNotImplemented, // EMR_SETCOLORSPACE 100
bHandleNotImplemented, // EMR_DELETECOLORSPACE 101
bHandleNotImplemented, // EMR_GLSRECORD 102
bHandleNotImplemented, // EMR_GLSBOUNDEDRECORD 103
bHandleNotImplemented, // EMR_PIXELFORMAT 104
bHandleNotImplemented, // 105
bHandleNotImplemented, // 106
bHandleNotImplemented, // 107
bHandleNotImplemented, // 108
bHandleNotImplemented, // 109
bHandleNotImplemented, // 110
bHandleNotImplemented, // EMR_COLORCORRECTPALETTE 111
bHandleNotImplemented, // EMR_ALPHABLEND 112
bHandleNotImplemented, // EMR_ALPHADIBBLEND 113
bHandleNotImplemented, // EMR_TRANSPARENTIMAGE 114
bHandleNotImplemented, // EMR_TRANSPARENTDIBIMAGE 115
bHandleNotImplemented // EMR_GRADIENTFILL 116
} ;
#if DBG
PSZ pszMfRecords[] = { "NULL RECORD ", "EMR_HEADER ", "EMR_POLYBEZIER ", "EMR_POLYGON ", "EMR_POLYLINE ", "EMR_POLYBEZIERTO ", "EMR_POLYLINETO ", "EMR_POLYPOLYLINE ", "EMR_POLYPOLYGON ", "EMR_SETWINDOWEXTEX ", "EMR_SETWINDOWORGEX ", "EMR_SETVIEWPORTEXTEX ", "EMR_SETVIEWPORTORGEX ", "EMR_SETBRUSHORGEX ", "EMR_EOF ", "EMR_SETPIXELV ", "EMR_SETMAPPERFLAGS ", "EMR_SETMAPMODE ", "EMR_SETBKMODE ", "EMR_SETPOLYFILLMODE ", "EMR_SETROP2 ", "EMR_SETSTRETCHBLTMODE ", "EMR_SETTEXTALIGN ", "EMR_SETCOLORADJUSTMENT ", "EMR_SETTEXTCOLOR ", "EMR_SETBKCOLOR ", "EMR_OFFSETCLIPRGN ", "EMR_MOVETOEX ", "EMR_SETMETARGN ", "EMR_EXCLUDECLIPRECT ", "EMR_INTERSECTCLIPRECT ", "EMR_SCALEVIEWPORTEXTEX ", "EMR_SCALEWINDOWEXTEX ", "EMR_SAVEDC ", "EMR_RESTOREDC ", "EMR_SETWORLDTRANSFORM ", "EMR_MODIFYWORLDTRANSFORM ", "EMR_SELECTOBJECT ", "EMR_CREATEPEN ", "EMR_CREATEBRUSHINDIRECT ", "EMR_DELETEOBJECT ", "EMR_ANGLEARC ", "EMR_ELLIPSE ", "EMR_RECTANGLE ", "EMR_ROUNDRECT ", "EMR_ARC ", "EMR_CHORD ", "EMR_PIE ", "EMR_SELECTPALETTE ", "EMR_CREATEPALETTE ", "EMR_SETPALETTEENTRIES ", "EMR_RESIZEPALETTE ", "EMR_REALIZEPALETTE ", "EMR_EXTFLOODFILL ", "EMR_LINETO ", "EMR_ARCTO ", "EMR_POLYDRAW ", "EMR_SETARCDIRECTION ", "EMR_SETMITERLIMIT ", "EMR_BEGINPATH ", "EMR_ENDPATH ", "EMR_CLOSEFIGURE ", "EMR_FILLPATH ", "EMR_STROKEANDFILLPATH ", "EMR_STROKEPATH ", "EMR_FLATTENPATH ", "EMR_WIDENPATH ", "EMR_SELECTCLIPPATH ", "EMR_ABORTPATH ", "unknown record ", "EMR_GDICOMMENT ", "EMR_FILLRGN ", "EMR_FRAMERGN ", "EMR_INVERTRGN ", "EMR_PAINTRGN ", "EMR_EXTSELECTCLIPRGN ", "EMR_BITBLT ", "EMR_STRETCHBLT ", "EMR_MASKBLT ", "EMR_PLGBLT ", "EMR_SETDIBITSTODEVICE ", "EMR_STRETCHDIBITS ", "EMR_EXTCREATEFONTINDIRECTW", "EMR_EXTTEXTOUTA ", "EMR_EXTTEXTOUTW ", "EMR_POLYBEZIER16 ", "EMR_POLYGON16 ", "EMR_POLYLINE16 ", "EMR_POLYBEZIERTO16 ", "EMR_POLYLINETO16 ", "EMR_POLYPOLYLINE16 ", "EMR_POLYPOLYGON16 ", "EMR_POLYDRAW16 ", "EMR_CREATEMONOBRUSH ", "EMR_CREATEDIBPATTERNBRUSHP", "EMR_EXTCREATEPEN ", "EMR_POLYTEXTOUTA ", "EMR_POLYTEXTOUTW ", "EMR_SETICMMODE ", "EMR_CREATECOLORSPACE ", "EMR_SETCOLORSPACE ", "EMR_DELETECOLORSPACE ", "EMR_GLSRECORD ", "EMR_GLSBOUNDEDRECORD ", "EMR_PIXELFORMAT ", "105 ", "106 ", "107 ", "108 ", "109 ", "110 ", "EMR_COLORCORRECTPALETTE ", "EMR_ALPHABLEND ", "EMR_ALPHADIBBLEND ", "EMR_TRANSPARENTIMAGE ", "EMR_TRANSPARENTDIBIMAGE ", "EMR_GRADIENTFILL " };
#endif
/*****************************************************************************
* Parse the Win32 metafile. * * The Win32 metafile is represented by the metafile bits pointed to * by pMetafileBits. The metafile bits may be obtained from a memory mapped * file, or from some shared memory (from the clipboard). *****************************************************************************/ BOOL bParseWin32Metafile(PBYTE pMetafileBits, PLOCALDC pLocalDC) { INT iType ; PVOID pVoid ; PENHMETARECORD pemr ; PENHMETAHEADER pMf32Header ; DWORD nFileSize ; BOOL bRet ; INT iRecordCount, iLastError ;
bRet = TRUE ;
// Get the file length from the header.
// Test to make sure the first record is a Win32 Metafile header.
pMf32Header = (PENHMETAHEADER) pMetafileBits ; if ( (pMf32Header->iType != EMR_HEADER) || (pMf32Header->dSignature != ENHMETA_SIGNATURE) ) { RIPS("MF3216: bParseWin32Metafile, First Record not a Win32 Metafile Header\n") ; return(FALSE) ; }
// Record a pointer to the beginning of the Win32 metafile and
// it's length incase we need to emit the Win32 metafile as a comment
// record(s).
pLocalDC->pMf32Bits = (PBYTE) pMf32Header ; pLocalDC->cMf32Bits = pMf32Header->nBytes ;
// Get the file size for the parser.
nFileSize = pMf32Header->nBytes ;
// Initialize pbCurrent, & pbEnd pointers into the
// metafile bits.
pLocalDC->pbCurrent = pMetafileBits ; pLocalDC->pbEnd = pLocalDC->pbCurrent + nFileSize ;
// Init the record count.
iRecordCount = 0 ;
// Go through the metafile bits. Handle each record based on
// it's type. bGetNextRecord returns TRUE if pemr contains
// a pointer to a record.
while (bGetNextRecord(pLocalDC, &pemr)) {
iRecordCount++ ;
// Set up a convienent point to the record.
pVoid = (PVOID) pemr ;
// Handle the record based on it's type.
iType = (INT) pemr->iType ;
// Check if the record type falls within the range of the
// call table. Eventually, all the record handlers should
// be in the call table.
if (iType <= EMR_LAST_MF3216_SUPPORTED) { bRet = pdofnDrawingOrders[iType](pVoid, pLocalDC) ; #if DBG
if (bRet == FALSE) { iLastError = GetLastError() ; PUTS1("MF3216: Error on Win32 Metafile record #: %d\n", iRecordCount) ; PUTS1("\tRecord type: %s\n", pszMfRecords[iType]) ; PUTS1("\tLast Error Code: %08.8X\n", iLastError) ; } #endif
#if 0
if (bRet == FALSE) break ; #else
// In ancient times (i.e., before NT4.0), someone explicitly
// removed the code above which exits the loop if the handler
// fails. Possibly this was a compatibility fix in which
// the app depended on the metafile conversion to continue
// even in the event of a failure.
//
// Unfortunately, this fix also allows the parser to continue
// even if the output buffer has run out of space. To
// minimize the change, we will explicitly look for this case
// and break out of the loop if it happens. (Refer to bEmit()
// in emit.c to see where ERROR_BUFFER_OVERFLOW is set).
if (pLocalDC->flags & ( ERR_BUFFER_OVERFLOW | ERR_XORCLIPPATH ) ) break ; #endif
} else { PUTS1("MF3216: bParseWin32Metafile - record not supported: %d\n", iType) ; } } #if 0
// Display some statictics
if (bRet == TRUE) { PUTS1("MF3216: %d Win32 Metafile records processed\n", iRecordCount) ; } #endif
return(bRet) ; }
/*****************************************************************************
* Get next record * * This is a support routine for bParseWin32Metafile. * It is assumed that pbCurrent, & pbEnd are initialized * the first time this routine is called. * * It returns TRUE if a valid pointer to record is returned in * pemr. If there are not more records FALSE is returned. * * We now need to take into consideration *****************************************************************************/ BOOL bGetNextRecord(PLOCALDC pLocalDC, PENHMETARECORD *ppemr) { DWORD nSize ;
// if we are recreating the objects then go through our list of objects
if (pLocalDC->iXORPass == OBJECTRECREATION) { if (pLocalDC->pW16RecreationSlot == NULL) { // All our objects are created... Set the next record to be the start
// of the second pass
pLocalDC->pbRecord = pLocalDC->pbChange ; pLocalDC->pbCurrent = pLocalDC->pbRecord ; *ppemr = (PENHMETARECORD) pLocalDC->pbCurrent ;
nSize = ((PENHMETARECORD) pLocalDC->pbCurrent)->nSize ; pLocalDC->pbCurrent += nSize ;
pLocalDC->iXORPass = ERASEXORPASS ;
DoSelectObject(pLocalDC, pLocalDC->lholdp32); DoSelectObject(pLocalDC, pLocalDC->lholdbr32);
return TRUE ; } else { PW16RECREATIONSLOT pW16RecreationSlot = pLocalDC->pW16RecreationSlot ; pLocalDC->pW16RecreationSlot = pW16RecreationSlot->pNext ; pLocalDC->pbRecord = (PBYTE) pW16RecreationSlot->pbCreatRec ; pLocalDC->pbCurrent = (PBYTE) pW16RecreationSlot->pbCreatRec ; *ppemr = (PENHMETARECORD) pLocalDC->pbCurrent ; nSize = ((PENHMETARECORD) pLocalDC->pbCurrent)->nSize ; pLocalDC->pbCurrent += nSize ;
LocalFree(pW16RecreationSlot);
return TRUE ; } }
// Check for the end of buffer.
// If this is the end return FALSE and set *ppemr to 0.
if (pLocalDC->pbCurrent == pLocalDC->pbEnd) { *ppemr = (PENHMETARECORD) NULL ; pLocalDC->pbRecord = NULL ; return (FALSE) ; }
// Well it's not the end of the buffer.
// So, return a pointer to this record, update pbCurrent, and
// return TRUE ;
*ppemr = (PENHMETARECORD) pLocalDC->pbCurrent ; pLocalDC->pbRecord = pLocalDC->pbCurrent ;
nSize = ((PENHMETARECORD) pLocalDC->pbCurrent)->nSize ; pLocalDC->pbCurrent += nSize ;
return(TRUE) ;
}
|