magickwand 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/ext/magickwand/drawing.c +1850 -0
- data/ext/magickwand/extconf.rb +3 -2
- data/ext/magickwand/magickwand.c +2 -2
- data/ext/magickwand/magickwand.h +12 -6
- data/ext/magickwand/utility.c +151 -24
- data/ext/magickwand/wand.c +104 -9
- data/lib/magickwand.rb +88 -1
- data/test/freezer.rb +12 -0
- data/test/test_drawing.rb +672 -0
- data/test/test_magickwand.rb +23 -10
- metadata +6 -4
- data/ext/magickwand/gc.c +0 -464
data/Rakefile
CHANGED
@@ -0,0 +1,1850 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
* drawing.c
|
4
|
+
* $Id: drawing.c 285 2009-08-14 23:09:24Z rmagick $
|
5
|
+
* Copyright (C) 2009 Timothy Paul Hunter
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "magickwand.h"
|
9
|
+
|
10
|
+
|
11
|
+
static void drawing_destroy(void *);
|
12
|
+
static VALUE polyshape(int, VALUE *, VALUE, void (*)(DrawingWand *, const unsigned long, const PointInfo *));
|
13
|
+
|
14
|
+
|
15
|
+
static VALUE drawing_allocate(VALUE klass)
|
16
|
+
{
|
17
|
+
Drawing *drawing;
|
18
|
+
return Data_Make_Struct(klass, Drawing, NULL, drawing_destroy, drawing);
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
static void drawing_destroy(void *p)
|
25
|
+
{
|
26
|
+
Drawing *drawing = (Drawing *)p;
|
27
|
+
|
28
|
+
if (drawing->wand)
|
29
|
+
{
|
30
|
+
drawing->wand = DestroyDrawingWand(drawing->wand);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
/*
|
38
|
+
* drawing = MagickWand::Drawing.new
|
39
|
+
*/
|
40
|
+
static VALUE drawing_initialize(VALUE obj)
|
41
|
+
{
|
42
|
+
Drawing *drawing;
|
43
|
+
|
44
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
45
|
+
drawing->wand = NewDrawingWand();
|
46
|
+
return obj;
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
/*
|
53
|
+
* Construct a new Drawing object
|
54
|
+
*/
|
55
|
+
VALUE mwr_drawing_new(void)
|
56
|
+
{
|
57
|
+
VALUE obj;
|
58
|
+
Drawing *drawing;
|
59
|
+
|
60
|
+
obj = Data_Make_Struct(mwr_cDrawing, Drawing, NULL, drawing_destroy, drawing);
|
61
|
+
drawing->wand = NewDrawingWand();
|
62
|
+
return obj;
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
/*
|
69
|
+
* drawing2 = drawing.dup
|
70
|
+
* drawing2 = drawing.clone
|
71
|
+
*/
|
72
|
+
static VALUE drawing_initialize_copy(VALUE obj, VALUE obj2)
|
73
|
+
{
|
74
|
+
Drawing *drawing, *drawing2;
|
75
|
+
|
76
|
+
if (obj == obj2)
|
77
|
+
{
|
78
|
+
return obj;
|
79
|
+
}
|
80
|
+
|
81
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
82
|
+
Data_Get_Struct(obj2, Drawing, drawing2);
|
83
|
+
|
84
|
+
drawing->wand = CloneDrawingWand(drawing2->wand);
|
85
|
+
return obj;
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
static VALUE drawing_inspect(VALUE obj)
|
92
|
+
{
|
93
|
+
Drawing *drawing;
|
94
|
+
volatile VALUE string;
|
95
|
+
char *text, *start, *end;
|
96
|
+
size_t len;
|
97
|
+
|
98
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
99
|
+
|
100
|
+
text = DrawGetVectorGraphics(drawing->wand);
|
101
|
+
|
102
|
+
// The drawing primitives are contained in the <vector-graphics> element.
|
103
|
+
// Delete everything else.
|
104
|
+
if (text)
|
105
|
+
{
|
106
|
+
start = strstr(text, "<vector-graphics>");
|
107
|
+
if (start)
|
108
|
+
{
|
109
|
+
end = strstr(start, "</vector-graphics>");
|
110
|
+
if (end)
|
111
|
+
{
|
112
|
+
start += 17;
|
113
|
+
len = end - start;
|
114
|
+
if (start[len-1] == '\n')
|
115
|
+
{
|
116
|
+
len -= 1;
|
117
|
+
}
|
118
|
+
string = rb_str_new(start, len);
|
119
|
+
}
|
120
|
+
else
|
121
|
+
{
|
122
|
+
goto no_graphics;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
else
|
126
|
+
{
|
127
|
+
goto no_graphics;
|
128
|
+
}
|
129
|
+
|
130
|
+
RelinquishMagickMemory(text);
|
131
|
+
}
|
132
|
+
else
|
133
|
+
{
|
134
|
+
goto no_graphics;
|
135
|
+
}
|
136
|
+
|
137
|
+
return string;
|
138
|
+
|
139
|
+
no_graphics:
|
140
|
+
return rb_call_super(0, NULL);
|
141
|
+
|
142
|
+
}
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
/*
|
148
|
+
* drawing.affine(sx, sy, rx, ry, tx, ty)
|
149
|
+
*/
|
150
|
+
static VALUE drawing_affine(VALUE obj, VALUE sx, VALUE sy, VALUE rx, VALUE ry, VALUE tx, VALUE ty)
|
151
|
+
{
|
152
|
+
Drawing *drawing;
|
153
|
+
AffineMatrix affine;
|
154
|
+
|
155
|
+
rb_check_frozen(obj);
|
156
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
157
|
+
|
158
|
+
affine.sx = NUM2DBL(sx);
|
159
|
+
affine.sy = NUM2DBL(sy);
|
160
|
+
affine.rx = NUM2DBL(rx);
|
161
|
+
affine.ry = NUM2DBL(ry);
|
162
|
+
affine.tx = NUM2DBL(tx);
|
163
|
+
affine.ty = NUM2DBL(ty);
|
164
|
+
|
165
|
+
DrawAffine(drawing->wand, &affine);
|
166
|
+
mwr_check_drawingwand_error(drawing->wand);
|
167
|
+
return obj;
|
168
|
+
}
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
/*
|
174
|
+
* drawing.annotation text, :x=>0, y=>0
|
175
|
+
*/
|
176
|
+
static VALUE drawing_annotation(int argc, VALUE *argv, VALUE obj)
|
177
|
+
{
|
178
|
+
Drawing *drawing;
|
179
|
+
VALUE str, options, v;
|
180
|
+
double x, y;
|
181
|
+
unsigned char *text;
|
182
|
+
|
183
|
+
rb_check_frozen(obj);
|
184
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
185
|
+
|
186
|
+
(void)rb_scan_args(argc, argv, "11", &str, &options);
|
187
|
+
text = (unsigned char *)StringValuePtr(str);
|
188
|
+
|
189
|
+
x = mwr_get_option(options, "x", &v) ? NUM2DBL(v) : 0.0;
|
190
|
+
y = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
191
|
+
DrawAnnotation(drawing->wand, x, y, text);
|
192
|
+
mwr_check_drawingwand_error(drawing->wand);
|
193
|
+
return obj;
|
194
|
+
}
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
/*
|
199
|
+
* drawing.arc(width, height, start, end, :x=>0, :y=>0)
|
200
|
+
*/
|
201
|
+
static VALUE drawing_arc(int argc, VALUE *argv, VALUE obj)
|
202
|
+
{
|
203
|
+
Drawing *drawing;
|
204
|
+
double sx, sy, ex, ey, sd, ed;
|
205
|
+
VALUE width, height, start, end, options, v;
|
206
|
+
|
207
|
+
rb_check_frozen(obj);
|
208
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
209
|
+
|
210
|
+
(void)rb_scan_args(argc, argv, "41", &width, &height, &start, &end, &options);
|
211
|
+
sx = mwr_get_option(options, "x", &v) ? NUM2DBL(v) : 0.0;
|
212
|
+
sy = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
213
|
+
ex = sx + NUM2DBL(width);
|
214
|
+
ey = sy + NUM2DBL(height);
|
215
|
+
sd = NUM2DBL(start);
|
216
|
+
ed = NUM2DBL(end);
|
217
|
+
|
218
|
+
DrawArc(drawing->wand, sx, sy, ex, ey, sd, ed);
|
219
|
+
mwr_check_drawingwand_error(drawing->wand);
|
220
|
+
return obj;
|
221
|
+
}
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
/*
|
227
|
+
* drawing.bezier(x1, y1, ..., xN, yN)
|
228
|
+
*/
|
229
|
+
static VALUE drawing_bezier(int argc, VALUE *argv, VALUE obj)
|
230
|
+
{
|
231
|
+
return polyshape(argc, argv, obj, DrawBezier);
|
232
|
+
}
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
/*
|
238
|
+
* drawing.circle r, :x=>0, :y=>0
|
239
|
+
*/
|
240
|
+
static VALUE drawing_circle(int argc, VALUE *argv, VALUE obj)
|
241
|
+
{
|
242
|
+
Drawing *drawing;
|
243
|
+
VALUE r, v, options;
|
244
|
+
double x, y;
|
245
|
+
double radius;
|
246
|
+
|
247
|
+
rb_check_frozen(obj);
|
248
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
249
|
+
|
250
|
+
(void)rb_scan_args(argc, argv, "11", &r, &options);
|
251
|
+
radius = NUM2DBL(r);
|
252
|
+
if (radius <= 0.0)
|
253
|
+
{
|
254
|
+
rb_raise(rb_eArgError, "radius must be positive (got %g)", radius);
|
255
|
+
}
|
256
|
+
|
257
|
+
x = mwr_get_option(options, "x", &v) ? NUM2DBL(v) : 0.0;
|
258
|
+
y = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
259
|
+
DrawCircle(drawing->wand, x, y, x+radius, y);
|
260
|
+
mwr_check_drawingwand_error(drawing->wand);
|
261
|
+
return obj;
|
262
|
+
}
|
263
|
+
|
264
|
+
|
265
|
+
|
266
|
+
static VALUE draw_color(int argc, VALUE *argv, VALUE obj,
|
267
|
+
void (*f)(DrawingWand *, const double, const double, const PaintMethod))
|
268
|
+
{
|
269
|
+
Drawing *drawing;
|
270
|
+
VALUE v, x, y, options;
|
271
|
+
double px, py;
|
272
|
+
PaintMethod paint_method;
|
273
|
+
PixelWand *pixelwand;
|
274
|
+
|
275
|
+
rb_check_frozen(obj);
|
276
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
277
|
+
|
278
|
+
(void)rb_scan_args(argc, argv, "21", &x, &y, &options);
|
279
|
+
px = NUM2DBL(x);
|
280
|
+
py = NUM2DBL(y);
|
281
|
+
|
282
|
+
(void) mwr_get_option(options, "method", &v);
|
283
|
+
paint_method = mwr_string_to_paintmethod(v, PointMethod, RaiseUndefinedOption);
|
284
|
+
if (paint_method == FillToBorderMethod)
|
285
|
+
{
|
286
|
+
#if defined(HAVE_DRAWSETBORDERCOLOR)
|
287
|
+
(void) mwr_get_option(options, "bordercolor", &v);
|
288
|
+
pixelwand = NewPixelWand();
|
289
|
+
PixelSetColor(pixelwand, StringValuePtr(v));
|
290
|
+
DrawSetBorderColor(drawing->wand, pixelwand);
|
291
|
+
DestroyPixelWand(pixelwand);
|
292
|
+
#else
|
293
|
+
rb_warning("MagickWand: The :bordercolor option is not supported by this release of ImageMagick");
|
294
|
+
pixelwand = pixelwand;
|
295
|
+
#endif
|
296
|
+
}
|
297
|
+
|
298
|
+
(*f)(drawing->wand, px, py, paint_method);
|
299
|
+
mwr_check_drawingwand_error(drawing->wand);
|
300
|
+
return obj;
|
301
|
+
}
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
|
306
|
+
/*
|
307
|
+
* drawing.color(x, y, :method=>"point", :bordercolor=>"#dfdfdfdfdfdf")
|
308
|
+
*/
|
309
|
+
static VALUE drawing_color(int argc, VALUE *argv, VALUE obj)
|
310
|
+
{
|
311
|
+
return draw_color(argc, argv, obj, DrawColor);
|
312
|
+
}
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
/*
|
318
|
+
* drawing.composite(wand, :x=>0, :y=>0, :width=>0, :height=>0, :compose=>"over")
|
319
|
+
*/
|
320
|
+
static VALUE drawing_composite(int argc, VALUE *argv, VALUE obj)
|
321
|
+
{
|
322
|
+
Drawing *drawing;
|
323
|
+
Wand *composite_wand;
|
324
|
+
VALUE v, options, compose_obj;
|
325
|
+
double x, y, width, height;
|
326
|
+
CompositeOperator compose;
|
327
|
+
|
328
|
+
rb_check_frozen(obj);
|
329
|
+
|
330
|
+
(void)rb_scan_args(argc, argv, "11", &compose_obj, &options);
|
331
|
+
x = mwr_get_option(options, "x", &v) ? NUM2DBL(v) : 0.0;
|
332
|
+
y = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
333
|
+
width = mwr_get_option(options, "width", &v) ? NUM2DBL(v) : 0.0;
|
334
|
+
height = mwr_get_option(options, "height", &v) ? NUM2DBL(v) : 0.0;
|
335
|
+
(void) mwr_get_option(options, "compose", &v);
|
336
|
+
compose = mwr_string_to_composetype(v, OverCompositeOp, RaiseUndefinedOption);
|
337
|
+
|
338
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
339
|
+
Data_Get_Struct(compose_obj, Wand, composite_wand);
|
340
|
+
|
341
|
+
DrawComposite(drawing->wand, compose, x, y, width, height, composite_wand->magickwand);
|
342
|
+
mwr_check_drawingwand_error(drawing->wand);
|
343
|
+
return obj;
|
344
|
+
}
|
345
|
+
|
346
|
+
|
347
|
+
|
348
|
+
|
349
|
+
/*
|
350
|
+
* drawing.ellipse(rx, ry, :start=>0, :end=>360, :x=>0, :y=>0)
|
351
|
+
* :x and :y are the origin.
|
352
|
+
*/
|
353
|
+
static VALUE drawing_ellipse(int argc, VALUE *argv, VALUE obj)
|
354
|
+
{
|
355
|
+
Drawing *drawing;
|
356
|
+
VALUE x_rad, y_rad, options, v;
|
357
|
+
double rx, ry, cx, cy;
|
358
|
+
double start, end;
|
359
|
+
|
360
|
+
rb_check_frozen(obj);
|
361
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
362
|
+
|
363
|
+
(void)rb_scan_args(argc, argv, "21", &x_rad, &y_rad, &options);
|
364
|
+
rx = NUM2DBL(x_rad);
|
365
|
+
ry = NUM2DBL(y_rad);
|
366
|
+
cx = mwr_get_option(options, "x", &v) ? NUM2DBL(v) : 0.0;
|
367
|
+
cy = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
368
|
+
start = mwr_get_option(options, "start", &v) ? NUM2DBL(v) : 0.0;
|
369
|
+
end = mwr_get_option(options, "end", &v) ? NUM2DBL(v) : 360.0;
|
370
|
+
|
371
|
+
DrawEllipse(drawing->wand, cx, cy, rx, ry, start, end);
|
372
|
+
mwr_check_drawingwand_error(drawing->wand);
|
373
|
+
return obj;
|
374
|
+
}
|
375
|
+
|
376
|
+
|
377
|
+
|
378
|
+
|
379
|
+
/*
|
380
|
+
* drawing.line(x1, y1, x2, y2)
|
381
|
+
*/
|
382
|
+
static VALUE drawing_line(VALUE obj, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
|
383
|
+
{
|
384
|
+
Drawing *drawing;
|
385
|
+
|
386
|
+
rb_check_frozen(obj);
|
387
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
388
|
+
|
389
|
+
DrawLine(drawing->wand, NUM2DBL(x1), NUM2DBL(y1), NUM2DBL(x2), NUM2DBL(y2));
|
390
|
+
mwr_check_drawingwand_error(drawing->wand);
|
391
|
+
return obj;
|
392
|
+
}
|
393
|
+
|
394
|
+
|
395
|
+
|
396
|
+
|
397
|
+
/*
|
398
|
+
* drawing.matte(x, y, :method=>"point", :bordermatte=>"#dfdfdfdfdfdf")
|
399
|
+
*/
|
400
|
+
static VALUE drawing_matte(int argc, VALUE *argv, VALUE obj)
|
401
|
+
{
|
402
|
+
return draw_color(argc, argv, obj, DrawMatte);
|
403
|
+
}
|
404
|
+
|
405
|
+
|
406
|
+
|
407
|
+
|
408
|
+
/*
|
409
|
+
* drawing.close_path()
|
410
|
+
*/
|
411
|
+
static VALUE drawing_path_close(VALUE obj)
|
412
|
+
{
|
413
|
+
Drawing *drawing;
|
414
|
+
|
415
|
+
rb_check_frozen(obj);
|
416
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
417
|
+
DrawPathClose(drawing->wand);
|
418
|
+
mwr_check_drawingwand_error(drawing->wand);
|
419
|
+
return obj;
|
420
|
+
}
|
421
|
+
|
422
|
+
|
423
|
+
|
424
|
+
|
425
|
+
static VALUE path_curve_to(VALUE obj, VALUE x1, VALUE y1,
|
426
|
+
VALUE x2, VALUE y2, VALUE x, VALUE y,
|
427
|
+
void (*f)(DrawingWand *, const double, const double, const double,
|
428
|
+
const double, const double, const double))
|
429
|
+
{
|
430
|
+
Drawing *drawing;
|
431
|
+
|
432
|
+
rb_check_frozen(obj);
|
433
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
434
|
+
(*f)(drawing->wand, NUM2DBL(x1), NUM2DBL(y1), NUM2DBL(x2), NUM2DBL(y2), NUM2DBL(x), NUM2DBL(y));
|
435
|
+
mwr_check_drawingwand_error(drawing->wand);
|
436
|
+
return obj;
|
437
|
+
}
|
438
|
+
|
439
|
+
|
440
|
+
|
441
|
+
/*
|
442
|
+
* path.curve_to_absolute(x1, y1, x2, y2, x, y)
|
443
|
+
*/
|
444
|
+
static VALUE drawing_path_curve_to_absolute(VALUE obj, VALUE x1, VALUE y1,
|
445
|
+
VALUE x2, VALUE y2, VALUE x, VALUE y)
|
446
|
+
{
|
447
|
+
return path_curve_to(obj, x1, y1, x2, y2, x, y, DrawPathCurveToAbsolute);
|
448
|
+
}
|
449
|
+
|
450
|
+
|
451
|
+
|
452
|
+
|
453
|
+
/*
|
454
|
+
* path.curve_to_relative(x1, y1, x2, y2, x, y)
|
455
|
+
*/
|
456
|
+
static VALUE drawing_path_curve_to_relative(VALUE obj, VALUE x1, VALUE y1,
|
457
|
+
VALUE x2, VALUE y2, VALUE x, VALUE y)
|
458
|
+
{
|
459
|
+
return path_curve_to(obj, x1, y1, x2, y2, x, y, DrawPathCurveToRelative);
|
460
|
+
}
|
461
|
+
|
462
|
+
|
463
|
+
|
464
|
+
|
465
|
+
static VALUE path_curve_to_quadratic_bezier(VALUE obj,
|
466
|
+
VALUE x1, VALUE y1, VALUE x, VALUE y,
|
467
|
+
void (*f)(DrawingWand *, const double, const double, const double, const double))
|
468
|
+
{
|
469
|
+
Drawing *drawing;
|
470
|
+
|
471
|
+
rb_check_frozen(obj);
|
472
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
473
|
+
(*f)(drawing->wand, NUM2DBL(x1), NUM2DBL(y1), NUM2DBL(x), NUM2DBL(y));
|
474
|
+
mwr_check_drawingwand_error(drawing->wand);
|
475
|
+
return obj;
|
476
|
+
}
|
477
|
+
|
478
|
+
|
479
|
+
|
480
|
+
|
481
|
+
/*
|
482
|
+
* path.curve_to_quadratic_bezier_absolute(x1, y1, x, y)
|
483
|
+
*/
|
484
|
+
static VALUE drawing_path_curve_to_quadratic_bezier_absolute(VALUE obj,
|
485
|
+
VALUE x1, VALUE y1, VALUE x, VALUE y)
|
486
|
+
{
|
487
|
+
return path_curve_to_quadratic_bezier(obj, x1, y1, x, y, DrawPathCurveToQuadraticBezierAbsolute);
|
488
|
+
}
|
489
|
+
|
490
|
+
|
491
|
+
|
492
|
+
|
493
|
+
/*
|
494
|
+
* path.curve_to_quadratic_bezier_relative(x1, y1, x, y)
|
495
|
+
*/
|
496
|
+
static VALUE drawing_path_curve_to_quadratic_bezier_relative(VALUE obj,
|
497
|
+
VALUE x1, VALUE y1, VALUE x, VALUE y)
|
498
|
+
{
|
499
|
+
return path_curve_to_quadratic_bezier(obj, x1, y1, x, y, DrawPathCurveToQuadraticBezierRelative);
|
500
|
+
}
|
501
|
+
|
502
|
+
|
503
|
+
|
504
|
+
|
505
|
+
static VALUE path_curve_to_quadratic_bezier_smooth(VALUE obj, VALUE x, VALUE y,
|
506
|
+
void (*f)(DrawingWand *, const double, const double))
|
507
|
+
{
|
508
|
+
Drawing *drawing;
|
509
|
+
|
510
|
+
rb_check_frozen(obj);
|
511
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
512
|
+
(*f)(drawing->wand, NUM2DBL(x), NUM2DBL(y));
|
513
|
+
mwr_check_drawingwand_error(drawing->wand);
|
514
|
+
return obj;
|
515
|
+
}
|
516
|
+
|
517
|
+
|
518
|
+
|
519
|
+
|
520
|
+
/*
|
521
|
+
* path.curve_to_quadratic_bezier_smooth_absolute(x, y)
|
522
|
+
*/
|
523
|
+
static VALUE drawing_path_curve_to_quadratic_bezier_smooth_absolute(VALUE obj, VALUE x, VALUE y)
|
524
|
+
{
|
525
|
+
return path_curve_to_quadratic_bezier_smooth(obj, x, y, DrawPathCurveToQuadraticBezierSmoothAbsolute);
|
526
|
+
}
|
527
|
+
|
528
|
+
|
529
|
+
|
530
|
+
|
531
|
+
/*
|
532
|
+
* path.curve_to_quadratic_bezier_smooth_relative(x, y)
|
533
|
+
*/
|
534
|
+
static VALUE drawing_path_curve_to_quadratic_bezier_smooth_relative(VALUE obj, VALUE x, VALUE y)
|
535
|
+
{
|
536
|
+
return path_curve_to_quadratic_bezier_smooth(obj, x, y, DrawPathCurveToQuadraticBezierSmoothRelative);
|
537
|
+
}
|
538
|
+
|
539
|
+
|
540
|
+
|
541
|
+
|
542
|
+
static VALUE path_curve_to_smooth(VALUE obj, VALUE x2, VALUE y2, VALUE x, VALUE y,
|
543
|
+
void (*f)(DrawingWand *, const double, const double, const double, const double))
|
544
|
+
{
|
545
|
+
Drawing *drawing;
|
546
|
+
|
547
|
+
rb_check_frozen(obj);
|
548
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
549
|
+
(*f)(drawing->wand, NUM2DBL(x2), NUM2DBL(y2), NUM2DBL(x), NUM2DBL(y));
|
550
|
+
mwr_check_drawingwand_error(drawing->wand);
|
551
|
+
return obj;
|
552
|
+
}
|
553
|
+
|
554
|
+
|
555
|
+
|
556
|
+
|
557
|
+
/*
|
558
|
+
* path.curve_to_smooth_absolute(x2, y2, x, y)
|
559
|
+
*/
|
560
|
+
static VALUE drawing_path_curve_to_smooth_absolute(VALUE obj, VALUE x2, VALUE y2, VALUE x, VALUE y)
|
561
|
+
{
|
562
|
+
return path_curve_to_smooth(obj, x2, y2, x, y, DrawPathCurveToSmoothAbsolute);
|
563
|
+
}
|
564
|
+
|
565
|
+
|
566
|
+
|
567
|
+
|
568
|
+
/*
|
569
|
+
* path.curve_to_smooth_relative(x2, y2, x, y)
|
570
|
+
*/
|
571
|
+
static VALUE drawing_path_curve_to_smooth_relative(VALUE obj, VALUE x2, VALUE y2, VALUE x, VALUE y)
|
572
|
+
{
|
573
|
+
return path_curve_to_smooth(obj, x2, y2, x, y, DrawPathCurveToSmoothRelative);
|
574
|
+
}
|
575
|
+
|
576
|
+
|
577
|
+
|
578
|
+
|
579
|
+
static VALUE path_elliptic_arc(VALUE obj, VALUE rx, VALUE ry,
|
580
|
+
VALUE x_axis_rotation, VALUE large_arc_flag, VALUE sweep_flag, VALUE x, VALUE y,
|
581
|
+
void (*f)(DrawingWand *, const double, const double, const double,
|
582
|
+
MagickBooleanType, MagickBooleanType, const double, const double))
|
583
|
+
{
|
584
|
+
Drawing *drawing;
|
585
|
+
|
586
|
+
rb_check_frozen(obj);
|
587
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
588
|
+
(*f)(drawing->wand, NUM2DBL(rx), NUM2DBL(ry), NUM2DBL(x_axis_rotation),
|
589
|
+
RTEST(large_arc_flag), RTEST(sweep_flag), NUM2DBL(x), NUM2DBL(y));
|
590
|
+
mwr_check_drawingwand_error(drawing->wand);
|
591
|
+
return obj;
|
592
|
+
}
|
593
|
+
|
594
|
+
|
595
|
+
|
596
|
+
|
597
|
+
/*
|
598
|
+
* path.elliptic_arc_absolute(rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
|
599
|
+
*/
|
600
|
+
static VALUE drawing_path_elliptic_arc_absolute(VALUE obj, VALUE rx, VALUE ry,
|
601
|
+
VALUE x_axis_rotation, VALUE large_arc_flag, VALUE sweep_flag, VALUE x, VALUE y)
|
602
|
+
{
|
603
|
+
return path_elliptic_arc(obj, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y,
|
604
|
+
DrawPathEllipticArcAbsolute);
|
605
|
+
}
|
606
|
+
|
607
|
+
|
608
|
+
|
609
|
+
|
610
|
+
/*
|
611
|
+
* path.elliptic_arc_relative(rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
|
612
|
+
*/
|
613
|
+
static VALUE drawing_path_elliptic_arc_relative(VALUE obj, VALUE rx, VALUE ry,
|
614
|
+
VALUE x_axis_rotation, VALUE large_arc_flag, VALUE sweep_flag, VALUE x, VALUE y)
|
615
|
+
{
|
616
|
+
return path_elliptic_arc(obj, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y,
|
617
|
+
DrawPathEllipticArcRelative);
|
618
|
+
}
|
619
|
+
|
620
|
+
|
621
|
+
|
622
|
+
|
623
|
+
static VALUE path_line_to(VALUE obj, VALUE x, VALUE y,
|
624
|
+
void (*f)(DrawingWand *, const double, const double))
|
625
|
+
{
|
626
|
+
Drawing *drawing;
|
627
|
+
|
628
|
+
rb_check_frozen(obj);
|
629
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
630
|
+
(*f)(drawing->wand, NUM2DBL(x), NUM2DBL(y));
|
631
|
+
mwr_check_drawingwand_error(drawing->wand);
|
632
|
+
return obj;
|
633
|
+
}
|
634
|
+
|
635
|
+
|
636
|
+
|
637
|
+
|
638
|
+
/*
|
639
|
+
* path.line_to_relative(x, y)
|
640
|
+
*/
|
641
|
+
static VALUE drawing_path_line_to_relative(VALUE obj, VALUE x, VALUE y)
|
642
|
+
{
|
643
|
+
return path_line_to(obj, x, y, DrawPathLineToRelative);
|
644
|
+
}
|
645
|
+
|
646
|
+
|
647
|
+
|
648
|
+
|
649
|
+
/*
|
650
|
+
* path.line_to_absolute(x, y)
|
651
|
+
*/
|
652
|
+
static VALUE drawing_path_line_to_absolute(VALUE obj, VALUE x, VALUE y)
|
653
|
+
{
|
654
|
+
return path_line_to(obj, x, y, DrawPathLineToAbsolute);
|
655
|
+
}
|
656
|
+
|
657
|
+
|
658
|
+
|
659
|
+
|
660
|
+
static VALUE path_line_to_direction(VALUE obj, VALUE coord,
|
661
|
+
void (*f)(DrawingWand *, const double))
|
662
|
+
{
|
663
|
+
Drawing *drawing;
|
664
|
+
|
665
|
+
rb_check_frozen(obj);
|
666
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
667
|
+
(*f)(drawing->wand, NUM2DBL(coord));
|
668
|
+
mwr_check_drawingwand_error(drawing->wand);
|
669
|
+
return obj;
|
670
|
+
}
|
671
|
+
|
672
|
+
|
673
|
+
|
674
|
+
|
675
|
+
/*
|
676
|
+
* path.line_to_horizontal_absolute(x)
|
677
|
+
*/
|
678
|
+
static VALUE drawing_path_line_to_horizontal_absolute(VALUE obj, VALUE x)
|
679
|
+
{
|
680
|
+
return path_line_to_direction(obj, x, DrawPathLineToHorizontalAbsolute);
|
681
|
+
}
|
682
|
+
|
683
|
+
|
684
|
+
|
685
|
+
|
686
|
+
/*
|
687
|
+
* path.line_to_horizontal_relative(x)
|
688
|
+
*/
|
689
|
+
static VALUE drawing_path_line_to_horizontal_relative(VALUE obj, VALUE x)
|
690
|
+
{
|
691
|
+
return path_line_to_direction(obj, x, DrawPathLineToHorizontalRelative);
|
692
|
+
}
|
693
|
+
|
694
|
+
|
695
|
+
|
696
|
+
|
697
|
+
/*
|
698
|
+
* path.line_to_vertical_absolute(y)
|
699
|
+
*/
|
700
|
+
static VALUE drawing_path_line_to_vertical_absolute(VALUE obj, VALUE y)
|
701
|
+
{
|
702
|
+
return path_line_to_direction(obj, y, DrawPathLineToVerticalAbsolute);
|
703
|
+
}
|
704
|
+
|
705
|
+
|
706
|
+
|
707
|
+
|
708
|
+
/*
|
709
|
+
* path.line_to_vertical_relative(y)
|
710
|
+
*/
|
711
|
+
static VALUE drawing_path_line_to_vertical_relative(VALUE obj, VALUE y)
|
712
|
+
{
|
713
|
+
return path_line_to_direction(obj, y, DrawPathLineToVerticalRelative);
|
714
|
+
}
|
715
|
+
|
716
|
+
|
717
|
+
|
718
|
+
|
719
|
+
/*
|
720
|
+
* path.move_to_absolute(x, y)
|
721
|
+
*/
|
722
|
+
static VALUE drawing_path_move_to_absolute(VALUE obj, VALUE x, VALUE y)
|
723
|
+
{
|
724
|
+
return path_line_to(obj, x, y, DrawPathMoveToAbsolute);
|
725
|
+
}
|
726
|
+
|
727
|
+
|
728
|
+
|
729
|
+
|
730
|
+
/*
|
731
|
+
* path.move_to_relative(x, y)
|
732
|
+
*/
|
733
|
+
static VALUE drawing_path_move_to_relative(VALUE obj, VALUE x, VALUE y)
|
734
|
+
{
|
735
|
+
return path_line_to(obj, x, y, DrawPathMoveToRelative);
|
736
|
+
}
|
737
|
+
|
738
|
+
|
739
|
+
|
740
|
+
|
741
|
+
/*
|
742
|
+
* private:
|
743
|
+
* self.finish_path()
|
744
|
+
*/
|
745
|
+
static VALUE drawing_path_finish(VALUE obj)
|
746
|
+
{
|
747
|
+
Drawing *drawing;
|
748
|
+
|
749
|
+
rb_check_frozen(obj);
|
750
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
751
|
+
DrawPathFinish(drawing->wand);
|
752
|
+
mwr_check_drawingwand_error(drawing->wand);
|
753
|
+
return obj;
|
754
|
+
}
|
755
|
+
|
756
|
+
|
757
|
+
|
758
|
+
|
759
|
+
/*
|
760
|
+
* private:
|
761
|
+
* self.start_path()
|
762
|
+
*/
|
763
|
+
static VALUE drawing_path_start(VALUE obj)
|
764
|
+
{
|
765
|
+
Drawing *drawing;
|
766
|
+
|
767
|
+
rb_check_frozen(obj);
|
768
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
769
|
+
DrawPathStart(drawing->wand);
|
770
|
+
mwr_check_drawingwand_error(drawing->wand);
|
771
|
+
return obj;
|
772
|
+
}
|
773
|
+
|
774
|
+
|
775
|
+
static VALUE polyshape(int argc, VALUE *argv, VALUE obj,
|
776
|
+
void (*f)(DrawingWand *, const unsigned long, const PointInfo *))
|
777
|
+
{
|
778
|
+
Drawing *drawing;
|
779
|
+
int x;
|
780
|
+
unsigned long number_coordinates, n;
|
781
|
+
PointInfo *coordinates;
|
782
|
+
|
783
|
+
rb_check_frozen(obj);
|
784
|
+
|
785
|
+
if (argc % 2 != 0)
|
786
|
+
{
|
787
|
+
rb_raise(rb_eArgError, "coordinates must be x,y pairs (%d arguments given)", argc);
|
788
|
+
}
|
789
|
+
|
790
|
+
number_coordinates = argc / 2;
|
791
|
+
// Can't fail! Ruby will stop if there's not enough memory...
|
792
|
+
coordinates = (PointInfo *)AcquireQuantumMemory(number_coordinates, sizeof(PointInfo));
|
793
|
+
|
794
|
+
x = 0;
|
795
|
+
for (n = 0; n < number_coordinates; n++)
|
796
|
+
{
|
797
|
+
coordinates[n].x = NUM2DBL(argv[x++]);
|
798
|
+
coordinates[n].y = NUM2DBL(argv[x++]);
|
799
|
+
}
|
800
|
+
|
801
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
802
|
+
(*f)(drawing->wand, number_coordinates, coordinates);
|
803
|
+
RelinquishMagickMemory((void *)coordinates);
|
804
|
+
mwr_check_drawingwand_error(drawing->wand);
|
805
|
+
return obj;
|
806
|
+
|
807
|
+
}
|
808
|
+
|
809
|
+
|
810
|
+
|
811
|
+
|
812
|
+
/*
|
813
|
+
* drawing.polygon(x1, y1, ..., xN, yN)
|
814
|
+
*/
|
815
|
+
static VALUE drawing_polygon(int argc, VALUE *argv, VALUE obj)
|
816
|
+
{
|
817
|
+
return polyshape(argc, argv, obj, DrawPolygon);
|
818
|
+
}
|
819
|
+
|
820
|
+
|
821
|
+
|
822
|
+
|
823
|
+
/*
|
824
|
+
* drawing.polyline(x1, y1, ..., xN, yN)
|
825
|
+
*/
|
826
|
+
static VALUE drawing_polyline(int argc, VALUE *argv, VALUE obj)
|
827
|
+
{
|
828
|
+
return polyshape(argc, argv, obj, DrawPolyline);
|
829
|
+
}
|
830
|
+
|
831
|
+
|
832
|
+
|
833
|
+
|
834
|
+
/*
|
835
|
+
* drawing.pop()
|
836
|
+
* drawing.pop("graphics-context")
|
837
|
+
* drawing.pop("defs")
|
838
|
+
* drawing.pop("clip_path")
|
839
|
+
* drawing.pop("pattern")
|
840
|
+
*/
|
841
|
+
static VALUE drawing_pop(int argc, VALUE *argv, VALUE obj)
|
842
|
+
{
|
843
|
+
Drawing *drawing;
|
844
|
+
VALUE thing;
|
845
|
+
char *what;
|
846
|
+
|
847
|
+
rb_check_frozen(obj);
|
848
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
849
|
+
|
850
|
+
(void)rb_scan_args(argc, argv, "01", &thing);
|
851
|
+
if (thing == Qnil)
|
852
|
+
{
|
853
|
+
PopDrawingWand(drawing->wand);
|
854
|
+
}
|
855
|
+
else
|
856
|
+
{
|
857
|
+
what = StringValuePtr(thing);
|
858
|
+
if (strcmp(what, "graphics_context") == 0)
|
859
|
+
{
|
860
|
+
PopDrawingWand(drawing->wand);
|
861
|
+
}
|
862
|
+
else if (strcmp(what, "defs") == 0)
|
863
|
+
{
|
864
|
+
DrawPopDefs(drawing->wand);
|
865
|
+
}
|
866
|
+
else if (strcmp(what, "clip_path") == 0)
|
867
|
+
{
|
868
|
+
DrawPopClipPath(drawing->wand);
|
869
|
+
}
|
870
|
+
else if (strcmp(what, "pattern") == 0)
|
871
|
+
{
|
872
|
+
DrawPopPattern(drawing->wand);
|
873
|
+
}
|
874
|
+
else
|
875
|
+
{
|
876
|
+
rb_raise(rb_eArgError, "don't know how to pop `%s'", what);
|
877
|
+
}
|
878
|
+
}
|
879
|
+
|
880
|
+
mwr_check_drawingwand_error(drawing->wand);
|
881
|
+
|
882
|
+
return obj;
|
883
|
+
}
|
884
|
+
|
885
|
+
|
886
|
+
|
887
|
+
|
888
|
+
/*
|
889
|
+
* drawing.push()
|
890
|
+
* drawing.push("graphics-context")
|
891
|
+
* drawing.push("defs")
|
892
|
+
* drawing.push("clip_path", name)
|
893
|
+
* drawing.push("pattern", name, :x=>0, :y=>0, :width=>0, :height=>0)
|
894
|
+
*/
|
895
|
+
static VALUE drawing_push(int argc, VALUE *argv, VALUE obj)
|
896
|
+
{
|
897
|
+
Drawing *drawing;
|
898
|
+
VALUE thing, arg2, v, options;
|
899
|
+
char *what, *name = NULL;
|
900
|
+
double x, y, width, height;
|
901
|
+
|
902
|
+
rb_check_frozen(obj);
|
903
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
904
|
+
|
905
|
+
(void)rb_scan_args(argc, argv, "03", &thing, &arg2, &options);
|
906
|
+
if (thing == Qnil)
|
907
|
+
{
|
908
|
+
PushDrawingWand(drawing->wand);
|
909
|
+
}
|
910
|
+
else
|
911
|
+
{
|
912
|
+
what = StringValuePtr(thing);
|
913
|
+
if (strcmp(what, "graphics_context") == 0)
|
914
|
+
{
|
915
|
+
PushDrawingWand(drawing->wand);
|
916
|
+
}
|
917
|
+
else if (strcmp(what, "defs") == 0)
|
918
|
+
{
|
919
|
+
DrawPushDefs(drawing->wand);
|
920
|
+
}
|
921
|
+
else if (strcmp(what, "clip_path") == 0)
|
922
|
+
{
|
923
|
+
name = StringValuePtr(arg2);
|
924
|
+
DrawPushClipPath(drawing->wand, name);
|
925
|
+
}
|
926
|
+
else if (strcmp(what, "pattern") == 0)
|
927
|
+
{
|
928
|
+
name = StringValuePtr(arg2);
|
929
|
+
x = mwr_get_option(options, "x", &v) ? NUM2DBL(v) : 0.0;
|
930
|
+
y = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
931
|
+
width = mwr_get_option(options, "width", &v) ? NUM2DBL(v) : 0.0;
|
932
|
+
height = mwr_get_option(options, "height", &v) ? NUM2DBL(v) : 0.0;
|
933
|
+
DrawPushPattern(drawing->wand, name, x, y, width, height);
|
934
|
+
}
|
935
|
+
else
|
936
|
+
{
|
937
|
+
rb_raise(rb_eArgError, "don't know how to push `%s'", what);
|
938
|
+
}
|
939
|
+
}
|
940
|
+
|
941
|
+
mwr_check_drawingwand_error(drawing->wand);
|
942
|
+
|
943
|
+
return obj;
|
944
|
+
}
|
945
|
+
|
946
|
+
|
947
|
+
|
948
|
+
|
949
|
+
/*
|
950
|
+
* drawing.rectangle(width, height, :x=>0, :y=>0, :rx=>0, :ry=>rx)
|
951
|
+
*/
|
952
|
+
static VALUE drawing_rectangle(int argc, VALUE *argv, VALUE obj)
|
953
|
+
{
|
954
|
+
Drawing *drawing;
|
955
|
+
VALUE v, w, h, options;
|
956
|
+
double x1, y1, x2, y2, rx, ry;
|
957
|
+
double width, height;
|
958
|
+
|
959
|
+
rb_check_frozen(obj);
|
960
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
961
|
+
|
962
|
+
(void)rb_scan_args(argc, argv, "21", &w, &h, &options);
|
963
|
+
width = NUM2DBL(w);
|
964
|
+
height = NUM2DBL(h);
|
965
|
+
x1 = mwr_get_option(options, "x", &v) ? NUM2DBL(v) : 0.0;
|
966
|
+
y1 = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
967
|
+
x2 = x1 + width;
|
968
|
+
y2 = y1 + height;
|
969
|
+
|
970
|
+
rx = mwr_get_option(options, "rx", &v) ? NUM2DBL(v) : 0.0;
|
971
|
+
ry = mwr_get_option(options, "ry", &v) ? NUM2DBL(v) : rx;
|
972
|
+
|
973
|
+
if (rx == 0.0 && ry != 0.0)
|
974
|
+
{
|
975
|
+
rb_raise(rb_eArgError, "When y corner radius is non-0 the x corner radius must also be non-0 (:ry=>%g)", ry);
|
976
|
+
}
|
977
|
+
|
978
|
+
if (rx == 0.0 && ry == 0.0)
|
979
|
+
{
|
980
|
+
DrawRectangle(drawing->wand, x1, y1, x2, y2);
|
981
|
+
}
|
982
|
+
else
|
983
|
+
{
|
984
|
+
DrawRoundRectangle(drawing->wand, x1, y1, x2, y2, rx, ry);
|
985
|
+
}
|
986
|
+
mwr_check_drawingwand_error(drawing->wand);
|
987
|
+
|
988
|
+
return obj;
|
989
|
+
}
|
990
|
+
|
991
|
+
|
992
|
+
|
993
|
+
|
994
|
+
/*
|
995
|
+
* drawing.rotate(angle, x=0, y=0)
|
996
|
+
*/
|
997
|
+
static VALUE drawing_rotate(int argc, VALUE *argv, VALUE obj)
|
998
|
+
{
|
999
|
+
Drawing *drawing;
|
1000
|
+
VALUE angle, x, y;
|
1001
|
+
double degrees, cx = 0.0, cy = 0.0;
|
1002
|
+
|
1003
|
+
rb_check_frozen(obj);
|
1004
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1005
|
+
|
1006
|
+
(void)rb_scan_args(argc, argv, "12", &angle, &x, &y);
|
1007
|
+
degrees = NUM2DBL(angle);
|
1008
|
+
cx = !NIL_P(x) ? NUM2DBL(x) : 0.0;
|
1009
|
+
cy = !NIL_P(y) ? NUM2DBL(y) : 0.0;
|
1010
|
+
|
1011
|
+
if (cx != 0.0 || cy != 0.0)
|
1012
|
+
{
|
1013
|
+
DrawTranslate(drawing->wand, cx, cy);
|
1014
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1015
|
+
}
|
1016
|
+
DrawRotate(drawing->wand, degrees);
|
1017
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1018
|
+
if (cx != 0.0 || cy != 0.0)
|
1019
|
+
{
|
1020
|
+
DrawTranslate(drawing->wand, -cx, -cy);
|
1021
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
return obj;
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
|
1028
|
+
|
1029
|
+
/*
|
1030
|
+
* drawing.scale(sx[, sy=sx])
|
1031
|
+
*/
|
1032
|
+
static VALUE drawing_scale(int argc, VALUE *argv, VALUE obj)
|
1033
|
+
{
|
1034
|
+
Drawing *drawing;
|
1035
|
+
VALUE x, y;
|
1036
|
+
double sx, sy;
|
1037
|
+
|
1038
|
+
rb_check_frozen(obj);
|
1039
|
+
|
1040
|
+
(void)rb_scan_args(argc, argv, "11", &x, &y);
|
1041
|
+
sx = NUM2DBL(x);
|
1042
|
+
sy = (y == Qnil) ? sx : NUM2DBL(y);
|
1043
|
+
|
1044
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1045
|
+
DrawScale(drawing->wand, sx, sy);
|
1046
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1047
|
+
return obj;
|
1048
|
+
}
|
1049
|
+
|
1050
|
+
|
1051
|
+
|
1052
|
+
|
1053
|
+
/*
|
1054
|
+
* :align => string
|
1055
|
+
* set text alignment
|
1056
|
+
*/
|
1057
|
+
static VALUE drawing_set_align(VALUE obj, VALUE align)
|
1058
|
+
{
|
1059
|
+
Drawing *drawing;
|
1060
|
+
AlignType type;
|
1061
|
+
|
1062
|
+
rb_check_frozen(obj);
|
1063
|
+
type = mwr_string_to_aligntype(align, LeftAlign, RaiseUndefinedOption);
|
1064
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1065
|
+
DrawSetTextAlignment(drawing->wand, type);
|
1066
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1067
|
+
return obj;
|
1068
|
+
}
|
1069
|
+
|
1070
|
+
|
1071
|
+
|
1072
|
+
|
1073
|
+
|
1074
|
+
/*
|
1075
|
+
* :antialias => boolean
|
1076
|
+
* turn text antialias on or off
|
1077
|
+
*/
|
1078
|
+
static VALUE drawing_set_antialias(VALUE obj, VALUE antialias)
|
1079
|
+
{
|
1080
|
+
Drawing *drawing;
|
1081
|
+
|
1082
|
+
rb_check_frozen(obj);
|
1083
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1084
|
+
DrawSetTextAntialias(drawing->wand, RTEST(antialias) ? MagickTrue : MagickFalse);
|
1085
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1086
|
+
return obj;
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
|
1090
|
+
|
1091
|
+
|
1092
|
+
/*
|
1093
|
+
* :decoration => string
|
1094
|
+
*/
|
1095
|
+
static VALUE drawing_set_decoration(VALUE obj, VALUE decoration)
|
1096
|
+
{
|
1097
|
+
Drawing *drawing;
|
1098
|
+
DecorationType type;
|
1099
|
+
|
1100
|
+
rb_check_frozen(obj);
|
1101
|
+
type = mwr_string_to_decorationtype(decoration, NoDecoration, RaiseUndefinedOption);
|
1102
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1103
|
+
DrawSetTextDecoration(drawing->wand, type);
|
1104
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1105
|
+
return obj;
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
|
1109
|
+
|
1110
|
+
|
1111
|
+
/*
|
1112
|
+
* :encoding => string
|
1113
|
+
*/
|
1114
|
+
static VALUE drawing_set_encoding(VALUE obj, VALUE encoding)
|
1115
|
+
{
|
1116
|
+
Drawing *drawing;
|
1117
|
+
|
1118
|
+
rb_check_frozen(obj);
|
1119
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1120
|
+
DrawSetTextEncoding(drawing->wand, StringValuePtr(encoding));
|
1121
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1122
|
+
return obj;
|
1123
|
+
}
|
1124
|
+
|
1125
|
+
|
1126
|
+
|
1127
|
+
/*
|
1128
|
+
* :family => string
|
1129
|
+
*/
|
1130
|
+
static VALUE drawing_set_family(VALUE obj, VALUE family)
|
1131
|
+
{
|
1132
|
+
Drawing *drawing;
|
1133
|
+
|
1134
|
+
rb_check_frozen(obj);
|
1135
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1136
|
+
DrawSetFontFamily(drawing->wand, StringValuePtr(family));
|
1137
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1138
|
+
return obj;
|
1139
|
+
}
|
1140
|
+
|
1141
|
+
|
1142
|
+
|
1143
|
+
|
1144
|
+
/*
|
1145
|
+
* :fill => string
|
1146
|
+
*/
|
1147
|
+
static VALUE drawing_set_fill(VALUE obj, VALUE fill)
|
1148
|
+
{
|
1149
|
+
Drawing *drawing;
|
1150
|
+
PixelWand *pixelwand;
|
1151
|
+
|
1152
|
+
rb_check_frozen(obj);
|
1153
|
+
pixelwand = NewPixelWand();
|
1154
|
+
|
1155
|
+
PixelSetColor(pixelwand, StringValuePtr(fill));
|
1156
|
+
mwr_check_pixelwand_error(pixelwand);
|
1157
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1158
|
+
DrawSetFillColor(drawing->wand, pixelwand);
|
1159
|
+
pixelwand = DestroyPixelWand(pixelwand);
|
1160
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1161
|
+
return obj;
|
1162
|
+
}
|
1163
|
+
|
1164
|
+
|
1165
|
+
|
1166
|
+
|
1167
|
+
/*
|
1168
|
+
* :fill_opacity => float
|
1169
|
+
*/
|
1170
|
+
static VALUE drawing_set_fill_opacity(VALUE obj, VALUE fill_opacity)
|
1171
|
+
{
|
1172
|
+
Drawing *drawing;
|
1173
|
+
double opacity;
|
1174
|
+
|
1175
|
+
rb_check_frozen(obj);
|
1176
|
+
opacity = NUM2DBL(fill_opacity);
|
1177
|
+
if (opacity < 0.0)
|
1178
|
+
{
|
1179
|
+
opacity = 0.0;
|
1180
|
+
}
|
1181
|
+
else if (opacity > 1.0)
|
1182
|
+
{
|
1183
|
+
opacity = 1.0;
|
1184
|
+
}
|
1185
|
+
|
1186
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1187
|
+
DrawSetFillOpacity(drawing->wand, opacity);
|
1188
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1189
|
+
return obj;
|
1190
|
+
}
|
1191
|
+
|
1192
|
+
|
1193
|
+
|
1194
|
+
|
1195
|
+
/*
|
1196
|
+
* :font => string
|
1197
|
+
*/
|
1198
|
+
static VALUE drawing_set_font(VALUE obj, VALUE font)
|
1199
|
+
{
|
1200
|
+
Drawing *drawing;
|
1201
|
+
|
1202
|
+
rb_check_frozen(obj);
|
1203
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1204
|
+
DrawSetFont(drawing->wand, StringValuePtr(font));
|
1205
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1206
|
+
return obj;
|
1207
|
+
}
|
1208
|
+
|
1209
|
+
|
1210
|
+
|
1211
|
+
|
1212
|
+
/*
|
1213
|
+
* :gravity => string
|
1214
|
+
*/
|
1215
|
+
static VALUE drawing_set_gravity(VALUE obj, VALUE gravity)
|
1216
|
+
{
|
1217
|
+
Drawing *drawing;
|
1218
|
+
GravityType type;
|
1219
|
+
|
1220
|
+
rb_check_frozen(obj);
|
1221
|
+
type = mwr_string_to_gravitytype(gravity, NorthWestGravity, RaiseUndefinedOption);
|
1222
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1223
|
+
DrawSetGravity(drawing->wand, type);
|
1224
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1225
|
+
return obj;
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
|
1229
|
+
|
1230
|
+
|
1231
|
+
/*
|
1232
|
+
* :interword_spacing => float
|
1233
|
+
*/
|
1234
|
+
static VALUE drawing_set_interword_spacing(VALUE obj, VALUE interword_spacing)
|
1235
|
+
{
|
1236
|
+
Drawing *drawing;
|
1237
|
+
|
1238
|
+
rb_check_frozen(obj);
|
1239
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1240
|
+
DrawSetTextInterwordSpacing(drawing->wand, NUM2DBL(interword_spacing));
|
1241
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1242
|
+
return obj;
|
1243
|
+
}
|
1244
|
+
|
1245
|
+
|
1246
|
+
|
1247
|
+
|
1248
|
+
/*
|
1249
|
+
* :kerning => float
|
1250
|
+
*/
|
1251
|
+
static VALUE drawing_set_kerning(VALUE obj, VALUE kerning)
|
1252
|
+
{
|
1253
|
+
Drawing *drawing;
|
1254
|
+
|
1255
|
+
rb_check_frozen(obj);
|
1256
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1257
|
+
DrawSetTextKerning(drawing->wand, NUM2DBL(kerning));
|
1258
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1259
|
+
return obj;
|
1260
|
+
}
|
1261
|
+
|
1262
|
+
|
1263
|
+
|
1264
|
+
|
1265
|
+
/*
|
1266
|
+
* :pointsize => float
|
1267
|
+
*/
|
1268
|
+
static VALUE drawing_set_pointsize(VALUE obj, VALUE pointsize)
|
1269
|
+
{
|
1270
|
+
Drawing *drawing;
|
1271
|
+
|
1272
|
+
rb_check_frozen(obj);
|
1273
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1274
|
+
DrawSetFontSize(drawing->wand, NUM2DBL(pointsize));
|
1275
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1276
|
+
return obj;
|
1277
|
+
}
|
1278
|
+
|
1279
|
+
|
1280
|
+
|
1281
|
+
|
1282
|
+
/*
|
1283
|
+
* :stretch => string
|
1284
|
+
*/
|
1285
|
+
static VALUE drawing_set_stretch(VALUE obj, VALUE stretch)
|
1286
|
+
{
|
1287
|
+
Drawing *drawing;
|
1288
|
+
StretchType type;
|
1289
|
+
|
1290
|
+
rb_check_frozen(obj);
|
1291
|
+
type = mwr_string_to_stretchtype(stretch, AnyStretch, RaiseUndefinedOption);
|
1292
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1293
|
+
DrawSetFontStretch(drawing->wand, type);
|
1294
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1295
|
+
return obj;
|
1296
|
+
}
|
1297
|
+
|
1298
|
+
|
1299
|
+
|
1300
|
+
/*
|
1301
|
+
* :stroke => string
|
1302
|
+
*/
|
1303
|
+
static VALUE drawing_set_stroke(VALUE obj, VALUE stroke)
|
1304
|
+
{
|
1305
|
+
Drawing *drawing;
|
1306
|
+
PixelWand *pixelwand;
|
1307
|
+
|
1308
|
+
rb_check_frozen(obj);
|
1309
|
+
pixelwand = NewPixelWand();
|
1310
|
+
|
1311
|
+
PixelSetColor(pixelwand, StringValuePtr(stroke));
|
1312
|
+
mwr_check_pixelwand_error(pixelwand);
|
1313
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1314
|
+
DrawSetStrokeColor(drawing->wand, pixelwand);
|
1315
|
+
pixelwand = DestroyPixelWand(pixelwand);
|
1316
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1317
|
+
return obj;
|
1318
|
+
}
|
1319
|
+
|
1320
|
+
|
1321
|
+
|
1322
|
+
|
1323
|
+
/*
|
1324
|
+
* :stroke_opacity => float
|
1325
|
+
*/
|
1326
|
+
static VALUE drawing_set_stroke_opacity(VALUE obj, VALUE stroke_opacity)
|
1327
|
+
{
|
1328
|
+
Drawing *drawing;
|
1329
|
+
double opacity;
|
1330
|
+
|
1331
|
+
rb_check_frozen(obj);
|
1332
|
+
opacity = NUM2DBL(stroke_opacity);
|
1333
|
+
if (opacity < 0.0)
|
1334
|
+
{
|
1335
|
+
opacity = 0.0;
|
1336
|
+
}
|
1337
|
+
else if (opacity > 1.0)
|
1338
|
+
{
|
1339
|
+
opacity = 1.0;
|
1340
|
+
}
|
1341
|
+
|
1342
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1343
|
+
DrawSetStrokeOpacity(drawing->wand, opacity);
|
1344
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1345
|
+
return obj;
|
1346
|
+
}
|
1347
|
+
|
1348
|
+
|
1349
|
+
|
1350
|
+
|
1351
|
+
/*
|
1352
|
+
* :stroke_width => float
|
1353
|
+
*/
|
1354
|
+
static VALUE drawing_set_stroke_width(VALUE obj, VALUE stroke_width)
|
1355
|
+
{
|
1356
|
+
Drawing *drawing;
|
1357
|
+
|
1358
|
+
rb_check_frozen(obj);
|
1359
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1360
|
+
DrawSetStrokeWidth(drawing->wand, NUM2DBL(stroke_width));
|
1361
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1362
|
+
return obj;
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
|
1366
|
+
|
1367
|
+
|
1368
|
+
/*
|
1369
|
+
* :style => string
|
1370
|
+
*/
|
1371
|
+
static VALUE drawing_set_style(VALUE obj, VALUE style)
|
1372
|
+
{
|
1373
|
+
Drawing *drawing;
|
1374
|
+
StyleType type;
|
1375
|
+
|
1376
|
+
rb_check_frozen(obj);
|
1377
|
+
type = mwr_string_to_styletype(style, NormalStyle, RaiseUndefinedOption);
|
1378
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1379
|
+
DrawSetFontStyle(drawing->wand, type);
|
1380
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1381
|
+
return obj;
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
|
1385
|
+
|
1386
|
+
|
1387
|
+
/*
|
1388
|
+
* :undercolor => string
|
1389
|
+
*/
|
1390
|
+
static VALUE drawing_set_undercolor(VALUE obj, VALUE undercolor)
|
1391
|
+
{
|
1392
|
+
Drawing *drawing;
|
1393
|
+
PixelWand *pixelwand;
|
1394
|
+
|
1395
|
+
rb_check_frozen(obj);
|
1396
|
+
pixelwand = NewPixelWand();
|
1397
|
+
|
1398
|
+
PixelSetColor(pixelwand, StringValuePtr(undercolor));
|
1399
|
+
mwr_check_pixelwand_error(pixelwand);
|
1400
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1401
|
+
DrawSetTextUnderColor(drawing->wand, pixelwand);
|
1402
|
+
pixelwand = DestroyPixelWand(pixelwand);
|
1403
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1404
|
+
return obj;
|
1405
|
+
}
|
1406
|
+
|
1407
|
+
|
1408
|
+
|
1409
|
+
|
1410
|
+
/*
|
1411
|
+
* :weight => fixnum
|
1412
|
+
*/
|
1413
|
+
static VALUE drawing_set_weight(VALUE obj, VALUE weight)
|
1414
|
+
{
|
1415
|
+
Drawing *drawing;
|
1416
|
+
unsigned long w;
|
1417
|
+
|
1418
|
+
rb_check_frozen(obj);
|
1419
|
+
if (TYPE(weight) == T_STRING)
|
1420
|
+
{
|
1421
|
+
w = mwr_string_to_weight(weight, 0, RaiseUndefinedOption);
|
1422
|
+
}
|
1423
|
+
else
|
1424
|
+
{
|
1425
|
+
w = FIX2ULONG(weight);
|
1426
|
+
}
|
1427
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1428
|
+
DrawSetFontWeight(drawing->wand, w);
|
1429
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1430
|
+
return obj;
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
|
1434
|
+
|
1435
|
+
|
1436
|
+
/*
|
1437
|
+
* drawing.skew(x, y=0.0)
|
1438
|
+
*/
|
1439
|
+
static VALUE drawing_skew(int argc, VALUE *argv, VALUE obj)
|
1440
|
+
{
|
1441
|
+
Drawing *drawing;
|
1442
|
+
VALUE x, y;
|
1443
|
+
double rx, ry;
|
1444
|
+
|
1445
|
+
rb_check_frozen(obj);
|
1446
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1447
|
+
|
1448
|
+
(void)rb_scan_args(argc, argv, "11", &x, &y);
|
1449
|
+
rx = NUM2DBL(x);
|
1450
|
+
ry = y != Qnil ? NUM2DBL(y) : 0.0;
|
1451
|
+
|
1452
|
+
if (rx != 0.0)
|
1453
|
+
{
|
1454
|
+
DrawSkewX(drawing->wand, rx);
|
1455
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1456
|
+
}
|
1457
|
+
if (ry != 0.0)
|
1458
|
+
{
|
1459
|
+
DrawSkewY(drawing->wand, ry);
|
1460
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
return obj;
|
1464
|
+
}
|
1465
|
+
|
1466
|
+
|
1467
|
+
|
1468
|
+
|
1469
|
+
/*
|
1470
|
+
* drawing.translate(tx, ty=0.0)
|
1471
|
+
*/
|
1472
|
+
static VALUE drawing_translate(int argc, VALUE *argv, VALUE obj)
|
1473
|
+
{
|
1474
|
+
Drawing *drawing;
|
1475
|
+
VALUE x, y;
|
1476
|
+
double tx, ty;
|
1477
|
+
|
1478
|
+
rb_check_frozen(obj);
|
1479
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1480
|
+
|
1481
|
+
(void)rb_scan_args(argc, argv, "11", &x, &y);
|
1482
|
+
tx = NUM2DBL(x);
|
1483
|
+
ty = (y != Qnil) ? NUM2DBL(y) : 0.0;
|
1484
|
+
|
1485
|
+
DrawTranslate(drawing->wand, tx, ty);
|
1486
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1487
|
+
return obj;
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
|
1491
|
+
|
1492
|
+
|
1493
|
+
/*
|
1494
|
+
* drawing.with(:clip_path=>"string")
|
1495
|
+
*/
|
1496
|
+
static VALUE drawing_with_clip_path(VALUE obj, VALUE clip_path)
|
1497
|
+
{
|
1498
|
+
Drawing *drawing;
|
1499
|
+
|
1500
|
+
rb_check_frozen(obj);
|
1501
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1502
|
+
|
1503
|
+
DrawSetClipPath(drawing->wand, StringValuePtr(clip_path));
|
1504
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1505
|
+
return obj;
|
1506
|
+
}
|
1507
|
+
|
1508
|
+
|
1509
|
+
|
1510
|
+
|
1511
|
+
static VALUE with_fill_rule(VALUE obj, VALUE fill_rule,
|
1512
|
+
void (*f)(DrawingWand *, const FillRule))
|
1513
|
+
{
|
1514
|
+
Drawing *drawing;
|
1515
|
+
FillRule rule;
|
1516
|
+
|
1517
|
+
rb_check_frozen(obj);
|
1518
|
+
rule = mwr_string_to_fillrule(fill_rule, NonZeroRule, RaiseUndefinedOption);
|
1519
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1520
|
+
(*f)(drawing->wand, rule);
|
1521
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1522
|
+
return obj;
|
1523
|
+
}
|
1524
|
+
|
1525
|
+
|
1526
|
+
|
1527
|
+
|
1528
|
+
/*
|
1529
|
+
* drawing.with(:clip_rule=>"rule")
|
1530
|
+
*/
|
1531
|
+
static VALUE drawing_with_clip_rule(VALUE obj, VALUE fill_rule)
|
1532
|
+
{
|
1533
|
+
return with_fill_rule(obj, fill_rule, DrawSetClipRule);
|
1534
|
+
}
|
1535
|
+
|
1536
|
+
|
1537
|
+
|
1538
|
+
|
1539
|
+
/*
|
1540
|
+
* drawing.with(:fill_rule=>"rule")
|
1541
|
+
*/
|
1542
|
+
static VALUE drawing_with_fill_rule(VALUE obj, VALUE fill_rule)
|
1543
|
+
{
|
1544
|
+
return with_fill_rule(obj, fill_rule, DrawSetFillRule);
|
1545
|
+
}
|
1546
|
+
|
1547
|
+
|
1548
|
+
|
1549
|
+
|
1550
|
+
/*
|
1551
|
+
* drawing.with(:clip_units=>"units")
|
1552
|
+
*/
|
1553
|
+
static VALUE drawing_with_clip_units(VALUE obj, VALUE units)
|
1554
|
+
{
|
1555
|
+
Drawing *drawing;
|
1556
|
+
ClipPathUnits clip_units;
|
1557
|
+
|
1558
|
+
rb_check_frozen(obj);
|
1559
|
+
clip_units = mwr_string_to_clip_units(units, UserSpaceOnUse, RaiseUndefinedOption);
|
1560
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1561
|
+
DrawSetClipUnits(drawing->wand, clip_units);
|
1562
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1563
|
+
return obj;
|
1564
|
+
}
|
1565
|
+
|
1566
|
+
|
1567
|
+
|
1568
|
+
|
1569
|
+
/*
|
1570
|
+
* drawing.with(:dash_array=>[n1,n2,n3...]
|
1571
|
+
*/
|
1572
|
+
static VALUE drawing_with_dash_array(int argc, VALUE *argv, VALUE obj)
|
1573
|
+
{
|
1574
|
+
Drawing *drawing;
|
1575
|
+
unsigned long n, nelements;
|
1576
|
+
double *dash_array;
|
1577
|
+
|
1578
|
+
rb_check_frozen(obj);
|
1579
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1580
|
+
|
1581
|
+
if (argc == 0 || (argc == 1 && argv[0] == Qnil))
|
1582
|
+
{
|
1583
|
+
DrawSetStrokeDashArray(drawing->wand, 0, NULL);
|
1584
|
+
}
|
1585
|
+
else
|
1586
|
+
{
|
1587
|
+
nelements = argc;
|
1588
|
+
dash_array = ALLOC_N(double, argc);
|
1589
|
+
for (n = 0; n < nelements; n++)
|
1590
|
+
{
|
1591
|
+
dash_array[n] = NUM2DBL(argv[n]);
|
1592
|
+
}
|
1593
|
+
DrawSetStrokeDashArray(drawing->wand, nelements, dash_array);
|
1594
|
+
xfree(dash_array);
|
1595
|
+
}
|
1596
|
+
|
1597
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1598
|
+
return obj;
|
1599
|
+
}
|
1600
|
+
|
1601
|
+
|
1602
|
+
|
1603
|
+
|
1604
|
+
/*
|
1605
|
+
* drawing.with(:dash_offset=>d)
|
1606
|
+
*/
|
1607
|
+
static VALUE drawing_with_dash_offset(VALUE obj, VALUE offset)
|
1608
|
+
{
|
1609
|
+
Drawing *drawing;
|
1610
|
+
|
1611
|
+
rb_check_frozen(obj);
|
1612
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1613
|
+
|
1614
|
+
DrawSetStrokeDashOffset(drawing->wand, NUM2DBL(offset));
|
1615
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1616
|
+
return obj;
|
1617
|
+
}
|
1618
|
+
|
1619
|
+
|
1620
|
+
|
1621
|
+
|
1622
|
+
/*
|
1623
|
+
* drawing.with(:line_cap=>"cap")
|
1624
|
+
*/
|
1625
|
+
static VALUE drawing_with_line_cap(VALUE obj, VALUE cap)
|
1626
|
+
{
|
1627
|
+
Drawing *drawing;
|
1628
|
+
LineCap linecap;
|
1629
|
+
|
1630
|
+
rb_check_frozen(obj);
|
1631
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1632
|
+
|
1633
|
+
linecap = mwr_string_to_line_cap(cap, ButtCap, RaiseUndefinedOption);
|
1634
|
+
DrawSetStrokeLineCap(drawing->wand, linecap);
|
1635
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1636
|
+
return obj;
|
1637
|
+
}
|
1638
|
+
|
1639
|
+
|
1640
|
+
|
1641
|
+
|
1642
|
+
|
1643
|
+
/*
|
1644
|
+
* drawing.with(:line_join=>"join")
|
1645
|
+
*/
|
1646
|
+
static VALUE drawing_with_line_join(VALUE obj, VALUE join)
|
1647
|
+
{
|
1648
|
+
Drawing *drawing;
|
1649
|
+
LineJoin linejoin;
|
1650
|
+
|
1651
|
+
rb_check_frozen(obj);
|
1652
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1653
|
+
|
1654
|
+
linejoin = mwr_string_to_line_join(join, MiterJoin, RaiseUndefinedOption);
|
1655
|
+
DrawSetStrokeLineJoin(drawing->wand, linejoin);
|
1656
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1657
|
+
return obj;
|
1658
|
+
}
|
1659
|
+
|
1660
|
+
|
1661
|
+
|
1662
|
+
|
1663
|
+
/*
|
1664
|
+
* drawing.with(:miter_limit=>i)
|
1665
|
+
*/
|
1666
|
+
static VALUE drawing_with_miter_limit(VALUE obj, VALUE limit)
|
1667
|
+
{
|
1668
|
+
Drawing *drawing;
|
1669
|
+
|
1670
|
+
rb_check_frozen(obj);
|
1671
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1672
|
+
DrawSetStrokeMiterLimit(drawing->wand, NUM2ULONG(limit));
|
1673
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1674
|
+
return obj;
|
1675
|
+
}
|
1676
|
+
|
1677
|
+
|
1678
|
+
|
1679
|
+
/*
|
1680
|
+
* ImageMagick expects the pattern name to start with '#'
|
1681
|
+
*/
|
1682
|
+
static VALUE set_pattern_URL(VALUE obj, VALUE pattern,
|
1683
|
+
MagickBooleanType (*f)(DrawingWand *, const char *))
|
1684
|
+
{
|
1685
|
+
Drawing *drawing;
|
1686
|
+
volatile VALUE url;
|
1687
|
+
|
1688
|
+
rb_check_frozen(obj);
|
1689
|
+
url = rb_str_plus(rb_str_new2("#"), pattern);
|
1690
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1691
|
+
(*f)(drawing->wand, StringValuePtr(url));
|
1692
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1693
|
+
return obj;
|
1694
|
+
}
|
1695
|
+
|
1696
|
+
|
1697
|
+
|
1698
|
+
|
1699
|
+
/*
|
1700
|
+
* drawing.with(:fill_pattern=>"pattern")
|
1701
|
+
*/
|
1702
|
+
static VALUE drawing_with_fill_pattern(VALUE obj, VALUE pattern)
|
1703
|
+
{
|
1704
|
+
return set_pattern_URL(obj, pattern, DrawSetFillPatternURL);
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
|
1708
|
+
|
1709
|
+
|
1710
|
+
/*
|
1711
|
+
* drawing.with(:stroke_pattern=>"pattern")
|
1712
|
+
*/
|
1713
|
+
static VALUE drawing_with_stroke_pattern(VALUE obj, VALUE pattern)
|
1714
|
+
{
|
1715
|
+
return set_pattern_URL(obj, pattern, DrawSetStrokePatternURL);
|
1716
|
+
}
|
1717
|
+
|
1718
|
+
|
1719
|
+
|
1720
|
+
|
1721
|
+
/*
|
1722
|
+
* drawing.with(:stroke_antialias=>boolean)
|
1723
|
+
*/
|
1724
|
+
static VALUE drawing_with_stroke_antialias(VALUE obj, VALUE antialias)
|
1725
|
+
{
|
1726
|
+
Drawing *drawing;
|
1727
|
+
|
1728
|
+
rb_check_frozen(obj);
|
1729
|
+
Data_Get_Struct(obj, Drawing, drawing);
|
1730
|
+
DrawSetStrokeAntialias(drawing->wand, RTEST(antialias) ? MagickTrue : MagickFalse);
|
1731
|
+
mwr_check_drawingwand_error(drawing->wand);
|
1732
|
+
return obj;
|
1733
|
+
}
|
1734
|
+
|
1735
|
+
|
1736
|
+
|
1737
|
+
|
1738
|
+
/*
|
1739
|
+
* MagickWand::Drawing class
|
1740
|
+
*/
|
1741
|
+
void mwr_init_Drawing(void)
|
1742
|
+
{
|
1743
|
+
mwr_cDrawing = rb_define_class_under(mwr_mMagickWand, "Drawing", rb_cObject);
|
1744
|
+
rb_define_alloc_func(mwr_cDrawing, drawing_allocate);
|
1745
|
+
|
1746
|
+
|
1747
|
+
// Methods in Object that must be overridden per class
|
1748
|
+
rb_define_method(mwr_cDrawing, "initialize", drawing_initialize, 0);
|
1749
|
+
rb_define_method(mwr_cDrawing, "initialize_copy", drawing_initialize_copy, 1);
|
1750
|
+
rb_define_method(mwr_cDrawing, "inspect", drawing_inspect, 0);
|
1751
|
+
|
1752
|
+
|
1753
|
+
// Private property setters are called during 'annotate' option processing.
|
1754
|
+
rb_define_private_method(mwr_cDrawing, "set_align", drawing_set_align, 1);
|
1755
|
+
rb_define_private_method(mwr_cDrawing, "set_antialias", drawing_set_antialias, 1);
|
1756
|
+
rb_define_private_method(mwr_cDrawing, "set_decoration", drawing_set_decoration, 1);
|
1757
|
+
rb_define_private_method(mwr_cDrawing, "set_encoding", drawing_set_encoding, 1);
|
1758
|
+
rb_define_private_method(mwr_cDrawing, "set_family", drawing_set_family, 1);
|
1759
|
+
rb_define_private_method(mwr_cDrawing, "set_fill", drawing_set_fill, 1);
|
1760
|
+
rb_define_private_method(mwr_cDrawing, "set_fill_opacity", drawing_set_fill_opacity, 1);
|
1761
|
+
rb_define_private_method(mwr_cDrawing, "set_font", drawing_set_font, 1);
|
1762
|
+
rb_define_private_method(mwr_cDrawing, "set_gravity", drawing_set_gravity, 1);
|
1763
|
+
rb_define_private_method(mwr_cDrawing, "set_interword_spacing", drawing_set_interword_spacing, 1);
|
1764
|
+
rb_define_private_method(mwr_cDrawing, "set_kerning", drawing_set_kerning, 1);
|
1765
|
+
rb_define_private_method(mwr_cDrawing, "set_pointsize", drawing_set_pointsize, 1);
|
1766
|
+
rb_define_private_method(mwr_cDrawing, "set_stretch", drawing_set_stretch, 1);
|
1767
|
+
rb_define_private_method(mwr_cDrawing, "set_stroke", drawing_set_stroke, 1);
|
1768
|
+
rb_define_private_method(mwr_cDrawing, "set_stroke_opacity", drawing_set_stroke_opacity, 1);
|
1769
|
+
rb_define_private_method(mwr_cDrawing, "set_stroke_width", drawing_set_stroke_width, 1);
|
1770
|
+
rb_define_private_method(mwr_cDrawing, "set_style", drawing_set_style, 1);
|
1771
|
+
rb_define_private_method(mwr_cDrawing, "set_undercolor", drawing_set_undercolor, 1);
|
1772
|
+
rb_define_private_method(mwr_cDrawing, "set_weight", drawing_set_weight, 1);
|
1773
|
+
|
1774
|
+
rb_define_private_method(mwr_cDrawing, "finish_path", drawing_path_finish, 0);
|
1775
|
+
rb_define_private_method(mwr_cDrawing, "pop", drawing_pop, -1);
|
1776
|
+
rb_define_private_method(mwr_cDrawing, "push", drawing_push, -1);
|
1777
|
+
rb_define_private_method(mwr_cDrawing, "start_path", drawing_path_start, 0);
|
1778
|
+
|
1779
|
+
// Private style and transform primitive methods called from 'with'
|
1780
|
+
rb_define_private_method(mwr_cDrawing, "with_align", drawing_set_align, 1);
|
1781
|
+
rb_define_private_method(mwr_cDrawing, "with_antialias", drawing_set_antialias, 1);
|
1782
|
+
rb_define_private_method(mwr_cDrawing, "with_clip_path", drawing_with_clip_path, 1);
|
1783
|
+
rb_define_private_method(mwr_cDrawing, "with_clip_rule", drawing_with_clip_rule, 1);
|
1784
|
+
rb_define_private_method(mwr_cDrawing, "with_clip_units", drawing_with_clip_units, 1);
|
1785
|
+
rb_define_private_method(mwr_cDrawing, "with_decoration", drawing_set_decoration, 1);
|
1786
|
+
rb_define_private_method(mwr_cDrawing, "with_encoding", drawing_set_encoding, 1);
|
1787
|
+
rb_define_private_method(mwr_cDrawing, "with_family", drawing_set_family, 1);
|
1788
|
+
rb_define_private_method(mwr_cDrawing, "with_fill", drawing_set_fill, 1);
|
1789
|
+
rb_define_private_method(mwr_cDrawing, "with_fill_opacity", drawing_set_fill_opacity, 1);
|
1790
|
+
rb_define_private_method(mwr_cDrawing, "with_fill_pattern", drawing_with_fill_pattern, 1);
|
1791
|
+
rb_define_private_method(mwr_cDrawing, "with_fill_rule", drawing_with_fill_rule, 1);
|
1792
|
+
rb_define_private_method(mwr_cDrawing, "with_font", drawing_set_font, 1);
|
1793
|
+
rb_define_private_method(mwr_cDrawing, "with_gravity", drawing_set_gravity, 1);
|
1794
|
+
rb_define_private_method(mwr_cDrawing, "with_interword_spacing", drawing_set_interword_spacing, 1);
|
1795
|
+
rb_define_private_method(mwr_cDrawing, "with_kerning", drawing_set_kerning, 1);
|
1796
|
+
rb_define_private_method(mwr_cDrawing, "with_pointsize", drawing_set_pointsize, 1);
|
1797
|
+
rb_define_private_method(mwr_cDrawing, "with_stretch", drawing_set_stretch, 1);
|
1798
|
+
rb_define_private_method(mwr_cDrawing, "with_stroke", drawing_set_stroke, 1);
|
1799
|
+
rb_define_private_method(mwr_cDrawing, "with_stroke_antialias", drawing_with_stroke_antialias, 1);
|
1800
|
+
rb_define_private_method(mwr_cDrawing, "with_dash_array", drawing_with_dash_array, -1);
|
1801
|
+
rb_define_private_method(mwr_cDrawing, "with_dash_offset", drawing_with_dash_offset, 1);
|
1802
|
+
rb_define_private_method(mwr_cDrawing, "with_line_cap", drawing_with_line_cap, 1);
|
1803
|
+
rb_define_private_method(mwr_cDrawing, "with_line_join", drawing_with_line_join, 1);
|
1804
|
+
rb_define_private_method(mwr_cDrawing, "with_miter_limit", drawing_with_miter_limit, 1);
|
1805
|
+
rb_define_private_method(mwr_cDrawing, "with_stroke_opacity", drawing_set_stroke_opacity, 1);
|
1806
|
+
rb_define_private_method(mwr_cDrawing, "with_stroke_pattern", drawing_with_stroke_pattern, 1);
|
1807
|
+
rb_define_private_method(mwr_cDrawing, "with_stroke_width", drawing_set_stroke_width, 1);
|
1808
|
+
rb_define_private_method(mwr_cDrawing, "with_style", drawing_set_style, 1);
|
1809
|
+
rb_define_private_method(mwr_cDrawing, "with_undercolor", drawing_set_undercolor, 1);
|
1810
|
+
rb_define_private_method(mwr_cDrawing, "with_text_antialias", drawing_set_antialias, 1);
|
1811
|
+
rb_define_private_method(mwr_cDrawing, "with_weight", drawing_set_weight, 1);
|
1812
|
+
|
1813
|
+
// Drawing primitive methods
|
1814
|
+
rb_define_method(mwr_cDrawing, "affine", drawing_affine, 6);
|
1815
|
+
rb_define_method(mwr_cDrawing, "annotation", drawing_annotation, -1);
|
1816
|
+
rb_define_method(mwr_cDrawing, "arc", drawing_arc, -1);
|
1817
|
+
rb_define_method(mwr_cDrawing, "bezier", drawing_bezier, -1);
|
1818
|
+
rb_define_method(mwr_cDrawing, "circle", drawing_circle, -1);
|
1819
|
+
rb_define_method(mwr_cDrawing, "close_path", drawing_path_close, 0);
|
1820
|
+
rb_define_method(mwr_cDrawing, "color", drawing_color, -1);
|
1821
|
+
rb_define_method(mwr_cDrawing, "composite", drawing_composite, -1);
|
1822
|
+
rb_define_method(mwr_cDrawing, "curve_to_absolute", drawing_path_curve_to_absolute, 6);
|
1823
|
+
rb_define_method(mwr_cDrawing, "curve_to_relative", drawing_path_curve_to_relative, 6);
|
1824
|
+
rb_define_method(mwr_cDrawing, "curve_to_quadratic_bezier_absolute", drawing_path_curve_to_quadratic_bezier_absolute, 4);
|
1825
|
+
rb_define_method(mwr_cDrawing, "curve_to_quadratic_bezier_relative", drawing_path_curve_to_quadratic_bezier_relative, 4);
|
1826
|
+
rb_define_method(mwr_cDrawing, "curve_to_quadratic_bezier_smooth_absolute", drawing_path_curve_to_quadratic_bezier_smooth_absolute, 2);
|
1827
|
+
rb_define_method(mwr_cDrawing, "curve_to_quadratic_bezier_smooth_relative", drawing_path_curve_to_quadratic_bezier_smooth_relative, 2);
|
1828
|
+
rb_define_method(mwr_cDrawing, "curve_to_smooth_absolute", drawing_path_curve_to_smooth_absolute, 4);
|
1829
|
+
rb_define_method(mwr_cDrawing, "curve_to_smooth_relative", drawing_path_curve_to_smooth_relative, 4);
|
1830
|
+
rb_define_method(mwr_cDrawing, "elliptic_arc_absolute", drawing_path_elliptic_arc_absolute, 7);
|
1831
|
+
rb_define_method(mwr_cDrawing, "elliptic_arc_relative", drawing_path_elliptic_arc_relative, 7);
|
1832
|
+
rb_define_method(mwr_cDrawing, "ellipse", drawing_ellipse, -1);
|
1833
|
+
rb_define_method(mwr_cDrawing, "line", drawing_line, 4);
|
1834
|
+
rb_define_method(mwr_cDrawing, "line_to_absolute", drawing_path_line_to_absolute, 2);
|
1835
|
+
rb_define_method(mwr_cDrawing, "line_to_horizontal_absolute", drawing_path_line_to_horizontal_absolute, 1);
|
1836
|
+
rb_define_method(mwr_cDrawing, "line_to_horizontal_relative", drawing_path_line_to_horizontal_relative, 1);
|
1837
|
+
rb_define_method(mwr_cDrawing, "line_to_relative", drawing_path_line_to_relative, 2);
|
1838
|
+
rb_define_method(mwr_cDrawing, "line_to_vertical_absolute", drawing_path_line_to_vertical_absolute, 1);
|
1839
|
+
rb_define_method(mwr_cDrawing, "line_to_vertical_relative", drawing_path_line_to_vertical_relative, 1);
|
1840
|
+
rb_define_method(mwr_cDrawing, "matte", drawing_matte, -1);
|
1841
|
+
rb_define_method(mwr_cDrawing, "move_to_absolute", drawing_path_move_to_absolute, 2);
|
1842
|
+
rb_define_method(mwr_cDrawing, "move_to_relative", drawing_path_move_to_relative, 2);
|
1843
|
+
rb_define_method(mwr_cDrawing, "polygon", drawing_polygon, -1);
|
1844
|
+
rb_define_method(mwr_cDrawing, "polyline", drawing_polyline, -1);
|
1845
|
+
rb_define_method(mwr_cDrawing, "rectangle", drawing_rectangle, -1);
|
1846
|
+
rb_define_method(mwr_cDrawing, "rotate", drawing_rotate, -1);
|
1847
|
+
rb_define_method(mwr_cDrawing, "scale", drawing_scale, -1);
|
1848
|
+
rb_define_method(mwr_cDrawing, "skew", drawing_skew, -1);
|
1849
|
+
rb_define_method(mwr_cDrawing, "translate", drawing_translate, -1);
|
1850
|
+
}
|