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.
- data/ChangeLog +22 -0
- data/README.html +11 -63
- data/README.txt +8 -56
- data/configure +214 -787
- data/configure.ac +22 -24
- data/doc/comtasks.html +2 -2
- data/doc/constants.html +5 -6
- data/doc/draw.html +33 -14
- data/doc/ex/clip_path.rb +3 -0
- data/doc/ex/path.rb +1 -1
- data/doc/ex/polaroid.rb +23 -0
- data/doc/ex/tspan01.rb +2 -2
- data/doc/ex/tspan02.rb +2 -2
- data/doc/ex/tspan03.rb +3 -3
- data/doc/ex/wet_floor.rb +54 -0
- data/doc/ilist.html +83 -4
- data/doc/image1.html +4 -5
- data/doc/image2.html +395 -266
- data/doc/image3.html +104 -8
- data/doc/imageattrs.html +2 -2
- data/doc/imusage.html +2 -2
- data/doc/index.html +22 -18
- data/doc/info.html +28 -6
- data/doc/magick.html +125 -4
- data/doc/optequiv.html +196 -21
- data/doc/rvg.html +2 -2
- data/doc/rvgclip.html +2 -2
- data/doc/rvggroup.html +2 -2
- data/doc/rvgimage.html +2 -2
- data/doc/rvgpattern.html +2 -2
- data/doc/rvgshape.html +2 -2
- data/doc/rvgstyle.html +2 -2
- data/doc/rvgtext.html +2 -2
- data/doc/rvgtspan.html +2 -2
- data/doc/rvgtut.html +3 -3
- data/doc/rvguse.html +2 -2
- data/doc/rvgxform.html +2 -2
- data/doc/struct.html +2 -2
- data/doc/usage.html +26 -5
- data/ext/RMagick/MANIFEST +3 -1
- data/ext/RMagick/rmagick.h +46 -12
- data/ext/RMagick/rmagick_config.h.in +12 -2
- data/ext/RMagick/rmdraw.c +202 -62
- data/ext/RMagick/rmfill.c +36 -36
- data/ext/RMagick/rmilist.c +75 -31
- data/ext/RMagick/rmimage.c +640 -323
- data/ext/RMagick/rminfo.c +76 -15
- data/ext/RMagick/rmmain.c +107 -30
- data/ext/RMagick/rmutil.c +97 -68
- data/lib/RMagick.rb +11 -11
- data/lib/rvg/clippath.rb +38 -36
- data/lib/rvg/container.rb +120 -118
- data/lib/rvg/deep_equal.rb +44 -42
- data/lib/rvg/describable.rb +49 -47
- data/lib/rvg/embellishable.rb +399 -397
- data/lib/rvg/misc.rb +613 -603
- data/lib/rvg/paint.rb +38 -36
- data/lib/rvg/pathdata.rb +124 -122
- data/lib/rvg/rvg.rb +202 -198
- data/lib/rvg/stretchable.rb +132 -130
- data/lib/rvg/stylable.rb +101 -99
- data/lib/rvg/text.rb +173 -171
- data/lib/rvg/transformable.rb +120 -118
- data/lib/rvg/units.rb +60 -58
- data/rmagick.gemspec +1 -1
- metadata +5 -3
data/lib/rvg/stretchable.rb
CHANGED
@@ -1,154 +1,156 @@
|
|
1
1
|
#--
|
2
|
-
# $Id: stretchable.rb,v 1.
|
3
|
-
# Copyright (C)
|
2
|
+
# $Id: stretchable.rb,v 1.4 2007/01/20 17:39:50 rmagick Exp $
|
3
|
+
# Copyright (C) 2007 Timothy P. Hunter
|
4
4
|
#++
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
6
|
+
module Magick
|
7
|
+
class RVG
|
8
|
+
|
9
|
+
module PreserveAspectRatio
|
10
|
+
#--
|
11
|
+
# Included in Stretchable module and Image class
|
12
|
+
#++
|
13
|
+
# Specifies how the image within a viewport should be scaled.
|
14
|
+
# [+align+] a combination of 'xMin', 'xMid', or 'xMax', followed by
|
15
|
+
# 'YMin', 'YMid', or 'YMax'
|
16
|
+
# [+meet_or_slice+] one of 'meet' or 'slice'
|
17
|
+
def preserve_aspect_ratio(align, meet_or_slice='meet')
|
18
|
+
@align = align.to_s
|
19
|
+
if @align != 'none'
|
20
|
+
m = /\A(xMin|xMid|xMax)(YMin|YMid|YMax)\z/.match(@align)
|
21
|
+
raise(ArgumentError, "unknown alignment specifier: #{@align}") unless m
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
if meet_or_slice
|
25
|
+
meet_or_slice = meet_or_slice.to_s.downcase
|
26
|
+
if meet_or_slice == 'meet' || meet_or_slice == 'slice'
|
27
|
+
@meet_or_slice = meet_or_slice
|
28
|
+
else
|
29
|
+
raise(ArgumentError, "specifier must be `meet' or `slice' (got #{meet_or_slice})")
|
30
|
+
end
|
29
31
|
end
|
32
|
+
yield(self) if block_given?
|
33
|
+
self
|
30
34
|
end
|
31
|
-
|
32
|
-
self
|
33
|
-
end
|
34
|
-
end # module PreserveAspectRatio
|
35
|
+
end # module PreserveAspectRatio
|
35
36
|
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
# The methods in this module describe the user-coordinate space.
|
39
|
+
# Only RVG objects are stretchable.
|
40
|
+
module Stretchable
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
private
|
43
|
+
# Scale to fit
|
44
|
+
def set_viewbox_none(width, height)
|
45
|
+
sx, sy = 1.0, 1.0
|
45
46
|
|
46
|
-
|
47
|
-
|
47
|
+
if @vbx_width
|
48
|
+
sx = width / @vbx_width
|
49
|
+
end
|
50
|
+
if @vbx_height
|
51
|
+
sy = height / @vbx_height
|
52
|
+
end
|
53
|
+
|
54
|
+
return [sx, sy]
|
48
55
|
end
|
49
|
-
|
50
|
-
|
56
|
+
|
57
|
+
# Use align attribute to compute x- and y-offset from viewport's upper-left corner.
|
58
|
+
def align_to_viewport(width, height, sx, sy)
|
59
|
+
tx = case @align
|
60
|
+
when /\AxMin/
|
61
|
+
0
|
62
|
+
when NilClass, /\AxMid/
|
63
|
+
(width - @vbx_width*sx) / 2.0
|
64
|
+
when /\AxMax/
|
65
|
+
width - @vbx_width*sx
|
66
|
+
end
|
67
|
+
|
68
|
+
ty = case @align
|
69
|
+
when /YMin\z/
|
70
|
+
0
|
71
|
+
when NilClass, /YMid\z/
|
72
|
+
(height - @vbx_height*sy) / 2.0
|
73
|
+
when /YMax\z/
|
74
|
+
height - @vbx_height*sy
|
75
|
+
end
|
76
|
+
return [tx, ty]
|
51
77
|
end
|
52
78
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def align_to_viewport(width, height, sx, sy)
|
58
|
-
tx = case @align
|
59
|
-
when /\AxMin/
|
60
|
-
0
|
61
|
-
when NilClass, /\AxMid/
|
62
|
-
(width - @vbx_width*sx) / 2.0
|
63
|
-
when /\AxMax/
|
64
|
-
width - @vbx_width*sx
|
79
|
+
# Scale to smaller viewbox dimension
|
80
|
+
def set_viewbox_meet(width, height)
|
81
|
+
sx = sy = [width / @vbx_width, height / @vbx_height].min
|
82
|
+
return [sx, sy]
|
65
83
|
end
|
66
84
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
(height - @vbx_height*sy) / 2.0
|
72
|
-
when /YMax\z/
|
73
|
-
height - @vbx_height*sy
|
85
|
+
# Scale to larger viewbox dimension
|
86
|
+
def set_viewbox_slice(width, height)
|
87
|
+
sx = sy = [width / @vbx_width, height / @vbx_height].max
|
88
|
+
return [sx, sy]
|
74
89
|
end
|
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
|
-
tx, ty
|
103
|
-
|
104
|
-
sx, sy
|
105
|
-
|
90
|
+
|
91
|
+
# Establish the viewbox as necessary
|
92
|
+
def add_viewbox_primitives(width, height, gc)
|
93
|
+
@vbx_width ||= width
|
94
|
+
@vbx_height ||= height
|
95
|
+
@vbx_x ||= 0.0
|
96
|
+
@vbx_y ||= 0.0
|
97
|
+
|
98
|
+
if @align == 'none'
|
99
|
+
sx, sy = set_viewbox_none(width, height)
|
100
|
+
tx, ty = 0, 0
|
101
|
+
elsif @meet_or_slice == 'meet'
|
102
|
+
sx, sy = set_viewbox_meet(width, height)
|
103
|
+
tx, ty = align_to_viewport(width, height, sx, sy)
|
104
|
+
else
|
105
|
+
sx, sy = set_viewbox_slice(width, height)
|
106
|
+
tx, ty = align_to_viewport(width, height, sx, sy)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Establish clipping path around the current viewport
|
110
|
+
name = __id__.to_s
|
111
|
+
gc.define_clip_path(name) do
|
112
|
+
gc.path("M0,0 l#{width},0 l0,#{height} l-#{width},0 l0,-#{height}z")
|
113
|
+
end
|
114
|
+
|
115
|
+
gc.clip_path(name)
|
116
|
+
# Add a non-scaled translation if meet or slice
|
117
|
+
gc.translate(tx, ty) if (tx.abs > 1.0e-10 || ty.abs > 1.0e-10)
|
118
|
+
# Scale viewbox as necessary
|
119
|
+
gc.scale(sx, sy) if (sx != 1.0 || sy != 1.0)
|
120
|
+
# Add a scaled translation if non-0 origin
|
121
|
+
gc.translate(-@vbx_x, -@vbx_y) if (@vbx_x.abs != 0.0 || @vbx_y.abs != 0)
|
106
122
|
end
|
107
123
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
124
|
+
def initialize(*args, &block)
|
125
|
+
super()
|
126
|
+
@vbx_x, @vbx_y, @vbx_width, @vbx_height = nil
|
127
|
+
@meet_or_slice = 'meet'
|
128
|
+
@align = nil
|
112
129
|
end
|
113
130
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
|
119
|
-
#
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
# Describe a user coordinate system to be imposed on the viewbox.
|
134
|
-
# The arguments must be numbers and the +width+ and +height+
|
135
|
-
# arguments must be positive.
|
136
|
-
def viewbox(x, y, width, height)
|
137
|
-
begin
|
138
|
-
@vbx_x = Float(x)
|
139
|
-
@vbx_y = Float(y)
|
140
|
-
@vbx_width = Float(width)
|
141
|
-
@vbx_height = Float(height)
|
142
|
-
rescue ArgumentError
|
143
|
-
raise ArgumentError, "arguments must be convertable to float (got #{x.class}, #{y.class}, #{width.class}, #{height.class})"
|
131
|
+
public
|
132
|
+
include PreserveAspectRatio
|
133
|
+
|
134
|
+
# Describe a user coordinate system to be imposed on the viewbox.
|
135
|
+
# The arguments must be numbers and the +width+ and +height+
|
136
|
+
# arguments must be positive.
|
137
|
+
def viewbox(x, y, width, height)
|
138
|
+
begin
|
139
|
+
@vbx_x = Float(x)
|
140
|
+
@vbx_y = Float(y)
|
141
|
+
@vbx_width = Float(width)
|
142
|
+
@vbx_height = Float(height)
|
143
|
+
rescue ArgumentError
|
144
|
+
raise ArgumentError, "arguments must be convertable to float (got #{x.class}, #{y.class}, #{width.class}, #{height.class})"
|
145
|
+
end
|
146
|
+
raise(ArgumentError, "viewbox width must be > 0 (#{width} given)") unless width >= 0
|
147
|
+
raise(ArgumentError, "viewbox height must be > 0 (#{height} given)") unless height >= 0
|
148
|
+
yield(self) if block_given?
|
149
|
+
self
|
144
150
|
end
|
145
|
-
raise(ArgumentError, "viewbox width must be > 0 (#{width} given)") unless width >= 0
|
146
|
-
raise(ArgumentError, "viewbox height must be > 0 (#{height} given)") unless height >= 0
|
147
|
-
yield(self) if block_given?
|
148
|
-
self
|
149
|
-
end
|
150
151
|
|
151
|
-
|
152
|
+
end # module Stretchable
|
152
153
|
|
153
|
-
end
|
154
|
+
end # class RVG
|
155
|
+
end # module Magick
|
154
156
|
|
data/lib/rvg/stylable.rb
CHANGED
@@ -1,116 +1,118 @@
|
|
1
1
|
#--
|
2
|
-
# $Id: stylable.rb,v 1.
|
3
|
-
# Copyright (C)
|
2
|
+
# $Id: stylable.rb,v 1.4 2007/01/20 17:49:57 rmagick Exp $
|
3
|
+
# Copyright (C) 2007 Timothy P. Hunter
|
4
4
|
#++
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
6
|
+
module Magick
|
7
|
+
class RVG
|
8
|
+
|
9
|
+
#:stopdoc:
|
10
|
+
STYLES = [:clip_path, :clip_rule, :fill, :fill_opacity, :fill_rule, :font,
|
11
|
+
:font_family, :font_size, :font_stretch, :font_style, :font_weight,
|
12
|
+
:opacity, :stroke, :stroke_dasharray, :stroke_dashoffset, :stroke_linecap,
|
13
|
+
:stroke_linejoin, :stroke_miterlimit, :stroke_opacity, :stroke_width,
|
14
|
+
:text_anchor, :text_decoration,
|
15
|
+
:glyph_orientation_vertical, :glyph_orientation_horizontal,
|
16
|
+
:letter_spacing, :word_spacing, :baseline_shift, :writing_mode]
|
17
|
+
|
18
|
+
Styles = Struct.new(*STYLES)
|
19
|
+
|
20
|
+
# Styles is a Struct class with a couple of extra methods
|
21
|
+
class Styles
|
22
|
+
|
23
|
+
def set(styles)
|
24
|
+
begin
|
25
|
+
styles.each_pair do |style, value|
|
26
|
+
begin
|
27
|
+
self[style] = value
|
28
|
+
rescue NoMethodError
|
29
|
+
raise ArgumentError, "unknown style `#{style}'"
|
30
|
+
end
|
29
31
|
end
|
32
|
+
rescue NoMethodError
|
33
|
+
raise ArgumentError, "style arguments must be in the form `style => value'"
|
30
34
|
end
|
31
|
-
|
32
|
-
raise ArgumentError, "style arguments must be in the form `style => value'"
|
35
|
+
self
|
33
36
|
end
|
34
|
-
self
|
35
|
-
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
# Iterate over the style names. Yield for each style that has a value.
|
39
|
+
def each_value
|
40
|
+
each_pair do |style, value|
|
41
|
+
yield(style, value) if value
|
42
|
+
end
|
41
43
|
end
|
42
|
-
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
# The "usual" deep_copy method doesn't copy a Struct correctly.
|
46
|
+
def deep_copy(h=nil)
|
47
|
+
copy = Styles.new
|
48
|
+
each_pair { |style, value| copy[style] = value }
|
49
|
+
return copy
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
+
end # class Styles
|
52
53
|
|
53
|
-
|
54
|
+
#:startdoc:
|
54
55
|
|
55
|
-
|
56
|
-
|
56
|
+
# This module is mixed into classes that can have styles.
|
57
|
+
module Stylable
|
57
58
|
|
58
|
-
|
59
|
+
private
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
# For each style that has a value, add a style primitive to the gc.
|
62
|
+
# Use splat to splat out Array arguments such as stroke_dasharray.
|
63
|
+
def add_style_primitives(gc)
|
64
|
+
@styles.each_value do |style, value|
|
65
|
+
if value.respond_to? :add_primitives
|
66
|
+
value.add_primitives(gc, style)
|
67
|
+
else
|
68
|
+
gc.__send__(style, *value)
|
69
|
+
end
|
68
70
|
end
|
69
71
|
end
|
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
|
-
end
|
72
|
+
|
73
|
+
def initialize
|
74
|
+
super
|
75
|
+
@styles = Styles.new
|
76
|
+
end
|
77
|
+
|
78
|
+
public
|
79
|
+
|
80
|
+
# This method can be used with any RVG, Group, Use, Text, or
|
81
|
+
# shape object. The argument is a hash. The style names are
|
82
|
+
# the hash keys. The style names and values are:
|
83
|
+
# [:clip_path] clipping path defined by clip_path
|
84
|
+
# [:clip_rule] 'evenodd' or 'nozero'
|
85
|
+
# [:fill] color name
|
86
|
+
# [:fill_opacity] the fill opacity, 0.0<=N<=1.0
|
87
|
+
# [:fill_rule] 'evenodd' or 'nozero'
|
88
|
+
# [:font] font name or font file name
|
89
|
+
# [:font_family] font family name, ex. 'serif'
|
90
|
+
# [:font_size] font size in points
|
91
|
+
# [:font_stretch] 'normal','ultra_condensed','extra_condensed',
|
92
|
+
# 'condensed','semi_condensed','semi_expanded',
|
93
|
+
# 'expanded','extra_expanded','ultra_expanded'
|
94
|
+
# [:font_style] 'normal','italic','oblique'
|
95
|
+
# [:font_weight] 'normal','bold','bolder','lighter', or
|
96
|
+
# a multiple of 100 between 100 and 900.
|
97
|
+
# [:opacity] both fill and stroke opacity, 0.0<=N<=1.0
|
98
|
+
# [:stroke] color name
|
99
|
+
# [:stroke_dasharray] dash pattern (Array)
|
100
|
+
# [:stroke_dashoffset] initial distance into dash pattern
|
101
|
+
# [:stroke_linecap] 'butt', 'round', 'square'
|
102
|
+
# [:stroke_linejoin] 'miter', 'round', 'bevel'
|
103
|
+
# [:stroke_miterlimit] miter length constraint
|
104
|
+
# [:stroke_opacity] the stroke opacity, 0.0<=N<=1.0
|
105
|
+
# [:stroke_width] stroke width
|
106
|
+
# [:text_anchor] 'start','middle','end'
|
107
|
+
# [:text_decoration] 'none','underline','overline','line_through'
|
108
|
+
def styles(styles)
|
109
|
+
@styles.set(styles)
|
110
|
+
yield(self) if block_given?
|
111
|
+
self
|
112
|
+
end
|
113
|
+
|
114
|
+
end # module Stylable
|
115
|
+
|
116
|
+
end # class RVG
|
117
|
+
end # module Magick
|
116
118
|
|