rmagick 4.0.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (420) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +14 -0
  3. data/.devcontainer/ImageMagick6/devcontainer.json +11 -0
  4. data/.devcontainer/devcontainer.json +11 -0
  5. data/.devcontainer/setup-repo.sh +10 -0
  6. data/.devcontainer/setup-user.sh +45 -0
  7. data/.editorconfig +3 -0
  8. data/.github/ISSUE_TEMPLATE.md +17 -0
  9. data/.github/workflows/ci.yml +138 -0
  10. data/.gitignore +5 -1
  11. data/.rspec +1 -0
  12. data/.rubocop.yml +24 -0
  13. data/.rubocop_todo.yml +150 -297
  14. data/.yardopts +5 -0
  15. data/CHANGELOG.md +222 -0
  16. data/CODE_OF_CONDUCT.md +122 -7
  17. data/CONTRIBUTING.md +14 -10
  18. data/README.md +316 -0
  19. data/Rakefile +59 -93
  20. data/before_install_linux.sh +23 -29
  21. data/before_install_osx.sh +58 -2
  22. data/ext/RMagick/extconf.rb +191 -110
  23. data/ext/RMagick/rmagick.c +77 -104
  24. data/ext/RMagick/rmagick.h +138 -99
  25. data/ext/RMagick/rmagick_gvl.h +224 -0
  26. data/ext/RMagick/rmdraw.c +464 -526
  27. data/ext/RMagick/rmenum.c +132 -121
  28. data/ext/RMagick/rmfill.c +223 -83
  29. data/ext/RMagick/rmilist.c +360 -288
  30. data/ext/RMagick/rmimage.c +5550 -4318
  31. data/ext/RMagick/rminfo.c +637 -818
  32. data/ext/RMagick/rmkinfo.c +88 -92
  33. data/ext/RMagick/rmmain.c +462 -263
  34. data/ext/RMagick/rmmontage.c +105 -150
  35. data/ext/RMagick/rmpixel.c +554 -359
  36. data/ext/RMagick/rmstruct.c +81 -94
  37. data/ext/RMagick/rmutil.c +279 -270
  38. data/lib/rmagick/version.rb +3 -1
  39. data/lib/rmagick.rb +2 -0
  40. data/lib/rmagick_internal.rb +118 -104
  41. data/lib/rvg/clippath.rb +2 -1
  42. data/lib/rvg/container.rb +10 -5
  43. data/lib/rvg/describable.rb +1 -1
  44. data/lib/rvg/embellishable.rb +5 -4
  45. data/lib/rvg/misc.rb +15 -12
  46. data/lib/rvg/paint.rb +2 -1
  47. data/lib/rvg/pathdata.rb +12 -11
  48. data/lib/rvg/rvg.rb +10 -6
  49. data/lib/rvg/stylable.rb +9 -7
  50. data/lib/rvg/text.rb +11 -6
  51. data/lib/rvg/transformable.rb +3 -2
  52. data/lib/rvg/units.rb +1 -1
  53. data/rmagick.gemspec +13 -12
  54. metadata +63 -419
  55. data/.appveyor.yml +0 -45
  56. data/.circleci/config.yml +0 -56
  57. data/.ruby-version +0 -1
  58. data/.simplecov +0 -27
  59. data/.travis.yml +0 -62
  60. data/Doxyfile +0 -1514
  61. data/README.textile +0 -259
  62. data/benchmarks/memory/README.md +0 -50
  63. data/benchmarks/memory/image_new.rb +0 -8
  64. data/benchmarks/memory/rmagick.gnuplot +0 -16
  65. data/deprecated/RMagick.rb +0 -6
  66. data/doc/.cvsignore +0 -1
  67. data/doc/comtasks.html +0 -287
  68. data/doc/constants.html +0 -1581
  69. data/doc/css/doc.css +0 -299
  70. data/doc/css/popup.css +0 -34
  71. data/doc/css/ref.css +0 -67
  72. data/doc/draw.html +0 -3272
  73. data/doc/ex/InitialCoords.rb +0 -22
  74. data/doc/ex/NewCoordSys.rb +0 -30
  75. data/doc/ex/OrigCoordSys.rb +0 -16
  76. data/doc/ex/PreserveAspectRatio.rb +0 -204
  77. data/doc/ex/RotateScale.rb +0 -36
  78. data/doc/ex/Skew.rb +0 -38
  79. data/doc/ex/Use01.rb +0 -15
  80. data/doc/ex/Use02.rb +0 -20
  81. data/doc/ex/Use03.rb +0 -16
  82. data/doc/ex/ViewBox.rb +0 -31
  83. data/doc/ex/adaptive_threshold.rb +0 -9
  84. data/doc/ex/add_noise.rb +0 -16
  85. data/doc/ex/affine.rb +0 -48
  86. data/doc/ex/affine_transform.rb +0 -20
  87. data/doc/ex/arc.rb +0 -49
  88. data/doc/ex/arcpath.rb +0 -32
  89. data/doc/ex/arcs01.rb +0 -28
  90. data/doc/ex/arcs02.rb +0 -59
  91. data/doc/ex/average.rb +0 -15
  92. data/doc/ex/axes.rb +0 -64
  93. data/doc/ex/baseline_shift01.rb +0 -17
  94. data/doc/ex/bilevel_channel.rb +0 -8
  95. data/doc/ex/blur_image.rb +0 -12
  96. data/doc/ex/border.rb +0 -10
  97. data/doc/ex/bounding_box.rb +0 -42
  98. data/doc/ex/cbezier1.rb +0 -41
  99. data/doc/ex/cbezier2.rb +0 -41
  100. data/doc/ex/cbezier3.rb +0 -41
  101. data/doc/ex/cbezier4.rb +0 -42
  102. data/doc/ex/cbezier5.rb +0 -42
  103. data/doc/ex/cbezier6.rb +0 -53
  104. data/doc/ex/channel.rb +0 -25
  105. data/doc/ex/charcoal.rb +0 -12
  106. data/doc/ex/chop.rb +0 -29
  107. data/doc/ex/circle.rb +0 -33
  108. data/doc/ex/circle01.rb +0 -16
  109. data/doc/ex/clip_path.rb +0 -60
  110. data/doc/ex/coalesce.rb +0 -57
  111. data/doc/ex/color_fill_to_border.rb +0 -29
  112. data/doc/ex/color_floodfill.rb +0 -28
  113. data/doc/ex/color_histogram.rb +0 -47
  114. data/doc/ex/color_reset.rb +0 -11
  115. data/doc/ex/colorize.rb +0 -16
  116. data/doc/ex/colors.rb +0 -64
  117. data/doc/ex/compose_mask.rb +0 -22
  118. data/doc/ex/composite.rb +0 -133
  119. data/doc/ex/composite_layers.rb +0 -52
  120. data/doc/ex/composite_tiled.rb +0 -21
  121. data/doc/ex/contrast.rb +0 -36
  122. data/doc/ex/crop.rb +0 -31
  123. data/doc/ex/crop_with_gravity.rb +0 -42
  124. data/doc/ex/cubic01.rb +0 -43
  125. data/doc/ex/cubic02.rb +0 -91
  126. data/doc/ex/cycle_colormap.rb +0 -21
  127. data/doc/ex/dissolve.rb +0 -12
  128. data/doc/ex/drawcomp.rb +0 -41
  129. data/doc/ex/drop_shadow.rb +0 -60
  130. data/doc/ex/edge.rb +0 -11
  131. data/doc/ex/ellipse.rb +0 -45
  132. data/doc/ex/ellipse01.rb +0 -21
  133. data/doc/ex/emboss.rb +0 -11
  134. data/doc/ex/enhance.rb +0 -28
  135. data/doc/ex/equalize.rb +0 -11
  136. data/doc/ex/evenodd.rb +0 -42
  137. data/doc/ex/fill_pattern.rb +0 -23
  138. data/doc/ex/flatten_images.rb +0 -36
  139. data/doc/ex/flip.rb +0 -11
  140. data/doc/ex/flop.rb +0 -11
  141. data/doc/ex/font_styles.rb +0 -32
  142. data/doc/ex/fonts.rb +0 -16
  143. data/doc/ex/frame.rb +0 -12
  144. data/doc/ex/gaussian_blur.rb +0 -11
  145. data/doc/ex/get_multiline_type_metrics.rb +0 -41
  146. data/doc/ex/get_pixels.rb +0 -45
  147. data/doc/ex/get_type_metrics.rb +0 -142
  148. data/doc/ex/gradientfill.rb +0 -27
  149. data/doc/ex/grav.rb +0 -45
  150. data/doc/ex/gravity.rb +0 -78
  151. data/doc/ex/group.rb +0 -26
  152. data/doc/ex/hatchfill.rb +0 -27
  153. data/doc/ex/image.rb +0 -44
  154. data/doc/ex/images/Apple.miff +0 -0
  155. data/doc/ex/images/Ballerina.jpg +0 -0
  156. data/doc/ex/images/Ballerina3.jpg +0 -0
  157. data/doc/ex/images/Button_0.gif +0 -0
  158. data/doc/ex/images/Button_1.gif +0 -0
  159. data/doc/ex/images/Button_2.gif +0 -0
  160. data/doc/ex/images/Button_3.gif +0 -0
  161. data/doc/ex/images/Button_4.gif +0 -0
  162. data/doc/ex/images/Button_5.gif +0 -0
  163. data/doc/ex/images/Button_6.gif +0 -0
  164. data/doc/ex/images/Button_7.gif +0 -0
  165. data/doc/ex/images/Button_8.gif +0 -0
  166. data/doc/ex/images/Button_9.gif +0 -0
  167. data/doc/ex/images/Button_A.gif +0 -0
  168. data/doc/ex/images/Button_B.gif +0 -0
  169. data/doc/ex/images/Button_C.gif +0 -0
  170. data/doc/ex/images/Button_D.gif +0 -0
  171. data/doc/ex/images/Button_E.gif +0 -0
  172. data/doc/ex/images/Button_F.gif +0 -0
  173. data/doc/ex/images/Button_G.gif +0 -0
  174. data/doc/ex/images/Button_H.gif +0 -0
  175. data/doc/ex/images/Button_I.gif +0 -0
  176. data/doc/ex/images/Button_J.gif +0 -0
  177. data/doc/ex/images/Button_K.gif +0 -0
  178. data/doc/ex/images/Button_L.gif +0 -0
  179. data/doc/ex/images/Button_M.gif +0 -0
  180. data/doc/ex/images/Button_N.gif +0 -0
  181. data/doc/ex/images/Button_O.gif +0 -0
  182. data/doc/ex/images/Button_P.gif +0 -0
  183. data/doc/ex/images/Button_Q.gif +0 -0
  184. data/doc/ex/images/Button_R.gif +0 -0
  185. data/doc/ex/images/Button_S.gif +0 -0
  186. data/doc/ex/images/Button_T.gif +0 -0
  187. data/doc/ex/images/Button_U.gif +0 -0
  188. data/doc/ex/images/Button_V.gif +0 -0
  189. data/doc/ex/images/Button_W.gif +0 -0
  190. data/doc/ex/images/Button_X.gif +0 -0
  191. data/doc/ex/images/Button_Y.gif +0 -0
  192. data/doc/ex/images/Button_Z.gif +0 -0
  193. data/doc/ex/images/Cheetah.jpg +0 -0
  194. data/doc/ex/images/Coffee.png +0 -0
  195. data/doc/ex/images/Flower_Hat.jpg +0 -0
  196. data/doc/ex/images/Gold_Statue.jpg +0 -0
  197. data/doc/ex/images/Hot_Air_Balloons.jpg +0 -0
  198. data/doc/ex/images/Hot_Air_Balloons_H.jpg +0 -0
  199. data/doc/ex/images/Leaf.miff +0 -0
  200. data/doc/ex/images/No.png +0 -0
  201. data/doc/ex/images/Polynesia.jpg +0 -0
  202. data/doc/ex/images/Red_Rocks.jpg +0 -0
  203. data/doc/ex/images/Rocks_On_Beach.miff +0 -0
  204. data/doc/ex/images/Shorts.jpg +0 -0
  205. data/doc/ex/images/Snake.png +0 -0
  206. data/doc/ex/images/Violin.jpg +0 -0
  207. data/doc/ex/images/Yellow_Rose.miff +0 -0
  208. data/doc/ex/images/big-duck.gif +0 -0
  209. data/doc/ex/images/duck.gif +0 -0
  210. data/doc/ex/images/duck0.gif +0 -0
  211. data/doc/ex/images/duck1.gif +0 -0
  212. data/doc/ex/images/duck10.gif +0 -0
  213. data/doc/ex/images/duck11.gif +0 -0
  214. data/doc/ex/images/duck12.gif +0 -0
  215. data/doc/ex/images/duck13.gif +0 -0
  216. data/doc/ex/images/duck14.gif +0 -0
  217. data/doc/ex/images/duck15.gif +0 -0
  218. data/doc/ex/images/duck2.gif +0 -0
  219. data/doc/ex/images/duck3.gif +0 -0
  220. data/doc/ex/images/duck4.gif +0 -0
  221. data/doc/ex/images/duck5.gif +0 -0
  222. data/doc/ex/images/duck6.gif +0 -0
  223. data/doc/ex/images/duck7.gif +0 -0
  224. data/doc/ex/images/duck8.gif +0 -0
  225. data/doc/ex/images/duck9.gif +0 -0
  226. data/doc/ex/images/graydient230x6.gif +0 -0
  227. data/doc/ex/images/image_with_profile.jpg +0 -0
  228. data/doc/ex/images/logo400x83.gif +0 -0
  229. data/doc/ex/images/model.miff +0 -0
  230. data/doc/ex/images/notimplemented.gif +0 -0
  231. data/doc/ex/images/smile.miff +0 -0
  232. data/doc/ex/images/spin.gif +0 -0
  233. data/doc/ex/implode.rb +0 -34
  234. data/doc/ex/level.rb +0 -11
  235. data/doc/ex/level_colors.rb +0 -11
  236. data/doc/ex/line.rb +0 -41
  237. data/doc/ex/line01.rb +0 -21
  238. data/doc/ex/mask.rb +0 -35
  239. data/doc/ex/matte_fill_to_border.rb +0 -39
  240. data/doc/ex/matte_floodfill.rb +0 -32
  241. data/doc/ex/matte_replace.rb +0 -39
  242. data/doc/ex/median_filter.rb +0 -28
  243. data/doc/ex/modulate.rb +0 -11
  244. data/doc/ex/mono.rb +0 -23
  245. data/doc/ex/morph.rb +0 -25
  246. data/doc/ex/mosaic.rb +0 -37
  247. data/doc/ex/motion_blur.rb +0 -11
  248. data/doc/ex/negate.rb +0 -11
  249. data/doc/ex/negate_channel.rb +0 -9
  250. data/doc/ex/nested_rvg.rb +0 -21
  251. data/doc/ex/nonzero.rb +0 -42
  252. data/doc/ex/normalize.rb +0 -11
  253. data/doc/ex/oil_paint.rb +0 -11
  254. data/doc/ex/opacity.rb +0 -37
  255. data/doc/ex/ordered_dither.rb +0 -11
  256. data/doc/ex/path.rb +0 -63
  257. data/doc/ex/pattern1.rb +0 -25
  258. data/doc/ex/pattern2.rb +0 -26
  259. data/doc/ex/polaroid.rb +0 -26
  260. data/doc/ex/polygon.rb +0 -23
  261. data/doc/ex/polygon01.rb +0 -21
  262. data/doc/ex/polyline.rb +0 -22
  263. data/doc/ex/polyline01.rb +0 -21
  264. data/doc/ex/posterize.rb +0 -8
  265. data/doc/ex/preview.rb +0 -8
  266. data/doc/ex/qbezierpath.rb +0 -52
  267. data/doc/ex/quad01.rb +0 -34
  268. data/doc/ex/quantize-m.rb +0 -25
  269. data/doc/ex/radial_blur.rb +0 -9
  270. data/doc/ex/raise.rb +0 -8
  271. data/doc/ex/random_threshold_channel.rb +0 -13
  272. data/doc/ex/rect01.rb +0 -14
  273. data/doc/ex/rect02.rb +0 -20
  274. data/doc/ex/rectangle.rb +0 -34
  275. data/doc/ex/reduce_noise.rb +0 -28
  276. data/doc/ex/remap.rb +0 -11
  277. data/doc/ex/remap_images.rb +0 -19
  278. data/doc/ex/resize_to_fill.rb +0 -8
  279. data/doc/ex/resize_to_fit.rb +0 -8
  280. data/doc/ex/roll.rb +0 -9
  281. data/doc/ex/rotate.rb +0 -44
  282. data/doc/ex/rotate_f.rb +0 -14
  283. data/doc/ex/roundrect.rb +0 -33
  284. data/doc/ex/rubyname.rb +0 -30
  285. data/doc/ex/rvg_clippath.rb +0 -12
  286. data/doc/ex/rvg_linecap.rb +0 -42
  287. data/doc/ex/rvg_linejoin.rb +0 -40
  288. data/doc/ex/rvg_opacity.rb +0 -18
  289. data/doc/ex/rvg_pattern.rb +0 -26
  290. data/doc/ex/rvg_stroke_dasharray.rb +0 -11
  291. data/doc/ex/segment.rb +0 -11
  292. data/doc/ex/sepiatone.rb +0 -7
  293. data/doc/ex/shade.rb +0 -11
  294. data/doc/ex/shadow.rb +0 -30
  295. data/doc/ex/shave.rb +0 -15
  296. data/doc/ex/shear.rb +0 -10
  297. data/doc/ex/sketch.rb +0 -17
  298. data/doc/ex/skewx.rb +0 -51
  299. data/doc/ex/skewy.rb +0 -47
  300. data/doc/ex/smile.rb +0 -126
  301. data/doc/ex/solarize.rb +0 -11
  302. data/doc/ex/sparse_color.rb +0 -55
  303. data/doc/ex/splice.rb +0 -8
  304. data/doc/ex/spread.rb +0 -11
  305. data/doc/ex/stegano.rb +0 -54
  306. data/doc/ex/stroke_dasharray.rb +0 -42
  307. data/doc/ex/stroke_fill.rb +0 -10
  308. data/doc/ex/stroke_linecap.rb +0 -44
  309. data/doc/ex/stroke_linejoin.rb +0 -48
  310. data/doc/ex/stroke_width.rb +0 -49
  311. data/doc/ex/swirl.rb +0 -17
  312. data/doc/ex/text.rb +0 -37
  313. data/doc/ex/text01.rb +0 -16
  314. data/doc/ex/text_align.rb +0 -36
  315. data/doc/ex/text_antialias.rb +0 -37
  316. data/doc/ex/text_styles.rb +0 -19
  317. data/doc/ex/text_undercolor.rb +0 -28
  318. data/doc/ex/texture_fill_to_border.rb +0 -34
  319. data/doc/ex/texture_floodfill.rb +0 -32
  320. data/doc/ex/texturefill.rb +0 -24
  321. data/doc/ex/threshold.rb +0 -13
  322. data/doc/ex/to_blob.rb +0 -13
  323. data/doc/ex/translate.rb +0 -39
  324. data/doc/ex/transparent.rb +0 -38
  325. data/doc/ex/transpose.rb +0 -9
  326. data/doc/ex/transverse.rb +0 -9
  327. data/doc/ex/tref01.rb +0 -24
  328. data/doc/ex/triangle01.rb +0 -15
  329. data/doc/ex/trim.rb +0 -23
  330. data/doc/ex/tspan01.rb +0 -17
  331. data/doc/ex/tspan02.rb +0 -17
  332. data/doc/ex/tspan03.rb +0 -19
  333. data/doc/ex/unsharp_mask.rb +0 -28
  334. data/doc/ex/viewex.rb +0 -33
  335. data/doc/ex/vignette.rb +0 -12
  336. data/doc/ex/watermark.rb +0 -27
  337. data/doc/ex/wave.rb +0 -9
  338. data/doc/ex/wet_floor.rb +0 -58
  339. data/doc/ex/writing_mode01.rb +0 -26
  340. data/doc/ex/writing_mode02.rb +0 -26
  341. data/doc/ilist.html +0 -2056
  342. data/doc/image1.html +0 -4680
  343. data/doc/image2.html +0 -3665
  344. data/doc/image3.html +0 -4522
  345. data/doc/imageattrs.html +0 -1638
  346. data/doc/imusage.html +0 -514
  347. data/doc/index.html +0 -416
  348. data/doc/info.html +0 -1499
  349. data/doc/magick.html +0 -570
  350. data/doc/optequiv.html +0 -2435
  351. data/doc/rvg.html +0 -975
  352. data/doc/rvgclip.html +0 -248
  353. data/doc/rvggroup.html +0 -305
  354. data/doc/rvgimage.html +0 -289
  355. data/doc/rvgpattern.html +0 -475
  356. data/doc/rvgshape.html +0 -406
  357. data/doc/rvgstyle.html +0 -270
  358. data/doc/rvgtext.html +0 -465
  359. data/doc/rvgtspan.html +0 -238
  360. data/doc/rvgtut.html +0 -530
  361. data/doc/rvguse.html +0 -145
  362. data/doc/rvgxform.html +0 -294
  363. data/doc/scripts/doc.js +0 -22
  364. data/doc/scripts/stripeTables.js +0 -23
  365. data/doc/struct.html +0 -1339
  366. data/doc/usage.html +0 -1621
  367. data/examples/constitute.rb +0 -7
  368. data/examples/crop_with_gravity.rb +0 -43
  369. data/examples/demo.rb +0 -323
  370. data/examples/describe.rb +0 -41
  371. data/examples/find_similar_region.rb +0 -34
  372. data/examples/histogram.rb +0 -312
  373. data/examples/identify.rb +0 -174
  374. data/examples/image_opacity.rb +0 -28
  375. data/examples/import_export.rb +0 -31
  376. data/examples/pattern_fill.rb +0 -37
  377. data/examples/rotating_text.rb +0 -45
  378. data/examples/spinner.rb +0 -49
  379. data/examples/thumbnail.rb +0 -64
  380. data/examples/vignette.rb +0 -78
  381. data/spec/rmagick/ImageList1_spec.rb +0 -24
  382. data/spec/rmagick/draw_spec.rb +0 -155
  383. data/spec/rmagick/image/blue_shift_spec.rb +0 -14
  384. data/spec/rmagick/image/channel_entropy_spec.rb +0 -9
  385. data/spec/rmagick/image/composite_spec.rb +0 -72
  386. data/spec/rmagick/image/constitute_spec.rb +0 -13
  387. data/spec/rmagick/image/dispatch_spec.rb +0 -16
  388. data/spec/rmagick/image/from_blob_spec.rb +0 -12
  389. data/spec/rmagick/image/ping_spec.rb +0 -12
  390. data/spec/rmagick/image/properties_spec.rb +0 -27
  391. data/spec/rmagick/image/read_spec.rb +0 -28
  392. data/spec/spec_helper.rb +0 -10
  393. data/spec/support/issue_200/app.rb +0 -8
  394. data/test/Draw.rb +0 -351
  395. data/test/Enum.rb +0 -228
  396. data/test/Fill.rb +0 -93
  397. data/test/Image1.rb +0 -606
  398. data/test/Image2.rb +0 -1408
  399. data/test/Image3.rb +0 -1086
  400. data/test/ImageList1.rb +0 -858
  401. data/test/ImageList2.rb +0 -375
  402. data/test/Image_attributes.rb +0 -635
  403. data/test/Import_Export.rb +0 -111
  404. data/test/Info.rb +0 -436
  405. data/test/KernelInfo.rb +0 -59
  406. data/test/Magick.rb +0 -311
  407. data/test/Pixel.rb +0 -259
  408. data/test/PolaroidOptions.rb +0 -23
  409. data/test/Preview.rb +0 -26
  410. data/test/Struct.rb +0 -45
  411. data/test/appearance/Montage.rb +0 -26
  412. data/test/appearance/appearance_assertion.rb +0 -13
  413. data/test/appearance/expected/montage_border_color.jpg +0 -0
  414. data/test/cmyk.icm +0 -0
  415. data/test/lib/internal/Draw.rb +0 -811
  416. data/test/lib/internal/Geometry.rb +0 -98
  417. data/test/lib/internal/Magick.rb +0 -40
  418. data/test/srgb.icm +0 -0
  419. data/test/test_all_basic.rb +0 -49
  420. data/test/tmpnam_test.rb +0 -50
data/ext/RMagick/rmdraw.c CHANGED
@@ -13,24 +13,50 @@
13
13
  #include "rmagick.h"
14
14
  #include "float.h"
15
15
 
16
- static void mark_Draw(void *);
17
- static void destroy_Draw(void *);
16
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
17
+ static void Draw_compact(void *drawptr);
18
+ #endif
19
+ static void Draw_mark(void *);
20
+ static void Draw_destroy(void *);
21
+ static size_t Draw_memsize(const void *);
18
22
  static VALUE new_DrawOptions(void);
23
+ static VALUE get_type_metrics(int, VALUE *, VALUE, gvl_function_t);
19
24
 
20
- /** Method that gets type metrics */
21
- typedef MagickBooleanType (get_type_metrics_func_t)(Image *, const DrawInfo *, TypeMetric *);
22
- static VALUE get_type_metrics(int, VALUE *, VALUE, get_type_metrics_func_t);
25
+ const rb_data_type_t rm_draw_data_type = {
26
+ "Magick::Draw",
27
+ {
28
+ Draw_mark,
29
+ Draw_destroy,
30
+ Draw_memsize,
31
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
32
+ Draw_compact,
33
+ #endif
34
+ },
35
+ 0, 0,
36
+ RUBY_TYPED_FROZEN_SHAREABLE,
37
+ };
38
+
39
+
40
+ DEFINE_GVL_STUB4(BlobToImage, const ImageInfo *, const void *, const size_t, ExceptionInfo *);
41
+ DEFINE_GVL_STUB4(ImageToBlob, const ImageInfo *, Image *, size_t *, ExceptionInfo *);
42
+ #if defined(IMAGEMAGICK_7)
43
+ DEFINE_GVL_STUB3(AnnotateImage, Image *, const DrawInfo *, ExceptionInfo *);
44
+ DEFINE_GVL_STUB3(DrawImage, Image *, const DrawInfo *, ExceptionInfo *);
45
+ DEFINE_GVL_STUB4(GetMultilineTypeMetrics, Image *, const DrawInfo *, TypeMetric *, ExceptionInfo *);
46
+ DEFINE_GVL_STUB4(GetTypeMetrics, Image *, const DrawInfo *, TypeMetric *, ExceptionInfo *);
47
+ #else
48
+ DEFINE_GVL_STUB2(AnnotateImage, Image *, const DrawInfo *);
49
+ DEFINE_GVL_STUB2(DrawImage, Image *, const DrawInfo *);
50
+ DEFINE_GVL_STUB3(GetMultilineTypeMetrics, Image *, const DrawInfo *, TypeMetric *);
51
+ DEFINE_GVL_STUB3(GetTypeMetrics, Image *, const DrawInfo *, TypeMetric *);
52
+ #endif
23
53
 
24
54
 
25
55
  /**
26
- * Set the affine matrix from an Magick::AffineMatrix.
27
- *
28
- * Ruby usage:
29
- * - @verbatim Draw#affine= @endverbatim
56
+ * Set the affine matrix from an {Magick::AffineMatrix}.
30
57
  *
31
- * @param self this object
32
- * @param matrix the affine matrix to set
33
- * @return matrix
58
+ * @param matrix [Magick::AffineMatrix] the affine matrix
59
+ * @return [Magick::AffineMatrix] the given matrix
34
60
  */
35
61
  VALUE
36
62
  Draw_affine_eq(VALUE self, VALUE matrix)
@@ -38,21 +64,17 @@ Draw_affine_eq(VALUE self, VALUE matrix)
38
64
  Draw *draw;
39
65
 
40
66
  rb_check_frozen(self);
41
- Data_Get_Struct(self, Draw, draw);
67
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
42
68
  Export_AffineMatrix(&draw->info->affine, matrix);
43
69
  return matrix;
44
70
  }
45
71
 
46
72
 
47
73
  /**
48
- * Set the text alignment.
74
+ * Set the text alignment from an {Magick::AlignType}.
49
75
  *
50
- * Ruby usage:
51
- * - @verbatim Draw#align= @endverbatim
52
- *
53
- * @param self this object
54
- * @param align the alignment
55
- * @return align
76
+ * @param align [Magick::AlignType] the text alignment
77
+ * @return [Magick::AlignType] the given align
56
78
  */
57
79
  VALUE
58
80
  Draw_align_eq(VALUE self, VALUE align)
@@ -60,21 +82,17 @@ Draw_align_eq(VALUE self, VALUE align)
60
82
  Draw *draw;
61
83
 
62
84
  rb_check_frozen(self);
63
- Data_Get_Struct(self, Draw, draw);
85
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
64
86
  VALUE_TO_ENUM(align, draw->info->align, AlignType);
65
87
  return align;
66
88
  }
67
89
 
68
90
 
69
91
  /**
70
- * Decorate attribute writer.
71
- *
72
- * Ruby usage:
73
- * - @verbatim Draw#decorate= @endverbatim
92
+ * Set text decorate from an {Magick::DecorationType}.
74
93
  *
75
- * @param self this object
76
- * @param decorate the decorate
77
- * @return decorate
94
+ * @param decorate [Magick::DecorationType] the decorate type
95
+ * @return [Magick::DecorationType] the given decorate
78
96
  */
79
97
  VALUE
80
98
  Draw_decorate_eq(VALUE self, VALUE decorate)
@@ -82,21 +100,17 @@ Draw_decorate_eq(VALUE self, VALUE decorate)
82
100
  Draw *draw;
83
101
 
84
102
  rb_check_frozen(self);
85
- Data_Get_Struct(self, Draw, draw);
103
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
86
104
  VALUE_TO_ENUM(decorate, draw->info->decorate, DecorationType);
87
105
  return decorate;
88
106
  }
89
107
 
90
108
 
91
109
  /**
92
- * Density attribute writer.
93
- *
94
- * Ruby usage:
95
- * - @verbatim Draw#density= @endverbatim
110
+ * Set density.
96
111
  *
97
- * @param self this object
98
- * @param density the density
99
- * @return density
112
+ * @param density [String] the density
113
+ * @return [String] the given density
100
114
  */
101
115
  VALUE
102
116
  Draw_density_eq(VALUE self, VALUE density)
@@ -104,22 +118,18 @@ Draw_density_eq(VALUE self, VALUE density)
104
118
  Draw *draw;
105
119
 
106
120
  rb_check_frozen(self);
107
- Data_Get_Struct(self, Draw, draw);
108
- magick_clone_string(&draw->info->density, StringValuePtr(density));
121
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
122
+ magick_clone_string(&draw->info->density, StringValueCStr(density));
109
123
 
110
124
  return density;
111
125
  }
112
126
 
113
127
 
114
128
  /**
115
- * Encoding attribute writer.
129
+ * Set text encoding.
116
130
  *
117
- * Ruby usage:
118
- * - @verbatim Draw#encoding= @endverbatim
119
- *
120
- * @param self this object
121
- * @param encoding the encoding
122
- * @return encoding
131
+ * @param encoding [String] the encoding name
132
+ * @return [String] the given encoding name
123
133
  */
124
134
  VALUE
125
135
  Draw_encoding_eq(VALUE self, VALUE encoding)
@@ -127,22 +137,18 @@ Draw_encoding_eq(VALUE self, VALUE encoding)
127
137
  Draw *draw;
128
138
 
129
139
  rb_check_frozen(self);
130
- Data_Get_Struct(self, Draw, draw);
131
- magick_clone_string(&draw->info->encoding, StringValuePtr(encoding));
140
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
141
+ magick_clone_string(&draw->info->encoding, StringValueCStr(encoding));
132
142
 
133
143
  return encoding;
134
144
  }
135
145
 
136
146
 
137
147
  /**
138
- * Fill attribute writer.
139
- *
140
- * Ruby usage:
141
- * - @verbatim Draw#fill= @endverbatim
148
+ * Set fill color.
142
149
  *
143
- * @param self this object
144
- * @param fill the fill
145
- * @return fill
150
+ * @param fill [Magick::Pixel, String] the fill color
151
+ * @return [Magick::Pixel, String] the given fill color
146
152
  */
147
153
  VALUE
148
154
  Draw_fill_eq(VALUE self, VALUE fill)
@@ -150,7 +156,7 @@ Draw_fill_eq(VALUE self, VALUE fill)
150
156
  Draw *draw;
151
157
 
152
158
  rb_check_frozen(self);
153
- Data_Get_Struct(self, Draw, draw);
159
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
154
160
  Color_to_PixelColor(&draw->info->fill, fill);
155
161
  return fill;
156
162
  }
@@ -159,23 +165,19 @@ Draw_fill_eq(VALUE self, VALUE fill)
159
165
  /**
160
166
  * Accept an image as a fill pattern.
161
167
  *
162
- * Ruby usage:
163
- * - @verbatim Draw#fill_pattern= @endverbatim
164
- *
165
- * @param self this object
166
- * @param pattern the fill pattern
167
- * @return pattern
168
- * @see Draw_stroke_pattern_eq
169
- * @see Draw_tile_eq
168
+ * @param pattern [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
169
+ * imagelist, uses the current image.
170
+ * @return [Magick::Image] the given pattern image
171
+ * @see #stroke_pattern=
172
+ * @see #tile=
170
173
  */
171
174
  VALUE
172
175
  Draw_fill_pattern_eq(VALUE self, VALUE pattern)
173
176
  {
174
177
  Draw *draw;
175
- Image *image;
176
178
 
177
179
  rb_check_frozen(self);
178
- Data_Get_Struct(self, Draw, draw);
180
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
179
181
 
180
182
  if (draw->info->fill_pattern != NULL)
181
183
  {
@@ -186,6 +188,8 @@ Draw_fill_pattern_eq(VALUE self, VALUE pattern)
186
188
 
187
189
  if (!NIL_P(pattern))
188
190
  {
191
+ Image *image;
192
+
189
193
  pattern = rm_cur_image(pattern);
190
194
  image = rm_check_destroyed(pattern);
191
195
  // Do not trace creation
@@ -197,14 +201,10 @@ Draw_fill_pattern_eq(VALUE self, VALUE pattern)
197
201
 
198
202
 
199
203
  /**
200
- * Font attribute writer.
201
- *
202
- * Ruby usage:
203
- * - @verbatim Draw#font= @endverbatim
204
+ * Set the font name.
204
205
  *
205
- * @param self this object
206
- * @param font the font
207
- * @return font
206
+ * @param font [String] the font name
207
+ * @return [String] the given font name
208
208
  */
209
209
  VALUE
210
210
  Draw_font_eq(VALUE self, VALUE font)
@@ -212,22 +212,18 @@ Draw_font_eq(VALUE self, VALUE font)
212
212
  Draw *draw;
213
213
 
214
214
  rb_check_frozen(self);
215
- Data_Get_Struct(self, Draw, draw);
216
- magick_clone_string(&draw->info->font, StringValuePtr(font));
215
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
216
+ magick_clone_string(&draw->info->font, StringValueCStr(font));
217
217
 
218
218
  return font;
219
219
  }
220
220
 
221
221
 
222
222
  /**
223
- * Font family attribute writer.
224
- *
225
- * Ruby usage:
226
- * - @verbatim Draw#family= @endverbatim
223
+ * Set the font family name.
227
224
  *
228
- * @param self this object
229
- * @param family the family
230
- * @return family
225
+ * @param family [String] the font family name
226
+ * @return [String] the given family name
231
227
  */
232
228
  VALUE
233
229
  Draw_font_family_eq(VALUE self, VALUE family)
@@ -235,22 +231,18 @@ Draw_font_family_eq(VALUE self, VALUE family)
235
231
  Draw *draw;
236
232
 
237
233
  rb_check_frozen(self);
238
- Data_Get_Struct(self, Draw, draw);
239
- magick_clone_string(&draw->info->family, StringValuePtr(family));
234
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
235
+ magick_clone_string(&draw->info->family, StringValueCStr(family));
240
236
 
241
237
  return family;
242
238
  }
243
239
 
244
240
 
245
241
  /**
246
- * Font_stretch attribute writer.
242
+ * Set the stretch as spacing between text characters.
247
243
  *
248
- * Ruby usage:
249
- * - @verbatim Draw#font_stretch= @endverbatim
250
- *
251
- * @param self this object
252
- * @param stretch the font_stretch
253
- * @return stretch
244
+ * @param stretch [Magick::StretchType] the stretch type
245
+ * @return [Magick::StretchType] the given stretch type
254
246
  */
255
247
  VALUE
256
248
  Draw_font_stretch_eq(VALUE self, VALUE stretch)
@@ -258,21 +250,17 @@ Draw_font_stretch_eq(VALUE self, VALUE stretch)
258
250
  Draw *draw;
259
251
 
260
252
  rb_check_frozen(self);
261
- Data_Get_Struct(self, Draw, draw);
253
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
262
254
  VALUE_TO_ENUM(stretch, draw->info->stretch, StretchType);
263
255
  return stretch;
264
256
  }
265
257
 
266
258
 
267
259
  /**
268
- * Font_style attribute writer.
260
+ * Set font style.
269
261
  *
270
- * Ruby usage:
271
- * - @verbatim Draw#font_style= @endverbatim
272
- *
273
- * @param self this object
274
- * @param style the font_style
275
- * @return style
262
+ * @param style [Magick::StyleType] the font style
263
+ * @return [Magick::StyleType] the given font style
276
264
  */
277
265
  VALUE
278
266
  Draw_font_style_eq(VALUE self, VALUE style)
@@ -280,25 +268,18 @@ Draw_font_style_eq(VALUE self, VALUE style)
280
268
  Draw *draw;
281
269
 
282
270
  rb_check_frozen(self);
283
- Data_Get_Struct(self, Draw, draw);
271
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
284
272
  VALUE_TO_ENUM(style, draw->info->style, StyleType);
285
273
  return style;
286
274
  }
287
275
 
288
276
 
289
277
  /**
290
- * Font_weight attribute writer.
291
- *
292
- * Ruby usage:
293
- * - @verbatim Draw#font_weight= @endverbatim
278
+ * Set font weight.
294
279
  *
295
- * Notes:
296
- * - The font weight can be one of the font weight constants or a number
297
- * between 100 and 900
298
- *
299
- * @param self this object
300
- * @param weight the font_weight
301
- * @return weight
280
+ * @param weight [Magick::WeightType, Numeric] the font weight
281
+ * @return [Magick::WeightType, Numeric] the given font weight
282
+ * @note The font weight can be one of the font weight constants or a number between 100 and 900
302
283
  */
303
284
  VALUE
304
285
  Draw_font_weight_eq(VALUE self, VALUE weight)
@@ -307,14 +288,14 @@ Draw_font_weight_eq(VALUE self, VALUE weight)
307
288
  size_t w;
308
289
 
309
290
  rb_check_frozen(self);
310
- Data_Get_Struct(self, Draw, draw);
291
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
311
292
 
312
293
  if (FIXNUM_P(weight))
313
294
  {
314
295
  w = FIX2INT(weight);
315
296
  if (w < 100 || w > 900)
316
297
  {
317
- rb_raise(rb_eArgError, "invalid font weight (%ld given)", w);
298
+ rb_raise(rb_eArgError, "invalid font weight (%"RMIuSIZE" given)", w);
318
299
  }
319
300
  draw->info->weight = w;
320
301
  }
@@ -351,27 +332,21 @@ Draw_font_weight_eq(VALUE self, VALUE weight)
351
332
 
352
333
 
353
334
  /**
354
- * Gravity attribute writer.
355
- *
356
- * Ruby usage:
357
- * - @verbatim Draw#gravity= @endverbatim
358
- *
359
- * Notes:
360
- * - From Magick++'s Image.h header file:
361
- * Gravity affects text placement in bounding area according to rules:
362
- * - NorthWestGravity text bottom-left corner placed at top-left
363
- * - NorthGravity text bottom-center placed at top-center
364
- * - NorthEastGravity text bottom-right corner placed at top-right
365
- * - WestGravity text left-center placed at left-center
366
- * - CenterGravity text center placed at center
367
- * - EastGravity text right-center placed at right-center
368
- * - SouthWestGravity text top-left placed at bottom-left
369
- * - SouthGravity text top-center placed at bottom-center
370
- * - SouthEastGravity text top-right placed at bottom-right
371
- *
372
- * @param self this object
373
- * @param grav the gravity
374
- * @return grav
335
+ * Set gravity to draw text.
336
+ * Gravity affects text placement in bounding area according to rules:
337
+ *
338
+ * - +NorthWestGravity+ - text bottom-left corner placed at top-left
339
+ * - +NorthGravity+ - text bottom-center placed at top-center
340
+ * - +NorthEastGravity+ - text bottom-right corner placed at top-right
341
+ * - +WestGravity+ - text left-center placed at left-center
342
+ * - +CenterGravity+ - text center placed at center
343
+ * - +EastGravity+ - text right-center placed at right-center
344
+ * - +SouthWestGravity+ - text top-left placed at bottom-left
345
+ * - +SouthGravity+ - text top-center placed at bottom-center
346
+ * - +SouthEastGravity+ - text top-right placed at bottom-right
347
+ *
348
+ * @param grav [Magick::GravityType] this gravity type
349
+ * @return [Magick::GravityType] the given gravity type
375
350
  */
376
351
  VALUE
377
352
  Draw_gravity_eq(VALUE self, VALUE grav)
@@ -379,7 +354,7 @@ Draw_gravity_eq(VALUE self, VALUE grav)
379
354
  Draw *draw;
380
355
 
381
356
  rb_check_frozen(self);
382
- Data_Get_Struct(self, Draw, draw);
357
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
383
358
  VALUE_TO_ENUM(grav, draw->info->gravity, GravityType);
384
359
 
385
360
  return grav;
@@ -387,17 +362,10 @@ Draw_gravity_eq(VALUE self, VALUE grav)
387
362
 
388
363
 
389
364
  /**
390
- * Space between two letters.
391
- *
392
- * Ruby usage:
393
- * - @verbatim Draw#gravity=float @endverbatim
365
+ * Set kerning as spacing between two letters.
394
366
  *
395
- * Notes:
396
- * - New for ImageMagick 6.4.7-8
397
- *
398
- * @param self this object
399
- * @param kerning the kerning
400
- * @return kerning
367
+ * @param kerning [Float] the kerning
368
+ * @return [Float] the given kerning
401
369
  */
402
370
  VALUE
403
371
  Draw_kerning_eq(VALUE self, VALUE kerning)
@@ -405,24 +373,17 @@ Draw_kerning_eq(VALUE self, VALUE kerning)
405
373
  Draw *draw;
406
374
 
407
375
  rb_check_frozen(self);
408
- Data_Get_Struct(self, Draw, draw);
376
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
409
377
  draw->info->kerning = NUM2DBL(kerning);
410
378
  return kerning;
411
379
  }
412
380
 
413
381
 
414
382
  /**
415
- * Space between two lines.
416
- *
417
- * Ruby usage:
418
- * - @verbatim Draw#interline_spacing= @endverbatim
419
- *
420
- * Notes:
421
- * - New for ImageMagick 6.5.5-8
383
+ * Set spacing between two lines.
422
384
  *
423
- * @param self this object
424
- * @param spacing the spacing
425
- * @return spacing
385
+ * @param spacing [Float] the spacing
386
+ * @return [Float] the given spacing
426
387
  */
427
388
  VALUE
428
389
  Draw_interline_spacing_eq(VALUE self, VALUE spacing)
@@ -430,24 +391,17 @@ Draw_interline_spacing_eq(VALUE self, VALUE spacing)
430
391
  Draw *draw;
431
392
 
432
393
  rb_check_frozen(self);
433
- Data_Get_Struct(self, Draw, draw);
394
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
434
395
  draw->info->interline_spacing = NUM2DBL(spacing);
435
396
  return spacing;
436
397
  }
437
398
 
438
399
 
439
400
  /**
440
- * Space between two words.
441
- *
442
- * Ruby usage:
443
- * - @verbatim Draw#interword_spacing= @endverbatim
401
+ * Set spacing between two words.
444
402
  *
445
- * Notes:
446
- * - New for ImageMagick 6.4.8-0
447
- *
448
- * @param self this object
449
- * @param spacing the spacing
450
- * @return spacing
403
+ * @param spacing [Float] the spacing
404
+ * @return [Float] the given spacing
451
405
  */
452
406
  VALUE
453
407
  Draw_interword_spacing_eq(VALUE self, VALUE spacing)
@@ -455,7 +409,7 @@ Draw_interword_spacing_eq(VALUE self, VALUE spacing)
455
409
  Draw *draw;
456
410
 
457
411
  rb_check_frozen(self);
458
- Data_Get_Struct(self, Draw, draw);
412
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
459
413
  draw->info->interword_spacing = NUM2DBL(spacing);
460
414
  return spacing;
461
415
  }
@@ -477,16 +431,18 @@ static VALUE
477
431
  image_to_str(Image *image)
478
432
  {
479
433
  VALUE dimg = Qnil;
480
- unsigned char *blob;
481
- size_t length;
482
- Info *info;
483
- ExceptionInfo *exception;
484
434
 
485
435
  if (image)
486
436
  {
437
+ unsigned char *blob;
438
+ size_t length;
439
+ Info *info;
440
+ ExceptionInfo *exception;
441
+
487
442
  info = CloneImageInfo(NULL);
488
443
  exception = AcquireExceptionInfo();
489
- blob = ImageToBlob(info, image, &length, exception);
444
+ GVL_STRUCT_TYPE(ImageToBlob) args = { info, image, &length, exception };
445
+ blob = (unsigned char *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ImageToBlob), &args);
490
446
  DestroyImageInfo(info);
491
447
  CHECK_EXCEPTION();
492
448
  DestroyExceptionInfo(exception);
@@ -516,14 +472,16 @@ static
516
472
  Image *str_to_image(VALUE str)
517
473
  {
518
474
  Image *image = NULL;
519
- Info *info;
520
- ExceptionInfo *exception;
521
475
 
522
476
  if (str != Qnil)
523
477
  {
478
+ Info *info;
479
+ ExceptionInfo *exception;
480
+
524
481
  info = CloneImageInfo(NULL);
525
482
  exception = AcquireExceptionInfo();
526
- image = BlobToImage(info, RSTRING_PTR(str), RSTRING_LEN(str), exception);
483
+ GVL_STRUCT_TYPE(BlobToImage) args = { info, RSTRING_PTR(str), RSTRING_LEN(str), exception };
484
+ image = (Image *)CALL_FUNC_WITHOUT_GVL(GVL_FUNC(BlobToImage), &args);
527
485
  DestroyImageInfo(info);
528
486
  CHECK_EXCEPTION();
529
487
  DestroyExceptionInfo(exception);
@@ -534,21 +492,16 @@ Image *str_to_image(VALUE str)
534
492
 
535
493
 
536
494
  /**
537
- * Custom marshal for Draw objects.
538
- *
539
- * Ruby usage:
540
- * - @verbatim Draw#marshal_dump @endverbatim
495
+ * Dump custom marshal for Draw objects.
541
496
  *
542
- * Notes:
543
- * - Instead of trying to replicate Ruby's support for cross-system
544
- * marshalling, exploit it. Convert the Draw fields to Ruby objects and
545
- * store them in a hash. Let Ruby marshal the hash.
546
- * - Commented out code that dumps/loads fields that are used internally by
547
- * ImageMagick and shouldn't be marshaled. I left the code as placeholders
548
- * so I'll know which fields have been deliberately omitted.
497
+ * - Instead of trying to replicate Ruby's support for cross-system
498
+ * marshalling, exploit it. Convert the Draw fields to Ruby objects and
499
+ * store them in a hash. Let Ruby marshal the hash.
500
+ * - Commented out code that dumps/loads fields that are used internally by
501
+ * ImageMagick and shouldn't be marshaled. I left the code as placeholders
502
+ * so I'll know which fields have been deliberately omitted.
549
503
  *
550
- * @param self this object
551
- * @return the marshalled object (as a Ruby hash)
504
+ * @return [Hash] the marshalled object
552
505
  * @todo Handle gradients when christy gets the new gradient support added (23Dec08)
553
506
  */
554
507
  VALUE
@@ -557,7 +510,7 @@ Draw_marshal_dump(VALUE self)
557
510
  Draw *draw;
558
511
  VALUE ddraw;
559
512
 
560
- Data_Get_Struct(self, Draw, draw);
513
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
561
514
 
562
515
  // Raise an exception if the Draw has a non-NULL gradient or element_reference field
563
516
  if (draw->info->element_reference.type != UndefinedReference
@@ -568,31 +521,17 @@ Draw_marshal_dump(VALUE self)
568
521
 
569
522
  ddraw = rb_hash_new();
570
523
 
571
- // rb_hash_aset(ddraw, CSTR2SYM("primitive"), MAGICK_STRING_TO_OBJ(draw->info->primitive)); internal
572
- // rb_hash_aset(ddraw, CSTR2SYM("geometry"), MAGICK_STRING_TO_OBJ(draw->info->geometry)); set by "text" primitive
573
- // rb_hash_aset(ddraw, CSTR2SYM("viewbox"), Import_RectangleInfo(&draw->info->viewbox)); internal
574
524
  rb_hash_aset(ddraw, CSTR2SYM("affine"), Import_AffineMatrix(&draw->info->affine));
575
525
  rb_hash_aset(ddraw, CSTR2SYM("gravity"), INT2FIX(draw->info->gravity));
576
526
  rb_hash_aset(ddraw, CSTR2SYM("fill"), Pixel_from_PixelColor(&draw->info->fill));
577
527
  rb_hash_aset(ddraw, CSTR2SYM("stroke"), Pixel_from_PixelColor(&draw->info->stroke));
578
528
  rb_hash_aset(ddraw, CSTR2SYM("stroke_width"), rb_float_new(draw->info->stroke_width));
579
- // rb_hash_aset(ddraw, CSTR2SYM("gradient"), Qnil); // not used yet
580
529
  rb_hash_aset(ddraw, CSTR2SYM("fill_pattern"), image_to_str(draw->info->fill_pattern));
581
- rb_hash_aset(ddraw, CSTR2SYM("tile"), Qnil); // deprecated
582
530
  rb_hash_aset(ddraw, CSTR2SYM("stroke_pattern"), image_to_str(draw->info->stroke_pattern));
583
531
  rb_hash_aset(ddraw, CSTR2SYM("stroke_antialias"), draw->info->stroke_antialias ? Qtrue : Qfalse);
584
532
  rb_hash_aset(ddraw, CSTR2SYM("text_antialias"), draw->info->text_antialias ? Qtrue : Qfalse);
585
- // rb_hash_aset(ddraw, CSTR2SYM("fill_rule"), INT2FIX(draw->info->fill_rule)); internal
586
- // rb_hash_aset(ddraw, CSTR2SYM("linecap"), INT2FIX(draw->info->linecap));
587
- // rb_hash_aset(ddraw, CSTR2SYM("linejoin"), INT2FIX(draw->info->linejoin));
588
- // rb_hash_aset(ddraw, CSTR2SYM("miterlimit"), ULONG2NUM(draw->info->miterlimit));
589
- // rb_hash_aset(ddraw, CSTR2SYM("dash_offset"), rb_float_new(draw->info->dash_offset));
590
533
  rb_hash_aset(ddraw, CSTR2SYM("decorate"), INT2FIX(draw->info->decorate));
591
- // rb_hash_aset(ddraw, CSTR2SYM("compose"), INT2FIX(draw->info->compose)); set via "image" primitive
592
- // rb_hash_aset(ddraw, CSTR2SYM("text"), MAGICK_STRING_TO_OBJ(draw->info->text)); set via "text" primitive
593
- // rb_hash_aset(ddraw, CSTR2SYM("face"), Qnil); internal
594
534
  rb_hash_aset(ddraw, CSTR2SYM("font"), MAGICK_STRING_TO_OBJ(draw->info->font));
595
- // rb_hash_aset(ddraw, CSTR2SYM("metrics"), Qnil); internal
596
535
  rb_hash_aset(ddraw, CSTR2SYM("family"), MAGICK_STRING_TO_OBJ(draw->info->family));
597
536
  rb_hash_aset(ddraw, CSTR2SYM("style"), INT2FIX(draw->info->style));
598
537
  rb_hash_aset(ddraw, CSTR2SYM("stretch"), INT2FIX(draw->info->stretch));
@@ -602,39 +541,27 @@ Draw_marshal_dump(VALUE self)
602
541
  rb_hash_aset(ddraw, CSTR2SYM("density"), MAGICK_STRING_TO_OBJ(draw->info->density));
603
542
  rb_hash_aset(ddraw, CSTR2SYM("align"), INT2FIX(draw->info->align));
604
543
  rb_hash_aset(ddraw, CSTR2SYM("undercolor"), Pixel_from_PixelColor(&draw->info->undercolor));
605
- // rb_hash_aset(ddraw, CSTR2SYM("border_color"), Pixel_from_PixelColor(&draw->info->border_color)); Montage and Polaroid
606
- // rb_hash_aset(ddraw, CSTR2SYM("server_name"), MAGICK_STRING_TO_OBJ(draw->info->server_name));
607
- // rb_hash_aset(ddraw, CSTR2SYM("dash_pattern"), dash_pattern_to_array(draw->info->dash_pattern)); internal
608
- // rb_hash_aset(ddraw, CSTR2SYM("clip_mask"), MAGICK_STRING_TO_OBJ(draw->info->clip_mask)); internal
609
- // rb_hash_aset(ddraw, CSTR2SYM("bounds"), Import_SegmentInfo(&draw->info->bounds)); internal
610
544
  rb_hash_aset(ddraw, CSTR2SYM("clip_units"), INT2FIX(draw->info->clip_units));
545
+ #if defined(IMAGEMAGICK_7)
546
+ rb_hash_aset(ddraw, CSTR2SYM("alpha"), QUANTUM2NUM(draw->info->alpha));
547
+ #else
611
548
  rb_hash_aset(ddraw, CSTR2SYM("opacity"), QUANTUM2NUM(draw->info->opacity));
612
- // rb_hash_aset(ddraw, CSTR2SYM("render"), draw->info->render ? Qtrue : Qfalse); internal
613
- // rb_hash_aset(ddraw, CSTR2SYM("element_reference"), Qnil); // not used yet
614
- // rb_hash_aset(ddraw, CSTR2SYM("debug"), draw->info->debug ? Qtrue : Qfalse);
549
+ #endif
615
550
  rb_hash_aset(ddraw, CSTR2SYM("kerning"), rb_float_new(draw->info->kerning));
616
551
  rb_hash_aset(ddraw, CSTR2SYM("interword_spacing"), rb_float_new(draw->info->interword_spacing));
617
552
 
618
553
  // Non-DrawInfo fields
619
554
  rb_hash_aset(ddraw, CSTR2SYM("primitives"), draw->primitives);
620
- // rb_hash_aset(ddraw, CSTR2SYM("shadow_color"), Pixel_from_PixelColor(&draw->shadow_color)); Polaroid-only
621
555
 
622
556
  return ddraw;
623
557
  }
624
558
 
625
559
 
626
560
  /**
627
- * Support Marsal.load.
628
- *
629
- * Ruby usage:
630
- * - @verbatim Draw#marshal_load @endverbatim
631
- *
632
- * Notes:
633
- * - On entry all fields are all-bits-0
561
+ * Load the marshalled object
634
562
  *
635
- * @param self this object
636
- * @param ddraw the marshalled object
637
- * @return self, once marshalled
563
+ * @param ddraw [Hash] the marshalled object
564
+ * @return [Magick::Draw] self, once marshalled
638
565
  */
639
566
  VALUE
640
567
  Draw_marshal_load(VALUE self, VALUE ddraw)
@@ -642,12 +569,17 @@ Draw_marshal_load(VALUE self, VALUE ddraw)
642
569
  Draw *draw;
643
570
  VALUE val;
644
571
 
645
- Data_Get_Struct(self, Draw, draw);
572
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
646
573
 
647
- OBJ_TO_MAGICK_STRING(draw->info->geometry, rb_hash_aref(ddraw, CSTR2SYM("geometry")));
574
+ if (draw->info == NULL)
575
+ {
576
+ ImageInfo *image_info;
648
577
 
649
- //val = rb_hash_aref(ddraw, CSTR2SYM("viewbox"));
650
- //Export_RectangleInfo(&draw->info->viewbox, val);
578
+ image_info = CloneImageInfo(NULL);
579
+ draw->info = CloneDrawInfo(image_info, (DrawInfo *) NULL);
580
+ DestroyImageInfo(image_info);
581
+ }
582
+ OBJ_TO_MAGICK_STRING(draw->info->geometry, rb_hash_aref(ddraw, CSTR2SYM("geometry")));
651
583
 
652
584
  val = rb_hash_aref(ddraw, CSTR2SYM("affine"));
653
585
  Export_AffineMatrix(&draw->info->affine, val);
@@ -681,7 +613,11 @@ Draw_marshal_load(VALUE self, VALUE ddraw)
681
613
  Color_to_PixelColor(&draw->info->undercolor, val);
682
614
 
683
615
  draw->info->clip_units = FIX2INT(rb_hash_aref(ddraw, CSTR2SYM("clip_units")));
616
+ #if defined(IMAGEMAGICK_7)
617
+ draw->info->alpha = NUM2QUANTUM(rb_hash_aref(ddraw, CSTR2SYM("alpha")));
618
+ #else
684
619
  draw->info->opacity = NUM2QUANTUM(rb_hash_aref(ddraw, CSTR2SYM("opacity")));
620
+ #endif
685
621
  draw->info->kerning = NUM2DBL(rb_hash_aref(ddraw, CSTR2SYM("kerning")));
686
622
  draw->info->interword_spacing = NUM2DBL(rb_hash_aref(ddraw, CSTR2SYM("interword_spacing")));
687
623
 
@@ -694,14 +630,10 @@ Draw_marshal_load(VALUE self, VALUE ddraw)
694
630
 
695
631
 
696
632
  /**
697
- * Pointsize attribute writer.
633
+ * Set point size to draw text.
698
634
  *
699
- * Ruby usage:
700
- * - @verbatim Draw#pointsize= @endverbatim
701
- *
702
- * @param self this object
703
- * @param pointsize the pointsize
704
- * @return pointsize
635
+ * @param pointsize [Float] the pointsize
636
+ * @return [Float] the given pointsize
705
637
  */
706
638
  VALUE
707
639
  Draw_pointsize_eq(VALUE self, VALUE pointsize)
@@ -709,26 +641,17 @@ Draw_pointsize_eq(VALUE self, VALUE pointsize)
709
641
  Draw *draw;
710
642
 
711
643
  rb_check_frozen(self);
712
- Data_Get_Struct(self, Draw, draw);
644
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
713
645
  draw->info->pointsize = NUM2DBL(pointsize);
714
646
  return pointsize;
715
647
  }
716
648
 
717
649
 
718
650
  /**
719
- * Set rotation attribute value.
720
- *
721
- * Ruby usage:
722
- * - @verbatim Magick::Draw#rotation= @endverbatim
651
+ * Set rotation. The argument should be in degrees.
723
652
  *
724
- * Notes:
725
- * - Argument should be in degrees
726
- * - Taken from Magick++'s Magick::Image::annotate method.
727
- * Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
728
- *
729
- * @param self this object
730
- * @param deg the number of degrees
731
- * @return deg
653
+ * @param deg [Float] the number of degrees
654
+ * @return [Float] the given degrees
732
655
  */
733
656
  VALUE
734
657
  Draw_rotation_eq(VALUE self, VALUE deg)
@@ -738,29 +661,24 @@ Draw_rotation_eq(VALUE self, VALUE deg)
738
661
  AffineMatrix affine, current;
739
662
 
740
663
  rb_check_frozen(self);
741
- Data_Get_Struct(self, Draw, draw);
664
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
742
665
 
743
666
  degrees = NUM2DBL(deg);
744
667
  if (fabs(degrees) > DBL_EPSILON)
745
668
  {
746
- affine.sx=1.0;
747
- affine.rx=0.0;
748
- affine.ry=0.0;
749
- affine.sy=1.0;
750
- affine.tx=0.0;
751
- affine.ty=0.0;
752
-
753
- current = draw->info->affine;
754
- affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
755
- affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
756
- affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
757
- affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
758
-
759
- draw->info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
760
- draw->info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
761
- draw->info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
762
- draw->info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
763
- draw->info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
669
+ current = draw->info->affine;
670
+ affine.sx = cos(DegreesToRadians(fmod(degrees, 360.0)));
671
+ affine.rx = sin(DegreesToRadians(fmod(degrees, 360.0)));
672
+ affine.tx = 0.0;
673
+ affine.ry = (-sin(DegreesToRadians(fmod(degrees, 360.0))));
674
+ affine.sy = cos(DegreesToRadians(fmod(degrees, 360.0)));
675
+ affine.ty = 0.0;
676
+
677
+ draw->info->affine.sx = current.sx*affine.sx+current.ry*affine.rx;
678
+ draw->info->affine.rx = current.rx*affine.sx+current.sy*affine.rx;
679
+ draw->info->affine.ry = current.sx*affine.ry+current.ry*affine.sy;
680
+ draw->info->affine.sy = current.rx*affine.ry+current.sy*affine.sy;
681
+ draw->info->affine.tx = current.sx*affine.tx+current.ry*affine.ty+current.tx;
764
682
  }
765
683
 
766
684
  return deg;
@@ -768,14 +686,10 @@ Draw_rotation_eq(VALUE self, VALUE deg)
768
686
 
769
687
 
770
688
  /**
771
- * Stroke attribute writer.
689
+ * Set stroke.
772
690
  *
773
- * Ruby usage:
774
- * - @verbatim Draw#stroke= @endverbatim
775
- *
776
- * @param self this object
777
- * @param stroke the stroke
778
- * @return stroke
691
+ * @param stroke [Magick::Pixel, String] the stroke
692
+ * @return [Magick::Pixel, String] the given stroke
779
693
  */
780
694
  VALUE
781
695
  Draw_stroke_eq(VALUE self, VALUE stroke)
@@ -783,7 +697,7 @@ Draw_stroke_eq(VALUE self, VALUE stroke)
783
697
  Draw *draw;
784
698
 
785
699
  rb_check_frozen(self);
786
- Data_Get_Struct(self, Draw, draw);
700
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
787
701
  Color_to_PixelColor(&draw->info->stroke, stroke);
788
702
  return stroke;
789
703
  }
@@ -792,22 +706,18 @@ Draw_stroke_eq(VALUE self, VALUE stroke)
792
706
  /**
793
707
  * Accept an image as a stroke pattern.
794
708
  *
795
- * Ruby usage:
796
- * - @verbatim Draw#stroke_pattern= @endverbatim
797
- *
798
- * @param self this object
799
- * @param pattern the pattern
800
- * @return pattern
801
- * @see Draw_fill_pattern_eq
709
+ * @param pattern [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
710
+ * imagelist, uses the current image.
711
+ * @return [Magick::Image] the given pattern
712
+ * @see #fill_pattern
802
713
  */
803
714
  VALUE
804
715
  Draw_stroke_pattern_eq(VALUE self, VALUE pattern)
805
716
  {
806
717
  Draw *draw;
807
- Image *image;
808
718
 
809
719
  rb_check_frozen(self);
810
- Data_Get_Struct(self, Draw, draw);
720
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
811
721
 
812
722
  if (draw->info->stroke_pattern != NULL)
813
723
  {
@@ -818,6 +728,8 @@ Draw_stroke_pattern_eq(VALUE self, VALUE pattern)
818
728
 
819
729
  if (!NIL_P(pattern))
820
730
  {
731
+ Image *image;
732
+
821
733
  // DestroyDrawInfo destroys the clone
822
734
  pattern = rm_cur_image(pattern);
823
735
  image = rm_check_destroyed(pattern);
@@ -830,14 +742,10 @@ Draw_stroke_pattern_eq(VALUE self, VALUE pattern)
830
742
 
831
743
 
832
744
  /**
833
- * Stroke_width attribute writer.
834
- *
835
- * Ruby usage:
836
- * - @verbatim Draw#stroke_width= @endverbatim
745
+ * Set stroke width.
837
746
  *
838
- * @param self this object
839
- * @param stroke_width the stroke_width
840
- * @return stroke_width
747
+ * @param stroke_width [Float] the stroke width
748
+ * @return [Float] the given stroke width
841
749
  */
842
750
  VALUE
843
751
  Draw_stroke_width_eq(VALUE self, VALUE stroke_width)
@@ -845,21 +753,17 @@ Draw_stroke_width_eq(VALUE self, VALUE stroke_width)
845
753
  Draw *draw;
846
754
 
847
755
  rb_check_frozen(self);
848
- Data_Get_Struct(self, Draw, draw);
756
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
849
757
  draw->info->stroke_width = NUM2DBL(stroke_width);
850
758
  return stroke_width;
851
759
  }
852
760
 
853
761
 
854
762
  /**
855
- * Text_antialias attribute writer.
763
+ * Set whether to enable text antialias.
856
764
  *
857
- * Ruby usage:
858
- * - @verbatim Draw#text_antialias= @endverbatim
859
- *
860
- * @param self this object
861
- * @param text_antialias the text_antialias
862
- * @return text_antialias
765
+ * @param text_antialias [Boolean] true if enable text antialias
766
+ * @return [Boolean] the given value
863
767
  */
864
768
  VALUE
865
769
  Draw_text_antialias_eq(VALUE self, VALUE text_antialias)
@@ -867,21 +771,17 @@ Draw_text_antialias_eq(VALUE self, VALUE text_antialias)
867
771
  Draw *draw;
868
772
 
869
773
  rb_check_frozen(self);
870
- Data_Get_Struct(self, Draw, draw);
774
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
871
775
  draw->info->text_antialias = (MagickBooleanType) RTEST(text_antialias);
872
776
  return text_antialias;
873
777
  }
874
778
 
875
779
 
876
780
  /**
877
- * Tile attribute writer.
878
- *
879
- * Ruby usage:
880
- * - @verbatim Draw#tile= @endverbatim
781
+ * Accept an image as a fill pattern. This is alias of {Draw#fill_pattern=}.
881
782
  *
882
- * @param self this object
883
- * @param image the image to tile
884
- * @return image
783
+ * @param image [Magick::Image] the image to tile
784
+ * @return [Magick::Image] the given image
885
785
  */
886
786
  VALUE
887
787
  Draw_tile_eq(VALUE self, VALUE image)
@@ -891,14 +791,10 @@ Draw_tile_eq(VALUE self, VALUE image)
891
791
 
892
792
 
893
793
  /**
894
- * Undercolor attribute writer.
895
- *
896
- * Ruby usage:
897
- * - @verbatim Draw#undercolor= @endverbatim
794
+ * Set undercolor.
898
795
  *
899
- * @param self this object
900
- * @param undercolor the undercolor
901
- * @return undercolor
796
+ * @param undercolor [Magick::Pixel, String] the undercolor
797
+ * @return [Magick::Pixel, String] the given undercolor
902
798
  */
903
799
  VALUE
904
800
  Draw_undercolor_eq(VALUE self, VALUE undercolor)
@@ -906,7 +802,7 @@ Draw_undercolor_eq(VALUE self, VALUE undercolor)
906
802
  Draw *draw;
907
803
 
908
804
  rb_check_frozen(self);
909
- Data_Get_Struct(self, Draw, draw);
805
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
910
806
  Color_to_PixelColor(&draw->info->undercolor, undercolor);
911
807
  return undercolor;
912
808
  }
@@ -915,21 +811,17 @@ Draw_undercolor_eq(VALUE self, VALUE undercolor)
915
811
  /**
916
812
  * Annotates an image with text.
917
813
  *
918
- * Ruby usage:
919
- * - @verbatim Draw#annotate(img, w, h, x, y, text) <{optional parms}> @endverbatim
920
- *
921
- * Notes:
922
- * - Additional Draw attribute methods may be called in the optional block,
923
- * which is executed in the context of an Draw object.
924
- *
925
- * @param self this object
926
- * @param image_arg the image
927
- * @param width_arg the width
928
- * @param height_arg the height
929
- * @param x_arg x position
930
- * @param y_arg y position
931
- * @param text the annotation text
932
- * @return self
814
+ * - Additional Draw attribute methods may be called in the optional block,
815
+ * which is executed in the context of an Draw object.
816
+ *
817
+ * @param image_arg [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
818
+ * imagelist, uses the current image.
819
+ * @param width_arg [Numeric] the width
820
+ * @param height_arg [Numeric] the height
821
+ * @param x_arg [Numeric] x position
822
+ * @param y_arg [Numeric] y position
823
+ * @param text [String] the annotation text
824
+ * @return [Magick::Draw] self
933
825
  */
934
826
  VALUE Draw_annotate(
935
827
  VALUE self,
@@ -946,10 +838,14 @@ VALUE Draw_annotate(
946
838
  long x, y;
947
839
  AffineMatrix keep;
948
840
  char geometry_str[100];
841
+ char *embed_text;
842
+ #if defined(IMAGEMAGICK_7)
843
+ ExceptionInfo *exception;
844
+ #endif
949
845
 
950
846
  // Save the affine matrix in case it is modified by
951
847
  // Draw#rotation=
952
- Data_Get_Struct(self, Draw, draw);
848
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
953
849
  keep = draw->info->affine;
954
850
 
955
851
  image_arg = rm_cur_image(image_arg);
@@ -959,13 +855,30 @@ VALUE Draw_annotate(
959
855
  // allowing the app a chance to modify the object's attributes
960
856
  if (rb_block_given_p())
961
857
  {
962
- (void)rb_obj_instance_eval(0, NULL, self);
858
+ rb_yield(self);
963
859
  }
964
860
 
965
861
  // Translate & store in Draw structure
966
- draw->info->text = InterpretImageProperties(NULL, image, StringValuePtr(text));
862
+ embed_text = StringValueCStr(text);
863
+ #if defined(IMAGEMAGICK_7)
864
+ exception = AcquireExceptionInfo();
865
+ draw->info->text = InterpretImageProperties(NULL, image, embed_text, exception);
866
+ if (rm_should_raise_exception(exception, RetainExceptionRetention))
867
+ {
868
+ if (draw->info->text)
869
+ {
870
+ magick_free(draw->info->text);
871
+ }
872
+ rm_raise_exception(exception);
873
+ }
874
+ #else
875
+ draw->info->text = InterpretImageProperties(NULL, image, embed_text);
876
+ #endif
967
877
  if (!draw->info->text)
968
878
  {
879
+ #if defined(IMAGEMAGICK_7)
880
+ DestroyExceptionInfo(exception);
881
+ #endif
969
882
  rb_raise(rb_eArgError, "no text");
970
883
  }
971
884
 
@@ -978,24 +891,34 @@ VALUE Draw_annotate(
978
891
 
979
892
  if (width == 0 && height == 0)
980
893
  {
981
- sprintf(geometry_str, "%+ld%+ld", x, y);
894
+ snprintf(geometry_str, sizeof(geometry_str), "%+ld%+ld", x, y);
982
895
  }
983
896
 
984
897
  // WxH is non-zero
985
898
  else
986
899
  {
987
- sprintf(geometry_str, "%lux%lu%+ld%+ld", width, height, x, y);
900
+ snprintf(geometry_str, sizeof(geometry_str), "%lux%lu%+ld%+ld", width, height, x, y);
988
901
  }
989
902
 
990
903
  magick_clone_string(&draw->info->geometry, geometry_str);
991
904
 
992
- (void) AnnotateImage(image, draw->info);
905
+ #if defined(IMAGEMAGICK_7)
906
+ GVL_STRUCT_TYPE(AnnotateImage) args = { image, draw->info, exception };
907
+ #else
908
+ GVL_STRUCT_TYPE(AnnotateImage) args = { image, draw->info };
909
+ #endif
910
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AnnotateImage), &args);
993
911
 
994
912
  magick_free(draw->info->text);
995
913
  draw->info->text = NULL;
996
914
  draw->info->affine = keep;
997
915
 
916
+ #if defined(IMAGEMAGICK_7)
917
+ CHECK_EXCEPTION();
918
+ DestroyExceptionInfo(exception);
919
+ #else
998
920
  rm_check_image_exception(image, RetainOnError);
921
+ #endif
999
922
 
1000
923
  return self;
1001
924
  }
@@ -1004,13 +927,7 @@ VALUE Draw_annotate(
1004
927
  /**
1005
928
  * Clones this object.
1006
929
  *
1007
- * Ruby usage:
1008
- * - @verbatim Draw#clone @endverbatim
1009
- *
1010
- * @param self this object
1011
- * @return the clone
1012
- * @see Draw_dup
1013
- * @see Draw_init_copy
930
+ * @return [Magick::Draw] the cloned object
1014
931
  */
1015
932
  VALUE
1016
933
  Draw_clone(VALUE self)
@@ -1030,21 +947,28 @@ Draw_clone(VALUE self)
1030
947
 
1031
948
 
1032
949
  /**
1033
- * Implement the "image" drawing primitive.
1034
- *
1035
- * Ruby usage:
1036
- * - @verbatim Draw#composite(x,y,width,height,img) @endverbatim
1037
- * - @verbatim Draw#composite(x,y,width,height,img,operator) @endverbatim
1038
- *
1039
- * Notes:
1040
- * - Default operator is overComposite
1041
- * - The "img" argument can be either an ImageList object or an Image
950
+ * Draw the image.
951
+ *
952
+ * @overload composite(x, y, width, height, image)
953
+ * @param x [Float] x position
954
+ * @param y [Float] y position
955
+ * @param width [Float] the width
956
+ * @param height [Float] the height
957
+ * @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
958
+ * imagelist, uses the current image.
959
+ *
960
+ * @overload composite(x, y, width, height, image, operator = Magick::OverCompositeOp)
961
+ * - The "image" argument can be either an ImageList object or an Image
1042
962
  * argument.
1043
- *
1044
- * @param argc number of input arguments
1045
- * @param argv array of input arguments
1046
- * @param self this object
1047
- * @return self
963
+ * @param x [Float] x position
964
+ * @param y [Float] y position
965
+ * @param width [Float] the width
966
+ * @param height [Float] the height
967
+ * @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
968
+ * imagelist, uses the current image.
969
+ * @param operator [Magick::CompositeOperator] the operator
970
+ *
971
+ * @return [Magick::Draw] self
1048
972
  */
1049
973
  VALUE
1050
974
  Draw_composite(int argc, VALUE *argv, VALUE self)
@@ -1086,25 +1010,25 @@ Draw_composite(int argc, VALUE *argv, VALUE self)
1086
1010
  rb_raise(rb_eArgError, "unknown composite operator (%d)", cop);
1087
1011
  }
1088
1012
 
1089
- Data_Get_Struct(self, Draw, draw);
1013
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1090
1014
 
1091
1015
  // Create a temp copy of the composite image
1092
- rm_write_temp_image(comp_img, name);
1016
+ rm_write_temp_image(comp_img, name, sizeof(name));
1093
1017
 
1094
1018
  // Add the temp filename to the filename array.
1095
1019
  // Use Magick storage since we need to keep the list around
1096
1020
  // until destroy_Draw is called.
1097
- tmpfile_name = magick_malloc(sizeof(struct TmpFile_Name)+strlen(name));
1021
+ tmpfile_name = magick_malloc(sizeof(struct TmpFile_Name) + rm_strnlen_s(name, sizeof(name)));
1098
1022
  strcpy(tmpfile_name->name, name);
1099
1023
  tmpfile_name->next = draw->tmpfile_ary;
1100
1024
  draw->tmpfile_ary = tmpfile_name;
1101
1025
 
1102
1026
  // Form the drawing primitive
1103
- (void) snprintf(primitive, sizeof(primitive), "image %s %g,%g,%g,%g '%s'", op, x, y, width, height, name);
1027
+ snprintf(primitive, sizeof(primitive), "image %s %g,%g,%g,%g '%s'", op, x, y, width, height, name);
1104
1028
 
1105
1029
 
1106
1030
  // Send "primitive" to self.
1107
- (void) rb_funcall(self, rb_intern("primitive"), 1, rb_str_new2(primitive));
1031
+ rb_funcall(self, rb_intern("primitive"), 1, rb_str_new2(primitive));
1108
1032
 
1109
1033
  RB_GC_GUARD(image);
1110
1034
 
@@ -1115,54 +1039,59 @@ Draw_composite(int argc, VALUE *argv, VALUE self)
1115
1039
  /**
1116
1040
  * Execute the stored drawing primitives on the current image.
1117
1041
  *
1118
- * Ruby usage:
1119
- * - @verbatim Draw#draw(i) @endverbatim
1120
- *
1121
- * @param self this object
1122
- * @param image_arg the image argument
1123
- * @return self
1042
+ * @param image_arg [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
1043
+ * imagelist, uses the current image.
1044
+ * @return [Magick::Draw] self
1124
1045
  */
1125
1046
  VALUE
1126
1047
  Draw_draw(VALUE self, VALUE image_arg)
1127
1048
  {
1128
1049
  Draw *draw;
1129
1050
  Image *image;
1051
+ #if defined(IMAGEMAGICK_7)
1052
+ ExceptionInfo *exception;
1053
+ #endif
1130
1054
 
1131
1055
  image_arg = rm_cur_image(image_arg);
1132
1056
  image = rm_check_frozen(image_arg);
1133
1057
 
1134
- Data_Get_Struct(self, Draw, draw);
1058
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1135
1059
  if (draw->primitives == 0)
1136
1060
  {
1137
1061
  rb_raise(rb_eArgError, "nothing to draw");
1138
1062
  }
1139
1063
 
1140
1064
  // Point the DrawInfo structure at the current set of primitives.
1141
- magick_clone_string(&(draw->info->primitive), StringValuePtr(draw->primitives));
1065
+ magick_clone_string(&(draw->info->primitive), StringValueCStr(draw->primitives));
1142
1066
 
1143
- (void) DrawImage(image, draw->info);
1144
- rm_check_image_exception(image, RetainOnError);
1067
+ #if defined(IMAGEMAGICK_7)
1068
+ exception = AcquireExceptionInfo();
1069
+ GVL_STRUCT_TYPE(DrawImage) args = { image, draw->info, exception };
1070
+ #else
1071
+ GVL_STRUCT_TYPE(DrawImage) args = { image, draw->info };
1072
+ #endif
1073
+ CALL_FUNC_WITHOUT_GVL(GVL_FUNC(DrawImage), &args);
1145
1074
 
1146
1075
  magick_free(draw->info->primitive);
1147
1076
  draw->info->primitive = NULL;
1148
1077
 
1078
+ #if defined(IMAGEMAGICK_7)
1079
+ CHECK_EXCEPTION();
1080
+ DestroyExceptionInfo(exception);
1081
+ #else
1082
+ rm_check_image_exception(image, RetainOnError);
1083
+ #endif
1084
+
1149
1085
  return self;
1150
1086
  }
1151
1087
 
1152
1088
 
1153
1089
  /**
1154
- * Copy a Draw object.
1090
+ * Duplicate a Draw object.
1155
1091
  *
1156
- * Ruby usage:
1157
- * - @verbatim Draw#dup @endverbatim
1092
+ * - Constructs a new Draw object, then calls initialize_copy.
1158
1093
  *
1159
- * Notes:
1160
- * - Constructs a new Draw object, then calls initialize_copy.
1161
- *
1162
- * @param self this object
1163
- * @return the duplicate
1164
- * @see Draw_clone
1165
- * @see Draw_init_copy
1094
+ * @return [Magick::Draw] the duplicated object
1166
1095
  */
1167
1096
  VALUE
1168
1097
  Draw_dup(VALUE self)
@@ -1172,12 +1101,7 @@ Draw_dup(VALUE self)
1172
1101
 
1173
1102
  draw = ALLOC(Draw);
1174
1103
  memset(draw, 0, sizeof(Draw));
1175
- dup = Data_Wrap_Struct(CLASS_OF(self), mark_Draw, destroy_Draw, draw);
1176
- if (rb_obj_tainted(self))
1177
- {
1178
- (void)rb_obj_taint(dup);
1179
- }
1180
-
1104
+ dup = TypedData_Wrap_Struct(CLASS_OF(self), &rm_draw_data_type, draw);
1181
1105
  RB_GC_GUARD(dup);
1182
1106
 
1183
1107
  return rb_funcall(dup, rm_ID_initialize_copy, 1, self);
@@ -1187,19 +1111,19 @@ Draw_dup(VALUE self)
1187
1111
  /**
1188
1112
  * Returns measurements for a given font and text string.
1189
1113
  *
1190
- * Ruby usage:
1191
- * - @verbatim Draw#get_type_metrics(text) @endverbatim
1192
- * - @verbatim Draw#get_type_metrics(image, text) @endverbatim
1114
+ * - If the image argument has been omitted, use a dummy image, but make sure
1115
+ * the text has none of the special characters that refer to image
1116
+ * attributes.
1193
1117
  *
1194
- * Notes:
1195
- * - If the image argument has been omitted, use a dummy image, but make sure
1196
- * the text has none of the special characters that refer to image
1197
- * attributes.
1118
+ * @overload get_type_metrics(text)
1119
+ * @param text [String] The string to be rendered.
1198
1120
  *
1199
- * @param argc number of input arguments
1200
- * @param argv array of input arguments
1201
- * @param self this object
1202
- * @return the duplicate
1121
+ * @overload get_type_metrics(image, text)
1122
+ * @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
1123
+ * imagelist, uses the current image.
1124
+ * @param text [String] The string to be rendered.
1125
+ *
1126
+ * @return [Magick::TypeMetric] The information for a specific string if rendered on a image.
1203
1127
  */
1204
1128
  VALUE
1205
1129
  Draw_get_type_metrics(
@@ -1207,26 +1131,26 @@ Draw_get_type_metrics(
1207
1131
  VALUE *argv,
1208
1132
  VALUE self)
1209
1133
  {
1210
- return get_type_metrics(argc, argv, self, GetTypeMetrics);
1134
+ return get_type_metrics(argc, argv, self, GVL_FUNC(GetTypeMetrics));
1211
1135
  }
1212
1136
 
1213
1137
 
1214
1138
  /**
1215
1139
  * Returns measurements for a given font and text string.
1216
1140
  *
1217
- * Ruby usage:
1218
- * - @verbatim Draw#get_multiline_type_metrics(text) @endverbatim
1219
- * - @verbatim Draw#get_multiline_type_metrics(image, text) @endverbatim
1141
+ * - If the image argument has been omitted, use a dummy image, but make sure
1142
+ * the text has none of the special characters that refer to image
1143
+ * attributes.
1220
1144
  *
1221
- * Notes:
1222
- * - If the image argument has been omitted, use a dummy image, but make sure
1223
- * the text has none of the special characters that refer to image
1224
- * attributes.
1145
+ * @overload get_multiline_type_metrics(text)
1146
+ * @param text [String] The string to be rendered.
1225
1147
  *
1226
- * @param argc number of input arguments
1227
- * @param argv array of input arguments
1228
- * @param self this object
1229
- * @return the duplicate
1148
+ * @overload Draw#get_multiline_type_metrics(image, text)
1149
+ * @param image [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
1150
+ * imagelist, uses the current image.
1151
+ * @param text [String] The string to be rendered.
1152
+ *
1153
+ * @return [Magick::TypeMetric] The information for a specific string if rendered on a image.
1230
1154
  */
1231
1155
  VALUE
1232
1156
  Draw_get_multiline_type_metrics(
@@ -1234,28 +1158,22 @@ Draw_get_multiline_type_metrics(
1234
1158
  VALUE *argv,
1235
1159
  VALUE self)
1236
1160
  {
1237
- return get_type_metrics(argc, argv, self, GetMultilineTypeMetrics);
1161
+ return get_type_metrics(argc, argv, self, GVL_FUNC(GetMultilineTypeMetrics));
1238
1162
  }
1239
1163
 
1240
1164
 
1241
1165
  /**
1242
1166
  * Initialize clone, dup methods.
1243
1167
  *
1244
- * Ruby usage:
1245
- * - @verbatim Draw#initialize_copy @endverbatim
1246
- *
1247
- * @param self this object
1248
1168
  * @param orig the original object
1249
- * @return self
1250
- * @see Draw_clone
1251
- * @see Draw_dup
1169
+ * @return [Magick::Draw] self
1252
1170
  */
1253
1171
  VALUE Draw_init_copy(VALUE self, VALUE orig)
1254
1172
  {
1255
1173
  Draw *copy, *original;
1256
1174
 
1257
- Data_Get_Struct(orig, Draw, original);
1258
- Data_Get_Struct(self, Draw, copy);
1175
+ TypedData_Get_Struct(orig, Draw, &rm_draw_data_type, original);
1176
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, copy);
1259
1177
 
1260
1178
  copy->info = CloneDrawInfo(NULL, original->info);
1261
1179
  if (!copy->info)
@@ -1275,11 +1193,7 @@ VALUE Draw_init_copy(VALUE self, VALUE orig)
1275
1193
  /**
1276
1194
  * Initialize Draw object.
1277
1195
  *
1278
- * Ruby usage:
1279
- * - @verbatim Draw#initialize <{ info initializers }> @endverbatim
1280
- *
1281
- * @param self this object
1282
- * @return self
1196
+ * @return [Magick::Draw] self
1283
1197
  */
1284
1198
  VALUE
1285
1199
  Draw_initialize(VALUE self)
@@ -1287,10 +1201,10 @@ Draw_initialize(VALUE self)
1287
1201
  Draw *draw, *draw_options;
1288
1202
  VALUE options;
1289
1203
 
1290
- Data_Get_Struct(self, Draw, draw);
1204
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1291
1205
 
1292
1206
  options = new_DrawOptions();
1293
- Data_Get_Struct(options, Draw, draw_options);
1207
+ TypedData_Get_Struct(options, Draw, &rm_draw_data_type, draw_options);
1294
1208
  draw->info = draw_options->info;
1295
1209
  draw_options->info = NULL;
1296
1210
 
@@ -1303,19 +1217,15 @@ Draw_initialize(VALUE self)
1303
1217
  /**
1304
1218
  * Display the primitives.
1305
1219
  *
1306
- * Ruby usage:
1307
- * - @verbatim Draw#inspect @endverbatim
1308
- *
1309
- * @param self this object
1310
- * @return the draw primitives or the Ruby string "(no primitives defined)" if
1311
- * they are not defined
1220
+ * @return [String] the draw primitives or the Ruby string "(no primitives defined)"
1221
+ * if they are not defined
1312
1222
  */
1313
1223
  VALUE
1314
1224
  Draw_inspect(VALUE self)
1315
1225
  {
1316
1226
  Draw *draw;
1317
1227
 
1318
- Data_Get_Struct(self, Draw, draw);
1228
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1319
1229
  return draw->primitives ? draw->primitives : rb_str_new2("(no primitives defined)");
1320
1230
  }
1321
1231
 
@@ -1323,13 +1233,7 @@ Draw_inspect(VALUE self)
1323
1233
  /**
1324
1234
  * Create a new Draw object.
1325
1235
  *
1326
- * Ruby usage:
1327
- * - @verbatim Draw.new @endverbatim
1328
- * - @verbatim Draw.allocate @endverbatim
1329
- *
1330
- * @param class the Ruby Draw class
1331
- * @return a new Draw object
1332
- * @throw ImageMagickError if no memory
1236
+ * @return [Magick::Draw] a new Draw object
1333
1237
  */
1334
1238
  VALUE Draw_alloc(VALUE class)
1335
1239
  {
@@ -1338,7 +1242,7 @@ VALUE Draw_alloc(VALUE class)
1338
1242
 
1339
1243
  draw = ALLOC(Draw);
1340
1244
  memset(draw, 0, sizeof(Draw));
1341
- draw_obj = Data_Wrap_Struct(class, mark_Draw, destroy_Draw, draw);
1245
+ draw_obj = TypedData_Wrap_Struct(class, &rm_draw_data_type, draw);
1342
1246
 
1343
1247
  RB_GC_GUARD(draw_obj);
1344
1248
 
@@ -1349,12 +1253,8 @@ VALUE Draw_alloc(VALUE class)
1349
1253
  /**
1350
1254
  * Add a drawing primitive to the list of primitives in the Draw object.
1351
1255
  *
1352
- * Ruby usage:
1353
- * - @verbatim Draw#primitive @endverbatim
1354
- *
1355
- * @param self this object
1356
- * @param primitive the primitive to add
1357
- * @return self
1256
+ * @param primitive [String] the primitive to add
1257
+ * @return [Magick::Draw] self
1358
1258
  */
1359
1259
  VALUE
1360
1260
  Draw_primitive(VALUE self, VALUE primitive)
@@ -1362,7 +1262,7 @@ Draw_primitive(VALUE self, VALUE primitive)
1362
1262
  Draw *draw;
1363
1263
 
1364
1264
  rb_check_frozen(self);
1365
- Data_Get_Struct(self, Draw, draw);
1265
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1366
1266
 
1367
1267
  if (draw->primitives == (VALUE)0)
1368
1268
  {
@@ -1370,13 +1270,32 @@ Draw_primitive(VALUE self, VALUE primitive)
1370
1270
  }
1371
1271
  else
1372
1272
  {
1373
- draw->primitives = rb_str_concat(draw->primitives, rb_str_new2("\n"));
1273
+ draw->primitives = rb_str_plus(draw->primitives, rb_str_new2("\n"));
1374
1274
  draw->primitives = rb_str_concat(draw->primitives, primitive);
1375
1275
  }
1376
1276
 
1377
1277
  return self;
1378
1278
  }
1379
1279
 
1280
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
1281
+ /**
1282
+ * Compact the objects.
1283
+ *
1284
+ * No Ruby usage (internal function)
1285
+ *
1286
+ * @param drawptr pointer to a Draw object
1287
+ */
1288
+ static void
1289
+ Draw_compact(void *drawptr)
1290
+ {
1291
+ Draw *draw = (Draw *)drawptr;
1292
+
1293
+ if (draw->primitives != (VALUE)0)
1294
+ {
1295
+ draw->primitives = rb_gc_location(draw->primitives);
1296
+ }
1297
+ }
1298
+ #endif
1380
1299
 
1381
1300
  /**
1382
1301
  * Mark referenced objects.
@@ -1386,13 +1305,17 @@ Draw_primitive(VALUE self, VALUE primitive)
1386
1305
  * @param drawptr pointer to a Draw object
1387
1306
  */
1388
1307
  static void
1389
- mark_Draw(void *drawptr)
1308
+ Draw_mark(void *drawptr)
1390
1309
  {
1391
1310
  Draw *draw = (Draw *)drawptr;
1392
1311
 
1393
1312
  if (draw->primitives != (VALUE)0)
1394
1313
  {
1314
+ #ifdef HAVE_RB_GC_MARK_MOVABLE
1315
+ rb_gc_mark_movable(draw->primitives);
1316
+ #else
1395
1317
  rb_gc_mark(draw->primitives);
1318
+ #endif
1396
1319
  }
1397
1320
  }
1398
1321
 
@@ -1405,20 +1328,21 @@ mark_Draw(void *drawptr)
1405
1328
  * @param drawptr pointer to a Draw object
1406
1329
  */
1407
1330
  static void
1408
- destroy_Draw(void *drawptr)
1331
+ Draw_destroy(void *drawptr)
1409
1332
  {
1410
1333
  Draw *draw = (Draw *)drawptr;
1411
- struct TmpFile_Name *tmpfile_name;
1412
1334
 
1413
1335
  if (draw->info)
1414
1336
  {
1415
- (void) DestroyDrawInfo(draw->info);
1337
+ DestroyDrawInfo(draw->info);
1416
1338
  draw->info = NULL;
1417
1339
  }
1418
1340
 
1419
1341
  // Erase any temporary image files.
1420
1342
  while (draw->tmpfile_ary)
1421
1343
  {
1344
+ struct TmpFile_Name *tmpfile_name;
1345
+
1422
1346
  tmpfile_name = draw->tmpfile_ary;
1423
1347
  draw->tmpfile_ary = draw->tmpfile_ary->next;
1424
1348
  rm_delete_temp_image(tmpfile_name->name);
@@ -1428,6 +1352,18 @@ destroy_Draw(void *drawptr)
1428
1352
  xfree(drawptr);
1429
1353
  }
1430
1354
 
1355
+ /**
1356
+ * Get Draw object size.
1357
+ *
1358
+ * No Ruby usage (internal function)
1359
+ *
1360
+ * @param infoptr pointer to the Draw object
1361
+ */
1362
+ static size_t
1363
+ Draw_memsize(const void *drawptr)
1364
+ {
1365
+ return sizeof(Draw);
1366
+ }
1431
1367
 
1432
1368
  /**
1433
1369
  * Allocate & initialize a DrawOptions object.
@@ -1446,16 +1382,10 @@ new_DrawOptions(void)
1446
1382
  /**
1447
1383
  * Create a DrawOptions object.
1448
1384
  *
1449
- * Ruby usage:
1450
- * - @verbatim DrawOptions#allocate @endverbatim
1451
- * - @verbatim DrawOptions#new @endverbatim
1452
- *
1453
- * Notes:
1454
- * - The DrawOptions class is the same as the Draw class except is has only
1455
- * the attribute writer functions
1385
+ * - The DrawOptions class is the same as the Draw class except is has only
1386
+ * the attribute writer functions
1456
1387
  *
1457
- * @param class the Ruby DrawOptions class
1458
- * @return a new DrawOptions object
1388
+ * @return [Magick::Image::DrawOptions] a new DrawOptions object
1459
1389
  */
1460
1390
  VALUE
1461
1391
  DrawOptions_alloc(VALUE class)
@@ -1465,7 +1395,7 @@ DrawOptions_alloc(VALUE class)
1465
1395
 
1466
1396
  draw_options = ALLOC(Draw);
1467
1397
  memset(draw_options, 0, sizeof(Draw));
1468
- draw_options_obj = Data_Wrap_Struct(class, mark_Draw, destroy_Draw, draw_options);
1398
+ draw_options_obj = TypedData_Wrap_Struct(class, &rm_draw_data_type, draw_options);
1469
1399
 
1470
1400
  RB_GC_GUARD(draw_options_obj);
1471
1401
 
@@ -1476,30 +1406,23 @@ DrawOptions_alloc(VALUE class)
1476
1406
  /**
1477
1407
  * Initialize a DrawOptions object.
1478
1408
  *
1479
- * Ruby usage:
1480
- * - @verbatim DrawOptions#initialize @endverbatim
1481
- *
1482
- * @param self this object
1483
- * @return self
1409
+ * @return [Magick::Image::DrawOptions] self
1484
1410
  */
1485
1411
  VALUE
1486
1412
  DrawOptions_initialize(VALUE self)
1487
1413
  {
1488
1414
  Draw *draw_options;
1489
1415
 
1490
- Data_Get_Struct(self, Draw, draw_options);
1416
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw_options);
1491
1417
  draw_options->info = AcquireDrawInfo();
1492
1418
  if (!draw_options->info)
1493
1419
  {
1494
1420
  rb_raise(rb_eNoMemError, "not enough memory to continue");
1495
1421
  }
1496
1422
 
1497
- GetDrawInfo(NULL, draw_options->info);
1498
-
1499
1423
  if (rb_block_given_p())
1500
1424
  {
1501
- // Run the block in self's context
1502
- (void) rb_obj_instance_eval(0, NULL, self);
1425
+ rb_yield(self);
1503
1426
  }
1504
1427
 
1505
1428
  return self;
@@ -1507,18 +1430,12 @@ DrawOptions_initialize(VALUE self)
1507
1430
 
1508
1431
 
1509
1432
  /**
1510
- * Allocate a new Magick::PolaroidOptions object.
1433
+ * Allocate a new Magick::Image::PolaroidOptions object.
1511
1434
  *
1512
- * Ruby usage:
1513
- * - @verbatim Magick::PolaroidOptions#allocate @endverbatim
1514
- * - @verbatim Magick::PolaroidOptions#new @endverbatim
1435
+ * - Internally a PolaroidOptions object is the same as a Draw object. The
1436
+ * methods are implemented by Draw methods in rmdraw.c.
1515
1437
  *
1516
- * Notes:
1517
- * - Internally a PolaroidOptions object is the same as a Draw object. The
1518
- * methods are implemented by Draw methods in rmdraw.c.
1519
- *
1520
- * @param class the Ruby PoloradoidOptions class
1521
- * @return a new DrawOptions object
1438
+ * @return [Magick::Image::PolaroidOptions] a new PolaroidOptions object
1522
1439
  */
1523
1440
  VALUE
1524
1441
  PolaroidOptions_alloc(VALUE class)
@@ -1532,10 +1449,10 @@ PolaroidOptions_alloc(VALUE class)
1532
1449
  draw = ALLOC(Draw);
1533
1450
  memset(draw, 0, sizeof(*draw));
1534
1451
 
1535
- draw->info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1536
- (void)(void) DestroyImageInfo(image_info);
1452
+ draw->info = CloneDrawInfo(image_info, (DrawInfo *) NULL);
1453
+ (void) DestroyImageInfo(image_info);
1537
1454
 
1538
- polaroid_obj = Data_Wrap_Struct(class, NULL, destroy_Draw, draw);
1455
+ polaroid_obj = TypedData_Wrap_Struct(class, &rm_draw_data_type, draw);
1539
1456
 
1540
1457
  RB_GC_GUARD(polaroid_obj);
1541
1458
 
@@ -1544,13 +1461,11 @@ PolaroidOptions_alloc(VALUE class)
1544
1461
 
1545
1462
 
1546
1463
  /**
1547
- * Yield to an optional block.
1548
- *
1549
- * Ruby usage:
1550
- * - @verbatim Magick::PolaroidOptions#initialize @endverbatim
1464
+ * Initialize a PolaroidOptions object.
1551
1465
  *
1552
- * @param self this object
1553
- * @return self
1466
+ * @yield [self]
1467
+ * @yieldparam self [Magick::Image::PolaroidOptions] self
1468
+ * @return [Magick::Image::PolaroidOptions] self
1554
1469
  */
1555
1470
  VALUE
1556
1471
  PolaroidOptions_initialize(VALUE self)
@@ -1559,20 +1474,20 @@ PolaroidOptions_initialize(VALUE self)
1559
1474
  ExceptionInfo *exception;
1560
1475
 
1561
1476
  // Default shadow color
1562
- Data_Get_Struct(self, Draw, draw);
1477
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1563
1478
 
1564
1479
  exception = AcquireExceptionInfo();
1565
- (void) QueryColorCompliance("gray75", AllCompliance, &draw->shadow_color, exception);
1566
- CHECK_EXCEPTION()
1567
- (void) QueryColorCompliance("#dfdfdf", AllCompliance, &draw->info->border_color, exception);
1568
- CHECK_EXCEPTION()
1480
+ QueryColorCompliance("gray75", AllCompliance, &draw->shadow_color, exception);
1481
+ CHECK_EXCEPTION();
1482
+ QueryColorCompliance("#dfdfdf", AllCompliance, &draw->info->border_color, exception);
1483
+ CHECK_EXCEPTION();
1569
1484
  DestroyExceptionInfo(exception);
1570
1485
 
1571
1486
  if (rb_block_given_p())
1572
1487
  {
1573
- // Run the block in self's context
1574
- (void) rb_obj_instance_eval(0, NULL, self);
1488
+ rb_yield(self);
1575
1489
  }
1490
+
1576
1491
  return self;
1577
1492
  }
1578
1493
 
@@ -1594,12 +1509,8 @@ rm_polaroid_new(void)
1594
1509
  /**
1595
1510
  * Set the shadow color attribute.
1596
1511
  *
1597
- * Ruby usage:
1598
- * - @verbatim PolaroidOptions#shadow_color= @endverbatim
1599
- *
1600
- * @param self this object
1601
- * @param shadow the shadow color
1602
- * @return shadow
1512
+ * @param shadow [Magick::Pixel, String] the shadow color
1513
+ * @return [Magick::Pixel, String] the given shadow color
1603
1514
  */
1604
1515
  VALUE
1605
1516
  PolaroidOptions_shadow_color_eq(VALUE self, VALUE shadow)
@@ -1607,21 +1518,17 @@ PolaroidOptions_shadow_color_eq(VALUE self, VALUE shadow)
1607
1518
  Draw *draw;
1608
1519
 
1609
1520
  rb_check_frozen(self);
1610
- Data_Get_Struct(self, Draw, draw);
1521
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1611
1522
  Color_to_PixelColor(&draw->shadow_color, shadow);
1612
1523
  return shadow;
1613
1524
  }
1614
1525
 
1615
1526
 
1616
1527
  /**
1617
- * Set the border color attribute.
1618
- *
1619
- * Ruby usage:
1620
- * - @verbatim PolaroidOptions#border_color= @endverbatim
1528
+ * Set the border color.
1621
1529
  *
1622
- * @param self this object
1623
- * @param border the border color
1624
- * @return border
1530
+ * @param border [Magick::Pixel, String] the border color
1531
+ * @return [Magick::Pixel, String] the given border color
1625
1532
  */
1626
1533
  VALUE
1627
1534
  PolaroidOptions_border_color_eq(VALUE self, VALUE border)
@@ -1629,7 +1536,7 @@ PolaroidOptions_border_color_eq(VALUE self, VALUE border)
1629
1536
  Draw *draw;
1630
1537
 
1631
1538
  rb_check_frozen(self);
1632
- Data_Get_Struct(self, Draw, draw);
1539
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1633
1540
  Color_to_PixelColor(&draw->info->border_color, border);
1634
1541
  return border;
1635
1542
  }
@@ -1648,11 +1555,11 @@ get_dummy_tm_img(VALUE klass)
1648
1555
  {
1649
1556
  #define DUMMY_IMG_CLASS_VAR "@@_dummy_img_"
1650
1557
  VALUE dummy_img = 0;
1651
- Info *info;
1652
- Image *image;
1653
1558
 
1654
1559
  if (rb_cvar_defined(klass, rb_intern(DUMMY_IMG_CLASS_VAR)) != Qtrue)
1655
1560
  {
1561
+ Info *info;
1562
+ Image *image;
1656
1563
 
1657
1564
  info = CloneImageInfo(NULL);
1658
1565
  if (!info)
@@ -1660,7 +1567,7 @@ get_dummy_tm_img(VALUE klass)
1660
1567
  rb_raise(rb_eNoMemError, "not enough memory to continue");
1661
1568
  }
1662
1569
  image = rm_acquire_image(info);
1663
- (void) DestroyImageInfo(info);
1570
+ DestroyImageInfo(info);
1664
1571
 
1665
1572
  if (!image)
1666
1573
  {
@@ -1678,6 +1585,9 @@ get_dummy_tm_img(VALUE klass)
1678
1585
  }
1679
1586
 
1680
1587
 
1588
+ // aliases for common use of structure types; GetMultilineTypeMetrics, GetTypeMetrics
1589
+ typedef GVL_STRUCT_TYPE(GetTypeMetrics) GVL_STRUCT_TYPE(get_type_metrics);
1590
+
1681
1591
  /**
1682
1592
  * Call a get-type-metrics function.
1683
1593
  *
@@ -1695,11 +1605,7 @@ get_dummy_tm_img(VALUE klass)
1695
1605
  * @see Draw_get_multiline_type_metrics
1696
1606
  */
1697
1607
  static VALUE
1698
- get_type_metrics(
1699
- int argc,
1700
- VALUE *argv,
1701
- VALUE self,
1702
- get_type_metrics_func_t getter)
1608
+ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
1703
1609
  {
1704
1610
  Image *image;
1705
1611
  Draw *draw;
@@ -1707,13 +1613,16 @@ get_type_metrics(
1707
1613
  TypeMetric metrics;
1708
1614
  char *text = NULL;
1709
1615
  long text_l;
1710
- unsigned int okay;
1616
+ MagickBooleanType okay;
1617
+ #if defined(IMAGEMAGICK_7)
1618
+ ExceptionInfo *exception;
1619
+ #endif
1711
1620
 
1712
1621
  switch (argc)
1713
1622
  {
1714
1623
  case 1: // use default image
1715
1624
  text = rm_str2cstr(argv[0], &text_l);
1716
- Data_Get_Struct(get_dummy_tm_img(CLASS_OF(self)), Image, image);
1625
+ TypedData_Get_Struct(get_dummy_tm_img(CLASS_OF(self)), Image, &rm_image_data_type, image);
1717
1626
  break;
1718
1627
  case 2:
1719
1628
  t = rm_cur_image(argv[0]);
@@ -1730,26 +1639,55 @@ get_type_metrics(
1730
1639
  rb_raise(rb_eArgError, "no text to measure");
1731
1640
  }
1732
1641
 
1733
- Data_Get_Struct(self, Draw, draw);
1642
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1643
+ #if defined(IMAGEMAGICK_7)
1644
+ exception = AcquireExceptionInfo();
1645
+ draw->info->text = InterpretImageProperties(NULL, image, text, exception);
1646
+ if (rm_should_raise_exception(exception, RetainExceptionRetention))
1647
+ {
1648
+ if (draw->info->text)
1649
+ {
1650
+ magick_free(draw->info->text);
1651
+ }
1652
+ rm_raise_exception(exception);
1653
+ }
1654
+ #else
1734
1655
  draw->info->text = InterpretImageProperties(NULL, image, text);
1656
+ #endif
1735
1657
  if (!draw->info->text)
1736
1658
  {
1659
+ #if defined(IMAGEMAGICK_7)
1660
+ DestroyExceptionInfo(exception);
1661
+ #endif
1737
1662
  rb_raise(rb_eArgError, "no text to measure");
1738
1663
  }
1739
1664
 
1740
- okay = (*getter)(image, draw->info, &metrics);
1665
+ #if defined(IMAGEMAGICK_7)
1666
+ GVL_STRUCT_TYPE(get_type_metrics) args = { image, draw->info, &metrics, exception };
1667
+ #else
1668
+ GVL_STRUCT_TYPE(get_type_metrics) args = { image, draw->info, &metrics };
1669
+ #endif
1670
+ okay = (MagickBooleanType)CALL_FUNC_WITHOUT_GVL(fp, &args);
1741
1671
 
1742
1672
  magick_free(draw->info->text);
1743
1673
  draw->info->text = NULL;
1744
1674
 
1745
1675
  if (!okay)
1746
1676
  {
1677
+ #if defined(IMAGEMAGICK_7)
1678
+ CHECK_EXCEPTION();
1679
+ DestroyExceptionInfo(exception);
1680
+ #else
1747
1681
  rm_check_image_exception(image, RetainOnError);
1682
+ #endif
1748
1683
 
1749
1684
  // Shouldn't get here...
1750
1685
  rb_raise(rb_eRuntimeError, "Can't measure text. Are the fonts installed? "
1751
1686
  "Is the FreeType library installed?");
1752
1687
  }
1688
+ #if defined(IMAGEMAGICK_7)
1689
+ DestroyExceptionInfo(exception);
1690
+ #endif
1753
1691
 
1754
1692
  RB_GC_GUARD(t);
1755
1693