Home | History | Annotate | Download | only in MagickWand
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %               DDDD   RRRR    AAA   W   W  IIIII  N   N    GGGG              %
      7 %               D   D  R   R  A   A  W   W    I    NN  N   G                  %
      8 %               D   D  RRRR   AAAAA  W   W    I    N N N   G  GG              %
      9 %               D   D  R R    A   A  W W W    I    N  NN   G   G              %
     10 %               DDDD   R  R   A   A   W W   IIIII  N   N    GGG               %
     11 %                                                                             %
     12 %                         W   W   AAA   N   N  DDDD                           %
     13 %                         W   W  A   A  NN  N  D   D                          %
     14 %                         W W W  AAAAA  N N N  D   D                          %
     15 %                         WW WW  A   A  N  NN  D   D                          %
     16 %                         W   W  A   A  N   N  DDDD                           %
     17 %                                                                             %
     18 %                                                                             %
     19 %                   MagickWand Image Vector Drawing Methods                   %
     20 %                                                                             %
     21 %                              Software Design                                %
     22 %                              Bob Friesenhahn                                %
     23 %                                March 2002                                   %
     24 %                                                                             %
     25 %                                                                             %
     26 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
     27 %  dedicated to making software imaging solutions freely available.           %
     28 %                                                                             %
     29 %  You may not use this file except in compliance with the License.  You may  %
     30 %  obtain a copy of the License at                                            %
     31 %                                                                             %
     32 %    https://imagemagick.org/script/license.php                               %
     33 %                                                                             %
     34 %  Unless required by applicable law or agreed to in writing, software        %
     35 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     36 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     37 %  See the License for the specific language governing permissions and        %
     38 %  limitations under the License.                                             %
     39 %                                                                             %
     40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     41 %
     42 %
     43 %
     44 */
     45 
     46 /*
     48   Include declarations.
     49 */
     50 #include "MagickWand/studio.h"
     51 #include "MagickWand/MagickWand.h"
     52 #include "MagickWand/magick-wand-private.h"
     53 #include "MagickWand/wand.h"
     54 #include "MagickCore/string-private.h"
     55 
     56 /*
     58   Define declarations.
     59 */
     60 #define DRAW_BINARY_IMPLEMENTATION 0
     61 
     62 #define CurrentContext  (wand->graphic_context[wand->index])
     63 #define DrawingWandId  "DrawingWand"
     64 #define ThrowDrawException(severity,tag,reason) (void) ThrowMagickException( \
     65   wand->exception,GetMagickModule(),severity,tag,"`%s'",reason);
     66 
     67 /*
     69   Typedef declarations.
     70 */
     71 typedef enum
     72 {
     73   PathDefaultOperation,
     74   PathCloseOperation,                        /* Z|z (none) */
     75   PathCurveToOperation,                      /* C|c (x1 y1 x2 y2 x y)+ */
     76   PathCurveToQuadraticBezierOperation,       /* Q|q (x1 y1 x y)+ */
     77   PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
     78   PathCurveToSmoothOperation,                /* S|s (x2 y2 x y)+ */
     79   PathEllipticArcOperation,                  /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
     80   PathLineToHorizontalOperation,             /* H|h x+ */
     81   PathLineToOperation,                       /* L|l (x y)+ */
     82   PathLineToVerticalOperation,               /* V|v y+ */
     83   PathMoveToOperation                        /* M|m (x y)+ */
     84 } PathOperation;
     85 
     86 typedef enum
     87 {
     88   DefaultPathMode,
     89   AbsolutePathMode,
     90   RelativePathMode
     91 } PathMode;
     92 
     93 struct _DrawingWand
     94 {
     95   size_t
     96     id;
     97 
     98   char
     99     name[MagickPathExtent];
    100 
    101   /* Support structures */
    102   Image
    103     *image;
    104 
    105   ExceptionInfo
    106     *exception;
    107 
    108   /* MVG output string and housekeeping */
    109   char
    110     *mvg;               /* MVG data */
    111 
    112   size_t
    113     mvg_alloc,          /* total allocated memory */
    114     mvg_length;         /* total MVG length */
    115 
    116   size_t
    117     mvg_width;          /* current line width */
    118 
    119   /* Pattern support */
    120   char
    121     *pattern_id;
    122 
    123   RectangleInfo
    124     pattern_bounds;
    125 
    126   size_t
    127     pattern_offset;
    128 
    129   /* Graphic wand */
    130   size_t
    131     index;              /* array index */
    132 
    133   DrawInfo
    134     **graphic_context;
    135 
    136   MagickBooleanType
    137     filter_off;         /* true if not filtering attributes */
    138 
    139   /* Pretty-printing depth */
    140   size_t
    141     indent_depth;       /* number of left-hand pad characters */
    142 
    143   /* Path operation support */
    144   PathOperation
    145     path_operation;
    146 
    147   PathMode
    148     path_mode;
    149 
    150   MagickBooleanType
    151     destroy,
    152     debug;
    153 
    154   size_t
    155     signature;
    156 };
    157 
    158 /*
    159   Forward declarations.
    160 */
    161 static int
    162   MVGPrintf(DrawingWand *,const char *,...) wand_attribute((format
    163     (printf,2,3))),
    164   MVGAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format
    165     (printf,2,3)));
    166 
    167 static void
    168   MVGAppendColor(DrawingWand *,const PixelInfo *);
    169 
    170 /*
    172   "Printf" for MVG commands
    173 */
    174 static int MVGPrintf(DrawingWand *wand,const char *format,...)
    175 {
    176   size_t
    177     extent;
    178 
    179   assert(wand != (DrawingWand *) NULL);
    180   if (wand->debug != MagickFalse)
    181     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format);
    182   assert(wand->signature == MagickWandSignature);
    183   extent=20UL*MagickPathExtent;
    184   if (wand->mvg == (char *) NULL)
    185     {
    186       wand->mvg=(char *) AcquireQuantumMemory(extent,sizeof(*wand->mvg));
    187       if (wand->mvg == (char *) NULL)
    188         {
    189           ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
    190             wand->name);
    191           return(-1);
    192         }
    193       wand->mvg_alloc=extent;
    194       wand->mvg_length=0;
    195     }
    196   if (wand->mvg_alloc < (wand->mvg_length+10*MagickPathExtent))
    197     {
    198       extent+=wand->mvg_alloc;
    199       wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,extent,
    200         sizeof(*wand->mvg));
    201       if (wand->mvg == (char *) NULL)
    202         {
    203           ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
    204             wand->name);
    205           return(-1);
    206         }
    207       wand->mvg_alloc=extent;
    208     }
    209   {
    210     int
    211       count;
    212 
    213     ssize_t
    214       offset;
    215 
    216     va_list
    217       argp;
    218 
    219     while (wand->mvg_width < wand->indent_depth)
    220     {
    221       wand->mvg[wand->mvg_length]=' ';
    222       wand->mvg_length++;
    223       wand->mvg_width++;
    224     }
    225     wand->mvg[wand->mvg_length]='\0';
    226     count=(-1);
    227     offset=(ssize_t) wand->mvg_alloc-wand->mvg_length-1;
    228     if (offset > 0)
    229       {
    230         va_start(argp,format);
    231 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
    232         count=vsnprintf(wand->mvg+wand->mvg_length,(size_t) offset,format,argp);
    233 #else
    234         count=vsprintf(wand->mvg+wand->mvg_length,format,argp);
    235 #endif
    236         va_end(argp);
    237       }
    238     if ((count < 0) || (count > (int) offset))
    239       ThrowDrawException(DrawError,"UnableToPrint",format)
    240     else
    241       {
    242         wand->mvg_length+=count;
    243         wand->mvg_width+=count;
    244       }
    245     wand->mvg[wand->mvg_length]='\0';
    246     if ((wand->mvg_length > 1) && (wand->mvg[wand->mvg_length-1] == '\n'))
    247       wand->mvg_width=0;
    248     assert((wand->mvg_length+1) < wand->mvg_alloc);
    249     return(count);
    250   }
    251 }
    252 
    253 static int MVGAutoWrapPrintf(DrawingWand *wand,const char *format,...)
    254 {
    255   char
    256     buffer[MagickPathExtent];
    257 
    258   int
    259     count;
    260 
    261   va_list
    262     argp;
    263 
    264   va_start(argp,format);
    265 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
    266   count=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
    267 #else
    268   count=vsprintf(buffer,format,argp);
    269 #endif
    270   va_end(argp);
    271   buffer[sizeof(buffer)-1]='\0';
    272   if (count < 0)
    273     ThrowDrawException(DrawError,"UnableToPrint",format)
    274   else
    275     {
    276       if (((wand->mvg_width + count) > 78) && (buffer[count-1] != '\n'))
    277         (void) MVGPrintf(wand, "\n");
    278       (void) MVGPrintf(wand,"%s",buffer);
    279     }
    280   return(count);
    281 }
    282 
    283 static void MVGAppendColor(DrawingWand *wand,const PixelInfo *packet)
    284 {
    285   if ((packet->red == 0) && (packet->green == 0) && (packet->blue == 0) &&
    286       (packet->alpha == (Quantum) TransparentAlpha))
    287     (void) MVGPrintf(wand,"none");
    288   else
    289     {
    290       char
    291         tuple[MagickPathExtent];
    292 
    293       PixelInfo
    294         pixel;
    295 
    296       GetPixelInfo(wand->image,&pixel);
    297       pixel.colorspace=sRGBColorspace;
    298       pixel.alpha_trait=packet->alpha != OpaqueAlpha ? BlendPixelTrait :
    299         UndefinedPixelTrait;
    300       pixel.red=(double) packet->red;
    301       pixel.green=(double) packet->green;
    302       pixel.blue=(double) packet->blue;
    303       pixel.alpha=(double) packet->alpha;
    304       GetColorTuple(&pixel,MagickTrue,tuple);
    305       (void) MVGPrintf(wand,"%s",tuple);
    306     }
    307 }
    308 
    309 static void MVGAppendPointsCommand(DrawingWand *wand,const char *command,
    310   const size_t number_coordinates,const PointInfo *coordinates)
    311 {
    312   const PointInfo
    313     *coordinate;
    314 
    315   size_t
    316     i;
    317 
    318   (void) MVGPrintf(wand,"%s",command);
    319   for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
    320   {
    321     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",coordinate->x,coordinate->y);
    322     coordinate++;
    323   }
    324   (void) MVGPrintf(wand, "\n");
    325 }
    326 
    327 static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine)
    328 {
    329   assert(wand != (DrawingWand *) NULL);
    330   assert(wand->signature == MagickWandSignature);
    331   if (wand->debug != MagickFalse)
    332     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    333   if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
    334       (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
    335     {
    336       AffineMatrix
    337         current;
    338 
    339       current=CurrentContext->affine;
    340       CurrentContext->affine.sx=affine->sx*current.sx+affine->ry*current.rx;
    341       CurrentContext->affine.rx=affine->rx*current.sx+affine->sy*current.rx;
    342       CurrentContext->affine.ry=affine->sx*current.ry+affine->ry*current.sy;
    343       CurrentContext->affine.sy=affine->rx*current.ry+affine->sy*current.sy;
    344       CurrentContext->affine.tx=affine->sx*current.tx+affine->ry*current.ty+
    345         affine->tx;
    346       CurrentContext->affine.ty=affine->rx*current.tx+affine->sy*current.ty+
    347         affine->ty;
    348     }
    349 }
    350 
    351 /*
    353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    354 %                                                                             %
    355 %                                                                             %
    356 %                                                                             %
    357 +   A c q u i r e D r a w i n g W a n d                                       %
    358 %                                                                             %
    359 %                                                                             %
    360 %                                                                             %
    361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    362 %
    363 %  AcquireDrawingWand() allocates an initial drawing wand which is an opaque
    364 %  handle required by the remaining drawing methods.
    365 %
    366 %  The format of the AcquireDrawingWand method is:
    367 %
    368 %      DrawingWand AcquireDrawingWand(const DrawInfo *draw_info,Image *image)
    369 %
    370 %  A description of each parameter follows:
    371 %
    372 %    o draw_info: Initial drawing defaults. Set to NULL to use defaults.
    373 %
    374 %    o image: the image to draw on.
    375 %
    376 */
    377 WandExport DrawingWand *AcquireDrawingWand(const DrawInfo *draw_info,
    378   Image *image)
    379 {
    380   DrawingWand
    381     *wand;
    382 
    383   wand=NewDrawingWand();
    384   if (draw_info != (const DrawInfo *) NULL)
    385     {
    386       CurrentContext=DestroyDrawInfo(CurrentContext);
    387       CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
    388     }
    389   if (image != (Image *) NULL)
    390     {
    391       wand->image=DestroyImage(wand->image);
    392       wand->destroy=MagickFalse;
    393     }
    394   wand->image=image;
    395   return(wand);
    396 }
    397 
    398 /*
    400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    401 %                                                                             %
    402 %                                                                             %
    403 %                                                                             %
    404 %   C l e a r D r a w i n g W a n d                                           %
    405 %                                                                             %
    406 %                                                                             %
    407 %                                                                             %
    408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    409 %
    410 %  ClearDrawingWand() clears resources associated with the drawing wand.
    411 %
    412 %  The format of the ClearDrawingWand method is:
    413 %
    414 %      void ClearDrawingWand(DrawingWand *wand)
    415 %
    416 %  A description of each parameter follows:
    417 %
    418 %    o wand: the drawing wand to clear.
    419 %
    420 */
    421 WandExport void ClearDrawingWand(DrawingWand *wand)
    422 {
    423   assert(wand != (DrawingWand *) NULL);
    424   assert(wand->signature == MagickWandSignature);
    425   if (wand->debug != MagickFalse)
    426     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    427   for ( ; wand->index > 0; wand->index--)
    428     CurrentContext=DestroyDrawInfo(CurrentContext);
    429   CurrentContext=DestroyDrawInfo(CurrentContext);
    430   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
    431     wand->graphic_context);
    432   if (wand->pattern_id != (char *) NULL)
    433     wand->pattern_id=DestroyString(wand->pattern_id);
    434   wand->mvg=DestroyString(wand->mvg);
    435   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
    436     wand->image=DestroyImage(wand->image);
    437   else
    438     wand->image=(Image *) NULL;
    439   wand->mvg=(char *) NULL;
    440   wand->mvg_alloc=0;
    441   wand->mvg_length=0;
    442   wand->mvg_width=0;
    443   wand->pattern_id=(char *) NULL;
    444   wand->pattern_offset=0;
    445   wand->pattern_bounds.x=0;
    446   wand->pattern_bounds.y=0;
    447   wand->pattern_bounds.width=0;
    448   wand->pattern_bounds.height=0;
    449   wand->index=0;
    450   wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
    451     sizeof(*wand->graphic_context));
    452   if (wand->graphic_context == (DrawInfo **) NULL)
    453     {
    454       ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
    455         wand->name);
    456       return;
    457     }
    458   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
    459   wand->filter_off=MagickTrue;
    460   wand->indent_depth=0;
    461   wand->path_operation=PathDefaultOperation;
    462   wand->path_mode=DefaultPathMode;
    463   wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception);
    464   ClearMagickException(wand->exception);
    465   wand->destroy=MagickTrue;
    466   wand->debug=IsEventLogging();
    467 }
    468 
    469 /*
    471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    472 %                                                                             %
    473 %                                                                             %
    474 %                                                                             %
    475 %   C l o n e D r a w i n g W a n d                                           %
    476 %                                                                             %
    477 %                                                                             %
    478 %                                                                             %
    479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    480 %
    481 %  CloneDrawingWand() makes an exact copy of the specified wand.
    482 %
    483 %  The format of the CloneDrawingWand method is:
    484 %
    485 %      DrawingWand *CloneDrawingWand(const DrawingWand *wand)
    486 %
    487 %  A description of each parameter follows:
    488 %
    489 %    o wand: the magick wand.
    490 %
    491 */
    492 WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
    493 {
    494   DrawingWand
    495     *clone_wand;
    496 
    497   register ssize_t
    498     i;
    499 
    500   assert(wand != (DrawingWand *) NULL);
    501   assert(wand->signature == MagickWandSignature);
    502   if (wand->debug != MagickFalse)
    503     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    504   clone_wand=(DrawingWand *) AcquireMagickMemory(sizeof(*clone_wand));
    505   if (clone_wand == (DrawingWand *) NULL)
    506     ThrowWandFatalException(ResourceLimitFatalError,
    507       "MemoryAllocationFailed",GetExceptionMessage(errno));
    508   (void) memset(clone_wand,0,sizeof(*clone_wand));
    509   clone_wand->id=AcquireWandId();
    510   (void) FormatLocaleString(clone_wand->name,MagickPathExtent,
    511     "DrawingWand-%.20g",(double) clone_wand->id);
    512   clone_wand->exception=AcquireExceptionInfo();
    513   InheritException(clone_wand->exception,wand->exception);
    514   clone_wand->mvg=AcquireString(wand->mvg);
    515   clone_wand->mvg_length=strlen(clone_wand->mvg);
    516   clone_wand->mvg_alloc=wand->mvg_length+1;
    517   clone_wand->mvg_width=wand->mvg_width;
    518   clone_wand->pattern_id=AcquireString(wand->pattern_id);
    519   clone_wand->pattern_offset=wand->pattern_offset;
    520   clone_wand->pattern_bounds=wand->pattern_bounds;
    521   clone_wand->index=wand->index;
    522   clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((size_t)
    523     wand->index+1UL,sizeof(*wand->graphic_context));
    524   if (clone_wand->graphic_context == (DrawInfo **) NULL)
    525     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
    526       GetExceptionMessage(errno));
    527   for (i=0; i <= (ssize_t) wand->index; i++)
    528     clone_wand->graphic_context[i]=CloneDrawInfo((ImageInfo *) NULL,
    529       wand->graphic_context[i]);
    530   clone_wand->filter_off=wand->filter_off;
    531   clone_wand->indent_depth=wand->indent_depth;
    532   clone_wand->path_operation=wand->path_operation;
    533   clone_wand->path_mode=wand->path_mode;
    534   clone_wand->image=wand->image;
    535   if (wand->image != (Image *) NULL)
    536     clone_wand->image=CloneImage(wand->image,0,0,MagickTrue,
    537       clone_wand->exception);
    538   clone_wand->destroy=MagickTrue;
    539   clone_wand->debug=IsEventLogging();
    540   if (clone_wand->debug != MagickFalse)
    541     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
    542   clone_wand->signature=MagickWandSignature;
    543   return(clone_wand);
    544 }
    545 
    546 /*
    548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    549 %                                                                             %
    550 %                                                                             %
    551 %                                                                             %
    552 %   D e s t r o y D r a w i n g W a n d                                       %
    553 %                                                                             %
    554 %                                                                             %
    555 %                                                                             %
    556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    557 %
    558 %  DestroyDrawingWand() frees all resources associated with the drawing wand.
    559 %  Once the drawing wand has been freed, it should not be used and further
    560 %  unless it re-allocated.
    561 %
    562 %  The format of the DestroyDrawingWand method is:
    563 %
    564 %      DrawingWand *DestroyDrawingWand(DrawingWand *wand)
    565 %
    566 %  A description of each parameter follows:
    567 %
    568 %    o wand: the drawing wand to destroy.
    569 %
    570 */
    571 WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
    572 {
    573   assert(wand != (DrawingWand *) NULL);
    574   assert(wand->signature == MagickWandSignature);
    575   if (wand->debug != MagickFalse)
    576     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    577   for ( ; wand->index > 0; wand->index--)
    578     CurrentContext=DestroyDrawInfo(CurrentContext);
    579   CurrentContext=DestroyDrawInfo(CurrentContext);
    580   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
    581     wand->graphic_context);
    582   if (wand->pattern_id != (char *) NULL)
    583     wand->pattern_id=DestroyString(wand->pattern_id);
    584   wand->mvg=DestroyString(wand->mvg);
    585   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
    586     wand->image=DestroyImage(wand->image);
    587   wand->image=(Image *) NULL;
    588   wand->exception=DestroyExceptionInfo(wand->exception);
    589   wand->signature=(~MagickWandSignature);
    590   RelinquishWandId(wand->id);
    591   wand=(DrawingWand *) RelinquishMagickMemory(wand);
    592   return(wand);
    593 }
    594 
    595 /*
    597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    598 %                                                                             %
    599 %                                                                             %
    600 %                                                                             %
    601 %   D r a w A f f i n e                                                       %
    602 %                                                                             %
    603 %                                                                             %
    604 %                                                                             %
    605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    606 %
    607 %  DrawAffine() adjusts the current affine transformation matrix with
    608 %  the specified affine transformation matrix. Note that the current affine
    609 %  transform is adjusted rather than replaced.
    610 %
    611 %  The format of the DrawAffine method is:
    612 %
    613 %      void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
    614 %
    615 %  A description of each parameter follows:
    616 %
    617 %    o wand: Drawing wand
    618 %
    619 %    o affine: Affine matrix parameters
    620 %
    621 */
    622 WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
    623 {
    624   assert(wand != (DrawingWand *) NULL);
    625   assert(wand->signature == MagickWandSignature);
    626   if (wand->debug != MagickFalse)
    627     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    628   assert(affine != (const AffineMatrix *) NULL);
    629   AdjustAffine(wand,affine);
    630   (void) MVGPrintf(wand,"affine %.20g %.20g %.20g %.20g %.20g %.20g\n",
    631     affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
    632 }
    633 
    634 /*
    636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    637 %                                                                             %
    638 %                                                                             %
    639 %                                                                             %
    640 %   D r a w A l p h a                                                         %
    641 %                                                                             %
    642 %                                                                             %
    643 %                                                                             %
    644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    645 %
    646 %  DrawAlpha() paints on the image's alpha channel in order to set effected
    647 %  pixels to transparent. The available paint methods are:
    648 %
    649 %    PointMethod: Select the target pixel
    650 %    ReplaceMethod: Select any pixel that matches the target pixel.
    651 %    FloodfillMethod: Select the target pixel and matching neighbors.
    652 %    FillToBorderMethod: Select the target pixel and neighbors not matching
    653 %      border color.
    654 %    ResetMethod: Select all pixels.
    655 %
    656 %  The format of the DrawAlpha method is:
    657 %
    658 %      void DrawAlpha(DrawingWand *wand,const double x,const double y,
    659 %        const PaintMethod paint_method)
    660 %
    661 %  A description of each parameter follows:
    662 %
    663 %    o wand: the drawing wand.
    664 %
    665 %    o x: x ordinate
    666 %
    667 %    o y: y ordinate
    668 %
    669 %    o paint_method: paint method.
    670 %
    671 */
    672 WandExport void DrawAlpha(DrawingWand *wand,const double x,const double y,
    673   const PaintMethod paint_method)
    674 {
    675   assert(wand != (DrawingWand *) NULL);
    676   assert(wand->signature == MagickWandSignature);
    677   if (wand->debug != MagickFalse)
    678     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    679   (void) MVGPrintf(wand,"alpha %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
    680     MagickMethodOptions,(ssize_t) paint_method));
    681 }
    682 
    683 /*
    685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    686 %                                                                             %
    687 %                                                                             %
    688 %                                                                             %
    689 %   D r a w A n n o t a t i o n                                               %
    690 %                                                                             %
    691 %                                                                             %
    692 %                                                                             %
    693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    694 %
    695 %  DrawAnnotation() draws text on the image.
    696 %
    697 %  The format of the DrawAnnotation method is:
    698 %
    699 %      void DrawAnnotation(DrawingWand *wand,const double x,
    700 %        const double y,const unsigned char *text)
    701 %
    702 %  A description of each parameter follows:
    703 %
    704 %    o wand: the drawing wand.
    705 %
    706 %    o x: x ordinate to left of text
    707 %
    708 %    o y: y ordinate to text baseline
    709 %
    710 %    o text: text to draw
    711 %
    712 */
    713 WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y,
    714   const unsigned char *text)
    715 {
    716   char
    717     *escaped_text;
    718 
    719   assert(wand != (DrawingWand *) NULL);
    720   assert(wand->signature == MagickWandSignature);
    721   if (wand->debug != MagickFalse)
    722     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    723   assert(text != (const unsigned char *) NULL);
    724   escaped_text=EscapeString((const char *) text,'\'');
    725   if (escaped_text != (char *) NULL)
    726     {
    727       (void) MVGPrintf(wand,"text %.20g %.20g '%s'\n",x,y,escaped_text);
    728       escaped_text=DestroyString(escaped_text);
    729     }
    730 }
    731 
    732 /*
    734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    735 %                                                                             %
    736 %                                                                             %
    737 %                                                                             %
    738 %   D r a w A r c                                                             %
    739 %                                                                             %
    740 %                                                                             %
    741 %                                                                             %
    742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    743 %
    744 %  DrawArc() draws an arc falling within a specified bounding rectangle on the
    745 %  image.
    746 %
    747 %  The format of the DrawArc method is:
    748 %
    749 %      void DrawArc(DrawingWand *wand,const double sx,const double sy,
    750 %        const double ex,const double ey,const double sd,const double ed)
    751 %
    752 %  A description of each parameter follows:
    753 %
    754 %    o wand: the drawing wand.
    755 %
    756 %    o sx: starting x ordinate of bounding rectangle
    757 %
    758 %    o sy: starting y ordinate of bounding rectangle
    759 %
    760 %    o ex: ending x ordinate of bounding rectangle
    761 %
    762 %    o ey: ending y ordinate of bounding rectangle
    763 %
    764 %    o sd: starting degrees of rotation
    765 %
    766 %    o ed: ending degrees of rotation
    767 %
    768 */
    769 WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy,
    770   const double ex,const double ey,const double sd,const double ed)
    771 {
    772   assert(wand != (DrawingWand *) NULL);
    773   assert(wand->signature == MagickWandSignature);
    774   if (wand->debug != MagickFalse)
    775     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    776   (void) MVGPrintf(wand,"arc %.20g %.20g %.20g %.20g %.20g %.20g\n",sx,sy,ex,
    777     ey,sd,ed);
    778 }
    779 
    780 /*
    782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    783 %                                                                             %
    784 %                                                                             %
    785 %                                                                             %
    786 %   D r a w B e z i e r                                                       %
    787 %                                                                             %
    788 %                                                                             %
    789 %                                                                             %
    790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    791 %
    792 %  DrawBezier() draws a bezier curve through a set of points on the image.
    793 %
    794 %  The format of the DrawBezier method is:
    795 %
    796 %      void DrawBezier(DrawingWand *wand,
    797 %        const size_t number_coordinates,const PointInfo *coordinates)
    798 %
    799 %  A description of each parameter follows:
    800 %
    801 %    o wand: the drawing wand.
    802 %
    803 %    o number_coordinates: number of coordinates
    804 %
    805 %    o coordinates: coordinates
    806 %
    807 */
    808 WandExport void DrawBezier(DrawingWand *wand,
    809   const size_t number_coordinates,const PointInfo *coordinates)
    810 {
    811   assert(wand != (DrawingWand *) NULL);
    812   assert(wand->signature == MagickWandSignature);
    813   if (wand->debug != MagickFalse)
    814     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    815   assert(coordinates != (const PointInfo *) NULL);
    816   MVGAppendPointsCommand(wand,"bezier",number_coordinates,coordinates);
    817 }
    818 
    819 /*
    821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    822 %                                                                             %
    823 %                                                                             %
    824 %                                                                             %
    825 %   D r a w C i r c l e                                                       %
    826 %                                                                             %
    827 %                                                                             %
    828 %                                                                             %
    829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    830 %
    831 %  DrawCircle() draws a circle on the image.
    832 %
    833 %  The format of the DrawCircle method is:
    834 %
    835 %      void DrawCircle(DrawingWand *wand,const double ox,
    836 %        const double oy,const double px, const double py)
    837 %
    838 %  A description of each parameter follows:
    839 %
    840 %    o wand: the drawing wand.
    841 %
    842 %    o ox: origin x ordinate
    843 %
    844 %    o oy: origin y ordinate
    845 %
    846 %    o px: perimeter x ordinate
    847 %
    848 %    o py: perimeter y ordinate
    849 %
    850 */
    851 WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
    852   const double px,const double py)
    853 {
    854   assert(wand != (DrawingWand *) NULL);
    855   assert(wand->signature == MagickWandSignature);
    856   if (wand->debug != MagickFalse)
    857     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    858   (void) MVGPrintf(wand,"circle %.20g %.20g %.20g %.20g\n",ox,oy,px,py);
    859 }
    860 
    861 /*
    863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    864 %                                                                             %
    865 %                                                                             %
    866 %                                                                             %
    867 %   D r a w C l e a r E x c e p t i o n                                       %
    868 %                                                                             %
    869 %                                                                             %
    870 %                                                                             %
    871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    872 %
    873 %  DrawClearException() clear any exceptions associated with the wand.
    874 %
    875 %  The format of the DrawClearException method is:
    876 %
    877 %      MagickBooleanType DrawClearException(DrawWand *wand)
    878 %
    879 %  A description of each parameter follows:
    880 %
    881 %    o wand: the drawing wand.
    882 %
    883 */
    884 WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
    885 {
    886   assert(wand != (DrawingWand *) NULL);
    887   assert(wand->signature == MagickWandSignature);
    888   if (wand->debug != MagickFalse)
    889     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
    890   ClearMagickException(wand->exception);
    891   return(MagickTrue);
    892 }
    893 
    894 /*
    895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    896 %                                                                             %
    897 %                                                                             %
    898 %                                                                             %
    899 %   D r a w C l o n e E x c e p t i o n I n f o                               %
    900 %                                                                             %
    901 %                                                                             %
    902 %                                                                             %
    903 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    904 %
    905 %  DrawCloneExceptionInfo() clones the ExceptionInfo structure within the wand.
    906 %
    907 %  The format of the DrawCloneExceptionInfo method is:
    908 %
    909 %      ExceptionInfo *DrawCloneExceptionInfo(DrawWand *wand)
    910 %
    911 %  A description of each parameter follows:
    912 %
    913 %    o wand: the drawing wand.
    914 %
    915 */
    916 WandExport ExceptionInfo *DrawCloneExceptionInfo(const DrawingWand *wand)
    917 {
    918   assert(wand != (DrawingWand *) NULL);
    919   assert(wand->signature == MagickWandSignature);
    920   if (wand->exception == (ExceptionInfo*) NULL)
    921     return (ExceptionInfo*) NULL;
    922   return CloneExceptionInfo(wand->exception);
    923 }
    924 
    925 /*
    926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    927 %                                                                             %
    928 %                                                                             %
    929 %                                                                             %
    930 %   D r a w C o l o r                                                         %
    931 %                                                                             %
    932 %                                                                             %
    933 %                                                                             %
    934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    935 %
    936 %  DrawColor() draws color on image using the current fill color, starting at
    937 %  specified position, and using specified paint method. The available paint
    938 %  methods are:
    939 %
    940 %    PointMethod: Recolors the target pixel
    941 %    ReplaceMethod: Recolor any pixel that matches the target pixel.
    942 %    FloodfillMethod: Recolors target pixels and matching neighbors.
    943 %    ResetMethod: Recolor all pixels.
    944 %
    945 %  The format of the DrawColor method is:
    946 %
    947 %      void DrawColor(DrawingWand *wand,const double x,const double y,
    948 %        const PaintMethod paint_method)
    949 %
    950 %  A description of each parameter follows:
    951 %
    952 %    o wand: the drawing wand.
    953 %
    954 %    o x: x ordinate.
    955 %
    956 %    o y: y ordinate.
    957 %
    958 %    o paint_method: paint method.
    959 %
    960 */
    961 WandExport void DrawColor(DrawingWand *wand, const double x, const double y,
    962   const PaintMethod paint_method)
    963 {
    964   assert(wand != (DrawingWand *)NULL);
    965   assert(wand->signature == MagickWandSignature);
    966   if (wand->debug != MagickFalse)
    967     (void) LogMagickEvent(WandEvent, GetMagickModule(), "%s", wand->name);
    968   (void) MVGPrintf(wand, "color %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
    969     MagickMethodOptions,(ssize_t) paint_method));
    970 }
    971 
    972 /*
    974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    975 %                                                                             %
    976 %                                                                             %
    977 %                                                                             %
    978 %   D r a w C o m p o s i t e                                                 %
    979 %                                                                             %
    980 %                                                                             %
    981 %                                                                             %
    982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    983 %
    984 %  DrawComposite() composites an image onto the current image, using the
    985 %  specified composition operator, specified position, and at the specified
    986 %  size.
    987 %
    988 %  The format of the DrawComposite method is:
    989 %
    990 %      MagickBooleanType DrawComposite(DrawingWand *wand,
    991 %        const CompositeOperator compose,const double x,
    992 %        const double y,const double width,const double height,
    993 %        MagickWand *magick_wand)
    994 %
    995 %  A description of each parameter follows:
    996 %
    997 %    o wand: the drawing wand.
    998 %
    999 %    o compose: composition operator
   1000 %
   1001 %    o x: x ordinate of top left corner
   1002 %
   1003 %    o y: y ordinate of top left corner
   1004 %
   1005 %    o width: Width to resize image to prior to compositing.  Specify zero to
   1006 %      use existing width.
   1007 %
   1008 %    o height: Height to resize image to prior to compositing.  Specify zero
   1009 %      to use existing height.
   1010 %
   1011 %    o magick_wand: Image to composite is obtained from this wand.
   1012 %
   1013 */
   1014 WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
   1015   const CompositeOperator compose,const double x,const double y,
   1016   const double width,const double height,MagickWand *magick_wand)
   1017 {
   1018   char
   1019     *base64,
   1020     *media_type;
   1021 
   1022   const char
   1023     *mode;
   1024 
   1025   ImageInfo
   1026     *image_info;
   1027 
   1028   Image
   1029     *clone_image,
   1030     *image;
   1031 
   1032   register char
   1033     *p;
   1034 
   1035   register ssize_t
   1036     i;
   1037 
   1038   size_t
   1039     blob_length,
   1040     encoded_length;
   1041 
   1042   unsigned char
   1043     *blob;
   1044 
   1045   assert(wand != (DrawingWand *) NULL);
   1046   assert(wand->signature == MagickWandSignature);
   1047   if (wand->debug != MagickFalse)
   1048     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1049   assert(magick_wand != (MagickWand *) NULL);
   1050   image=GetImageFromMagickWand(magick_wand);
   1051   if (image == (Image *) NULL)
   1052     return(MagickFalse);
   1053   clone_image=CloneImage(image,0,0,MagickTrue,wand->exception);
   1054   if (clone_image == (Image *) NULL)
   1055     return(MagickFalse);
   1056   image_info=AcquireImageInfo();
   1057   (void) CopyMagickString(image_info->magick,"MIFF",MagickPathExtent);
   1058   blob_length=2048;
   1059   blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
   1060     wand->exception);
   1061   image_info=DestroyImageInfo(image_info);
   1062   clone_image=DestroyImageList(clone_image);
   1063   if (blob == (void *) NULL)
   1064     return(MagickFalse);
   1065   encoded_length=0;
   1066   base64=Base64Encode(blob,blob_length,&encoded_length);
   1067   blob=(unsigned char *) RelinquishMagickMemory(blob);
   1068   if (base64 == (char *) NULL)
   1069     {
   1070       char
   1071         buffer[MagickPathExtent];
   1072 
   1073       (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g bytes",(double)
   1074         (4L*blob_length/3L+4L));
   1075       ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
   1076         wand->name);
   1077       return(MagickFalse);
   1078     }
   1079   mode=CommandOptionToMnemonic(MagickComposeOptions,(ssize_t) compose);
   1080   media_type=MagickToMime(image->magick);
   1081   (void) MVGPrintf(wand,"image %s %.20g %.20g %.20g %.20g 'data:%s;base64,\n",
   1082     mode,x,y,width,height,media_type);
   1083   p=base64;
   1084   for (i=(ssize_t) encoded_length; i > 0; i-=76)
   1085   {
   1086     (void) MVGPrintf(wand,"%.76s",p);
   1087     p+=76;
   1088     if (i > 76)
   1089       (void) MVGPrintf(wand,"\n");
   1090   }
   1091   (void) MVGPrintf(wand,"'\n");
   1092   media_type=DestroyString(media_type);
   1093   base64=DestroyString(base64);
   1094   return(MagickTrue);
   1095 }
   1096 
   1097 /*
   1099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1100 %                                                                             %
   1101 %                                                                             %
   1102 %                                                                             %
   1103 %   D r a w C o m m e n t                                                     %
   1104 %                                                                             %
   1105 %                                                                             %
   1106 %                                                                             %
   1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1108 %
   1109 %  DrawComment() adds a comment to a vector output stream.
   1110 %
   1111 %  The format of the DrawComment method is:
   1112 %
   1113 %      void DrawComment(DrawingWand *wand,const char *comment)
   1114 %
   1115 %  A description of each parameter follows:
   1116 %
   1117 %    o wand: the drawing wand.
   1118 %
   1119 %    o comment: comment text
   1120 %
   1121 */
   1122 WandExport void DrawComment(DrawingWand *wand,const char *comment)
   1123 {
   1124   (void) MVGPrintf(wand,"#%s\n",comment);
   1125 }
   1126 
   1127 /*
   1129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1130 %                                                                             %
   1131 %                                                                             %
   1132 %                                                                             %
   1133 %   D r a w E l l i p s e                                                     %
   1134 %                                                                             %
   1135 %                                                                             %
   1136 %                                                                             %
   1137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1138 %
   1139 %  DrawEllipse() draws an ellipse on the image.
   1140 %
   1141 %  The format of the DrawEllipse method is:
   1142 %
   1143 %       void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
   1144 %         const double rx,const double ry,const double start,const double end)
   1145 %
   1146 %  A description of each parameter follows:
   1147 %
   1148 %    o wand: the drawing wand.
   1149 %
   1150 %    o ox: origin x ordinate
   1151 %
   1152 %    o oy: origin y ordinate
   1153 %
   1154 %    o rx: radius in x
   1155 %
   1156 %    o ry: radius in y
   1157 %
   1158 %    o start: starting rotation in degrees
   1159 %
   1160 %    o end: ending rotation in degrees
   1161 %
   1162 */
   1163 WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
   1164   const double rx,const double ry,const double start,const double end)
   1165 {
   1166   assert(wand != (DrawingWand *) NULL);
   1167   assert(wand->signature == MagickWandSignature);
   1168   if (wand->debug != MagickFalse)
   1169     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1170   (void) MVGPrintf(wand,"ellipse %.20g %.20g %.20g %.20g %.20g %.20g\n",ox,oy,
   1171     rx,ry,start,end);
   1172 }
   1173 
   1174 /*
   1176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1177 %                                                                             %
   1178 %                                                                             %
   1179 %                                                                             %
   1180 %   D r a w G e t B o r d e r C o l o r                                       %
   1181 %                                                                             %
   1182 %                                                                             %
   1183 %                                                                             %
   1184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1185 %
   1186 %  DrawGetBorderColor() returns the border color used for drawing bordered
   1187 %  objects.
   1188 %
   1189 %  The format of the DrawGetBorderColor method is:
   1190 %
   1191 %      void DrawGetBorderColor(const DrawingWand *wand,
   1192 %        PixelWand *border_color)
   1193 %
   1194 %  A description of each parameter follows:
   1195 %
   1196 %    o wand: the drawing wand.
   1197 %
   1198 %    o border_color: Return the border color.
   1199 %
   1200 */
   1201 WandExport void DrawGetBorderColor(const DrawingWand *wand,
   1202   PixelWand *border_color)
   1203 {
   1204   assert(wand != (const DrawingWand *) NULL);
   1205   assert(wand->signature == MagickWandSignature);
   1206   assert(border_color != (PixelWand *) NULL);
   1207   if (wand->debug != MagickFalse)
   1208     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1209   PixelSetPixelColor(border_color,&CurrentContext->border_color);
   1210 }
   1211 
   1212 /*
   1214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1215 %                                                                             %
   1216 %                                                                             %
   1217 %                                                                             %
   1218 %   D r a w G e t C l i p P a t h                                             %
   1219 %                                                                             %
   1220 %                                                                             %
   1221 %                                                                             %
   1222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1223 %
   1224 %  DrawGetClipPath() obtains the current clipping path ID. The value returned
   1225 %  must be deallocated by the user when it is no longer needed.
   1226 %
   1227 %  The format of the DrawGetClipPath method is:
   1228 %
   1229 %      char *DrawGetClipPath(const DrawingWand *wand)
   1230 %
   1231 %  A description of each parameter follows:
   1232 %
   1233 %    o wand: the drawing wand.
   1234 %
   1235 */
   1236 WandExport char *DrawGetClipPath(const DrawingWand *wand)
   1237 {
   1238   assert(wand != (const DrawingWand *) NULL);
   1239   assert(wand->signature == MagickWandSignature);
   1240   if (wand->debug != MagickFalse)
   1241     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1242   if (CurrentContext->clip_mask != (char *) NULL)
   1243     return((char *) AcquireString(CurrentContext->clip_mask));
   1244   return((char *) NULL);
   1245 }
   1246 
   1247 /*
   1249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1250 %                                                                             %
   1251 %                                                                             %
   1252 %                                                                             %
   1253 %   D r a w G e t C l i p R u l e                                             %
   1254 %                                                                             %
   1255 %                                                                             %
   1256 %                                                                             %
   1257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1258 %
   1259 %  DrawGetClipRule() returns the current polygon fill rule to be used by the
   1260 %  clipping path.
   1261 %
   1262 %  The format of the DrawGetClipRule method is:
   1263 %
   1264 %     FillRule DrawGetClipRule(const DrawingWand *wand)
   1265 %
   1266 %  A description of each parameter follows:
   1267 %
   1268 %    o wand: the drawing wand.
   1269 %
   1270 */
   1271 WandExport FillRule DrawGetClipRule(const DrawingWand *wand)
   1272 {
   1273   assert(wand != (const DrawingWand *) NULL);
   1274   assert(wand->signature == MagickWandSignature);
   1275   if (wand->debug != MagickFalse)
   1276     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1277   return(CurrentContext->fill_rule);
   1278 }
   1279 
   1280 /*
   1282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1283 %                                                                             %
   1284 %                                                                             %
   1285 %                                                                             %
   1286 %   D r a w G e t C l i p U n i t s                                           %
   1287 %                                                                             %
   1288 %                                                                             %
   1289 %                                                                             %
   1290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1291 %
   1292 %  DrawGetClipUnits() returns the interpretation of clip path units.
   1293 %
   1294 %  The format of the DrawGetClipUnits method is:
   1295 %
   1296 %      ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
   1297 %
   1298 %  A description of each parameter follows:
   1299 %
   1300 %    o wand: the drawing wand.
   1301 %
   1302 */
   1303 WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
   1304 {
   1305   assert(wand != (const DrawingWand *) NULL);
   1306   assert(wand->signature == MagickWandSignature);
   1307   if (wand->debug != MagickFalse)
   1308     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1309   return(CurrentContext->clip_units);
   1310 }
   1311 
   1312 /*
   1314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1315 %                                                                             %
   1316 %                                                                             %
   1317 %                                                                             %
   1318 %   D r a w G e t D e n s i t y                                               %
   1319 %                                                                             %
   1320 %                                                                             %
   1321 %                                                                             %
   1322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1323 %
   1324 %  DrawGetDensity() obtains the vertical and horizontal resolution. The value
   1325 %  returned must be deallocated by the user when it is no longer needed.
   1326 %
   1327 %  The format of the DrawGetDensity method is:
   1328 %
   1329 %      char *DrawGetDensity(const DrawingWand *wand)
   1330 %
   1331 %  A description of each parameter follows:
   1332 %
   1333 %    o wand: the drawing wand.
   1334 %
   1335 */
   1336 WandExport char *DrawGetDensity(const DrawingWand *wand)
   1337 {
   1338   assert(wand != (const DrawingWand *) NULL);
   1339   assert(wand->signature == MagickWandSignature);
   1340   if (wand->debug != MagickFalse)
   1341     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1342   if (CurrentContext->density != (char *) NULL)
   1343     return((char *) AcquireString(CurrentContext->density));
   1344   return((char *) NULL);
   1345 }
   1346 
   1347 /*
   1349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1350 %                                                                             %
   1351 %                                                                             %
   1352 %                                                                             %
   1353 %   D r a w G e t E x c e p t i o n                                           %
   1354 %                                                                             %
   1355 %                                                                             %
   1356 %                                                                             %
   1357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1358 %
   1359 %  DrawGetException() returns the severity, reason, and description of any
   1360 %  error that occurs when using other methods in this API.
   1361 %
   1362 %  The format of the DrawGetException method is:
   1363 %
   1364 %      char *DrawGetException(const DrawWand *wand,
   1365 %        ExceptionType *severity)
   1366 %
   1367 %  A description of each parameter follows:
   1368 %
   1369 %    o wand: the drawing wand.
   1370 %
   1371 %    o severity: the severity of the error is returned here.
   1372 %
   1373 */
   1374 WandExport char *DrawGetException(const DrawingWand *wand,
   1375   ExceptionType *severity)
   1376 {
   1377   char
   1378     *description;
   1379 
   1380   assert(wand != (const DrawingWand *) NULL);
   1381   assert(wand->signature == MagickWandSignature);
   1382   if (wand->debug != MagickFalse)
   1383     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1384   assert(severity != (ExceptionType *) NULL);
   1385   *severity=wand->exception->severity;
   1386   description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
   1387     sizeof(*description));
   1388   if (description == (char *) NULL)
   1389     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
   1390       wand->name);
   1391   *description='\0';
   1392   if (wand->exception->reason != (char *) NULL)
   1393     (void) CopyMagickString(description,GetLocaleExceptionMessage(
   1394       wand->exception->severity,wand->exception->reason),
   1395       MagickPathExtent);
   1396   if (wand->exception->description != (char *) NULL)
   1397     {
   1398       (void) ConcatenateMagickString(description," (",MagickPathExtent);
   1399       (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
   1400         wand->exception->severity,wand->exception->description),
   1401         MagickPathExtent);
   1402       (void) ConcatenateMagickString(description,")",MagickPathExtent);
   1403     }
   1404   return(description);
   1405 }
   1406 
   1407 /*
   1409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1410 %                                                                             %
   1411 %                                                                             %
   1412 %                                                                             %
   1413 %   P i x e l G e t E x c e p t i o n T y p e                                 %
   1414 %                                                                             %
   1415 %                                                                             %
   1416 %                                                                             %
   1417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1418 %
   1419 %  DrawGetExceptionType() the exception type associated with the wand.  If
   1420 %  no exception has occurred, UndefinedExceptionType is returned.
   1421 %
   1422 %  The format of the DrawGetExceptionType method is:
   1423 %
   1424 %      ExceptionType DrawGetExceptionType(const DrawWand *wand)
   1425 %
   1426 %  A description of each parameter follows:
   1427 %
   1428 %    o wand: the magick wand.
   1429 %
   1430 */
   1431 WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand)
   1432 {
   1433   assert(wand != (const DrawingWand *) NULL);
   1434   assert(wand->signature == MagickWandSignature);
   1435   if (wand->debug != MagickFalse)
   1436     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1437   return(wand->exception->severity);
   1438 }
   1439 
   1440 /*
   1442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1443 %                                                                             %
   1444 %                                                                             %
   1445 %                                                                             %
   1446 %   D r a w G e t F i l l C o l o r                                           %
   1447 %                                                                             %
   1448 %                                                                             %
   1449 %                                                                             %
   1450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1451 %
   1452 %  DrawGetFillColor() returns the fill color used for drawing filled objects.
   1453 %
   1454 %  The format of the DrawGetFillColor method is:
   1455 %
   1456 %      void DrawGetFillColor(const DrawingWand *wand,
   1457 %        PixelWand *fill_color)
   1458 %
   1459 %  A description of each parameter follows:
   1460 %
   1461 %    o wand: the drawing wand.
   1462 %
   1463 %    o fill_color: Return the fill color.
   1464 %
   1465 */
   1466 WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color)
   1467 {
   1468   assert(wand != (const DrawingWand *) NULL);
   1469   assert(wand->signature == MagickWandSignature);
   1470   assert(fill_color != (PixelWand *) NULL);
   1471   if (wand->debug != MagickFalse)
   1472     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1473   PixelSetPixelColor(fill_color,&CurrentContext->fill);
   1474 }
   1475 
   1476 /*
   1478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1479 %                                                                             %
   1480 %                                                                             %
   1481 %                                                                             %
   1482 %   D r a w G e t F i l l O p a c i t y                                       %
   1483 %                                                                             %
   1484 %                                                                             %
   1485 %                                                                             %
   1486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1487 %
   1488 %  DrawGetFillOpacity() returns the alpha used when drawing using the fill
   1489 %  color or fill texture.  Fully opaque is 1.0.
   1490 %
   1491 %  The format of the DrawGetFillOpacity method is:
   1492 %
   1493 %      double DrawGetFillOpacity(const DrawingWand *wand)
   1494 %
   1495 %  A description of each parameter follows:
   1496 %
   1497 %    o wand: the drawing wand.
   1498 %
   1499 */
   1500 WandExport double DrawGetFillOpacity(const DrawingWand *wand)
   1501 {
   1502   double
   1503     alpha;
   1504 
   1505   assert(wand != (const DrawingWand *) NULL);
   1506   assert(wand->signature == MagickWandSignature);
   1507   if (wand->debug != MagickFalse)
   1508     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1509   alpha=(double) QuantumScale*CurrentContext->fill.alpha;
   1510   return(alpha);
   1511 }
   1512 
   1513 /*
   1515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1516 %                                                                             %
   1517 %                                                                             %
   1518 %                                                                             %
   1519 %   D r a w G e t F i l l R u l e                                             %
   1520 %                                                                             %
   1521 %                                                                             %
   1522 %                                                                             %
   1523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1524 %
   1525 %  DrawGetFillRule() returns the fill rule used while drawing polygons.
   1526 %
   1527 %  The format of the DrawGetFillRule method is:
   1528 %
   1529 %      FillRule DrawGetFillRule(const DrawingWand *wand)
   1530 %
   1531 %  A description of each parameter follows:
   1532 %
   1533 %    o wand: the drawing wand.
   1534 %
   1535 */
   1536 WandExport FillRule DrawGetFillRule(const DrawingWand *wand)
   1537 {
   1538   assert(wand != (const DrawingWand *) NULL);
   1539   assert(wand->signature == MagickWandSignature);
   1540   if (wand->debug != MagickFalse)
   1541     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1542   return(CurrentContext->fill_rule);
   1543 }
   1544 
   1545 /*
   1547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1548 %                                                                             %
   1549 %                                                                             %
   1550 %                                                                             %
   1551 %   D r a w G e t F o n t                                                     %
   1552 %                                                                             %
   1553 %                                                                             %
   1554 %                                                                             %
   1555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1556 %
   1557 %  DrawGetFont() returns a null-terminaged string specifying the font used
   1558 %  when annotating with text. The value returned must be freed by the user
   1559 %  when no longer needed.
   1560 %
   1561 %  The format of the DrawGetFont method is:
   1562 %
   1563 %      char *DrawGetFont(const DrawingWand *wand)
   1564 %
   1565 %  A description of each parameter follows:
   1566 %
   1567 %    o wand: the drawing wand.
   1568 %
   1569 */
   1570 WandExport char *DrawGetFont(const DrawingWand *wand)
   1571 {
   1572   assert(wand != (const DrawingWand *) NULL);
   1573   assert(wand->signature == MagickWandSignature);
   1574   if (wand->debug != MagickFalse)
   1575     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1576   if (CurrentContext->font != (char *) NULL)
   1577     return(AcquireString(CurrentContext->font));
   1578   return((char *) NULL);
   1579 }
   1580 
   1581 /*
   1583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1584 %                                                                             %
   1585 %                                                                             %
   1586 %                                                                             %
   1587 %   D r a w G e t F o n t F a m i l y                                         %
   1588 %                                                                             %
   1589 %                                                                             %
   1590 %                                                                             %
   1591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1592 %
   1593 %  DrawGetFontFamily() returns the font family to use when annotating with text.
   1594 %  The value returned must be freed by the user when it is no longer needed.
   1595 %
   1596 %  The format of the DrawGetFontFamily method is:
   1597 %
   1598 %      char *DrawGetFontFamily(const DrawingWand *wand)
   1599 %
   1600 %  A description of each parameter follows:
   1601 %
   1602 %    o wand: the drawing wand.
   1603 %
   1604 */
   1605 WandExport char *DrawGetFontFamily(const DrawingWand *wand)
   1606 {
   1607   assert(wand != (const DrawingWand *) NULL);
   1608   assert(wand->signature == MagickWandSignature);
   1609   if (wand->debug != MagickFalse)
   1610     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1611   if (CurrentContext->family != NULL)
   1612     return(AcquireString(CurrentContext->family));
   1613   return((char *) NULL);
   1614 }
   1615 
   1616 /*
   1618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1619 %                                                                             %
   1620 %                                                                             %
   1621 %                                                                             %
   1622 %   D r a w G e t F o n t R e s o l u t i o n                                 %
   1623 %                                                                             %
   1624 %                                                                             %
   1625 %                                                                             %
   1626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1627 %
   1628 %  DrawGetFontResolution() gets the image X and Y resolution.
   1629 %
   1630 %  The format of the DrawGetFontResolution method is:
   1631 %
   1632 %      MagickBooleanType DrawGetFontResolution(const DrawingWand *wand,
   1633 %        double *x,double *y)
   1634 %
   1635 %  A description of each parameter follows:
   1636 %
   1637 %    o wand: the magick wand.
   1638 %
   1639 %    o x: the x-resolution.
   1640 %
   1641 %    o y: the y-resolution.
   1642 %
   1643 */
   1644 WandExport MagickBooleanType DrawGetFontResolution(const DrawingWand *wand,
   1645   double *x,double *y)
   1646 {
   1647   assert(wand != (DrawingWand *) NULL);
   1648   assert(wand->signature == MagickWandSignature);
   1649   if (wand->debug != MagickFalse)
   1650     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1651   *x=72.0;
   1652   *y=72.0;
   1653   if (CurrentContext->density != (char *) NULL)
   1654     {
   1655       GeometryInfo
   1656         geometry_info;
   1657 
   1658       MagickStatusType
   1659         flags;
   1660 
   1661       flags=ParseGeometry(CurrentContext->density,&geometry_info);
   1662       *x=geometry_info.rho;
   1663       *y=geometry_info.sigma;
   1664       if ((flags & SigmaValue) == MagickFalse)
   1665         *y=(*x);
   1666     }
   1667   return(MagickTrue);
   1668 }
   1669 
   1670 /*
   1672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1673 %                                                                             %
   1674 %                                                                             %
   1675 %                                                                             %
   1676 %   D r a w G e t F o n t S i z e                                             %
   1677 %                                                                             %
   1678 %                                                                             %
   1679 %                                                                             %
   1680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1681 %
   1682 %  DrawGetFontSize() returns the font pointsize used when annotating with text.
   1683 %
   1684 %  The format of the DrawGetFontSize method is:
   1685 %
   1686 %      double DrawGetFontSize(const DrawingWand *wand)
   1687 %
   1688 %  A description of each parameter follows:
   1689 %
   1690 %    o wand: the drawing wand.
   1691 %
   1692 */
   1693 WandExport double DrawGetFontSize(const DrawingWand *wand)
   1694 {
   1695   assert(wand != (const DrawingWand *) NULL);
   1696   assert(wand->signature == MagickWandSignature);
   1697   if (wand->debug != MagickFalse)
   1698     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1699   return(CurrentContext->pointsize);
   1700 }
   1701 
   1702 /*
   1704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1705 %                                                                             %
   1706 %                                                                             %
   1707 %                                                                             %
   1708 %   D r a w G e t F o n t S t r e t c h                                       %
   1709 %                                                                             %
   1710 %                                                                             %
   1711 %                                                                             %
   1712 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1713 %
   1714 %  DrawGetFontStretch() returns the font stretch used when annotating with text.
   1715 %
   1716 %  The format of the DrawGetFontStretch method is:
   1717 %
   1718 %      StretchType DrawGetFontStretch(const DrawingWand *wand)
   1719 %
   1720 %  A description of each parameter follows:
   1721 %
   1722 %    o wand: the drawing wand.
   1723 %
   1724 */
   1725 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
   1726 {
   1727   assert(wand != (const DrawingWand *) NULL);
   1728   assert(wand->signature == MagickWandSignature);
   1729   if (wand->debug != MagickFalse)
   1730     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1731   return(CurrentContext->stretch);
   1732 }
   1733 
   1734 /*
   1736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1737 %                                                                             %
   1738 %                                                                             %
   1739 %                                                                             %
   1740 %   D r a w G e t F o n t S t y l e                                           %
   1741 %                                                                             %
   1742 %                                                                             %
   1743 %                                                                             %
   1744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1745 %
   1746 %  DrawGetFontStyle() returns the font style used when annotating with text.
   1747 %
   1748 %  The format of the DrawGetFontStyle method is:
   1749 %
   1750 %      StyleType DrawGetFontStyle(const DrawingWand *wand)
   1751 %
   1752 %  A description of each parameter follows:
   1753 %
   1754 %    o wand: the drawing wand.
   1755 %
   1756 */
   1757 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
   1758 {
   1759   assert(wand != (const DrawingWand *) NULL);
   1760   assert(wand->signature == MagickWandSignature);
   1761   if (wand->debug != MagickFalse)
   1762     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1763   return(CurrentContext->style);
   1764 }
   1765 
   1766 /*
   1768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1769 %                                                                             %
   1770 %                                                                             %
   1771 %                                                                             %
   1772 %   D r a w G e t F o n t W e i g h t                                         %
   1773 %                                                                             %
   1774 %                                                                             %
   1775 %                                                                             %
   1776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1777 %
   1778 %  DrawGetFontWeight() returns the font weight used when annotating with text.
   1779 %
   1780 %  The format of the DrawGetFontWeight method is:
   1781 %
   1782 %      size_t DrawGetFontWeight(const DrawingWand *wand)
   1783 %
   1784 %  A description of each parameter follows:
   1785 %
   1786 %    o wand: the drawing wand.
   1787 %
   1788 */
   1789 WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
   1790 {
   1791   assert(wand != (const DrawingWand *) NULL);
   1792   assert(wand->signature == MagickWandSignature);
   1793   if (wand->debug != MagickFalse)
   1794     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1795   return(CurrentContext->weight);
   1796 }
   1797 
   1798 /*
   1800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1801 %                                                                             %
   1802 %                                                                             %
   1803 %                                                                             %
   1804 %   D r a w G e t G r a v i t y                                               %
   1805 %                                                                             %
   1806 %                                                                             %
   1807 %                                                                             %
   1808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1809 %
   1810 %  DrawGetGravity() returns the text placement gravity used when annotating
   1811 %  with text.
   1812 %
   1813 %  The format of the DrawGetGravity method is:
   1814 %
   1815 %      GravityType DrawGetGravity(const DrawingWand *wand)
   1816 %
   1817 %  A description of each parameter follows:
   1818 %
   1819 %    o wand: the drawing wand.
   1820 %
   1821 */
   1822 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
   1823 {
   1824   assert(wand != (const DrawingWand *) NULL);
   1825   assert(wand->signature == MagickWandSignature);
   1826   if (wand->debug != MagickFalse)
   1827     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1828   return(CurrentContext->gravity);
   1829 }
   1830 
   1831 /*
   1833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1834 %                                                                             %
   1835 %                                                                             %
   1836 %                                                                             %
   1837 %   D r a w G e t O p a c i t y                                               %
   1838 %                                                                             %
   1839 %                                                                             %
   1840 %                                                                             %
   1841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1842 %
   1843 %  DrawGetOpacity() returns the alpha used when drawing with the fill
   1844 %  or stroke color or texture.  Fully opaque is 1.0.
   1845 %
   1846 %  The format of the DrawGetOpacity method is:
   1847 %
   1848 %      double DrawGetOpacity(const DrawingWand *wand)
   1849 %
   1850 %  A description of each parameter follows:
   1851 %
   1852 %    o wand: the drawing wand.
   1853 %
   1854 */
   1855 WandExport double DrawGetOpacity(const DrawingWand *wand)
   1856 {
   1857   double
   1858     alpha;
   1859 
   1860   assert(wand != (const DrawingWand *) NULL);
   1861   assert(wand->signature == MagickWandSignature);
   1862   if (wand->debug != MagickFalse)
   1863     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1864   alpha=(double) QuantumScale*CurrentContext->alpha;
   1865   return(alpha);
   1866 }
   1867 
   1868 /*
   1870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1871 %                                                                             %
   1872 %                                                                             %
   1873 %                                                                             %
   1874 %   D r a w G e t S t r o k e A n t i a l i a s                               %
   1875 %                                                                             %
   1876 %                                                                             %
   1877 %                                                                             %
   1878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1879 %
   1880 %  DrawGetStrokeAntialias() returns the current stroke antialias setting.
   1881 %  Stroked outlines are antialiased by default.  When antialiasing is disabled
   1882 %  stroked pixels are thresholded to determine if the stroke color or
   1883 %  underlying canvas color should be used.
   1884 %
   1885 %  The format of the DrawGetStrokeAntialias method is:
   1886 %
   1887 %      MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
   1888 %
   1889 %  A description of each parameter follows:
   1890 %
   1891 %    o wand: the drawing wand.
   1892 %
   1893 */
   1894 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
   1895 {
   1896   assert(wand != (const DrawingWand *) NULL);
   1897   assert(wand->signature == MagickWandSignature);
   1898   if (wand->debug != MagickFalse)
   1899     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1900   return(CurrentContext->stroke_antialias);
   1901 }
   1902 
   1903 /*
   1905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1906 %                                                                             %
   1907 %                                                                             %
   1908 %                                                                             %
   1909 %   D r a w G e t S t r o k e C o l o r                                       %
   1910 %                                                                             %
   1911 %                                                                             %
   1912 %                                                                             %
   1913 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1914 %
   1915 %  DrawGetStrokeColor() returns the color used for stroking object outlines.
   1916 %
   1917 %  The format of the DrawGetStrokeColor method is:
   1918 %
   1919 %      void DrawGetStrokeColor(const DrawingWand *wand,
   1920 %        PixelWand *stroke_color)
   1921 %
   1922 %  A description of each parameter follows:
   1923 %
   1924 %    o wand: the drawing wand.
   1925 %
   1926 %    o stroke_color: Return the stroke color.
   1927 %
   1928 */
   1929 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
   1930   PixelWand *stroke_color)
   1931 {
   1932   assert(wand != (const DrawingWand *) NULL);
   1933   assert(wand->signature == MagickWandSignature);
   1934   assert(stroke_color != (PixelWand *) NULL);
   1935   if (wand->debug != MagickFalse)
   1936     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1937   PixelSetPixelColor(stroke_color,&CurrentContext->stroke);
   1938 }
   1939 
   1940 /*
   1942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1943 %                                                                             %
   1944 %                                                                             %
   1945 %                                                                             %
   1946 %   D r a w G e t S t r o k e D a s h A r r a y                               %
   1947 %                                                                             %
   1948 %                                                                             %
   1949 %                                                                             %
   1950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1951 %
   1952 %  DrawGetStrokeDashArray() returns an array representing the pattern of
   1953 %  dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
   1954 %  array must be freed once it is no longer required by the user.
   1955 %
   1956 %  The format of the DrawGetStrokeDashArray method is:
   1957 %
   1958 %      double *DrawGetStrokeDashArray(const DrawingWand *wand,
   1959 %        size_t *number_elements)
   1960 %
   1961 %  A description of each parameter follows:
   1962 %
   1963 %    o wand: the drawing wand.
   1964 %
   1965 %    o number_elements: address to place number of elements in dash array
   1966 %
   1967 */
   1968 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
   1969   size_t *number_elements)
   1970 {
   1971   double
   1972     *dasharray;
   1973 
   1974   register const double
   1975     *p;
   1976 
   1977   register double
   1978     *q;
   1979 
   1980   register ssize_t
   1981     i;
   1982 
   1983   size_t
   1984     n;
   1985 
   1986   assert(wand != (const DrawingWand *) NULL);
   1987   assert(wand->signature == MagickWandSignature);
   1988   if (wand->debug != MagickFalse)
   1989     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   1990   assert(number_elements != (size_t *) NULL);
   1991   n=0;
   1992   p=CurrentContext->dash_pattern;
   1993   if (p != (const double *) NULL)
   1994     while (fabs(*p++) >= MagickEpsilon)
   1995       n++;
   1996   *number_elements=n;
   1997   dasharray=(double *) NULL;
   1998   if (n != 0)
   1999     {
   2000       dasharray=(double *) AcquireQuantumMemory((size_t) n+1UL,
   2001         sizeof(*dasharray));
   2002       if (dasharray != (double *) NULL)
   2003         {
   2004           p=CurrentContext->dash_pattern;
   2005           q=dasharray;
   2006           for (i=0; i < (ssize_t) n; i++)
   2007             *q++=(*p++);
   2008           *q=0.0;
   2009         }
   2010     }
   2011   return(dasharray);
   2012 }
   2013 
   2014 /*
   2016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2017 %                                                                             %
   2018 %                                                                             %
   2019 %                                                                             %
   2020 %   D r a w G e t S t r o k e D a s h O f f s e t                             %
   2021 %                                                                             %
   2022 %                                                                             %
   2023 %                                                                             %
   2024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2025 %
   2026 %  DrawGetStrokeDashOffset() returns the offset into the dash pattern to
   2027 %  start the dash.
   2028 %
   2029 %  The format of the DrawGetStrokeDashOffset method is:
   2030 %
   2031 %      double DrawGetStrokeDashOffset(const DrawingWand *wand)
   2032 %
   2033 %  A description of each parameter follows:
   2034 %
   2035 %    o wand: the drawing wand.
   2036 %
   2037 */
   2038 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
   2039 {
   2040   assert(wand != (const DrawingWand *) NULL);
   2041   assert(wand->signature == MagickWandSignature);
   2042   if (wand->debug != MagickFalse)
   2043     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2044   return(CurrentContext->dash_offset);
   2045 }
   2046 
   2047 /*
   2049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2050 %                                                                             %
   2051 %                                                                             %
   2052 %                                                                             %
   2053 %   D r a w G e t S t r o k e L i n e C a p                                   %
   2054 %                                                                             %
   2055 %                                                                             %
   2056 %                                                                             %
   2057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2058 %
   2059 %  DrawGetStrokeLineCap() returns the shape to be used at the end of
   2060 %  open subpaths when they are stroked. Values of LineCap are
   2061 %  UndefinedCap, ButtCap, RoundCap, and SquareCap.
   2062 %
   2063 %  The format of the DrawGetStrokeLineCap method is:
   2064 %
   2065 %      LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
   2066 %
   2067 %  A description of each parameter follows:
   2068 %
   2069 %    o wand: the drawing wand.
   2070 %
   2071 */
   2072 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
   2073 {
   2074   assert(wand != (const DrawingWand *) NULL);
   2075   assert(wand->signature == MagickWandSignature);
   2076   if (wand->debug != MagickFalse)
   2077     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2078   return(CurrentContext->linecap);
   2079 }
   2080 
   2081 /*
   2083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2084 %                                                                             %
   2085 %                                                                             %
   2086 %                                                                             %
   2087 %   D r a w G e t S t r o k e L i n e J o i n                                 %
   2088 %                                                                             %
   2089 %                                                                             %
   2090 %                                                                             %
   2091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2092 %
   2093 %  DrawGetStrokeLineJoin() returns the shape to be used at the
   2094 %  corners of paths (or other vector shapes) when they are
   2095 %  stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
   2096 %  and BevelJoin.
   2097 %
   2098 %  The format of the DrawGetStrokeLineJoin method is:
   2099 %
   2100 %      LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
   2101 %
   2102 %  A description of each parameter follows:
   2103 %
   2104 %    o wand: the drawing wand.
   2105 %
   2106 */
   2107 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
   2108 {
   2109   assert(wand != (const DrawingWand *) NULL);
   2110   assert(wand->signature == MagickWandSignature);
   2111   if (wand->debug != MagickFalse)
   2112     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2113   return(CurrentContext->linejoin);
   2114 }
   2115 
   2116 /*
   2118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2119 %                                                                             %
   2120 %                                                                             %
   2121 %                                                                             %
   2122 %   D r a w G e t S t r o k e M i t e r L i m i t                             %
   2123 %                                                                             %
   2124 %                                                                             %
   2125 %                                                                             %
   2126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2127 %
   2128 %  DrawGetStrokeMiterLimit() returns the miter limit. When two line
   2129 %  segments meet at a sharp angle and miter joins have been specified for
   2130 %  'lineJoin', it is possible for the miter to extend far beyond the
   2131 %  thickness of the line stroking the path. The miterLimit' imposes a
   2132 %  limit on the ratio of the miter length to the 'lineWidth'.
   2133 %
   2134 %  The format of the DrawGetStrokeMiterLimit method is:
   2135 %
   2136 %      size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
   2137 %
   2138 %  A description of each parameter follows:
   2139 %
   2140 %    o wand: the drawing wand.
   2141 %
   2142 */
   2143 WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
   2144 {
   2145   assert(wand != (const DrawingWand *) NULL);
   2146   assert(wand->signature == MagickWandSignature);
   2147   if (wand->debug != MagickFalse)
   2148     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2149   return CurrentContext->miterlimit;
   2150 }
   2151 
   2152 /*
   2154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2155 %                                                                             %
   2156 %                                                                             %
   2157 %                                                                             %
   2158 %   D r a w G e t S t r o k e O p a c i t y                                   %
   2159 %                                                                             %
   2160 %                                                                             %
   2161 %                                                                             %
   2162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2163 %
   2164 %  DrawGetStrokeOpacity() returns the alpha of stroked object outlines.
   2165 %
   2166 %  The format of the DrawGetStrokeOpacity method is:
   2167 %
   2168 %      double DrawGetStrokeOpacity(const DrawingWand *wand)
   2169 %
   2170 %  A description of each parameter follows:
   2171 %
   2172 %    o wand: the drawing wand.
   2173 %
   2174 */
   2175 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
   2176 {
   2177   double
   2178     alpha;
   2179 
   2180   assert(wand != (const DrawingWand *) NULL);
   2181   assert(wand->signature == MagickWandSignature);
   2182   if (wand->debug != MagickFalse)
   2183     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2184   alpha=(double) QuantumScale*CurrentContext->stroke.alpha;
   2185   return(alpha);
   2186 }
   2187 
   2188 /*
   2190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2191 %                                                                             %
   2192 %                                                                             %
   2193 %                                                                             %
   2194 %   D r a w G e t S t r o k e W i d t h                                       %
   2195 %                                                                             %
   2196 %                                                                             %
   2197 %                                                                             %
   2198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2199 %
   2200 %  DrawGetStrokeWidth() returns the width of the stroke used to draw object
   2201 %  outlines.
   2202 %
   2203 %  The format of the DrawGetStrokeWidth method is:
   2204 %
   2205 %      double DrawGetStrokeWidth(const DrawingWand *wand)
   2206 %
   2207 %  A description of each parameter follows:
   2208 %
   2209 %    o wand: the drawing wand.
   2210 %
   2211 */
   2212 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
   2213 {
   2214   assert(wand != (const DrawingWand *) NULL);
   2215   assert(wand->signature == MagickWandSignature);
   2216   if (wand->debug != MagickFalse)
   2217     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2218   return(CurrentContext->stroke_width);
   2219 }
   2220 
   2221 /*
   2223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2224 %                                                                             %
   2225 %                                                                             %
   2226 %                                                                             %
   2227 %   D r a w G e t T e x t A l i g n m e n t                                   %
   2228 %                                                                             %
   2229 %                                                                             %
   2230 %                                                                             %
   2231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2232 %
   2233 %  DrawGetTextAlignment() returns the alignment applied when annotating with
   2234 %  text.
   2235 %
   2236 %  The format of the DrawGetTextAlignment method is:
   2237 %
   2238 %      AlignType DrawGetTextAlignment(const DrawingWand *wand)
   2239 %
   2240 %  A description of each parameter follows:
   2241 %
   2242 %    o wand: the drawing wand.
   2243 %
   2244 */
   2245 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
   2246 {
   2247   assert(wand != (const DrawingWand *) NULL);
   2248   assert(wand->signature == MagickWandSignature);
   2249   if (wand->debug != MagickFalse)
   2250     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2251   return(CurrentContext->align);
   2252 }
   2253 
   2254 /*
   2256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2257 %                                                                             %
   2258 %                                                                             %
   2259 %                                                                             %
   2260 %   D r a w G e t T e x t A n t i a l i a s                                   %
   2261 %                                                                             %
   2262 %                                                                             %
   2263 %                                                                             %
   2264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2265 %
   2266 %  DrawGetTextAntialias() returns the current text antialias setting, which
   2267 %  determines whether text is antialiased.  Text is antialiased by default.
   2268 %
   2269 %  The format of the DrawGetTextAntialias method is:
   2270 %
   2271 %      MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
   2272 %
   2273 %  A description of each parameter follows:
   2274 %
   2275 %    o wand: the drawing wand.
   2276 %
   2277 */
   2278 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
   2279 {
   2280   assert(wand != (const DrawingWand *) NULL);
   2281   assert(wand->signature == MagickWandSignature);
   2282   if (wand->debug != MagickFalse)
   2283     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2284   return(CurrentContext->text_antialias);
   2285 }
   2286 
   2287 /*
   2289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2290 %                                                                             %
   2291 %                                                                             %
   2292 %                                                                             %
   2293 %   D r a w G e t T e x t D e c o r a t i o n                                 %
   2294 %                                                                             %
   2295 %                                                                             %
   2296 %                                                                             %
   2297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2298 %
   2299 %  DrawGetTextDecoration() returns the decoration applied when annotating with
   2300 %  text.
   2301 %
   2302 %  The format of the DrawGetTextDecoration method is:
   2303 %
   2304 %      DecorationType DrawGetTextDecoration(const DrawingWand *wand)
   2305 %
   2306 %  A description of each parameter follows:
   2307 %
   2308 %    o wand: the drawing wand.
   2309 %
   2310 */
   2311 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
   2312 {
   2313   assert(wand != (const DrawingWand *) NULL);
   2314   assert(wand->signature == MagickWandSignature);
   2315   if (wand->debug != MagickFalse)
   2316     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2317   return(CurrentContext->decorate);
   2318 }
   2319 
   2320 /*
   2322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2323 %                                                                             %
   2324 %                                                                             %
   2325 %                                                                             %
   2326 %   D r a w G e t T e x t D i r e c t i o n                                   %
   2327 %                                                                             %
   2328 %                                                                             %
   2329 %                                                                             %
   2330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2331 %
   2332 %  DrawGetTextDirection() returns the direction that will be used when
   2333 %  annotating with text.
   2334 %
   2335 %  The format of the DrawGetTextDirection method is:
   2336 %
   2337 %      DirectionType DrawGetTextDirection(const DrawingWand *wand)
   2338 %
   2339 %  A description of each parameter follows:
   2340 %
   2341 %    o wand: the drawing wand.
   2342 %
   2343 */
   2344 WandExport DirectionType DrawGetTextDirection(const DrawingWand *wand)
   2345 {
   2346   assert(wand != (const DrawingWand *) NULL);
   2347   assert(wand->signature == MagickWandSignature);
   2348   if (wand->debug != MagickFalse)
   2349     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2350   return(CurrentContext->direction);
   2351 }
   2352 
   2353 /*
   2355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2356 %                                                                             %
   2357 %                                                                             %
   2358 %                                                                             %
   2359 %   D r a w G e t T e x t E n c o d i n g                                     %
   2360 %                                                                             %
   2361 %                                                                             %
   2362 %                                                                             %
   2363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2364 %
   2365 %  DrawGetTextEncoding() returns a null-terminated string which specifies the
   2366 %  code set used for text annotations. The string must be freed by the user
   2367 %  once it is no longer required.
   2368 %
   2369 %  The format of the DrawGetTextEncoding method is:
   2370 %
   2371 %      char *DrawGetTextEncoding(const DrawingWand *wand)
   2372 %
   2373 %  A description of each parameter follows:
   2374 %
   2375 %    o wand: the drawing wand.
   2376 %
   2377 */
   2378 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
   2379 {
   2380   assert(wand != (const DrawingWand *) NULL);
   2381   assert(wand->signature == MagickWandSignature);
   2382   if (wand->debug != MagickFalse)
   2383     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2384   if (CurrentContext->encoding != (char *) NULL)
   2385     return((char *) AcquireString(CurrentContext->encoding));
   2386   return((char *) NULL);
   2387 }
   2388 
   2389 /*
   2391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2392 %                                                                             %
   2393 %                                                                             %
   2394 %                                                                             %
   2395 %   D r a w G e t T e x t K e r n i n g                                       %
   2396 %                                                                             %
   2397 %                                                                             %
   2398 %                                                                             %
   2399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2400 %
   2401 %  DrawGetTextKerning() gets the spacing between characters in text.
   2402 %
   2403 %  The format of the DrawSetFontKerning method is:
   2404 %
   2405 %      double DrawGetTextKerning(DrawingWand *wand)
   2406 %
   2407 %  A description of each parameter follows:
   2408 %
   2409 %    o wand: the drawing wand.
   2410 %
   2411 */
   2412 WandExport double DrawGetTextKerning(DrawingWand *wand)
   2413 {
   2414   assert(wand != (DrawingWand *) NULL);
   2415   assert(wand->signature == MagickWandSignature);
   2416 
   2417   if (wand->debug != MagickFalse)
   2418     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2419   return(CurrentContext->kerning);
   2420 }
   2421 
   2422 /*
   2424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2425 %                                                                             %
   2426 %                                                                             %
   2427 %                                                                             %
   2428 %   D r a w G e t T e x t I n t e r l i n e S p a c i n g                     %
   2429 %                                                                             %
   2430 %                                                                             %
   2431 %                                                                             %
   2432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2433 %
   2434 %  DrawGetTextInterlineSpacing() gets the spacing between lines in text.
   2435 %
   2436 %  The format of the DrawGetTextInterlineSpacing method is:
   2437 %
   2438 %      double DrawGetTextInterlineSpacing(DrawingWand *wand)
   2439 %
   2440 %  A description of each parameter follows:
   2441 %
   2442 %    o wand: the drawing wand.
   2443 %
   2444 */
   2445 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
   2446 {
   2447   assert(wand != (DrawingWand *) NULL);
   2448   assert(wand->signature == MagickWandSignature);
   2449   if (wand->debug != MagickFalse)
   2450     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2451   return(CurrentContext->interline_spacing);
   2452 }
   2453 
   2454 /*
   2456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2457 %                                                                             %
   2458 %                                                                             %
   2459 %                                                                             %
   2460 %   D r a w G e t T e x t I n t e r w o r d S p a c i n g                     %
   2461 %                                                                             %
   2462 %                                                                             %
   2463 %                                                                             %
   2464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2465 %
   2466 %  DrawGetTextInterwordSpacing() gets the spacing between words in text.
   2467 %
   2468 %  The format of the DrawSetFontKerning method is:
   2469 %
   2470 %      double DrawGetTextInterwordSpacing(DrawingWand *wand)
   2471 %
   2472 %  A description of each parameter follows:
   2473 %
   2474 %    o wand: the drawing wand.
   2475 %
   2476 */
   2477 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
   2478 {
   2479   assert(wand != (DrawingWand *) NULL);
   2480   assert(wand->signature == MagickWandSignature);
   2481   if (wand->debug != MagickFalse)
   2482     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2483   return(CurrentContext->interword_spacing);
   2484 }
   2485 
   2486 /*
   2488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2489 %                                                                             %
   2490 %                                                                             %
   2491 %                                                                             %
   2492 %   D r a w G e t T y p e M e t r i c s                                       %
   2493 %                                                                             %
   2494 %                                                                             %
   2495 %                                                                             %
   2496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2497 %
   2498 %  DrawGetTypeMetrics() returns the following information for the specified
   2499 %  font and text:
   2500 %
   2501 %    character width
   2502 %    character height
   2503 %    ascender
   2504 %    descender
   2505 %    text width
   2506 %    text height
   2507 %    maximum horizontal advance
   2508 %    bounds: x1
   2509 %    bounds: y1
   2510 %    bounds: x2
   2511 %    bounds: y2
   2512 %    origin: x
   2513 %    origin: y
   2514 %    underline position
   2515 %    underline thickness
   2516 %
   2517 %  The format of the DrawGetTypeMetrics method is:
   2518 %
   2519 %      MagickBooleanType DrawGetTypeMetrics(const DrawingWand *wand,
   2520 %        const char *text,MagickBooleanType ignore_newlines,
   2521 $        TypeMetric *metrics)
   2522 %
   2523 %  A description of each parameter follows:
   2524 %
   2525 %    o wand: the drawing wand.
   2526 %
   2527 %    o text: text to draw.
   2528 %
   2529 %    o metrics: Return the font metrics in this structure.
   2530 %
   2531 %    o ignore_newlines: indicates whether newlines should be ignored.
   2532 %
   2533 %    o metrics: Return the font metrics in this structure.
   2534 %
   2535 */
   2536 WandExport MagickBooleanType DrawGetTypeMetrics(const DrawingWand *wand,
   2537   const char *text,MagickBooleanType ignore_newlines,TypeMetric *metrics)
   2538 {
   2539   DrawInfo
   2540     *draw_info;
   2541 
   2542   MagickBooleanType
   2543     status;
   2544 
   2545   assert(wand != (const DrawingWand *) NULL);
   2546   assert(wand->signature == MagickWandSignature);
   2547   if (wand->debug != MagickFalse)
   2548     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2549   draw_info=PeekDrawingWand(wand);
   2550   if (draw_info == (DrawInfo *) NULL)
   2551     return(MagickFalse);
   2552   (void) CloneString(&draw_info->text,text);
   2553   if (ignore_newlines != MagickFalse)
   2554     status=GetTypeMetrics(wand->image,draw_info,metrics,wand->exception);
   2555   else
   2556     status=GetMultilineTypeMetrics(wand->image,draw_info,metrics,
   2557       wand->exception);
   2558   draw_info=DestroyDrawInfo(draw_info);
   2559   return(status);
   2560 }
   2561 
   2562 /*
   2564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2565 %                                                                             %
   2566 %                                                                             %
   2567 %                                                                             %
   2568 %   D r a w G e t V e c t o r G r a p h i c s                                 %
   2569 %                                                                             %
   2570 %                                                                             %
   2571 %                                                                             %
   2572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2573 %
   2574 %  DrawGetVectorGraphics() returns a null-terminated string which specifies the
   2575 %  vector graphics generated by any graphics calls made since the wand was
   2576 %  instantiated.  The string must be freed by the user once it is no longer
   2577 %  required.
   2578 %
   2579 %  The format of the DrawGetVectorGraphics method is:
   2580 %
   2581 %      char *DrawGetVectorGraphics(DrawingWand *wand)
   2582 %
   2583 %  A description of each parameter follows:
   2584 %
   2585 %    o wand: the drawing wand.
   2586 %
   2587 */
   2588 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
   2589 {
   2590   char
   2591     value[MagickPathExtent],
   2592     *xml;
   2593 
   2594   PixelInfo
   2595     pixel;
   2596 
   2597   register ssize_t
   2598     i;
   2599 
   2600   XMLTreeInfo
   2601     *child,
   2602     *xml_info;
   2603 
   2604   assert(wand != (const DrawingWand *) NULL);
   2605   assert(wand->signature == MagickWandSignature);
   2606   if (wand->debug != MagickFalse)
   2607     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2608   xml_info=NewXMLTreeTag("drawing-wand");
   2609   if (xml_info == (XMLTreeInfo *) NULL)
   2610     return((char *) NULL);
   2611   (void) SetXMLTreeContent(xml_info," ");
   2612   GetPixelInfo(wand->image,&pixel);
   2613   child=AddChildToXMLTree(xml_info,"clip-path",0);
   2614   if (child != (XMLTreeInfo *) NULL)
   2615     (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
   2616   child=AddChildToXMLTree(xml_info,"clip-units",0);
   2617   if (child != (XMLTreeInfo *) NULL)
   2618     {
   2619       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2620         MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),
   2621         MagickPathExtent);
   2622       (void) SetXMLTreeContent(child,value);
   2623     }
   2624   child=AddChildToXMLTree(xml_info,"decorate",0);
   2625   if (child != (XMLTreeInfo *) NULL)
   2626     {
   2627       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2628         MagickDecorateOptions,(ssize_t) CurrentContext->decorate),
   2629         MagickPathExtent);
   2630       (void) SetXMLTreeContent(child,value);
   2631     }
   2632   child=AddChildToXMLTree(xml_info,"encoding",0);
   2633   if (child != (XMLTreeInfo *) NULL)
   2634     (void) SetXMLTreeContent(child,CurrentContext->encoding);
   2635   child=AddChildToXMLTree(xml_info,"fill",0);
   2636   if (child != (XMLTreeInfo *) NULL)
   2637     {
   2638       if (CurrentContext->fill.alpha != OpaqueAlpha)
   2639         pixel.alpha_trait=CurrentContext->fill.alpha != OpaqueAlpha ?
   2640           BlendPixelTrait : UndefinedPixelTrait;
   2641       pixel=CurrentContext->fill;
   2642       GetColorTuple(&pixel,MagickTrue,value);
   2643       (void) SetXMLTreeContent(child,value);
   2644     }
   2645   child=AddChildToXMLTree(xml_info,"fill-opacity",0);
   2646   if (child != (XMLTreeInfo *) NULL)
   2647     {
   2648       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2649         (double) (QuantumScale*CurrentContext->fill.alpha));
   2650       (void) SetXMLTreeContent(child,value);
   2651     }
   2652   child=AddChildToXMLTree(xml_info,"fill-rule",0);
   2653   if (child != (XMLTreeInfo *) NULL)
   2654     {
   2655       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2656         MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),
   2657         MagickPathExtent);
   2658       (void) SetXMLTreeContent(child,value);
   2659     }
   2660   child=AddChildToXMLTree(xml_info,"font",0);
   2661   if (child != (XMLTreeInfo *) NULL)
   2662     (void) SetXMLTreeContent(child,CurrentContext->font);
   2663   child=AddChildToXMLTree(xml_info,"font-family",0);
   2664   if (child != (XMLTreeInfo *) NULL)
   2665     (void) SetXMLTreeContent(child,CurrentContext->family);
   2666   child=AddChildToXMLTree(xml_info,"font-size",0);
   2667   if (child != (XMLTreeInfo *) NULL)
   2668     {
   2669       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2670         CurrentContext->pointsize);
   2671       (void) SetXMLTreeContent(child,value);
   2672     }
   2673   child=AddChildToXMLTree(xml_info,"font-stretch",0);
   2674   if (child != (XMLTreeInfo *) NULL)
   2675     {
   2676       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2677         MagickStretchOptions,(ssize_t) CurrentContext->stretch),
   2678         MagickPathExtent);
   2679       (void) SetXMLTreeContent(child,value);
   2680     }
   2681   child=AddChildToXMLTree(xml_info,"font-style",0);
   2682   if (child != (XMLTreeInfo *) NULL)
   2683     {
   2684       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2685         MagickStyleOptions,(ssize_t) CurrentContext->style),MagickPathExtent);
   2686       (void) SetXMLTreeContent(child,value);
   2687     }
   2688   child=AddChildToXMLTree(xml_info,"font-weight",0);
   2689   if (child != (XMLTreeInfo *) NULL)
   2690     {
   2691       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
   2692         CurrentContext->weight);
   2693       (void) SetXMLTreeContent(child,value);
   2694     }
   2695   child=AddChildToXMLTree(xml_info,"gravity",0);
   2696   if (child != (XMLTreeInfo *) NULL)
   2697     {
   2698       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2699         MagickGravityOptions,(ssize_t) CurrentContext->gravity),
   2700         MagickPathExtent);
   2701       (void) SetXMLTreeContent(child,value);
   2702     }
   2703   child=AddChildToXMLTree(xml_info,"stroke",0);
   2704   if (child != (XMLTreeInfo *) NULL)
   2705     {
   2706       if (CurrentContext->stroke.alpha != OpaqueAlpha)
   2707         pixel.alpha_trait=CurrentContext->stroke.alpha != OpaqueAlpha ?
   2708           BlendPixelTrait : UndefinedPixelTrait;
   2709       pixel=CurrentContext->stroke;
   2710       GetColorTuple(&pixel,MagickTrue,value);
   2711       (void) SetXMLTreeContent(child,value);
   2712     }
   2713   child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
   2714   if (child != (XMLTreeInfo *) NULL)
   2715     {
   2716       (void) FormatLocaleString(value,MagickPathExtent,"%d",
   2717         CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
   2718       (void) SetXMLTreeContent(child,value);
   2719     }
   2720   child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
   2721   if ((child != (XMLTreeInfo *) NULL) &&
   2722       (CurrentContext->dash_pattern != (double *) NULL))
   2723     {
   2724       char
   2725         *dash_pattern;
   2726 
   2727       dash_pattern=AcquireString((char *) NULL);
   2728       for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++)
   2729       {
   2730         if (i != 0)
   2731           (void) ConcatenateString(&dash_pattern,",");
   2732         (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2733           CurrentContext->dash_pattern[i]);
   2734         (void) ConcatenateString(&dash_pattern,value);
   2735       }
   2736       (void) SetXMLTreeContent(child,dash_pattern);
   2737       dash_pattern=DestroyString(dash_pattern);
   2738     }
   2739   child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
   2740   if (child != (XMLTreeInfo *) NULL)
   2741     {
   2742       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2743         CurrentContext->dash_offset);
   2744       (void) SetXMLTreeContent(child,value);
   2745     }
   2746   child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
   2747   if (child != (XMLTreeInfo *) NULL)
   2748     {
   2749       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2750         MagickLineCapOptions,(ssize_t) CurrentContext->linecap),
   2751         MagickPathExtent);
   2752       (void) SetXMLTreeContent(child,value);
   2753     }
   2754   child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
   2755   if (child != (XMLTreeInfo *) NULL)
   2756     {
   2757       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2758         MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
   2759         MagickPathExtent);
   2760       (void) SetXMLTreeContent(child,value);
   2761     }
   2762   child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
   2763   if (child != (XMLTreeInfo *) NULL)
   2764     {
   2765       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
   2766         CurrentContext->miterlimit);
   2767       (void) SetXMLTreeContent(child,value);
   2768     }
   2769   child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
   2770   if (child != (XMLTreeInfo *) NULL)
   2771     {
   2772       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2773         (double) (QuantumScale*CurrentContext->stroke.alpha));
   2774       (void) SetXMLTreeContent(child,value);
   2775     }
   2776   child=AddChildToXMLTree(xml_info,"stroke-width",0);
   2777   if (child != (XMLTreeInfo *) NULL)
   2778     {
   2779       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2780         CurrentContext->stroke_width);
   2781       (void) SetXMLTreeContent(child,value);
   2782     }
   2783   child=AddChildToXMLTree(xml_info,"text-align",0);
   2784   if (child != (XMLTreeInfo *) NULL)
   2785     {
   2786       (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
   2787         (ssize_t) CurrentContext->align),MagickPathExtent);
   2788       (void) SetXMLTreeContent(child,value);
   2789     }
   2790   child=AddChildToXMLTree(xml_info,"text-antialias",0);
   2791   if (child != (XMLTreeInfo *) NULL)
   2792     {
   2793       (void) FormatLocaleString(value,MagickPathExtent,"%d",
   2794         CurrentContext->text_antialias != MagickFalse ? 1 : 0);
   2795       (void) SetXMLTreeContent(child,value);
   2796     }
   2797   child=AddChildToXMLTree(xml_info,"text-undercolor",0);
   2798   if (child != (XMLTreeInfo *) NULL)
   2799     {
   2800       if (CurrentContext->undercolor.alpha != OpaqueAlpha)
   2801         pixel.alpha_trait=CurrentContext->undercolor.alpha != OpaqueAlpha ?
   2802           BlendPixelTrait : UndefinedPixelTrait;
   2803       pixel=CurrentContext->undercolor;
   2804       GetColorTuple(&pixel,MagickTrue,value);
   2805       (void) SetXMLTreeContent(child,value);
   2806     }
   2807   child=AddChildToXMLTree(xml_info,"vector-graphics",0);
   2808   if (child != (XMLTreeInfo *) NULL)
   2809     (void) SetXMLTreeContent(child,wand->mvg);
   2810   xml=XMLTreeInfoToXML(xml_info);
   2811   xml_info=DestroyXMLTree(xml_info);
   2812   return(xml);
   2813 }
   2814 
   2815 /*
   2817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2818 %                                                                             %
   2819 %                                                                             %
   2820 %                                                                             %
   2821 %   D r a w G e t T e x t U n d e r C o l o r                                 %
   2822 %                                                                             %
   2823 %                                                                             %
   2824 %                                                                             %
   2825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2826 %
   2827 %  DrawGetTextUnderColor() returns the color of a background rectangle
   2828 %  to place under text annotations.
   2829 %
   2830 %  The format of the DrawGetTextUnderColor method is:
   2831 %
   2832 %      void DrawGetTextUnderColor(const DrawingWand *wand,
   2833 %        PixelWand *under_color)
   2834 %
   2835 %  A description of each parameter follows:
   2836 %
   2837 %    o wand: the drawing wand.
   2838 %
   2839 %    o under_color: Return the under color.
   2840 %
   2841 */
   2842 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
   2843   PixelWand *under_color)
   2844 {
   2845   assert(wand != (const DrawingWand *) NULL);
   2846   assert(wand->signature == MagickWandSignature);
   2847   assert(under_color != (PixelWand *) NULL);
   2848   if (wand->debug != MagickFalse)
   2849     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2850   PixelSetPixelColor(under_color,&CurrentContext->undercolor);
   2851 }
   2852 
   2853 /*
   2855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2856 %                                                                             %
   2857 %                                                                             %
   2858 %                                                                             %
   2859 %   D r a w L i n e                                                           %
   2860 %                                                                             %
   2861 %                                                                             %
   2862 %                                                                             %
   2863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2864 %
   2865 %  DrawLine() draws a line on the image using the current stroke color,
   2866 %  stroke alpha, and stroke width.
   2867 %
   2868 %  The format of the DrawLine method is:
   2869 %
   2870 %      void DrawLine(DrawingWand *wand,const double sx,const double sy,
   2871 %        const double ex,const double ey)
   2872 %
   2873 %  A description of each parameter follows:
   2874 %
   2875 %    o wand: the drawing wand.
   2876 %
   2877 %    o sx: starting x ordinate
   2878 %
   2879 %    o sy: starting y ordinate
   2880 %
   2881 %    o ex: ending x ordinate
   2882 %
   2883 %    o ey: ending y ordinate
   2884 %
   2885 */
   2886 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
   2887   const double ex,const double ey)
   2888 {
   2889   assert(wand != (DrawingWand *) NULL);
   2890   assert(wand->signature == MagickWandSignature);
   2891   if (wand->debug != MagickFalse)
   2892     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2893   (void) MVGPrintf(wand,"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey);
   2894 }
   2895 
   2896 /*
   2898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2899 %                                                                             %
   2900 %                                                                             %
   2901 %                                                                             %
   2902 %   D r a w P a t h C l o s e                                                 %
   2903 %                                                                             %
   2904 %                                                                             %
   2905 %                                                                             %
   2906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2907 %
   2908 %  DrawPathClose() adds a path element to the current path which closes the
   2909 %  current subpath by drawing a straight line from the current point to the
   2910 %  current subpath's most recent starting point (usually, the most recent
   2911 %  moveto point).
   2912 %
   2913 %  The format of the DrawPathClose method is:
   2914 %
   2915 %      void DrawPathClose(DrawingWand *wand)
   2916 %
   2917 %  A description of each parameter follows:
   2918 %
   2919 %    o wand: the drawing wand.
   2920 %
   2921 */
   2922 WandExport void DrawPathClose(DrawingWand *wand)
   2923 {
   2924   assert(wand != (DrawingWand *) NULL);
   2925   assert(wand->signature == MagickWandSignature);
   2926   if (wand->debug != MagickFalse)
   2927     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2928   (void) MVGAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
   2929     "Z" : "z");
   2930 }
   2931 
   2932 /*
   2934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2935 %                                                                             %
   2936 %                                                                             %
   2937 %                                                                             %
   2938 %   D r a w P a t h C u r v e T o A b s o l u t e                             %
   2939 %                                                                             %
   2940 %                                                                             %
   2941 %                                                                             %
   2942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2943 %
   2944 %  DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
   2945 %  point to (x,y) using (x1,y1) as the control point at the beginning of
   2946 %  the curve and (x2,y2) as the control point at the end of the curve using
   2947 %  absolute coordinates. At the end of the command, the new current point
   2948 %  becomes the final (x,y) coordinate pair used in the polybezier.
   2949 %
   2950 %  The format of the DrawPathCurveToAbsolute method is:
   2951 %
   2952 %      void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
   2953 %        const double y1,const double x2,const double y2,const double x,
   2954 %        const double y)
   2955 %
   2956 %  A description of each parameter follows:
   2957 %
   2958 %    o wand: the drawing wand.
   2959 %
   2960 %    o x1: x ordinate of control point for curve beginning
   2961 %
   2962 %    o y1: y ordinate of control point for curve beginning
   2963 %
   2964 %    o x2: x ordinate of control point for curve ending
   2965 %
   2966 %    o y2: y ordinate of control point for curve ending
   2967 %
   2968 %    o x: x ordinate of the end of the curve
   2969 %
   2970 %    o y: y ordinate of the end of the curve
   2971 %
   2972 */
   2973 
   2974 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
   2975   const double x1,const double y1,const double x2,const double y2,
   2976   const double x,const double y)
   2977 {
   2978   assert(wand != (DrawingWand *) NULL);
   2979   assert(wand->signature == MagickWandSignature);
   2980   if (wand->debug != MagickFalse)
   2981     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2982   if ((wand->path_operation != PathCurveToOperation) ||
   2983       (wand->path_mode != mode))
   2984     {
   2985       wand->path_operation=PathCurveToOperation;
   2986       wand->path_mode=mode;
   2987       (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g %.20g %.20g",
   2988         mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
   2989     }
   2990   else
   2991     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1,
   2992       x2,y2,x,y);
   2993 }
   2994 
   2995 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
   2996   const double y1,const double x2,const double y2,const double x,const double y)
   2997 {
   2998   assert(wand != (DrawingWand *) NULL);
   2999   assert(wand->signature == MagickWandSignature);
   3000   if (wand->debug != MagickFalse)
   3001     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3002   DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
   3003 }
   3004 
   3005 /*
   3007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3008 %                                                                             %
   3009 %                                                                             %
   3010 %                                                                             %
   3011 %   D r a w P a t h C u r v e T o R e l a t i v e                             %
   3012 %                                                                             %
   3013 %                                                                             %
   3014 %                                                                             %
   3015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3016 %
   3017 %  DrawPathCurveToRelative() draws a cubic Bezier curve from the current
   3018 %  point to (x,y) using (x1,y1) as the control point at the beginning of
   3019 %  the curve and (x2,y2) as the control point at the end of the curve using
   3020 %  relative coordinates. At the end of the command, the new current point
   3021 %  becomes the final (x,y) coordinate pair used in the polybezier.
   3022 %
   3023 %  The format of the DrawPathCurveToRelative method is:
   3024 %
   3025 %      void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
   3026 %        const double y1,const double x2,const double y2,const double x,
   3027 %        const double y)
   3028 %
   3029 %  A description of each parameter follows:
   3030 %
   3031 %    o wand: the drawing wand.
   3032 %
   3033 %    o x1: x ordinate of control point for curve beginning
   3034 %
   3035 %    o y1: y ordinate of control point for curve beginning
   3036 %
   3037 %    o x2: x ordinate of control point for curve ending
   3038 %
   3039 %    o y2: y ordinate of control point for curve ending
   3040 %
   3041 %    o x: x ordinate of the end of the curve
   3042 %
   3043 %    o y: y ordinate of the end of the curve
   3044 %
   3045 */
   3046 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
   3047   const double y1,const double x2,const double y2,const double x,const double y)
   3048 {
   3049   assert(wand != (DrawingWand *) NULL);
   3050   assert(wand->signature == MagickWandSignature);
   3051   if (wand->debug != MagickFalse)
   3052     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3053   DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
   3054 }
   3055 
   3056 /*
   3058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3059 %                                                                             %
   3060 %                                                                             %
   3061 %                                                                             %
   3062 % D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r A b s o l u t e %
   3063 %                                                                             %
   3064 %                                                                             %
   3065 %                                                                             %
   3066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3067 %
   3068 %  DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
   3069 %  from the current point to (x,y) using (x1,y1) as the control point using
   3070 %  absolute coordinates. At the end of the command, the new current point
   3071 %  becomes the final (x,y) coordinate pair used in the polybezier.
   3072 %
   3073 %  The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
   3074 %
   3075 %      void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
   3076 %        const double x1,const double y1,onst double x,const double y)
   3077 %
   3078 %  A description of each parameter follows:
   3079 %
   3080 %    o wand: the drawing wand.
   3081 %
   3082 %    o x1: x ordinate of the control point
   3083 %
   3084 %    o y1: y ordinate of the control point
   3085 %
   3086 %    o x: x ordinate of final point
   3087 %
   3088 %    o y: y ordinate of final point
   3089 %
   3090 */
   3091 
   3092 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
   3093   const PathMode mode,const double x1,double y1,const double x,const double y)
   3094 {
   3095   assert(wand != (DrawingWand *) NULL);
   3096   assert(wand->signature == MagickWandSignature);
   3097   if (wand->debug != MagickFalse)
   3098     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3099   if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
   3100       (wand->path_mode != mode))
   3101     {
   3102       wand->path_operation=PathCurveToQuadraticBezierOperation;
   3103       wand->path_mode=mode;
   3104       (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g",
   3105          mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
   3106     }
   3107   else
   3108     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x1,y1,x,y);
   3109 }
   3110 
   3111 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
   3112   const double x1,const double y1,const double x,const double y)
   3113 {
   3114   assert(wand != (DrawingWand *) NULL);
   3115   assert(wand->signature == MagickWandSignature);
   3116   if (wand->debug != MagickFalse)
   3117     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3118   DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
   3119 }
   3120 
   3121 /*
   3123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3124 %                                                                             %
   3125 %                                                                             %
   3126 %                                                                             %
   3127 % D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r R e l a t i v e %
   3128 %                                                                             %
   3129 %                                                                             %
   3130 %                                                                             %
   3131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3132 %
   3133 %  DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
   3134 %  from the current point to (x,y) using (x1,y1) as the control point using
   3135 %  relative coordinates. At the end of the command, the new current point
   3136 %  becomes the final (x,y) coordinate pair used in the polybezier.
   3137 %
   3138 %  The format of the DrawPathCurveToQuadraticBezierRelative method is:
   3139 %
   3140 %      void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
   3141 %        const double x1,const double y1,const double x,const double y)
   3142 %
   3143 %  A description of each parameter follows:
   3144 %
   3145 %    o wand: the drawing wand.
   3146 %
   3147 %    o x1: x ordinate of the control point
   3148 %
   3149 %    o y1: y ordinate of the control point
   3150 %
   3151 %    o x: x ordinate of final point
   3152 %
   3153 %    o y: y ordinate of final point
   3154 %
   3155 */
   3156 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
   3157   const double x1,const double y1,const double x,const double y)
   3158 {
   3159   assert(wand != (DrawingWand *) NULL);
   3160   assert(wand->signature == MagickWandSignature);
   3161   if (wand->debug != MagickFalse)
   3162     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3163   DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
   3164 }
   3165 
   3166 /*
   3168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3169 %                                                                             %
   3170 %                                                                             %
   3171 %                                                                             %
   3172 %   D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h   %
   3173 %                                                                             %
   3174 %                                                                             %
   3175 %                                                                             %
   3176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3177 %
   3178 %  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
   3179 %  Bezier curve (using absolute coordinates) from the current point to
   3180 %  (x,y). The control point is assumed to be the reflection of the
   3181 %  control point on the previous command relative to the current
   3182 %  point. (If there is no previous command or if the previous command was
   3183 %  not a DrawPathCurveToQuadraticBezierAbsolute,
   3184 %  DrawPathCurveToQuadraticBezierRelative,
   3185 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
   3186 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
   3187 %  is coincident with the current point.). At the end of the command, the
   3188 %  new current point becomes the final (x,y) coordinate pair used in the
   3189 %  polybezier.
   3190 %
   3191 %  The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
   3192 %
   3193 %      void DrawPathCurveToQuadraticBezierSmoothAbsolute(
   3194 %        DrawingWand *wand,const double x,const double y)
   3195 %
   3196 %  A description of each parameter follows:
   3197 %
   3198 %    o wand: the drawing wand.
   3199 %
   3200 %    o x: x ordinate of final point
   3201 %
   3202 %    o y: y ordinate of final point
   3203 %
   3204 */
   3205 
   3206 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
   3207   const PathMode mode,const double x,const double y)
   3208 {
   3209   assert(wand != (DrawingWand *) NULL);
   3210   assert(wand->signature == MagickWandSignature);
   3211   if (wand->debug != MagickFalse)
   3212     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3213   if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
   3214       (wand->path_mode != mode))
   3215     {
   3216       wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
   3217       wand->path_mode=mode;
   3218       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
   3219         'T' : 't',x,y);
   3220     }
   3221   else
   3222     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
   3223 }
   3224 
   3225 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
   3226   const double x,const double y)
   3227 {
   3228   assert(wand != (DrawingWand *) NULL);
   3229   assert(wand->signature == MagickWandSignature);
   3230   if (wand->debug != MagickFalse)
   3231     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3232   DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
   3233 }
   3234 
   3235 /*
   3237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3238 %                                                                             %
   3239 %                                                                             %
   3240 %                                                                             %
   3241 %   D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h   %
   3242 %                                                                             %
   3243 %                                                                             %
   3244 %                                                                             %
   3245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3246 %
   3247 %  DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic Bezier
   3248 %  curve (using relative coordinates) from the current point to (x,y). The
   3249 %  control point is assumed to be the reflection of the control point on the
   3250 %  previous command relative to the current point. (If there is no previous
   3251 %  command or if the previous command was not a
   3252 %  DrawPathCurveToQuadraticBezierAbsolute,
   3253 %  DrawPathCurveToQuadraticBezierRelative,
   3254 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
   3255 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
   3256 %  coincident with the current point.). At the end of the command, the new
   3257 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
   3258 %
   3259 %  The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
   3260 %
   3261 %      void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
   3262 %        const double x,const double y)
   3263 %
   3264 %  A description of each parameter follows:
   3265 %
   3266 %    o wand: the drawing wand.
   3267 %
   3268 %    o x: x ordinate of final point
   3269 %
   3270 %    o y: y ordinate of final point
   3271 %
   3272 */
   3273 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
   3274   const double x,const double y)
   3275 {
   3276   DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
   3277 }
   3278 
   3279 /*
   3281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3282 %                                                                             %
   3283 %                                                                             %
   3284 %                                                                             %
   3285 %   D r a w P a t h C u r v e T o S m o o t h A b s o l u t e                 %
   3286 %                                                                             %
   3287 %                                                                             %
   3288 %                                                                             %
   3289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3290 %
   3291 %  DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
   3292 %  current point to (x,y) using absolute coordinates. The first control
   3293 %  point is assumed to be the reflection of the second control point on
   3294 %  the previous command relative to the current point. (If there is no
   3295 %  previous command or if the previous command was not an
   3296 %  DrawPathCurveToAbsolute, DrawPathCurveToRelative,
   3297 %  DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
   3298 %  the first control point is coincident with the current point.) (x2,y2)
   3299 %  is the second control point (i.e., the control point at the end of the
   3300 %  curve). At the end of the command, the new current point becomes the
   3301 %  final (x,y) coordinate pair used in the polybezier.
   3302 %
   3303 %  The format of the DrawPathCurveToSmoothAbsolute method is:
   3304 %
   3305 %      void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
   3306 %        const double x2,const double y2,const double x,const double y)
   3307 %
   3308 %  A description of each parameter follows:
   3309 %
   3310 %    o wand: the drawing wand.
   3311 %
   3312 %    o x2: x ordinate of second control point
   3313 %
   3314 %    o y2: y ordinate of second control point
   3315 %
   3316 %    o x: x ordinate of termination point
   3317 %
   3318 %    o y: y ordinate of termination point
   3319 %
   3320 */
   3321 
   3322 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
   3323   const double x2,const double y2,const double x,const double y)
   3324 {
   3325   assert(wand != (DrawingWand *) NULL);
   3326   assert(wand->signature == MagickWandSignature);
   3327   if (wand->debug != MagickFalse)
   3328     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3329   if ((wand->path_operation != PathCurveToSmoothOperation) ||
   3330       (wand->path_mode != mode))
   3331     {
   3332       wand->path_operation=PathCurveToSmoothOperation;
   3333       wand->path_mode=mode;
   3334       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g %.20g %.20g",
   3335         mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
   3336     }
   3337   else
   3338     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x2,y2,x,y);
   3339 }
   3340 
   3341 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
   3342   const double y2,const double x,const double y)
   3343 {
   3344   assert(wand != (DrawingWand *) NULL);
   3345   assert(wand->signature == MagickWandSignature);
   3346   if (wand->debug != MagickFalse)
   3347     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3348   DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
   3349 }
   3350 
   3351 /*
   3353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3354 %                                                                             %
   3355 %                                                                             %
   3356 %                                                                             %
   3357 %   D r a w P a t h C u r v e T o S m o o t h R e l a t i v e                 %
   3358 %                                                                             %
   3359 %                                                                             %
   3360 %                                                                             %
   3361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3362 %
   3363 %  DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
   3364 %  point to (x,y) using relative coordinates. The first control point is
   3365 %  assumed to be the reflection of the second control point on the previous
   3366 %  command relative to the current point. (If there is no previous command or
   3367 %  if the previous command was not an DrawPathCurveToAbsolute,
   3368 %  DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
   3369 %  DrawPathCurveToSmoothRelative, assume the first control point is coincident
   3370 %  with the current point.) (x2,y2) is the second control point (i.e., the
   3371 %  control point at the end of the curve). At the end of the command, the new
   3372 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
   3373 %
   3374 %  The format of the DrawPathCurveToSmoothRelative method is:
   3375 %
   3376 %      void DrawPathCurveToSmoothRelative(DrawingWand *wand,
   3377 %        const double x2,const double y2,const double x,const double y)
   3378 %
   3379 %  A description of each parameter follows:
   3380 %
   3381 %    o wand: the drawing wand.
   3382 %
   3383 %    o x2: x ordinate of second control point
   3384 %
   3385 %    o y2: y ordinate of second control point
   3386 %
   3387 %    o x: x ordinate of termination point
   3388 %
   3389 %    o y: y ordinate of termination point
   3390 %
   3391 */
   3392 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
   3393   const double y2,const double x,const double y)
   3394 {
   3395   assert(wand != (DrawingWand *) NULL);
   3396   assert(wand->signature == MagickWandSignature);
   3397   if (wand->debug != MagickFalse)
   3398     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3399   DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
   3400 }
   3401 
   3402 /*
   3404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3405 %                                                                             %
   3406 %                                                                             %
   3407 %                                                                             %
   3408 %   D r a w P a t h E l l i p t i c A r c A b s o l u t e                     %
   3409 %                                                                             %
   3410 %                                                                             %
   3411 %                                                                             %
   3412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3413 %
   3414 %  DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
   3415 %  to (x, y) using absolute coordinates. The size and orientation of the
   3416 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
   3417 %  indicates how the ellipse as a whole is rotated relative to the current
   3418 %  coordinate system. The center (cx, cy) of the ellipse is calculated
   3419 %  automagically to satisfy the constraints imposed by the other parameters.
   3420 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
   3421 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
   3422 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
   3423 %  clock-wise rotation.
   3424 %
   3425 %  The format of the DrawPathEllipticArcAbsolute method is:
   3426 %
   3427 %      void DrawPathEllipticArcAbsolute(DrawingWand *wand,
   3428 %        const double rx,const double ry,const double x_axis_rotation,
   3429 %        const MagickBooleanType large_arc_flag,
   3430 %        const MagickBooleanType sweep_flag,const double x,const double y)
   3431 %
   3432 %  A description of each parameter follows:
   3433 %
   3434 %    o wand: the drawing wand.
   3435 %
   3436 %    o rx: x radius
   3437 %
   3438 %    o ry: y radius
   3439 %
   3440 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
   3441 %        relative to the current coordinate system
   3442 %
   3443 %    o large_arc_flag: If non-zero (true) then draw the larger of the
   3444 %        available arcs
   3445 %
   3446 %    o sweep_flag: If non-zero (true) then draw the arc matching a
   3447 %        clock-wise rotation
   3448 %
   3449 %
   3450 */
   3451 
   3452 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
   3453   const double rx,const double ry,const double x_axis_rotation,
   3454   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
   3455   const double x,const double y)
   3456 {
   3457   assert(wand != (DrawingWand *) NULL);
   3458   assert(wand->signature == MagickWandSignature);
   3459   if (wand->debug != MagickFalse)
   3460     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3461   if ((wand->path_operation != PathEllipticArcOperation) ||
   3462       (wand->path_mode != mode))
   3463     {
   3464       wand->path_operation=PathEllipticArcOperation;
   3465       wand->path_mode=mode;
   3466       (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %u %u %.20g %.20g",
   3467         mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
   3468         large_arc_flag,sweep_flag,x,y);
   3469     }
   3470   else
   3471     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry,
   3472       x_axis_rotation,large_arc_flag,sweep_flag,x,y);
   3473 }
   3474 
   3475 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
   3476   const double ry,const double x_axis_rotation,
   3477   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
   3478   const double x,const double y)
   3479 {
   3480   assert(wand != (DrawingWand *) NULL);
   3481   assert(wand->signature == MagickWandSignature);
   3482   if (wand->debug != MagickFalse)
   3483     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3484   DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
   3485     large_arc_flag,sweep_flag,x,y);
   3486 }
   3487 
   3488 /*
   3490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3491 %                                                                             %
   3492 %                                                                             %
   3493 %                                                                             %
   3494 %   D r a w P a t h E l l i p t i c A r c R e l a t i v e                     %
   3495 %                                                                             %
   3496 %                                                                             %
   3497 %                                                                             %
   3498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3499 %
   3500 %  DrawPathEllipticArcRelative() draws an elliptical arc from the current point
   3501 %  to (x, y) using relative coordinates. The size and orientation of the
   3502 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
   3503 %  indicates how the ellipse as a whole is rotated relative to the current
   3504 %  coordinate system. The center (cx, cy) of the ellipse is calculated
   3505 %  automagically to satisfy the constraints imposed by the other parameters.
   3506 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
   3507 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
   3508 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
   3509 %  clock-wise rotation.
   3510 %
   3511 %  The format of the DrawPathEllipticArcRelative method is:
   3512 %
   3513 %      void DrawPathEllipticArcRelative(DrawingWand *wand,
   3514 %        const double rx,const double ry,const double x_axis_rotation,
   3515 %        const MagickBooleanType large_arc_flag,
   3516 %        const MagickBooleanType sweep_flag,const double x,const double y)
   3517 %
   3518 %  A description of each parameter follows:
   3519 %
   3520 %    o wand: the drawing wand.
   3521 %
   3522 %    o rx: x radius
   3523 %
   3524 %    o ry: y radius
   3525 %
   3526 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
   3527 %                       relative to the current coordinate system
   3528 %
   3529 %    o large_arc_flag: If non-zero (true) then draw the larger of the
   3530 %                      available arcs
   3531 %
   3532 %    o sweep_flag: If non-zero (true) then draw the arc matching a
   3533 %                  clock-wise rotation
   3534 %
   3535 */
   3536 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
   3537   const double ry,const double x_axis_rotation,
   3538   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
   3539   const double x,const double y)
   3540 {
   3541   DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
   3542     large_arc_flag,sweep_flag,x,y);
   3543 }
   3544 
   3545 /*
   3547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3548 %                                                                             %
   3549 %                                                                             %
   3550 %                                                                             %
   3551 %   D r a w P a t h F i n i s h                                               %
   3552 %                                                                             %
   3553 %                                                                             %
   3554 %                                                                             %
   3555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3556 %
   3557 %  DrawPathFinish() terminates the current path.
   3558 %
   3559 %  The format of the DrawPathFinish method is:
   3560 %
   3561 %      void DrawPathFinish(DrawingWand *wand)
   3562 %
   3563 %  A description of each parameter follows:
   3564 %
   3565 %    o wand: the drawing wand.
   3566 %
   3567 */
   3568 WandExport void DrawPathFinish(DrawingWand *wand)
   3569 {
   3570   assert(wand != (DrawingWand *) NULL);
   3571   assert(wand->signature == MagickWandSignature);
   3572   if (wand->debug != MagickFalse)
   3573     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3574   (void) MVGPrintf(wand,"'\n");
   3575   wand->path_operation=PathDefaultOperation;
   3576   wand->path_mode=DefaultPathMode;
   3577 }
   3578 
   3579 /*
   3581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3582 %                                                                             %
   3583 %                                                                             %
   3584 %                                                                             %
   3585 %   D r a w P a t h L i n e T o A b s o l u t e                               %
   3586 %                                                                             %
   3587 %                                                                             %
   3588 %                                                                             %
   3589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3590 %
   3591 %  DrawPathLineToAbsolute() draws a line path from the current point to the
   3592 %  given coordinate using absolute coordinates. The coordinate then becomes
   3593 %  the new current point.
   3594 %
   3595 %  The format of the DrawPathLineToAbsolute method is:
   3596 %
   3597 %      void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
   3598 %        const double y)
   3599 %
   3600 %  A description of each parameter follows:
   3601 %
   3602 %    o wand: the drawing wand.
   3603 %
   3604 %    o x: target x ordinate
   3605 %
   3606 %    o y: target y ordinate
   3607 %
   3608 */
   3609 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
   3610   const double x,const double y)
   3611 {
   3612   assert(wand != (DrawingWand *) NULL);
   3613   assert(wand->signature == MagickWandSignature);
   3614   if (wand->debug != MagickFalse)
   3615     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3616   if ((wand->path_operation != PathLineToOperation) ||
   3617       (wand->path_mode != mode))
   3618     {
   3619       wand->path_operation=PathLineToOperation;
   3620       wand->path_mode=mode;
   3621       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
   3622         'L' : 'l',x,y);
   3623     }
   3624   else
   3625     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
   3626 }
   3627 
   3628 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
   3629   const double y)
   3630 {
   3631   assert(wand != (DrawingWand *) NULL);
   3632   assert(wand->signature == MagickWandSignature);
   3633   if (wand->debug != MagickFalse)
   3634     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3635   DrawPathLineTo(wand,AbsolutePathMode,x,y);
   3636 }
   3637 
   3638 /*
   3640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3641 %                                                                             %
   3642 %                                                                             %
   3643 %                                                                             %
   3644 %   D r a w P a t h L i n e T o R e l a t i v e                               %
   3645 %                                                                             %
   3646 %                                                                             %
   3647 %                                                                             %
   3648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3649 %
   3650 %  DrawPathLineToRelative() draws a line path from the current point to the
   3651 %  given coordinate using relative coordinates. The coordinate then becomes
   3652 %  the new current point.
   3653 %
   3654 %  The format of the DrawPathLineToRelative method is:
   3655 %
   3656 %      void DrawPathLineToRelative(DrawingWand *wand,const double x,
   3657 %        const double y)
   3658 %
   3659 %  A description of each parameter follows:
   3660 %
   3661 %    o wand: the drawing wand.
   3662 %
   3663 %    o x: target x ordinate
   3664 %
   3665 %    o y: target y ordinate
   3666 %
   3667 */
   3668 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
   3669   const double y)
   3670 {
   3671   assert(wand != (DrawingWand *) NULL);
   3672   assert(wand->signature == MagickWandSignature);
   3673   if (wand->debug != MagickFalse)
   3674     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3675   DrawPathLineTo(wand,RelativePathMode,x,y);
   3676 }
   3677 
   3678 /*
   3680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3681 %                                                                             %
   3682 %                                                                             %
   3683 %                                                                             %
   3684 %   D r a w P a t h L i n e T o H o r i z o n t a l A b s o l u t e           %
   3685 %                                                                             %
   3686 %                                                                             %
   3687 %                                                                             %
   3688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3689 %
   3690 %  DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
   3691 %  current point to the target point using absolute coordinates.  The target
   3692 %  point then becomes the new current point.
   3693 %
   3694 %  The format of the DrawPathLineToHorizontalAbsolute method is:
   3695 %
   3696 %      void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,const double x)
   3697 %
   3698 %  A description of each parameter follows:
   3699 %
   3700 %    o wand: the drawing wand.
   3701 %
   3702 %    o x: target x ordinate
   3703 %
   3704 */
   3705 
   3706 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
   3707   const double x)
   3708 {
   3709   assert(wand != (DrawingWand *) NULL);
   3710   assert(wand->signature == MagickWandSignature);
   3711   if (wand->debug != MagickFalse)
   3712     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3713   if ((wand->path_operation != PathLineToHorizontalOperation) ||
   3714       (wand->path_mode != mode))
   3715     {
   3716       wand->path_operation=PathLineToHorizontalOperation;
   3717       wand->path_mode=mode;
   3718       (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
   3719         'H' : 'h',x);
   3720     }
   3721   else
   3722     (void) MVGAutoWrapPrintf(wand," %.20g",x);
   3723 }
   3724 
   3725 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
   3726   const double x)
   3727 {
   3728   assert(wand != (DrawingWand *) NULL);
   3729   assert(wand->signature == MagickWandSignature);
   3730   if (wand->debug != MagickFalse)
   3731     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3732   DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
   3733 }
   3734 
   3735 /*
   3737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3738 %                                                                             %
   3739 %                                                                             %
   3740 %                                                                             %
   3741 %   D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e           %
   3742 %                                                                             %
   3743 %                                                                             %
   3744 %                                                                             %
   3745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3746 %
   3747 %  DrawPathLineToHorizontalRelative() draws a horizontal line path from the
   3748 %  current point to the target point using relative coordinates.  The target
   3749 %  point then becomes the new current point.
   3750 %
   3751 %  The format of the DrawPathLineToHorizontalRelative method is:
   3752 %
   3753 %      void DrawPathLineToHorizontalRelative(DrawingWand *wand,
   3754 %        const double x)
   3755 %
   3756 %  A description of each parameter follows:
   3757 %
   3758 %    o wand: the drawing wand.
   3759 %
   3760 %    o x: target x ordinate
   3761 %
   3762 */
   3763 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
   3764   const double x)
   3765 {
   3766   DrawPathLineToHorizontal(wand,RelativePathMode,x);
   3767 }
   3768 
   3769 /*
   3771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3772 %                                                                             %
   3773 %                                                                             %
   3774 %                                                                             %
   3775 %   D r a w P a t h L i n e T o V e r t i c a l A b s o l u t e               %
   3776 %                                                                             %
   3777 %                                                                             %
   3778 %                                                                             %
   3779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3780 %
   3781 %  DrawPathLineToVerticalAbsolute() draws a vertical line path from the
   3782 %  current point to the target point using absolute coordinates.  The target
   3783 %  point then becomes the new current point.
   3784 %
   3785 %  The format of the DrawPathLineToVerticalAbsolute method is:
   3786 %
   3787 %      void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
   3788 %        const double y)
   3789 %
   3790 %  A description of each parameter follows:
   3791 %
   3792 %    o wand: the drawing wand.
   3793 %
   3794 %    o y: target y ordinate
   3795 %
   3796 */
   3797 
   3798 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
   3799   const double y)
   3800 {
   3801   assert(wand != (DrawingWand *) NULL);
   3802   assert(wand->signature == MagickWandSignature);
   3803   if (wand->debug != MagickFalse)
   3804     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3805   if ((wand->path_operation != PathLineToVerticalOperation) ||
   3806       (wand->path_mode != mode))
   3807     {
   3808       wand->path_operation=PathLineToVerticalOperation;
   3809       wand->path_mode=mode;
   3810       (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
   3811         'V' : 'v',y);
   3812     }
   3813   else
   3814     (void) MVGAutoWrapPrintf(wand," %.20g",y);
   3815 }
   3816 
   3817 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
   3818 {
   3819   assert(wand != (DrawingWand *) NULL);
   3820   assert(wand->signature == MagickWandSignature);
   3821   if (wand->debug != MagickFalse)
   3822     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3823   DrawPathLineToVertical(wand,AbsolutePathMode,y);
   3824 }
   3825 
   3826 /*
   3828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3829 %                                                                             %
   3830 %                                                                             %
   3831 %                                                                             %
   3832 %   D r a w P a t h L i n e T o V e r t i c a l R e l a t i v e               %
   3833 %                                                                             %
   3834 %                                                                             %
   3835 %                                                                             %
   3836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3837 %
   3838 %  DrawPathLineToVerticalRelative() draws a vertical line path from the
   3839 %  current point to the target point using relative coordinates.  The target
   3840 %  point then becomes the new current point.
   3841 %
   3842 %  The format of the DrawPathLineToVerticalRelative method is:
   3843 %
   3844 %      void DrawPathLineToVerticalRelative(DrawingWand *wand,
   3845 %        const double y)
   3846 %
   3847 %  A description of each parameter follows:
   3848 %
   3849 %    o wand: the drawing wand.
   3850 %
   3851 %    o y: target y ordinate
   3852 %
   3853 */
   3854 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
   3855 {
   3856   assert(wand != (DrawingWand *) NULL);
   3857   assert(wand->signature == MagickWandSignature);
   3858   if (wand->debug != MagickFalse)
   3859     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3860   DrawPathLineToVertical(wand,RelativePathMode,y);
   3861 }
   3862 /*
   3863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3864 %                                                                             %
   3865 %                                                                             %
   3866 %                                                                             %
   3867 %   D r a w P a t h M o v e T o A b s o l u t e                               %
   3868 %                                                                             %
   3869 %                                                                             %
   3870 %                                                                             %
   3871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3872 %
   3873 %  DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
   3874 %  using absolute coordinates. The current point then becomes the
   3875 %  specified coordinate.
   3876 %
   3877 %  The format of the DrawPathMoveToAbsolute method is:
   3878 %
   3879 %      void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
   3880 %        const double y)
   3881 %
   3882 %  A description of each parameter follows:
   3883 %
   3884 %    o wand: the drawing wand.
   3885 %
   3886 %    o x: target x ordinate
   3887 %
   3888 %    o y: target y ordinate
   3889 %
   3890 */
   3891 
   3892 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
   3893   const double y)
   3894 {
   3895   assert(wand != (DrawingWand *) NULL);
   3896   assert(wand->signature == MagickWandSignature);
   3897   if (wand->debug != MagickFalse)
   3898     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3899   if ((wand->path_operation != PathMoveToOperation) ||
   3900       (wand->path_mode != mode))
   3901     {
   3902       wand->path_operation=PathMoveToOperation;
   3903       wand->path_mode=mode;
   3904       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
   3905         'M' : 'm',x,y);
   3906     }
   3907   else
   3908     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
   3909 }
   3910 
   3911 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
   3912   const double y)
   3913 {
   3914   assert(wand != (DrawingWand *) NULL);
   3915   assert(wand->signature == MagickWandSignature);
   3916   if (wand->debug != MagickFalse)
   3917     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3918   DrawPathMoveTo(wand,AbsolutePathMode,x,y);
   3919 }
   3920 
   3921 /*
   3923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3924 %                                                                             %
   3925 %                                                                             %
   3926 %                                                                             %
   3927 %   D r a w P a t h M o v e T o R e l a t i v e                               %
   3928 %                                                                             %
   3929 %                                                                             %
   3930 %                                                                             %
   3931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3932 %
   3933 %  DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
   3934 %  relative coordinates. The current point then becomes the specified
   3935 %  coordinate.
   3936 %
   3937 %  The format of the DrawPathMoveToRelative method is:
   3938 %
   3939 %      void DrawPathMoveToRelative(DrawingWand *wand,const double x,
   3940 %        const double y)
   3941 %
   3942 %  A description of each parameter follows:
   3943 %
   3944 %    o wand: the drawing wand.
   3945 %
   3946 %    o x: target x ordinate
   3947 %
   3948 %    o y: target y ordinate
   3949 %
   3950 */
   3951 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
   3952   const double y)
   3953 {
   3954   assert(wand != (DrawingWand *) NULL);
   3955   assert(wand->signature == MagickWandSignature);
   3956   if (wand->debug != MagickFalse)
   3957     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3958   DrawPathMoveTo(wand,RelativePathMode,x,y);
   3959 }
   3960 
   3961 /*
   3963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3964 %                                                                             %
   3965 %                                                                             %
   3966 %                                                                             %
   3967 %   D r a w P a t h S t a r t                                                 %
   3968 %                                                                             %
   3969 %                                                                             %
   3970 %                                                                             %
   3971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3972 %
   3973 %  DrawPathStart() declares the start of a path drawing list which is terminated
   3974 %  by a matching DrawPathFinish() command. All other DrawPath commands must
   3975 %  be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
   3976 %  is because path drawing commands are subordinate commands and they do not
   3977 %  function by themselves.
   3978 %
   3979 %  The format of the DrawPathStart method is:
   3980 %
   3981 %      void DrawPathStart(DrawingWand *wand)
   3982 %
   3983 %  A description of each parameter follows:
   3984 %
   3985 %    o wand: the drawing wand.
   3986 %
   3987 */
   3988 WandExport void DrawPathStart(DrawingWand *wand)
   3989 {
   3990   assert(wand != (DrawingWand *) NULL);
   3991   assert(wand->signature == MagickWandSignature);
   3992   if (wand->debug != MagickFalse)
   3993     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3994   (void) MVGPrintf(wand,"path '");
   3995   wand->path_operation=PathDefaultOperation;
   3996   wand->path_mode=DefaultPathMode;
   3997 }
   3998 
   3999 /*
   4001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4002 %                                                                             %
   4003 %                                                                             %
   4004 %                                                                             %
   4005 %   D r a w P o i n t                                                         %
   4006 %                                                                             %
   4007 %                                                                             %
   4008 %                                                                             %
   4009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4010 %
   4011 %  DrawPoint() draws a point using the current fill color.
   4012 %
   4013 %  The format of the DrawPoint method is:
   4014 %
   4015 %      void DrawPoint(DrawingWand *wand,const double x,const double y)
   4016 %
   4017 %  A description of each parameter follows:
   4018 %
   4019 %    o wand: the drawing wand.
   4020 %
   4021 %    o x: target x coordinate
   4022 %
   4023 %    o y: target y coordinate
   4024 %
   4025 */
   4026 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
   4027 {
   4028   assert(wand != (DrawingWand *) NULL);
   4029   assert(wand->signature == MagickWandSignature);
   4030   if (wand->debug != MagickFalse)
   4031     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4032   (void) MVGPrintf(wand,"point %.20g %.20g\n",x,y);
   4033 }
   4034 
   4035 /*
   4037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4038 %                                                                             %
   4039 %                                                                             %
   4040 %                                                                             %
   4041 %   D r a w P o l y g o n                                                     %
   4042 %                                                                             %
   4043 %                                                                             %
   4044 %                                                                             %
   4045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4046 %
   4047 %  DrawPolygon() draws a polygon using the current stroke, stroke width, and
   4048 %  fill color or texture, using the specified array of coordinates.
   4049 %
   4050 %  The format of the DrawPolygon method is:
   4051 %
   4052 %      void DrawPolygon(DrawingWand *wand,
   4053 %        const size_t number_coordinates,const PointInfo *coordinates)
   4054 %
   4055 %  A description of each parameter follows:
   4056 %
   4057 %    o wand: the drawing wand.
   4058 %
   4059 %    o number_coordinates: number of coordinates
   4060 %
   4061 %    o coordinates: coordinate array
   4062 %
   4063 */
   4064 WandExport void DrawPolygon(DrawingWand *wand,
   4065   const size_t number_coordinates,const PointInfo *coordinates)
   4066 {
   4067   assert(wand != (DrawingWand *) NULL);
   4068   assert(wand->signature == MagickWandSignature);
   4069   if (wand->debug != MagickFalse)
   4070     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4071   MVGAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
   4072 }
   4073 
   4074 /*
   4076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4077 %                                                                             %
   4078 %                                                                             %
   4079 %                                                                             %
   4080 %   D r a w P o l y l i n e                                                   %
   4081 %                                                                             %
   4082 %                                                                             %
   4083 %                                                                             %
   4084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4085 %
   4086 %  DrawPolyline() draws a polyline using the current stroke, stroke width, and
   4087 %  fill color or texture, using the specified array of coordinates.
   4088 %
   4089 %  The format of the DrawPolyline method is:
   4090 %
   4091 %      void DrawPolyline(DrawingWand *wand,
   4092 %        const size_t number_coordinates,const PointInfo *coordinates)
   4093 %
   4094 %  A description of each parameter follows:
   4095 %
   4096 %    o wand: the drawing wand.
   4097 %
   4098 %    o number_coordinates: number of coordinates
   4099 %
   4100 %    o coordinates: coordinate array
   4101 %
   4102 */
   4103 WandExport void DrawPolyline(DrawingWand *wand,
   4104   const size_t number_coordinates,const PointInfo *coordinates)
   4105 {
   4106   assert(wand != (DrawingWand *) NULL);
   4107   assert(wand->signature == MagickWandSignature);
   4108   if (wand->debug != MagickFalse)
   4109     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4110   MVGAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
   4111 }
   4112 
   4113 /*
   4115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4116 %                                                                             %
   4117 %                                                                             %
   4118 %                                                                             %
   4119 %   D r a w P o p C l i p P a t h                                             %
   4120 %                                                                             %
   4121 %                                                                             %
   4122 %                                                                             %
   4123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4124 %
   4125 %  DrawPopClipPath() terminates a clip path definition.
   4126 %
   4127 %  The format of the DrawPopClipPath method is:
   4128 %
   4129 %      void DrawPopClipPath(DrawingWand *wand)
   4130 %
   4131 %  A description of each parameter follows:
   4132 %
   4133 %    o wand: the drawing wand.
   4134 %
   4135 */
   4136 WandExport void DrawPopClipPath(DrawingWand *wand)
   4137 {
   4138   assert(wand != (DrawingWand *) NULL);
   4139   assert(wand->signature == MagickWandSignature);
   4140   if (wand->debug != MagickFalse)
   4141     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4142   if (wand->indent_depth > 0)
   4143     wand->indent_depth--;
   4144   (void) MVGPrintf(wand,"pop clip-path\n");
   4145 }
   4146 
   4147 /*
   4149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4150 %                                                                             %
   4151 %                                                                             %
   4152 %                                                                             %
   4153 %   D r a w P o p D e f s                                                     %
   4154 %                                                                             %
   4155 %                                                                             %
   4156 %                                                                             %
   4157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4158 %
   4159 %  DrawPopDefs() terminates a definition list.
   4160 %
   4161 %  The format of the DrawPopDefs method is:
   4162 %
   4163 %      void DrawPopDefs(DrawingWand *wand)
   4164 %
   4165 %  A description of each parameter follows:
   4166 %
   4167 %    o wand: the drawing wand.
   4168 %
   4169 */
   4170 WandExport void DrawPopDefs(DrawingWand *wand)
   4171 {
   4172   assert(wand != (DrawingWand *) NULL);
   4173   assert(wand->signature == MagickWandSignature);
   4174   if (wand->debug != MagickFalse)
   4175     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4176   if (wand->indent_depth > 0)
   4177     wand->indent_depth--;
   4178   (void) MVGPrintf(wand,"pop defs\n");
   4179 }
   4180 
   4181 /*
   4183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4184 %                                                                             %
   4185 %                                                                             %
   4186 %                                                                             %
   4187 %   D r a w P o p P a t t e r n                                               %
   4188 %                                                                             %
   4189 %                                                                             %
   4190 %                                                                             %
   4191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4192 %
   4193 %  DrawPopPattern() terminates a pattern definition.
   4194 %
   4195 %  The format of the DrawPopPattern method is:
   4196 %
   4197 %      MagickBooleanType DrawPopPattern(DrawingWand *wand)
   4198 %
   4199 %  A description of each parameter follows:
   4200 %
   4201 %    o wand: the drawing wand.
   4202 %
   4203 */
   4204 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
   4205 {
   4206   char
   4207     geometry[MagickPathExtent],
   4208     key[MagickPathExtent];
   4209 
   4210   assert(wand != (DrawingWand *) NULL);
   4211   assert(wand->signature == MagickWandSignature);
   4212   if (wand->debug != MagickFalse)
   4213     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4214   if (wand->image == (Image *) NULL)
   4215     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   4216   if (wand->pattern_id == (const char *) NULL)
   4217     {
   4218       ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
   4219         wand->name);
   4220       return(MagickFalse);
   4221     }
   4222   (void) FormatLocaleString(key,MagickPathExtent,"%s",wand->pattern_id);
   4223   (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
   4224   (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g%+.20g%+.20g",
   4225     (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
   4226     (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
   4227   (void) SetImageArtifact(wand->image,key,geometry);
   4228   wand->pattern_id=DestroyString(wand->pattern_id);
   4229   wand->pattern_offset=0;
   4230   wand->pattern_bounds.x=0;
   4231   wand->pattern_bounds.y=0;
   4232   wand->pattern_bounds.width=0;
   4233   wand->pattern_bounds.height=0;
   4234   wand->filter_off=MagickTrue;
   4235   if (wand->indent_depth > 0)
   4236     wand->indent_depth--;
   4237   (void) MVGPrintf(wand,"pop pattern\n");
   4238   return(MagickTrue);
   4239 }
   4240 
   4241 /*
   4243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4244 %                                                                             %
   4245 %                                                                             %
   4246 %                                                                             %
   4247 %   D r a w P u s h C l i p P a t h                                           %
   4248 %                                                                             %
   4249 %                                                                             %
   4250 %                                                                             %
   4251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4252 %
   4253 %  DrawPushClipPath() starts a clip path definition which is comprized of any
   4254 %  number of drawing commands and terminated by a DrawPopClipPath() command.
   4255 %
   4256 %  The format of the DrawPushClipPath method is:
   4257 %
   4258 %      void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
   4259 %
   4260 %  A description of each parameter follows:
   4261 %
   4262 %    o wand: the drawing wand.
   4263 %
   4264 %    o clip_mask_id: string identifier to associate with the clip path for
   4265 %      later use.
   4266 %
   4267 */
   4268 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
   4269 {
   4270   assert(wand != (DrawingWand *) NULL);
   4271   assert(wand->signature == MagickWandSignature);
   4272   if (wand->debug != MagickFalse)
   4273     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4274   assert(clip_mask_id != (const char *) NULL);
   4275   (void) MVGPrintf(wand,"push clip-path \"%s\"\n",clip_mask_id);
   4276   wand->indent_depth++;
   4277 }
   4278 
   4279 /*
   4281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4282 %                                                                             %
   4283 %                                                                             %
   4284 %                                                                             %
   4285 %   D r a w P u s h D e f s                                                   %
   4286 %                                                                             %
   4287 %                                                                             %
   4288 %                                                                             %
   4289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4290 %
   4291 %  DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
   4292 %  command create named elements (e.g. clip-paths, textures, etc.) which
   4293 %  may safely be processed earlier for the sake of efficiency.
   4294 %
   4295 %  The format of the DrawPushDefs method is:
   4296 %
   4297 %      void DrawPushDefs(DrawingWand *wand)
   4298 %
   4299 %  A description of each parameter follows:
   4300 %
   4301 %    o wand: the drawing wand.
   4302 %
   4303 */
   4304 WandExport void DrawPushDefs(DrawingWand *wand)
   4305 {
   4306   assert(wand != (DrawingWand *) NULL);
   4307   assert(wand->signature == MagickWandSignature);
   4308   if (wand->debug != MagickFalse)
   4309     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4310   (void) MVGPrintf(wand,"push defs\n");
   4311   wand->indent_depth++;
   4312 }
   4313 
   4314 /*
   4316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4317 %                                                                             %
   4318 %                                                                             %
   4319 %                                                                             %
   4320 %   D r a w P u s h P a t t e r n                                             %
   4321 %                                                                             %
   4322 %                                                                             %
   4323 %                                                                             %
   4324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4325 %
   4326 %  DrawPushPattern() indicates that subsequent commands up to a
   4327 %  DrawPopPattern() command comprise the definition of a named pattern.
   4328 %  The pattern space is assigned top left corner coordinates, a width
   4329 %  and height, and becomes its own drawing space.  Anything which can
   4330 %  be drawn may be used in a pattern definition.
   4331 %  Named patterns may be used as stroke or brush definitions.
   4332 %
   4333 %  The format of the DrawPushPattern method is:
   4334 %
   4335 %      MagickBooleanType DrawPushPattern(DrawingWand *wand,
   4336 %        const char *pattern_id,const double x,const double y,
   4337 %        const double width,const double height)
   4338 %
   4339 %  A description of each parameter follows:
   4340 %
   4341 %    o wand: the drawing wand.
   4342 %
   4343 %    o pattern_id: pattern identification for later reference
   4344 %
   4345 %    o x: x ordinate of top left corner
   4346 %
   4347 %    o y: y ordinate of top left corner
   4348 %
   4349 %    o width: width of pattern space
   4350 %
   4351 %    o height: height of pattern space
   4352 %
   4353 */
   4354 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
   4355   const char *pattern_id,const double x,const double y,const double width,
   4356   const double height)
   4357 {
   4358   assert(wand != (DrawingWand *) NULL);
   4359   assert(wand->signature == MagickWandSignature);
   4360   if (wand->debug != MagickFalse)
   4361     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4362   assert(pattern_id != (const char *) NULL);
   4363   if (wand->pattern_id != NULL)
   4364     {
   4365       ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
   4366         wand->pattern_id);
   4367       return(MagickFalse);
   4368     }
   4369   wand->filter_off=MagickTrue;
   4370   (void) MVGPrintf(wand,"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id,
   4371     x,y,width,height);
   4372   wand->indent_depth++;
   4373   wand->pattern_id=AcquireString(pattern_id);
   4374   wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
   4375   wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
   4376   wand->pattern_bounds.width=(size_t) floor(width+0.5);
   4377   wand->pattern_bounds.height=(size_t) floor(height+0.5);
   4378   wand->pattern_offset=wand->mvg_length;
   4379   return(MagickTrue);
   4380 }
   4381 
   4382 /*
   4384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4385 %                                                                             %
   4386 %                                                                             %
   4387 %                                                                             %
   4388 %   D r a w R e c t a n g l e                                                 %
   4389 %                                                                             %
   4390 %                                                                             %
   4391 %                                                                             %
   4392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4393 %
   4394 %  DrawRectangle() draws a rectangle given two coordinates and using the
   4395 %  current stroke, stroke width, and fill settings.
   4396 %
   4397 %  The format of the DrawRectangle method is:
   4398 %
   4399 %      void DrawRectangle(DrawingWand *wand,const double x1,
   4400 %        const double y1,const double x2,const double y2)
   4401 %
   4402 %  A description of each parameter follows:
   4403 %
   4404 %    o x1: x ordinate of first coordinate
   4405 %
   4406 %    o y1: y ordinate of first coordinate
   4407 %
   4408 %    o x2: x ordinate of second coordinate
   4409 %
   4410 %    o y2: y ordinate of second coordinate
   4411 %
   4412 */
   4413 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
   4414   const double x2,const double y2)
   4415 {
   4416   assert(wand != (DrawingWand *) NULL);
   4417   assert(wand->signature == MagickWandSignature);
   4418   if (wand->debug != MagickFalse)
   4419     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4420   if ((fabs(x2-x1) < MagickEpsilon) && (fabs(y2-y1) < MagickEpsilon))
   4421     (void) MVGPrintf(wand,"point %.20g %.20g\n",x1,y1);
   4422   else
   4423    (void) MVGPrintf(wand,"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
   4424 }
   4425 
   4426 /*
   4428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4429 %                                                                             %
   4430 %                                                                             %
   4431 %                                                                             %
   4432 +   D r a w R e n d e r                                                       %
   4433 %                                                                             %
   4434 %                                                                             %
   4435 %                                                                             %
   4436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4437 %
   4438 %  DrawRender() renders all preceding drawing commands onto the image.
   4439 %
   4440 %  The format of the DrawRender method is:
   4441 %
   4442 %      MagickBooleanType DrawRender(DrawingWand *wand)
   4443 %
   4444 %  A description of each parameter follows:
   4445 %
   4446 %    o wand: the drawing wand.
   4447 %
   4448 */
   4449 WandExport MagickBooleanType DrawRender(DrawingWand *wand)
   4450 {
   4451   MagickBooleanType
   4452     status;
   4453 
   4454   assert(wand != (const DrawingWand *) NULL);
   4455   assert(wand->signature == MagickWandSignature);
   4456   if (wand->debug != MagickFalse)
   4457     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4458   CurrentContext->primitive=wand->mvg;
   4459   if (wand->debug != MagickFalse)
   4460     (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
   4461   if (wand->image == (Image *) NULL)
   4462     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   4463   status=DrawImage(wand->image,CurrentContext,wand->exception);
   4464   CurrentContext->primitive=(char *) NULL;
   4465   return(status);
   4466 }
   4467 
   4468 /*
   4470 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4471 %                                                                             %
   4472 %                                                                             %
   4473 %                                                                             %
   4474 %   D r a w R e s e t V e c t o r G r a p h i c s                             %
   4475 %                                                                             %
   4476 %                                                                             %
   4477 %                                                                             %
   4478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4479 %
   4480 %  DrawResetVectorGraphics() resets the vector graphics associated with the
   4481 %  specified wand.
   4482 %
   4483 %  The format of the DrawResetVectorGraphics method is:
   4484 %
   4485 %      void DrawResetVectorGraphics(DrawingWand *wand)
   4486 %
   4487 %  A description of each parameter follows:
   4488 %
   4489 %    o wand: the drawing wand.
   4490 %
   4491 */
   4492 WandExport void DrawResetVectorGraphics(DrawingWand *wand)
   4493 {
   4494   assert(wand != (DrawingWand *) NULL);
   4495   assert(wand->signature == MagickWandSignature);
   4496   if (wand->debug != MagickFalse)
   4497     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4498   if (wand->mvg != (char *) NULL)
   4499     wand->mvg=DestroyString(wand->mvg);
   4500   wand->mvg_alloc=0;
   4501   wand->mvg_length=0;
   4502   wand->mvg_width=0;
   4503 }
   4504 
   4505 /*
   4507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4508 %                                                                             %
   4509 %                                                                             %
   4510 %                                                                             %
   4511 %   D r a w R o t a t e                                                       %
   4512 %                                                                             %
   4513 %                                                                             %
   4514 %                                                                             %
   4515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4516 %
   4517 %  DrawRotate() applies the specified rotation to the current coordinate space.
   4518 %
   4519 %  The format of the DrawRotate method is:
   4520 %
   4521 %      void DrawRotate(DrawingWand *wand,const double degrees)
   4522 %
   4523 %  A description of each parameter follows:
   4524 %
   4525 %    o wand: the drawing wand.
   4526 %
   4527 %    o degrees: degrees of rotation
   4528 %
   4529 */
   4530 WandExport void DrawRotate(DrawingWand *wand,const double degrees)
   4531 {
   4532   assert(wand != (DrawingWand *) NULL);
   4533   assert(wand->signature == MagickWandSignature);
   4534   if (wand->debug != MagickFalse)
   4535     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4536   (void) MVGPrintf(wand,"rotate %.20g\n",degrees);
   4537 }
   4538 
   4539 /*
   4541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4542 %                                                                             %
   4543 %                                                                             %
   4544 %                                                                             %
   4545 %   D r a w R o u n d R e c t a n g l e                                       %
   4546 %                                                                             %
   4547 %                                                                             %
   4548 %                                                                             %
   4549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4550 %
   4551 %  DrawRoundRectangle() draws a rounted rectangle given two coordinates,
   4552 %  x & y corner radiuses and using the current stroke, stroke width,
   4553 %  and fill settings.
   4554 %
   4555 %  The format of the DrawRoundRectangle method is:
   4556 %
   4557 %      void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
   4558 %        double x2,double y2,double rx,double ry)
   4559 %
   4560 %  A description of each parameter follows:
   4561 %
   4562 %    o wand: the drawing wand.
   4563 %
   4564 %    o x1: x ordinate of first coordinate
   4565 %
   4566 %    o y1: y ordinate of first coordinate
   4567 %
   4568 %    o x2: x ordinate of second coordinate
   4569 %
   4570 %    o y2: y ordinate of second coordinate
   4571 %
   4572 %    o rx: radius of corner in horizontal direction
   4573 %
   4574 %    o ry: radius of corner in vertical direction
   4575 %
   4576 */
   4577 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
   4578   double x2,double y2,double rx,double ry)
   4579 {
   4580   assert(wand != (DrawingWand *) NULL);
   4581   assert(wand->signature == MagickWandSignature);
   4582   if (wand->debug != MagickFalse)
   4583     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4584   (void) MVGPrintf(wand,"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n",
   4585     x1,y1,x2,y2,rx,ry);
   4586 }
   4587 
   4588 /*
   4590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4591 %                                                                             %
   4592 %                                                                             %
   4593 %                                                                             %
   4594 %   D r a w S c a l e                                                         %
   4595 %                                                                             %
   4596 %                                                                             %
   4597 %                                                                             %
   4598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4599 %
   4600 %  DrawScale() adjusts the scaling factor to apply in the horizontal and
   4601 %  vertical directions to the current coordinate space.
   4602 %
   4603 %  The format of the DrawScale method is:
   4604 %
   4605 %      void DrawScale(DrawingWand *wand,const double x,const double y)
   4606 %
   4607 %  A description of each parameter follows:
   4608 %
   4609 %    o wand: the drawing wand.
   4610 %
   4611 %    o x: horizontal scale factor
   4612 %
   4613 %    o y: vertical scale factor
   4614 %
   4615 */
   4616 WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
   4617 {
   4618   assert(wand != (DrawingWand *) NULL);
   4619   assert(wand->signature == MagickWandSignature);
   4620   if (wand->debug != MagickFalse)
   4621     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4622   (void) MVGPrintf(wand,"scale %.20g %.20g\n",x,y);
   4623 }
   4624 
   4625 /*
   4627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4628 %                                                                             %
   4629 %                                                                             %
   4630 %                                                                             %
   4631 %   D r a w S e t B o r d e r C o l o r                                       %
   4632 %                                                                             %
   4633 %                                                                             %
   4634 %                                                                             %
   4635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4636 %
   4637 %  DrawSetBorderColor() sets the border color to be used for drawing bordered
   4638 %  objects.
   4639 %
   4640 %  The format of the DrawSetBorderColor method is:
   4641 %
   4642 %      void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
   4643 %
   4644 %  A description of each parameter follows:
   4645 %
   4646 %    o wand: the drawing wand.
   4647 %
   4648 %    o border_wand: border wand.
   4649 %
   4650 */
   4651 WandExport void DrawSetBorderColor(DrawingWand *wand,
   4652   const PixelWand *border_wand)
   4653 {
   4654   PixelInfo
   4655     *current_border,
   4656     border_color,
   4657     new_border;
   4658 
   4659   assert(wand != (DrawingWand *) NULL);
   4660   assert(wand->signature == MagickWandSignature);
   4661   if (wand->debug != MagickFalse)
   4662     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4663   assert(border_wand != (const PixelWand *) NULL);
   4664   PixelGetQuantumPacket(border_wand,&border_color);
   4665   new_border=border_color;
   4666   current_border=(&CurrentContext->border_color);
   4667   if ((wand->filter_off != MagickFalse) ||
   4668       (IsPixelInfoEquivalent(current_border,&new_border) == MagickFalse))
   4669     {
   4670       CurrentContext->border_color=new_border;
   4671       (void) MVGPrintf(wand,"border-color '");
   4672       MVGAppendColor(wand,&border_color);
   4673       (void) MVGPrintf(wand,"'\n");
   4674     }
   4675 }
   4676 
   4677 /*
   4679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4680 %                                                                             %
   4681 %                                                                             %
   4682 %                                                                             %
   4683 %   D r a w S e t C l i p P a t h                                             %
   4684 %                                                                             %
   4685 %                                                                             %
   4686 %                                                                             %
   4687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4688 %
   4689 %  DrawSetClipPath() associates a named clipping path with the image.  Only
   4690 %  the areas drawn on by the clipping path will be modified as ssize_t as it
   4691 %  remains in effect.
   4692 %
   4693 %  The format of the DrawSetClipPath method is:
   4694 %
   4695 %      MagickBooleanType DrawSetClipPath(DrawingWand *wand,
   4696 %        const char *clip_mask)
   4697 %
   4698 %  A description of each parameter follows:
   4699 %
   4700 %    o wand: the drawing wand.
   4701 %
   4702 %    o clip_mask: name of clipping path to associate with image
   4703 %
   4704 */
   4705 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
   4706   const char *clip_mask)
   4707 {
   4708   assert(wand != (DrawingWand *) NULL);
   4709   if (wand->debug != MagickFalse)
   4710     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
   4711   assert(wand->signature == MagickWandSignature);
   4712   assert(clip_mask != (const char *) NULL);
   4713   if ((CurrentContext->clip_mask == (const char *) NULL) ||
   4714       (wand->filter_off != MagickFalse) ||
   4715       (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
   4716     {
   4717       (void) CloneString(&CurrentContext->clip_mask,clip_mask);
   4718 #if DRAW_BINARY_IMPLEMENTATION
   4719       if (wand->image == (Image *) NULL)
   4720         ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   4721       (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask,
   4722         wand->exception);
   4723 #endif
   4724       (void) MVGPrintf(wand,"clip-path url(#%s)\n",clip_mask);
   4725     }
   4726   return(MagickTrue);
   4727 }
   4728 
   4729 /*
   4731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4732 %                                                                             %
   4733 %                                                                             %
   4734 %                                                                             %
   4735 %   D r a w S e t C l i p R u l e                                             %
   4736 %                                                                             %
   4737 %                                                                             %
   4738 %                                                                             %
   4739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4740 %
   4741 %  DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
   4742 %
   4743 %  The format of the DrawSetClipRule method is:
   4744 %
   4745 %      void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
   4746 %
   4747 %  A description of each parameter follows:
   4748 %
   4749 %    o wand: the drawing wand.
   4750 %
   4751 %    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
   4752 %
   4753 */
   4754 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
   4755 {
   4756   assert(wand != (DrawingWand *) NULL);
   4757   assert(wand->signature == MagickWandSignature);
   4758   if (wand->debug != MagickFalse)
   4759     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4760   if ((wand->filter_off != MagickFalse) ||
   4761       (CurrentContext->fill_rule != fill_rule))
   4762     {
   4763       CurrentContext->fill_rule=fill_rule;
   4764       (void) MVGPrintf(wand, "clip-rule '%s'\n",CommandOptionToMnemonic(
   4765         MagickFillRuleOptions,(ssize_t) fill_rule));
   4766     }
   4767 }
   4768 
   4769 /*
   4771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4772 %                                                                             %
   4773 %                                                                             %
   4774 %                                                                             %
   4775 %   D r a w S e t C l i p U n i t s                                           %
   4776 %                                                                             %
   4777 %                                                                             %
   4778 %                                                                             %
   4779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4780 %
   4781 %  DrawSetClipUnits() sets the interpretation of clip path units.
   4782 %
   4783 %  The format of the DrawSetClipUnits method is:
   4784 %
   4785 %      void DrawSetClipUnits(DrawingWand *wand,
   4786 %        const ClipPathUnits clip_units)
   4787 %
   4788 %  A description of each parameter follows:
   4789 %
   4790 %    o wand: the drawing wand.
   4791 %
   4792 %    o clip_units: units to use (UserSpace, UserSpaceOnUse, or
   4793 %      ObjectBoundingBox)
   4794 %
   4795 */
   4796 WandExport void DrawSetClipUnits(DrawingWand *wand,
   4797   const ClipPathUnits clip_units)
   4798 {
   4799   assert(wand != (DrawingWand *) NULL);
   4800   assert(wand->signature == MagickWandSignature);
   4801   if (wand->debug != MagickFalse)
   4802     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4803   if ((wand->filter_off != MagickFalse) ||
   4804       (CurrentContext->clip_units != clip_units))
   4805     {
   4806       CurrentContext->clip_units=clip_units;
   4807       if (clip_units == ObjectBoundingBox)
   4808         {
   4809           AffineMatrix
   4810             affine;
   4811 
   4812           GetAffineMatrix(&affine);
   4813           affine.sx=CurrentContext->bounds.x2;
   4814           affine.sy=CurrentContext->bounds.y2;
   4815           affine.tx=CurrentContext->bounds.x1;
   4816           affine.ty=CurrentContext->bounds.y1;
   4817           AdjustAffine(wand,&affine);
   4818         }
   4819       (void) MVGPrintf(wand, "clip-units '%s'\n",CommandOptionToMnemonic(
   4820         MagickClipPathOptions,(ssize_t) clip_units));
   4821     }
   4822 }
   4823 
   4824 /*
   4826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4827 %                                                                             %
   4828 %                                                                             %
   4829 %                                                                             %
   4830 %   D r a w S e t D e n s i t y                                               %
   4831 %                                                                             %
   4832 %                                                                             %
   4833 %                                                                             %
   4834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4835 %
   4836 %  DrawSetDensity() sets the vertical and horizontal resolution.
   4837 %
   4838 %  The format of the DrawSetDensity method is:
   4839 %
   4840 %      MagickBooleanType DrawSetDensity(DrawingWand *wand,
   4841 %        const char *density)
   4842 %
   4843 %  A description of each parameter follows:
   4844 %
   4845 %    o wand: the drawing wand.
   4846 %
   4847 %    o density: the vertical and horizontal resolution.
   4848 %
   4849 */
   4850 WandExport MagickBooleanType DrawSetDensity(DrawingWand *wand,
   4851   const char *density)
   4852 {
   4853   assert(wand != (DrawingWand *) NULL);
   4854   if (wand->debug != MagickFalse)
   4855     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",density);
   4856   assert(wand->signature == MagickWandSignature);
   4857   assert(density != (const char *) NULL);
   4858   if ((CurrentContext->density == (const char *) NULL) ||
   4859       (wand->filter_off != MagickFalse) ||
   4860       (LocaleCompare(CurrentContext->density,density) != 0))
   4861     {
   4862       (void) CloneString(&CurrentContext->density,density);
   4863       (void) MVGPrintf(wand,"density '%s'\n",density);
   4864     }
   4865   return(MagickTrue);
   4866 }
   4867 
   4868 /*
   4869 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4870 %                                                                             %
   4871 %                                                                             %
   4872 %                                                                             %
   4873 %   D r a w S e t F i l l C o l o r                                           %
   4874 %                                                                             %
   4875 %                                                                             %
   4876 %                                                                             %
   4877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4878 %
   4879 %  DrawSetFillColor() sets the fill color to be used for drawing filled objects.
   4880 %
   4881 %  The format of the DrawSetFillColor method is:
   4882 %
   4883 %      void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
   4884 %
   4885 %  A description of each parameter follows:
   4886 %
   4887 %    o wand: the drawing wand.
   4888 %
   4889 %    o fill_wand: fill wand.
   4890 %
   4891 */
   4892 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
   4893 {
   4894   PixelInfo
   4895     *current_fill,
   4896     fill_color,
   4897     new_fill;
   4898 
   4899   assert(wand != (DrawingWand *) NULL);
   4900   assert(wand->signature == MagickWandSignature);
   4901   if (wand->debug != MagickFalse)
   4902     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4903   assert(fill_wand != (const PixelWand *) NULL);
   4904   PixelGetQuantumPacket(fill_wand,&fill_color);
   4905   new_fill=fill_color;
   4906   current_fill=(&CurrentContext->fill);
   4907   if ((wand->filter_off != MagickFalse) ||
   4908       (IsPixelInfoEquivalent(current_fill,&new_fill) == MagickFalse))
   4909     {
   4910       CurrentContext->fill=new_fill;
   4911       (void) MVGPrintf(wand,"fill '");
   4912       MVGAppendColor(wand,&fill_color);
   4913       (void) MVGPrintf(wand,"'\n");
   4914     }
   4915 }
   4916 
   4917 /*
   4919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4920 %                                                                             %
   4921 %                                                                             %
   4922 %                                                                             %
   4923 %   D r a w S e t F i l l O p a c i t y                                       %
   4924 %                                                                             %
   4925 %                                                                             %
   4926 %                                                                             %
   4927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4928 %
   4929 %  DrawSetFillOpacity() sets the alpha to use when drawing using the fill
   4930 %  color or fill texture.  Fully opaque is 1.0.
   4931 %
   4932 %  The format of the DrawSetFillOpacity method is:
   4933 %
   4934 %      void DrawSetFillOpacity(DrawingWand *wand,const double fill_alpha)
   4935 %
   4936 %  A description of each parameter follows:
   4937 %
   4938 %    o wand: the drawing wand.
   4939 %
   4940 %    o fill_opacity: fill opacity
   4941 %
   4942 */
   4943 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
   4944 {
   4945   double
   4946     alpha;
   4947 
   4948   assert(wand != (DrawingWand *) NULL);
   4949   assert(wand->signature == MagickWandSignature);
   4950   if (wand->debug != MagickFalse)
   4951     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4952   alpha=(double) ClampToQuantum(QuantumRange*fill_opacity);
   4953   if ((wand->filter_off != MagickFalse) ||
   4954       (CurrentContext->fill.alpha != alpha))
   4955     {
   4956       CurrentContext->fill.alpha=alpha;
   4957       (void) MVGPrintf(wand,"fill-opacity %.20g\n",fill_opacity);
   4958     }
   4959 }
   4960 
   4961 /*
   4963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4964 %                                                                             %
   4965 %                                                                             %
   4966 %                                                                             %
   4967 %   D r a w S e t F o n t R e s o l u t i o n                                 %
   4968 %                                                                             %
   4969 %                                                                             %
   4970 %                                                                             %
   4971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4972 %
   4973 %  DrawSetFontResolution() sets the image resolution.
   4974 %
   4975 %  The format of the DrawSetFontResolution method is:
   4976 %
   4977 %      MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
   4978 %        const double x_resolution,const double y_resolution)
   4979 %
   4980 %  A description of each parameter follows:
   4981 %
   4982 %    o wand: the magick wand.
   4983 %
   4984 %    o x_resolution: the image x resolution.
   4985 %
   4986 %    o y_resolution: the image y resolution.
   4987 %
   4988 */
   4989 WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
   4990   const double x_resolution,const double y_resolution)
   4991 {
   4992   char
   4993     density[MagickPathExtent];
   4994 
   4995   assert(wand != (DrawingWand *) NULL);
   4996   assert(wand->signature == MagickWandSignature);
   4997   if (wand->debug != MagickFalse)
   4998     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4999   (void) FormatLocaleString(density,MagickPathExtent,"%.20gx%.20g",x_resolution,
   5000     y_resolution);
   5001   (void) CloneString(&CurrentContext->density,density);
   5002   return(MagickTrue);
   5003 }
   5004 
   5005 /*
   5007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5008 %                                                                             %
   5009 %                                                                             %
   5010 %                                                                             %
   5011 %   D r a w S e t O p a c i t y                                               %
   5012 %                                                                             %
   5013 %                                                                             %
   5014 %                                                                             %
   5015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5016 %
   5017 %  DrawSetOpacity() sets the alpha to use when drawing using the fill or
   5018 %  stroke color or texture.  Fully opaque is 1.0.
   5019 %
   5020 %  The format of the DrawSetOpacity method is:
   5021 %
   5022 %      void DrawSetOpacity(DrawingWand *wand,const double alpha)
   5023 %
   5024 %  A description of each parameter follows:
   5025 %
   5026 %    o wand: the drawing wand.
   5027 %
   5028 %    o opacity: fill and stroke opacity.  The value 1.0 is opaque.
   5029 %
   5030 */
   5031 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
   5032 {
   5033   Quantum
   5034     quantum_alpha;
   5035 
   5036   assert(wand != (DrawingWand *) NULL);
   5037   assert(wand->signature == MagickWandSignature);
   5038   if (wand->debug != MagickFalse)
   5039     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5040   quantum_alpha=ClampToQuantum(QuantumRange*opacity);
   5041   if ((wand->filter_off != MagickFalse) ||
   5042       (CurrentContext->alpha != quantum_alpha))
   5043     {
   5044       CurrentContext->alpha=quantum_alpha;
   5045       (void) MVGPrintf(wand,"opacity %.20g\n",opacity);
   5046     }
   5047 }
   5048 
   5049 /*
   5051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5052 %                                                                             %
   5053 %                                                                             %
   5054 %                                                                             %
   5055 %   D r a w S e t F i l l P a t t e r n U R L                                 %
   5056 %                                                                             %
   5057 %                                                                             %
   5058 %                                                                             %
   5059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5060 %
   5061 %  DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
   5062 %  objects. Only local URLs ("#identifier") are supported at this time. These
   5063 %  local URLs are normally created by defining a named fill pattern with
   5064 %  DrawPushPattern/DrawPopPattern.
   5065 %
   5066 %  The format of the DrawSetFillPatternURL method is:
   5067 %
   5068 %      MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
   5069 %        const char *fill_url)
   5070 %
   5071 %  A description of each parameter follows:
   5072 %
   5073 %    o wand: the drawing wand.
   5074 %
   5075 %    o fill_url: URL to use to obtain fill pattern.
   5076 %
   5077 */
   5078 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
   5079   const char *fill_url)
   5080 {
   5081   char
   5082     pattern[MagickPathExtent],
   5083     pattern_spec[MagickPathExtent];
   5084 
   5085   assert(wand != (DrawingWand *) NULL);
   5086   assert(wand->signature == MagickWandSignature);
   5087   if (wand->debug != MagickFalse)
   5088     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
   5089   if (wand->image == (Image *) NULL)
   5090     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   5091   assert(fill_url != (const char *) NULL);
   5092   if (*fill_url != '#')
   5093     {
   5094       ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
   5095       return(MagickFalse);
   5096     }
   5097   (void) FormatLocaleString(pattern,MagickPathExtent,"%s",fill_url+1);
   5098   if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
   5099     {
   5100       ThrowDrawException(DrawError,"URLNotFound",fill_url)
   5101       return(MagickFalse);
   5102     }
   5103   (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",fill_url);
   5104 #if DRAW_BINARY_IMPLEMENTATION
   5105   DrawPatternPath(wand->image,CurrentContext,pattern_spec,
   5106     &CurrentContext->fill_pattern);
   5107 #endif
   5108   if (CurrentContext->fill.alpha != (Quantum) TransparentAlpha)
   5109     CurrentContext->fill.alpha=(double) CurrentContext->alpha;
   5110   (void) MVGPrintf(wand,"fill %s\n",pattern_spec);
   5111   return(MagickTrue);
   5112 }
   5113 
   5114 /*
   5116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5117 %                                                                             %
   5118 %                                                                             %
   5119 %                                                                             %
   5120 %   D r a w S e t F i l l R u l e                                             %
   5121 %                                                                             %
   5122 %                                                                             %
   5123 %                                                                             %
   5124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5125 %
   5126 %  DrawSetFillRule() sets the fill rule to use while drawing polygons.
   5127 %
   5128 %  The format of the DrawSetFillRule method is:
   5129 %
   5130 %      void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
   5131 %
   5132 %  A description of each parameter follows:
   5133 %
   5134 %    o wand: the drawing wand.
   5135 %
   5136 %    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
   5137 %
   5138 */
   5139 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
   5140 {
   5141   assert(wand != (DrawingWand *) NULL);
   5142   assert(wand->signature == MagickWandSignature);
   5143   if (wand->debug != MagickFalse)
   5144     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5145   if ((wand->filter_off != MagickFalse) ||
   5146       (CurrentContext->fill_rule != fill_rule))
   5147     {
   5148       CurrentContext->fill_rule=fill_rule;
   5149       (void) MVGPrintf(wand, "fill-rule '%s'\n",CommandOptionToMnemonic(
   5150         MagickFillRuleOptions,(ssize_t) fill_rule));
   5151     }
   5152 }
   5153 
   5154 /*
   5156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5157 %                                                                             %
   5158 %                                                                             %
   5159 %                                                                             %
   5160 %   D r a w S e t F o n t                                                     %
   5161 %                                                                             %
   5162 %                                                                             %
   5163 %                                                                             %
   5164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5165 %
   5166 %  DrawSetFont() sets the fully-sepecified font to use when annotating with
   5167 %  text.
   5168 %
   5169 %  The format of the DrawSetFont method is:
   5170 %
   5171 %      MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
   5172 %
   5173 %  A description of each parameter follows:
   5174 %
   5175 %    o wand: the drawing wand.
   5176 %
   5177 %    o font_name: font name
   5178 %
   5179 */
   5180 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
   5181   const char *font_name)
   5182 {
   5183   assert(wand != (DrawingWand *) NULL);
   5184   assert(wand->signature == MagickWandSignature);
   5185   if (wand->debug != MagickFalse)
   5186     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5187   assert(font_name != (const char *) NULL);
   5188   if ((wand->filter_off != MagickFalse) ||
   5189       (CurrentContext->font == (char *) NULL) ||
   5190       (LocaleCompare(CurrentContext->font,font_name) != 0))
   5191     {
   5192       (void) CloneString(&CurrentContext->font,font_name);
   5193       (void) MVGPrintf(wand,"font '%s'\n",font_name);
   5194     }
   5195   return(MagickTrue);
   5196 }
   5197 
   5198 /*
   5200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5201 %                                                                             %
   5202 %                                                                             %
   5203 %                                                                             %
   5204 %   D r a w S e t F o n t F a m i l y                                         %
   5205 %                                                                             %
   5206 %                                                                             %
   5207 %                                                                             %
   5208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5209 %
   5210 %  DrawSetFontFamily() sets the font family to use when annotating with text.
   5211 %
   5212 %  The format of the DrawSetFontFamily method is:
   5213 %
   5214 %      MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
   5215 %        const char *font_family)
   5216 %
   5217 %  A description of each parameter follows:
   5218 %
   5219 %    o wand: the drawing wand.
   5220 %
   5221 %    o font_family: font family
   5222 %
   5223 */
   5224 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
   5225   const char *font_family)
   5226 {
   5227   assert(wand != (DrawingWand *) NULL);
   5228   assert(wand->signature == MagickWandSignature);
   5229   if (wand->debug != MagickFalse)
   5230     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5231   assert(font_family != (const char *) NULL);
   5232   if ((wand->filter_off != MagickFalse) ||
   5233       (CurrentContext->family == (const char *) NULL) ||
   5234       (LocaleCompare(CurrentContext->family,font_family) != 0))
   5235     {
   5236       (void) CloneString(&CurrentContext->family,font_family);
   5237       (void) MVGPrintf(wand,"font-family '%s'\n",font_family);
   5238     }
   5239   return(MagickTrue);
   5240 }
   5241 
   5242 /*
   5244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5245 %                                                                             %
   5246 %                                                                             %
   5247 %                                                                             %
   5248 %   D r a w S e t F o n t S i z e                                             %
   5249 %                                                                             %
   5250 %                                                                             %
   5251 %                                                                             %
   5252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5253 %
   5254 %  DrawSetFontSize() sets the font pointsize to use when annotating with text.
   5255 %
   5256 %  The format of the DrawSetFontSize method is:
   5257 %
   5258 %      void DrawSetFontSize(DrawingWand *wand,const double pointsize)
   5259 %
   5260 %  A description of each parameter follows:
   5261 %
   5262 %    o wand: the drawing wand.
   5263 %
   5264 %    o pointsize: text pointsize
   5265 %
   5266 */
   5267 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
   5268 {
   5269   assert(wand != (DrawingWand *) NULL);
   5270   assert(wand->signature == MagickWandSignature);
   5271   if (wand->debug != MagickFalse)
   5272     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5273   if ((wand->filter_off != MagickFalse) ||
   5274       (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon))
   5275     {
   5276       CurrentContext->pointsize=pointsize;
   5277       (void) MVGPrintf(wand,"font-size %.20g\n",pointsize);
   5278     }
   5279 }
   5280 
   5281 /*
   5283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5284 %                                                                             %
   5285 %                                                                             %
   5286 %                                                                             %
   5287 %   D r a w S e t F o n t S t r e t c h                                       %
   5288 %                                                                             %
   5289 %                                                                             %
   5290 %                                                                             %
   5291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5292 %
   5293 %  DrawSetFontStretch() sets the font stretch to use when annotating with text.
   5294 %  The AnyStretch enumeration acts as a wild-card "don't care" option.
   5295 %
   5296 %  The format of the DrawSetFontStretch method is:
   5297 %
   5298 %      void DrawSetFontStretch(DrawingWand *wand,
   5299 %        const StretchType font_stretch)
   5300 %
   5301 %  A description of each parameter follows:
   5302 %
   5303 %    o wand: the drawing wand.
   5304 %
   5305 %    o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
   5306 %                    CondensedStretch, SemiCondensedStretch,
   5307 %                    SemiExpandedStretch, ExpandedStretch,
   5308 %                    ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
   5309 %
   5310 */
   5311 WandExport void DrawSetFontStretch(DrawingWand *wand,
   5312   const StretchType font_stretch)
   5313 {
   5314   assert(wand != (DrawingWand *) NULL);
   5315   assert(wand->signature == MagickWandSignature);
   5316   if (wand->debug != MagickFalse)
   5317     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5318   if ((wand->filter_off != MagickFalse) ||
   5319       (CurrentContext->stretch != font_stretch))
   5320     {
   5321       CurrentContext->stretch=font_stretch;
   5322       (void) MVGPrintf(wand, "font-stretch '%s'\n",CommandOptionToMnemonic(
   5323         MagickStretchOptions,(ssize_t) font_stretch));
   5324     }
   5325 }
   5326 
   5327 /*
   5329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5330 %                                                                             %
   5331 %                                                                             %
   5332 %                                                                             %
   5333 %   D r a w S e t F o n t S t y l e                                           %
   5334 %                                                                             %
   5335 %                                                                             %
   5336 %                                                                             %
   5337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5338 %
   5339 %  DrawSetFontStyle() sets the font style to use when annotating with text.
   5340 %  The AnyStyle enumeration acts as a wild-card "don't care" option.
   5341 %
   5342 %  The format of the DrawSetFontStyle method is:
   5343 %
   5344 %      void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
   5345 %
   5346 %  A description of each parameter follows:
   5347 %
   5348 %    o wand: the drawing wand.
   5349 %
   5350 %    o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
   5351 %
   5352 */
   5353 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
   5354 {
   5355   assert(wand != (DrawingWand *) NULL);
   5356   assert(wand->signature == MagickWandSignature);
   5357   if (wand->debug != MagickFalse)
   5358     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5359   if ((wand->filter_off != MagickFalse) ||
   5360       (CurrentContext->style != style))
   5361     {
   5362       CurrentContext->style=style;
   5363       (void) MVGPrintf(wand, "font-style '%s'\n",CommandOptionToMnemonic(
   5364         MagickStyleOptions,(ssize_t) style));
   5365     }
   5366 }
   5367 
   5368 /*
   5370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5371 %                                                                             %
   5372 %                                                                             %
   5373 %                                                                             %
   5374 %   D r a w S e t F o n t W e i g h t                                         %
   5375 %                                                                             %
   5376 %                                                                             %
   5377 %                                                                             %
   5378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5379 %
   5380 %  DrawSetFontWeight() sets the font weight to use when annotating with text.
   5381 %
   5382 %  The format of the DrawSetFontWeight method is:
   5383 %
   5384 %      void DrawSetFontWeight(DrawingWand *wand,
   5385 %        const size_t font_weight)
   5386 %
   5387 %  A description of each parameter follows:
   5388 %
   5389 %    o wand: the drawing wand.
   5390 %
   5391 %    o font_weight: font weight (valid range 100-900)
   5392 %
   5393 */
   5394 WandExport void DrawSetFontWeight(DrawingWand *wand,
   5395   const size_t font_weight)
   5396 {
   5397   assert(wand != (DrawingWand *) NULL);
   5398   assert(wand->signature == MagickWandSignature);
   5399   if (wand->debug != MagickFalse)
   5400     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5401   if ((wand->filter_off != MagickFalse) ||
   5402       (CurrentContext->weight != font_weight))
   5403     {
   5404       CurrentContext->weight=font_weight;
   5405       (void) MVGPrintf(wand,"font-weight %.20g\n",(double) font_weight);
   5406     }
   5407 }
   5408 
   5409 /*
   5411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5412 %                                                                             %
   5413 %                                                                             %
   5414 %                                                                             %
   5415 %   D r a w S e t G r a v i t y                                               %
   5416 %                                                                             %
   5417 %                                                                             %
   5418 %                                                                             %
   5419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5420 %
   5421 %  DrawSetGravity() sets the text placement gravity to use when annotating
   5422 %  with text.
   5423 %
   5424 %  The format of the DrawSetGravity method is:
   5425 %
   5426 %      void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
   5427 %
   5428 %  A description of each parameter follows:
   5429 %
   5430 %    o wand: the drawing wand.
   5431 %
   5432 %    o gravity: positioning gravity (NorthWestGravity, NorthGravity,
   5433 %               NorthEastGravity, WestGravity, CenterGravity,
   5434 %               EastGravity, SouthWestGravity, SouthGravity,
   5435 %               SouthEastGravity)
   5436 %
   5437 */
   5438 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
   5439 {
   5440   assert(wand != (DrawingWand *) NULL);
   5441   assert(wand->signature == MagickWandSignature);
   5442   if (wand->debug != MagickFalse)
   5443     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5444   if ((wand->filter_off != MagickFalse) ||
   5445       (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
   5446     {
   5447       CurrentContext->gravity=gravity;
   5448       (void) MVGPrintf(wand,"gravity '%s'\n",CommandOptionToMnemonic(
   5449         MagickGravityOptions,(ssize_t) gravity));
   5450     }
   5451 }
   5452 
   5453 /*
   5455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5456 %                                                                             %
   5457 %                                                                             %
   5458 %                                                                             %
   5459 %   D r a w S e t S t r o k e C o l o r                                       %
   5460 %                                                                             %
   5461 %                                                                             %
   5462 %                                                                             %
   5463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5464 %
   5465 %  DrawSetStrokeColor() sets the color used for stroking object outlines.
   5466 %
   5467 %  The format of the DrawSetStrokeColor method is:
   5468 %
   5469 %      void DrawSetStrokeColor(DrawingWand *wand,
   5470 %        const PixelWand *stroke_wand)
   5471 %
   5472 %  A description of each parameter follows:
   5473 %
   5474 %    o wand: the drawing wand.
   5475 %
   5476 %    o stroke_wand: stroke wand.
   5477 %
   5478 */
   5479 WandExport void DrawSetStrokeColor(DrawingWand *wand,
   5480   const PixelWand *stroke_wand)
   5481 {
   5482   PixelInfo
   5483     *current_stroke,
   5484     new_stroke,
   5485     stroke_color;
   5486 
   5487   assert(wand != (DrawingWand *) NULL);
   5488   assert(wand->signature == MagickWandSignature);
   5489   if (wand->debug != MagickFalse)
   5490     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5491   assert(stroke_wand != (const PixelWand *) NULL);
   5492   PixelGetQuantumPacket(stroke_wand,&stroke_color);
   5493   new_stroke=stroke_color;
   5494   current_stroke=(&CurrentContext->stroke);
   5495   if ((wand->filter_off != MagickFalse) ||
   5496       (IsPixelInfoEquivalent(current_stroke,&new_stroke) == MagickFalse))
   5497     {
   5498       CurrentContext->stroke=new_stroke;
   5499       (void) MVGPrintf(wand,"stroke '");
   5500       MVGAppendColor(wand,&stroke_color);
   5501       (void) MVGPrintf(wand,"'\n");
   5502     }
   5503 }
   5504 
   5505 /*
   5507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5508 %                                                                             %
   5509 %                                                                             %
   5510 %                                                                             %
   5511 %   D r a w S e t S t r o k e P a t t e r n U R L                             %
   5512 %                                                                             %
   5513 %                                                                             %
   5514 %                                                                             %
   5515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5516 %
   5517 %  DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
   5518 %
   5519 %  The format of the DrawSetStrokePatternURL method is:
   5520 %
   5521 %      MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
   5522 %        const char *stroke_url)
   5523 %
   5524 %  A description of each parameter follows:
   5525 %
   5526 %    o wand: the drawing wand.
   5527 %
   5528 %    o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
   5529 %
   5530 */
   5531 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
   5532   const char *stroke_url)
   5533 {
   5534   char
   5535     pattern[MagickPathExtent],
   5536     pattern_spec[MagickPathExtent];
   5537 
   5538   assert(wand != (DrawingWand *) NULL);
   5539   assert(wand->signature == MagickWandSignature);
   5540   if (wand->debug != MagickFalse)
   5541     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5542   if (wand->image == (Image *) NULL)
   5543     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   5544   assert(stroke_url != NULL);
   5545   if (stroke_url[0] != '#')
   5546     ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
   5547   (void) FormatLocaleString(pattern,MagickPathExtent,"%s",stroke_url+1);
   5548   if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
   5549     {
   5550       ThrowDrawException(DrawError,"URLNotFound",stroke_url)
   5551       return(MagickFalse);
   5552     }
   5553   (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",stroke_url);
   5554 #if DRAW_BINARY_IMPLEMENTATION
   5555   DrawPatternPath(wand->image,CurrentContext,pattern_spec,
   5556     &CurrentContext->stroke_pattern);
   5557 #endif
   5558   if (CurrentContext->stroke.alpha != (Quantum) TransparentAlpha)
   5559     CurrentContext->stroke.alpha=(double) CurrentContext->alpha;
   5560   (void) MVGPrintf(wand,"stroke %s\n",pattern_spec);
   5561   return(MagickTrue);
   5562 }
   5563 
   5564 /*
   5566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5567 %                                                                             %
   5568 %                                                                             %
   5569 %                                                                             %
   5570 %   D r a w S e t S t r o k e A n t i a l i a s                               %
   5571 %                                                                             %
   5572 %                                                                             %
   5573 %                                                                             %
   5574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5575 %
   5576 %  DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
   5577 %  Stroked outlines are antialiased by default.  When antialiasing is disabled
   5578 %  stroked pixels are thresholded to determine if the stroke color or
   5579 %  underlying canvas color should be used.
   5580 %
   5581 %  The format of the DrawSetStrokeAntialias method is:
   5582 %
   5583 %      void DrawSetStrokeAntialias(DrawingWand *wand,
   5584 %        const MagickBooleanType stroke_antialias)
   5585 %
   5586 %  A description of each parameter follows:
   5587 %
   5588 %    o wand: the drawing wand.
   5589 %
   5590 %    o stroke_antialias: set to false (zero) to disable antialiasing
   5591 %
   5592 */
   5593 WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
   5594   const MagickBooleanType stroke_antialias)
   5595 {
   5596   assert(wand != (DrawingWand *) NULL);
   5597   assert(wand->signature == MagickWandSignature);
   5598   if (wand->debug != MagickFalse)
   5599     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5600   if ((wand->filter_off != MagickFalse) ||
   5601       (CurrentContext->stroke_antialias != stroke_antialias))
   5602     {
   5603       CurrentContext->stroke_antialias=stroke_antialias;
   5604       (void) MVGPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
   5605         1 : 0);
   5606     }
   5607 }
   5608 
   5609 /*
   5611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5612 %                                                                             %
   5613 %                                                                             %
   5614 %                                                                             %
   5615 %   D r a w S e t S t r o k e D a s h A r r a y                               %
   5616 %                                                                             %
   5617 %                                                                             %
   5618 %                                                                             %
   5619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5620 %
   5621 %  DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
   5622 %  stroke paths. The stroke dash array represents an array of numbers that
   5623 %  specify the lengths of alternating dashes and gaps in pixels. If an odd
   5624 %  number of values is provided, then the list of values is repeated to yield
   5625 %  an even number of values. To remove an existing dash array, pass a zero
   5626 %  number_elements argument and null dasharray.  A typical stroke dash array
   5627 %  might contain the members 5 3 2.
   5628 %
   5629 %  The format of the DrawSetStrokeDashArray method is:
   5630 %
   5631 %      MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
   5632 %        const size_t number_elements,const double *dasharray)
   5633 %
   5634 %  A description of each parameter follows:
   5635 %
   5636 %    o wand: the drawing wand.
   5637 %
   5638 %    o number_elements: number of elements in dash array
   5639 %
   5640 %    o dasharray: dash array values
   5641 %
   5642 */
   5643 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
   5644   const size_t number_elements,const double *dasharray)
   5645 {
   5646   MagickBooleanType
   5647     update;
   5648 
   5649   register const double
   5650     *p;
   5651 
   5652   register double
   5653     *q;
   5654 
   5655   register ssize_t
   5656     i;
   5657 
   5658   size_t
   5659     n_new,
   5660     n_old;
   5661 
   5662   assert(wand != (DrawingWand *) NULL);
   5663   assert(wand->signature == MagickWandSignature);
   5664   if (wand->debug != MagickFalse)
   5665     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5666   n_new=number_elements;
   5667   if (dasharray == (const double *) NULL)
   5668     n_new=0;
   5669   n_old=0;
   5670   update=MagickFalse;
   5671   q=CurrentContext->dash_pattern;
   5672   if (q != (const double *) NULL)
   5673     while (fabs(*q++) < MagickEpsilon)
   5674       n_old++;
   5675   if ((n_old == 0) && (n_new == 0))
   5676     update=MagickFalse;
   5677   else
   5678     if (n_old != n_new)
   5679       update=MagickTrue;
   5680     else
   5681       if ((CurrentContext->dash_pattern != (double *) NULL) &&
   5682           (dasharray != (double *) NULL))
   5683         {
   5684           p=dasharray;
   5685           q=CurrentContext->dash_pattern;
   5686           for (i=0; i < (ssize_t) n_new; i++)
   5687           {
   5688             if (fabs((*p)-(*q)) >= MagickEpsilon)
   5689               {
   5690                 update=MagickTrue;
   5691                 break;
   5692               }
   5693             p++;
   5694             q++;
   5695           }
   5696         }
   5697   if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
   5698     {
   5699       if (CurrentContext->dash_pattern != (double *) NULL)
   5700         CurrentContext->dash_pattern=(double *)
   5701           RelinquishMagickMemory(CurrentContext->dash_pattern);
   5702       if (n_new != 0)
   5703         {
   5704           CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
   5705             n_new+1UL,sizeof(*CurrentContext->dash_pattern));
   5706           if (CurrentContext->dash_pattern == (double *) NULL)
   5707             {
   5708               ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
   5709                 wand->name);
   5710               return(MagickFalse);
   5711             }
   5712           for (i=0; i < (ssize_t) n_new; i++)
   5713           {
   5714             CurrentContext->dash_pattern[i]=0.0;
   5715             if (dasharray != (double *) NULL)
   5716               CurrentContext->dash_pattern[i]=dasharray[i];
   5717           }
   5718           CurrentContext->dash_pattern[n_new]=0.0;
   5719         }
   5720       (void) MVGPrintf(wand,"stroke-dasharray ");
   5721       if (n_new == 0)
   5722         (void) MVGPrintf(wand,"none\n");
   5723       else
   5724         if (dasharray != (double *) NULL)
   5725           {
   5726             for (i=0; i < (ssize_t) n_new; i++)
   5727             {
   5728               if (i != 0)
   5729                 (void) MVGPrintf(wand,",");
   5730               (void) MVGPrintf(wand,"%.20g",dasharray[i]);
   5731             }
   5732             (void) MVGPrintf(wand,"\n");
   5733           }
   5734     }
   5735   return(MagickTrue);
   5736 }
   5737 
   5738 /*
   5740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5741 %                                                                             %
   5742 %                                                                             %
   5743 %                                                                             %
   5744 %   D r a w S e t S t r o k e D a s h O f f s e t                             %
   5745 %                                                                             %
   5746 %                                                                             %
   5747 %                                                                             %
   5748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5749 %
   5750 %  DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
   5751 %  start the dash.
   5752 %
   5753 %  The format of the DrawSetStrokeDashOffset method is:
   5754 %
   5755 %      void DrawSetStrokeDashOffset(DrawingWand *wand,
   5756 %        const double dash_offset)
   5757 %
   5758 %  A description of each parameter follows:
   5759 %
   5760 %    o wand: the drawing wand.
   5761 %
   5762 %    o dash_offset: dash offset
   5763 %
   5764 */
   5765 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
   5766   const double dash_offset)
   5767 {
   5768   assert(wand != (DrawingWand *) NULL);
   5769   assert(wand->signature == MagickWandSignature);
   5770   if (wand->debug != MagickFalse)
   5771     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5772   if ((wand->filter_off != MagickFalse) ||
   5773      (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon))
   5774     {
   5775       CurrentContext->dash_offset=dash_offset;
   5776       (void) MVGPrintf(wand,"stroke-dashoffset %.20g\n",dash_offset);
   5777     }
   5778 }
   5779 
   5780 /*
   5782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5783 %                                                                             %
   5784 %                                                                             %
   5785 %                                                                             %
   5786 %   D r a w S e t S t r o k e L i n e C a p                                   %
   5787 %                                                                             %
   5788 %                                                                             %
   5789 %                                                                             %
   5790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5791 %
   5792 %  DrawSetStrokeLineCap() specifies the shape to be used at the end of
   5793 %  open subpaths when they are stroked. Values of LineCap are
   5794 %  UndefinedCap, ButtCap, RoundCap, and SquareCap.
   5795 %
   5796 %  The format of the DrawSetStrokeLineCap method is:
   5797 %
   5798 %      void DrawSetStrokeLineCap(DrawingWand *wand,
   5799 %        const LineCap linecap)
   5800 %
   5801 %  A description of each parameter follows:
   5802 %
   5803 %    o wand: the drawing wand.
   5804 %
   5805 %    o linecap: linecap style
   5806 %
   5807 */
   5808 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
   5809 {
   5810   assert(wand != (DrawingWand *) NULL);
   5811   assert(wand->signature == MagickWandSignature);
   5812   if (wand->debug != MagickFalse)
   5813     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5814   if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap))
   5815     {
   5816       CurrentContext->linecap=linecap;
   5817       (void) MVGPrintf(wand,"stroke-linecap '%s'\n",CommandOptionToMnemonic(
   5818         MagickLineCapOptions,(ssize_t) linecap));
   5819     }
   5820 }
   5821 
   5822 /*
   5824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5825 %                                                                             %
   5826 %                                                                             %
   5827 %                                                                             %
   5828 %   D r a w S e t S t r o k e L i n e J o i n                                 %
   5829 %                                                                             %
   5830 %                                                                             %
   5831 %                                                                             %
   5832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5833 %
   5834 %  DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
   5835 %  paths (or other vector shapes) when they are stroked. Values of LineJoin are
   5836 %  UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
   5837 %
   5838 %  The format of the DrawSetStrokeLineJoin method is:
   5839 %
   5840 %      void DrawSetStrokeLineJoin(DrawingWand *wand,
   5841 %        const LineJoin linejoin)
   5842 %
   5843 %  A description of each parameter follows:
   5844 %
   5845 %    o wand: the drawing wand.
   5846 %
   5847 %    o linejoin: line join style
   5848 %
   5849 */
   5850 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
   5851 {
   5852   assert(wand != (DrawingWand *) NULL);
   5853   assert(wand->signature == MagickWandSignature);
   5854   if (wand->debug != MagickFalse)
   5855     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5856   if ((wand->filter_off != MagickFalse) ||
   5857       (CurrentContext->linejoin != linejoin))
   5858     {
   5859       CurrentContext->linejoin=linejoin;
   5860       (void) MVGPrintf(wand, "stroke-linejoin '%s'\n",CommandOptionToMnemonic(
   5861         MagickLineJoinOptions,(ssize_t) linejoin));
   5862     }
   5863 }
   5864 
   5865 /*
   5867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5868 %                                                                             %
   5869 %                                                                             %
   5870 %                                                                             %
   5871 %   D r a w S e t S t r o k e M i t e r L i m i t                             %
   5872 %                                                                             %
   5873 %                                                                             %
   5874 %                                                                             %
   5875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5876 %
   5877 %  DrawSetStrokeMiterLimit() specifies the miter limit. When two line
   5878 %  segments meet at a sharp angle and miter joins have been specified for
   5879 %  'lineJoin', it is possible for the miter to extend far beyond the
   5880 %  thickness of the line stroking the path. The miterLimit' imposes a
   5881 %  limit on the ratio of the miter length to the 'lineWidth'.
   5882 %
   5883 %  The format of the DrawSetStrokeMiterLimit method is:
   5884 %
   5885 %      void DrawSetStrokeMiterLimit(DrawingWand *wand,
   5886 %        const size_t miterlimit)
   5887 %
   5888 %  A description of each parameter follows:
   5889 %
   5890 %    o wand: the drawing wand.
   5891 %
   5892 %    o miterlimit: miter limit
   5893 %
   5894 */
   5895 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
   5896   const size_t miterlimit)
   5897 {
   5898   assert(wand != (DrawingWand *) NULL);
   5899   assert(wand->signature == MagickWandSignature);
   5900   if (wand->debug != MagickFalse)
   5901     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5902   if (CurrentContext->miterlimit != miterlimit)
   5903     {
   5904       CurrentContext->miterlimit=miterlimit;
   5905       (void) MVGPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit);
   5906     }
   5907 }
   5908 
   5909 /*
   5911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5912 %                                                                             %
   5913 %                                                                             %
   5914 %                                                                             %
   5915 %   D r a w S e t S t r o k e O p a c i t y                                   %
   5916 %                                                                             %
   5917 %                                                                             %
   5918 %                                                                             %
   5919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5920 %
   5921 %  DrawSetStrokeOpacity() specifies the alpha of stroked object outlines.
   5922 %
   5923 %  The format of the DrawSetStrokeOpacity method is:
   5924 %
   5925 %      void DrawSetStrokeOpacity(DrawingWand *wand,
   5926 %        const double stroke_alpha)
   5927 %
   5928 %  A description of each parameter follows:
   5929 %
   5930 %    o wand: the drawing wand.
   5931 %
   5932 %    o opacity: stroke opacity.  The value 1.0 is opaque.
   5933 %
   5934 */
   5935 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
   5936   const double opacity)
   5937 {
   5938   double
   5939     alpha;
   5940 
   5941   assert(wand != (DrawingWand *) NULL);
   5942   assert(wand->signature == MagickWandSignature);
   5943   if (wand->debug != MagickFalse)
   5944     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5945   alpha=(double) ClampToQuantum(QuantumRange*opacity);
   5946   if ((wand->filter_off != MagickFalse) ||
   5947       (CurrentContext->stroke.alpha != alpha))
   5948     {
   5949       CurrentContext->stroke.alpha=alpha;
   5950       (void) MVGPrintf(wand,"stroke-opacity %.20g\n",opacity);
   5951     }
   5952 }
   5953 
   5954 /*
   5956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5957 %                                                                             %
   5958 %                                                                             %
   5959 %                                                                             %
   5960 %   D r a w S e t S t r o k e W i d t h                                       %
   5961 %                                                                             %
   5962 %                                                                             %
   5963 %                                                                             %
   5964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5965 %
   5966 %  DrawSetStrokeWidth() sets the width of the stroke used to draw object
   5967 %  outlines.
   5968 %
   5969 %  The format of the DrawSetStrokeWidth method is:
   5970 %
   5971 %      void DrawSetStrokeWidth(DrawingWand *wand,
   5972 %        const double stroke_width)
   5973 %
   5974 %  A description of each parameter follows:
   5975 %
   5976 %    o wand: the drawing wand.
   5977 %
   5978 %    o stroke_width: stroke width
   5979 %
   5980 */
   5981 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
   5982 {
   5983   assert(wand != (DrawingWand *) NULL);
   5984   assert(wand->signature == MagickWandSignature);
   5985   if (wand->debug != MagickFalse)
   5986     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5987   if ((wand->filter_off != MagickFalse) ||
   5988       (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon))
   5989     {
   5990       CurrentContext->stroke_width=stroke_width;
   5991       (void) MVGPrintf(wand,"stroke-width %.20g\n",stroke_width);
   5992     }
   5993 }
   5994 
   5995 /*
   5997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5998 %                                                                             %
   5999 %                                                                             %
   6000 %                                                                             %
   6001 %   D r a w S e t T e x t A l i g n m e n t                                   %
   6002 %                                                                             %
   6003 %                                                                             %
   6004 %                                                                             %
   6005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6006 %
   6007 %  DrawSetTextAlignment() specifies a text alignment to be applied when
   6008 %  annotating with text.
   6009 %
   6010 %  The format of the DrawSetTextAlignment method is:
   6011 %
   6012 %      void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
   6013 %
   6014 %  A description of each parameter follows:
   6015 %
   6016 %    o wand: the drawing wand.
   6017 %
   6018 %    o alignment: text alignment.  One of UndefinedAlign, LeftAlign,
   6019 %      CenterAlign, or RightAlign.
   6020 %
   6021 */
   6022 WandExport void DrawSetTextAlignment(DrawingWand *wand,
   6023   const AlignType alignment)
   6024 {
   6025   assert(wand != (DrawingWand *) NULL);
   6026   assert(wand->signature == MagickWandSignature);
   6027   if (wand->debug != MagickFalse)
   6028     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6029   if ((wand->filter_off != MagickFalse) ||
   6030       (CurrentContext->align != alignment))
   6031     {
   6032       CurrentContext->align=alignment;
   6033       (void) MVGPrintf(wand,"text-align '%s'\n",CommandOptionToMnemonic(
   6034         MagickAlignOptions,(ssize_t) alignment));
   6035     }
   6036 }
   6037 
   6038 /*
   6040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6041 %                                                                             %
   6042 %                                                                             %
   6043 %                                                                             %
   6044 %   D r a w S e t T e x t A n t i a l i a s                                   %
   6045 %                                                                             %
   6046 %                                                                             %
   6047 %                                                                             %
   6048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6049 %
   6050 %  DrawSetTextAntialias() controls whether text is antialiased.  Text is
   6051 %  antialiased by default.
   6052 %
   6053 %  The format of the DrawSetTextAntialias method is:
   6054 %
   6055 %      void DrawSetTextAntialias(DrawingWand *wand,
   6056 %        const MagickBooleanType text_antialias)
   6057 %
   6058 %  A description of each parameter follows:
   6059 %
   6060 %    o wand: the drawing wand.
   6061 %
   6062 %    o text_antialias: antialias boolean. Set to false (0) to disable
   6063 %      antialiasing.
   6064 %
   6065 */
   6066 WandExport void DrawSetTextAntialias(DrawingWand *wand,
   6067   const MagickBooleanType text_antialias)
   6068 {
   6069   assert(wand != (DrawingWand *) NULL);
   6070   assert(wand->signature == MagickWandSignature);
   6071   if (wand->debug != MagickFalse)
   6072     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6073   if ((wand->filter_off != MagickFalse) ||
   6074       (CurrentContext->text_antialias != text_antialias))
   6075     {
   6076       CurrentContext->text_antialias=text_antialias;
   6077       (void) MVGPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
   6078     }
   6079 }
   6080 
   6081 /*
   6083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6084 %                                                                             %
   6085 %                                                                             %
   6086 %                                                                             %
   6087 %   D r a w S e t T e x t D e c o r a t i o n                                 %
   6088 %                                                                             %
   6089 %                                                                             %
   6090 %                                                                             %
   6091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6092 %
   6093 %  DrawSetTextDecoration() specifies a decoration to be applied when
   6094 %  annotating with text.
   6095 %
   6096 %  The format of the DrawSetTextDecoration method is:
   6097 %
   6098 %      void DrawSetTextDecoration(DrawingWand *wand,
   6099 %        const DecorationType decoration)
   6100 %
   6101 %  A description of each parameter follows:
   6102 %
   6103 %    o wand: the drawing wand.
   6104 %
   6105 %    o decoration: text decoration.  One of NoDecoration, UnderlineDecoration,
   6106 %      OverlineDecoration, or LineThroughDecoration
   6107 %
   6108 */
   6109 WandExport void DrawSetTextDecoration(DrawingWand *wand,
   6110   const DecorationType decoration)
   6111 {
   6112   assert(wand != (DrawingWand *) NULL);
   6113   assert(wand->signature == MagickWandSignature);
   6114   if (wand->debug != MagickFalse)
   6115     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6116   if ((wand->filter_off != MagickFalse) ||
   6117       (CurrentContext->decorate != decoration))
   6118     {
   6119       CurrentContext->decorate=decoration;
   6120       (void) MVGPrintf(wand,"decorate '%s'\n",CommandOptionToMnemonic(
   6121         MagickDecorateOptions,(ssize_t) decoration));
   6122     }
   6123 }
   6124 
   6125 /*
   6127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6128 %                                                                             %
   6129 %                                                                             %
   6130 %                                                                             %
   6131 %   D r a w S e t T e x t D i r e c t i o n                                   %
   6132 %                                                                             %
   6133 %                                                                             %
   6134 %                                                                             %
   6135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6136 %
   6137 %  DrawSetTextDirection() specifies the direction to be used when
   6138 %  annotating with text.
   6139 %
   6140 %  The format of the DrawSetTextDirection method is:
   6141 %
   6142 %      void DrawSetTextDirection(DrawingWand *wand,
   6143 %        const DirectionType direction)
   6144 %
   6145 %  A description of each parameter follows:
   6146 %
   6147 %    o wand: the drawing wand.
   6148 %
   6149 %    o direction: text direction. One of RightToLeftDirection,
   6150 %      LeftToRightDirection
   6151 %
   6152 */
   6153 WandExport void DrawSetTextDirection(DrawingWand *wand,
   6154   const DirectionType direction)
   6155 {
   6156   assert(wand != (DrawingWand *) NULL);
   6157   assert(wand->signature == MagickWandSignature);
   6158 
   6159   if (wand->debug != MagickFalse)
   6160     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6161   if ((wand->filter_off != MagickFalse) ||
   6162       (CurrentContext->direction != direction))
   6163     {
   6164       CurrentContext->direction=direction;
   6165       (void) MVGPrintf(wand,"direction '%s'\n",CommandOptionToMnemonic(
   6166         MagickDirectionOptions,(ssize_t) direction));
   6167     }
   6168 }
   6169 
   6170 /*
   6171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6172 %                                                                             %
   6173 %                                                                             %
   6174 %                                                                             %
   6175 %   D r a w S e t T e x t E n c o d i n g                                     %
   6176 %                                                                             %
   6177 %                                                                             %
   6178 %                                                                             %
   6179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6180 %
   6181 %  DrawSetTextEncoding() specifies the code set to use for text
   6182 %  annotations. The only character encoding which may be specified
   6183 %  at this time is "UTF-8" for representing Unicode as a sequence of
   6184 %  bytes. Specify an empty string to set text encoding to the system's
   6185 %  default. Successful text annotation using Unicode may require fonts
   6186 %  designed to support Unicode.
   6187 %
   6188 %  The format of the DrawSetTextEncoding method is:
   6189 %
   6190 %      void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
   6191 %
   6192 %  A description of each parameter follows:
   6193 %
   6194 %    o wand: the drawing wand.
   6195 %
   6196 %    o encoding: character string specifying text encoding
   6197 %
   6198 */
   6199 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
   6200 {
   6201   assert(wand != (DrawingWand *) NULL);
   6202   assert(wand->signature == MagickWandSignature);
   6203   if (wand->debug != MagickFalse)
   6204     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6205   assert(encoding != (char *) NULL);
   6206   if ((wand->filter_off != MagickFalse) ||
   6207       (CurrentContext->encoding == (char *) NULL) ||
   6208       (LocaleCompare(CurrentContext->encoding,encoding) != 0))
   6209     {
   6210       (void) CloneString(&CurrentContext->encoding,encoding);
   6211       (void) MVGPrintf(wand,"encoding '%s'\n",encoding);
   6212     }
   6213 }
   6214 
   6215 /*
   6217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6218 %                                                                             %
   6219 %                                                                             %
   6220 %                                                                             %
   6221 %   D r a w S e t T e x t K e r n i n g                                       %
   6222 %                                                                             %
   6223 %                                                                             %
   6224 %                                                                             %
   6225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6226 %
   6227 %  DrawSetTextKerning() sets the spacing between characters in text.
   6228 %
   6229 %  The format of the DrawSetTextKerning method is:
   6230 %
   6231 %      void DrawSetTextKerning(DrawingWand *wand,const double kerning)
   6232 %
   6233 %  A description of each parameter follows:
   6234 %
   6235 %    o wand: the drawing wand.
   6236 %
   6237 %    o kerning: text kerning
   6238 %
   6239 */
   6240 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
   6241 {
   6242   assert(wand != (DrawingWand *) NULL);
   6243   assert(wand->signature == MagickWandSignature);
   6244 
   6245   if (wand->debug != MagickFalse)
   6246     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6247   if ((wand->filter_off != MagickFalse) &&
   6248       (fabs((CurrentContext->kerning-kerning)) >= MagickEpsilon))
   6249     {
   6250       CurrentContext->kerning=kerning;
   6251       (void) MVGPrintf(wand,"kerning %lf\n",kerning);
   6252     }
   6253 }
   6254 
   6255 /*
   6257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6258 %                                                                             %
   6259 %                                                                             %
   6260 %                                                                             %
   6261 %   D r a w S e t T e x t I n t e r l i n e S p a c i n g                     %
   6262 %                                                                             %
   6263 %                                                                             %
   6264 %                                                                             %
   6265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6266 %
   6267 %  DrawSetTextInterlineSpacing() sets the spacing between line in text.
   6268 %
   6269 %  The format of the DrawSetInterlineSpacing method is:
   6270 %
   6271 %      void DrawSetTextInterlineSpacing(DrawingWand *wand,
   6272 %        const double interline_spacing)
   6273 %
   6274 %  A description of each parameter follows:
   6275 %
   6276 %    o wand: the drawing wand.
   6277 %
   6278 %    o interline_spacing: text line spacing
   6279 %
   6280 */
   6281 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
   6282   const double interline_spacing)
   6283 {
   6284   assert(wand != (DrawingWand *) NULL);
   6285   assert(wand->signature == MagickWandSignature);
   6286 
   6287   if (wand->debug != MagickFalse)
   6288     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6289   if ((wand->filter_off != MagickFalse) ||
   6290       (fabs((CurrentContext->interline_spacing-
   6291         interline_spacing)) >= MagickEpsilon))
   6292     {
   6293       CurrentContext->interline_spacing=interline_spacing;
   6294       (void) MVGPrintf(wand,"interline-spacing %lf\n",interline_spacing);
   6295     }
   6296 }
   6297 
   6298 /*
   6300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6301 %                                                                             %
   6302 %                                                                             %
   6303 %                                                                             %
   6304 %   D r a w S e t T e x t I n t e r w o r d S p a c i n g                     %
   6305 %                                                                             %
   6306 %                                                                             %
   6307 %                                                                             %
   6308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6309 %
   6310 %  DrawSetTextInterwordSpacing() sets the spacing between words in text.
   6311 %
   6312 %  The format of the DrawSetInterwordSpacing method is:
   6313 %
   6314 %      void DrawSetTextInterwordSpacing(DrawingWand *wand,
   6315 %        const double interword_spacing)
   6316 %
   6317 %  A description of each parameter follows:
   6318 %
   6319 %    o wand: the drawing wand.
   6320 %
   6321 %    o interword_spacing: text word spacing
   6322 %
   6323 */
   6324 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
   6325   const double interword_spacing)
   6326 {
   6327   assert(wand != (DrawingWand *) NULL);
   6328   assert(wand->signature == MagickWandSignature);
   6329 
   6330   if (wand->debug != MagickFalse)
   6331     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6332   if ((wand->filter_off != MagickFalse) ||
   6333       (fabs((CurrentContext->interword_spacing-
   6334         interword_spacing)) >= MagickEpsilon))
   6335     {
   6336       CurrentContext->interword_spacing=interword_spacing;
   6337       (void) MVGPrintf(wand,"interword-spacing %lf\n",interword_spacing);
   6338     }
   6339 }
   6340 
   6341 /*
   6343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6344 %                                                                             %
   6345 %                                                                             %
   6346 %                                                                             %
   6347 %   D r a w S e t T e x t U n d e r C o l o r                                 %
   6348 %                                                                             %
   6349 %                                                                             %
   6350 %                                                                             %
   6351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6352 %
   6353 %  DrawSetTextUnderColor() specifies the color of a background rectangle
   6354 %  to place under text annotations.
   6355 %
   6356 %  The format of the DrawSetTextUnderColor method is:
   6357 %
   6358 %      void DrawSetTextUnderColor(DrawingWand *wand,
   6359 %        const PixelWand *under_wand)
   6360 %
   6361 %  A description of each parameter follows:
   6362 %
   6363 %    o wand: the drawing wand.
   6364 %
   6365 %    o under_wand: text under wand.
   6366 %
   6367 */
   6368 WandExport void DrawSetTextUnderColor(DrawingWand *wand,
   6369   const PixelWand *under_wand)
   6370 {
   6371   PixelInfo
   6372     under_color;
   6373 
   6374   assert(wand != (DrawingWand *) NULL);
   6375   assert(wand->signature == MagickWandSignature);
   6376   if (wand->debug != MagickFalse)
   6377     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6378   assert(under_wand != (const PixelWand *) NULL);
   6379   PixelGetQuantumPacket(under_wand,&under_color);
   6380   if ((wand->filter_off != MagickFalse) ||
   6381       (IsPixelInfoEquivalent(&CurrentContext->undercolor,&under_color) == MagickFalse))
   6382     {
   6383       CurrentContext->undercolor=under_color;
   6384       (void) MVGPrintf(wand,"text-undercolor '");
   6385       MVGAppendColor(wand,&under_color);
   6386       (void) MVGPrintf(wand,"'\n");
   6387     }
   6388 }
   6389 
   6390 /*
   6392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6393 %                                                                             %
   6394 %                                                                             %
   6395 %                                                                             %
   6396 %   D r a w S e t V e c t o r G r a p h i c s                                 %
   6397 %                                                                             %
   6398 %                                                                             %
   6399 %                                                                             %
   6400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6401 %
   6402 %  DrawSetVectorGraphics() sets the vector graphics associated with the
   6403 %  specified wand.  Use this method with DrawGetVectorGraphics() as a method
   6404 %  to persist the vector graphics state.
   6405 %
   6406 %  The format of the DrawSetVectorGraphics method is:
   6407 %
   6408 %      MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
   6409 %        const char *xml)
   6410 %
   6411 %  A description of each parameter follows:
   6412 %
   6413 %    o wand: the drawing wand.
   6414 %
   6415 %    o xml: the drawing wand XML.
   6416 %
   6417 */
   6418 
   6419 static inline MagickBooleanType IsPoint(const char *point)
   6420 {
   6421   char
   6422     *p;
   6423 
   6424   long
   6425     value;
   6426 
   6427   value=strtol(point,&p,10);
   6428   (void) value;
   6429   return(p != point ? MagickTrue : MagickFalse);
   6430 }
   6431 
   6432 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
   6433   const char *xml)
   6434 {
   6435   const char
   6436     *value;
   6437 
   6438   XMLTreeInfo
   6439     *child,
   6440     *xml_info;
   6441 
   6442   assert(wand != (DrawingWand *) NULL);
   6443   assert(wand->signature == MagickWandSignature);
   6444   if (wand->debug != MagickFalse)
   6445     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6446   CurrentContext=DestroyDrawInfo(CurrentContext);
   6447   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
   6448   if (xml == (const char *) NULL)
   6449     return(MagickFalse);
   6450   xml_info=NewXMLTree(xml,wand->exception);
   6451   if (xml_info == (XMLTreeInfo *) NULL)
   6452     return(MagickFalse);
   6453   child=GetXMLTreeChild(xml_info,"clip-path");
   6454   if (child != (XMLTreeInfo *) NULL)
   6455     (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
   6456   child=GetXMLTreeChild(xml_info,"clip-units");
   6457   if (child != (XMLTreeInfo *) NULL)
   6458     {
   6459       value=GetXMLTreeContent(child);
   6460       if (value != (const char *) NULL)
   6461         CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption(
   6462           MagickClipPathOptions,MagickFalse,value);
   6463     }
   6464   child=GetXMLTreeChild(xml_info,"decorate");
   6465   if (child != (XMLTreeInfo *) NULL)
   6466     {
   6467       value=GetXMLTreeContent(child);
   6468       if (value != (const char *) NULL)
   6469         CurrentContext->decorate=(DecorationType) ParseCommandOption(
   6470           MagickDecorateOptions,MagickFalse,value);
   6471     }
   6472   child=GetXMLTreeChild(xml_info,"encoding");
   6473   if (child != (XMLTreeInfo *) NULL)
   6474     (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
   6475   child=GetXMLTreeChild(xml_info,"fill");
   6476   if (child != (XMLTreeInfo *) NULL)
   6477     {
   6478       value=GetXMLTreeContent(child);
   6479       if (value != (const char *) NULL)
   6480         (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->fill,
   6481           wand->exception);
   6482     }
   6483   child=GetXMLTreeChild(xml_info,"fill-opacity");
   6484   if (child != (XMLTreeInfo *) NULL)
   6485     {
   6486       value=GetXMLTreeContent(child);
   6487       if (value != (const char *) NULL)
   6488         CurrentContext->fill.alpha=(double) ClampToQuantum(QuantumRange*
   6489           (1.0-StringToDouble(value,(char **) NULL)));
   6490     }
   6491   child=GetXMLTreeChild(xml_info,"fill-rule");
   6492   if (child != (XMLTreeInfo *) NULL)
   6493     {
   6494       value=GetXMLTreeContent(child);
   6495       if (value != (const char *) NULL)
   6496         CurrentContext->fill_rule=(FillRule) ParseCommandOption(
   6497           MagickFillRuleOptions,MagickFalse,value);
   6498     }
   6499   child=GetXMLTreeChild(xml_info,"font");
   6500   if (child != (XMLTreeInfo *) NULL)
   6501     (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
   6502   child=GetXMLTreeChild(xml_info,"font-family");
   6503   if (child != (XMLTreeInfo *) NULL)
   6504     (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
   6505   child=GetXMLTreeChild(xml_info,"font-size");
   6506   if (child != (XMLTreeInfo *) NULL)
   6507     {
   6508       value=GetXMLTreeContent(child);
   6509       if (value != (const char *) NULL)
   6510         CurrentContext->pointsize=StringToDouble(value,(char **) NULL);
   6511     }
   6512   child=GetXMLTreeChild(xml_info,"font-stretch");
   6513   if (child != (XMLTreeInfo *) NULL)
   6514     {
   6515       value=GetXMLTreeContent(child);
   6516       if (value != (const char *) NULL)
   6517         CurrentContext->stretch=(StretchType) ParseCommandOption(
   6518           MagickStretchOptions,MagickFalse,value);
   6519     }
   6520   child=GetXMLTreeChild(xml_info,"font-style");
   6521   if (child != (XMLTreeInfo *) NULL)
   6522     {
   6523       value=GetXMLTreeContent(child);
   6524       if (value != (const char *) NULL)
   6525         CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
   6526           MagickFalse,value);
   6527     }
   6528   child=GetXMLTreeChild(xml_info,"font-weight");
   6529   if (child != (XMLTreeInfo *) NULL)
   6530     {
   6531       value=GetXMLTreeContent(child);
   6532       if (value != (const char *) NULL)
   6533         {
   6534           ssize_t
   6535             weight;
   6536 
   6537           weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
   6538           if (weight == -1)
   6539             weight=(ssize_t) StringToUnsignedLong(value);
   6540           CurrentContext->weight=(size_t) weight;
   6541         }
   6542     }
   6543   child=GetXMLTreeChild(xml_info,"gravity");
   6544   if (child != (XMLTreeInfo *) NULL)
   6545     {
   6546       value=GetXMLTreeContent(child);
   6547       if (value != (const char *) NULL)
   6548         CurrentContext->gravity=(GravityType) ParseCommandOption(
   6549           MagickGravityOptions,MagickFalse,value);
   6550     }
   6551   child=GetXMLTreeChild(xml_info,"stroke");
   6552   if (child != (XMLTreeInfo *) NULL)
   6553     {
   6554       value=GetXMLTreeContent(child);
   6555       if (value != (const char *) NULL)
   6556         (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->stroke,
   6557           wand->exception);
   6558     }
   6559   child=GetXMLTreeChild(xml_info,"stroke-antialias");
   6560   if (child != (XMLTreeInfo *) NULL)
   6561     {
   6562       value=GetXMLTreeContent(child);
   6563       if (value != (const char *) NULL)
   6564         CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
   6565           MagickFalse;
   6566     }
   6567   child=GetXMLTreeChild(xml_info,"stroke-dasharray");
   6568   if (child != (XMLTreeInfo *) NULL)
   6569     {
   6570       char
   6571         token[MagickPathExtent];
   6572 
   6573       const char
   6574         *q;
   6575 
   6576       register ssize_t
   6577         x;
   6578 
   6579       ssize_t
   6580         j;
   6581 
   6582       value=GetXMLTreeContent(child);
   6583       if (value != (const char *) NULL)
   6584         {
   6585           if (CurrentContext->dash_pattern != (double *) NULL)
   6586             CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
   6587               CurrentContext->dash_pattern);
   6588           q=(char *) value;
   6589           if (IsPoint(q) != MagickFalse)
   6590             {
   6591               const char
   6592                 *p;
   6593 
   6594               p=q;
   6595               GetNextToken(p,&p,MagickPathExtent,token);
   6596               if (*token == ',')
   6597                 GetNextToken(p,&p,MagickPathExtent,token);
   6598               for (x=0; IsPoint(token) != MagickFalse; x++)
   6599               {
   6600                 GetNextToken(p,&p,MagickPathExtent,token);
   6601                 if (*token == ',')
   6602                   GetNextToken(p,&p,MagickPathExtent,token);
   6603               }
   6604               CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
   6605                 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
   6606               if (CurrentContext->dash_pattern == (double *) NULL)
   6607                 ThrowWandFatalException(ResourceLimitFatalError,
   6608                   "MemoryAllocationFailed",wand->name);
   6609               for (j=0; j < x; j++)
   6610               {
   6611                 GetNextToken(q,&q,MagickPathExtent,token);
   6612                 if (*token == ',')
   6613                   GetNextToken(q,&q,MagickPathExtent,token);
   6614                 CurrentContext->dash_pattern[j]=StringToDouble(token,
   6615                   (char **) NULL);
   6616               }
   6617               if ((x & 0x01) != 0)
   6618                 for ( ; j < (2*x); j++)
   6619                   CurrentContext->dash_pattern[j]=
   6620                     CurrentContext->dash_pattern[j-x];
   6621               CurrentContext->dash_pattern[j]=0.0;
   6622             }
   6623         }
   6624     }
   6625   child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
   6626   if (child != (XMLTreeInfo *) NULL)
   6627     {
   6628       value=GetXMLTreeContent(child);
   6629       if (value != (const char *) NULL)
   6630         CurrentContext->dash_offset=StringToDouble(value,(char **) NULL);
   6631     }
   6632   child=GetXMLTreeChild(xml_info,"stroke-linecap");
   6633   if (child != (XMLTreeInfo *) NULL)
   6634     {
   6635       value=GetXMLTreeContent(child);
   6636       if (value != (const char *) NULL)
   6637         CurrentContext->linecap=(LineCap) ParseCommandOption(
   6638           MagickLineCapOptions,MagickFalse,value);
   6639     }
   6640   child=GetXMLTreeChild(xml_info,"stroke-linejoin");
   6641   if (child != (XMLTreeInfo *) NULL)
   6642     {
   6643       value=GetXMLTreeContent(child);
   6644       if (value != (const char *) NULL)
   6645         CurrentContext->linejoin=(LineJoin) ParseCommandOption(
   6646           MagickLineJoinOptions,MagickFalse,value);
   6647     }
   6648   child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
   6649   if (child != (XMLTreeInfo *) NULL)
   6650     {
   6651       value=GetXMLTreeContent(child);
   6652       if (value != (const char *) NULL)
   6653         CurrentContext->miterlimit=StringToUnsignedLong(value);
   6654     }
   6655   child=GetXMLTreeChild(xml_info,"stroke-opacity");
   6656   if (child != (XMLTreeInfo *) NULL)
   6657     {
   6658       value=GetXMLTreeContent(child);
   6659       if (value != (const char *) NULL)
   6660         CurrentContext->stroke.alpha=(double) ClampToQuantum(QuantumRange*
   6661           (1.0-StringToDouble(value,(char **) NULL)));
   6662     }
   6663   child=GetXMLTreeChild(xml_info,"stroke-width");
   6664   if (child != (XMLTreeInfo *) NULL)
   6665     {
   6666       value=GetXMLTreeContent(child);
   6667       if (value != (const char *) NULL)
   6668         {
   6669           ssize_t
   6670             weight;
   6671 
   6672           weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
   6673           if (weight == -1)
   6674             weight=(ssize_t) StringToUnsignedLong(value);
   6675           CurrentContext->stroke_width=(double) weight;
   6676         }
   6677     }
   6678   child=GetXMLTreeChild(xml_info,"text-align");
   6679   if (child != (XMLTreeInfo *) NULL)
   6680     {
   6681       value=GetXMLTreeContent(child);
   6682       if (value != (const char *) NULL)
   6683         CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
   6684           MagickFalse,value);
   6685     }
   6686   child=GetXMLTreeChild(xml_info,"text-antialias");
   6687   if (child != (XMLTreeInfo *) NULL)
   6688     {
   6689       value=GetXMLTreeContent(child);
   6690       if (value != (const char *) NULL)
   6691         CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
   6692           MagickFalse;
   6693     }
   6694   child=GetXMLTreeChild(xml_info,"text-undercolor");
   6695   if (child != (XMLTreeInfo *) NULL)
   6696     {
   6697       value=GetXMLTreeContent(child);
   6698       if (value != (const char *) NULL)
   6699         (void) QueryColorCompliance(value,AllCompliance,
   6700           &CurrentContext->undercolor,wand->exception);
   6701     }
   6702   child=GetXMLTreeChild(xml_info,"vector-graphics");
   6703   if (child != (XMLTreeInfo *) NULL)
   6704     {
   6705       (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
   6706       wand->mvg_length=strlen(wand->mvg);
   6707       wand->mvg_alloc=wand->mvg_length+1;
   6708     }
   6709   xml_info=DestroyXMLTree(xml_info);
   6710   return(MagickTrue);
   6711 }
   6712 
   6713 /*
   6715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6716 %                                                                             %
   6717 %                                                                             %
   6718 %                                                                             %
   6719 %   D r a w S k e w X                                                         %
   6720 %                                                                             %
   6721 %                                                                             %
   6722 %                                                                             %
   6723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6724 %
   6725 %  DrawSkewX() skews the current coordinate system in the horizontal
   6726 %  direction.
   6727 %
   6728 %  The format of the DrawSkewX method is:
   6729 %
   6730 %      void DrawSkewX(DrawingWand *wand,const double degrees)
   6731 %
   6732 %  A description of each parameter follows:
   6733 %
   6734 %    o wand: the drawing wand.
   6735 %
   6736 %    o degrees: number of degrees to skew the coordinates
   6737 %
   6738 */
   6739 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
   6740 {
   6741   assert(wand != (DrawingWand *) NULL);
   6742   assert(wand->signature == MagickWandSignature);
   6743   if (wand->debug != MagickFalse)
   6744     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6745   (void) MVGPrintf(wand,"skewX %.20g\n",degrees);
   6746 }
   6747 
   6748 /*
   6750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6751 %                                                                             %
   6752 %                                                                             %
   6753 %                                                                             %
   6754 %   D r a w S k e w Y                                                         %
   6755 %                                                                             %
   6756 %                                                                             %
   6757 %                                                                             %
   6758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6759 %
   6760 %  DrawSkewY() skews the current coordinate system in the vertical
   6761 %  direction.
   6762 %
   6763 %  The format of the DrawSkewY method is:
   6764 %
   6765 %      void DrawSkewY(DrawingWand *wand,const double degrees)
   6766 %
   6767 %  A description of each parameter follows:
   6768 %
   6769 %    o wand: the drawing wand.
   6770 %
   6771 %    o degrees: number of degrees to skew the coordinates
   6772 %
   6773 */
   6774 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
   6775 {
   6776   assert(wand != (DrawingWand *) NULL);
   6777   assert(wand->signature == MagickWandSignature);
   6778   if (wand->debug != MagickFalse)
   6779     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6780   (void) MVGPrintf(wand,"skewY %.20g\n",degrees);
   6781 }
   6782 
   6783 /*
   6785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6786 %                                                                             %
   6787 %                                                                             %
   6788 %                                                                             %
   6789 %   D r a w T r a n s l a t e                                                 %
   6790 %                                                                             %
   6791 %                                                                             %
   6792 %                                                                             %
   6793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6794 %
   6795 %  DrawTranslate() applies a translation to the current coordinate
   6796 %  system which moves the coordinate system origin to the specified
   6797 %  coordinate.
   6798 %
   6799 %  The format of the DrawTranslate method is:
   6800 %
   6801 %      void DrawTranslate(DrawingWand *wand,const double x,
   6802 %        const double y)
   6803 %
   6804 %  A description of each parameter follows:
   6805 %
   6806 %    o wand: the drawing wand.
   6807 %
   6808 %    o x: new x ordinate for coordinate system origin
   6809 %
   6810 %    o y: new y ordinate for coordinate system origin
   6811 %
   6812 */
   6813 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
   6814 {
   6815   assert(wand != (DrawingWand *) NULL);
   6816   assert(wand->signature == MagickWandSignature);
   6817   if (wand->debug != MagickFalse)
   6818     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6819   (void) MVGPrintf(wand,"translate %.20g %.20g\n",x,y);
   6820 }
   6821 
   6822 /*
   6824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6825 %                                                                             %
   6826 %                                                                             %
   6827 %                                                                             %
   6828 %   D r a w S e t V i e w b o x                                               %
   6829 %                                                                             %
   6830 %                                                                             %
   6831 %                                                                             %
   6832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6833 %
   6834 %  DrawSetViewbox() sets the overall canvas size to be recorded with the
   6835 %  drawing vector data.  Usually this will be specified using the same
   6836 %  size as the canvas image.  When the vector data is saved to SVG or MVG
   6837 %  formats, the viewbox is use to specify the size of the canvas image that
   6838 %  a viewer will render the vector data on.
   6839 %
   6840 %  The format of the DrawSetViewbox method is:
   6841 %
   6842 %      void DrawSetViewbox(DrawingWand *wand,const double x1,const double y1,
   6843 %        const double x2,const double y2)
   6844 %
   6845 %  A description of each parameter follows:
   6846 %
   6847 %    o wand: the drawing wand.
   6848 %
   6849 %    o x1: left x ordinate
   6850 %
   6851 %    o y1: top y ordinate
   6852 %
   6853 %    o x2: right x ordinate
   6854 %
   6855 %    o y2: bottom y ordinate
   6856 %
   6857 */
   6858 WandExport void DrawSetViewbox(DrawingWand *wand,const double x1,
   6859   const double y1,const double x2,const double y2)
   6860 {
   6861   assert(wand != (DrawingWand *) NULL);
   6862   assert(wand->signature == MagickWandSignature);
   6863   if (wand->debug != MagickFalse)
   6864     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6865   (void) MVGPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
   6866 }
   6867 
   6868 /*
   6870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6871 %                                                                             %
   6872 %                                                                             %
   6873 %                                                                             %
   6874 %   I s D r a w i n g W a n d                                                 %
   6875 %                                                                             %
   6876 %                                                                             %
   6877 %                                                                             %
   6878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6879 %
   6880 %  IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
   6881 %
   6882 %  The format of the IsDrawingWand method is:
   6883 %
   6884 %      MagickBooleanType IsDrawingWand(const DrawingWand *wand)
   6885 %
   6886 %  A description of each parameter follows:
   6887 %
   6888 %    o wand: the drawing wand.
   6889 %
   6890 */
   6891 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
   6892 {
   6893   if (wand == (const DrawingWand *) NULL)
   6894     return(MagickFalse);
   6895   if (wand->signature != MagickWandSignature)
   6896     return(MagickFalse);
   6897   if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
   6898     return(MagickFalse);
   6899   return(MagickTrue);
   6900 }
   6901 
   6902 /*
   6904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6905 %                                                                             %
   6906 %                                                                             %
   6907 %                                                                             %
   6908 %   N e w D r a w i n g W a n d                                               %
   6909 %                                                                             %
   6910 %                                                                             %
   6911 %                                                                             %
   6912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6913 %
   6914 %  NewDrawingWand() returns a drawing wand required for all other methods in
   6915 %  the API.
   6916 %
   6917 %  The format of the NewDrawingWand method is:
   6918 %
   6919 %      DrawingWand *NewDrawingWand(void)
   6920 %
   6921 */
   6922 WandExport DrawingWand *NewDrawingWand(void)
   6923 {
   6924   const char
   6925     *quantum;
   6926 
   6927   DrawingWand
   6928     *wand;
   6929 
   6930   size_t
   6931     depth;
   6932 
   6933   quantum=GetMagickQuantumDepth(&depth);
   6934   if (depth != MAGICKCORE_QUANTUM_DEPTH)
   6935     ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
   6936   wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand));
   6937   if (wand == (DrawingWand *) NULL)
   6938     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
   6939       GetExceptionMessage(errno));
   6940   (void) memset(wand,0,sizeof(*wand));
   6941   wand->id=AcquireWandId();
   6942   (void) FormatLocaleString(wand->name,MagickPathExtent,"%s-%.20g",
   6943     DrawingWandId,(double) wand->id);
   6944   if (wand->debug != MagickFalse)
   6945     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6946   wand->mvg=(char *) NULL;
   6947   wand->mvg_alloc=0;
   6948   wand->mvg_length=0;
   6949   wand->mvg_width=0;
   6950   wand->pattern_id=(char *) NULL;
   6951   wand->pattern_offset=0;
   6952   wand->pattern_bounds.x=0;
   6953   wand->pattern_bounds.y=0;
   6954   wand->pattern_bounds.width=0;
   6955   wand->pattern_bounds.height=0;
   6956   wand->index=0;
   6957   wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(
   6958     *wand->graphic_context));
   6959   if (wand->graphic_context == (DrawInfo **) NULL)
   6960     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
   6961       GetExceptionMessage(errno));
   6962   wand->filter_off=MagickTrue;
   6963   wand->indent_depth=0;
   6964   wand->path_operation=PathDefaultOperation;
   6965   wand->path_mode=DefaultPathMode;
   6966   wand->exception=AcquireExceptionInfo();
   6967   wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception);
   6968   wand->destroy=MagickTrue;
   6969   wand->debug=IsEventLogging();
   6970   wand->signature=MagickWandSignature;
   6971   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
   6972   return(wand);
   6973 }
   6974 
   6975 /*
   6977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6978 %                                                                             %
   6979 %                                                                             %
   6980 %                                                                             %
   6981 %   P e e k D r a w i n g W a n d                                             %
   6982 %                                                                             %
   6983 %                                                                             %
   6984 %                                                                             %
   6985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6986 %
   6987 %  PeekDrawingWand() returns the current drawing wand.
   6988 %
   6989 %  The format of the PeekDrawingWand method is:
   6990 %
   6991 %      DrawInfo *PeekDrawingWand(const DrawingWand *wand)
   6992 %
   6993 %  A description of each parameter follows:
   6994 %
   6995 %    o wand: the drawing wand.
   6996 %
   6997 */
   6998 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
   6999 {
   7000   DrawInfo
   7001     *draw_info;
   7002 
   7003   assert(wand != (const DrawingWand *) NULL);
   7004   assert(wand->signature == MagickWandSignature);
   7005   if (wand->debug != MagickFalse)
   7006     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   7007   draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
   7008   (void) CloneString(&draw_info->primitive,wand->mvg);
   7009   return(draw_info);
   7010 }
   7011 
   7012 /*
   7014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7015 %                                                                             %
   7016 %                                                                             %
   7017 %                                                                             %
   7018 %   P o p D r a w i n g W a n d                                               %
   7019 %                                                                             %
   7020 %                                                                             %
   7021 %                                                                             %
   7022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7023 %
   7024 %  PopDrawingWand() destroys the current drawing wand and returns to the
   7025 %  previously pushed drawing wand. Multiple drawing wands may exist. It is an
   7026 %  error to attempt to pop more drawing wands than have been pushed, and it is
   7027 %  proper form to pop all drawing wands which have been pushed.
   7028 %
   7029 %  The format of the PopDrawingWand method is:
   7030 %
   7031 %      MagickBooleanType PopDrawingWand(DrawingWand *wand)
   7032 %
   7033 %  A description of each parameter follows:
   7034 %
   7035 %    o wand: the drawing wand.
   7036 %
   7037 */
   7038 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
   7039 {
   7040   assert(wand != (DrawingWand *) NULL);
   7041   assert(wand->signature == MagickWandSignature);
   7042   if (wand->debug != MagickFalse)
   7043     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   7044   if (wand->index == 0)
   7045     {
   7046       ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
   7047       return(MagickFalse);
   7048     }
   7049   /*
   7050     Destroy clip path if not same in preceding wand.
   7051   */
   7052 #if DRAW_BINARY_IMPLEMENTATION
   7053   if (wand->image == (Image *) NULL)
   7054     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   7055   if (CurrentContext->clip_mask != (char *) NULL)
   7056     if (LocaleCompare(CurrentContext->clip_mask,
   7057         wand->graphic_context[wand->index-1]->clip_mask) != 0)
   7058       (void) SetImageMask(wand->image,WritePixelMask,(Image *) NULL,
   7059         wand->exception);
   7060 #endif
   7061   CurrentContext=DestroyDrawInfo(CurrentContext);
   7062   wand->index--;
   7063   if (wand->indent_depth > 0)
   7064     wand->indent_depth--;
   7065   (void) MVGPrintf(wand,"pop graphic-context\n");
   7066   return(MagickTrue);
   7067 }
   7068 
   7069 /*
   7071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7072 %                                                                             %
   7073 %                                                                             %
   7074 %                                                                             %
   7075 %   P u s h D r a w i n g W a n d                                             %
   7076 %                                                                             %
   7077 %                                                                             %
   7078 %                                                                             %
   7079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7080 %
   7081 %  PushDrawingWand() clones the current drawing wand to create a new drawing
   7082 %  wand.  The original drawing wand(s) may be returned to by invoking
   7083 %  PopDrawingWand().  The drawing wands are stored on a drawing wand stack.
   7084 %  For every Pop there must have already been an equivalent Push.
   7085 %
   7086 %  The format of the PushDrawingWand method is:
   7087 %
   7088 %      MagickBooleanType PushDrawingWand(DrawingWand *wand)
   7089 %
   7090 %  A description of each parameter follows:
   7091 %
   7092 %    o wand: the drawing wand.
   7093 %
   7094 */
   7095 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
   7096 {
   7097   assert(wand != (DrawingWand *) NULL);
   7098   assert(wand->signature == MagickWandSignature);
   7099   if (wand->debug != MagickFalse)
   7100     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   7101   wand->index++;
   7102   wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
   7103     (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
   7104   if (wand->graphic_context == (DrawInfo **) NULL)
   7105     {
   7106       wand->index--;
   7107       ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
   7108         wand->name);
   7109       return(MagickFalse);
   7110     }
   7111   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
   7112     wand->graphic_context[wand->index-1]);
   7113   (void) MVGPrintf(wand,"push graphic-context\n");
   7114   wand->indent_depth++;
   7115   return(MagickTrue);
   7116 }
   7117