rmagick4j 0.3.1-java → 0.3.2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
data/lib/magick4j.jar CHANGED
Binary file
@@ -1,5 +1,8 @@
1
1
  require 'java'
2
+ # TODO See about using Raven to get gems of jhlabs and svgsalamander?
3
+ require 'jhlabs-filters.jar'
2
4
  require 'magick4j.jar'
5
+ require 'svgsalamander.jar'
3
6
  require 'observer'
4
7
 
5
8
  module Magick
@@ -0,0 +1,48 @@
1
+ #--
2
+ # $Id: clippath.rb,v 1.3 2007/01/20 17:39:48 rmagick Exp $
3
+ # Copyright (C) 2007 Timothy P. Hunter
4
+ #++
5
+ module Magick
6
+ class RVG
7
+
8
+ class ClipPath
9
+ include ShapeConstructors
10
+ include UseConstructors
11
+ include TextConstructors
12
+ include Describable
13
+ include Stylable
14
+ include Duplicatable
15
+
16
+ # Create a clipping path. Within the block create an outline
17
+ # from one or more paths, basic shapes, text objects, or +use+.
18
+ # Everything drawn within the outline will be displayed.
19
+ # Anything drawn outside the outline will not.
20
+ #
21
+ # If the clipping path contains a +use+, it
22
+ # must directly reference path, basic shape, or text objects.
23
+ #
24
+ # Attach the clipping path to an object with the :clip_path style.
25
+ def initialize(clip_path_units='userSpaceOnUse')
26
+ super()
27
+ if ! ['userSpaceOnUse', 'objectBoundingBox'].include?(clip_path_units)
28
+ raise ArgumentError, "undefined value for clip path units: #{clip_path_units}"
29
+ end
30
+ @clip_path_units = clip_path_units
31
+ @content = Content.new
32
+ yield(self) if block_given?
33
+ end
34
+
35
+ def add_primitives(gc, style) #:nodoc:
36
+ name = __id__.to_s
37
+ gc.define_clip_path(name) do
38
+ gc.clip_units(@clip_path_units)
39
+ @content.each { |element| element.add_primitives(gc) }
40
+ end
41
+ gc.clip_path(name)
42
+ end
43
+
44
+ end # class ClipPath
45
+
46
+ end # class RVG
47
+ end # module Magick
48
+
@@ -0,0 +1,131 @@
1
+ #--
2
+ # $Id: container.rb,v 1.3 2007/01/20 17:39:49 rmagick Exp $
3
+ # Copyright (C) 2007 Timothy P. Hunter
4
+ #++
5
+
6
+ module Magick
7
+ class RVG
8
+
9
+ # Content is simply an Array with a deep_copy method.
10
+ # When unit-testing, it also has a deep_equal method.
11
+ class Content < Array #:nodoc:
12
+
13
+ def deep_copy(h = {})
14
+ me = self.__id__
15
+ copy = h[me]
16
+ unless copy
17
+ copy = self.class.new
18
+ each do |c|
19
+ copy << case
20
+ when c.nil?
21
+ nil
22
+ when c.respond_to?(:deep_copy)
23
+ c.deep_copy(h)
24
+ when c.respond_to?(:dup)
25
+ c.dup rescue c
26
+ else
27
+ c
28
+ end
29
+ end
30
+ copy.freeze if frozen?
31
+ h[me] = copy
32
+ end
33
+ return copy
34
+ end
35
+
36
+ end # class Content
37
+
38
+ # Define a collection of shapes, text, etc. that can be reused.
39
+ # Group objects are _containers_. That is, styles and transforms defined
40
+ # on the group are used by contained objects such as shapes, text, and
41
+ # nested groups unless overridden by a nested container or the object itself.
42
+ # Groups can be reused with the RVG::UseConstructors#use method.
43
+ # Create groups within
44
+ # containers with the RVG::StructureConstructors#g method.
45
+ #
46
+ # Example:
47
+ # # All elements in the group will be translated by 50 in the
48
+ # # x-direction and 10 in the y-direction.
49
+ # rvg.g.translate(50, 10).styles(:stroke=>'red',:fill=>'none') do |grp|
50
+ # # The line will be red.
51
+ # grp.line(10,10, 20,20)
52
+ # # The circle will be blue.
53
+ # grp.circle(10, 20, 20).styles(:stroke=>'blue')
54
+ # end
55
+ class Group
56
+ include Stylable
57
+ include Transformable
58
+ include Embellishable
59
+ include Describable
60
+ include Duplicatable
61
+
62
+ def initialize
63
+ super
64
+ @content = Content.new
65
+ yield(self) if block_given?
66
+ end
67
+
68
+ def add_primitives(gc) #:nodoc:
69
+ gc.push
70
+ add_transform_primitives(gc)
71
+ add_style_primitives(gc)
72
+ @content.each { |element| element.add_primitives(gc) }
73
+ gc.pop
74
+ end
75
+
76
+ # Translate container according to #use arguments
77
+ def ref(x, y, width, height) #:nodoc:
78
+ translate(x, y) if (x != 0 || y != 0)
79
+ end
80
+
81
+ # Append an arbitrary object to the group's content. Called
82
+ # by #use to insert a non-container object into a group.
83
+ def <<(obj) #:nodoc:
84
+ @content << obj
85
+ end
86
+
87
+ end # class Group
88
+
89
+
90
+ # A Use object allows the re-use of RVG and RVG::Group
91
+ # objects within a container. Create a Use object with the
92
+ # RVG::UseConstructors#use method.
93
+ class Use
94
+ include Stylable
95
+ include Transformable
96
+ include Duplicatable
97
+
98
+ # In a container, Use objects are created indirectly via the
99
+ # RVG::UseConstructors#use method.
100
+ # The +x+ and +y+ arguments
101
+ # can be used to specify an additional translation for
102
+ # the group. The +width+ and +height+ arguments specify
103
+ # a width and height for referenced RVG objects.
104
+ def initialize(element, x=0, y=0, width=nil, height=nil)
105
+ super()
106
+
107
+ # If the element is not a group, defs, symbol, or rvg,
108
+ # wrap a group around it so it can get a transform and
109
+ # possibly a new viewport.
110
+ if ! element.respond_to?(:ref)
111
+ @element = Group.new
112
+ @element << element.deep_copy
113
+ else
114
+ @element = element.deep_copy
115
+ end
116
+ @element.ref(x, y, width, height)
117
+ end
118
+
119
+ def add_primitives(gc) #:nodoc:
120
+ gc.push
121
+ add_transform_primitives(gc)
122
+ add_style_primitives(gc)
123
+ @element.add_primitives(gc)
124
+ gc.pop
125
+ end
126
+
127
+ end # class Use
128
+
129
+ end # class RVG
130
+ end # module Magick
131
+
@@ -0,0 +1,56 @@
1
+ module Magick
2
+ class RVG
3
+
4
+ [PathData, Styles, Transforms].each do |c|
5
+ c.class_eval do
6
+ def deep_equal(other)
7
+ if self != other
8
+ puts "#{c.inspect} not equal.\nself:#{self} != other:#{other}"
9
+ return false
10
+ end
11
+ return true
12
+ end
13
+ end
14
+ end
15
+
16
+ [Shape, TextBase, Image, Group, Content, Use, ClipPath, Pattern, self].each do |c|
17
+ c.class_eval do
18
+ def deep_equal(other)
19
+ ivs = self.instance_variables
20
+
21
+ ivs.each do |iv|
22
+ itv = self.instance_variable_get(iv)
23
+ otv = other.instance_variable_get(iv)
24
+ if itv.respond_to?(:deep_equal)
25
+ if itv.equal?(otv)
26
+ puts "#{iv} has deep_equal but self.#{iv} and other.#{iv} are the same object."
27
+ return false
28
+ end
29
+ if !itv.deep_equal(otv)
30
+ puts "Not equal.\nself.#{iv}=#{itv.inspect}\nother.#{iv}=#{otv.inspect}"
31
+ return false
32
+ end
33
+ else
34
+ case itv
35
+ when Float, Symbol, TrueClass, FalseClass, Fixnum, NilClass
36
+ return false if itv != otv
37
+ else
38
+ if itv.equal?(otv)
39
+ puts "#{iv} is dup-able but self.#{iv} and other.#{iv} are the same object."
40
+ return false
41
+ end
42
+ if itv != otv
43
+ puts "Not equal.\nself.#{iv}=#{itv.inspect}\nother.#{iv}=#{otv.inspect}"
44
+ return false
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ return true
51
+ end
52
+ end
53
+ end
54
+
55
+ end # class RVG
56
+ end # module Magick
@@ -0,0 +1,53 @@
1
+ #--
2
+ # $Id: describable.rb,v 1.3 2007/01/20 17:39:49 rmagick Exp $
3
+ # Copyright (C) 2007 Timothy P. Hunter
4
+ #++
5
+
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
53
+
@@ -0,0 +1,417 @@
1
+ #--
2
+ # $Id: embellishable.rb,v 1.7 2007/01/20 17:39:49 rmagick Exp $
3
+ # Copyright (C) 2007 Timothy P. Hunter
4
+ #++
5
+
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
22
+ end
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]
57
+ end
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]
69
+ end
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]
82
+ end
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)
138
+ end
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]
201
+ end
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)
224
+ end
225
+
226
+ def init_viewbox()
227
+ @align = nil
228
+ @vbx_width, @vbx_height = @image.columns, @image.rows
229
+ @meet_or_slice = 'meet'
230
+ end
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"
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
277
+
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
283
+ end
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
343
+ end
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
367
+ end
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
417
+