|
|
/**************************************************************************\
* * Copyright (c) 1999 Microsoft Corporation * * Module Name: * * MetaWmf.hpp * * Abstract: * * Metafile definitions for WMF and EMF playback * * Created: * * 1/6/2000 DCurtis * \**************************************************************************/
#ifndef _METAWMF_HPP
#define _METAWMF_HPP
//#define GDIP_EXCEPTIONS 0
#define GDIP_TRY __try {
#define GDIP_CATCH } __except(EXCEPTION_EXECUTE_HANDLER) {
#define GDIP_ENDCATCH }
#define GDIP_RECORDBUFFER_SIZE 2048 // >= 1138 so pattern brushes work
#define SIZEOF_METARECORDHEADER (sizeof(DWORD) + sizeof(WORD))
#define NUM_STOCK_FONTS (DEFAULT_GUI_FONT - OEM_FIXED_FONT + 1)
#define NUM_STOCK_RECOLOR_OBJS 7
/*****************************************************************************
Commenting.
These interfaces allow comments to be added to a metafile DC which describe grouping and other information useful for decoding metafiles, the interfaces which take an MSODC have no effect if the DC is not a picture (PICT, WMF or EMF) DC.
For PICT files there are two levels of structure, the public comment "kind" which is a globally defined comment and the "private" comment kind, which is used for application-specific comments. In a PICT the public comment kind is the kind argument to PicComment and the private kind is used if the public value is pictApplicationComment.
In a WMF the signature indicates whether the comment is public or private, all comments look like the PICT private comment.
In an EMF GdiComment() defines some "public" comments plus a format for "private" comments - see the Win32 API documentation. ******************************************************************* JohnBo **/
// Definition of the comment codes used in the various metafile formats.
const ULONG msosignaturePublic =0xFFFFFFFF; // WMF public signature.
const ULONG msosignaturePPOld =0x5050FE54; // PowerPoint 2 signature
const ULONG msosignaturePP =0x50504E54; // PowerPoint signature
const ULONG msosignature =0x50504E54; // Office/Escher signature
// The following enumeration defines the ukind values in the above structure,
// note that these duplicate the PICT comment kinds for groups because in
// a WMF (but *NOT* a PICT or EMF) and MSOMFCOMMENT structure must be used,
// this enumeration contains all the valid kinds, including both the public
// and private kinds, these may overlap because they are distinguished by
// the "signature".
typedef enum { // Public WMF comments - signature == msosignaturePublic.
msocommentBeginGroup = 0x0000, // Public WMF begin group.
msocommentEndGroup = 0x0001, // Public WMF end group.
msocommentBeginHeader = 0x0002, msocommentEndHeader = 0x0003, msocommentCreator = 0x0004, msocommentWinVersion = 0x0005,
// Private PICT and WMF comments - signature == msosignature.
msocommentVersion = 0x0000, msocommentBFileBlock = 0x0001, // UNUSED
msocommentBeginPicture = 0x0002, msocommentEndPicture = 0x0003, msocommentDevInfo = 0x0004, msocommentBeginHyperOpaque = 0x0005, // UNUSED
msocommentEndHyperOpaque = 0x0006, // UNUSED
msocommentBeginFade = 0x0007, msocommentEndFade = 0x0008, msocommentDitherDetect = 0x0009, // Not used now?
// New values used in Office97.
msocommentPictureDescription = 0x0101, // Description text.
msocommentBeginGelEffect = 0x0102, msocommentEndGelEffect = 0x0103, msocommentBeginClipPath = 0x0104, msocommentEndClipPath = 0x0105, msocommentBeginSrcCopy = 0x0106, msocommentEndSrcCopy = 0x0107,
// Reserved comments used internally by Mac PP4.
msocommentPictUnmute = 0x7FFE, msocommentPictMute = 0x7FFF,
// The following is a flag - what is it for?
msocommentRegistered = 0x8000 } MSOMFCOMMENTKIND;
typedef struct { UINT Handle; COLORREF Color; BOOL Brush; } RecolorStockObject;
extern RecolorStockObject RecolorStockObjectList[NUM_STOCK_RECOLOR_OBJS];
enum GdipHdcType { UnknownHdc = 0x00000000, ScreenHdc = 0x00000001, BitmapHdc = 0x00000002, MetafileHdc = 0x00000004, PrinterHdc = 0x00000008, PostscriptHdc = 0x00010000, PostscriptPrinterHdc = PrinterHdc | PostscriptHdc, EmfHdc = 0x00100000 | MetafileHdc, WmfHdc = 0x00200000 | MetafileHdc, };
enum MfFsmState { MfFsmStart, MfFsmPSData, MfFsmCreateBrushIndirect, MfFsmSelectBrush, MfFsmCreatePenIndirect, MfFsmSelectPen, MfFsmSetROP, };
class MfEnumState { protected: GdipHdcType HdcType; HDC Hdc; INT SaveDcVal; INT SaveDcCount; INT NumObjects; // num objects in handle table
INT SizeAllocedRecord; INT ModifiedRecordSize; INT BytesEnumerated; BOOL ExternalEnumeration; HPALETTE CurrentPalette; HFONT DefaultFont; HFONT StockFonts[NUM_STOCK_FONTS]; HANDLETABLE * HandleTable; GpRecolor * Recolor; ColorAdjustType AdjustType; const BYTE * RecordData; UINT RecordDataSize; EmfPlusRecordType RecordType; InterpolationMode Interpolation; BOOL Is8Bpp; BOOL IsHalftonePalette; COLORREF BkColor; COLORREF TextColor; RECT DestRectDevice; BOOL RopUsed; DpContext * Context; union { const VOID * CurrentRecord; const METARECORD * CurrentWmfRecord; const ENHMETARECORD * CurrentEmfRecord; }; union { VOID * ModifiedRecord; METARECORD * ModifiedWmfRecord; ENHMETARECORD * ModifiedEmfRecord; }; union { VOID * AllocedRecord; METARECORD * AllocedWmfRecord; ENHMETARECORD * AllocedEmfRecord; }; BYTE RecordBuffer[GDIP_RECORDBUFFER_SIZE]; MfFsmState FsmState; BOOL GdiCentricMode; BOOL SoftekFilter; HGDIOBJ RecoloredStockHandle[NUM_STOCK_RECOLOR_OBJS]; BOOL SrcCopyOnly;
public: MfEnumState( HDC hdc, BOOL externalEnumeration, InterpolationMode interpolation, GpRecolor * recolor, ColorAdjustType adjustType, const RECT * dest, DpContext * context ); ~MfEnumState();
BOOL IsValid() { return (SaveDcVal != 0); } BOOL IsMetafile() { return ((HdcType & MetafileHdc) == MetafileHdc); } BOOL IsPostscript() { return ((HdcType & PostscriptHdc) == PostscriptHdc); } BOOL IsPrinter() { return ((HdcType & PrinterHdc) == PrinterHdc);} BOOL IsPostscriptPrinter(){ return ((HdcType & PostscriptPrinterHdc) == PostscriptPrinterHdc);} BOOL IsBitmap() { return ((HdcType & BitmapHdc) == BitmapHdc); } BOOL IsScreen() { return ((HdcType & ScreenHdc) == ScreenHdc); } BOOL GetRopUsed() { return RopUsed; } VOID ResetRopUsed() { RopUsed = FALSE; }
VOID StartRecord( HDC hdc, HANDLETABLE * handleTable, INT numObjects, const VOID * currentRecord, EmfPlusRecordType recordType, UINT recordDataSize, const BYTE * recordData ) { ASSERT(hdc != NULL);
Hdc = hdc; ModifiedRecord = NULL; ModifiedRecordSize = 0; CurrentRecord = currentRecord; RecordType = recordType; RecordDataSize = recordDataSize; RecordData = recordData; BytesEnumerated += GetCurrentRecordSize();
if ((handleTable != NULL) && (numObjects > 0)) { HandleTable = handleTable; NumObjects = numObjects; } else { WARNING(("NULL handle table and/or no objects")); HandleTable = NULL; NumObjects = 0; } }
virtual BOOL ProcessRecord( EmfPlusRecordType recordType, UINT recordDataSize, const BYTE * recordData ) = 0;
virtual BOOL PlayRecord() = 0;
VOID SaveHdc() { SaveDcCount--; this->PlayRecord(); }
virtual VOID RestoreHdc() = 0; VOID SelectPalette(INT objectIndex);
protected: virtual INT GetCurrentRecordSize() const = 0; BOOL CreateRecordToModify(INT size = 0); COLORREF ModifyColor( COLORREF color, ColorAdjustType adjustType ); INT GetModifiedDibSize( BITMAPINFOHEADER UNALIGNED * dibInfo, UINT numPalEntries, UINT dibBitsSize, UINT & usage ); VOID ModifyDib( UINT usage, BITMAPINFOHEADER UNALIGNED * srcDibInfo, BYTE * srcBits, BITMAPINFOHEADER UNALIGNED * dstDibInfo, UINT numPalEntries, UINT srcDibBitsSize, ColorAdjustType adjustType ); VOID Modify16BppDib( INT width, INT posHeight, BYTE * srcPixels, DWORD UNALIGNED * bitFields, BYTE * dstPixels, ColorAdjustType adjustType ); VOID Modify24BppDib( INT width, INT posHeight, BYTE * srcPixels, DWORD UNALIGNED * bitFields, BYTE * dstPixels, ColorAdjustType adjustType ); VOID Modify32BppDib( INT width, INT posHeight, BYTE * srcPixels, DWORD UNALIGNED * bitFields, BYTE * dstPixels, ColorAdjustType adjustType ); VOID OutputDIB( HDC hdc, const RECTL * bounds, INT dstX, INT dstY, INT dstWidth, INT dstHeight, INT srcX, INT srcY, INT srcWidth, INT srcHeight, BITMAPINFOHEADER UNALIGNED * dibInfo, BYTE * bits, // if NULL, this is a packed DIB
UINT usage, DWORD rop, BOOL isWmfDib ); virtual BOOL CreateAndPlayOutputDIBRecord( HDC hdc, const RECTL * bounds, INT dstX, INT dstY, INT dstWidth, INT dstHeight, INT srcX, INT srcY, INT srcWidth, INT srcHeight, BITMAPINFOHEADER UNALIGNED * dibInfo, BYTE * bits, // if NULL, this is a packed DIB
UINT usage, DWORD rop )=0;
virtual BOOL CreateAndPlayCommentRecord() { return TRUE; }
virtual VOID IntersectDestRect()=0; };
class WmfEnumState : public MfEnumState { public: BOOL IgnorePostscript;
protected: INT MetafileSize; HPEN HpenSave; HBRUSH HbrushSave; HPALETTE HpaletteSave; HFONT HfontSave; HBITMAP HbitmapSave; HRGN HregionSave; BOOL FirstViewportOrg; BOOL FirstViewportExt; GpMatrix ViewportXForm; POINT ImgViewportOrg; SIZE ImgViewportExt; POINT DstViewportOrg; SIZE DstViewportExt; BOOL IsFirstRecord;
public: WmfEnumState( HDC hdc, HMETAFILE hWmf, BOOL externalEnumeration, InterpolationMode interpolation, const RECT * dstRect, const RECT * deviceRect, DpContext * context, GpRecolor * recolor = NULL, ColorAdjustType adjustType = ColorAdjustTypeDefault ); ~WmfEnumState();
virtual BOOL ProcessRecord( EmfPlusRecordType recordType, UINT recordDataSize, const BYTE * recordData );
virtual BOOL PlayRecord(); virtual VOID RestoreHdc();
VOID EndRecord(); VOID SetBkColor() { BkColor = *((COLORREF UNALIGNED *)&(((WORD UNALIGNED *)RecordData)[0])); ModifyRecordColor(0, ColorAdjustTypeBrush); this->PlayRecord(); } VOID SetTextColor() { TextColor = *((COLORREF UNALIGNED *)&(((WORD UNALIGNED *)RecordData)[0])); ModifyRecordColor(0, ColorAdjustTypeText); this->PlayRecord(); } VOID FloodFill() { ModifyRecordColor(0, ColorAdjustTypeBrush); this->PlayRecord(); } VOID ExtFloodFill() { ModifyRecordColor(1, ColorAdjustTypeBrush); this->PlayRecord(); } VOID SetPixel() { ModifyRecordColor(0, ColorAdjustTypePen); this->PlayRecord(); } VOID DibCreatePatternBrush(); VOID CreatePatternBrush(); VOID CreatePenIndirect(); VOID CreateBrushIndirect(); VOID BitBlt(); VOID StretchBlt() { this->BitBlt(); } VOID Escape(); VOID SetDIBitsToDevice(); VOID PolyPolygon(); VOID DIBBitBlt(); VOID DIBStretchBlt() { this->DIBBitBlt(); } VOID StretchDIBits(); VOID SetViewportOrg(); VOID SetViewportExt(); VOID Rectangle(); VOID CreateFontIndirect(); VOID SelectObject(); VOID CreateRegion(); VOID SetROP2();
protected: virtual INT GetCurrentRecordSize() const { return RecordDataSize + SIZEOF_METARECORDHEADER; } BOOL CreateCopyOfCurrentRecord(); VOID ModifyRecordColor( INT paramIndex, ColorAdjustType adjustType ); VOID MakeSolidBlackBrush(); VOID CalculateViewportMatrix(); virtual BOOL CreateAndPlayOutputDIBRecord( HDC hdc, const RECTL * bounds, INT dstX, INT dstY, INT dstWidth, INT dstHeight, INT srcX, INT srcY, INT srcWidth, INT srcHeight, BITMAPINFOHEADER UNALIGNED * dibInfo, BYTE * bits, // if NULL, this is a packed DIB
UINT usage, DWORD rop );
virtual VOID IntersectDestRect(); };
class EmfEnumState : public MfEnumState { protected: HRGN ClipRgn; POINT BrushOrg; HPALETTE Palette;
public: EmfEnumState( HDC hdc, HENHMETAFILE hEmf, const RECT * dest, const RECT * deviceRect, BOOL externalEnumeration, InterpolationMode interpolation, DpContext * context, GpRecolor * recolor = NULL, ColorAdjustType adjustType = ColorAdjustTypeDefault ); ~EmfEnumState() { GpFree(AllocedRecord);
if (IsMetafile()) { // Bug 106406 from Office: Missing RestoreDC in EMF
// Account for unbalanced SaveDC/RestoreDC pairs and
// restore to the saveDC state
::RestoreDC(Hdc, SaveDcCount - 1); } else { ::RestoreDC(Hdc, SaveDcVal); } }
virtual BOOL ProcessRecord( EmfPlusRecordType recordType, UINT recordDataSize, const BYTE * recordData );
// returns a pointer to the current record, but the header may
// not actually be there -- just the data of the record.
const ENHMETARECORD * GetPartialRecord() { if (CurrentEmfRecord != NULL) { return CurrentEmfRecord; } ASSERT(RecordData != NULL); return (const ENHMETARECORD *)(((const BYTE *)RecordData) - sizeof(EMR)); }
virtual BOOL PlayRecord(); virtual VOID RestoreHdc();
VOID Header(); VOID SelectPalette(INT objectIndex); VOID SetPixelV() { ModifyRecordColor(2, ColorAdjustTypePen); this->PlayRecord(); } VOID SetTextColor() { TextColor = ((COLORREF *)RecordData)[0]; ModifyRecordColor(0, ColorAdjustTypeText); this->PlayRecord(); } VOID SetBkColor() { BkColor = ((COLORREF *)RecordData)[0]; ModifyRecordColor(0, ColorAdjustTypeBrush); this->PlayRecord(); } VOID CreatePen(); VOID CreateBrushIndirect(); VOID ExtFloodFill() { ModifyRecordColor(2, ColorAdjustTypeBrush); this->PlayRecord(); } VOID GdiComment(); VOID BitBlt(); VOID StretchBlt(); VOID SetDIBitsToDevice(); VOID StretchDIBits(); VOID CreateDibPatternBrushPt(); VOID ExtCreatePen(); VOID MaskBlt() { // !!! to do
ResetRecordBounds(); this->PlayRecord(); } VOID PlgBlt() { // !!! to do
ResetRecordBounds(); this->PlayRecord(); } VOID GradientFill() { // !!! to do
this->PlayRecord(); } VOID TransparentBlt() { // !!! to do
ResetRecordBounds(); this->PlayRecord(); } VOID AlphaBlend() { // !!! to do
ResetRecordBounds(); this->PlayRecord(); } VOID ExtEscape(); VOID ExtCreateFontIndirect(); VOID SelectObject(); VOID SetROP2(); VOID ExtTextOutW(); VOID Rectangle();
protected: virtual INT GetCurrentRecordSize() const { return RecordDataSize + sizeof(EMR); } BOOL CreateCopyOfCurrentRecord(); VOID ModifyRecordColor( INT paramIndex, ColorAdjustType adjustType ); BOOL ValidObjectIndex(INT objectIndex) { return ((objectIndex > 0) && (objectIndex < NumObjects)); } BITMAPINFOHEADER * CreateModifiedDib( BITMAPINFOHEADER * srcDibInfo, BYTE * srcBits, UINT & usage, DWORD rop ); virtual BOOL CreateAndPlayOutputDIBRecord( HDC hdc, const RECTL * bounds, INT dstX, INT dstY, INT dstWidth, INT dstHeight, INT srcX, INT srcY, INT srcWidth, INT srcHeight, BITMAPINFOHEADER UNALIGNED * dibInfo, BYTE * bits, // if NULL, this is a packed DIB
UINT usage, DWORD rop ); virtual VOID IntersectDestRect();
VOID ResetRecordBounds(); virtual BOOL CreateAndPlayCommentRecord() { // This will create an Empty comment record and play it through GDI
// This is necessary to invalidate the Transform cache that Win9x keeps
// while playing metafiles. If we need to query the current transform
// this makes sure that the result is the current one and not the
// previously cached transform
// Allocate a comment buffer that has 1 DWORD in the Data field.
BYTE buffer[(sizeof(EMRGDICOMMENT)+3) & ~3]; EMRGDICOMMENT* comment = (EMRGDICOMMENT*) buffer; comment->emr.iType = EMR_GDICOMMENT; comment->emr.nSize = (sizeof(EMRGDICOMMENT)+3) & ~3; comment->cbData = 4; *(DWORD*)(comment->Data) = 0;
return PlayEnhMetaFileRecord(Hdc, HandleTable, (ENHMETARECORD*)comment, NumObjects); }
};
BOOL GetDibNumPalEntries( BOOL isWmfDib, UINT biSize, UINT biBitCount, UINT biCompression, UINT biClrUsed, UINT * numPalEntries );
UINT GetDibBitsSize( BITMAPINFOHEADER UNALIGNED * dibInfo );
inline static BOOL IsSourceInRop3( DWORD rop3 ) { return (rop3 & 0xCCCC0000) != ((rop3 << 2) & 0xCCCC0000); }
#endif // !_METAWMF_HPP
|