~ubuntu-branches/ubuntu/intrepid/graphicsmagick/intrepid

« back to all changes in this revision

Viewing changes to magick/draw.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2006-05-06 16:28:08 UTC
  • Revision ID: james.westby@ubuntu.com-20060506162808-vt2ni3r5nytcszms
Tags: upstream-1.1.7
ImportĀ upstreamĀ versionĀ 1.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
% Copyright (C) 2003 GraphicsMagick Group
 
3
% Copyright (C) 2002 ImageMagick Studio
 
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
 
5
%
 
6
% This program is covered by multiple licenses, which are described in
 
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
 
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
 
9
%
 
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
11
%                                                                             %
 
12
%                                                                             %
 
13
%                                                                             %
 
14
%                        DDDD   RRRR    AAA   W   W                           %
 
15
%                        D   D  R   R  A   A  W   W                           %
 
16
%                        D   D  RRRR   AAAAA  W   W                           %
 
17
%                        D   D  R R    A   A  W W W                           %
 
18
%                        DDDD   R  R   A   A   W W                            %
 
19
%                                                                             %
 
20
%                                                                             %
 
21
%                 GraphicsMagick Image Vector Drawing Methods                 %
 
22
%                                                                             %
 
23
%                                                                             %
 
24
%                              Software Design                                %
 
25
%                              Bob Friesenhahn                                %
 
26
%                                March 2002                                   %
 
27
%                                                                             %
 
28
%                                                                             %
 
29
%                                                                             %
 
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
31
%
 
32
%
 
33
*/
 
34
 
 
35
/*
 
36
  Include declarations.
 
37
*/
 
38
#include "magick/studio.h"
 
39
#include "magick/attribute.h"
 
40
#include "magick/blob.h"
 
41
#include "magick/color.h"
 
42
#include "magick/draw.h"
 
43
#include "magick/gem.h"
 
44
#include "magick/log.h"
 
45
#include "magick/magick.h"
 
46
#include "magick/monitor.h"
 
47
#include "magick/utility.h"
 
48
 
 
49
/*
 
50
  Define declarations.
 
51
*/
 
52
#define DRAW_BINARY_IMPLEMENTATION 0
 
53
 
 
54
#define ThrowDrawException(code,reason,description) \
 
55
{ \
 
56
  if (context->image->exception.severity > (long)code) \
 
57
    ThrowException(&context->image->exception,code,reason,description); \
 
58
  return; \
 
59
}
 
60
#define ThrowDrawException3(code,reason,description) \
 
61
{ \
 
62
  if (context->image->exception.severity > (long)code) \
 
63
    ThrowException3(&context->image->exception,code,reason,description); \
 
64
  return; \
 
65
}
 
66
 
 
67
#define CurrentContext (context->graphic_context[context->index])
 
68
#define PixelPacketMatch(p,q) (((p)->red == (q)->red) && \
 
69
  ((p)->green == (q)->green) && ((p)->blue == (q)->blue) && \
 
70
  ((p)->opacity == (q)->opacity))
 
71
 
 
72
/*
 
73
  Typedef declarations.
 
74
*/
 
75
typedef enum
 
76
{
 
77
  PathDefaultOperation,
 
78
  PathCloseOperation,                           /* Z|z (none) */
 
79
  PathCurveToOperation,                         /* C|c (x1 y1 x2 y2 x y)+ */
 
80
  PathCurveToQuadraticBezierOperation,          /* Q|q (x1 y1 x y)+ */
 
81
  PathCurveToQuadraticBezierSmoothOperation,    /* T|t (x y)+ */
 
82
  PathCurveToSmoothOperation,                   /* S|s (x2 y2 x y)+ */
 
83
  PathEllipticArcOperation,                     /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
 
84
  PathLineToHorizontalOperation,                /* H|h x+ */
 
85
  PathLineToOperation,                          /* L|l (x y)+ */
 
86
  PathLineToVerticalOperation,                  /* V|v y+ */
 
87
  PathMoveToOperation                           /* M|m (x y)+ */
 
88
} PathOperation;
 
89
 
 
90
typedef enum
 
91
{
 
92
  DefaultPathMode,
 
93
  AbsolutePathMode,
 
94
  RelativePathMode
 
95
} PathMode;
 
96
 
 
97
struct _DrawContext
 
98
{
 
99
  /* Support structures */
 
100
  Image
 
101
    *image;
 
102
 
 
103
  /* MVG output string and housekeeping */
 
104
  char
 
105
    *mvg;               /* MVG data */
 
106
 
 
107
  size_t
 
108
    mvg_alloc,          /* total allocated memory */
 
109
    mvg_length;         /* total MVG length */
 
110
 
 
111
  unsigned int
 
112
    mvg_width;          /* current line length */
 
113
 
 
114
  /* Pattern support */
 
115
  char
 
116
    *pattern_id;
 
117
 
 
118
  RectangleInfo
 
119
    pattern_bounds;
 
120
 
 
121
  size_t
 
122
    pattern_offset;
 
123
 
 
124
  /* Graphic context */
 
125
  unsigned int
 
126
    index;              /* array index */
 
127
 
 
128
  DrawInfo
 
129
    **graphic_context;
 
130
 
 
131
  int
 
132
    filter_off;         /* true if not filtering attributes */
 
133
 
 
134
  /* Pretty-printing depth */
 
135
  unsigned int
 
136
    indent_depth;       /* number of left-hand pad characters */
 
137
 
 
138
  /* Path operation support */
 
139
  PathOperation
 
140
    path_operation;
 
141
 
 
142
  PathMode
 
143
    path_mode;
 
144
 
 
145
  /* Structure unique signature */
 
146
  unsigned long
 
147
    signature;
 
148
};
 
149
 
 
150
/* Vector table for invoking subordinate renderers */
 
151
struct _DrawVTable
 
152
{
 
153
  void (*DrawAnnotation)
 
154
    (DrawContext context, const double x, const double y,
 
155
     const unsigned char *text);
 
156
  void (*DrawArc)
 
157
    (DrawContext context, const double sx, const double sy,
 
158
     const double ex, const double ey, const double sd, const double ed);
 
159
  void (*DrawBezier)
 
160
    (DrawContext context, const unsigned long num_coords, const PointInfo *coordinates);
 
161
  void (*DrawCircle)
 
162
    (DrawContext context, const double ox, const double oy,
 
163
     const double px, const double py);
 
164
  void (*DrawColor)
 
165
    (DrawContext context, const double x, const double y,
 
166
     const PaintMethod paintMethod);
 
167
  void (*DrawComment)
 
168
    (DrawContext context,const char* comment);
 
169
  void (*DrawDestroyContext)
 
170
    (DrawContext context);
 
171
  void (*DrawEllipse)
 
172
    (DrawContext context, const double ox, const double oy,
 
173
     const double rx, const double ry, const double start, const double end);
 
174
  void (*DrawComposite)
 
175
    (DrawContext context, const CompositeOperator composite_operator,
 
176
     const double x, const double y, const double width, const double height,
 
177
     const Image * image );
 
178
  void (*DrawLine)
 
179
    (DrawContext context, const double sx, const double sy,
 
180
     const double ex, const double ey);
 
181
  void (*DrawMatte)
 
182
    (DrawContext context, const double x, const double y,
 
183
     const PaintMethod paint_method);
 
184
  void (*DrawPathClose)
 
185
    (DrawContext context);
 
186
  void (*DrawPathCurveToAbsolute)
 
187
    (DrawContext context, const double x1, const double y1,
 
188
     const double x2, const double y2, const double x, const double y);
 
189
  void (*DrawPathCurveToRelative)
 
190
    (DrawContext context, const double x1, const double y1,
 
191
     const double x2, const double y2, const double x, const double y);
 
192
  void (*DrawPathCurveToQuadraticBezierAbsolute)
 
193
    (DrawContext context, const double x1, const double y1,
 
194
     const double x, const double y);
 
195
  void (*DrawPathCurveToQuadraticBezierRelative)
 
196
    (DrawContext context, const double x1, const double y1,
 
197
     const double x, const double y);
 
198
  void (*DrawPathCurveToQuadraticBezierSmoothAbsolute)
 
199
    (DrawContext context, const double x, const double y);
 
200
  void (*DrawPathCurveToQuadraticBezierSmoothRelative)
 
201
    (DrawContext context, const double x, const double y);
 
202
  void (*DrawPathCurveToSmoothAbsolute)
 
203
    (DrawContext context, const double x2, const double y2,
 
204
     const double x, const double y);
 
205
  void (*DrawPathCurveToSmoothRelative)
 
206
    (DrawContext context, const double x2, const double y2,
 
207
     const double x, const double y);
 
208
  void (*DrawPathEllipticArcAbsolute)
 
209
    (DrawContext context, const double rx, const double ry,
 
210
     const double x_axis_rotation, unsigned int large_arc_flag,
 
211
     unsigned int sweep_flag, const double x, const double y);
 
212
  void (*DrawPathEllipticArcRelative)
 
213
    (DrawContext context, const double rx, const double ry,
 
214
     const double x_axis_rotation, unsigned int large_arc_flag,
 
215
     unsigned int sweep_flag, const double x, const double y);
 
216
  void (*DrawPathFinish)
 
217
    (DrawContext context);
 
218
  void (*DrawPathLineToAbsolute)
 
219
    (DrawContext context, const double x, const double y);
 
220
  void (*DrawPathLineToRelative)
 
221
    (DrawContext context, const double x, const double y);
 
222
  void (*DrawPathLineToHorizontalAbsolute)
 
223
    (DrawContext context, const double x);
 
224
  void (*DrawPathLineToHorizontalRelative)
 
225
    (DrawContext context, const double x);
 
226
  void (*DrawPathLineToVerticalAbsolute)
 
227
    (DrawContext context, const double y);
 
228
  void (*DrawPathLineToVerticalRelative)
 
229
    (DrawContext context, const double y);
 
230
  void (*DrawPathMoveToAbsolute)
 
231
    (DrawContext context, const double x, const double y);
 
232
  void (*DrawPathMoveToRelative)
 
233
    (DrawContext context, const double x, const double y);
 
234
  void (*DrawPathStart)
 
235
    (DrawContext context);
 
236
  void (*DrawPoint)
 
237
    (DrawContext context, const double x, const double y);
 
238
  void (*DrawPolygon)
 
239
    (DrawContext context, const unsigned long num_coords, const PointInfo * coordinates);
 
240
  void (*DrawPolyline)
 
241
    (DrawContext context, const unsigned long num_coords, const PointInfo * coordinates);
 
242
  void (*DrawPopClipPath)
 
243
    (DrawContext context);
 
244
  void (*DrawPopDefs)
 
245
    (DrawContext context);
 
246
  void (*DrawPopGraphicContext)
 
247
    (DrawContext context);
 
248
  void (*DrawPopPattern)
 
249
    (DrawContext context);
 
250
  void (*DrawPushClipPath)
 
251
    (DrawContext context, const char *clip_path_id);
 
252
  void (*DrawPushDefs)
 
253
    (DrawContext context);
 
254
  void (*DrawPushGraphicContext)
 
255
    (DrawContext context);
 
256
  void (*DrawPushPattern)
 
257
    (DrawContext context, const char *pattern_id,
 
258
     const double x, const double y, const double width, const double height);
 
259
  void (*DrawRectangle)
 
260
    (DrawContext context, const double x1, const double y1,
 
261
     const double x2, const double y2);
 
262
  void (*DrawRoundRectangle)
 
263
    (DrawContext context, double x1, double y1,
 
264
     double x2, double y2, double rx, double ry);
 
265
  void (*DrawAffine)
 
266
    (DrawContext context, const AffineMatrix *affine);
 
267
  void (*DrawSetClipPath)
 
268
    (DrawContext context, const char *clip_path);
 
269
  void (*DrawSetClipRule)
 
270
    (DrawContext context, const FillRule fill_rule);
 
271
  void (*DrawSetClipUnits)
 
272
    (DrawContext context, const ClipPathUnits clip_units);
 
273
  void (*DrawSetFillColor)
 
274
    (DrawContext context, const PixelPacket * fill_color);
 
275
  void (*DrawSetFillOpacity)
 
276
    (DrawContext context, const double fill_opacity);
 
277
  void (*DrawSetFillRule)
 
278
    (DrawContext context, const FillRule fill_rule);
 
279
  void (*DrawSetFillPatternURL)
 
280
    (DrawContext context, const char* fill_url);
 
281
  void (*DrawSetFont)
 
282
    (DrawContext context, const char *font_name);
 
283
  void (*DrawSetFontFamily)
 
284
    (DrawContext context, const char *font_family);
 
285
  void (*DrawSetFontSize)
 
286
    (DrawContext context, const double font_pointsize);
 
287
  void (*DrawSetFontStretch)
 
288
    (DrawContext context, const StretchType font_stretch);
 
289
  void (*DrawSetFontStyle)
 
290
    (DrawContext context, const StyleType font_style);
 
291
  void (*DrawSetFontWeight)
 
292
    (DrawContext context, const unsigned long font_weight);
 
293
  void (*DrawSetGravity)
 
294
    (DrawContext context, const GravityType gravity);
 
295
  void (*DrawRotate)
 
296
    (DrawContext context, const double degrees);
 
297
  void (*DrawScale)
 
298
    (DrawContext context, const double x, const double y);
 
299
  void (*DrawSkewX)
 
300
    (DrawContext context, const double degrees);
 
301
  void (*DrawSkewY)
 
302
    (DrawContext context, const double degrees);
 
303
/*   void (*DrawSetStopColor) */
 
304
/*     (DrawContext context, const PixelPacket * color, const double offset); */
 
305
  void (*DrawSetStrokeAntialias)
 
306
    (DrawContext context, const unsigned int true_false);
 
307
  void (*DrawSetStrokeColor)
 
308
    (DrawContext context, const PixelPacket * stroke_color);
 
309
  void (*DrawSetStrokeDashArray)
 
310
    (DrawContext context,const double *dasharray);
 
311
  void (*DrawSetStrokeDashOffset)
 
312
    (DrawContext context,const double dashoffset);
 
313
  void (*DrawSetStrokeLineCap)
 
314
    (DrawContext context, const LineCap linecap);
 
315
  void (*DrawSetStrokeLineJoin)
 
316
    (DrawContext context, const LineJoin linejoin);
 
317
  void (*DrawSetStrokeMiterLimit)
 
318
    (DrawContext context,const unsigned long miterlimit);
 
319
  void (*DrawSetStrokeOpacity)
 
320
    (DrawContext context, const double opacity);
 
321
  void (*DrawSetStrokePatternURL)
 
322
    (DrawContext context, const char* stroke_url);
 
323
  void (*DrawSetStrokeWidth)
 
324
    (DrawContext context, const double width);
 
325
  void (*DrawSetTextAntialias)
 
326
    (DrawContext context, const unsigned int true_false);
 
327
  void (*DrawSetTextDecoration)
 
328
    (DrawContext context, const DecorationType decoration);
 
329
  void (*DrawSetTextUnderColor)
 
330
    (DrawContext context, const PixelPacket * color);
 
331
  void (*DrawTranslate)
 
332
    (DrawContext context, const double x, const double y);
 
333
  void (*DrawSetViewbox)
 
334
    (DrawContext context, unsigned long x1, unsigned long y1,
 
335
     unsigned long x2, unsigned long y2);
 
336
};
 
337
 
 
338
/*
 
339
  Forward declarations.
 
340
*/
 
341
static int
 
342
  MvgPrintf(DrawContext context, const char *format, ...)
 
343
#if defined(__GNUC__)
 
344
__attribute__ ((format (printf, 2, 3)))
 
345
#endif
 
346
,
 
347
  MvgAutoWrapPrintf(DrawContext context, const char *format, ...)
 
348
#if defined(__GNUC__)
 
349
__attribute__ ((format (printf, 2, 3)))
 
350
#endif
 
351
;
 
352
static void
 
353
  MvgAppendColor(DrawContext context, const PixelPacket *color);
 
354
 
 
355
 
 
356
/* "Printf" for MVG commands */
 
357
static int MvgPrintf(DrawContext context, const char *format, ...)
 
358
{
 
359
  const size_t
 
360
    alloc_size = MaxTextExtent * 20; /* 40K */
 
361
 
 
362
  assert(context != (DrawContext)NULL);
 
363
  assert(context->signature == MagickSignature);
 
364
 
 
365
  /* Allocate initial memory */
 
366
  if (context->mvg == (char*) NULL)
 
367
    {
 
368
      context->mvg = MagickAllocateMemory(char *,alloc_size);
 
369
      if( context->mvg == (char*) NULL )
 
370
        {
 
371
          ThrowException3(&context->image->exception,ResourceLimitError,
 
372
            MemoryAllocationFailed,UnableToDrawOnImage);
 
373
          return -1;
 
374
        }
 
375
 
 
376
      context->mvg_alloc = alloc_size;
 
377
      context->mvg_length = 0;
 
378
      if (context->mvg == 0)
 
379
        {
 
380
          ThrowException3(&context->image->exception,ResourceLimitError,
 
381
            MemoryAllocationFailed,UnableToDrawOnImage);
 
382
          return -1;
 
383
        }
 
384
    }
 
385
 
 
386
  /* Re-allocate additional memory if necessary (ensure 20K unused) */
 
387
  if (context->mvg_alloc < (context->mvg_length + MaxTextExtent * 10))
 
388
    {
 
389
      size_t realloc_size = context->mvg_alloc + alloc_size;
 
390
 
 
391
      MagickReallocMemory(context->mvg, realloc_size);
 
392
      if (context->mvg == NULL)
 
393
        {
 
394
          ThrowException3(&context->image->exception,ResourceLimitError,
 
395
            MemoryAllocationFailed,UnableToDrawOnImage);
 
396
          return -1;
 
397
        }
 
398
      context->mvg_alloc = realloc_size;
 
399
    }
 
400
 
 
401
  /* Write to end of existing MVG string */
 
402
  {
 
403
    int
 
404
      formatted_length; /* must be a signed type! */
 
405
 
 
406
    va_list
 
407
      argp;
 
408
 
 
409
    /* Pretty-print indentation */
 
410
    while(context->mvg_width < context->indent_depth)
 
411
      {
 
412
        context->mvg[context->mvg_length] = ' ';
 
413
        ++context->mvg_length;
 
414
        ++context->mvg_width;
 
415
      }
 
416
    context->mvg[context->mvg_length] = 0;
 
417
 
 
418
    va_start(argp, format);
 
419
#if defined(HAVE_VSNPRINTF)
 
420
    formatted_length =
 
421
      vsnprintf(context->mvg + context->mvg_length,
 
422
                context->mvg_alloc - context->mvg_length - 1, format, argp);
 
423
#else
 
424
#  if defined(HAVE_VSPRINTF)
 
425
    formatted_length = vsprintf(context->mvg + context->mvg_length, format, argp);
 
426
#  else
 
427
#    error Neither vsnprintf or vsprintf is available.
 
428
#  endif
 
429
#endif
 
430
    va_end(argp);
 
431
 
 
432
    if (formatted_length < 0)
 
433
      {
 
434
        ThrowException(&context->image->exception,DrawError,UnableToPrint,
 
435
          format);
 
436
      }
 
437
    else
 
438
      {
 
439
        context->mvg_length += formatted_length;
 
440
        context->mvg_width += formatted_length;
 
441
      }
 
442
    context->mvg[context->mvg_length] = 0;
 
443
 
 
444
    /* Re-evaluate mvg_width */
 
445
    if( (context->mvg_length > 1) &&
 
446
        (context->mvg[context->mvg_length-1] == '\n') )
 
447
      context->mvg_width = 0;
 
448
 
 
449
    assert(context->mvg_length + 1 < context->mvg_alloc);
 
450
 
 
451
    return formatted_length;
 
452
  }
 
453
}
 
454
 
 
455
/* "Printf" for MVG commands, with autowrap at 78 characters */
 
456
static int MvgAutoWrapPrintf(DrawContext context, const char *format, ...)
 
457
{
 
458
  va_list
 
459
    argp;
 
460
 
 
461
  int
 
462
    formatted_length;
 
463
 
 
464
  char
 
465
    buffer[MaxTextExtent];
 
466
 
 
467
  va_start(argp, format);
 
468
#if defined(HAVE_VSNPRINTF)
 
469
  formatted_length = vsnprintf(buffer, sizeof(buffer) - 1, format, argp);
 
470
#else
 
471
#  if defined(HAVE_VSPRINTF)
 
472
  formatted_length = vsprintf(buffer, format, argp);
 
473
#  else
 
474
#    error Neither vsnprintf or vsprintf is available.
 
475
#  endif
 
476
#endif
 
477
  va_end(argp);
 
478
  *(buffer+sizeof(buffer)-1)=0;
 
479
 
 
480
  if (formatted_length < 0)
 
481
    {
 
482
      ThrowException(&context->image->exception,DrawError,UnableToPrint,
 
483
        format);
 
484
    }
 
485
  else
 
486
    {
 
487
      if( ((context->mvg_width + formatted_length) > 78) &&
 
488
          buffer[formatted_length-1] != '\n' )
 
489
        MvgPrintf(context, "\n");
 
490
 
 
491
      MvgPrintf(context, "%s", buffer);
 
492
    }
 
493
 
 
494
  return formatted_length;
 
495
}
 
496
 
 
497
static void MvgAppendColor(DrawContext context, const PixelPacket *color)
 
498
{
 
499
  if(color->red == 0 && color->green == 0 && color->blue == 0 &&
 
500
     color->opacity == TransparentOpacity)
 
501
    {
 
502
      MvgPrintf(context,"none");
 
503
    }
 
504
  else
 
505
    {
 
506
      char
 
507
        tuple[MaxTextExtent];
 
508
 
 
509
      GetColorTuple(color,context->image->depth,context->image->matte,True,
 
510
                    tuple);
 
511
      MvgPrintf(context,"%.1024s",tuple);
 
512
    }
 
513
}
 
514
 
 
515
static void MvgAppendPointsCommand(DrawContext context, const char* command,
 
516
                                   const unsigned long num_coords,
 
517
                                   const PointInfo * coordinates)
 
518
{
 
519
  const PointInfo
 
520
    *coordinate;
 
521
 
 
522
  size_t
 
523
    i;
 
524
 
 
525
  MvgPrintf(context, command);
 
526
  for (i = num_coords, coordinate = coordinates; i; i--)
 
527
    {
 
528
      MvgAutoWrapPrintf(context," %.4g,%.4g", coordinate->x, coordinate->y);
 
529
      ++coordinate;
 
530
    }
 
531
 
 
532
  MvgPrintf(context, "\n");
 
533
}
 
534
 
 
535
static void AdjustAffine(DrawContext context, const AffineMatrix *affine)
 
536
{
 
537
  assert(context != (DrawContext)NULL);
 
538
  assert(context->signature == MagickSignature);
 
539
 
 
540
  if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
 
541
      (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
 
542
    {
 
543
      AffineMatrix
 
544
        current;
 
545
 
 
546
      current = CurrentContext->affine;
 
547
      CurrentContext->affine.sx=current.sx*affine->sx+current.ry*affine->rx;
 
548
      CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
 
549
      CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
 
550
      CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
 
551
      CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+current.tx;
 
552
      CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+current.ty;
 
553
    }
 
554
}
 
555
 
 
556
/*
 
557
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
558
%                                                                             %
 
559
%                                                                             %
 
560
%                                                                             %
 
561
%   D r a w A n n o t a t i o n                                               %
 
562
%                                                                             %
 
563
%                                                                             %
 
564
%                                                                             %
 
565
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
566
%
 
567
%  DrawAnnotation() draws text on the image.
 
568
%
 
569
%  The format of the DrawAnnotation method is:
 
570
%
 
571
%      void DrawAnnotation(DrawContext context,
 
572
%                          const double x, const double y,
 
573
%                          const unsigned char *text)
 
574
%
 
575
%  A description of each parameter follows:
 
576
%
 
577
%    o context: drawing context
 
578
%
 
579
%    o x: x ordinate to left of text
 
580
%
 
581
%    o y: y ordinate to text baseline
 
582
%
 
583
%    o text: text to draw
 
584
%
 
585
*/
 
586
MagickExport void DrawAnnotation(DrawContext context,
 
587
                                 const double x, const double y,
 
588
                                 const unsigned char *text)
 
589
{
 
590
  char
 
591
    *escaped_text;
 
592
 
 
593
  assert(context != (DrawContext)NULL);
 
594
  assert(context->signature == MagickSignature);
 
595
  assert(text != (const unsigned char *) NULL);
 
596
 
 
597
  escaped_text=EscapeString((const char*)text,'\'');
 
598
  MvgPrintf(context, "text %.4g,%.4g '%.1024s'\n", x, y, escaped_text);
 
599
  MagickFreeMemory(escaped_text);
 
600
}
 
601
 
 
602
/*
 
603
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
604
%                                                                             %
 
605
%                                                                             %
 
606
%                                                                             %
 
607
%   D r a w A f f i n e                                                       %
 
608
%                                                                             %
 
609
%                                                                             %
 
610
%                                                                             %
 
611
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
612
%
 
613
%  DrawAffine() adjusts the current affine transformation matrix with
 
614
%  the specified affine transformation matrix. Note that the current affine
 
615
%  transform is adjusted rather than replaced.
 
616
%
 
617
%  The format of the DrawAffine method is:
 
618
%
 
619
%      void DrawAffine(DrawContext context, const AffineMatrix *affine)
 
620
%
 
621
%  A description of each parameter follows:
 
622
%
 
623
%    o context: Drawing context
 
624
%
 
625
%    o affine: Affine matrix parameters
 
626
%
 
627
*/
 
628
MagickExport void DrawAffine(DrawContext context, const AffineMatrix *affine)
 
629
{
 
630
  assert(context != (DrawContext)NULL);
 
631
  assert(context->signature == MagickSignature);
 
632
  assert(affine != (const AffineMatrix *)NULL);
 
633
 
 
634
  AdjustAffine( context, affine );
 
635
 
 
636
  MvgPrintf(context, "affine %.6g,%.6g,%.6g,%.6g,%.6g,%.6g\n",
 
637
            affine->sx, affine->rx, affine->ry, affine->sy,
 
638
            affine->tx, affine->ty);
 
639
}
 
640
 
 
641
/*
 
642
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
643
%                                                                             %
 
644
%                                                                             %
 
645
%                                                                             %
 
646
%   D r a w A l l o c a t e C o n t e x t                                     %
 
647
%                                                                             %
 
648
%                                                                             %
 
649
%                                                                             %
 
650
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
651
%
 
652
%  DrawAllocateContext() allocates an initial drawing context which is an
 
653
%  opaque handle required by the remaining drawing methods.
 
654
%
 
655
%  The format of the DrawAllocateContext method is:
 
656
%
 
657
%      DrawContext DrawAllocateContext(const DrawInfo *draw_info,
 
658
%                                      Image *image)
 
659
%
 
660
%  A description of each parameter follows:
 
661
%
 
662
%    o draw_info: Initial drawing defaults. Set to NULL to use
 
663
%                 GraphicsMagick defaults.
 
664
%
 
665
%    o image: The image to draw on.
 
666
%
 
667
*/
 
668
MagickExport DrawContext DrawAllocateContext(const DrawInfo *draw_info,
 
669
                                             Image *image)
 
670
{
 
671
  DrawContext
 
672
    context;
 
673
 
 
674
  /* Allocate initial drawing context */
 
675
  context = MagickAllocateMemory(DrawContext,sizeof(struct _DrawContext));
 
676
  if(context == (DrawContext) NULL)
 
677
    MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
 
678
      UnableToAllocateDrawContext);
 
679
 
 
680
  /* Support structures */
 
681
  context->image = image;
 
682
 
 
683
  /* MVG output string and housekeeping */
 
684
  context->mvg = NULL;
 
685
  context->mvg_alloc = 0;
 
686
  context->mvg_length = 0;
 
687
  context->mvg_width = 0;
 
688
 
 
689
  /* Pattern support */
 
690
  context->pattern_id = NULL;
 
691
  context->pattern_offset = 0;
 
692
 
 
693
  context->pattern_bounds.x = 0;
 
694
  context->pattern_bounds.y = 0;
 
695
  context->pattern_bounds.width = 0;
 
696
  context->pattern_bounds.height = 0;
 
697
 
 
698
  /* Graphic context */
 
699
  context->index = 0;
 
700
  context->graphic_context=MagickAllocateMemory(DrawInfo **,sizeof(DrawInfo *));
 
701
  if(context->graphic_context == (DrawInfo **) NULL)
 
702
    {
 
703
      ThrowException3(&context->image->exception,ResourceLimitError,
 
704
        MemoryAllocationFailed,UnableToDrawOnImage);
 
705
      return (DrawContext) NULL;
 
706
    }
 
707
  CurrentContext=CloneDrawInfo((ImageInfo*)NULL,draw_info);
 
708
  if(CurrentContext == (DrawInfo*) NULL)
 
709
    {
 
710
      ThrowException3(&context->image->exception,ResourceLimitError,
 
711
        MemoryAllocationFailed,UnableToDrawOnImage);
 
712
      return (DrawContext) NULL;
 
713
    }
 
714
 
 
715
  context->filter_off = False;
 
716
 
 
717
  /* Pretty-printing depth */
 
718
  context->indent_depth = 0;
 
719
 
 
720
  /* Path operation support */
 
721
  context->path_operation = PathDefaultOperation;
 
722
  context->path_mode = DefaultPathMode;
 
723
 
 
724
  /* Structure unique signature */
 
725
  context->signature = MagickSignature;
 
726
 
 
727
  return context;
 
728
}
 
729
 
 
730
/*
 
731
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
732
%                                                                             %
 
733
%                                                                             %
 
734
%                                                                             %
 
735
%   D r a w A r c                                                             %
 
736
%                                                                             %
 
737
%                                                                             %
 
738
%                                                                             %
 
739
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
740
%
 
741
%  DrawArc() draws an arc falling within a specified bounding rectangle on the
 
742
%  image.
 
743
%
 
744
%  The format of the DrawArc method is:
 
745
%
 
746
%      void DrawArc(DrawContext context,
 
747
%                   const double sx, const double sy,
 
748
%                   const double ex, const double ey,
 
749
%                   const double sd, const double ed)
 
750
%
 
751
%  A description of each parameter follows:
 
752
%
 
753
%    o context: drawing context
 
754
%
 
755
%    o sx: starting x ordinate of bounding rectangle
 
756
%
 
757
%    o sy: starting y ordinate of bounding rectangle
 
758
%
 
759
%    o ex: ending x ordinate of bounding rectangle
 
760
%
 
761
%    o ey: ending y ordinate of bounding rectangle
 
762
%
 
763
%    o sd: starting degrees of rotation
 
764
%
 
765
%    o ed: ending degrees of rotation
 
766
%
 
767
*/
 
768
MagickExport void DrawArc(DrawContext context,
 
769
                          const double sx, const double sy,
 
770
                          const double ex, const double ey,
 
771
                          const double sd, const double ed)
 
772
{
 
773
  assert(context != (DrawContext)NULL);
 
774
  assert(context->signature == MagickSignature);
 
775
 
 
776
  MvgPrintf(context, "arc %.4g,%.4g %.4g,%.4g %.4g,%.4g\n",
 
777
            sx, sy, ex, ey, sd, ed);
 
778
}
 
779
 
 
780
/*
 
781
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
782
%                                                                             %
 
783
%                                                                             %
 
784
%                                                                             %
 
785
%   D r a w B e z i e r                                                       %
 
786
%                                                                             %
 
787
%                                                                             %
 
788
%                                                                             %
 
789
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
790
%
 
791
%  DrawBezier() draws a bezier curve through a set of points on the image.
 
792
%
 
793
%  The format of the DrawBezier method is:
 
794
%
 
795
%      void DrawBezier(DrawContext context, const unsigned long num_coords,
 
796
%                      const PointInfo *coordinates)
 
797
%
 
798
%  A description of each parameter follows:
 
799
%
 
800
%    o context: drawing context
 
801
%
 
802
%    o num_coords: number of coordinates
 
803
%
 
804
%    o coordinates: coordinates
 
805
%
 
806
*/
 
807
MagickExport void DrawBezier(DrawContext context, const unsigned long num_coords,
 
808
                             const PointInfo *coordinates)
 
809
{
 
810
  assert(context != (DrawContext)NULL);
 
811
  assert(context->signature == MagickSignature);
 
812
  assert(coordinates != (const PointInfo *) NULL);
 
813
 
 
814
  MvgAppendPointsCommand(context,"bezier",num_coords,coordinates);
 
815
}
 
816
 
 
817
/*
 
818
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
819
%                                                                             %
 
820
%                                                                             %
 
821
%                                                                             %
 
822
%   D r a w C i r c l e                                                       %
 
823
%                                                                             %
 
824
%                                                                             %
 
825
%                                                                             %
 
826
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
827
%
 
828
%  DrawCircle() draws a circle on the image.
 
829
%
 
830
%  The format of the DrawCircle method is:
 
831
%
 
832
%      void DrawCircle(DrawContext context, const double ox,
 
833
%                      const double oy, const double px, const double py)
 
834
%
 
835
%  A description of each parameter follows:
 
836
%
 
837
%    o context: drawing context
 
838
%
 
839
%    o ox: origin x ordinate
 
840
%
 
841
%    o oy: origin y ordinate
 
842
%
 
843
%    o px: perimeter x ordinate
 
844
%
 
845
%    o py: perimeter y ordinate
 
846
%
 
847
*/
 
848
MagickExport void DrawCircle(DrawContext context, const double ox,
 
849
                             const double oy, const double px, const double py)
 
850
{
 
851
  assert(context != (DrawContext)NULL);
 
852
  assert(context->signature == MagickSignature);
 
853
 
 
854
  MvgPrintf(context, "circle %.4g,%.4g %.4g,%.4g\n", ox, oy, px, py);
 
855
}
 
856
 
 
857
/*
 
858
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
859
%                                                                             %
 
860
%                                                                             %
 
861
%                                                                             %
 
862
%   D r a w G e t C l i p P a t h                                             %
 
863
%                                                                             %
 
864
%                                                                             %
 
865
%                                                                             %
 
866
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
867
%
 
868
%  DrawGetClipPath() obtains the current clipping path ID. The value returned
 
869
%  must be deallocated by the user when it is no longer needed.
 
870
%
 
871
%  The format of the DrawGetClipPath method is:
 
872
%
 
873
%      char *DrawGetClipPath(DrawContext context)
 
874
%
 
875
%  A description of each parameter follows:
 
876
%
 
877
%    o context: drawing context
 
878
%
 
879
*/
 
880
MagickExport char *DrawGetClipPath(DrawContext context)
 
881
{
 
882
  assert(context != (DrawContext)NULL);
 
883
  assert(context->signature == MagickSignature);
 
884
 
 
885
  if (CurrentContext->clip_path != (char *) NULL)
 
886
    return (char *)AllocateString(CurrentContext->clip_path);
 
887
  else
 
888
    return (char *) NULL;
 
889
}
 
890
 
 
891
/*
 
892
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
893
%                                                                             %
 
894
%                                                                             %
 
895
%                                                                             %
 
896
%   D r a w S e t C l i p P a t h                                             %
 
897
%                                                                             %
 
898
%                                                                             %
 
899
%                                                                             %
 
900
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
901
%
 
902
%  DrawSetClipPath() associates a named clipping path with the image.  Only
 
903
%  the areas drawn on by the clipping path will be modified as long as it
 
904
%  remains in effect.
 
905
%
 
906
%  The format of the DrawSetClipPath method is:
 
907
%
 
908
%      void DrawSetClipPath(DrawContext context, const char *clip_path)
 
909
%
 
910
%  A description of each parameter follows:
 
911
%
 
912
%    o context: drawing context
 
913
%
 
914
%    o clip_path: name of clipping path to associate with image
 
915
%
 
916
*/
 
917
MagickExport void DrawSetClipPath(DrawContext context, const char *clip_path)
 
918
{
 
919
  assert(context != (DrawContext)NULL);
 
920
  assert(context->signature == MagickSignature);
 
921
  assert(clip_path != (const char *) NULL);
 
922
 
 
923
  if( CurrentContext->clip_path == NULL || context->filter_off ||
 
924
      LocaleCompare(CurrentContext->clip_path,clip_path) != 0)
 
925
    {
 
926
      CloneString(&CurrentContext->clip_path,clip_path);
 
927
      if(CurrentContext->clip_path == (char*)NULL)
 
928
        ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
 
929
          UnableToDrawOnImage);
 
930
 
 
931
#if DRAW_BINARY_IMPLEMENTATION
 
932
      (void) DrawClipPath(context->image,CurrentContext,CurrentContext->clip_path);
 
933
#endif
 
934
 
 
935
      MvgPrintf(context, "clip-path url(#%s)\n", clip_path);
 
936
    }
 
937
}
 
938
 
 
939
/*
 
940
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
941
%                                                                             %
 
942
%                                                                             %
 
943
%                                                                             %
 
944
%   D r a w G e t C l i p R u l e                                             %
 
945
%                                                                             %
 
946
%                                                                             %
 
947
%                                                                             %
 
948
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
949
%
 
950
%  DrawGetClipRule() returns the current polygon fill rule to be used by the
 
951
%  clipping path.
 
952
%
 
953
%  The format of the DrawGetClipRule method is:
 
954
%
 
955
%     FillRule DrawGetClipRule(DrawContext context)
 
956
%
 
957
%  A description of each parameter follows:
 
958
%
 
959
%    o context: drawing context
 
960
%
 
961
*/
 
962
MagickExport FillRule DrawGetClipRule(DrawContext context)
 
963
{
 
964
  assert(context != (DrawContext)NULL);
 
965
  assert(context->signature == MagickSignature);
 
966
 
 
967
  return CurrentContext->fill_rule;
 
968
}
 
969
 
 
970
/*
 
971
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
972
%                                                                             %
 
973
%                                                                             %
 
974
%                                                                             %
 
975
%   D r a w S e t C l i p R u l e                                             %
 
976
%                                                                             %
 
977
%                                                                             %
 
978
%                                                                             %
 
979
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
980
%
 
981
%  DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
 
982
%
 
983
%  The format of the DrawSetClipRule method is:
 
984
%
 
985
%      void DrawSetClipRule(DrawContext context,
 
986
%                           const FillRule fill_rule)
 
987
%
 
988
%  A description of each parameter follows:
 
989
%
 
990
%    o context: drawing context
 
991
%
 
992
%    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
 
993
%
 
994
*/
 
995
MagickExport void DrawSetClipRule(DrawContext context,
 
996
                                  const FillRule fill_rule)
 
997
{
 
998
  const char
 
999
    *p = NULL;
 
1000
 
 
1001
  assert(context != (DrawContext)NULL);
 
1002
  assert(context->signature == MagickSignature);
 
1003
 
 
1004
  if(context->filter_off || (CurrentContext->fill_rule != fill_rule))
 
1005
    {
 
1006
      CurrentContext->fill_rule = fill_rule;
 
1007
 
 
1008
      switch (fill_rule)
 
1009
        {
 
1010
        case EvenOddRule:
 
1011
          p = "evenodd";
 
1012
          break;
 
1013
        case NonZeroRule:
 
1014
          p = "nonzero";
 
1015
          break;
 
1016
        default:
 
1017
          break;
 
1018
        }
 
1019
 
 
1020
      if (p != NULL)
 
1021
        MvgPrintf(context, "clip-rule %s\n", p);
 
1022
    }
 
1023
}
 
1024
 
 
1025
/*
 
1026
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1027
%                                                                             %
 
1028
%                                                                             %
 
1029
%                                                                             %
 
1030
%   D r a w G e t C l i p U n i t s                                           %
 
1031
%                                                                             %
 
1032
%                                                                             %
 
1033
%                                                                             %
 
1034
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1035
%
 
1036
%  DrawGetClipUnits() returns the interpretation of clip path units.
 
1037
%
 
1038
%  The format of the DrawGetClipUnits method is:
 
1039
%
 
1040
%      ClipPathUnits DrawGetClipUnits(DrawContext context)
 
1041
%
 
1042
%  A description of each parameter follows:
 
1043
%
 
1044
%    o context: drawing context
 
1045
%
 
1046
*/
 
1047
MagickExport ClipPathUnits DrawGetClipUnits(DrawContext context)
 
1048
{
 
1049
  assert(context != (DrawContext)NULL);
 
1050
  assert(context->signature == MagickSignature);
 
1051
 
 
1052
  return CurrentContext->clip_units;
 
1053
}
 
1054
 
 
1055
/*
 
1056
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1057
%                                                                             %
 
1058
%                                                                             %
 
1059
%                                                                             %
 
1060
%   D r a w S e t C l i p U n i t s                                           %
 
1061
%                                                                             %
 
1062
%                                                                             %
 
1063
%                                                                             %
 
1064
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1065
%
 
1066
%  DrawSetClipUnits() sets the interpretation of clip path units.
 
1067
%
 
1068
%  The format of the DrawSetClipUnits method is:
 
1069
%
 
1070
%      void DrawSetClipUnits(DrawContext context,
 
1071
%                            const ClipPathUnits clip_units)
 
1072
%
 
1073
%  A description of each parameter follows:
 
1074
%
 
1075
%    o context: drawing context
 
1076
%
 
1077
%    o clip_units: units to use (UserSpace, UserSpaceOnUse, or ObjectBoundingBox)
 
1078
%
 
1079
*/
 
1080
MagickExport void DrawSetClipUnits(DrawContext context,
 
1081
                                   const ClipPathUnits clip_units)
 
1082
{
 
1083
  const char
 
1084
    *p = NULL;
 
1085
 
 
1086
  assert(context != (DrawContext)NULL);
 
1087
  assert(context->signature == MagickSignature);
 
1088
 
 
1089
  if(context->filter_off || (CurrentContext->clip_units != clip_units))
 
1090
    {
 
1091
      CurrentContext->clip_units = clip_units;
 
1092
 
 
1093
      if ( clip_units == ObjectBoundingBox )
 
1094
        {
 
1095
          AffineMatrix
 
1096
            affine;
 
1097
 
 
1098
          IdentityAffine(&affine);
 
1099
 
 
1100
          affine.sx=CurrentContext->bounds.x2;
 
1101
          affine.sy=CurrentContext->bounds.y2;
 
1102
          affine.tx=CurrentContext->bounds.x1;
 
1103
          affine.ty=CurrentContext->bounds.y1;
 
1104
 
 
1105
          AdjustAffine( context, &affine );
 
1106
        }
 
1107
 
 
1108
      switch (clip_units)
 
1109
        {
 
1110
        case UserSpace:
 
1111
          p = "userSpace";
 
1112
          break;
 
1113
        case UserSpaceOnUse:
 
1114
          p = "userSpaceOnUse";
 
1115
          break;
 
1116
        case ObjectBoundingBox:
 
1117
          p = "objectBoundingBox";
 
1118
          break;
 
1119
        }
 
1120
 
 
1121
      if (p != NULL)
 
1122
        MvgPrintf(context, "clip-units %s\n", p);
 
1123
    }
 
1124
}
 
1125
 
 
1126
/*
 
1127
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1128
%                                                                             %
 
1129
%                                                                             %
 
1130
%                                                                             %
 
1131
%   D r a w C o l o r                                                         %
 
1132
%                                                                             %
 
1133
%                                                                             %
 
1134
%                                                                             %
 
1135
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1136
%
 
1137
%  DrawColor() draws color on image using the current fill color, starting at
 
1138
%  specified position, and using specified paint method. The available paint
 
1139
%  methods are:
 
1140
%
 
1141
%    PointMethod: Recolors the target pixel
 
1142
%    ReplaceMethod: Recolor any pixel that matches the target pixel.
 
1143
%    FloodfillMethod: Recolors target pixels and matching neighbors.
 
1144
%    FillToBorderMethod: Recolor target pixels and neighbors not matching border color.
 
1145
%    ResetMethod: Recolor all pixels.
 
1146
%
 
1147
%  The format of the DrawColor method is:
 
1148
%
 
1149
%      void DrawColor(DrawContext context,
 
1150
%                     const double x, const double y,
 
1151
%                     const PaintMethod paintMethod)
 
1152
%
 
1153
%  A description of each parameter follows:
 
1154
%
 
1155
%    o context: drawing context
 
1156
%
 
1157
%    o x: x ordinate
 
1158
%
 
1159
%    o y: y ordinate
 
1160
%
 
1161
%    o paintMethod: paint method
 
1162
%
 
1163
*/
 
1164
MagickExport void DrawColor(DrawContext context,
 
1165
                            const double x, const double y,
 
1166
                            const PaintMethod paintMethod)
 
1167
{
 
1168
  const char
 
1169
    *p = NULL;
 
1170
 
 
1171
  assert(context != (DrawContext)NULL);
 
1172
  assert(context->signature == MagickSignature);
 
1173
 
 
1174
  switch (paintMethod)
 
1175
    {
 
1176
    case PointMethod:
 
1177
      p = "point";
 
1178
      break;
 
1179
    case ReplaceMethod:
 
1180
      p = "replace";
 
1181
      break;
 
1182
    case FloodfillMethod:
 
1183
      p = "floodfill";
 
1184
      break;
 
1185
    case FillToBorderMethod:
 
1186
      p = "filltoborder";
 
1187
      break;
 
1188
    case ResetMethod:
 
1189
      p = "reset";
 
1190
      break;
 
1191
    }
 
1192
 
 
1193
  if (p != NULL)
 
1194
    MvgPrintf(context, "color %.4g,%.4g %s\n", x, y, p);
 
1195
}
 
1196
 
 
1197
/*
 
1198
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1199
%                                                                             %
 
1200
%                                                                             %
 
1201
%                                                                             %
 
1202
%   D r a w C o m m e n t                                                     %
 
1203
%                                                                             %
 
1204
%                                                                             %
 
1205
%                                                                             %
 
1206
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1207
%
 
1208
%  DrawComment() adds a comment to a vector output stream.
 
1209
%
 
1210
%  The format of the DrawComment method is:
 
1211
%
 
1212
%      void DrawComment(DrawContext context,const char* comment)
 
1213
%
 
1214
%  A description of each parameter follows:
 
1215
%
 
1216
%    o context: drawing context
 
1217
%
 
1218
%    o comment: comment text
 
1219
%
 
1220
*/
 
1221
MagickExport void DrawComment(DrawContext context,const char* comment)
 
1222
{
 
1223
  /* FIXME: should handle multi-line comments by inserting # before
 
1224
     new lines */
 
1225
  MvgPrintf(context, "#%s\n", comment);
 
1226
}
 
1227
 
 
1228
/*
 
1229
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1230
%                                                                             %
 
1231
%                                                                             %
 
1232
%                                                                             %
 
1233
%   D r a w D e s t r o y C o n t e x t                                       %
 
1234
%                                                                             %
 
1235
%                                                                             %
 
1236
%                                                                             %
 
1237
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1238
%
 
1239
%  DrawDestroyContext() frees all resources associated with the drawing
 
1240
%  context. Once the drawing context has been freed, it should not be used
 
1241
%  any further unless it re-allocated.
 
1242
%
 
1243
%  The format of the DrawDestroyContext method is:
 
1244
%
 
1245
%      void DrawDestroyContext(DrawContext context)
 
1246
%
 
1247
%  A description of each parameter follows:
 
1248
%
 
1249
%    o context: drawing context to destroy
 
1250
%
 
1251
*/
 
1252
MagickExport void DrawDestroyContext(DrawContext context)
 
1253
{
 
1254
  assert(context != (DrawContext)NULL);
 
1255
  assert(context->signature == MagickSignature);
 
1256
 
 
1257
  /* Path operation support */
 
1258
  context->path_operation = PathDefaultOperation;
 
1259
  context->path_mode = DefaultPathMode;
 
1260
 
 
1261
  /* Pretty-printing depth */
 
1262
  context->indent_depth = 0;
 
1263
 
 
1264
  /* Graphic context */
 
1265
  for ( ; context->index > 0; context->index--)
 
1266
    {
 
1267
      DestroyDrawInfo(CurrentContext);
 
1268
      CurrentContext = (DrawInfo*) NULL;
 
1269
    }
 
1270
  DestroyDrawInfo(CurrentContext);
 
1271
  CurrentContext = (DrawInfo*) NULL;
 
1272
  MagickFreeMemory(context->graphic_context);
 
1273
 
 
1274
  /* Pattern support */
 
1275
  MagickFreeMemory(context->pattern_id);
 
1276
  context->pattern_offset = 0;
 
1277
 
 
1278
  context->pattern_bounds.x = 0;
 
1279
  context->pattern_bounds.y = 0;
 
1280
  context->pattern_bounds.width = 0;
 
1281
  context->pattern_bounds.height = 0;
 
1282
 
 
1283
  /* MVG output string and housekeeping */
 
1284
  MagickFreeMemory(context->mvg);
 
1285
  context->mvg_alloc = 0;
 
1286
  context->mvg_length = 0;
 
1287
 
 
1288
  /* Support structures */
 
1289
  context->image = (Image*)NULL;
 
1290
 
 
1291
  /* Context itself */
 
1292
  context->signature = 0;
 
1293
  MagickFreeMemory(context);
 
1294
}
 
1295
 
 
1296
/*
 
1297
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1298
%                                                                             %
 
1299
%                                                                             %
 
1300
%                                                                             %
 
1301
%   D r a w E l l i p s e                                                     %
 
1302
%                                                                             %
 
1303
%                                                                             %
 
1304
%                                                                             %
 
1305
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1306
%
 
1307
%  DrawEllipse() draws an ellipse on the image.
 
1308
%
 
1309
%  The format of the DrawEllipse method is:
 
1310
%
 
1311
%       void DrawEllipse(DrawContext context,
 
1312
%                        const double ox, const double oy,
 
1313
%                        const double rx, const double ry,
 
1314
%                        const double start, const double end)
 
1315
%
 
1316
%  A description of each parameter follows:
 
1317
%
 
1318
%    o context: drawing context
 
1319
%
 
1320
%    o ox: origin x ordinate
 
1321
%
 
1322
%    o oy: origin y ordinate
 
1323
%
 
1324
%    o rx: radius in x
 
1325
%
 
1326
%    o ry: radius in y
 
1327
%
 
1328
%    o start: starting rotation in degrees
 
1329
%
 
1330
%    o end: ending rotation in degrees
 
1331
%
 
1332
*/
 
1333
MagickExport void DrawEllipse(DrawContext context,
 
1334
                              const double ox, const double oy,
 
1335
                              const double rx, const double ry,
 
1336
                              const double start, const double end)
 
1337
{
 
1338
  assert(context != (DrawContext)NULL);
 
1339
  assert(context->signature == MagickSignature);
 
1340
 
 
1341
  MvgPrintf(context, "ellipse %.4g,%.4g %.4g,%.4g %.4g,%.4g\n",
 
1342
            ox, oy, rx, ry, start, end);
 
1343
}
 
1344
 
 
1345
/*
 
1346
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1347
%                                                                             %
 
1348
%                                                                             %
 
1349
%                                                                             %
 
1350
%   D r a w G e t F i l l C o l o r                                           %
 
1351
%                                                                             %
 
1352
%                                                                             %
 
1353
%                                                                             %
 
1354
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1355
%
 
1356
%  DrawGetFillColor() returns the fill color used for drawing filled objects.
 
1357
%
 
1358
%  The format of the DrawGetFillColor method is:
 
1359
%
 
1360
%      PixelPacket DrawGetFillColor(DrawContext context)
 
1361
%
 
1362
%  A description of each parameter follows:
 
1363
%
 
1364
%    o context: drawing context
 
1365
*/
 
1366
MagickExport PixelPacket DrawGetFillColor(DrawContext context)
 
1367
{
 
1368
  assert(context != (DrawContext)NULL);
 
1369
  assert(context->signature == MagickSignature);
 
1370
 
 
1371
  return CurrentContext->fill;
 
1372
}
 
1373
 
 
1374
/*
 
1375
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1376
%                                                                             %
 
1377
%                                                                             %
 
1378
%                                                                             %
 
1379
%   D r a w S e t F i l l C o l o r                                           %
 
1380
%                                                                             %
 
1381
%                                                                             %
 
1382
%                                                                             %
 
1383
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1384
%
 
1385
%  DrawSetFillColor() sets the fill color to be used for drawing filled objects.
 
1386
%
 
1387
%  The format of the DrawSetFillColor method is:
 
1388
%
 
1389
%      void DrawSetFillColor(DrawContext context,
 
1390
%                            const PixelPacket * fill_color)
 
1391
%
 
1392
%  A description of each parameter follows:
 
1393
%
 
1394
%    o context: drawing context
 
1395
%
 
1396
%    o fill_color: fill color
 
1397
%
 
1398
*/
 
1399
MagickExport void DrawSetFillColor(DrawContext context,
 
1400
                                   const PixelPacket *fill_color)
 
1401
{
 
1402
  PixelPacket
 
1403
    *current_fill,
 
1404
    new_fill;
 
1405
 
 
1406
  assert(context != (DrawContext)NULL);
 
1407
  assert(context->signature == MagickSignature);
 
1408
  assert(fill_color != (const PixelPacket *) NULL);
 
1409
 
 
1410
  new_fill = *fill_color;
 
1411
 
 
1412
  /* Inherit base opacity */
 
1413
  if(new_fill.opacity == OpaqueOpacity)
 
1414
    new_fill.opacity = CurrentContext->opacity;
 
1415
 
 
1416
  current_fill = &CurrentContext->fill;
 
1417
  if( context->filter_off || !(PixelPacketMatch(current_fill,&new_fill)) )
 
1418
    {
 
1419
      CurrentContext->fill = new_fill;
 
1420
 
 
1421
      MvgPrintf(context, "fill '");
 
1422
      MvgAppendColor(context, fill_color);
 
1423
      MvgPrintf(context, "'\n");
 
1424
    }
 
1425
}
 
1426
 
 
1427
/*
 
1428
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1429
%                                                                             %
 
1430
%                                                                             %
 
1431
%                                                                             %
 
1432
%   D r a w S e t F i l l C o l o r S t r i n g                               %
 
1433
%                                                                             %
 
1434
%                                                                             %
 
1435
%                                                                             %
 
1436
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1437
%
 
1438
%  DrawSetFillColorString() sets the fill color to be used for drawing filled
 
1439
%  objects.
 
1440
%
 
1441
%  The format of the DrawSetFillColorString method is:
 
1442
%
 
1443
%      void DrawSetFillColorString(DrawContext context, const char* fill_color)
 
1444
%
 
1445
%  A description of each parameter follows:
 
1446
%
 
1447
%    o context: drawing context
 
1448
%
 
1449
%    o fill_color: fill color
 
1450
%
 
1451
*/
 
1452
MagickExport void DrawSetFillColorString(DrawContext context,
 
1453
                                         const char* fill_color)
 
1454
{
 
1455
  PixelPacket
 
1456
    pixel_packet;
 
1457
 
 
1458
  if(QueryColorDatabase(fill_color,&pixel_packet,&context->image->exception))
 
1459
    DrawSetFillColor(context,&pixel_packet);
 
1460
}
 
1461
 
 
1462
/*
 
1463
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1464
%                                                                             %
 
1465
%                                                                             %
 
1466
%                                                                             %
 
1467
%   D r a w S e t F i l l P a t t e r n U R L                                 %
 
1468
%                                                                             %
 
1469
%                                                                             %
 
1470
%                                                                             %
 
1471
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1472
%
 
1473
%  DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
 
1474
%  objects. Only local URLs ("#identifier") are supported at this time. These
 
1475
%  local URLs are normally created by defining a named fill pattern with
 
1476
%  DrawPushPattern/DrawPopPattern.
 
1477
%
 
1478
%  The format of the DrawSetFillPatternURL method is:
 
1479
%
 
1480
%      void DrawSetFillPatternURL(DrawContext context, const char* fill_url)
 
1481
%
 
1482
%  A description of each parameter follows:
 
1483
%
 
1484
%    o context: drawing context
 
1485
%
 
1486
%    o fill_url: URL to use to obtain fill pattern.
 
1487
%
 
1488
*/
 
1489
MagickExport void DrawSetFillPatternURL(DrawContext context, const char* fill_url)
 
1490
{
 
1491
  char
 
1492
    pattern[MaxTextExtent];
 
1493
 
 
1494
  assert(context != (DrawContext)NULL);
 
1495
  assert(context->signature == MagickSignature);
 
1496
  assert(fill_url != NULL);
 
1497
 
 
1498
  if(fill_url[0] != '#')
 
1499
    ThrowDrawException(DrawWarning,NotARelativeURL, fill_url);
 
1500
 
 
1501
  FormatString(pattern,"[%.1024s]",fill_url+1);
 
1502
 
 
1503
  if (GetImageAttribute(context->image,pattern) == (ImageAttribute *) NULL)
 
1504
    {
 
1505
      ThrowDrawException(DrawWarning,URLNotFound, fill_url)
 
1506
    }
 
1507
  else
 
1508
    {
 
1509
      char
 
1510
        pattern_spec[MaxTextExtent];
 
1511
 
 
1512
      FormatString(pattern_spec,"url(%.1024s)",fill_url);
 
1513
#if DRAW_BINARY_IMPLEMENTATION
 
1514
      DrawPatternPath(context->image,CurrentContext,pattern_spec,&CurrentContext->fill_pattern);
 
1515
#endif
 
1516
      /* Inherit base opacity */
 
1517
      if (CurrentContext->fill.opacity != TransparentOpacity)
 
1518
        CurrentContext->fill.opacity=CurrentContext->opacity;
 
1519
 
 
1520
      MvgPrintf(context, "fill %s\n",pattern_spec);
 
1521
    }
 
1522
}
 
1523
 
 
1524
/*
 
1525
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1526
%                                                                             %
 
1527
%                                                                             %
 
1528
%                                                                             %
 
1529
%   D r a w G e t F i l l O p a c i t y                                       %
 
1530
%                                                                             %
 
1531
%                                                                             %
 
1532
%                                                                             %
 
1533
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1534
%
 
1535
%  DrawGetFillOpacity() returns the opacity used when drawing using the fill
 
1536
%  color or fill texture.  Fully opaque is 1.0.
 
1537
%
 
1538
%  The format of the DrawGetFillOpacity method is:
 
1539
%
 
1540
%      double DrawGetFillOpacity(DrawContext context)
 
1541
%
 
1542
%  A description of each parameter follows:
 
1543
%
 
1544
%    o context: drawing context
 
1545
%
 
1546
*/
 
1547
MagickExport double DrawGetFillOpacity(DrawContext context)
 
1548
{
 
1549
  assert(context != (DrawContext)NULL);
 
1550
  assert(context->signature == MagickSignature);
 
1551
 
 
1552
  return (((double)(MaxRGB-CurrentContext->fill.opacity))/MaxRGB);
 
1553
}
 
1554
 
 
1555
/*
 
1556
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1557
%                                                                             %
 
1558
%                                                                             %
 
1559
%                                                                             %
 
1560
%   D r a w S e t F i l l O p a c i t y                                       %
 
1561
%                                                                             %
 
1562
%                                                                             %
 
1563
%                                                                             %
 
1564
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1565
%
 
1566
%  DrawSetFillOpacity() sets the opacity to use when drawing using the fill
 
1567
%  color or fill texture.  Fully opaque is 1.0.
 
1568
%
 
1569
%  The format of the DrawSetFillOpacity method is:
 
1570
%
 
1571
%      void DrawSetFillOpacity(DrawContext context, const double fill_opacity)
 
1572
%
 
1573
%  A description of each parameter follows:
 
1574
%
 
1575
%    o context: drawing context
 
1576
%
 
1577
%    o fill_opacity: fill opacity
 
1578
%
 
1579
*/
 
1580
MagickExport void DrawSetFillOpacity(DrawContext context,
 
1581
                                     const double fill_opacity)
 
1582
{
 
1583
  Quantum
 
1584
    quantum_opacity;
 
1585
 
 
1586
  double
 
1587
    validated_opacity;
 
1588
 
 
1589
  assert(context != (DrawContext)NULL);
 
1590
  assert(context->signature == MagickSignature);
 
1591
 
 
1592
  validated_opacity=(fill_opacity < 0.0 ? 0.0 : (fill_opacity > 1.0 ? 1.0 : fill_opacity));
 
1593
  quantum_opacity = (Quantum) (((double) MaxRGB*(1.0-validated_opacity))+0.5);
 
1594
 
 
1595
  if (context->filter_off || (CurrentContext->fill.opacity != quantum_opacity))
 
1596
    {
 
1597
      CurrentContext->fill.opacity = quantum_opacity;
 
1598
      MvgPrintf(context, "fill-opacity %.4g\n", validated_opacity);
 
1599
    }
 
1600
}
 
1601
 
 
1602
/*
 
1603
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1604
%                                                                             %
 
1605
%                                                                             %
 
1606
%                                                                             %
 
1607
%   D r a w G e t F i l l R u l e                                             %
 
1608
%                                                                             %
 
1609
%                                                                             %
 
1610
%                                                                             %
 
1611
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1612
%
 
1613
%  DrawGetFillRule() returns the fill rule used while drawing polygons.
 
1614
%
 
1615
%  The format of the DrawGetFillRule method is:
 
1616
%
 
1617
%      FillRule DrawGetFillRule(DrawContext context)
 
1618
%
 
1619
%  A description of each parameter follows:
 
1620
%
 
1621
%    o context: drawing context
 
1622
*/
 
1623
MagickExport FillRule DrawGetFillRule(DrawContext context)
 
1624
{
 
1625
  assert(context != (DrawContext)NULL);
 
1626
  assert(context->signature == MagickSignature);
 
1627
 
 
1628
  return CurrentContext->fill_rule;
 
1629
}
 
1630
 
 
1631
/*
 
1632
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1633
%                                                                             %
 
1634
%                                                                             %
 
1635
%                                                                             %
 
1636
%   D r a w S e t F i l l R u l e                                             %
 
1637
%                                                                             %
 
1638
%                                                                             %
 
1639
%                                                                             %
 
1640
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1641
%
 
1642
%  DrawSetFillRule() sets the fill rule to use while drawing polygons.
 
1643
%
 
1644
%  The format of the DrawSetFillRule method is:
 
1645
%
 
1646
%      void DrawSetFillRule(DrawContext context, const FillRule fill_rule)
 
1647
%
 
1648
%  A description of each parameter follows:
 
1649
%
 
1650
%    o context: drawing context
 
1651
%
 
1652
%    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
 
1653
%
 
1654
*/
 
1655
MagickExport void DrawSetFillRule(DrawContext context,
 
1656
                                  const FillRule fill_rule)
 
1657
{
 
1658
  const char
 
1659
    *p = NULL;
 
1660
 
 
1661
  assert(context != (DrawContext)NULL);
 
1662
  assert(context->signature == MagickSignature);
 
1663
 
 
1664
  if(context->filter_off || (CurrentContext->fill_rule != fill_rule))
 
1665
    {
 
1666
      CurrentContext->fill_rule = fill_rule;
 
1667
 
 
1668
      switch (fill_rule)
 
1669
        {
 
1670
        case EvenOddRule:
 
1671
          p = "evenodd";
 
1672
          break;
 
1673
        case NonZeroRule:
 
1674
          p = "nonzero";
 
1675
          break;
 
1676
        default:
 
1677
          break;
 
1678
        }
 
1679
 
 
1680
      if (p != NULL)
 
1681
        MvgPrintf(context, "fill-rule %s\n", p);
 
1682
    }
 
1683
}
 
1684
 
 
1685
/*
 
1686
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1687
%                                                                             %
 
1688
%                                                                             %
 
1689
%                                                                             %
 
1690
%   D r a w G e t F o n t                                                     %
 
1691
%                                                                             %
 
1692
%                                                                             %
 
1693
%                                                                             %
 
1694
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1695
%
 
1696
%  DrawGetFont() returns a null-terminaged string specifying the font used
 
1697
%  when annotating with text. The value returned must be freed by the user
 
1698
%  when no longer needed.
 
1699
%
 
1700
%  The format of the DrawGetFont method is:
 
1701
%
 
1702
%      char *DrawGetFont(DrawContext context)
 
1703
%
 
1704
%  A description of each parameter follows:
 
1705
%
 
1706
%    o context: drawing context
 
1707
*/
 
1708
MagickExport char *DrawGetFont(DrawContext context)
 
1709
{
 
1710
  assert(context != (DrawContext)NULL);
 
1711
  assert(context->signature == MagickSignature);
 
1712
 
 
1713
  if (CurrentContext->font != (char *) NULL)
 
1714
    return AllocateString(CurrentContext->font);
 
1715
  else
 
1716
    return (char *) NULL;
 
1717
}
 
1718
 
 
1719
/*
 
1720
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1721
%                                                                             %
 
1722
%                                                                             %
 
1723
%                                                                             %
 
1724
%   D r a w S e t F o n t                                                     %
 
1725
%                                                                             %
 
1726
%                                                                             %
 
1727
%                                                                             %
 
1728
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1729
%
 
1730
%  DrawSetFont() sets the fully-sepecified font to use when annotating with
 
1731
%  text.
 
1732
%
 
1733
%  The format of the DrawSetFont method is:
 
1734
%
 
1735
%      void DrawSetFont(DrawContext context, const char *font_name)
 
1736
%
 
1737
%  A description of each parameter follows:
 
1738
%
 
1739
%    o context: drawing context
 
1740
%
 
1741
%    o font_name: font name
 
1742
%
 
1743
*/
 
1744
MagickExport void DrawSetFont(DrawContext context, const char *font_name)
 
1745
{
 
1746
  assert(context != (DrawContext)NULL);
 
1747
  assert(context->signature == MagickSignature);
 
1748
  assert(font_name != (const char *) NULL);
 
1749
 
 
1750
  if(context->filter_off || (CurrentContext->font == NULL) ||
 
1751
     LocaleCompare(CurrentContext->font,font_name) != 0)
 
1752
    {
 
1753
      (void) CloneString(&CurrentContext->font,font_name);
 
1754
      if(CurrentContext->font == (char*)NULL)
 
1755
        ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
 
1756
          UnableToDrawOnImage);
 
1757
      MvgPrintf(context, "font '%s'\n", font_name);
 
1758
    }
 
1759
}
 
1760
 
 
1761
/*
 
1762
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1763
%                                                                             %
 
1764
%                                                                             %
 
1765
%                                                                             %
 
1766
%   D r a w G e t F o n t F a m i l y                                         %
 
1767
%                                                                             %
 
1768
%                                                                             %
 
1769
%                                                                             %
 
1770
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1771
%
 
1772
%  DrawGetFontFamily() returns the font family to use when annotating with text.
 
1773
%  The value returned must be freed by the user when it is no longer needed.
 
1774
%
 
1775
%  The format of the DrawGetFontFamily method is:
 
1776
%
 
1777
%      char *DrawGetFontFamily(DrawContext context)
 
1778
%
 
1779
%  A description of each parameter follows:
 
1780
%
 
1781
%    o context: drawing context
 
1782
*/
 
1783
MagickExport char *DrawGetFontFamily(DrawContext context)
 
1784
{
 
1785
  assert(context != (DrawContext)NULL);
 
1786
  assert(context->signature == MagickSignature);
 
1787
 
 
1788
  if (CurrentContext->family != NULL)
 
1789
    return AllocateString(CurrentContext->family);
 
1790
  else
 
1791
    return (char *) NULL;
 
1792
}
 
1793
 
 
1794
/*
 
1795
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1796
%                                                                             %
 
1797
%                                                                             %
 
1798
%                                                                             %
 
1799
%   D r a w S e t F o n t F a m i l y                                         %
 
1800
%                                                                             %
 
1801
%                                                                             %
 
1802
%                                                                             %
 
1803
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1804
%
 
1805
%  DrawSetFontFamily() sets the font family to use when annotating with text.
 
1806
%
 
1807
%  The format of the DrawSetFontFamily method is:
 
1808
%
 
1809
%      void DrawSetFontFamily(DrawContext context, const char *font_family)
 
1810
%
 
1811
%  A description of each parameter follows:
 
1812
%
 
1813
%    o context: drawing context
 
1814
%
 
1815
%    o font_family: font family
 
1816
%
 
1817
*/
 
1818
MagickExport void DrawSetFontFamily(DrawContext context,
 
1819
                                    const char *font_family)
 
1820
{
 
1821
  assert(context != (DrawContext)NULL);
 
1822
  assert(context->signature == MagickSignature);
 
1823
  assert(font_family != (const char *) NULL);
 
1824
 
 
1825
  if(context->filter_off || (CurrentContext->family == NULL) ||
 
1826
     LocaleCompare(CurrentContext->family,font_family) != 0)
 
1827
    {
 
1828
      (void) CloneString(&CurrentContext->family,font_family);
 
1829
      if(CurrentContext->family == (char*)NULL)
 
1830
        ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
 
1831
          UnableToDrawOnImage);
 
1832
      MvgPrintf(context, "font-family '%s'\n", font_family);
 
1833
    }
 
1834
}
 
1835
 
 
1836
/*
 
1837
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1838
%                                                                             %
 
1839
%                                                                             %
 
1840
%                                                                             %
 
1841
%   D r a w G e t F o n t S i z e                                             %
 
1842
%                                                                             %
 
1843
%                                                                             %
 
1844
%                                                                             %
 
1845
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1846
%
 
1847
%  DrawGetFontSize() returns the font pointsize used when annotating with text.
 
1848
%
 
1849
%  The format of the DrawGetFontSize method is:
 
1850
%
 
1851
%      double DrawGetFontSize(DrawContext context)
 
1852
%
 
1853
%  A description of each parameter follows:
 
1854
%
 
1855
%    o context: drawing context
 
1856
*/
 
1857
MagickExport double DrawGetFontSize(DrawContext context)
 
1858
{
 
1859
  assert(context != (DrawContext)NULL);
 
1860
  assert(context->signature == MagickSignature);
 
1861
 
 
1862
  return CurrentContext->pointsize;
 
1863
}
 
1864
 
 
1865
/*
 
1866
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1867
%                                                                             %
 
1868
%                                                                             %
 
1869
%                                                                             %
 
1870
%   D r a w S e t F o n t S i z e                                             %
 
1871
%                                                                             %
 
1872
%                                                                             %
 
1873
%                                                                             %
 
1874
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1875
%
 
1876
%  DrawSetFontSize() sets the font pointsize to use when annotating with text.
 
1877
%
 
1878
%  The format of the DrawSetFontSize method is:
 
1879
%
 
1880
%      void DrawSetFontSize(DrawContext context, const double pointsize)
 
1881
%
 
1882
%  A description of each parameter follows:
 
1883
%
 
1884
%    o context: drawing context
 
1885
%
 
1886
%    o pointsize: text pointsize
 
1887
%
 
1888
*/
 
1889
MagickExport void DrawSetFontSize(DrawContext context,
 
1890
                                  const double pointsize)
 
1891
{
 
1892
  assert(context != (DrawContext)NULL);
 
1893
  assert(context->signature == MagickSignature);
 
1894
 
 
1895
  if(context->filter_off ||
 
1896
     (AbsoluteValue(CurrentContext->pointsize-pointsize) > MagickEpsilon))
 
1897
    {
 
1898
      CurrentContext->pointsize=pointsize;
 
1899
 
 
1900
      MvgPrintf(context, "font-size %.4g\n", pointsize);
 
1901
    }
 
1902
}
 
1903
 
 
1904
/*
 
1905
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1906
%                                                                             %
 
1907
%                                                                             %
 
1908
%                                                                             %
 
1909
%   D r a w G e t F o n t S t r e t c h                                       %
 
1910
%                                                                             %
 
1911
%                                                                             %
 
1912
%                                                                             %
 
1913
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1914
%
 
1915
%  DrawGetFontStretch() returns the font stretch used when annotating with text.
 
1916
%
 
1917
%  The format of the DrawGetFontStretch method is:
 
1918
%
 
1919
%      StretchType DrawGetFontStretch(DrawContext context)
 
1920
%
 
1921
%  A description of each parameter follows:
 
1922
%
 
1923
%    o context: drawing context
 
1924
*/
 
1925
MagickExport StretchType DrawGetFontStretch(DrawContext context)
 
1926
{
 
1927
  assert(context != (DrawContext)NULL);
 
1928
  assert(context->signature == MagickSignature);
 
1929
 
 
1930
  return CurrentContext->stretch;
 
1931
}
 
1932
 
 
1933
/*
 
1934
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1935
%                                                                             %
 
1936
%                                                                             %
 
1937
%                                                                             %
 
1938
%   D r a w S e t F o n t S t r e t c h                                       %
 
1939
%                                                                             %
 
1940
%                                                                             %
 
1941
%                                                                             %
 
1942
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1943
%
 
1944
%  DrawSetFontStretch() sets the font stretch to use when annotating with text.
 
1945
%  The AnyStretch enumeration acts as a wild-card "don't care" option.
 
1946
%
 
1947
%  The format of the DrawSetFontStretch method is:
 
1948
%
 
1949
%      void DrawSetFontStretch(DrawContext context,
 
1950
%                              const StretchType font_stretch)
 
1951
%
 
1952
%  A description of each parameter follows:
 
1953
%
 
1954
%    o context: drawing context
 
1955
%
 
1956
%    o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
 
1957
%                    CondensedStretch, SemiCondensedStretch,
 
1958
%                    SemiExpandedStretch, ExpandedStretch,
 
1959
%                    ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
 
1960
%
 
1961
*/
 
1962
MagickExport void DrawSetFontStretch(DrawContext context,
 
1963
                                     const StretchType font_stretch)
 
1964
{
 
1965
  const char
 
1966
    *p = NULL;
 
1967
 
 
1968
  assert(context != (DrawContext)NULL);
 
1969
  assert(context->signature == MagickSignature);
 
1970
 
 
1971
  if(context->filter_off || (CurrentContext->stretch != font_stretch))
 
1972
    {
 
1973
      CurrentContext->stretch=font_stretch;
 
1974
 
 
1975
      switch (font_stretch)
 
1976
        {
 
1977
        case NormalStretch:
 
1978
          p = "normal";
 
1979
          break;
 
1980
        case UltraCondensedStretch:
 
1981
          p = "ultra-condensed";
 
1982
          break;
 
1983
        case ExtraCondensedStretch:
 
1984
          p = "extra-condensed";
 
1985
          break;
 
1986
        case CondensedStretch:
 
1987
          p = "condensed";
 
1988
          break;
 
1989
        case SemiCondensedStretch:
 
1990
          p = "semi-condensed";
 
1991
          break;
 
1992
        case SemiExpandedStretch:
 
1993
          p = "semi-expanded";
 
1994
          break;
 
1995
        case ExpandedStretch:
 
1996
          p = "expanded";
 
1997
          break;
 
1998
        case ExtraExpandedStretch:
 
1999
          p = "extra-expanded";
 
2000
          break;
 
2001
        case UltraExpandedStretch:
 
2002
          p = "ultra-expanded";
 
2003
          break;
 
2004
        case AnyStretch:
 
2005
          p = "all";
 
2006
          break;
 
2007
        }
 
2008
 
 
2009
      if (p != NULL)
 
2010
        MvgPrintf(context, "font-stretch '%s'\n", p);
 
2011
    }
 
2012
}
 
2013
 
 
2014
/*
 
2015
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2016
%                                                                             %
 
2017
%                                                                             %
 
2018
%                                                                             %
 
2019
%   D r a w G e t F o n t S t y l e                                           %
 
2020
%                                                                             %
 
2021
%                                                                             %
 
2022
%                                                                             %
 
2023
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2024
%
 
2025
%  DrawGetFontStyle() returns the font style used when annotating with text.
 
2026
%
 
2027
%  The format of the DrawGetFontStyle method is:
 
2028
%
 
2029
%      StyleType DrawGetFontStyle(DrawContext context)
 
2030
%
 
2031
%  A description of each parameter follows:
 
2032
%
 
2033
%    o context: drawing context
 
2034
*/
 
2035
MagickExport StyleType DrawGetFontStyle(DrawContext context)
 
2036
{
 
2037
  assert(context != (DrawContext)NULL);
 
2038
  assert(context->signature == MagickSignature);
 
2039
 
 
2040
  return CurrentContext->style;
 
2041
}
 
2042
 
 
2043
/*
 
2044
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2045
%                                                                             %
 
2046
%                                                                             %
 
2047
%                                                                             %
 
2048
%   D r a w S e t F o n t S t y l e                                           %
 
2049
%                                                                             %
 
2050
%                                                                             %
 
2051
%                                                                             %
 
2052
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2053
%
 
2054
%  DrawSetFontStyle() sets the font style to use when annotating with text.
 
2055
%  The AnyStyle enumeration acts as a wild-card "don't care" option.
 
2056
%
 
2057
%  The format of the DrawSetFontStyle method is:
 
2058
%
 
2059
%      void DrawSetFontStyle(DrawContext context, const StyleType style)
 
2060
%
 
2061
%  A description of each parameter follows:
 
2062
%
 
2063
%    o context: drawing context
 
2064
%
 
2065
%    o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
 
2066
%
 
2067
*/
 
2068
MagickExport void DrawSetFontStyle(DrawContext context,
 
2069
                                   const StyleType style)
 
2070
{
 
2071
  const char
 
2072
    *p = NULL;
 
2073
 
 
2074
  assert(context != (DrawContext)NULL);
 
2075
  assert(context->signature == MagickSignature);
 
2076
 
 
2077
  if(context->filter_off || (CurrentContext->style != style))
 
2078
    {
 
2079
      CurrentContext->style=style;
 
2080
 
 
2081
      switch (style)
 
2082
        {
 
2083
        case NormalStyle:
 
2084
          p = "normal";
 
2085
          break;
 
2086
        case ItalicStyle:
 
2087
          p = "italic";
 
2088
          break;
 
2089
        case ObliqueStyle:
 
2090
          p = "oblique";
 
2091
          break;
 
2092
        case AnyStyle:
 
2093
          p = "all";
 
2094
          break;
 
2095
        }
 
2096
 
 
2097
      if (p != NULL)
 
2098
        MvgPrintf(context, "font-style '%s'\n", p);
 
2099
    }
 
2100
}
 
2101
 
 
2102
/*
 
2103
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2104
%                                                                             %
 
2105
%                                                                             %
 
2106
%                                                                             %
 
2107
%   D r a w G e t F o n t W e i g h t                                         %
 
2108
%                                                                             %
 
2109
%                                                                             %
 
2110
%                                                                             %
 
2111
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2112
%
 
2113
%  DrawGetFontWeight() returns the font weight used when annotating with text.
 
2114
%
 
2115
%  The format of the DrawGetFontWeight method is:
 
2116
%
 
2117
%      unsigned long DrawGetFontWeight(DrawContext context)
 
2118
%
 
2119
%  A description of each parameter follows:
 
2120
%
 
2121
%    o context: drawing context
 
2122
*/
 
2123
MagickExport unsigned long DrawGetFontWeight(DrawContext context)
 
2124
{
 
2125
  assert(context != (DrawContext)NULL);
 
2126
  assert(context->signature == MagickSignature);
 
2127
 
 
2128
  return CurrentContext->weight;
 
2129
}
 
2130
 
 
2131
/*
 
2132
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2133
%                                                                             %
 
2134
%                                                                             %
 
2135
%                                                                             %
 
2136
%   D r a w S e t F o n t W e i g h t                                         %
 
2137
%                                                                             %
 
2138
%                                                                             %
 
2139
%                                                                             %
 
2140
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2141
%
 
2142
%  DrawSetFontWeight() sets the font weight to use when annotating with text.
 
2143
%
 
2144
%  The format of the DrawSetFontWeight method is:
 
2145
%
 
2146
%      void DrawSetFontWeight(DrawContext context,
 
2147
%                             const unsigned long font_weight)
 
2148
%
 
2149
%  A description of each parameter follows:
 
2150
%
 
2151
%    o context: drawing context
 
2152
%
 
2153
%    o font_weight: font weight (valid range 100-900)
 
2154
%
 
2155
*/
 
2156
MagickExport void DrawSetFontWeight(DrawContext context,
 
2157
                                    const unsigned long font_weight)
 
2158
{
 
2159
  assert(context != (DrawContext)NULL);
 
2160
  assert(context->signature == MagickSignature);
 
2161
 
 
2162
  if(context->filter_off || (CurrentContext->weight != font_weight))
 
2163
    {
 
2164
      CurrentContext->weight=font_weight;
 
2165
      MvgPrintf(context, "font-weight %lu\n", font_weight);
 
2166
    }
 
2167
}
 
2168
 
 
2169
/*
 
2170
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2171
%                                                                             %
 
2172
%                                                                             %
 
2173
%                                                                             %
 
2174
%   D r a w G e t G r a v i t y                                               %
 
2175
%                                                                             %
 
2176
%                                                                             %
 
2177
%                                                                             %
 
2178
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2179
%
 
2180
%  DrawGetGravity() returns the text placement gravity used when annotating
 
2181
%  with text.
 
2182
%
 
2183
%  The format of the DrawGetGravity method is:
 
2184
%
 
2185
%      GravityType DrawGetGravity(DrawContext context)
 
2186
%
 
2187
%  A description of each parameter follows:
 
2188
%
 
2189
%    o context: drawing context
 
2190
*/
 
2191
MagickExport GravityType DrawGetGravity(DrawContext context)
 
2192
{
 
2193
  assert(context != (DrawContext)NULL);
 
2194
  assert(context->signature == MagickSignature);
 
2195
 
 
2196
  return CurrentContext->gravity;
 
2197
}
 
2198
 
 
2199
/*
 
2200
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2201
%                                                                             %
 
2202
%                                                                             %
 
2203
%                                                                             %
 
2204
%   D r a w S e t G r a v i t y                                               %
 
2205
%                                                                             %
 
2206
%                                                                             %
 
2207
%                                                                             %
 
2208
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2209
%
 
2210
%  DrawSetGravity() sets the text placement gravity to use when annotating
 
2211
%  with text.
 
2212
%
 
2213
%  The format of the DrawSetGravity method is:
 
2214
%
 
2215
%      void DrawSetGravity(DrawContext context, const GravityType gravity)
 
2216
%
 
2217
%  A description of each parameter follows:
 
2218
%
 
2219
%    o context: drawing context
 
2220
%
 
2221
%    o gravity: positioning gravity (NorthWestGravity, NorthGravity,
 
2222
%               NorthEastGravity, WestGravity, CenterGravity,
 
2223
%               EastGravity, SouthWestGravity, SouthGravity,
 
2224
%               SouthEastGravity)
 
2225
%
 
2226
*/
 
2227
MagickExport void DrawSetGravity(DrawContext context,
 
2228
                                 const GravityType gravity)
 
2229
{
 
2230
  const char
 
2231
    *p = NULL;
 
2232
 
 
2233
  assert(context != (DrawContext)NULL);
 
2234
  assert(context->signature == MagickSignature);
 
2235
 
 
2236
  if(context->filter_off || (CurrentContext->gravity != gravity))
 
2237
    {
 
2238
      CurrentContext->gravity=gravity;
 
2239
 
 
2240
      switch (gravity)
 
2241
        {
 
2242
        case NorthWestGravity:
 
2243
          p = "NorthWest";
 
2244
          break;
 
2245
        case NorthGravity:
 
2246
          p = "North";
 
2247
          break;
 
2248
        case NorthEastGravity:
 
2249
          p = "NorthEast";
 
2250
          break;
 
2251
        case WestGravity:
 
2252
          p = "West";
 
2253
          break;
 
2254
        case CenterGravity:
 
2255
          p = "Center";
 
2256
          break;
 
2257
        case EastGravity:
 
2258
          p = "East";
 
2259
          break;
 
2260
        case SouthWestGravity:
 
2261
          p = "SouthWest";
 
2262
          break;
 
2263
        case SouthGravity:
 
2264
          p = "South";
 
2265
          break;
 
2266
        case SouthEastGravity:
 
2267
          p = "SouthEast";
 
2268
          break;
 
2269
        case StaticGravity:
 
2270
        case ForgetGravity:
 
2271
          {
 
2272
          }
 
2273
          break;
 
2274
        }
 
2275
 
 
2276
      if (p != NULL)
 
2277
        MvgPrintf(context, "gravity %s\n", p);
 
2278
    }
 
2279
}
 
2280
 
 
2281
/*
 
2282
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2283
%                                                                             %
 
2284
%                                                                             %
 
2285
%                                                                             %
 
2286
%   D r a w C o m p o s i t e                                                 %
 
2287
%                                                                             %
 
2288
%                                                                             %
 
2289
%                                                                             %
 
2290
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2291
%
 
2292
%  DrawComposite() composites an image onto the current image, using the
 
2293
%  specified composition operator, specified position, and at the specified
 
2294
%  size.
 
2295
%
 
2296
%  The format of the DrawComposite method is:
 
2297
%
 
2298
%      void DrawComposite(DrawContext context,
 
2299
%                         const CompositeOperator composite_operator,
 
2300
%                         const double x, const double y,
 
2301
%                         const double width, const double height,
 
2302
%                         const Image * image )
 
2303
%
 
2304
%  A description of each parameter follows:
 
2305
%
 
2306
%    o context: drawing context
 
2307
%
 
2308
%    o composite_operator: composition operator
 
2309
%
 
2310
%    o x: x ordinate of top left corner
 
2311
%
 
2312
%    o y: y ordinate of top left corner
 
2313
%
 
2314
%    o width: Width to resize image to prior to compositing.  Specify zero to
 
2315
%             use existing width.
 
2316
%
 
2317
%    o height: Height to resize image to prior to compositing.  Specify zero
 
2318
%             to use existing height.
 
2319
%
 
2320
%    o image: Image to composite
 
2321
%
 
2322
*/
 
2323
MagickExport void DrawComposite(DrawContext context,
 
2324
                                const CompositeOperator composite_operator,
 
2325
                                const double x, const double y,
 
2326
                                const double width, const double height,
 
2327
                                const Image * image )
 
2328
 
 
2329
{
 
2330
  ImageInfo
 
2331
    *image_info;
 
2332
 
 
2333
  Image
 
2334
    *clone_image;
 
2335
 
 
2336
  char
 
2337
    *media_type = NULL,
 
2338
    *base64 = NULL;
 
2339
 
 
2340
  const char
 
2341
    *mode = NULL;
 
2342
 
 
2343
  unsigned char
 
2344
    *blob = (unsigned char*)NULL;
 
2345
 
 
2346
  size_t
 
2347
    blob_length = 2048,
 
2348
    encoded_length = 0;
 
2349
 
 
2350
  MonitorHandler
 
2351
    handler;
 
2352
 
 
2353
  assert(context != (DrawContext)NULL);
 
2354
  assert(image != (Image *) NULL);
 
2355
  assert(width != 0);
 
2356
  assert(height != 0);
 
2357
  assert(*image->magick != '\0');
 
2358
  
 
2359
/*   LogMagickEvent(CoderEvent,GetMagickModule(),"DrawComposite columns=%ld rows=%ld magick=%s ", */
 
2360
/*                  image->columns, image->rows, image->magick ); */
 
2361
 
 
2362
  clone_image = CloneImage(image,0,0,True,&context->image->exception);
 
2363
  if(!clone_image)
 
2364
    return;
 
2365
 
 
2366
  image_info = CloneImageInfo((ImageInfo*)NULL);
 
2367
  if(!image_info)
 
2368
    ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
 
2369
      UnableToDrawOnImage);
 
2370
  handler=SetMonitorHandler((MonitorHandler) NULL);
 
2371
  blob = (unsigned char*)ImageToBlob( image_info, clone_image, &blob_length,
 
2372
                                      &context->image->exception );
 
2373
  (void) SetMonitorHandler(handler);
 
2374
  DestroyImageInfo(image_info);
 
2375
  DestroyImageList(clone_image);
 
2376
  if(!blob)
 
2377
    return;
 
2378
 
 
2379
  base64 = Base64Encode(blob,blob_length,&encoded_length);
 
2380
  MagickFreeMemory(blob);
 
2381
  if(!base64)
 
2382
    {
 
2383
      char
 
2384
        buffer[MaxTextExtent];
 
2385
 
 
2386
      FormatString(buffer,"%ld bytes", (4L*blob_length/3L+4L));
 
2387
      ThrowDrawException(ResourceLimitWarning,MemoryAllocationFailed,buffer)
 
2388
    }
 
2389
 
 
2390
  mode = "copy";
 
2391
  switch (composite_operator)
 
2392
    {
 
2393
    case AddCompositeOp:
 
2394
      mode = "add";
 
2395
      break;
 
2396
    case AtopCompositeOp:
 
2397
      mode = "atop";
 
2398
      break;
 
2399
    case BumpmapCompositeOp:
 
2400
      mode = "bumpmap";
 
2401
      break;
 
2402
    case ClearCompositeOp:
 
2403
      mode = "clear";
 
2404
      break;
 
2405
    case ColorizeCompositeOp:
 
2406
      mode = "colorize_not_supported";
 
2407
      break;
 
2408
    case CopyBlueCompositeOp:
 
2409
      mode = "copyblue";
 
2410
      break;
 
2411
    case CopyCompositeOp:
 
2412
      mode = "copy";
 
2413
      break;
 
2414
    case CopyGreenCompositeOp:
 
2415
      mode = "copygreen";
 
2416
      break;
 
2417
    case CopyOpacityCompositeOp:
 
2418
      mode = "copyopacity";
 
2419
      break;
 
2420
    case CopyRedCompositeOp:
 
2421
      mode = "copyred";
 
2422
      break;
 
2423
    case DarkenCompositeOp:
 
2424
      mode = "darken_not_supported";
 
2425
      break;
 
2426
    case DifferenceCompositeOp:
 
2427
      mode = "difference";
 
2428
      break;
 
2429
    case DisplaceCompositeOp:
 
2430
      mode = "displace_not_supported";
 
2431
      break;
 
2432
    case DissolveCompositeOp:
 
2433
      mode = "dissolve_not_supported";
 
2434
      break;
 
2435
    case HueCompositeOp:
 
2436
      mode = "hue_not_supported";
 
2437
      break;
 
2438
    case InCompositeOp:
 
2439
      mode = "in";
 
2440
      break;
 
2441
    case LightenCompositeOp:
 
2442
      mode = "lighten_not_supported";
 
2443
      break;
 
2444
    case LuminizeCompositeOp:
 
2445
      mode = "luminize_not_supported";
 
2446
      break;
 
2447
    case MinusCompositeOp:
 
2448
      mode = "minus";
 
2449
      break;
 
2450
    case ModulateCompositeOp:
 
2451
      mode = "modulate_not_supported";
 
2452
      break;
 
2453
    case MultiplyCompositeOp:
 
2454
      mode = "multiply";
 
2455
      break;
 
2456
    case NoCompositeOp:
 
2457
      mode = "no_not_supported";
 
2458
      break;
 
2459
    case OutCompositeOp:
 
2460
      mode = "out";
 
2461
      break;
 
2462
    case OverCompositeOp:
 
2463
      mode = "over";
 
2464
      break;
 
2465
    case OverlayCompositeOp:
 
2466
      mode = "overlay_not_supported";
 
2467
      break;
 
2468
    case PlusCompositeOp:
 
2469
      mode = "plus";
 
2470
      break;
 
2471
    case SaturateCompositeOp:
 
2472
      mode = "saturate_not_supported";
 
2473
      break;
 
2474
    case ScreenCompositeOp:
 
2475
      mode = "screen_not_supported";
 
2476
      break;
 
2477
    case SubtractCompositeOp:
 
2478
      mode = "subtract";
 
2479
      break;
 
2480
    case ThresholdCompositeOp:
 
2481
      mode = "threshold";
 
2482
      break;
 
2483
    case XorCompositeOp:
 
2484
      mode = "xor";
 
2485
      break;
 
2486
    default:
 
2487
      break;
 
2488
    }
 
2489
 
 
2490
  media_type = MagickToMime( image->magick );
 
2491
 
 
2492
  if( media_type != NULL )
 
2493
    {
 
2494
      char
 
2495
        *str;
 
2496
 
 
2497
      int
 
2498
        remaining;
 
2499
 
 
2500
      MvgPrintf(context, "image %s %.4g,%.4g %.4g,%.4g 'data:%s;base64,\n",
 
2501
                mode, x, y, width, height, media_type);
 
2502
 
 
2503
      remaining = (int)encoded_length;
 
2504
      str = base64;
 
2505
      while( remaining > 0 )
 
2506
        {
 
2507
          MvgPrintf(context,"%.76s", str);
 
2508
          remaining -= 76;
 
2509
          str += 76;
 
2510
          if(remaining > 0)
 
2511
            MvgPrintf(context,"\n");
 
2512
        }
 
2513
 
 
2514
      MvgPrintf(context,"'\n");
 
2515
    }
 
2516
 
 
2517
  MagickFreeMemory(base64);
 
2518
  MagickFreeMemory(media_type);
 
2519
}
 
2520
 
 
2521
/*
 
2522
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2523
%                                                                             %
 
2524
%                                                                             %
 
2525
%                                                                             %
 
2526
%   D r a w L i n e                                                           %
 
2527
%                                                                             %
 
2528
%                                                                             %
 
2529
%                                                                             %
 
2530
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2531
%
 
2532
%  DrawLine() draws a line on the image using the current stroke color,
 
2533
%  stroke opacity, and stroke width.
 
2534
%
 
2535
%  The format of the DrawLine method is:
 
2536
%
 
2537
%      void DrawLine(DrawContext context,
 
2538
%                    const double sx, const double sy,
 
2539
%                    const double ex, const double ey)
 
2540
%
 
2541
%  A description of each parameter follows:
 
2542
%
 
2543
%    o context: drawing context
 
2544
%
 
2545
%    o sx: starting x ordinate
 
2546
%
 
2547
%    o sy: starting y ordinate
 
2548
%
 
2549
%    o ex: ending x ordinate
 
2550
%
 
2551
%    o ey: ending y ordinate
 
2552
%
 
2553
*/
 
2554
MagickExport void DrawLine(DrawContext context,
 
2555
                           const double sx, const double sy,
 
2556
                           const double ex, const double ey)
 
2557
{
 
2558
  assert(context != (DrawContext)NULL);
 
2559
  assert(context->signature == MagickSignature);
 
2560
 
 
2561
  MvgPrintf(context, "line %.4g,%.4g %.4g,%.4g\n", sx, sy, ex, ey);
 
2562
}
 
2563
 
 
2564
/*
 
2565
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2566
%                                                                             %
 
2567
%                                                                             %
 
2568
%                                                                             %
 
2569
%   D r a w M a t t e                                                         %
 
2570
%                                                                             %
 
2571
%                                                                             %
 
2572
%                                                                             %
 
2573
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2574
%
 
2575
%  DrawMatte() paints on the image's opacity channel in order to set effected
 
2576
%  pixels to transparent.
 
2577
%  to influence the opacity of pixels. The available paint
 
2578
%  methods are:
 
2579
%
 
2580
%    PointMethod: Select the target pixel
 
2581
%    ReplaceMethod: Select any pixel that matches the target pixel.
 
2582
%    FloodfillMethod: Select the target pixel and matching neighbors.
 
2583
%    FillToBorderMethod: Select the target pixel and neighbors not matching
 
2584
%                        border color.
 
2585
%    ResetMethod: Select all pixels.
 
2586
%
 
2587
%  The format of the DrawMatte method is:
 
2588
%
 
2589
%      void DrawMatte(DrawContext context,
 
2590
%                     const double x, const double y,
 
2591
%                     const PaintMethod paint_method)
 
2592
%
 
2593
%  A description of each parameter follows:
 
2594
%
 
2595
%    o context: drawing context
 
2596
%
 
2597
%    o x: x ordinate
 
2598
%
 
2599
%    o y: y ordinate
 
2600
%
 
2601
%    o paint_method:
 
2602
%
 
2603
*/
 
2604
MagickExport void DrawMatte(DrawContext context,
 
2605
                            const double x, const double y,
 
2606
                            const PaintMethod paint_method)
 
2607
{
 
2608
  const char
 
2609
    *p = NULL;
 
2610
 
 
2611
  assert(context != (DrawContext)NULL);
 
2612
  assert(context->signature == MagickSignature);
 
2613
 
 
2614
  switch (paint_method)
 
2615
    {
 
2616
    case PointMethod:
 
2617
      p = "point";
 
2618
      break;
 
2619
    case ReplaceMethod:
 
2620
      p = "replace";
 
2621
      break;
 
2622
    case FloodfillMethod:
 
2623
      p = "floodfill";
 
2624
      break;
 
2625
    case FillToBorderMethod:
 
2626
      p = "filltoborder";
 
2627
      break;
 
2628
    case ResetMethod:
 
2629
      p = "reset";
 
2630
      break;
 
2631
    }
 
2632
 
 
2633
  if (p != NULL)
 
2634
    MvgPrintf(context, "matte %.4g,%.4g %s\n", x, y, p);
 
2635
}
 
2636
 
 
2637
/*
 
2638
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2639
%                                                                             %
 
2640
%                                                                             %
 
2641
%                                                                             %
 
2642
%   D r a w P a t h C l o s e                                                 %
 
2643
%                                                                             %
 
2644
%                                                                             %
 
2645
%                                                                             %
 
2646
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2647
%
 
2648
%  DrawPathClose() adds a path element to the current path which closes the
 
2649
%  current subpath by drawing a straight line from the current point to the
 
2650
%  current subpath's most recent starting point (usually, the most recent
 
2651
%  moveto point).
 
2652
%
 
2653
%  The format of the DrawPathClose method is:
 
2654
%
 
2655
%      void DrawPathClose(DrawContext context)
 
2656
%
 
2657
%  A description of each parameter follows:
 
2658
%
 
2659
%    o context: drawing context
 
2660
%
 
2661
*/
 
2662
MagickExport void DrawPathClose(DrawContext context)
 
2663
{
 
2664
  assert(context != (DrawContext)NULL);
 
2665
  assert(context->signature == MagickSignature);
 
2666
 
 
2667
  MvgAutoWrapPrintf(context, "%s", context->path_mode == AbsolutePathMode ? "Z" : "z");
 
2668
}
 
2669
 
 
2670
/*
 
2671
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2672
%                                                                             %
 
2673
%                                                                             %
 
2674
%                                                                             %
 
2675
%   D r a w P a t h C u r v e T o A b s o l u t e                             %
 
2676
%                                                                             %
 
2677
%                                                                             %
 
2678
%                                                                             %
 
2679
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2680
%
 
2681
%  DrawPathCurveToAbsolute() draws a cubic Bļæ½zier curve from the current
 
2682
%  point to (x,y) using (x1,y1) as the control point at the beginning of
 
2683
%  the curve and (x2,y2) as the control point at the end of the curve using
 
2684
%  absolute coordinates. At the end of the command, the new current point
 
2685
%  becomes the final (x,y) coordinate pair used in the polybezier.
 
2686
%
 
2687
%  The format of the DrawPathCurveToAbsolute method is:
 
2688
%
 
2689
%      void DrawPathCurveToAbsolute(DrawContext context,
 
2690
%                                   const double x1, const double y1,
 
2691
%                                   const double x2, const double y2,
 
2692
%                                   const double x, const double y)
 
2693
%
 
2694
%  A description of each parameter follows:
 
2695
%
 
2696
%    o context: drawing context
 
2697
%
 
2698
%    o x1: x ordinate of control point for curve beginning
 
2699
%
 
2700
%    o y1: y ordinate of control point for curve beginning
 
2701
%
 
2702
%    o x2: x ordinate of control point for curve ending
 
2703
%
 
2704
%    o y2: y ordinate of control point for curve ending
 
2705
%
 
2706
%    o x: x ordinate of the end of the curve
 
2707
%
 
2708
%    o y: y ordinate of the end of the curve
 
2709
%
 
2710
*/
 
2711
static void DrawPathCurveTo(DrawContext context,
 
2712
                            const PathMode mode,
 
2713
                            const double x1, const double y1,
 
2714
                            const double x2, const double y2,
 
2715
                            const double x, const double y)
 
2716
{
 
2717
  assert(context != (DrawContext)NULL);
 
2718
  assert(context->signature == MagickSignature);
 
2719
 
 
2720
  if ((context->path_operation != PathCurveToOperation)
 
2721
      || (context->path_mode != mode))
 
2722
    {
 
2723
      context->path_operation = PathCurveToOperation;
 
2724
      context->path_mode = mode;
 
2725
      MvgAutoWrapPrintf(context, "%c%.4g,%.4g %.4g,%.4g %.4g,%.4g",
 
2726
                        mode == AbsolutePathMode ? 'C' : 'c',
 
2727
                        x1, y1, x2, y2, x, y);
 
2728
    }
 
2729
  else
 
2730
    MvgAutoWrapPrintf(context, " %.4g,%.4g %.4g,%.4g %.4g,%.4g",
 
2731
                      x1, y1, x2, y2, x, y);
 
2732
}
 
2733
MagickExport void DrawPathCurveToAbsolute(DrawContext context,
 
2734
                                          const double x1, const double y1,
 
2735
                                          const double x2, const double y2,
 
2736
                                          const double x, const double y)
 
2737
{
 
2738
  assert(context != (DrawContext)NULL);
 
2739
  assert(context->signature == MagickSignature);
 
2740
 
 
2741
  DrawPathCurveTo(context, AbsolutePathMode, x1, y1, x2, y2, x, y);
 
2742
}
 
2743
 
 
2744
/*
 
2745
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2746
%                                                                             %
 
2747
%                                                                             %
 
2748
%                                                                             %
 
2749
%   D r a w P a t h C u r v e T o R e l a t i v e                             %
 
2750
%                                                                             %
 
2751
%                                                                             %
 
2752
%                                                                             %
 
2753
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2754
%
 
2755
%  DrawPathCurveToRelative() draws a cubic Bļæ½zier curve from the current
 
2756
%  point to (x,y) using (x1,y1) as the control point at the beginning of
 
2757
%  the curve and (x2,y2) as the control point at the end of the curve using
 
2758
%  relative coordinates. At the end of the command, the new current point
 
2759
%  becomes the final (x,y) coordinate pair used in the polybezier.
 
2760
%
 
2761
%  The format of the DrawPathCurveToRelative method is:
 
2762
%
 
2763
%      void DrawPathCurveToRelative(DrawContext context,
 
2764
%                                   const double x1, const double y1,
 
2765
%                                   const double x2, const double y2,
 
2766
%                                   const double x, const double y)
 
2767
%
 
2768
%  A description of each parameter follows:
 
2769
%
 
2770
%    o context: drawing context
 
2771
%
 
2772
%    o x1: x ordinate of control point for curve beginning
 
2773
%
 
2774
%    o y1: y ordinate of control point for curve beginning
 
2775
%
 
2776
%    o x2: x ordinate of control point for curve ending
 
2777
%
 
2778
%    o y2: y ordinate of control point for curve ending
 
2779
%
 
2780
%    o x: x ordinate of the end of the curve
 
2781
%
 
2782
%    o y: y ordinate of the end of the curve
 
2783
%
 
2784
*/
 
2785
MagickExport void DrawPathCurveToRelative(DrawContext context,
 
2786
                                          const double x1, const double y1,
 
2787
                                          const double x2, const double y2,
 
2788
                                          const double x, const double y)
 
2789
{
 
2790
  assert(context != (DrawContext)NULL);
 
2791
  assert(context->signature == MagickSignature);
 
2792
 
 
2793
  DrawPathCurveTo(context, RelativePathMode, x1, y1, x2, y2, x, y);
 
2794
}
 
2795
 
 
2796
/*
 
2797
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2798
%                                                                             %
 
2799
%                                                                             %
 
2800
%                                                                             %
 
2801
%   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 %
 
2802
%                                                                             %
 
2803
%                                                                             %
 
2804
%                                                                             %
 
2805
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2806
%
 
2807
%  DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bļæ½zier curve
 
2808
%  from the current point to (x,y) using (x1,y1) as the control point using
 
2809
%  absolute coordinates. At the end of the command, the new current point
 
2810
%  becomes the final (x,y) coordinate pair used in the polybezier.
 
2811
%
 
2812
%  The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
 
2813
%
 
2814
%      void DrawPathCurveToQuadraticBezierAbsolute(DrawContext context,
 
2815
%                                                  const double x1,
 
2816
%                                                  const double y1,
 
2817
%                                                  const double x,
 
2818
%                                                  const double y)
 
2819
%
 
2820
%  A description of each parameter follows:
 
2821
%
 
2822
%    o context: drawing context
 
2823
%
 
2824
%    o x1: x ordinate of the control point
 
2825
%
 
2826
%    o y1: y ordinate of the control point
 
2827
%
 
2828
%    o x: x ordinate of final point
 
2829
%
 
2830
%    o y: y ordinate of final point
 
2831
%
 
2832
*/
 
2833
static void DrawPathCurveToQuadraticBezier(DrawContext context,
 
2834
                                           const PathMode mode,
 
2835
                                           const double x1, double y1,
 
2836
                                           const double x, const double y)
 
2837
{
 
2838
  assert(context != (DrawContext)NULL);
 
2839
  assert(context->signature == MagickSignature);
 
2840
 
 
2841
  if ((context->path_operation != PathCurveToQuadraticBezierOperation)
 
2842
      || (context->path_mode != mode))
 
2843
    {
 
2844
      context->path_operation = PathCurveToQuadraticBezierOperation;
 
2845
      context->path_mode = mode;
 
2846
      MvgAutoWrapPrintf(context, "%c%.4g,%.4g %.4g,%.4g",
 
2847
                        mode == AbsolutePathMode ? 'Q' : 'q', x1, y1, x, y);
 
2848
    }
 
2849
  else
 
2850
    MvgAutoWrapPrintf(context, " %.4g,%.4g %.4g,%.4g", x1, y1, x, y);
 
2851
}
 
2852
MagickExport void DrawPathCurveToQuadraticBezierAbsolute(DrawContext context,
 
2853
                                                         const double x1,
 
2854
                                                         const double y1,
 
2855
                                                         const double x,
 
2856
                                                         const double y)
 
2857
{
 
2858
  assert(context != (DrawContext)NULL);
 
2859
  assert(context->signature == MagickSignature);
 
2860
 
 
2861
  DrawPathCurveToQuadraticBezier(context, AbsolutePathMode, x1, y1, x, y);
 
2862
}
 
2863
 
 
2864
/*
 
2865
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2866
%                                                                             %
 
2867
%                                                                             %
 
2868
%                                                                             %
 
2869
%   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 %
 
2870
%                                                                             %
 
2871
%                                                                             %
 
2872
%                                                                             %
 
2873
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2874
%
 
2875
%  DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bļæ½zier curve
 
2876
%  from the current point to (x,y) using (x1,y1) as the control point using
 
2877
%  relative coordinates. At the end of the command, the new current point
 
2878
%  becomes the final (x,y) coordinate pair used in the polybezier.
 
2879
%
 
2880
%  The format of the DrawPathCurveToQuadraticBezierRelative method is:
 
2881
%
 
2882
%      void DrawPathCurveToQuadraticBezierRelative(DrawContext context,
 
2883
%                                                  const double x1,
 
2884
%                                                  const double y1,
 
2885
%                                                  const double x,
 
2886
%                                                  const double y)
 
2887
%
 
2888
%  A description of each parameter follows:
 
2889
%
 
2890
%    o context: drawing context
 
2891
%
 
2892
%    o x1: x ordinate of the control point
 
2893
%
 
2894
%    o y1: y ordinate of the control point
 
2895
%
 
2896
%    o x: x ordinate of final point
 
2897
%
 
2898
%    o y: y ordinate of final point
 
2899
%
 
2900
*/
 
2901
MagickExport void DrawPathCurveToQuadraticBezierRelative(DrawContext context,
 
2902
                                                         const double x1,
 
2903
                                                         const double y1,
 
2904
                                                         const double x,
 
2905
                                                         const double y)
 
2906
{
 
2907
  assert(context != (DrawContext)NULL);
 
2908
  assert(context->signature == MagickSignature);
 
2909
 
 
2910
  DrawPathCurveToQuadraticBezier(context, RelativePathMode, x1, y1, x, y);
 
2911
}
 
2912
 
 
2913
/*
 
2914
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2915
%                                                                             %
 
2916
%                                                                             %
 
2917
%                                                                             %
 
2918
%   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 A b s o l u t e %
 
2919
%                                                                             %
 
2920
%                                                                             %
 
2921
%                                                                             %
 
2922
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2923
%
 
2924
%  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
 
2925
%  Bļæ½zier curve (using absolute coordinates) from the current point to
 
2926
%  (x,y). The control point is assumed to be the reflection of the
 
2927
%  control point on the previous command relative to the current
 
2928
%  point. (If there is no previous command or if the previous command was
 
2929
%  not a DrawPathCurveToQuadraticBezierAbsolute,
 
2930
%  DrawPathCurveToQuadraticBezierRelative,
 
2931
%  DrawPathCurveToQuadraticBezierSmoothAbsolut or
 
2932
%  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
 
2933
%  is coincident with the current point.). At the end of the command, the
 
2934
%  new current point becomes the final (x,y) coordinate pair used in the
 
2935
%  polybezier.
 
2936
%
 
2937
%  The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
 
2938
%
 
2939
%      void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawContext
 
2940
%                                                        context,
 
2941
%                                                        const double x,
 
2942
%                                                        const double y)
 
2943
%
 
2944
%  A description of each parameter follows:
 
2945
%
 
2946
%    o context: drawing context
 
2947
%
 
2948
%    o x: x ordinate of final point
 
2949
%
 
2950
%    o y: y ordinate of final point
 
2951
%
 
2952
*/
 
2953
static void DrawPathCurveToQuadraticBezierSmooth(DrawContext context,
 
2954
                                                 const PathMode mode,
 
2955
                                                 const double x, const double y)
 
2956
{
 
2957
  assert(context != (DrawContext)NULL);
 
2958
  assert(context->signature == MagickSignature);
 
2959
 
 
2960
  if ((context->path_operation != PathCurveToQuadraticBezierSmoothOperation)
 
2961
      || (context->path_mode != mode))
 
2962
    {
 
2963
      context->path_operation = PathCurveToQuadraticBezierSmoothOperation;
 
2964
      context->path_mode = mode;
 
2965
      MvgAutoWrapPrintf(context, "%c%.4g,%.4g",
 
2966
                        mode == AbsolutePathMode ? 'T' : 't', x, y);
 
2967
    }
 
2968
  else
 
2969
    MvgAutoWrapPrintf(context, " %.4g,%.4g", x, y);
 
2970
}
 
2971
MagickExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawContext
 
2972
                                                               context,
 
2973
                                                               const double x,
 
2974
                                                               const double y)
 
2975
{
 
2976
  assert(context != (DrawContext)NULL);
 
2977
  assert(context->signature == MagickSignature);
 
2978
 
 
2979
  DrawPathCurveToQuadraticBezierSmooth(context, AbsolutePathMode, x, y);
 
2980
}
 
2981
 
 
2982
/*
 
2983
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2984
%                                                                             %
 
2985
%                                                                             %
 
2986
%                                                                             %
 
2987
%   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 R e l a t i v e %
 
2988
%                                                                             %
 
2989
%                                                                             %
 
2990
%                                                                             %
 
2991
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
2992
%
 
2993
%  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
 
2994
%  Bļæ½zier curve (using relative coordinates) from the current point to
 
2995
%  (x,y). The control point is assumed to be the reflection of the
 
2996
%  control point on the previous command relative to the current
 
2997
%  point. (If there is no previous command or if the previous command was
 
2998
%  not a DrawPathCurveToQuadraticBezierAbsolute,
 
2999
%  DrawPathCurveToQuadraticBezierRelative,
 
3000
%  DrawPathCurveToQuadraticBezierSmoothAbsolut or
 
3001
%  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
 
3002
%  is coincident with the current point.). At the end of the command, the
 
3003
%  new current point becomes the final (x,y) coordinate pair used in the
 
3004
%  polybezier.
 
3005
%
 
3006
%  The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
 
3007
%
 
3008
%      void DrawPathCurveToQuadraticBezierSmoothRelative(DrawContext
 
3009
%                                                        context,
 
3010
%                                                        const double x,
 
3011
%                                                        const double y)
 
3012
%
 
3013
%  A description of each parameter follows:
 
3014
%
 
3015
%    o context: drawing context
 
3016
%
 
3017
%    o x: x ordinate of final point
 
3018
%
 
3019
%    o y: y ordinate of final point
 
3020
%
 
3021
%
 
3022
*/
 
3023
MagickExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawContext
 
3024
                                                               context,
 
3025
                                                               const double x,
 
3026
                                                               const double y)
 
3027
{
 
3028
  DrawPathCurveToQuadraticBezierSmooth(context, RelativePathMode, x, y);
 
3029
}
 
3030
 
 
3031
/*
 
3032
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3033
%                                                                             %
 
3034
%                                                                             %
 
3035
%                                                                             %
 
3036
%   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                 %
 
3037
%                                                                             %
 
3038
%                                                                             %
 
3039
%                                                                             %
 
3040
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3041
%
 
3042
%  DrawPathCurveToSmoothAbsolute() draws a cubic Bļæ½zier curve from the
 
3043
%  current point to (x,y) using absolute coordinates. The first control
 
3044
%  point is assumed to be the reflection of the second control point on
 
3045
%  the previous command relative to the current point. (If there is no
 
3046
%  previous command or if the previous command was not an
 
3047
%  DrawPathCurveToAbsolute, DrawPathCurveToRelative,
 
3048
%  DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
 
3049
%  the first control point is coincident with the current point.) (x2,y2)
 
3050
%  is the second control point (i.e., the control point at the end of the
 
3051
%  curve). At the end of the command, the new current point becomes the
 
3052
%  final (x,y) coordinate pair used in the polybezier.
 
3053
%
 
3054
%  The format of the DrawPathCurveToSmoothAbsolute method is:
 
3055
%
 
3056
%      void DrawPathCurveToSmoothAbsolute(DrawContext context,
 
3057
%                                         const double x2, const double y2,
 
3058
%                                         const double x, const double y)
 
3059
%
 
3060
%  A description of each parameter follows:
 
3061
%
 
3062
%    o context: drawing context
 
3063
%
 
3064
%    o x2: x ordinate of second control point
 
3065
%
 
3066
%    o y2: y ordinate of second control point
 
3067
%
 
3068
%    o x: x ordinate of termination point
 
3069
%
 
3070
%    o y: y ordinate of termination point
 
3071
%
 
3072
%
 
3073
*/
 
3074
static void DrawPathCurveToSmooth(DrawContext context, const PathMode mode,
 
3075
                                  const double x2, const double y2,
 
3076
                                  const double x, const double y)
 
3077
{
 
3078
  assert(context != (DrawContext)NULL);
 
3079
  assert(context->signature == MagickSignature);
 
3080
 
 
3081
  if ((context->path_operation != PathCurveToSmoothOperation)
 
3082
      || (context->path_mode != mode))
 
3083
    {
 
3084
      context->path_operation = PathCurveToSmoothOperation;
 
3085
      context->path_mode = mode;
 
3086
      MvgAutoWrapPrintf(context, "%c%.4g,%.4g %.4g,%.4g",
 
3087
                        mode == AbsolutePathMode ? 'S' : 's', x2, y2, x, y);
 
3088
    }
 
3089
  else
 
3090
    MvgAutoWrapPrintf(context, " %.4g,%.4g %.4g,%.4g", x2, y2, x, y);
 
3091
}
 
3092
MagickExport void DrawPathCurveToSmoothAbsolute(DrawContext context,
 
3093
                                                const double x2, const double y2,
 
3094
                                                const double x, const double y)
 
3095
{
 
3096
  assert(context != (DrawContext)NULL);
 
3097
  assert(context->signature == MagickSignature);
 
3098
 
 
3099
  DrawPathCurveToSmooth(context, AbsolutePathMode, x2, y2, x, y);
 
3100
}
 
3101
 
 
3102
/*
 
3103
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3104
%                                                                             %
 
3105
%                                                                             %
 
3106
%                                                                             %
 
3107
%   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                 %
 
3108
%                                                                             %
 
3109
%                                                                             %
 
3110
%                                                                             %
 
3111
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3112
%
 
3113
%  DrawPathCurveToSmoothRelative() draws a cubic Bļæ½zier curve from the
 
3114
%  current point to (x,y) using relative coordinates. The first control
 
3115
%  point is assumed to be the reflection of the second control point on
 
3116
%  the previous command relative to the current point. (If there is no
 
3117
%  previous command or if the previous command was not an
 
3118
%  DrawPathCurveToAbsolute, DrawPathCurveToRelative,
 
3119
%  DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
 
3120
%  the first control point is coincident with the current point.) (x2,y2)
 
3121
%  is the second control point (i.e., the control point at the end of the
 
3122
%  curve). At the end of the command, the new current point becomes the
 
3123
%  final (x,y) coordinate pair used in the polybezier.
 
3124
%
 
3125
%  The format of the DrawPathCurveToSmoothRelative method is:
 
3126
%
 
3127
%      void DrawPathCurveToSmoothRelative(DrawContext context,
 
3128
%                                         const double x2, const double y2,
 
3129
%                                         const double x, const double y)
 
3130
%
 
3131
%  A description of each parameter follows:
 
3132
%
 
3133
%    o context: drawing context
 
3134
%
 
3135
%    o x2: x ordinate of second control point
 
3136
%
 
3137
%    o y2: y ordinate of second control point
 
3138
%
 
3139
%    o x: x ordinate of termination point
 
3140
%
 
3141
%    o y: y ordinate of termination point
 
3142
%
 
3143
%
 
3144
*/
 
3145
MagickExport void DrawPathCurveToSmoothRelative(DrawContext context,
 
3146
                                                const double x2, const double y2,
 
3147
                                                const double x, const double y)
 
3148
{
 
3149
  assert(context != (DrawContext)NULL);
 
3150
  assert(context->signature == MagickSignature);
 
3151
 
 
3152
  DrawPathCurveToSmooth(context, RelativePathMode, x2, y2, x, y);
 
3153
}
 
3154
 
 
3155
/*
 
3156
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3157
%                                                                             %
 
3158
%                                                                             %
 
3159
%                                                                             %
 
3160
%   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                     %
 
3161
%                                                                             %
 
3162
%                                                                             %
 
3163
%                                                                             %
 
3164
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3165
%
 
3166
%  DrawPathEllipticArcAbsolute() draws an elliptical arc from the current
 
3167
%  point to (x, y) using absolute coordinates. The size and orientation
 
3168
%  of the ellipse are defined by two radii (rx, ry) and an
 
3169
%  xAxisRotation, which indicates how the ellipse as a whole is rotated
 
3170
%  relative to the current coordinate system. The center (cx, cy) of the
 
3171
%  ellipse is calculated automatically to satisfy the constraints imposed
 
3172
%  by the other parameters. largeArcFlag and sweepFlag contribute to the
 
3173
%  automatic calculations and help determine how the arc is drawn. If
 
3174
%  largeArcFlag is true then draw the larger of the available arcs. If
 
3175
%  sweepFlag is true, then draw the arc matching a clock-wise rotation.
 
3176
%
 
3177
%  The format of the DrawPathEllipticArcAbsolute method is:
 
3178
%
 
3179
%      void DrawPathEllipticArcAbsolute(DrawContext context,
 
3180
%                                       const double rx, const double ry,
 
3181
%                                       const double x_axis_rotation,
 
3182
%                                       unsigned int large_arc_flag,
 
3183
%                                       unsigned int sweep_flag,
 
3184
%                                       const double x, const double y)
 
3185
%
 
3186
%  A description of each parameter follows:
 
3187
%
 
3188
%    o context: drawing context
 
3189
%
 
3190
%    o rx: x radius
 
3191
%
 
3192
%    o ry: y radius
 
3193
%
 
3194
%    o x_axis_rotation: indicates how the ellipse as a whole is rotated
 
3195
%                       relative to the current coordinate system
 
3196
%
 
3197
%    o large_arc_flag: If non-zero (true) then draw the larger of the
 
3198
%                      available arcs
 
3199
%
 
3200
%    o sweep_flag: If non-zero (true) then draw the arc matching a
 
3201
%                  clock-wise rotation
 
3202
%
 
3203
%
 
3204
*/
 
3205
static void DrawPathEllipticArc(DrawContext context, const PathMode mode,
 
3206
                                const double rx, const double ry,
 
3207
                                const double x_axis_rotation,
 
3208
                                unsigned int large_arc_flag,
 
3209
                                unsigned int sweep_flag,
 
3210
                                const double x, const double y)
 
3211
{
 
3212
  assert(context != (DrawContext)NULL);
 
3213
  assert(context->signature == MagickSignature);
 
3214
 
 
3215
  if ((context->path_operation != PathEllipticArcOperation)
 
3216
      || (context->path_mode != mode))
 
3217
    {
 
3218
      context->path_operation = PathEllipticArcOperation;
 
3219
      context->path_mode = mode;
 
3220
      MvgAutoWrapPrintf(context, "%c%.4g,%.4g %.4g %u %u %.4g,%.4g",
 
3221
                        mode == AbsolutePathMode ? 'A' : 'a', rx, ry, x_axis_rotation,
 
3222
                        large_arc_flag, sweep_flag, x, y);
 
3223
    }
 
3224
  else
 
3225
    MvgAutoWrapPrintf(context, " %.4g,%.4g %.4g %u %u %.4g,%.4g", rx, ry,
 
3226
                      x_axis_rotation, large_arc_flag, sweep_flag, x, y);
 
3227
}
 
3228
MagickExport void DrawPathEllipticArcAbsolute(DrawContext context,
 
3229
                                              const double rx, const double ry,
 
3230
                                              const double x_axis_rotation,
 
3231
                                              unsigned int large_arc_flag,
 
3232
                                              unsigned int sweep_flag,
 
3233
                                              const double x, const double y)
 
3234
{
 
3235
  assert(context != (DrawContext)NULL);
 
3236
  assert(context->signature == MagickSignature);
 
3237
 
 
3238
  DrawPathEllipticArc(context, AbsolutePathMode, rx, ry, x_axis_rotation,
 
3239
                      large_arc_flag, sweep_flag, x, y);
 
3240
}
 
3241
 
 
3242
/*
 
3243
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3244
%                                                                             %
 
3245
%                                                                             %
 
3246
%                                                                             %
 
3247
%   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                     %
 
3248
%                                                                             %
 
3249
%                                                                             %
 
3250
%                                                                             %
 
3251
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3252
%
 
3253
%  DrawPathEllipticArcRelative() draws an elliptical arc from the current
 
3254
%  point to (x, y) using relative coordinates. The size and orientation
 
3255
%  of the ellipse are defined by two radii (rx, ry) and an
 
3256
%  xAxisRotation, which indicates how the ellipse as a whole is rotated
 
3257
%  relative to the current coordinate system. The center (cx, cy) of the
 
3258
%  ellipse is calculated automatically to satisfy the constraints imposed
 
3259
%  by the other parameters. largeArcFlag and sweepFlag contribute to the
 
3260
%  automatic calculations and help determine how the arc is drawn. If
 
3261
%  largeArcFlag is true then draw the larger of the available arcs. If
 
3262
%  sweepFlag is true, then draw the arc matching a clock-wise rotation.
 
3263
%
 
3264
%  The format of the DrawPathEllipticArcRelative method is:
 
3265
%
 
3266
%      void DrawPathEllipticArcRelative(DrawContext context,
 
3267
%                                       const double rx, const double ry,
 
3268
%                                       const double x_axis_rotation,
 
3269
%                                       unsigned int large_arc_flag,
 
3270
%                                       unsigned int sweep_flag,
 
3271
%                                       const double x, const double y)
 
3272
%
 
3273
%  A description of each parameter follows:
 
3274
%
 
3275
%    o context: drawing context
 
3276
%
 
3277
%    o rx: x radius
 
3278
%
 
3279
%    o ry: y radius
 
3280
%
 
3281
%    o x_axis_rotation: indicates how the ellipse as a whole is rotated
 
3282
%                       relative to the current coordinate system
 
3283
%
 
3284
%    o large_arc_flag: If non-zero (true) then draw the larger of the
 
3285
%                      available arcs
 
3286
%
 
3287
%    o sweep_flag: If non-zero (true) then draw the arc matching a
 
3288
%                  clock-wise rotation
 
3289
%
 
3290
*/
 
3291
MagickExport void DrawPathEllipticArcRelative(DrawContext context,
 
3292
                                              const double rx, const double ry,
 
3293
                                              const double x_axis_rotation,
 
3294
                                              unsigned int large_arc_flag,
 
3295
                                              unsigned int sweep_flag,
 
3296
                                              const double x, const double y)
 
3297
{
 
3298
  DrawPathEllipticArc(context, RelativePathMode, rx, ry, x_axis_rotation,
 
3299
                      large_arc_flag, sweep_flag, x, y);
 
3300
}
 
3301
 
 
3302
/*
 
3303
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3304
%                                                                             %
 
3305
%                                                                             %
 
3306
%                                                                             %
 
3307
%   D r a w P a t h F i n i s h                                               %
 
3308
%                                                                             %
 
3309
%                                                                             %
 
3310
%                                                                             %
 
3311
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3312
%
 
3313
%  DrawPathFinish() terminates the current path.
 
3314
%
 
3315
%  The format of the DrawPathFinish method is:
 
3316
%
 
3317
%      void DrawPathFinish(DrawContext context)
 
3318
%
 
3319
%  A description of each parameter follows:
 
3320
%
 
3321
%    o context: drawing context
 
3322
%
 
3323
*/
 
3324
MagickExport void DrawPathFinish(DrawContext context)
 
3325
{
 
3326
  assert(context != (DrawContext)NULL);
 
3327
  assert(context->signature == MagickSignature);
 
3328
 
 
3329
  MvgPrintf(context, "'\n");
 
3330
  context->path_operation = PathDefaultOperation;
 
3331
  context->path_mode = DefaultPathMode;
 
3332
}
 
3333
 
 
3334
/*
 
3335
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3336
%                                                                             %
 
3337
%                                                                             %
 
3338
%                                                                             %
 
3339
%   D r a w P a t h L i n e T o A b s o l u t e                               %
 
3340
%                                                                             %
 
3341
%                                                                             %
 
3342
%                                                                             %
 
3343
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3344
%
 
3345
%  DrawPathLineToAbsolute() draws a line path from the current point to the
 
3346
%  given coordinate using absolute coordinates. The coordinate then becomes
 
3347
%  the new current point.
 
3348
%
 
3349
%  The format of the DrawPathLineToAbsolute method is:
 
3350
%
 
3351
%      void DrawPathLineToAbsolute(DrawContext context,
 
3352
%                                  const double x, const double y)
 
3353
%
 
3354
%  A description of each parameter follows:
 
3355
%
 
3356
%    o context: drawing context
 
3357
%
 
3358
%    o x: target x ordinate
 
3359
%
 
3360
%    o y: target y ordinate
 
3361
%
 
3362
*/
 
3363
static void DrawPathLineTo(DrawContext context,
 
3364
                           const PathMode mode,
 
3365
                           const double x, const double y)
 
3366
{
 
3367
  assert(context != (DrawContext)NULL);
 
3368
  assert(context->signature == MagickSignature);
 
3369
 
 
3370
  if ((context->path_operation != PathLineToOperation)
 
3371
      || (context->path_mode != mode))
 
3372
    {
 
3373
      context->path_operation = PathLineToOperation;
 
3374
      context->path_mode = mode;
 
3375
      MvgAutoWrapPrintf(context, "%c%.4g,%.4g",
 
3376
                        mode == AbsolutePathMode ? 'L' : 'l', x, y);
 
3377
    }
 
3378
  else
 
3379
    MvgAutoWrapPrintf(context, " %.4g,%.4g", x, y);
 
3380
}
 
3381
MagickExport void DrawPathLineToAbsolute(DrawContext context,
 
3382
                                         const double x, const double y)
 
3383
{
 
3384
  assert(context != (DrawContext)NULL);
 
3385
  assert(context->signature == MagickSignature);
 
3386
 
 
3387
  DrawPathLineTo(context, AbsolutePathMode, x, y);
 
3388
}
 
3389
 
 
3390
/*
 
3391
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3392
%                                                                             %
 
3393
%                                                                             %
 
3394
%                                                                             %
 
3395
%   D r a w P a t h L i n e T o R e l a t i v e                               %
 
3396
%                                                                             %
 
3397
%                                                                             %
 
3398
%                                                                             %
 
3399
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3400
%
 
3401
%  DrawPathLineToRelative() draws a line path from the current point to the
 
3402
%  given coordinate using relative coordinates. The coordinate then becomes
 
3403
%  the new current point.
 
3404
%
 
3405
%  The format of the DrawPathLineToRelative method is:
 
3406
%
 
3407
%      void DrawPathLineToRelative(DrawContext context,
 
3408
%                                  const double x, const double y)
 
3409
%
 
3410
%  A description of each parameter follows:
 
3411
%
 
3412
%    o context: drawing context
 
3413
%
 
3414
%    o x: target x ordinate
 
3415
%
 
3416
%    o y: target y ordinate
 
3417
%
 
3418
*/
 
3419
MagickExport void DrawPathLineToRelative(DrawContext context,
 
3420
                                         const double x, const double y)
 
3421
{
 
3422
  assert(context != (DrawContext)NULL);
 
3423
  assert(context->signature == MagickSignature);
 
3424
 
 
3425
  DrawPathLineTo(context, RelativePathMode, x, y);
 
3426
}
 
3427
 
 
3428
/*
 
3429
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3430
%                                                                             %
 
3431
%                                                                             %
 
3432
%                                                                             %
 
3433
%   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           %
 
3434
%                                                                             %
 
3435
%                                                                             %
 
3436
%                                                                             %
 
3437
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3438
%
 
3439
%  DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
 
3440
%  current point to the target point using absolute coordinates.  The target
 
3441
%  point then becomes the new current point.
 
3442
%
 
3443
%  The format of the DrawPathLineToHorizontalAbsolute method is:
 
3444
%
 
3445
%      void DrawPathLineToHorizontalAbsolute(DrawContext context,
 
3446
%                                            const double x)
 
3447
%
 
3448
%  A description of each parameter follows:
 
3449
%
 
3450
%    o context: drawing context
 
3451
%
 
3452
%    o x: target x ordinate
 
3453
%
 
3454
*/
 
3455
 
 
3456
static void DrawPathLineToHorizontal(DrawContext context,
 
3457
                                     const PathMode mode, const double x)
 
3458
{
 
3459
  assert(context != (DrawContext)NULL);
 
3460
  assert(context->signature == MagickSignature);
 
3461
 
 
3462
  if ((context->path_operation != PathLineToHorizontalOperation)
 
3463
      || (context->path_mode != mode))
 
3464
    {
 
3465
      context->path_operation = PathLineToHorizontalOperation;
 
3466
      context->path_mode = mode;
 
3467
      MvgAutoWrapPrintf(context, "%c%.4g",
 
3468
                        mode == AbsolutePathMode ? 'H' : 'h', x);
 
3469
    }
 
3470
  else
 
3471
    MvgAutoWrapPrintf(context, " %.4g", x);
 
3472
}
 
3473
MagickExport void DrawPathLineToHorizontalAbsolute(DrawContext context,
 
3474
                                                   const double x)
 
3475
{
 
3476
  assert(context != (DrawContext)NULL);
 
3477
  assert(context->signature == MagickSignature);
 
3478
 
 
3479
  DrawPathLineToHorizontal(context, AbsolutePathMode, x);
 
3480
}
 
3481
 
 
3482
/*
 
3483
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3484
%                                                                             %
 
3485
%                                                                             %
 
3486
%                                                                             %
 
3487
%   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           %
 
3488
%                                                                             %
 
3489
%                                                                             %
 
3490
%                                                                             %
 
3491
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3492
%
 
3493
%  DrawPathLineToHorizontalRelative() draws a horizontal line path from the
 
3494
%  current point to the target point using relative coordinates.  The target
 
3495
%  point then becomes the new current point.
 
3496
%
 
3497
%  The format of the DrawPathLineToHorizontalRelative method is:
 
3498
%
 
3499
%      void DrawPathLineToHorizontalRelative(DrawContext context, const double x)
 
3500
%
 
3501
%  A description of each parameter follows:
 
3502
%
 
3503
%    o context: drawing context
 
3504
%
 
3505
%    o x: target x ordinate
 
3506
%
 
3507
*/
 
3508
MagickExport void DrawPathLineToHorizontalRelative(DrawContext context,
 
3509
                                                   const double x)
 
3510
{
 
3511
  DrawPathLineToHorizontal(context, RelativePathMode, x);
 
3512
}
 
3513
 
 
3514
/*
 
3515
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3516
%                                                                             %
 
3517
%                                                                             %
 
3518
%                                                                             %
 
3519
%   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               %
 
3520
%                                                                             %
 
3521
%                                                                             %
 
3522
%                                                                             %
 
3523
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3524
%
 
3525
%  DrawPathLineToVerticalAbsolute() draws a vertical line path from the
 
3526
%  current point to the target point using absolute coordinates.  The target
 
3527
%  point then becomes the new current point.
 
3528
%
 
3529
%  The format of the DrawPathLineToVerticalAbsolute method is:
 
3530
%
 
3531
%      void DrawPathLineToVerticalAbsolute(DrawContext context,
 
3532
%                                          const double y)
 
3533
%
 
3534
%  A description of each parameter follows:
 
3535
%
 
3536
%    o context: drawing context
 
3537
%
 
3538
%    o y: target y ordinate
 
3539
%
 
3540
*/
 
3541
static void DrawPathLineToVertical(DrawContext context, const PathMode mode,
 
3542
                                   const double y)
 
3543
{
 
3544
  assert(context != (DrawContext)NULL);
 
3545
  assert(context->signature == MagickSignature);
 
3546
 
 
3547
  if ((context->path_operation != PathLineToVerticalOperation)
 
3548
      || (context->path_mode != mode))
 
3549
    {
 
3550
      context->path_operation = PathLineToVerticalOperation;
 
3551
      context->path_mode = mode;
 
3552
      MvgAutoWrapPrintf(context, "%c%.4g",
 
3553
                        mode == AbsolutePathMode ? 'V' : 'v', y);
 
3554
    }
 
3555
  else
 
3556
    MvgAutoWrapPrintf(context, " %.4g", y);
 
3557
}
 
3558
MagickExport void DrawPathLineToVerticalAbsolute(DrawContext context,
 
3559
                                                 const double y)
 
3560
{
 
3561
  assert(context != (DrawContext)NULL);
 
3562
  assert(context->signature == MagickSignature);
 
3563
 
 
3564
  DrawPathLineToVertical(context, AbsolutePathMode, y);
 
3565
}
 
3566
 
 
3567
/*
 
3568
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3569
%                                                                             %
 
3570
%                                                                             %
 
3571
%                                                                             %
 
3572
%   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               %
 
3573
%                                                                             %
 
3574
%                                                                             %
 
3575
%                                                                             %
 
3576
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3577
%
 
3578
%  DrawPathLineToVerticalRelative() draws a vertical line path from the
 
3579
%  current point to the target point using relative coordinates.  The target
 
3580
%  point then becomes the new current point.
 
3581
%
 
3582
%  The format of the DrawPathLineToVerticalRelative method is:
 
3583
%
 
3584
%      void DrawPathLineToVerticalRelative(DrawContext context,
 
3585
%                                          const double y)
 
3586
%
 
3587
%  A description of each parameter follows:
 
3588
%
 
3589
%    o context: drawing context
 
3590
%
 
3591
%    o y: target y ordinate
 
3592
%
 
3593
*/
 
3594
MagickExport void DrawPathLineToVerticalRelative(DrawContext context,
 
3595
                                                 const double y)
 
3596
{
 
3597
  assert(context != (DrawContext)NULL);
 
3598
  assert(context->signature == MagickSignature);
 
3599
 
 
3600
  DrawPathLineToVertical(context, RelativePathMode, y);
 
3601
}
 
3602
/*
 
3603
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3604
%                                                                             %
 
3605
%                                                                             %
 
3606
%                                                                             %
 
3607
%   D r a w P a t h M o v e T o A b s o l u t e                               %
 
3608
%                                                                             %
 
3609
%                                                                             %
 
3610
%                                                                             %
 
3611
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3612
%
 
3613
%  DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
 
3614
%  using absolute coordinates. The current point then becomes the
 
3615
%  specified coordinate.
 
3616
%
 
3617
%  The format of the DrawPathMoveToAbsolute method is:
 
3618
%
 
3619
%      void DrawPathMoveToAbsolute(DrawContext context, const double x,
 
3620
%                                  const double y)
 
3621
%
 
3622
%  A description of each parameter follows:
 
3623
%
 
3624
%    o context: drawing context
 
3625
%
 
3626
%    o x: target x ordinate
 
3627
%
 
3628
%    o y: target y ordinate
 
3629
%
 
3630
*/
 
3631
 static void DrawPathMoveTo(DrawContext context, const PathMode mode,
 
3632
                           const double x, const double y)
 
3633
{
 
3634
  assert(context != (DrawContext)NULL);
 
3635
  assert(context->signature == MagickSignature);
 
3636
 
 
3637
  if ((context->path_operation != PathMoveToOperation)
 
3638
      || (context->path_mode != mode))
 
3639
    {
 
3640
      context->path_operation = PathMoveToOperation;
 
3641
      context->path_mode = mode;
 
3642
      MvgAutoWrapPrintf(context, "%c%.4g,%.4g",
 
3643
                        mode == AbsolutePathMode ? 'M' : 'm', x, y);
 
3644
    }
 
3645
  else
 
3646
    MvgAutoWrapPrintf(context, " %.4g,%.4g", x, y);
 
3647
}
 
3648
 
 
3649
MagickExport void DrawPathMoveToAbsolute(DrawContext context, const double x,
 
3650
                                         const double y)
 
3651
{
 
3652
  assert(context != (DrawContext)NULL);
 
3653
  assert(context->signature == MagickSignature);
 
3654
 
 
3655
  DrawPathMoveTo(context, AbsolutePathMode, x, y);
 
3656
}
 
3657
 
 
3658
/*
 
3659
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3660
%                                                                             %
 
3661
%                                                                             %
 
3662
%                                                                             %
 
3663
%   D r a w P a t h M o v e T o R e l a t i v e                               %
 
3664
%                                                                             %
 
3665
%                                                                             %
 
3666
%                                                                             %
 
3667
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3668
%
 
3669
%  DrawPathMoveToRelative() starts a new sub-path at the given coordinate
 
3670
%  using relative coordinates. The current point then becomes the
 
3671
%  specified coordinate.
 
3672
%
 
3673
%  The format of the DrawPathMoveToRelative method is:
 
3674
%
 
3675
%      void DrawPathMoveToRelative(DrawContext context,
 
3676
%                                  const double x, const double y)
 
3677
%
 
3678
%  A description of each parameter follows:
 
3679
%
 
3680
%    o context: drawing context
 
3681
%
 
3682
%    o x: target x ordinate
 
3683
%
 
3684
%    o y: target y ordinate
 
3685
%
 
3686
*/
 
3687
MagickExport void DrawPathMoveToRelative(DrawContext context,
 
3688
                                         const double x, const double y)
 
3689
{
 
3690
  assert(context != (DrawContext)NULL);
 
3691
  assert(context->signature == MagickSignature);
 
3692
 
 
3693
  DrawPathMoveTo(context, RelativePathMode, x, y);
 
3694
}
 
3695
 
 
3696
/*
 
3697
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3698
%                                                                             %
 
3699
%                                                                             %
 
3700
%                                                                             %
 
3701
%   D r a w P a t h S t a r t                                                 %
 
3702
%                                                                             %
 
3703
%                                                                             %
 
3704
%                                                                             %
 
3705
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3706
%
 
3707
%  DrawPathStart() declares the start of a path drawing list which is terminated
 
3708
%  by a matching DrawPathFinish() command. All other DrawPath commands must
 
3709
%  be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
 
3710
%  is because path drawing commands are subordinate commands and they do not
 
3711
%  function by themselves.
 
3712
%
 
3713
%  The format of the DrawPathStart method is:
 
3714
%
 
3715
%      void DrawPathStart(DrawContext context)
 
3716
%
 
3717
%  A description of each parameter follows:
 
3718
%
 
3719
%    o context: drawing context
 
3720
%
 
3721
*/
 
3722
MagickExport void DrawPathStart(DrawContext context)
 
3723
{
 
3724
  assert(context != (DrawContext)NULL);
 
3725
  assert(context->signature == MagickSignature);
 
3726
 
 
3727
  MvgPrintf(context, "path '");
 
3728
  context->path_operation = PathDefaultOperation;
 
3729
  context->path_mode = DefaultPathMode;
 
3730
}
 
3731
 
 
3732
/*
 
3733
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3734
%                                                                             %
 
3735
%                                                                             %
 
3736
%                                                                             %
 
3737
%   D r a w P e e k G r a p h i c C o n t e x t                               %
 
3738
%                                                                             %
 
3739
%                                                                             %
 
3740
%                                                                             %
 
3741
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3742
%
 
3743
%  DrawPeekGraphicContext() returns a copy of the the DrawInfo structure at
 
3744
%  the head of the drawing context stack. The user is responsible for
 
3745
%  deallocating the returned object using DestroyDrawInfo.
 
3746
%
 
3747
%  The format of the DrawPeekGraphicContext method is:
 
3748
%
 
3749
%      DrawInfo *DrawPeekGraphicContext(const DrawContext context)
 
3750
%
 
3751
%  A description of each parameter follows:
 
3752
%
 
3753
%    o context: drawing context
 
3754
%
 
3755
*/
 
3756
MagickExport DrawInfo *DrawPeekGraphicContext(const DrawContext context)
 
3757
{
 
3758
  DrawInfo
 
3759
    *draw_info;
 
3760
 
 
3761
  assert(context != (DrawContext)NULL);
 
3762
  assert(context->signature == MagickSignature);
 
3763
  draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
 
3764
  CloneString(&draw_info->primitive,context->mvg);
 
3765
  CurrentContext->primitive=context->mvg;
 
3766
  return(draw_info);
 
3767
}
 
3768
 
 
3769
/*
 
3770
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3771
%                                                                             %
 
3772
%                                                                             %
 
3773
%                                                                             %
 
3774
%   D r a w P o i n t                                                         %
 
3775
%                                                                             %
 
3776
%                                                                             %
 
3777
%                                                                             %
 
3778
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3779
%
 
3780
%  DrawPoint() draws a point using the current stroke color and stroke
 
3781
%  thickness at the specified coordinates.
 
3782
%
 
3783
%  The format of the DrawPoint method is:
 
3784
%
 
3785
%      void DrawPoint(DrawContext context, const double x, const double y)
 
3786
%
 
3787
%  A description of each parameter follows:
 
3788
%
 
3789
%    o context: drawing context
 
3790
%
 
3791
%    o x: target x coordinate
 
3792
%
 
3793
%    o y: target y coordinate
 
3794
%
 
3795
*/
 
3796
MagickExport void DrawPoint(DrawContext context,
 
3797
                            const double x, const double y)
 
3798
{
 
3799
  assert(context != (DrawContext)NULL);
 
3800
  assert(context->signature == MagickSignature);
 
3801
 
 
3802
  MvgPrintf(context, "point %.4g,%.4g\n", x, y);
 
3803
}
 
3804
 
 
3805
/*
 
3806
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3807
%                                                                             %
 
3808
%                                                                             %
 
3809
%                                                                             %
 
3810
%   D r a w P o l y g o n                                                     %
 
3811
%                                                                             %
 
3812
%                                                                             %
 
3813
%                                                                             %
 
3814
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3815
%
 
3816
%  DrawPolygon() draws a polygon using the current stroke, stroke width, and
 
3817
%  fill color or texture, using the specified array of coordinates.
 
3818
%
 
3819
%  The format of the DrawPolygon method is:
 
3820
%
 
3821
%      void DrawPolygon(DrawContext context,
 
3822
%                       const unsigned long num_coords,
 
3823
%                       const PointInfo * coordinates)
 
3824
%
 
3825
%  A description of each parameter follows:
 
3826
%
 
3827
%    o context: drawing context
 
3828
%
 
3829
%    o num_coords: number of coordinates
 
3830
%
 
3831
%    o coordinates: coordinate array
 
3832
%
 
3833
*/
 
3834
MagickExport void DrawPolygon(DrawContext context,
 
3835
                              const unsigned long num_coords,
 
3836
                              const PointInfo * coordinates)
 
3837
{
 
3838
  assert(context != (DrawContext)NULL);
 
3839
  assert(context->signature == MagickSignature);
 
3840
 
 
3841
  MvgAppendPointsCommand(context,"polygon",num_coords,coordinates);
 
3842
}
 
3843
 
 
3844
/*
 
3845
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3846
%                                                                             %
 
3847
%                                                                             %
 
3848
%                                                                             %
 
3849
%   D r a w P o l y l i n e                                                   %
 
3850
%                                                                             %
 
3851
%                                                                             %
 
3852
%                                                                             %
 
3853
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3854
%
 
3855
%  DrawPolyline() draws a polyline using the current stroke, stroke width, and
 
3856
%  fill color or texture, using the specified array of coordinates.
 
3857
%
 
3858
%  The format of the DrawPolyline method is:
 
3859
%
 
3860
%      void DrawPolyline(DrawContext context,
 
3861
%                        const unsigned long num_coords,
 
3862
%                        const PointInfo * coordinates)
 
3863
%
 
3864
%  A description of each parameter follows:
 
3865
%
 
3866
%    o context: drawing context
 
3867
%
 
3868
%    o num_coords: number of coordinates
 
3869
%
 
3870
%    o coordinates: coordinate array
 
3871
%
 
3872
*/
 
3873
MagickExport void DrawPolyline(DrawContext context,
 
3874
                               const unsigned long num_coords,
 
3875
                               const PointInfo * coordinates)
 
3876
{
 
3877
  assert(context != (DrawContext)NULL);
 
3878
  assert(context->signature == MagickSignature);
 
3879
 
 
3880
  MvgAppendPointsCommand(context,"polyline",num_coords,coordinates);
 
3881
}
 
3882
 
 
3883
/*
 
3884
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3885
%                                                                             %
 
3886
%                                                                             %
 
3887
%                                                                             %
 
3888
%   D r a w P o p C l i p P a t h                                             %
 
3889
%                                                                             %
 
3890
%                                                                             %
 
3891
%                                                                             %
 
3892
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3893
%
 
3894
%  DrawPopClipPath() terminates a clip path definition.
 
3895
%
 
3896
%  The format of the DrawPopClipPath method is:
 
3897
%
 
3898
%      void DrawPopClipPath(DrawContext context)
 
3899
%
 
3900
%  A description of each parameter follows:
 
3901
%
 
3902
%    o context: drawing context
 
3903
%
 
3904
*/
 
3905
MagickExport void DrawPopClipPath(DrawContext context)
 
3906
{
 
3907
  assert(context != (DrawContext)NULL);
 
3908
  assert(context->signature == MagickSignature);
 
3909
 
 
3910
  if(context->indent_depth > 0)
 
3911
    context->indent_depth--;
 
3912
  MvgPrintf(context, "pop clip-path\n");
 
3913
}
 
3914
 
 
3915
/*
 
3916
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3917
%                                                                             %
 
3918
%                                                                             %
 
3919
%                                                                             %
 
3920
%   D r a w P o p D e f s                                                     %
 
3921
%                                                                             %
 
3922
%                                                                             %
 
3923
%                                                                             %
 
3924
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3925
%
 
3926
%  DrawPopDefs() terminates a definition list
 
3927
%
 
3928
%  The format of the DrawPopDefs method is:
 
3929
%
 
3930
%      void DrawPopDefs(DrawContext context)
 
3931
%
 
3932
%  A description of each parameter follows:
 
3933
%
 
3934
%    o context: drawing context
 
3935
%
 
3936
*/
 
3937
MagickExport void DrawPopDefs(DrawContext context)
 
3938
{
 
3939
  assert(context != (DrawContext)NULL);
 
3940
  assert(context->signature == MagickSignature);
 
3941
 
 
3942
  if(context->indent_depth > 0)
 
3943
    context->indent_depth--;
 
3944
  MvgPrintf(context, "pop defs\n");
 
3945
}
 
3946
 
 
3947
/*
 
3948
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3949
%                                                                             %
 
3950
%                                                                             %
 
3951
%                                                                             %
 
3952
%   D r a w P o p G r a p h i c C o n t e x t                                 %
 
3953
%                                                                             %
 
3954
%                                                                             %
 
3955
%                                                                             %
 
3956
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
3957
%
 
3958
%  DrawPopGraphicContext() destroys the current context returning to the
 
3959
%  previously pushed context. Multiple contexts may exist. It is an error
 
3960
%  to attempt to pop more contexts than have been pushed, and it is proper
 
3961
%  form to pop all contexts which have been pushed.
 
3962
%
 
3963
%  The format of the DrawPopGraphicContext method is:
 
3964
%
 
3965
%      void DrawPopGraphicContext(DrawContext context)
 
3966
%
 
3967
%  A description of each parameter follows:
 
3968
%
 
3969
%    o context: drawing context
 
3970
%
 
3971
*/
 
3972
MagickExport void DrawPopGraphicContext(DrawContext context)
 
3973
{
 
3974
  assert(context != (DrawContext)NULL);
 
3975
  assert(context->signature == MagickSignature);
 
3976
 
 
3977
  if(context->index > 0)
 
3978
    {
 
3979
      /* Destroy clip path if not same in preceding context */
 
3980
#if DRAW_BINARY_IMPLEMENTATION
 
3981
      if (CurrentContext->clip_path != (char *) NULL)
 
3982
        if (LocaleCompare(CurrentContext->clip_path,
 
3983
                          context->graphic_context[context->index-1]->clip_path) != 0)
 
3984
          (void) SetImageClipMask(context->image,(Image *) NULL);
 
3985
#endif
 
3986
 
 
3987
      DestroyDrawInfo(CurrentContext);
 
3988
      CurrentContext=(DrawInfo*)NULL;
 
3989
      context->index--;
 
3990
 
 
3991
      if(context->indent_depth > 0)
 
3992
        context->indent_depth--;
 
3993
      MvgPrintf(context, "pop graphic-context\n");
 
3994
    }
 
3995
  else
 
3996
    {
 
3997
      ThrowDrawException(DrawError,UnbalancedGraphicContextPushPop,NULL)
 
3998
    }
 
3999
}
 
4000
 
 
4001
/*
 
4002
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4003
%                                                                             %
 
4004
%                                                                             %
 
4005
%                                                                             %
 
4006
%   D r a w P o p P a t t e r n                                               %
 
4007
%                                                                             %
 
4008
%                                                                             %
 
4009
%                                                                             %
 
4010
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4011
%
 
4012
%  DrawPopPattern() terminates a pattern definition.
 
4013
%
 
4014
%  The format of the DrawPopPattern method is:
 
4015
%
 
4016
%      void DrawPopPattern(DrawContext context)
 
4017
%
 
4018
%  A description of each parameter follows:
 
4019
%
 
4020
%    o context: drawing context
 
4021
%
 
4022
*/
 
4023
MagickExport void DrawPopPattern(DrawContext context)
 
4024
{
 
4025
  char
 
4026
    geometry[MaxTextExtent],
 
4027
    key[MaxTextExtent];
 
4028
 
 
4029
  assert(context != (DrawContext)NULL);
 
4030
  assert(context->signature == MagickSignature);
 
4031
 
 
4032
  if( context->pattern_id == NULL )
 
4033
    ThrowDrawException(DrawWarning,NotCurrentlyPushingPatternDefinition,NULL);
 
4034
 
 
4035
  FormatString(key,"[%.1024s]",context->pattern_id);
 
4036
 
 
4037
  (void) SetImageAttribute(context->image,key,context->mvg+context->pattern_offset);
 
4038
  FormatString(geometry,"%lux%lu%+ld%+ld",
 
4039
               context->pattern_bounds.width,context->pattern_bounds.height,
 
4040
               context->pattern_bounds.x,context->pattern_bounds.y);
 
4041
  (void) SetImageAttribute(context->image,key,geometry);
 
4042
 
 
4043
  MagickFreeMemory(context->pattern_id);
 
4044
  context->pattern_offset = 0;
 
4045
 
 
4046
  context->pattern_bounds.x = 0;
 
4047
  context->pattern_bounds.y = 0;
 
4048
  context->pattern_bounds.width = 0;
 
4049
  context->pattern_bounds.height = 0;
 
4050
 
 
4051
  context->filter_off = False;
 
4052
 
 
4053
  if(context->indent_depth > 0)
 
4054
    context->indent_depth--;
 
4055
  MvgPrintf(context, "pop pattern\n");
 
4056
}
 
4057
 
 
4058
/*
 
4059
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4060
%                                                                             %
 
4061
%                                                                             %
 
4062
%                                                                             %
 
4063
%   D r a w P u s h C l i p P a t h                                           %
 
4064
%                                                                             %
 
4065
%                                                                             %
 
4066
%                                                                             %
 
4067
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4068
%
 
4069
%  DrawPushClipPath() starts a clip path definition which is comprized of
 
4070
%  any number of drawing commands and terminated by a DrawPopClipPath()
 
4071
%  command.
 
4072
%
 
4073
%  The format of the DrawPushClipPath method is:
 
4074
%
 
4075
%      void DrawPushClipPath(DrawContext context, const char *clip_path_id)
 
4076
%
 
4077
%  A description of each parameter follows:
 
4078
%
 
4079
%    o context: drawing context
 
4080
%
 
4081
%    o clip_path_id: string identifier to associate with the clip path for
 
4082
%      later use.
 
4083
%
 
4084
*/
 
4085
MagickExport void DrawPushClipPath(DrawContext context,
 
4086
                                   const char *clip_path_id)
 
4087
{
 
4088
  assert(context != (DrawContext)NULL);
 
4089
  assert(context->signature == MagickSignature);
 
4090
  assert(clip_path_id != (const char *) NULL);
 
4091
 
 
4092
  MvgPrintf(context, "push clip-path %s\n", clip_path_id);
 
4093
  context->indent_depth++;
 
4094
}
 
4095
 
 
4096
/*
 
4097
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4098
%                                                                             %
 
4099
%                                                                             %
 
4100
%                                                                             %
 
4101
%   D r a w P u s h D e f s                                                   %
 
4102
%                                                                             %
 
4103
%                                                                             %
 
4104
%                                                                             %
 
4105
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4106
%
 
4107
%  DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
 
4108
%  command create named elements (e.g. clip-paths, textures, etc.) which
 
4109
%  may safely be processed earlier for the sake of efficiency.
 
4110
%
 
4111
%  The format of the DrawPushDefs method is:
 
4112
%
 
4113
%      void DrawPushDefs(DrawContext context)
 
4114
%
 
4115
%  A description of each parameter follows:
 
4116
%
 
4117
%    o context: drawing context
 
4118
%
 
4119
*/
 
4120
MagickExport void DrawPushDefs(DrawContext context)
 
4121
{
 
4122
  assert(context != (DrawContext)NULL);
 
4123
  assert(context->signature == MagickSignature);
 
4124
 
 
4125
  MvgPrintf(context, "push defs\n");
 
4126
  context->indent_depth++;
 
4127
}
 
4128
 
 
4129
/*
 
4130
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4131
%                                                                             %
 
4132
%                                                                             %
 
4133
%                                                                             %
 
4134
%   D r a w P u s h G r a p h i c C o n t e x t                               %
 
4135
%                                                                             %
 
4136
%                                                                             %
 
4137
%                                                                             %
 
4138
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4139
%
 
4140
%  DrawPushGraphicContext() clones the current drawing context to create a
 
4141
%  new drawing context. The original drawing context(s) may be returned to
 
4142
%  by invoking DrawPopGraphicContext().  The contexts are stored on a context
 
4143
%  stack.  For every Pop there must have already been an equivalent Push.
 
4144
%
 
4145
%  The format of the DrawPushGraphicContext method is:
 
4146
%
 
4147
%      void DrawPushGraphicContext(DrawContext context)
 
4148
%
 
4149
%  A description of each parameter follows:
 
4150
%
 
4151
%    o context: drawing context
 
4152
%
 
4153
*/
 
4154
MagickExport void DrawPushGraphicContext(DrawContext context)
 
4155
{
 
4156
  assert(context != (DrawContext)NULL);
 
4157
  assert(context->signature == MagickSignature);
 
4158
 
 
4159
  context->index++;
 
4160
  MagickReallocMemory(context->graphic_context,
 
4161
                  (context->index+1)*sizeof(DrawInfo *));
 
4162
  if (context->graphic_context == (DrawInfo **) NULL)
 
4163
    {
 
4164
      ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
 
4165
        UnableToDrawOnImage)
 
4166
    }
 
4167
  CurrentContext=
 
4168
    CloneDrawInfo((ImageInfo *) NULL,context->graphic_context[context->index-1]);
 
4169
  MvgPrintf(context, "push graphic-context\n");
 
4170
  context->indent_depth++;
 
4171
}
 
4172
 
 
4173
/*
 
4174
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4175
%                                                                             %
 
4176
%                                                                             %
 
4177
%                                                                             %
 
4178
%   D r a w P u s h P a t t e r n                                             %
 
4179
%                                                                             %
 
4180
%                                                                             %
 
4181
%                                                                             %
 
4182
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4183
%
 
4184
%  DrawPushPattern() indicates that subsequent commands up to a
 
4185
%  DrawPopPattern() command comprise the definition of a named pattern.
 
4186
%  The pattern space is assigned top left corner coordinates, a width
 
4187
%  and height, and becomes its own drawing space.  Anything which can
 
4188
%  be drawn may be used in a pattern definition.
 
4189
%  Named patterns may be used as stroke or brush definitions.
 
4190
%
 
4191
%  The format of the DrawPushPattern method is:
 
4192
%
 
4193
%      void DrawPushPattern(DrawContext context,
 
4194
%                           const char *pattern_id,
 
4195
%                           const double x, const double y,
 
4196
%                           const double width, const double height)
 
4197
%
 
4198
%  A description of each parameter follows:
 
4199
%
 
4200
%    o context: drawing context
 
4201
%
 
4202
%    o pattern_id: pattern identification for later reference
 
4203
%
 
4204
%    o x: x ordinate of top left corner
 
4205
%
 
4206
%    o y: y ordinate of top left corner
 
4207
%
 
4208
%    o width: width of pattern space
 
4209
%
 
4210
%    o height: height of pattern space
 
4211
%
 
4212
*/
 
4213
MagickExport void DrawPushPattern(DrawContext context,
 
4214
                                  const char *pattern_id,
 
4215
                                  const double x, const double y,
 
4216
                                  const double width, const double height)
 
4217
{
 
4218
  assert(context != (DrawContext)NULL);
 
4219
  assert(context->signature == MagickSignature);
 
4220
  assert(pattern_id != (const char *) NULL);
 
4221
 
 
4222
  if( context->pattern_id != NULL )
 
4223
    ThrowDrawException(DrawError,AlreadyPushingPatternDefinition,
 
4224
      context->pattern_id);
 
4225
 
 
4226
  context->filter_off = True;
 
4227
 
 
4228
  MvgPrintf(context, "push pattern %s %.4g,%.4g %.4g,%.4g\n",
 
4229
            pattern_id, x, y, width, height);
 
4230
  context->indent_depth++;
 
4231
 
 
4232
  /* Record current pattern ID, bounds, and start position in MVG */
 
4233
  context->pattern_id = AllocateString(pattern_id);
 
4234
  context->pattern_bounds.x = (long) ceil(x-0.5);
 
4235
  context->pattern_bounds.y = (long) ceil(y-0.5);
 
4236
  context->pattern_bounds.width = (unsigned long) floor(width+0.5);
 
4237
  context->pattern_bounds.height = (unsigned long) floor(height+0.5);
 
4238
  context->pattern_offset = context->mvg_length;
 
4239
}
 
4240
 
 
4241
/*
 
4242
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4243
%                                                                             %
 
4244
%                                                                             %
 
4245
%                                                                             %
 
4246
%   D r a w R e c t a n g l e                                                 %
 
4247
%                                                                             %
 
4248
%                                                                             %
 
4249
%                                                                             %
 
4250
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4251
%
 
4252
%  DrawRectangle() draws a rectangle given two coordinates and using
 
4253
%  the current stroke, stroke width, and fill settings.
 
4254
%
 
4255
%  The format of the DrawRectangle method is:
 
4256
%
 
4257
%      void DrawRectangle(DrawContext context,
 
4258
%                         const double x1, const double y1,
 
4259
%                         const double x2, const double y2)
 
4260
%
 
4261
%  A description of each parameter follows:
 
4262
%
 
4263
%    o x1: x ordinate of first coordinate
 
4264
%
 
4265
%    o y1: y ordinate of first coordinate
 
4266
%
 
4267
%    o x2: x ordinate of second coordinate
 
4268
%
 
4269
%    o y2: y ordinate of second coordinate
 
4270
%
 
4271
*/
 
4272
MagickExport void DrawRectangle(DrawContext context,
 
4273
                                const double x1, const double y1,
 
4274
                                const double x2, const double y2)
 
4275
{
 
4276
  assert(context != (DrawContext)NULL);
 
4277
  assert(context->signature == MagickSignature);
 
4278
  MvgPrintf(context, "rectangle %.4g,%.4g %.4g,%.4g\n", x1, y1, x2, y2);
 
4279
}
 
4280
 
 
4281
/*
 
4282
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4283
%                                                                             %
 
4284
%                                                                             %
 
4285
%                                                                             %
 
4286
%   D r a w R e n d e r                                                       %
 
4287
%                                                                             %
 
4288
%                                                                             %
 
4289
%                                                                             %
 
4290
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4291
%
 
4292
%  DrawRender() renders all preceding drawing commands onto the image.
 
4293
%
 
4294
%  The format of the DrawRender method is:
 
4295
%
 
4296
%      int DrawRender(const DrawContext context)
 
4297
%
 
4298
%  A description of each parameter follows:
 
4299
%
 
4300
%    o context: drawing context
 
4301
%
 
4302
*/
 
4303
MagickExport int DrawRender(const DrawContext context)
 
4304
{
 
4305
  assert(context != (DrawContext)NULL);
 
4306
  assert(context->signature == MagickSignature);
 
4307
 
 
4308
  CurrentContext->primitive = context->mvg;
 
4309
  (void) LogMagickEvent(RenderEvent,GetMagickModule(),"MVG:\n'%s'\n",context->mvg);
 
4310
  DrawImage(context->image, CurrentContext);
 
4311
  CurrentContext->primitive = (char *) NULL;
 
4312
 
 
4313
  return True;
 
4314
}
 
4315
 
 
4316
/*
 
4317
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4318
%                                                                             %
 
4319
%                                                                             %
 
4320
%                                                                             %
 
4321
%   D r a w R o t a t e                                                       %
 
4322
%                                                                             %
 
4323
%                                                                             %
 
4324
%                                                                             %
 
4325
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4326
%
 
4327
%  DrawRotate() applies the specified rotation to the current coordinate
 
4328
%  space.
 
4329
%
 
4330
%  The format of the DrawRotate method is:
 
4331
%
 
4332
%      void DrawRotate(DrawContext context, const double degrees)
 
4333
%
 
4334
%  A description of each parameter follows:
 
4335
%
 
4336
%    o context: drawing context
 
4337
%
 
4338
%    o degrees: degrees of rotation
 
4339
%
 
4340
*/
 
4341
MagickExport void DrawRotate(DrawContext context, const double degrees)
 
4342
{
 
4343
  AffineMatrix
 
4344
    affine;
 
4345
 
 
4346
  assert(context != (DrawContext)NULL);
 
4347
  assert(context->signature == MagickSignature);
 
4348
 
 
4349
  IdentityAffine(&affine);
 
4350
  affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
 
4351
  affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
 
4352
  affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
 
4353
  affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
 
4354
  AdjustAffine( context, &affine );
 
4355
 
 
4356
  MvgPrintf(context, "rotate %.4g\n", degrees);
 
4357
}
 
4358
 
 
4359
/*
 
4360
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4361
%                                                                             %
 
4362
%                                                                             %
 
4363
%                                                                             %
 
4364
%   D r a w R o u n d R e c t a n g l e                                       %
 
4365
%                                                                             %
 
4366
%                                                                             %
 
4367
%                                                                             %
 
4368
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4369
%
 
4370
%  DrawRoundRectangle() draws a rounted rectangle given two coordinates,
 
4371
%  x & y corner radiuses and using the current stroke, stroke width,
 
4372
%  and fill settings.
 
4373
%
 
4374
%  The format of the DrawRoundRectangle method is:
 
4375
%
 
4376
%      void DrawRoundRectangle(DrawContext context,
 
4377
%                              double x1, double y1,
 
4378
%                              double x2, double y2,
 
4379
%                              double rx, double ry)
 
4380
%
 
4381
%  A description of each parameter follows:
 
4382
%
 
4383
%    o context: drawing context
 
4384
%
 
4385
%    o x1: x ordinate of first coordinate
 
4386
%
 
4387
%    o y1: y ordinate of first coordinate
 
4388
%
 
4389
%    o x2: x ordinate of second coordinate
 
4390
%
 
4391
%    o y2: y ordinate of second coordinate
 
4392
%
 
4393
%    o rx: radius of corner in horizontal direction
 
4394
%
 
4395
%    o ry: radius of corner in vertical direction
 
4396
%
 
4397
*/
 
4398
MagickExport void DrawRoundRectangle(DrawContext context,
 
4399
                                     double x1, double y1,
 
4400
                                     double x2, double y2,
 
4401
                                     double rx, double ry)
 
4402
{
 
4403
  assert(context != (DrawContext)NULL);
 
4404
  assert(context->signature == MagickSignature);
 
4405
 
 
4406
  MvgPrintf(context, "roundrectangle %.4g,%.4g %.4g,%.4g %.4g,%.4g\n",
 
4407
            x1, y1, x2, y2, rx, ry);
 
4408
}
 
4409
 
 
4410
/*
 
4411
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4412
%                                                                             %
 
4413
%                                                                             %
 
4414
%                                                                             %
 
4415
%   D r a w S c a l e                                                         %
 
4416
%                                                                             %
 
4417
%                                                                             %
 
4418
%                                                                             %
 
4419
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4420
%
 
4421
%  DrawScale() adjusts the scaling factor to apply in the horizontal and
 
4422
%  vertical directions to the current coordinate space.
 
4423
%
 
4424
%  The format of the DrawScale method is:
 
4425
%
 
4426
%      void DrawScale(DrawContext context, const double x, const double y)
 
4427
%
 
4428
%  A description of each parameter follows:
 
4429
%
 
4430
%    o context: drawing context
 
4431
%
 
4432
%    o x: horizontal scale factor
 
4433
%
 
4434
%    o y: vertical scale factor
 
4435
%
 
4436
*/
 
4437
MagickExport void DrawScale(DrawContext context,
 
4438
                               const double x, const double y)
 
4439
{
 
4440
  AffineMatrix
 
4441
    affine;
 
4442
 
 
4443
  assert(context != (DrawContext)NULL);
 
4444
  assert(context->signature == MagickSignature);
 
4445
 
 
4446
  IdentityAffine(&affine);
 
4447
  affine.sx=x;
 
4448
  affine.sy=y;
 
4449
  AdjustAffine( context, &affine );
 
4450
 
 
4451
  MvgPrintf(context, "scale %.4g,%.4g\n", x, y);
 
4452
}
 
4453
 
 
4454
/*
 
4455
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4456
%                                                                             %
 
4457
%                                                                             %
 
4458
%                                                                             %
 
4459
%   D r a w S k e w X                                                         %
 
4460
%                                                                             %
 
4461
%                                                                             %
 
4462
%                                                                             %
 
4463
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4464
%
 
4465
%  DrawSkewX() skews the current coordinate system in the horizontal
 
4466
%  direction.
 
4467
%
 
4468
%  The format of the DrawSkewX method is:
 
4469
%
 
4470
%      void DrawSkewX(DrawContext context, const double degrees)
 
4471
%
 
4472
%  A description of each parameter follows:
 
4473
%
 
4474
%    o context: drawing context
 
4475
%
 
4476
%    o degrees: number of degrees to skew the coordinates
 
4477
%
 
4478
*/
 
4479
MagickExport void DrawSkewX(DrawContext context, const double degrees)
 
4480
{
 
4481
  AffineMatrix
 
4482
    affine;
 
4483
 
 
4484
  assert(context != (DrawContext)NULL);
 
4485
  assert(context->signature == MagickSignature);
 
4486
 
 
4487
  IdentityAffine(&affine);
 
4488
  affine.ry=tan(DegreesToRadians(fmod(degrees,360.0)));
 
4489
  AdjustAffine(context,&affine);
 
4490
 
 
4491
  MvgPrintf(context, "skewX %.4g\n", degrees);
 
4492
}
 
4493
 
 
4494
/*
 
4495
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4496
%                                                                             %
 
4497
%                                                                             %
 
4498
%                                                                             %
 
4499
%   D r a w S k e w Y                                                         %
 
4500
%                                                                             %
 
4501
%                                                                             %
 
4502
%                                                                             %
 
4503
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4504
%
 
4505
%  DrawSkewY() skews the current coordinate system in the vertical
 
4506
%  direction.
 
4507
%
 
4508
%  The format of the DrawSkewY method is:
 
4509
%
 
4510
%      void DrawSkewY(DrawContext context, const double degrees)
 
4511
%
 
4512
%  A description of each parameter follows:
 
4513
%
 
4514
%    o context: drawing context
 
4515
%
 
4516
%    o degrees: number of degrees to skew the coordinates
 
4517
%
 
4518
*/
 
4519
MagickExport void DrawSkewY(DrawContext context, const double degrees)
 
4520
{
 
4521
  AffineMatrix
 
4522
    affine;
 
4523
 
 
4524
  assert(context != (DrawContext)NULL);
 
4525
  assert(context->signature == MagickSignature);
 
4526
 
 
4527
  IdentityAffine(&affine);
 
4528
  affine.rx=tan(DegreesToRadians(fmod(degrees,360.0)));
 
4529
  DrawAffine(context,&affine);
 
4530
 
 
4531
  MvgPrintf(context, "skewY %.4g\n", degrees);
 
4532
}
 
4533
 
 
4534
#if 0
 
4535
 
 
4536
/*
 
4537
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4538
%                                                                             %
 
4539
%                                                                             %
 
4540
%                                                                             %
 
4541
%   D r a w S e t S t o p C o l o r                                           %
 
4542
%                                                                             %
 
4543
%                                                                             %
 
4544
%                                                                             %
 
4545
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4546
%
 
4547
%  DrawSetStopColor() sets the stop color and offset for gradients
 
4548
%
 
4549
%  The format of the DrawSetStopColor method is:
 
4550
%
 
4551
%      void DrawSetStopColor(DrawContext context,
 
4552
%                            const PixelPacket * stop_color,
 
4553
%                            const double offset)
 
4554
%
 
4555
%  A description of each parameter follows:
 
4556
%
 
4557
%    o context: drawing context
 
4558
%
 
4559
%    o stop_color:
 
4560
%
 
4561
%    o offset:
 
4562
%
 
4563
*/
 
4564
/* This is gradient stuff so it shouldn't be supported yet */
 
4565
MagickExport void DrawSetStopColor(DrawContext context,
 
4566
                                   const PixelPacket * stop_color,
 
4567
                                   const double offset)
 
4568
{
 
4569
  assert(context != (DrawContext)NULL);
 
4570
  assert(context->signature == MagickSignature);
 
4571
  assert(stop_color != (const PixelPacket *) NULL);
 
4572
 
 
4573
 
 
4574
  MvgPrintf(context, "stop-color ");
 
4575
  MvgAppendColor(context, stop_color);
 
4576
  MvgPrintf(context, "\n");
 
4577
}
 
4578
#endif
 
4579
 
 
4580
/*
 
4581
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4582
%                                                                             %
 
4583
%                                                                             %
 
4584
%                                                                             %
 
4585
%   D r a w G e t S t r o k e C o l o r                                       %
 
4586
%                                                                             %
 
4587
%                                                                             %
 
4588
%                                                                             %
 
4589
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4590
%
 
4591
%  DrawGetStrokeColor() returns the color used for stroking object outlines.
 
4592
%
 
4593
%  The format of the DrawGetStrokeColor method is:
 
4594
%
 
4595
%      PixelPacket DrawGetStrokeColor(DrawContext context)
 
4596
%
 
4597
%  A description of each parameter follows:
 
4598
%
 
4599
%    o context: drawing context
 
4600
%
 
4601
*/
 
4602
MagickExport PixelPacket DrawGetStrokeColor(DrawContext context)
 
4603
{
 
4604
  assert(context != (DrawContext)NULL);
 
4605
  assert(context->signature == MagickSignature);
 
4606
 
 
4607
  return CurrentContext->stroke;
 
4608
}
 
4609
 
 
4610
/*
 
4611
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4612
%                                                                             %
 
4613
%                                                                             %
 
4614
%                                                                             %
 
4615
%   D r a w S e t S t r o k e C o l o r                                       %
 
4616
%                                                                             %
 
4617
%                                                                             %
 
4618
%                                                                             %
 
4619
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4620
%
 
4621
%  DrawSetStrokeColor() sets the color used for stroking object outlines.
 
4622
%
 
4623
%  The format of the DrawSetStrokeColor method is:
 
4624
%
 
4625
%      void DrawSetStrokeColor(DrawContext context,
 
4626
%                              const PixelPacket * stroke_color)
 
4627
%
 
4628
%  A description of each parameter follows:
 
4629
%
 
4630
%    o context: drawing context
 
4631
%
 
4632
%    o stroke_color: stroke color
 
4633
%
 
4634
*/
 
4635
MagickExport void DrawSetStrokeColor(DrawContext context,
 
4636
                                     const PixelPacket * stroke_color)
 
4637
{
 
4638
  PixelPacket
 
4639
    *current_stroke,
 
4640
    new_stroke;
 
4641
 
 
4642
  assert(context != (DrawContext)NULL);
 
4643
  assert(context->signature == MagickSignature);
 
4644
  assert(stroke_color != (const PixelPacket *) NULL);
 
4645
 
 
4646
  new_stroke = *stroke_color;
 
4647
 
 
4648
  /* Inherit base opacity */
 
4649
  if(new_stroke.opacity == OpaqueOpacity)
 
4650
    new_stroke.opacity = CurrentContext->opacity;
 
4651
 
 
4652
  current_stroke = &CurrentContext->stroke;
 
4653
  if( context->filter_off || !(PixelPacketMatch(current_stroke,&new_stroke)) )
 
4654
    {
 
4655
      CurrentContext->stroke = new_stroke;
 
4656
 
 
4657
      MvgPrintf(context, "stroke '");
 
4658
      MvgAppendColor(context, stroke_color);
 
4659
      MvgPrintf(context, "'\n");
 
4660
    }
 
4661
}
 
4662
 
 
4663
/*
 
4664
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4665
%                                                                             %
 
4666
%                                                                             %
 
4667
%                                                                             %
 
4668
%   D r a w S e t S t r o k e C o l o r S t r i n g                           %
 
4669
%                                                                             %
 
4670
%                                                                             %
 
4671
%                                                                             %
 
4672
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4673
%
 
4674
%  DrawSetStrokeColorString() sets the color used for stroking object outlines.
 
4675
%
 
4676
%  The format of the DrawSetStrokeColorString method is:
 
4677
%
 
4678
%      void DrawSetStrokeColorString(DrawContext context,
 
4679
%                                    const char* stroke_color)
 
4680
%
 
4681
%  A description of each parameter follows:
 
4682
%
 
4683
%    o context: drawing context
 
4684
%
 
4685
%    o stroke_color: stroke color
 
4686
%
 
4687
*/
 
4688
MagickExport void DrawSetStrokeColorString(DrawContext context,
 
4689
                                           const char* stroke_color)
 
4690
{
 
4691
  PixelPacket
 
4692
    pixel_packet;
 
4693
 
 
4694
  if(QueryColorDatabase(stroke_color,&pixel_packet,&context->image->exception))
 
4695
    DrawSetStrokeColor(context,&pixel_packet);
 
4696
}
 
4697
 
 
4698
/*
 
4699
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4700
%                                                                             %
 
4701
%                                                                             %
 
4702
%                                                                             %
 
4703
%   D r a w S e t S t r o k e P a t t e r n U R L                             %
 
4704
%                                                                             %
 
4705
%                                                                             %
 
4706
%                                                                             %
 
4707
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4708
%
 
4709
%  DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
 
4710
%
 
4711
%  The format of the DrawSetStrokePatternURL method is:
 
4712
%
 
4713
%      void DrawSetStrokePatternURL(DrawContext context, const char* stroke_url)
 
4714
%
 
4715
%  A description of each parameter follows:
 
4716
%
 
4717
%    o context: drawing context
 
4718
%
 
4719
%    o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
 
4720
%
 
4721
*/
 
4722
MagickExport void DrawSetStrokePatternURL(DrawContext context,
 
4723
                                          const char* stroke_url)
 
4724
{
 
4725
  char
 
4726
    pattern[MaxTextExtent];
 
4727
 
 
4728
  assert(context != (DrawContext)NULL);
 
4729
  assert(context->signature == MagickSignature);
 
4730
  assert(stroke_url != NULL);
 
4731
 
 
4732
  if(stroke_url[0] != '#')
 
4733
    ThrowDrawException(DrawWarning, NotARelativeURL, stroke_url);
 
4734
 
 
4735
  FormatString(pattern,"[%.1024s]",stroke_url+1);
 
4736
 
 
4737
  if (GetImageAttribute(context->image,pattern) == (ImageAttribute *) NULL)
 
4738
    {
 
4739
      ThrowDrawException(DrawWarning, URLNotFound, stroke_url)
 
4740
    }
 
4741
  else
 
4742
    {
 
4743
      char
 
4744
        pattern_spec[MaxTextExtent];
 
4745
 
 
4746
      FormatString(pattern_spec,"url(%.1024s)",stroke_url);
 
4747
#if DRAW_BINARY_IMPLEMENTATION
 
4748
      DrawPatternPath(context->image,CurrentContext,pattern_spec,&CurrentContext->stroke_pattern);
 
4749
#endif
 
4750
      /* Inherit base opacity */
 
4751
      if (CurrentContext->stroke.opacity == OpaqueOpacity)
 
4752
        CurrentContext->stroke.opacity=CurrentContext->opacity;
 
4753
 
 
4754
      MvgPrintf(context, "stroke %s\n",pattern_spec);
 
4755
    }
 
4756
}
 
4757
 
 
4758
/*
 
4759
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4760
%                                                                             %
 
4761
%                                                                             %
 
4762
%                                                                             %
 
4763
%   D r a w G e t S t r o k e A n t i a l i a s                               %
 
4764
%                                                                             %
 
4765
%                                                                             %
 
4766
%                                                                             %
 
4767
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4768
%
 
4769
%  DrawGetStrokeAntialias() returns the current stroke antialias setting.
 
4770
%  Stroked outlines are antialiased by default.  When antialiasing is disabled
 
4771
%  stroked pixels are thresholded to determine if the stroke color or
 
4772
%  underlying canvas color should be used.
 
4773
%
 
4774
%  The format of the DrawGetStrokeAntialias method is:
 
4775
%
 
4776
%      unsigned int DrawGetStrokeAntialias(DrawContext context)
 
4777
%
 
4778
%  A description of each parameter follows:
 
4779
%
 
4780
%    o context: drawing context
 
4781
*/
 
4782
MagickExport unsigned int DrawGetStrokeAntialias(DrawContext context)
 
4783
{
 
4784
  assert(context != (DrawContext)NULL);
 
4785
  assert(context->signature == MagickSignature);
 
4786
 
 
4787
  return CurrentContext->stroke_antialias;
 
4788
}
 
4789
 
 
4790
/*
 
4791
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4792
%                                                                             %
 
4793
%                                                                             %
 
4794
%                                                                             %
 
4795
%   D r a w S e t S t r o k e A n t i a l i a s                               %
 
4796
%                                                                             %
 
4797
%                                                                             %
 
4798
%                                                                             %
 
4799
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4800
%
 
4801
%  DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
 
4802
%  Stroked outlines are antialiased by default.  When antialiasing is disabled
 
4803
%  stroked pixels are thresholded to determine if the stroke color or
 
4804
%  underlying canvas color should be used.
 
4805
%
 
4806
%  The format of the DrawSetStrokeAntialias method is:
 
4807
%
 
4808
%      void DrawSetStrokeAntialias(DrawContext context,
 
4809
%                                  const unsigned int stroke_antialias)
 
4810
%
 
4811
%  A description of each parameter follows:
 
4812
%
 
4813
%    o context: drawing context
 
4814
%
 
4815
%    o stroke_antialias: set to false (zero) to disable antialiasing
 
4816
%
 
4817
*/
 
4818
MagickExport void DrawSetStrokeAntialias(DrawContext context,
 
4819
                                         const unsigned int stroke_antialias)
 
4820
{
 
4821
  assert(context != (DrawContext)NULL);
 
4822
  assert(context->signature == MagickSignature);
 
4823
 
 
4824
  if(context->filter_off || (CurrentContext->stroke_antialias != stroke_antialias))
 
4825
    {
 
4826
      CurrentContext->stroke_antialias = stroke_antialias;
 
4827
 
 
4828
      MvgPrintf(context, "stroke-antialias %i\n", stroke_antialias ? 1 : 0);
 
4829
    }
 
4830
}
 
4831
 
 
4832
/*
 
4833
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4834
%                                                                             %
 
4835
%                                                                             %
 
4836
%                                                                             %
 
4837
%   D r a w G e t S t r o k e D a s h A r r a y                               %
 
4838
%                                                                             %
 
4839
%                                                                             %
 
4840
%                                                                             %
 
4841
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4842
%
 
4843
%  DrawGetStrokeDashArray() returns an array representing the pattern of
 
4844
%  dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
 
4845
%  array must be freed once it is no longer required by the user.
 
4846
%
 
4847
%  The format of the DrawGetStrokeDashArray method is:
 
4848
%
 
4849
%      double *DrawGetStrokeDashArray(DrawContext context,unsigned long *num_elems)
 
4850
%
 
4851
%  A description of each parameter follows:
 
4852
%
 
4853
%    o context: drawing context
 
4854
%
 
4855
%    o num_elems: address to place number of elements in dash array
 
4856
%
 
4857
% */
 
4858
MagickExport double *DrawGetStrokeDashArray(DrawContext context,
 
4859
                                            unsigned long *num_elems)
 
4860
{
 
4861
  register const double
 
4862
    *p;
 
4863
 
 
4864
  register double
 
4865
    *q;
 
4866
 
 
4867
  double
 
4868
    *dasharray;
 
4869
 
 
4870
  unsigned int
 
4871
    i,
 
4872
    n = 0;
 
4873
 
 
4874
  assert(context != (DrawContext)NULL);
 
4875
  assert(context->signature == MagickSignature);
 
4876
  assert(num_elems != (unsigned long *)NULL);
 
4877
 
 
4878
  p = CurrentContext->dash_pattern;
 
4879
  if( p != (const double *) NULL )
 
4880
    while( *p++ != 0)
 
4881
      n++;
 
4882
 
 
4883
  *num_elems = n;
 
4884
  dasharray = (double *)NULL;
 
4885
  if (n != 0)
 
4886
    {
 
4887
      dasharray = MagickAllocateMemory(double *, n*sizeof(double));
 
4888
      p = CurrentContext->dash_pattern;
 
4889
      q = dasharray;
 
4890
      i = n;
 
4891
      while( i-- )
 
4892
        *q++ = *p++;
 
4893
    }
 
4894
  return dasharray;
 
4895
}
 
4896
 
 
4897
/*
 
4898
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4899
%                                                                             %
 
4900
%                                                                             %
 
4901
%                                                                             %
 
4902
%   D r a w S e t S t r o k e D a s h A r r a y                               %
 
4903
%                                                                             %
 
4904
%                                                                             %
 
4905
%                                                                             %
 
4906
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
4907
%
 
4908
%  DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
 
4909
%  stroke paths. The strokeDashArray represents an array of numbers that
 
4910
%  specify the lengths of alternating dashes and gaps in pixels. If an odd
 
4911
%  number of values is provided, then the list of values is repeated to yield
 
4912
%  an even number of values. To remove an existing dash array, pass a zero
 
4913
%  num_elems argument and null dasharray.
 
4914
%  A typical strokeDashArray_ array might contain the members 5 3 2.
 
4915
%
 
4916
%  The format of the DrawSetStrokeDashArray method is:
 
4917
%
 
4918
%      void DrawSetStrokeDashArray(DrawContext context,
 
4919
%                                  const unsigned long num_elems,
 
4920
%                                  const double *dasharray)
 
4921
%
 
4922
%  A description of each parameter follows:
 
4923
%
 
4924
%    o context: drawing context
 
4925
%
 
4926
%    o num_elems: number of elements in dash array
 
4927
%
 
4928
%    o dasharray: dash array values
 
4929
%
 
4930
% */
 
4931
MagickExport void DrawSetStrokeDashArray(DrawContext context,
 
4932
                                         const unsigned long num_elems,
 
4933
                                         const double *dasharray)
 
4934
{
 
4935
  register const double
 
4936
    *p;
 
4937
 
 
4938
  register double
 
4939
    *q;
 
4940
 
 
4941
  unsigned int
 
4942
    i,
 
4943
    updated = False,
 
4944
    n_new = num_elems,
 
4945
    n_old = 0;
 
4946
 
 
4947
  assert(context != (DrawContext)NULL);
 
4948
  assert(context->signature == MagickSignature);
 
4949
 
 
4950
  q = CurrentContext->dash_pattern;
 
4951
  if( q != (const double *) NULL )
 
4952
    while( *q++ != 0)
 
4953
      n_old++;
 
4954
 
 
4955
  if( (n_old == 0) && (n_new == 0) )
 
4956
    {
 
4957
      updated = False;
 
4958
    }
 
4959
  else if( n_old != n_new )
 
4960
    {
 
4961
      updated = True;
 
4962
    }
 
4963
  else if((CurrentContext->dash_pattern != (double*)NULL)
 
4964
          && (dasharray != (double*)NULL))
 
4965
    {
 
4966
      p = dasharray;
 
4967
      q = CurrentContext->dash_pattern;
 
4968
      i = n_new;
 
4969
      while( i-- )
 
4970
        {
 
4971
          if(AbsoluteValue(*p - *q) > MagickEpsilon)
 
4972
            {
 
4973
              updated = True;
 
4974
              break;
 
4975
            }
 
4976
          ++p;
 
4977
          ++q;
 
4978
        }
 
4979
    }
 
4980
 
 
4981
  if( context->filter_off || updated )
 
4982
    {
 
4983
      if(CurrentContext->dash_pattern != (double*)NULL)
 
4984
        MagickFreeMemory(CurrentContext->dash_pattern);
 
4985
 
 
4986
      if( n_new != 0)
 
4987
        {
 
4988
          CurrentContext->dash_pattern = MagickAllocateMemory(double *,
 
4989
            (n_new+1)*sizeof(double));
 
4990
          if(CurrentContext->dash_pattern)
 
4991
            {
 
4992
              q=CurrentContext->dash_pattern;
 
4993
              p=dasharray;
 
4994
              while( *p )
 
4995
                *q++=*p++;
 
4996
              *q=0;
 
4997
            }
 
4998
          else
 
4999
            {
 
5000
              ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
 
5001
                UnableToDrawOnImage)
 
5002
            }
 
5003
        }
 
5004
 
 
5005
      MvgPrintf(context, "stroke-dasharray ");
 
5006
      if ( n_new == 0 )
 
5007
        MvgPrintf(context, "none");
 
5008
      else
 
5009
        {
 
5010
          p = dasharray;
 
5011
          i = n_new;
 
5012
          MvgPrintf(context, "%.4g", *p++);
 
5013
          while (i--)
 
5014
            MvgPrintf(context, ",%.4g", *p++);
 
5015
        }
 
5016
      MvgPrintf(context, "0 \n");
 
5017
    }
 
5018
}
 
5019
 
 
5020
/*
 
5021
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5022
%                                                                             %
 
5023
%                                                                             %
 
5024
%                                                                             %
 
5025
%   D r a w G e t S t r o k e D a s h O f f s e t                             %
 
5026
%                                                                             %
 
5027
%                                                                             %
 
5028
%                                                                             %
 
5029
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5030
%
 
5031
%  DrawGetStrokeDashOffset() returns the offset into the dash pattern to
 
5032
%  start the dash.
 
5033
%
 
5034
%  The format of the DrawGetStrokeDashOffset method is:
 
5035
%
 
5036
%      double DrawGetStrokeDashOffset(DrawContext context)
 
5037
%
 
5038
%  A description of each parameter follows:
 
5039
%
 
5040
%    o context: drawing context
 
5041
%
 
5042
*/
 
5043
MagickExport double DrawGetStrokeDashOffset(DrawContext context)
 
5044
{
 
5045
  assert(context != (DrawContext)NULL);
 
5046
  assert(context->signature == MagickSignature);
 
5047
 
 
5048
  return CurrentContext->dash_offset;
 
5049
}
 
5050
 
 
5051
/*
 
5052
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5053
%                                                                             %
 
5054
%                                                                             %
 
5055
%                                                                             %
 
5056
%   D r a w S e t S t r o k e D a s h O f f s e t                             %
 
5057
%                                                                             %
 
5058
%                                                                             %
 
5059
%                                                                             %
 
5060
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5061
%
 
5062
%  DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
 
5063
%  start the dash.
 
5064
%
 
5065
%  The format of the DrawSetStrokeDashOffset method is:
 
5066
%
 
5067
%      void DrawSetStrokeDashOffset(DrawContext context,
 
5068
%                                   const double dash_offset)
 
5069
%
 
5070
%  A description of each parameter follows:
 
5071
%
 
5072
%    o context: drawing context
 
5073
%
 
5074
%    o dash_offset: dash offset
 
5075
%
 
5076
*/
 
5077
MagickExport void DrawSetStrokeDashOffset(DrawContext context,
 
5078
                                          const double dash_offset)
 
5079
{
 
5080
  assert(context != (DrawContext)NULL);
 
5081
  assert(context->signature == MagickSignature);
 
5082
 
 
5083
  if(context->filter_off ||
 
5084
     (AbsoluteValue(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
 
5085
    {
 
5086
      CurrentContext->dash_offset = dash_offset;
 
5087
 
 
5088
      MvgPrintf(context, "stroke-dashoffset %.4g\n", dash_offset);
 
5089
    }
 
5090
}
 
5091
 
 
5092
/*
 
5093
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5094
%                                                                             %
 
5095
%                                                                             %
 
5096
%                                                                             %
 
5097
%   D r a w G e t S t r o k e L i n e C a p                                   %
 
5098
%                                                                             %
 
5099
%                                                                             %
 
5100
%                                                                             %
 
5101
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5102
%
 
5103
%  DrawGetStrokeLineCap() returns the shape to be used at the end of
 
5104
%  open subpaths when they are stroked. Values of LineCap are
 
5105
%  UndefinedCap, ButtCap, RoundCap, and SquareCap.
 
5106
%
 
5107
%  The format of the DrawGetStrokeLineCap method is:
 
5108
%
 
5109
%      LineCap DrawGetStrokeLineCap(DrawContext context)
 
5110
%
 
5111
%  A description of each parameter follows:
 
5112
%
 
5113
%    o context: drawing context
 
5114
%
 
5115
% */
 
5116
MagickExport LineCap DrawGetStrokeLineCap(DrawContext context)
 
5117
{
 
5118
  assert(context != (DrawContext)NULL);
 
5119
  assert(context->signature == MagickSignature);
 
5120
 
 
5121
  return CurrentContext->linecap;
 
5122
}
 
5123
 
 
5124
/*
 
5125
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5126
%                                                                             %
 
5127
%                                                                             %
 
5128
%                                                                             %
 
5129
%   D r a w S e t S t r o k e L i n e C a p                                   %
 
5130
%                                                                             %
 
5131
%                                                                             %
 
5132
%                                                                             %
 
5133
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5134
%
 
5135
%  DrawSetStrokeLineCap() specifies the shape to be used at the end of
 
5136
%  open subpaths when they are stroked. Values of LineCap are
 
5137
%  UndefinedCap, ButtCap, RoundCap, and SquareCap.
 
5138
%
 
5139
%  The format of the DrawSetStrokeLineCap method is:
 
5140
%
 
5141
%      void DrawSetStrokeLineCap(DrawContext context,
 
5142
%                                const LineCap linecap)
 
5143
%
 
5144
%  A description of each parameter follows:
 
5145
%
 
5146
%    o context: drawing context
 
5147
%
 
5148
%    o linecap: linecap style
 
5149
%
 
5150
% */
 
5151
MagickExport void DrawSetStrokeLineCap(DrawContext context,
 
5152
                                       const LineCap linecap)
 
5153
{
 
5154
  assert(context != (DrawContext)NULL);
 
5155
  assert(context->signature == MagickSignature);
 
5156
 
 
5157
  if(context->filter_off || (CurrentContext->linecap != linecap))
 
5158
    {
 
5159
      const char
 
5160
        *p = NULL;
 
5161
 
 
5162
      CurrentContext->linecap = linecap;
 
5163
 
 
5164
      switch (linecap)
 
5165
        {
 
5166
        case ButtCap:
 
5167
          p = "butt";
 
5168
          break;
 
5169
        case RoundCap:
 
5170
          p = "round";
 
5171
          break;
 
5172
        case SquareCap:
 
5173
          p = "square";
 
5174
          break;
 
5175
        default:
 
5176
          break;
 
5177
        }
 
5178
 
 
5179
      if (p != NULL)
 
5180
        MvgPrintf(context, "stroke-linecap %s\n", p);
 
5181
    }
 
5182
}
 
5183
 
 
5184
/*
 
5185
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5186
%                                                                             %
 
5187
%                                                                             %
 
5188
%                                                                             %
 
5189
%   D r a w G e t S t r o k e L i n e J o i n                                 %
 
5190
%                                                                             %
 
5191
%                                                                             %
 
5192
%                                                                             %
 
5193
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5194
%
 
5195
%  DrawGetStrokeLineJoin() returns the shape to be used at the
 
5196
%  corners of paths (or other vector shapes) when they are
 
5197
%  stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
 
5198
%  and BevelJoin.
 
5199
%
 
5200
%  The format of the DrawGetStrokeLineJoin method is:
 
5201
%
 
5202
%      LineJoin DrawGetStrokeLineJoin(DrawContext context)
 
5203
%
 
5204
%  A description of each parameter follows:
 
5205
%
 
5206
%    o context: drawing context
 
5207
%
 
5208
% */
 
5209
MagickExport LineJoin DrawGetStrokeLineJoin(DrawContext context)
 
5210
{
 
5211
  assert(context != (DrawContext)NULL);
 
5212
  assert(context->signature == MagickSignature);
 
5213
 
 
5214
  return CurrentContext->linejoin;
 
5215
}
 
5216
 
 
5217
/*
 
5218
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5219
%                                                                             %
 
5220
%                                                                             %
 
5221
%                                                                             %
 
5222
%   D r a w S e t S t r o k e L i n e J o i n                                 %
 
5223
%                                                                             %
 
5224
%                                                                             %
 
5225
%                                                                             %
 
5226
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5227
%
 
5228
%  DrawSetStrokeLineJoin() specifies the shape to be used at the
 
5229
%  corners of paths (or other vector shapes) when they are
 
5230
%  stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
 
5231
%  and BevelJoin.
 
5232
%
 
5233
%  The format of the DrawSetStrokeLineJoin method is:
 
5234
%
 
5235
%      void DrawSetStrokeLineJoin(DrawContext context, const LineJoin linejoin)
 
5236
%
 
5237
%  A description of each parameter follows:
 
5238
%
 
5239
%    o context: drawing context
 
5240
%
 
5241
%    o linejoin: line join style
 
5242
%
 
5243
% */
 
5244
MagickExport void DrawSetStrokeLineJoin(DrawContext context,
 
5245
                                        const LineJoin linejoin)
 
5246
{
 
5247
  assert(context != (DrawContext)NULL);
 
5248
  assert(context->signature == MagickSignature);
 
5249
 
 
5250
  if(context->filter_off || (CurrentContext->linejoin != linejoin))
 
5251
    {
 
5252
      const char
 
5253
        *p = NULL;
 
5254
 
 
5255
      CurrentContext->linejoin = linejoin;
 
5256
 
 
5257
      switch (linejoin)
 
5258
        {
 
5259
        case MiterJoin:
 
5260
          p = "miter";
 
5261
          break;
 
5262
        case RoundJoin:
 
5263
          p = "round";
 
5264
          break;
 
5265
        case BevelJoin:
 
5266
          p = "square";
 
5267
          break;
 
5268
        default:
 
5269
          break;
 
5270
        }
 
5271
 
 
5272
      if (p != NULL)
 
5273
        MvgPrintf(context, "stroke-linejoin %s\n", p);
 
5274
    }
 
5275
}
 
5276
 
 
5277
/*
 
5278
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5279
%                                                                             %
 
5280
%                                                                             %
 
5281
%                                                                             %
 
5282
%   D r a w G e t S t r o k e M i t e r L i m i t                             %
 
5283
%                                                                             %
 
5284
%                                                                             %
 
5285
%                                                                             %
 
5286
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5287
%
 
5288
%  DrawGetStrokeMiterLimit() returns the miter limit. When two line
 
5289
%  segments meet at a sharp angle and miter joins have been specified for
 
5290
%  'lineJoin', it is possible for the miter to extend far beyond the
 
5291
%  thickness of the line stroking the path. The miterLimit' imposes a
 
5292
%  limit on the ratio of the miter length to the 'lineWidth'.
 
5293
%
 
5294
%  The format of the DrawGetStrokeMiterLimit method is:
 
5295
%
 
5296
%      unsigned long DrawGetStrokeMiterLimit(DrawContext context)
 
5297
%
 
5298
%  A description of each parameter follows:
 
5299
%
 
5300
%    o context: drawing context
 
5301
%
 
5302
% */
 
5303
MagickExport unsigned long DrawGetStrokeMiterLimit(DrawContext context)
 
5304
{
 
5305
  assert(context != (DrawContext)NULL);
 
5306
  assert(context->signature == MagickSignature);
 
5307
 
 
5308
  return CurrentContext->miterlimit;
 
5309
}
 
5310
 
 
5311
/*
 
5312
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5313
%                                                                             %
 
5314
%                                                                             %
 
5315
%                                                                             %
 
5316
%   D r a w S e t S t r o k e M i t e r L i m i t                             %
 
5317
%                                                                             %
 
5318
%                                                                             %
 
5319
%                                                                             %
 
5320
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5321
%
 
5322
%  DrawSetStrokeMiterLimit() specifies the miter limit. When two line
 
5323
%  segments meet at a sharp angle and miter joins have been specified for
 
5324
%  'lineJoin', it is possible for the miter to extend far beyond the
 
5325
%  thickness of the line stroking the path. The miterLimit' imposes a
 
5326
%  limit on the ratio of the miter length to the 'lineWidth'.
 
5327
%
 
5328
%  The format of the DrawSetStrokeMiterLimit method is:
 
5329
%
 
5330
%      void DrawSetStrokeMiterLimit(DrawContext context,
 
5331
%                                   const unsigned long miterlimit)
 
5332
%
 
5333
%  A description of each parameter follows:
 
5334
%
 
5335
%    o context: drawing context
 
5336
%
 
5337
%    o miterlimit: miter limit
 
5338
%
 
5339
% */
 
5340
MagickExport void DrawSetStrokeMiterLimit(DrawContext context,
 
5341
                                          const unsigned long miterlimit)
 
5342
{
 
5343
  assert(context != (DrawContext)NULL);
 
5344
  assert(context->signature == MagickSignature);
 
5345
 
 
5346
  if(CurrentContext->miterlimit != miterlimit)
 
5347
    {
 
5348
      CurrentContext->miterlimit = miterlimit;
 
5349
 
 
5350
      MvgPrintf(context, "stroke-miterlimit %lu\n", miterlimit);
 
5351
    }
 
5352
}
 
5353
 
 
5354
/*
 
5355
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5356
%                                                                             %
 
5357
%                                                                             %
 
5358
%                                                                             %
 
5359
%   D r a w G e t S t r o k e O p a c i t y                                   %
 
5360
%                                                                             %
 
5361
%                                                                             %
 
5362
%                                                                             %
 
5363
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5364
%
 
5365
%  DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
 
5366
%
 
5367
%  The format of the DrawGetStrokeOpacity method is:
 
5368
%
 
5369
%      double DrawGetStrokeOpacity(DrawContext context)
 
5370
%
 
5371
%  A description of each parameter follows:
 
5372
%
 
5373
%    o context: drawing context
 
5374
*/
 
5375
MagickExport double DrawGetStrokeOpacity(DrawContext context)
 
5376
{
 
5377
  assert(context != (DrawContext)NULL);
 
5378
  assert(context->signature == MagickSignature);
 
5379
 
 
5380
  return (((double)(MaxRGB-CurrentContext->stroke.opacity))/MaxRGB);
 
5381
}
 
5382
 
 
5383
/*
 
5384
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5385
%                                                                             %
 
5386
%                                                                             %
 
5387
%                                                                             %
 
5388
%   D r a w S e t S t r o k e O p a c i t y                                   %
 
5389
%                                                                             %
 
5390
%                                                                             %
 
5391
%                                                                             %
 
5392
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5393
%
 
5394
%  DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
 
5395
%
 
5396
%  The format of the DrawSetStrokeOpacity method is:
 
5397
%
 
5398
%      void DrawSetStrokeOpacity(DrawContext context,
 
5399
%                                const double stroke_opacity)
 
5400
%
 
5401
%  A description of each parameter follows:
 
5402
%
 
5403
%    o context: drawing context
 
5404
%
 
5405
%    o stroke_opacity: stroke opacity.  The value 1.0 is opaque.
 
5406
%
 
5407
*/
 
5408
MagickExport void DrawSetStrokeOpacity(DrawContext context,
 
5409
                                       const double stroke_opacity)
 
5410
{
 
5411
  Quantum
 
5412
    quantum_opacity;
 
5413
 
 
5414
  double
 
5415
    validated_opacity;
 
5416
 
 
5417
  assert(context != (DrawContext)NULL);
 
5418
  assert(context->signature == MagickSignature);
 
5419
 
 
5420
  validated_opacity=(stroke_opacity < 0.0 ? 0.0 : (stroke_opacity > 1.0 ? 1.0 : stroke_opacity));
 
5421
  quantum_opacity = (Quantum) (((double) MaxRGB*(1.0-validated_opacity))+0.5);
 
5422
 
 
5423
  if (context->filter_off || (CurrentContext->stroke.opacity != quantum_opacity))
 
5424
    {
 
5425
      CurrentContext->stroke.opacity = quantum_opacity;
 
5426
      MvgPrintf(context, "stroke-opacity %.4g\n", validated_opacity);
 
5427
    }
 
5428
}
 
5429
 
 
5430
/*
 
5431
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5432
%                                                                             %
 
5433
%                                                                             %
 
5434
%                                                                             %
 
5435
%   D r a w G e t S t r o k e W i d t h                                       %
 
5436
%                                                                             %
 
5437
%                                                                             %
 
5438
%                                                                             %
 
5439
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5440
%
 
5441
%  DrawGetStrokeWidth() returns the width of the stroke used to draw object
 
5442
%  outlines.
 
5443
%
 
5444
%  The format of the DrawGetStrokeWidth method is:
 
5445
%
 
5446
%      double DrawGetStrokeWidth(DrawContext context)
 
5447
%
 
5448
%  A description of each parameter follows:
 
5449
%
 
5450
%    o context: drawing context
 
5451
%
 
5452
*/
 
5453
MagickExport double DrawGetStrokeWidth(DrawContext context)
 
5454
{
 
5455
  assert(context != (DrawContext)NULL);
 
5456
  assert(context->signature == MagickSignature);
 
5457
 
 
5458
  return CurrentContext->stroke_width;
 
5459
}
 
5460
 
 
5461
/*
 
5462
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5463
%                                                                             %
 
5464
%                                                                             %
 
5465
%                                                                             %
 
5466
%   D r a w S e t S t r o k e W i d t h                                       %
 
5467
%                                                                             %
 
5468
%                                                                             %
 
5469
%                                                                             %
 
5470
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5471
%
 
5472
%  DrawSetStrokeWidth() sets the width of the stroke used to draw object
 
5473
%  outlines.
 
5474
%
 
5475
%  The format of the DrawSetStrokeWidth method is:
 
5476
%
 
5477
%      void DrawSetStrokeWidth(DrawContext context, const double stroke_width)
 
5478
%
 
5479
%  A description of each parameter follows:
 
5480
%
 
5481
%    o context: drawing context
 
5482
%
 
5483
%    o stroke_width: stroke width
 
5484
%
 
5485
*/
 
5486
MagickExport void DrawSetStrokeWidth(DrawContext context,
 
5487
                                     const double stroke_width)
 
5488
{
 
5489
  assert(context != (DrawContext)NULL);
 
5490
  assert(context->signature == MagickSignature);
 
5491
 
 
5492
  if (context->filter_off ||
 
5493
      (AbsoluteValue(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
 
5494
    {
 
5495
      CurrentContext->stroke_width = stroke_width;
 
5496
 
 
5497
      MvgPrintf(context, "stroke-width %.4g\n", stroke_width);
 
5498
    }
 
5499
}
 
5500
 
 
5501
/*
 
5502
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5503
%                                                                             %
 
5504
%                                                                             %
 
5505
%                                                                             %
 
5506
%   D r a w G e t T e x t A n t i a l i a s                                   %
 
5507
%                                                                             %
 
5508
%                                                                             %
 
5509
%                                                                             %
 
5510
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5511
%
 
5512
%  DrawGetTextAntialias() returns the current text antialias setting, which
 
5513
%  determines whether text is antialiased.  Text is antialiased by default.
 
5514
%
 
5515
%  The format of the DrawGetTextAntialias method is:
 
5516
%
 
5517
%      unsigned int DrawGetTextAntialias(DrawContext context)
 
5518
%
 
5519
%  A description of each parameter follows:
 
5520
%
 
5521
%    o context: drawing context
 
5522
%
 
5523
*/
 
5524
MagickExport unsigned int DrawGetTextAntialias(DrawContext context)
 
5525
{
 
5526
  assert(context != (DrawContext)NULL);
 
5527
  assert(context->signature == MagickSignature);
 
5528
 
 
5529
  return CurrentContext->text_antialias;
 
5530
}
 
5531
 
 
5532
/*
 
5533
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5534
%                                                                             %
 
5535
%                                                                             %
 
5536
%                                                                             %
 
5537
%   D r a w S e t T e x t A n t i a l i a s                                   %
 
5538
%                                                                             %
 
5539
%                                                                             %
 
5540
%                                                                             %
 
5541
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5542
%
 
5543
%  DrawSetTextAntialias() controls whether text is antialiased.  Text is
 
5544
%  antialiased by default.
 
5545
%
 
5546
%  The format of the DrawSetTextAntialias method is:
 
5547
%
 
5548
%      void DrawSetTextAntialias(DrawContext context,
 
5549
%                                const unsigned int text_antialias)
 
5550
%
 
5551
%  A description of each parameter follows:
 
5552
%
 
5553
%    o context: drawing context
 
5554
%
 
5555
%    o text_antialias: antialias boolean. Set to false (0) to disable
 
5556
%                      antialiasing.
 
5557
%
 
5558
*/
 
5559
MagickExport void DrawSetTextAntialias(DrawContext context,
 
5560
                                       const unsigned int text_antialias)
 
5561
{
 
5562
  assert(context != (DrawContext)NULL);
 
5563
  assert(context->signature == MagickSignature);
 
5564
 
 
5565
  if (context->filter_off || (CurrentContext->text_antialias != text_antialias))
 
5566
    {
 
5567
      CurrentContext->text_antialias = text_antialias;
 
5568
 
 
5569
      MvgPrintf(context, "text-antialias %i\n", text_antialias ? 1 : 0);
 
5570
    }
 
5571
}
 
5572
 
 
5573
/*
 
5574
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5575
%                                                                             %
 
5576
%                                                                             %
 
5577
%                                                                             %
 
5578
%   D r a w G e t T e x t D e c o r a t i o n                                 %
 
5579
%                                                                             %
 
5580
%                                                                             %
 
5581
%                                                                             %
 
5582
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5583
%
 
5584
%  DrawGetTextDecoration() returns the decoration applied when annotating with
 
5585
%  text.
 
5586
%
 
5587
%  The format of the DrawGetTextDecoration method is:
 
5588
%
 
5589
%      DecorationType DrawGetTextDecoration(DrawContext context)
 
5590
%
 
5591
%  A description of each parameter follows:
 
5592
%
 
5593
%    o context: drawing context
 
5594
%
 
5595
*/
 
5596
MagickExport DecorationType DrawGetTextDecoration(DrawContext context)
 
5597
{
 
5598
  assert(context != (DrawContext)NULL);
 
5599
  assert(context->signature == MagickSignature);
 
5600
  
 
5601
  return CurrentContext->decorate;
 
5602
}
 
5603
 
 
5604
/*
 
5605
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5606
%                                                                             %
 
5607
%                                                                             %
 
5608
%                                                                             %
 
5609
%   D r a w S e t T e x t D e c o r a t i o n                                 %
 
5610
%                                                                             %
 
5611
%                                                                             %
 
5612
%                                                                             %
 
5613
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5614
%
 
5615
%  DrawSetTextDecoration() specifies a decoration to be applied when
 
5616
%  annotating with text.
 
5617
%
 
5618
%  The format of the DrawSetTextDecoration method is:
 
5619
%
 
5620
%      void DrawSetTextDecoration(DrawContext context,
 
5621
%                                 const DecorationType decoration)
 
5622
%
 
5623
%  A description of each parameter follows:
 
5624
%
 
5625
%    o context: drawing context
 
5626
%
 
5627
%    o decoration: text decoration.  One of NoDecoration, UnderlineDecoration,
 
5628
%                                    OverlineDecoration, or LineThroughDecoration
 
5629
%
 
5630
*/
 
5631
MagickExport void DrawSetTextDecoration(DrawContext context,
 
5632
                                        const DecorationType decoration)
 
5633
{
 
5634
  const char
 
5635
    *p = NULL;
 
5636
 
 
5637
  assert(context != (DrawContext)NULL);
 
5638
  assert(context->signature == MagickSignature);
 
5639
 
 
5640
  if (context->filter_off || (CurrentContext->decorate != decoration))
 
5641
    {
 
5642
      CurrentContext->decorate = decoration;
 
5643
 
 
5644
      switch (decoration)
 
5645
        {
 
5646
        case NoDecoration:
 
5647
          p = "none";
 
5648
          break;
 
5649
        case UnderlineDecoration:
 
5650
          p = "underline";
 
5651
          break;
 
5652
        case OverlineDecoration:
 
5653
          p = "overline";
 
5654
          break;
 
5655
        case LineThroughDecoration:
 
5656
          p = "line-through";
 
5657
          break;
 
5658
        }
 
5659
 
 
5660
      if (p != NULL)
 
5661
        MvgPrintf(context, "decorate %s\n", p);
 
5662
    }
 
5663
}
 
5664
 
 
5665
/*
 
5666
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5667
%                                                                             %
 
5668
%                                                                             %
 
5669
%                                                                             %
 
5670
%   D r a w G e t T e x t E n c o d i n g                                     %
 
5671
%                                                                             %
 
5672
%                                                                             %
 
5673
%                                                                             %
 
5674
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5675
%
 
5676
%  DrawGetTextEncoding() returns a null-terminated string which specifies the
 
5677
%  code set used for text annotations. The string must be freed by the user
 
5678
%  once it is no longer required.
 
5679
%
 
5680
%  The format of the DrawGetTextEncoding method is:
 
5681
%
 
5682
%      char *DrawGetTextEncoding(DrawContext context)
 
5683
%
 
5684
%  A description of each parameter follows:
 
5685
%
 
5686
%    o context: drawing context
 
5687
%
 
5688
% */
 
5689
MagickExport char *DrawGetTextEncoding(DrawContext context)
 
5690
{
 
5691
  assert(context != (DrawContext)NULL);
 
5692
  assert(context->signature == MagickSignature);
 
5693
 
 
5694
  if (CurrentContext->encoding != (char *)NULL)
 
5695
    return (char *) AllocateString(CurrentContext->encoding);
 
5696
  else
 
5697
    return (char *) NULL;
 
5698
}
 
5699
 
 
5700
/*
 
5701
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5702
%                                                                             %
 
5703
%                                                                             %
 
5704
%                                                                             %
 
5705
%   D r a w S e t T e x t E n c o d i n g                                     %
 
5706
%                                                                             %
 
5707
%                                                                             %
 
5708
%                                                                             %
 
5709
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5710
%
 
5711
%  DrawSetTextEncoding() specifies specifies the code set to use for
 
5712
%  text annotations. The only character encoding which may be specified
 
5713
%  at this time is "UTF-8" for representing Unicode as a sequence of
 
5714
%  bytes. Specify an empty string to set text encoding to the system's
 
5715
%  default. Successful text annotation using Unicode may require fonts
 
5716
%  designed to support Unicode.
 
5717
%
 
5718
%  The format of the DrawSetTextEncoding method is:
 
5719
%
 
5720
%      void DrawSetTextEncoding(DrawContext context, const char* encoding)
 
5721
%
 
5722
%  A description of each parameter follows:
 
5723
%
 
5724
%    o context: drawing context
 
5725
%
 
5726
%    o encoding: character string specifying text encoding
 
5727
%
 
5728
*/
 
5729
MagickExport void DrawSetTextEncoding(DrawContext context, const char* encoding)
 
5730
{
 
5731
  assert(context != (DrawContext)NULL);
 
5732
  assert(context->signature == MagickSignature);
 
5733
  assert(encoding != (char *) NULL);
 
5734
 
 
5735
  if (context->filter_off || (CurrentContext->encoding == (char *) NULL) ||
 
5736
      (LocaleCompare(CurrentContext->encoding,encoding) != 0))
 
5737
    {
 
5738
        CloneString(&CurrentContext->encoding,encoding);
 
5739
 
 
5740
      MvgPrintf(context, "encoding '%s'\n", encoding);
 
5741
    }
 
5742
}
 
5743
 
 
5744
/*
 
5745
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5746
%                                                                             %
 
5747
%                                                                             %
 
5748
%                                                                             %
 
5749
%   D r a w G e t T e x t U n d e r C o l o r                                 %
 
5750
%                                                                             %
 
5751
%                                                                             %
 
5752
%                                                                             %
 
5753
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5754
%
 
5755
%  DrawGetTextUnderColor() returns the color of a background rectangle
 
5756
%  to place under text annotations.
 
5757
%
 
5758
%  The format of the DrawGetTextUnderColor method is:
 
5759
%
 
5760
%      PixelPacket DrawGetTextUnderColor(DrawContext context)
 
5761
%
 
5762
%  A description of each parameter follows:
 
5763
%
 
5764
%    o context: drawing context
 
5765
%
 
5766
*/
 
5767
MagickExport PixelPacket DrawGetTextUnderColor(DrawContext context)
 
5768
{
 
5769
  assert(context != (DrawContext)NULL);
 
5770
  assert(context->signature == MagickSignature);
 
5771
 
 
5772
  return CurrentContext->undercolor;
 
5773
}
 
5774
 
 
5775
/*
 
5776
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5777
%                                                                             %
 
5778
%                                                                             %
 
5779
%                                                                             %
 
5780
%   D r a w S e t T e x t U n d e r C o l o r                                 %
 
5781
%                                                                             %
 
5782
%                                                                             %
 
5783
%                                                                             %
 
5784
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5785
%
 
5786
%  DrawSetTextUnderColor() specifies the color of a background rectangle
 
5787
%  to place under text annotations.
 
5788
%
 
5789
%  The format of the DrawSetTextUnderColor method is:
 
5790
%
 
5791
%      void DrawSetTextUnderColor(DrawContext context,
 
5792
%                                 const PixelPacket *under_color)
 
5793
%
 
5794
%  A description of each parameter follows:
 
5795
%
 
5796
%    o context: drawing context
 
5797
%
 
5798
%    o under_color: text under color
 
5799
%
 
5800
*/
 
5801
MagickExport void DrawSetTextUnderColor(DrawContext context,
 
5802
                                        const PixelPacket *under_color)
 
5803
{
 
5804
  assert(context != (DrawContext)NULL);
 
5805
  assert(context->signature == MagickSignature);
 
5806
  assert(under_color != (const PixelPacket *)NULL);
 
5807
 
 
5808
  if (context->filter_off || !(PixelPacketMatch(&CurrentContext->undercolor, under_color)))
 
5809
    {
 
5810
      CurrentContext->undercolor = *under_color;
 
5811
      MvgPrintf(context, "text-undercolor '");
 
5812
      MvgAppendColor(context, under_color);
 
5813
      MvgPrintf(context, "'\n");
 
5814
    }
 
5815
}
 
5816
 
 
5817
/*
 
5818
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5819
%                                                                             %
 
5820
%                                                                             %
 
5821
%                                                                             %
 
5822
%   D r a w S e t T e x t U n d e r C o l o r S t r i n g                     %
 
5823
%                                                                             %
 
5824
%                                                                             %
 
5825
%                                                                             %
 
5826
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5827
%
 
5828
%  DrawSetTextUnderColorString() specifies the color of a background rectangle
 
5829
%  to place under text annotations.
 
5830
%
 
5831
%  The format of the DrawSetTextUnderColorString method is:
 
5832
%
 
5833
%      void DrawSetTextUnderColorString(DrawContext context,
 
5834
%                                       const char* under_color)
 
5835
%
 
5836
%  A description of each parameter follows:
 
5837
%
 
5838
%    o context: drawing context
 
5839
%
 
5840
%    o under_color: text under color
 
5841
%
 
5842
*/
 
5843
MagickExport void DrawSetTextUnderColorString(DrawContext context,
 
5844
                                              const char* under_color)
 
5845
{
 
5846
  PixelPacket
 
5847
    pixel_packet;
 
5848
 
 
5849
  if(QueryColorDatabase(under_color,&pixel_packet,&context->image->exception))
 
5850
    DrawSetTextUnderColor(context,&pixel_packet);
 
5851
}
 
5852
 
 
5853
/*
 
5854
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5855
%                                                                             %
 
5856
%                                                                             %
 
5857
%                                                                             %
 
5858
%   D r a w T r a n s l a t e                                                 %
 
5859
%                                                                             %
 
5860
%                                                                             %
 
5861
%                                                                             %
 
5862
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5863
%
 
5864
%  DrawTranslate() applies a translation to the current coordinate
 
5865
%  system which moves the coordinate system origin to the specified
 
5866
%  coordinate.
 
5867
%
 
5868
%  The format of the DrawTranslate method is:
 
5869
%
 
5870
%      void DrawTranslate(DrawContext context,
 
5871
%                            const double x, const double y)
 
5872
%
 
5873
%  A description of each parameter follows:
 
5874
%
 
5875
%    o context: drawing context
 
5876
%
 
5877
%    o x: new x ordinate for coordinate system origin
 
5878
%
 
5879
%    o y: new y ordinate for coordinate system origin
 
5880
%
 
5881
*/
 
5882
MagickExport void DrawTranslate(DrawContext context,
 
5883
                                   const double x, const double y)
 
5884
{
 
5885
  AffineMatrix
 
5886
    affine;
 
5887
 
 
5888
  assert(context != (DrawContext)NULL);
 
5889
  assert(context->signature == MagickSignature);
 
5890
 
 
5891
  IdentityAffine(&affine);
 
5892
  affine.tx=x;
 
5893
  affine.ty=y;
 
5894
  AdjustAffine( context, &affine );
 
5895
 
 
5896
  MvgPrintf(context, "translate %.4g,%.4g\n", x, y);
 
5897
}
 
5898
 
 
5899
/*
 
5900
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5901
%                                                                             %
 
5902
%                                                                             %
 
5903
%                                                                             %
 
5904
%   D r a w S e t V i e w b o x                                               %
 
5905
%                                                                             %
 
5906
%                                                                             %
 
5907
%                                                                             %
 
5908
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
5909
%
 
5910
%  DrawSetViewbox() sets the overall canvas size to be recorded with the
 
5911
%  drawing vector data.  Usually this will be specified using the same
 
5912
%  size as the canvas image.  When the vector data is saved to SVG or MVG
 
5913
%  formats, the viewbox is use to specify the size of the canvas image that
 
5914
%  a viewer will render the vector data on.
 
5915
%
 
5916
%  The format of the DrawSetViewbox method is:
 
5917
%
 
5918
%      void DrawSetViewbox(DrawContext context,
 
5919
%                          unsigned long x1, unsigned long y1,
 
5920
%                          unsigned long x2, unsigned long y2)
 
5921
%
 
5922
%  A description of each parameter follows:
 
5923
%
 
5924
%    o context: drawing context
 
5925
%
 
5926
%    o x1: left x ordinate
 
5927
%
 
5928
%    o y1: top y ordinate
 
5929
%
 
5930
%    o x2: right x ordinate
 
5931
%
 
5932
%    o y2: bottom y ordinate
 
5933
%
 
5934
*/
 
5935
MagickExport void DrawSetViewbox(DrawContext context,
 
5936
                                 unsigned long x1, unsigned long y1,
 
5937
                                 unsigned long x2, unsigned long y2)
 
5938
{
 
5939
  assert(context != (DrawContext)NULL);
 
5940
  assert(context->signature == MagickSignature);
 
5941
 
 
5942
  MvgPrintf(context, "viewbox %lu %lu %lu %lu\n", x1, y1, x2, y2);
 
5943
}