drawing-wand.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %               DDDD   RRRR    AAA   W   W  IIIII  N   N    GGGG              %
00007 %               D   D  R   R  A   A  W   W    I    NN  N   G                  %
00008 %               D   D  RRRR   AAAAA  W   W    I    N N N   G  GG              %
00009 %               D   D  R R    A   A  W W W    I    N  NN   G   G              %
00010 %               DDDD   R  R   A   A   W W   IIIII  N   N    GGG               %
00011 %                                                                             %
00012 %                         W   W   AAA   N   N  DDDD                           %
00013 %                         W   W  A   A  NN  N  D   D                          %
00014 %                         W W W  AAAAA  N N N  D   D                          %
00015 %                         WW WW  A   A  N  NN  D   D                          %
00016 %                         W   W  A   A  N   N  DDDD                           %
00017 %                                                                             %
00018 %                                                                             %
00019 %                   MagickWand Image Vector Drawing Methods                   %
00020 %                                                                             %
00021 %                              Software Design                                %
00022 %                              Bob Friesenhahn                                %
00023 %                                March 2002                                   %
00024 %                                                                             %
00025 %                                                                             %
00026 %  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
00027 %  dedicated to making software imaging solutions freely available.           %
00028 %                                                                             %
00029 %  You may not use this file except in compliance with the License.  You may  %
00030 %  obtain a copy of the License at                                            %
00031 %                                                                             %
00032 %    http://www.imagemagick.org/script/license.php                            %
00033 %                                                                             %
00034 %  Unless required by applicable law or agreed to in writing, software        %
00035 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00036 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00037 %  See the License for the specific language governing permissions and        %
00038 %  limitations under the License.                                             %
00039 %                                                                             %
00040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00041 %
00042 %
00043 %
00044 */
00045 
00046 /*
00047   Include declarations.
00048 */
00049 #include "wand/studio.h"
00050 #include "wand/MagickWand.h"
00051 #include "wand/magick-wand-private.h"
00052 #include "wand/wand.h"
00053 
00054 /*
00055   Define declarations.
00056 */
00057 #define DRAW_BINARY_IMPLEMENTATION 0
00058 
00059 #define CurrentContext  (wand->graphic_context[wand->index])
00060 #define DrawingWandId  "DrawingWand"
00061 #define ThrowDrawException(severity,tag,reason) (void) ThrowMagickException( \
00062   wand->exception,GetMagickModule(),severity,tag,"`%s'",reason);
00063 
00064 /*
00065   Typedef declarations.
00066 */
00067 typedef enum
00068 {
00069   PathDefaultOperation,
00070   PathCloseOperation,                        /* Z|z (none) */
00071   PathCurveToOperation,                      /* C|c (x1 y1 x2 y2 x y)+ */
00072   PathCurveToQuadraticBezierOperation,       /* Q|q (x1 y1 x y)+ */
00073   PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
00074   PathCurveToSmoothOperation,                /* S|s (x2 y2 x y)+ */
00075   PathEllipticArcOperation,                  /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
00076   PathLineToHorizontalOperation,             /* H|h x+ */
00077   PathLineToOperation,                       /* L|l (x y)+ */
00078   PathLineToVerticalOperation,               /* V|v y+ */
00079   PathMoveToOperation                        /* M|m (x y)+ */
00080 } PathOperation;
00081 
00082 typedef enum
00083 {
00084   DefaultPathMode,
00085   AbsolutePathMode,
00086   RelativePathMode
00087 } PathMode;
00088 
00089 struct _DrawingWand
00090 {
00091   unsigned long
00092     id;
00093 
00094   char
00095     name[MaxTextExtent];
00096 
00097   /* Support structures */
00098   Image
00099     *image;
00100 
00101   ExceptionInfo
00102     *exception;
00103 
00104   /* MVG output string and housekeeping */
00105   char
00106     *mvg;               /* MVG data */
00107 
00108   size_t
00109     mvg_alloc,          /* total allocated memory */
00110     mvg_length;         /* total MVG length */
00111 
00112   unsigned long
00113     mvg_width;          /* current line width */
00114 
00115   /* Pattern support */
00116   char
00117     *pattern_id;
00118 
00119   RectangleInfo
00120     pattern_bounds;
00121 
00122   size_t
00123     pattern_offset;
00124 
00125   /* Graphic wand */
00126   unsigned long
00127     index;              /* array index */
00128 
00129   DrawInfo
00130     **graphic_context;
00131 
00132   MagickBooleanType
00133     filter_off;         /* true if not filtering attributes */
00134 
00135   /* Pretty-printing depth */
00136   unsigned long
00137     indent_depth;       /* number of left-hand pad characters */
00138 
00139   /* Path operation support */
00140   PathOperation
00141     path_operation;
00142 
00143   PathMode
00144     path_mode;
00145 
00146   MagickBooleanType
00147     destroy,
00148     debug;
00149 
00150   unsigned long
00151     signature;
00152 };
00153 
00154 /* Vector table for invoking subordinate renderers */
00155 struct _DrawVTable
00156 {
00157   DrawingWand *(*DestroyDrawingWand) (DrawingWand *);
00158   void (*DrawAnnotation)(DrawingWand *,const double,const double,
00159     const unsigned char *);
00160   void (*DrawArc)(DrawingWand *,const double,const double,const double,
00161     const double,const double,const double);
00162   void (*DrawBezier)(DrawingWand *,const unsigned long,const PointInfo *);
00163   void (*DrawCircle)(DrawingWand *,const double,const double,const double,
00164     const double);
00165   void (*DrawColor)(DrawingWand *,const double,const double,const PaintMethod);
00166   void (*DrawComment)(DrawingWand *,const char *);
00167   void (*DrawEllipse)(DrawingWand *,const double,const double,const double,
00168     const double,const double,const double);
00169   MagickBooleanType (*DrawComposite)(DrawingWand *,const CompositeOperator,
00170     const double,const double,const double,const double,const Image *);
00171   void (*DrawLine)(DrawingWand *,const double,const double,const double,
00172     const double);
00173   void (*DrawMatte)(DrawingWand *,const double,const double,const PaintMethod);
00174   void (*DrawPathClose)(DrawingWand *);
00175   void (*DrawPathCurveToAbsolute)(DrawingWand *,const double,const double,
00176     const double,const double,const double,const double);
00177   void (*DrawPathCurveToRelative)(DrawingWand *,const double,const double,
00178     const double,const double,const double,const double);
00179   void (*DrawPathCurveToQuadraticBezierAbsolute)(DrawingWand *,const double,
00180     const double,const double,const double);
00181   void (*DrawPathCurveToQuadraticBezierRelative)(DrawingWand *,const double,
00182     const double,const double,const double);
00183   void (*DrawPathCurveToQuadraticBezierSmoothAbsolute)(DrawingWand *,
00184     const double,const double);
00185   void (*DrawPathCurveToQuadraticBezierSmoothRelative)(DrawingWand *,
00186     const double,const double);
00187   void (*DrawPathCurveToSmoothAbsolute)(DrawingWand *,const double,
00188     const double,const double,const double);
00189   void (*DrawPathCurveToSmoothRelative)(DrawingWand *,const double,
00190     const double,const double,const double);
00191   void (*DrawPathEllipticArcAbsolute)(DrawingWand *,const double,const double,
00192     const double,const MagickBooleanType,const MagickBooleanType,const double,
00193     const double);
00194   void (*DrawPathEllipticArcRelative)(DrawingWand *,const double,const double,
00195     const double,const MagickBooleanType,const MagickBooleanType,const double,
00196     const double);
00197   void (*DrawPathFinish)(DrawingWand *);
00198   void (*DrawPathLineToAbsolute)(DrawingWand *,const double,const double);
00199   void (*DrawPathLineToRelative)(DrawingWand *,const double,const double);
00200   void (*DrawPathLineToHorizontalAbsolute)(DrawingWand *,const double);
00201   void (*DrawPathLineToHorizontalRelative)(DrawingWand *,const double);
00202   void (*DrawPathLineToVerticalAbsolute)(DrawingWand *,const double);
00203   void (*DrawPathLineToVerticalRelative)(DrawingWand *,const double);
00204   void (*DrawPathMoveToAbsolute)(DrawingWand *,const double,const double);
00205   void (*DrawPathMoveToRelative)(DrawingWand *,const double,const double);
00206   void (*DrawPathStart)(DrawingWand *);
00207   void (*DrawPoint)(DrawingWand *,const double,const double);
00208   void (*DrawPolygon)(DrawingWand *,const unsigned long,const PointInfo *);
00209   void (*DrawPolyline)(DrawingWand *,const unsigned long,const PointInfo *);
00210   void (*DrawPopClipPath)(DrawingWand *);
00211   void (*DrawPopDefs)(DrawingWand *);
00212   MagickBooleanType (*DrawPopPattern)(DrawingWand *);
00213   void (*DrawPushClipPath)(DrawingWand *,const char *);
00214   void (*DrawPushDefs)(DrawingWand *);
00215   MagickBooleanType (*DrawPushPattern)(DrawingWand *,const char *,const double,
00216     const double,const double,const double);
00217   void (*DrawRectangle)(DrawingWand *,const double,const double,const double,
00218     const double);
00219   void (*DrawRoundRectangle)(DrawingWand *,double,double,double,double,
00220     double,double);
00221   void (*DrawAffine)(DrawingWand *,const AffineMatrix *);
00222   MagickBooleanType (*DrawSetClipPath)(DrawingWand *,const char *);
00223   void (*DrawSetClipRule)(DrawingWand *,const FillRule);
00224   void (*DrawSetClipUnits)(DrawingWand *,const ClipPathUnits);
00225   void (*DrawSetFillColor)(DrawingWand *,const PixelWand *);
00226   void (*DrawSetFillRule)(DrawingWand *,const FillRule);
00227   MagickBooleanType (*DrawSetFillPatternURL)(DrawingWand *,const char *);
00228   MagickBooleanType (*DrawSetFont)(DrawingWand *,const char *);
00229   MagickBooleanType (*DrawSetFontFamily)(DrawingWand *,const char *);
00230   void (*DrawSetFontSize)(DrawingWand *,const double);
00231   void (*DrawSetFontStretch)(DrawingWand *,const StretchType);
00232   void (*DrawSetFontStyle)(DrawingWand *,const StyleType);
00233   void (*DrawSetFontWeight)(DrawingWand *,const unsigned long);
00234   void (*DrawSetGravity)(DrawingWand *,const GravityType);
00235   void (*DrawRotate)(DrawingWand *,const double);
00236   void (*DrawScale)(DrawingWand *,const double,const double);
00237   void (*DrawSkewX)(DrawingWand *,const double);
00238   void (*DrawSkewY)(DrawingWand *,const double);
00239   void (*DrawSetStrokeAntialias)(DrawingWand *,const MagickBooleanType);
00240   void (*DrawSetStrokeColor)(DrawingWand *,const PixelWand *);
00241   MagickBooleanType (*DrawSetStrokeDashArray)(DrawingWand *,const double *);
00242   void (*DrawSetStrokeDashOffset)(DrawingWand *,const double);
00243   void (*DrawSetStrokeLineCap)(DrawingWand *,const LineCap);
00244   void (*DrawSetStrokeLineJoin)(DrawingWand *,const LineJoin);
00245   void (*DrawSetStrokeMiterLimit)(DrawingWand *,const unsigned long);
00246   MagickBooleanType (*DrawSetStrokePatternURL)(DrawingWand *,const char *);
00247   void (*DrawSetStrokeWidth)(DrawingWand *,const double);
00248   void (*DrawSetTextAntialias)(DrawingWand *,const MagickBooleanType);
00249   void (*DrawSetTextDecoration)(DrawingWand *,const DecorationType);
00250   void (*DrawSetTextUnderColor)(DrawingWand *,const PixelWand *);
00251   void (*DrawTranslate)(DrawingWand *,const double,const double);
00252   void (*DrawSetViewbox)(DrawingWand *,unsigned long,unsigned long,
00253     unsigned long,unsigned long);
00254   void (*PeekDrawingWand)(DrawingWand *);
00255   MagickBooleanType (*PopDrawingWand)(DrawingWand *);
00256   MagickBooleanType (*PushDrawingWand)(DrawingWand *);
00257 };
00258 
00259 /*
00260   Forward declarations.
00261 */
00262 static int
00263   MvgPrintf(DrawingWand *,const char *,...) wand_attribute((format
00264     (printf,2,3))),
00265   MvgAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format
00266     (printf,2,3)));
00267 
00268 static void
00269   MvgAppendColor(DrawingWand *,const PixelPacket *);
00270 
00271 /*
00272   "Printf" for MVG commands
00273 */
00274 static int MvgPrintf(DrawingWand *wand,const char *format,...)
00275 {
00276   size_t
00277     alloc_size;
00278 
00279   if (wand->debug != MagickFalse)
00280     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format);
00281   assert(wand != (DrawingWand *) NULL);
00282   assert(wand->signature == WandSignature);
00283   alloc_size=20UL*MaxTextExtent;
00284   if (wand->mvg == (char *) NULL)
00285     {
00286       wand->mvg=(char *) AcquireQuantumMemory(alloc_size,sizeof(*wand->mvg));
00287       if (wand->mvg == (char *) NULL)
00288         {
00289           ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
00290             wand->name);
00291           return(-1);
00292         }
00293       wand->mvg_alloc=alloc_size;
00294       wand->mvg_length=0;
00295     }
00296   if (wand->mvg_alloc < (wand->mvg_length+10*MaxTextExtent))
00297     {
00298       size_t
00299         realloc_size;
00300 
00301       realloc_size=wand->mvg_alloc+alloc_size;
00302       wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,realloc_size,
00303         sizeof(*wand->mvg));
00304       if (wand->mvg == (char *) NULL)
00305         {
00306           ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
00307             wand->name);
00308           return -1;
00309         }
00310       wand->mvg_alloc=realloc_size;
00311     }
00312   {
00313     int
00314       formatted_length;
00315 
00316     va_list
00317       argp;
00318 
00319     while (wand->mvg_width < wand->indent_depth)
00320     {
00321       wand->mvg[wand->mvg_length]=' ';
00322       wand->mvg_length++;
00323       wand->mvg_width++;
00324     }
00325     wand->mvg[wand->mvg_length]='\0';
00326     va_start(argp, format);
00327 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
00328     formatted_length=vsnprintf(wand->mvg+wand->mvg_length,
00329       wand->mvg_alloc-wand->mvg_length-1,format,argp);
00330 #else
00331     formatted_length=vsprintf(wand->mvg+wand->mvg_length,
00332       format,argp);
00333 #endif
00334     va_end(argp);
00335     if (formatted_length < 0)
00336       ThrowDrawException(DrawError,"UnableToPrint",format)
00337     else
00338       {
00339         wand->mvg_length+=formatted_length;
00340         wand->mvg_width+=formatted_length;
00341       }
00342     wand->mvg[wand->mvg_length]='\0';
00343     if ((wand->mvg_length > 1) &&
00344         (wand->mvg[wand->mvg_length-1] == '\n'))
00345       wand->mvg_width=0;
00346     assert((wand->mvg_length+1) < wand->mvg_alloc);
00347     return formatted_length;
00348   }
00349 }
00350 
00351 static int MvgAutoWrapPrintf(DrawingWand *wand,const char *format,...)
00352 {
00353   char
00354     buffer[MaxTextExtent];
00355 
00356   int
00357     formatted_length;
00358 
00359   va_list
00360     argp;
00361 
00362   va_start(argp,format);
00363 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
00364   formatted_length=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
00365 #else
00366   formatted_length=vsprintf(buffer,format,argp);
00367 #endif
00368   va_end(argp);
00369   *(buffer+sizeof(buffer)-1)='\0';
00370   if (formatted_length < 0)
00371     ThrowDrawException(DrawError,"UnableToPrint",format)
00372   else
00373     {
00374       if (((wand->mvg_width + formatted_length) > 78) &&
00375           (buffer[formatted_length-1] != '\n'))
00376         (void) MvgPrintf(wand, "\n");
00377       (void) MvgPrintf(wand,"%s",buffer);
00378     }
00379   return(formatted_length);
00380 }
00381 
00382 static void MvgAppendColor(DrawingWand *wand,const PixelPacket *color)
00383 {
00384   if ((color->red == 0) && (color->green == 0) && (color->blue == 0) &&
00385      (color->opacity == (Quantum) TransparentOpacity))
00386     (void) MvgPrintf(wand,"none");
00387   else
00388     {
00389       char
00390         tuple[MaxTextExtent];
00391 
00392       MagickPixelPacket
00393         pixel;
00394 
00395       GetMagickPixelPacket(wand->image,&pixel);
00396       pixel.colorspace=RGBColorspace;
00397       pixel.matte=color->opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
00398       pixel.red=(MagickRealType) color->red;
00399       pixel.green=(MagickRealType) color->green;
00400       pixel.blue=(MagickRealType) color->blue;
00401       pixel.opacity=(MagickRealType) color->opacity;
00402       GetColorTuple(&pixel,MagickTrue,tuple);
00403       (void) MvgPrintf(wand,"%s",tuple);
00404     }
00405 }
00406 
00407 static void MvgAppendPointsCommand(DrawingWand *wand,const char *command,
00408   const unsigned long number_coordinates,const PointInfo *coordinates)
00409 {
00410   const PointInfo
00411     *coordinate;
00412 
00413   unsigned long
00414     i;
00415 
00416   (void) MvgPrintf(wand,"%s",command);
00417   for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
00418   {
00419     (void) MvgAutoWrapPrintf(wand," %g,%g",coordinate->x,coordinate->y);
00420     coordinate++;
00421   }
00422   (void) MvgPrintf(wand, "\n");
00423 }
00424 
00425 static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine)
00426 {
00427   assert(wand != (DrawingWand *) NULL);
00428   assert(wand->signature == WandSignature);
00429   if (wand->debug != MagickFalse)
00430     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00431   if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
00432       (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
00433     {
00434       AffineMatrix
00435         current;
00436 
00437       current=CurrentContext->affine;
00438       CurrentContext->affine.sx=current.sx*affine->sx+current.ry*affine->rx;
00439       CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
00440       CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
00441       CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
00442       CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+
00443         current.tx;
00444       CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+
00445         current.ty;
00446     }
00447 }
00448 
00449 /*
00450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00451 %                                                                             %
00452 %                                                                             %
00453 %                                                                             %
00454 %   C l e a r D r a w i n g W a n d                                           %
00455 %                                                                             %
00456 %                                                                             %
00457 %                                                                             %
00458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00459 %
00460 %  ClearDrawingWand() clear resources associated with the drawing wand.
00461 %
00462 %  The format of the ClearDrawingWand method is:
00463 %
00464 %      DrawingWand *ClearDrawingWand(DrawingWand *wand)
00465 %
00466 %  A description of each parameter follows:
00467 %
00468 %    o wand: the drawing wand. to destroy
00469 %
00470 */
00471 WandExport void ClearDrawingWand(DrawingWand *wand)
00472 {
00473   assert(wand != (DrawingWand *) NULL);
00474   assert(wand->signature == WandSignature);
00475   if (wand->debug != MagickFalse)
00476     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00477   for ( ; wand->index > 0; wand->index--)
00478     CurrentContext=DestroyDrawInfo(CurrentContext);
00479   CurrentContext=DestroyDrawInfo(CurrentContext);
00480   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
00481     wand->graphic_context);
00482   if (wand->pattern_id != (char *) NULL)
00483     wand->pattern_id=DestroyString(wand->pattern_id);
00484   wand->mvg=DestroyString(wand->mvg);
00485   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
00486     wand->image=DestroyImage(wand->image);
00487   else
00488     wand->image=(Image *) NULL;
00489   wand->mvg=(char *) NULL;
00490   wand->mvg_alloc=0;
00491   wand->mvg_length=0;
00492   wand->mvg_width=0;
00493   wand->pattern_id=(char *) NULL;
00494   wand->pattern_offset=0;
00495   wand->pattern_bounds.x=0;
00496   wand->pattern_bounds.y=0;
00497   wand->pattern_bounds.width=0;
00498   wand->pattern_bounds.height=0;
00499   wand->index=0;
00500   wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
00501     sizeof(*wand->graphic_context));
00502   if (wand->graphic_context == (DrawInfo **) NULL)
00503     {
00504       ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
00505         wand->name);
00506       return;
00507     }
00508   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
00509   wand->filter_off=MagickTrue;
00510   wand->indent_depth=0;
00511   wand->path_operation=PathDefaultOperation;
00512   wand->path_mode=DefaultPathMode;
00513   wand->image=AcquireImage((const ImageInfo *) NULL);
00514   ClearMagickException(wand->exception);
00515   wand->destroy=MagickTrue;
00516   wand->debug=IsEventLogging();
00517 }
00518 
00519 /*
00520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00521 %                                                                             %
00522 %                                                                             %
00523 %                                                                             %
00524 %   C l o n e D r a w i n g W a n d                                           %
00525 %                                                                             %
00526 %                                                                             %
00527 %                                                                             %
00528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00529 %
00530 %  CloneDrawingWand() makes an exact copy of the specified wand.
00531 %
00532 %  The format of the CloneDrawingWand method is:
00533 %
00534 %      DrawingWand *CloneDrawingWand(const DrawingWand *wand)
00535 %
00536 %  A description of each parameter follows:
00537 %
00538 %    o wand: the magick wand.
00539 %
00540 %
00541 */
00542 WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
00543 {
00544   DrawingWand
00545     *clone_wand;
00546 
00547   register long
00548     i;
00549 
00550   assert(wand != (DrawingWand *) NULL);
00551   assert(wand->signature == WandSignature);
00552   if (wand->debug != MagickFalse)
00553     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00554   clone_wand=(DrawingWand *) AcquireMagickMemory(sizeof(*clone_wand));
00555   if (clone_wand == (DrawingWand *) NULL)
00556     ThrowWandFatalException(ResourceLimitFatalError,
00557       "MemoryAllocationFailed",strerror(errno));
00558   (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
00559   clone_wand->id=AcquireWandId();
00560   (void) FormatMagickString(clone_wand->name,MaxTextExtent,"DrawingWand-%lu",
00561     clone_wand->id);
00562   clone_wand->exception=AcquireExceptionInfo();
00563   InheritException(clone_wand->exception,wand->exception);
00564   clone_wand->mvg=AcquireString(wand->mvg);
00565   clone_wand->mvg_length=strlen(clone_wand->mvg);
00566   clone_wand->mvg_alloc=wand->mvg_length+1;
00567   clone_wand->mvg_width=wand->mvg_width;
00568   clone_wand->pattern_id=AcquireString(wand->pattern_id);
00569   clone_wand->pattern_offset=wand->pattern_offset;
00570   clone_wand->pattern_bounds=wand->pattern_bounds;
00571   clone_wand->index=wand->index;
00572   clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((size_t)
00573     wand->index+1UL,sizeof(*wand->graphic_context));
00574   if (clone_wand->graphic_context == (DrawInfo **) NULL)
00575     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
00576       strerror(errno));
00577   for (i=0; i <= (long) wand->index; i++)
00578     clone_wand->graphic_context[i]=
00579       CloneDrawInfo((ImageInfo *) NULL,wand->graphic_context[i]);
00580   clone_wand->filter_off=wand->filter_off;
00581   clone_wand->indent_depth=wand->indent_depth;
00582   clone_wand->path_operation=wand->path_operation;
00583   clone_wand->path_mode=wand->path_mode;
00584   clone_wand->image=wand->image;
00585   if (wand->image != (Image *) NULL)
00586     clone_wand->image=CloneImage(wand->image,0,0,MagickTrue,
00587       clone_wand->exception);
00588   clone_wand->destroy=wand->destroy;
00589   clone_wand->debug=IsEventLogging();
00590   if (clone_wand->debug != MagickFalse)
00591     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
00592   clone_wand->signature=WandSignature;
00593   return(clone_wand);
00594 }
00595 
00596 /*
00597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00598 %                                                                             %
00599 %                                                                             %
00600 %                                                                             %
00601 %   D e s t r o y D r a w i n g W a n d                                       %
00602 %                                                                             %
00603 %                                                                             %
00604 %                                                                             %
00605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00606 %
00607 %  DestroyDrawingWand() frees all resources associated with the drawing wand.
00608 %  Once the drawing wand has been freed, it should not be used and further
00609 %  unless it re-allocated.
00610 %
00611 %  The format of the DestroyDrawingWand method is:
00612 %
00613 %      DrawingWand *DestroyDrawingWand(DrawingWand *wand)
00614 %
00615 %  A description of each parameter follows:
00616 %
00617 %    o wand: the drawing wand. to destroy
00618 %
00619 */
00620 WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
00621 {
00622   assert(wand != (DrawingWand *) NULL);
00623   assert(wand->signature == WandSignature);
00624   if (wand->debug != MagickFalse)
00625     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00626   for ( ; wand->index > 0; wand->index--)
00627     CurrentContext=DestroyDrawInfo(CurrentContext);
00628   CurrentContext=DestroyDrawInfo(CurrentContext);
00629   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
00630     wand->graphic_context);
00631   if (wand->pattern_id != (char *) NULL)
00632     wand->pattern_id=DestroyString(wand->pattern_id);
00633   wand->mvg=DestroyString(wand->mvg);
00634   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
00635     wand->image=DestroyImage(wand->image);
00636   wand->image=(Image *) NULL;
00637   wand->exception=DestroyExceptionInfo(wand->exception);
00638   wand->signature=(~WandSignature);
00639   RelinquishWandId(wand->id);
00640   wand=(DrawingWand *) RelinquishMagickMemory(wand);
00641   return(wand);
00642 }
00643 
00644 /*
00645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00646 %                                                                             %
00647 %                                                                             %
00648 %                                                                             %
00649 %   D r a w A f f i n e                                                       %
00650 %                                                                             %
00651 %                                                                             %
00652 %                                                                             %
00653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00654 %
00655 %  DrawAffine() adjusts the current affine transformation matrix with
00656 %  the specified affine transformation matrix. Note that the current affine
00657 %  transform is adjusted rather than replaced.
00658 %
00659 %  The format of the DrawAffine method is:
00660 %
00661 %      void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
00662 %
00663 %  A description of each parameter follows:
00664 %
00665 %    o wand: Drawing wand
00666 %
00667 %    o affine: Affine matrix parameters
00668 %
00669 */
00670 WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
00671 {
00672   assert(wand != (DrawingWand *) NULL);
00673   assert(wand->signature == WandSignature);
00674   if (wand->debug != MagickFalse)
00675     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00676   assert(affine != (const AffineMatrix *) NULL);
00677   AdjustAffine(wand,affine);
00678   (void) MvgPrintf(wand,"affine %g,%g,%g,%g,%g,%g\n",affine->sx,affine->rx,
00679     affine->ry,affine->sy,affine->tx,affine->ty);
00680 }
00681 
00682 /*
00683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00684 %                                                                             %
00685 %                                                                             %
00686 %                                                                             %
00687 +   D r a w A l l o c a t e W a n d                                           %
00688 %                                                                             %
00689 %                                                                             %
00690 %                                                                             %
00691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00692 %
00693 %  DrawAllocateWand() allocates an initial drawing wand which is an
00694 %  opaque handle required by the remaining drawing methods.
00695 %
00696 %  The format of the DrawAllocateWand method is:
00697 %
00698 %      DrawingWand DrawAllocateWand(const DrawInfo *draw_info,Image *image)
00699 %
00700 %  A description of each parameter follows:
00701 %
00702 %    o draw_info: Initial drawing defaults. Set to NULL to use
00703 %                 ImageMagick defaults.
00704 %
00705 %    o image: the image to draw on.
00706 %
00707 */
00708 WandExport DrawingWand *DrawAllocateWand(const DrawInfo *draw_info,Image *image)
00709 {
00710   DrawingWand
00711     *wand;
00712 
00713   wand=NewDrawingWand();
00714   if (draw_info != (const DrawInfo *) NULL)
00715     {
00716       CurrentContext=DestroyDrawInfo(CurrentContext);
00717       CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
00718     }
00719   if (image != (Image *) NULL)
00720     {
00721       wand->image=DestroyImage(wand->image);
00722       wand->destroy=MagickFalse;
00723     }
00724   wand->image=image;
00725   return(wand);
00726 }
00727 
00728 /*
00729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00730 %                                                                             %
00731 %                                                                             %
00732 %                                                                             %
00733 %   D r a w A n n o t a t i o n                                               %
00734 %                                                                             %
00735 %                                                                             %
00736 %                                                                             %
00737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00738 %
00739 %  DrawAnnotation() draws text on the image.
00740 %
00741 %  The format of the DrawAnnotation method is:
00742 %
00743 %      void DrawAnnotation(DrawingWand *wand,const double x,
00744 %        const double y,const unsigned char *text)
00745 %
00746 %  A description of each parameter follows:
00747 %
00748 %    o wand: the drawing wand.
00749 %
00750 %    o x: x ordinate to left of text
00751 %
00752 %    o y: y ordinate to text baseline
00753 %
00754 %    o text: text to draw
00755 %
00756 */
00757 WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y,
00758   const unsigned char *text)
00759 {
00760   char
00761     *escaped_text;
00762 
00763   assert(wand != (DrawingWand *) NULL);
00764   assert(wand->signature == WandSignature);
00765   if (wand->debug != MagickFalse)
00766     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00767   assert(text != (const unsigned char *) NULL);
00768   escaped_text=EscapeString((const char *) text,'\'');
00769   (void) MvgPrintf(wand,"text %g,%g '%s'\n",x,y,escaped_text);
00770   escaped_text=DestroyString(escaped_text);
00771 }
00772 
00773 /*
00774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00775 %                                                                             %
00776 %                                                                             %
00777 %                                                                             %
00778 %   D r a w A r c                                                             %
00779 %                                                                             %
00780 %                                                                             %
00781 %                                                                             %
00782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00783 %
00784 %  DrawArc() draws an arc falling within a specified bounding rectangle on the
00785 %  image.
00786 %
00787 %  The format of the DrawArc method is:
00788 %
00789 %      void DrawArc(DrawingWand *wand,const double sx,const double sy,
00790 %        const double ex,const double ey,const double sd,const double ed)
00791 %
00792 %  A description of each parameter follows:
00793 %
00794 %    o wand: the drawing wand.
00795 %
00796 %    o sx: starting x ordinate of bounding rectangle
00797 %
00798 %    o sy: starting y ordinate of bounding rectangle
00799 %
00800 %    o ex: ending x ordinate of bounding rectangle
00801 %
00802 %    o ey: ending y ordinate of bounding rectangle
00803 %
00804 %    o sd: starting degrees of rotation
00805 %
00806 %    o ed: ending degrees of rotation
00807 %
00808 */
00809 WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy,
00810   const double ex,const double ey,const double sd,const double ed)
00811 {
00812   assert(wand != (DrawingWand *) NULL);
00813   assert(wand->signature == WandSignature);
00814   if (wand->debug != MagickFalse)
00815     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00816   (void) MvgPrintf(wand,"arc %g,%g %g,%g %g,%g\n",sx,sy,ex,ey,sd,ed);
00817 }
00818 
00819 /*
00820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00821 %                                                                             %
00822 %                                                                             %
00823 %                                                                             %
00824 %   D r a w B e z i e r                                                       %
00825 %                                                                             %
00826 %                                                                             %
00827 %                                                                             %
00828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00829 %
00830 %  DrawBezier() draws a bezier curve through a set of points on the image.
00831 %
00832 %  The format of the DrawBezier method is:
00833 %
00834 %      void DrawBezier(DrawingWand *wand,
00835 %        const unsigned long number_coordinates,const PointInfo *coordinates)
00836 %
00837 %  A description of each parameter follows:
00838 %
00839 %    o wand: the drawing wand.
00840 %
00841 %    o number_coordinates: number of coordinates
00842 %
00843 %    o coordinates: coordinates
00844 %
00845 */
00846 WandExport void DrawBezier(DrawingWand *wand,
00847   const unsigned long number_coordinates,const PointInfo *coordinates)
00848 {
00849   assert(wand != (DrawingWand *) NULL);
00850   assert(wand->signature == WandSignature);
00851   if (wand->debug != MagickFalse)
00852     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00853   assert(coordinates != (const PointInfo *) NULL);
00854   MvgAppendPointsCommand(wand,"bezier",number_coordinates,coordinates);
00855 }
00856 
00857 /*
00858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00859 %                                                                             %
00860 %                                                                             %
00861 %                                                                             %
00862 %   D r a w C i r c l e                                                       %
00863 %                                                                             %
00864 %                                                                             %
00865 %                                                                             %
00866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00867 %
00868 %  DrawCircle() draws a circle on the image.
00869 %
00870 %  The format of the DrawCircle method is:
00871 %
00872 %      void DrawCircle(DrawingWand *wand,const double ox,
00873 %        const double oy,const double px, const double py)
00874 %
00875 %  A description of each parameter follows:
00876 %
00877 %    o wand: the drawing wand.
00878 %
00879 %    o ox: origin x ordinate
00880 %
00881 %    o oy: origin y ordinate
00882 %
00883 %    o px: perimeter x ordinate
00884 %
00885 %    o py: perimeter y ordinate
00886 %
00887 */
00888 WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
00889   const double px,const double py)
00890 {
00891   assert(wand != (DrawingWand *) NULL);
00892   assert(wand->signature == WandSignature);
00893   if (wand->debug != MagickFalse)
00894     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00895   (void) MvgPrintf(wand,"circle %g,%g %g,%g\n",ox,oy,px,py);
00896 }
00897 
00898 /*
00899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00900 %                                                                             %
00901 %                                                                             %
00902 %                                                                             %
00903 %   D r a w C l e a r E x c e p t i o n                                       %
00904 %                                                                             %
00905 %                                                                             %
00906 %                                                                             %
00907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00908 %
00909 %  DrawClearException() clear any exceptions associated with the wand.
00910 %
00911 %  The format of the DrawClearException method is:
00912 %
00913 %      MagickBooleanType DrawClearException(DrawWand *wand)
00914 %
00915 %  A description of each parameter follows:
00916 %
00917 %    o wand: the drawing wand.
00918 %
00919 */
00920 WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
00921 {
00922   assert(wand != (DrawingWand *) NULL);
00923   assert(wand->signature == WandSignature);
00924   if (wand->debug != MagickFalse)
00925     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
00926   ClearMagickException(wand->exception);
00927   return(MagickTrue);
00928 }
00929 
00930 /*
00931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00932 %                                                                             %
00933 %                                                                             %
00934 %                                                                             %
00935 %   D r a w C o m p o s i t e                                                 %
00936 %                                                                             %
00937 %                                                                             %
00938 %                                                                             %
00939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00940 %
00941 %  DrawComposite() composites an image onto the current image, using the
00942 %  specified composition operator, specified position, and at the specified
00943 %  size.
00944 %
00945 %  The format of the DrawComposite method is:
00946 %
00947 %      MagickBooleanType DrawComposite(DrawingWand *wand,
00948 %        const CompositeOperator compose,const double x,
00949 %        const double y,const double width,const double height,
00950 %        MagickWand *magick_wand)
00951 %
00952 %  A description of each parameter follows:
00953 %
00954 %    o wand: the drawing wand.
00955 %
00956 %    o compose: composition operator
00957 %
00958 %    o x: x ordinate of top left corner
00959 %
00960 %    o y: y ordinate of top left corner
00961 %
00962 %    o width: Width to resize image to prior to compositing.  Specify zero to
00963 %      use existing width.
00964 %
00965 %    o height: Height to resize image to prior to compositing.  Specify zero
00966 %      to use existing height.
00967 %
00968 %    o magick_wand: Image to composite is obtained from this wand.
00969 %
00970 */
00971 WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
00972   const CompositeOperator compose,c