Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

443 lines
22 KiB

/*****************************************************************************
*
* 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)
)
{
RIP("MF3216: bParseWin32Metafile, First Record not a Win32 Metafile Header\n") ;
return(FALSE) ;
}
if (!IsValidEnhMetaRecord(pLocalDC->pht, pMf32Header))
{
EMFVALFAIL(("MF3216: bParseWin32Metafile, IsValidEnhMetaRecord failed\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 ;
if (pLocalDC->pbEnd < pLocalDC->pbCurrent)
{
RIP("MF3216: bParseWin32Metafile, pointer arithmetic overflow\n");
return(FALSE);
}
// 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))
{
if (!IsValidEnhMetaRecord(pLocalDC->pht, pemr))
{
EMFVALFAIL(("MF3216: bParseWin32Metafile, IsValidEnhMetaRecord failed\n"));
bRet = FALSE;
break;
}
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)
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.
*****************************************************************************/
BOOL bGetNextRecord(PLOCALDC pLocalDC, PENHMETARECORD *ppemr)
{
DWORD nSize ;
// 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 ;
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 ;
nSize = ((PENHMETARECORD) pLocalDC->pbCurrent)->nSize ;
pLocalDC->pbCurrent += nSize ;
return(TRUE) ;
}