rmagick 2.15.3 → 2.15.4

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.

Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +14 -0
  3. data/.rubocop.yml +27 -3
  4. data/.travis.yml +9 -6
  5. data/CHANGELOG.md +4 -0
  6. data/CONTRIBUTING.md +10 -0
  7. data/README.textile +4 -0
  8. data/before_install_linux.sh +4 -4
  9. data/doc/ex/gravity.rb +2 -1
  10. data/ext/RMagick/extconf.rb +60 -17
  11. data/lib/rmagick/version.rb +1 -1
  12. data/lib/rvg/clippath.rb +37 -36
  13. data/lib/rvg/container.rb +106 -107
  14. data/lib/rvg/deep_equal.rb +46 -48
  15. data/lib/rvg/describable.rb +35 -36
  16. data/lib/rvg/embellishable.rb +384 -380
  17. data/lib/rvg/misc.rb +705 -690
  18. data/lib/rvg/paint.rb +39 -40
  19. data/lib/rvg/pathdata.rb +120 -121
  20. data/lib/rvg/rvg.rb +212 -209
  21. data/lib/rvg/stretchable.rb +159 -158
  22. data/lib/rvg/stylable.rb +99 -100
  23. data/lib/rvg/text.rb +0 -1
  24. data/lib/rvg/transformable.rb +110 -110
  25. data/lib/rvg/units.rb +58 -58
  26. data/rmagick.gemspec +1 -1
  27. data/spec/rmagick/image/blue_shift_spec.rb +16 -0
  28. data/spec/rmagick/image/composite_spec.rb +140 -0
  29. data/spec/rmagick/image/constitute_spec.rb +15 -0
  30. data/spec/rmagick/image/dispatch_spec.rb +18 -0
  31. data/spec/rmagick/image/from_blob_spec.rb +14 -0
  32. data/spec/rmagick/image/ping_spec.rb +14 -0
  33. data/spec/rmagick/image/properties_spec.rb +29 -0
  34. data/spec/spec_helper.rb +3 -0
  35. data/test/Image1.rb +524 -718
  36. data/test/Image2.rb +1262 -1262
  37. data/test/Image3.rb +973 -973
  38. data/test/ImageList2.rb +341 -341
  39. data/test/Image_attributes.rb +678 -678
  40. data/test/Info.rb +336 -336
  41. data/test/Magick.rb +245 -242
  42. data/test/Pixel.rb +105 -105
  43. data/test/Preview.rb +42 -42
  44. metadata +21 -6
@@ -3,7 +3,6 @@
3
3
  # Copyright (C) 2009 Timothy P. Hunter
4
4
  #++
5
5
  # Text-related classes
6
-
7
6
  module Magick
8
7
  class RVG
9
8
  # Base class for Tspan, Tref and Text.
@@ -2,125 +2,125 @@
2
2
  # $Id: transformable.rb,v 1.5 2009/02/28 23:52:28 rmagick Exp $
3
3
  # Copyright (C) 2009 Timothy P. Hunter
4
4
  #++
5
-
6
5
  module Magick
7
- class RVG
8
- # Transforms is an Array with a deep_copy method.
9
- # During unit-testing it also has a deep_equal method.
10
- class Transforms < Array #:nodoc:
11
- def deep_copy(h=nil)
12
- copy = self.class.new
13
- each { |transform| copy << [transform[0], transform[1].dup] }
14
- copy
15
- end
16
- end # class Transform
6
+ class RVG
7
+ # Transforms is an Array with a deep_copy method.
8
+ # During unit-testing it also has a deep_equal method.
9
+ class Transforms < Array #:nodoc:
10
+ def deep_copy(h = nil)
11
+ copy = self.class.new
12
+ each { |transform| copy << [transform[0], transform[1].dup] }
13
+ copy
14
+ end
15
+ end # class Transform
17
16
 
18
- # Transformations are operations on the coordinate system.
19
- # All the transformations defined within a container (an RVG object
20
- # or a group) are applied before drawing any shapes or text.
21
- # All transformations are applied in the order they were
22
- # defined. <em>Note:</em> This means that
23
- # g.translate(10,20).scale(2)
24
- # is not the same as
25
- # g.scale(2).translate(10,20)
26
- module Transformable
27
- private
17
+ # Transformations are operations on the coordinate system.
18
+ # All the transformations defined within a container (an RVG object
19
+ # or a group) are applied before drawing any shapes or text.
20
+ # All transformations are applied in the order they were
21
+ # defined. <em>Note:</em> This means that
22
+ # g.translate(10,20).scale(2)
23
+ # is not the same as
24
+ # g.scale(2).translate(10,20)
25
+ module Transformable
26
+ private
28
27
 
29
- # Apply transforms in the same order they were specified!
30
- def add_transform_primitives(gc)
31
- @transforms.each { |transform| gc.__send__(transform[0], *transform[1]) }
32
- end
28
+ # Apply transforms in the same order they were specified!
29
+ def add_transform_primitives(gc)
30
+ @transforms.each { |transform| gc.__send__(transform[0], *transform[1]) }
31
+ end
33
32
 
34
- def initialize(*args, &block)
35
- super()
36
- @transforms = Transforms.new
37
- end
33
+ def initialize(*args, &block)
34
+ super()
35
+ @transforms = Transforms.new
36
+ end
38
37
 
39
- public
38
+ public
40
39
 
41
- # Applies the transformation matrix [sx, rx, ry, sy, tx, ty]
42
- def matrix(sx, rx, ry, sy, tx, ty)
43
- begin
44
- @transforms << [:affine, [Float(sx), Float(rx), Float(ry), Float(sy), Float(tx), Float(ty)]]
45
- rescue ArgumentError
46
- raise ArgumentError, "arguments must be convertable to float (got #{sx.class}, #{rx.class}, #{ry.class}, #{sy.class}, #{sx.class}, #{sx.class}, #{tx.class}, #{ty.class})"
47
- end
48
- yield(self) if block_given?
49
- self
50
- end
40
+ # Applies the transformation matrix [sx, rx, ry, sy, tx, ty]
41
+ def matrix(sx, rx, ry, sy, tx, ty)
42
+ begin
43
+ @transforms << [:affine, [Float(sx), Float(rx), Float(ry), Float(sy), Float(tx), Float(ty)]]
44
+ rescue ArgumentError
45
+ raise ArgumentError, "arguments must be convertable to float (got #{sx.class}, #{rx.class}, #{ry.class}, #{sy.class}, #{sx.class}, #{sx.class}, #{tx.class}, #{ty.class})"
46
+ end
47
+ yield(self) if block_given?
48
+ self
49
+ end
51
50
 
52
- # Add <tt>tx</tt> to all x-coordinates and <tt>ty</tt>
53
- # to all y-coordinates. If <tt>ty</tt> is omitted it defaults
54
- # to <tt>tx</tt>.
55
- def translate(tx, ty=nil)
56
- ty ||= tx
57
- begin
58
- @transforms << [:translate, [Float(tx), Float(ty)]]
59
- rescue ArgumentError
60
- raise ArgumentError, "arguments must be convertable to float (got #{tx.class}, #{ty.class})"
61
- end
62
- yield(self) if block_given?
63
- self
64
- end
51
+ # Add <tt>tx</tt> to all x-coordinates and <tt>ty</tt>
52
+ # to all y-coordinates. If <tt>ty</tt> is omitted it defaults
53
+ # to <tt>tx</tt>.
54
+ def translate(tx, ty = nil)
55
+ ty ||= tx
56
+ begin
57
+ @transforms << [:translate, [Float(tx), Float(ty)]]
58
+ rescue ArgumentError
59
+ raise ArgumentError, "arguments must be convertable to float (got #{tx.class}, #{ty.class})"
60
+ end
61
+ yield(self) if block_given?
62
+ self
63
+ end
65
64
 
66
- # Multiply the x-coordinates by <tt>sx</tt> and the y-coordinates
67
- # by <tt>sy</tt>. If <tt>sy</tt> is omitted it defaults to <tt>sx</tt>.
68
- def scale(sx, sy=nil)
69
- sy ||= sx
70
- begin
71
- @transforms << [:scale, [Float(sx), Float(sy)]]
72
- rescue ArgumentError
73
- raise ArgumentError, "arguments must be convertable to float (got #{sx.class}, #{sy.class})"
74
- end
75
- yield(self) if block_given?
76
- self
77
- end
65
+ # Multiply the x-coordinates by <tt>sx</tt> and the y-coordinates
66
+ # by <tt>sy</tt>. If <tt>sy</tt> is omitted it defaults to <tt>sx</tt>.
67
+ def scale(sx, sy = nil)
68
+ sy ||= sx
69
+ begin
70
+ @transforms << [:scale, [Float(sx), Float(sy)]]
71
+ rescue ArgumentError
72
+ raise ArgumentError, "arguments must be convertable to float (got #{sx.class}, #{sy.class})"
73
+ end
74
+ yield(self) if block_given?
75
+ self
76
+ end
78
77
 
79
- # This method can take either of two argument lists:
80
- # [rotate(angle)] rotate by <tt>angle</tt> degrees
81
- # [rotate(angle, cx, cy)] rotate by <tt>angle</tt> degrees about
82
- # the point [<tt>cx</tt>, <tt>cy</tt>].
83
- def rotate(angle, *args)
84
- begin
85
- case args.length
86
- when 0
87
- @transforms << [:rotate, [Float(angle)]]
88
- when 2
89
- cx, cy = Float(args[0]), Float(args[1])
90
- @transforms << [:translate, [cx, cy]]
91
- @transforms << [:rotate, [angle]]
92
- @transforms << [:translate, [-cx, -cy]]
93
- else
94
- fail ArgumentError, "wrong number of arguments (#{args.length} for 1 or 3)"
95
- end
96
- rescue ArgumentError
97
- raise ArgumentError, "arguments must be convertable to float (got #{[angle, *args].collect {|a| a.class}.join(', ')})"
98
- end
99
- yield(self) if block_given?
100
- self
101
- end
78
+ # This method can take either of two argument lists:
79
+ # [rotate(angle)] rotate by <tt>angle</tt> degrees
80
+ # [rotate(angle, cx, cy)] rotate by <tt>angle</tt> degrees about
81
+ # the point [<tt>cx</tt>, <tt>cy</tt>].
82
+ def rotate(angle, *args)
83
+ begin
84
+ case args.length
85
+ when 0
86
+ @transforms << [:rotate, [Float(angle)]]
87
+ when 2
88
+ cx = Float(args[0])
89
+ cy = Float(args[1])
90
+ @transforms << [:translate, [cx, cy]]
91
+ @transforms << [:rotate, [angle]]
92
+ @transforms << [:translate, [-cx, -cy]]
93
+ else
94
+ fail ArgumentError, "wrong number of arguments (#{args.length} for 1 or 3)"
95
+ end
96
+ rescue ArgumentError
97
+ raise ArgumentError, "arguments must be convertable to float (got #{[angle, *args].collect {|a| a.class}.join(', ')})"
98
+ end
99
+ yield(self) if block_given?
100
+ self
101
+ end
102
102
 
103
- # Skew the X-axis by <tt>angle</tt> degrees.
104
- def skewX(angle)
105
- begin
106
- @transforms << [:skewx, [Float(angle)]]
107
- rescue ArgumentError
108
- raise ArgumentError, "argument must be convertable to float (got #{angle.class})"
109
- end
110
- yield(self) if block_given?
111
- self
112
- end
103
+ # Skew the X-axis by <tt>angle</tt> degrees.
104
+ def skewX(angle)
105
+ begin
106
+ @transforms << [:skewx, [Float(angle)]]
107
+ rescue ArgumentError
108
+ raise ArgumentError, "argument must be convertable to float (got #{angle.class})"
109
+ end
110
+ yield(self) if block_given?
111
+ self
112
+ end
113
113
 
114
- # Skew the Y-axis by <tt>angle</tt> degrees.
115
- def skewY(angle)
116
- begin
117
- @transforms << [:skewy, [Float(angle)]]
118
- rescue ArgumentError
119
- raise ArgumentError, "argument must be convertable to float (got #{angle.class})"
120
- end
121
- yield(self) if block_given?
122
- self
123
- end
124
- end # module Transformable
125
- end # class RVG
114
+ # Skew the Y-axis by <tt>angle</tt> degrees.
115
+ def skewY(angle)
116
+ begin
117
+ @transforms << [:skewy, [Float(angle)]]
118
+ rescue ArgumentError
119
+ raise ArgumentError, "argument must be convertable to float (got #{angle.class})"
120
+ end
121
+ yield(self) if block_given?
122
+ self
123
+ end
124
+ end # module Transformable
125
+ end # class RVG
126
126
  end # module Magick
@@ -1,63 +1,63 @@
1
1
  # $Id: units.rb,v 1.5 2009/02/28 23:52:28 rmagick Exp $
2
2
  # Copyright (C) 2009 Timothy P. Hunter
3
3
  module Magick
4
- class RVG
5
- # Define RVG.dpi and RVG.dpi=. Add conversions to Fixnum and Float classes
6
- class << self
7
- attr_reader :dpi
8
- def dpi=(n)
9
- unless defined?(@dpi)
10
- [Float, Fixnum].each do |c|
11
- c.class_eval <<-END_DEFS
12
- # the default measurement - 1px is 1 pixel
13
- def px
14
- self
15
- end
16
- # inches
17
- def in
18
- self * ::Magick::RVG.dpi
19
- end
20
- # millimeters
21
- def mm
22
- self * ::Magick::RVG.dpi / 25.4
23
- end
24
- # centimeters
25
- def cm
26
- self * ::Magick::RVG.dpi / 2.54
27
- end
28
- # points
29
- def pt
30
- self * ::Magick::RVG.dpi / 72.0
31
- end
32
- # picas
33
- def pc
34
- self * ::Magick::RVG.dpi / 6.0
35
- end
36
- # percentage of the argument
37
- def pct(of)
38
- self * Float(of) / 100.0
39
- end
40
- # the default is deg
41
- def deg
42
- self
43
- end
44
- # radians -> degrees
45
- def rad
46
- self * 180.0 / Math::PI
47
- end
48
- # grads -> degrees
49
- def grad
50
- self * 9.0 / 10.0
51
- end
52
- END_DEFS
53
- end
54
- end
4
+ class RVG
5
+ # Define RVG.dpi and RVG.dpi=. Add conversions to Fixnum and Float classes
6
+ class << self
7
+ attr_reader :dpi
8
+ def dpi=(n)
9
+ unless defined?(@dpi)
10
+ [Float, Fixnum].each do |c|
11
+ c.class_eval <<-END_DEFS
12
+ # the default measurement - 1px is 1 pixel
13
+ def px
14
+ self
15
+ end
16
+ # inches
17
+ def in
18
+ self * ::Magick::RVG.dpi
19
+ end
20
+ # millimeters
21
+ def mm
22
+ self * ::Magick::RVG.dpi / 25.4
23
+ end
24
+ # centimeters
25
+ def cm
26
+ self * ::Magick::RVG.dpi / 2.54
27
+ end
28
+ # points
29
+ def pt
30
+ self * ::Magick::RVG.dpi / 72.0
31
+ end
32
+ # picas
33
+ def pc
34
+ self * ::Magick::RVG.dpi / 6.0
35
+ end
36
+ # percentage of the argument
37
+ def pct(of)
38
+ self * Float(of) / 100.0
39
+ end
40
+ # the default is deg
41
+ def deg
42
+ self
43
+ end
44
+ # radians -> degrees
45
+ def rad
46
+ self * 180.0 / Math::PI
47
+ end
48
+ # grads -> degrees
49
+ def grad
50
+ self * 9.0 / 10.0
51
+ end
52
+ END_DEFS
53
+ end
54
+ end
55
55
 
56
- @dpi = Float(n)
57
- return @dpi
58
- rescue ArgumentError
59
- raise TypeError, "Can't convert `#{n}' to Float"
60
- end
61
- end # class << self
62
- end # class RVG
56
+ @dpi = Float(n)
57
+ return @dpi
58
+ rescue ArgumentError
59
+ raise TypeError, "Can't convert `#{n}' to Float"
60
+ end
61
+ end # class << self
62
+ end # class RVG
63
63
  end # module Magick
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_development_dependency 'rspec', '~> 3.2.0'
34
34
 
35
35
  if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('1.9.2')
36
- s.add_development_dependency 'rubocop'
36
+ s.add_development_dependency 'rubocop', '~> 0.33.0'
37
37
  end
38
38
 
39
39
  if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.2.0')
@@ -0,0 +1,16 @@
1
+ RSpec.describe Magick::Image, '#blue_shift' do
2
+
3
+ let(:img) { Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first }
4
+
5
+ it 'returns a new Image' do
6
+ res = img.blue_shift
7
+ expect(res).to be_instance_of(Magick::Image)
8
+ expect(res).not_to eq img
9
+ end
10
+
11
+ it 'accepts one argument' do
12
+ expect { img.blue_shift(2) }.not_to raise_error
13
+ expect { img.blue_shift(2, 3) }.to raise_error(ArgumentError)
14
+ end
15
+
16
+ end
@@ -0,0 +1,140 @@
1
+ RSpec.describe Magick::Image, '#composite' do
2
+
3
+ let(:img1) { Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first }
4
+ let(:img2) { Magick::Image.read(IMAGES_DIR+'/Button_1.gif').first }
5
+ let(:composite_ops) do
6
+ [
7
+ Magick::UndefinedCompositeOp,
8
+ Magick::NoCompositeOp,
9
+ Magick::AddCompositeOp,
10
+ Magick::AtopCompositeOp,
11
+ Magick::BumpmapCompositeOp,
12
+ Magick::ClearCompositeOp,
13
+ Magick::ColorizeCompositeOp,
14
+ Magick::CopyBlueCompositeOp,
15
+ Magick::CopyCompositeOp,
16
+ Magick::CopyGreenCompositeOp,
17
+ Magick::CopyOpacityCompositeOp,
18
+ Magick::CopyRedCompositeOp,
19
+ Magick::CopyCyanCompositeOp,
20
+ Magick::CopyMagentaCompositeOp,
21
+ Magick::CopyYellowCompositeOp,
22
+ Magick::CopyBlackCompositeOp,
23
+ Magick::DarkenCompositeOp,
24
+ Magick::DifferenceCompositeOp,
25
+ Magick::DisplaceCompositeOp,
26
+ Magick::DissolveCompositeOp,
27
+ Magick::DstAtopCompositeOp,
28
+ Magick::DstCompositeOp,
29
+ Magick::DstInCompositeOp,
30
+ Magick::DstOutCompositeOp,
31
+ Magick::DstOverCompositeOp,
32
+ Magick::HueCompositeOp,
33
+ Magick::InCompositeOp,
34
+ Magick::LightenCompositeOp,
35
+ Magick::LuminizeCompositeOp,
36
+ Magick::MinusCompositeOp,
37
+ Magick::ModulateCompositeOp,
38
+ Magick::MultiplyCompositeOp,
39
+ Magick::OutCompositeOp,
40
+ Magick::OverCompositeOp,
41
+ Magick::OverlayCompositeOp,
42
+ Magick::PlusCompositeOp,
43
+ Magick::ReplaceCompositeOp,
44
+ Magick::SaturateCompositeOp,
45
+ Magick::ScreenCompositeOp,
46
+ Magick::SrcAtopCompositeOp,
47
+ Magick::SrcCompositeOp,
48
+ Magick::SrcInCompositeOp,
49
+ Magick::SrcOutCompositeOp,
50
+ Magick::SrcOverCompositeOp,
51
+ Magick::SubtractCompositeOp,
52
+ Magick::ThresholdCompositeOp,
53
+ Magick::XorCompositeOp,
54
+ Magick::BlendCompositeOp,
55
+ Magick::ColorBurnCompositeOp,
56
+ Magick::ColorDodgeCompositeOp,
57
+ Magick::ExclusionCompositeOp,
58
+ Magick::HardLightCompositeOp,
59
+ Magick::SoftLightCompositeOp
60
+ ]
61
+ end
62
+ let(:gravity) do
63
+ [
64
+ Magick::NorthEastGravity,
65
+ Magick::EastGravity,
66
+ Magick::SouthWestGravity,
67
+ Magick::SouthGravity,
68
+ Magick::SouthEastGravity
69
+ ]
70
+ end
71
+
72
+ it 'raises an error given invalid arguments' do
73
+ expect { img1.composite }.to raise_error(ArgumentError)
74
+ expect { img1.composite(img2) }.to raise_error(ArgumentError)
75
+ expect do
76
+ img1.composite(img2, Magick::NorthWestGravity)
77
+ end.to raise_error(ArgumentError)
78
+ expect { img1.composite(2) }.to raise_error(ArgumentError)
79
+ expect { img1.composite(img2, 2) }.to raise_error(ArgumentError)
80
+ end
81
+
82
+ context 'when given 3 arguments' do
83
+ it 'works when 2nd argument is a gravity' do
84
+ composite_ops.each do |op|
85
+ gravity.each do |grav|
86
+ expect { img1.composite(img2, grav, op) }.not_to raise_error
87
+ end
88
+ end
89
+ end
90
+
91
+ it 'raises an error when 2nd argument is not a gravity' do
92
+ expect do
93
+ img1.composite(img2, 2, Magick::OverCompositeOp)
94
+ end.to raise_error(TypeError)
95
+ end
96
+ end
97
+
98
+ context 'when given 4 arguments' do
99
+ it 'works when 4th argument is a composite operator' do
100
+ # there are way too many CompositeOperators to test them all, so just try
101
+ # few representative ops
102
+ composite_ops.each do |op|
103
+ expect { img1.composite(img2, 0, 0, op) }.not_to raise_error
104
+ end
105
+ end
106
+
107
+ it 'returns a new Magick::Image object' do
108
+ res = img1.composite(img2, 0, 0, Magick::OverCompositeOp)
109
+ expect(res).to be_instance_of(Magick::Image)
110
+ end
111
+
112
+ it 'raises an error when 4th argument is not a composite operator' do
113
+ expect { img1.composite(img2, 0, 0, 2) }.to raise_error(TypeError)
114
+ end
115
+ end
116
+
117
+ context 'when given 5 arguments' do
118
+ it 'works when 2nd argument is gravity and 5th is a composite operator' do
119
+ composite_ops.each do |op|
120
+ gravity.each do |grav|
121
+ expect { img1.composite(img2, grav, 0, 0, op) }.not_to raise_error
122
+ end
123
+ end
124
+ end
125
+
126
+ it 'raises an error when 2nd argument is not a gravity' do
127
+ expect do
128
+ img1.composite(img2, 0, 0, 2, Magick::OverCompositeOp)
129
+ end.to raise_error(TypeError)
130
+ end
131
+ end
132
+
133
+ it 'raises an error when the image has been destroyed' do
134
+ img2.destroy!
135
+ expect do
136
+ img1.composite(img2, Magick::CenterGravity, Magick::OverCompositeOp)
137
+ end.to raise_error(Magick::DestroyedImageError)
138
+ end
139
+
140
+ end