?? api.c
字號:
/* libwmf (api/api.c): library for wmf conversion Copyright (C) 2000 - various; see CREDITS, ChangeLog, and sources The libwmf Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The libwmf Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the libwmf Library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "wmfconfig.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "wmfdefs.h"#include "api/api.h"/** * Creates and initializes an instance of the \b libwmf library for a specified device layer. * * @param API_return pointer to a wmfAPI* (the API handle use henceforth) * @param flags bitwise OR of WMF_OPT_ options * @param options pointer to wmfAPI_Options structure * * This is the first and necessary step when using \b libwmf. Options are passed via the wmfAPI_Options * structure and \p flags. wmf_api_create allocates the wmfAPI structure and initializes the color and * font tables, the metafile player, and the device layer. If successful then the pointer to the wmfAPI * structure is returned via \p API_return, otherwise all allocated memory is released and the library * exits with an appropriate error. * * @return The error state of the library: \b wmf_E_None indicates successful creation and initialization * of the library, and \p *API_return will be non-zero. For any other error value \p *API_return * will be zero. */wmf_error_t wmf_api_create (wmfAPI** API_return,unsigned long flags,wmfAPI_Options* options){ wmfAPI* API = 0; wmfMemoryManager* MM = 0; wmf_error_t err = wmf_E_None; (*API_return) = 0; if (flags & WMF_OPT_ARGS) wmf_arg (&flags,options);/* Initialize memory management array & allocate */ if (flags & WMF_OPT_ALLOC) { MM = (wmfMemoryManager*) options->malloc (options->context,sizeof (wmfMemoryManager)); } else { MM = (wmfMemoryManager*) malloc (sizeof (wmfMemoryManager)); } if (MM == 0) { if ((flags & WMF_OPT_NO_ERROR) == 0) { fputs ("wmf_api_create: insufficient memory!\n",stderr); } return (wmf_E_InsMem); } MM->count = 0; MM->max = 32; if (flags & WMF_OPT_ALLOC) { MM->list = (void**) options->malloc (options->context,MM->max * sizeof (void*)); } else { MM->list = (void**) malloc (MM->max * sizeof (void*)); } if (MM->list == 0) { if ((flags & WMF_OPT_NO_ERROR) == 0) { fputs ("wmf_api_create: insufficient memory!\n",stderr); } if (flags & WMF_OPT_ALLOC) { options->free (options->context,MM); } else { free (MM); } return (wmf_E_InsMem); } if (flags & WMF_OPT_ALLOC) { MM->context = options->context; MM->malloc = options->malloc; MM->realloc = options->realloc; MM->free = options->free; } else { MM->context = 0; MM->malloc = 0; MM->realloc = 0; MM->free = 0; }/* Allocate wmfAPI structure */ if (flags & WMF_OPT_ALLOC) { API = (wmfAPI*) options->malloc (options->context,sizeof (wmfAPI)); } else { API = (wmfAPI*) malloc (sizeof (wmfAPI)); } if (API == 0) { if ((flags & WMF_OPT_NO_ERROR) == 0) { fputs ("wmf_api_create: insufficient memory!\n",stderr); } if (flags & WMF_OPT_ALLOC) { options->free (options->context,MM->list); options->free (options->context,MM); } else { free (MM->list); free (MM); } return (wmf_E_InsMem); } API->memory_data = (void*) MM;/* Initialize debug, error & other streams */ if (flags & WMF_OPT_NO_DEBUG) API->debug_out = 0; else { if (flags & WMF_OPT_LOG_DEBUG) API->debug_out = options->debug_out; else { API->debug_out = stdout; } } if (flags & WMF_OPT_NO_ERROR) API->error_out = 0; else { if (flags & WMF_OPT_LOG_ERROR) API->error_out = options->error_out; else { API->error_out = stderr; } } API->MetaHeader.pmh = &(API->PlaceableMetaHeader); API->MetaHeader.wmfheader = &(API->Head); API->File = &(API->MetaHeader); API->File->filein = 0; /* Input stream: file (unused) */ API->buffer_data = 0; /* Input stream */ API->bbuf.read = 0; API->bbuf.seek = 0; API->bbuf.tell = 0;/* Status function & context */ API->status.context = 0; API->status.function = 0;/* General purpose string buffer */ API->string_buffer.length = 0; API->string_buffer.buffer = 0;/* Zero some unset pointers */ API->function_reference = 0; API->font_data = 0; API->fonts = 0; API->color_data = 0;/* Library error state: */ API->err = wmf_E_None;/* Finally: flags, etc. */ API->flags = flags;/* ---- Henceforth all allocation to be done via api ---- *//* Initialize string buffer */ API->string_buffer.length = 64; API->string_buffer.buffer = wmf_malloc (API,API->string_buffer.length * sizeof (char)); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); err = wmf_api_destroy (API); return (err); }/* Create color data - must be done prior to IPA initialization */ wmf_ipa_color_init (API); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); err = wmf_api_destroy (API); return (err); }/* Create ipa function interface */ API->function_reference = wmf_malloc (API,sizeof (wmfFunctionReference)); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); err = wmf_api_destroy (API); return (err); }/* Create ipa-device data */ if (flags & WMF_OPT_FUNCTION) { options->function (API); } else if (flags & WMF_OPT_MODULE) /* TODO... TODO... TODO... */ { WMF_ERROR (API,"libwmf: module interface not implemented yet..."); WMF_ERROR (API," unable to initialize device layer!"); API->err = wmf_E_Glitch; } else { WMF_ERROR (API,"libwmf: unable to initialize device layer!"); API->err = wmf_E_Glitch; } if (ERR (API)) { WMF_DEBUG (API,"bailing..."); err = wmf_api_destroy (API); return (err); }/* Create font data */ wmf_ipa_font_init (API,options); wmf_arg_fontdirs (API,options); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); err = wmf_api_destroy (API); return (err); }/* Create player data */ wmf_player_init (API); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); err = wmf_api_destroy (API); return (err); }/* Have successfully created the API... */ (*API_return) = API; return (wmf_E_None);}/** * Close the device layer, if open, and release all allocated memory attached to the memory manager. * * @param API the API handle * * @return The final error state of the library. */wmf_error_t wmf_api_destroy (wmfAPI* API) /* Basically free all alloced memory */{ wmf_error_t err; /* associated with the API */ wmfMemoryManager* MM = (wmfMemoryManager*) API->memory_data; wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference; wmfFontData* FD = (wmfFontData*) API->font_data; if (FR) { /* FR->device_close must be the first action of wmf_api_destroy in case * FR->device_close decides, for whatever reason, to re-play the meta file * or to acquire API resources... */ if ((API->flags & API_DEVICE_OPEN) && FR->device_close) FR->device_close (API); } if (API->flags & API_FTLIBRARY_OPEN) { FT_Done_FreeType (FD->Library); } err = API->err; while (MM->count) { MM->count--; if (MM->free) { MM->free (MM->context,MM->list[MM->count]); } else { free (MM->list[MM->count]); } } if (MM->free) { MM->free (MM->context,API); MM->free (MM->context,MM->list); MM->free (MM->context,MM); } else { free (API); free (MM->list); free (MM); } return (err);}/* ERROR & DEBUG Reporting * ======================= *//** * Set the error state of the library to wmf_E_Assert. * * @param API the API handle * @param file file name * @param line line number * * This should only be called via the macro WMF_ASSERT(API,<expr>) which is defined (for debug builds only) * as: * @verbatim#define WMF_ASSERT(Z,M) if (!(M)) wmf_assert (Z,__FILE__,__LINE__)@endverbatim * i.e., if <expr> evaluates to 0 then call wmf_assert() with current file name and line number. */void wmf_assert (wmfAPI* API,char* file,int line){ wmf_error (API,file,line,"Assertion failed!"); API->err = wmf_E_Assert;}/** * Print message to error stream. * * @param API the API handle * @param file file name * @param line line number * @param msg message to print * * This should only be called via the macro WMF_ERROR(API,msg) which calls wmf_error() with the current file * name and line number. */void wmf_error (wmfAPI* API,char* file,int line,char* msg){ if (API->error_out == 0) return; fprintf (API->error_out,"ERROR: %s (%d): %s\n",file,line,msg); fflush (API->error_out);}/** * Print message to debug stream. * * @param API the API handle * @param file file name * @param line line number * @param msg message to print * * This should only be called via the macro WMF_DEBUG(API,msg) which (in debug builds only) calls * wmf_debug() with the current file name and line number. */void wmf_debug (wmfAPI* API,char* file,int line,char* msg){ if (API->debug_out == 0) return; fprintf (API->debug_out,"%s (%d): %s\n",file,line,msg); fflush (API->debug_out);}/** * Print formatted message to debug stream. * * @param API the API handle * @param msg message to print * * With syntax similar to printf(), wmf_printf() prints formatted output to the debug stream. */void wmf_printf (wmfAPI* API,char* msg,...){ va_list argp; va_start (argp,msg); if (API->debug_out) { vfprintf (API->debug_out,msg,argp); fflush (API->debug_out); } va_end (argp);}/* Memory management interface * =========================== *//** * Allocate memory of specified size and attach to the API's memory manager's internal list. * * @param API the API handle * @param size size in bytes of memory required * * With syntax similar to malloc(), wmf_malloc() allocates \p size bytes of memory and adds a reference to * it in the memory manager's list. To free the memory, use wmf_free(). * * @return Pointer to new memory, or zero on failure. * Sets error state \b wmf_E_InsMem on failure. */void* wmf_malloc (wmfAPI* API,size_t size){ wmfMemoryManager* MM = (wmfMemoryManager*) API->memory_data; void* mem = 0; void** more = 0; if (size == 0) { WMF_DEBUG (API,"wmf_[*]alloc: attempt to allocate zero-sized memory!"); return (0); } if (MM->count == MM->max) { if (MM->realloc) { more = (void**) MM->realloc (MM->context,MM->list,(MM->max+32) * sizeof (void*)); } else { more = (void**) realloc (MM->list,(MM->max+32) * sizeof (void*));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -