rmagick 2.13.4 → 2.16.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 (281) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +14 -0
  3. data/.hound.yml +2 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +340 -0
  6. data/.simplecov +27 -0
  7. data/.travis.yml +29 -12
  8. data/CHANGELOG.md +915 -0
  9. data/CODE_OF_CONDUCT.md +13 -0
  10. data/CONTRIBUTING.md +31 -3
  11. data/Gemfile +3 -0
  12. data/README.textile +94 -4
  13. data/Rakefile +57 -45
  14. data/before_install_linux.sh +26 -6
  15. data/deprecated/RMagick.rb +6 -0
  16. data/doc/comtasks.html +1 -1
  17. data/doc/draw.html +7 -4
  18. data/doc/ex/InitialCoords.rb +16 -17
  19. data/doc/ex/NewCoordSys.rb +21 -23
  20. data/doc/ex/OrigCoordSys.rb +8 -10
  21. data/doc/ex/PreserveAspectRatio.rb +182 -183
  22. data/doc/ex/RotateScale.rb +27 -28
  23. data/doc/ex/Skew.rb +27 -27
  24. data/doc/ex/Use01.rb +7 -8
  25. data/doc/ex/Use02.rb +11 -12
  26. data/doc/ex/Use03.rb +7 -7
  27. data/doc/ex/ViewBox.rb +16 -18
  28. data/doc/ex/adaptive_threshold.rb +4 -5
  29. data/doc/ex/add_noise.rb +4 -5
  30. data/doc/ex/affine.rb +4 -4
  31. data/doc/ex/affine_transform.rb +4 -4
  32. data/doc/ex/arc.rb +10 -10
  33. data/doc/ex/arcpath.rb +7 -8
  34. data/doc/ex/arcs01.rb +10 -10
  35. data/doc/ex/arcs02.rb +36 -38
  36. data/doc/ex/average.rb +5 -5
  37. data/doc/ex/axes.rb +4 -4
  38. data/doc/ex/baseline_shift01.rb +11 -12
  39. data/doc/ex/bilevel_channel.rb +2 -3
  40. data/doc/ex/blur_image.rb +2 -2
  41. data/doc/ex/border.rb +2 -2
  42. data/doc/ex/bounding_box.rb +9 -11
  43. data/doc/ex/cbezier1.rb +3 -4
  44. data/doc/ex/cbezier2.rb +3 -4
  45. data/doc/ex/cbezier3.rb +3 -4
  46. data/doc/ex/cbezier4.rb +3 -4
  47. data/doc/ex/cbezier5.rb +2 -3
  48. data/doc/ex/cbezier6.rb +3 -3
  49. data/doc/ex/channel.rb +10 -11
  50. data/doc/ex/charcoal.rb +2 -2
  51. data/doc/ex/chop.rb +2 -2
  52. data/doc/ex/circle.rb +3 -3
  53. data/doc/ex/circle01.rb +6 -7
  54. data/doc/ex/clip_path.rb +12 -12
  55. data/doc/ex/coalesce.rb +32 -35
  56. data/doc/ex/color_fill_to_border.rb +6 -6
  57. data/doc/ex/color_floodfill.rb +2 -2
  58. data/doc/ex/color_histogram.rb +17 -18
  59. data/doc/ex/color_reset.rb +2 -2
  60. data/doc/ex/colorize.rb +2 -2
  61. data/doc/ex/colors.rb +30 -30
  62. data/doc/ex/compose_mask.rb +8 -9
  63. data/doc/ex/composite.rb +14 -16
  64. data/doc/ex/composite_layers.rb +15 -15
  65. data/doc/ex/composite_tiled.rb +5 -7
  66. data/doc/ex/contrast.rb +12 -12
  67. data/doc/ex/crop.rb +3 -3
  68. data/doc/ex/crop_with_gravity.rb +13 -17
  69. data/doc/ex/cubic01.rb +18 -20
  70. data/doc/ex/cubic02.rb +64 -67
  71. data/doc/ex/cycle_colormap.rb +2 -2
  72. data/doc/ex/dissolve.rb +2 -3
  73. data/doc/ex/drawcomp.rb +34 -34
  74. data/doc/ex/drop_shadow.rb +8 -8
  75. data/doc/ex/edge.rb +2 -2
  76. data/doc/ex/ellipse.rb +4 -4
  77. data/doc/ex/ellipse01.rb +10 -11
  78. data/doc/ex/emboss.rb +2 -2
  79. data/doc/ex/enhance.rb +2 -2
  80. data/doc/ex/equalize.rb +2 -2
  81. data/doc/ex/evenodd.rb +31 -32
  82. data/doc/ex/fill_pattern.rb +12 -15
  83. data/doc/ex/flatten_images.rb +13 -13
  84. data/doc/ex/flip.rb +2 -2
  85. data/doc/ex/flop.rb +2 -2
  86. data/doc/ex/font_styles.rb +21 -23
  87. data/doc/ex/fonts.rb +14 -14
  88. data/doc/ex/frame.rb +3 -3
  89. data/doc/ex/gaussian_blur.rb +2 -2
  90. data/doc/ex/get_multiline_type_metrics.rb +6 -7
  91. data/doc/ex/get_pixels.rb +13 -14
  92. data/doc/ex/get_type_metrics.rb +26 -31
  93. data/doc/ex/gradientfill.rb +12 -12
  94. data/doc/ex/grav.rb +4 -5
  95. data/doc/ex/gravity.rb +61 -60
  96. data/doc/ex/group.rb +16 -16
  97. data/doc/ex/hatchfill.rb +10 -10
  98. data/doc/ex/image.rb +29 -31
  99. data/doc/ex/implode.rb +17 -17
  100. data/doc/ex/level.rb +2 -2
  101. data/doc/ex/level_colors.rb +4 -4
  102. data/doc/ex/line.rb +4 -5
  103. data/doc/ex/line01.rb +11 -13
  104. data/doc/ex/mask.rb +7 -8
  105. data/doc/ex/matte_fill_to_border.rb +2 -3
  106. data/doc/ex/matte_floodfill.rb +2 -3
  107. data/doc/ex/matte_replace.rb +2 -3
  108. data/doc/ex/median_filter.rb +2 -2
  109. data/doc/ex/modulate.rb +2 -2
  110. data/doc/ex/mono.rb +4 -4
  111. data/doc/ex/morph.rb +7 -8
  112. data/doc/ex/mosaic.rb +15 -15
  113. data/doc/ex/motion_blur.rb +2 -2
  114. data/doc/ex/negate.rb +2 -2
  115. data/doc/ex/negate_channel.rb +2 -2
  116. data/doc/ex/nested_rvg.rb +11 -11
  117. data/doc/ex/nonzero.rb +31 -32
  118. data/doc/ex/normalize.rb +2 -2
  119. data/doc/ex/oil_paint.rb +2 -2
  120. data/doc/ex/opacity.rb +3 -3
  121. data/doc/ex/ordered_dither.rb +2 -2
  122. data/doc/ex/path.rb +4 -5
  123. data/doc/ex/pattern1.rb +10 -10
  124. data/doc/ex/pattern2.rb +7 -7
  125. data/doc/ex/polaroid.rb +13 -14
  126. data/doc/ex/polygon.rb +6 -7
  127. data/doc/ex/polygon01.rb +10 -12
  128. data/doc/ex/polyline.rb +4 -5
  129. data/doc/ex/polyline01.rb +11 -13
  130. data/doc/ex/posterize.rb +2 -2
  131. data/doc/ex/preview.rb +3 -4
  132. data/doc/ex/qbezierpath.rb +5 -5
  133. data/doc/ex/quad01.rb +23 -25
  134. data/doc/ex/quantize-m.rb +5 -5
  135. data/doc/ex/radial_blur.rb +2 -2
  136. data/doc/ex/raise.rb +2 -2
  137. data/doc/ex/random_threshold_channel.rb +2 -2
  138. data/doc/ex/rect01.rb +6 -7
  139. data/doc/ex/rect02.rb +9 -11
  140. data/doc/ex/rectangle.rb +3 -4
  141. data/doc/ex/reduce_noise.rb +2 -2
  142. data/doc/ex/remap.rb +7 -8
  143. data/doc/ex/remap_images.rb +9 -11
  144. data/doc/ex/resize_to_fill.rb +3 -5
  145. data/doc/ex/resize_to_fit.rb +3 -5
  146. data/doc/ex/roll.rb +2 -2
  147. data/doc/ex/rotate.rb +6 -7
  148. data/doc/ex/rotate_f.rb +2 -2
  149. data/doc/ex/roundrect.rb +4 -5
  150. data/doc/ex/rubyname.rb +11 -11
  151. data/doc/ex/rvg_clippath.rb +5 -7
  152. data/doc/ex/rvg_linecap.rb +25 -26
  153. data/doc/ex/rvg_linejoin.rb +25 -26
  154. data/doc/ex/rvg_opacity.rb +10 -11
  155. data/doc/ex/rvg_pattern.rb +15 -15
  156. data/doc/ex/rvg_stroke_dasharray.rb +6 -7
  157. data/doc/ex/segment.rb +2 -2
  158. data/doc/ex/sepiatone.rb +2 -3
  159. data/doc/ex/shade.rb +2 -2
  160. data/doc/ex/shadow.rb +2 -3
  161. data/doc/ex/shave.rb +2 -2
  162. data/doc/ex/shear.rb +3 -3
  163. data/doc/ex/sketch.rb +2 -3
  164. data/doc/ex/skewx.rb +4 -5
  165. data/doc/ex/skewy.rb +3 -3
  166. data/doc/ex/smile.rb +113 -113
  167. data/doc/ex/solarize.rb +2 -2
  168. data/doc/ex/sparse_color.rb +29 -30
  169. data/doc/ex/splice.rb +2 -3
  170. data/doc/ex/spread.rb +2 -2
  171. data/doc/ex/stegano.rb +34 -34
  172. data/doc/ex/stroke_dasharray.rb +4 -5
  173. data/doc/ex/stroke_fill.rb +4 -5
  174. data/doc/ex/stroke_linecap.rb +3 -3
  175. data/doc/ex/stroke_linejoin.rb +3 -3
  176. data/doc/ex/stroke_width.rb +3 -3
  177. data/doc/ex/swirl.rb +2 -2
  178. data/doc/ex/text.rb +4 -4
  179. data/doc/ex/text01.rb +7 -8
  180. data/doc/ex/text_align.rb +2 -2
  181. data/doc/ex/text_antialias.rb +9 -10
  182. data/doc/ex/text_styles.rb +11 -13
  183. data/doc/ex/text_undercolor.rb +2 -2
  184. data/doc/ex/texture_fill_to_border.rb +6 -6
  185. data/doc/ex/texture_floodfill.rb +2 -2
  186. data/doc/ex/texturefill.rb +10 -11
  187. data/doc/ex/threshold.rb +2 -2
  188. data/doc/ex/to_blob.rb +4 -5
  189. data/doc/ex/translate.rb +6 -6
  190. data/doc/ex/transparent.rb +5 -5
  191. data/doc/ex/transpose.rb +2 -2
  192. data/doc/ex/transverse.rb +2 -2
  193. data/doc/ex/tref01.rb +11 -12
  194. data/doc/ex/triangle01.rb +5 -6
  195. data/doc/ex/trim.rb +1 -2
  196. data/doc/ex/tspan01.rb +8 -9
  197. data/doc/ex/tspan02.rb +9 -11
  198. data/doc/ex/tspan03.rb +9 -11
  199. data/doc/ex/unsharp_mask.rb +2 -2
  200. data/doc/ex/viewex.rb +19 -21
  201. data/doc/ex/vignette.rb +2 -2
  202. data/doc/ex/watermark.rb +15 -16
  203. data/doc/ex/wave.rb +2 -2
  204. data/doc/ex/wet_floor.rb +17 -18
  205. data/doc/ex/writing_mode01.rb +8 -9
  206. data/doc/ex/writing_mode02.rb +8 -8
  207. data/doc/ilist.html +1 -1
  208. data/doc/usage.html +8 -8
  209. data/examples/constitute.rb +6 -6
  210. data/examples/crop_with_gravity.rb +13 -17
  211. data/examples/demo.rb +305 -305
  212. data/examples/describe.rb +27 -28
  213. data/examples/find_similar_region.rb +16 -16
  214. data/examples/histogram.rb +228 -232
  215. data/examples/identify.rb +165 -167
  216. data/examples/image_opacity.rb +4 -4
  217. data/examples/import_export.rb +10 -10
  218. data/examples/pattern_fill.rb +9 -9
  219. data/examples/rotating_text.rb +13 -14
  220. data/examples/spinner.rb +18 -19
  221. data/examples/thumbnail.rb +13 -14
  222. data/examples/vignette.rb +8 -9
  223. data/ext/RMagick/extconf.rb +489 -367
  224. data/ext/RMagick/rmagick.c +11 -4
  225. data/ext/RMagick/rmagick.h +4 -0
  226. data/ext/RMagick/rmdraw.c +49 -18
  227. data/ext/RMagick/rmenum.c +18 -7
  228. data/ext/RMagick/rmfill.c +4 -1
  229. data/ext/RMagick/rmilist.c +49 -13
  230. data/ext/RMagick/rmimage.c +196 -59
  231. data/ext/RMagick/rminfo.c +33 -10
  232. data/ext/RMagick/rmmain.c +18 -6
  233. data/ext/RMagick/rmmontage.c +12 -4
  234. data/ext/RMagick/rmpixel.c +18 -5
  235. data/ext/RMagick/rmstruct.c +108 -31
  236. data/ext/RMagick/rmutil.c +50 -26
  237. data/lib/rmagick/version.rb +4 -3
  238. data/lib/rmagick_internal.rb +1159 -1176
  239. data/lib/rvg/clippath.rb +36 -39
  240. data/lib/rvg/container.rb +115 -124
  241. data/lib/rvg/deep_equal.rb +46 -50
  242. data/lib/rvg/describable.rb +41 -47
  243. data/lib/rvg/embellishable.rb +384 -410
  244. data/lib/rvg/misc.rb +697 -714
  245. data/lib/rvg/paint.rb +42 -47
  246. data/lib/rvg/pathdata.rb +120 -125
  247. data/lib/rvg/rvg.rb +213 -213
  248. data/lib/rvg/stretchable.rb +159 -162
  249. data/lib/rvg/stylable.rb +109 -117
  250. data/lib/rvg/text.rb +9 -24
  251. data/lib/rvg/transformable.rb +120 -127
  252. data/lib/rvg/units.rb +58 -61
  253. data/rmagick.gemspec +46 -15
  254. data/spec/rmagick/ImageList1_spec.rb +24 -0
  255. data/spec/rmagick/draw_spec.rb +156 -0
  256. data/spec/rmagick/image/blue_shift_spec.rb +16 -0
  257. data/spec/rmagick/image/composite_spec.rb +140 -0
  258. data/spec/rmagick/image/constitute_spec.rb +15 -0
  259. data/spec/rmagick/image/dispatch_spec.rb +18 -0
  260. data/spec/rmagick/image/from_blob_spec.rb +14 -0
  261. data/spec/rmagick/image/ping_spec.rb +14 -0
  262. data/spec/rmagick/image/properties_spec.rb +29 -0
  263. data/spec/spec_helper.rb +4 -0
  264. data/test/Image1.rb +529 -727
  265. data/test/Image2.rb +1291 -1299
  266. data/test/Image3.rb +978 -981
  267. data/test/ImageList1.rb +7 -9
  268. data/test/ImageList2.rb +346 -350
  269. data/test/Image_attributes.rb +683 -686
  270. data/test/Import_Export.rb +25 -30
  271. data/test/Info.rb +339 -343
  272. data/test/Magick.rb +250 -253
  273. data/test/Pixel.rb +107 -110
  274. data/test/Preview.rb +48 -53
  275. data/test/test_all_basic.rb +15 -11
  276. data/test/tmpnam_test.rb +3 -3
  277. data/wercker.yml +10 -0
  278. metadata +77 -10
  279. data/ChangeLog +0 -816
  280. data/lib/RMagick.rb +0 -1
  281. data/test/Draw.rb +0 -121
@@ -2,167 +2,164 @@
2
2
  # $Id: stretchable.rb,v 1.7 2009/02/28 23:52:28 rmagick Exp $
3
3
  # Copyright (C) 2009 Timothy P. Hunter
4
4
  #++
5
-
6
5
  module Magick
7
- class RVG
8
-
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
23
-
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
31
- end
32
- yield(self) if block_given?
33
- self
34
- end
35
- end # module PreserveAspectRatio
36
-
37
-
38
- # The methods in this module describe the user-coordinate space.
39
- # RVG and Pattern objects are stretchable.
40
- module Stretchable
41
-
42
- private
43
- # Scale to fit
44
- def set_viewbox_none(width, height)
45
- sx, sy = 1.0, 1.0
46
-
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]
55
- end
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]
77
- end
78
-
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]
83
- end
84
-
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]
89
- end
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)
122
- end
123
-
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
129
- end
130
-
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
-
149
- # return the user-coordinate space attributes if defined
150
- class << self
151
- if not defined? @redefined then
152
- @redefined = true
153
- define_method(:x) { @vbx_x }
154
- define_method(:y) { @vbx_y }
155
- define_method(:width) { @vbx_width}
156
- define_method(:height) { @vbx_height }
157
- end
158
- end
159
-
160
- yield(self) if block_given?
161
- self
162
- end
163
-
164
- end # module Stretchable
165
-
166
- end # class RVG
6
+ class RVG
7
+ module PreserveAspectRatio
8
+ #--
9
+ # Included in Stretchable module and Image class
10
+ #++
11
+ # Specifies how the image within a viewport should be scaled.
12
+ # [+align+] a combination of 'xMin', 'xMid', or 'xMax', followed by
13
+ # 'YMin', 'YMid', or 'YMax'
14
+ # [+meet_or_slice+] one of 'meet' or 'slice'
15
+ def preserve_aspect_ratio(align, meet_or_slice='meet')
16
+ @align = align.to_s
17
+ if @align != 'none'
18
+ m = /\A(xMin|xMid|xMax)(YMin|YMid|YMax)\z/.match(@align)
19
+ fail(ArgumentError, "unknown alignment specifier: #{@align}") unless m
20
+ end
21
+
22
+ if meet_or_slice
23
+ meet_or_slice = meet_or_slice.to_s.downcase
24
+ if meet_or_slice == 'meet' || meet_or_slice == 'slice'
25
+ @meet_or_slice = meet_or_slice
26
+ else
27
+ fail(ArgumentError, "specifier must be `meet' or `slice' (got #{meet_or_slice})")
28
+ end
29
+ end
30
+ yield(self) if block_given?
31
+ self
32
+ end
33
+ end # module PreserveAspectRatio
34
+
35
+ # The methods in this module describe the user-coordinate space.
36
+ # RVG and Pattern objects are stretchable.
37
+ module Stretchable
38
+ private
39
+
40
+ # Scale to fit
41
+ def set_viewbox_none(width, height)
42
+ sx = 1.0
43
+ sy = 1.0
44
+
45
+ if @vbx_width
46
+ sx = width / @vbx_width
47
+ end
48
+ if @vbx_height
49
+ sy = height / @vbx_height
50
+ end
51
+
52
+ [sx, sy]
53
+ end
54
+
55
+ # Use align attribute to compute x- and y-offset from viewport's upper-left corner.
56
+ def align_to_viewport(width, height, sx, sy)
57
+ tx = case @align
58
+ when /\AxMin/
59
+ 0
60
+ when NilClass, /\AxMid/
61
+ (width - @vbx_width*sx) / 2.0
62
+ when /\AxMax/
63
+ width - @vbx_width*sx
64
+ end
65
+
66
+ ty = case @align
67
+ when /YMin\z/
68
+ 0
69
+ when NilClass, /YMid\z/
70
+ (height - @vbx_height*sy) / 2.0
71
+ when /YMax\z/
72
+ height - @vbx_height*sy
73
+ end
74
+ [tx, ty]
75
+ end
76
+
77
+ # Scale to smaller viewbox dimension
78
+ def set_viewbox_meet(width, height)
79
+ sx = sy = [width / @vbx_width, height / @vbx_height].min
80
+ [sx, sy]
81
+ end
82
+
83
+ # Scale to larger viewbox dimension
84
+ def set_viewbox_slice(width, height)
85
+ sx = sy = [width / @vbx_width, height / @vbx_height].max
86
+ [sx, sy]
87
+ end
88
+
89
+ # Establish the viewbox as necessary
90
+ def add_viewbox_primitives(width, height, gc)
91
+ @vbx_width ||= width
92
+ @vbx_height ||= height
93
+ @vbx_x ||= 0.0
94
+ @vbx_y ||= 0.0
95
+
96
+ if @align == 'none'
97
+ sx, sy = set_viewbox_none(width, height)
98
+ tx = 0
99
+ ty = 0
100
+ elsif @meet_or_slice == 'meet'
101
+ sx, sy = set_viewbox_meet(width, height)
102
+ tx, ty = align_to_viewport(width, height, sx, sy)
103
+ else
104
+ sx, sy = set_viewbox_slice(width, height)
105
+ tx, ty = align_to_viewport(width, height, sx, sy)
106
+ end
107
+
108
+ # Establish clipping path around the current viewport
109
+ name = __id__.to_s
110
+ gc.define_clip_path(name) do
111
+ gc.path("M0,0 l#{width},0 l0,#{height} l-#{width},0 l0,-#{height}z")
112
+ end
113
+
114
+ gc.clip_path(name)
115
+ # Add a non-scaled translation if meet or slice
116
+ gc.translate(tx, ty) if tx.abs > 1.0e-10 || ty.abs > 1.0e-10
117
+ # Scale viewbox as necessary
118
+ gc.scale(sx, sy) if sx != 1.0 || sy != 1.0
119
+ # Add a scaled translation if non-0 origin
120
+ gc.translate(-@vbx_x, -@vbx_y) if @vbx_x.abs != 0.0 || @vbx_y.abs != 0
121
+ end
122
+
123
+ def initialize(*args, &block)
124
+ super()
125
+ @vbx_x, @vbx_y, @vbx_width, @vbx_height = nil
126
+ @meet_or_slice = 'meet'
127
+ @align = nil
128
+ end
129
+
130
+ public
131
+
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
+ fail(ArgumentError, "viewbox width must be > 0 (#{width} given)") unless width >= 0
147
+ fail(ArgumentError, "viewbox height must be > 0 (#{height} given)") unless height >= 0
148
+
149
+ # return the user-coordinate space attributes if defined
150
+ class << self
151
+ unless defined? @redefined
152
+ @redefined = true
153
+ define_method(:x) { @vbx_x }
154
+ define_method(:y) { @vbx_y }
155
+ define_method(:width) { @vbx_width}
156
+ define_method(:height) { @vbx_height }
157
+ end
158
+ end
159
+
160
+ yield(self) if block_given?
161
+ self
162
+ end
163
+ end # module Stretchable
164
+ end # class RVG
167
165
  end # module Magick
168
-
data/lib/rvg/stylable.rb CHANGED
@@ -2,123 +2,115 @@
2
2
  # $Id: stylable.rb,v 1.7 2009/02/28 23:52:28 rmagick Exp $
3
3
  # Copyright (C) 2009 Timothy P. Hunter
4
4
  #++
5
-
6
5
  module Magick
7
- class RVG
8
-
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
31
- end
32
- rescue NoMethodError
33
- raise ArgumentError, "style arguments must be in the form `style => value'"
34
- end
35
- self
36
- end
37
-
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
43
- end
44
-
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
6
+ class RVG
7
+ #:stopdoc:
8
+ STYLES = [: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
+
16
+ Styles = Struct.new(*STYLES)
17
+
18
+ # Styles is a Struct class with a couple of extra methods
19
+ class Styles
20
+ def set(styles)
21
+ begin
22
+ styles.each_pair do |style, value|
23
+ begin
24
+ self[style] = value
25
+ rescue NoMethodError
26
+ raise ArgumentError, "unknown style `#{style}'"
50
27
  end
51
-
52
- end # class Styles
53
-
54
- #:startdoc:
55
-
56
- # This module is mixed into classes that can have styles.
57
- module Stylable
58
-
59
- private
60
-
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
70
- end
71
- 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
- # [:baseline_shift] modify the text baseline
84
- # [:clip_path] clipping path defined by clip_path
85
- # [:clip_rule] 'evenodd' or 'nozero'
86
- # [:fill] color name
87
- # [:fill_opacity] the fill opacity, 0.0<=N<=1.0
88
- # [:fill_rule] 'evenodd' or 'nozero'
89
- # [:font] font name or font file name
90
- # [:font_family] font family name, ex. 'serif'
91
- # [:font_size] font size in points
92
- # [:font_stretch] 'normal','ultra_condensed','extra_condensed',
93
- # 'condensed','semi_condensed','semi_expanded',
94
- # 'expanded','extra_expanded','ultra_expanded'
95
- # [:font_style] 'normal','italic','oblique'
96
- # [:font_weight] 'normal','bold','bolder','lighter', or
97
- # a multiple of 100 between 100 and 900.
98
- # [:glyph_orientation_horizontal] 0, 90, 180, 270
99
- # [:glyph_orientation_vertical] 0, 90, 180, 270
100
- # [:letter_spacing] modify the spacing between letters
101
- # [:opacity] both fill and stroke opacity, 0.0<=N<=1.0
102
- # [:stroke] color name
103
- # [:stroke_dasharray] dash pattern (Array)
104
- # [:stroke_dashoffset] initial distance into dash pattern
105
- # [:stroke_linecap] 'butt', 'round', 'square'
106
- # [:stroke_linejoin] 'miter', 'round', 'bevel'
107
- # [:stroke_miterlimit] miter length constraint
108
- # [:stroke_opacity] the stroke opacity, 0.0<=N<=1.0
109
- # [:stroke_width] stroke width
110
- # [:text_anchor] 'start','middle','end'
111
- # [:text_decoration] 'none','underline','overline','line_through'
112
- # [:word_spacing] modify the spacing between words
113
- # [:writing_mode] 'lr-tb', 'lr', 'rt-tb', 'rl', 'tb-rl', 'tb'
114
- def styles(styles)
115
- @styles.set(styles)
116
- yield(self) if block_given?
117
- self
118
- end
119
-
120
- end # module Stylable
121
-
122
- end # class RVG
28
+ end
29
+ rescue NoMethodError
30
+ raise ArgumentError, "style arguments must be in the form `style => value'"
31
+ end
32
+ self
33
+ end
34
+
35
+ # Iterate over the style names. Yield for each style that has a value.
36
+ def each_value
37
+ each_pair do |style, value|
38
+ yield(style, value) if value
39
+ end
40
+ end
41
+
42
+ # The "usual" deep_copy method doesn't copy a Struct correctly.
43
+ def deep_copy(h=nil)
44
+ copy = Styles.new
45
+ each_pair { |style, value| copy[style] = value }
46
+ copy
47
+ end
48
+ end # class Styles
49
+
50
+ #:startdoc:
51
+
52
+ # This module is mixed into classes that can have styles.
53
+ module Stylable
54
+ private
55
+
56
+ # For each style that has a value, add a style primitive to the gc.
57
+ # Use splat to splat out Array arguments such as stroke_dasharray.
58
+ def add_style_primitives(gc)
59
+ @styles.each_value do |style, value|
60
+ if value.respond_to? :add_primitives
61
+ value.add_primitives(gc, style)
62
+ else
63
+ gc.__send__(style, *value)
64
+ end
65
+ end
66
+ end
67
+
68
+ def initialize
69
+ super
70
+ @styles = Styles.new
71
+ end
72
+
73
+ public
74
+
75
+ # This method can be used with any RVG, Group, Use, Text, or
76
+ # shape object. The argument is a hash. The style names are
77
+ # the hash keys. The style names and values are:
78
+ # [:baseline_shift] modify the text baseline
79
+ # [:clip_path] clipping path defined by clip_path
80
+ # [:clip_rule] 'evenodd' or 'nozero'
81
+ # [:fill] color name
82
+ # [:fill_opacity] the fill opacity, 0.0<=N<=1.0
83
+ # [:fill_rule] 'evenodd' or 'nozero'
84
+ # [:font] font name or font file name
85
+ # [:font_family] font family name, ex. 'serif'
86
+ # [:font_size] font size in points
87
+ # [:font_stretch] 'normal','ultra_condensed','extra_condensed',
88
+ # 'condensed','semi_condensed','semi_expanded',
89
+ # 'expanded','extra_expanded','ultra_expanded'
90
+ # [:font_style] 'normal','italic','oblique'
91
+ # [:font_weight] 'normal','bold','bolder','lighter', or
92
+ # a multiple of 100 between 100 and 900.
93
+ # [:glyph_orientation_horizontal] 0, 90, 180, 270
94
+ # [:glyph_orientation_vertical] 0, 90, 180, 270
95
+ # [:letter_spacing] modify the spacing between letters
96
+ # [:opacity] both fill and stroke opacity, 0.0<=N<=1.0
97
+ # [:stroke] color name
98
+ # [:stroke_dasharray] dash pattern (Array)
99
+ # [:stroke_dashoffset] initial distance into dash pattern
100
+ # [:stroke_linecap] 'butt', 'round', 'square'
101
+ # [:stroke_linejoin] 'miter', 'round', 'bevel'
102
+ # [:stroke_miterlimit] miter length constraint
103
+ # [:stroke_opacity] the stroke opacity, 0.0<=N<=1.0
104
+ # [:stroke_width] stroke width
105
+ # [:text_anchor] 'start','middle','end'
106
+ # [:text_decoration] 'none','underline','overline','line_through'
107
+ # [:word_spacing] modify the spacing between words
108
+ # [:writing_mode] 'lr-tb', 'lr', 'rt-tb', 'rl', 'tb-rl', 'tb'
109
+ def styles(styles)
110
+ @styles.set(styles)
111
+ yield(self) if block_given?
112
+ self
113
+ end
114
+ end # module Stylable
115
+ end # class RVG
123
116
  end # module Magick
124
-