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 +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/ext/magickwand/extconf.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
-
MAGICKWAND_VERSION = "0.
|
3
|
+
MAGICKWAND_VERSION = "0.2.0"
|
4
4
|
MIN_IM_VERS = "6.5.0"
|
5
5
|
MIN_IM_VERS_NO = MIN_IM_VERS.tr(".","").to_i
|
6
6
|
|
@@ -50,7 +50,8 @@ unless have_library("MagickWand", "MagickWandGenesis", headers)
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# ImageMagick features Release added
|
53
|
-
["
|
53
|
+
["DrawSetBorderColor", # 6.5.4
|
54
|
+
"MagickSetColorspace", # 6.5.1
|
54
55
|
"MagickSetImageFuzz" # 6.5.1
|
55
56
|
].each do |func|
|
56
57
|
have_func(func, headers)
|
data/ext/magickwand/magickwand.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* magickwand.c
|
3
|
-
* $Id: magickwand.c
|
3
|
+
* $Id: magickwand.c 164 2009-06-21 16:52:27Z rmagick $
|
4
4
|
* Copyright (C) 2009 Timothy Paul Hunter
|
5
5
|
*/
|
6
6
|
|
@@ -145,7 +145,7 @@ void Init_magickwand(void)
|
|
145
145
|
ImageMagick_config();
|
146
146
|
|
147
147
|
mwr_init_Wand();
|
148
|
-
|
148
|
+
mwr_init_Drawing();
|
149
149
|
mwr_init_ImageMagickError();
|
150
150
|
mwr_init_FatalImageMagickError();
|
151
151
|
|
data/ext/magickwand/magickwand.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* magickwand.h
|
3
|
-
* $Id: magickwand.h
|
3
|
+
* $Id: magickwand.h 285 2009-08-14 23:09:24Z rmagick $
|
4
4
|
* Copyright (C) 2009 Timothy Paul Hunter
|
5
5
|
*/
|
6
6
|
|
@@ -32,8 +32,8 @@ typedef struct
|
|
32
32
|
|
33
33
|
typedef struct
|
34
34
|
{
|
35
|
-
DrawingWand *
|
36
|
-
}
|
35
|
+
DrawingWand *wand;
|
36
|
+
} Drawing;
|
37
37
|
|
38
38
|
|
39
39
|
// What to do when an option value is not in the list of defined option values
|
@@ -48,7 +48,7 @@ typedef enum {
|
|
48
48
|
*/
|
49
49
|
VALUE mwr_mMagickWand;
|
50
50
|
VALUE mwr_cWand;
|
51
|
-
VALUE
|
51
|
+
VALUE mwr_cDrawing;
|
52
52
|
VALUE mwr_eImageMagickError;
|
53
53
|
VALUE mwr_eFatalImageMagickError;
|
54
54
|
|
@@ -56,7 +56,7 @@ VALUE mwr_eFatalImageMagickError;
|
|
56
56
|
/*
|
57
57
|
* Extern functions
|
58
58
|
*/
|
59
|
-
extern void
|
59
|
+
extern void mwr_init_Drawing(void);
|
60
60
|
extern void mwr_init_Wand(void);
|
61
61
|
extern void mwr_init_ImageMagickError(void);
|
62
62
|
extern void mwr_init_FatalImageMagickError(void);
|
@@ -67,18 +67,24 @@ extern void mwr_check_error(ExceptionInfo *);
|
|
67
67
|
extern MagickBooleanType mwr_get_option(VALUE, const char *, VALUE *);
|
68
68
|
extern char *mwr_imagetype_to_s(ImageType);
|
69
69
|
extern VALUE mwr_pixelpacket_to_hex(Image *, PixelPacket *);
|
70
|
+
extern VALUE mwr_pixelwand_to_hex(Image *, PixelWand *);
|
70
71
|
extern void mwr_option_value_error(const char *, const char *);
|
71
72
|
extern VALUE mwr_option_values_to_hash(char *);
|
72
73
|
extern AlignType mwr_string_to_aligntype(VALUE, AlignType, OnUndefinedOption);
|
73
74
|
extern ChannelType mwr_string_to_channeltype(VALUE, ChannelType, OnUndefinedOption);
|
75
|
+
extern ClipPathUnits mwr_string_to_clip_units(VALUE, ClipPathUnits, OnUndefinedOption);
|
74
76
|
extern ColorspaceType mwr_string_to_colorspacetype(VALUE, ColorspaceType, OnUndefinedOption);
|
75
77
|
extern CompositeOperator mwr_string_to_composetype(VALUE, CompositeOperator, OnUndefinedOption);
|
76
78
|
extern CompressionType mwr_string_to_compressiontype(VALUE, CompressionType, OnUndefinedOption);
|
77
79
|
extern DecorationType mwr_string_to_decorationtype(VALUE, DecorationType, OnUndefinedOption);
|
80
|
+
extern FillRule mwr_string_to_fillrule(VALUE, FillRule, OnUndefinedOption);
|
78
81
|
extern FilterTypes mwr_string_to_filtertypes(VALUE, FilterTypes, OnUndefinedOption);
|
79
82
|
extern GravityType mwr_string_to_gravitytype(VALUE, GravityType, OnUndefinedOption);
|
80
83
|
extern ImageType mwr_string_to_imagetype(VALUE, ImageType, OnUndefinedOption);
|
84
|
+
extern LineCap mwr_string_to_line_cap(VALUE, LineCap, OnUndefinedOption);
|
85
|
+
extern LineJoin mwr_string_to_line_join(VALUE, LineJoin, OnUndefinedOption);
|
81
86
|
extern MetricType mwr_string_to_metrictype(VALUE, MetricType, OnUndefinedOption);
|
87
|
+
extern PaintMethod mwr_string_to_paintmethod(VALUE, PaintMethod, OnUndefinedOption);
|
82
88
|
extern StorageType mwr_string_to_storagetype(VALUE, StorageType, OnUndefinedOption);
|
83
89
|
extern StretchType mwr_string_to_stretchtype(VALUE, StretchType, OnUndefinedOption);
|
84
90
|
extern StyleType mwr_string_to_styletype(VALUE, StyleType, OnUndefinedOption);
|
@@ -87,5 +93,5 @@ extern char *mwr_format_size(const MagickSizeType, char *);
|
|
87
93
|
extern void mwr_get_pixelpacket_from_pixelwand(PixelPacket *, PixelWand *);
|
88
94
|
extern void mwr_get_pixelwand_from_pixelpacket(PixelWand *, PixelPacket *);
|
89
95
|
extern void mwr_process_options(VALUE, VALUE);
|
90
|
-
extern VALUE
|
96
|
+
extern VALUE mwr_drawing_new(void);
|
91
97
|
#endif
|
data/ext/magickwand/utility.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
/*
|
3
3
|
* utility.c
|
4
|
-
* $Id: utility.c
|
4
|
+
* $Id: utility.c 285 2009-08-14 23:09:24Z rmagick $
|
5
5
|
* Copyright (C) 2009 Timothy Paul Hunter
|
6
6
|
*/
|
7
7
|
|
@@ -38,6 +38,7 @@ static ValueList align_types[] = {
|
|
38
38
|
{ "right", (long) RightAlign },
|
39
39
|
{ "start", (long) LeftAlign },
|
40
40
|
{ NULL, (long) UndefinedAlign } };
|
41
|
+
|
41
42
|
static ValueList channel_types[] = {
|
42
43
|
{ "all", (long) AllChannels },
|
43
44
|
{ "alpha", (long) OpacityChannel },
|
@@ -59,6 +60,13 @@ static ValueList channel_types[] = {
|
|
59
60
|
{ "saturation", (long) GreenChannel },
|
60
61
|
{ "yellow", (long) YellowChannel },
|
61
62
|
{ NULL, (long) UndefinedChannel} };
|
63
|
+
|
64
|
+
static ValueList clip_units[] = {
|
65
|
+
{ "objectboundingbox", (long) ObjectBoundingBox },
|
66
|
+
{ "userspace", (long) UserSpace },
|
67
|
+
{ "userspaceonuse", (long) UserSpaceOnUse } };
|
68
|
+
|
69
|
+
|
62
70
|
static ValueList colorspace_types[] = {
|
63
71
|
{ "cmy", (long) CMYColorspace },
|
64
72
|
{ "cmyk", (long) CMYKColorspace },
|
@@ -83,6 +91,7 @@ static ValueList colorspace_types[] = {
|
|
83
91
|
{ "ypbpr", (long) YPbPrColorspace },
|
84
92
|
{ "yuv", (long) YUVColorspace },
|
85
93
|
{ NULL, (long) UndefinedColorspace } };
|
94
|
+
|
86
95
|
static ValueList compose_types[] = {
|
87
96
|
{ "add", (long) AddCompositeOp },
|
88
97
|
{ "atop", (long) AtopCompositeOp },
|
@@ -142,6 +151,7 @@ static ValueList compose_types[] = {
|
|
142
151
|
{ "threshold", (long) ThresholdCompositeOp },
|
143
152
|
{ "xor", (long) XorCompositeOp },
|
144
153
|
{ NULL, (long) UndefinedCompositeOp } };
|
154
|
+
|
145
155
|
static ValueList compression_types[] = {
|
146
156
|
{ "bzip", (long) BZipCompression },
|
147
157
|
{ "dxt1", (long) DXT1Compression },
|
@@ -159,12 +169,19 @@ static ValueList compression_types[] = {
|
|
159
169
|
{ "zip", (long) ZipCompression },
|
160
170
|
{ "runlengthencoded", (long) RLECompression },
|
161
171
|
{ NULL, (long) UndefinedCompression } };
|
172
|
+
|
162
173
|
static ValueList decoration_types[] = {
|
163
174
|
{ "linethrough", (long) LineThroughDecoration },
|
164
175
|
{ "none", (long) NoDecoration },
|
165
176
|
{ "overline", (long) OverlineDecoration },
|
166
177
|
{ "underline", (long) UnderlineDecoration },
|
167
178
|
{ NULL, (long) UndefinedDecoration } };
|
179
|
+
|
180
|
+
static ValueList fill_rules[] = {
|
181
|
+
{ "evenodd", (long) EvenOddRule },
|
182
|
+
{ "nonzero", (long) NonZeroRule },
|
183
|
+
{ NULL, (long) UndefinedRule } };
|
184
|
+
|
168
185
|
static ValueList filter_types[] = {
|
169
186
|
{"bartlett", (long) BartlettFilter},
|
170
187
|
{"bessel", (long) BesselFilter},
|
@@ -217,6 +234,19 @@ static ValueList gravity_types[] = {
|
|
217
234
|
{ "west", (long) WestGravity },
|
218
235
|
{ "static", (long) StaticGravity },
|
219
236
|
{ NULL, (long) UndefinedGravity } };
|
237
|
+
|
238
|
+
static ValueList line_caps[] = {
|
239
|
+
{ "butt", (long) ButtCap },
|
240
|
+
{ "round", (long) RoundCap },
|
241
|
+
{ "square", (long) SquareCap },
|
242
|
+
{ NULL, (long) UndefinedCap } };
|
243
|
+
|
244
|
+
static ValueList line_joins[] = {
|
245
|
+
{ "bevel", (long) BevelJoin },
|
246
|
+
{ "miter", (long) MiterJoin },
|
247
|
+
{ "round", (long) RoundJoin },
|
248
|
+
{ NULL, (long) UndefinedJoin } };
|
249
|
+
|
220
250
|
static ValueList metric_types[] = {
|
221
251
|
{ "ae", (long) AbsoluteErrorMetric },
|
222
252
|
{ "mae", (long) MeanAbsoluteErrorMetric },
|
@@ -226,6 +256,15 @@ static ValueList metric_types[] = {
|
|
226
256
|
{ "psnr", (long) PeakSignalToNoiseRatioMetric },
|
227
257
|
{ "rmse", (long) RootMeanSquaredErrorMetric },
|
228
258
|
{ NULL, (long) UndefinedMetric } };
|
259
|
+
|
260
|
+
static ValueList paint_methods[] = {
|
261
|
+
{ "filltoborder", (long) FillToBorderMethod },
|
262
|
+
{ "floodfill", (long) FloodfillMethod },
|
263
|
+
{ "point", (long) PointMethod },
|
264
|
+
{ "replace", (long) ReplaceMethod },
|
265
|
+
{ "reset", (long) ResetMethod },
|
266
|
+
{ NULL, (long) UndefinedMethod } };
|
267
|
+
|
229
268
|
static ValueList storage_types[] = {
|
230
269
|
{ "char", (long) CharPixel },
|
231
270
|
{ "double", (long) DoublePixel },
|
@@ -235,6 +274,7 @@ static ValueList storage_types[] = {
|
|
235
274
|
{ "quantum", (long) QuantumPixel },
|
236
275
|
{ "short", (long) ShortPixel },
|
237
276
|
{ NULL, (long) UndefinedPixel } };
|
277
|
+
|
238
278
|
static ValueList stretch_types[] = {
|
239
279
|
{ "any", (long) AnyStretch },
|
240
280
|
{ "condensed", (long) CondensedStretch },
|
@@ -247,12 +287,14 @@ static ValueList stretch_types[] = {
|
|
247
287
|
{ "ultracondensed", (long) UltraCondensedStretch },
|
248
288
|
{ "ultraexpanded", (long) UltraExpandedStretch },
|
249
289
|
{ NULL, (long) UndefinedStretch } };
|
290
|
+
|
250
291
|
static ValueList style_types[] = {
|
251
|
-
{ "any",
|
292
|
+
{ "any", (long) AnyStyle },
|
252
293
|
{ "italic", (long) ItalicStyle },
|
253
294
|
{ "normal", (long) NormalStyle },
|
254
295
|
{ "oblique", (long) ObliqueStyle },
|
255
296
|
{ NULL, (long) UndefinedStyle } };
|
297
|
+
|
256
298
|
static ValueList weight_types[] = {
|
257
299
|
{ "any", 0L },
|
258
300
|
{ "light", 100L },
|
@@ -261,21 +303,26 @@ static ValueList weight_types[] = {
|
|
261
303
|
{ NULL, 0L } };
|
262
304
|
|
263
305
|
static OptionList option_list[] = {
|
264
|
-
{"align",
|
265
|
-
{"channel",
|
266
|
-
{"
|
267
|
-
{"
|
268
|
-
{"
|
269
|
-
{"
|
270
|
-
{"
|
271
|
-
{"
|
272
|
-
{"
|
273
|
-
{"
|
274
|
-
{"
|
275
|
-
{"
|
276
|
-
{"
|
277
|
-
{"
|
278
|
-
{
|
306
|
+
{"align", align_types},
|
307
|
+
{"channel", channel_types},
|
308
|
+
{"clip_units", clip_units},
|
309
|
+
{"colorspace", colorspace_types},
|
310
|
+
{"compose", compose_types},
|
311
|
+
{"compress", compression_types},
|
312
|
+
{"decoration", decoration_types},
|
313
|
+
{"fillrule", fill_rules},
|
314
|
+
{"filter", filter_types},
|
315
|
+
{"gravity", gravity_types},
|
316
|
+
{"metric", metric_types},
|
317
|
+
{"method", paint_methods},
|
318
|
+
{"type", image_types},
|
319
|
+
{"storage_type", storage_types},
|
320
|
+
{"line_cap", line_caps},
|
321
|
+
{"line_join", line_joins},
|
322
|
+
{"stretch", stretch_types},
|
323
|
+
{"style", style_types},
|
324
|
+
{"weight", weight_types},
|
325
|
+
{NULL, NULL} };
|
279
326
|
|
280
327
|
|
281
328
|
|
@@ -390,6 +437,11 @@ ChannelType mwr_string_to_channeltype(VALUE s, ChannelType defval, OnUndefinedOp
|
|
390
437
|
return (ChannelType) string_to_enum("channel", channel_types, s, (long)defval, undef);
|
391
438
|
}
|
392
439
|
|
440
|
+
ClipPathUnits mwr_string_to_clip_units(VALUE s, ClipPathUnits defval, OnUndefinedOption undef)
|
441
|
+
{
|
442
|
+
return (ClipPathUnits) string_to_enum("clip_units", clip_units, s, (long)defval, undef);
|
443
|
+
}
|
444
|
+
|
393
445
|
ColorspaceType mwr_string_to_colorspacetype(VALUE s, ColorspaceType defval, OnUndefinedOption undef)
|
394
446
|
{
|
395
447
|
return (ColorspaceType) string_to_enum("colorspace", colorspace_types, s, (long)defval, undef);
|
@@ -410,6 +462,11 @@ DecorationType mwr_string_to_decorationtype(VALUE s, DecorationType defval, OnUn
|
|
410
462
|
return (DecorationType) string_to_enum("decoration", decoration_types, s, (long)defval, undef);
|
411
463
|
}
|
412
464
|
|
465
|
+
FillRule mwr_string_to_fillrule(VALUE s, FillRule defval, OnUndefinedOption undef)
|
466
|
+
{
|
467
|
+
return (FillRule) string_to_enum("fillrule", fill_rules, s, (long)defval, undef);
|
468
|
+
}
|
469
|
+
|
413
470
|
FilterTypes mwr_string_to_filtertypes(VALUE s, FilterTypes defval, OnUndefinedOption undef)
|
414
471
|
{
|
415
472
|
return (FilterTypes) string_to_enum("filter", filter_types, s, (long)defval, undef);
|
@@ -425,11 +482,26 @@ ImageType mwr_string_to_imagetype(VALUE s, ImageType defval, OnUndefinedOption u
|
|
425
482
|
return (ImageType) string_to_enum("type", image_types, s, (long)defval, undef);
|
426
483
|
}
|
427
484
|
|
485
|
+
LineCap mwr_string_to_line_cap(VALUE s, LineCap defval, OnUndefinedOption undef)
|
486
|
+
{
|
487
|
+
return (LineCap) string_to_enum("line_cap", line_caps, s, (long)defval, undef);
|
488
|
+
}
|
489
|
+
|
490
|
+
LineJoin mwr_string_to_line_join(VALUE s, LineJoin defval, OnUndefinedOption undef)
|
491
|
+
{
|
492
|
+
return (LineCap) string_to_enum("line_join", line_joins, s, (long)defval, undef);
|
493
|
+
}
|
494
|
+
|
428
495
|
MetricType mwr_string_to_metrictype(VALUE s, MetricType defval, OnUndefinedOption undef)
|
429
496
|
{
|
430
497
|
return (MetricType) string_to_enum("type", metric_types, s, (long)defval, undef);
|
431
498
|
}
|
432
499
|
|
500
|
+
PaintMethod mwr_string_to_paintmethod(VALUE s, PaintMethod defval, OnUndefinedOption undef)
|
501
|
+
{
|
502
|
+
return (PaintMethod) string_to_enum("method", paint_methods, s, (long)defval, undef);
|
503
|
+
}
|
504
|
+
|
433
505
|
StorageType mwr_string_to_storagetype(VALUE s, StorageType defval, OnUndefinedOption undef)
|
434
506
|
{
|
435
507
|
return (StretchType) string_to_enum("storage_type", storage_types, s, (long)defval, undef);
|
@@ -533,6 +605,21 @@ extern void mwr_get_pixelwand_from_pixelpacket(PixelWand *pixelwand, PixelPacket
|
|
533
605
|
|
534
606
|
|
535
607
|
|
608
|
+
/*
|
609
|
+
* Return the hex representation of the pixel as a Ruby string.
|
610
|
+
* (The PixelWand method always returns the rgb() representation.)
|
611
|
+
*/
|
612
|
+
extern VALUE mwr_pixelwand_to_hex(Image *image, PixelWand *pixelwand)
|
613
|
+
{
|
614
|
+
PixelPacket pixelpacket;
|
615
|
+
|
616
|
+
mwr_get_pixelpacket_from_pixelwand(&pixelpacket, pixelwand);
|
617
|
+
return mwr_pixelpacket_to_hex(image, &pixelpacket);
|
618
|
+
}
|
619
|
+
|
620
|
+
|
621
|
+
|
622
|
+
|
536
623
|
/*
|
537
624
|
* Return the hex representation of the pixel as a Ruby string.
|
538
625
|
* (The PixelWand method always returns the rgb() representation.)
|
@@ -659,16 +746,55 @@ static VALUE rescue_option(VALUE args, VALUE errinfo)
|
|
659
746
|
* rescue NoMethodError
|
660
747
|
* raise(ArgumentError, "undefined option :#{option}")
|
661
748
|
* end
|
749
|
+
*
|
750
|
+
* Because the options hash is unordered in 1.8.*, we make two passes over the
|
751
|
+
* options. The :stroke_opacity and :fill_opacity options must succeed the
|
752
|
+
* :stroke and :fill options, otherwise the opacity specified by the colors
|
753
|
+
* overrides the opacity specified by the :xxx_opacity options. So the first
|
754
|
+
* pass specifically skips these two options, and the second pass skips over
|
755
|
+
* all but these two options.
|
662
756
|
*/
|
663
|
-
|
757
|
+
|
758
|
+
static int options_pass_1(VALUE option, VALUE value, VALUE obj)
|
664
759
|
{
|
665
760
|
VALUE args;
|
761
|
+
volatile VALUE fill_opacity, stroke_opacity;
|
762
|
+
|
763
|
+
fill_opacity = ID2SYM(rb_intern("fill_opacity"));
|
764
|
+
stroke_opacity = ID2SYM(rb_intern("stroke_opacity"));
|
765
|
+
|
766
|
+
if (!(option == fill_opacity || option == stroke_opacity))
|
767
|
+
{
|
768
|
+
args = rb_ary_new2(3);
|
769
|
+
rb_ary_push(args, option);
|
770
|
+
rb_ary_push(args, value);
|
771
|
+
rb_ary_push(args, obj);
|
772
|
+
(void) rb_rescue(call_option_setter, args, rescue_option, args);
|
773
|
+
}
|
774
|
+
|
775
|
+
return 0;
|
776
|
+
}
|
777
|
+
|
778
|
+
|
779
|
+
|
780
|
+
|
781
|
+
static int options_pass_2(VALUE option, VALUE value, VALUE obj)
|
782
|
+
{
|
783
|
+
VALUE args;
|
784
|
+
volatile VALUE fill_opacity, stroke_opacity;
|
785
|
+
|
786
|
+
fill_opacity = ID2SYM(rb_intern("fill_opacity"));
|
787
|
+
stroke_opacity = ID2SYM(rb_intern("stroke_opacity"));
|
788
|
+
|
789
|
+
if (option == fill_opacity || option == stroke_opacity)
|
790
|
+
{
|
791
|
+
args = rb_ary_new2(3);
|
792
|
+
rb_ary_push(args, option);
|
793
|
+
rb_ary_push(args, value);
|
794
|
+
rb_ary_push(args, obj);
|
795
|
+
(void) rb_rescue(call_option_setter, args, rescue_option, args);
|
796
|
+
}
|
666
797
|
|
667
|
-
args = rb_ary_new2(3);
|
668
|
-
rb_ary_push(args, option);
|
669
|
-
rb_ary_push(args, value);
|
670
|
-
rb_ary_push(args, obj);
|
671
|
-
(void) rb_rescue(call_option_setter, args, rescue_option, args);
|
672
798
|
return 0;
|
673
799
|
}
|
674
800
|
|
@@ -682,7 +808,8 @@ void mwr_process_options(VALUE obj, VALUE options)
|
|
682
808
|
{
|
683
809
|
if (options != Qnil)
|
684
810
|
{
|
685
|
-
rb_hash_foreach(options,
|
811
|
+
rb_hash_foreach(options, options_pass_1, obj);
|
812
|
+
rb_hash_foreach(options, options_pass_2, obj);
|
686
813
|
}
|
687
814
|
}
|
688
815
|
|
data/ext/magickwand/wand.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* wand.c
|
3
|
-
* $Id: wand.c
|
3
|
+
* $Id: wand.c 275 2009-08-13 22:30:55Z rmagick $
|
4
4
|
* Copyright (C) 2009 Timothy Paul Hunter
|
5
5
|
*/
|
6
6
|
|
@@ -253,7 +253,7 @@ leave:
|
|
253
253
|
static VALUE wand_annotate(int argc, VALUE *argv, VALUE obj)
|
254
254
|
{
|
255
255
|
Wand *wand;
|
256
|
-
|
256
|
+
Drawing *drawing;
|
257
257
|
double x, y, angle;
|
258
258
|
volatile VALUE graphics_context;
|
259
259
|
VALUE v, text, options;
|
@@ -271,11 +271,11 @@ static VALUE wand_annotate(int argc, VALUE *argv, VALUE obj)
|
|
271
271
|
y = mwr_get_option(options, "y", &v) ? NUM2DBL(v) : 0.0;
|
272
272
|
angle = mwr_get_option(options, "angle", &v) ? NUM2DBL(v) : 0.0;
|
273
273
|
|
274
|
-
graphics_context =
|
275
|
-
Data_Get_Struct(graphics_context,
|
274
|
+
graphics_context = mwr_drawing_new();
|
275
|
+
Data_Get_Struct(graphics_context, Drawing, drawing);
|
276
276
|
|
277
277
|
// Override default NorthWest gravity. It's useless.
|
278
|
-
DrawSetGravity(
|
278
|
+
DrawSetGravity(drawing->wand, CenterGravity);
|
279
279
|
mwr_process_options(graphics_context, options);
|
280
280
|
|
281
281
|
Data_Get_Struct(obj, Wand, wand);
|
@@ -283,7 +283,7 @@ static VALUE wand_annotate(int argc, VALUE *argv, VALUE obj)
|
|
283
283
|
MagickResetIterator(wand->magickwand);
|
284
284
|
while (MagickNextImage(wand->magickwand) != MagickFalse)
|
285
285
|
{
|
286
|
-
MagickAnnotateImage(wand->magickwand,
|
286
|
+
MagickAnnotateImage(wand->magickwand, drawing->wand, x, y, angle, text_string);
|
287
287
|
}
|
288
288
|
|
289
289
|
return obj;
|
@@ -471,6 +471,72 @@ static VALUE wand_background(VALUE obj)
|
|
471
471
|
|
472
472
|
|
473
473
|
|
474
|
+
/*
|
475
|
+
* returns the border color property for the 0th image
|
476
|
+
*/
|
477
|
+
static VALUE wand_bordercolor(VALUE obj)
|
478
|
+
{
|
479
|
+
Wand *wand;
|
480
|
+
PixelWand *bordercolor;
|
481
|
+
Image *image;
|
482
|
+
volatile VALUE color;
|
483
|
+
|
484
|
+
if (FIX2LONG(wand_length(obj)) == 0)
|
485
|
+
{
|
486
|
+
return Qnil;
|
487
|
+
}
|
488
|
+
|
489
|
+
Data_Get_Struct(obj, Wand, wand);
|
490
|
+
|
491
|
+
MagickResetIterator(wand->magickwand);
|
492
|
+
bordercolor = NewPixelWand();
|
493
|
+
MagickGetImageBorderColor(wand->magickwand, bordercolor);
|
494
|
+
mwr_check_magickwand_error(wand->magickwand);
|
495
|
+
|
496
|
+
image = GetImageFromMagickWand(wand->magickwand);
|
497
|
+
mwr_check_magickwand_error(wand->magickwand);
|
498
|
+
|
499
|
+
color = mwr_pixelwand_to_hex(image, bordercolor);
|
500
|
+
DestroyPixelWand(bordercolor);
|
501
|
+
|
502
|
+
return color;
|
503
|
+
}
|
504
|
+
|
505
|
+
|
506
|
+
|
507
|
+
|
508
|
+
/*
|
509
|
+
* sets the border color property for the 0th image
|
510
|
+
*/
|
511
|
+
static VALUE wand_bordercolor_set(VALUE obj, VALUE color)
|
512
|
+
{
|
513
|
+
Wand *wand;
|
514
|
+
PixelWand *pixelwand;
|
515
|
+
char *bordercolor;
|
516
|
+
|
517
|
+
rb_check_frozen(obj);
|
518
|
+
|
519
|
+
Data_Get_Struct(obj, Wand, wand);
|
520
|
+
|
521
|
+
bordercolor = StringValuePtr(color);
|
522
|
+
pixelwand = NewPixelWand();
|
523
|
+
PixelSetColor(pixelwand, bordercolor);
|
524
|
+
mwr_check_pixelwand_error(pixelwand);
|
525
|
+
|
526
|
+
MagickResetIterator(wand->magickwand);
|
527
|
+
while (MagickNextImage(wand->magickwand) != MagickFalse)
|
528
|
+
{
|
529
|
+
(void) MagickSetImageBorderColor(wand->magickwand, pixelwand);
|
530
|
+
mwr_check_magickwand_error(wand->magickwand);
|
531
|
+
}
|
532
|
+
DestroyPixelWand(pixelwand);
|
533
|
+
|
534
|
+
return color;
|
535
|
+
}
|
536
|
+
|
537
|
+
|
538
|
+
|
539
|
+
|
474
540
|
static VALUE convolve(int argc, VALUE *argv, VALUE obj,
|
475
541
|
MagickBooleanType (*convolve)(MagickWand *, const ChannelType, const double, const double))
|
476
542
|
{
|
@@ -520,17 +586,17 @@ static VALUE wand_border(int argc, VALUE *argv, VALUE obj)
|
|
520
586
|
Wand *wand;
|
521
587
|
PixelWand *pixelwand;
|
522
588
|
VALUE color, wt, ht;
|
523
|
-
char *
|
589
|
+
char *bordercolor;
|
524
590
|
unsigned long width, height;
|
525
591
|
|
526
592
|
rb_check_frozen(obj);
|
527
593
|
(void) rb_scan_args(argc, argv, "12", &color, &wt, &ht);
|
528
|
-
|
594
|
+
bordercolor = StringValuePtr(color);
|
529
595
|
width = wt != Qnil ? NUM2ULONG(wt) : 1UL;
|
530
596
|
height = ht != Qnil ? NUM2ULONG(ht) : width;
|
531
597
|
|
532
598
|
pixelwand = NewPixelWand();
|
533
|
-
PixelSetColor(pixelwand,
|
599
|
+
PixelSetColor(pixelwand, bordercolor);
|
534
600
|
mwr_check_pixelwand_error(pixelwand);
|
535
601
|
|
536
602
|
Data_Get_Struct(obj, Wand, wand);
|
@@ -971,6 +1037,10 @@ static VALUE wand_display(VALUE obj)
|
|
971
1037
|
Wand *wand;
|
972
1038
|
|
973
1039
|
Data_Get_Struct(obj, Wand, wand);
|
1040
|
+
if (MagickGetNumberImages(wand->magickwand) == 0UL)
|
1041
|
+
{
|
1042
|
+
return Qnil;
|
1043
|
+
}
|
974
1044
|
MagickDisplayImages(wand->magickwand, NULL);
|
975
1045
|
mwr_check_magickwand_error(wand->magickwand);
|
976
1046
|
return obj;
|
@@ -979,6 +1049,28 @@ static VALUE wand_display(VALUE obj)
|
|
979
1049
|
|
980
1050
|
|
981
1051
|
|
1052
|
+
static VALUE wand_draw(VALUE obj, VALUE drawing_obj)
|
1053
|
+
{
|
1054
|
+
Wand *wand;
|
1055
|
+
Drawing *drawing;
|
1056
|
+
|
1057
|
+
rb_check_frozen(obj);
|
1058
|
+
Data_Get_Struct(obj, Wand, wand);
|
1059
|
+
Data_Get_Struct(drawing_obj, Drawing, drawing);
|
1060
|
+
|
1061
|
+
MagickResetIterator(wand->magickwand);
|
1062
|
+
while (MagickNextImage(wand->magickwand) != MagickFalse)
|
1063
|
+
{
|
1064
|
+
MagickDrawImage(wand->magickwand, drawing->wand);
|
1065
|
+
mwr_check_magickwand_error(wand->magickwand);
|
1066
|
+
}
|
1067
|
+
|
1068
|
+
return obj;
|
1069
|
+
}
|
1070
|
+
|
1071
|
+
|
1072
|
+
|
1073
|
+
|
982
1074
|
/*
|
983
1075
|
* (>= 1.8.7) if no block return enumerator
|
984
1076
|
*/
|
@@ -2262,6 +2354,8 @@ void mwr_init_Wand(void)
|
|
2262
2354
|
rb_define_method(mwr_cWand, "animate", wand_animate, -1);
|
2263
2355
|
rb_define_method(mwr_cWand, "annotate", wand_annotate, -1);
|
2264
2356
|
rb_define_method(mwr_cWand, "background", wand_background, 0);
|
2357
|
+
rb_define_method(mwr_cWand, "bordercolor", wand_bordercolor, 0);
|
2358
|
+
rb_define_method(mwr_cWand, "bordercolor=", wand_bordercolor_set, 1);
|
2265
2359
|
rb_define_method(mwr_cWand, "blur", wand_blur, -1);
|
2266
2360
|
rb_define_method(mwr_cWand, "border", wand_border, -1);
|
2267
2361
|
rb_define_method(mwr_cWand, "colors", wand_colors, 0);
|
@@ -2273,6 +2367,7 @@ void mwr_init_Wand(void)
|
|
2273
2367
|
rb_define_method(mwr_cWand, "depth", wand_depth, 0);
|
2274
2368
|
rb_define_method(mwr_cWand, "dimensions", wand_dimensions, 0);
|
2275
2369
|
rb_define_method(mwr_cWand, "display", wand_display, 0);
|
2370
|
+
rb_define_method(mwr_cWand, "draw", wand_draw, 1);
|
2276
2371
|
rb_define_method(mwr_cWand, "export_pixels", wand_export_pixels, -1);
|
2277
2372
|
rb_define_method(mwr_cWand, "filename", wand_filename, 0);
|
2278
2373
|
rb_define_method(mwr_cWand, "format", wand_format, 0);
|