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/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);
|