magickwand 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require "rake/extensiontask"
2
2
 
3
3
  spec = Gem::Specification.new do |s|
4
4
  s.name = "magickwand"
5
- s.version = "0.1.0"
5
+ s.version = "0.2.0"
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.extensions = FileList["ext/magickwand/extconf.rb"]
8
8
  s.authors = ["Tim Hunter"]
@@ -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
+ }