rmagick-windows 2.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +14 -0
  3. data/.gitignore +23 -0
  4. data/.hound.yml +2 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +340 -0
  7. data/.simplecov +27 -0
  8. data/.travis.yml +60 -0
  9. data/CHANGELOG.md +915 -0
  10. data/CODE_OF_CONDUCT.md +13 -0
  11. data/CONTRIBUTING.md +50 -0
  12. data/Doxyfile +1514 -0
  13. data/Gemfile +10 -0
  14. data/LICENSE +20 -0
  15. data/README.textile +257 -0
  16. data/Rakefile +188 -0
  17. data/before_install_linux.sh +32 -0
  18. data/before_install_osx.sh +2 -0
  19. data/deprecated/RMagick.rb +6 -0
  20. data/doc/.cvsignore +1 -0
  21. data/doc/comtasks.html +287 -0
  22. data/doc/constants.html +1581 -0
  23. data/doc/css/doc.css +299 -0
  24. data/doc/css/popup.css +34 -0
  25. data/doc/css/ref.css +67 -0
  26. data/doc/draw.html +3272 -0
  27. data/doc/ex/InitialCoords.rb +22 -0
  28. data/doc/ex/NewCoordSys.rb +30 -0
  29. data/doc/ex/OrigCoordSys.rb +16 -0
  30. data/doc/ex/PreserveAspectRatio.rb +204 -0
  31. data/doc/ex/RotateScale.rb +36 -0
  32. data/doc/ex/Skew.rb +38 -0
  33. data/doc/ex/Use01.rb +15 -0
  34. data/doc/ex/Use02.rb +20 -0
  35. data/doc/ex/Use03.rb +16 -0
  36. data/doc/ex/ViewBox.rb +31 -0
  37. data/doc/ex/adaptive_threshold.rb +9 -0
  38. data/doc/ex/add_noise.rb +16 -0
  39. data/doc/ex/affine.rb +48 -0
  40. data/doc/ex/affine_transform.rb +20 -0
  41. data/doc/ex/arc.rb +49 -0
  42. data/doc/ex/arcpath.rb +32 -0
  43. data/doc/ex/arcs01.rb +28 -0
  44. data/doc/ex/arcs02.rb +59 -0
  45. data/doc/ex/average.rb +15 -0
  46. data/doc/ex/axes.rb +64 -0
  47. data/doc/ex/baseline_shift01.rb +17 -0
  48. data/doc/ex/bilevel_channel.rb +8 -0
  49. data/doc/ex/blur_image.rb +12 -0
  50. data/doc/ex/border.rb +10 -0
  51. data/doc/ex/bounding_box.rb +42 -0
  52. data/doc/ex/cbezier1.rb +41 -0
  53. data/doc/ex/cbezier2.rb +41 -0
  54. data/doc/ex/cbezier3.rb +41 -0
  55. data/doc/ex/cbezier4.rb +42 -0
  56. data/doc/ex/cbezier5.rb +42 -0
  57. data/doc/ex/cbezier6.rb +53 -0
  58. data/doc/ex/channel.rb +25 -0
  59. data/doc/ex/charcoal.rb +12 -0
  60. data/doc/ex/chop.rb +29 -0
  61. data/doc/ex/circle.rb +33 -0
  62. data/doc/ex/circle01.rb +16 -0
  63. data/doc/ex/clip_path.rb +60 -0
  64. data/doc/ex/coalesce.rb +57 -0
  65. data/doc/ex/color_fill_to_border.rb +29 -0
  66. data/doc/ex/color_floodfill.rb +28 -0
  67. data/doc/ex/color_histogram.rb +47 -0
  68. data/doc/ex/color_reset.rb +11 -0
  69. data/doc/ex/colorize.rb +16 -0
  70. data/doc/ex/colors.rb +64 -0
  71. data/doc/ex/compose_mask.rb +22 -0
  72. data/doc/ex/composite.rb +133 -0
  73. data/doc/ex/composite_layers.rb +53 -0
  74. data/doc/ex/composite_tiled.rb +21 -0
  75. data/doc/ex/contrast.rb +36 -0
  76. data/doc/ex/crop.rb +31 -0
  77. data/doc/ex/crop_with_gravity.rb +42 -0
  78. data/doc/ex/cubic01.rb +43 -0
  79. data/doc/ex/cubic02.rb +91 -0
  80. data/doc/ex/cycle_colormap.rb +21 -0
  81. data/doc/ex/dissolve.rb +12 -0
  82. data/doc/ex/drawcomp.rb +42 -0
  83. data/doc/ex/drop_shadow.rb +60 -0
  84. data/doc/ex/edge.rb +11 -0
  85. data/doc/ex/ellipse.rb +45 -0
  86. data/doc/ex/ellipse01.rb +21 -0
  87. data/doc/ex/emboss.rb +11 -0
  88. data/doc/ex/enhance.rb +28 -0
  89. data/doc/ex/equalize.rb +11 -0
  90. data/doc/ex/evenodd.rb +42 -0
  91. data/doc/ex/fill_pattern.rb +23 -0
  92. data/doc/ex/flatten_images.rb +36 -0
  93. data/doc/ex/flip.rb +11 -0
  94. data/doc/ex/flop.rb +11 -0
  95. data/doc/ex/font_styles.rb +32 -0
  96. data/doc/ex/fonts.rb +20 -0
  97. data/doc/ex/frame.rb +12 -0
  98. data/doc/ex/gaussian_blur.rb +11 -0
  99. data/doc/ex/get_multiline_type_metrics.rb +41 -0
  100. data/doc/ex/get_pixels.rb +47 -0
  101. data/doc/ex/get_type_metrics.rb +141 -0
  102. data/doc/ex/gradientfill.rb +27 -0
  103. data/doc/ex/grav.rb +45 -0
  104. data/doc/ex/gravity.rb +80 -0
  105. data/doc/ex/group.rb +26 -0
  106. data/doc/ex/hatchfill.rb +27 -0
  107. data/doc/ex/image.rb +44 -0
  108. data/doc/ex/images/Apple.miff +0 -0
  109. data/doc/ex/images/Ballerina.jpg +0 -0
  110. data/doc/ex/images/Ballerina3.jpg +0 -0
  111. data/doc/ex/images/Button_0.gif +0 -0
  112. data/doc/ex/images/Button_1.gif +0 -0
  113. data/doc/ex/images/Button_2.gif +0 -0
  114. data/doc/ex/images/Button_3.gif +0 -0
  115. data/doc/ex/images/Button_4.gif +0 -0
  116. data/doc/ex/images/Button_5.gif +0 -0
  117. data/doc/ex/images/Button_6.gif +0 -0
  118. data/doc/ex/images/Button_7.gif +0 -0
  119. data/doc/ex/images/Button_8.gif +0 -0
  120. data/doc/ex/images/Button_9.gif +0 -0
  121. data/doc/ex/images/Button_A.gif +0 -0
  122. data/doc/ex/images/Button_B.gif +0 -0
  123. data/doc/ex/images/Button_C.gif +0 -0
  124. data/doc/ex/images/Button_D.gif +0 -0
  125. data/doc/ex/images/Button_E.gif +0 -0
  126. data/doc/ex/images/Button_F.gif +0 -0
  127. data/doc/ex/images/Button_G.gif +0 -0
  128. data/doc/ex/images/Button_H.gif +0 -0
  129. data/doc/ex/images/Button_I.gif +0 -0
  130. data/doc/ex/images/Button_J.gif +0 -0
  131. data/doc/ex/images/Button_K.gif +0 -0
  132. data/doc/ex/images/Button_L.gif +0 -0
  133. data/doc/ex/images/Button_M.gif +0 -0
  134. data/doc/ex/images/Button_N.gif +0 -0
  135. data/doc/ex/images/Button_O.gif +0 -0
  136. data/doc/ex/images/Button_P.gif +0 -0
  137. data/doc/ex/images/Button_Q.gif +0 -0
  138. data/doc/ex/images/Button_R.gif +0 -0
  139. data/doc/ex/images/Button_S.gif +0 -0
  140. data/doc/ex/images/Button_T.gif +0 -0
  141. data/doc/ex/images/Button_U.gif +0 -0
  142. data/doc/ex/images/Button_V.gif +0 -0
  143. data/doc/ex/images/Button_W.gif +0 -0
  144. data/doc/ex/images/Button_X.gif +0 -0
  145. data/doc/ex/images/Button_Y.gif +0 -0
  146. data/doc/ex/images/Button_Z.gif +0 -0
  147. data/doc/ex/images/Cheetah.jpg +0 -0
  148. data/doc/ex/images/Coffee.wmf +0 -0
  149. data/doc/ex/images/Flower_Hat.jpg +0 -0
  150. data/doc/ex/images/Gold_Statue.jpg +0 -0
  151. data/doc/ex/images/Hot_Air_Balloons.jpg +0 -0
  152. data/doc/ex/images/Hot_Air_Balloons_H.jpg +0 -0
  153. data/doc/ex/images/Leaf.miff +0 -0
  154. data/doc/ex/images/No.wmf +0 -0
  155. data/doc/ex/images/Polynesia.jpg +0 -0
  156. data/doc/ex/images/Red_Rocks.jpg +0 -0
  157. data/doc/ex/images/Rocks_On_Beach.miff +0 -0
  158. data/doc/ex/images/Shorts.jpg +0 -0
  159. data/doc/ex/images/Snake.wmf +0 -0
  160. data/doc/ex/images/Violin.jpg +0 -0
  161. data/doc/ex/images/Yellow_Rose.miff +0 -0
  162. data/doc/ex/images/big-duck.gif +0 -0
  163. data/doc/ex/images/duck.gif +0 -0
  164. data/doc/ex/images/duck0.gif +0 -0
  165. data/doc/ex/images/duck1.gif +0 -0
  166. data/doc/ex/images/duck10.gif +0 -0
  167. data/doc/ex/images/duck11.gif +0 -0
  168. data/doc/ex/images/duck12.gif +0 -0
  169. data/doc/ex/images/duck13.gif +0 -0
  170. data/doc/ex/images/duck14.gif +0 -0
  171. data/doc/ex/images/duck15.gif +0 -0
  172. data/doc/ex/images/duck2.gif +0 -0
  173. data/doc/ex/images/duck3.gif +0 -0
  174. data/doc/ex/images/duck4.gif +0 -0
  175. data/doc/ex/images/duck5.gif +0 -0
  176. data/doc/ex/images/duck6.gif +0 -0
  177. data/doc/ex/images/duck7.gif +0 -0
  178. data/doc/ex/images/duck8.gif +0 -0
  179. data/doc/ex/images/duck9.gif +0 -0
  180. data/doc/ex/images/graydient230x6.gif +0 -0
  181. data/doc/ex/images/image_with_profile.jpg +0 -0
  182. data/doc/ex/images/logo400x83.gif +0 -0
  183. data/doc/ex/images/model.miff +0 -0
  184. data/doc/ex/images/notimplemented.gif +0 -0
  185. data/doc/ex/images/smile.miff +0 -0
  186. data/doc/ex/images/spin.gif +0 -0
  187. data/doc/ex/implode.rb +34 -0
  188. data/doc/ex/level.rb +11 -0
  189. data/doc/ex/level_colors.rb +11 -0
  190. data/doc/ex/line.rb +41 -0
  191. data/doc/ex/line01.rb +21 -0
  192. data/doc/ex/mask.rb +35 -0
  193. data/doc/ex/matte_fill_to_border.rb +39 -0
  194. data/doc/ex/matte_floodfill.rb +32 -0
  195. data/doc/ex/matte_replace.rb +39 -0
  196. data/doc/ex/median_filter.rb +28 -0
  197. data/doc/ex/modulate.rb +11 -0
  198. data/doc/ex/mono.rb +23 -0
  199. data/doc/ex/morph.rb +25 -0
  200. data/doc/ex/mosaic.rb +35 -0
  201. data/doc/ex/motion_blur.rb +11 -0
  202. data/doc/ex/negate.rb +11 -0
  203. data/doc/ex/negate_channel.rb +9 -0
  204. data/doc/ex/nested_rvg.rb +21 -0
  205. data/doc/ex/nonzero.rb +42 -0
  206. data/doc/ex/normalize.rb +11 -0
  207. data/doc/ex/oil_paint.rb +11 -0
  208. data/doc/ex/opacity.rb +37 -0
  209. data/doc/ex/ordered_dither.rb +11 -0
  210. data/doc/ex/path.rb +63 -0
  211. data/doc/ex/pattern1.rb +25 -0
  212. data/doc/ex/pattern2.rb +26 -0
  213. data/doc/ex/polaroid.rb +27 -0
  214. data/doc/ex/polygon.rb +23 -0
  215. data/doc/ex/polygon01.rb +21 -0
  216. data/doc/ex/polyline.rb +22 -0
  217. data/doc/ex/polyline01.rb +21 -0
  218. data/doc/ex/posterize.rb +8 -0
  219. data/doc/ex/preview.rb +8 -0
  220. data/doc/ex/qbezierpath.rb +52 -0
  221. data/doc/ex/quad01.rb +34 -0
  222. data/doc/ex/quantize-m.rb +25 -0
  223. data/doc/ex/radial_blur.rb +9 -0
  224. data/doc/ex/raise.rb +8 -0
  225. data/doc/ex/random_threshold_channel.rb +13 -0
  226. data/doc/ex/rect01.rb +14 -0
  227. data/doc/ex/rect02.rb +20 -0
  228. data/doc/ex/rectangle.rb +34 -0
  229. data/doc/ex/reduce_noise.rb +28 -0
  230. data/doc/ex/remap.rb +11 -0
  231. data/doc/ex/remap_images.rb +19 -0
  232. data/doc/ex/resize_to_fill.rb +8 -0
  233. data/doc/ex/resize_to_fit.rb +8 -0
  234. data/doc/ex/roll.rb +9 -0
  235. data/doc/ex/rotate.rb +44 -0
  236. data/doc/ex/rotate_f.rb +14 -0
  237. data/doc/ex/roundrect.rb +33 -0
  238. data/doc/ex/rubyname.rb +30 -0
  239. data/doc/ex/rvg_clippath.rb +12 -0
  240. data/doc/ex/rvg_linecap.rb +42 -0
  241. data/doc/ex/rvg_linejoin.rb +40 -0
  242. data/doc/ex/rvg_opacity.rb +18 -0
  243. data/doc/ex/rvg_pattern.rb +26 -0
  244. data/doc/ex/rvg_stroke_dasharray.rb +11 -0
  245. data/doc/ex/segment.rb +11 -0
  246. data/doc/ex/sepiatone.rb +7 -0
  247. data/doc/ex/shade.rb +11 -0
  248. data/doc/ex/shadow.rb +30 -0
  249. data/doc/ex/shave.rb +15 -0
  250. data/doc/ex/shear.rb +10 -0
  251. data/doc/ex/sketch.rb +17 -0
  252. data/doc/ex/skewx.rb +51 -0
  253. data/doc/ex/skewy.rb +47 -0
  254. data/doc/ex/smile.rb +125 -0
  255. data/doc/ex/solarize.rb +11 -0
  256. data/doc/ex/sparse_color.rb +54 -0
  257. data/doc/ex/splice.rb +8 -0
  258. data/doc/ex/spread.rb +11 -0
  259. data/doc/ex/stegano.rb +55 -0
  260. data/doc/ex/stroke_dasharray.rb +42 -0
  261. data/doc/ex/stroke_fill.rb +10 -0
  262. data/doc/ex/stroke_linecap.rb +44 -0
  263. data/doc/ex/stroke_linejoin.rb +48 -0
  264. data/doc/ex/stroke_width.rb +49 -0
  265. data/doc/ex/swirl.rb +17 -0
  266. data/doc/ex/text.rb +37 -0
  267. data/doc/ex/text01.rb +16 -0
  268. data/doc/ex/text_align.rb +36 -0
  269. data/doc/ex/text_antialias.rb +37 -0
  270. data/doc/ex/text_styles.rb +19 -0
  271. data/doc/ex/text_undercolor.rb +28 -0
  272. data/doc/ex/texture_fill_to_border.rb +34 -0
  273. data/doc/ex/texture_floodfill.rb +32 -0
  274. data/doc/ex/texturefill.rb +24 -0
  275. data/doc/ex/threshold.rb +13 -0
  276. data/doc/ex/to_blob.rb +13 -0
  277. data/doc/ex/translate.rb +39 -0
  278. data/doc/ex/transparent.rb +38 -0
  279. data/doc/ex/transpose.rb +9 -0
  280. data/doc/ex/transverse.rb +9 -0
  281. data/doc/ex/tref01.rb +24 -0
  282. data/doc/ex/triangle01.rb +15 -0
  283. data/doc/ex/trim.rb +23 -0
  284. data/doc/ex/tspan01.rb +17 -0
  285. data/doc/ex/tspan02.rb +17 -0
  286. data/doc/ex/tspan03.rb +19 -0
  287. data/doc/ex/unsharp_mask.rb +28 -0
  288. data/doc/ex/viewex.rb +33 -0
  289. data/doc/ex/vignette.rb +12 -0
  290. data/doc/ex/watermark.rb +27 -0
  291. data/doc/ex/wave.rb +9 -0
  292. data/doc/ex/wet_floor.rb +58 -0
  293. data/doc/ex/writing_mode01.rb +26 -0
  294. data/doc/ex/writing_mode02.rb +26 -0
  295. data/doc/ilist.html +2056 -0
  296. data/doc/image1.html +4680 -0
  297. data/doc/image2.html +3665 -0
  298. data/doc/image3.html +4522 -0
  299. data/doc/imageattrs.html +1638 -0
  300. data/doc/imusage.html +514 -0
  301. data/doc/index.html +416 -0
  302. data/doc/info.html +1499 -0
  303. data/doc/magick.html +565 -0
  304. data/doc/optequiv.html +2435 -0
  305. data/doc/rvg.html +975 -0
  306. data/doc/rvgclip.html +248 -0
  307. data/doc/rvggroup.html +305 -0
  308. data/doc/rvgimage.html +289 -0
  309. data/doc/rvgpattern.html +475 -0
  310. data/doc/rvgshape.html +406 -0
  311. data/doc/rvgstyle.html +270 -0
  312. data/doc/rvgtext.html +465 -0
  313. data/doc/rvgtspan.html +238 -0
  314. data/doc/rvgtut.html +530 -0
  315. data/doc/rvguse.html +145 -0
  316. data/doc/rvgxform.html +294 -0
  317. data/doc/scripts/doc.js +22 -0
  318. data/doc/scripts/stripeTables.js +23 -0
  319. data/doc/struct.html +1339 -0
  320. data/doc/usage.html +1621 -0
  321. data/examples/constitute.rb +7 -0
  322. data/examples/crop_with_gravity.rb +42 -0
  323. data/examples/demo.rb +324 -0
  324. data/examples/describe.rb +43 -0
  325. data/examples/find_similar_region.rb +34 -0
  326. data/examples/histogram.rb +321 -0
  327. data/examples/identify.rb +185 -0
  328. data/examples/image_opacity.rb +29 -0
  329. data/examples/import_export.rb +31 -0
  330. data/examples/pattern_fill.rb +38 -0
  331. data/examples/rotating_text.rb +44 -0
  332. data/examples/spinner.rb +49 -0
  333. data/examples/thumbnail.rb +64 -0
  334. data/examples/vignette.rb +78 -0
  335. data/ext/RMagick/extconf.rb +548 -0
  336. data/ext/RMagick/rmagick.c +401 -0
  337. data/ext/RMagick/rmagick.h +1287 -0
  338. data/ext/RMagick/rmdraw.c +2022 -0
  339. data/ext/RMagick/rmenum.c +1235 -0
  340. data/ext/RMagick/rmfill.c +720 -0
  341. data/ext/RMagick/rmilist.c +1270 -0
  342. data/ext/RMagick/rmimage.c +15427 -0
  343. data/ext/RMagick/rminfo.c +2590 -0
  344. data/ext/RMagick/rmmain.c +1741 -0
  345. data/ext/RMagick/rmmontage.c +519 -0
  346. data/ext/RMagick/rmpixel.c +1114 -0
  347. data/ext/RMagick/rmstruct.c +1124 -0
  348. data/ext/RMagick/rmutil.c +1754 -0
  349. data/lib/rmagick.rb +1 -0
  350. data/lib/rmagick/version.rb +6 -0
  351. data/lib/rmagick_internal.rb +1947 -0
  352. data/lib/rvg/clippath.rb +45 -0
  353. data/lib/rvg/container.rb +122 -0
  354. data/lib/rvg/deep_equal.rb +52 -0
  355. data/lib/rvg/describable.rb +47 -0
  356. data/lib/rvg/embellishable.rb +391 -0
  357. data/lib/rvg/misc.rb +723 -0
  358. data/lib/rvg/paint.rb +50 -0
  359. data/lib/rvg/pathdata.rb +126 -0
  360. data/lib/rvg/rvg.rb +283 -0
  361. data/lib/rvg/stretchable.rb +165 -0
  362. data/lib/rvg/stylable.rb +116 -0
  363. data/lib/rvg/text.rb +172 -0
  364. data/lib/rvg/transformable.rb +126 -0
  365. data/lib/rvg/units.rb +63 -0
  366. data/rmagick.gemspec +46 -0
  367. data/spec/rmagick/ImageList1_spec.rb +24 -0
  368. data/spec/rmagick/draw_spec.rb +156 -0
  369. data/spec/rmagick/image/blue_shift_spec.rb +16 -0
  370. data/spec/rmagick/image/composite_spec.rb +140 -0
  371. data/spec/rmagick/image/constitute_spec.rb +15 -0
  372. data/spec/rmagick/image/dispatch_spec.rb +18 -0
  373. data/spec/rmagick/image/from_blob_spec.rb +14 -0
  374. data/spec/rmagick/image/ping_spec.rb +14 -0
  375. data/spec/rmagick/image/properties_spec.rb +29 -0
  376. data/spec/spec_helper.rb +4 -0
  377. data/test/Image1.rb +565 -0
  378. data/test/Image2.rb +1304 -0
  379. data/test/Image3.rb +1030 -0
  380. data/test/ImageList1.rb +806 -0
  381. data/test/ImageList2.rb +385 -0
  382. data/test/Image_attributes.rb +697 -0
  383. data/test/Import_Export.rb +121 -0
  384. data/test/Info.rb +345 -0
  385. data/test/Magick.rb +321 -0
  386. data/test/Pixel.rb +116 -0
  387. data/test/Preview.rb +57 -0
  388. data/test/cmyk.icm +0 -0
  389. data/test/srgb.icm +0 -0
  390. data/test/test_all_basic.rb +38 -0
  391. data/test/tmpnam_test.rb +50 -0
  392. data/wercker.yml +10 -0
  393. metadata +509 -0
@@ -0,0 +1,2022 @@
1
+ /**************************************************************************//**
2
+ * Contains Draw class methods.
3
+ *
4
+ * Copyright © 2002 - 2009 by Timothy P. Hunter
5
+ *
6
+ * Changes since Nov. 2009 copyright © by Benjamin Thomas and Omer Bar-or
7
+ *
8
+ * @file rmdraw.c
9
+ * @version $Id: rmdraw.c,v 1.83 2009/12/20 02:33:33 baror Exp $
10
+ * @author Tim Hunter
11
+ ******************************************************************************/
12
+
13
+ #include "rmagick.h"
14
+ #include "float.h"
15
+
16
+ static void mark_Draw(void *);
17
+ static void destroy_Draw(void *);
18
+ static VALUE new_DrawOptions(void);
19
+
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);
23
+
24
+
25
+ /**
26
+ * Set the affine matrix from an Magick::AffineMatrix.
27
+ *
28
+ * Ruby usage:
29
+ * - @verbatim Draw#affine= @endverbatim
30
+ *
31
+ * @param self this object
32
+ * @param matrix the affine matrix to set
33
+ * @return self
34
+ */
35
+ VALUE
36
+ Draw_affine_eq(VALUE self, VALUE matrix)
37
+ {
38
+ Draw *draw;
39
+
40
+ rb_check_frozen(self);
41
+ Data_Get_Struct(self, Draw, draw);
42
+ Export_AffineMatrix(&draw->info->affine, matrix);
43
+ return self;
44
+ }
45
+
46
+
47
+ /**
48
+ * Set the text alignment.
49
+ *
50
+ * Ruby usage:
51
+ * - @verbatim Draw#align= @endverbatim
52
+ *
53
+ * @param self this object
54
+ * @param align the alignment
55
+ * @return self
56
+ */
57
+ VALUE
58
+ Draw_align_eq(VALUE self, VALUE align)
59
+ {
60
+ Draw *draw;
61
+
62
+ rb_check_frozen(self);
63
+ Data_Get_Struct(self, Draw, draw);
64
+ VALUE_TO_ENUM(align, draw->info->align, AlignType);
65
+ return self;
66
+ }
67
+
68
+
69
+ /**
70
+ * Decorate attribute writer.
71
+ *
72
+ * Ruby usage:
73
+ * - @verbatim Draw#decorate= @endverbatim
74
+ *
75
+ * @param self this object
76
+ * @param decorate the decorate
77
+ * @return self
78
+ */
79
+ VALUE
80
+ Draw_decorate_eq(VALUE self, VALUE decorate)
81
+ {
82
+ Draw *draw;
83
+
84
+ rb_check_frozen(self);
85
+ Data_Get_Struct(self, Draw, draw);
86
+ VALUE_TO_ENUM(decorate, draw->info->decorate, DecorationType);
87
+ return self;
88
+ }
89
+
90
+
91
+ /**
92
+ * Density attribute writer.
93
+ *
94
+ * Ruby usage:
95
+ * - @verbatim Draw#density= @endverbatim
96
+ *
97
+ * @param self this object
98
+ * @param density the density
99
+ * @return self
100
+ */
101
+ VALUE
102
+ Draw_density_eq(VALUE self, VALUE density)
103
+ {
104
+ Draw *draw;
105
+
106
+ rb_check_frozen(self);
107
+ Data_Get_Struct(self, Draw, draw);
108
+ magick_clone_string(&draw->info->density, StringValuePtr(density));
109
+
110
+ return self;
111
+ }
112
+
113
+
114
+ /**
115
+ * Encoding attribute writer.
116
+ *
117
+ * Ruby usage:
118
+ * - @verbatim Draw#encoding= @endverbatim
119
+ *
120
+ * @param self this object
121
+ * @param encoding the encoding
122
+ * @return self
123
+ */
124
+ VALUE
125
+ Draw_encoding_eq(VALUE self, VALUE encoding)
126
+ {
127
+ Draw *draw;
128
+
129
+ rb_check_frozen(self);
130
+ Data_Get_Struct(self, Draw, draw);
131
+ magick_clone_string(&draw->info->encoding, StringValuePtr(encoding));
132
+
133
+ return self;
134
+ }
135
+
136
+
137
+ /**
138
+ * Fill attribute writer.
139
+ *
140
+ * Ruby usage:
141
+ * - @verbatim Draw#fill= @endverbatim
142
+ *
143
+ * @param self this object
144
+ * @param fill the fill
145
+ * @return self
146
+ */
147
+ VALUE
148
+ Draw_fill_eq(VALUE self, VALUE fill)
149
+ {
150
+ Draw *draw;
151
+
152
+ rb_check_frozen(self);
153
+ Data_Get_Struct(self, Draw, draw);
154
+ Color_to_PixelPacket(&draw->info->fill, fill);
155
+ return self;
156
+ }
157
+
158
+
159
+ /**
160
+ * Accept an image as a fill pattern.
161
+ *
162
+ * Ruby usage:
163
+ * - @verbatim Draw#fill_pattern= @endverbatim
164
+ *
165
+ * @param self this object
166
+ * @param pattern the fill pattern
167
+ * @return self
168
+ * @see Draw_stroke_pattern_eq
169
+ * @see Draw_tile_eq
170
+ */
171
+ VALUE
172
+ Draw_fill_pattern_eq(VALUE self, VALUE pattern)
173
+ {
174
+ Draw *draw;
175
+ Image *image;
176
+
177
+ rb_check_frozen(self);
178
+ Data_Get_Struct(self, Draw, draw);
179
+
180
+ if (draw->info->fill_pattern != NULL)
181
+ {
182
+ // Do not trace destruction
183
+ DestroyImage(draw->info->fill_pattern);
184
+ draw->info->fill_pattern = NULL;
185
+ }
186
+
187
+ if (!NIL_P(pattern))
188
+ {
189
+ pattern = rm_cur_image(pattern);
190
+ image = rm_check_destroyed(pattern);
191
+ // Do not trace creation
192
+ draw->info->fill_pattern = rm_clone_image(image);
193
+ }
194
+
195
+ return self;
196
+ }
197
+
198
+
199
+ /**
200
+ * Font attribute writer.
201
+ *
202
+ * Ruby usage:
203
+ * - @verbatim Draw#font= @endverbatim
204
+ *
205
+ * @param self this object
206
+ * @param font the font
207
+ * @return self
208
+ */
209
+ VALUE
210
+ Draw_font_eq(VALUE self, VALUE font)
211
+ {
212
+ Draw *draw;
213
+
214
+ rb_check_frozen(self);
215
+ Data_Get_Struct(self, Draw, draw);
216
+ magick_clone_string(&draw->info->font, StringValuePtr(font));
217
+
218
+ return self;
219
+ }
220
+
221
+
222
+ /**
223
+ * Font family attribute writer.
224
+ *
225
+ * Ruby usage:
226
+ * - @verbatim Draw#family= @endverbatim
227
+ *
228
+ * @param self this object
229
+ * @param family the family
230
+ * @return self
231
+ */
232
+ VALUE
233
+ Draw_font_family_eq(VALUE self, VALUE family)
234
+ {
235
+ Draw *draw;
236
+
237
+ rb_check_frozen(self);
238
+ Data_Get_Struct(self, Draw, draw);
239
+ magick_clone_string(&draw->info->family, StringValuePtr(family));
240
+
241
+ return self;
242
+ }
243
+
244
+
245
+ /**
246
+ * Font_stretch attribute writer.
247
+ *
248
+ * Ruby usage:
249
+ * - @verbatim Draw#font_stretch= @endverbatim
250
+ *
251
+ * @param self this object
252
+ * @param stretch the font_stretch
253
+ * @return self
254
+ */
255
+ VALUE
256
+ Draw_font_stretch_eq(VALUE self, VALUE stretch)
257
+ {
258
+ Draw *draw;
259
+
260
+ rb_check_frozen(self);
261
+ Data_Get_Struct(self, Draw, draw);
262
+ VALUE_TO_ENUM(stretch, draw->info->stretch, StretchType);
263
+ return self;
264
+ }
265
+
266
+
267
+ /**
268
+ * Font_style attribute writer.
269
+ *
270
+ * Ruby usage:
271
+ * - @verbatim Draw#font_style= @endverbatim
272
+ *
273
+ * @param self this object
274
+ * @param style the font_style
275
+ * @return self
276
+ */
277
+ VALUE
278
+ Draw_font_style_eq(VALUE self, VALUE style)
279
+ {
280
+ Draw *draw;
281
+
282
+ rb_check_frozen(self);
283
+ Data_Get_Struct(self, Draw, draw);
284
+ VALUE_TO_ENUM(style, draw->info->style, StyleType);
285
+ return self;
286
+ }
287
+
288
+
289
+ /**
290
+ * Font_weight attribute writer.
291
+ *
292
+ * Ruby usage:
293
+ * - @verbatim Draw#font_weight= @endverbatim
294
+ *
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 self
302
+ */
303
+ VALUE
304
+ Draw_font_weight_eq(VALUE self, VALUE weight)
305
+ {
306
+ Draw *draw;
307
+ WeightType w;
308
+
309
+ rb_check_frozen(self);
310
+ Data_Get_Struct(self, Draw, draw);
311
+
312
+ if (FIXNUM_P(weight))
313
+ {
314
+ w = (WeightType) FIX2INT(weight);
315
+ if (w < 100 || w > 900)
316
+ {
317
+ rb_raise(rb_eArgError, "invalid font weight (%d given)", w);
318
+ }
319
+ draw->info->weight = w;
320
+ }
321
+ else
322
+ {
323
+ VALUE_TO_ENUM(weight, w, WeightType);
324
+ switch (w)
325
+ {
326
+ case AnyWeight:
327
+ draw->info->weight = 0;
328
+ break;
329
+ case NormalWeight:
330
+ draw->info->weight = 400;
331
+ break;
332
+ case BoldWeight:
333
+ draw->info->weight = 700;
334
+ break;
335
+ case BolderWeight:
336
+ if (draw->info->weight <= 800)
337
+ draw->info->weight += 100;
338
+ break;
339
+ case LighterWeight:
340
+ if (draw->info->weight >= 100)
341
+ draw->info->weight -= 100;
342
+ break;
343
+ default:
344
+ rb_raise(rb_eArgError, "unknown font weight");
345
+ break;
346
+ }
347
+ }
348
+
349
+ return self;
350
+ }
351
+
352
+
353
+ /**
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 self
375
+ */
376
+ VALUE
377
+ Draw_gravity_eq(VALUE self, VALUE grav)
378
+ {
379
+ Draw *draw;
380
+
381
+ rb_check_frozen(self);
382
+ Data_Get_Struct(self, Draw, draw);
383
+ VALUE_TO_ENUM(grav, draw->info->gravity, GravityType);
384
+
385
+ return self;
386
+ }
387
+
388
+
389
+ /**
390
+ * Space between two letters.
391
+ *
392
+ * Ruby usage:
393
+ * - @verbatim Draw#gravity=float @endverbatim
394
+ *
395
+ * Notes:
396
+ * - New for ImageMagick 6.4.7-8
397
+ *
398
+ * @param self this object
399
+ * @param kerning the kerning
400
+ * @return self
401
+ */
402
+ VALUE
403
+ Draw_kerning_eq(VALUE self, VALUE kerning)
404
+ {
405
+ #if defined(HAVE_ST_KERNING)
406
+ Draw *draw;
407
+
408
+ rb_check_frozen(self);
409
+ Data_Get_Struct(self, Draw, draw);
410
+ draw->info->kerning = NUM2DBL(kerning);
411
+ return self;
412
+ #else
413
+ rm_not_implemented();
414
+ return (VALUE)0;
415
+ self = self;
416
+ kerning = kerning;
417
+ #endif
418
+ }
419
+
420
+
421
+ /**
422
+ * Space between two lines.
423
+ *
424
+ * Ruby usage:
425
+ * - @verbatim Draw#interline_spacing= @endverbatim
426
+ *
427
+ * Notes:
428
+ * - New for ImageMagick 6.5.5-8
429
+ *
430
+ * @param self this object
431
+ * @param spacing the spacing
432
+ * @return self
433
+ */
434
+ VALUE
435
+ Draw_interline_spacing_eq(VALUE self, VALUE spacing)
436
+ {
437
+ #if defined(HAVE_ST_INTERLINE_SPACING)
438
+ Draw *draw;
439
+
440
+ rb_check_frozen(self);
441
+ Data_Get_Struct(self, Draw, draw);
442
+ draw->info->interline_spacing = NUM2DBL(spacing);
443
+ return self;
444
+ #else
445
+ rm_not_implemented();
446
+ return (VALUE)0;
447
+ self = self;
448
+ spacing = spacing;
449
+ #endif
450
+ }
451
+
452
+
453
+ /**
454
+ * Space between two words.
455
+ *
456
+ * Ruby usage:
457
+ * - @verbatim Draw#interword_spacing= @endverbatim
458
+ *
459
+ * Notes:
460
+ * - New for ImageMagick 6.4.8-0
461
+ *
462
+ * @param self this object
463
+ * @param spacing the spacing
464
+ * @return self
465
+ */
466
+ VALUE
467
+ Draw_interword_spacing_eq(VALUE self, VALUE spacing)
468
+ {
469
+ #if defined(HAVE_ST_INTERWORD_SPACING)
470
+ Draw *draw;
471
+
472
+ rb_check_frozen(self);
473
+ Data_Get_Struct(self, Draw, draw);
474
+ draw->info->interword_spacing = NUM2DBL(spacing);
475
+ return self;
476
+ #else
477
+ rm_not_implemented();
478
+ return (VALUE)0;
479
+ self = self;
480
+ spacing = spacing;
481
+ #endif
482
+ }
483
+
484
+
485
+ /**
486
+ * Convert an image to a blob and the blob to a String.
487
+ *
488
+ * No Ruby usage (internal function)
489
+ *
490
+ * Notes:
491
+ * - Returns Qnil if there is no image
492
+ *
493
+ * @param image the Image to convert
494
+ * @return Ruby string representation of image
495
+ * @see str_to_image
496
+ */
497
+ static VALUE
498
+ image_to_str(Image *image)
499
+ {
500
+ VALUE dimg = Qnil;
501
+ unsigned char *blob;
502
+ size_t length;
503
+ Info *info;
504
+ ExceptionInfo *exception;
505
+
506
+ if (image)
507
+ {
508
+ info = CloneImageInfo(NULL);
509
+ exception = AcquireExceptionInfo();
510
+ blob = ImageToBlob(info, image, &length, exception);
511
+ DestroyImageInfo(info);
512
+ CHECK_EXCEPTION();
513
+ DestroyExceptionInfo(exception);
514
+ dimg = rb_str_new((char *)blob, (long)length);
515
+ magick_free((void*)blob);
516
+ }
517
+
518
+ RB_GC_GUARD(dimg);
519
+
520
+ return dimg;
521
+ }
522
+
523
+
524
+ /**
525
+ * Undo the image_to_str, above.
526
+ *
527
+ * No Ruby usage (internal function)
528
+ *
529
+ * Notes:
530
+ * - Returns NULL if the argument is Qnil
531
+ *
532
+ * @param str the Ruby string to convert
533
+ * @return Image represented by str
534
+ * @see image_to_str
535
+ */
536
+ static
537
+ Image *str_to_image(VALUE str)
538
+ {
539
+ Image *image = NULL;
540
+ Info *info;
541
+ ExceptionInfo *exception;
542
+
543
+ if (str != Qnil)
544
+ {
545
+ info = CloneImageInfo(NULL);
546
+ exception = AcquireExceptionInfo();
547
+ image = BlobToImage(info, RSTRING_PTR(str), RSTRING_LEN(str), exception);
548
+ DestroyImageInfo(info);
549
+ CHECK_EXCEPTION();
550
+ DestroyExceptionInfo(exception);
551
+ }
552
+
553
+ return image;
554
+ }
555
+
556
+
557
+ /**
558
+ * Custom marshal for Draw objects.
559
+ *
560
+ * Ruby usage:
561
+ * - @verbatim Draw#marshal_dump @endverbatim
562
+ *
563
+ * Notes:
564
+ * - Instead of trying to replicate Ruby's support for cross-system
565
+ * marshalling, exploit it. Convert the Draw fields to Ruby objects and
566
+ * store them in a hash. Let Ruby marshal the hash.
567
+ * - Commented out code that dumps/loads fields that are used internally by
568
+ * ImageMagick and shouldn't be marshaled. I left the code as placeholders
569
+ * so I'll know which fields have been deliberately omitted.
570
+ *
571
+ * @param self this object
572
+ * @return the marshalled object (as a Ruby hash)
573
+ * @todo Handle gradients when christy gets the new gradient support added (23Dec08)
574
+ */
575
+ VALUE
576
+ Draw_marshal_dump(VALUE self)
577
+ {
578
+ Draw *draw;
579
+ VALUE ddraw;
580
+
581
+ Data_Get_Struct(self, Draw, draw);
582
+
583
+ // Raise an exception if the Draw has a non-NULL gradient or element_reference field
584
+ if (draw->info->element_reference.type != UndefinedReference
585
+ || draw->info->gradient.type != UndefinedGradient)
586
+ {
587
+ rb_raise(rb_eTypeError, "can't dump gradient definition");
588
+ }
589
+
590
+ ddraw = rb_hash_new();
591
+
592
+ // rb_hash_aset(ddraw, CSTR2SYM("primitive"), MAGICK_STRING_TO_OBJ(draw->info->primitive)); internal
593
+ // rb_hash_aset(ddraw, CSTR2SYM("geometry"), MAGICK_STRING_TO_OBJ(draw->info->geometry)); set by "text" primitive
594
+ // rb_hash_aset(ddraw, CSTR2SYM("viewbox"), Import_RectangleInfo(&draw->info->viewbox)); internal
595
+ rb_hash_aset(ddraw, CSTR2SYM("affine"), Import_AffineMatrix(&draw->info->affine));
596
+ rb_hash_aset(ddraw, CSTR2SYM("gravity"), INT2FIX(draw->info->gravity));
597
+ rb_hash_aset(ddraw, CSTR2SYM("fill"), Pixel_from_PixelPacket(&draw->info->fill));
598
+ rb_hash_aset(ddraw, CSTR2SYM("stroke"), Pixel_from_PixelPacket(&draw->info->stroke));
599
+ rb_hash_aset(ddraw, CSTR2SYM("stroke_width"), rb_float_new(draw->info->stroke_width));
600
+ // rb_hash_aset(ddraw, CSTR2SYM("gradient"), Qnil); // not used yet
601
+ rb_hash_aset(ddraw, CSTR2SYM("fill_pattern"), image_to_str(draw->info->fill_pattern));
602
+ rb_hash_aset(ddraw, CSTR2SYM("tile"), Qnil); // deprecated
603
+ rb_hash_aset(ddraw, CSTR2SYM("stroke_pattern"), image_to_str(draw->info->stroke_pattern));
604
+ rb_hash_aset(ddraw, CSTR2SYM("stroke_antialias"), draw->info->stroke_antialias ? Qtrue : Qfalse);
605
+ rb_hash_aset(ddraw, CSTR2SYM("text_antialias"), draw->info->text_antialias ? Qtrue : Qfalse);
606
+ // rb_hash_aset(ddraw, CSTR2SYM("fill_rule"), INT2FIX(draw->info->fill_rule)); internal
607
+ // rb_hash_aset(ddraw, CSTR2SYM("linecap"), INT2FIX(draw->info->linecap));
608
+ // rb_hash_aset(ddraw, CSTR2SYM("linejoin"), INT2FIX(draw->info->linejoin));
609
+ // rb_hash_aset(ddraw, CSTR2SYM("miterlimit"), ULONG2NUM(draw->info->miterlimit));
610
+ // rb_hash_aset(ddraw, CSTR2SYM("dash_offset"), rb_float_new(draw->info->dash_offset));
611
+ rb_hash_aset(ddraw, CSTR2SYM("decorate"), INT2FIX(draw->info->decorate));
612
+ // rb_hash_aset(ddraw, CSTR2SYM("compose"), INT2FIX(draw->info->compose)); set via "image" primitive
613
+ // rb_hash_aset(ddraw, CSTR2SYM("text"), MAGICK_STRING_TO_OBJ(draw->info->text)); set via "text" primitive
614
+ // rb_hash_aset(ddraw, CSTR2SYM("face"), Qnil); internal
615
+ rb_hash_aset(ddraw, CSTR2SYM("font"), MAGICK_STRING_TO_OBJ(draw->info->font));
616
+ // rb_hash_aset(ddraw, CSTR2SYM("metrics"), Qnil); internal
617
+ rb_hash_aset(ddraw, CSTR2SYM("family"), MAGICK_STRING_TO_OBJ(draw->info->family));
618
+ rb_hash_aset(ddraw, CSTR2SYM("style"), INT2FIX(draw->info->style));
619
+ rb_hash_aset(ddraw, CSTR2SYM("stretch"), INT2FIX(draw->info->stretch));
620
+ rb_hash_aset(ddraw, CSTR2SYM("weight"), ULONG2NUM(draw->info->weight));
621
+ rb_hash_aset(ddraw, CSTR2SYM("encoding"), MAGICK_STRING_TO_OBJ(draw->info->encoding));
622
+ rb_hash_aset(ddraw, CSTR2SYM("pointsize"), rb_float_new(draw->info->pointsize));
623
+ rb_hash_aset(ddraw, CSTR2SYM("density"), MAGICK_STRING_TO_OBJ(draw->info->density));
624
+ rb_hash_aset(ddraw, CSTR2SYM("align"), INT2FIX(draw->info->align));
625
+ rb_hash_aset(ddraw, CSTR2SYM("undercolor"), Pixel_from_PixelPacket(&draw->info->undercolor));
626
+ // rb_hash_aset(ddraw, CSTR2SYM("border_color"), Pixel_from_PixelPacket(&draw->info->border_color)); Montage and Polaroid
627
+ // rb_hash_aset(ddraw, CSTR2SYM("server_name"), MAGICK_STRING_TO_OBJ(draw->info->server_name));
628
+ // rb_hash_aset(ddraw, CSTR2SYM("dash_pattern"), dash_pattern_to_array(draw->info->dash_pattern)); internal
629
+ // rb_hash_aset(ddraw, CSTR2SYM("clip_mask"), MAGICK_STRING_TO_OBJ(draw->info->clip_mask)); internal
630
+ // rb_hash_aset(ddraw, CSTR2SYM("bounds"), Import_SegmentInfo(&draw->info->bounds)); internal
631
+ rb_hash_aset(ddraw, CSTR2SYM("clip_units"), INT2FIX(draw->info->clip_units));
632
+ rb_hash_aset(ddraw, CSTR2SYM("opacity"), QUANTUM2NUM(draw->info->opacity));
633
+ // rb_hash_aset(ddraw, CSTR2SYM("render"), draw->info->render ? Qtrue : Qfalse); internal
634
+ // rb_hash_aset(ddraw, CSTR2SYM("element_reference"), Qnil); // not used yet
635
+ // rb_hash_aset(ddraw, CSTR2SYM("debug"), draw->info->debug ? Qtrue : Qfalse);
636
+ #if defined(HAVE_ST_KERNING)
637
+ rb_hash_aset(ddraw, CSTR2SYM("kerning"), rb_float_new(draw->info->kerning));
638
+ #endif
639
+ #if defined(HAVE_ST_INTERWORD_SPACING)
640
+ rb_hash_aset(ddraw, CSTR2SYM("interword_spacing"), rb_float_new(draw->info->interword_spacing));
641
+ #endif
642
+
643
+ // Non-DrawInfo fields
644
+ rb_hash_aset(ddraw, CSTR2SYM("primitives"), draw->primitives);
645
+ // rb_hash_aset(ddraw, CSTR2SYM("shadow_color"), Pixel_from_PixelPacket(&draw->shadow_color)); Polaroid-only
646
+
647
+ return ddraw;
648
+ }
649
+
650
+
651
+ /**
652
+ * Support Marsal.load.
653
+ *
654
+ * Ruby usage:
655
+ * - @verbatim Draw#marshal_load @endverbatim
656
+ *
657
+ * Notes:
658
+ * - On entry all fields are all-bits-0
659
+ *
660
+ * @param self this object
661
+ * @param ddraw the marshalled object
662
+ * @return self, once marshalled
663
+ */
664
+ VALUE
665
+ Draw_marshal_load(VALUE self, VALUE ddraw)
666
+ {
667
+ Draw *draw;
668
+ Pixel *pixel;
669
+ VALUE val;
670
+
671
+ Data_Get_Struct(self, Draw, draw);
672
+
673
+ draw->info = magick_malloc(sizeof(DrawInfo));
674
+ if (!draw->info)
675
+ {
676
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
677
+ }
678
+ GetDrawInfo(NULL, draw->info);
679
+
680
+ OBJ_TO_MAGICK_STRING(draw->info->geometry, rb_hash_aref(ddraw, CSTR2SYM("geometry")));
681
+
682
+ //val = rb_hash_aref(ddraw, CSTR2SYM("viewbox"));
683
+ //Export_RectangleInfo(&draw->info->viewbox, val);
684
+
685
+ val = rb_hash_aref(ddraw, CSTR2SYM("affine"));
686
+ Export_AffineMatrix(&draw->info->affine, val);
687
+
688
+ draw->info->gravity = (GravityType) FIX2INT(rb_hash_aref(ddraw, CSTR2SYM("gravity")));
689
+
690
+ val = rb_hash_aref(ddraw, CSTR2SYM("fill"));
691
+ Data_Get_Struct(val, Pixel, pixel);
692
+ draw->info->fill = *pixel;
693
+
694
+ val = rb_hash_aref(ddraw, CSTR2SYM("stroke"));
695
+ Data_Get_Struct(val, Pixel, pixel);
696
+ draw->info->stroke = *pixel;
697
+
698
+ draw->info->stroke_width = NUM2DBL(rb_hash_aref(ddraw, CSTR2SYM("stroke_width")));
699
+ draw->info->fill_pattern = str_to_image(rb_hash_aref(ddraw, CSTR2SYM("fill_pattern")));
700
+ draw->info->stroke_pattern = str_to_image(rb_hash_aref(ddraw, CSTR2SYM("stroke_pattern")));
701
+ draw->info->stroke_antialias = RTEST(rb_hash_aref(ddraw, CSTR2SYM("stroke_antialias")));
702
+ draw->info->text_antialias = RTEST(rb_hash_aref(ddraw, CSTR2SYM("text_antialias")));
703
+ draw->info->decorate = (DecorationType) FIX2INT(rb_hash_aref(ddraw, CSTR2SYM("decorate")));
704
+ OBJ_TO_MAGICK_STRING(draw->info->font, rb_hash_aref(ddraw, CSTR2SYM("font")));
705
+ OBJ_TO_MAGICK_STRING(draw->info->family, rb_hash_aref(ddraw, CSTR2SYM("family")));
706
+
707
+ draw->info->style = (StyleType) FIX2INT(rb_hash_aref(ddraw, CSTR2SYM("style")));
708
+ draw->info->stretch = (StretchType) FIX2INT(rb_hash_aref(ddraw, CSTR2SYM("stretch")));
709
+ draw->info->weight = NUM2ULONG(rb_hash_aref(ddraw, CSTR2SYM("weight")));
710
+ OBJ_TO_MAGICK_STRING(draw->info->encoding, rb_hash_aref(ddraw, CSTR2SYM("encoding")));
711
+ draw->info->pointsize = NUM2DBL(rb_hash_aref(ddraw, CSTR2SYM("pointsize")));
712
+ OBJ_TO_MAGICK_STRING(draw->info->density, rb_hash_aref(ddraw, CSTR2SYM("density")));
713
+ draw->info->align = (AlignType) FIX2INT(rb_hash_aref(ddraw, CSTR2SYM("align")));
714
+
715
+ val = rb_hash_aref(ddraw, CSTR2SYM("undercolor"));
716
+ Data_Get_Struct(val, Pixel, pixel);
717
+ draw->info->undercolor = *pixel;
718
+
719
+ draw->info->clip_units = FIX2INT(rb_hash_aref(ddraw, CSTR2SYM("clip_units")));
720
+ draw->info->opacity = NUM2QUANTUM(rb_hash_aref(ddraw, CSTR2SYM("opacity")));
721
+ #if defined(HAVE_ST_KERNING)
722
+ draw->info->kerning = NUM2DBL(rb_hash_aref(ddraw, CSTR2SYM("kerning")));
723
+ #endif
724
+ #if defined(HAVE_ST_INTERWORD_SPACING)
725
+ draw->info->interword_spacing = NUM2DBL(rb_hash_aref(ddraw, CSTR2SYM("interword_spacing")));
726
+ #endif
727
+
728
+ draw->primitives = rb_hash_aref(ddraw, CSTR2SYM("primitives"));
729
+
730
+ RB_GC_GUARD(val);
731
+
732
+ return self;
733
+ }
734
+
735
+
736
+ /**
737
+ * Pointsize attribute writer.
738
+ *
739
+ * Ruby usage:
740
+ * - @verbatim Draw#pointsize= @endverbatim
741
+ *
742
+ * @param self this object
743
+ * @param pointsize the pointsize
744
+ * @return self
745
+ */
746
+ VALUE
747
+ Draw_pointsize_eq(VALUE self, VALUE pointsize)
748
+ {
749
+ Draw *draw;
750
+
751
+ rb_check_frozen(self);
752
+ Data_Get_Struct(self, Draw, draw);
753
+ draw->info->pointsize = NUM2DBL(pointsize);
754
+ return self;
755
+ }
756
+
757
+
758
+ /**
759
+ * Set rotation attribute value.
760
+ *
761
+ * Ruby usage:
762
+ * - @verbatim Magick::Draw#rotation= @endverbatim
763
+ *
764
+ * Notes:
765
+ * - Argument should be in degrees
766
+ * - Taken from Magick++'s Magick::Image::annotate method.
767
+ * Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
768
+ *
769
+ * @param self this object
770
+ * @param deg the number of degrees
771
+ * @return self
772
+ */
773
+ VALUE
774
+ Draw_rotation_eq(VALUE self, VALUE deg)
775
+ {
776
+ Draw *draw;
777
+ double degrees;
778
+ AffineMatrix affine, current;
779
+
780
+ rb_check_frozen(self);
781
+ Data_Get_Struct(self, Draw, draw);
782
+
783
+ degrees = NUM2DBL(deg);
784
+ if (fabs(degrees) > DBL_EPSILON)
785
+ {
786
+ affine.sx=1.0;
787
+ affine.rx=0.0;
788
+ affine.ry=0.0;
789
+ affine.sy=1.0;
790
+ affine.tx=0.0;
791
+ affine.ty=0.0;
792
+
793
+ current = draw->info->affine;
794
+ affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
795
+ affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
796
+ affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
797
+ affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
798
+
799
+ draw->info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
800
+ draw->info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
801
+ draw->info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
802
+ draw->info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
803
+ draw->info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
804
+ }
805
+
806
+ return self;
807
+ }
808
+
809
+
810
+ /**
811
+ * Stroke attribute writer.
812
+ *
813
+ * Ruby usage:
814
+ * - @verbatim Draw#stroke= @endverbatim
815
+ *
816
+ * @param self this object
817
+ * @param stroke the stroke
818
+ * @return self
819
+ */
820
+ VALUE
821
+ Draw_stroke_eq(VALUE self, VALUE stroke)
822
+ {
823
+ Draw *draw;
824
+
825
+ rb_check_frozen(self);
826
+ Data_Get_Struct(self, Draw, draw);
827
+ Color_to_PixelPacket(&draw->info->stroke, stroke);
828
+ return self;
829
+ }
830
+
831
+
832
+ /**
833
+ * Accept an image as a stroke pattern.
834
+ *
835
+ * Ruby usage:
836
+ * - @verbatim Draw#stroke_pattern= @endverbatim
837
+ *
838
+ * @param self this object
839
+ * @param pattern the pattern
840
+ * @return self
841
+ * @see Draw_fill_pattern_eq
842
+ */
843
+ VALUE
844
+ Draw_stroke_pattern_eq(VALUE self, VALUE pattern)
845
+ {
846
+ Draw *draw;
847
+ Image *image;
848
+
849
+ rb_check_frozen(self);
850
+ Data_Get_Struct(self, Draw, draw);
851
+
852
+ if (draw->info->stroke_pattern != NULL)
853
+ {
854
+ // Do not trace destruction
855
+ DestroyImage(draw->info->stroke_pattern);
856
+ draw->info->stroke_pattern = NULL;
857
+ }
858
+
859
+ if (!NIL_P(pattern))
860
+ {
861
+ // DestroyDrawInfo destroys the clone
862
+ pattern = rm_cur_image(pattern);
863
+ image = rm_check_destroyed(pattern);
864
+ // Do not trace creation
865
+ draw->info->stroke_pattern = rm_clone_image(image);
866
+ }
867
+
868
+ return self;
869
+ }
870
+
871
+
872
+ /**
873
+ * Stroke_width attribute writer.
874
+ *
875
+ * Ruby usage:
876
+ * - @verbatim Draw#stroke_width= @endverbatim
877
+ *
878
+ * @param self this object
879
+ * @param stroke_width the stroke_width
880
+ * @return self
881
+ */
882
+ VALUE
883
+ Draw_stroke_width_eq(VALUE self, VALUE stroke_width)
884
+ {
885
+ Draw *draw;
886
+
887
+ rb_check_frozen(self);
888
+ Data_Get_Struct(self, Draw, draw);
889
+ draw->info->stroke_width = NUM2DBL(stroke_width);
890
+ return self;
891
+ }
892
+
893
+
894
+ /**
895
+ * Text_antialias attribute writer.
896
+ *
897
+ * Ruby usage:
898
+ * - @verbatim Draw#text_antialias= @endverbatim
899
+ *
900
+ * @param self this object
901
+ * @param text_antialias the text_antialias
902
+ * @return self
903
+ */
904
+ VALUE
905
+ Draw_text_antialias_eq(VALUE self, VALUE text_antialias)
906
+ {
907
+ Draw *draw;
908
+
909
+ rb_check_frozen(self);
910
+ Data_Get_Struct(self, Draw, draw);
911
+ draw->info->text_antialias = (MagickBooleanType) RTEST(text_antialias);
912
+ return self;
913
+ }
914
+
915
+
916
+ /**
917
+ * Tile attribute writer.
918
+ *
919
+ * Ruby usage:
920
+ * - @verbatim Draw#tile= @endverbatim
921
+ *
922
+ * @param self this object
923
+ * @param image the image to tile
924
+ * @return self
925
+ */
926
+ VALUE
927
+ Draw_tile_eq(VALUE self, VALUE image)
928
+ {
929
+ return Draw_fill_pattern_eq(self, image);
930
+ }
931
+
932
+
933
+ /**
934
+ * Undercolor attribute writer.
935
+ *
936
+ * Ruby usage:
937
+ * - @verbatim Draw#undercolor= @endverbatim
938
+ *
939
+ * @param self this object
940
+ * @param undercolor the undercolor
941
+ * @return self
942
+ */
943
+ VALUE
944
+ Draw_undercolor_eq(VALUE self, VALUE undercolor)
945
+ {
946
+ Draw *draw;
947
+
948
+ rb_check_frozen(self);
949
+ Data_Get_Struct(self, Draw, draw);
950
+ Color_to_PixelPacket(&draw->info->undercolor, undercolor);
951
+ return self;
952
+ }
953
+
954
+
955
+ /**
956
+ * Annotates an image with text.
957
+ *
958
+ * Ruby usage:
959
+ * - @verbatim Draw#annotate(img, w, h, x, y, text) <{optional parms}> @endverbatim
960
+ *
961
+ * Notes:
962
+ * - Additional Draw attribute methods may be called in the optional block,
963
+ * which is executed in the context of an Draw object.
964
+ *
965
+ * @param self this object
966
+ * @param image_arg the image
967
+ * @param width_arg the width
968
+ * @param height_arg the height
969
+ * @param x_arg x position
970
+ * @param y_arg y position
971
+ * @param text the annotation text
972
+ * @return self
973
+ */
974
+ VALUE Draw_annotate(
975
+ VALUE self,
976
+ VALUE image_arg,
977
+ VALUE width_arg,
978
+ VALUE height_arg,
979
+ VALUE x_arg,
980
+ VALUE y_arg,
981
+ VALUE text)
982
+ {
983
+ Draw *draw;
984
+ Image *image;
985
+ unsigned long width, height;
986
+ long x, y;
987
+ AffineMatrix keep;
988
+ char geometry_str[50];
989
+
990
+ // Save the affine matrix in case it is modified by
991
+ // Draw#rotation=
992
+ Data_Get_Struct(self, Draw, draw);
993
+ keep = draw->info->affine;
994
+
995
+ image_arg = rm_cur_image(image_arg);
996
+ image = rm_check_frozen(image_arg);
997
+
998
+ // If we have an optional parm block, run it in self's context,
999
+ // allowing the app a chance to modify the object's attributes
1000
+ if (rb_block_given_p())
1001
+ {
1002
+ (void)rb_obj_instance_eval(0, NULL, self);
1003
+ }
1004
+
1005
+ // Translate & store in Draw structure
1006
+ draw->info->text = InterpretImageProperties(NULL, image, StringValuePtr(text));
1007
+ if (!draw->info->text)
1008
+ {
1009
+ rb_raise(rb_eArgError, "no text");
1010
+ }
1011
+
1012
+ // Create geometry string, copy to Draw structure, overriding
1013
+ // any previously existing value.
1014
+ width = NUM2ULONG(width_arg);
1015
+ height = NUM2ULONG(height_arg);
1016
+ x = NUM2LONG(x_arg);
1017
+ y = NUM2LONG(y_arg);
1018
+
1019
+ if (width == 0 && height == 0)
1020
+ {
1021
+ sprintf(geometry_str, "%+ld%+ld", x, y);
1022
+ }
1023
+
1024
+ // WxH is non-zero
1025
+ else
1026
+ {
1027
+ sprintf(geometry_str, "%lux%lu%+ld%+ld", width, height, x, y);
1028
+ }
1029
+
1030
+ magick_clone_string(&draw->info->geometry, geometry_str);
1031
+
1032
+ (void) AnnotateImage(image, draw->info);
1033
+
1034
+ magick_free(draw->info->text);
1035
+ draw->info->text = NULL;
1036
+ draw->info->affine = keep;
1037
+
1038
+ rm_check_image_exception(image, RetainOnError);
1039
+
1040
+ return self;
1041
+ }
1042
+
1043
+
1044
+ /**
1045
+ * Clones this object.
1046
+ *
1047
+ * Ruby usage:
1048
+ * - @verbatim Draw#clone @endverbatim
1049
+ *
1050
+ * @param self this object
1051
+ * @return the clone
1052
+ * @see Draw_dup
1053
+ * @see Draw_init_copy
1054
+ */
1055
+ VALUE
1056
+ Draw_clone(VALUE self)
1057
+ {
1058
+ VALUE clone;
1059
+
1060
+ clone = Draw_dup(self);
1061
+ if (OBJ_FROZEN(self))
1062
+ {
1063
+ OBJ_FREEZE(clone);
1064
+ }
1065
+
1066
+ RB_GC_GUARD(clone);
1067
+
1068
+ return clone;
1069
+ }
1070
+
1071
+
1072
+ /**
1073
+ * Implement the "image" drawing primitive.
1074
+ *
1075
+ * Ruby usage:
1076
+ * - @verbatim Draw#composite(x,y,width,height,img) @endverbatim
1077
+ * - @verbatim Draw#composite(x,y,width,height,img,operator) @endverbatim
1078
+ *
1079
+ * Notes:
1080
+ * - Default operator is overComposite
1081
+ * - The "img" argument can be either an ImageList object or an Image
1082
+ * argument.
1083
+ *
1084
+ * @param argc number of input arguments
1085
+ * @param argv array of input arguments
1086
+ * @param self this object
1087
+ * @return self
1088
+ */
1089
+ VALUE
1090
+ Draw_composite(int argc, VALUE *argv, VALUE self)
1091
+ {
1092
+ Draw *draw;
1093
+ const char *op = "Over";
1094
+ double x, y, width, height;
1095
+ CompositeOperator cop = OverCompositeOp;
1096
+ VALUE image;
1097
+ Image *comp_img;
1098
+ struct TmpFile_Name *tmpfile_name;
1099
+ char name[MaxTextExtent];
1100
+ // Buffer for "image" primitive
1101
+ char primitive[MaxTextExtent];
1102
+
1103
+ if (argc < 5 || argc > 6)
1104
+ {
1105
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 5 or 6)", argc);
1106
+ }
1107
+
1108
+ // Retrieve the image to composite
1109
+ image = rm_cur_image(argv[4]);
1110
+ (void) rm_check_destroyed(image);
1111
+
1112
+ x = NUM2DBL(argv[0]);
1113
+ y = NUM2DBL(argv[1]);
1114
+ width = NUM2DBL(argv[2]);
1115
+ height = NUM2DBL(argv[3]);
1116
+
1117
+ // The default composition operator is "Over".
1118
+ if (argc == 6)
1119
+ {
1120
+ VALUE_TO_ENUM(argv[5], cop, CompositeOperator);
1121
+
1122
+ switch (cop)
1123
+ {
1124
+ case AddCompositeOp:
1125
+ op = "Add";
1126
+ break;
1127
+ case AtopCompositeOp:
1128
+ op = "Atop";
1129
+ break;
1130
+ case BlendCompositeOp:
1131
+ op = "Blend";
1132
+ break;
1133
+ #if defined(HAVE_ENUM_BLURCOMPOSITEOP)
1134
+ case BlurCompositeOp:
1135
+ op = "Blur";
1136
+ break;
1137
+ #endif
1138
+ case BumpmapCompositeOp:
1139
+ op = "Bumpmap";
1140
+ break;
1141
+ case ChangeMaskCompositeOp:
1142
+ op = "ChangeMask";
1143
+ break;
1144
+ case ClearCompositeOp:
1145
+ op = "Clear";
1146
+ break;
1147
+ case ColorBurnCompositeOp:
1148
+ op = "ColorBurn";
1149
+ break;
1150
+ case ColorDodgeCompositeOp:
1151
+ op = "ColorDodge";
1152
+ break;
1153
+ case ColorizeCompositeOp:
1154
+ op = "Colorize";
1155
+ break;
1156
+ case CopyCompositeOp:
1157
+ op = "Copy";
1158
+ break;
1159
+ case CopyBlackCompositeOp:
1160
+ op = "CopyBlack";
1161
+ break;
1162
+ case CopyBlueCompositeOp:
1163
+ op = "CopyBlue";
1164
+ break;
1165
+ case CopyCyanCompositeOp:
1166
+ op = "CopyCyan";
1167
+ break;
1168
+ case CopyGreenCompositeOp:
1169
+ op = "CopyGreen";
1170
+ break;
1171
+ case CopyMagentaCompositeOp:
1172
+ op = "CopyMagenta";
1173
+ break;
1174
+ case CopyOpacityCompositeOp:
1175
+ op = "CopyOpacity";
1176
+ break;
1177
+ case CopyRedCompositeOp:
1178
+ op = "CopyRed";
1179
+ break;
1180
+ case CopyYellowCompositeOp:
1181
+ op = "CopyYellow";
1182
+ break;
1183
+ case DarkenCompositeOp:
1184
+ op = "Darken";
1185
+ break;
1186
+ #if defined(HAVE_ENUM_DISTORTCOMPOSITEOP)
1187
+ case DistortCompositeOp:
1188
+ op = "Distort";
1189
+ break;
1190
+ #endif
1191
+ case DivideCompositeOp:
1192
+ op = "Divide";
1193
+ break;
1194
+ case DstCompositeOp:
1195
+ op = "Dst";
1196
+ break;
1197
+ case DstAtopCompositeOp:
1198
+ op = "DstAtop";
1199
+ break;
1200
+ case DstInCompositeOp:
1201
+ op = "DstIn";
1202
+ break;
1203
+ case DstOutCompositeOp:
1204
+ op = "DstOut";
1205
+ break;
1206
+ case DstOverCompositeOp:
1207
+ op = "DstOver";
1208
+ break;
1209
+ case DifferenceCompositeOp:
1210
+ op = "Difference";
1211
+ break;
1212
+ case DisplaceCompositeOp:
1213
+ op = "Displace";
1214
+ break;
1215
+ case DissolveCompositeOp:
1216
+ op = "Dissolve";
1217
+ break;
1218
+ case ExclusionCompositeOp:
1219
+ op = "Exclusion";
1220
+ break;
1221
+ case HardLightCompositeOp:
1222
+ op = "HardLight";
1223
+ break;
1224
+ case HueCompositeOp:
1225
+ op = "Hue";
1226
+ break;
1227
+ case InCompositeOp:
1228
+ op = "In";
1229
+ break;
1230
+ case LightenCompositeOp:
1231
+ op = "Lighten";
1232
+ break;
1233
+ #if defined(HAVE_ENUM_LINEARBURNCOMPOSITEOP)
1234
+ case LinearBurnCompositeOp:
1235
+ op = "LinearBurn";
1236
+ break;
1237
+ #endif
1238
+ #if defined(HAVE_ENUM_LINEARDODGECOMPOSITEOP)
1239
+ case LinearDodgeCompositeOp:
1240
+ op = "LinearDodge";
1241
+ break;
1242
+ #endif
1243
+ case LinearLightCompositeOp:
1244
+ op = "LinearLight";
1245
+ break;
1246
+ case LuminizeCompositeOp:
1247
+ op = "Luminize";
1248
+ break;
1249
+ case MinusCompositeOp:
1250
+ op = "Minus";
1251
+ break;
1252
+ case ModulateCompositeOp:
1253
+ op = "Modulate";
1254
+ break;
1255
+ case MultiplyCompositeOp:
1256
+ op = "Multiply";
1257
+ break;
1258
+ case OutCompositeOp:
1259
+ op = "Out";
1260
+ break;
1261
+ case OverCompositeOp:
1262
+ op = "Over";
1263
+ break;
1264
+ case OverlayCompositeOp:
1265
+ op = "Overlay";
1266
+ break;
1267
+ #if defined(HAVE_ENUM_PEGTOPLIGHTCOMPOSITEOP)
1268
+ case PegtopLightCompositeOp:
1269
+ op = "PegtopLight";
1270
+ break;
1271
+ #endif
1272
+ #if defined(HAVE_ENUM_PINLIGHTCOMPOSITEOP)
1273
+ case PinLightCompositeOp:
1274
+ op = "PinLight";
1275
+ break;
1276
+ #endif
1277
+ case PlusCompositeOp:
1278
+ op = "Plus";
1279
+ break;
1280
+ case ReplaceCompositeOp:
1281
+ op = "Replace";
1282
+ break;
1283
+ case SaturateCompositeOp:
1284
+ op = "Saturate";
1285
+ break;
1286
+ case ScreenCompositeOp:
1287
+ op = "Screen";
1288
+ break;
1289
+ case SoftLightCompositeOp:
1290
+ op = "SoftLight";
1291
+ break;
1292
+ case SrcCompositeOp:
1293
+ op = "Src";
1294
+ break;
1295
+ case SrcAtopCompositeOp:
1296
+ op = "SrcAtop";
1297
+ break;
1298
+ case SrcInCompositeOp:
1299
+ op = "SrcIn";
1300
+ break;
1301
+ case SrcOutCompositeOp:
1302
+ op = "SrcOut";
1303
+ break;
1304
+ case SrcOverCompositeOp:
1305
+ op = "SrcOver";
1306
+ break;
1307
+ case SubtractCompositeOp:
1308
+ op = "Subtract";
1309
+ break;
1310
+ case ThresholdCompositeOp:
1311
+ op = "Threshold";
1312
+ break;
1313
+ #if defined(HAVE_ENUM_VIVIDLIGHTCOMPOSITEOP)
1314
+ case VividLightCompositeOp:
1315
+ op = "VividLight";
1316
+ break;
1317
+ #endif
1318
+ case XorCompositeOp:
1319
+ op = "Xor";
1320
+ break;
1321
+ default:
1322
+ rb_raise(rb_eArgError, "unknown composite operator (%d)", cop);
1323
+ break;
1324
+ }
1325
+ }
1326
+
1327
+ Data_Get_Struct(self, Draw, draw);
1328
+
1329
+ // Create a temp copy of the composite image
1330
+ Data_Get_Struct(image, Image, comp_img);
1331
+ rm_write_temp_image(comp_img, name);
1332
+
1333
+ // Add the temp filename to the filename array.
1334
+ // Use Magick storage since we need to keep the list around
1335
+ // until destroy_Draw is called.
1336
+ tmpfile_name = magick_malloc(sizeof(struct TmpFile_Name)+strlen(name));
1337
+ strcpy(tmpfile_name->name, name);
1338
+ tmpfile_name->next = draw->tmpfile_ary;
1339
+ draw->tmpfile_ary = tmpfile_name;
1340
+
1341
+ // Form the drawing primitive
1342
+ (void) sprintf(primitive, "image %s %g,%g,%g,%g '%s'", op, x, y, width, height, name);
1343
+
1344
+
1345
+ // Send "primitive" to self.
1346
+ (void) rb_funcall(self, rb_intern("primitive"), 1, rb_str_new2(primitive));
1347
+
1348
+ RB_GC_GUARD(image);
1349
+
1350
+ return self;
1351
+ }
1352
+
1353
+
1354
+ /**
1355
+ * Execute the stored drawing primitives on the current image.
1356
+ *
1357
+ * Ruby usage:
1358
+ * - @verbatim Draw#draw(i) @endverbatim
1359
+ *
1360
+ * @param self this object
1361
+ * @param image_arg the image argument
1362
+ * @return self
1363
+ */
1364
+ VALUE
1365
+ Draw_draw(VALUE self, VALUE image_arg)
1366
+ {
1367
+ Draw *draw;
1368
+ Image *image;
1369
+
1370
+ image_arg = rm_cur_image(image_arg);
1371
+ image = rm_check_frozen(image_arg);
1372
+
1373
+ Data_Get_Struct(self, Draw, draw);
1374
+ if (draw->primitives == 0)
1375
+ {
1376
+ rb_raise(rb_eArgError, "nothing to draw");
1377
+ }
1378
+
1379
+ // Point the DrawInfo structure at the current set of primitives.
1380
+ magick_clone_string(&(draw->info->primitive), StringValuePtr(draw->primitives));
1381
+
1382
+ (void) DrawImage(image, draw->info);
1383
+ rm_check_image_exception(image, RetainOnError);
1384
+
1385
+ magick_free(draw->info->primitive);
1386
+ draw->info->primitive = NULL;
1387
+
1388
+ return self;
1389
+ }
1390
+
1391
+
1392
+ /**
1393
+ * Copy a Draw object.
1394
+ *
1395
+ * Ruby usage:
1396
+ * - @verbatim Draw#dup @endverbatim
1397
+ *
1398
+ * Notes:
1399
+ * - Constructs a new Draw object, then calls initialize_copy.
1400
+ *
1401
+ * @param self this object
1402
+ * @return the duplicate
1403
+ * @see Draw_clone
1404
+ * @see Draw_init_copy
1405
+ */
1406
+ VALUE
1407
+ Draw_dup(VALUE self)
1408
+ {
1409
+ Draw *draw;
1410
+ VALUE dup;
1411
+
1412
+ draw = ALLOC(Draw);
1413
+ memset(draw, 0, sizeof(Draw));
1414
+ dup = Data_Wrap_Struct(CLASS_OF(self), mark_Draw, destroy_Draw, draw);
1415
+ if (rb_obj_tainted(self))
1416
+ {
1417
+ (void)rb_obj_taint(dup);
1418
+ }
1419
+
1420
+ RB_GC_GUARD(dup);
1421
+
1422
+ return rb_funcall(dup, rm_ID_initialize_copy, 1, self);
1423
+ }
1424
+
1425
+
1426
+ /**
1427
+ * Returns measurements for a given font and text string.
1428
+ *
1429
+ * Ruby usage:
1430
+ * - @verbatim Draw#get_type_metrics(text) @endverbatim
1431
+ * - @verbatim Draw#get_type_metrics(image, text) @endverbatim
1432
+ *
1433
+ * Notes:
1434
+ * - If the image argument has been omitted, use a dummy image, but make sure
1435
+ * the text has none of the special characters that refer to image
1436
+ * attributes.
1437
+ *
1438
+ * @param argc number of input arguments
1439
+ * @param argv array of input arguments
1440
+ * @param self this object
1441
+ * @return the duplicate
1442
+ */
1443
+ VALUE
1444
+ Draw_get_type_metrics(
1445
+ int argc,
1446
+ VALUE *argv,
1447
+ VALUE self)
1448
+ {
1449
+ return get_type_metrics(argc, argv, self, GetTypeMetrics);
1450
+ }
1451
+
1452
+
1453
+ /**
1454
+ * Returns measurements for a given font and text string.
1455
+ *
1456
+ * Ruby usage:
1457
+ * - @verbatim Draw#get_multiline_type_metrics(text) @endverbatim
1458
+ * - @verbatim Draw#get_multiline_type_metrics(image, text) @endverbatim
1459
+ *
1460
+ * Notes:
1461
+ * - If the image argument has been omitted, use a dummy image, but make sure
1462
+ * the text has none of the special characters that refer to image
1463
+ * attributes.
1464
+ *
1465
+ * @param argc number of input arguments
1466
+ * @param argv array of input arguments
1467
+ * @param self this object
1468
+ * @return the duplicate
1469
+ */
1470
+ VALUE
1471
+ Draw_get_multiline_type_metrics(
1472
+ int argc,
1473
+ VALUE *argv,
1474
+ VALUE self)
1475
+ {
1476
+ return get_type_metrics(argc, argv, self, GetMultilineTypeMetrics);
1477
+ }
1478
+
1479
+
1480
+ /**
1481
+ * Initialize clone, dup methods.
1482
+ *
1483
+ * Ruby usage:
1484
+ * - @verbatim Draw#initialize_copy @endverbatim
1485
+ *
1486
+ * @param self this object
1487
+ * @param orig the original object
1488
+ * @return self
1489
+ * @see Draw_clone
1490
+ * @see Draw_dup
1491
+ */
1492
+ VALUE Draw_init_copy(VALUE self, VALUE orig)
1493
+ {
1494
+ Draw *copy, *original;
1495
+
1496
+ Data_Get_Struct(orig, Draw, original);
1497
+ Data_Get_Struct(self, Draw, copy);
1498
+
1499
+ copy->info = CloneDrawInfo(NULL, original->info);
1500
+ if (!copy->info)
1501
+ {
1502
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
1503
+ }
1504
+
1505
+ if (original->primitives)
1506
+ {
1507
+ copy->primitives = rb_str_dup(original->primitives);
1508
+ }
1509
+
1510
+ return self;
1511
+ }
1512
+
1513
+
1514
+ /**
1515
+ * Initialize Draw object.
1516
+ *
1517
+ * Ruby usage:
1518
+ * - @verbatim Draw#initialize <{ info initializers }> @endverbatim
1519
+ *
1520
+ * @param self this object
1521
+ * @return self
1522
+ */
1523
+ VALUE
1524
+ Draw_initialize(VALUE self)
1525
+ {
1526
+ Draw *draw, *draw_options;
1527
+ VALUE options;
1528
+
1529
+ Data_Get_Struct(self, Draw, draw);
1530
+
1531
+ options = new_DrawOptions();
1532
+ Data_Get_Struct(options, Draw, draw_options);
1533
+ draw->info = draw_options->info;
1534
+ draw_options->info = NULL;
1535
+
1536
+ RB_GC_GUARD(options);
1537
+
1538
+ return self;
1539
+ }
1540
+
1541
+
1542
+ /**
1543
+ * Display the primitives.
1544
+ *
1545
+ * Ruby usage:
1546
+ * - @verbatim Draw#inspect @endverbatim
1547
+ *
1548
+ * @param self this object
1549
+ * @return the draw primitives or the Ruby string "(no primitives defined)" if
1550
+ * they are not defined
1551
+ */
1552
+ VALUE
1553
+ Draw_inspect(VALUE self)
1554
+ {
1555
+ Draw *draw;
1556
+
1557
+ Data_Get_Struct(self, Draw, draw);
1558
+ return draw->primitives ? draw->primitives : rb_str_new2("(no primitives defined)");
1559
+ }
1560
+
1561
+
1562
+ /**
1563
+ * Create a new Draw object.
1564
+ *
1565
+ * Ruby usage:
1566
+ * - @verbatim Draw.new @endverbatim
1567
+ * - @verbatim Draw.allocate @endverbatim
1568
+ *
1569
+ * @param class the Ruby Draw class
1570
+ * @return a new Draw object
1571
+ * @throw ImageMagickError if no memory
1572
+ */
1573
+ VALUE Draw_alloc(VALUE class)
1574
+ {
1575
+ Draw *draw;
1576
+ VALUE draw_obj;
1577
+
1578
+ draw = ALLOC(Draw);
1579
+ memset(draw, 0, sizeof(Draw));
1580
+ draw_obj = Data_Wrap_Struct(class, mark_Draw, destroy_Draw, draw);
1581
+
1582
+ RB_GC_GUARD(draw_obj);
1583
+
1584
+ return draw_obj;
1585
+ }
1586
+
1587
+
1588
+ /**
1589
+ * Add a drawing primitive to the list of primitives in the Draw object.
1590
+ *
1591
+ * Ruby usage:
1592
+ * - @verbatim Draw#primitive @endverbatim
1593
+ *
1594
+ * @param self this object
1595
+ * @param primitive the primitive to add
1596
+ * @return self
1597
+ */
1598
+ VALUE
1599
+ Draw_primitive(VALUE self, VALUE primitive)
1600
+ {
1601
+ Draw *draw;
1602
+
1603
+ rb_check_frozen(self);
1604
+ Data_Get_Struct(self, Draw, draw);
1605
+
1606
+ if (draw->primitives == (VALUE)0)
1607
+ {
1608
+ draw->primitives = primitive;
1609
+ }
1610
+ else
1611
+ {
1612
+ draw->primitives = rb_str_concat(draw->primitives, rb_str_new2("\n"));
1613
+ draw->primitives = rb_str_concat(draw->primitives, primitive);
1614
+ }
1615
+
1616
+ return self;
1617
+ }
1618
+
1619
+
1620
+ /**
1621
+ * Mark referenced objects.
1622
+ *
1623
+ * No Ruby usage (internal function)
1624
+ *
1625
+ * @param drawptr pointer to a Draw object
1626
+ */
1627
+ static void
1628
+ mark_Draw(void *drawptr)
1629
+ {
1630
+ Draw *draw = (Draw *)drawptr;
1631
+
1632
+ if (draw->primitives != (VALUE)0)
1633
+ {
1634
+ rb_gc_mark(draw->primitives);
1635
+ }
1636
+ }
1637
+
1638
+
1639
+ /**
1640
+ * Free the memory associated with an Draw object.
1641
+ *
1642
+ * No Ruby usage (internal function)
1643
+ *
1644
+ * @param drawptr pointer to a Draw object
1645
+ */
1646
+ static void
1647
+ destroy_Draw(void *drawptr)
1648
+ {
1649
+ Draw *draw = (Draw *)drawptr;
1650
+ struct TmpFile_Name *tmpfile_name;
1651
+
1652
+ if (draw->info)
1653
+ {
1654
+ (void) DestroyDrawInfo(draw->info);
1655
+ draw->info = NULL;
1656
+ }
1657
+
1658
+ // Erase any temporary image files.
1659
+ while (draw->tmpfile_ary)
1660
+ {
1661
+ tmpfile_name = draw->tmpfile_ary;
1662
+ draw->tmpfile_ary = draw->tmpfile_ary->next;
1663
+ rm_delete_temp_image(tmpfile_name->name);
1664
+ magick_free(tmpfile_name);
1665
+ }
1666
+
1667
+ xfree(drawptr);
1668
+ }
1669
+
1670
+
1671
+ /**
1672
+ * Allocate & initialize a DrawOptions object.
1673
+ *
1674
+ * No Ruby usage (internal function)
1675
+ *
1676
+ * @return a new DrawOptions object
1677
+ */
1678
+ static VALUE
1679
+ new_DrawOptions(void)
1680
+ {
1681
+ return DrawOptions_initialize(Draw_alloc(Class_DrawOptions));
1682
+ }
1683
+
1684
+
1685
+ /**
1686
+ * Create a DrawOptions object.
1687
+ *
1688
+ * Ruby usage:
1689
+ * - @verbatim DrawOptions#allocate @endverbatim
1690
+ * - @verbatim DrawOptions#new @endverbatim
1691
+ *
1692
+ * Notes:
1693
+ * - The DrawOptions class is the same as the Draw class except is has only
1694
+ * the attribute writer functions
1695
+ *
1696
+ * @param class the Ruby DrawOptions class
1697
+ * @return a new DrawOptions object
1698
+ */
1699
+ VALUE
1700
+ DrawOptions_alloc(VALUE class)
1701
+ {
1702
+ Draw *draw_options;
1703
+ VALUE draw_options_obj;
1704
+
1705
+ draw_options = ALLOC(Draw);
1706
+ memset(draw_options, 0, sizeof(Draw));
1707
+ draw_options_obj = Data_Wrap_Struct(class, mark_Draw, destroy_Draw, draw_options);
1708
+
1709
+ RB_GC_GUARD(draw_options_obj);
1710
+
1711
+ return draw_options_obj;
1712
+ }
1713
+
1714
+
1715
+ /**
1716
+ * Initialize a DrawOptions object.
1717
+ *
1718
+ * Ruby usage:
1719
+ * - @verbatim DrawOptions#initialize @endverbatim
1720
+ *
1721
+ * @param self this object
1722
+ * @return self
1723
+ */
1724
+ VALUE
1725
+ DrawOptions_initialize(VALUE self)
1726
+ {
1727
+ Draw *draw_options;
1728
+
1729
+ Data_Get_Struct(self, Draw, draw_options);
1730
+ draw_options->info = magick_malloc(sizeof(DrawInfo));
1731
+ if (!draw_options->info)
1732
+ {
1733
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
1734
+ }
1735
+
1736
+ GetDrawInfo(NULL, draw_options->info);
1737
+
1738
+ if (rb_block_given_p())
1739
+ {
1740
+ // Run the block in self's context
1741
+ (void) rb_obj_instance_eval(0, NULL, self);
1742
+ }
1743
+
1744
+ return self;
1745
+ }
1746
+
1747
+
1748
+ /**
1749
+ * Allocate a new Magick::PolaroidOptions object.
1750
+ *
1751
+ * Ruby usage:
1752
+ * - @verbatim Magick::PolaroidOptions#allocate @endverbatim
1753
+ * - @verbatim Magick::PolaroidOptions#new @endverbatim
1754
+ *
1755
+ * Notes:
1756
+ * - Internally a PolaroidOptions object is the same as a Draw object. The
1757
+ * methods are implemented by Draw methods in rmdraw.c.
1758
+ *
1759
+ * @param class the Ruby PoloradoidOptions class
1760
+ * @return a new DrawOptions object
1761
+ */
1762
+ VALUE
1763
+ PolaroidOptions_alloc(VALUE class)
1764
+ {
1765
+ VALUE polaroid_obj;
1766
+ ImageInfo *image_info;
1767
+ Draw *draw;
1768
+
1769
+ image_info = CloneImageInfo(NULL);
1770
+
1771
+ draw = ALLOC(Draw);
1772
+ memset(draw, 0, sizeof(*draw));
1773
+
1774
+ draw->info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1775
+ (void)(void) DestroyImageInfo(image_info);
1776
+
1777
+ polaroid_obj = Data_Wrap_Struct(class, NULL, destroy_Draw, draw);
1778
+
1779
+ RB_GC_GUARD(polaroid_obj);
1780
+
1781
+ return polaroid_obj;
1782
+ }
1783
+
1784
+
1785
+ /**
1786
+ * Yield to an optional block.
1787
+ *
1788
+ * Ruby usage:
1789
+ * - @verbatim Magick::PolaroidOptions#initialize @endverbatim
1790
+ *
1791
+ * @param self this object
1792
+ * @return self
1793
+ */
1794
+ VALUE
1795
+ PolaroidOptions_initialize(VALUE self)
1796
+ {
1797
+ Draw *draw;
1798
+ ExceptionInfo *exception;
1799
+
1800
+ // Default shadow color
1801
+ Data_Get_Struct(self, Draw, draw);
1802
+
1803
+ exception = AcquireExceptionInfo();
1804
+ (void) QueryColorDatabase("gray75", &draw->shadow_color, exception);
1805
+ CHECK_EXCEPTION()
1806
+ (void) QueryColorDatabase("#dfdfdf", &draw->info->border_color, exception);
1807
+
1808
+ if (rb_block_given_p())
1809
+ {
1810
+ // Run the block in self's context
1811
+ (void) rb_obj_instance_eval(0, NULL, self);
1812
+ }
1813
+ return self;
1814
+ }
1815
+
1816
+
1817
+ /**
1818
+ * Allocate a PolaroidOptions instance.
1819
+ *
1820
+ * No Ruby usage (internal function)
1821
+ *
1822
+ * @return new PolaroidOptions object
1823
+ */
1824
+ VALUE
1825
+ rm_polaroid_new(void)
1826
+ {
1827
+ return PolaroidOptions_initialize(PolaroidOptions_alloc(Class_PolaroidOptions));
1828
+ }
1829
+
1830
+
1831
+ /**
1832
+ * Set the shadow color attribute.
1833
+ *
1834
+ * Ruby usage:
1835
+ * - @verbatim PolaroidOptions#shadow_color= @endverbatim
1836
+ *
1837
+ * @param self this object
1838
+ * @param shadow the shadow color
1839
+ * @return self
1840
+ */
1841
+ VALUE
1842
+ PolaroidOptions_shadow_color_eq(VALUE self, VALUE shadow)
1843
+ {
1844
+ Draw *draw;
1845
+
1846
+ Data_Get_Struct(self, Draw, draw);
1847
+ Color_to_PixelPacket(&draw->shadow_color, shadow);
1848
+ return self;
1849
+ }
1850
+
1851
+
1852
+ /**
1853
+ * Set the border color attribute.
1854
+ *
1855
+ * Ruby usage:
1856
+ * - @verbatim PolaroidOptions#border_color= @endverbatim
1857
+ *
1858
+ * @param self this object
1859
+ * @param border the border color
1860
+ * @return self
1861
+ */
1862
+ VALUE
1863
+ PolaroidOptions_border_color_eq(VALUE self, VALUE border)
1864
+ {
1865
+ Draw *draw;
1866
+
1867
+ Data_Get_Struct(self, Draw, draw);
1868
+ Color_to_PixelPacket(&draw->info->border_color, border);
1869
+ return self;
1870
+ }
1871
+
1872
+
1873
+ /**
1874
+ * Create a dummy object of an image class.
1875
+ *
1876
+ * No Ruby usage (internal function)
1877
+ *
1878
+ * @param klass the class for which to create a dummy
1879
+ * @return the newly allocated dummy
1880
+ */
1881
+ static VALUE
1882
+ get_dummy_tm_img(VALUE klass)
1883
+ {
1884
+ #define DUMMY_IMG_CLASS_VAR "@@_dummy_img_"
1885
+ VALUE dummy_img = 0;
1886
+ Info *info;
1887
+ Image *image;
1888
+
1889
+ if (rb_cvar_defined(klass, rb_intern(DUMMY_IMG_CLASS_VAR)) != Qtrue)
1890
+ {
1891
+
1892
+ info = CloneImageInfo(NULL);
1893
+ if (!info)
1894
+ {
1895
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
1896
+ }
1897
+ image = AcquireImage(info);
1898
+ if (!image)
1899
+ {
1900
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
1901
+ }
1902
+ (void) DestroyImageInfo(info);
1903
+ dummy_img = rm_image_new(image);
1904
+
1905
+ rb_cv_set(klass, DUMMY_IMG_CLASS_VAR, dummy_img);
1906
+ }
1907
+ dummy_img = rb_cv_get(klass, DUMMY_IMG_CLASS_VAR);
1908
+
1909
+ RB_GC_GUARD(dummy_img);
1910
+
1911
+ return dummy_img;
1912
+ }
1913
+
1914
+
1915
+ /**
1916
+ * Call a get-type-metrics function.
1917
+ *
1918
+ * No Ruby usage (internal function)
1919
+ *
1920
+ * Notes:
1921
+ * - called by Draw_get_type_metrics and Draw_get_multiline_type_metrics
1922
+ *
1923
+ * @param argc number of input arguments
1924
+ * @param argv array of input arguments
1925
+ * @param self this object
1926
+ * @param getter which type metrics to get
1927
+ * @return the type metrics
1928
+ * @see Draw_get_type_metrics
1929
+ * @see Draw_get_multiline_type_metrics
1930
+ */
1931
+ static VALUE
1932
+ get_type_metrics(
1933
+ int argc,
1934
+ VALUE *argv,
1935
+ VALUE self,
1936
+ get_type_metrics_func_t getter)
1937
+ {
1938
+ static char attrs[] = "OPbcdefghiklmnopqrstuwxyz[@#%";
1939
+ #define ATTRS_L ((int)(sizeof(attrs)-1))
1940
+ Image *image;
1941
+ Draw *draw;
1942
+ VALUE t;
1943
+ TypeMetric metrics;
1944
+ char *text = NULL;
1945
+ long text_l;
1946
+ long x;
1947
+ unsigned int okay;
1948
+
1949
+ switch (argc)
1950
+ {
1951
+ case 1: // use default image
1952
+ text = rm_str2cstr(argv[0], &text_l);
1953
+
1954
+ for (x = 0; x < text_l-1; x++)
1955
+ {
1956
+ // Ensure text string doesn't refer to image attributes.
1957
+ if (text[x] == '%')
1958
+ {
1959
+ int y;
1960
+ char spec = text[x+1];
1961
+
1962
+ if (spec == '%')
1963
+ {
1964
+ x++;
1965
+ }
1966
+ else
1967
+ {
1968
+ for (y = 0; y < ATTRS_L; y++)
1969
+ {
1970
+ if (spec == attrs[y])
1971
+ {
1972
+ rb_raise(rb_eArgError,
1973
+ "text string contains image attribute reference `%%%c'",
1974
+ spec);
1975
+ }
1976
+ }
1977
+ }
1978
+ }
1979
+ }
1980
+
1981
+ Data_Get_Struct(get_dummy_tm_img(CLASS_OF(self)), Image, image);
1982
+ break;
1983
+ case 2:
1984
+ t = rm_cur_image(argv[0]);
1985
+ image = rm_check_destroyed(t);
1986
+ text = rm_str2cstr(argv[1], &text_l);
1987
+ break; // okay
1988
+ default:
1989
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
1990
+ break;
1991
+ }
1992
+
1993
+ if (text_l == 0)
1994
+ {
1995
+ rb_raise(rb_eArgError, "no text to measure");
1996
+ }
1997
+
1998
+ Data_Get_Struct(self, Draw, draw);
1999
+ draw->info->text = InterpretImageProperties(NULL, image, text);
2000
+ if (!draw->info->text)
2001
+ {
2002
+ rb_raise(rb_eArgError, "no text to measure");
2003
+ }
2004
+
2005
+ okay = (*getter)(image, draw->info, &metrics);
2006
+
2007
+ magick_free(draw->info->text);
2008
+ draw->info->text = NULL;
2009
+
2010
+ if (!okay)
2011
+ {
2012
+ rm_check_image_exception(image, RetainOnError);
2013
+
2014
+ // Shouldn't get here...
2015
+ rb_raise(rb_eRuntimeError, "Can't measure text. Are the fonts installed? "
2016
+ "Is the FreeType library installed?");
2017
+ }
2018
+
2019
+ RB_GC_GUARD(t);
2020
+
2021
+ return Import_TypeMetric(&metrics);
2022
+ }