libwmf-0.2.0 Tutorial 1: The API

Contents

Introduction

The figure below illustrates the tripartite division of application, interpreter, and device layer. The internal workings of each of the three is irrelevant; all that matters is the three interfaces which are separate. The core of libwmf is the interpreter, and as such only the interfaces between (a) the interpreter and the application - the API - and (b) the interpreter and the device layer - the IPA - are defined. Applications that wish to implement their own new device layer are free therefore to define whatever interface is suitable.

libwmf includes two device layers: eps for conversion to EPS (Encapsulated Postscript) or PS (Postscript); and gd for conversion to PNG or JPEG image formats. Included with libwmf are converters for these: wmf2eps and wmf2gd respectively. The source-code for these is an excellent place to see how to use the various features of the API and device-layer interfaces.

Header Files

All libwmf header files are now in a libwmf subdirectory. In general you will need to include two. Unless you are writing a new device layer, which will be discussed later, you should include only libwmf/api.h and the header for whichever device layer you are interested in, for example:

#include <libwmf/api.h>
#include <libwmf/gd.h>

The gd device layer uses the GD library, included with libwmf, to output images in PNG (or possibly in JPEG) format. Alternatively, if you wish the output to be in PS or EPS format, you would include:

#include <libwmf/api.h>
#include <libwmf/eps.h>

Creating The API

For each metafile you wish to process and convert to a given image type, you must create an instance of the API. This can be sophisticated or simple. In its simplest form, the only thing that needs to be specified is which device layer you wish to use. For example, to use GD:

	wmfAPI_Options options;
	wmfAPI* API;

	wmf_error_t error;

	unsigned long flags;

	/* */

	flags = WMF_OPT_FUNCTION;

	options.function = wmf_gd_function;

	/* Other Options */

	error = wmf_api_create (&API,flags,&options);
	if (error != wmf_E_None)
	{	wmf_api_destroy (API);

		/* */
	}

	/* */

The library performs all memory allocation with respect to the API, and destroying the instance will free up all associated memory:

	error = wmf_api_destroy (API);

There are a number of different options which can be used when creating the API. The structure of wmfAPI_Options is:

typedef struct _wmfAPI_Options wmfAPI_Options;

struct _wmfAPI_Options
{	void* context;

	void* (*malloc)  (void* context,size_t size);
	void* (*realloc) (void* context,void* mem,size_t size);
	void  (*free)    (void* context,void* mem);

	int    argc;
	char** argv;

	char** fontdirs; /* NULL-terminated list of directories to search for font files */

	struct
	{	wmfFontMap* wmf; /* {0,*}-terminated list: wmf-font-name -> ps-font-name */
		wmfMapping* sub; /* {0,*}-terminated list: wmf-font-name substring equiv */
		wmfMapping* ps;  /* {0,*}-terminated list: ps-font-name -> pfb-file-name */
	} font;

	char* sys_fontmap_file;
	char* xtra_fontmap_file;

	void (*function) (wmfAPI*);

	char*  module;
	char** dirs;

	FILE* debug_out;
	FILE* error_out;
};