rmagick 1.14.1 → 1.15.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.

Files changed (66) hide show
  1. data/ChangeLog +22 -0
  2. data/README.html +11 -63
  3. data/README.txt +8 -56
  4. data/configure +214 -787
  5. data/configure.ac +22 -24
  6. data/doc/comtasks.html +2 -2
  7. data/doc/constants.html +5 -6
  8. data/doc/draw.html +33 -14
  9. data/doc/ex/clip_path.rb +3 -0
  10. data/doc/ex/path.rb +1 -1
  11. data/doc/ex/polaroid.rb +23 -0
  12. data/doc/ex/tspan01.rb +2 -2
  13. data/doc/ex/tspan02.rb +2 -2
  14. data/doc/ex/tspan03.rb +3 -3
  15. data/doc/ex/wet_floor.rb +54 -0
  16. data/doc/ilist.html +83 -4
  17. data/doc/image1.html +4 -5
  18. data/doc/image2.html +395 -266
  19. data/doc/image3.html +104 -8
  20. data/doc/imageattrs.html +2 -2
  21. data/doc/imusage.html +2 -2
  22. data/doc/index.html +22 -18
  23. data/doc/info.html +28 -6
  24. data/doc/magick.html +125 -4
  25. data/doc/optequiv.html +196 -21
  26. data/doc/rvg.html +2 -2
  27. data/doc/rvgclip.html +2 -2
  28. data/doc/rvggroup.html +2 -2
  29. data/doc/rvgimage.html +2 -2
  30. data/doc/rvgpattern.html +2 -2
  31. data/doc/rvgshape.html +2 -2
  32. data/doc/rvgstyle.html +2 -2
  33. data/doc/rvgtext.html +2 -2
  34. data/doc/rvgtspan.html +2 -2
  35. data/doc/rvgtut.html +3 -3
  36. data/doc/rvguse.html +2 -2
  37. data/doc/rvgxform.html +2 -2
  38. data/doc/struct.html +2 -2
  39. data/doc/usage.html +26 -5
  40. data/ext/RMagick/MANIFEST +3 -1
  41. data/ext/RMagick/rmagick.h +46 -12
  42. data/ext/RMagick/rmagick_config.h.in +12 -2
  43. data/ext/RMagick/rmdraw.c +202 -62
  44. data/ext/RMagick/rmfill.c +36 -36
  45. data/ext/RMagick/rmilist.c +75 -31
  46. data/ext/RMagick/rmimage.c +640 -323
  47. data/ext/RMagick/rminfo.c +76 -15
  48. data/ext/RMagick/rmmain.c +107 -30
  49. data/ext/RMagick/rmutil.c +97 -68
  50. data/lib/RMagick.rb +11 -11
  51. data/lib/rvg/clippath.rb +38 -36
  52. data/lib/rvg/container.rb +120 -118
  53. data/lib/rvg/deep_equal.rb +44 -42
  54. data/lib/rvg/describable.rb +49 -47
  55. data/lib/rvg/embellishable.rb +399 -397
  56. data/lib/rvg/misc.rb +613 -603
  57. data/lib/rvg/paint.rb +38 -36
  58. data/lib/rvg/pathdata.rb +124 -122
  59. data/lib/rvg/rvg.rb +202 -198
  60. data/lib/rvg/stretchable.rb +132 -130
  61. data/lib/rvg/stylable.rb +101 -99
  62. data/lib/rvg/text.rb +173 -171
  63. data/lib/rvg/transformable.rb +120 -118
  64. data/lib/rvg/units.rb +60 -58
  65. data/rmagick.gemspec +1 -1
  66. metadata +5 -3
@@ -1,51 +1,53 @@
1
1
  #--
2
- # $Id: describable.rb,v 1.2 2005/12/31 14:41:04 rmagick Exp $
3
- # Copyright (C) 2006 Timothy P. Hunter
2
+ # $Id: describable.rb,v 1.3 2007/01/20 17:39:49 rmagick Exp $
3
+ # Copyright (C) 2007 Timothy P. Hunter
4
4
  #++
5
5
 
6
- class Magick::RVG
7
-
8
- #--
9
- # Corresponds to SVG's Description.class
10
- #++
11
- # This module defines a number of metadata attributes.
12
- module Describable
13
-
14
- private
15
-
16
- def initialize(*args, &block) #:nodoc:
17
- super
18
- @title, @desc, @metadata = nil
19
- end
20
-
21
- public
22
-
23
- # Sets the object description
24
- attr_writer :desc
25
- # Sets the object title
26
- attr_writer :title
27
- # Sets the object metadata
28
- attr_writer :metadata
29
-
30
- # Returns the title of this object. The RVG object title is stored as
31
- # the 'title' property on the image
32
- def title
33
- @title.to_s
34
- end
35
-
36
- # Returns the description of this object. The RVG object description is
37
- # stored as the 'desc' property on the image
38
- def desc
39
- @desc.to_s
40
- end
41
-
42
- # Returns additional metadata of this object. The RVG object metadata
43
- # are stored as the 'metadata' property on the image
44
- def metadata
45
- @metadata.to_s
46
- end
47
-
48
- end # module Describable
49
-
50
- end # class Magick::RVG
6
+ module Magick
7
+ class RVG
8
+
9
+ #--
10
+ # Corresponds to SVG's Description.class
11
+ #++
12
+ # This module defines a number of metadata attributes.
13
+ module Describable
14
+
15
+ private
16
+
17
+ def initialize(*args, &block) #:nodoc:
18
+ super
19
+ @title, @desc, @metadata = nil
20
+ end
21
+
22
+ public
23
+
24
+ # Sets the object description
25
+ attr_writer :desc
26
+ # Sets the object title
27
+ attr_writer :title
28
+ # Sets the object metadata
29
+ attr_writer :metadata
30
+
31
+ # Returns the title of this object. The RVG object title is stored as
32
+ # the 'title' property on the image
33
+ def title
34
+ @title.to_s
35
+ end
36
+
37
+ # Returns the description of this object. The RVG object description is
38
+ # stored as the 'desc' property on the image
39
+ def desc
40
+ @desc.to_s
41
+ end
42
+
43
+ # Returns additional metadata of this object. The RVG object metadata
44
+ # are stored as the 'metadata' property on the image
45
+ def metadata
46
+ @metadata.to_s
47
+ end
48
+
49
+ end # module Describable
50
+
51
+ end # class RVG
52
+ end # module Magick
51
53
 
@@ -1,415 +1,417 @@
1
1
  #--
2
- # $Id: embellishable.rb,v 1.6 2005/12/31 14:41:04 rmagick Exp $
3
- # Copyright (C) 2006 Timothy P. Hunter
2
+ # $Id: embellishable.rb,v 1.7 2007/01/20 17:39:49 rmagick Exp $
3
+ # Copyright (C) 2007 Timothy P. Hunter
4
4
  #++
5
5
 
6
- class Magick::RVG
7
-
8
- # Parent class of Circle, Ellipse, Text, etc.
9
- class Shape #:nodoc:
10
- include Stylable
11
- include Transformable
12
- include Duplicatable
13
-
14
- # Each shape can have its own set of transforms and styles.
15
- def add_primitives(gc)
16
- gc.push
17
- add_transform_primitives(gc)
18
- add_style_primitives(gc)
19
- gc.__send__(@primitive, *@args)
20
- gc.pop
21
- end
22
-
23
- end # class Shape
24
-
25
- class Circle < Shape
26
-
27
- # Define a circle with radius +r+ and centered at [<tt>cx</tt>, <tt>cy</tt>].
28
- # Use the RVG::ShapeConstructors#circle method to create Circle objects in a container.
29
- def initialize(r, cx=0, cy=0)
30
- super()
31
- r, cx, cy = Magick::RVG.convert_to_float(r, cx, cy)
32
- if r < 0
33
- raise ArgumentError, "radius must be >= 0 (#{r} given)"
6
+ module Magick
7
+ class RVG
8
+
9
+ # Parent class of Circle, Ellipse, Text, etc.
10
+ class Shape #:nodoc:
11
+ include Stylable
12
+ include Transformable
13
+ include Duplicatable
14
+
15
+ # Each shape can have its own set of transforms and styles.
16
+ def add_primitives(gc)
17
+ gc.push
18
+ add_transform_primitives(gc)
19
+ add_style_primitives(gc)
20
+ gc.__send__(@primitive, *@args)
21
+ gc.pop
34
22
  end
35
- @primitive = :circle
36
- @args = [cx, cy, cx+r, cy]
37
- self
38
- end
39
-
40
- end # class Circle
41
-
42
- class Ellipse < Shape
43
-
44
- # Define an ellipse with a center at [<tt>cx</tt>, <tt>cy</tt>], a horizontal radius +rx+
45
- # and a vertical radius +ry+.
46
- # Use the RVG::ShapeConstructors#ellipse method to create Ellipse objects in a container.
47
- def initialize(rx, ry, cx=0, cy=0)
48
- super()
49
- rx, ry, cx, cy = Magick::RVG.convert_to_float(rx, ry, cx, cy)
50
- if rx < 0 || ry < 0
51
- raise ArgumentError, "radii must be >= 0 (#{rx}, #{ry} given)"
23
+
24
+ end # class Shape
25
+
26
+ class Circle < Shape
27
+
28
+ # Define a circle with radius +r+ and centered at [<tt>cx</tt>, <tt>cy</tt>].
29
+ # Use the RVG::ShapeConstructors#circle method to create Circle objects in a container.
30
+ def initialize(r, cx=0, cy=0)
31
+ super()
32
+ r, cx, cy = Magick::RVG.convert_to_float(r, cx, cy)
33
+ if r < 0
34
+ raise ArgumentError, "radius must be >= 0 (#{r} given)"
35
+ end
36
+ @primitive = :circle
37
+ @args = [cx, cy, cx+r, cy]
38
+ self
39
+ end
40
+
41
+ end # class Circle
42
+
43
+ class Ellipse < Shape
44
+
45
+ # Define an ellipse with a center at [<tt>cx</tt>, <tt>cy</tt>], a horizontal radius +rx+
46
+ # and a vertical radius +ry+.
47
+ # Use the RVG::ShapeConstructors#ellipse method to create Ellipse objects in a container.
48
+ def initialize(rx, ry, cx=0, cy=0)
49
+ super()
50
+ rx, ry, cx, cy = Magick::RVG.convert_to_float(rx, ry, cx, cy)
51
+ if rx < 0 || ry < 0
52
+ raise ArgumentError, "radii must be >= 0 (#{rx}, #{ry} given)"
53
+ end
54
+ @primitive = :ellipse
55
+ # Ellipses are always complete.
56
+ @args = [cx, cy, rx, ry, 0, 360]
52
57
  end
53
- @primitive = :ellipse
54
- # Ellipses are always complete.
55
- @args = [cx, cy, rx, ry, 0, 360]
56
- end
57
-
58
- end # class Ellipse
59
-
60
- class Line < Shape
61
-
62
- # Define a line from [<tt>x1</tt>, <tt>y1</tt>] to [<tt>x2</tt>, <tt>y2</tt>].
63
- # Use the RVG::ShapeConstructors#line method to create Line objects in a container.
64
- def initialize(x1=0, y1=0, x2=0, y2=0)
65
- super()
66
- @primitive = :line
67
- @args = [x1, y1, x2, y2]
68
- end
69
-
70
- end # class Line
71
-
72
- class Path < Shape
73
-
74
- # Define an SVG path. The argument can be either a path string
75
- # or a PathData object.
76
- # Use the RVG::ShapeConstructors#path method to create Path objects in a container.
77
- def initialize(path)
78
- super()
79
- @primitive = :path
80
- @args = [path.to_s]
81
- end
82
-
83
- end # class Path
84
-
85
- class Rect < Shape
86
-
87
- # Define a width x height rectangle. The upper-left corner is at [<tt>x</tt>, <tt>y</tt>].
88
- # If either <tt>width</tt> or <tt>height</tt> is 0, the rectangle is not rendered.
89
- # Use the RVG::ShapeConstructors#rect method to create Rect objects in a container.
90
- def initialize(width, height, x=0, y=0)
91
- super()
92
- width, height, x, y = Magick::RVG.convert_to_float(width, height, x, y)
93
- if width < 0 || height < 0
94
- raise ArgumentError, "width, height must be >= 0 (#{width}, #{height} given)"
58
+
59
+ end # class Ellipse
60
+
61
+ class Line < Shape
62
+
63
+ # Define a line from [<tt>x1</tt>, <tt>y1</tt>] to [<tt>x2</tt>, <tt>y2</tt>].
64
+ # Use the RVG::ShapeConstructors#line method to create Line objects in a container.
65
+ def initialize(x1=0, y1=0, x2=0, y2=0)
66
+ super()
67
+ @primitive = :line
68
+ @args = [x1, y1, x2, y2]
95
69
  end
96
- @args = [x, y, x+width, y+height]
97
- @primitive = :rectangle
98
- end
99
-
100
- # Specify optional rounded corners for a rectangle. The arguments
101
- # are the x- and y-axis radii. If y is omitted it defaults to x.
102
- def round(rx, ry=nil)
103
- rx, ry = Magick::RVG.convert_to_float(rx, ry || rx)
104
- if rx < 0 || ry < 0
105
- raise ArgumentError, "rx, ry must be >= 0 (#{rx}, #{ry} given)"
70
+
71
+ end # class Line
72
+
73
+ class Path < Shape
74
+
75
+ # Define an SVG path. The argument can be either a path string
76
+ # or a PathData object.
77
+ # Use the RVG::ShapeConstructors#path method to create Path objects in a container.
78
+ def initialize(path)
79
+ super()
80
+ @primitive = :path
81
+ @args = [path.to_s]
106
82
  end
107
- @args << rx << ry
108
- @primitive = :roundrectangle
109
- self
110
- end
111
-
112
- end # class Rect
113
-
114
- class PolyShape < Shape
115
-
116
- def polypoints(points)
117
- case points.length
118
- when 1
119
- points = Array(points[0])
120
- when 2
121
- x_coords = Array(points[0])
122
- y_coords = Array(points[1])
123
- unless x_coords.length > 0 && y_coords.length > 0
124
- raise ArgumentError, "array arguments must contain at least one point"
125
- end
126
- n = x_coords.length - y_coords.length
127
- short = n > 0 ? y_coords : x_coords
128
- olen = short.length
129
- n.abs.times {|x| short << short[x % olen]}
130
- points = x_coords.zip(y_coords).flatten
83
+
84
+ end # class Path
85
+
86
+ class Rect < Shape
87
+
88
+ # Define a width x height rectangle. The upper-left corner is at [<tt>x</tt>, <tt>y</tt>].
89
+ # If either <tt>width</tt> or <tt>height</tt> is 0, the rectangle is not rendered.
90
+ # Use the RVG::ShapeConstructors#rect method to create Rect objects in a container.
91
+ def initialize(width, height, x=0, y=0)
92
+ super()
93
+ width, height, x, y = Magick::RVG.convert_to_float(width, height, x, y)
94
+ if width < 0 || height < 0
95
+ raise ArgumentError, "width, height must be >= 0 (#{width}, #{height} given)"
96
+ end
97
+ @args = [x, y, x+width, y+height]
98
+ @primitive = :rectangle
99
+ end
100
+
101
+ # Specify optional rounded corners for a rectangle. The arguments
102
+ # are the x- and y-axis radii. If y is omitted it defaults to x.
103
+ def round(rx, ry=nil)
104
+ rx, ry = Magick::RVG.convert_to_float(rx, ry || rx)
105
+ if rx < 0 || ry < 0
106
+ raise ArgumentError, "rx, ry must be >= 0 (#{rx}, #{ry} given)"
107
+ end
108
+ @args << rx << ry
109
+ @primitive = :roundrectangle
110
+ self
111
+ end
112
+
113
+ end # class Rect
114
+
115
+ class PolyShape < Shape
116
+
117
+ def polypoints(points)
118
+ case points.length
119
+ when 1
120
+ points = Array(points[0])
121
+ when 2
122
+ x_coords = Array(points[0])
123
+ y_coords = Array(points[1])
124
+ unless x_coords.length > 0 && y_coords.length > 0
125
+ raise ArgumentError, "array arguments must contain at least one point"
126
+ end
127
+ n = x_coords.length - y_coords.length
128
+ short = n > 0 ? y_coords : x_coords
129
+ olen = short.length
130
+ n.abs.times {|x| short << short[x % olen]}
131
+ points = x_coords.zip(y_coords).flatten
132
+ end
133
+ n = points.length
134
+ if n < 4 || n % 2 != 0
135
+ raise ArgumentError, "insufficient/odd number of points specified: #{n}"
136
+ end
137
+ return Magick::RVG.convert_to_float(*points)
131
138
  end
132
- n = points.length
133
- if n < 4 || n % 2 != 0
134
- raise ArgumentError, "insufficient/odd number of points specified: #{n}"
139
+
140
+ end # class PolyShape
141
+
142
+ class Polygon < PolyShape
143
+
144
+ # Draws a polygon. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
145
+ # define the points that make up the polygon. At least two
146
+ # points must be specified. If the last point is not the
147
+ # same as the first, adds an additional point to close
148
+ # the polygon.
149
+ # Use the RVG::ShapeConstructors#polygon method to create Polygon objects in a container.
150
+ def initialize(*points)
151
+ super()
152
+ @primitive = :polygon
153
+ @args = polypoints(points)
154
+ end
155
+
156
+ end # class Polygon
157
+
158
+ class Polyline < PolyShape
159
+
160
+ # Draws a polyline. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
161
+ # define the points that make up the polyline. At least two
162
+ # points must be specified.
163
+ # Use the RVG::ShapeConstructors#polyline method to create Polyline objects in a container.
164
+ def initialize(*points)
165
+ super()
166
+ points = polypoints(points)
167
+ @primitive = :polyline
168
+ @args = Magick::RVG.convert_to_float(*points)
169
+ end
170
+
171
+ end # class Polyline
172
+
173
+
174
+ class Image
175
+ include Stylable
176
+ include Transformable
177
+ include Describable
178
+ include PreserveAspectRatio
179
+ include Duplicatable
180
+
181
+ private
182
+ def align_to_viewport(scale)
183
+ tx = case @align
184
+ when 'none', /\AxMin/
185
+ 0
186
+ when NilClass, /\AxMid/
187
+ (@width - @image.columns*scale) / 2.0
188
+ when /\AxMax/
189
+ @width - @image.columns*scale
190
+ end
191
+
192
+ ty = case @align
193
+ when 'none', /YMin\z/
194
+ 0
195
+ when NilClass, /YMid\z/
196
+ (@height - @image.rows*scale) / 2.0
197
+ when /YMax\z/
198
+ @height - @image.rows*scale
199
+ end
200
+ return [tx, ty]
135
201
  end
136
- return Magick::RVG.convert_to_float(*points)
137
- end
138
-
139
- end # class PolyShape
140
-
141
- class Polygon < PolyShape
142
-
143
- # Draws a polygon. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
144
- # define the points that make up the polygon. At least two
145
- # points must be specified. If the last point is not the
146
- # same as the first, adds an additional point to close
147
- # the polygon.
148
- # Use the RVG::ShapeConstructors#polygon method to create Polygon objects in a container.
149
- def initialize(*points)
150
- super()
151
- @primitive = :polygon
152
- @args = polypoints(points)
153
- end
154
-
155
- end # class Polygon
156
-
157
- class Polyline < PolyShape
158
-
159
- # Draws a polyline. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
160
- # define the points that make up the polyline. At least two
161
- # points must be specified.
162
- # Use the RVG::ShapeConstructors#polyline method to create Polyline objects in a container.
163
- def initialize(*points)
164
- super()
165
- points = polypoints(points)
166
- @primitive = :polyline
167
- @args = Magick::RVG.convert_to_float(*points)
168
- end
169
-
170
- end # class Polyline
171
-
172
-
173
- class Image
174
- include Stylable
175
- include Transformable
176
- include Describable
177
- include PreserveAspectRatio
178
- include Duplicatable
179
-
180
- private
181
- def align_to_viewport(scale)
182
- tx = case @align
183
- when 'none', /\AxMin/
184
- 0
185
- when NilClass, /\AxMid/
186
- (@width - @image.columns*scale) / 2.0
187
- when /\AxMax/
188
- @width - @image.columns*scale
202
+
203
+ def add_composite_primitive(gc)
204
+ if @align == 'none'
205
+ # Let RMagick do the scaling
206
+ scale = 1.0
207
+ width, height = @width, @height
208
+ elsif @meet_or_slice == 'meet'
209
+ scale = [@width/@image.columns, @height/@image.rows].min
210
+ width, height = @image.columns, @image.rows
211
+ else
212
+ # Establish clipping path around the current viewport
213
+ name = __id__.to_s
214
+ gc.define_clip_path(name) do
215
+ gc.path("M#{@x},#{@y} l#{@width},0 l0,#{@height} l-#{@width},0 l0,-#{@height}z")
216
+ end
217
+
218
+ gc.clip_path(name)
219
+ scale = [@width/@image.columns, @height/@image.rows].max
220
+ width, height = @image.columns, @image.rows
221
+ end
222
+ tx, ty = align_to_viewport(scale)
223
+ gc.composite(@x+tx, @y+ty, width*scale, height*scale, @image)
189
224
  end
190
225
 
191
- ty = case @align
192
- when 'none', /YMin\z/
193
- 0
194
- when NilClass, /YMid\z/
195
- (@height - @image.rows*scale) / 2.0
196
- when /YMax\z/
197
- @height - @image.rows*scale
226
+ def init_viewbox()
227
+ @align = nil
228
+ @vbx_width, @vbx_height = @image.columns, @image.rows
229
+ @meet_or_slice = 'meet'
198
230
  end
199
- return [tx, ty]
200
- end
201
-
202
- def add_composite_primitive(gc)
203
- if @align == 'none'
204
- # Let RMagick do the scaling
205
- scale = 1.0
206
- width, height = @width, @height
207
- elsif @meet_or_slice == 'meet'
208
- scale = [@width/@image.columns, @height/@image.rows].min
209
- width, height = @image.columns, @image.rows
210
- else
211
- # Establish clipping path around the current viewport
212
- name = __id__.to_s
213
- gc.define_clip_path(name) do
214
- gc.path("M#{@x},#{@y} l#{@width},0 l0,#{@height} l-#{@width},0 l0,-#{@height}z")
231
+
232
+ public
233
+
234
+ # Composite a raster image in the viewport defined by [x,y] and
235
+ # +width+ and +height+.
236
+ # Use the RVG::ImageConstructors#image method to create Text objects in a container.
237
+ def initialize(image, width=nil, height=nil, x=0, y=0)
238
+ super() # run module initializers
239
+ @image = image.copy # use a copy of the image in case app. re-uses the argument
240
+ @x, @y, @width, @height = Magick::RVG.convert_to_float(x, y, width || @image.columns, height || @image.rows)
241
+ if @width < 0 || @height < 0
242
+ raise ArgumentError, "width, height must be >= 0"
215
243
  end
244
+ init_viewbox()
245
+ end
246
+
247
+ def add_primitives(gc) #:nodoc:
248
+ # Do not render if width or height is 0
249
+ return if @width == 0 || @height == 0
250
+ gc.push
251
+ add_transform_primitives(gc)
252
+ add_style_primitives(gc)
253
+ add_composite_primitive(gc)
254
+ gc.pop
255
+ end
256
+
257
+ end # class Image
258
+
259
+
260
+ # Methods that construct basic shapes within a container
261
+ module ShapeConstructors
262
+
263
+ # Draws a circle whose center is [<tt>cx</tt>, <tt>cy</tt>] and radius is +r+.
264
+ def circle(r, cx=0, cy=0)
265
+ circle = Circle.new(r, cx, cy)
266
+ @content << circle
267
+ return circle
268
+ end
269
+
270
+ # Draws an ellipse whose center is [<tt>cx</tt>, <tt>cy</tt>] and having
271
+ # a horizontal radius +rx+ and vertical radius +ry+.
272
+ def ellipse(rx, ry, cx=0, cy=0)
273
+ ellipse = Ellipse.new(rx, ry, cx, cy)
274
+ @content << ellipse
275
+ return ellipse
276
+ end
216
277
 
217
- gc.clip_path(name)
218
- scale = [@width/@image.columns, @height/@image.rows].max
219
- width, height = @image.columns, @image.rows
278
+ # Draws a line from [<tt>x1</tt>, <tt>y1</tt>] to [<tt>x2</tt>, <tt>y2</tt>].
279
+ def line(x1=0, y1=0, x2=0, y2=0)
280
+ line = Line.new(x1, y1, x2, y2)
281
+ @content << line
282
+ return line
220
283
  end
221
- tx, ty = align_to_viewport(scale)
222
- gc.composite(@x+tx, @y+ty, width*scale, height*scale, @image)
223
- end
224
-
225
- def init_viewbox()
226
- @align = nil
227
- @vbx_width, @vbx_height = @image.columns, @image.rows
228
- @meet_or_slice = 'meet'
229
- end
230
-
231
- public
232
-
233
- # Composite a raster image in the viewport defined by [x,y] and
234
- # +width+ and +height+.
235
- # Use the RVG::ImageConstructors#image method to create Text objects in a container.
236
- def initialize(image, width=nil, height=nil, x=0, y=0)
237
- super() # run module initializers
238
- @image = image.copy # use a copy of the image in case app. re-uses the argument
239
- @x, @y, @width, @height = Magick::RVG.convert_to_float(x, y, width || @image.columns, height || @image.rows)
240
- if @width < 0 || @height < 0
241
- raise ArgumentError, "width, height must be >= 0"
284
+
285
+ # Draws a path defined by an SVG path string or a PathData
286
+ # object.
287
+ def path(path)
288
+ path = Path.new(path)
289
+ @content << path
290
+ return path
291
+ end
292
+
293
+ # Draws a rectangle whose upper-left corner is [<tt>x</tt>, <tt>y</tt>] and
294
+ # with the specified +width+ and +height+. Unless otherwise
295
+ # specified the rectangle has square corners. Returns a
296
+ # Rectangle object.
297
+ #
298
+ # Draw a rectangle with rounded corners by calling the #round
299
+ # method on the Rectangle object. <tt>rx</tt> and <tt>ry</tt> are
300
+ # the corner radii in the x- and y-directions. For example:
301
+ # canvas.rect(width, height, x, y).round(8, 6)
302
+ # If <tt>ry</tt> is omitted it defaults to <tt>rx</tt>.
303
+ def rect(width, height, x=0, y=0)
304
+ rect = Rect.new(width, height, x, y)
305
+ @content << rect
306
+ return rect
307
+ end
308
+
309
+ # Draws a polygon. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
310
+ # define the points that make up the polygon. At least two
311
+ # points must be specified. If the last point is not the
312
+ # same as the first, adds an additional point to close
313
+ # the polygon.
314
+ def polygon(*points)
315
+ polygon = Polygon.new(*points)
316
+ @content << polygon
317
+ return polygon
318
+ end
319
+
320
+ # Draws a polyline. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
321
+ # define the points that make up the polyline. At least two
322
+ # points must be specified.
323
+ def polyline(*points)
324
+ polyline = Polyline.new(*points)
325
+ @content << polyline
326
+ return polyline
327
+ end
328
+
329
+ end # module ShapeContent
330
+
331
+ # Methods that reference ("use") other drawable objects within a container
332
+ module UseConstructors
333
+
334
+ # Reference an object to be inserted into the container's
335
+ # content. [<tt>x</tt>,<tt>y</tt>] is the offset from the upper-left
336
+ # corner. If the argument is an RVG or Image object and +width+ and +height+
337
+ # are specified, these values will override the +width+ and +height+
338
+ # attributes on the argument.
339
+ def use(obj, x=0, y=0, width=nil, height=nil)
340
+ use = Use.new(obj, x, y, width, height)
341
+ @content << use
342
+ return use
242
343
  end
243
- init_viewbox()
244
- end
245
-
246
- def add_primitives(gc) #:nodoc:
247
- # Do not render if width or height is 0
248
- return if @width == 0 || @height == 0
249
- gc.push
250
- add_transform_primitives(gc)
251
- add_style_primitives(gc)
252
- add_composite_primitive(gc)
253
- gc.pop
254
- end
255
-
256
- end # class Image
257
-
258
-
259
- # Methods that construct basic shapes within a container
260
- module ShapeConstructors
261
-
262
- # Draws a circle whose center is [<tt>cx</tt>, <tt>cy</tt>] and radius is +r+.
263
- def circle(r, cx=0, cy=0)
264
- circle = Circle.new(r, cx, cy)
265
- @content << circle
266
- return circle
267
- end
268
-
269
- # Draws an ellipse whose center is [<tt>cx</tt>, <tt>cy</tt>] and having
270
- # a horizontal radius +rx+ and vertical radius +ry+.
271
- def ellipse(rx, ry, cx=0, cy=0)
272
- ellipse = Ellipse.new(rx, ry, cx, cy)
273
- @content << ellipse
274
- return ellipse
275
- end
276
-
277
- # Draws a line from [<tt>x1</tt>, <tt>y1</tt>] to [<tt>x2</tt>, <tt>y2</tt>].
278
- def line(x1=0, y1=0, x2=0, y2=0)
279
- line = Line.new(x1, y1, x2, y2)
280
- @content << line
281
- return line
282
- end
283
-
284
- # Draws a path defined by an SVG path string or a PathData
285
- # object.
286
- def path(path)
287
- path = Path.new(path)
288
- @content << path
289
- return path
290
- end
291
-
292
- # Draws a rectangle whose upper-left corner is [<tt>x</tt>, <tt>y</tt>] and
293
- # with the specified +width+ and +height+. Unless otherwise
294
- # specified the rectangle has square corners. Returns a
295
- # Rectangle object.
296
- #
297
- # Draw a rectangle with rounded corners by calling the #round
298
- # method on the Rectangle object. <tt>rx</tt> and <tt>ry</tt> are
299
- # the corner radii in the x- and y-directions. For example:
300
- # canvas.rect(width, height, x, y).round(8, 6)
301
- # If <tt>ry</tt> is omitted it defaults to <tt>rx</tt>.
302
- def rect(width, height, x=0, y=0)
303
- rect = Rect.new(width, height, x, y)
304
- @content << rect
305
- return rect
306
- end
307
-
308
- # Draws a polygon. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
309
- # define the points that make up the polygon. At least two
310
- # points must be specified. If the last point is not the
311
- # same as the first, adds an additional point to close
312
- # the polygon.
313
- def polygon(*points)
314
- polygon = Polygon.new(*points)
315
- @content << polygon
316
- return polygon
317
- end
318
-
319
- # Draws a polyline. The arguments are [<tt>x</tt>, <tt>y</tt>] pairs that
320
- # define the points that make up the polyline. At least two
321
- # points must be specified.
322
- def polyline(*points)
323
- polyline = Polyline.new(*points)
324
- @content << polyline
325
- return polyline
326
- end
327
-
328
- end # module ShapeContent
329
-
330
- # Methods that reference ("use") other drawable objects within a container
331
- module UseConstructors
332
-
333
- # Reference an object to be inserted into the container's
334
- # content. [<tt>x</tt>,<tt>y</tt>] is the offset from the upper-left
335
- # corner. If the argument is an RVG or Image object and +width+ and +height+
336
- # are specified, these values will override the +width+ and +height+
337
- # attributes on the argument.
338
- def use(obj, x=0, y=0, width=nil, height=nil)
339
- use = Use.new(obj, x, y, width, height)
340
- @content << use
341
- return use
342
- end
343
-
344
- end # module UseConstructors
345
-
346
- # Methods that construct container objects within a container
347
- module StructureConstructors
348
-
349
- # Establishes a new viewport. [<tt>x</tt>, <tt>y</tt>] is the coordinate of the
350
- # upper-left corner within the containing viewport. This is a
351
- # _container_ method. Styles and
352
- # transforms specified on this object will be used by objects
353
- # contained within, unless overridden by an inner container or
354
- # the contained object itself.
355
- def rvg(cols, rows, x=0, y=0, &block)
356
- rvg = Magick::RVG.new(cols, rows, &block)
357
- begin
358
- x, y = Float(x), Float(y)
359
- rescue ArgumentError
360
- args = [cols, rows, x, y]
361
- raise ArgumentError, "at least one argument is not convertable to Float (got #{args.collect {|a| a.class}.join(', ')})"
344
+
345
+ end # module UseConstructors
346
+
347
+ # Methods that construct container objects within a container
348
+ module StructureConstructors
349
+
350
+ # Establishes a new viewport. [<tt>x</tt>, <tt>y</tt>] is the coordinate of the
351
+ # upper-left corner within the containing viewport. This is a
352
+ # _container_ method. Styles and
353
+ # transforms specified on this object will be used by objects
354
+ # contained within, unless overridden by an inner container or
355
+ # the contained object itself.
356
+ def rvg(cols, rows, x=0, y=0, &block)
357
+ rvg = Magick::RVG.new(cols, rows, &block)
358
+ begin
359
+ x, y = Float(x), Float(y)
360
+ rescue ArgumentError
361
+ args = [cols, rows, x, y]
362
+ raise ArgumentError, "at least one argument is not convertable to Float (got #{args.collect {|a| a.class}.join(', ')})"
363
+ end
364
+ rvg.corner(x, y)
365
+ @content << rvg
366
+ return rvg
362
367
  end
363
- rvg.corner(x, y)
364
- @content << rvg
365
- return rvg
366
- end
367
-
368
- # Defines a group.
369
- #
370
- # This method constructs a new
371
- # Group _container_ object. The styles and
372
- # transforms specified on this object will be used by objects
373
- # contained within, unless overridden by an inner container or
374
- # the contained object itself.
375
- # Define grouped elements by calling RVG::Embellishable
376
- # methods within the associated block.
377
- def g(&block)
378
- group = Group.new(&block)
379
- @content << group
380
- return group
381
- end
382
-
383
- end # module StructureConstructors
384
-
385
- # Methods that construct raster image objects within a container
386
- module ImageConstructors
387
-
388
- # Composite a raster image at [<tt>x</tt>,<tt>y</tt>]
389
- # in a viewport of the specified <tt>width</tt> and <tt>height</tt>.
390
- # If not specified, the width and height are the width and height
391
- # of the image. Use the RVG::PreserveAspectRatio#preserve_aspect_ratio method to
392
- # control the placement and scaling of the image within the
393
- # viewport. By default, the image is scaled to fit inside the
394
- # viewport and centered within the viewport.
395
- def image(image, width=nil, height=nil, x=0, y=0)
396
- img = Image.new(image, width, height, x, y)
397
- @content << img
398
- return img
399
- end
400
-
401
- end # module ImageConstructors
402
-
403
- # Methods that create shapes, text, and other drawable objects
404
- # within container objects such as ::Magick::RVG and
405
- # ::Magick::RVG::Group
406
- module Embellishable
407
- include StructureConstructors
408
- include ShapeConstructors
409
- include TextConstructors
410
- include UseConstructors
411
- include ImageConstructors
412
- end # module Embellishable
413
-
414
- end # class Magick::RVG
368
+
369
+ # Defines a group.
370
+ #
371
+ # This method constructs a new
372
+ # Group _container_ object. The styles and
373
+ # transforms specified on this object will be used by objects
374
+ # contained within, unless overridden by an inner container or
375
+ # the contained object itself.
376
+ # Define grouped elements by calling RVG::Embellishable
377
+ # methods within the associated block.
378
+ def g(&block)
379
+ group = Group.new(&block)
380
+ @content << group
381
+ return group
382
+ end
383
+
384
+ end # module StructureConstructors
385
+
386
+ # Methods that construct raster image objects within a container
387
+ module ImageConstructors
388
+
389
+ # Composite a raster image at [<tt>x</tt>,<tt>y</tt>]
390
+ # in a viewport of the specified <tt>width</tt> and <tt>height</tt>.
391
+ # If not specified, the width and height are the width and height
392
+ # of the image. Use the RVG::PreserveAspectRatio#preserve_aspect_ratio method to
393
+ # control the placement and scaling of the image within the
394
+ # viewport. By default, the image is scaled to fit inside the
395
+ # viewport and centered within the viewport.
396
+ def image(image, width=nil, height=nil, x=0, y=0)
397
+ img = Image.new(image, width, height, x, y)
398
+ @content << img
399
+ return img
400
+ end
401
+
402
+ end # module ImageConstructors
403
+
404
+ # Methods that create shapes, text, and other drawable objects
405
+ # within container objects such as ::Magick::RVG and
406
+ # ::Magick::RVG::Group
407
+ module Embellishable
408
+ include StructureConstructors
409
+ include ShapeConstructors
410
+ include TextConstructors
411
+ include UseConstructors
412
+ include ImageConstructors
413
+ end # module Embellishable
414
+
415
+ end # class RVG
416
+ end # module Magick
415
417