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
@@ -4,48 +4,47 @@
4
4
  #++
5
5
  # Defines paint server classes.
6
6
  # Eventually this will include gradients.
7
-
8
7
  module Magick
9
- class RVG
10
- class Pattern
11
- include StructureConstructors
12
- include UseConstructors
13
- include ShapeConstructors
14
- include TextConstructors
15
- include ImageConstructors
16
- include Stretchable
17
- include Duplicatable
18
- include Stylable
8
+ class RVG
9
+ class Pattern
10
+ include StructureConstructors
11
+ include UseConstructors
12
+ include ShapeConstructors
13
+ include TextConstructors
14
+ include ImageConstructors
15
+ include Stretchable
16
+ include Duplicatable
17
+ include Stylable
19
18
 
20
- # Return upper-left corner, width, height of viewport in user coordinates.
21
- # Usually these are the values specified when the Pattern object is
22
- # created, but they can be changed by a call to the viewbox method.
23
- attr_reader :x, :y, :width, :height
19
+ # Return upper-left corner, width, height of viewport in user coordinates.
20
+ # Usually these are the values specified when the Pattern object is
21
+ # created, but they can be changed by a call to the viewbox method.
22
+ attr_reader :x, :y, :width, :height
24
23
 
25
- # Create a pattern that can be used with the :fill or :stroke styles.
26
- # The +width+ and +height+ arguments define the viewport.
27
- # The pattern will be repeated at <tt>x+m*width</tt> and <tt>y+n*height</tt>
28
- # offsets.
29
- #
30
- # Define the pattern in the block.
31
- # The pattern can be composed of shapes (rectangle, circles, etc.), text,
32
- # raster images and container objects. You can include graphic objects by
33
- # referring to them with #use.
34
- def initialize(width=0, height=0, x=0, y=0)
35
- super()
36
- @width, @height, @x, @y = Magick::RVG.convert_to_float(width, height, x, y)
37
- @content = Content.new
38
- yield(self) if block_given?
39
- end
24
+ # Create a pattern that can be used with the :fill or :stroke styles.
25
+ # The +width+ and +height+ arguments define the viewport.
26
+ # The pattern will be repeated at <tt>x+m*width</tt> and <tt>y+n*height</tt>
27
+ # offsets.
28
+ #
29
+ # Define the pattern in the block.
30
+ # The pattern can be composed of shapes (rectangle, circles, etc.), text,
31
+ # raster images and container objects. You can include graphic objects by
32
+ # referring to them with #use.
33
+ def initialize(width = 0, height = 0, x = 0, y = 0)
34
+ super()
35
+ @width, @height, @x, @y = Magick::RVG.convert_to_float(width, height, x, y)
36
+ @content = Content.new
37
+ yield(self) if block_given?
38
+ end
40
39
 
41
- def add_primitives(gc, style) #:nodoc:
42
- name = __id__.to_s
43
- gc.pattern(name, @x, @y, @width, @height) do
44
- add_viewbox_primitives(@width, @height, gc)
45
- @content.each { |element| element.add_primitives(gc) }
46
- end
47
- gc.__send__(style, name)
48
- end
49
- end # class Pattern
50
- end # class RVG
40
+ def add_primitives(gc, style) #:nodoc:
41
+ name = __id__.to_s
42
+ gc.pattern(name, @x, @y, @width, @height) do
43
+ add_viewbox_primitives(@width, @height, gc)
44
+ @content.each { |element| element.add_primitives(gc) }
45
+ end
46
+ gc.__send__(style, name)
47
+ end
48
+ end # class Pattern
49
+ end # class RVG
51
50
  end # module Magick
@@ -2,126 +2,125 @@
2
2
  # $Id: pathdata.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
- # The PathData class provides an object-oriented way to produce an SVG
9
- # path. Each of the methods corresponds to a path command. Construct a
10
- # path by calling one or more methods. The path object can be passed
11
- # as an argument to the RVG::ShapeConstructors#path method.
12
- class PathData
13
- private
14
-
15
- def add_points(req, *coords)
16
- if coords
17
- if coords.length % req != 0
18
- fail ArgumentError, "wrong number of coordinates specified. A multiple of #{req} required, #{req+coords.length} given."
19
- end
20
- coords.each {|c| @path << ('%g' % c)}
21
- end
22
- end
23
-
24
- public
25
-
26
- # Construct an empty path
27
- def initialize
28
- @path = ''
29
- end
30
-
31
- # Convert the path to its string equivalent.
32
- def to_s
33
- @path
34
- end
35
-
36
- def deep_copy(h=nil) #:nodoc:
37
- @path.dup
38
- end
39
-
40
- # Add a <tt>moveto</tt> command. If <tt>abs</tt> is
41
- # <tt>true</tt> the coordinates are absolute, otherwise
42
- # the coordinates are relative.
43
- def moveto(abs, x, y, *coords)
44
- @path << sprintf('%s%g,%g ', (abs ? 'M' : 'm'), x, y)
45
- # "subsequent pairs are treated as implicit lineto commands"
46
- add_points(2, *coords)
47
- end
48
-
49
- # Add a <tt>closepath</tt> command. The <tt>abs</tt> argument
50
- # is ignored.
51
- def closepath(abs=true)
52
- @path << 'Z' # ignore `abs'
53
- end
54
-
55
- # Add a <tt>lineto</tt> command. Any number of x,y coordinate
56
- # pairs may be specified. If <tt>abs</tt> is
57
- # <tt>true</tt> the coordinates are absolute, otherwise
58
- # the coordinates are relative.
59
- def lineto(abs, x, y, *coords)
60
- @path << sprintf('%s%g,%g ', (abs ? 'L' : 'l'), x, y)
61
- # "a number of coordinate pairs may be specified to draw a polyline"
62
- add_points(2, *coords)
63
- end
64
-
65
- # Add a <tt>horizontal lineto</tt> command. If <tt>abs</tt> is
66
- # <tt>true</tt> the coordinates are absolute, otherwise
67
- # the coordinates are relative.
68
- def hlineto(abs, x)
69
- @path << sprintf('%s%g ', (abs ? 'H' : 'h'), x)
70
- end
71
-
72
- # Add a <tt>vertical lineto</tt> command. If <tt>abs</tt> is
73
- # <tt>true</tt> the coordinates are absolute, otherwise
74
- # the coordinates are relative.
75
- def vlineto(abs, y)
76
- @path << sprintf('%s%g ', (abs ? 'V' : 'v'), y)
77
- end
78
-
79
- # Add a <tt>curveto</tt> (<em>cubic Bezier</em>) command.
80
- # If <tt>abs</tt> is
81
- # <tt>true</tt> the coordinates are absolute, otherwise
82
- # the coordinates are relative.
83
- def curveto(abs, x1, y1, x2, y2, x, y, *coords)
84
- @path << sprintf('%s%g,%g %g,%g %g,%g ', (abs ? 'C' : 'c'), x1, y1, x2, y2, x, y)
85
- # "multiple sets of coordinates may be specified to draw a polybezier"
86
- add_points(6, *coords)
87
- end
88
-
89
- # Add a <tt>smooth curveto</tt> (<em>cubic Bezier</em>) command.
90
- # If <tt>abs</tt> is
91
- # <tt>true</tt> the coordinates are absolute, otherwise
92
- # the coordinates are relative.
93
- def smooth_curveto(abs, x2, y2, x, y, *coords)
94
- @path << sprintf('%s%g,%g %g,%g ', (abs ? 'S' : 's'), x2, y2, x, y)
95
- # "multiple sets of coordinates may be specified to draw a polybezier"
96
- add_points(4, *coords)
97
- end
98
-
99
- # Add a <tt>quadratic Bezier curveto</tt> command.
100
- # If <tt>abs</tt> is
101
- # <tt>true</tt> the coordinates are absolute, otherwise
102
- # the coordinates are relative.
103
- def quadratic_curveto(abs, x1, y1, x, y, *coords)
104
- @path << sprintf('%s%g,%g %g,%g ', (abs ? 'Q' : 'q'), x1, y1, x, y)
105
- add_points(4, *coords)
106
- end
107
-
108
- # Add a <tt>smooth quadratic Bezier curveto</tt> command.
109
- # If <tt>abs</tt> is
110
- # <tt>true</tt> the coordinates are absolute, otherwise
111
- # the coordinates are relative.
112
- def smooth_quadratic_curveto(abs, x, y, *coords)
113
- @path << sprintf('%s%g,%g ', (abs ? 'T' : 't'), x, y)
114
- add_points(2, *coords)
115
- end
116
-
117
- # Add an <tt>arc</tt> command.
118
- # If <tt>abs</tt> is
119
- # <tt>true</tt> the coordinates are absolute, otherwise
120
- # the coordinates are relative.
121
-
122
- def arc(abs, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
123
- @path << sprintf('%s%g,%g %g %d %d %g,%g ', (abs ? 'A' : 'a'), rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
124
- end
125
- end # class PathData
126
- end # class RVG
6
+ class RVG
7
+ # The PathData class provides an object-oriented way to produce an SVG
8
+ # path. Each of the methods corresponds to a path command. Construct a
9
+ # path by calling one or more methods. The path object can be passed
10
+ # as an argument to the RVG::ShapeConstructors#path method.
11
+ class PathData
12
+ private
13
+
14
+ def add_points(req, *coords)
15
+ if coords
16
+ if coords.length % req != 0
17
+ fail ArgumentError, "wrong number of coordinates specified. A multiple of #{req} required, #{req+coords.length} given."
18
+ end
19
+ coords.each {|c| @path << ('%g' % c)}
20
+ end
21
+ end
22
+
23
+ public
24
+
25
+ # Construct an empty path
26
+ def initialize
27
+ @path = ''
28
+ end
29
+
30
+ # Convert the path to its string equivalent.
31
+ def to_s
32
+ @path
33
+ end
34
+
35
+ def deep_copy(h = nil) #:nodoc:
36
+ @path.dup
37
+ end
38
+
39
+ # Add a <tt>moveto</tt> command. If <tt>abs</tt> is
40
+ # <tt>true</tt> the coordinates are absolute, otherwise
41
+ # the coordinates are relative.
42
+ def moveto(abs, x, y, *coords)
43
+ @path << sprintf('%s%g,%g ', (abs ? 'M' : 'm'), x, y)
44
+ # "subsequent pairs are treated as implicit lineto commands"
45
+ add_points(2, *coords)
46
+ end
47
+
48
+ # Add a <tt>closepath</tt> command. The <tt>abs</tt> argument
49
+ # is ignored.
50
+ def closepath(abs = true)
51
+ @path << 'Z' # ignore `abs'
52
+ end
53
+
54
+ # Add a <tt>lineto</tt> command. Any number of x,y coordinate
55
+ # pairs may be specified. If <tt>abs</tt> is
56
+ # <tt>true</tt> the coordinates are absolute, otherwise
57
+ # the coordinates are relative.
58
+ def lineto(abs, x, y, *coords)
59
+ @path << sprintf('%s%g,%g ', (abs ? 'L' : 'l'), x, y)
60
+ # "a number of coordinate pairs may be specified to draw a polyline"
61
+ add_points(2, *coords)
62
+ end
63
+
64
+ # Add a <tt>horizontal lineto</tt> command. If <tt>abs</tt> is
65
+ # <tt>true</tt> the coordinates are absolute, otherwise
66
+ # the coordinates are relative.
67
+ def hlineto(abs, x)
68
+ @path << sprintf('%s%g ', (abs ? 'H' : 'h'), x)
69
+ end
70
+
71
+ # Add a <tt>vertical lineto</tt> command. If <tt>abs</tt> is
72
+ # <tt>true</tt> the coordinates are absolute, otherwise
73
+ # the coordinates are relative.
74
+ def vlineto(abs, y)
75
+ @path << sprintf('%s%g ', (abs ? 'V' : 'v'), y)
76
+ end
77
+
78
+ # Add a <tt>curveto</tt> (<em>cubic Bezier</em>) command.
79
+ # If <tt>abs</tt> is
80
+ # <tt>true</tt> the coordinates are absolute, otherwise
81
+ # the coordinates are relative.
82
+ def curveto(abs, x1, y1, x2, y2, x, y, *coords)
83
+ @path << sprintf('%s%g,%g %g,%g %g,%g ', (abs ? 'C' : 'c'), x1, y1, x2, y2, x, y)
84
+ # "multiple sets of coordinates may be specified to draw a polybezier"
85
+ add_points(6, *coords)
86
+ end
87
+
88
+ # Add a <tt>smooth curveto</tt> (<em>cubic Bezier</em>) command.
89
+ # If <tt>abs</tt> is
90
+ # <tt>true</tt> the coordinates are absolute, otherwise
91
+ # the coordinates are relative.
92
+ def smooth_curveto(abs, x2, y2, x, y, *coords)
93
+ @path << sprintf('%s%g,%g %g,%g ', (abs ? 'S' : 's'), x2, y2, x, y)
94
+ # "multiple sets of coordinates may be specified to draw a polybezier"
95
+ add_points(4, *coords)
96
+ end
97
+
98
+ # Add a <tt>quadratic Bezier curveto</tt> command.
99
+ # If <tt>abs</tt> is
100
+ # <tt>true</tt> the coordinates are absolute, otherwise
101
+ # the coordinates are relative.
102
+ def quadratic_curveto(abs, x1, y1, x, y, *coords)
103
+ @path << sprintf('%s%g,%g %g,%g ', (abs ? 'Q' : 'q'), x1, y1, x, y)
104
+ add_points(4, *coords)
105
+ end
106
+
107
+ # Add a <tt>smooth quadratic Bezier curveto</tt> command.
108
+ # If <tt>abs</tt> is
109
+ # <tt>true</tt> the coordinates are absolute, otherwise
110
+ # the coordinates are relative.
111
+ def smooth_quadratic_curveto(abs, x, y, *coords)
112
+ @path << sprintf('%s%g,%g ', (abs ? 'T' : 't'), x, y)
113
+ add_points(2, *coords)
114
+ end
115
+
116
+ # Add an <tt>arc</tt> command.
117
+ # If <tt>abs</tt> is
118
+ # <tt>true</tt> the coordinates are absolute, otherwise
119
+ # the coordinates are relative.
120
+
121
+ def arc(abs, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
122
+ @path << sprintf('%s%g,%g %g %d %d %g,%g ', (abs ? 'A' : 'a'), rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
123
+ end
124
+ end # class PathData
125
+ end # class RVG
127
126
  end # module Magick
@@ -27,7 +27,6 @@
27
27
  # OSI Certified is a certification mark of the Open Source Initiative.
28
28
  #
29
29
  #++############################################################################
30
-
31
30
  require 'rmagick'
32
31
  require 'rvg/misc'
33
32
  require 'rvg/describable'
@@ -47,234 +46,238 @@ require 'pp' if ENV['debug_rvg']
47
46
  # RVG is the main class in this library. All graphic elements
48
47
  # must be contained within an RVG object.
49
48
  module Magick
50
- class RVG
51
- include Stylable
52
- include Transformable
53
- include Stretchable
54
- include Embellishable
55
- include Describable
56
- include Duplicatable
49
+ class RVG
50
+ include Stylable
51
+ include Transformable
52
+ include Stretchable
53
+ include Embellishable
54
+ include Describable
55
+ include Duplicatable
57
56
 
58
- private
57
+ private
59
58
 
60
- # background_fill defaults to 'none'. If background_fill has been set to something
61
- # else, combine it with the background_fill_opacity.
62
- def bgfill
63
- if @background_fill.nil?
64
- color = Magick::Pixel.new(0,0,0,Magick::TransparentOpacity)
65
- else
66
- color = @background_fill
67
- color.opacity = (1.0 - @background_fill_opacity) * Magick::TransparentOpacity
68
- end
69
- color
70
- end
59
+ # background_fill defaults to 'none'. If background_fill has been set to something
60
+ # else, combine it with the background_fill_opacity.
61
+ def bgfill
62
+ if @background_fill.nil?
63
+ color = Magick::Pixel.new(0,0,0,Magick::TransparentOpacity)
64
+ else
65
+ color = @background_fill
66
+ color.opacity = (1.0 - @background_fill_opacity) * Magick::TransparentOpacity
67
+ end
68
+ color
69
+ end
71
70
 
72
- def new_canvas
73
- if @background_pattern
74
- canvas = Magick::Image.new(@width, @height, @background_pattern)
75
- elsif @background_image
76
- if @width != @background_image.columns || @height != @background_image.rows
77
- canvas = case @background_position
78
- when :scaled
79
- @background_image.resize(@width, @height)
80
- when :tiled
81
- Magick::Image.new(@width, @height, Magick::TextureFill.new(@background_image))
82
- when :fit
83
- width, height = @width, @height
84
- bgcolor = bgfill
85
- @background_image.change_geometry(Magick::Geometry.new(width, height)) do |new_cols, new_rows|
86
- bg_image = @background_image.resize(new_cols, new_rows)
87
- if bg_image.columns != width || bg_image.rows != height
88
- bg = Magick::Image.new(width, height) { self.background_color = bgcolor }
89
- bg_image = bg.composite!(bg_image, Magick::CenterGravity, Magick::OverCompositeOp)
90
- end
91
- bg_image
92
- end
93
- end
94
- else
95
- canvas = @background_image.copy
71
+ def new_canvas
72
+ if @background_pattern
73
+ canvas = Magick::Image.new(@width, @height, @background_pattern)
74
+ elsif @background_image
75
+ if @width != @background_image.columns || @height != @background_image.rows
76
+ canvas = case @background_position
77
+ when :scaled
78
+ @background_image.resize(@width, @height)
79
+ when :tiled
80
+ Magick::Image.new(@width, @height, Magick::TextureFill.new(@background_image))
81
+ when :fit
82
+ width = @width
83
+ height = @height
84
+ bgcolor = bgfill
85
+ @background_image.change_geometry(Magick::Geometry.new(width, height)) do |new_cols, new_rows|
86
+ bg_image = @background_image.resize(new_cols, new_rows)
87
+ if bg_image.columns != width || bg_image.rows != height
88
+ bg = Magick::Image.new(width, height) { self.background_color = bgcolor }
89
+ bg_image = bg.composite!(bg_image, Magick::CenterGravity, Magick::OverCompositeOp)
96
90
  end
97
- else
98
- bgcolor = bgfill
99
- canvas = Magick::Image.new(Integer(@width), Integer(@height)) { self.background_color = bgcolor }
100
- end
101
- canvas[:desc] = @desc if @desc
102
- canvas[:title] = @title if @title
103
- canvas[:metadata] = @metadata if @metadata
104
- canvas
91
+ bg_image
92
+ end
93
+ end
94
+ else
95
+ canvas = @background_image.copy
105
96
  end
97
+ else
98
+ bgcolor = bgfill
99
+ canvas = Magick::Image.new(Integer(@width), Integer(@height)) { self.background_color = bgcolor }
100
+ end
101
+ canvas[:desc] = @desc if @desc
102
+ canvas[:title] = @title if @title
103
+ canvas[:metadata] = @metadata if @metadata
104
+ canvas
105
+ end
106
106
 
107
- if ENV['debug_prim']
108
- def print_gc(gc)
109
- primitives = gc.inspect.split(/\n/)
110
- indent = 0
111
- primitives.each do |cmd|
112
- indent -= 1 if cmd['pop ']
113
- print((' '*indent), cmd, "\n")
114
- indent += 1 if cmd['push ']
115
- end
116
- end
107
+ if ENV['debug_prim']
108
+ def print_gc(gc)
109
+ primitives = gc.inspect.split(/\n/)
110
+ indent = 0
111
+ primitives.each do |cmd|
112
+ indent -= 1 if cmd['pop ']
113
+ print((' '*indent), cmd, "\n")
114
+ indent += 1 if cmd['push ']
117
115
  end
116
+ end
117
+ end
118
118
 
119
- public
119
+ public
120
120
 
121
- WORD_SEP = / / # Regexp to separate words
121
+ WORD_SEP = / / # Regexp to separate words
122
122
 
123
- # The background image specified by background_image=
124
- attr_reader :background_image
125
- # The background image layout specified by background_position=
126
- attr_reader :background_position
127
- # The background fill color specified by background_fill=
128
- attr_reader :background_fill
129
- # The background fill color opacity specified by background_fill_opacity=
130
- attr_reader :background_fill_opacity
131
- # The image after drawing has completed
132
- attr_reader :canvas
133
- # For embedded RVG objects, the x-axis coordinate of the upper-left corner
134
- attr_reader :x
135
- # For embedded RVG objects, the x-axis coordinate of the upper-left corner
136
- attr_reader :y
137
- attr_reader :width, :height
123
+ # The background image specified by background_image=
124
+ attr_reader :background_image
125
+ # The background image layout specified by background_position=
126
+ attr_reader :background_position
127
+ # The background fill color specified by background_fill=
128
+ attr_reader :background_fill
129
+ # The background fill color opacity specified by background_fill_opacity=
130
+ attr_reader :background_fill_opacity
131
+ # The image after drawing has completed
132
+ attr_reader :canvas
133
+ # For embedded RVG objects, the x-axis coordinate of the upper-left corner
134
+ attr_reader :x
135
+ # For embedded RVG objects, the x-axis coordinate of the upper-left corner
136
+ attr_reader :y
137
+ attr_reader :width, :height
138
138
 
139
- # Sets an image to use as the canvas background. See background_position= for layout options.
140
- def background_image=(bg_image)
141
- warn 'background_image= has no effect in nested RVG objects' if @nested
142
- if bg_image && !bg_image.is_a?(Magick::Image)
143
- fail ArgumentError, "background image must be an Image (got #{bg_image.class})"
144
- end
145
- @background_image = bg_image
146
- end
139
+ # Sets an image to use as the canvas background. See background_position= for layout options.
140
+ def background_image=(bg_image)
141
+ warn 'background_image= has no effect in nested RVG objects' if @nested
142
+ if bg_image && !bg_image.is_a?(Magick::Image)
143
+ fail ArgumentError, "background image must be an Image (got #{bg_image.class})"
144
+ end
145
+ @background_image = bg_image
146
+ end
147
147
 
148
- # Sets an object to use to fill the canvas background.
149
- # The object must have a <tt>fill</tt> method. See the <b>Fill Classes</b>
150
- # section in the RMagick doc for more information.
151
- def background_pattern=(filler)
152
- warn 'background_pattern= has no effect in nested RVG objects' if @nested
153
- @background_pattern = filler
154
- end
148
+ # Sets an object to use to fill the canvas background.
149
+ # The object must have a <tt>fill</tt> method. See the <b>Fill Classes</b>
150
+ # section in the RMagick doc for more information.
151
+ def background_pattern=(filler)
152
+ warn 'background_pattern= has no effect in nested RVG objects' if @nested
153
+ @background_pattern = filler
154
+ end
155
155
 
156
- # How to position the background image on the canvas. One of the following symbols:
157
- # [:scaled] Scale the image to the canvas width and height.
158
- # [:tiled] Tile the image across the canvas.
159
- # [:fit] Scale the image to fit within the canvas while retaining the
160
- # image proportions. Center the image on the canvas. Color any part of
161
- # the canvas not covered by the image with the background color.
162
- def background_position=(pos)
163
- warn 'background_position= has no effect in nested RVG objects' if @nested
164
- bg_pos = pos.to_s.downcase
165
- unless ['scaled', 'tiled', 'fit'].include?(bg_pos)
166
- fail ArgumentError, "background position must be `scaled', `tiled', or `fit' (#{pos} given)"
167
- end
168
- @background_position = bg_pos.to_sym
169
- end
156
+ # How to position the background image on the canvas. One of the following symbols:
157
+ # [:scaled] Scale the image to the canvas width and height.
158
+ # [:tiled] Tile the image across the canvas.
159
+ # [:fit] Scale the image to fit within the canvas while retaining the
160
+ # image proportions. Center the image on the canvas. Color any part of
161
+ # the canvas not covered by the image with the background color.
162
+ def background_position=(pos)
163
+ warn 'background_position= has no effect in nested RVG objects' if @nested
164
+ bg_pos = pos.to_s.downcase
165
+ unless ['scaled', 'tiled', 'fit'].include?(bg_pos)
166
+ fail ArgumentError, "background position must be `scaled', `tiled', or `fit' (#{pos} given)"
167
+ end
168
+ @background_position = bg_pos.to_sym
169
+ end
170
170
 
171
- # Sets the canvas background color. Either a Magick::Pixel or a color name.
172
- # The default fill is "none", that is, transparent black.
173
- def background_fill=(color)
174
- warn 'background_fill= has no effect in nested RVG objects' if @nested
175
- if !color.is_a?(Magick::Pixel)
176
- begin
177
- @background_fill = Magick::Pixel.from_color(color)
178
- rescue Magick::ImageMagickError
179
- raise ArgumentError, "unknown color `#{color}'"
180
- rescue TypeError
181
- raise TypeError, "cannot convert #{color.class} into Pixel"
182
- rescue
183
- raise ArgumentError, "argument must be a color name or a Pixel (got #{color.class})"
184
- end
185
- else
186
- @background_fill = color
187
- end
171
+ # Sets the canvas background color. Either a Magick::Pixel or a color name.
172
+ # The default fill is "none", that is, transparent black.
173
+ def background_fill=(color)
174
+ warn 'background_fill= has no effect in nested RVG objects' if @nested
175
+ if !color.is_a?(Magick::Pixel)
176
+ begin
177
+ @background_fill = Magick::Pixel.from_color(color)
178
+ rescue Magick::ImageMagickError
179
+ raise ArgumentError, "unknown color `#{color}'"
180
+ rescue TypeError
181
+ raise TypeError, "cannot convert #{color.class} into Pixel"
182
+ rescue
183
+ raise ArgumentError, "argument must be a color name or a Pixel (got #{color.class})"
188
184
  end
185
+ else
186
+ @background_fill = color
187
+ end
188
+ end
189
189
 
190
- # Opacity of the background fill color, a number between 0.0 (transparent) and
191
- # 1.0 (opaque). The default is 1.0 when the background_fill= attribute has been set.
192
- def background_fill_opacity=(opacity)
193
- warn 'background_fill_opacity= has no effect in nested RVG objects' if @nested
194
- begin
195
- @background_fill_opacity = Float(opacity)
196
- rescue ArgumentError
197
- raise ArgumentError, "background_fill_opacity must be a number between 0 and 1 (#{opacity} given)"
198
- end
199
- end
190
+ # Opacity of the background fill color, a number between 0.0 (transparent) and
191
+ # 1.0 (opaque). The default is 1.0 when the background_fill= attribute has been set.
192
+ def background_fill_opacity=(opacity)
193
+ warn 'background_fill_opacity= has no effect in nested RVG objects' if @nested
194
+ begin
195
+ @background_fill_opacity = Float(opacity)
196
+ rescue ArgumentError
197
+ raise ArgumentError, "background_fill_opacity must be a number between 0 and 1 (#{opacity} given)"
198
+ end
199
+ end
200
200
 
201
- # Draw a +width+ x +height+ image. The image is specified by calling
202
- # one or more drawing methods on the RVG object.
203
- # You can group the drawing method calls in the optional associated block.
204
- # The +x+ and +y+ arguments have no meaning for the outermost RVG object.
205
- # On nested RVG objects [+x+, +y+] is the coordinate of the upper-left
206
- # corner in the containing canvas on which the nested RVG object is placed.
207
- #
208
- # Drawing occurs on a +canvas+ created by the #draw method. By default the
209
- # canvas is transparent. You can specify a different canvas with the
210
- # #background_fill= or #background_image= methods.
211
- #
212
- # RVG objects are _containers_. That is, styles and transforms defined
213
- # on the object are used by contained objects such as shapes, text, and
214
- # groups unless overridden by an inner container or the object itself.
215
- def initialize(width=nil, height=nil)
216
- super
217
- @width, @height = width, height
218
- @content = Content.new
219
- @canvas = nil
220
- @background_fill = nil
221
- @background_fill_opacity = 1.0 # applies only if background_fill= is used
222
- @background_position = :scaled
223
- @background_pattern, @background_image, @desc, @title, @metadata = nil
224
- @x, @y = 0.0, 0.0
225
- @nested = false
226
- yield(self) if block_given?
227
- end
201
+ # Draw a +width+ x +height+ image. The image is specified by calling
202
+ # one or more drawing methods on the RVG object.
203
+ # You can group the drawing method calls in the optional associated block.
204
+ # The +x+ and +y+ arguments have no meaning for the outermost RVG object.
205
+ # On nested RVG objects [+x+, +y+] is the coordinate of the upper-left
206
+ # corner in the containing canvas on which the nested RVG object is placed.
207
+ #
208
+ # Drawing occurs on a +canvas+ created by the #draw method. By default the
209
+ # canvas is transparent. You can specify a different canvas with the
210
+ # #background_fill= or #background_image= methods.
211
+ #
212
+ # RVG objects are _containers_. That is, styles and transforms defined
213
+ # on the object are used by contained objects such as shapes, text, and
214
+ # groups unless overridden by an inner container or the object itself.
215
+ def initialize(width = nil, height = nil)
216
+ super
217
+ @width = width
218
+ @height = height
219
+ @content = Content.new
220
+ @canvas = nil
221
+ @background_fill = nil
222
+ @background_fill_opacity = 1.0 # applies only if background_fill= is used
223
+ @background_position = :scaled
224
+ @background_pattern, @background_image, @desc, @title, @metadata = nil
225
+ @x = 0.0
226
+ @y = 0.0
227
+ @nested = false
228
+ yield(self) if block_given?
229
+ end
228
230
 
229
- # Construct a canvas or reuse an existing canvas.
230
- # Execute drawing commands. Return the canvas.
231
- def draw
232
- fail StandardError, 'draw not permitted in nested RVG objects' if @nested
233
- @canvas ||= new_canvas # allow drawing over existing canvas
234
- gc = Utility::GraphicContext.new
235
- add_outermost_primitives(gc)
236
- pp(self) if ENV['debug_rvg']
237
- print_gc(gc) if ENV['debug_prim']
238
- gc.draw(@canvas)
239
- @canvas
240
- end
231
+ # Construct a canvas or reuse an existing canvas.
232
+ # Execute drawing commands. Return the canvas.
233
+ def draw
234
+ fail StandardError, 'draw not permitted in nested RVG objects' if @nested
235
+ @canvas ||= new_canvas # allow drawing over existing canvas
236
+ gc = Utility::GraphicContext.new
237
+ add_outermost_primitives(gc)
238
+ pp(self) if ENV['debug_rvg']
239
+ print_gc(gc) if ENV['debug_prim']
240
+ gc.draw(@canvas)
241
+ @canvas
242
+ end
241
243
 
242
- # Accept #use arguments. Use (x,y) to generate an additional translate.
243
- # Override @width and @height if new values are supplied.
244
- def ref(x, y, rw, rh) #:nodoc:
245
- translate(x, y) if x != 0 || y != 0
246
- @width = rw if rw
247
- @height = rh if rh
248
- end
244
+ # Accept #use arguments. Use (x,y) to generate an additional translate.
245
+ # Override @width and @height if new values are supplied.
246
+ def ref(x, y, rw, rh) #:nodoc:
247
+ translate(x, y) if x != 0 || y != 0
248
+ @width = rw if rw
249
+ @height = rh if rh
250
+ end
249
251
 
250
- # Used by Magick::Embellishable.rvg to set non-0 x- and y-coordinates
251
- def corner(x, y) #:nodoc:
252
- @nested = true
253
- @x, @y = Float(x), Float(y)
254
- translate(@x, @y) if @x != 0.0 || @y != 0.0
255
- end
252
+ # Used by Magick::Embellishable.rvg to set non-0 x- and y-coordinates
253
+ def corner(x, y) #:nodoc:
254
+ @nested = true
255
+ @x = Float(x)
256
+ @y = Float(y)
257
+ translate(@x, @y) if @x != 0.0 || @y != 0.0
258
+ end
256
259
 
257
- # Primitives for the outermost RVG object
258
- def add_outermost_primitives(gc) #:nodoc:
259
- add_transform_primitives(gc)
260
- gc.push
261
- add_viewbox_primitives(@width, @height, gc)
262
- add_style_primitives(gc)
263
- @content.each { |element| element.add_primitives(gc) }
264
- gc.pop
265
- self
266
- end
260
+ # Primitives for the outermost RVG object
261
+ def add_outermost_primitives(gc) #:nodoc:
262
+ add_transform_primitives(gc)
263
+ gc.push
264
+ add_viewbox_primitives(@width, @height, gc)
265
+ add_style_primitives(gc)
266
+ @content.each { |element| element.add_primitives(gc) }
267
+ gc.pop
268
+ self
269
+ end
267
270
 
268
- # Primitives for nested RVG objects
269
- def add_primitives(gc) #:nodoc:
270
- if @width.nil? || @height.nil?
271
- fail ArgumentError, 'RVG width or height undefined'
272
- elsif @width == 0 || @height == 0
273
- return self
274
- end
275
- gc.push
276
- add_outermost_primitives(gc)
277
- gc.pop
278
- end
279
- end # end class RVG
271
+ # Primitives for nested RVG objects
272
+ def add_primitives(gc) #:nodoc:
273
+ if @width.nil? || @height.nil?
274
+ fail ArgumentError, 'RVG width or height undefined'
275
+ elsif @width == 0 || @height == 0
276
+ return self
277
+ end
278
+ gc.push
279
+ add_outermost_primitives(gc)
280
+ gc.pop
281
+ end
282
+ end # end class RVG
280
283
  end # end module Magick