The following information is provided as is, and the authors take no responsibility for the correctness.
For GDI+ records embedded in EMF please see the EMF+ documentation.
Enhanced metafiles provide true device independence. You can think of the picture stored in an enhanced metafile as a “snapshot” of the video display taken at a particular moment. This “snapshot” maintains its dimensions no matter where it appears—on a printer, a plotter, the desktop, or in the client area of any application.
You can use enhanced metafiles to store a picture created by using the GDI functions (including new path and transformation functions). Because the enhanced metafile format is standardized, pictures that are stored in this format can be copied from one application to another; and, because the pictures are truly device independent, they are guaranteed to maintain their shape and proportion on any output device.
Internally, a metafile is an array of variable-length structures called metafile records. The first records in the metafile specify general information such as the resolution of the device on which the picture was created, the dimensions of the picture, and so on. The remaining records, which constitute the bulk of any metafile, correspond to the graphics device interface (GDI) functions required to draw the picture. These records are stored in the metafile after a special metafile device context is created. This metafile device context is then used for all drawing operations required to create the picture. When the system processes a GDI function associated with a metafile DC, it converts the function into the appropriate data and stores this data in a record appended to the metafile.
You can find more information about Enhanced metafiles in Feng Yuan’s book "Windows Graphics Programming: Win32 GDI and DirectDraw"
[MS-EMF]: Enhanced Metafile Format Specification |
The following information is provided as is, and the authors take no responsibility for the correctness.
This page will only provide information about some undocumented features. More info about the documented and well known parts can be found in the Microsoft Platform SDK.
The EMF format is described in the Micosoft Windows® Platform SDK.
Enhanced Metafiles in Win32 - Old DDK Help File
enhmet.zip
With GDI+, Microsoft released a new metafile format called EMF+. EMF+ metafiles are much friendlier to GDI+ operations.
For more information please see the EMF+ documentation.
There is also a file format called “Compressed Windows Enhanced Metafile” with the file extension “.EMZ”. The file is a DEFLATE compressed EMF file. You can use zlib to extract the contained EMF file.
The EMF streams which are used in the Windows SPL - Microsoft® Windows Spool File Format files, include various undocumented records.
Including the following record identifiers:
EMR_RESERVED_069 69 (#45) /* WINVER >= #0400 (Windows NT4) */ /* WINVER >= #0500 (Windows 2000) */ EMR_DRAWESCAPE 105 (#69) EMR_EXTESCAPE 106 (#6A) EMR_STARTDOC 107 (#6B) EMR_SMALLTEXTOUT 108 (#6C) EMR_FORCEUFIMAPPING 109 (#6D) EMR_NAMEDESCAPE 110 (#6E) EMR_ALPHABLEND 114 (#72) EMR_TRANSPARENTDIB 117 (#75) EMR_SETLINKEDUFIS 119 (#77) EMR_SETTEXTJUSTIFICATION 120 (#78) EMR_COLORMATCHTOTARGETW 121 (#79) /* WINVER >= #0501 (Windows XP) */
Some records are documented here:
Under Windows 2000, when you create a font in a metafile device context it is saved to a EMREXTCREATEFONTINDIRECTW structure which is 368 bytes in size. Under Windows 95 this structure is only 332 bytes long. The contents of these structures appear to be entirely different after the first 104 bytes.
Does anyone know the new structure of EMR_EXTCREATEFONTINDIRECTW in Windows 2000?
Note that the following code is not consistent. The first data after ihFont is indeed a LOGFONTW, which is the start of an EXTLOGFONTW struct, but the next field after it is not consistent with EXTLOGFONTW as documented in WinGDI.h. Therefore either LOGFONTW or EXTLOGFONTW are being stored differently when the length is 368.
TYPE EMREXTCREATEFONTINDIRECTW_368 = RECORD emr : EMR; ihFont : DWORD; // Font handle index elfw : EXTLOGFONTW; undocumented : array[0..103] of Byte; END;
Part of the undocument array appears to be a DESIGNVECTOR based on the presense of the “STAMP” “dv 0×08” near the end. Every example I have seen has a dvNumAxes of zero. The following is a C type definition of that structure.typedef struct tagDESIGNVECTOR { DWORD dvReserved;//STAMP_DESIGNVECTOR (0x8000000 + 'd' + ('v' << 8)) DWORD dvNumAxes; LONG dvValues[dvNumAxes]; } DESIGNVECTOR;Based on this, I thought the new format might be ENUMLOGFONTEXDVW but the EXTLOGFONTW is off by one DWORD since the ihFont value is missing.
— James Newton 2007/02/01 19:04
TYPE EMREXTESCAPE = RECORD emr : EMR; nEscape : DWORD; nSize : DWORD; // == sizeof(DRAWPATRECT) pattern : DRAWPATRECT; END;
For more information see Printer Escape Functions
Sometimes EMREXTESCAPE records (together with image data) are stored in the spool file even in case the application calls extEscape() simply to check for JPEG or PNG support. Such records seem completely useless during EMF playback, and can significantly increase the data size.
— Zhivko Tabakov 2005/09/05 02:49
If you print out RTF documents via word and if you’re using drawing objects like lines in your document, then this record will be also used to create an escape-sequence (in my case it was a postscript escape-sequenz) for drawing the line. The line also isn’t visible when doing a playback of the emf-spoolfile on screen...
— Joachim Klinger 2006/04/25 03:15
Excel printing also uses this type of record DRAWPATTERNRECT for cell boundings, but only for thin lines! The records are device dependend (printer resolution)
— Dieter Riekert 2007/11/22 20:06
The EMR record type 108 can be 2 different records. EMRSMALLTEXTOUT or EM_SMALLTEXTOUTCLIP. Look at the flags in fOptions, to see what type is used. The fOptions field also specifies if the ANSI or UNICODE version is used.
The interpretation of the reference point depends on the current text-alignment mode. An application can retrieve this mode by calling the getTextAlign function; an application can alter this mode by calling the setTextAlign function.
By default, the current position is not used or updated by this function. However, an application can call the setTextAlign function with the fMode parameter set to TA_UPDATECP to permit the system to use and update the current position each time the application calls textOut for a specified device context. When this flag is set, the system ignores the nXStart and nYStart parameters on subsequent textOut calls.
//Structure select flags //Extra flags in fuOptions, see also ExtTextOut function CONST ETO_NO_RECT = $100; // if set use EMRSMALLTEXTOUT else use EMRSMALLTEXTOUTCLIP ETO_SMALL_CHARS = $200; // if set use ANSI version else UNICODE //Structures TYPE EMRSMALLTEXTOUTCLIPA = RECORD emr : EMR; ptlReference : TPoint; //might be in negative numbers, so take abs nChars : DWORD; fuOptions : DWORD; // this record type // != ETO_NO_RECT // == ETO_SMALL_CHARS // also holds fuOptions like in the ExtTextOut function iGraphicsMode : DWORD; //See iMode parameter of SetGraphicsMode exScale : Single; //X and Y scales from Page units to .01mm units eyScale : Single; // if graphics mode is GM_COMPATIBLE. rclClip : TRect; cString : Array[0..0] of char; //This is followed by the string array END; EMRSMALLTEXTOUTCLIPW = RECORD emr : EMR; ptlReference : TPoint; nChars : DWORD; fuOptions : DWORD; // this record type // != ETO_NO_RECT // != ETO_SMALL_CHARS // also holds fuOptions like in the ExtTextOut function iGraphicsMode : DWORD; //See iMode parameter of SetGraphicsMode exScale : Single; //X and Y scales from Page units to .01mm units eyScale : Single; //if graphics mode is GM_COMPATIBLE. rclClip : TRect; cString : Array[0..0] of WideChar; //This is followed by the string array END; EMRSMALLTEXTOUTA = RECORD emr : EMR; ptlReference : TPoint; nChars : DWORD; fuOptions : DWORD; // this record type // == ETO_NO_RECT // == ETO_SMALL_CHARS // also holds fuOptions like in the ExtTextOut function iGraphicsMode : DWORD; //See iMode parameter of SetGraphicsMode exScale : Single; //X and Y scales from Page units to .01mm units eyScale : Single; //if graphics mode is GM_COMPATIBLE. cString : Array[0..0] of char; //This is followed by the string array END; EMRSMALLTEXTOUTW = RECORD emr : EMR; ptlReference : TPoint; nChars : DWORD; fuOptions : DWORD; // this record type // == ETO_NO_RECT // != ETO_SMALL_CHARS // also holds fuOptions like in the ExtTextOut function iGraphicsMode : DWORD; //See iMode parameter of SetGraphicsMode exScale : Single; //X and Y scales from Page units to .01mm units eyScale : Single; //if graphics mode is GM_COMPATIBLE. cString : Array[0..0] of WideChar; //This is followed by the string array END;
pyemf is a pure python module that provides bindings for an ECMA-234 compliant vector graphics library.
FreeHEP is a Java library which includes a the vector graphics package, that allows to convert EMF Metafiles to SVG, or Java2D drawings to EMF
libEMF is a C/C++ library which provides a drawing toolkit based on ECMA-234. The general purpose of this library is to create vector graphics files on POSIX systems.
Microsoft Developer Network Technology Group (June 10, 1993) Old DDK Help File
A viewer application for EMF format spool files.
Suppose you have a database of “old” EMF/WMF documents. Wouldn’t it be nice if you could pass those documents to a GDI+ function and, magically, get better outputs?
A program to manipulate Windows Metafile data. This open-source software displays, scales, rotates documents, and, using GDI+, optionally enhances their quality.
| Windows Graphics Programming: Win32 GDI and DirectDraw, by Feng Yuan. The world’s most complete guide to Windows graphics programming! -Win32 GDI and DirectDraw: Accurate, under the hood, and in depth -Beyond the API: Internals, restrictions, performance, and real-life problems -Complete: Pixel, lines, curves, filled area, bitmap, image processing, fonts, text, metafile, printing -And more ISBN 0130869856 |