rmagick 2.16.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rmagick might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.appveyor.yml +19 -0
- data/.circleci/config.yml +56 -0
- data/.rubocop.yml +8 -335
- data/.rubocop_todo.yml +255 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -49
- data/CHANGELOG.md +23 -0
- data/CONTRIBUTING.md +34 -0
- data/Gemfile +0 -6
- data/README.textile +11 -3
- data/Rakefile +23 -15
- data/before_install_linux.sh +12 -15
- data/doc/ex/InitialCoords.rb +4 -4
- data/doc/ex/NewCoordSys.rb +4 -4
- data/doc/ex/OrigCoordSys.rb +2 -2
- data/doc/ex/PreserveAspectRatio.rb +34 -34
- data/doc/ex/RotateScale.rb +7 -7
- data/doc/ex/Skew.rb +7 -7
- data/doc/ex/Use01.rb +1 -1
- data/doc/ex/Use02.rb +4 -4
- data/doc/ex/Use03.rb +2 -2
- data/doc/ex/ViewBox.rb +4 -4
- data/doc/ex/affine.rb +5 -5
- data/doc/ex/affine_transform.rb +3 -3
- data/doc/ex/arc.rb +9 -9
- data/doc/ex/arcpath.rb +2 -2
- data/doc/ex/arcs01.rb +6 -6
- data/doc/ex/arcs02.rb +8 -8
- data/doc/ex/axes.rb +11 -11
- data/doc/ex/baseline_shift01.rb +5 -5
- data/doc/ex/bilevel_channel.rb +1 -1
- data/doc/ex/blur_image.rb +1 -1
- data/doc/ex/border.rb +1 -1
- data/doc/ex/bounding_box.rb +11 -11
- data/doc/ex/cbezier1.rb +12 -12
- data/doc/ex/cbezier2.rb +13 -13
- data/doc/ex/cbezier3.rb +13 -13
- data/doc/ex/cbezier4.rb +13 -13
- data/doc/ex/cbezier5.rb +13 -13
- data/doc/ex/cbezier6.rb +19 -19
- data/doc/ex/channel.rb +2 -2
- data/doc/ex/chop.rb +2 -2
- data/doc/ex/circle.rb +7 -7
- data/doc/ex/circle01.rb +2 -2
- data/doc/ex/clip_path.rb +6 -6
- data/doc/ex/coalesce.rb +6 -6
- data/doc/ex/color_fill_to_border.rb +8 -8
- data/doc/ex/color_floodfill.rb +8 -8
- data/doc/ex/color_histogram.rb +2 -2
- data/doc/ex/color_reset.rb +2 -2
- data/doc/ex/colors.rb +4 -4
- data/doc/ex/compose_mask.rb +2 -2
- data/doc/ex/composite.rb +39 -39
- data/doc/ex/composite_layers.rb +1 -2
- data/doc/ex/contrast.rb +3 -3
- data/doc/ex/crop.rb +2 -2
- data/doc/ex/crop_with_gravity.rb +5 -5
- data/doc/ex/cubic01.rb +12 -12
- data/doc/ex/cubic02.rb +22 -22
- data/doc/ex/cycle_colormap.rb +3 -3
- data/doc/ex/dissolve.rb +0 -0
- data/doc/ex/drawcomp.rb +8 -9
- data/doc/ex/drop_shadow.rb +4 -4
- data/doc/ex/ellipse.rb +9 -9
- data/doc/ex/ellipse01.rb +3 -3
- data/doc/ex/enhance.rb +2 -2
- data/doc/ex/evenodd.rb +19 -19
- data/doc/ex/fill_pattern.rb +3 -3
- data/doc/ex/flatten_images.rb +1 -1
- data/doc/ex/font_styles.rb +13 -13
- data/doc/ex/fonts.rb +2 -6
- data/doc/ex/frame.rb +1 -1
- data/doc/ex/get_multiline_type_metrics.rb +3 -3
- data/doc/ex/get_pixels.rb +4 -6
- data/doc/ex/get_type_metrics.rb +26 -25
- data/doc/ex/gradientfill.rb +2 -2
- data/doc/ex/grav.rb +12 -12
- data/doc/ex/gravity.rb +14 -16
- data/doc/ex/group.rb +11 -11
- data/doc/ex/hatchfill.rb +2 -2
- data/doc/ex/image.rb +9 -9
- data/doc/ex/implode.rb +2 -2
- data/doc/ex/line.rb +10 -10
- data/doc/ex/line01.rb +7 -7
- data/doc/ex/mask.rb +0 -0
- data/doc/ex/matte_fill_to_border.rb +3 -3
- data/doc/ex/matte_floodfill.rb +2 -2
- data/doc/ex/matte_replace.rb +3 -3
- data/doc/ex/median_filter.rb +2 -2
- data/doc/ex/mono.rb +2 -2
- data/doc/ex/morph.rb +1 -1
- data/doc/ex/mosaic.rb +7 -5
- data/doc/ex/motion_blur.rb +1 -1
- data/doc/ex/negate_channel.rb +0 -0
- data/doc/ex/nested_rvg.rb +2 -2
- data/doc/ex/nonzero.rb +19 -19
- data/doc/ex/opacity.rb +9 -9
- data/doc/ex/path.rb +17 -17
- data/doc/ex/pattern1.rb +4 -4
- data/doc/ex/pattern2.rb +2 -2
- data/doc/ex/polaroid.rb +0 -1
- data/doc/ex/polygon.rb +7 -7
- data/doc/ex/polygon01.rb +7 -7
- data/doc/ex/polyline.rb +7 -7
- data/doc/ex/polyline01.rb +8 -8
- data/doc/ex/posterize.rb +0 -0
- data/doc/ex/qbezierpath.rb +16 -16
- data/doc/ex/quad01.rb +6 -6
- data/doc/ex/quantize-m.rb +2 -2
- data/doc/ex/random_threshold_channel.rb +1 -1
- data/doc/ex/rect01.rb +2 -2
- data/doc/ex/rect02.rb +3 -3
- data/doc/ex/rectangle.rb +6 -6
- data/doc/ex/reduce_noise.rb +2 -2
- data/doc/ex/remap.rb +0 -0
- data/doc/ex/resize_to_fill.rb +0 -0
- data/doc/ex/resize_to_fit.rb +0 -0
- data/doc/ex/roll.rb +1 -1
- data/doc/ex/rotate.rb +8 -8
- data/doc/ex/rotate_f.rb +1 -1
- data/doc/ex/roundrect.rb +6 -6
- data/doc/ex/rubyname.rb +4 -4
- data/doc/ex/rvg_clippath.rb +3 -3
- data/doc/ex/rvg_linecap.rb +7 -7
- data/doc/ex/rvg_linejoin.rb +7 -7
- data/doc/ex/rvg_opacity.rb +5 -5
- data/doc/ex/rvg_pattern.rb +8 -8
- data/doc/ex/rvg_stroke_dasharray.rb +2 -2
- data/doc/ex/sepiatone.rb +0 -0
- data/doc/ex/shadow.rb +6 -6
- data/doc/ex/shear.rb +2 -2
- data/doc/ex/skewx.rb +8 -8
- data/doc/ex/skewy.rb +9 -9
- data/doc/ex/smile.rb +5 -4
- data/doc/ex/sparse_color.rb +0 -4
- data/doc/ex/splice.rb +1 -1
- data/doc/ex/stegano.rb +4 -5
- data/doc/ex/stroke_dasharray.rb +10 -10
- data/doc/ex/stroke_fill.rb +2 -2
- data/doc/ex/stroke_linecap.rb +12 -12
- data/doc/ex/stroke_linejoin.rb +12 -12
- data/doc/ex/stroke_width.rb +11 -11
- data/doc/ex/swirl.rb +2 -2
- data/doc/ex/text.rb +6 -6
- data/doc/ex/text01.rb +4 -4
- data/doc/ex/text_align.rb +5 -5
- data/doc/ex/text_antialias.rb +2 -2
- data/doc/ex/text_styles.rb +8 -8
- data/doc/ex/text_undercolor.rb +4 -4
- data/doc/ex/texture_fill_to_border.rb +8 -8
- data/doc/ex/texture_floodfill.rb +8 -8
- data/doc/ex/texturefill.rb +2 -2
- data/doc/ex/threshold.rb +2 -2
- data/doc/ex/to_blob.rb +1 -1
- data/doc/ex/translate.rb +8 -8
- data/doc/ex/transparent.rb +6 -6
- data/doc/ex/transpose.rb +0 -0
- data/doc/ex/transverse.rb +0 -0
- data/doc/ex/tref01.rb +6 -6
- data/doc/ex/triangle01.rb +2 -2
- data/doc/ex/trim.rb +2 -2
- data/doc/ex/tspan01.rb +5 -5
- data/doc/ex/tspan02.rb +5 -5
- data/doc/ex/tspan03.rb +5 -5
- data/doc/ex/unsharp_mask.rb +3 -3
- data/doc/ex/viewex.rb +5 -5
- data/doc/ex/vignette.rb +0 -0
- data/doc/ex/watermark.rb +6 -6
- data/doc/ex/wet_floor.rb +2 -2
- data/doc/ex/writing_mode01.rb +12 -12
- data/doc/ex/writing_mode02.rb +12 -12
- data/examples/constitute.rb +1 -1
- data/examples/crop_with_gravity.rb +5 -5
- data/examples/demo.rb +6 -7
- data/examples/describe.rb +8 -10
- data/examples/find_similar_region.rb +3 -3
- data/examples/histogram.rb +192 -201
- data/examples/identify.rb +62 -73
- data/examples/image_opacity.rb +0 -1
- data/examples/import_export.rb +1 -1
- data/examples/pattern_fill.rb +3 -4
- data/examples/rotating_text.rb +5 -4
- data/examples/spinner.rb +5 -5
- data/examples/thumbnail.rb +3 -3
- data/examples/vignette.rb +5 -5
- data/ext/RMagick/extconf.rb +213 -230
- data/ext/RMagick/rmagick.c +1 -0
- data/ext/RMagick/rmagick.h +26 -29
- data/ext/RMagick/rmdraw.c +3 -38
- data/ext/RMagick/rmenum.c +36 -0
- data/ext/RMagick/rmimage.c +166 -10
- data/ext/RMagick/rminfo.c +7 -2
- data/ext/RMagick/rmkinfo.c +247 -0
- data/ext/RMagick/rmmain.c +96 -0
- data/ext/RMagick/rmutil.c +4 -0
- data/lib/rmagick/version.rb +3 -3
- data/lib/rmagick_internal.rb +226 -308
- data/lib/rvg/clippath.rb +2 -4
- data/lib/rvg/container.rb +25 -22
- data/lib/rvg/deep_equal.rb +11 -11
- data/lib/rvg/describable.rb +2 -2
- data/lib/rvg/embellishable.rb +60 -66
- data/lib/rvg/misc.rb +122 -128
- data/lib/rvg/pathdata.rb +15 -17
- data/lib/rvg/rvg.rb +41 -44
- data/lib/rvg/stretchable.rb +22 -28
- data/lib/rvg/stylable.rb +10 -10
- data/lib/rvg/text.rb +164 -165
- data/lib/rvg/transformable.rb +15 -15
- data/lib/rvg/units.rb +2 -2
- data/rmagick.gemspec +9 -33
- data/spec/rmagick/draw_spec.rb +5 -6
- data/spec/rmagick/image/blue_shift_spec.rb +1 -3
- data/spec/rmagick/image/channel_entropy_spec.rb +9 -0
- data/spec/rmagick/image/composite_spec.rb +2 -4
- data/spec/rmagick/image/constitute_spec.rb +2 -4
- data/spec/rmagick/image/dispatch_spec.rb +1 -3
- data/spec/rmagick/image/from_blob_spec.rb +1 -3
- data/spec/rmagick/image/ping_spec.rb +1 -3
- data/spec/rmagick/image/properties_spec.rb +0 -2
- data/spec/rmagick/image/read_spec.rb +28 -0
- data/spec/spec_helper.rb +7 -1
- data/spec/support/issue_200/app.rb +8 -0
- data/test/Image1.rb +70 -70
- data/test/Image2.rb +369 -361
- data/test/Image3.rb +64 -63
- data/test/ImageList1.rb +796 -792
- data/test/ImageList2.rb +43 -44
- data/test/Image_attributes.rb +26 -48
- data/test/Import_Export.rb +71 -77
- data/test/Info.rb +30 -31
- data/test/Magick.rb +47 -46
- data/test/Pixel.rb +24 -24
- data/test/Preview.rb +7 -6
- data/test/test_all_basic.rb +15 -7
- data/test/tmpnam_test.rb +3 -3
- metadata +57 -18
data/lib/rvg/pathdata.rb
CHANGED
@@ -12,12 +12,10 @@ module Magick
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def add_points(req, *coords)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
coords.each {|c| @path << ('%g' % c)}
|
20
|
-
end
|
15
|
+
return unless coords
|
16
|
+
raise ArgumentError, "wrong number of coordinates specified. A multiple of #{req} required, #{req + coords.length} given." if coords.length % req != 0
|
17
|
+
|
18
|
+
coords.each { |c| @path << format('%g', c) }
|
21
19
|
end
|
22
20
|
|
23
21
|
public
|
@@ -32,7 +30,7 @@ module Magick
|
|
32
30
|
@path
|
33
31
|
end
|
34
32
|
|
35
|
-
def deep_copy(
|
33
|
+
def deep_copy(_h = nil) #:nodoc:
|
36
34
|
@path.dup
|
37
35
|
end
|
38
36
|
|
@@ -40,14 +38,14 @@ module Magick
|
|
40
38
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
41
39
|
# the coordinates are relative.
|
42
40
|
def moveto(abs, x, y, *coords)
|
43
|
-
@path <<
|
41
|
+
@path << format('%s%g,%g ', (abs ? 'M' : 'm'), x, y)
|
44
42
|
# "subsequent pairs are treated as implicit lineto commands"
|
45
43
|
add_points(2, *coords)
|
46
44
|
end
|
47
45
|
|
48
46
|
# Add a <tt>closepath</tt> command. The <tt>abs</tt> argument
|
49
47
|
# is ignored.
|
50
|
-
def closepath(
|
48
|
+
def closepath(_abs = true)
|
51
49
|
@path << 'Z' # ignore `abs'
|
52
50
|
end
|
53
51
|
|
@@ -56,7 +54,7 @@ module Magick
|
|
56
54
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
57
55
|
# the coordinates are relative.
|
58
56
|
def lineto(abs, x, y, *coords)
|
59
|
-
@path <<
|
57
|
+
@path << format('%s%g,%g ', (abs ? 'L' : 'l'), x, y)
|
60
58
|
# "a number of coordinate pairs may be specified to draw a polyline"
|
61
59
|
add_points(2, *coords)
|
62
60
|
end
|
@@ -65,14 +63,14 @@ module Magick
|
|
65
63
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
66
64
|
# the coordinates are relative.
|
67
65
|
def hlineto(abs, x)
|
68
|
-
@path <<
|
66
|
+
@path << format('%s%g ', (abs ? 'H' : 'h'), x)
|
69
67
|
end
|
70
68
|
|
71
69
|
# Add a <tt>vertical lineto</tt> command. If <tt>abs</tt> is
|
72
70
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
73
71
|
# the coordinates are relative.
|
74
72
|
def vlineto(abs, y)
|
75
|
-
@path <<
|
73
|
+
@path << format('%s%g ', (abs ? 'V' : 'v'), y)
|
76
74
|
end
|
77
75
|
|
78
76
|
# Add a <tt>curveto</tt> (<em>cubic Bezier</em>) command.
|
@@ -80,7 +78,7 @@ module Magick
|
|
80
78
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
81
79
|
# the coordinates are relative.
|
82
80
|
def curveto(abs, x1, y1, x2, y2, x, y, *coords)
|
83
|
-
@path <<
|
81
|
+
@path << format('%s%g,%g %g,%g %g,%g ', (abs ? 'C' : 'c'), x1, y1, x2, y2, x, y)
|
84
82
|
# "multiple sets of coordinates may be specified to draw a polybezier"
|
85
83
|
add_points(6, *coords)
|
86
84
|
end
|
@@ -90,7 +88,7 @@ module Magick
|
|
90
88
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
91
89
|
# the coordinates are relative.
|
92
90
|
def smooth_curveto(abs, x2, y2, x, y, *coords)
|
93
|
-
@path <<
|
91
|
+
@path << format('%s%g,%g %g,%g ', (abs ? 'S' : 's'), x2, y2, x, y)
|
94
92
|
# "multiple sets of coordinates may be specified to draw a polybezier"
|
95
93
|
add_points(4, *coords)
|
96
94
|
end
|
@@ -100,7 +98,7 @@ module Magick
|
|
100
98
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
101
99
|
# the coordinates are relative.
|
102
100
|
def quadratic_curveto(abs, x1, y1, x, y, *coords)
|
103
|
-
@path <<
|
101
|
+
@path << format('%s%g,%g %g,%g ', (abs ? 'Q' : 'q'), x1, y1, x, y)
|
104
102
|
add_points(4, *coords)
|
105
103
|
end
|
106
104
|
|
@@ -109,7 +107,7 @@ module Magick
|
|
109
107
|
# <tt>true</tt> the coordinates are absolute, otherwise
|
110
108
|
# the coordinates are relative.
|
111
109
|
def smooth_quadratic_curveto(abs, x, y, *coords)
|
112
|
-
@path <<
|
110
|
+
@path << format('%s%g,%g ', (abs ? 'T' : 't'), x, y)
|
113
111
|
add_points(2, *coords)
|
114
112
|
end
|
115
113
|
|
@@ -119,7 +117,7 @@ module Magick
|
|
119
117
|
# the coordinates are relative.
|
120
118
|
|
121
119
|
def arc(abs, rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
|
122
|
-
@path <<
|
120
|
+
@path << format('%s%g,%g %g %d %d %g,%g ', (abs ? 'A' : 'a'), rx, ry, x_axis_rotation, large_arc_flag, sweep_flag, x, y)
|
123
121
|
end
|
124
122
|
end # class PathData
|
125
123
|
end # class RVG
|
data/lib/rvg/rvg.rb
CHANGED
@@ -60,7 +60,7 @@ module Magick
|
|
60
60
|
# else, combine it with the background_fill_opacity.
|
61
61
|
def bgfill
|
62
62
|
if @background_fill.nil?
|
63
|
-
color = Magick::Pixel.new(0,0,0,Magick::TransparentOpacity)
|
63
|
+
color = Magick::Pixel.new(0, 0, 0, Magick::TransparentOpacity)
|
64
64
|
else
|
65
65
|
color = @background_fill
|
66
66
|
color.opacity = (1.0 - @background_fill_opacity) * Magick::TransparentOpacity
|
@@ -72,28 +72,28 @@ module Magick
|
|
72
72
|
if @background_pattern
|
73
73
|
canvas = Magick::Image.new(@width, @height, @background_pattern)
|
74
74
|
elsif @background_image
|
75
|
-
if @width != @background_image.columns || @height != @background_image.rows
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
75
|
+
canvas = if @width != @background_image.columns || @height != @background_image.rows
|
76
|
+
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)
|
90
|
+
end
|
91
|
+
bg_image
|
92
|
+
end
|
93
|
+
end
|
94
|
+
else
|
95
|
+
@background_image.copy
|
96
|
+
end
|
97
97
|
else
|
98
98
|
bgcolor = bgfill
|
99
99
|
canvas = Magick::Image.new(Integer(@width), Integer(@height)) { self.background_color = bgcolor }
|
@@ -110,7 +110,7 @@ module Magick
|
|
110
110
|
indent = 0
|
111
111
|
primitives.each do |cmd|
|
112
112
|
indent -= 1 if cmd['pop ']
|
113
|
-
print((' '*indent), cmd, "\n")
|
113
|
+
print((' ' * indent), cmd, "\n")
|
114
114
|
indent += 1 if cmd['push ']
|
115
115
|
end
|
116
116
|
end
|
@@ -118,7 +118,7 @@ module Magick
|
|
118
118
|
|
119
119
|
public
|
120
120
|
|
121
|
-
WORD_SEP = / /
|
121
|
+
WORD_SEP = / / # Regexp to separate words
|
122
122
|
|
123
123
|
# The background image specified by background_image=
|
124
124
|
attr_reader :background_image
|
@@ -139,9 +139,8 @@ module Magick
|
|
139
139
|
# Sets an image to use as the canvas background. See background_position= for layout options.
|
140
140
|
def background_image=(bg_image)
|
141
141
|
warn 'background_image= has no effect in nested RVG objects' if @nested
|
142
|
-
if bg_image && !bg_image.is_a?(Magick::Image)
|
143
|
-
|
144
|
-
end
|
142
|
+
raise ArgumentError, "background image must be an Image (got #{bg_image.class})" if bg_image && !bg_image.is_a?(Magick::Image)
|
143
|
+
|
145
144
|
@background_image = bg_image
|
146
145
|
end
|
147
146
|
|
@@ -162,9 +161,8 @@ module Magick
|
|
162
161
|
def background_position=(pos)
|
163
162
|
warn 'background_position= has no effect in nested RVG objects' if @nested
|
164
163
|
bg_pos = pos.to_s.downcase
|
165
|
-
|
166
|
-
|
167
|
-
end
|
164
|
+
raise ArgumentError, "background position must be `scaled', `tiled', or `fit' (#{pos} given)" unless %w[scaled tiled fit].include?(bg_pos)
|
165
|
+
|
168
166
|
@background_position = bg_pos.to_sym
|
169
167
|
end
|
170
168
|
|
@@ -179,7 +177,7 @@ module Magick
|
|
179
177
|
raise ArgumentError, "unknown color `#{color}'"
|
180
178
|
rescue TypeError
|
181
179
|
raise TypeError, "cannot convert #{color.class} into Pixel"
|
182
|
-
rescue
|
180
|
+
rescue StandardError
|
183
181
|
raise ArgumentError, "argument must be a color name or a Pixel (got #{color.class})"
|
184
182
|
end
|
185
183
|
else
|
@@ -219,7 +217,7 @@ module Magick
|
|
219
217
|
@content = Content.new
|
220
218
|
@canvas = nil
|
221
219
|
@background_fill = nil
|
222
|
-
@background_fill_opacity = 1.0
|
220
|
+
@background_fill_opacity = 1.0 # applies only if background_fill= is used
|
223
221
|
@background_position = :scaled
|
224
222
|
@background_pattern, @background_image, @desc, @title, @metadata = nil
|
225
223
|
@x = 0.0
|
@@ -231,8 +229,9 @@ module Magick
|
|
231
229
|
# Construct a canvas or reuse an existing canvas.
|
232
230
|
# Execute drawing commands. Return the canvas.
|
233
231
|
def draw
|
234
|
-
|
235
|
-
|
232
|
+
raise StandardError, 'draw not permitted in nested RVG objects' if @nested
|
233
|
+
|
234
|
+
@canvas ||= new_canvas # allow drawing over existing canvas
|
236
235
|
gc = Utility::GraphicContext.new
|
237
236
|
add_outermost_primitives(gc)
|
238
237
|
pp(self) if ENV['debug_rvg']
|
@@ -243,14 +242,14 @@ module Magick
|
|
243
242
|
|
244
243
|
# Accept #use arguments. Use (x,y) to generate an additional translate.
|
245
244
|
# Override @width and @height if new values are supplied.
|
246
|
-
def ref(x, y, rw, rh)
|
245
|
+
def ref(x, y, rw, rh) #:nodoc:
|
247
246
|
translate(x, y) if x != 0 || y != 0
|
248
247
|
@width = rw if rw
|
249
248
|
@height = rh if rh
|
250
249
|
end
|
251
250
|
|
252
251
|
# Used by Magick::Embellishable.rvg to set non-0 x- and y-coordinates
|
253
|
-
def corner(x, y)
|
252
|
+
def corner(x, y) #:nodoc:
|
254
253
|
@nested = true
|
255
254
|
@x = Float(x)
|
256
255
|
@y = Float(y)
|
@@ -258,7 +257,7 @@ module Magick
|
|
258
257
|
end
|
259
258
|
|
260
259
|
# Primitives for the outermost RVG object
|
261
|
-
def add_outermost_primitives(gc)
|
260
|
+
def add_outermost_primitives(gc) #:nodoc:
|
262
261
|
add_transform_primitives(gc)
|
263
262
|
gc.push
|
264
263
|
add_viewbox_primitives(@width, @height, gc)
|
@@ -269,12 +268,10 @@ module Magick
|
|
269
268
|
end
|
270
269
|
|
271
270
|
# Primitives for nested RVG objects
|
272
|
-
def add_primitives(gc)
|
273
|
-
if @width.nil? || @height.nil?
|
274
|
-
|
275
|
-
|
276
|
-
return self
|
277
|
-
end
|
271
|
+
def add_primitives(gc) #:nodoc:
|
272
|
+
raise ArgumentError, 'RVG width or height undefined' if @width.nil? || @height.nil?
|
273
|
+
return self if @width.zero? || @height.zero?
|
274
|
+
|
278
275
|
gc.push
|
279
276
|
add_outermost_primitives(gc)
|
280
277
|
gc.pop
|
data/lib/rvg/stretchable.rb
CHANGED
@@ -12,25 +12,23 @@ module Magick
|
|
12
12
|
# [+align+] a combination of 'xMin', 'xMid', or 'xMax', followed by
|
13
13
|
# 'YMin', 'YMid', or 'YMax'
|
14
14
|
# [+meet_or_slice+] one of 'meet' or 'slice'
|
15
|
-
def preserve_aspect_ratio(align, meet_or_slice='meet')
|
15
|
+
def preserve_aspect_ratio(align, meet_or_slice = 'meet')
|
16
16
|
@align = align.to_s
|
17
17
|
if @align != 'none'
|
18
18
|
m = /\A(xMin|xMid|xMax)(YMin|YMid|YMax)\z/.match(@align)
|
19
|
-
|
19
|
+
raise(ArgumentError, "unknown alignment specifier: #{@align}") unless m
|
20
20
|
end
|
21
21
|
|
22
22
|
if meet_or_slice
|
23
23
|
meet_or_slice = meet_or_slice.to_s.downcase
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
fail(ArgumentError, "specifier must be `meet' or `slice' (got #{meet_or_slice})")
|
28
|
-
end
|
24
|
+
raise(ArgumentError, "specifier must be `meet' or `slice' (got #{meet_or_slice})") unless %w[meet slice].include?(meet_or_slice)
|
25
|
+
|
26
|
+
@meet_or_slice = meet_or_slice
|
29
27
|
end
|
30
28
|
yield(self) if block_given?
|
31
29
|
self
|
32
30
|
end
|
33
|
-
end
|
31
|
+
end # module PreserveAspectRatio
|
34
32
|
|
35
33
|
# The methods in this module describe the user-coordinate space.
|
36
34
|
# RVG and Pattern objects are stretchable.
|
@@ -42,12 +40,8 @@ module Magick
|
|
42
40
|
sx = 1.0
|
43
41
|
sy = 1.0
|
44
42
|
|
45
|
-
if @vbx_width
|
46
|
-
|
47
|
-
end
|
48
|
-
if @vbx_height
|
49
|
-
sy = height / @vbx_height
|
50
|
-
end
|
43
|
+
sx = width / @vbx_width if @vbx_width
|
44
|
+
sy = height / @vbx_height if @vbx_height
|
51
45
|
|
52
46
|
[sx, sy]
|
53
47
|
end
|
@@ -58,19 +52,19 @@ module Magick
|
|
58
52
|
when /\AxMin/
|
59
53
|
0
|
60
54
|
when NilClass, /\AxMid/
|
61
|
-
(width - @vbx_width*sx) / 2.0
|
55
|
+
(width - @vbx_width * sx) / 2.0
|
62
56
|
when /\AxMax/
|
63
|
-
width - @vbx_width*sx
|
64
|
-
|
57
|
+
width - @vbx_width * sx
|
58
|
+
end
|
65
59
|
|
66
60
|
ty = case @align
|
67
61
|
when /YMin\z/
|
68
62
|
0
|
69
63
|
when NilClass, /YMid\z/
|
70
|
-
(height - @vbx_height*sy) / 2.0
|
64
|
+
(height - @vbx_height * sy) / 2.0
|
71
65
|
when /YMax\z/
|
72
|
-
height - @vbx_height*sy
|
73
|
-
|
66
|
+
height - @vbx_height * sy
|
67
|
+
end
|
74
68
|
[tx, ty]
|
75
69
|
end
|
76
70
|
|
@@ -120,7 +114,7 @@ module Magick
|
|
120
114
|
gc.translate(-@vbx_x, -@vbx_y) if @vbx_x.abs != 0.0 || @vbx_y.abs != 0
|
121
115
|
end
|
122
116
|
|
123
|
-
def initialize(*
|
117
|
+
def initialize(*_args)
|
124
118
|
super()
|
125
119
|
@vbx_x, @vbx_y, @vbx_width, @vbx_height = nil
|
126
120
|
@meet_or_slice = 'meet'
|
@@ -143,17 +137,17 @@ module Magick
|
|
143
137
|
rescue ArgumentError
|
144
138
|
raise ArgumentError, "arguments must be convertable to float (got #{x.class}, #{y.class}, #{width.class}, #{height.class})"
|
145
139
|
end
|
146
|
-
|
147
|
-
|
140
|
+
raise(ArgumentError, "viewbox width must be > 0 (#{width} given)") unless width >= 0
|
141
|
+
raise(ArgumentError, "viewbox height must be > 0 (#{height} given)") unless height >= 0
|
148
142
|
|
149
143
|
# return the user-coordinate space attributes if defined
|
150
144
|
class << self
|
151
145
|
unless defined? @redefined
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
146
|
+
@redefined = true
|
147
|
+
define_method(:x) { @vbx_x }
|
148
|
+
define_method(:y) { @vbx_y }
|
149
|
+
define_method(:width) { @vbx_width }
|
150
|
+
define_method(:height) { @vbx_height }
|
157
151
|
end
|
158
152
|
end
|
159
153
|
|
data/lib/rvg/stylable.rb
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
module Magick
|
6
6
|
class RVG
|
7
7
|
#:stopdoc:
|
8
|
-
STYLES = [
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
STYLES = %i[clip_path clip_rule fill fill_opacity fill_rule font
|
9
|
+
font_family font_size font_stretch font_style font_weight
|
10
|
+
opacity stroke stroke_dasharray stroke_dashoffset stroke_linecap
|
11
|
+
stroke_linejoin stroke_miterlimit stroke_opacity stroke_width
|
12
|
+
text_anchor text_decoration
|
13
|
+
glyph_orientation_vertical glyph_orientation_horizontal
|
14
|
+
letter_spacing word_spacing baseline_shift writing_mode]
|
15
15
|
|
16
16
|
Styles = Struct.new(*STYLES)
|
17
17
|
|
@@ -40,12 +40,12 @@ module Magick
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# The "usual" deep_copy method doesn't copy a Struct correctly.
|
43
|
-
def deep_copy(
|
43
|
+
def deep_copy(_h = nil)
|
44
44
|
copy = Styles.new
|
45
45
|
each_pair { |style, value| copy[style] = value }
|
46
46
|
copy
|
47
47
|
end
|
48
|
-
end
|
48
|
+
end # class Styles
|
49
49
|
|
50
50
|
#:startdoc:
|
51
51
|
|
@@ -111,6 +111,6 @@ module Magick
|
|
111
111
|
yield(self) if block_given?
|
112
112
|
self
|
113
113
|
end
|
114
|
-
end
|
114
|
+
end # module Stylable
|
115
115
|
end # class RVG
|
116
116
|
end # module Magick
|
data/lib/rvg/text.rb
CHANGED
@@ -4,169 +4,168 @@
|
|
4
4
|
#++
|
5
5
|
# Text-related classes
|
6
6
|
module Magick
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
end # class RVG
|
7
|
+
class RVG
|
8
|
+
# Base class for Tspan, Tref and Text.
|
9
|
+
class TextBase
|
10
|
+
include Stylable
|
11
|
+
include Duplicatable
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def initialize(text) #:nodoc:
|
16
|
+
super()
|
17
|
+
@text = text.to_s if text
|
18
|
+
@dx = @dy = 0
|
19
|
+
@rotation = 0
|
20
|
+
@tspans = Content.new
|
21
|
+
yield(self) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
public
|
25
|
+
|
26
|
+
# Create a new text chunk. Each chunk can have its own initial position and styles.
|
27
|
+
# If <tt>x</tt> and <tt>y</tt> are omitted the text starts at the current text
|
28
|
+
# position.
|
29
|
+
def tspan(text, x = nil, y = nil)
|
30
|
+
tspan = Tspan.new(text, x, y)
|
31
|
+
tspan.parent = self
|
32
|
+
@tspans << tspan
|
33
|
+
tspan
|
34
|
+
end
|
35
|
+
|
36
|
+
# Add <tt>x</tt> and <tt>y</tt> to the current text position.
|
37
|
+
def d(x, y = 0)
|
38
|
+
@dx, @dy = Magick::RVG.convert_to_float(x, y)
|
39
|
+
yield(self) if block_given?
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
# Rotate the text about the current text position.
|
44
|
+
def rotate(degrees)
|
45
|
+
@rotation = Magick::RVG.convert_to_float(degrees)[0]
|
46
|
+
yield(self) if block_given?
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# We do our own transformations.
|
51
|
+
def add_primitives(gc) #:nodoc:
|
52
|
+
return if !@text && @tspans.empty?
|
53
|
+
|
54
|
+
gc.push
|
55
|
+
x = cx + @dx
|
56
|
+
y = cy + @dy
|
57
|
+
if @rotation != 0
|
58
|
+
gc.translate(x, y)
|
59
|
+
gc.rotate(@rotation)
|
60
|
+
gc.translate(-x, -y)
|
61
|
+
end
|
62
|
+
add_style_primitives(gc)
|
63
|
+
if @text
|
64
|
+
x2, y2 = gc.text(x, y, @text)
|
65
|
+
self.cx = x + x2
|
66
|
+
self.cy = y + y2
|
67
|
+
end
|
68
|
+
@tspans.each do |tspan|
|
69
|
+
tspan.add_primitives(gc)
|
70
|
+
end
|
71
|
+
gc.pop
|
72
|
+
end
|
73
|
+
end # class TextBase
|
74
|
+
|
75
|
+
# Tspan and Tref shared methods - read/update @cx, @cy in parent Text object.
|
76
|
+
module TextLink #:nodoc:
|
77
|
+
def add_primitives(gc)
|
78
|
+
@parent.cx = @x if @x
|
79
|
+
@parent.cy = @y if @y
|
80
|
+
super
|
81
|
+
end
|
82
|
+
|
83
|
+
def cx
|
84
|
+
@parent.cx
|
85
|
+
end
|
86
|
+
|
87
|
+
def cy
|
88
|
+
@parent.cy
|
89
|
+
end
|
90
|
+
|
91
|
+
def cx=(x)
|
92
|
+
@parent.cx = x
|
93
|
+
end
|
94
|
+
|
95
|
+
def cy=(y)
|
96
|
+
@parent.cy = y
|
97
|
+
end
|
98
|
+
end # module TextLink
|
99
|
+
|
100
|
+
class Tref < TextBase #:nodoc:
|
101
|
+
include TextLink
|
102
|
+
|
103
|
+
def initialize(obj, x, y, parent)
|
104
|
+
@x, @y = Magick::RVG.convert_to_float(x, y, :allow_nil)
|
105
|
+
super(nil)
|
106
|
+
@tspans << obj
|
107
|
+
@parent = parent
|
108
|
+
end
|
109
|
+
end # class Tref
|
110
|
+
|
111
|
+
class Tspan < TextBase #:nodoc:
|
112
|
+
include TextLink
|
113
|
+
|
114
|
+
attr_accessor :parent
|
115
|
+
|
116
|
+
# Define a text segment starting at (<tt>x</tt>, <tt>y</tt>).
|
117
|
+
# If <tt>x</tt> and <tt>y</tt> are omitted the segment starts
|
118
|
+
# at the current text position.
|
119
|
+
#
|
120
|
+
# Tspan objects can contain Tspan objects.
|
121
|
+
def initialize(text = nil, x = nil, y = nil, &block)
|
122
|
+
@x, @y = Magick::RVG.convert_to_float(x, y, :allow_nil)
|
123
|
+
super(text, &block)
|
124
|
+
end
|
125
|
+
end # class Tspan
|
126
|
+
|
127
|
+
class Text < TextBase
|
128
|
+
attr_accessor :cx, :cy #:nodoc:
|
129
|
+
|
130
|
+
# Define a text string starting at [<tt>x</tt>, <tt>y</tt>].
|
131
|
+
# Use the RVG::TextConstructors#text method to create Text objects in a container.
|
132
|
+
#
|
133
|
+
# container.text(100, 100, "Simple text").styles(:font=>'Arial')
|
134
|
+
#
|
135
|
+
# Text objects can contain Tspan objects.
|
136
|
+
#
|
137
|
+
# container.text(100, 100).styles(:font=>'Arial') do |t|
|
138
|
+
# t.tspan("Red text").styles(:fill=>'red')
|
139
|
+
# t.tspan("Blue text").styles(:fill=>'blue')
|
140
|
+
# end
|
141
|
+
def initialize(x = 0, y = 0, text = nil, &block)
|
142
|
+
@cx, @cy = Magick::RVG.convert_to_float(x, y)
|
143
|
+
super(text, &block)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Reference a Tspan object. <tt>x</tt> and <tt>y</tt> are just
|
147
|
+
# like <tt>x</tt> and <tt>y</tt> in RVG::TextBase#tspan
|
148
|
+
def tref(obj, x = nil, y = nil)
|
149
|
+
raise ArgumentError, "wrong argument type #{obj.class} (expected Tspan)" unless obj.is_a?(Tspan)
|
150
|
+
|
151
|
+
obj = obj.deep_copy
|
152
|
+
obj.parent = self
|
153
|
+
tref = Tref.new(obj, x, y, self)
|
154
|
+
@tspans << tref
|
155
|
+
tref
|
156
|
+
end
|
157
|
+
end # class Text
|
158
|
+
|
159
|
+
# Methods that construct text objects within a container
|
160
|
+
module TextConstructors
|
161
|
+
# Draw a text string at (<tt>x</tt>,<tt>y</tt>). The string can
|
162
|
+
# be omitted. Optionally, define text chunks within the associated
|
163
|
+
# block.
|
164
|
+
def text(x = 0, y = 0, text = nil, &block)
|
165
|
+
t = Text.new(x, y, text, &block)
|
166
|
+
@content << t
|
167
|
+
t
|
168
|
+
end
|
169
|
+
end # module TextConstructors
|
170
|
+
end # class RVG
|
172
171
|
end # module Magick
|