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
18typedef 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
58typedef struct
59{
60    INT16           Left;
61    INT16           Top;
62    INT16           Right;
63    INT16           Bottom;
64} APMRect16;
65
66typedef 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
110class MetafileHeader
111{
112public:
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
132public:
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