1 /**************************************************************************\ 2 * 3 * Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved. 4 * 5 * Module Name: 6 * 7 * Metafile headers 8 * 9 * Abstract: 10 * 11 * Declarations for various metafile header structures. 12 * 13 \**************************************************************************/ 14 15 #ifndef _GDIPLUSMETAHEADER_H 16 #define _GDIPLUSMETAHEADER_H 17 18 typedef struct 19 { 20 DWORD iType; // Record type EMR_HEADER 21 DWORD nSize; // Record size in bytes. This may be greater 22 // than the sizeof(ENHMETAHEADER). 23 RECTL rclBounds; // Inclusive-inclusive bounds in device units 24 RECTL rclFrame; // Inclusive-inclusive Picture Frame of metafile in .01 mm units 25 DWORD dSignature; // Signature. Must be ENHMETA_SIGNATURE. 26 DWORD nVersion; // Version number 27 DWORD nBytes; // Size of the metafile in bytes 28 DWORD nRecords; // Number of records in the metafile 29 WORD nHandles; // Number of handles in the handle table 30 // Handle index zero is reserved. 31 WORD sReserved; // Reserved. Must be zero. 32 DWORD nDescription; // Number of chars in the unicode description string 33 // This is 0 if there is no description string 34 DWORD offDescription; // Offset to the metafile description record. 35 // This is 0 if there is no description string 36 DWORD nPalEntries; // Number of entries in the metafile palette. 37 SIZEL szlDevice; // Size of the reference device in pels 38 SIZEL szlMillimeters; // Size of the reference device in millimeters 39 } ENHMETAHEADER3; 40 41 // Aldus Placeable Metafiles 42 43 // Placeable Metafiles were created by Aldus Corporation as a non-standard 44 // way of specifying how a metafile is mapped and scaled on an output device. 45 // Placeable metafiles are quite wide-spread, but not directly supported by 46 // the Windows API. To playback a placeable metafile using the Windows API, 47 // you will first need to strip the placeable metafile header from the file. 48 // This is typically performed by copying the metafile to a temporary file 49 // starting at file offset 22 (0x16). The contents of the temporary file may 50 // then be used as input to the Windows GetMetaFile(), PlayMetaFile(), 51 // CopyMetaFile(), etc. GDI functions. 52 53 // Each placeable metafile begins with a 22-byte header, 54 // followed by a standard metafile: 55 56 #include <pshpack2.h> // set structure packing to 2 57 58 typedef struct 59 { 60 INT16 Left; 61 INT16 Top; 62 INT16 Right; 63 INT16 Bottom; 64 } APMRect16; 65 66 typedef struct 67 { 68 UINT32 Key; // GDIP_WMF_ALDUSKEY 69 INT16 Hmf; // Metafile HANDLE number (always 0) 70 APMRect16 BoundingBox; // Coordinates in metafile units 71 INT16 Inch; // Number of metafile units per inch 72 UINT32 Reserved; // Reserved (always 0) 73 INT16 Checksum; // Checksum value for previous 10 WORDs 74 } APMFileHeader; 75 76 #include <poppack.h> 77 78 // Key contains a special identification value that indicates the presence 79 // of a placeable metafile header and is always 0x9AC6CDD7. 80 81 // Handle is used to stored the handle of the metafile in memory. When written 82 // to disk, this field is not used and will always contains the value 0. 83 84 // Left, Top, Right, and Bottom contain the coordinates of the upper-left 85 // and lower-right corners of the image on the output device. These are 86 // measured in twips. 87 88 // A twip (meaning "twentieth of a point") is the logical unit of measurement 89 // used in Windows Metafiles. A twip is equal to 1/1440 of an inch. Thus 720 90 // twips equal 1/2 inch, while 32,768 twips is 22.75 inches. 91 92 // Inch contains the number of twips per inch used to represent the image. 93 // Normally, there are 1440 twips per inch; however, this number may be 94 // changed to scale the image. A value of 720 indicates that the image is 95 // double its normal size, or scaled to a factor of 2:1. A value of 360 96 // indicates a scale of 4:1, while a value of 2880 indicates that the image 97 // is scaled down in size by a factor of two. A value of 1440 indicates 98 // a 1:1 scale ratio. 99 100 // Reserved is not used and is always set to 0. 101 102 // Checksum contains a checksum value for the previous 10 WORDs in the header. 103 // This value can be used in an attempt to detect if the metafile has become 104 // corrupted. The checksum is calculated by XORing each WORD value to an 105 // initial value of 0. 106 107 // If the metafile was recorded with a reference Hdc that was a display. 108 #define GDIP_EMFPLUSFLAGS_DISPLAY 0x00000001 109 110 class MetafileHeader 111 { 112 public: 113 MetafileType Type; 114 UINT Size; // Size of the metafile (in bytes) 115 UINT Version; // EMF+, EMF, or WMF version 116 UINT EmfPlusFlags; 117 REAL DpiX; 118 REAL DpiY; 119 INT X; // Bounds in device units 120 INT Y; 121 INT Width; 122 INT Height; 123 union 124 { 125 METAHEADER WmfHeader; 126 ENHMETAHEADER3 EmfHeader; 127 }; 128 INT EmfPlusHeaderSize; // size of the EMF+ header in file 129 INT LogicalDpiX; // Logical Dpi of reference Hdc 130 INT LogicalDpiY; // usually valid only for EMF+ files 131 132 public: 133 // Get the metafile type 134 MetafileType GetType() const { return Type; } 135 136 // Get the size of the metafile in BYTEs 137 UINT GetMetafileSize() const { return Size; } 138 139 // If IsEmfPlus, this is the EMF+ version; else it is the WMF or EMF version 140 UINT GetVersion() const { return Version; } 141 142 // Get the EMF+ flags associated with the metafile 143 UINT GetEmfPlusFlags() const { return EmfPlusFlags; } 144 145 // Get the X Dpi of the metafile 146 REAL GetDpiX() const { return DpiX; } 147 148 // Get the Y Dpi of the metafile 149 REAL GetDpiY() const { return DpiY; } 150 151 // Get the bounds of the metafile in device units 152 VOID GetBounds (OUT Rect *rect) const 153 { 154 rect->X = X; 155 rect->Y = Y; 156 rect->Width = Width; 157 rect->Height = Height; 158 } 159 160 // Is it any type of WMF (standard or Aldus Placeable Metafile)? 161 BOOL IsWmf() const 162 { 163 return ((Type == MetafileTypeWmf) || (Type == MetafileTypeWmfAldus)); 164 } 165 166 // Is this an Aldus Placeable Metafile? 167 BOOL IsWmfAldus() const { return (Type == MetafileTypeWmf); } 168 169 // Is this an EMF (not an EMF+)? 170 BOOL IsEmf() const { return (Type == MetafileTypeEmf); } 171 172 // Is this an EMF or EMF+ file? 173 BOOL IsEmfOrEmfPlus() const { return (Type >= MetafileTypeEmf); } 174 175 // Is this an EMF+ file? 176 BOOL IsEmfPlus() const { return (Type >= MetafileTypeEmfPlusOnly); } 177 178 // Is this an EMF+ dual (has dual, down-level records) file? 179 BOOL IsEmfPlusDual() const { return (Type == MetafileTypeEmfPlusDual); } 180 181 // Is this an EMF+ only (no dual records) file? 182 BOOL IsEmfPlusOnly() const { return (Type == MetafileTypeEmfPlusOnly); } 183 184 // If it's an EMF+ file, was it recorded against a display Hdc? 185 BOOL IsDisplay() const 186 { 187 return (IsEmfPlus() && 188 ((EmfPlusFlags & GDIP_EMFPLUSFLAGS_DISPLAY) != 0)); 189 } 190 191 // Get the WMF header of the metafile (if it is a WMF) 192 const METAHEADER * GetWmfHeader() const 193 { 194 if (IsWmf()) 195 { 196 return &WmfHeader; 197 } 198 return NULL; 199 } 200 201 // Get the EMF header of the metafile (if it is an EMF) 202 const ENHMETAHEADER3 * GetEmfHeader() const 203 { 204 if (IsEmfOrEmfPlus()) 205 { 206 return &EmfHeader; 207 } 208 return NULL; 209 } 210 }; 211 212 #endif 213 214