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-2016 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 %    http://www.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   if (wand->debug != MagickFalse)
    180     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format);
    181   assert(wand != (DrawingWand *) NULL);
    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) ResetMagickMemory(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       p=CurrentContext->dash_pattern;
   2003       q=dasharray;
   2004       for (i=0; i < (ssize_t) n; i++)
   2005         *q++=(*p++);
   2006       *q=0.0;
   2007     }
   2008   return(dasharray);
   2009 }
   2010 
   2011 /*
   2013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2014 %                                                                             %
   2015 %                                                                             %
   2016 %                                                                             %
   2017 %   D r a w G e t S t r o k e D a s h O f f s e t                             %
   2018 %                                                                             %
   2019 %                                                                             %
   2020 %                                                                             %
   2021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2022 %
   2023 %  DrawGetStrokeDashOffset() returns the offset into the dash pattern to
   2024 %  start the dash.
   2025 %
   2026 %  The format of the DrawGetStrokeDashOffset method is:
   2027 %
   2028 %      double DrawGetStrokeDashOffset(const DrawingWand *wand)
   2029 %
   2030 %  A description of each parameter follows:
   2031 %
   2032 %    o wand: the drawing wand.
   2033 %
   2034 */
   2035 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
   2036 {
   2037   assert(wand != (const DrawingWand *) NULL);
   2038   assert(wand->signature == MagickWandSignature);
   2039   if (wand->debug != MagickFalse)
   2040     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2041   return(CurrentContext->dash_offset);
   2042 }
   2043 
   2044 /*
   2046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2047 %                                                                             %
   2048 %                                                                             %
   2049 %                                                                             %
   2050 %   D r a w G e t S t r o k e L i n e C a p                                   %
   2051 %                                                                             %
   2052 %                                                                             %
   2053 %                                                                             %
   2054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2055 %
   2056 %  DrawGetStrokeLineCap() returns the shape to be used at the end of
   2057 %  open subpaths when they are stroked. Values of LineCap are
   2058 %  UndefinedCap, ButtCap, RoundCap, and SquareCap.
   2059 %
   2060 %  The format of the DrawGetStrokeLineCap method is:
   2061 %
   2062 %      LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
   2063 %
   2064 %  A description of each parameter follows:
   2065 %
   2066 %    o wand: the drawing wand.
   2067 %
   2068 */
   2069 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
   2070 {
   2071   assert(wand != (const DrawingWand *) NULL);
   2072   assert(wand->signature == MagickWandSignature);
   2073   if (wand->debug != MagickFalse)
   2074     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2075   return(CurrentContext->linecap);
   2076 }
   2077 
   2078 /*
   2080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2081 %                                                                             %
   2082 %                                                                             %
   2083 %                                                                             %
   2084 %   D r a w G e t S t r o k e L i n e J o i n                                 %
   2085 %                                                                             %
   2086 %                                                                             %
   2087 %                                                                             %
   2088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2089 %
   2090 %  DrawGetStrokeLineJoin() returns the shape to be used at the
   2091 %  corners of paths (or other vector shapes) when they are
   2092 %  stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
   2093 %  and BevelJoin.
   2094 %
   2095 %  The format of the DrawGetStrokeLineJoin method is:
   2096 %
   2097 %      LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
   2098 %
   2099 %  A description of each parameter follows:
   2100 %
   2101 %    o wand: the drawing wand.
   2102 %
   2103 */
   2104 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
   2105 {
   2106   assert(wand != (const DrawingWand *) NULL);
   2107   assert(wand->signature == MagickWandSignature);
   2108   if (wand->debug != MagickFalse)
   2109     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2110   return(CurrentContext->linejoin);
   2111 }
   2112 
   2113 /*
   2115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2116 %                                                                             %
   2117 %                                                                             %
   2118 %                                                                             %
   2119 %   D r a w G e t S t r o k e M i t e r L i m i t                             %
   2120 %                                                                             %
   2121 %                                                                             %
   2122 %                                                                             %
   2123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2124 %
   2125 %  DrawGetStrokeMiterLimit() returns the miter limit. When two line
   2126 %  segments meet at a sharp angle and miter joins have been specified for
   2127 %  'lineJoin', it is possible for the miter to extend far beyond the
   2128 %  thickness of the line stroking the path. The miterLimit' imposes a
   2129 %  limit on the ratio of the miter length to the 'lineWidth'.
   2130 %
   2131 %  The format of the DrawGetStrokeMiterLimit method is:
   2132 %
   2133 %      size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
   2134 %
   2135 %  A description of each parameter follows:
   2136 %
   2137 %    o wand: the drawing wand.
   2138 %
   2139 */
   2140 WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
   2141 {
   2142   assert(wand != (const DrawingWand *) NULL);
   2143   assert(wand->signature == MagickWandSignature);
   2144   if (wand->debug != MagickFalse)
   2145     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2146   return CurrentContext->miterlimit;
   2147 }
   2148 
   2149 /*
   2151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2152 %                                                                             %
   2153 %                                                                             %
   2154 %                                                                             %
   2155 %   D r a w G e t S t r o k e O p a c i t y                                   %
   2156 %                                                                             %
   2157 %                                                                             %
   2158 %                                                                             %
   2159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2160 %
   2161 %  DrawGetStrokeOpacity() returns the alpha of stroked object outlines.
   2162 %
   2163 %  The format of the DrawGetStrokeOpacity method is:
   2164 %
   2165 %      double DrawGetStrokeOpacity(const DrawingWand *wand)
   2166 %
   2167 %  A description of each parameter follows:
   2168 %
   2169 %    o wand: the drawing wand.
   2170 %
   2171 */
   2172 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
   2173 {
   2174   double
   2175     alpha;
   2176 
   2177   assert(wand != (const DrawingWand *) NULL);
   2178   assert(wand->signature == MagickWandSignature);
   2179   if (wand->debug != MagickFalse)
   2180     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2181   alpha=(double) QuantumScale*CurrentContext->stroke.alpha;
   2182   return(alpha);
   2183 }
   2184 
   2185 /*
   2187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2188 %                                                                             %
   2189 %                                                                             %
   2190 %                                                                             %
   2191 %   D r a w G e t S t r o k e W i d t h                                       %
   2192 %                                                                             %
   2193 %                                                                             %
   2194 %                                                                             %
   2195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2196 %
   2197 %  DrawGetStrokeWidth() returns the width of the stroke used to draw object
   2198 %  outlines.
   2199 %
   2200 %  The format of the DrawGetStrokeWidth method is:
   2201 %
   2202 %      double DrawGetStrokeWidth(const DrawingWand *wand)
   2203 %
   2204 %  A description of each parameter follows:
   2205 %
   2206 %    o wand: the drawing wand.
   2207 %
   2208 */
   2209 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
   2210 {
   2211   assert(wand != (const DrawingWand *) NULL);
   2212   assert(wand->signature == MagickWandSignature);
   2213   if (wand->debug != MagickFalse)
   2214     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2215   return(CurrentContext->stroke_width);
   2216 }
   2217 
   2218 /*
   2220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2221 %                                                                             %
   2222 %                                                                             %
   2223 %                                                                             %
   2224 %   D r a w G e t T e x t A l i g n m e n t                                   %
   2225 %                                                                             %
   2226 %                                                                             %
   2227 %                                                                             %
   2228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2229 %
   2230 %  DrawGetTextAlignment() returns the alignment applied when annotating with
   2231 %  text.
   2232 %
   2233 %  The format of the DrawGetTextAlignment method is:
   2234 %
   2235 %      AlignType DrawGetTextAlignment(const DrawingWand *wand)
   2236 %
   2237 %  A description of each parameter follows:
   2238 %
   2239 %    o wand: the drawing wand.
   2240 %
   2241 */
   2242 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
   2243 {
   2244   assert(wand != (const DrawingWand *) NULL);
   2245   assert(wand->signature == MagickWandSignature);
   2246   if (wand->debug != MagickFalse)
   2247     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2248   return(CurrentContext->align);
   2249 }
   2250 
   2251 /*
   2253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2254 %                                                                             %
   2255 %                                                                             %
   2256 %                                                                             %
   2257 %   D r a w G e t T e x t A n t i a l i a s                                   %
   2258 %                                                                             %
   2259 %                                                                             %
   2260 %                                                                             %
   2261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2262 %
   2263 %  DrawGetTextAntialias() returns the current text antialias setting, which
   2264 %  determines whether text is antialiased.  Text is antialiased by default.
   2265 %
   2266 %  The format of the DrawGetTextAntialias method is:
   2267 %
   2268 %      MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
   2269 %
   2270 %  A description of each parameter follows:
   2271 %
   2272 %    o wand: the drawing wand.
   2273 %
   2274 */
   2275 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
   2276 {
   2277   assert(wand != (const DrawingWand *) NULL);
   2278   assert(wand->signature == MagickWandSignature);
   2279   if (wand->debug != MagickFalse)
   2280     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2281   return(CurrentContext->text_antialias);
   2282 }
   2283 
   2284 /*
   2286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2287 %                                                                             %
   2288 %                                                                             %
   2289 %                                                                             %
   2290 %   D r a w G e t T e x t D e c o r a t i o n                                 %
   2291 %                                                                             %
   2292 %                                                                             %
   2293 %                                                                             %
   2294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2295 %
   2296 %  DrawGetTextDecoration() returns the decoration applied when annotating with
   2297 %  text.
   2298 %
   2299 %  The format of the DrawGetTextDecoration method is:
   2300 %
   2301 %      DecorationType DrawGetTextDecoration(const DrawingWand *wand)
   2302 %
   2303 %  A description of each parameter follows:
   2304 %
   2305 %    o wand: the drawing wand.
   2306 %
   2307 */
   2308 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
   2309 {
   2310   assert(wand != (const DrawingWand *) NULL);
   2311   assert(wand->signature == MagickWandSignature);
   2312   if (wand->debug != MagickFalse)
   2313     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2314   return(CurrentContext->decorate);
   2315 }
   2316 
   2317 /*
   2319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2320 %                                                                             %
   2321 %                                                                             %
   2322 %                                                                             %
   2323 %   D r a w G e t T e x t D i r e c t i o n                                   %
   2324 %                                                                             %
   2325 %                                                                             %
   2326 %                                                                             %
   2327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2328 %
   2329 %  DrawGetTextDirection() returns the direction that will be used when
   2330 %  annotating with text.
   2331 %
   2332 %  The format of the DrawGetTextDirection method is:
   2333 %
   2334 %      DirectionType DrawGetTextDirection(const DrawingWand *wand)
   2335 %
   2336 %  A description of each parameter follows:
   2337 %
   2338 %    o wand: the drawing wand.
   2339 %
   2340 */
   2341 WandExport DirectionType DrawGetTextDirection(const DrawingWand *wand)
   2342 {
   2343   assert(wand != (const DrawingWand *) NULL);
   2344   assert(wand->signature == MagickWandSignature);
   2345   if (wand->debug != MagickFalse)
   2346     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2347   return(CurrentContext->direction);
   2348 }
   2349 
   2350 /*
   2352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2353 %                                                                             %
   2354 %                                                                             %
   2355 %                                                                             %
   2356 %   D r a w G e t T e x t E n c o d i n g                                     %
   2357 %                                                                             %
   2358 %                                                                             %
   2359 %                                                                             %
   2360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2361 %
   2362 %  DrawGetTextEncoding() returns a null-terminated string which specifies the
   2363 %  code set used for text annotations. The string must be freed by the user
   2364 %  once it is no longer required.
   2365 %
   2366 %  The format of the DrawGetTextEncoding method is:
   2367 %
   2368 %      char *DrawGetTextEncoding(const DrawingWand *wand)
   2369 %
   2370 %  A description of each parameter follows:
   2371 %
   2372 %    o wand: the drawing wand.
   2373 %
   2374 */
   2375 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
   2376 {
   2377   assert(wand != (const DrawingWand *) NULL);
   2378   assert(wand->signature == MagickWandSignature);
   2379   if (wand->debug != MagickFalse)
   2380     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2381   if (CurrentContext->encoding != (char *) NULL)
   2382     return((char *) AcquireString(CurrentContext->encoding));
   2383   return((char *) NULL);
   2384 }
   2385 
   2386 /*
   2388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2389 %                                                                             %
   2390 %                                                                             %
   2391 %                                                                             %
   2392 %   D r a w G e t T e x t K e r n i n g                                       %
   2393 %                                                                             %
   2394 %                                                                             %
   2395 %                                                                             %
   2396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2397 %
   2398 %  DrawGetTextKerning() gets the spacing between characters in text.
   2399 %
   2400 %  The format of the DrawSetFontKerning method is:
   2401 %
   2402 %      double DrawGetTextKerning(DrawingWand *wand)
   2403 %
   2404 %  A description of each parameter follows:
   2405 %
   2406 %    o wand: the drawing wand.
   2407 %
   2408 */
   2409 WandExport double DrawGetTextKerning(DrawingWand *wand)
   2410 {
   2411   assert(wand != (DrawingWand *) NULL);
   2412   assert(wand->signature == MagickWandSignature);
   2413 
   2414   if (wand->debug != MagickFalse)
   2415     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2416   return(CurrentContext->kerning);
   2417 }
   2418 
   2419 /*
   2421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2422 %                                                                             %
   2423 %                                                                             %
   2424 %                                                                             %
   2425 %   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                     %
   2426 %                                                                             %
   2427 %                                                                             %
   2428 %                                                                             %
   2429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2430 %
   2431 %  DrawGetTextInterlineSpacing() gets the spacing between lines in text.
   2432 %
   2433 %  The format of the DrawGetTextInterlineSpacing method is:
   2434 %
   2435 %      double DrawGetTextInterlineSpacing(DrawingWand *wand)
   2436 %
   2437 %  A description of each parameter follows:
   2438 %
   2439 %    o wand: the drawing wand.
   2440 %
   2441 */
   2442 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
   2443 {
   2444   assert(wand != (DrawingWand *) NULL);
   2445   assert(wand->signature == MagickWandSignature);
   2446   if (wand->debug != MagickFalse)
   2447     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2448   return(CurrentContext->interline_spacing);
   2449 }
   2450 
   2451 /*
   2453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2454 %                                                                             %
   2455 %                                                                             %
   2456 %                                                                             %
   2457 %   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                     %
   2458 %                                                                             %
   2459 %                                                                             %
   2460 %                                                                             %
   2461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2462 %
   2463 %  DrawGetTextInterwordSpacing() gets the spacing between words in text.
   2464 %
   2465 %  The format of the DrawSetFontKerning method is:
   2466 %
   2467 %      double DrawGetTextInterwordSpacing(DrawingWand *wand)
   2468 %
   2469 %  A description of each parameter follows:
   2470 %
   2471 %    o wand: the drawing wand.
   2472 %
   2473 */
   2474 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
   2475 {
   2476   assert(wand != (DrawingWand *) NULL);
   2477   assert(wand->signature == MagickWandSignature);
   2478   if (wand->debug != MagickFalse)
   2479     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2480   return(CurrentContext->interword_spacing);
   2481 }
   2482 
   2483 /*
   2485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2486 %                                                                             %
   2487 %                                                                             %
   2488 %                                                                             %
   2489 %   D r a w G e t V e c t o r G r a p h i c s                                 %
   2490 %                                                                             %
   2491 %                                                                             %
   2492 %                                                                             %
   2493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2494 %
   2495 %  DrawGetVectorGraphics() returns a null-terminated string which specifies the
   2496 %  vector graphics generated by any graphics calls made since the wand was
   2497 %  instantiated.  The string must be freed by the user once it is no longer
   2498 %  required.
   2499 %
   2500 %  The format of the DrawGetVectorGraphics method is:
   2501 %
   2502 %      char *DrawGetVectorGraphics(DrawingWand *wand)
   2503 %
   2504 %  A description of each parameter follows:
   2505 %
   2506 %    o wand: the drawing wand.
   2507 %
   2508 */
   2509 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
   2510 {
   2511   char
   2512     value[MagickPathExtent],
   2513     *xml;
   2514 
   2515   PixelInfo
   2516     pixel;
   2517 
   2518   register ssize_t
   2519     i;
   2520 
   2521   XMLTreeInfo
   2522     *child,
   2523     *xml_info;
   2524 
   2525   assert(wand != (const DrawingWand *) NULL);
   2526   assert(wand->signature == MagickWandSignature);
   2527   if (wand->debug != MagickFalse)
   2528     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2529   xml_info=NewXMLTreeTag("drawing-wand");
   2530   if (xml_info == (XMLTreeInfo *) NULL)
   2531     return((char *) NULL);
   2532   (void) SetXMLTreeContent(xml_info," ");
   2533   GetPixelInfo(wand->image,&pixel);
   2534   child=AddChildToXMLTree(xml_info,"clip-path",0);
   2535   if (child != (XMLTreeInfo *) NULL)
   2536     (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
   2537   child=AddChildToXMLTree(xml_info,"clip-units",0);
   2538   if (child != (XMLTreeInfo *) NULL)
   2539     {
   2540       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2541         MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),
   2542         MagickPathExtent);
   2543       (void) SetXMLTreeContent(child,value);
   2544     }
   2545   child=AddChildToXMLTree(xml_info,"decorate",0);
   2546   if (child != (XMLTreeInfo *) NULL)
   2547     {
   2548       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2549         MagickDecorateOptions,(ssize_t) CurrentContext->decorate),
   2550         MagickPathExtent);
   2551       (void) SetXMLTreeContent(child,value);
   2552     }
   2553   child=AddChildToXMLTree(xml_info,"encoding",0);
   2554   if (child != (XMLTreeInfo *) NULL)
   2555     (void) SetXMLTreeContent(child,CurrentContext->encoding);
   2556   child=AddChildToXMLTree(xml_info,"fill",0);
   2557   if (child != (XMLTreeInfo *) NULL)
   2558     {
   2559       if (CurrentContext->fill.alpha != OpaqueAlpha)
   2560         pixel.alpha_trait=CurrentContext->fill.alpha != OpaqueAlpha ?
   2561           BlendPixelTrait : UndefinedPixelTrait;
   2562       pixel=CurrentContext->fill;
   2563       GetColorTuple(&pixel,MagickTrue,value);
   2564       (void) SetXMLTreeContent(child,value);
   2565     }
   2566   child=AddChildToXMLTree(xml_info,"fill-opacity",0);
   2567   if (child != (XMLTreeInfo *) NULL)
   2568     {
   2569       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2570         (double) (QuantumScale*CurrentContext->fill.alpha));
   2571       (void) SetXMLTreeContent(child,value);
   2572     }
   2573   child=AddChildToXMLTree(xml_info,"fill-rule",0);
   2574   if (child != (XMLTreeInfo *) NULL)
   2575     {
   2576       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2577         MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),
   2578         MagickPathExtent);
   2579       (void) SetXMLTreeContent(child,value);
   2580     }
   2581   child=AddChildToXMLTree(xml_info,"font",0);
   2582   if (child != (XMLTreeInfo *) NULL)
   2583     (void) SetXMLTreeContent(child,CurrentContext->font);
   2584   child=AddChildToXMLTree(xml_info,"font-family",0);
   2585   if (child != (XMLTreeInfo *) NULL)
   2586     (void) SetXMLTreeContent(child,CurrentContext->family);
   2587   child=AddChildToXMLTree(xml_info,"font-size",0);
   2588   if (child != (XMLTreeInfo *) NULL)
   2589     {
   2590       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2591         CurrentContext->pointsize);
   2592       (void) SetXMLTreeContent(child,value);
   2593     }
   2594   child=AddChildToXMLTree(xml_info,"font-stretch",0);
   2595   if (child != (XMLTreeInfo *) NULL)
   2596     {
   2597       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2598         MagickStretchOptions,(ssize_t) CurrentContext->stretch),
   2599         MagickPathExtent);
   2600       (void) SetXMLTreeContent(child,value);
   2601     }
   2602   child=AddChildToXMLTree(xml_info,"font-style",0);
   2603   if (child != (XMLTreeInfo *) NULL)
   2604     {
   2605       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2606         MagickStyleOptions,(ssize_t) CurrentContext->style),MagickPathExtent);
   2607       (void) SetXMLTreeContent(child,value);
   2608     }
   2609   child=AddChildToXMLTree(xml_info,"font-weight",0);
   2610   if (child != (XMLTreeInfo *) NULL)
   2611     {
   2612       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
   2613         CurrentContext->weight);
   2614       (void) SetXMLTreeContent(child,value);
   2615     }
   2616   child=AddChildToXMLTree(xml_info,"gravity",0);
   2617   if (child != (XMLTreeInfo *) NULL)
   2618     {
   2619       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2620         MagickGravityOptions,(ssize_t) CurrentContext->gravity),
   2621         MagickPathExtent);
   2622       (void) SetXMLTreeContent(child,value);
   2623     }
   2624   child=AddChildToXMLTree(xml_info,"stroke",0);
   2625   if (child != (XMLTreeInfo *) NULL)
   2626     {
   2627       if (CurrentContext->stroke.alpha != OpaqueAlpha)
   2628         pixel.alpha_trait=CurrentContext->stroke.alpha != OpaqueAlpha ?
   2629           BlendPixelTrait : UndefinedPixelTrait;
   2630       pixel=CurrentContext->stroke;
   2631       GetColorTuple(&pixel,MagickTrue,value);
   2632       (void) SetXMLTreeContent(child,value);
   2633     }
   2634   child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
   2635   if (child != (XMLTreeInfo *) NULL)
   2636     {
   2637       (void) FormatLocaleString(value,MagickPathExtent,"%d",
   2638         CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
   2639       (void) SetXMLTreeContent(child,value);
   2640     }
   2641   child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
   2642   if ((child != (XMLTreeInfo *) NULL) &&
   2643       (CurrentContext->dash_pattern != (double *) NULL))
   2644     {
   2645       char
   2646         *dash_pattern;
   2647 
   2648       dash_pattern=AcquireString((char *) NULL);
   2649       for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++)
   2650       {
   2651         if (i != 0)
   2652           (void) ConcatenateString(&dash_pattern,",");
   2653         (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2654           CurrentContext->dash_pattern[i]);
   2655         (void) ConcatenateString(&dash_pattern,value);
   2656       }
   2657       (void) SetXMLTreeContent(child,dash_pattern);
   2658       dash_pattern=DestroyString(dash_pattern);
   2659     }
   2660   child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
   2661   if (child != (XMLTreeInfo *) NULL)
   2662     {
   2663       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2664         CurrentContext->dash_offset);
   2665       (void) SetXMLTreeContent(child,value);
   2666     }
   2667   child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
   2668   if (child != (XMLTreeInfo *) NULL)
   2669     {
   2670       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2671         MagickLineCapOptions,(ssize_t) CurrentContext->linecap),
   2672         MagickPathExtent);
   2673       (void) SetXMLTreeContent(child,value);
   2674     }
   2675   child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
   2676   if (child != (XMLTreeInfo *) NULL)
   2677     {
   2678       (void) CopyMagickString(value,CommandOptionToMnemonic(
   2679         MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
   2680         MagickPathExtent);
   2681       (void) SetXMLTreeContent(child,value);
   2682     }
   2683   child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
   2684   if (child != (XMLTreeInfo *) NULL)
   2685     {
   2686       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
   2687         CurrentContext->miterlimit);
   2688       (void) SetXMLTreeContent(child,value);
   2689     }
   2690   child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
   2691   if (child != (XMLTreeInfo *) NULL)
   2692     {
   2693       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2694         (double) (QuantumScale*CurrentContext->stroke.alpha));
   2695       (void) SetXMLTreeContent(child,value);
   2696     }
   2697   child=AddChildToXMLTree(xml_info,"stroke-width",0);
   2698   if (child != (XMLTreeInfo *) NULL)
   2699     {
   2700       (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   2701         CurrentContext->stroke_width);
   2702       (void) SetXMLTreeContent(child,value);
   2703     }
   2704   child=AddChildToXMLTree(xml_info,"text-align",0);
   2705   if (child != (XMLTreeInfo *) NULL)
   2706     {
   2707       (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
   2708         (ssize_t) CurrentContext->align),MagickPathExtent);
   2709       (void) SetXMLTreeContent(child,value);
   2710     }
   2711   child=AddChildToXMLTree(xml_info,"text-antialias",0);
   2712   if (child != (XMLTreeInfo *) NULL)
   2713     {
   2714       (void) FormatLocaleString(value,MagickPathExtent,"%d",
   2715         CurrentContext->text_antialias != MagickFalse ? 1 : 0);
   2716       (void) SetXMLTreeContent(child,value);
   2717     }
   2718   child=AddChildToXMLTree(xml_info,"text-undercolor",0);
   2719   if (child != (XMLTreeInfo *) NULL)
   2720     {
   2721       if (CurrentContext->undercolor.alpha != OpaqueAlpha)
   2722         pixel.alpha_trait=CurrentContext->undercolor.alpha != OpaqueAlpha ?
   2723           BlendPixelTrait : UndefinedPixelTrait;
   2724       pixel=CurrentContext->undercolor;
   2725       GetColorTuple(&pixel,MagickTrue,value);
   2726       (void) SetXMLTreeContent(child,value);
   2727     }
   2728   child=AddChildToXMLTree(xml_info,"vector-graphics",0);
   2729   if (child != (XMLTreeInfo *) NULL)
   2730     (void) SetXMLTreeContent(child,wand->mvg);
   2731   xml=XMLTreeInfoToXML(xml_info);
   2732   xml_info=DestroyXMLTree(xml_info);
   2733   return(xml);
   2734 }
   2735 
   2736 /*
   2738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2739 %                                                                             %
   2740 %                                                                             %
   2741 %                                                                             %
   2742 %   D r a w G e t T e x t U n d e r C o l o r                                 %
   2743 %                                                                             %
   2744 %                                                                             %
   2745 %                                                                             %
   2746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2747 %
   2748 %  DrawGetTextUnderColor() returns the color of a background rectangle
   2749 %  to place under text annotations.
   2750 %
   2751 %  The format of the DrawGetTextUnderColor method is:
   2752 %
   2753 %      void DrawGetTextUnderColor(const DrawingWand *wand,
   2754 %        PixelWand *under_color)
   2755 %
   2756 %  A description of each parameter follows:
   2757 %
   2758 %    o wand: the drawing wand.
   2759 %
   2760 %    o under_color: Return the under color.
   2761 %
   2762 */
   2763 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
   2764   PixelWand *under_color)
   2765 {
   2766   assert(wand != (const DrawingWand *) NULL);
   2767   assert(wand->signature == MagickWandSignature);
   2768   assert(under_color != (PixelWand *) NULL);
   2769   if (wand->debug != MagickFalse)
   2770     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2771   PixelSetPixelColor(under_color,&CurrentContext->undercolor);
   2772 }
   2773 
   2774 /*
   2776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2777 %                                                                             %
   2778 %                                                                             %
   2779 %                                                                             %
   2780 %   D r a w L i n e                                                           %
   2781 %                                                                             %
   2782 %                                                                             %
   2783 %                                                                             %
   2784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2785 %
   2786 %  DrawLine() draws a line on the image using the current stroke color,
   2787 %  stroke alpha, and stroke width.
   2788 %
   2789 %  The format of the DrawLine method is:
   2790 %
   2791 %      void DrawLine(DrawingWand *wand,const double sx,const double sy,
   2792 %        const double ex,const double ey)
   2793 %
   2794 %  A description of each parameter follows:
   2795 %
   2796 %    o wand: the drawing wand.
   2797 %
   2798 %    o sx: starting x ordinate
   2799 %
   2800 %    o sy: starting y ordinate
   2801 %
   2802 %    o ex: ending x ordinate
   2803 %
   2804 %    o ey: ending y ordinate
   2805 %
   2806 */
   2807 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
   2808   const double ex,const double ey)
   2809 {
   2810   assert(wand != (DrawingWand *) NULL);
   2811   assert(wand->signature == MagickWandSignature);
   2812   if (wand->debug != MagickFalse)
   2813     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2814   (void) MVGPrintf(wand,"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey);
   2815 }
   2816 
   2817 /*
   2819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2820 %                                                                             %
   2821 %                                                                             %
   2822 %                                                                             %
   2823 %   D r a w P a t h C l o s e                                                 %
   2824 %                                                                             %
   2825 %                                                                             %
   2826 %                                                                             %
   2827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2828 %
   2829 %  DrawPathClose() adds a path element to the current path which closes the
   2830 %  current subpath by drawing a straight line from the current point to the
   2831 %  current subpath's most recent starting point (usually, the most recent
   2832 %  moveto point).
   2833 %
   2834 %  The format of the DrawPathClose method is:
   2835 %
   2836 %      void DrawPathClose(DrawingWand *wand)
   2837 %
   2838 %  A description of each parameter follows:
   2839 %
   2840 %    o wand: the drawing wand.
   2841 %
   2842 */
   2843 WandExport void DrawPathClose(DrawingWand *wand)
   2844 {
   2845   assert(wand != (DrawingWand *) NULL);
   2846   assert(wand->signature == MagickWandSignature);
   2847   if (wand->debug != MagickFalse)
   2848     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2849   (void) MVGAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
   2850     "Z" : "z");
   2851 }
   2852 
   2853 /*
   2855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2856 %                                                                             %
   2857 %                                                                             %
   2858 %                                                                             %
   2859 %   D r a w P a t h C u r v e T o A b s o l u t e                             %
   2860 %                                                                             %
   2861 %                                                                             %
   2862 %                                                                             %
   2863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2864 %
   2865 %  DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
   2866 %  point to (x,y) using (x1,y1) as the control point at the beginning of
   2867 %  the curve and (x2,y2) as the control point at the end of the curve using
   2868 %  absolute coordinates. At the end of the command, the new current point
   2869 %  becomes the final (x,y) coordinate pair used in the polybezier.
   2870 %
   2871 %  The format of the DrawPathCurveToAbsolute method is:
   2872 %
   2873 %      void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
   2874 %        const double y1,const double x2,const double y2,const double x,
   2875 %        const double y)
   2876 %
   2877 %  A description of each parameter follows:
   2878 %
   2879 %    o wand: the drawing wand.
   2880 %
   2881 %    o x1: x ordinate of control point for curve beginning
   2882 %
   2883 %    o y1: y ordinate of control point for curve beginning
   2884 %
   2885 %    o x2: x ordinate of control point for curve ending
   2886 %
   2887 %    o y2: y ordinate of control point for curve ending
   2888 %
   2889 %    o x: x ordinate of the end of the curve
   2890 %
   2891 %    o y: y ordinate of the end of the curve
   2892 %
   2893 */
   2894 
   2895 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
   2896   const double x1,const double y1,const double x2,const double y2,
   2897   const double x,const double y)
   2898 {
   2899   assert(wand != (DrawingWand *) NULL);
   2900   assert(wand->signature == MagickWandSignature);
   2901   if (wand->debug != MagickFalse)
   2902     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2903   if ((wand->path_operation != PathCurveToOperation) ||
   2904       (wand->path_mode != mode))
   2905     {
   2906       wand->path_operation=PathCurveToOperation;
   2907       wand->path_mode=mode;
   2908       (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g %.20g %.20g",
   2909         mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
   2910     }
   2911   else
   2912     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1,
   2913       x2,y2,x,y);
   2914 }
   2915 
   2916 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
   2917   const double y1,const double x2,const double y2,const double x,const double y)
   2918 {
   2919   assert(wand != (DrawingWand *) NULL);
   2920   assert(wand->signature == MagickWandSignature);
   2921   if (wand->debug != MagickFalse)
   2922     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2923   DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
   2924 }
   2925 
   2926 /*
   2928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2929 %                                                                             %
   2930 %                                                                             %
   2931 %                                                                             %
   2932 %   D r a w P a t h C u r v e T o R e l a t i v e                             %
   2933 %                                                                             %
   2934 %                                                                             %
   2935 %                                                                             %
   2936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2937 %
   2938 %  DrawPathCurveToRelative() draws a cubic Bezier curve from the current
   2939 %  point to (x,y) using (x1,y1) as the control point at the beginning of
   2940 %  the curve and (x2,y2) as the control point at the end of the curve using
   2941 %  relative coordinates. At the end of the command, the new current point
   2942 %  becomes the final (x,y) coordinate pair used in the polybezier.
   2943 %
   2944 %  The format of the DrawPathCurveToRelative method is:
   2945 %
   2946 %      void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
   2947 %        const double y1,const double x2,const double y2,const double x,
   2948 %        const double y)
   2949 %
   2950 %  A description of each parameter follows:
   2951 %
   2952 %    o wand: the drawing wand.
   2953 %
   2954 %    o x1: x ordinate of control point for curve beginning
   2955 %
   2956 %    o y1: y ordinate of control point for curve beginning
   2957 %
   2958 %    o x2: x ordinate of control point for curve ending
   2959 %
   2960 %    o y2: y ordinate of control point for curve ending
   2961 %
   2962 %    o x: x ordinate of the end of the curve
   2963 %
   2964 %    o y: y ordinate of the end of the curve
   2965 %
   2966 */
   2967 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
   2968   const double y1,const double x2,const double y2,const double x,const double y)
   2969 {
   2970   assert(wand != (DrawingWand *) NULL);
   2971   assert(wand->signature == MagickWandSignature);
   2972   if (wand->debug != MagickFalse)
   2973     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   2974   DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
   2975 }
   2976 
   2977 /*
   2979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2980 %                                                                             %
   2981 %                                                                             %
   2982 %                                                                             %
   2983 % 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 %
   2984 %                                                                             %
   2985 %                                                                             %
   2986 %                                                                             %
   2987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2988 %
   2989 %  DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
   2990 %  from the current point to (x,y) using (x1,y1) as the control point using
   2991 %  absolute coordinates. At the end of the command, the new current point
   2992 %  becomes the final (x,y) coordinate pair used in the polybezier.
   2993 %
   2994 %  The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
   2995 %
   2996 %      void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
   2997 %        const double x1,const double y1,onst double x,const double y)
   2998 %
   2999 %  A description of each parameter follows:
   3000 %
   3001 %    o wand: the drawing wand.
   3002 %
   3003 %    o x1: x ordinate of the control point
   3004 %
   3005 %    o y1: y ordinate of the control point
   3006 %
   3007 %    o x: x ordinate of final point
   3008 %
   3009 %    o y: y ordinate of final point
   3010 %
   3011 */
   3012 
   3013 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
   3014   const PathMode mode,const double x1,double y1,const double x,const double y)
   3015 {
   3016   assert(wand != (DrawingWand *) NULL);
   3017   assert(wand->signature == MagickWandSignature);
   3018   if (wand->debug != MagickFalse)
   3019     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3020   if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
   3021       (wand->path_mode != mode))
   3022     {
   3023       wand->path_operation=PathCurveToQuadraticBezierOperation;
   3024       wand->path_mode=mode;
   3025       (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g",
   3026          mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
   3027     }
   3028   else
   3029     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x1,y1,x,y);
   3030 }
   3031 
   3032 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
   3033   const double x1,const double y1,const double x,const double y)
   3034 {
   3035   assert(wand != (DrawingWand *) NULL);
   3036   assert(wand->signature == MagickWandSignature);
   3037   if (wand->debug != MagickFalse)
   3038     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3039   DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
   3040 }
   3041 
   3042 /*
   3044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3045 %                                                                             %
   3046 %                                                                             %
   3047 %                                                                             %
   3048 % 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 %
   3049 %                                                                             %
   3050 %                                                                             %
   3051 %                                                                             %
   3052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3053 %
   3054 %  DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
   3055 %  from the current point to (x,y) using (x1,y1) as the control point using
   3056 %  relative coordinates. At the end of the command, the new current point
   3057 %  becomes the final (x,y) coordinate pair used in the polybezier.
   3058 %
   3059 %  The format of the DrawPathCurveToQuadraticBezierRelative method is:
   3060 %
   3061 %      void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
   3062 %        const double x1,const double y1,const double x,const double y)
   3063 %
   3064 %  A description of each parameter follows:
   3065 %
   3066 %    o wand: the drawing wand.
   3067 %
   3068 %    o x1: x ordinate of the control point
   3069 %
   3070 %    o y1: y ordinate of the control point
   3071 %
   3072 %    o x: x ordinate of final point
   3073 %
   3074 %    o y: y ordinate of final point
   3075 %
   3076 */
   3077 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
   3078   const double x1,const double y1,const double x,const double y)
   3079 {
   3080   assert(wand != (DrawingWand *) NULL);
   3081   assert(wand->signature == MagickWandSignature);
   3082   if (wand->debug != MagickFalse)
   3083     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3084   DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
   3085 }
   3086 
   3087 /*
   3089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3090 %                                                                             %
   3091 %                                                                             %
   3092 %                                                                             %
   3093 %   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   %
   3094 %                                                                             %
   3095 %                                                                             %
   3096 %                                                                             %
   3097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3098 %
   3099 %  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
   3100 %  Bezier curve (using absolute coordinates) from the current point to
   3101 %  (x,y). The control point is assumed to be the reflection of the
   3102 %  control point on the previous command relative to the current
   3103 %  point. (If there is no previous command or if the previous command was
   3104 %  not a DrawPathCurveToQuadraticBezierAbsolute,
   3105 %  DrawPathCurveToQuadraticBezierRelative,
   3106 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
   3107 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
   3108 %  is coincident with the current point.). At the end of the command, the
   3109 %  new current point becomes the final (x,y) coordinate pair used in the
   3110 %  polybezier.
   3111 %
   3112 %  The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
   3113 %
   3114 %      void DrawPathCurveToQuadraticBezierSmoothAbsolute(
   3115 %        DrawingWand *wand,const double x,const double y)
   3116 %
   3117 %  A description of each parameter follows:
   3118 %
   3119 %    o wand: the drawing wand.
   3120 %
   3121 %    o x: x ordinate of final point
   3122 %
   3123 %    o y: y ordinate of final point
   3124 %
   3125 */
   3126 
   3127 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
   3128   const PathMode mode,const double x,const double y)
   3129 {
   3130   assert(wand != (DrawingWand *) NULL);
   3131   assert(wand->signature == MagickWandSignature);
   3132   if (wand->debug != MagickFalse)
   3133     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3134   if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
   3135       (wand->path_mode != mode))
   3136     {
   3137       wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
   3138       wand->path_mode=mode;
   3139       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
   3140         'T' : 't',x,y);
   3141     }
   3142   else
   3143     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
   3144 }
   3145 
   3146 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
   3147   const double x,const double y)
   3148 {
   3149   assert(wand != (DrawingWand *) NULL);
   3150   assert(wand->signature == MagickWandSignature);
   3151   if (wand->debug != MagickFalse)
   3152     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3153   DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
   3154 }
   3155 
   3156 /*
   3158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3159 %                                                                             %
   3160 %                                                                             %
   3161 %                                                                             %
   3162 %   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   %
   3163 %                                                                             %
   3164 %                                                                             %
   3165 %                                                                             %
   3166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3167 %
   3168 %  DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic Bezier
   3169 %  curve (using relative coordinates) from the current point to (x,y). The
   3170 %  control point is assumed to be the reflection of the control point on the
   3171 %  previous command relative to the current point. (If there is no previous
   3172 %  command or if the previous command was not a
   3173 %  DrawPathCurveToQuadraticBezierAbsolute,
   3174 %  DrawPathCurveToQuadraticBezierRelative,
   3175 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
   3176 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
   3177 %  coincident with the current point.). At the end of the command, the new
   3178 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
   3179 %
   3180 %  The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
   3181 %
   3182 %      void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
   3183 %        const double x,const double y)
   3184 %
   3185 %  A description of each parameter follows:
   3186 %
   3187 %    o wand: the drawing wand.
   3188 %
   3189 %    o x: x ordinate of final point
   3190 %
   3191 %    o y: y ordinate of final point
   3192 %
   3193 */
   3194 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
   3195   const double x,const double y)
   3196 {
   3197   DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
   3198 }
   3199 
   3200 /*
   3202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3203 %                                                                             %
   3204 %                                                                             %
   3205 %                                                                             %
   3206 %   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                 %
   3207 %                                                                             %
   3208 %                                                                             %
   3209 %                                                                             %
   3210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3211 %
   3212 %  DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
   3213 %  current point to (x,y) using absolute coordinates. The first control
   3214 %  point is assumed to be the reflection of the second control point on
   3215 %  the previous command relative to the current point. (If there is no
   3216 %  previous command or if the previous command was not an
   3217 %  DrawPathCurveToAbsolute, DrawPathCurveToRelative,
   3218 %  DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
   3219 %  the first control point is coincident with the current point.) (x2,y2)
   3220 %  is the second control point (i.e., the control point at the end of the
   3221 %  curve). At the end of the command, the new current point becomes the
   3222 %  final (x,y) coordinate pair used in the polybezier.
   3223 %
   3224 %  The format of the DrawPathCurveToSmoothAbsolute method is:
   3225 %
   3226 %      void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
   3227 %        const double x2,const double y2,const double x,const double y)
   3228 %
   3229 %  A description of each parameter follows:
   3230 %
   3231 %    o wand: the drawing wand.
   3232 %
   3233 %    o x2: x ordinate of second control point
   3234 %
   3235 %    o y2: y ordinate of second control point
   3236 %
   3237 %    o x: x ordinate of termination point
   3238 %
   3239 %    o y: y ordinate of termination point
   3240 %
   3241 */
   3242 
   3243 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
   3244   const double x2,const double y2,const double x,const double y)
   3245 {
   3246   assert(wand != (DrawingWand *) NULL);
   3247   assert(wand->signature == MagickWandSignature);
   3248   if (wand->debug != MagickFalse)
   3249     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3250   if ((wand->path_operation != PathCurveToSmoothOperation) ||
   3251       (wand->path_mode != mode))
   3252     {
   3253       wand->path_operation=PathCurveToSmoothOperation;
   3254       wand->path_mode=mode;
   3255       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g %.20g %.20g",
   3256         mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
   3257     }
   3258   else
   3259     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x2,y2,x,y);
   3260 }
   3261 
   3262 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
   3263   const double y2,const double x,const double y)
   3264 {
   3265   assert(wand != (DrawingWand *) NULL);
   3266   assert(wand->signature == MagickWandSignature);
   3267   if (wand->debug != MagickFalse)
   3268     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3269   DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
   3270 }
   3271 
   3272 /*
   3274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3275 %                                                                             %
   3276 %                                                                             %
   3277 %                                                                             %
   3278 %   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                 %
   3279 %                                                                             %
   3280 %                                                                             %
   3281 %                                                                             %
   3282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3283 %
   3284 %  DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
   3285 %  point to (x,y) using relative coordinates. The first control point is
   3286 %  assumed to be the reflection of the second control point on the previous
   3287 %  command relative to the current point. (If there is no previous command or
   3288 %  if the previous command was not an DrawPathCurveToAbsolute,
   3289 %  DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
   3290 %  DrawPathCurveToSmoothRelative, assume the first control point is coincident
   3291 %  with the current point.) (x2,y2) is the second control point (i.e., the
   3292 %  control point at the end of the curve). At the end of the command, the new
   3293 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
   3294 %
   3295 %  The format of the DrawPathCurveToSmoothRelative method is:
   3296 %
   3297 %      void DrawPathCurveToSmoothRelative(DrawingWand *wand,
   3298 %        const double x2,const double y2,const double x,const double y)
   3299 %
   3300 %  A description of each parameter follows:
   3301 %
   3302 %    o wand: the drawing wand.
   3303 %
   3304 %    o x2: x ordinate of second control point
   3305 %
   3306 %    o y2: y ordinate of second control point
   3307 %
   3308 %    o x: x ordinate of termination point
   3309 %
   3310 %    o y: y ordinate of termination point
   3311 %
   3312 */
   3313 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
   3314   const double y2,const double x,const double y)
   3315 {
   3316   assert(wand != (DrawingWand *) NULL);
   3317   assert(wand->signature == MagickWandSignature);
   3318   if (wand->debug != MagickFalse)
   3319     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3320   DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
   3321 }
   3322 
   3323 /*
   3325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3326 %                                                                             %
   3327 %                                                                             %
   3328 %                                                                             %
   3329 %   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                     %
   3330 %                                                                             %
   3331 %                                                                             %
   3332 %                                                                             %
   3333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3334 %
   3335 %  DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
   3336 %  to (x, y) using absolute coordinates. The size and orientation of the
   3337 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
   3338 %  indicates how the ellipse as a whole is rotated relative to the current
   3339 %  coordinate system. The center (cx, cy) of the ellipse is calculated
   3340 %  automagically to satisfy the constraints imposed by the other parameters.
   3341 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
   3342 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
   3343 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
   3344 %  clock-wise rotation.
   3345 %
   3346 %  The format of the DrawPathEllipticArcAbsolute method is:
   3347 %
   3348 %      void DrawPathEllipticArcAbsolute(DrawingWand *wand,
   3349 %        const double rx,const double ry,const double x_axis_rotation,
   3350 %        const MagickBooleanType large_arc_flag,
   3351 %        const MagickBooleanType sweep_flag,const double x,const double y)
   3352 %
   3353 %  A description of each parameter follows:
   3354 %
   3355 %    o wand: the drawing wand.
   3356 %
   3357 %    o rx: x radius
   3358 %
   3359 %    o ry: y radius
   3360 %
   3361 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
   3362 %        relative to the current coordinate system
   3363 %
   3364 %    o large_arc_flag: If non-zero (true) then draw the larger of the
   3365 %        available arcs
   3366 %
   3367 %    o sweep_flag: If non-zero (true) then draw the arc matching a
   3368 %        clock-wise rotation
   3369 %
   3370 %
   3371 */
   3372 
   3373 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
   3374   const double rx,const double ry,const double x_axis_rotation,
   3375   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
   3376   const double x,const double y)
   3377 {
   3378   assert(wand != (DrawingWand *) NULL);
   3379   assert(wand->signature == MagickWandSignature);
   3380   if (wand->debug != MagickFalse)
   3381     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3382   if ((wand->path_operation != PathEllipticArcOperation) ||
   3383       (wand->path_mode != mode))
   3384     {
   3385       wand->path_operation=PathEllipticArcOperation;
   3386       wand->path_mode=mode;
   3387       (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %u %u %.20g %.20g",
   3388         mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
   3389         large_arc_flag,sweep_flag,x,y);
   3390     }
   3391   else
   3392     (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry,
   3393       x_axis_rotation,large_arc_flag,sweep_flag,x,y);
   3394 }
   3395 
   3396 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
   3397   const double ry,const double x_axis_rotation,
   3398   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
   3399   const double x,const double y)
   3400 {
   3401   assert(wand != (DrawingWand *) NULL);
   3402   assert(wand->signature == MagickWandSignature);
   3403   if (wand->debug != MagickFalse)
   3404     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3405   DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
   3406     large_arc_flag,sweep_flag,x,y);
   3407 }
   3408 
   3409 /*
   3411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3412 %                                                                             %
   3413 %                                                                             %
   3414 %                                                                             %
   3415 %   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                     %
   3416 %                                                                             %
   3417 %                                                                             %
   3418 %                                                                             %
   3419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3420 %
   3421 %  DrawPathEllipticArcRelative() draws an elliptical arc from the current point
   3422 %  to (x, y) using relative coordinates. The size and orientation of the
   3423 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
   3424 %  indicates how the ellipse as a whole is rotated relative to the current
   3425 %  coordinate system. The center (cx, cy) of the ellipse is calculated
   3426 %  automagically to satisfy the constraints imposed by the other parameters.
   3427 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
   3428 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
   3429 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
   3430 %  clock-wise rotation.
   3431 %
   3432 %  The format of the DrawPathEllipticArcRelative method is:
   3433 %
   3434 %      void DrawPathEllipticArcRelative(DrawingWand *wand,
   3435 %        const double rx,const double ry,const double x_axis_rotation,
   3436 %        const MagickBooleanType large_arc_flag,
   3437 %        const MagickBooleanType sweep_flag,const double x,const double y)
   3438 %
   3439 %  A description of each parameter follows:
   3440 %
   3441 %    o wand: the drawing wand.
   3442 %
   3443 %    o rx: x radius
   3444 %
   3445 %    o ry: y radius
   3446 %
   3447 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
   3448 %                       relative to the current coordinate system
   3449 %
   3450 %    o large_arc_flag: If non-zero (true) then draw the larger of the
   3451 %                      available arcs
   3452 %
   3453 %    o sweep_flag: If non-zero (true) then draw the arc matching a
   3454 %                  clock-wise rotation
   3455 %
   3456 */
   3457 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
   3458   const double ry,const double x_axis_rotation,
   3459   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
   3460   const double x,const double y)
   3461 {
   3462   DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
   3463     large_arc_flag,sweep_flag,x,y);
   3464 }
   3465 
   3466 /*
   3468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3469 %                                                                             %
   3470 %                                                                             %
   3471 %                                                                             %
   3472 %   D r a w P a t h F i n i s h                                               %
   3473 %                                                                             %
   3474 %                                                                             %
   3475 %                                                                             %
   3476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3477 %
   3478 %  DrawPathFinish() terminates the current path.
   3479 %
   3480 %  The format of the DrawPathFinish method is:
   3481 %
   3482 %      void DrawPathFinish(DrawingWand *wand)
   3483 %
   3484 %  A description of each parameter follows:
   3485 %
   3486 %    o wand: the drawing wand.
   3487 %
   3488 */
   3489 WandExport void DrawPathFinish(DrawingWand *wand)
   3490 {
   3491   assert(wand != (DrawingWand *) NULL);
   3492   assert(wand->signature == MagickWandSignature);
   3493   if (wand->debug != MagickFalse)
   3494     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3495   (void) MVGPrintf(wand,"'\n");
   3496   wand->path_operation=PathDefaultOperation;
   3497   wand->path_mode=DefaultPathMode;
   3498 }
   3499 
   3500 /*
   3502 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3503 %                                                                             %
   3504 %                                                                             %
   3505 %                                                                             %
   3506 %   D r a w P a t h L i n e T o A b s o l u t e                               %
   3507 %                                                                             %
   3508 %                                                                             %
   3509 %                                                                             %
   3510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3511 %
   3512 %  DrawPathLineToAbsolute() draws a line path from the current point to the
   3513 %  given coordinate using absolute coordinates. The coordinate then becomes
   3514 %  the new current point.
   3515 %
   3516 %  The format of the DrawPathLineToAbsolute method is:
   3517 %
   3518 %      void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
   3519 %        const double y)
   3520 %
   3521 %  A description of each parameter follows:
   3522 %
   3523 %    o wand: the drawing wand.
   3524 %
   3525 %    o x: target x ordinate
   3526 %
   3527 %    o y: target y ordinate
   3528 %
   3529 */
   3530 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
   3531   const double x,const double y)
   3532 {
   3533   assert(wand != (DrawingWand *) NULL);
   3534   assert(wand->signature == MagickWandSignature);
   3535   if (wand->debug != MagickFalse)
   3536     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3537   if ((wand->path_operation != PathLineToOperation) ||
   3538       (wand->path_mode != mode))
   3539     {
   3540       wand->path_operation=PathLineToOperation;
   3541       wand->path_mode=mode;
   3542       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
   3543         'L' : 'l',x,y);
   3544     }
   3545   else
   3546     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
   3547 }
   3548 
   3549 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
   3550   const double y)
   3551 {
   3552   assert(wand != (DrawingWand *) NULL);
   3553   assert(wand->signature == MagickWandSignature);
   3554   if (wand->debug != MagickFalse)
   3555     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3556   DrawPathLineTo(wand,AbsolutePathMode,x,y);
   3557 }
   3558 
   3559 /*
   3561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3562 %                                                                             %
   3563 %                                                                             %
   3564 %                                                                             %
   3565 %   D r a w P a t h L i n e T o R e l a t i v e                               %
   3566 %                                                                             %
   3567 %                                                                             %
   3568 %                                                                             %
   3569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3570 %
   3571 %  DrawPathLineToRelative() draws a line path from the current point to the
   3572 %  given coordinate using relative coordinates. The coordinate then becomes
   3573 %  the new current point.
   3574 %
   3575 %  The format of the DrawPathLineToRelative method is:
   3576 %
   3577 %      void DrawPathLineToRelative(DrawingWand *wand,const double x,
   3578 %        const double y)
   3579 %
   3580 %  A description of each parameter follows:
   3581 %
   3582 %    o wand: the drawing wand.
   3583 %
   3584 %    o x: target x ordinate
   3585 %
   3586 %    o y: target y ordinate
   3587 %
   3588 */
   3589 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
   3590   const double y)
   3591 {
   3592   assert(wand != (DrawingWand *) NULL);
   3593   assert(wand->signature == MagickWandSignature);
   3594   if (wand->debug != MagickFalse)
   3595     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3596   DrawPathLineTo(wand,RelativePathMode,x,y);
   3597 }
   3598 
   3599 /*
   3601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3602 %                                                                             %
   3603 %                                                                             %
   3604 %                                                                             %
   3605 %   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           %
   3606 %                                                                             %
   3607 %                                                                             %
   3608 %                                                                             %
   3609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3610 %
   3611 %  DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
   3612 %  current point to the target point using absolute coordinates.  The target
   3613 %  point then becomes the new current point.
   3614 %
   3615 %  The format of the DrawPathLineToHorizontalAbsolute method is:
   3616 %
   3617 %      void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,const double x)
   3618 %
   3619 %  A description of each parameter follows:
   3620 %
   3621 %    o wand: the drawing wand.
   3622 %
   3623 %    o x: target x ordinate
   3624 %
   3625 */
   3626 
   3627 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
   3628   const double x)
   3629 {
   3630   assert(wand != (DrawingWand *) NULL);
   3631   assert(wand->signature == MagickWandSignature);
   3632   if (wand->debug != MagickFalse)
   3633     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3634   if ((wand->path_operation != PathLineToHorizontalOperation) ||
   3635       (wand->path_mode != mode))
   3636     {
   3637       wand->path_operation=PathLineToHorizontalOperation;
   3638       wand->path_mode=mode;
   3639       (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
   3640         'H' : 'h',x);
   3641     }
   3642   else
   3643     (void) MVGAutoWrapPrintf(wand," %.20g",x);
   3644 }
   3645 
   3646 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
   3647   const double x)
   3648 {
   3649   assert(wand != (DrawingWand *) NULL);
   3650   assert(wand->signature == MagickWandSignature);
   3651   if (wand->debug != MagickFalse)
   3652     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3653   DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
   3654 }
   3655 
   3656 /*
   3658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3659 %                                                                             %
   3660 %                                                                             %
   3661 %                                                                             %
   3662 %   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           %
   3663 %                                                                             %
   3664 %                                                                             %
   3665 %                                                                             %
   3666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3667 %
   3668 %  DrawPathLineToHorizontalRelative() draws a horizontal line path from the
   3669 %  current point to the target point using relative coordinates.  The target
   3670 %  point then becomes the new current point.
   3671 %
   3672 %  The format of the DrawPathLineToHorizontalRelative method is:
   3673 %
   3674 %      void DrawPathLineToHorizontalRelative(DrawingWand *wand,
   3675 %        const double x)
   3676 %
   3677 %  A description of each parameter follows:
   3678 %
   3679 %    o wand: the drawing wand.
   3680 %
   3681 %    o x: target x ordinate
   3682 %
   3683 */
   3684 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
   3685   const double x)
   3686 {
   3687   DrawPathLineToHorizontal(wand,RelativePathMode,x);
   3688 }
   3689 
   3690 /*
   3692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3693 %                                                                             %
   3694 %                                                                             %
   3695 %                                                                             %
   3696 %   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               %
   3697 %                                                                             %
   3698 %                                                                             %
   3699 %                                                                             %
   3700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3701 %
   3702 %  DrawPathLineToVerticalAbsolute() draws a vertical line path from the
   3703 %  current point to the target point using absolute coordinates.  The target
   3704 %  point then becomes the new current point.
   3705 %
   3706 %  The format of the DrawPathLineToVerticalAbsolute method is:
   3707 %
   3708 %      void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
   3709 %        const double y)
   3710 %
   3711 %  A description of each parameter follows:
   3712 %
   3713 %    o wand: the drawing wand.
   3714 %
   3715 %    o y: target y ordinate
   3716 %
   3717 */
   3718 
   3719 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
   3720   const double y)
   3721 {
   3722   assert(wand != (DrawingWand *) NULL);
   3723   assert(wand->signature == MagickWandSignature);
   3724   if (wand->debug != MagickFalse)
   3725     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3726   if ((wand->path_operation != PathLineToVerticalOperation) ||
   3727       (wand->path_mode != mode))
   3728     {
   3729       wand->path_operation=PathLineToVerticalOperation;
   3730       wand->path_mode=mode;
   3731       (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
   3732         'V' : 'v',y);
   3733     }
   3734   else
   3735     (void) MVGAutoWrapPrintf(wand," %.20g",y);
   3736 }
   3737 
   3738 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
   3739 {
   3740   assert(wand != (DrawingWand *) NULL);
   3741   assert(wand->signature == MagickWandSignature);
   3742   if (wand->debug != MagickFalse)
   3743     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3744   DrawPathLineToVertical(wand,AbsolutePathMode,y);
   3745 }
   3746 
   3747 /*
   3749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3750 %                                                                             %
   3751 %                                                                             %
   3752 %                                                                             %
   3753 %   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               %
   3754 %                                                                             %
   3755 %                                                                             %
   3756 %                                                                             %
   3757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3758 %
   3759 %  DrawPathLineToVerticalRelative() draws a vertical line path from the
   3760 %  current point to the target point using relative coordinates.  The target
   3761 %  point then becomes the new current point.
   3762 %
   3763 %  The format of the DrawPathLineToVerticalRelative method is:
   3764 %
   3765 %      void DrawPathLineToVerticalRelative(DrawingWand *wand,
   3766 %        const double y)
   3767 %
   3768 %  A description of each parameter follows:
   3769 %
   3770 %    o wand: the drawing wand.
   3771 %
   3772 %    o y: target y ordinate
   3773 %
   3774 */
   3775 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
   3776 {
   3777   assert(wand != (DrawingWand *) NULL);
   3778   assert(wand->signature == MagickWandSignature);
   3779   if (wand->debug != MagickFalse)
   3780     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3781   DrawPathLineToVertical(wand,RelativePathMode,y);
   3782 }
   3783 /*
   3784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3785 %                                                                             %
   3786 %                                                                             %
   3787 %                                                                             %
   3788 %   D r a w P a t h M o v e T o A b s o l u t e                               %
   3789 %                                                                             %
   3790 %                                                                             %
   3791 %                                                                             %
   3792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3793 %
   3794 %  DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
   3795 %  using absolute coordinates. The current point then becomes the
   3796 %  specified coordinate.
   3797 %
   3798 %  The format of the DrawPathMoveToAbsolute method is:
   3799 %
   3800 %      void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
   3801 %        const double y)
   3802 %
   3803 %  A description of each parameter follows:
   3804 %
   3805 %    o wand: the drawing wand.
   3806 %
   3807 %    o x: target x ordinate
   3808 %
   3809 %    o y: target y ordinate
   3810 %
   3811 */
   3812 
   3813 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
   3814   const double y)
   3815 {
   3816   assert(wand != (DrawingWand *) NULL);
   3817   assert(wand->signature == MagickWandSignature);
   3818   if (wand->debug != MagickFalse)
   3819     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3820   if ((wand->path_operation != PathMoveToOperation) ||
   3821       (wand->path_mode != mode))
   3822     {
   3823       wand->path_operation=PathMoveToOperation;
   3824       wand->path_mode=mode;
   3825       (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
   3826         'M' : 'm',x,y);
   3827     }
   3828   else
   3829     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
   3830 }
   3831 
   3832 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
   3833   const double y)
   3834 {
   3835   assert(wand != (DrawingWand *) NULL);
   3836   assert(wand->signature == MagickWandSignature);
   3837   if (wand->debug != MagickFalse)
   3838     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3839   DrawPathMoveTo(wand,AbsolutePathMode,x,y);
   3840 }
   3841 
   3842 /*
   3844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3845 %                                                                             %
   3846 %                                                                             %
   3847 %                                                                             %
   3848 %   D r a w P a t h M o v e T o R e l a t i v e                               %
   3849 %                                                                             %
   3850 %                                                                             %
   3851 %                                                                             %
   3852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3853 %
   3854 %  DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
   3855 %  relative coordinates. The current point then becomes the specified
   3856 %  coordinate.
   3857 %
   3858 %  The format of the DrawPathMoveToRelative method is:
   3859 %
   3860 %      void DrawPathMoveToRelative(DrawingWand *wand,const double x,
   3861 %        const double y)
   3862 %
   3863 %  A description of each parameter follows:
   3864 %
   3865 %    o wand: the drawing wand.
   3866 %
   3867 %    o x: target x ordinate
   3868 %
   3869 %    o y: target y ordinate
   3870 %
   3871 */
   3872 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
   3873   const double y)
   3874 {
   3875   assert(wand != (DrawingWand *) NULL);
   3876   assert(wand->signature == MagickWandSignature);
   3877   if (wand->debug != MagickFalse)
   3878     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3879   DrawPathMoveTo(wand,RelativePathMode,x,y);
   3880 }
   3881 
   3882 /*
   3884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3885 %                                                                             %
   3886 %                                                                             %
   3887 %                                                                             %
   3888 %   D r a w P a t h S t a r t                                                 %
   3889 %                                                                             %
   3890 %                                                                             %
   3891 %                                                                             %
   3892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3893 %
   3894 %  DrawPathStart() declares the start of a path drawing list which is terminated
   3895 %  by a matching DrawPathFinish() command. All other DrawPath commands must
   3896 %  be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
   3897 %  is because path drawing commands are subordinate commands and they do not
   3898 %  function by themselves.
   3899 %
   3900 %  The format of the DrawPathStart method is:
   3901 %
   3902 %      void DrawPathStart(DrawingWand *wand)
   3903 %
   3904 %  A description of each parameter follows:
   3905 %
   3906 %    o wand: the drawing wand.
   3907 %
   3908 */
   3909 WandExport void DrawPathStart(DrawingWand *wand)
   3910 {
   3911   assert(wand != (DrawingWand *) NULL);
   3912   assert(wand->signature == MagickWandSignature);
   3913   if (wand->debug != MagickFalse)
   3914     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3915   (void) MVGPrintf(wand,"path '");
   3916   wand->path_operation=PathDefaultOperation;
   3917   wand->path_mode=DefaultPathMode;
   3918 }
   3919 
   3920 /*
   3922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3923 %                                                                             %
   3924 %                                                                             %
   3925 %                                                                             %
   3926 %   D r a w P o i n t                                                         %
   3927 %                                                                             %
   3928 %                                                                             %
   3929 %                                                                             %
   3930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3931 %
   3932 %  DrawPoint() draws a point using the current fill color.
   3933 %
   3934 %  The format of the DrawPoint method is:
   3935 %
   3936 %      void DrawPoint(DrawingWand *wand,const double x,const double y)
   3937 %
   3938 %  A description of each parameter follows:
   3939 %
   3940 %    o wand: the drawing wand.
   3941 %
   3942 %    o x: target x coordinate
   3943 %
   3944 %    o y: target y coordinate
   3945 %
   3946 */
   3947 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
   3948 {
   3949   assert(wand != (DrawingWand *) NULL);
   3950   assert(wand->signature == MagickWandSignature);
   3951   if (wand->debug != MagickFalse)
   3952     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3953   (void) MVGPrintf(wand,"point %.20g %.20g\n",x,y);
   3954 }
   3955 
   3956 /*
   3958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3959 %                                                                             %
   3960 %                                                                             %
   3961 %                                                                             %
   3962 %   D r a w P o l y g o n                                                     %
   3963 %                                                                             %
   3964 %                                                                             %
   3965 %                                                                             %
   3966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3967 %
   3968 %  DrawPolygon() draws a polygon using the current stroke, stroke width, and
   3969 %  fill color or texture, using the specified array of coordinates.
   3970 %
   3971 %  The format of the DrawPolygon method is:
   3972 %
   3973 %      void DrawPolygon(DrawingWand *wand,
   3974 %        const size_t number_coordinates,const PointInfo *coordinates)
   3975 %
   3976 %  A description of each parameter follows:
   3977 %
   3978 %    o wand: the drawing wand.
   3979 %
   3980 %    o number_coordinates: number of coordinates
   3981 %
   3982 %    o coordinates: coordinate array
   3983 %
   3984 */
   3985 WandExport void DrawPolygon(DrawingWand *wand,
   3986   const size_t number_coordinates,const PointInfo *coordinates)
   3987 {
   3988   assert(wand != (DrawingWand *) NULL);
   3989   assert(wand->signature == MagickWandSignature);
   3990   if (wand->debug != MagickFalse)
   3991     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   3992   MVGAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
   3993 }
   3994 
   3995 /*
   3997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3998 %                                                                             %
   3999 %                                                                             %
   4000 %                                                                             %
   4001 %   D r a w P o l y l i n e                                                   %
   4002 %                                                                             %
   4003 %                                                                             %
   4004 %                                                                             %
   4005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4006 %
   4007 %  DrawPolyline() draws a polyline using the current stroke, stroke width, and
   4008 %  fill color or texture, using the specified array of coordinates.
   4009 %
   4010 %  The format of the DrawPolyline method is:
   4011 %
   4012 %      void DrawPolyline(DrawingWand *wand,
   4013 %        const size_t number_coordinates,const PointInfo *coordinates)
   4014 %
   4015 %  A description of each parameter follows:
   4016 %
   4017 %    o wand: the drawing wand.
   4018 %
   4019 %    o number_coordinates: number of coordinates
   4020 %
   4021 %    o coordinates: coordinate array
   4022 %
   4023 */
   4024 WandExport void DrawPolyline(DrawingWand *wand,
   4025   const size_t number_coordinates,const PointInfo *coordinates)
   4026 {
   4027   assert(wand != (DrawingWand *) NULL);
   4028   assert(wand->signature == MagickWandSignature);
   4029   if (wand->debug != MagickFalse)
   4030     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4031   MVGAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
   4032 }
   4033 
   4034 /*
   4036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4037 %                                                                             %
   4038 %                                                                             %
   4039 %                                                                             %
   4040 %   D r a w P o p C l i p P a t h                                             %
   4041 %                                                                             %
   4042 %                                                                             %
   4043 %                                                                             %
   4044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4045 %
   4046 %  DrawPopClipPath() terminates a clip path definition.
   4047 %
   4048 %  The format of the DrawPopClipPath method is:
   4049 %
   4050 %      void DrawPopClipPath(DrawingWand *wand)
   4051 %
   4052 %  A description of each parameter follows:
   4053 %
   4054 %    o wand: the drawing wand.
   4055 %
   4056 */
   4057 WandExport void DrawPopClipPath(DrawingWand *wand)
   4058 {
   4059   assert(wand != (DrawingWand *) NULL);
   4060   assert(wand->signature == MagickWandSignature);
   4061   if (wand->debug != MagickFalse)
   4062     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4063   if (wand->indent_depth > 0)
   4064     wand->indent_depth--;
   4065   (void) MVGPrintf(wand,"pop clip-path\n");
   4066 }
   4067 
   4068 /*
   4070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4071 %                                                                             %
   4072 %                                                                             %
   4073 %                                                                             %
   4074 %   D r a w P o p D e f s                                                     %
   4075 %                                                                             %
   4076 %                                                                             %
   4077 %                                                                             %
   4078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4079 %
   4080 %  DrawPopDefs() terminates a definition list.
   4081 %
   4082 %  The format of the DrawPopDefs method is:
   4083 %
   4084 %      void DrawPopDefs(DrawingWand *wand)
   4085 %
   4086 %  A description of each parameter follows:
   4087 %
   4088 %    o wand: the drawing wand.
   4089 %
   4090 */
   4091 WandExport void DrawPopDefs(DrawingWand *wand)
   4092 {
   4093   assert(wand != (DrawingWand *) NULL);
   4094   assert(wand->signature == MagickWandSignature);
   4095   if (wand->debug != MagickFalse)
   4096     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4097   if (wand->indent_depth > 0)
   4098     wand->indent_depth--;
   4099   (void) MVGPrintf(wand,"pop defs\n");
   4100 }
   4101 
   4102 /*
   4104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4105 %                                                                             %
   4106 %                                                                             %
   4107 %                                                                             %
   4108 %   D r a w P o p P a t t e r n                                               %
   4109 %                                                                             %
   4110 %                                                                             %
   4111 %                                                                             %
   4112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4113 %
   4114 %  DrawPopPattern() terminates a pattern definition.
   4115 %
   4116 %  The format of the DrawPopPattern method is:
   4117 %
   4118 %      MagickBooleanType DrawPopPattern(DrawingWand *wand)
   4119 %
   4120 %  A description of each parameter follows:
   4121 %
   4122 %    o wand: the drawing wand.
   4123 %
   4124 */
   4125 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
   4126 {
   4127   char
   4128     geometry[MagickPathExtent],
   4129     key[MagickPathExtent];
   4130 
   4131   assert(wand != (DrawingWand *) NULL);
   4132   assert(wand->signature == MagickWandSignature);
   4133   if (wand->debug != MagickFalse)
   4134     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4135   if (wand->image == (Image *) NULL)
   4136     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   4137   if (wand->pattern_id == (const char *) NULL)
   4138     {
   4139       ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
   4140         wand->name);
   4141       return(MagickFalse);
   4142     }
   4143   (void) FormatLocaleString(key,MagickPathExtent,"%s",wand->pattern_id);
   4144   (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
   4145   (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g%+.20g%+.20g",
   4146     (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
   4147     (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
   4148   (void) SetImageArtifact(wand->image,key,geometry);
   4149   wand->pattern_id=DestroyString(wand->pattern_id);
   4150   wand->pattern_offset=0;
   4151   wand->pattern_bounds.x=0;
   4152   wand->pattern_bounds.y=0;
   4153   wand->pattern_bounds.width=0;
   4154   wand->pattern_bounds.height=0;
   4155   wand->filter_off=MagickTrue;
   4156   if (wand->indent_depth > 0)
   4157     wand->indent_depth--;
   4158   (void) MVGPrintf(wand,"pop pattern\n");
   4159   return(MagickTrue);
   4160 }
   4161 
   4162 /*
   4164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4165 %                                                                             %
   4166 %                                                                             %
   4167 %                                                                             %
   4168 %   D r a w P u s h C l i p P a t h                                           %
   4169 %                                                                             %
   4170 %                                                                             %
   4171 %                                                                             %
   4172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4173 %
   4174 %  DrawPushClipPath() starts a clip path definition which is comprized of any
   4175 %  number of drawing commands and terminated by a DrawPopClipPath() command.
   4176 %
   4177 %  The format of the DrawPushClipPath method is:
   4178 %
   4179 %      void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
   4180 %
   4181 %  A description of each parameter follows:
   4182 %
   4183 %    o wand: the drawing wand.
   4184 %
   4185 %    o clip_mask_id: string identifier to associate with the clip path for
   4186 %      later use.
   4187 %
   4188 */
   4189 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
   4190 {
   4191   assert(wand != (DrawingWand *) NULL);
   4192   assert(wand->signature == MagickWandSignature);
   4193   if (wand->debug != MagickFalse)
   4194     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4195   assert(clip_mask_id != (const char *) NULL);
   4196   (void) MVGPrintf(wand,"push clip-path %s\n",clip_mask_id);
   4197   wand->indent_depth++;
   4198 }
   4199 
   4200 /*
   4202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4203 %                                                                             %
   4204 %                                                                             %
   4205 %                                                                             %
   4206 %   D r a w P u s h D e f s                                                   %
   4207 %                                                                             %
   4208 %                                                                             %
   4209 %                                                                             %
   4210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4211 %
   4212 %  DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
   4213 %  command create named elements (e.g. clip-paths, textures, etc.) which
   4214 %  may safely be processed earlier for the sake of efficiency.
   4215 %
   4216 %  The format of the DrawPushDefs method is:
   4217 %
   4218 %      void DrawPushDefs(DrawingWand *wand)
   4219 %
   4220 %  A description of each parameter follows:
   4221 %
   4222 %    o wand: the drawing wand.
   4223 %
   4224 */
   4225 WandExport void DrawPushDefs(DrawingWand *wand)
   4226 {
   4227   assert(wand != (DrawingWand *) NULL);
   4228   assert(wand->signature == MagickWandSignature);
   4229   if (wand->debug != MagickFalse)
   4230     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4231   (void) MVGPrintf(wand,"push defs\n");
   4232   wand->indent_depth++;
   4233 }
   4234 
   4235 /*
   4237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4238 %                                                                             %
   4239 %                                                                             %
   4240 %                                                                             %
   4241 %   D r a w P u s h P a t t e r n                                             %
   4242 %                                                                             %
   4243 %                                                                             %
   4244 %                                                                             %
   4245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4246 %
   4247 %  DrawPushPattern() indicates that subsequent commands up to a
   4248 %  DrawPopPattern() command comprise the definition of a named pattern.
   4249 %  The pattern space is assigned top left corner coordinates, a width
   4250 %  and height, and becomes its own drawing space.  Anything which can
   4251 %  be drawn may be used in a pattern definition.
   4252 %  Named patterns may be used as stroke or brush definitions.
   4253 %
   4254 %  The format of the DrawPushPattern method is:
   4255 %
   4256 %      MagickBooleanType DrawPushPattern(DrawingWand *wand,
   4257 %        const char *pattern_id,const double x,const double y,
   4258 %        const double width,const double height)
   4259 %
   4260 %  A description of each parameter follows:
   4261 %
   4262 %    o wand: the drawing wand.
   4263 %
   4264 %    o pattern_id: pattern identification for later reference
   4265 %
   4266 %    o x: x ordinate of top left corner
   4267 %
   4268 %    o y: y ordinate of top left corner
   4269 %
   4270 %    o width: width of pattern space
   4271 %
   4272 %    o height: height of pattern space
   4273 %
   4274 */
   4275 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
   4276   const char *pattern_id,const double x,const double y,const double width,
   4277   const double height)
   4278 {
   4279   assert(wand != (DrawingWand *) NULL);
   4280   assert(wand->signature == MagickWandSignature);
   4281   if (wand->debug != MagickFalse)
   4282     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4283   assert(pattern_id != (const char *) NULL);
   4284   if (wand->pattern_id != NULL)
   4285     {
   4286       ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
   4287         wand->pattern_id);
   4288       return(MagickFalse);
   4289     }
   4290   wand->filter_off=MagickTrue;
   4291   (void) MVGPrintf(wand,"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id,
   4292     x,y,width,height);
   4293   wand->indent_depth++;
   4294   wand->pattern_id=AcquireString(pattern_id);
   4295   wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
   4296   wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
   4297   wand->pattern_bounds.width=(size_t) floor(width+0.5);
   4298   wand->pattern_bounds.height=(size_t) floor(height+0.5);
   4299   wand->pattern_offset=wand->mvg_length;
   4300   return(MagickTrue);
   4301 }
   4302 
   4303 /*
   4305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4306 %                                                                             %
   4307 %                                                                             %
   4308 %                                                                             %
   4309 %   D r a w R e c t a n g l e                                                 %
   4310 %                                                                             %
   4311 %                                                                             %
   4312 %                                                                             %
   4313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4314 %
   4315 %  DrawRectangle() draws a rectangle given two coordinates and using the
   4316 %  current stroke, stroke width, and fill settings.
   4317 %
   4318 %  The format of the DrawRectangle method is:
   4319 %
   4320 %      void DrawRectangle(DrawingWand *wand,const double x1,
   4321 %        const double y1,const double x2,const double y2)
   4322 %
   4323 %  A description of each parameter follows:
   4324 %
   4325 %    o x1: x ordinate of first coordinate
   4326 %
   4327 %    o y1: y ordinate of first coordinate
   4328 %
   4329 %    o x2: x ordinate of second coordinate
   4330 %
   4331 %    o y2: y ordinate of second coordinate
   4332 %
   4333 */
   4334 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
   4335   const double x2,const double y2)
   4336 {
   4337   assert(wand != (DrawingWand *) NULL);
   4338   assert(wand->signature == MagickWandSignature);
   4339   if (wand->debug != MagickFalse)
   4340     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4341   (void) MVGPrintf(wand,"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
   4342 }
   4343 
   4344 /*
   4346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4347 %                                                                             %
   4348 %                                                                             %
   4349 %                                                                             %
   4350 +   D r a w R e n d e r                                                       %
   4351 %                                                                             %
   4352 %                                                                             %
   4353 %                                                                             %
   4354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4355 %
   4356 %  DrawRender() renders all preceding drawing commands onto the image.
   4357 %
   4358 %  The format of the DrawRender method is:
   4359 %
   4360 %      MagickBooleanType DrawRender(DrawingWand *wand)
   4361 %
   4362 %  A description of each parameter follows:
   4363 %
   4364 %    o wand: the drawing wand.
   4365 %
   4366 */
   4367 WandExport MagickBooleanType DrawRender(DrawingWand *wand)
   4368 {
   4369   MagickBooleanType
   4370     status;
   4371 
   4372   assert(wand != (const DrawingWand *) NULL);
   4373   assert(wand->signature == MagickWandSignature);
   4374   if (wand->debug != MagickFalse)
   4375     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4376   CurrentContext->primitive=wand->mvg;
   4377   if (wand->debug != MagickFalse)
   4378     (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
   4379   if (wand->image == (Image *) NULL)
   4380     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   4381   status=DrawImage(wand->image,CurrentContext,wand->exception);
   4382   CurrentContext->primitive=(char *) NULL;
   4383   return(status);
   4384 }
   4385 
   4386 /*
   4388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4389 %                                                                             %
   4390 %                                                                             %
   4391 %                                                                             %
   4392 %   D r a w R e s e t V e c t o r G r a p h i c s                             %
   4393 %                                                                             %
   4394 %                                                                             %
   4395 %                                                                             %
   4396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4397 %
   4398 %  DrawResetVectorGraphics() resets the vector graphics associated with the
   4399 %  specified wand.
   4400 %
   4401 %  The format of the DrawResetVectorGraphics method is:
   4402 %
   4403 %      void DrawResetVectorGraphics(DrawingWand *wand)
   4404 %
   4405 %  A description of each parameter follows:
   4406 %
   4407 %    o wand: the drawing wand.
   4408 %
   4409 */
   4410 WandExport void DrawResetVectorGraphics(DrawingWand *wand)
   4411 {
   4412   assert(wand != (DrawingWand *) NULL);
   4413   assert(wand->signature == MagickWandSignature);
   4414   if (wand->debug != MagickFalse)
   4415     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4416   if (wand->mvg != (char *) NULL)
   4417     wand->mvg=DestroyString(wand->mvg);
   4418   wand->mvg_alloc=0;
   4419   wand->mvg_length=0;
   4420   wand->mvg_width=0;
   4421 }
   4422 
   4423 /*
   4425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4426 %                                                                             %
   4427 %                                                                             %
   4428 %                                                                             %
   4429 %   D r a w R o t a t e                                                       %
   4430 %                                                                             %
   4431 %                                                                             %
   4432 %                                                                             %
   4433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4434 %
   4435 %  DrawRotate() applies the specified rotation to the current coordinate space.
   4436 %
   4437 %  The format of the DrawRotate method is:
   4438 %
   4439 %      void DrawRotate(DrawingWand *wand,const double degrees)
   4440 %
   4441 %  A description of each parameter follows:
   4442 %
   4443 %    o wand: the drawing wand.
   4444 %
   4445 %    o degrees: degrees of rotation
   4446 %
   4447 */
   4448 WandExport void DrawRotate(DrawingWand *wand,const double degrees)
   4449 {
   4450   assert(wand != (DrawingWand *) NULL);
   4451   assert(wand->signature == MagickWandSignature);
   4452   if (wand->debug != MagickFalse)
   4453     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4454   (void) MVGPrintf(wand,"rotate %.20g\n",degrees);
   4455 }
   4456 
   4457 /*
   4459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4460 %                                                                             %
   4461 %                                                                             %
   4462 %                                                                             %
   4463 %   D r a w R o u n d R e c t a n g l e                                       %
   4464 %                                                                             %
   4465 %                                                                             %
   4466 %                                                                             %
   4467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4468 %
   4469 %  DrawRoundRectangle() draws a rounted rectangle given two coordinates,
   4470 %  x & y corner radiuses and using the current stroke, stroke width,
   4471 %  and fill settings.
   4472 %
   4473 %  The format of the DrawRoundRectangle method is:
   4474 %
   4475 %      void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
   4476 %        double x2,double y2,double rx,double ry)
   4477 %
   4478 %  A description of each parameter follows:
   4479 %
   4480 %    o wand: the drawing wand.
   4481 %
   4482 %    o x1: x ordinate of first coordinate
   4483 %
   4484 %    o y1: y ordinate of first coordinate
   4485 %
   4486 %    o x2: x ordinate of second coordinate
   4487 %
   4488 %    o y2: y ordinate of second coordinate
   4489 %
   4490 %    o rx: radius of corner in horizontal direction
   4491 %
   4492 %    o ry: radius of corner in vertical direction
   4493 %
   4494 */
   4495 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
   4496   double x2,double y2,double rx,double ry)
   4497 {
   4498   assert(wand != (DrawingWand *) NULL);
   4499   assert(wand->signature == MagickWandSignature);
   4500   if (wand->debug != MagickFalse)
   4501     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4502   (void) MVGPrintf(wand,"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n",
   4503     x1,y1,x2,y2,rx,ry);
   4504 }
   4505 
   4506 /*
   4508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4509 %                                                                             %
   4510 %                                                                             %
   4511 %                                                                             %
   4512 %   D r a w S c a l e                                                         %
   4513 %                                                                             %
   4514 %                                                                             %
   4515 %                                                                             %
   4516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4517 %
   4518 %  DrawScale() adjusts the scaling factor to apply in the horizontal and
   4519 %  vertical directions to the current coordinate space.
   4520 %
   4521 %  The format of the DrawScale method is:
   4522 %
   4523 %      void DrawScale(DrawingWand *wand,const double x,const double y)
   4524 %
   4525 %  A description of each parameter follows:
   4526 %
   4527 %    o wand: the drawing wand.
   4528 %
   4529 %    o x: horizontal scale factor
   4530 %
   4531 %    o y: vertical scale factor
   4532 %
   4533 */
   4534 WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
   4535 {
   4536   assert(wand != (DrawingWand *) NULL);
   4537   assert(wand->signature == MagickWandSignature);
   4538   if (wand->debug != MagickFalse)
   4539     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4540   (void) MVGPrintf(wand,"scale %.20g %.20g\n",x,y);
   4541 }
   4542 
   4543 /*
   4545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4546 %                                                                             %
   4547 %                                                                             %
   4548 %                                                                             %
   4549 %   D r a w S e t B o r d e r C o l o r                                       %
   4550 %                                                                             %
   4551 %                                                                             %
   4552 %                                                                             %
   4553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4554 %
   4555 %  DrawSetBorderColor() sets the border color to be used for drawing bordered
   4556 %  objects.
   4557 %
   4558 %  The format of the DrawSetBorderColor method is:
   4559 %
   4560 %      void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
   4561 %
   4562 %  A description of each parameter follows:
   4563 %
   4564 %    o wand: the drawing wand.
   4565 %
   4566 %    o border_wand: border wand.
   4567 %
   4568 */
   4569 WandExport void DrawSetBorderColor(DrawingWand *wand,
   4570   const PixelWand *border_wand)
   4571 {
   4572   PixelInfo
   4573     *current_border,
   4574     border_color,
   4575     new_border;
   4576 
   4577   assert(wand != (DrawingWand *) NULL);
   4578   assert(wand->signature == MagickWandSignature);
   4579   if (wand->debug != MagickFalse)
   4580     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4581   assert(border_wand != (const PixelWand *) NULL);
   4582   PixelGetQuantumPacket(border_wand,&border_color);
   4583   new_border=border_color;
   4584   current_border=(&CurrentContext->border_color);
   4585   if ((wand->filter_off != MagickFalse) ||
   4586       (IsPixelInfoEquivalent(current_border,&new_border) == MagickFalse))
   4587     {
   4588       CurrentContext->border_color=new_border;
   4589       (void) MVGPrintf(wand,"border-color '");
   4590       MVGAppendColor(wand,&border_color);
   4591       (void) MVGPrintf(wand,"'\n");
   4592     }
   4593 }
   4594 
   4595 /*
   4597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4598 %                                                                             %
   4599 %                                                                             %
   4600 %                                                                             %
   4601 %   D r a w S e t C l i p P a t h                                             %
   4602 %                                                                             %
   4603 %                                                                             %
   4604 %                                                                             %
   4605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4606 %
   4607 %  DrawSetClipPath() associates a named clipping path with the image.  Only
   4608 %  the areas drawn on by the clipping path will be modified as ssize_t as it
   4609 %  remains in effect.
   4610 %
   4611 %  The format of the DrawSetClipPath method is:
   4612 %
   4613 %      MagickBooleanType DrawSetClipPath(DrawingWand *wand,
   4614 %        const char *clip_mask)
   4615 %
   4616 %  A description of each parameter follows:
   4617 %
   4618 %    o wand: the drawing wand.
   4619 %
   4620 %    o clip_mask: name of clipping path to associate with image
   4621 %
   4622 */
   4623 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
   4624   const char *clip_mask)
   4625 {
   4626   if (wand->debug != MagickFalse)
   4627     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
   4628   assert(wand != (DrawingWand *) NULL);
   4629   assert(wand->signature == MagickWandSignature);
   4630   assert(clip_mask != (const char *) NULL);
   4631   if ((CurrentContext->clip_mask == (const char *) NULL) ||
   4632       (wand->filter_off != MagickFalse) ||
   4633       (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
   4634     {
   4635       (void) CloneString(&CurrentContext->clip_mask,clip_mask);
   4636 #if DRAW_BINARY_IMPLEMENTATION
   4637       if (wand->image == (Image *) NULL)
   4638         ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   4639       (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
   4640 #endif
   4641       (void) MVGPrintf(wand,"clip-path url(#%s)\n",clip_mask);
   4642     }
   4643   return(MagickTrue);
   4644 }
   4645 
   4646 /*
   4648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4649 %                                                                             %
   4650 %                                                                             %
   4651 %                                                                             %
   4652 %   D r a w S e t C l i p R u l e                                             %
   4653 %                                                                             %
   4654 %                                                                             %
   4655 %                                                                             %
   4656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4657 %
   4658 %  DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
   4659 %
   4660 %  The format of the DrawSetClipRule method is:
   4661 %
   4662 %      void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
   4663 %
   4664 %  A description of each parameter follows:
   4665 %
   4666 %    o wand: the drawing wand.
   4667 %
   4668 %    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
   4669 %
   4670 */
   4671 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
   4672 {
   4673   assert(wand != (DrawingWand *) NULL);
   4674   assert(wand->signature == MagickWandSignature);
   4675   if (wand->debug != MagickFalse)
   4676     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4677   if ((wand->filter_off != MagickFalse) ||
   4678       (CurrentContext->fill_rule != fill_rule))
   4679     {
   4680       CurrentContext->fill_rule=fill_rule;
   4681       (void) MVGPrintf(wand, "clip-rule '%s'\n",CommandOptionToMnemonic(
   4682         MagickFillRuleOptions,(ssize_t) fill_rule));
   4683     }
   4684 }
   4685 
   4686 /*
   4688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4689 %                                                                             %
   4690 %                                                                             %
   4691 %                                                                             %
   4692 %   D r a w S e t C l i p U n i t s                                           %
   4693 %                                                                             %
   4694 %                                                                             %
   4695 %                                                                             %
   4696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4697 %
   4698 %  DrawSetClipUnits() sets the interpretation of clip path units.
   4699 %
   4700 %  The format of the DrawSetClipUnits method is:
   4701 %
   4702 %      void DrawSetClipUnits(DrawingWand *wand,
   4703 %        const ClipPathUnits clip_units)
   4704 %
   4705 %  A description of each parameter follows:
   4706 %
   4707 %    o wand: the drawing wand.
   4708 %
   4709 %    o clip_units: units to use (UserSpace, UserSpaceOnUse, or
   4710 %      ObjectBoundingBox)
   4711 %
   4712 */
   4713 WandExport void DrawSetClipUnits(DrawingWand *wand,
   4714   const ClipPathUnits clip_units)
   4715 {
   4716   assert(wand != (DrawingWand *) NULL);
   4717   assert(wand->signature == MagickWandSignature);
   4718   if (wand->debug != MagickFalse)
   4719     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4720   if ((wand->filter_off != MagickFalse) ||
   4721       (CurrentContext->clip_units != clip_units))
   4722     {
   4723       CurrentContext->clip_units=clip_units;
   4724       if (clip_units == ObjectBoundingBox)
   4725         {
   4726           AffineMatrix
   4727             affine;
   4728 
   4729           GetAffineMatrix(&affine);
   4730           affine.sx=CurrentContext->bounds.x2;
   4731           affine.sy=CurrentContext->bounds.y2;
   4732           affine.tx=CurrentContext->bounds.x1;
   4733           affine.ty=CurrentContext->bounds.y1;
   4734           AdjustAffine(wand,&affine);
   4735         }
   4736       (void) MVGPrintf(wand, "clip-units '%s'\n",CommandOptionToMnemonic(
   4737         MagickClipPathOptions,(ssize_t) clip_units));
   4738     }
   4739 }
   4740 
   4741 /*
   4743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4744 %                                                                             %
   4745 %                                                                             %
   4746 %                                                                             %
   4747 %   D r a w S e t D e n s i t y                                               %
   4748 %                                                                             %
   4749 %                                                                             %
   4750 %                                                                             %
   4751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4752 %
   4753 %  DrawSetDensity() sets the vertical and horizontal resolution.
   4754 %
   4755 %  The format of the DrawSetDensity method is:
   4756 %
   4757 %      MagickBooleanType DrawSetDensity(DrawingWand *wand,
   4758 %        const char *density)
   4759 %
   4760 %  A description of each parameter follows:
   4761 %
   4762 %    o wand: the drawing wand.
   4763 %
   4764 %    o density: the vertical and horizontal resolution.
   4765 %
   4766 */
   4767 WandExport MagickBooleanType DrawSetDensity(DrawingWand *wand,
   4768   const char *density)
   4769 {
   4770   if (wand->debug != MagickFalse)
   4771     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",density);
   4772   assert(wand != (DrawingWand *) NULL);
   4773   assert(wand->signature == MagickWandSignature);
   4774   assert(density != (const char *) NULL);
   4775   if ((CurrentContext->density == (const char *) NULL) ||
   4776       (wand->filter_off != MagickFalse) ||
   4777       (LocaleCompare(CurrentContext->density,density) != 0))
   4778     {
   4779       (void) CloneString(&CurrentContext->density,density);
   4780       (void) MVGPrintf(wand,"density '%s'\n",density);
   4781     }
   4782   return(MagickTrue);
   4783 }
   4784 
   4785 /*
   4786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4787 %                                                                             %
   4788 %                                                                             %
   4789 %                                                                             %
   4790 %   D r a w S e t F i l l C o l o r                                           %
   4791 %                                                                             %
   4792 %                                                                             %
   4793 %                                                                             %
   4794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4795 %
   4796 %  DrawSetFillColor() sets the fill color to be used for drawing filled objects.
   4797 %
   4798 %  The format of the DrawSetFillColor method is:
   4799 %
   4800 %      void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
   4801 %
   4802 %  A description of each parameter follows:
   4803 %
   4804 %    o wand: the drawing wand.
   4805 %
   4806 %    o fill_wand: fill wand.
   4807 %
   4808 */
   4809 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
   4810 {
   4811   PixelInfo
   4812     *current_fill,
   4813     fill_color,
   4814     new_fill;
   4815 
   4816   assert(wand != (DrawingWand *) NULL);
   4817   assert(wand->signature == MagickWandSignature);
   4818   if (wand->debug != MagickFalse)
   4819     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4820   assert(fill_wand != (const PixelWand *) NULL);
   4821   PixelGetQuantumPacket(fill_wand,&fill_color);
   4822   new_fill=fill_color;
   4823   current_fill=(&CurrentContext->fill);
   4824   if ((wand->filter_off != MagickFalse) ||
   4825       (IsPixelInfoEquivalent(current_fill,&new_fill) == MagickFalse))
   4826     {
   4827       CurrentContext->fill=new_fill;
   4828       (void) MVGPrintf(wand,"fill '");
   4829       MVGAppendColor(wand,&fill_color);
   4830       (void) MVGPrintf(wand,"'\n");
   4831     }
   4832 }
   4833 
   4834 /*
   4836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4837 %                                                                             %
   4838 %                                                                             %
   4839 %                                                                             %
   4840 %   D r a w S e t F i l l O p a c i t y                                       %
   4841 %                                                                             %
   4842 %                                                                             %
   4843 %                                                                             %
   4844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4845 %
   4846 %  DrawSetFillOpacity() sets the alpha to use when drawing using the fill
   4847 %  color or fill texture.  Fully opaque is 1.0.
   4848 %
   4849 %  The format of the DrawSetFillOpacity method is:
   4850 %
   4851 %      void DrawSetFillOpacity(DrawingWand *wand,const double fill_alpha)
   4852 %
   4853 %  A description of each parameter follows:
   4854 %
   4855 %    o wand: the drawing wand.
   4856 %
   4857 %    o fill_opacity: fill opacity
   4858 %
   4859 */
   4860 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
   4861 {
   4862   double
   4863     alpha;
   4864 
   4865   assert(wand != (DrawingWand *) NULL);
   4866   assert(wand->signature == MagickWandSignature);
   4867   if (wand->debug != MagickFalse)
   4868     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4869   alpha=(double) ClampToQuantum(QuantumRange*fill_opacity);
   4870   if ((wand->filter_off != MagickFalse) ||
   4871       (CurrentContext->fill.alpha != alpha))
   4872     {
   4873       CurrentContext->fill.alpha=alpha;
   4874       (void) MVGPrintf(wand,"fill-opacity %.20g\n",fill_opacity);
   4875     }
   4876 }
   4877 
   4878 /*
   4880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4881 %                                                                             %
   4882 %                                                                             %
   4883 %                                                                             %
   4884 %   D r a w S e t F o n t R e s o l u t i o n                                 %
   4885 %                                                                             %
   4886 %                                                                             %
   4887 %                                                                             %
   4888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4889 %
   4890 %  DrawSetFontResolution() sets the image resolution.
   4891 %
   4892 %  The format of the DrawSetFontResolution method is:
   4893 %
   4894 %      MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
   4895 %        const double x_resolution,const double y_resolution)
   4896 %
   4897 %  A description of each parameter follows:
   4898 %
   4899 %    o wand: the magick wand.
   4900 %
   4901 %    o x_resolution: the image x resolution.
   4902 %
   4903 %    o y_resolution: the image y resolution.
   4904 %
   4905 */
   4906 WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
   4907   const double x_resolution,const double y_resolution)
   4908 {
   4909   char
   4910     density[MagickPathExtent];
   4911 
   4912   assert(wand != (DrawingWand *) NULL);
   4913   assert(wand->signature == MagickWandSignature);
   4914   if (wand->debug != MagickFalse)
   4915     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4916   (void) FormatLocaleString(density,MagickPathExtent,"%.20gx%.20g",x_resolution,
   4917     y_resolution);
   4918   (void) CloneString(&CurrentContext->density,density);
   4919   return(MagickTrue);
   4920 }
   4921 
   4922 /*
   4924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4925 %                                                                             %
   4926 %                                                                             %
   4927 %                                                                             %
   4928 %   D r a w S e t O p a c i t y                                               %
   4929 %                                                                             %
   4930 %                                                                             %
   4931 %                                                                             %
   4932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4933 %
   4934 %  DrawSetOpacity() sets the alpha to use when drawing using the fill or
   4935 %  stroke color or texture.  Fully opaque is 1.0.
   4936 %
   4937 %  The format of the DrawSetOpacity method is:
   4938 %
   4939 %      void DrawSetOpacity(DrawingWand *wand,const double alpha)
   4940 %
   4941 %  A description of each parameter follows:
   4942 %
   4943 %    o wand: the drawing wand.
   4944 %
   4945 %    o opacity: fill and stroke opacity.  The value 1.0 is opaque.
   4946 %
   4947 */
   4948 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
   4949 {
   4950   Quantum
   4951     quantum_alpha;
   4952 
   4953   assert(wand != (DrawingWand *) NULL);
   4954   assert(wand->signature == MagickWandSignature);
   4955   if (wand->debug != MagickFalse)
   4956     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   4957   quantum_alpha=ClampToQuantum(QuantumRange*opacity);
   4958   if ((wand->filter_off != MagickFalse) ||
   4959       (CurrentContext->alpha != quantum_alpha))
   4960     {
   4961       CurrentContext->alpha=quantum_alpha;
   4962       (void) MVGPrintf(wand,"opacity %.20g\n",opacity);
   4963     }
   4964 }
   4965 
   4966 /*
   4968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4969 %                                                                             %
   4970 %                                                                             %
   4971 %                                                                             %
   4972 %   D r a w S e t F i l l P a t t e r n U R L                                 %
   4973 %                                                                             %
   4974 %                                                                             %
   4975 %                                                                             %
   4976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4977 %
   4978 %  DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
   4979 %  objects. Only local URLs ("#identifier") are supported at this time. These
   4980 %  local URLs are normally created by defining a named fill pattern with
   4981 %  DrawPushPattern/DrawPopPattern.
   4982 %
   4983 %  The format of the DrawSetFillPatternURL method is:
   4984 %
   4985 %      MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
   4986 %        const char *fill_url)
   4987 %
   4988 %  A description of each parameter follows:
   4989 %
   4990 %    o wand: the drawing wand.
   4991 %
   4992 %    o fill_url: URL to use to obtain fill pattern.
   4993 %
   4994 */
   4995 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
   4996   const char *fill_url)
   4997 {
   4998   char
   4999     pattern[MagickPathExtent],
   5000     pattern_spec[MagickPathExtent];
   5001 
   5002   assert(wand != (DrawingWand *) NULL);
   5003   assert(wand->signature == MagickWandSignature);
   5004   if (wand->debug != MagickFalse)
   5005     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
   5006   if (wand->image == (Image *) NULL)
   5007     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   5008   assert(fill_url != (const char *) NULL);
   5009   if (*fill_url != '#')
   5010     {
   5011       ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
   5012       return(MagickFalse);
   5013     }
   5014   (void) FormatLocaleString(pattern,MagickPathExtent,"%s",fill_url+1);
   5015   if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
   5016     {
   5017       ThrowDrawException(DrawError,"URLNotFound",fill_url)
   5018       return(MagickFalse);
   5019     }
   5020   (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",fill_url);
   5021 #if DRAW_BINARY_IMPLEMENTATION
   5022   DrawPatternPath(wand->image,CurrentContext,pattern_spec,
   5023     &CurrentContext->fill_pattern);
   5024 #endif
   5025   if (CurrentContext->fill.alpha != (Quantum) TransparentAlpha)
   5026     CurrentContext->fill.alpha=(double) CurrentContext->alpha;
   5027   (void) MVGPrintf(wand,"fill %s\n",pattern_spec);
   5028   return(MagickTrue);
   5029 }
   5030 
   5031 /*
   5033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5034 %                                                                             %
   5035 %                                                                             %
   5036 %                                                                             %
   5037 %   D r a w S e t F i l l R u l e                                             %
   5038 %                                                                             %
   5039 %                                                                             %
   5040 %                                                                             %
   5041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5042 %
   5043 %  DrawSetFillRule() sets the fill rule to use while drawing polygons.
   5044 %
   5045 %  The format of the DrawSetFillRule method is:
   5046 %
   5047 %      void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
   5048 %
   5049 %  A description of each parameter follows:
   5050 %
   5051 %    o wand: the drawing wand.
   5052 %
   5053 %    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
   5054 %
   5055 */
   5056 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
   5057 {
   5058   assert(wand != (DrawingWand *) NULL);
   5059   assert(wand->signature == MagickWandSignature);
   5060   if (wand->debug != MagickFalse)
   5061     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5062   if ((wand->filter_off != MagickFalse) ||
   5063       (CurrentContext->fill_rule != fill_rule))
   5064     {
   5065       CurrentContext->fill_rule=fill_rule;
   5066       (void) MVGPrintf(wand, "fill-rule '%s'\n",CommandOptionToMnemonic(
   5067         MagickFillRuleOptions,(ssize_t) fill_rule));
   5068     }
   5069 }
   5070 
   5071 /*
   5073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5074 %                                                                             %
   5075 %                                                                             %
   5076 %                                                                             %
   5077 %   D r a w S e t F o n t                                                     %
   5078 %                                                                             %
   5079 %                                                                             %
   5080 %                                                                             %
   5081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5082 %
   5083 %  DrawSetFont() sets the fully-sepecified font to use when annotating with
   5084 %  text.
   5085 %
   5086 %  The format of the DrawSetFont method is:
   5087 %
   5088 %      MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
   5089 %
   5090 %  A description of each parameter follows:
   5091 %
   5092 %    o wand: the drawing wand.
   5093 %
   5094 %    o font_name: font name
   5095 %
   5096 */
   5097 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
   5098   const char *font_name)
   5099 {
   5100   assert(wand != (DrawingWand *) NULL);
   5101   assert(wand->signature == MagickWandSignature);
   5102   if (wand->debug != MagickFalse)
   5103     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5104   assert(font_name != (const char *) NULL);
   5105   if ((wand->filter_off != MagickFalse) ||
   5106       (CurrentContext->font == (char *) NULL) ||
   5107       (LocaleCompare(CurrentContext->font,font_name) != 0))
   5108     {
   5109       (void) CloneString(&CurrentContext->font,font_name);
   5110       (void) MVGPrintf(wand,"font '%s'\n",font_name);
   5111     }
   5112   return(MagickTrue);
   5113 }
   5114 
   5115 /*
   5117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5118 %                                                                             %
   5119 %                                                                             %
   5120 %                                                                             %
   5121 %   D r a w S e t F o n t F a m i l y                                         %
   5122 %                                                                             %
   5123 %                                                                             %
   5124 %                                                                             %
   5125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5126 %
   5127 %  DrawSetFontFamily() sets the font family to use when annotating with text.
   5128 %
   5129 %  The format of the DrawSetFontFamily method is:
   5130 %
   5131 %      MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
   5132 %        const char *font_family)
   5133 %
   5134 %  A description of each parameter follows:
   5135 %
   5136 %    o wand: the drawing wand.
   5137 %
   5138 %    o font_family: font family
   5139 %
   5140 */
   5141 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
   5142   const char *font_family)
   5143 {
   5144   assert(wand != (DrawingWand *) NULL);
   5145   assert(wand->signature == MagickWandSignature);
   5146   if (wand->debug != MagickFalse)
   5147     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5148   assert(font_family != (const char *) NULL);
   5149   if ((wand->filter_off != MagickFalse) ||
   5150       (CurrentContext->family == (const char *) NULL) ||
   5151       (LocaleCompare(CurrentContext->family,font_family) != 0))
   5152     {
   5153       (void) CloneString(&CurrentContext->family,font_family);
   5154       (void) MVGPrintf(wand,"font-family '%s'\n",font_family);
   5155     }
   5156   return(MagickTrue);
   5157 }
   5158 
   5159 /*
   5161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5162 %                                                                             %
   5163 %                                                                             %
   5164 %                                                                             %
   5165 %   D r a w S e t F o n t S i z e                                             %
   5166 %                                                                             %
   5167 %                                                                             %
   5168 %                                                                             %
   5169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5170 %
   5171 %  DrawSetFontSize() sets the font pointsize to use when annotating with text.
   5172 %
   5173 %  The format of the DrawSetFontSize method is:
   5174 %
   5175 %      void DrawSetFontSize(DrawingWand *wand,const double pointsize)
   5176 %
   5177 %  A description of each parameter follows:
   5178 %
   5179 %    o wand: the drawing wand.
   5180 %
   5181 %    o pointsize: text pointsize
   5182 %
   5183 */
   5184 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
   5185 {
   5186   assert(wand != (DrawingWand *) NULL);
   5187   assert(wand->signature == MagickWandSignature);
   5188   if (wand->debug != MagickFalse)
   5189     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5190   if ((wand->filter_off != MagickFalse) ||
   5191       (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon))
   5192     {
   5193       CurrentContext->pointsize=pointsize;
   5194       (void) MVGPrintf(wand,"font-size %.20g\n",pointsize);
   5195     }
   5196 }
   5197 
   5198 /*
   5200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5201 %                                                                             %
   5202 %                                                                             %
   5203 %                                                                             %
   5204 %   D r a w S e t F o n t S t r e t c h                                       %
   5205 %                                                                             %
   5206 %                                                                             %
   5207 %                                                                             %
   5208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5209 %
   5210 %  DrawSetFontStretch() sets the font stretch to use when annotating with text.
   5211 %  The AnyStretch enumeration acts as a wild-card "don't care" option.
   5212 %
   5213 %  The format of the DrawSetFontStretch method is:
   5214 %
   5215 %      void DrawSetFontStretch(DrawingWand *wand,
   5216 %        const StretchType font_stretch)
   5217 %
   5218 %  A description of each parameter follows:
   5219 %
   5220 %    o wand: the drawing wand.
   5221 %
   5222 %    o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
   5223 %                    CondensedStretch, SemiCondensedStretch,
   5224 %                    SemiExpandedStretch, ExpandedStretch,
   5225 %                    ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
   5226 %
   5227 */
   5228 WandExport void DrawSetFontStretch(DrawingWand *wand,
   5229   const StretchType font_stretch)
   5230 {
   5231   assert(wand != (DrawingWand *) NULL);
   5232   assert(wand->signature == MagickWandSignature);
   5233   if (wand->debug != MagickFalse)
   5234     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5235   if ((wand->filter_off != MagickFalse) ||
   5236       (CurrentContext->stretch != font_stretch))
   5237     {
   5238       CurrentContext->stretch=font_stretch;
   5239       (void) MVGPrintf(wand, "font-stretch '%s'\n",CommandOptionToMnemonic(
   5240         MagickStretchOptions,(ssize_t) font_stretch));
   5241     }
   5242 }
   5243 
   5244 /*
   5246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5247 %                                                                             %
   5248 %                                                                             %
   5249 %                                                                             %
   5250 %   D r a w S e t F o n t S t y l e                                           %
   5251 %                                                                             %
   5252 %                                                                             %
   5253 %                                                                             %
   5254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5255 %
   5256 %  DrawSetFontStyle() sets the font style to use when annotating with text.
   5257 %  The AnyStyle enumeration acts as a wild-card "don't care" option.
   5258 %
   5259 %  The format of the DrawSetFontStyle method is:
   5260 %
   5261 %      void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
   5262 %
   5263 %  A description of each parameter follows:
   5264 %
   5265 %    o wand: the drawing wand.
   5266 %
   5267 %    o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
   5268 %
   5269 */
   5270 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
   5271 {
   5272   assert(wand != (DrawingWand *) NULL);
   5273   assert(wand->signature == MagickWandSignature);
   5274   if (wand->debug != MagickFalse)
   5275     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5276   if ((wand->filter_off != MagickFalse) ||
   5277       (CurrentContext->style != style))
   5278     {
   5279       CurrentContext->style=style;
   5280       (void) MVGPrintf(wand, "font-style '%s'\n",CommandOptionToMnemonic(
   5281         MagickStyleOptions,(ssize_t) style));
   5282     }
   5283 }
   5284 
   5285 /*
   5287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5288 %                                                                             %
   5289 %                                                                             %
   5290 %                                                                             %
   5291 %   D r a w S e t F o n t W e i g h t                                         %
   5292 %                                                                             %
   5293 %                                                                             %
   5294 %                                                                             %
   5295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5296 %
   5297 %  DrawSetFontWeight() sets the font weight to use when annotating with text.
   5298 %
   5299 %  The format of the DrawSetFontWeight method is:
   5300 %
   5301 %      void DrawSetFontWeight(DrawingWand *wand,
   5302 %        const size_t font_weight)
   5303 %
   5304 %  A description of each parameter follows:
   5305 %
   5306 %    o wand: the drawing wand.
   5307 %
   5308 %    o font_weight: font weight (valid range 100-900)
   5309 %
   5310 */
   5311 WandExport void DrawSetFontWeight(DrawingWand *wand,
   5312   const size_t font_weight)
   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->weight != font_weight))
   5320     {
   5321       CurrentContext->weight=font_weight;
   5322       (void) MVGPrintf(wand,"font-weight %.20g\n",(double) font_weight);
   5323     }
   5324 }
   5325 
   5326 /*
   5328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5329 %                                                                             %
   5330 %                                                                             %
   5331 %                                                                             %
   5332 %   D r a w S e t G r a v i t y                                               %
   5333 %                                                                             %
   5334 %                                                                             %
   5335 %                                                                             %
   5336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5337 %
   5338 %  DrawSetGravity() sets the text placement gravity to use when annotating
   5339 %  with text.
   5340 %
   5341 %  The format of the DrawSetGravity method is:
   5342 %
   5343 %      void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
   5344 %
   5345 %  A description of each parameter follows:
   5346 %
   5347 %    o wand: the drawing wand.
   5348 %
   5349 %    o gravity: positioning gravity (NorthWestGravity, NorthGravity,
   5350 %               NorthEastGravity, WestGravity, CenterGravity,
   5351 %               EastGravity, SouthWestGravity, SouthGravity,
   5352 %               SouthEastGravity)
   5353 %
   5354 */
   5355 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
   5356 {
   5357   assert(wand != (DrawingWand *) NULL);
   5358   assert(wand->signature == MagickWandSignature);
   5359   if (wand->debug != MagickFalse)
   5360     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5361   if ((wand->filter_off != MagickFalse) ||
   5362       (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
   5363     {
   5364       CurrentContext->gravity=gravity;
   5365       (void) MVGPrintf(wand,"gravity '%s'\n",CommandOptionToMnemonic(
   5366         MagickGravityOptions,(ssize_t) gravity));
   5367     }
   5368 }
   5369 
   5370 /*
   5372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5373 %                                                                             %
   5374 %                                                                             %
   5375 %                                                                             %
   5376 %   D r a w S e t S t r o k e C o l o r                                       %
   5377 %                                                                             %
   5378 %                                                                             %
   5379 %                                                                             %
   5380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5381 %
   5382 %  DrawSetStrokeColor() sets the color used for stroking object outlines.
   5383 %
   5384 %  The format of the DrawSetStrokeColor method is:
   5385 %
   5386 %      void DrawSetStrokeColor(DrawingWand *wand,
   5387 %        const PixelWand *stroke_wand)
   5388 %
   5389 %  A description of each parameter follows:
   5390 %
   5391 %    o wand: the drawing wand.
   5392 %
   5393 %    o stroke_wand: stroke wand.
   5394 %
   5395 */
   5396 WandExport void DrawSetStrokeColor(DrawingWand *wand,
   5397   const PixelWand *stroke_wand)
   5398 {
   5399   PixelInfo
   5400     *current_stroke,
   5401     new_stroke,
   5402     stroke_color;
   5403 
   5404   assert(wand != (DrawingWand *) NULL);
   5405   assert(wand->signature == MagickWandSignature);
   5406   if (wand->debug != MagickFalse)
   5407     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5408   assert(stroke_wand != (const PixelWand *) NULL);
   5409   PixelGetQuantumPacket(stroke_wand,&stroke_color);
   5410   new_stroke=stroke_color;
   5411   current_stroke=(&CurrentContext->stroke);
   5412   if ((wand->filter_off != MagickFalse) ||
   5413       (IsPixelInfoEquivalent(current_stroke,&new_stroke) == MagickFalse))
   5414     {
   5415       CurrentContext->stroke=new_stroke;
   5416       (void) MVGPrintf(wand,"stroke '");
   5417       MVGAppendColor(wand,&stroke_color);
   5418       (void) MVGPrintf(wand,"'\n");
   5419     }
   5420 }
   5421 
   5422 /*
   5424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5425 %                                                                             %
   5426 %                                                                             %
   5427 %                                                                             %
   5428 %   D r a w S e t S t r o k e P a t t e r n U R L                             %
   5429 %                                                                             %
   5430 %                                                                             %
   5431 %                                                                             %
   5432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5433 %
   5434 %  DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
   5435 %
   5436 %  The format of the DrawSetStrokePatternURL method is:
   5437 %
   5438 %      MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
   5439 %        const char *stroke_url)
   5440 %
   5441 %  A description of each parameter follows:
   5442 %
   5443 %    o wand: the drawing wand.
   5444 %
   5445 %    o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
   5446 %
   5447 */
   5448 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
   5449   const char *stroke_url)
   5450 {
   5451   char
   5452     pattern[MagickPathExtent],
   5453     pattern_spec[MagickPathExtent];
   5454 
   5455   assert(wand != (DrawingWand *) NULL);
   5456   assert(wand->signature == MagickWandSignature);
   5457   if (wand->debug != MagickFalse)
   5458     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5459   if (wand->image == (Image *) NULL)
   5460     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   5461   assert(stroke_url != NULL);
   5462   if (stroke_url[0] != '#')
   5463     ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
   5464   (void) FormatLocaleString(pattern,MagickPathExtent,"%s",stroke_url+1);
   5465   if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
   5466     {
   5467       ThrowDrawException(DrawError,"URLNotFound",stroke_url)
   5468       return(MagickFalse);
   5469     }
   5470   (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",stroke_url);
   5471 #if DRAW_BINARY_IMPLEMENTATION
   5472   DrawPatternPath(wand->image,CurrentContext,pattern_spec,
   5473     &CurrentContext->stroke_pattern);
   5474 #endif
   5475   if (CurrentContext->stroke.alpha != (Quantum) TransparentAlpha)
   5476     CurrentContext->stroke.alpha=(double) CurrentContext->alpha;
   5477   (void) MVGPrintf(wand,"stroke %s\n",pattern_spec);
   5478   return(MagickTrue);
   5479 }
   5480 
   5481 /*
   5483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5484 %                                                                             %
   5485 %                                                                             %
   5486 %                                                                             %
   5487 %   D r a w S e t S t r o k e A n t i a l i a s                               %
   5488 %                                                                             %
   5489 %                                                                             %
   5490 %                                                                             %
   5491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5492 %
   5493 %  DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
   5494 %  Stroked outlines are antialiased by default.  When antialiasing is disabled
   5495 %  stroked pixels are thresholded to determine if the stroke color or
   5496 %  underlying canvas color should be used.
   5497 %
   5498 %  The format of the DrawSetStrokeAntialias method is:
   5499 %
   5500 %      void DrawSetStrokeAntialias(DrawingWand *wand,
   5501 %        const MagickBooleanType stroke_antialias)
   5502 %
   5503 %  A description of each parameter follows:
   5504 %
   5505 %    o wand: the drawing wand.
   5506 %
   5507 %    o stroke_antialias: set to false (zero) to disable antialiasing
   5508 %
   5509 */
   5510 WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
   5511   const MagickBooleanType stroke_antialias)
   5512 {
   5513   assert(wand != (DrawingWand *) NULL);
   5514   assert(wand->signature == MagickWandSignature);
   5515   if (wand->debug != MagickFalse)
   5516     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5517   if ((wand->filter_off != MagickFalse) ||
   5518       (CurrentContext->stroke_antialias != stroke_antialias))
   5519     {
   5520       CurrentContext->stroke_antialias=stroke_antialias;
   5521       (void) MVGPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
   5522         1 : 0);
   5523     }
   5524 }
   5525 
   5526 /*
   5528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5529 %                                                                             %
   5530 %                                                                             %
   5531 %                                                                             %
   5532 %   D r a w S e t S t r o k e D a s h A r r a y                               %
   5533 %                                                                             %
   5534 %                                                                             %
   5535 %                                                                             %
   5536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5537 %
   5538 %  DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
   5539 %  stroke paths. The stroke dash array represents an array of numbers that
   5540 %  specify the lengths of alternating dashes and gaps in pixels. If an odd
   5541 %  number of values is provided, then the list of values is repeated to yield
   5542 %  an even number of values. To remove an existing dash array, pass a zero
   5543 %  number_elements argument and null dasharray.  A typical stroke dash array
   5544 %  might contain the members 5 3 2.
   5545 %
   5546 %  The format of the DrawSetStrokeDashArray method is:
   5547 %
   5548 %      MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
   5549 %        const size_t number_elements,const double *dasharray)
   5550 %
   5551 %  A description of each parameter follows:
   5552 %
   5553 %    o wand: the drawing wand.
   5554 %
   5555 %    o number_elements: number of elements in dash array
   5556 %
   5557 %    o dasharray: dash array values
   5558 %
   5559 */
   5560 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
   5561   const size_t number_elements,const double *dasharray)
   5562 {
   5563   MagickBooleanType
   5564     update;
   5565 
   5566   register const double
   5567     *p;
   5568 
   5569   register double
   5570     *q;
   5571 
   5572   register ssize_t
   5573     i;
   5574 
   5575   size_t
   5576     n_new,
   5577     n_old;
   5578 
   5579   assert(wand != (DrawingWand *) NULL);
   5580   assert(wand->signature == MagickWandSignature);
   5581   if (wand->debug != MagickFalse)
   5582     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5583   n_new=number_elements;
   5584   if (dasharray == (const double *) NULL)
   5585     n_new=0;
   5586   n_old=0;
   5587   update=MagickFalse;
   5588   q=CurrentContext->dash_pattern;
   5589   if (q != (const double *) NULL)
   5590     while (fabs(*q++) < MagickEpsilon)
   5591       n_old++;
   5592   if ((n_old == 0) && (n_new == 0))
   5593     update=MagickFalse;
   5594   else
   5595     if (n_old != n_new)
   5596       update=MagickTrue;
   5597     else
   5598       if ((CurrentContext->dash_pattern != (double *) NULL) &&
   5599           (dasharray != (double *) NULL))
   5600         {
   5601           p=dasharray;
   5602           q=CurrentContext->dash_pattern;
   5603           for (i=0; i < (ssize_t) n_new; i++)
   5604           {
   5605             if (fabs((*p)-(*q)) >= MagickEpsilon)
   5606               {
   5607                 update=MagickTrue;
   5608                 break;
   5609               }
   5610             p++;
   5611             q++;
   5612           }
   5613         }
   5614   if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
   5615     {
   5616       if (CurrentContext->dash_pattern != (double *) NULL)
   5617         CurrentContext->dash_pattern=(double *)
   5618           RelinquishMagickMemory(CurrentContext->dash_pattern);
   5619       if (n_new != 0)
   5620         {
   5621           CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
   5622             n_new+1UL,sizeof(*CurrentContext->dash_pattern));
   5623           if (CurrentContext->dash_pattern == (double *) NULL)
   5624             {
   5625               ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
   5626                 wand->name);
   5627               return(MagickFalse);
   5628             }
   5629           for (i=0; i < (ssize_t) n_new; i++)
   5630           {
   5631             CurrentContext->dash_pattern[i]=0.0;
   5632             if (dasharray != (double *) NULL)
   5633               CurrentContext->dash_pattern[i]=dasharray[i];
   5634           }
   5635           CurrentContext->dash_pattern[n_new]=0.0;
   5636         }
   5637       (void) MVGPrintf(wand,"stroke-dasharray ");
   5638       if (n_new == 0)
   5639         (void) MVGPrintf(wand,"none\n");
   5640       else
   5641         if (dasharray != (double *) NULL)
   5642           {
   5643             for (i=0; i < (ssize_t) n_new; i++)
   5644             {
   5645               if (i != 0)
   5646                 (void) MVGPrintf(wand,",");
   5647               (void) MVGPrintf(wand,"%.20g",dasharray[i]);
   5648             }
   5649             (void) MVGPrintf(wand,"\n");
   5650           }
   5651     }
   5652   return(MagickTrue);
   5653 }
   5654 
   5655 /*
   5657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5658 %                                                                             %
   5659 %                                                                             %
   5660 %                                                                             %
   5661 %   D r a w S e t S t r o k e D a s h O f f s e t                             %
   5662 %                                                                             %
   5663 %                                                                             %
   5664 %                                                                             %
   5665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5666 %
   5667 %  DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
   5668 %  start the dash.
   5669 %
   5670 %  The format of the DrawSetStrokeDashOffset method is:
   5671 %
   5672 %      void DrawSetStrokeDashOffset(DrawingWand *wand,
   5673 %        const double dash_offset)
   5674 %
   5675 %  A description of each parameter follows:
   5676 %
   5677 %    o wand: the drawing wand.
   5678 %
   5679 %    o dash_offset: dash offset
   5680 %
   5681 */
   5682 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
   5683   const double dash_offset)
   5684 {
   5685   assert(wand != (DrawingWand *) NULL);
   5686   assert(wand->signature == MagickWandSignature);
   5687   if (wand->debug != MagickFalse)
   5688     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5689   if ((wand->filter_off != MagickFalse) ||
   5690      (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon))
   5691     {
   5692       CurrentContext->dash_offset=dash_offset;
   5693       (void) MVGPrintf(wand,"stroke-dashoffset %.20g\n",dash_offset);
   5694     }
   5695 }
   5696 
   5697 /*
   5699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5700 %                                                                             %
   5701 %                                                                             %
   5702 %                                                                             %
   5703 %   D r a w S e t S t r o k e L i n e C a p                                   %
   5704 %                                                                             %
   5705 %                                                                             %
   5706 %                                                                             %
   5707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5708 %
   5709 %  DrawSetStrokeLineCap() specifies the shape to be used at the end of
   5710 %  open subpaths when they are stroked. Values of LineCap are
   5711 %  UndefinedCap, ButtCap, RoundCap, and SquareCap.
   5712 %
   5713 %  The format of the DrawSetStrokeLineCap method is:
   5714 %
   5715 %      void DrawSetStrokeLineCap(DrawingWand *wand,
   5716 %        const LineCap linecap)
   5717 %
   5718 %  A description of each parameter follows:
   5719 %
   5720 %    o wand: the drawing wand.
   5721 %
   5722 %    o linecap: linecap style
   5723 %
   5724 */
   5725 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
   5726 {
   5727   assert(wand != (DrawingWand *) NULL);
   5728   assert(wand->signature == MagickWandSignature);
   5729   if (wand->debug != MagickFalse)
   5730     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5731   if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap))
   5732     {
   5733       CurrentContext->linecap=linecap;
   5734       (void) MVGPrintf(wand,"stroke-linecap '%s'\n",CommandOptionToMnemonic(
   5735         MagickLineCapOptions,(ssize_t) linecap));
   5736     }
   5737 }
   5738 
   5739 /*
   5741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5742 %                                                                             %
   5743 %                                                                             %
   5744 %                                                                             %
   5745 %   D r a w S e t S t r o k e L i n e J o i n                                 %
   5746 %                                                                             %
   5747 %                                                                             %
   5748 %                                                                             %
   5749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5750 %
   5751 %  DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
   5752 %  paths (or other vector shapes) when they are stroked. Values of LineJoin are
   5753 %  UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
   5754 %
   5755 %  The format of the DrawSetStrokeLineJoin method is:
   5756 %
   5757 %      void DrawSetStrokeLineJoin(DrawingWand *wand,
   5758 %        const LineJoin linejoin)
   5759 %
   5760 %  A description of each parameter follows:
   5761 %
   5762 %    o wand: the drawing wand.
   5763 %
   5764 %    o linejoin: line join style
   5765 %
   5766 */
   5767 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
   5768 {
   5769   assert(wand != (DrawingWand *) NULL);
   5770   assert(wand->signature == MagickWandSignature);
   5771   if (wand->debug != MagickFalse)
   5772     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5773   if ((wand->filter_off != MagickFalse) ||
   5774       (CurrentContext->linejoin != linejoin))
   5775     {
   5776       CurrentContext->linejoin=linejoin;
   5777       (void) MVGPrintf(wand, "stroke-linejoin '%s'\n",CommandOptionToMnemonic(
   5778         MagickLineJoinOptions,(ssize_t) linejoin));
   5779     }
   5780 }
   5781 
   5782 /*
   5784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5785 %                                                                             %
   5786 %                                                                             %
   5787 %                                                                             %
   5788 %   D r a w S e t S t r o k e M i t e r L i m i t                             %
   5789 %                                                                             %
   5790 %                                                                             %
   5791 %                                                                             %
   5792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5793 %
   5794 %  DrawSetStrokeMiterLimit() specifies the miter limit. When two line
   5795 %  segments meet at a sharp angle and miter joins have been specified for
   5796 %  'lineJoin', it is possible for the miter to extend far beyond the
   5797 %  thickness of the line stroking the path. The miterLimit' imposes a
   5798 %  limit on the ratio of the miter length to the 'lineWidth'.
   5799 %
   5800 %  The format of the DrawSetStrokeMiterLimit method is:
   5801 %
   5802 %      void DrawSetStrokeMiterLimit(DrawingWand *wand,
   5803 %        const size_t miterlimit)
   5804 %
   5805 %  A description of each parameter follows:
   5806 %
   5807 %    o wand: the drawing wand.
   5808 %
   5809 %    o miterlimit: miter limit
   5810 %
   5811 */
   5812 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
   5813   const size_t miterlimit)
   5814 {
   5815   assert(wand != (DrawingWand *) NULL);
   5816   assert(wand->signature == MagickWandSignature);
   5817   if (wand->debug != MagickFalse)
   5818     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5819   if (CurrentContext->miterlimit != miterlimit)
   5820     {
   5821       CurrentContext->miterlimit=miterlimit;
   5822       (void) MVGPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit);
   5823     }
   5824 }
   5825 
   5826 /*
   5828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5829 %                                                                             %
   5830 %                                                                             %
   5831 %                                                                             %
   5832 %   D r a w S e t S t r o k e O p a c i t y                                   %
   5833 %                                                                             %
   5834 %                                                                             %
   5835 %                                                                             %
   5836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5837 %
   5838 %  DrawSetStrokeOpacity() specifies the alpha of stroked object outlines.
   5839 %
   5840 %  The format of the DrawSetStrokeOpacity method is:
   5841 %
   5842 %      void DrawSetStrokeOpacity(DrawingWand *wand,
   5843 %        const double stroke_alpha)
   5844 %
   5845 %  A description of each parameter follows:
   5846 %
   5847 %    o wand: the drawing wand.
   5848 %
   5849 %    o opacity: stroke opacity.  The value 1.0 is opaque.
   5850 %
   5851 */
   5852 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
   5853   const double opacity)
   5854 {
   5855   double
   5856     alpha;
   5857 
   5858   assert(wand != (DrawingWand *) NULL);
   5859   assert(wand->signature == MagickWandSignature);
   5860   if (wand->debug != MagickFalse)
   5861     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5862   alpha=(double) ClampToQuantum(QuantumRange*opacity);
   5863   if ((wand->filter_off != MagickFalse) ||
   5864       (CurrentContext->stroke.alpha != alpha))
   5865     {
   5866       CurrentContext->stroke.alpha=alpha;
   5867       (void) MVGPrintf(wand,"stroke-opacity %.20g\n",opacity);
   5868     }
   5869 }
   5870 
   5871 /*
   5873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5874 %                                                                             %
   5875 %                                                                             %
   5876 %                                                                             %
   5877 %   D r a w S e t S t r o k e W i d t h                                       %
   5878 %                                                                             %
   5879 %                                                                             %
   5880 %                                                                             %
   5881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5882 %
   5883 %  DrawSetStrokeWidth() sets the width of the stroke used to draw object
   5884 %  outlines.
   5885 %
   5886 %  The format of the DrawSetStrokeWidth method is:
   5887 %
   5888 %      void DrawSetStrokeWidth(DrawingWand *wand,
   5889 %        const double stroke_width)
   5890 %
   5891 %  A description of each parameter follows:
   5892 %
   5893 %    o wand: the drawing wand.
   5894 %
   5895 %    o stroke_width: stroke width
   5896 %
   5897 */
   5898 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
   5899 {
   5900   assert(wand != (DrawingWand *) NULL);
   5901   assert(wand->signature == MagickWandSignature);
   5902   if (wand->debug != MagickFalse)
   5903     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5904   if ((wand->filter_off != MagickFalse) ||
   5905       (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon))
   5906     {
   5907       CurrentContext->stroke_width=stroke_width;
   5908       (void) MVGPrintf(wand,"stroke-width %.20g\n",stroke_width);
   5909     }
   5910 }
   5911 
   5912 /*
   5914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5915 %                                                                             %
   5916 %                                                                             %
   5917 %                                                                             %
   5918 %   D r a w S e t T e x t A l i g n m e n t                                   %
   5919 %                                                                             %
   5920 %                                                                             %
   5921 %                                                                             %
   5922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5923 %
   5924 %  DrawSetTextAlignment() specifies a text alignment to be applied when
   5925 %  annotating with text.
   5926 %
   5927 %  The format of the DrawSetTextAlignment method is:
   5928 %
   5929 %      void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
   5930 %
   5931 %  A description of each parameter follows:
   5932 %
   5933 %    o wand: the drawing wand.
   5934 %
   5935 %    o alignment: text alignment.  One of UndefinedAlign, LeftAlign,
   5936 %      CenterAlign, or RightAlign.
   5937 %
   5938 */
   5939 WandExport void DrawSetTextAlignment(DrawingWand *wand,
   5940   const AlignType alignment)
   5941 {
   5942   assert(wand != (DrawingWand *) NULL);
   5943   assert(wand->signature == MagickWandSignature);
   5944   if (wand->debug != MagickFalse)
   5945     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5946   if ((wand->filter_off != MagickFalse) ||
   5947       (CurrentContext->align != alignment))
   5948     {
   5949       CurrentContext->align=alignment;
   5950       (void) MVGPrintf(wand,"text-align '%s'\n",CommandOptionToMnemonic(
   5951         MagickAlignOptions,(ssize_t) alignment));
   5952     }
   5953 }
   5954 
   5955 /*
   5957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5958 %                                                                             %
   5959 %                                                                             %
   5960 %                                                                             %
   5961 %   D r a w S e t T e x t A n t i a l i a s                                   %
   5962 %                                                                             %
   5963 %                                                                             %
   5964 %                                                                             %
   5965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5966 %
   5967 %  DrawSetTextAntialias() controls whether text is antialiased.  Text is
   5968 %  antialiased by default.
   5969 %
   5970 %  The format of the DrawSetTextAntialias method is:
   5971 %
   5972 %      void DrawSetTextAntialias(DrawingWand *wand,
   5973 %        const MagickBooleanType text_antialias)
   5974 %
   5975 %  A description of each parameter follows:
   5976 %
   5977 %    o wand: the drawing wand.
   5978 %
   5979 %    o text_antialias: antialias boolean. Set to false (0) to disable
   5980 %      antialiasing.
   5981 %
   5982 */
   5983 WandExport void DrawSetTextAntialias(DrawingWand *wand,
   5984   const MagickBooleanType text_antialias)
   5985 {
   5986   assert(wand != (DrawingWand *) NULL);
   5987   assert(wand->signature == MagickWandSignature);
   5988   if (wand->debug != MagickFalse)
   5989     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   5990   if ((wand->filter_off != MagickFalse) ||
   5991       (CurrentContext->text_antialias != text_antialias))
   5992     {
   5993       CurrentContext->text_antialias=text_antialias;
   5994       (void) MVGPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
   5995     }
   5996 }
   5997 
   5998 /*
   6000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6001 %                                                                             %
   6002 %                                                                             %
   6003 %                                                                             %
   6004 %   D r a w S e t T e x t D e c o r a t i o n                                 %
   6005 %                                                                             %
   6006 %                                                                             %
   6007 %                                                                             %
   6008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6009 %
   6010 %  DrawSetTextDecoration() specifies a decoration to be applied when
   6011 %  annotating with text.
   6012 %
   6013 %  The format of the DrawSetTextDecoration method is:
   6014 %
   6015 %      void DrawSetTextDecoration(DrawingWand *wand,
   6016 %        const DecorationType decoration)
   6017 %
   6018 %  A description of each parameter follows:
   6019 %
   6020 %    o wand: the drawing wand.
   6021 %
   6022 %    o decoration: text decoration.  One of NoDecoration, UnderlineDecoration,
   6023 %      OverlineDecoration, or LineThroughDecoration
   6024 %
   6025 */
   6026 WandExport void DrawSetTextDecoration(DrawingWand *wand,
   6027   const DecorationType decoration)
   6028 {
   6029   assert(wand != (DrawingWand *) NULL);
   6030   assert(wand->signature == MagickWandSignature);
   6031   if (wand->debug != MagickFalse)
   6032     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6033   if ((wand->filter_off != MagickFalse) ||
   6034       (CurrentContext->decorate != decoration))
   6035     {
   6036       CurrentContext->decorate=decoration;
   6037       (void) MVGPrintf(wand,"decorate '%s'\n",CommandOptionToMnemonic(
   6038         MagickDecorateOptions,(ssize_t) decoration));
   6039     }
   6040 }
   6041 
   6042 /*
   6044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6045 %                                                                             %
   6046 %                                                                             %
   6047 %                                                                             %
   6048 %   D r a w S e t T e x t D i r e c t i o n                                   %
   6049 %                                                                             %
   6050 %                                                                             %
   6051 %                                                                             %
   6052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6053 %
   6054 %  DrawSetTextDirection() specifies the direction to be used when
   6055 %  annotating with text.
   6056 %
   6057 %  The format of the DrawSetTextDirection method is:
   6058 %
   6059 %      void DrawSetTextDirection(DrawingWand *wand,
   6060 %        const DirectionType direction)
   6061 %
   6062 %  A description of each parameter follows:
   6063 %
   6064 %    o wand: the drawing wand.
   6065 %
   6066 %    o direction: text direction. One of RightToLeftDirection,
   6067 %      LeftToRightDirection
   6068 %
   6069 */
   6070 WandExport void DrawSetTextDirection(DrawingWand *wand,
   6071   const DirectionType direction)
   6072 {
   6073   assert(wand != (DrawingWand *) NULL);
   6074   assert(wand->signature == MagickWandSignature);
   6075 
   6076   if (wand->debug != MagickFalse)
   6077     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6078   if ((wand->filter_off != MagickFalse) ||
   6079       (CurrentContext->direction != direction))
   6080     {
   6081       CurrentContext->direction=direction;
   6082       (void) MVGPrintf(wand,"direction '%s'\n",CommandOptionToMnemonic(
   6083         MagickDirectionOptions,(ssize_t) direction));
   6084     }
   6085 }
   6086 
   6087 /*
   6088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6089 %                                                                             %
   6090 %                                                                             %
   6091 %                                                                             %
   6092 %   D r a w S e t T e x t E n c o d i n g                                     %
   6093 %                                                                             %
   6094 %                                                                             %
   6095 %                                                                             %
   6096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6097 %
   6098 %  DrawSetTextEncoding() specifies the code set to use for text
   6099 %  annotations. The only character encoding which may be specified
   6100 %  at this time is "UTF-8" for representing Unicode as a sequence of
   6101 %  bytes. Specify an empty string to set text encoding to the system's
   6102 %  default. Successful text annotation using Unicode may require fonts
   6103 %  designed to support Unicode.
   6104 %
   6105 %  The format of the DrawSetTextEncoding method is:
   6106 %
   6107 %      void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
   6108 %
   6109 %  A description of each parameter follows:
   6110 %
   6111 %    o wand: the drawing wand.
   6112 %
   6113 %    o encoding: character string specifying text encoding
   6114 %
   6115 */
   6116 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
   6117 {
   6118   assert(wand != (DrawingWand *) NULL);
   6119   assert(wand->signature == MagickWandSignature);
   6120   if (wand->debug != MagickFalse)
   6121     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6122   assert(encoding != (char *) NULL);
   6123   if ((wand->filter_off != MagickFalse) ||
   6124       (CurrentContext->encoding == (char *) NULL) ||
   6125       (LocaleCompare(CurrentContext->encoding,encoding) != 0))
   6126     {
   6127       (void) CloneString(&CurrentContext->encoding,encoding);
   6128       (void) MVGPrintf(wand,"encoding '%s'\n",encoding);
   6129     }
   6130 }
   6131 
   6132 /*
   6134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6135 %                                                                             %
   6136 %                                                                             %
   6137 %                                                                             %
   6138 %   D r a w S e t T e x t K e r n i n g                                       %
   6139 %                                                                             %
   6140 %                                                                             %
   6141 %                                                                             %
   6142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6143 %
   6144 %  DrawSetTextKerning() sets the spacing between characters in text.
   6145 %
   6146 %  The format of the DrawSetTextKerning method is:
   6147 %
   6148 %      void DrawSetTextKerning(DrawingWand *wand,const double kerning)
   6149 %
   6150 %  A description of each parameter follows:
   6151 %
   6152 %    o wand: the drawing wand.
   6153 %
   6154 %    o kerning: text kerning
   6155 %
   6156 */
   6157 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
   6158 {
   6159   assert(wand != (DrawingWand *) NULL);
   6160   assert(wand->signature == MagickWandSignature);
   6161 
   6162   if (wand->debug != MagickFalse)
   6163     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6164   if ((wand->filter_off != MagickFalse) &&
   6165       ((CurrentContext->kerning-kerning) >= MagickEpsilon))
   6166     {
   6167       CurrentContext->kerning=kerning;
   6168       (void) MVGPrintf(wand,"kerning %lf\n",kerning);
   6169     }
   6170 }
   6171 
   6172 /*
   6174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6175 %                                                                             %
   6176 %                                                                             %
   6177 %                                                                             %
   6178 %   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                     %
   6179 %                                                                             %
   6180 %                                                                             %
   6181 %                                                                             %
   6182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6183 %
   6184 %  DrawSetTextInterlineSpacing() sets the spacing between line in text.
   6185 %
   6186 %  The format of the DrawSetInterlineSpacing method is:
   6187 %
   6188 %      void DrawSetTextInterlineSpacing(DrawingWand *wand,
   6189 %        const double interline_spacing)
   6190 %
   6191 %  A description of each parameter follows:
   6192 %
   6193 %    o wand: the drawing wand.
   6194 %
   6195 %    o interline_spacing: text line spacing
   6196 %
   6197 */
   6198 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
   6199   const double interline_spacing)
   6200 {
   6201   assert(wand != (DrawingWand *) NULL);
   6202   assert(wand->signature == MagickWandSignature);
   6203 
   6204   if (wand->debug != MagickFalse)
   6205     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6206   if ((wand->filter_off != MagickFalse) &&
   6207       ((CurrentContext->interline_spacing-interline_spacing) >= MagickEpsilon))
   6208     {
   6209       CurrentContext->interline_spacing=interline_spacing;
   6210       (void) MVGPrintf(wand,"interline-spacing %lf\n",interline_spacing);
   6211     }
   6212 }
   6213 
   6214 /*
   6216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6217 %                                                                             %
   6218 %                                                                             %
   6219 %                                                                             %
   6220 %   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                     %
   6221 %                                                                             %
   6222 %                                                                             %
   6223 %                                                                             %
   6224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6225 %
   6226 %  DrawSetTextInterwordSpacing() sets the spacing between words in text.
   6227 %
   6228 %  The format of the DrawSetInterwordSpacing method is:
   6229 %
   6230 %      void DrawSetTextInterwordSpacing(DrawingWand *wand,
   6231 %        const double interword_spacing)
   6232 %
   6233 %  A description of each parameter follows:
   6234 %
   6235 %    o wand: the drawing wand.
   6236 %
   6237 %    o interword_spacing: text word spacing
   6238 %
   6239 */
   6240 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
   6241   const double interword_spacing)
   6242 {
   6243   assert(wand != (DrawingWand *) NULL);
   6244   assert(wand->signature == MagickWandSignature);
   6245 
   6246   if (wand->debug != MagickFalse)
   6247     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6248   if ((wand->filter_off != MagickFalse) &&
   6249       ((CurrentContext->interword_spacing-interword_spacing) >= MagickEpsilon))
   6250     {
   6251       CurrentContext->interword_spacing=interword_spacing;
   6252       (void) MVGPrintf(wand,"interword-spacing %lf\n",interword_spacing);
   6253     }
   6254 }
   6255 
   6256 /*
   6258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6259 %                                                                             %
   6260 %                                                                             %
   6261 %                                                                             %
   6262 %   D r a w S e t T e x t U n d e r C o l o r                                 %
   6263 %                                                                             %
   6264 %                                                                             %
   6265 %                                                                             %
   6266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6267 %
   6268 %  DrawSetTextUnderColor() specifies the color of a background rectangle
   6269 %  to place under text annotations.
   6270 %
   6271 %  The format of the DrawSetTextUnderColor method is:
   6272 %
   6273 %      void DrawSetTextUnderColor(DrawingWand *wand,
   6274 %        const PixelWand *under_wand)
   6275 %
   6276 %  A description of each parameter follows:
   6277 %
   6278 %    o wand: the drawing wand.
   6279 %
   6280 %    o under_wand: text under wand.
   6281 %
   6282 */
   6283 WandExport void DrawSetTextUnderColor(DrawingWand *wand,
   6284   const PixelWand *under_wand)
   6285 {
   6286   PixelInfo
   6287     under_color;
   6288 
   6289   assert(wand != (DrawingWand *) NULL);
   6290   assert(wand->signature == MagickWandSignature);
   6291   if (wand->debug != MagickFalse)
   6292     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6293   assert(under_wand != (const PixelWand *) NULL);
   6294   PixelGetQuantumPacket(under_wand,&under_color);
   6295   if ((wand->filter_off != MagickFalse) ||
   6296       (IsPixelInfoEquivalent(&CurrentContext->undercolor,&under_color) == MagickFalse))
   6297     {
   6298       CurrentContext->undercolor=under_color;
   6299       (void) MVGPrintf(wand,"text-undercolor '");
   6300       MVGAppendColor(wand,&under_color);
   6301       (void) MVGPrintf(wand,"'\n");
   6302     }
   6303 }
   6304 
   6305 /*
   6307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6308 %                                                                             %
   6309 %                                                                             %
   6310 %                                                                             %
   6311 %   D r a w S e t V e c t o r G r a p h i c s                                 %
   6312 %                                                                             %
   6313 %                                                                             %
   6314 %                                                                             %
   6315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6316 %
   6317 %  DrawSetVectorGraphics() sets the vector graphics associated with the
   6318 %  specified wand.  Use this method with DrawGetVectorGraphics() as a method
   6319 %  to persist the vector graphics state.
   6320 %
   6321 %  The format of the DrawSetVectorGraphics method is:
   6322 %
   6323 %      MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
   6324 %        const char *xml)
   6325 %
   6326 %  A description of each parameter follows:
   6327 %
   6328 %    o wand: the drawing wand.
   6329 %
   6330 %    o xml: the drawing wand XML.
   6331 %
   6332 */
   6333 
   6334 static inline MagickBooleanType IsPoint(const char *point)
   6335 {
   6336   char
   6337     *p;
   6338 
   6339   long
   6340     value;
   6341 
   6342   value=strtol(point,&p,10);
   6343   (void) value;
   6344   return(p != point ? MagickTrue : MagickFalse);
   6345 }
   6346 
   6347 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
   6348   const char *xml)
   6349 {
   6350   const char
   6351     *value;
   6352 
   6353   XMLTreeInfo
   6354     *child,
   6355     *xml_info;
   6356 
   6357   assert(wand != (DrawingWand *) NULL);
   6358   assert(wand->signature == MagickWandSignature);
   6359   if (wand->debug != MagickFalse)
   6360     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6361   CurrentContext=DestroyDrawInfo(CurrentContext);
   6362   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
   6363   if (xml == (const char *) NULL)
   6364     return(MagickFalse);
   6365   xml_info=NewXMLTree(xml,wand->exception);
   6366   if (xml_info == (XMLTreeInfo *) NULL)
   6367     return(MagickFalse);
   6368   child=GetXMLTreeChild(xml_info,"clip-path");
   6369   if (child != (XMLTreeInfo *) NULL)
   6370     (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
   6371   child=GetXMLTreeChild(xml_info,"clip-units");
   6372   if (child != (XMLTreeInfo *) NULL)
   6373     {
   6374       value=GetXMLTreeContent(child);
   6375       if (value != (const char *) NULL)
   6376         CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption(
   6377           MagickClipPathOptions,MagickFalse,value);
   6378     }
   6379   child=GetXMLTreeChild(xml_info,"decorate");
   6380   if (child != (XMLTreeInfo *) NULL)
   6381     {
   6382       value=GetXMLTreeContent(child);
   6383       if (value != (const char *) NULL)
   6384         CurrentContext->decorate=(DecorationType) ParseCommandOption(
   6385           MagickDecorateOptions,MagickFalse,value);
   6386     }
   6387   child=GetXMLTreeChild(xml_info,"encoding");
   6388   if (child != (XMLTreeInfo *) NULL)
   6389     (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
   6390   child=GetXMLTreeChild(xml_info,"fill");
   6391   if (child != (XMLTreeInfo *) NULL)
   6392     {
   6393       value=GetXMLTreeContent(child);
   6394       if (value != (const char *) NULL)
   6395         (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->fill,
   6396           wand->exception);
   6397     }
   6398   child=GetXMLTreeChild(xml_info,"fill-opacity");
   6399   if (child != (XMLTreeInfo *) NULL)
   6400     {
   6401       value=GetXMLTreeContent(child);
   6402       if (value != (const char *) NULL)
   6403         CurrentContext->fill.alpha=(double) ClampToQuantum(QuantumRange*
   6404           (1.0-StringToDouble(value,(char **) NULL)));
   6405     }
   6406   child=GetXMLTreeChild(xml_info,"fill-rule");
   6407   if (child != (XMLTreeInfo *) NULL)
   6408     {
   6409       value=GetXMLTreeContent(child);
   6410       if (value != (const char *) NULL)
   6411         CurrentContext->fill_rule=(FillRule) ParseCommandOption(
   6412           MagickFillRuleOptions,MagickFalse,value);
   6413     }
   6414   child=GetXMLTreeChild(xml_info,"font");
   6415   if (child != (XMLTreeInfo *) NULL)
   6416     (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
   6417   child=GetXMLTreeChild(xml_info,"font-family");
   6418   if (child != (XMLTreeInfo *) NULL)
   6419     (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
   6420   child=GetXMLTreeChild(xml_info,"font-size");
   6421   if (child != (XMLTreeInfo *) NULL)
   6422     {
   6423       value=GetXMLTreeContent(child);
   6424       if (value != (const char *) NULL)
   6425         CurrentContext->pointsize=StringToDouble(value,(char **) NULL);
   6426     }
   6427   child=GetXMLTreeChild(xml_info,"font-stretch");
   6428   if (child != (XMLTreeInfo *) NULL)
   6429     {
   6430       value=GetXMLTreeContent(child);
   6431       if (value != (const char *) NULL)
   6432         CurrentContext->stretch=(StretchType) ParseCommandOption(
   6433           MagickStretchOptions,MagickFalse,value);
   6434     }
   6435   child=GetXMLTreeChild(xml_info,"font-style");
   6436   if (child != (XMLTreeInfo *) NULL)
   6437     {
   6438       value=GetXMLTreeContent(child);
   6439       if (value != (const char *) NULL)
   6440         CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
   6441           MagickFalse,value);
   6442     }
   6443   child=GetXMLTreeChild(xml_info,"font-weight");
   6444   if (child != (XMLTreeInfo *) NULL)
   6445     {
   6446       value=GetXMLTreeContent(child);
   6447       if (value != (const char *) NULL)
   6448         {
   6449           ssize_t
   6450             weight;
   6451 
   6452           weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
   6453           if (weight == -1)
   6454             weight=StringToUnsignedLong(value);
   6455           CurrentContext->weight=weight;
   6456         }
   6457     }
   6458   child=GetXMLTreeChild(xml_info,"gravity");
   6459   if (child != (XMLTreeInfo *) NULL)
   6460     {
   6461       value=GetXMLTreeContent(child);
   6462       if (value != (const char *) NULL)
   6463         CurrentContext->gravity=(GravityType) ParseCommandOption(
   6464           MagickGravityOptions,MagickFalse,value);
   6465     }
   6466   child=GetXMLTreeChild(xml_info,"stroke");
   6467   if (child != (XMLTreeInfo *) NULL)
   6468     {
   6469       value=GetXMLTreeContent(child);
   6470       if (value != (const char *) NULL)
   6471         (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->stroke,
   6472           wand->exception);
   6473     }
   6474   child=GetXMLTreeChild(xml_info,"stroke-antialias");
   6475   if (child != (XMLTreeInfo *) NULL)
   6476     {
   6477       value=GetXMLTreeContent(child);
   6478       if (value != (const char *) NULL)
   6479         CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
   6480           MagickFalse;
   6481     }
   6482   child=GetXMLTreeChild(xml_info,"stroke-dasharray");
   6483   if (child != (XMLTreeInfo *) NULL)
   6484     {
   6485       char
   6486         token[MagickPathExtent];
   6487 
   6488       const char
   6489         *q;
   6490 
   6491       register ssize_t
   6492         x;
   6493 
   6494       ssize_t
   6495         j;
   6496 
   6497       value=GetXMLTreeContent(child);
   6498       if (value != (const char *) NULL)
   6499         {
   6500           if (CurrentContext->dash_pattern != (double *) NULL)
   6501             CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
   6502               CurrentContext->dash_pattern);
   6503           q=(char *) value;
   6504           if (IsPoint(q) != MagickFalse)
   6505             {
   6506               const char
   6507                 *p;
   6508 
   6509               p=q;
   6510               GetNextToken(p,&p,MagickPathExtent,token);
   6511               if (*token == ',')
   6512                 GetNextToken(p,&p,MagickPathExtent,token);
   6513               for (x=0; IsPoint(token) != MagickFalse; x++)
   6514               {
   6515                 GetNextToken(p,&p,MagickPathExtent,token);
   6516                 if (*token == ',')
   6517                   GetNextToken(p,&p,MagickPathExtent,token);
   6518               }
   6519               CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
   6520                 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
   6521               if (CurrentContext->dash_pattern == (double *) NULL)
   6522                 ThrowWandFatalException(ResourceLimitFatalError,
   6523                   "MemoryAllocationFailed",wand->name);
   6524               for (j=0; j < x; j++)
   6525               {
   6526                 GetNextToken(q,&q,MagickPathExtent,token);
   6527                 if (*token == ',')
   6528                   GetNextToken(q,&q,MagickPathExtent,token);
   6529                 CurrentContext->dash_pattern[j]=StringToDouble(token,
   6530                   (char **) NULL);
   6531               }
   6532               if ((x & 0x01) != 0)
   6533                 for ( ; j < (2*x); j++)
   6534                   CurrentContext->dash_pattern[j]=
   6535                     CurrentContext->dash_pattern[j-x];
   6536               CurrentContext->dash_pattern[j]=0.0;
   6537             }
   6538         }
   6539     }
   6540   child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
   6541   if (child != (XMLTreeInfo *) NULL)
   6542     {
   6543       value=GetXMLTreeContent(child);
   6544       if (value != (const char *) NULL)
   6545         CurrentContext->dash_offset=StringToDouble(value,(char **) NULL);
   6546     }
   6547   child=GetXMLTreeChild(xml_info,"stroke-linecap");
   6548   if (child != (XMLTreeInfo *) NULL)
   6549     {
   6550       value=GetXMLTreeContent(child);
   6551       if (value != (const char *) NULL)
   6552         CurrentContext->linecap=(LineCap) ParseCommandOption(
   6553           MagickLineCapOptions,MagickFalse,value);
   6554     }
   6555   child=GetXMLTreeChild(xml_info,"stroke-linejoin");
   6556   if (child != (XMLTreeInfo *) NULL)
   6557     {
   6558       value=GetXMLTreeContent(child);
   6559       if (value != (const char *) NULL)
   6560         CurrentContext->linejoin=(LineJoin) ParseCommandOption(
   6561           MagickLineJoinOptions,MagickFalse,value);
   6562     }
   6563   child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
   6564   if (child != (XMLTreeInfo *) NULL)
   6565     {
   6566       value=GetXMLTreeContent(child);
   6567       if (value != (const char *) NULL)
   6568         CurrentContext->miterlimit=StringToUnsignedLong(value);
   6569     }
   6570   child=GetXMLTreeChild(xml_info,"stroke-opacity");
   6571   if (child != (XMLTreeInfo *) NULL)
   6572     {
   6573       value=GetXMLTreeContent(child);
   6574       if (value != (const char *) NULL)
   6575         CurrentContext->stroke.alpha=(double) ClampToQuantum(QuantumRange*
   6576           (1.0-StringToDouble(value,(char **) NULL)));
   6577     }
   6578   child=GetXMLTreeChild(xml_info,"stroke-width");
   6579   if (child != (XMLTreeInfo *) NULL)
   6580     {
   6581       value=GetXMLTreeContent(child);
   6582       if (value != (const char *) NULL)
   6583         CurrentContext->stroke_width=StringToDouble(value,(char **) NULL);
   6584     }
   6585   child=GetXMLTreeChild(xml_info,"text-align");
   6586   if (child != (XMLTreeInfo *) NULL)
   6587     {
   6588       value=GetXMLTreeContent(child);
   6589       if (value != (const char *) NULL)
   6590         CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
   6591           MagickFalse,value);
   6592     }
   6593   child=GetXMLTreeChild(xml_info,"text-antialias");
   6594   if (child != (XMLTreeInfo *) NULL)
   6595     {
   6596       value=GetXMLTreeContent(child);
   6597       if (value != (const char *) NULL)
   6598         CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
   6599           MagickFalse;
   6600     }
   6601   child=GetXMLTreeChild(xml_info,"text-undercolor");
   6602   if (child != (XMLTreeInfo *) NULL)
   6603     {
   6604       value=GetXMLTreeContent(child);
   6605       if (value != (const char *) NULL)
   6606         (void) QueryColorCompliance(value,AllCompliance,
   6607           &CurrentContext->undercolor,wand->exception);
   6608     }
   6609   child=GetXMLTreeChild(xml_info,"vector-graphics");
   6610   if (child != (XMLTreeInfo *) NULL)
   6611     {
   6612       (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
   6613       wand->mvg_length=strlen(wand->mvg);
   6614       wand->mvg_alloc=wand->mvg_length+1;
   6615     }
   6616   xml_info=DestroyXMLTree(xml_info);
   6617   return(MagickTrue);
   6618 }
   6619 
   6620 /*
   6622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6623 %                                                                             %
   6624 %                                                                             %
   6625 %                                                                             %
   6626 %   D r a w S k e w X                                                         %
   6627 %                                                                             %
   6628 %                                                                             %
   6629 %                                                                             %
   6630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6631 %
   6632 %  DrawSkewX() skews the current coordinate system in the horizontal
   6633 %  direction.
   6634 %
   6635 %  The format of the DrawSkewX method is:
   6636 %
   6637 %      void DrawSkewX(DrawingWand *wand,const double degrees)
   6638 %
   6639 %  A description of each parameter follows:
   6640 %
   6641 %    o wand: the drawing wand.
   6642 %
   6643 %    o degrees: number of degrees to skew the coordinates
   6644 %
   6645 */
   6646 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
   6647 {
   6648   assert(wand != (DrawingWand *) NULL);
   6649   assert(wand->signature == MagickWandSignature);
   6650   if (wand->debug != MagickFalse)
   6651     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6652   (void) MVGPrintf(wand,"skewX %.20g\n",degrees);
   6653 }
   6654 
   6655 /*
   6657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6658 %                                                                             %
   6659 %                                                                             %
   6660 %                                                                             %
   6661 %   D r a w S k e w Y                                                         %
   6662 %                                                                             %
   6663 %                                                                             %
   6664 %                                                                             %
   6665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6666 %
   6667 %  DrawSkewY() skews the current coordinate system in the vertical
   6668 %  direction.
   6669 %
   6670 %  The format of the DrawSkewY method is:
   6671 %
   6672 %      void DrawSkewY(DrawingWand *wand,const double degrees)
   6673 %
   6674 %  A description of each parameter follows:
   6675 %
   6676 %    o wand: the drawing wand.
   6677 %
   6678 %    o degrees: number of degrees to skew the coordinates
   6679 %
   6680 */
   6681 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
   6682 {
   6683   assert(wand != (DrawingWand *) NULL);
   6684   assert(wand->signature == MagickWandSignature);
   6685   if (wand->debug != MagickFalse)
   6686     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6687   (void) MVGPrintf(wand,"skewY %.20g\n",degrees);
   6688 }
   6689 
   6690 /*
   6692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6693 %                                                                             %
   6694 %                                                                             %
   6695 %                                                                             %
   6696 %   D r a w T r a n s l a t e                                                 %
   6697 %                                                                             %
   6698 %                                                                             %
   6699 %                                                                             %
   6700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6701 %
   6702 %  DrawTranslate() applies a translation to the current coordinate
   6703 %  system which moves the coordinate system origin to the specified
   6704 %  coordinate.
   6705 %
   6706 %  The format of the DrawTranslate method is:
   6707 %
   6708 %      void DrawTranslate(DrawingWand *wand,const double x,
   6709 %        const double y)
   6710 %
   6711 %  A description of each parameter follows:
   6712 %
   6713 %    o wand: the drawing wand.
   6714 %
   6715 %    o x: new x ordinate for coordinate system origin
   6716 %
   6717 %    o y: new y ordinate for coordinate system origin
   6718 %
   6719 */
   6720 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
   6721 {
   6722   assert(wand != (DrawingWand *) NULL);
   6723   assert(wand->signature == MagickWandSignature);
   6724   if (wand->debug != MagickFalse)
   6725     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6726   (void) MVGPrintf(wand,"translate %.20g %.20g\n",x,y);
   6727 }
   6728 
   6729 /*
   6731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6732 %                                                                             %
   6733 %                                                                             %
   6734 %                                                                             %
   6735 %   D r a w S e t V i e w b o x                                               %
   6736 %                                                                             %
   6737 %                                                                             %
   6738 %                                                                             %
   6739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6740 %
   6741 %  DrawSetViewbox() sets the overall canvas size to be recorded with the
   6742 %  drawing vector data.  Usually this will be specified using the same
   6743 %  size as the canvas image.  When the vector data is saved to SVG or MVG
   6744 %  formats, the viewbox is use to specify the size of the canvas image that
   6745 %  a viewer will render the vector data on.
   6746 %
   6747 %  The format of the DrawSetViewbox method is:
   6748 %
   6749 %      void DrawSetViewbox(DrawingWand *wand,const double x1,const double y1,
   6750 %        const double x2,const double y2)
   6751 %
   6752 %  A description of each parameter follows:
   6753 %
   6754 %    o wand: the drawing wand.
   6755 %
   6756 %    o x1: left x ordinate
   6757 %
   6758 %    o y1: top y ordinate
   6759 %
   6760 %    o x2: right x ordinate
   6761 %
   6762 %    o y2: bottom y ordinate
   6763 %
   6764 */
   6765 WandExport void DrawSetViewbox(DrawingWand *wand,const double x1,
   6766   const double y1,const double x2,const double y2)
   6767 {
   6768   assert(wand != (DrawingWand *) NULL);
   6769   assert(wand->signature == MagickWandSignature);
   6770   if (wand->debug != MagickFalse)
   6771     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6772   (void) MVGPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
   6773 }
   6774 
   6775 /*
   6777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6778 %                                                                             %
   6779 %                                                                             %
   6780 %                                                                             %
   6781 %   I s D r a w i n g W a n d                                                 %
   6782 %                                                                             %
   6783 %                                                                             %
   6784 %                                                                             %
   6785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6786 %
   6787 %  IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
   6788 %
   6789 %  The format of the IsDrawingWand method is:
   6790 %
   6791 %      MagickBooleanType IsDrawingWand(const DrawingWand *wand)
   6792 %
   6793 %  A description of each parameter follows:
   6794 %
   6795 %    o wand: the drawing wand.
   6796 %
   6797 */
   6798 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
   6799 {
   6800   if (wand == (const DrawingWand *) NULL)
   6801     return(MagickFalse);
   6802   if (wand->signature != MagickWandSignature)
   6803     return(MagickFalse);
   6804   if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
   6805     return(MagickFalse);
   6806   return(MagickTrue);
   6807 }
   6808 
   6809 /*
   6811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6812 %                                                                             %
   6813 %                                                                             %
   6814 %                                                                             %
   6815 %   N e w D r a w i n g W a n d                                               %
   6816 %                                                                             %
   6817 %                                                                             %
   6818 %                                                                             %
   6819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6820 %
   6821 %  NewDrawingWand() returns a drawing wand required for all other methods in
   6822 %  the API.
   6823 %
   6824 %  The format of the NewDrawingWand method is:
   6825 %
   6826 %      DrawingWand *NewDrawingWand(void)
   6827 %
   6828 */
   6829 WandExport DrawingWand *NewDrawingWand(void)
   6830 {
   6831   const char
   6832     *quantum;
   6833 
   6834   DrawingWand
   6835     *wand;
   6836 
   6837   size_t
   6838     depth;
   6839 
   6840   quantum=GetMagickQuantumDepth(&depth);
   6841   if (depth != MAGICKCORE_QUANTUM_DEPTH)
   6842     ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
   6843   wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand));
   6844   if (wand == (DrawingWand *) NULL)
   6845     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
   6846       GetExceptionMessage(errno));
   6847   (void) ResetMagickMemory(wand,0,sizeof(*wand));
   6848   wand->id=AcquireWandId();
   6849   (void) FormatLocaleString(wand->name,MagickPathExtent,"%s-%.20g",
   6850     DrawingWandId,(double) wand->id);
   6851   if (wand->debug != MagickFalse)
   6852     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6853   wand->mvg=(char *) NULL;
   6854   wand->mvg_alloc=0;
   6855   wand->mvg_length=0;
   6856   wand->mvg_width=0;
   6857   wand->pattern_id=(char *) NULL;
   6858   wand->pattern_offset=0;
   6859   wand->pattern_bounds.x=0;
   6860   wand->pattern_bounds.y=0;
   6861   wand->pattern_bounds.width=0;
   6862   wand->pattern_bounds.height=0;
   6863   wand->index=0;
   6864   wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(
   6865     *wand->graphic_context));
   6866   if (wand->graphic_context == (DrawInfo **) NULL)
   6867     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
   6868       GetExceptionMessage(errno));
   6869   wand->filter_off=MagickTrue;
   6870   wand->indent_depth=0;
   6871   wand->path_operation=PathDefaultOperation;
   6872   wand->path_mode=DefaultPathMode;
   6873   wand->exception=AcquireExceptionInfo();
   6874   wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception);
   6875   wand->destroy=MagickTrue;
   6876   wand->debug=IsEventLogging();
   6877   wand->signature=MagickWandSignature;
   6878   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
   6879   return(wand);
   6880 }
   6881 
   6882 /*
   6884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6885 %                                                                             %
   6886 %                                                                             %
   6887 %                                                                             %
   6888 %   P e e k D r a w i n g W a n d                                             %
   6889 %                                                                             %
   6890 %                                                                             %
   6891 %                                                                             %
   6892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6893 %
   6894 %  PeekDrawingWand() returns the current drawing wand.
   6895 %
   6896 %  The format of the PeekDrawingWand method is:
   6897 %
   6898 %      DrawInfo *PeekDrawingWand(const DrawingWand *wand)
   6899 %
   6900 %  A description of each parameter follows:
   6901 %
   6902 %    o wand: the drawing wand.
   6903 %
   6904 */
   6905 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
   6906 {
   6907   DrawInfo
   6908     *draw_info;
   6909 
   6910   assert(wand != (const DrawingWand *) NULL);
   6911   assert(wand->signature == MagickWandSignature);
   6912   if (wand->debug != MagickFalse)
   6913     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6914   draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
   6915   GetAffineMatrix(&draw_info->affine);
   6916   (void) CloneString(&draw_info->primitive,wand->mvg);
   6917   return(draw_info);
   6918 }
   6919 
   6920 /*
   6922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6923 %                                                                             %
   6924 %                                                                             %
   6925 %                                                                             %
   6926 %   P o p D r a w i n g W a n d                                               %
   6927 %                                                                             %
   6928 %                                                                             %
   6929 %                                                                             %
   6930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6931 %
   6932 %  PopDrawingWand() destroys the current drawing wand and returns to the
   6933 %  previously pushed drawing wand. Multiple drawing wands may exist. It is an
   6934 %  error to attempt to pop more drawing wands than have been pushed, and it is
   6935 %  proper form to pop all drawing wands which have been pushed.
   6936 %
   6937 %  The format of the PopDrawingWand method is:
   6938 %
   6939 %      MagickBooleanType PopDrawingWand(DrawingWand *wand)
   6940 %
   6941 %  A description of each parameter follows:
   6942 %
   6943 %    o wand: the drawing wand.
   6944 %
   6945 */
   6946 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
   6947 {
   6948   assert(wand != (DrawingWand *) NULL);
   6949   assert(wand->signature == MagickWandSignature);
   6950   if (wand->debug != MagickFalse)
   6951     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   6952   if (wand->index == 0)
   6953     {
   6954       ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
   6955       return(MagickFalse);
   6956     }
   6957   /*
   6958     Destroy clip path if not same in preceding wand.
   6959   */
   6960 #if DRAW_BINARY_IMPLEMENTATION
   6961   if (wand->image == (Image *) NULL)
   6962     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
   6963   if (CurrentContext->clip_mask != (char *) NULL)
   6964     if (LocaleCompare(CurrentContext->clip_mask,
   6965         wand->graphic_context[wand->index-1]->clip_mask) != 0)
   6966       (void) SetImageMask(wand->image,ReadPixelMask,(Image *) NULL,
   6967         wand->exception);
   6968 #endif
   6969   CurrentContext=DestroyDrawInfo(CurrentContext);
   6970   wand->index--;
   6971   if (wand->indent_depth > 0)
   6972     wand->indent_depth--;
   6973   (void) MVGPrintf(wand,"pop graphic-context\n");
   6974   return(MagickTrue);
   6975 }
   6976 
   6977 /*
   6979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6980 %                                                                             %
   6981 %                                                                             %
   6982 %                                                                             %
   6983 %   P u s h D r a w i n g W a n d                                             %
   6984 %                                                                             %
   6985 %                                                                             %
   6986 %                                                                             %
   6987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6988 %
   6989 %  PushDrawingWand() clones the current drawing wand to create a new drawing
   6990 %  wand.  The original drawing wand(s) may be returned to by invoking
   6991 %  PopDrawingWand().  The drawing wands are stored on a drawing wand stack.
   6992 %  For every Pop there must have already been an equivalent Push.
   6993 %
   6994 %  The format of the PushDrawingWand method is:
   6995 %
   6996 %      MagickBooleanType PushDrawingWand(DrawingWand *wand)
   6997 %
   6998 %  A description of each parameter follows:
   6999 %
   7000 %    o wand: the drawing wand.
   7001 %
   7002 */
   7003 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
   7004 {
   7005   assert(wand != (DrawingWand *) NULL);
   7006   assert(wand->signature == MagickWandSignature);
   7007   if (wand->debug != MagickFalse)
   7008     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
   7009   wand->index++;
   7010   wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
   7011     (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
   7012   if (wand->graphic_context == (DrawInfo **) NULL)
   7013     {
   7014       wand->index--;
   7015       ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
   7016         wand->name);
   7017       return(MagickFalse);
   7018     }
   7019   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
   7020     wand->graphic_context[wand->index-1]);
   7021   (void) MVGPrintf(wand,"push graphic-context\n");
   7022   wand->indent_depth++;
   7023   return(MagickTrue);
   7024 }
   7025