| Herd Software Development
|=
DaVinci Graphics Library
|==
DaVinci Documentation Home Search Order


An introduction to metafiles

Design

Windows' GDI, the Graphic Device Interface, is the core software "engine" responsible for displaying graphic data onscreen. GDI is responsible for everything from painting the color of the desktop background to drawing the individual components of dialogs to displaying every text character on the screen. Applications can directly access the GDI for graphics generation through functions such as MoveToEx/LineTo, Rectangle and SetPixel. Metafiles are filed GDI drawing functions. They are basic Windows programming technologies for clipboard data exchange and OLE technology.

Scaleability

Since BMPs can't easily be resized or reproportioned without significant distortion to the image, metafiles are generally used for situations requiring scalability of the image. The GDI drawing functions are executed based on the current resolution of the output device, thus allowing image quality to be the bast the device is able to do.

Drawing a metafile directly to a printer allows the printer to use it's high-quality resolution of 1200 DPI or so, while the screen usually only offers 96 DPI. However some applications - like Delphi's TImage first draw the Metafile to a screen-Bitmap and afterwards use that low-resolution bitmap for printing in poor quality.

A mayor disadvantage of Metafiles is their very limited machine-independence. Changing the printer driver or printing the metafile from another machine might seriously change the image, especially if the fonts used in the MetaFile are not available for the new device or not installed on the new Computer.

Coordinate systems: how metafiles set the proportions of components of an image

The resolution of the output device is not normally known when a metafile is generated. The device could be a 1200dpi professional printer or a 48dpi monitor screen, or anything in between. So applications which generate metafiles use "logical coordinates" rather than fixed ones. Logical coordinates for each component of an image can then be multiplied by an appropriate amount to create the correct length, width and curvature for a component as it will appear on the output device.

Using logical coordinates when outputting the image to a device (in the case of metafiles, outputting is referred to as "playing" the metafile, rather than displaying it) the GDI performs coordinate conversions according to the specifications of the real resolution of the device (SetViewportExtEx and the logical size in the metafile (SetWindowExtEx

Creating a metafile: tips for coding with metafiles

Generation of metafiles begins with the creation of an HDC handle:
HDC hMeta = CreateMetaFile(NULL);

Note that any metafile not created solely for use within the program, then it should be created using MM_ANISOTROPIC mode.
SetMapMode(hMeta,  MM_ANISOTROPIC);
SetWindowExtEx(hMeta, xx, yy, NULL);
SetWindowOrgEx(hMeta, xx, yy, NULL);

Now virtually any drawing function can be executed on the metafile, including creating a line...
MoveTo(hMeta, 100, 100);
LineTo(hMeta, 200, 400);

...drawing a rectangle...
Rectangle(hMeta, 10, 10, 50, 50);

...and outputting text, among others.
HFONT hFont = CreateFont ( ... )
HFONT hFontOld = SelectObject( hMeta, hFont );
ExtTextOuT( hMeta ...)
SelectObject(hMeta, hFontOld);
DeleteObject(hFont)

Important note: Nothing can be read from a metafile. Functions such as DrawText, GetTextMetrics, GetTextExtent and others normally used with DIBs cannot be applied to metafiles.

Before a newly-created metafile can be played, it must be closed. It can be assigned to a hMetafile at the time it is closed to make it available for display.
HMETAFILE hFile = CloseMetaFile(hMeta);

The file can now be played to a device context using PlayMetaFile(hDC, hFile). At this time, SetWindowExt is modified, and the previous device context should be saved before playing by calling SaveDC.

In order to determine the size of the display, applications call SetViewportExt and SetViewportOrg.
PAINTSTRUCT	ps;
HWND		hDC = BeginPaint(hWnd, &ps);
RECT		rc;

GetClientRect(hWnd, &rc);

SetMapMode(hDC, MM_ANISOTROPIC);
SetViewportExtEx(hDC, rc.right, rc.bottom, NULL);
SetViewportOrgEx(hDC, 0, 0, NULL);

PlayMetaFile(hDC, hBild);

Advantages of metafiles

Disadvantages of metafiles

Placeable metafiles

The Windows API functions CreateMetaFile and GetMetaFile make it possible to work with metafiles at file level, but these functions are limited to nonplaceable metafiles. Nonplaceable metafiles do not contain information regarding the default metric size in millimeters or inches required to display the metafile. These metafiles are also devoid of information relating to aspect ratio, so the proportions of the bounding rectangle will not be known when the file is loaded into an application. For this reason, almost all applications use placeable metafiles which typically use the file extension .WMF.

Placeable metafiles also have an additional header, whose structure is documented in the API Windows 3.1 as METAFILEHEADER.

DaVinci will import metafiles regardless of whether they contain a header. Since the data in the header cannot be stored in the HMETAFILE handle, this information is stored in a separate structure called METARESOLUTION.

A .WMF metafile can only be displayed to scale if both a METARESOLUTION structure and a HMETAFILE handle are available to, and used by, the application.