Main Page   Class Hierarchy   Compound List   File List   Compound Members  

libEMF: Enhanced Metafile Library

1.0.1

Table of Contents

Introduction

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 which can be imported into StarOffice/OpenOffice. The Enhanced MetaFile (EMF) is one of the two color vector graphics format which is "vectorially" understood by SO/OO. (SO/OO can import Encapsulated PostScript files, but will only display it if it has a bitmap preview image. SO/OO can also import a DXF file, but as near as I can tell, this is only monochrome. OpenOffice now has an XML based file format; in the future, use of this format will probably supplant this library.) The EMF format also has the additional advantage that it can be "broken" into its constituent components and edited like any other SO/OO graphics object.

My general interest in this library is for making scientific plots with gnuplot and Grace(forthcoming). Therefore, this software includes patches to those programs to add the EMF as an output option. This library is mostly limited to the graphics commands required for gnuplot and Grace output drivers, though it's trivial to add new ones.

It is also possible now to generate EMF files from PSTOEDIT on POSIX systems. Therefore, if your graphics code only outputs PostScript, you can now easily convert it to EMF.

libEMF is hosted on SourceForge. If you have questions or comments, try out the libEMF mailing list.

What's New?

Version 1.0.1 is minor update. libEMF has been updated to compile cleanly with GCC 3.x. The header files have been reorganized slightly so that if the headers are installed in /usr/include, you do not need an extra -I option. You should now access libEMF headers with:

#include <libEMF/emf.h>

Compilation

libEMF uses a standard autoconf-generated configure script to prepare it for compilation. If you want to activate printing of EMF records, run the configure script with:

./configure --enable-editing

A single program is provided which can print the complete contents of a metafie (as far as the library understands them, anyway),

printemf metafile.emf

Documentation

The documentation of this project is generated with Doxygen and is largely for the internals of the library. However, the graphics commands which are available from C are given here.

Example

You will probably only use libEMF in the context of an output driver for another graphics program, but should you want to do some custom graphics generation, here is an annotated example.

#include <libEMF/emf.h> // Will depend on your installation of libEMF

int main ( int argc, char* argv[] )
{

The first step is to create a device context for the metafile. The usual way this is accomplished is by acquiring a copy of the "desktop" device context and using it as a starting point for the metafile device context. libEMF supports the commands GetDesktopWindow() and GetDC(), but they are just dummy functions. The metafile device context has its own internal definitions.

The metafile creation subroutine takes four arguments (the first of which, the reference device context as obtained above, is ignored). The second argument is the path name of the metafile; you can use whatever name is valid on the system, but SO/OO prefers the file to end with the .emf extension. The third argument gives the size and position of the metafile; since SO/OO ignores the position, the first two values should be zero; the second pair of values should give the desired physical width and height of the drawing in units of 1/1000-th centimeters. The last argument to the creation routine is the description of the metafile; by convention, this consists of two null-terminated strings with an extra '\0' at the end.

   HWND desktop = GetDesktopWindow();
   HDC dc = GetDC( desktop );

   RECT size = { 0, 0, 10000, 10000 }; // 10cm x 10cm
   PCSTR filename = "example.emf";
   PCSTR description = "Example metafile created\0with libEMF\0";

   HDC metaDC = CreateEnhMetaFile( 0, filename, &size, description );

Next, we want to set the drawing properties of the pen, brush and font to something other than the default, say a wide, cyan pen and a solid, blue brush, and a bold Helvetica font.

   LOGPEN lpen = { PS_SOLID, {2000,2000}, RGB(0,0xff,0xff) };
   LOGBRUSH lbrush = { BS_SOLID, RGB(0x0,0x0,0xff), HS_HORIZONTAL };
   HPEN pen = CreatePenIndirect( &lpen );
   HBRUSH brush = CreateBrushIndirect( &lbrush );
   HFONT font = CreateFont( -1100, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET,
                      OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
                      DEFAULT_PITCH | FF_DONTCARE, "Helvetica" );

   // Make these the active objects for their respective types

   SelectObject( metaDC, pen );
   SelectObject( metaDC, brush );
   SelectObject( metaDC, font );

Set the window size to the natural coordinates of the drawing. Here, we want to draw on a 100x100 grid.

   SetWindowExtEx( metaDC, 100, 100, 0 );

Now, we can draw as we like. For example, we'll make a solid background with some text centered in the window.

   Rectangle( metaDC, 0, 0, 100, 100 );

   SetTextColor( metaDC, RGB(0,0xff,0) );
   SetTextAlign( metaDC, TA_CENTER+TA_BASELINE );
   SetBkMode( metaDC, TRANSPARENT );
   TextOutA( metaDC, 50, 50, "Welcome to libEMF", 17 );

Finally, the metafile is written to disk when the metafile is closed. Delete the metafile and its assocated device context to free all the memory they have consumed.

   metafile = CloseEnhMetaFile( metaDC );
   DeleteEnhMetaFile( metafile );
   DeleteDC( metaDC );

   return 0;
}

This is result of importing example.emf into OO and exporting the drawing as a PNG file (after using The GIMP to crop the transparent boundary).

example.png

Acknowledgements

Special thanks to Wolfgang Glunz (wglunz@pstoedit.net) for suggestions and help testing.


Copyright © 2002 lignum Computing, Inc., libemf@lignumcomputing.com


Hosted by SourceForge Logo


Generated at Mon Jan 13 21:34:19 2003 for EMF by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001