/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%                             W   W   M   M  FFFFF                            %
%                             W   W   MM MM  F                                %
%                             W W W   M M M  FFF                              %
%                             WW WW   M   M  F                                %
%                             W   W   M   M  F                                %
%                                                                             %
%                                                                             %
%                        Read Windows Metafile Format                         %
%                                                                             %
%                              Software Design                                %
%                                   Cristy                                    %
%                               December 2000                                 %
%                                                                             %
%                                                                             %
%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
%  dedicated to making software imaging solutions freely available.           %
%                                                                             %
%  You may not use this file except in compliance with the License.  You may  %
%  obtain a copy of the License at                                            %
%                                                                             %
%    http://www.imagemagick.org/script/license.php                            %
%                                                                             %
%  Unless required by applicable law or agreed to in writing, software        %
%  distributed under the License is distributed on an "AS IS" BASIS,          %
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
%  See the License for the specific language governing permissions and        %
%  limitations under the License.                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/

/*
  Include declarations.
*/
#include "MagickCore/studio.h"
#include "MagickCore/property.h"
#include "MagickCore/blob.h"
#include "MagickCore/blob-private.h"
#include "MagickCore/color.h"
#include "MagickCore/color-private.h"
#include "MagickCore/constitute.h"
#include "MagickCore/exception.h"
#include "MagickCore/exception-private.h"
#include "MagickCore/image.h"
#include "MagickCore/image-private.h"
#include "MagickCore/list.h"
#include "MagickCore/log.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
#include "MagickCore/monitor.h"
#include "MagickCore/monitor-private.h"
#include "MagickCore/paint.h"
#include "MagickCore/quantum-private.h"
#include "MagickCore/static.h"
#include "MagickCore/string_.h"
#include "MagickCore/module.h"
#include "MagickCore/type.h"
#include "MagickCore/module.h"
#include "MagickWand/MagickWand.h"

#if defined(__CYGWIN__)
#undef MAGICKCORE_SANS_DELEGATE 
#endif

#if defined(MAGICKCORE_SANS_DELEGATE)
#include "libwmf/api.h"
#include "libwmf/eps.h"

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d W M F I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadWMFImage() reads an Windows Metafile image file and returns it.  It
%  allocates the memory necessary for the new Image structure and returns a
%  pointer to the new image.
%
%  The format of the ReadWMFImage method is:
%
%      Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/

static int WMFReadBlob(void *image)
{
  return(ReadBlobByte((Image *) image));
}

static int WMFSeekBlob(void *image,long offset)
{
  return((int) SeekBlob((Image *) image,(MagickOffsetType) offset,SEEK_SET));
}

static long WMFTellBlob(void *image)
{
  return((long) TellBlob((Image*) image));
}

static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    filename[MagickPathExtent];

  int
    unique_file;

  FILE
    *file;

  Image
    *image;

  ImageInfo
    *read_info;

  MagickBooleanType
    status;

  size_t
    flags;

  wmfAPI
    *wmf_info;

  wmfAPI_Options
    options;

  wmfD_Rect
    bounding_box;

  wmf_eps_t
    *eps_info;

  wmf_error_t
    wmf_status;

  /*
    Read WMF image.
  */
  image=AcquireImage(image_info,exception);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  wmf_info=(wmfAPI *) NULL;
  flags=0;
  flags|=WMF_OPT_IGNORE_NONFATAL;
  flags|=WMF_OPT_FUNCTION;
  options.function=wmf_eps_function;
  wmf_status=wmf_api_create(&wmf_info,(unsigned long) flags,&options);
  if (wmf_status != wmf_E_None)
    {
      if (wmf_info != (wmfAPI *) NULL)
        wmf_api_destroy(wmf_info);
      ThrowReaderException(DelegateError,"UnableToInitializeWMFLibrary");
    }
  wmf_status=wmf_bbuf_input(wmf_info,WMFReadBlob,WMFSeekBlob,WMFTellBlob,
    (void *) image);
  if (wmf_status != wmf_E_None)
    {
      ipa_device_close(wmf_info);
      wmf_api_destroy(wmf_info);
      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
        image->filename);
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  wmf_status=wmf_scan(wmf_info,0,&bounding_box);
  if (wmf_status != wmf_E_None)
    {
      ipa_device_close(wmf_info);
      wmf_api_destroy(wmf_info);
      ThrowReaderException(DelegateError,"FailedToScanFile");
    }
  eps_info=WMF_EPS_GetData(wmf_info);
  file=(FILE *) NULL;
  unique_file=AcquireUniqueFileResource(filename);
  if (unique_file != -1)
    file=fdopen(unique_file,"wb");
  if ((unique_file == -1) || (file == (FILE *) NULL))
    {
      ipa_device_close(wmf_info);
      wmf_api_destroy(wmf_info);
      ThrowReaderException(FileOpenError,"UnableToCreateTemporaryFile");
    }
  eps_info->out=wmf_stream_create(wmf_info,file);
  eps_info->bbox=bounding_box;
  wmf_status=wmf_play(wmf_info,0,&bounding_box);
  if (wmf_status != wmf_E_None)
    {
      ipa_device_close(wmf_info);
      wmf_api_destroy(wmf_info);
      ThrowReaderException(DelegateError,"FailedToRenderFile");
    }
  (void) fclose(file);
  wmf_api_destroy(wmf_info);
  (void) CloseBlob(image);
  image=DestroyImage(image);
  /*
    Read EPS image.
  */
  read_info=CloneImageInfo(image_info);
  SetImageInfoBlob(read_info,(void *) NULL,0);
  (void) FormatLocaleString(read_info->filename,MagickPathExtent,"eps:%s",
    filename);
  image=ReadImage(read_info,exception);
  read_info=DestroyImageInfo(read_info);
  if (image != (Image *) NULL)
    {
      (void) CopyMagickString(image->filename,image_info->filename,
        MagickPathExtent);
      (void) CopyMagickString(image->magick_filename,image_info->filename,
        MagickPathExtent);
      (void) CopyMagickString(image->magick,"WMF",MagickPathExtent);
    }
  (void) RelinquishUniqueFileResource(filename);
  return(GetFirstImageInList(image));
}
#elif defined(MAGICKCORE_WMF_DELEGATE)

#define ERR(API)  ((API)->err != wmf_E_None)
#define XC(x) ((double) x)
#define YC(y) ((double) y)

#if !defined(M_PI)
#  define M_PI  MagickPI
#endif

#if defined(MAGICKCORE_HAVE_FT2BUILD_H)
#  include <ft2build.h>
#endif

#include "libwmf/fund.h"
#include "libwmf/types.h"
#include "libwmf/api.h"
#undef SRCCOPY
#undef SRCPAINT
#undef SRCAND
#undef SRCINVERT
#undef SRCERASE
#undef NOTSRCCOPY
#undef NOTSRCERASE
#undef MERGECOPY
#undef MERGEPAINT
#undef PATCOPY
#undef PATPAINT
#undef PATINVERT
#undef DSTINVERT
#undef BLACKNESS
#undef WHITENESS

/* The following additinal undefs were required for MinGW */
#undef BS_HOLLOW
#undef PS_STYLE_MASK
#undef PS_ENDCAP_ROUND
#undef PS_ENDCAP_SQUARE
#undef PS_ENDCAP_FLAT
#undef PS_ENDCAP_MASK
#undef PS_JOIN_ROUND
#undef PS_JOIN_BEVEL
#undef PS_JOIN_MITER
#undef PS_COSMETIC
#undef PS_GEOMETRIC
#undef PS_TYPE_MASK
#undef STRETCH_ANDSCANS
#undef STRETCH_ORSCANS
#undef STRETCH_DELETESCANS
#undef STRETCH_HALFTONE
#undef ETO_OPAQUE
#undef ETO_CLIPPED
#undef ETO_GLYPH_INDEX
#undef ETO_RTLREADING

#include "libwmf/defs.h"
#include "libwmf/ipa.h"
#include "libwmf/color.h"
#include "libwmf/macro.h"

/* Unit conversions */
#define TWIPS_PER_INCH        1440
#define CENTIMETERS_PER_INCH  2.54
#define POINTS_PER_INCH       72

#if defined(MAGICKCORE_WMF_DELEGATE)
# define wmf_api_create(api,flags,options) wmf_lite_create(api,flags,options)
# define wmf_api_destroy(api) wmf_lite_destroy(api)
# undef WMF_FONT_PSNAME
# define WMF_FONT_PSNAME(F) ((F)->user_data ? ((wmf_magick_font_t*) (F)->user_data)->ps_name : 0)

typedef struct _wmf_magick_font_t wmf_magick_font_t;

struct _wmf_magick_font_t
{
  char*  ps_name;
  double pointsize;
};

#endif

typedef struct _wmf_magick_t wmf_magick_t;

struct _wmf_magick_t
{
  /* Bounding box */
  wmfD_Rect
    bbox;

  /* Scale and translation factors */
  double
    scale_x,
    scale_y,
    translate_x,
    translate_y,
    rotate;

  /* Vector output */
  DrawingWand
    *draw_wand;

  ExceptionInfo
    *exception;

  /* ImageMagick image */
  Image
    *image;

  /* ImageInfo */
  const ImageInfo
    *image_info;

  /* DrawInfo */
  DrawInfo
    *draw_info;

  /* Pattern ID */
  unsigned long
    pattern_id;

  /* Clip path flag */
  MagickBooleanType
    clipping;

  /* Clip path ID */
  unsigned long
    clip_mask_id;

  /* Push depth */
  long
    push_depth;
};


#define WMF_MAGICK_GetData(Z) ((wmf_magick_t*)((Z)->device_data))
#define WMF_MAGICK_GetFontData(Z) \
  ((wmf_magick_font_t*)((wmfFontData *)Z->font_data)->user_data)

#define WmfDrawingWand (((wmf_magick_t*)((API)->device_data))->draw_wand)

/* Enum to control whether util_set_brush applies brush to fill or
   stroke. */
typedef enum
{
  BrushApplyFill,
  BrushApplyStroke
} BrushApply;


/* Enum to specify arc type */
typedef enum
{
  magick_arc_ellipse = 0,
  magick_arc_open,
  magick_arc_pie,
  magick_arc_chord
}
magick_arc_t;

#if defined(MAGICKCORE_WMF_DELEGATE)
static void  lite_font_init (wmfAPI* API, wmfAPI_Options* options);
static void  lite_font_map(wmfAPI* API,wmfFont* font);
static float lite_font_stringwidth(wmfAPI* API, wmfFont* font, char* str);
#endif

static void         draw_fill_color_rgb(wmfAPI* API, const wmfRGB* rgb);
static void         draw_stroke_color_rgb(wmfAPI* API, const wmfRGB* rgb);
static void         draw_pattern_push(wmfAPI* API, unsigned long id, unsigned long columns, unsigned long rows);
static int          ipa_blob_read(void* wand);
static int          ipa_blob_seek(void* wand,long position);
static long         ipa_blob_tell(void* wand);
static void         ipa_bmp_draw(wmfAPI * API, wmfBMP_Draw_t * bmp_draw);
static void         ipa_bmp_free(wmfAPI * API, wmfBMP * bmp);
static void         ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read);
static void         ipa_device_begin(wmfAPI * API);
static void         ipa_device_close(wmfAPI * API);
static void         ipa_device_end(wmfAPI * API);
static void         ipa_device_open(wmfAPI * API);
static void         ipa_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc);
static void         ipa_draw_chord(wmfAPI * API, wmfDrawArc_t * draw_arc);
static void         ipa_draw_ellipse(wmfAPI * API, wmfDrawArc_t * draw_arc);
static void         ipa_draw_line(wmfAPI * API, wmfDrawLine_t * draw_line);
static void         ipa_draw_pie(wmfAPI * API, wmfDrawArc_t * draw_arc);
static void         ipa_draw_pixel(wmfAPI * API, wmfDrawPixel_t * draw_pixel);
static void         ipa_draw_polygon(wmfAPI * API, wmfPolyLine_t * poly_line);
#if defined(MAGICKCORE_WMF_DELEGATE)
static void         ipa_draw_polypolygon(wmfAPI * API, wmfPolyPoly_t* polypolygon);
#endif
static void         ipa_draw_rectangle(wmfAPI * API, wmfDrawRectangle_t * draw_rect);
static void         ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text);
static void         ipa_flood_exterior(wmfAPI * API, wmfFlood_t * flood);
static void         ipa_flood_interior(wmfAPI * API, wmfFlood_t * flood);
static void         ipa_functions(wmfAPI * API);
static void         ipa_poly_line(wmfAPI * API, wmfPolyLine_t * poly_line);
static void         ipa_region_clip(wmfAPI * API, wmfPolyRectangle_t * poly_rect);
static void         ipa_region_frame(wmfAPI * API, wmfPolyRectangle_t * poly_rect);
static void         ipa_region_paint(wmfAPI * API, wmfPolyRectangle_t * poly_rect);
static void         ipa_rop_draw(wmfAPI * API, wmfROP_Draw_t * rop_draw);
static void         ipa_udata_copy(wmfAPI * API, wmfUserData_t * userdata);
static void         ipa_udata_free(wmfAPI * API, wmfUserData_t * userdata);
static void         ipa_udata_init(wmfAPI * API, wmfUserData_t * userdata);
static void         ipa_udata_set(wmfAPI * API, wmfUserData_t * userdata);
static int          magick_progress_callback(void* wand,float quantum);
static void         util_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc,magick_arc_t finish);
#if defined(MAGICKCORE_WMF_DELEGATE)
/*static int          util_font_weight( const char* font );*/
#endif
static double       util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height, ExceptionInfo *);
static void         util_set_brush(wmfAPI * API, wmfDC * dc, const BrushApply brush_apply);
static void         util_set_pen(wmfAPI * API, wmfDC * dc);

/* Progress callback */
int magick_progress_callback(void *context,float quantum)
{
  Image
    *image;

  MagickBooleanType
    status;

  (void) quantum;
  image=(Image *) context;
  assert(image->signature == MagickCoreSignature);
  status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
    GetBlobSize(image));
  return(status != MagickFalse ? 0 : 1);
}

/* Set fill color */
static void draw_fill_color_string(DrawingWand *drawing_wand,const char *color)
{
  PixelWand
    *fill_color;

  fill_color=NewPixelWand();
  PixelSetColor(fill_color,color);
  DrawSetFillColor(drawing_wand,fill_color);
  fill_color=DestroyPixelWand(fill_color);
}
static void draw_fill_color_rgb( wmfAPI* API, const wmfRGB* rgb )
{
  PixelWand
    *fill_color;

  fill_color=NewPixelWand();
  PixelSetRedQuantum(fill_color,ScaleCharToQuantum(rgb->r));
  PixelSetGreenQuantum(fill_color,ScaleCharToQuantum(rgb->g));
  PixelSetBlueQuantum(fill_color,ScaleCharToQuantum(rgb->b));
  PixelSetAlphaQuantum(fill_color,OpaqueAlpha);
  DrawSetFillColor(WmfDrawingWand,fill_color);
  fill_color=DestroyPixelWand(fill_color);
}

/* Set stroke color */
static void draw_stroke_color_string(DrawingWand *drawing_wand,const char *color)
{
  PixelWand
    *stroke_color;

  stroke_color=NewPixelWand();
  PixelSetColor(stroke_color,color);
  DrawSetStrokeColor(drawing_wand,stroke_color);
  stroke_color=DestroyPixelWand(stroke_color);
}

static void draw_stroke_color_rgb( wmfAPI* API, const wmfRGB* rgb )
{
  PixelWand
    *stroke_color;

  stroke_color=NewPixelWand();
  PixelSetRedQuantum(stroke_color,ScaleCharToQuantum(rgb->r));
  PixelSetGreenQuantum(stroke_color,ScaleCharToQuantum(rgb->g));
  PixelSetBlueQuantum(stroke_color,ScaleCharToQuantum(rgb->b));
  PixelSetAlphaQuantum(stroke_color,OpaqueAlpha);
  DrawSetStrokeColor(WmfDrawingWand,stroke_color);
  stroke_color=DestroyPixelWand(stroke_color);
}

/* Set under color */
static void draw_under_color_string(DrawingWand *drawing_wand,const char *color)
{
  PixelWand
    *under_color;

  under_color=NewPixelWand();
  PixelSetColor(under_color,color);
  DrawSetTextUnderColor(drawing_wand,under_color);
  under_color=DestroyPixelWand(under_color);
}

static void draw_pattern_push( wmfAPI* API,
                               unsigned long id,
                               unsigned long columns,
                               unsigned long rows )
{
  char
    pattern_id[MagickPathExtent];

  (void) FormatLocaleString(pattern_id,MagickPathExtent,"brush_%lu",id);
  (void) DrawPushPattern(WmfDrawingWand,pattern_id,0,0,columns,rows);
}

/* Pattern/Bit BLT with raster operation (ROP) support.  Invoked by
   META_PATBLT, which is equivalent to Windows PatBlt() call, or by
   META_DIBBITBLT which is equivalent to Windows BitBlt() call. */

/* The BitBlt function transfers pixels from a rectangular area in one
   device wand called the 'source', to a rectangular area of the
   same size in another device wand, called the 'destination'. */

static void ipa_rop_draw(wmfAPI * API, wmfROP_Draw_t * rop_draw)
{
/*   wmfBrush */
/*     *brush = WMF_DC_BRUSH(rop_draw->dc); */

/*   wmfBMP */
/*     *brush_bmp = WMF_BRUSH_BITMAP(brush); */

  if (TO_FILL(rop_draw) == 0)
    return;

  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  /* FIXME: finish implementing (once we know what it is supposed to do!) */

  /*
  struct _wmfROP_Draw_t
  {       wmfDC* dc;

    wmfD_Coord TL;
    wmfD_Coord BR;

    U32 ROP;

    double pixel_width;
    double pixel_height;
  };
  */

/*   if (brush_bmp && brush_bmp->data != 0) */
/*     printf("Have an image!\n"); */

  switch (rop_draw->ROP) /* Ternary raster operations */
    {
    case SRCCOPY: /* dest = source */
      printf("ipa_rop_draw SRCCOPY ROP mode not implemented\n");
      break;
    case SRCPAINT: /* dest = source OR dest */
      printf("ipa_rop_draw SRCPAINT ROP mode not implemented\n");
      break;
    case SRCAND: /* dest = source AND dest */
      printf("ipa_rop_draw SRCAND ROP mode not implemented\n");
      break;
    case SRCINVERT: /* dest = source XOR dest */
      printf("ipa_rop_draw SRCINVERT ROP mode not implemented\n");
      break;
    case SRCERASE: /* dest = source AND (NOT dest) */
      printf("ipa_rop_draw SRCERASE ROP mode not implemented\n");
      break;
    case NOTSRCCOPY: /* dest = (NOT source) */
      printf("ipa_rop_draw NOTSRCCOPY ROP mode not implemented\n");
      break;
    case NOTSRCERASE: /* dest = (NOT src) AND (NOT dest) */
      printf("ipa_rop_draw NOTSRCERASE ROP mode not implemented\n");
      break;
    case MERGECOPY: /* dest = (source AND pattern) */
      printf("ipa_rop_draw MERGECOPY ROP mode not implemented\n");
      break;
    case MERGEPAINT: /* dest = (NOT source) OR dest */
      printf("ipa_rop_draw MERGEPAINT ROP mode not implemented\n");
      break;
    case PATCOPY: /* dest = pattern */
      util_set_brush(API, rop_draw->dc, BrushApplyFill);
      break;
    case PATPAINT: /* dest = DPSnoo */
      printf("ipa_rop_draw PATPAINT ROP mode not implemented\n");
      break;
    case PATINVERT: /* dest = pattern XOR dest */
      printf("ipa_rop_draw PATINVERT ROP mode not implemented\n");
      break;
    case DSTINVERT: /* dest = (NOT dest) */
      printf("ipa_rop_draw DSTINVERT ROP mode not implemented\n");
      break;
    case BLACKNESS: /* dest = BLACK */
      draw_fill_color_string(WmfDrawingWand,"black");
      break;
    case WHITENESS: /* dest = WHITE */
      draw_fill_color_string(WmfDrawingWand,"white");
      break;
    default:
      printf("ipa_rop_draw 0x%x ROP mode not implemented\n", rop_draw->ROP);
      break;
    }

  DrawRectangle(WmfDrawingWand,
                 XC(rop_draw->TL.x), YC(rop_draw->TL.y),
                 XC(rop_draw->BR.x), YC(rop_draw->BR.y));

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_bmp_draw(wmfAPI *API, wmfBMP_Draw_t *bmp_draw)
{
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  ExceptionInfo
    *exception;

  Image
    *image;

  MagickWand
    *magick_wand;

  double
    height,
    width;

  PixelInfo
    white;

  if (bmp_draw->bmp.data == 0)
    return;

  image = (Image*)bmp_draw->bmp.data;
  if (!image)
     return;

  exception=ddata->exception;
  if (bmp_draw->crop.x || bmp_draw->crop.y ||
     (bmp_draw->crop.w != bmp_draw->bmp.width) ||
     (bmp_draw->crop.h != bmp_draw->bmp.height))
    {
      /* Image needs to be cropped */
      Image
        *crop_image;

      RectangleInfo
        crop_info;

      crop_info.x = bmp_draw->crop.x;
      crop_info.y = bmp_draw->crop.y;
      crop_info.width = bmp_draw->crop.w;
      crop_info.height = bmp_draw->crop.h;

      crop_image = CropImage( image, &crop_info, exception );
      if (crop_image)
        {
          image=DestroyImageList(image);
          image = crop_image;
          bmp_draw->bmp.data = (void*)image;
        }
    }

  QueryColorCompliance( "white", AllCompliance, &white, exception );

  if ( ddata->image_info->texture ||
       !(IsPixelInfoEquivalent(&ddata->image_info->background_color,&white)) ||
       ddata->image_info->background_color.alpha != OpaqueAlpha )
  {
    /*
      Set image white background to transparent so that it may be
      overlaid over non-white backgrounds.
    */
    QueryColorCompliance( "white", AllCompliance, &white, exception );
    TransparentPaintImage( image, &white, QuantumRange, MagickFalse, exception );
  }

  width = fabs(bmp_draw->pixel_width * (double) bmp_draw->crop.w);
  height = fabs(bmp_draw->pixel_height * (double) bmp_draw->crop.h);
  magick_wand=NewMagickWandFromImage(image);
  (void) DrawComposite(WmfDrawingWand, CopyCompositeOp,
    XC(bmp_draw->pt.x) * ddata->scale_x, YC(bmp_draw->pt.y) * ddata->scale_y,
    width * ddata->scale_x, height * ddata->scale_y, magick_wand);
  magick_wand=DestroyMagickWand(magick_wand);

#if 0
  printf("bmp_draw->bmp.data   = 0x%lx\n", (long)bmp_draw->bmp.data);
  printf("registry id          = %li\n", id);
  /* printf("pixel_width          = %g\n", bmp_draw->pixel_width); */
  /* printf("pixel_height         = %g\n", bmp_draw->pixel_height); */
  printf("bmp_draw->bmp WxH    = %ix%i\n", bmp_draw->bmp.width, bmp_draw->bmp.height);
  printf("bmp_draw->crop WxH   = %ix%i\n", bmp_draw->crop.w, bmp_draw->crop.h);
  printf("bmp_draw->crop x,y   = %i,%i\n", bmp_draw->crop.x, bmp_draw->crop.y);
  printf("image size WxH       = %lux%lu\n", image->columns, image->rows);
#endif
}

static void ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read) {
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  ExceptionInfo
    *exception;

  Image
    *image;

  ImageInfo
    *image_info;

  bmp_read->bmp.data = 0;

  image_info=CloneImageInfo(ddata->image_info);
  exception=ddata->exception;
  (void) CopyMagickString(image_info->magick,"DIB",MagickPathExtent);
  if (bmp_read->width || bmp_read->height)
    {
      char
        size[MagickPathExtent];

      (void) FormatLocaleString(size,MagickPathExtent,"%ux%u",bmp_read->width,
        bmp_read->height);
      CloneString(&image_info->size,size);
    }
#if 0
  printf("ipa_bmp_read: buffer=0x%lx length=%ld, width=%i, height=%i\n",
   (long) bmp_read->buffer, bmp_read->length,
   bmp_read->width, bmp_read->height);
#endif
  image=BlobToImage(image_info, (const void *) bmp_read->buffer,
    bmp_read->length, exception);
  image_info=DestroyImageInfo(image_info);
  if (image != (Image *) NULL)
    {
#if 0
      printf("ipa_bmp_read: rows=%ld,columns=%ld\n\n", image->rows, image->columns);
#endif

      bmp_read->bmp.data   = (void*)image;
      bmp_read->bmp.width  = (U16)image->columns;
      bmp_read->bmp.height = (U16)image->rows;
    }
}

static void ipa_bmp_free(wmfAPI * API, wmfBMP * bmp)
{
  (void) API;
  DestroyImageList((Image*)bmp->data);
  bmp->data = (void*) 0;
  bmp->width = (U16) 0;
  bmp->height = (U16) 0;
}

/*
  This called by wmf_play() the *first* time the meta file is played
 */
static void ipa_device_open(wmfAPI * API)
{
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData (API);

  ddata->pattern_id = 0;
  ddata->clipping = MagickFalse;
  ddata->clip_mask_id = 0;

  ddata->push_depth = 0;

  ddata->draw_wand = AcquireDrawingWand(ddata->draw_info,ddata->image);
}

/*
  This called by wmf_api_destroy()
 */
static void ipa_device_close(wmfAPI * API)
{
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  if (ddata->draw_wand != (DrawingWand *) NULL)
    {
      DestroyDrawingWand(ddata->draw_wand);
      ddata->draw_wand=(DrawingWand *) NULL;
    }
  if (ddata->draw_info != (DrawInfo *) NULL)
    {
      DestroyDrawInfo(ddata->draw_info);
      ddata->draw_info=(DrawInfo *)NULL;
    }
  RelinquishMagickMemory(WMF_MAGICK_GetFontData(API)->ps_name);
}

/*
  This called from the beginning of each play for initial page setup
 */
static void ipa_device_begin(wmfAPI * API)
{
  char
    comment[MagickPathExtent];

  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  /* Make SVG output happy */
  (void) PushDrawingWand(WmfDrawingWand);

  DrawSetViewbox(WmfDrawingWand, 0, 0, ddata->image->columns, ddata->image->rows );

  (void) FormatLocaleString(comment,MagickPathExtent,"Created by ImageMagick %s",
    GetMagickVersion((size_t *) NULL));
  DrawComment(WmfDrawingWand,comment);

  /* Scale width and height to image */
  DrawScale(WmfDrawingWand, ddata->scale_x, ddata->scale_y);

  /* Translate to TL corner of bounding box */
  DrawTranslate(WmfDrawingWand, ddata->translate_x, ddata->translate_y);

  /* Apply rotation */
  DrawRotate(WmfDrawingWand, ddata->rotate);

  if (ddata->image_info->texture == NULL)
    {
      PixelWand
        *background_color;

      /* Draw rectangle in background color */
      background_color=NewPixelWand();
      PixelSetPixelColor(background_color,&ddata->image->background_color);
      DrawSetFillColor(WmfDrawingWand,background_color);
      background_color=DestroyPixelWand(background_color);
      DrawRectangle(WmfDrawingWand,
                     XC(ddata->bbox.TL.x),YC(ddata->bbox.TL.y),
                     XC(ddata->bbox.BR.x),YC(ddata->bbox.BR.y));
    }
  else
    {
      /* Draw rectangle with texture image the SVG way */
      Image
        *image;

      ImageInfo
        *image_info;

      ExceptionInfo
        *exception;

      exception=AcquireExceptionInfo();

      image_info = CloneImageInfo((ImageInfo *) 0);
      (void) CopyMagickString(image_info->filename,ddata->image_info->texture,
        MagickPathExtent);
      if ( ddata->image_info->size )
        CloneString(&image_info->size,ddata->image_info->size);

      image = ReadImage(image_info,exception);
      (void) DestroyExceptionInfo(exception);
      image_info=DestroyImageInfo(image_info);
      if (image)
        {
          char
            pattern_id[MagickPathExtent];

          MagickWand
            *magick_wand;

          (void) CopyMagickString(image->magick,"MIFF",MagickPathExtent);
          DrawPushDefs(WmfDrawingWand);
          draw_pattern_push(API,ddata->pattern_id,image->columns,image->rows);
          magick_wand=NewMagickWandFromImage(image);
          (void) DrawComposite(WmfDrawingWand,CopyCompositeOp,0,0,
            image->columns,image->rows,magick_wand);
          magick_wand=DestroyMagickWand(magick_wand);
          (void) DrawPopPattern(WmfDrawingWand);
          DrawPopDefs(WmfDrawingWand);
          (void) FormatLocaleString(pattern_id,MagickPathExtent,"#brush_%lu",
            ddata->pattern_id);
          (void) DrawSetFillPatternURL(WmfDrawingWand,pattern_id);
          ++ddata->pattern_id;
          DrawRectangle(WmfDrawingWand,
            XC(ddata->bbox.TL.x),YC(ddata->bbox.TL.y),
            XC(ddata->bbox.BR.x),YC(ddata->bbox.BR.y));
          image=DestroyImageList(image);
        }
      else
        {
          LogMagickEvent(CoderEvent,GetMagickModule(),
            "reading texture image failed!");
        }
    }

  DrawSetClipRule(WmfDrawingWand,EvenOddRule); /* Default for WMF is ALTERNATE polygon fill mode */
  draw_fill_color_string(WmfDrawingWand,"none"); /* Default brush is WHITE_BRUSH */
  draw_stroke_color_string(WmfDrawingWand,"none"); /* Default pen is BLACK_PEN */
  DrawSetStrokeLineCap(WmfDrawingWand,ButtCap); /* Default linecap is PS_ENDCAP_FLAT */
  DrawSetStrokeLineJoin(WmfDrawingWand,MiterJoin); /* Default linejoin is PS_JOIN_MITER */
  draw_under_color_string(WmfDrawingWand,"white"); /* Default text box is white */
}

/*
  This called from the end of each play for page termination
 */
static void ipa_device_end(wmfAPI * API)
{
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  /* Reset any existing clip paths by popping wand */
  if (ddata->clipping)
    (void) PopDrawingWand(WmfDrawingWand);
  ddata->clipping = MagickFalse;

  /* Make SVG output happy */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_flood_interior(wmfAPI * API, wmfFlood_t * flood)
{
  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  draw_fill_color_rgb(API,&(flood->color));

  DrawColor(WmfDrawingWand,XC(flood->pt.x), YC(flood->pt.y),
            FillToBorderMethod);

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_flood_exterior(wmfAPI * API, wmfFlood_t * flood)
{
  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  draw_fill_color_rgb(API,&(flood->color));

  if (flood->type == FLOODFILLSURFACE)
    DrawColor(WmfDrawingWand, XC(flood->pt.x), YC(flood->pt.y),
              FloodfillMethod);
  else
    DrawColor(WmfDrawingWand, XC(flood->pt.x), YC(flood->pt.y),
              FillToBorderMethod);

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_draw_pixel(wmfAPI * API, wmfDrawPixel_t * draw_pixel)
{
  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  draw_stroke_color_string(WmfDrawingWand,"none");

  draw_fill_color_rgb(API,&(draw_pixel->color));

  DrawRectangle(WmfDrawingWand,
                 XC(draw_pixel->pt.x),
                 YC(draw_pixel->pt.y),
                 XC(draw_pixel->pt.x + draw_pixel->pixel_width),
                 YC(draw_pixel->pt.y + draw_pixel->pixel_height));

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_draw_pie(wmfAPI * API, wmfDrawArc_t * draw_arc)
{
  util_draw_arc(API, draw_arc, magick_arc_pie);
}

static void ipa_draw_chord(wmfAPI * API, wmfDrawArc_t * draw_arc)
{
  util_draw_arc(API, draw_arc, magick_arc_chord);
}

static void ipa_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc)
{
  util_draw_arc(API, draw_arc, magick_arc_open);
}

static void ipa_draw_ellipse(wmfAPI * API, wmfDrawArc_t * draw_arc)
{
  util_draw_arc(API, draw_arc, magick_arc_ellipse);
}

static void util_draw_arc(wmfAPI * API,
          wmfDrawArc_t * draw_arc, magick_arc_t finish)
{
  wmfD_Coord
    BR,
    O,
    TL,
    center,
    end,
    start;

  double
    phi_e = 360,
    phi_s = 0;

  double
    Rx,
    Ry;

  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  if (TO_FILL(draw_arc) || TO_DRAW(draw_arc))
    {
      center.x = (draw_arc->TL.x + draw_arc->BR.x) / 2;
      center.y = (draw_arc->TL.y + draw_arc->BR.y) / 2;
      start = center;
      end = center;

      if (finish != magick_arc_ellipse)
        {
          draw_arc->start.x += center.x;
          draw_arc->start.y += center.y;

          draw_arc->end.x += center.x;
          draw_arc->end.y += center.y;
        }

      TL = draw_arc->TL;
      BR = draw_arc->BR;

      O = center;

      if (finish != magick_arc_ellipse)
        {
          start = draw_arc->start;
          end = draw_arc->end;
        }

      Rx = (BR.x - TL.x) / 2;
      Ry = (BR.y - TL.y) / 2;

      if (finish != magick_arc_ellipse)
        {
          start.x -= O.x;
          start.y -= O.y;

          end.x -= O.x;
          end.y -= O.y;

          phi_s = atan2((double) start.y, (double) start.x) * 180 / MagickPI;
          phi_e = atan2((double) end.y, (double) end.x) * 180 / MagickPI;

          if (phi_e <= phi_s)
            phi_e += 360;
        }

      util_set_pen(API, draw_arc->dc);
      if (finish == magick_arc_open)
        draw_fill_color_string(WmfDrawingWand,"none");
      else
        util_set_brush(API, draw_arc->dc, BrushApplyFill);

      if (finish == magick_arc_ellipse)
        DrawEllipse(WmfDrawingWand, XC(O.x), YC(O.y), Rx, Ry, 0, 360);
      else if (finish == magick_arc_pie)
        {
          DrawPathStart(WmfDrawingWand);
          DrawPathMoveToAbsolute(WmfDrawingWand, XC(O.x+start.x),
            YC(O.y+start.y));
          DrawPathEllipticArcAbsolute(WmfDrawingWand, Rx, Ry, 0, MagickFalse,
            MagickTrue, XC(O.x+end.x), YC(O.y+end.y));
          DrawPathLineToAbsolute(WmfDrawingWand, XC(O.x), YC(O.y));
          DrawPathClose(WmfDrawingWand);
          DrawPathFinish(WmfDrawingWand);
        }
        else if (finish == magick_arc_chord)
        {
          DrawArc(WmfDrawingWand, XC(draw_arc->TL.x), YC(draw_arc->TL.y),
            XC(draw_arc->BR.x), XC(draw_arc->BR.y), phi_s, phi_e);
          DrawLine(WmfDrawingWand, XC(draw_arc->BR.x-start.x),
            YC(draw_arc->BR.y-start.y), XC(draw_arc->BR.x-end.x),
            YC(draw_arc->BR.y-end.y));
        }
        else      /* if (finish == magick_arc_open) */
          DrawArc(WmfDrawingWand, XC(draw_arc->TL.x), YC(draw_arc->TL.y),
            XC(draw_arc->BR.x), XC(draw_arc->BR.y), phi_s, phi_e);
    }

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_draw_line(wmfAPI * API, wmfDrawLine_t * draw_line)
{
  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  if (TO_DRAW(draw_line))
    {
      util_set_pen(API, draw_line->dc);
      DrawLine(WmfDrawingWand,
               XC(draw_line->from.x), YC(draw_line->from.y),
               XC(draw_line->to.x), YC(draw_line->to.y));
    }

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_poly_line(wmfAPI * API, wmfPolyLine_t * polyline)
{
  if (polyline->count <= 2)
    return;

  if (TO_DRAW(polyline))
    {
      int
        point;

      /* Save graphic wand */
      (void) PushDrawingWand(WmfDrawingWand);

      util_set_pen(API, polyline->dc);

      DrawPathStart(WmfDrawingWand);
      DrawPathMoveToAbsolute(WmfDrawingWand,
                             XC(polyline->pt[0].x),
                             YC(polyline->pt[0].y));
      for (point = 1; point < polyline->count; point++)
        {
          DrawPathLineToAbsolute(WmfDrawingWand,
                                 XC(polyline->pt[point].x),
                                 YC(polyline->pt[point].y));
        }
      DrawPathFinish(WmfDrawingWand);

      /* Restore graphic wand */
      (void) PopDrawingWand(WmfDrawingWand);
    }
}

static void ipa_draw_polygon(wmfAPI * API, wmfPolyLine_t * polyline)
{
  if (polyline->count <= 2)
    return;

  if (TO_FILL(polyline) || TO_DRAW(polyline))
    {
      int
        point;

      /* Save graphic wand */
      (void) PushDrawingWand(WmfDrawingWand);

      util_set_pen(API, polyline->dc);
      util_set_brush(API, polyline->dc, BrushApplyFill);

      DrawPathStart(WmfDrawingWand);
      DrawPathMoveToAbsolute(WmfDrawingWand,
                             XC(polyline->pt[0].x),
                             YC(polyline->pt[0].y));
      for (point = 1; point < polyline->count; point++)
        {
          DrawPathLineToAbsolute(WmfDrawingWand,
                                 XC(polyline->pt[point].x),
                                 YC(polyline->pt[point].y));
        }
      DrawPathClose(WmfDrawingWand);
      DrawPathFinish(WmfDrawingWand);

      /* Restore graphic wand */
      (void) PopDrawingWand(WmfDrawingWand);
    }
}

/* Draw a polypolygon.  A polypolygon is a list of polygons */
#if defined(MAGICKCORE_WMF_DELEGATE)
static void ipa_draw_polypolygon(wmfAPI * API, wmfPolyPoly_t* polypolygon)
{
  if (TO_FILL(polypolygon) || TO_DRAW(polypolygon))
    {
      int
        polygon,
        point;

      wmfPolyLine_t
        polyline;

      /* Save graphic wand */
      (void) PushDrawingWand(WmfDrawingWand);

      util_set_pen(API, polypolygon->dc);
      util_set_brush(API, polypolygon->dc, BrushApplyFill);

      DrawPathStart(WmfDrawingWand);
      for (polygon = 0; polygon < polypolygon->npoly; polygon++)
        {
          polyline.dc = polypolygon->dc;
          polyline.pt = polypolygon->pt[polygon];
          polyline.count = polypolygon->count[polygon];
          if ((polyline.count > 2) && polyline.pt)
            {
              DrawPathMoveToAbsolute(WmfDrawingWand,
                                     XC(polyline.pt[0].x),
                                     YC(polyline.pt[0].y));
              for (point = 1; point < polyline.count; point++)
                {
                  DrawPathLineToAbsolute(WmfDrawingWand,
                                         XC(polyline.pt[point].x),
                                         YC(polyline.pt[point].y));
                }
              DrawPathClose(WmfDrawingWand);
            }
        }
      DrawPathFinish(WmfDrawingWand);

      /* Restore graphic wand */
      (void) PopDrawingWand(WmfDrawingWand);
    }
}
#endif

static void ipa_draw_rectangle(wmfAPI * API, wmfDrawRectangle_t * draw_rect)
{
  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  if (TO_FILL(draw_rect) || TO_DRAW(draw_rect))
    {
      util_set_pen(API, draw_rect->dc);
      util_set_brush(API, draw_rect->dc, BrushApplyFill);

      if ((draw_rect->width > 0) || (draw_rect->height > 0))
        DrawRoundRectangle(WmfDrawingWand,
                           XC(draw_rect->TL.x), YC(draw_rect->TL.y),
                           XC(draw_rect->BR.x), YC(draw_rect->BR.y),
                           draw_rect->width / 2, draw_rect->height / 2);
      else
        DrawRectangle(WmfDrawingWand,
                      XC(draw_rect->TL.x), YC(draw_rect->TL.y),
                      XC(draw_rect->BR.x), YC(draw_rect->BR.y));
    }

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

/* Draw an un-filled rectangle using the current brush */
static void ipa_region_frame(wmfAPI * API, wmfPolyRectangle_t * poly_rect)
{
  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  if (TO_FILL(poly_rect) || TO_DRAW(poly_rect))
    {
      long
        i;

      draw_fill_color_string(WmfDrawingWand,"none");
      util_set_brush(API, poly_rect->dc, BrushApplyStroke);

      for (i = 0; i < (long) poly_rect->count; i++)
        {
          DrawRectangle(WmfDrawingWand,
                         XC(poly_rect->TL[i].x), YC(poly_rect->TL[i].y),
                         XC(poly_rect->BR[i].x), YC(poly_rect->BR[i].y));
        }
    }

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_region_paint(wmfAPI * API, wmfPolyRectangle_t * poly_rect)
{

  if (poly_rect->count == 0)
    return;

  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  if (TO_FILL (poly_rect))
    {
      long
        i;

      draw_stroke_color_string(WmfDrawingWand,"none");
      util_set_brush(API, poly_rect->dc, BrushApplyFill);

      for (i = 0; i < (long) poly_rect->count; i++)
        {
          DrawRectangle(WmfDrawingWand,
                         XC(poly_rect->TL[i].x), YC(poly_rect->TL[i].y),
                         XC(poly_rect->BR[i].x), YC(poly_rect->BR[i].y));
        }
    }

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);
}

static void ipa_region_clip(wmfAPI *API, wmfPolyRectangle_t *poly_rect)
{
  long
    i;

  wmf_magick_t
    *ddata = WMF_MAGICK_GetData (API);

  /* Reset any existing clip paths by popping wand */
  if (ddata->clipping)
    (void) PopDrawingWand(WmfDrawingWand);
  ddata->clipping = MagickFalse;

  if (poly_rect->count > 0)
    {
      char
        clip_mask_id[MagickPathExtent];

      /* Define clip path */
      ddata->clip_mask_id++;
      DrawPushDefs(WmfDrawingWand);
      (void) FormatLocaleString(clip_mask_id,MagickPathExtent,"clip_%lu",
        ddata->clip_mask_id);
      DrawPushClipPath(WmfDrawingWand,clip_mask_id);
      (void) PushDrawingWand(WmfDrawingWand);
      for (i = 0; i < (long) poly_rect->count; i++)
        {
          DrawRectangle(WmfDrawingWand,
                         XC(poly_rect->TL[i].x), YC(poly_rect->TL[i].y),
                         XC(poly_rect->BR[i].x), YC(poly_rect->BR[i].y));
        }
      (void) PopDrawingWand(WmfDrawingWand);
      DrawPopClipPath(WmfDrawingWand);
      DrawPopDefs(WmfDrawingWand);

      /* Push wand for new clip paths */
      (void) PushDrawingWand(WmfDrawingWand);
      (void) DrawSetClipPath(WmfDrawingWand,clip_mask_id);
      ddata->clipping = MagickTrue;
    }
}

static void ipa_functions(wmfAPI *API)
{
  wmf_magick_t
    *ddata = 0;

  wmfFunctionReference
    *FR = (wmfFunctionReference *) API->function_reference;

  /*
     IPA function reference links
   */
  FR->device_open = ipa_device_open;
  FR->device_close = ipa_device_close;
  FR->device_begin = ipa_device_begin;
  FR->device_end = ipa_device_end;
  FR->flood_interior = ipa_flood_interior;
  FR->flood_exterior = ipa_flood_exterior;
  FR->draw_pixel = ipa_draw_pixel;
  FR->draw_pie = ipa_draw_pie;
  FR->draw_chord = ipa_draw_chord;
  FR->draw_arc = ipa_draw_arc;
  FR->draw_ellipse = ipa_draw_ellipse;
  FR->draw_line = ipa_draw_line;
  FR->poly_line = ipa_poly_line;
  FR->draw_polygon = ipa_draw_polygon;
#if defined(MAGICKCORE_WMF_DELEGATE)
  FR->draw_polypolygon = ipa_draw_polypolygon;
#endif
  FR->draw_rectangle = ipa_draw_rectangle;
  FR->rop_draw = ipa_rop_draw;
  FR->bmp_draw = ipa_bmp_draw;
  FR->bmp_read = ipa_bmp_read;
  FR->bmp_free = ipa_bmp_free;
  FR->draw_text = ipa_draw_text;
  FR->udata_init = ipa_udata_init;
  FR->udata_copy = ipa_udata_copy;
  FR->udata_set = ipa_udata_set;
  FR->udata_free = ipa_udata_free;
  FR->region_frame = ipa_region_frame;
  FR->region_paint = ipa_region_paint;
  FR->region_clip = ipa_region_clip;

  /*
     Allocate device data structure
   */
  ddata = (wmf_magick_t *) wmf_malloc(API, sizeof(wmf_magick_t));
  if (ERR(API))
    return;

  (void) ResetMagickMemory((void *) ddata, 0, sizeof(wmf_magick_t));
  API->device_data = (void *) ddata;

  /*
     Device data defaults
   */
  ddata->image = 0;
}

static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text)
{
  double
    angle = 0,      /* text rotation angle */
    bbox_height,    /* bounding box height */
    bbox_width,      /* bounding box width */
    pointsize = 0;    /* pointsize to output font with desired height */

  ExceptionInfo
    *exception;

  TypeMetric
    metrics;

  wmfD_Coord
    BL,        /* bottom left of bounding box */
    BR,        /* bottom right of bounding box */
    TL,        /* top left of bounding box */
    TR;        /* top right of bounding box */

  wmfD_Coord
    point;      /* text placement point */

  wmfFont
    *font;

  wmf_magick_t
    * ddata = WMF_MAGICK_GetData(API);

  point = draw_text->pt;

  /* Choose bounding box and calculate its width and height */
  {
    double dx,
      dy;

    if ( draw_text->flags)
      {
        TL = draw_text->TL;
        BR = draw_text->BR;
        TR.x = draw_text->BR.x;
        TR.y = draw_text->TL.y;
        BL.x = draw_text->TL.x;
        BL.y = draw_text->BR.y;
      }
    else
      {
        TL = draw_text->bbox.TL;
        BR = draw_text->bbox.BR;
        TR = draw_text->bbox.TR;
        BL = draw_text->bbox.BL;
      }
    dx = ((TR.x - TL.x) + (BR.x - BL.x)) / 2;
    dy = ((TR.y - TL.y) + (BR.y - BL.y)) / 2;
    bbox_width = hypot(dx,dy);
    dx = ((BL.x - TL.x) + (BR.x - TR.x)) / 2;
    dy = ((BL.y - TL.y) + (BR.y - TR.y)) / 2;
    bbox_height = hypot(dx,dy);
  }

  font = WMF_DC_FONT(draw_text->dc);

  /* Convert font_height to equivalent pointsize */
  exception=ddata->exception;
  pointsize = util_pointsize( API, font, draw_text->str, draw_text->font_height, exception);

  /* Save graphic wand */
  (void) PushDrawingWand(WmfDrawingWand);

  (void) bbox_width;
  (void) bbox_height;
#if 0
  printf("\nipa_draw_text\n");
  printf("Text                    = \"%s\"\n", draw_text->str);
  /* printf("WMF_FONT_NAME:          = \"%s\"\n", WMF_FONT_NAME(font)); */
  printf("WMF_FONT_PSNAME:        = \"%s\"\n", WMF_FONT_PSNAME(font));
  printf("Bounding box            TL=%g,%g BR=%g,%g\n",
         TL.x, TL.y, BR.x, BR.y );
  /* printf("Text box                = %gx%g\n", bbox_width, bbox_height); */
  /* printf("WMF_FONT_HEIGHT         = %i\n", (int)WMF_FONT_HEIGHT(font)); */
  printf("Pointsize               = %g\n", pointsize);
  fflush(stdout);
#endif

  /*
   * Obtain font metrics if required
   *
   */
  if ((WMF_DC_TEXTALIGN(draw_text->dc) & TA_CENTER) ||
      (WMF_TEXT_UNDERLINE(font)) || (WMF_TEXT_STRIKEOUT(font)))
    {
      Image
        *image = ddata->image;

      DrawInfo
        *draw_info;

      draw_info=ddata->draw_info;
      draw_info->font=WMF_FONT_PSNAME(font);
      draw_info->pointsize = pointsize;
      draw_info->text=draw_text->str;

      if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
        {
          /* Center the text if it is not yet centered and should be */
          if ((WMF_DC_TEXTALIGN(draw_text->dc) & TA_CENTER))
            {
              double
                text_width = metrics.width * (ddata->scale_y / ddata->scale_x);

#if defined(MAGICKCORE_WMF_DELEGATE)
              point.x -= text_width / 2;
#else
              point.x += bbox_width / 2 - text_width / 2;
#endif
            }
        }
      draw_info->font=NULL;
      draw_info->text=NULL;
    }

  /* Set text background color */
  if (draw_text->flags & ETO_OPAQUE)
    {
      /* Draw bounding-box background color (META_EXTTEXTOUT mode) */
      draw_stroke_color_string(WmfDrawingWand,"none");
      draw_fill_color_rgb(API,WMF_DC_BACKGROUND(draw_text->dc));
      DrawRectangle(WmfDrawingWand,
                    XC(draw_text->TL.x),YC(draw_text->TL.y),
                    XC(draw_text->BR.x),YC(draw_text->BR.y));
      draw_fill_color_string(WmfDrawingWand,"none");
    }
  else
    {
      /* Set text undercolor */
      if (WMF_DC_OPAQUE(draw_text->dc))
        {
          wmfRGB
            *box = WMF_DC_BACKGROUND(draw_text->dc);

          PixelWand
            *under_color;

          under_color=NewPixelWand();
          PixelSetRedQuantum(under_color,ScaleCharToQuantum(box->r));
          PixelSetGreenQuantum(under_color,ScaleCharToQuantum(box->g));
          PixelSetBlueQuantum(under_color,ScaleCharToQuantum(box->b));
          PixelSetAlphaQuantum(under_color,OpaqueAlpha);
          DrawSetTextUnderColor(WmfDrawingWand,under_color);
          under_color=DestroyPixelWand(under_color);
        }
      else
        draw_under_color_string(WmfDrawingWand,"none");
    }

  /* Set text clipping (META_EXTTEXTOUT mode) */
  if ( draw_text->flags & ETO_CLIPPED)
    {
    }

  /* Set stroke color */
  draw_stroke_color_string(WmfDrawingWand,"none");

  /* Set fill color */
  draw_fill_color_rgb(API,WMF_DC_TEXTCOLOR(draw_text->dc));

  /* Output font size */
  (void) DrawSetFontSize(WmfDrawingWand,pointsize);

  /* Output Postscript font name */
  (void) DrawSetFont(WmfDrawingWand, WMF_FONT_PSNAME(font));

  /* Translate coordinates so target is 0,0 */
  DrawTranslate(WmfDrawingWand, XC(point.x), YC(point.y));

  /* Transform horizontal scale to draw text at 1:1 ratio */
  DrawScale(WmfDrawingWand, ddata->scale_y / ddata->scale_x, 1.0);

  /* Apply rotation */
  /* ImageMagick's drawing rotation is clockwise from horizontal
     while WMF drawing rotation is counterclockwise from horizontal */
  angle = fabs(RadiansToDegrees(2 * MagickPI - WMF_TEXT_ANGLE(font)));
  if (angle == 360)
    angle = 0;
  if (angle != 0)
    DrawRotate(WmfDrawingWand, angle);

  /*
   * Render text
   *
   */

  /* Output string */
  DrawAnnotation(WmfDrawingWand, 0, 0, (unsigned char*)draw_text->str);

  /* Underline text the Windows way (at the bottom) */
  if (WMF_TEXT_UNDERLINE(font))
    {
      double
        line_height;

      wmfD_Coord
        ulBR,      /* bottom right of underline rectangle */
        ulTL;      /* top left of underline rectangle */

      line_height = ((double)1/(ddata->scale_x))*metrics.underline_thickness;
      if (metrics.underline_thickness < 1.5)
        line_height *= 0.55;
      ulTL.x = 0;
      ulTL.y = fabs(metrics.descent) - line_height;
      ulBR.x = metrics.width;
      ulBR.y = fabs(metrics.descent);

      DrawRectangle(WmfDrawingWand,
                    XC(ulTL.x), YC(ulTL.y), XC(ulBR.x), YC(ulBR.y));
    }

  /* Strikeout text the Windows way */
  if (WMF_TEXT_STRIKEOUT(font))
    {
      double line_height;

      wmfD_Coord
        ulBR,      /* bottom right of strikeout rectangle */
        ulTL;      /* top left of strikeout rectangle */

      line_height = ((double)1/(ddata->scale_x))*metrics.underline_thickness;

      if (metrics.underline_thickness < 2.0)
        line_height *= 0.55;
      ulTL.x = 0;
      ulTL.y = -(((double) metrics.ascent) / 2 + line_height / 2);
      ulBR.x = metrics.width;
      ulBR.y = -(((double) metrics.ascent) / 2 - line_height / 2);

      DrawRectangle(WmfDrawingWand,
                    XC(ulTL.x), YC(ulTL.y), XC(ulBR.x), YC(ulBR.y));

    }

  /* Restore graphic wand */
  (void) PopDrawingWand(WmfDrawingWand);

#if 0
  (void) PushDrawingWand(WmfDrawingWand);
  draw_stroke_color_string(WmfDrawingWand,"red");
  draw_fill_color_string(WmfDrawingWand,"none");
  DrawRectangle(WmfDrawingWand,
                XC(TL.x), YC(TL.y),
                XC(BR.x), YC(BR.y));
  draw_stroke_color_string(WmfDrawingWand,"none");
  (void) PopDrawingWand(WmfDrawingWand);
#endif

}

static void ipa_udata_init(wmfAPI * API, wmfUserData_t * userdata)
{
  (void) API;
  (void) userdata;
  /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */

}

static void ipa_udata_copy(wmfAPI * API, wmfUserData_t * userdata)
{
  (void) API;
  (void) userdata;
  /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */

}

static void ipa_udata_set(wmfAPI * API, wmfUserData_t * userdata)
{
  (void) API;
  (void) userdata;
  /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */

}

static void ipa_udata_free(wmfAPI *API, wmfUserData_t *userdata)
{
  (void) API;
  (void) userdata;
  /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */

}

static void util_set_brush(wmfAPI *API, wmfDC *dc,const BrushApply brush_apply)
{
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  wmfBrush
    *brush = WMF_DC_BRUSH(dc);

  /* Set polygon fill rule */
  switch (WMF_DC_POLYFILL(dc))  /* Is this correct ?? */
    {
    case WINDING:
      DrawSetClipRule(WmfDrawingWand,NonZeroRule);
      break;

    case ALTERNATE:
    default:
      DrawSetClipRule(WmfDrawingWand,EvenOddRule);
      break;
    }

  switch (WMF_BRUSH_STYLE(brush))
    {
    case BS_SOLID /* 0 */:
      /* WMF_BRUSH_COLOR specifies brush color, WMF_BRUSH_HATCH
         ignored */
      {
        if ( brush_apply == BrushApplyStroke )
          draw_stroke_color_rgb(API,WMF_BRUSH_COLOR(brush));
        else
          draw_fill_color_rgb(API,WMF_BRUSH_COLOR(brush));
        break;
      }
    case BS_HOLLOW /* 1 */:    /* BS_HOLLOW & BS_NULL share enum */
      /* WMF_BRUSH_COLOR and WMF_BRUSH_HATCH ignored */
      {
        if ( brush_apply == BrushApplyStroke )
          draw_stroke_color_string(WmfDrawingWand,"none");
        else
          draw_fill_color_string(WmfDrawingWand,"none");
        break;
      }
    case BS_HATCHED /* 2 */:
      /* WMF_BRUSH_COLOR specifies the hatch color, WMF_BRUSH_HATCH
         specifies the hatch brush style. If WMF_DC_OPAQUE, then
         WMF_DC_BACKGROUND specifies hatch background color.  */
      {
        DrawPushDefs(WmfDrawingWand);
        draw_pattern_push(API, ddata->pattern_id, 8, 8);
        (void) PushDrawingWand(WmfDrawingWand);

        if (WMF_DC_OPAQUE(dc))
          {
            if ( brush_apply == BrushApplyStroke )
              draw_stroke_color_rgb(API,WMF_DC_BACKGROUND(dc));
            else
              draw_fill_color_rgb(API,WMF_DC_BACKGROUND(dc));

            DrawRectangle(WmfDrawingWand, 0, 0, 7, 7 );
          }

        DrawSetStrokeAntialias(WmfDrawingWand, MagickFalse);
        DrawSetStrokeWidth(WmfDrawingWand, 1);

        draw_stroke_color_rgb(API,WMF_BRUSH_COLOR(brush));

        switch ((unsigned int) WMF_BRUSH_HATCH(brush))
          {

          case HS_HORIZONTAL:  /* ----- */
            {
              DrawLine(WmfDrawingWand, 0, 3, 7,3);
              break;
            }
          case HS_VERTICAL:  /* ||||| */
            {
              DrawLine(WmfDrawingWand, 3, 0, 3, 7);
              break;
            }
          case HS_FDIAGONAL:  /* \\\\\ */
            {
              DrawLine(WmfDrawingWand, 0, 0, 7, 7);
              break;
            }
          case HS_BDIAGONAL:  /* / */
            {
              DrawLine(WmfDrawingWand, 0, 7, 7, 0 );
              break;
            }
          case HS_CROSS:  /* +++++ */
            {
              DrawLine(WmfDrawingWand, 0, 3, 7, 3 );
              DrawLine(WmfDrawingWand, 3, 0, 3, 7 );
              break;
            }
          case HS_DIAGCROSS:  /* xxxxx */
            {
              DrawLine(WmfDrawingWand, 0, 0, 7, 7 );
              DrawLine(WmfDrawingWand, 0, 7, 7, 0 );
              break;
            }
          default:
            {
              printf("util_set_brush: unexpected brush hatch enumeration %u\n",
                     (unsigned int)WMF_BRUSH_HATCH(brush));
            }
          }
        (void) PopDrawingWand(WmfDrawingWand);
        (void) DrawPopPattern(WmfDrawingWand);
        DrawPopDefs(WmfDrawingWand);
        {
          char
            pattern_id[MagickPathExtent];

          (void) FormatLocaleString(pattern_id,MagickPathExtent,"#brush_%lu",
            ddata->pattern_id);
          if (brush_apply == BrushApplyStroke )
            (void) DrawSetStrokePatternURL(WmfDrawingWand,pattern_id);
          else
            (void) DrawSetFillPatternURL(WmfDrawingWand,pattern_id);
          ++ddata->pattern_id;
        }
        break;
      }
    case BS_PATTERN /* 3 */:
      /* WMF_BRUSH_COLOR ignored, WMF_BRUSH_HATCH provides handle to
         bitmap */
      {
        printf("util_set_brush: BS_PATTERN not supported\n");
        break;
      }
    case BS_INDEXED /* 4 */:
      {
        printf("util_set_brush: BS_INDEXED not supported\n");
        break;
      }
    case BS_DIBPATTERN /* 5 */:
      {
        wmfBMP
          *brush_bmp = WMF_BRUSH_BITMAP(brush);

        if (brush_bmp && brush_bmp->data != 0)
          {
            CompositeOperator
              mode;

            const Image
              *image;

            MagickWand
              *magick_wand;

            image = (Image*)brush_bmp->data;

            mode = CopyCompositeOp;  /* Default is copy */
            switch (WMF_DC_ROP(dc))
              {
                /* Binary raster ops */
              case R2_BLACK:
                printf("util_set_brush: R2_BLACK ROP2 mode not supported!\n");
                break;
              case R2_NOTMERGEPEN:
                printf("util_set_brush: R2_NOTMERGEPEN ROP2 mode not supported!\n");
                break;
              case R2_MASKNOTPEN:
                printf("util_set_brush R2_MASKNOTPEN ROP2 mode not supported!\n");
                break;
              case R2_NOTCOPYPEN:
                printf("util_set_brush: R2_NOTCOPYPEN ROP2 mode not supported!\n");
                break;
              case R2_MASKPENNOT:
                printf("util_set_brush: R2_MASKPENNOT ROP2 mode not supported!\n");
                break;
              case R2_NOT:
                printf("util_set_brush: R2_NOT ROP2 mode not supported!\n");
                break;
              case R2_XORPEN:
                printf("util_set_brush: R2_XORPEN ROP2 mode not supported!\n");
                break;
              case R2_NOTMASKPEN:
                printf("util_set_brush: R2_NOTMASKPEN ROP2 mode not supported!\n");
                break;
              case R2_MASKPEN:
                printf("util_set_brush: R2_MASKPEN ROP2 mode not supported!\n");
                break;
              case R2_NOTXORPEN:
                printf("util_set_brush: R2_NOTXORPEN ROP2 mode not supported!\n");
                break;
              case R2_NOP:
                printf("util_set_brush: R2_NOP ROP2 mode not supported!\n");
                break;
              case R2_MERGENOTPEN:
                printf("util_set_brush: R2_MERGENOTPEN ROP2 mode not supported!\n");
                break;
              case R2_COPYPEN:
                mode = CopyCompositeOp;
                break;
              case R2_MERGEPENNOT:
                printf("util_set_brush: R2_MERGEPENNOT ROP2 mode not supported!\n");
                break;
              case R2_MERGEPEN:
                printf("util_set_brush: R2_MERGEPEN ROP2 mode not supported!\n");
                break;
              case R2_WHITE:
                printf("util_set_brush: R2_WHITE ROP2 mode not supported!\n");
                break;
              default:
                {
                  printf("util_set_brush: unexpected ROP2 enumeration %u!\n",
                         (unsigned int)WMF_DC_ROP(dc));
                }
              }

            DrawPushDefs(WmfDrawingWand);
            draw_pattern_push(API, ddata->pattern_id, brush_bmp->width,
              brush_bmp->height);
            magick_wand=NewMagickWandFromImage(image);
            (void) DrawComposite(WmfDrawingWand,mode, 0, 0, brush_bmp->width,
              brush_bmp->height, magick_wand);
            magick_wand=DestroyMagickWand(magick_wand);
            (void) DrawPopPattern(WmfDrawingWand);
            DrawPopDefs(WmfDrawingWand);

            {
              char
                pattern_id[MagickPathExtent];

              (void) FormatLocaleString(pattern_id,MagickPathExtent,"#brush_%lu",
                ddata->pattern_id);
              if ( brush_apply == BrushApplyStroke )
                (void) DrawSetStrokePatternURL(WmfDrawingWand,pattern_id);
              else
                (void) DrawSetFillPatternURL(WmfDrawingWand,pattern_id);
              ++ddata->pattern_id;
            }
          }
        else
          printf("util_set_brush: no BMP image data!\n");

        break;
      }
    case BS_DIBPATTERNPT /* 6 */:
      /* WMF_BRUSH_COLOR ignored, WMF_BRUSH_HATCH provides pointer to
         DIB */
      {
        printf("util_set_brush: BS_DIBPATTERNPT not supported\n");
        break;
      }
    case BS_PATTERN8X8 /* 7 */:
      {
        printf("util_set_brush: BS_PATTERN8X8 not supported\n");
        break;
      }
    case BS_DIBPATTERN8X8 /* 8 */:
      {
        printf("util_set_brush: BS_DIBPATTERN8X8 not supported\n");
        break;
      }
    default:
      {
      }
    }
}

static void util_set_pen(wmfAPI * API, wmfDC * dc)
{
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  wmfPen
    *pen = 0;

  double
    pen_width,
    pixel_width;

  unsigned int
    pen_style;

  pen = WMF_DC_PEN(dc);

  pen_width = (WMF_PEN_WIDTH(pen) + WMF_PEN_HEIGHT(pen)) / 2;

  /* Pixel width is inverse of pixel scale */
  pixel_width = (((double) 1 / (ddata->scale_x)) +
                 ((double) 1 / (ddata->scale_y))) / 2;

  /* Don't allow pen_width to be much less than pixel_width in order
     to avoid dissapearing or spider-web lines */
  pen_width = MagickMax(pen_width, pixel_width*0.8);

  pen_style = (unsigned int) WMF_PEN_STYLE(pen);

  /* Pen style specified? */
  if (pen_style == PS_NULL)
    {
      draw_stroke_color_string(WmfDrawingWand,"none");
      return;
    }

  DrawSetStrokeAntialias(WmfDrawingWand, MagickTrue );
  DrawSetStrokeWidth(WmfDrawingWand, (unsigned long) MagickMax(0.0, pen_width));

  {
    LineCap
      linecap;

    switch ((unsigned int) WMF_PEN_ENDCAP(pen))
      {
      case PS_ENDCAP_SQUARE:
        linecap = SquareCap;
        break;
      case PS_ENDCAP_ROUND:
        linecap = RoundCap;
        break;
      case PS_ENDCAP_FLAT:
      default:
        linecap = ButtCap;
        break;
      }
    DrawSetStrokeLineCap(WmfDrawingWand, linecap);
  }

  {
    LineJoin
      linejoin;

    switch ((unsigned int) WMF_PEN_JOIN(pen))
      {
      case PS_JOIN_BEVEL:
        linejoin = BevelJoin;
        break;
      case PS_JOIN_ROUND:
        linejoin = RoundJoin;
        break;
      case PS_JOIN_MITER:
      default:
        linejoin = MiterJoin;
        break;
      }
    DrawSetStrokeLineJoin(WmfDrawingWand,linejoin);
  }

  {
    double
      dasharray[7];

    switch (pen_style)
      {
      case PS_DASH:    /* -------  */
        {
          /* Pattern 18,7 */
          dasharray[0] = pixel_width * 18;
          dasharray[1] = pixel_width * 7;
          dasharray[2] = 0;

          DrawSetStrokeAntialias(WmfDrawingWand,MagickFalse);
          (void) DrawSetStrokeDashArray(WmfDrawingWand,2,dasharray);
          break;
        }
      case PS_ALTERNATE:
      case PS_DOT:    /* .......  */
        {
          /* Pattern 3,3 */
          dasharray[0] = pixel_width * 3;
          dasharray[1] = pixel_width * 3;
          dasharray[2] = 0;

          DrawSetStrokeAntialias(WmfDrawingWand,MagickFalse);
          (void) DrawSetStrokeDashArray(WmfDrawingWand,2,dasharray);
          break;
        }
      case PS_DASHDOT:    /* _._._._  */
        {
          /* Pattern 9,6,3,6 */
          dasharray[0] = pixel_width * 9;
          dasharray[1] = pixel_width * 6;
          dasharray[2] = pixel_width * 3;
          dasharray[3] = pixel_width * 6;
          dasharray[4] = 0;

          DrawSetStrokeAntialias(WmfDrawingWand,MagickFalse);
          (void) DrawSetStrokeDashArray(WmfDrawingWand,4,dasharray);
          break;
        }
      case PS_DASHDOTDOT:  /* _.._.._  */
        {
          /* Pattern 9,3,3,3,3,3 */
          dasharray[0] = pixel_width * 9;
          dasharray[1] = pixel_width * 3;
          dasharray[2] = pixel_width * 3;
          dasharray[3] = pixel_width * 3;
          dasharray[4] = pixel_width * 3;
          dasharray[5] = pixel_width * 3;
          dasharray[6] = 0;

          DrawSetStrokeAntialias(WmfDrawingWand,MagickFalse);
          (void) DrawSetStrokeDashArray(WmfDrawingWand,6,dasharray);
          break;
        }
      case PS_INSIDEFRAME:  /* There is nothing to do in this case... */
      case PS_SOLID:
      default:
        {
          (void) DrawSetStrokeDashArray(WmfDrawingWand,0,(double *) NULL);
          break;
        }
      }
  }

  draw_stroke_color_rgb(API,WMF_PEN_COLOR(pen));
}

/* Estimate font pointsize based on Windows font parameters */
static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height, ExceptionInfo *exception)
{
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  Image
    *image = ddata->image;

  TypeMetric
    metrics;

  DrawInfo
    *draw_info;

  double
    pointsize = 0;

  draw_info=ddata->draw_info;
  if (draw_info == (const DrawInfo *) NULL)
    return 0;

  draw_info->font=WMF_FONT_PSNAME(font);
  draw_info->pointsize=font_height;
  draw_info->text=str;

  if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
    {

      if (strlen(str) == 1)
        {
          pointsize = (font_height *
                       ( font_height / (metrics.ascent + fabs(metrics.descent))));
          draw_info->pointsize = pointsize;
          if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
            pointsize *= (font_height / ( metrics.ascent + fabs(metrics.descent)));
        }
      else
        {
          pointsize = (font_height * (font_height / (metrics.height)));
          draw_info->pointsize = pointsize;
          if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
            pointsize *= (font_height / metrics.height);

        }
#if 0
      draw_info.pointsize = pointsize;
      if (GetTypeMetrics(image, &draw_info, &metrics, exception) != MagickFalse)
        pointsize *= (font_height / (metrics.ascent + fabs(metrics.descent)));
      pointsize *= 1.114286; /* Magic number computed through trial and error */
#endif
    }

  draw_info->font=NULL;
  draw_info->text=NULL;
#if 0
  printf("String    = %s\n", str);
  printf("Font      = %s\n", WMF_FONT_PSNAME(font));
  printf("lfHeight  = %g\n", font_height);
  printf("bounds    = %g,%g %g,%g\n", metrics.bounds.x1, metrics.bounds.y1,
         metrics.bounds.x2,metrics.bounds.y2);
  printf("ascent    = %g\n", metrics.ascent);
  printf("descent   = %g\n", metrics.descent);
  printf("height    = %g\n", metrics.height);
  printf("Pointsize = %g\n", pointsize);
#endif

  return floor(pointsize);
}

#if defined(MAGICKCORE_WMF_DELEGATE)
/* Estimate weight based on font name */
/*
static int util_font_weight( const char* font )
{
  int
    weight;

  weight = 400;
  if ((strstr(font,"Normal") || strstr(font,"Regular")))
    weight = 400;
  else if ( strstr(font,"Bold") )
    {
      weight = 700;
      if ((strstr(font,"Semi") || strstr(font,"Demi")))
        weight = 600;
      if ( (strstr(font,"Extra") || strstr(font,"Ultra")))
        weight = 800;
    }
  else if ( strstr(font,"Light") )
    {
      weight = 300;
      if ( (strstr(font,"Extra") || strstr(font,"Ultra")))
        weight = 200;
    }
  else if ((strstr(font,"Heavy") || strstr(font,"Black")))
    weight = 900;
  else if ( strstr(font,"Thin") )
    weight = 100;
  return weight;
}
*/

/*
 * Returns width of string in points, assuming (unstretched) font size of 1pt
 * (similar to wmf_ipa_font_stringwidth)
 *
 * This extremely odd at best, particularly since player/meta.h has access
 * to the corrected font_height (as drawtext.font_height) when it invokes the
 * stringwidth callback.  It should be possible to compute the real stringwidth!
 */
static float lite_font_stringwidth( wmfAPI* API, wmfFont* font, char* str)
{
#if 0
  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  Image
    *image = ddata->image;

  DrawInfo
    *draw_info;

  ExceptionInfo
    *exception;

  TypeMetric
    metrics;

  float
    stringwidth = 0;

  double
    orig_x_resolution,
    orig_y_resolution;

  ResolutionType
    orig_resolution_units;

  orig_x_resolution = image->resolution.x;
  orig_y_resolution = image->resolution.y;
  orig_resolution_units = image->units;

  draw_info=ddata->draw_info;
  if (draw_info == (const DrawInfo *) NULL)
    return 0;

  draw_info->font=WMF_FONT_PSNAME(font);
  draw_info->pointsize=12;
  draw_info->text=str;

  image->resolution.x = 72;
  image->resolution.y = 72;
  image->units = PixelsPerInchResolution;

  exception=ddata->exception;
  if (GetTypeMetrics(image, draw_info, &metrics, exception) != MagickFalse)
    stringwidth = ((metrics.width * 72)/(image->resolution.x * draw_info->pointsize)); /* *0.916348; */

  draw_info->font=NULL;
  draw_info->text=NULL;

#if 0
  printf("\nlite_font_stringwidth\n");
  printf("string                  = \"%s\"\n", str);
  printf("WMF_FONT_NAME           = \"%s\"\n", WMF_FONT_NAME(font));
  printf("WMF_FONT_PSNAME         = \"%s\"\n", WMF_FONT_PSNAME(font));
  printf("stringwidth             = %g\n", stringwidth);
  /* printf("WMF_FONT_HEIGHT         = %i\n", (int)WMF_FONT_HEIGHT(font)); */
  /* printf("WMF_FONT_WIDTH          = %i\n", (int)WMF_FONT_WIDTH(font)); */
  fflush(stdout);
#endif

  image->resolution.x = orig_x_resolution;
  image->resolution.y = orig_y_resolution;
  image->units = orig_resolution_units;

  return stringwidth;
#else
  (void) API;
  (void) font;
  (void) str;

  return 0;
#endif
}

/* Map font (similar to wmf_ipa_font_map) */

/* Mappings to Postscript fonts: family, normal, italic, bold, bolditalic */
static wmfFontMap WMFFontMap[] = {
  { (char *) "Courier",            (char *) "Courier",
    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
    (char *) "Courier-BoldOblique"   },
  { (char *) "Helvetica",          (char *) "Helvetica",
    (char *) "Helvetica-Oblique",  (char *) "Helvetica-Bold",
    (char *) "Helvetica-BoldOblique" },
  { (char *) "Modern",             (char *) "Courier",
    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
    (char *) "Courier-BoldOblique"   },
  { (char *) "Monotype Corsiva",   (char *) "Courier",
    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
    (char *) "Courier-BoldOblique"   },
  { (char *) "News Gothic",        (char *) "Helvetica",
    (char *) "Helvetica-Oblique",  (char *) "Helvetica-Bold",
    (char *) "Helvetica-BoldOblique" },
  { (char *) "Symbol",             (char *) "Symbol",
    (char *) "Symbol",             (char *) "Symbol",
    (char *) "Symbol"                },
  { (char *) "System",             (char *) "Courier",
    (char *) "Courier-Oblique",    (char *) "Courier-Bold",
    (char *) "Courier-BoldOblique"   },
  { (char *) "Times",              (char *) "Times-Roman",
    (char *) "Times-Italic",       (char *) "Times-Bold",
    (char *) "Times-BoldItalic"      },
  { (char *) NULL,                 (char *) NULL,
    (char *) NULL,                 (char *) NULL,
    (char *) NULL                   }
};


/* Mapping between base name and Ghostscript family name */
static wmfMapping SubFontMap[] =
{
  { (char *) "Arial", (char *) "Helvetica", FT_ENCODING_NONE },
  { (char *) "Courier", (char *) "Courier", FT_ENCODING_NONE },
  { (char *) "Fixed", (char *) "Courier", FT_ENCODING_NONE },
  { (char *) "Helvetica", (char *) "Helvetica", FT_ENCODING_NONE },
  { (char *) "Sans", (char *) "Helvetica", FT_ENCODING_NONE },
  { (char *) "Sym", (char *) "Symbol", FT_ENCODING_NONE },
  { (char *) "Terminal", (char *) "Courier", FT_ENCODING_NONE },
  { (char *) "Times", (char *) "Times", FT_ENCODING_NONE },
  { (char *) "Wingdings", (char *) "Symbol", FT_ENCODING_NONE },
  { (char *)  NULL, (char *) NULL, FT_ENCODING_NONE }
};

static void lite_font_map( wmfAPI* API, wmfFont* font)
{
  wmfFontData
    *font_data;

  wmf_magick_font_t
    *magick_font;

  wmf_magick_t
    *ddata = WMF_MAGICK_GetData(API);

  ExceptionInfo
    *exception;

  const TypeInfo
    *type_info,
    *type_info_base;

  const char
    *wmf_font_name;

  if (font == 0)
    return;

  font_data = (wmfFontData*)API->font_data;
  font->user_data = font_data->user_data;
  magick_font = (wmf_magick_font_t*)font->user_data;
  wmf_font_name = WMF_FONT_NAME(font);

  if (magick_font->ps_name != (char *) NULL)
    magick_font->ps_name=DestroyString(magick_font->ps_name);

  exception=ddata->exception;
  type_info_base=GetTypeInfo("*",exception);
  if (type_info_base == 0)
     return;

  /* Certain short-hand font names are not the proper Windows names
     and should be promoted to the proper names */
  if (LocaleCompare(wmf_font_name,"Times") == 0)
    wmf_font_name = "Times New Roman";
  else if (LocaleCompare(wmf_font_name,"Courier") == 0)
    wmf_font_name = "Courier New";

  /* Look for a family-based best-match */
  if (!magick_font->ps_name)
    {
      int
        target_weight;

      if (WMF_FONT_WEIGHT(font) == 0)
        target_weight = 400;
      else
        target_weight = WMF_FONT_WEIGHT(font);
      type_info=GetTypeInfoByFamily(wmf_font_name,AnyStyle,AnyStretch,
        target_weight,exception);
      if (type_info == (const TypeInfo *) NULL)
        type_info=GetTypeInfoByFamily(wmf_font_name,AnyStyle,AnyStretch,0,
          exception);
      if (type_info != (const TypeInfo *) NULL)
        CloneString(&magick_font->ps_name,type_info->name);
    }

  /* Now let's try simple substitution mappings from WMFFontMap */
  if (!magick_font->ps_name)
    {
      char
        target[MagickPathExtent];

      int
        target_weight = 400,
        want_italic = MagickFalse,
        want_bold = MagickFalse,
        i;

      if ( WMF_FONT_WEIGHT(font) != 0 )
        target_weight = WMF_FONT_WEIGHT(font);

      if ( (target_weight > 550) || ((strstr(wmf_font_name,"Bold") ||
                                     strstr(wmf_font_name,"Heavy") ||
                                     strstr(wmf_font_name,"Black"))) )
        want_bold = MagickTrue;

      if ( (WMF_FONT_ITALIC(font)) || ((strstr(wmf_font_name,"Italic") ||
                                       strstr(wmf_font_name,"Oblique"))) )
        want_italic = MagickTrue;

      (void) CopyMagickString(target,"Times",MagickPathExtent);
      for( i=0; SubFontMap[i].name != NULL; i++ )
        {
          if (LocaleCompare(wmf_font_name, SubFontMap[i].name) == 0)
            {
              (void) CopyMagickString(target,SubFontMap[i].mapping,
                MagickPathExtent);
              break;
            }
        }

      for( i=0; WMFFontMap[i].name != NULL; i++ )
        {
          if (LocaleNCompare(WMFFontMap[i].name,target,strlen(WMFFontMap[i].name)) == 0)
            {
              if (want_bold && want_italic)
                CloneString(&magick_font->ps_name,WMFFontMap[i].bolditalic);
              else if (want_italic)
                CloneString(&magick_font->ps_name,WMFFontMap[i].italic);
              else if (want_bold)
                CloneString(&magick_font->ps_name,WMFFontMap[i].bold);
              else
                CloneString(&magick_font->ps_name,WMFFontMap[i].normal);
            }
        }
    }

#if 0
  printf("\nlite_font_map\n");
  printf("WMF_FONT_NAME           = \"%s\"\n", WMF_FONT_NAME(font));
  printf("WMF_FONT_WEIGHT         = %i\n",  WMF_FONT_WEIGHT(font));
  printf("WMF_FONT_PSNAME         = \"%s\"\n", WMF_FONT_PSNAME(font));
  fflush(stdout);
#endif

}

/* Initialize API font structures */
static void lite_font_init( wmfAPI* API, wmfAPI_Options* options)
{
  wmfFontData
    *font_data;

  (void) options;
  API->fonts = 0;

  /* Allocate wmfFontData data structure */
  API->font_data = wmf_malloc(API,sizeof(wmfFontData));
  if (ERR (API))
    return;

  font_data = (wmfFontData*)API->font_data;

  /* Assign function to map font (type wmfMap) */
  font_data->map = lite_font_map;

  /* Assign function to return string width in points (type wmfStringWidth) */
  font_data->stringwidth = lite_font_stringwidth;

  /* Assign user data, not used by libwmflite (type void*) */
  font_data->user_data = wmf_malloc(API,sizeof(wmf_magick_font_t));
  if (ERR(API))
    return;
  ((wmf_magick_font_t*)font_data->user_data)->ps_name = 0;
  ((wmf_magick_font_t*)font_data->user_data)->pointsize = 0;
}

#endif /* MAGICKCORE_WMF_DELEGATE */

/* BLOB read byte */
static int ipa_blob_read(void* wand)
{
  return ReadBlobByte((Image*)wand);
}

/* BLOB seek */
static int ipa_blob_seek(void* wand,long position)
{
  return (int)SeekBlob((Image*)wand,(MagickOffsetType) position,SEEK_SET);
}

/* BLOB tell */
static long ipa_blob_tell(void* wand)
{
  return (long)TellBlob((Image*)wand);
}

static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  double
    bounding_height,
    bounding_width,
    image_height,
    image_height_inch,
    image_width,
    image_width_inch,
    resolution_y,
    resolution_x,
    units_per_inch;

  float
    wmf_width,
    wmf_height;

  Image
    *image;

  MagickBooleanType
    status;

  unsigned long
    wmf_options_flags = 0;

  wmf_error_t
    wmf_error;

  wmf_magick_t
    *ddata = 0;

  wmfAPI
    *API = 0;

  wmfAPI_Options
    wmf_api_options;

  wmfD_Rect
    bbox;

  image=AcquireImage(image_info,exception);
  if (OpenBlob(image_info,image,ReadBinaryBlobMode,exception) == MagickFalse)
    {
      if (image->debug != MagickFalse)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  OpenBlob failed");
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "leave ReadWMFImage()");
        }
      image=DestroyImageList(image);
      return((Image *) NULL);
    }

  /*
   * Create WMF API
   *
   */

  /* Register callbacks */
  wmf_options_flags |= WMF_OPT_FUNCTION;
  (void) ResetMagickMemory(&wmf_api_options, 0, sizeof(wmf_api_options));
  wmf_api_options.function = ipa_functions;

  /* Ignore non-fatal errors */
  wmf_options_flags |= WMF_OPT_IGNORE_NONFATAL;

  wmf_error = wmf_api_create(&API, wmf_options_flags, &wmf_api_options);
  if (wmf_error != wmf_E_None)
    {
      if (API)
        wmf_api_destroy(API);
      if (image->debug != MagickFalse)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  wmf_api_create failed");
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "leave ReadWMFImage()");
        }
      ThrowReaderException(DelegateError,"UnableToInitializeWMFLibrary");
    }

  /* Register progress monitor */
  wmf_status_function(API,image,magick_progress_callback);

  ddata=WMF_MAGICK_GetData(API);
  ddata->image=image;
  ddata->image_info=image_info;
  ddata->draw_info=CloneDrawInfo(image_info,(const DrawInfo *) NULL);
  ddata->exception=exception;
  ddata->draw_info->font=(char *)
    RelinquishMagickMemory(ddata->draw_info->font);
  ddata->draw_info->text=(char *)
    RelinquishMagickMemory(ddata->draw_info->text);

#if defined(MAGICKCORE_WMF_DELEGATE)
  /* Must initialize font subystem for WMFlite interface */
  lite_font_init (API,&wmf_api_options); /* similar to wmf_ipa_font_init in src/font.c */
  /* wmf_arg_fontdirs (API,options); */ /* similar to wmf_arg_fontdirs in src/wmf.c */

#endif

  /*
   * Open BLOB input via libwmf API
   *
   */
  wmf_error = wmf_bbuf_input(API,ipa_blob_read,ipa_blob_seek,
    ipa_blob_tell,(void*)image);
  if (wmf_error != wmf_E_None)
    {
      wmf_api_destroy(API);
      if (image->debug != MagickFalse)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  wmf_bbuf_input failed");
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "leave ReadWMFImage()");
        }
      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
        image->filename);
      image=DestroyImageList(image);
      return((Image *) NULL);
    }

  /*
   * Scan WMF file
   *
   */
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Scanning WMF to obtain bounding box");
  wmf_error=wmf_scan(API, 0, &bbox);
  if (wmf_error != wmf_E_None)
    {
      wmf_api_destroy(API);
      if (image->debug != MagickFalse)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  wmf_scan failed with wmf_error %d", wmf_error);
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "leave ReadWMFImage()");
        }
      ThrowReaderException(DelegateError,"FailedToScanFile");
    }

  /*
   * Compute dimensions and scale factors
   *
   */

  ddata->bbox=bbox;

  /* User specified resolution */
  resolution_y=DefaultResolution;
  if (image->resolution.y != 0.0)
    {
      resolution_y = image->resolution.y;
      if (image->units == PixelsPerCentimeterResolution)
        resolution_y *= CENTIMETERS_PER_INCH;
    }
  resolution_x=DefaultResolution;
  if (image->resolution.x != 0.0)
    {
      resolution_x = image->resolution.x;
      if (image->units == PixelsPerCentimeterResolution)
        resolution_x *= CENTIMETERS_PER_INCH;
    }

  /* Obtain output size expressed in metafile units */
  wmf_error=wmf_size(API,&wmf_width,&wmf_height);
  if (wmf_error != wmf_E_None)
    {
      wmf_api_destroy(API);
      if (image->debug != MagickFalse)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  wmf_size failed with wmf_error %d", wmf_error);
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "leave ReadWMFImage()");
        }
      ThrowReaderException(DelegateError,"FailedToComputeOutputSize");
    }

  /* Obtain (or guess) metafile units */
  if ((API)->File->placeable)
    units_per_inch=(API)->File->pmh->Inch;
  else if ( (wmf_width*wmf_height) < 1024*1024)
    units_per_inch=POINTS_PER_INCH;  /* MM_TEXT */
  else
    units_per_inch=TWIPS_PER_INCH;  /* MM_TWIPS */

  /* Calculate image width and height based on specified DPI
     resolution */
  image_width_inch  = (double) wmf_width / units_per_inch;
  image_height_inch = (double) wmf_height / units_per_inch;
  image_width       = image_width_inch * resolution_x;
  image_height      = image_height_inch * resolution_y;

  /* Compute bounding box scale factors and origin translations
   *
   * This all just a hack since libwmf does not currently seem to
   * provide the mapping between LOGICAL coordinates and DEVICE
   * coordinates. This mapping is necessary in order to know
   * where to place the logical bounding box within the image.
   *
   */

  bounding_width  = bbox.BR.x - bbox.TL.x;
  bounding_height = bbox.BR.y - bbox.TL.y;

  ddata->scale_x = image_width/bounding_width;
  ddata->translate_x = 0-bbox.TL.x;
  ddata->rotate = 0;

  /* Heuristic: guess that if the vertical coordinates mostly span
     negative values, then the image must be inverted. */
  if ( fabs(bbox.BR.y) > fabs(bbox.TL.y) )
    {
      /* Normal (Origin at top left of image) */
      ddata->scale_y = (image_height/bounding_height);
      ddata->translate_y = 0-bbox.TL.y;
    }
  else
    {
      /* Inverted (Origin at bottom left of image) */
      ddata->scale_y = (-image_height/bounding_height);
      ddata->translate_y = 0-bbox.BR.y;
    }

  if (image->debug != MagickFalse)
    {
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "  Placeable metafile:          %s",
         (API)->File->placeable ? "Yes" : "No");

      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Size in metafile units:      %gx%g",wmf_width,wmf_height);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Metafile units/inch:         %g",units_per_inch);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Size in inches:              %gx%g",
        image_width_inch,image_height_inch);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Bounding Box:                %g,%g %g,%g",
        bbox.TL.x, bbox.TL.y, bbox.BR.x, bbox.BR.y);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Bounding width x height:     %gx%g",bounding_width,
        bounding_height);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Output resolution:           %gx%g",resolution_x,resolution_y);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Image size:                  %gx%g",image_width,image_height);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Bounding box scale factor:   %g,%g",ddata->scale_x,
        ddata->scale_y);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Translation:                 %g,%g",
        ddata->translate_x, ddata->translate_y);
    }

#if 0
#if 0
  {
    typedef struct _wmfPlayer_t wmfPlayer_t;
    struct _wmfPlayer_t
    {
      wmfPen   default_pen;
      wmfBrush default_brush;
      wmfFont  default_font;

      wmfDC* dc; /* current dc */
    };

    wmfDC
      *dc;

#define WMF_ELICIT_DC(API) (((wmfPlayer_t*)((API)->player_data))->dc)

    dc = WMF_ELICIT_DC(API);

    printf("dc->Window.Ox     = %d\n", dc->Window.Ox);
    printf("dc->Window.Oy     = %d\n", dc->Window.Oy);
    printf("dc->Window.width  = %d\n", dc->Window.width);
    printf("dc->Window.height = %d\n", dc->Window.height);
    printf("dc->pixel_width   = %g\n", dc->pixel_width);
    printf("dc->pixel_height  = %g\n", dc->pixel_height);
#if defined(MAGICKCORE_WMF_DELEGATE)  /* Only in libwmf 0.3 */
    printf("dc->Ox            = %.d\n", dc->Ox);
    printf("dc->Oy            = %.d\n", dc->Oy);
    printf("dc->width         = %.d\n", dc->width);
    printf("dc->height        = %.d\n", dc->height);
#endif

  }
#endif

#endif

  /*
   * Create canvas image
   *
   */
  image->rows=(unsigned long) ceil(image_height);
  image->columns=(unsigned long) ceil(image_width);

  if (image_info->ping != MagickFalse)
    {
      wmf_api_destroy(API);
      (void) CloseBlob(image);
      if (image->debug != MagickFalse)
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
          "leave ReadWMFImage()");
      return(GetFirstImageInList(image));
    }
  status=SetImageExtent(image,image->columns,image->rows,exception);
  if (status == MagickFalse)
    return(DestroyImageList(image));
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
       "  Creating canvas image with size %lux%lu",(unsigned long) image->rows,
       (unsigned long) image->columns);

  /*
   * Set solid background color
   */
  {
    image->background_color = image_info->background_color;
    if (image->background_color.alpha != OpaqueAlpha)
      image->alpha_trait=BlendPixelTrait;
    (void) SetImageBackgroundColor(image,exception);
  }
  /*
   * Play file to generate Vector drawing commands
   *
   */

  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Playing WMF to prepare vectors");

  wmf_error = wmf_play(API, 0, &bbox);
  if (wmf_error != wmf_E_None)
    {
      wmf_api_destroy(API);
      if (image->debug != MagickFalse)
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "  Playing WMF failed with wmf_error %d", wmf_error);
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "leave ReadWMFImage()");
        }
      ThrowReaderException(DelegateError,"FailedToRenderFile");
    }

  /*
   * Scribble on canvas image
   *
   */

  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
      "  Rendering WMF vectors");
  DrawRender(ddata->draw_wand);

  if (image->debug != MagickFalse)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");

  /* Cleanup allocated data */
  wmf_api_destroy(API);
  (void) CloseBlob(image);

  /* Return image */
  return image;
}
#endif

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e g i s t e r W M F I m a g e                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RegisterWMFImage() adds attributes for the WMF image format to
%  the list of supported formats.  The attributes include the image format
%  tag, a method to read and/or write the format, whether the format
%  supports the saving of more than one frame to the same file or blob,
%  whether the format supports native in-memory I/O, and a brief
%  description of the format.
%
%  The format of the RegisterWMFImage method is:
%
%      size_t RegisterWMFImage(void)
%
*/
ModuleExport size_t RegisterWMFImage(void)
{
  MagickInfo
    *entry;

  entry = AcquireMagickInfo("WMF","WMZ","Compressed Windows Meta File");
#if defined(MAGICKCORE_SANS_DELEGATE) || defined(MAGICKCORE_WMF_DELEGATE)
  entry->decoder=ReadWMFImage;
#endif
  entry->flags|=CoderSeekableStreamFlag;
  (void) RegisterMagickInfo(entry);
  entry=AcquireMagickInfo("WMF","WMF","Windows Meta File");
#if defined(MAGICKCORE_SANS_DELEGATE) || defined(MAGICKCORE_WMF_DELEGATE)
  entry->decoder=ReadWMFImage;
#endif
  (void) RegisterMagickInfo(entry);
  return(MagickImageCoderSignature);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   U n r e g i s t e r W M F I m a g e                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  UnregisterWMFImage() removes format registrations made by the
%  WMF module from the list of supported formats.
%
%  The format of the UnregisterWMFImage method is:
%
%      UnregisterWMFImage(void)
%
*/
ModuleExport void UnregisterWMFImage(void)
{
  (void) UnregisterMagickInfo("WMZ");
  (void) UnregisterMagickInfo("WMF");
}
