rmagick 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rmagick might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.appveyor.yml +4 -4
- data/.circleci/config.yml +1 -1
- data/.gitignore +1 -0
- data/.rubocop_todo.yml +6 -0
- data/.travis.yml +26 -8
- data/CHANGELOG.md +104 -0
- data/before_install_linux.sh +19 -10
- data/benchmarks/memory/README.md +50 -0
- data/benchmarks/memory/image_new.rb +8 -0
- data/benchmarks/memory/rmagick.gnuplot +16 -0
- data/doc/ex/coalesce.rb +2 -2
- data/doc/ex/drawcomp.rb +3 -3
- data/doc/ex/get_pixels.rb +1 -1
- data/doc/ex/images/Coffee.png +0 -0
- data/doc/ex/images/No.png +0 -0
- data/doc/ex/images/Snake.png +0 -0
- data/doc/ex/implode.rb +2 -2
- data/doc/ex/mask.rb +1 -1
- data/doc/ex/matte_fill_to_border.rb +1 -1
- data/doc/ex/matte_floodfill.rb +1 -1
- data/doc/ex/matte_replace.rb +1 -1
- data/doc/ex/stegano.rb +1 -1
- data/examples/constitute.rb +1 -1
- data/examples/crop_with_gravity.rb +1 -1
- data/examples/demo.rb +4 -4
- data/examples/find_similar_region.rb +1 -1
- data/examples/histogram.rb +3 -3
- data/examples/identify.rb +46 -46
- data/examples/image_opacity.rb +2 -2
- data/examples/vignette.rb +3 -3
- data/ext/RMagick/extconf.rb +19 -15
- data/ext/RMagick/rmagick.c +1 -2
- data/ext/RMagick/rmagick.h +59 -30
- data/ext/RMagick/rmdraw.c +62 -274
- data/ext/RMagick/rmenum.c +121 -665
- data/ext/RMagick/rmfill.c +7 -7
- data/ext/RMagick/rmilist.c +91 -7
- data/ext/RMagick/rmimage.c +568 -379
- data/ext/RMagick/rminfo.c +152 -110
- data/ext/RMagick/rmkinfo.c +17 -1
- data/ext/RMagick/rmmain.c +75 -74
- data/ext/RMagick/rmmontage.c +33 -33
- data/ext/RMagick/rmpixel.c +75 -14
- data/ext/RMagick/rmstruct.c +5 -5
- data/ext/RMagick/rmutil.c +3 -13
- data/lib/obsolete.rb +66 -0
- data/lib/rmagick/version.rb +1 -1
- data/lib/rmagick_internal.rb +54 -41
- data/spec/rmagick/image/composite_spec.rb +5 -76
- data/spec/rmagick/image/properties_spec.rb +1 -1
- data/test/Draw.rb +52 -115
- data/test/Enum.rb +153 -1
- data/test/Fill.rb +1 -1
- data/test/Image1.rb +97 -43
- data/test/Image2.rb +140 -36
- data/test/Image3.rb +110 -120
- data/test/ImageList1.rb +46 -11
- data/test/ImageList2.rb +11 -21
- data/test/Image_attributes.rb +81 -127
- data/test/Import_Export.rb +2 -2
- data/test/Info.rb +5 -1
- data/test/KernelInfo.rb +67 -0
- data/test/Magick.rb +17 -35
- data/test/Pixel.rb +193 -24
- data/test/PolaroidOptions.rb +1 -1
- data/test/Preview.rb +3 -35
- data/test/Struct.rb +45 -0
- data/test/appearance/Montage.rb +26 -0
- data/test/appearance/appearance_assertion.rb +13 -0
- data/test/appearance/expected/montage_border_color.jpg +0 -0
- data/test/lib/Obsolete.rb +30 -0
- data/test/lib/internal/Draw.rb +823 -0
- data/test/lib/internal/Geometry.rb +98 -0
- data/test/lib/internal/Magick.rb +40 -0
- data/test/test_all_basic.rb +16 -17
- metadata +27 -5
- data/doc/ex/images/Coffee.wmf +0 -0
- data/doc/ex/images/No.wmf +0 -0
- data/doc/ex/images/Snake.wmf +0 -0
data/ext/RMagick/rmpixel.c
CHANGED
@@ -110,6 +110,24 @@ DEF_ATTR_READER(Pixel, green, int)
|
|
110
110
|
*/
|
111
111
|
DEF_ATTR_READER(Pixel, blue, int)
|
112
112
|
|
113
|
+
/**
|
114
|
+
* Get Pixel alpha attribute.
|
115
|
+
*
|
116
|
+
* Ruby usage:
|
117
|
+
* - @verbatim Pixel#alpha @endverbatim
|
118
|
+
*
|
119
|
+
* @param self this object
|
120
|
+
* @return the alpha value
|
121
|
+
*/
|
122
|
+
VALUE
|
123
|
+
Pixel_alpha(VALUE self)
|
124
|
+
{
|
125
|
+
Pixel *pixel;
|
126
|
+
Data_Get_Struct(self, Pixel, pixel);
|
127
|
+
return C_int_to_R_int(QuantumRange - pixel->opacity);
|
128
|
+
}
|
129
|
+
|
130
|
+
|
113
131
|
/**
|
114
132
|
* Get Pixel opacity attribute.
|
115
133
|
*
|
@@ -118,8 +136,16 @@ DEF_ATTR_READER(Pixel, blue, int)
|
|
118
136
|
*
|
119
137
|
* @param self this object
|
120
138
|
* @return the opacity value
|
139
|
+
* @deprecated This method has been deprecated. Please use Pixel_alpha.
|
121
140
|
*/
|
122
|
-
|
141
|
+
VALUE
|
142
|
+
Pixel_opacity(VALUE self)
|
143
|
+
{
|
144
|
+
Pixel *pixel;
|
145
|
+
rb_warning("Pixel#opacity is deprecated; use Pixel#alpha.");
|
146
|
+
Data_Get_Struct(self, Pixel, pixel);
|
147
|
+
return C_int_to_R_int(pixel->opacity);
|
148
|
+
}
|
123
149
|
|
124
150
|
/**
|
125
151
|
* Set Pixel red attribute.
|
@@ -172,6 +198,35 @@ DEF_PIXEL_CHANNEL_WRITER(green)
|
|
172
198
|
*/
|
173
199
|
DEF_PIXEL_CHANNEL_WRITER(blue)
|
174
200
|
|
201
|
+
/**
|
202
|
+
* Set Pixel alpha attribute.
|
203
|
+
*
|
204
|
+
* Ruby usage:
|
205
|
+
* - @verbatim Pixel#alpha= @endverbatim
|
206
|
+
*
|
207
|
+
* Notes:
|
208
|
+
* - Pixel is Observable. Setters call changed, notify_observers
|
209
|
+
* - Setters return their argument values for backward compatibility to when
|
210
|
+
* Pixel was a Struct class.
|
211
|
+
*
|
212
|
+
* @param self this object
|
213
|
+
* @param v the alpha value
|
214
|
+
* @return self
|
215
|
+
*/
|
216
|
+
VALUE
|
217
|
+
Pixel_alpha_eq(VALUE self, VALUE v)
|
218
|
+
{
|
219
|
+
Pixel *pixel;
|
220
|
+
|
221
|
+
rb_check_frozen(self);
|
222
|
+
Data_Get_Struct(self, Pixel, pixel);
|
223
|
+
pixel->opacity = QuantumRange - APP2QUANTUM(v);
|
224
|
+
(void) rb_funcall(self, rm_ID_changed, 0);
|
225
|
+
(void) rb_funcall(self, rm_ID_notify_observers, 1, self);
|
226
|
+
return QUANTUM2NUM(QuantumRange - pixel->opacity);
|
227
|
+
}
|
228
|
+
|
229
|
+
|
175
230
|
/**
|
176
231
|
* Set Pixel opacity attribute.
|
177
232
|
*
|
@@ -186,9 +241,21 @@ DEF_PIXEL_CHANNEL_WRITER(blue)
|
|
186
241
|
* @param self this object
|
187
242
|
* @param v the opacity value
|
188
243
|
* @return self
|
244
|
+
* @deprecated This method has been deprecated. Please use Pixel_alpha_eq.
|
189
245
|
*/
|
190
|
-
|
246
|
+
VALUE
|
247
|
+
Pixel_opacity_eq(VALUE self, VALUE v)
|
248
|
+
{
|
249
|
+
Pixel *pixel;
|
191
250
|
|
251
|
+
rb_warning("Pixel#opacity= is deprecated; use Pixel#alpha=.");
|
252
|
+
rb_check_frozen(self);
|
253
|
+
Data_Get_Struct(self, Pixel, pixel);
|
254
|
+
pixel->opacity = APP2QUANTUM(v);
|
255
|
+
(void) rb_funcall(self, rm_ID_changed, 0);
|
256
|
+
(void) rb_funcall(self, rm_ID_notify_observers, 1, self);
|
257
|
+
return QUANTUM2NUM(pixel->opacity);
|
258
|
+
}
|
192
259
|
|
193
260
|
/*
|
194
261
|
* Get/set Pixel CMYK attributes.
|
@@ -421,13 +488,12 @@ Pixel_eql_q(VALUE self, VALUE other)
|
|
421
488
|
VALUE
|
422
489
|
Pixel_fcmp(int argc, VALUE *argv, VALUE self)
|
423
490
|
{
|
491
|
+
double fuzz = 0.0;
|
492
|
+
unsigned int equal;
|
493
|
+
ColorspaceType colorspace = RGBColorspace;
|
424
494
|
Image *image;
|
425
495
|
Info *info;
|
426
|
-
|
427
496
|
Pixel *this, *that;
|
428
|
-
ColorspaceType colorspace = RGBColorspace;
|
429
|
-
double fuzz = 0.0;
|
430
|
-
unsigned int equal;
|
431
497
|
|
432
498
|
switch (argc)
|
433
499
|
{
|
@@ -493,14 +559,12 @@ Pixel_fcmp(int argc, VALUE *argv, VALUE self)
|
|
493
559
|
* @see Pixel_to_color
|
494
560
|
*/
|
495
561
|
VALUE
|
496
|
-
Pixel_from_color(VALUE class, VALUE name)
|
562
|
+
Pixel_from_color(VALUE class ATTRIBUTE_UNUSED, VALUE name)
|
497
563
|
{
|
498
564
|
PixelColor pp;
|
499
565
|
ExceptionInfo *exception;
|
500
566
|
MagickBooleanType okay;
|
501
567
|
|
502
|
-
class = class; // defeat "never referenced" message from icc
|
503
|
-
|
504
568
|
exception = AcquireExceptionInfo();
|
505
569
|
okay = QueryColorCompliance(StringValuePtr(name), AllCompliance, &pp, exception);
|
506
570
|
CHECK_EXCEPTION()
|
@@ -536,7 +600,7 @@ Pixel_from_color(VALUE class, VALUE name)
|
|
536
600
|
* @return a new Magick::Pixel object
|
537
601
|
*/
|
538
602
|
VALUE
|
539
|
-
Pixel_from_hsla(int argc, VALUE *argv, VALUE class)
|
603
|
+
Pixel_from_hsla(int argc, VALUE *argv, VALUE class ATTRIBUTE_UNUSED)
|
540
604
|
{
|
541
605
|
double h, s, l, a = 1.0;
|
542
606
|
MagickPixel pp;
|
@@ -544,8 +608,6 @@ Pixel_from_hsla(int argc, VALUE *argv, VALUE class)
|
|
544
608
|
char name[50];
|
545
609
|
MagickBooleanType alpha = MagickFalse;
|
546
610
|
|
547
|
-
class = class; // defeat "unused parameter" message.
|
548
|
-
|
549
611
|
switch (argc)
|
550
612
|
{
|
551
613
|
case 4:
|
@@ -613,12 +675,11 @@ Pixel_from_hsla(int argc, VALUE *argv, VALUE class)
|
|
613
675
|
* @deprecated This method has been deprecated. Please use Pixel_from_hsla.
|
614
676
|
*/
|
615
677
|
VALUE
|
616
|
-
Pixel_from_HSL(VALUE class, VALUE hsl)
|
678
|
+
Pixel_from_HSL(VALUE class ATTRIBUTE_UNUSED, VALUE hsl)
|
617
679
|
{
|
618
680
|
PixelColor rgb;
|
619
681
|
double hue, saturation, luminosity;
|
620
682
|
|
621
|
-
class = class; // defeat "never referenced" message from icc
|
622
683
|
memset(&rgb, 0, sizeof(rgb));
|
623
684
|
|
624
685
|
hsl = rb_Array(hsl); // Ensure array
|
data/ext/RMagick/rmstruct.c
CHANGED
@@ -233,7 +233,7 @@ Import_ColorInfo(const ColorInfo *ci)
|
|
233
233
|
name = rb_str_new2(ci->name);
|
234
234
|
|
235
235
|
compliance_type = ci->compliance;
|
236
|
-
compliance =
|
236
|
+
compliance = ComplianceType_find(compliance_type);
|
237
237
|
color = Pixel_from_MagickPixel(&(ci->color));
|
238
238
|
|
239
239
|
RB_GC_GUARD(name);
|
@@ -390,8 +390,8 @@ Import_TypeInfo(const TypeInfo *ti)
|
|
390
390
|
|
391
391
|
name = rb_str_new2(ti->name);
|
392
392
|
family = rb_str_new2(ti->family);
|
393
|
-
style =
|
394
|
-
stretch =
|
393
|
+
style = StyleType_find(ti->style);
|
394
|
+
stretch = StretchType_find(ti->stretch);
|
395
395
|
weight = ULONG2NUM(ti->weight);
|
396
396
|
description = ti->description ? rb_str_new2(ti->description) : Qnil;
|
397
397
|
encoding = ti->encoding ? rb_str_new2(ti->encoding) : Qnil;
|
@@ -451,8 +451,8 @@ Export_TypeInfo(TypeInfo *ti, VALUE st)
|
|
451
451
|
{
|
452
452
|
(void) CloneString((char **)&(ti->family), StringValuePtr(m));
|
453
453
|
}
|
454
|
-
m = rb_ary_entry(members, 3); ti->style = m == Qnil ? 0 : FIX2INT(m);
|
455
|
-
m = rb_ary_entry(members, 4); ti->stretch = m == Qnil ? 0 : FIX2INT(m);
|
454
|
+
m = rb_ary_entry(members, 3); ti->style = m == Qnil ? 0 : FIX2INT(Enum_to_i(m));
|
455
|
+
m = rb_ary_entry(members, 4); ti->stretch = m == Qnil ? 0 : FIX2INT(Enum_to_i(m));
|
456
456
|
m = rb_ary_entry(members, 5); ti->weight = m == Qnil ? 0 : FIX2INT(m);
|
457
457
|
|
458
458
|
m = rb_ary_entry(members, 6);
|
data/ext/RMagick/rmutil.c
CHANGED
@@ -359,10 +359,7 @@ rm_str2cstr(VALUE str, long *len)
|
|
359
359
|
static VALUE
|
360
360
|
arg_is_number(VALUE arg)
|
361
361
|
{
|
362
|
-
|
363
|
-
d = NUM2DBL(arg);
|
364
|
-
d = d; // satisfy icc
|
365
|
-
return arg;
|
362
|
+
return DBL2NUM(NUM2DBL(arg));
|
366
363
|
}
|
367
364
|
|
368
365
|
|
@@ -472,9 +469,8 @@ check_num2dbl(VALUE obj)
|
|
472
469
|
* @return 0
|
473
470
|
*/
|
474
471
|
static VALUE
|
475
|
-
rescue_not_dbl(VALUE ignored)
|
472
|
+
rescue_not_dbl(VALUE ignored ATTRIBUTE_UNUSED)
|
476
473
|
{
|
477
|
-
ignored = ignored; // defeat gcc message
|
478
474
|
return INT2FIX(0);
|
479
475
|
}
|
480
476
|
|
@@ -1490,7 +1486,7 @@ rm_clone_image(Image *image)
|
|
1490
1486
|
*/
|
1491
1487
|
MagickBooleanType
|
1492
1488
|
rm_progress_monitor(
|
1493
|
-
const char *tag,
|
1489
|
+
const char *tag ATTRIBUTE_UNUSED,
|
1494
1490
|
const MagickOffsetType of,
|
1495
1491
|
const MagickSizeType sp,
|
1496
1492
|
void *client_data)
|
@@ -1509,8 +1505,6 @@ rm_progress_monitor(
|
|
1509
1505
|
return MagickTrue;
|
1510
1506
|
}
|
1511
1507
|
|
1512
|
-
tag = tag; // defeat gcc message
|
1513
|
-
|
1514
1508
|
#if defined(HAVE_LONG_LONG) // defined in Ruby's defines.h
|
1515
1509
|
offset = rb_ll2inum(of);
|
1516
1510
|
span = rb_ull2inum(sp);
|
@@ -1625,11 +1619,7 @@ format_exception(const ExceptionType severity, const char *reason, const char *d
|
|
1625
1619
|
int len;
|
1626
1620
|
memset(msg, 0, sizeof(ERROR_MSG_SIZE));
|
1627
1621
|
|
1628
|
-
#if defined(HAVE_SNPRINTF)
|
1629
1622
|
len = snprintf(msg, ERROR_MSG_SIZE, "%s%s%s",
|
1630
|
-
#else
|
1631
|
-
len = sprintf(msg, "%.500s%s%.500s",
|
1632
|
-
#endif
|
1633
1623
|
GetLocaleExceptionMessage(severity, reason),
|
1634
1624
|
description ? ": " : "",
|
1635
1625
|
description ? GetLocaleExceptionMessage(severity, description) : "");
|
data/lib/obsolete.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Magick
|
2
|
+
AddCompositeOp = ModulusAddCompositeOp
|
3
|
+
deprecate_constant 'AddCompositeOp'
|
4
|
+
|
5
|
+
AlphaChannelType = AlphaChannelOption
|
6
|
+
deprecate_constant 'AlphaChannelType'
|
7
|
+
|
8
|
+
ColorSeparationMatteType = ColorSeparationAlphaType
|
9
|
+
deprecate_constant 'ColorSeparationMatteType'
|
10
|
+
|
11
|
+
CopyOpacityCompositeOp = CopyAlphaCompositeOp
|
12
|
+
deprecate_constant 'CopyOpacityCompositeOp'
|
13
|
+
|
14
|
+
DistortImageMethod = DistortMethod
|
15
|
+
deprecate_constant 'DistortImageMethod'
|
16
|
+
|
17
|
+
DivideCompositeOp = DivideDstCompositeOp
|
18
|
+
deprecate_constant 'DivideDstCompositeOp'
|
19
|
+
|
20
|
+
FilterTypes = FilterType
|
21
|
+
deprecate_constant 'FilterTypes'
|
22
|
+
|
23
|
+
GrayscaleMatteType = GrayscaleAlphaType
|
24
|
+
deprecate_constant 'GrayscaleMatteType'
|
25
|
+
|
26
|
+
ImageLayerMethod = LayerMethod
|
27
|
+
deprecate_constant 'ImageLayerMethod'
|
28
|
+
|
29
|
+
InterpolatePixelMethod = PixelInterpolateMethod
|
30
|
+
deprecate_constant 'InterpolatePixelMethod'
|
31
|
+
|
32
|
+
MeanErrorPerPixelMetric = MeanErrorPerPixelErrorMetric
|
33
|
+
deprecate_constant 'MeanErrorPerPixelMetric'
|
34
|
+
|
35
|
+
MinusCompositeOp = MinusDstCompositeOp
|
36
|
+
deprecate_constant 'MinusCompositeOp'
|
37
|
+
|
38
|
+
PaletteBilevelMatteType = PaletteBilevelAlphaType
|
39
|
+
deprecate_constant 'PaletteBilevelMatteType'
|
40
|
+
|
41
|
+
PaletteMatteType = PaletteAlphaType
|
42
|
+
deprecate_constant 'PaletteMatteType'
|
43
|
+
|
44
|
+
PeakSignalToNoiseRatioMetric = PeakSignalToNoiseRatioErrorMetric
|
45
|
+
deprecate_constant 'PeakSignalToNoiseRatioMetric'
|
46
|
+
|
47
|
+
SubtractCompositeOp = ModulusSubtractCompositeOp
|
48
|
+
deprecate_constant 'SubtractCompositeOp'
|
49
|
+
|
50
|
+
TrueColorMatteType = TrueColorAlphaType
|
51
|
+
deprecate_constant 'TrueColorMatteType'
|
52
|
+
|
53
|
+
UndefinedMetric = UndefinedErrorMetric
|
54
|
+
deprecate_constant 'UndefinedMetric'
|
55
|
+
|
56
|
+
deprecate_constant 'ConstantVirtualPixelMethod'
|
57
|
+
deprecate_constant 'FlattenAlphaChannel'
|
58
|
+
deprecate_constant 'IntegerPixel'
|
59
|
+
deprecate_constant 'MatteChannel'
|
60
|
+
deprecate_constant 'OpaqueOpacity'
|
61
|
+
deprecate_constant 'Rec601LumaColorspace'
|
62
|
+
deprecate_constant 'Rec709LumaColorspace'
|
63
|
+
deprecate_constant 'ResetAlphaChannel'
|
64
|
+
deprecate_constant 'StaticGravity'
|
65
|
+
deprecate_constant 'TransparentOpacity'
|
66
|
+
end
|
data/lib/rmagick/version.rb
CHANGED
data/lib/rmagick_internal.rb
CHANGED
@@ -20,6 +20,7 @@ end
|
|
20
20
|
|
21
21
|
require 'English'
|
22
22
|
require 'RMagick2.so'
|
23
|
+
require 'obsolete.rb'
|
23
24
|
|
24
25
|
module Magick
|
25
26
|
@formats = nil
|
@@ -220,6 +221,13 @@ module Magick
|
|
220
221
|
end
|
221
222
|
end
|
222
223
|
|
224
|
+
def check_opacity(opacity)
|
225
|
+
return if opacity.is_a?(String) && opacity['%']
|
226
|
+
|
227
|
+
value = Float(opacity)
|
228
|
+
Kernel.raise ArgumentError, 'opacity must be >= 0 and <= 1.0' if value < 0 || value > 1.0
|
229
|
+
end
|
230
|
+
|
223
231
|
public
|
224
232
|
|
225
233
|
# Apply coordinate transformations to support scaling (s), rotation (r),
|
@@ -228,6 +236,13 @@ module Magick
|
|
228
236
|
primitive 'affine ' + format('%g,%g,%g,%g,%g,%g', sx, rx, ry, sy, tx, ty)
|
229
237
|
end
|
230
238
|
|
239
|
+
# Set alpha (make transparent) in image according to the specified
|
240
|
+
# colorization rule
|
241
|
+
def alpha(x, y, method)
|
242
|
+
Kernel.raise ArgumentError, 'Unknown paint method' unless PAINT_METHOD_NAMES.key?(method.to_i)
|
243
|
+
primitive 'matte ' + format('%g,%g, %s', x, y, PAINT_METHOD_NAMES[method.to_i])
|
244
|
+
end
|
245
|
+
|
231
246
|
# Draw an arc.
|
232
247
|
def arc(start_x, start_y, end_x, end_y, start_degrees, end_degrees)
|
233
248
|
primitive 'arc ' + format('%g,%g %g,%g %g,%g',
|
@@ -241,7 +256,7 @@ module Magick
|
|
241
256
|
elsif points.length.odd?
|
242
257
|
Kernel.raise ArgumentError, 'odd number of arguments specified'
|
243
258
|
end
|
244
|
-
primitive 'bezier ' + points.join(',')
|
259
|
+
primitive 'bezier ' + points.map! { |x| format('%g', x) }.join(',')
|
245
260
|
end
|
246
261
|
|
247
262
|
# Draw a circle
|
@@ -270,7 +285,7 @@ module Magick
|
|
270
285
|
# point, replace, floodfill, filltoborder,reset
|
271
286
|
def color(x, y, method)
|
272
287
|
Kernel.raise ArgumentError, "Unknown PaintMethod: #{method}" unless PAINT_METHOD_NAMES.key?(method.to_i)
|
273
|
-
primitive
|
288
|
+
primitive 'color ' + format('%g,%g,%s', x, y, PAINT_METHOD_NAMES[method.to_i])
|
274
289
|
end
|
275
290
|
|
276
291
|
# Specify EITHER the text decoration (none, underline, overline,
|
@@ -290,7 +305,7 @@ module Magick
|
|
290
305
|
# (pop) graphic-context".
|
291
306
|
def define_clip_path(name)
|
292
307
|
push('defs')
|
293
|
-
push(
|
308
|
+
push("clip-path \"#{name}\"")
|
294
309
|
push('graphic-context')
|
295
310
|
yield
|
296
311
|
ensure
|
@@ -320,6 +335,7 @@ module Magick
|
|
320
335
|
|
321
336
|
# Specify fill opacity (use "xx%" to indicate percentage)
|
322
337
|
def fill_opacity(opacity)
|
338
|
+
check_opacity(opacity)
|
323
339
|
primitive "fill-opacity #{opacity}"
|
324
340
|
end
|
325
341
|
|
@@ -350,10 +366,10 @@ module Magick
|
|
350
366
|
# The font weight argument can be either a font weight
|
351
367
|
# constant or [100,200,...,900]
|
352
368
|
def font_weight(weight)
|
353
|
-
if
|
369
|
+
if weight.is_a?(WeightType)
|
354
370
|
primitive "font-weight #{FONT_WEIGHT_NAMES[weight.to_i]}"
|
355
371
|
else
|
356
|
-
primitive "font-weight #{weight}"
|
372
|
+
primitive "font-weight #{Integer(weight)}"
|
357
373
|
end
|
358
374
|
end
|
359
375
|
|
@@ -364,6 +380,12 @@ module Magick
|
|
364
380
|
primitive "gravity #{GRAVITY_NAMES[grav.to_i]}"
|
365
381
|
end
|
366
382
|
|
383
|
+
def image(composite, x, y, width, height, image_file_path)
|
384
|
+
Kernel.raise ArgumentError, 'Unknown composite' unless composite.is_a?(CompositeOperator)
|
385
|
+
composite_name = composite.to_s.sub!('CompositeOp', '')
|
386
|
+
primitive 'image ' + format('%s %g,%g %g,%g %s', composite_name, x, y, width, height, enquote(image_file_path))
|
387
|
+
end
|
388
|
+
|
367
389
|
# IM 6.5.5-8 and later
|
368
390
|
def interline_spacing(space)
|
369
391
|
begin
|
@@ -408,16 +430,15 @@ module Magick
|
|
408
430
|
# Set matte (make transparent) in image according to the specified
|
409
431
|
# colorization rule
|
410
432
|
def matte(x, y, method)
|
433
|
+
Kernel.warn 'Draw#matte is deprecated. Use Draw#alpha instead.'
|
411
434
|
Kernel.raise ArgumentError, 'Unknown paint method' unless PAINT_METHOD_NAMES.key?(method.to_i)
|
412
|
-
primitive
|
435
|
+
primitive 'matte ' + format('%g,%g, %s', x, y, PAINT_METHOD_NAMES[method.to_i])
|
413
436
|
end
|
414
437
|
|
415
438
|
# Specify drawing fill and stroke opacities. If the value is a string
|
416
439
|
# ending with a %, the number will be multiplied by 0.01.
|
417
440
|
def opacity(opacity)
|
418
|
-
|
419
|
-
Kernel.raise ArgumentError, 'opacity must be >= 0 and <= 1.0' if opacity < 0 || opacity > 1.0
|
420
|
-
end
|
441
|
+
check_opacity(opacity)
|
421
442
|
primitive "opacity #{opacity}"
|
422
443
|
end
|
423
444
|
|
@@ -433,7 +454,7 @@ module Magick
|
|
433
454
|
# as the argument to the 'fill' or 'stroke' methods
|
434
455
|
def pattern(name, x, y, width, height)
|
435
456
|
push('defs')
|
436
|
-
push("pattern #{name}
|
457
|
+
push("pattern #{name} " + format('%g %g %g %g', x, y, width, height))
|
437
458
|
push('graphic-context')
|
438
459
|
yield
|
439
460
|
ensure
|
@@ -444,13 +465,13 @@ module Magick
|
|
444
465
|
|
445
466
|
# Set point to fill color.
|
446
467
|
def point(x, y)
|
447
|
-
primitive
|
468
|
+
primitive 'point ' + format('%g,%g', x, y)
|
448
469
|
end
|
449
470
|
|
450
471
|
# Specify the font size in points. Yes, the primitive is "font-size" but
|
451
472
|
# in other places this value is called the "pointsize". Give it both names.
|
452
473
|
def pointsize(points)
|
453
|
-
primitive
|
474
|
+
primitive 'font-size ' + format('%g', points)
|
454
475
|
end
|
455
476
|
alias font_size pointsize
|
456
477
|
|
@@ -461,7 +482,7 @@ module Magick
|
|
461
482
|
elsif points.length.odd?
|
462
483
|
Kernel.raise ArgumentError, 'odd number of points specified'
|
463
484
|
end
|
464
|
-
primitive 'polygon ' + points.join(',')
|
485
|
+
primitive 'polygon ' + points.map! { |x| format('%g', x) }.join(',')
|
465
486
|
end
|
466
487
|
|
467
488
|
# Draw a polyline
|
@@ -471,7 +492,7 @@ module Magick
|
|
471
492
|
elsif points.length.odd?
|
472
493
|
Kernel.raise ArgumentError, 'odd number of points specified'
|
473
494
|
end
|
474
|
-
primitive 'polyline ' + points.join(',')
|
495
|
+
primitive 'polyline ' + points.map! { |x| format('%g', x) }.join(',')
|
475
496
|
end
|
476
497
|
|
477
498
|
# Return to the previously-saved set of whatever
|
@@ -511,7 +532,7 @@ module Magick
|
|
511
532
|
|
512
533
|
# Specify coordinate space rotation. "angle" is measured in degrees
|
513
534
|
def rotate(angle)
|
514
|
-
primitive
|
535
|
+
primitive 'rotate ' + format('%g', angle)
|
515
536
|
end
|
516
537
|
|
517
538
|
# Draw a rectangle with rounded corners
|
@@ -522,15 +543,15 @@ module Magick
|
|
522
543
|
|
523
544
|
# Specify scaling to be applied to coordinate space on subsequent drawing commands.
|
524
545
|
def scale(x, y)
|
525
|
-
primitive
|
546
|
+
primitive 'scale ' + format('%g,%g', x, y)
|
526
547
|
end
|
527
548
|
|
528
549
|
def skewx(angle)
|
529
|
-
primitive
|
550
|
+
primitive 'skewX ' + format('%g', angle)
|
530
551
|
end
|
531
552
|
|
532
553
|
def skewy(angle)
|
533
|
-
primitive
|
554
|
+
primitive 'skewY ' + format('%g', angle)
|
534
555
|
end
|
535
556
|
|
536
557
|
# Specify the object stroke, a color name or pattern name.
|
@@ -560,7 +581,7 @@ module Magick
|
|
560
581
|
|
561
582
|
# Specify the initial offset in the dash pattern
|
562
583
|
def stroke_dashoffset(value = 0)
|
563
|
-
primitive
|
584
|
+
primitive 'stroke-dashoffset ' + format('%g', value)
|
564
585
|
end
|
565
586
|
|
566
587
|
def stroke_linecap(value)
|
@@ -580,13 +601,14 @@ module Magick
|
|
580
601
|
|
581
602
|
# Specify opacity of stroke drawing color
|
582
603
|
# (use "xx%" to indicate percentage)
|
583
|
-
def stroke_opacity(
|
584
|
-
|
604
|
+
def stroke_opacity(opacity)
|
605
|
+
check_opacity(opacity)
|
606
|
+
primitive "stroke-opacity #{opacity}"
|
585
607
|
end
|
586
608
|
|
587
609
|
# Specify stroke (outline) width in pixels.
|
588
610
|
def stroke_width(pixels)
|
589
|
-
primitive
|
611
|
+
primitive 'stroke-width ' + format('%g', pixels)
|
590
612
|
end
|
591
613
|
|
592
614
|
# Draw text at position x,y. Add quotes to text that is not already quoted.
|
@@ -604,7 +626,7 @@ module Magick
|
|
604
626
|
# escape existing braces, surround with braces
|
605
627
|
text = '{' + text.gsub(/[}]/) { |b| '\\' + b } + '}'
|
606
628
|
end
|
607
|
-
primitive
|
629
|
+
primitive 'text ' + format('%g,%g %s', x, y, text)
|
608
630
|
end
|
609
631
|
|
610
632
|
# Specify text alignment relative to a given point
|
@@ -633,7 +655,7 @@ module Magick
|
|
633
655
|
# Specify center of coordinate space to use for subsequent drawing
|
634
656
|
# commands.
|
635
657
|
def translate(x, y)
|
636
|
-
primitive
|
658
|
+
primitive 'translate ' + format('%g,%g', x, y)
|
637
659
|
end
|
638
660
|
end # class Magick::Draw
|
639
661
|
|
@@ -904,9 +926,9 @@ module Magick
|
|
904
926
|
# Make the pixel at (x,y) transparent.
|
905
927
|
def matte_point(x, y)
|
906
928
|
f = copy
|
907
|
-
f.
|
929
|
+
f.alpha(OpaqueAlphaChannel) unless f.alpha?
|
908
930
|
pixel = f.pixel_color(x, y)
|
909
|
-
pixel.
|
931
|
+
pixel.alpha = TransparentAlpha
|
910
932
|
f.pixel_color(x, y, pixel)
|
911
933
|
f
|
912
934
|
end
|
@@ -915,7 +937,7 @@ module Magick
|
|
915
937
|
# pixel at (x, y).
|
916
938
|
def matte_replace(x, y)
|
917
939
|
f = copy
|
918
|
-
f.
|
940
|
+
f.alpha(OpaqueAlphaChannel) unless f.alpha?
|
919
941
|
target = f.pixel_color(x, y)
|
920
942
|
f.transparent(target)
|
921
943
|
end
|
@@ -924,23 +946,21 @@ module Magick
|
|
924
946
|
# at (x,y) and is a neighbor.
|
925
947
|
def matte_floodfill(x, y)
|
926
948
|
f = copy
|
927
|
-
f.
|
949
|
+
f.alpha(OpaqueAlphaChannel) unless f.alpha?
|
928
950
|
target = f.pixel_color(x, y)
|
929
|
-
f.matte_flood_fill(target,
|
930
|
-
x, y, FloodfillMethod)
|
951
|
+
f.matte_flood_fill(target, x, y, FloodfillMethod, alpha: TransparentAlpha)
|
931
952
|
end
|
932
953
|
|
933
954
|
# Make transparent any neighbor pixel that is not the border color.
|
934
955
|
def matte_fill_to_border(x, y)
|
935
956
|
f = copy
|
936
|
-
f.
|
937
|
-
f.matte_flood_fill(border_color,
|
938
|
-
x, y, FillToBorderMethod)
|
957
|
+
f.alpha(OpaqueAlphaChannel) unless f.alpha?
|
958
|
+
f.matte_flood_fill(border_color, x, y, FillToBorderMethod, alpha: TransparentAlpha)
|
939
959
|
end
|
940
960
|
|
941
961
|
# Make all pixels transparent.
|
942
962
|
def matte_reset!
|
943
|
-
|
963
|
+
alpha(TransparentAlphaChannel)
|
944
964
|
self
|
945
965
|
end
|
946
966
|
|
@@ -1376,13 +1396,6 @@ module Magick
|
|
1376
1396
|
end
|
1377
1397
|
alias size length
|
1378
1398
|
|
1379
|
-
# Array#nitems is not available in 1.9
|
1380
|
-
if Array.instance_methods.include?('nitems')
|
1381
|
-
def nitems
|
1382
|
-
@images.nitems
|
1383
|
-
end
|
1384
|
-
end
|
1385
|
-
|
1386
1399
|
def clear
|
1387
1400
|
@scene = nil
|
1388
1401
|
@images.clear
|