/**************************************************************************\ | |
* | |
* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved. | |
* | |
* Module Name: | |
* | |
* Metafile headers | |
* | |
* Abstract: | |
* | |
* Declarations for various metafile header structures. | |
* | |
\**************************************************************************/ | |
#ifndef _GDIPLUSMETAHEADER_H | |
#define _GDIPLUSMETAHEADER_H | |
typedef struct | |
{ | |
DWORD iType; // Record type EMR_HEADER | |
DWORD nSize; // Record size in bytes. This may be greater | |
// than the sizeof(ENHMETAHEADER). | |
RECTL rclBounds; // Inclusive-inclusive bounds in device units | |
RECTL rclFrame; // Inclusive-inclusive Picture Frame of metafile in .01 mm units | |
DWORD dSignature; // Signature. Must be ENHMETA_SIGNATURE. | |
DWORD nVersion; // Version number | |
DWORD nBytes; // Size of the metafile in bytes | |
DWORD nRecords; // Number of records in the metafile | |
WORD nHandles; // Number of handles in the handle table | |
// Handle index zero is reserved. | |
WORD sReserved; // Reserved. Must be zero. | |
DWORD nDescription; // Number of chars in the unicode description string | |
// This is 0 if there is no description string | |
DWORD offDescription; // Offset to the metafile description record. | |
// This is 0 if there is no description string | |
DWORD nPalEntries; // Number of entries in the metafile palette. | |
SIZEL szlDevice; // Size of the reference device in pels | |
SIZEL szlMillimeters; // Size of the reference device in millimeters | |
} ENHMETAHEADER3; | |
// Aldus Placeable Metafiles | |
// Placeable Metafiles were created by Aldus Corporation as a non-standard | |
// way of specifying how a metafile is mapped and scaled on an output device. | |
// Placeable metafiles are quite wide-spread, but not directly supported by | |
// the Windows API. To playback a placeable metafile using the Windows API, | |
// you will first need to strip the placeable metafile header from the file. | |
// This is typically performed by copying the metafile to a temporary file | |
// starting at file offset 22 (0x16). The contents of the temporary file may | |
// then be used as input to the Windows GetMetaFile(), PlayMetaFile(), | |
// CopyMetaFile(), etc. GDI functions. | |
// Each placeable metafile begins with a 22-byte header, | |
// followed by a standard metafile: | |
#include <pshpack2.h> // set structure packing to 2 | |
typedef struct | |
{ | |
INT16 Left; | |
INT16 Top; | |
INT16 Right; | |
INT16 Bottom; | |
} APMRect16; | |
typedef struct | |
{ | |
UINT32 Key; // GDIP_WMF_ALDUSKEY | |
INT16 Hmf; // Metafile HANDLE number (always 0) | |
APMRect16 BoundingBox; // Coordinates in metafile units | |
INT16 Inch; // Number of metafile units per inch | |
UINT32 Reserved; // Reserved (always 0) | |
INT16 Checksum; // Checksum value for previous 10 WORDs | |
} APMFileHeader; | |
#include <poppack.h> | |
// Key contains a special identification value that indicates the presence | |
// of a placeable metafile header and is always 0x9AC6CDD7. | |
// Handle is used to stored the handle of the metafile in memory. When written | |
// to disk, this field is not used and will always contains the value 0. | |
// Left, Top, Right, and Bottom contain the coordinates of the upper-left | |
// and lower-right corners of the image on the output device. These are | |
// measured in twips. | |
// A twip (meaning "twentieth of a point") is the logical unit of measurement | |
// used in Windows Metafiles. A twip is equal to 1/1440 of an inch. Thus 720 | |
// twips equal 1/2 inch, while 32,768 twips is 22.75 inches. | |
// Inch contains the number of twips per inch used to represent the image. | |
// Normally, there are 1440 twips per inch; however, this number may be | |
// changed to scale the image. A value of 720 indicates that the image is | |
// double its normal size, or scaled to a factor of 2:1. A value of 360 | |
// indicates a scale of 4:1, while a value of 2880 indicates that the image | |
// is scaled down in size by a factor of two. A value of 1440 indicates | |
// a 1:1 scale ratio. | |
// Reserved is not used and is always set to 0. | |
// Checksum contains a checksum value for the previous 10 WORDs in the header. | |
// This value can be used in an attempt to detect if the metafile has become | |
// corrupted. The checksum is calculated by XORing each WORD value to an | |
// initial value of 0. | |
// If the metafile was recorded with a reference Hdc that was a display. | |
#define GDIP_EMFPLUSFLAGS_DISPLAY 0x00000001 | |
class MetafileHeader | |
{ | |
public: | |
MetafileType Type; | |
UINT Size; // Size of the metafile (in bytes) | |
UINT Version; // EMF+, EMF, or WMF version | |
UINT EmfPlusFlags; | |
REAL DpiX; | |
REAL DpiY; | |
INT X; // Bounds in device units | |
INT Y; | |
INT Width; | |
INT Height; | |
union | |
{ | |
METAHEADER WmfHeader; | |
ENHMETAHEADER3 EmfHeader; | |
}; | |
INT EmfPlusHeaderSize; // size of the EMF+ header in file | |
INT LogicalDpiX; // Logical Dpi of reference Hdc | |
INT LogicalDpiY; // usually valid only for EMF+ files | |
public: | |
// Get the metafile type | |
MetafileType GetType() const { return Type; } | |
// Get the size of the metafile in BYTEs | |
UINT GetMetafileSize() const { return Size; } | |
// If IsEmfPlus, this is the EMF+ version; else it is the WMF or EMF version | |
UINT GetVersion() const { return Version; } | |
// Get the EMF+ flags associated with the metafile | |
UINT GetEmfPlusFlags() const { return EmfPlusFlags; } | |
// Get the X Dpi of the metafile | |
REAL GetDpiX() const { return DpiX; } | |
// Get the Y Dpi of the metafile | |
REAL GetDpiY() const { return DpiY; } | |
// Get the bounds of the metafile in device units | |
VOID GetBounds (OUT Rect *rect) const | |
{ | |
rect->X = X; | |
rect->Y = Y; | |
rect->Width = Width; | |
rect->Height = Height; | |
} | |
// Is it any type of WMF (standard or Aldus Placeable Metafile)? | |
BOOL IsWmf() const | |
{ | |
return ((Type == MetafileTypeWmf) || (Type == MetafileTypeWmfAldus)); | |
} | |
// Is this an Aldus Placeable Metafile? | |
BOOL IsWmfAldus() const { return (Type == MetafileTypeWmf); } | |
// Is this an EMF (not an EMF+)? | |
BOOL IsEmf() const { return (Type == MetafileTypeEmf); } | |
// Is this an EMF or EMF+ file? | |
BOOL IsEmfOrEmfPlus() const { return (Type >= MetafileTypeEmf); } | |
// Is this an EMF+ file? | |
BOOL IsEmfPlus() const { return (Type >= MetafileTypeEmfPlusOnly); } | |
// Is this an EMF+ dual (has dual, down-level records) file? | |
BOOL IsEmfPlusDual() const { return (Type == MetafileTypeEmfPlusDual); } | |
// Is this an EMF+ only (no dual records) file? | |
BOOL IsEmfPlusOnly() const { return (Type == MetafileTypeEmfPlusOnly); } | |
// If it's an EMF+ file, was it recorded against a display Hdc? | |
BOOL IsDisplay() const | |
{ | |
return (IsEmfPlus() && | |
((EmfPlusFlags & GDIP_EMFPLUSFLAGS_DISPLAY) != 0)); | |
} | |
// Get the WMF header of the metafile (if it is a WMF) | |
const METAHEADER * GetWmfHeader() const | |
{ | |
if (IsWmf()) | |
{ | |
return &WmfHeader; | |
} | |
return NULL; | |
} | |
// Get the EMF header of the metafile (if it is an EMF) | |
const ENHMETAHEADER3 * GetEmfHeader() const | |
{ | |
if (IsEmfOrEmfPlus()) | |
{ | |
return &EmfHeader; | |
} | |
return NULL; | |
} | |
}; | |
#endif | |