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.
- checksums.yaml +7 -0
- data/.editorconfig +14 -0
- data/.gitignore +23 -0
- data/.hound.yml +2 -0
- data/.rspec +1 -0
- data/.rubocop.yml +340 -0
- data/.simplecov +27 -0
- data/.travis.yml +60 -0
- data/CHANGELOG.md +915 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/CONTRIBUTING.md +50 -0
- data/Doxyfile +1514 -0
- data/Gemfile +10 -0
- data/LICENSE +20 -0
- data/README.textile +257 -0
- data/Rakefile +188 -0
- data/before_install_linux.sh +32 -0
- data/before_install_osx.sh +2 -0
- data/deprecated/RMagick.rb +6 -0
- data/doc/.cvsignore +1 -0
- data/doc/comtasks.html +287 -0
- data/doc/constants.html +1581 -0
- data/doc/css/doc.css +299 -0
- data/doc/css/popup.css +34 -0
- data/doc/css/ref.css +67 -0
- data/doc/draw.html +3272 -0
- data/doc/ex/InitialCoords.rb +22 -0
- data/doc/ex/NewCoordSys.rb +30 -0
- data/doc/ex/OrigCoordSys.rb +16 -0
- data/doc/ex/PreserveAspectRatio.rb +204 -0
- data/doc/ex/RotateScale.rb +36 -0
- data/doc/ex/Skew.rb +38 -0
- data/doc/ex/Use01.rb +15 -0
- data/doc/ex/Use02.rb +20 -0
- data/doc/ex/Use03.rb +16 -0
- data/doc/ex/ViewBox.rb +31 -0
- data/doc/ex/adaptive_threshold.rb +9 -0
- data/doc/ex/add_noise.rb +16 -0
- data/doc/ex/affine.rb +48 -0
- data/doc/ex/affine_transform.rb +20 -0
- data/doc/ex/arc.rb +49 -0
- data/doc/ex/arcpath.rb +32 -0
- data/doc/ex/arcs01.rb +28 -0
- data/doc/ex/arcs02.rb +59 -0
- data/doc/ex/average.rb +15 -0
- data/doc/ex/axes.rb +64 -0
- data/doc/ex/baseline_shift01.rb +17 -0
- data/doc/ex/bilevel_channel.rb +8 -0
- data/doc/ex/blur_image.rb +12 -0
- data/doc/ex/border.rb +10 -0
- data/doc/ex/bounding_box.rb +42 -0
- data/doc/ex/cbezier1.rb +41 -0
- data/doc/ex/cbezier2.rb +41 -0
- data/doc/ex/cbezier3.rb +41 -0
- data/doc/ex/cbezier4.rb +42 -0
- data/doc/ex/cbezier5.rb +42 -0
- data/doc/ex/cbezier6.rb +53 -0
- data/doc/ex/channel.rb +25 -0
- data/doc/ex/charcoal.rb +12 -0
- data/doc/ex/chop.rb +29 -0
- data/doc/ex/circle.rb +33 -0
- data/doc/ex/circle01.rb +16 -0
- data/doc/ex/clip_path.rb +60 -0
- data/doc/ex/coalesce.rb +57 -0
- data/doc/ex/color_fill_to_border.rb +29 -0
- data/doc/ex/color_floodfill.rb +28 -0
- data/doc/ex/color_histogram.rb +47 -0
- data/doc/ex/color_reset.rb +11 -0
- data/doc/ex/colorize.rb +16 -0
- data/doc/ex/colors.rb +64 -0
- data/doc/ex/compose_mask.rb +22 -0
- data/doc/ex/composite.rb +133 -0
- data/doc/ex/composite_layers.rb +53 -0
- data/doc/ex/composite_tiled.rb +21 -0
- data/doc/ex/contrast.rb +36 -0
- data/doc/ex/crop.rb +31 -0
- data/doc/ex/crop_with_gravity.rb +42 -0
- data/doc/ex/cubic01.rb +43 -0
- data/doc/ex/cubic02.rb +91 -0
- data/doc/ex/cycle_colormap.rb +21 -0
- data/doc/ex/dissolve.rb +12 -0
- data/doc/ex/drawcomp.rb +42 -0
- data/doc/ex/drop_shadow.rb +60 -0
- data/doc/ex/edge.rb +11 -0
- data/doc/ex/ellipse.rb +45 -0
- data/doc/ex/ellipse01.rb +21 -0
- data/doc/ex/emboss.rb +11 -0
- data/doc/ex/enhance.rb +28 -0
- data/doc/ex/equalize.rb +11 -0
- data/doc/ex/evenodd.rb +42 -0
- data/doc/ex/fill_pattern.rb +23 -0
- data/doc/ex/flatten_images.rb +36 -0
- data/doc/ex/flip.rb +11 -0
- data/doc/ex/flop.rb +11 -0
- data/doc/ex/font_styles.rb +32 -0
- data/doc/ex/fonts.rb +20 -0
- data/doc/ex/frame.rb +12 -0
- data/doc/ex/gaussian_blur.rb +11 -0
- data/doc/ex/get_multiline_type_metrics.rb +41 -0
- data/doc/ex/get_pixels.rb +47 -0
- data/doc/ex/get_type_metrics.rb +141 -0
- data/doc/ex/gradientfill.rb +27 -0
- data/doc/ex/grav.rb +45 -0
- data/doc/ex/gravity.rb +80 -0
- data/doc/ex/group.rb +26 -0
- data/doc/ex/hatchfill.rb +27 -0
- data/doc/ex/image.rb +44 -0
- data/doc/ex/images/Apple.miff +0 -0
- data/doc/ex/images/Ballerina.jpg +0 -0
- data/doc/ex/images/Ballerina3.jpg +0 -0
- data/doc/ex/images/Button_0.gif +0 -0
- data/doc/ex/images/Button_1.gif +0 -0
- data/doc/ex/images/Button_2.gif +0 -0
- data/doc/ex/images/Button_3.gif +0 -0
- data/doc/ex/images/Button_4.gif +0 -0
- data/doc/ex/images/Button_5.gif +0 -0
- data/doc/ex/images/Button_6.gif +0 -0
- data/doc/ex/images/Button_7.gif +0 -0
- data/doc/ex/images/Button_8.gif +0 -0
- data/doc/ex/images/Button_9.gif +0 -0
- data/doc/ex/images/Button_A.gif +0 -0
- data/doc/ex/images/Button_B.gif +0 -0
- data/doc/ex/images/Button_C.gif +0 -0
- data/doc/ex/images/Button_D.gif +0 -0
- data/doc/ex/images/Button_E.gif +0 -0
- data/doc/ex/images/Button_F.gif +0 -0
- data/doc/ex/images/Button_G.gif +0 -0
- data/doc/ex/images/Button_H.gif +0 -0
- data/doc/ex/images/Button_I.gif +0 -0
- data/doc/ex/images/Button_J.gif +0 -0
- data/doc/ex/images/Button_K.gif +0 -0
- data/doc/ex/images/Button_L.gif +0 -0
- data/doc/ex/images/Button_M.gif +0 -0
- data/doc/ex/images/Button_N.gif +0 -0
- data/doc/ex/images/Button_O.gif +0 -0
- data/doc/ex/images/Button_P.gif +0 -0
- data/doc/ex/images/Button_Q.gif +0 -0
- data/doc/ex/images/Button_R.gif +0 -0
- data/doc/ex/images/Button_S.gif +0 -0
- data/doc/ex/images/Button_T.gif +0 -0
- data/doc/ex/images/Button_U.gif +0 -0
- data/doc/ex/images/Button_V.gif +0 -0
- data/doc/ex/images/Button_W.gif +0 -0
- data/doc/ex/images/Button_X.gif +0 -0
- data/doc/ex/images/Button_Y.gif +0 -0
- data/doc/ex/images/Button_Z.gif +0 -0
- data/doc/ex/images/Cheetah.jpg +0 -0
- data/doc/ex/images/Coffee.wmf +0 -0
- data/doc/ex/images/Flower_Hat.jpg +0 -0
- data/doc/ex/images/Gold_Statue.jpg +0 -0
- data/doc/ex/images/Hot_Air_Balloons.jpg +0 -0
- data/doc/ex/images/Hot_Air_Balloons_H.jpg +0 -0
- data/doc/ex/images/Leaf.miff +0 -0
- data/doc/ex/images/No.wmf +0 -0
- data/doc/ex/images/Polynesia.jpg +0 -0
- data/doc/ex/images/Red_Rocks.jpg +0 -0
- data/doc/ex/images/Rocks_On_Beach.miff +0 -0
- data/doc/ex/images/Shorts.jpg +0 -0
- data/doc/ex/images/Snake.wmf +0 -0
- data/doc/ex/images/Violin.jpg +0 -0
- data/doc/ex/images/Yellow_Rose.miff +0 -0
- data/doc/ex/images/big-duck.gif +0 -0
- data/doc/ex/images/duck.gif +0 -0
- data/doc/ex/images/duck0.gif +0 -0
- data/doc/ex/images/duck1.gif +0 -0
- data/doc/ex/images/duck10.gif +0 -0
- data/doc/ex/images/duck11.gif +0 -0
- data/doc/ex/images/duck12.gif +0 -0
- data/doc/ex/images/duck13.gif +0 -0
- data/doc/ex/images/duck14.gif +0 -0
- data/doc/ex/images/duck15.gif +0 -0
- data/doc/ex/images/duck2.gif +0 -0
- data/doc/ex/images/duck3.gif +0 -0
- data/doc/ex/images/duck4.gif +0 -0
- data/doc/ex/images/duck5.gif +0 -0
- data/doc/ex/images/duck6.gif +0 -0
- data/doc/ex/images/duck7.gif +0 -0
- data/doc/ex/images/duck8.gif +0 -0
- data/doc/ex/images/duck9.gif +0 -0
- data/doc/ex/images/graydient230x6.gif +0 -0
- data/doc/ex/images/image_with_profile.jpg +0 -0
- data/doc/ex/images/logo400x83.gif +0 -0
- data/doc/ex/images/model.miff +0 -0
- data/doc/ex/images/notimplemented.gif +0 -0
- data/doc/ex/images/smile.miff +0 -0
- data/doc/ex/images/spin.gif +0 -0
- data/doc/ex/implode.rb +34 -0
- data/doc/ex/level.rb +11 -0
- data/doc/ex/level_colors.rb +11 -0
- data/doc/ex/line.rb +41 -0
- data/doc/ex/line01.rb +21 -0
- data/doc/ex/mask.rb +35 -0
- data/doc/ex/matte_fill_to_border.rb +39 -0
- data/doc/ex/matte_floodfill.rb +32 -0
- data/doc/ex/matte_replace.rb +39 -0
- data/doc/ex/median_filter.rb +28 -0
- data/doc/ex/modulate.rb +11 -0
- data/doc/ex/mono.rb +23 -0
- data/doc/ex/morph.rb +25 -0
- data/doc/ex/mosaic.rb +35 -0
- data/doc/ex/motion_blur.rb +11 -0
- data/doc/ex/negate.rb +11 -0
- data/doc/ex/negate_channel.rb +9 -0
- data/doc/ex/nested_rvg.rb +21 -0
- data/doc/ex/nonzero.rb +42 -0
- data/doc/ex/normalize.rb +11 -0
- data/doc/ex/oil_paint.rb +11 -0
- data/doc/ex/opacity.rb +37 -0
- data/doc/ex/ordered_dither.rb +11 -0
- data/doc/ex/path.rb +63 -0
- data/doc/ex/pattern1.rb +25 -0
- data/doc/ex/pattern2.rb +26 -0
- data/doc/ex/polaroid.rb +27 -0
- data/doc/ex/polygon.rb +23 -0
- data/doc/ex/polygon01.rb +21 -0
- data/doc/ex/polyline.rb +22 -0
- data/doc/ex/polyline01.rb +21 -0
- data/doc/ex/posterize.rb +8 -0
- data/doc/ex/preview.rb +8 -0
- data/doc/ex/qbezierpath.rb +52 -0
- data/doc/ex/quad01.rb +34 -0
- data/doc/ex/quantize-m.rb +25 -0
- data/doc/ex/radial_blur.rb +9 -0
- data/doc/ex/raise.rb +8 -0
- data/doc/ex/random_threshold_channel.rb +13 -0
- data/doc/ex/rect01.rb +14 -0
- data/doc/ex/rect02.rb +20 -0
- data/doc/ex/rectangle.rb +34 -0
- data/doc/ex/reduce_noise.rb +28 -0
- data/doc/ex/remap.rb +11 -0
- data/doc/ex/remap_images.rb +19 -0
- data/doc/ex/resize_to_fill.rb +8 -0
- data/doc/ex/resize_to_fit.rb +8 -0
- data/doc/ex/roll.rb +9 -0
- data/doc/ex/rotate.rb +44 -0
- data/doc/ex/rotate_f.rb +14 -0
- data/doc/ex/roundrect.rb +33 -0
- data/doc/ex/rubyname.rb +30 -0
- data/doc/ex/rvg_clippath.rb +12 -0
- data/doc/ex/rvg_linecap.rb +42 -0
- data/doc/ex/rvg_linejoin.rb +40 -0
- data/doc/ex/rvg_opacity.rb +18 -0
- data/doc/ex/rvg_pattern.rb +26 -0
- data/doc/ex/rvg_stroke_dasharray.rb +11 -0
- data/doc/ex/segment.rb +11 -0
- data/doc/ex/sepiatone.rb +7 -0
- data/doc/ex/shade.rb +11 -0
- data/doc/ex/shadow.rb +30 -0
- data/doc/ex/shave.rb +15 -0
- data/doc/ex/shear.rb +10 -0
- data/doc/ex/sketch.rb +17 -0
- data/doc/ex/skewx.rb +51 -0
- data/doc/ex/skewy.rb +47 -0
- data/doc/ex/smile.rb +125 -0
- data/doc/ex/solarize.rb +11 -0
- data/doc/ex/sparse_color.rb +54 -0
- data/doc/ex/splice.rb +8 -0
- data/doc/ex/spread.rb +11 -0
- data/doc/ex/stegano.rb +55 -0
- data/doc/ex/stroke_dasharray.rb +42 -0
- data/doc/ex/stroke_fill.rb +10 -0
- data/doc/ex/stroke_linecap.rb +44 -0
- data/doc/ex/stroke_linejoin.rb +48 -0
- data/doc/ex/stroke_width.rb +49 -0
- data/doc/ex/swirl.rb +17 -0
- data/doc/ex/text.rb +37 -0
- data/doc/ex/text01.rb +16 -0
- data/doc/ex/text_align.rb +36 -0
- data/doc/ex/text_antialias.rb +37 -0
- data/doc/ex/text_styles.rb +19 -0
- data/doc/ex/text_undercolor.rb +28 -0
- data/doc/ex/texture_fill_to_border.rb +34 -0
- data/doc/ex/texture_floodfill.rb +32 -0
- data/doc/ex/texturefill.rb +24 -0
- data/doc/ex/threshold.rb +13 -0
- data/doc/ex/to_blob.rb +13 -0
- data/doc/ex/translate.rb +39 -0
- data/doc/ex/transparent.rb +38 -0
- data/doc/ex/transpose.rb +9 -0
- data/doc/ex/transverse.rb +9 -0
- data/doc/ex/tref01.rb +24 -0
- data/doc/ex/triangle01.rb +15 -0
- data/doc/ex/trim.rb +23 -0
- data/doc/ex/tspan01.rb +17 -0
- data/doc/ex/tspan02.rb +17 -0
- data/doc/ex/tspan03.rb +19 -0
- data/doc/ex/unsharp_mask.rb +28 -0
- data/doc/ex/viewex.rb +33 -0
- data/doc/ex/vignette.rb +12 -0
- data/doc/ex/watermark.rb +27 -0
- data/doc/ex/wave.rb +9 -0
- data/doc/ex/wet_floor.rb +58 -0
- data/doc/ex/writing_mode01.rb +26 -0
- data/doc/ex/writing_mode02.rb +26 -0
- data/doc/ilist.html +2056 -0
- data/doc/image1.html +4680 -0
- data/doc/image2.html +3665 -0
- data/doc/image3.html +4522 -0
- data/doc/imageattrs.html +1638 -0
- data/doc/imusage.html +514 -0
- data/doc/index.html +416 -0
- data/doc/info.html +1499 -0
- data/doc/magick.html +565 -0
- data/doc/optequiv.html +2435 -0
- data/doc/rvg.html +975 -0
- data/doc/rvgclip.html +248 -0
- data/doc/rvggroup.html +305 -0
- data/doc/rvgimage.html +289 -0
- data/doc/rvgpattern.html +475 -0
- data/doc/rvgshape.html +406 -0
- data/doc/rvgstyle.html +270 -0
- data/doc/rvgtext.html +465 -0
- data/doc/rvgtspan.html +238 -0
- data/doc/rvgtut.html +530 -0
- data/doc/rvguse.html +145 -0
- data/doc/rvgxform.html +294 -0
- data/doc/scripts/doc.js +22 -0
- data/doc/scripts/stripeTables.js +23 -0
- data/doc/struct.html +1339 -0
- data/doc/usage.html +1621 -0
- data/examples/constitute.rb +7 -0
- data/examples/crop_with_gravity.rb +42 -0
- data/examples/demo.rb +324 -0
- data/examples/describe.rb +43 -0
- data/examples/find_similar_region.rb +34 -0
- data/examples/histogram.rb +321 -0
- data/examples/identify.rb +185 -0
- data/examples/image_opacity.rb +29 -0
- data/examples/import_export.rb +31 -0
- data/examples/pattern_fill.rb +38 -0
- data/examples/rotating_text.rb +44 -0
- data/examples/spinner.rb +49 -0
- data/examples/thumbnail.rb +64 -0
- data/examples/vignette.rb +78 -0
- data/ext/RMagick/extconf.rb +548 -0
- data/ext/RMagick/rmagick.c +401 -0
- data/ext/RMagick/rmagick.h +1287 -0
- data/ext/RMagick/rmdraw.c +2022 -0
- data/ext/RMagick/rmenum.c +1235 -0
- data/ext/RMagick/rmfill.c +720 -0
- data/ext/RMagick/rmilist.c +1270 -0
- data/ext/RMagick/rmimage.c +15427 -0
- data/ext/RMagick/rminfo.c +2590 -0
- data/ext/RMagick/rmmain.c +1741 -0
- data/ext/RMagick/rmmontage.c +519 -0
- data/ext/RMagick/rmpixel.c +1114 -0
- data/ext/RMagick/rmstruct.c +1124 -0
- data/ext/RMagick/rmutil.c +1754 -0
- data/lib/rmagick.rb +1 -0
- data/lib/rmagick/version.rb +6 -0
- data/lib/rmagick_internal.rb +1947 -0
- data/lib/rvg/clippath.rb +45 -0
- data/lib/rvg/container.rb +122 -0
- data/lib/rvg/deep_equal.rb +52 -0
- data/lib/rvg/describable.rb +47 -0
- data/lib/rvg/embellishable.rb +391 -0
- data/lib/rvg/misc.rb +723 -0
- data/lib/rvg/paint.rb +50 -0
- data/lib/rvg/pathdata.rb +126 -0
- data/lib/rvg/rvg.rb +283 -0
- data/lib/rvg/stretchable.rb +165 -0
- data/lib/rvg/stylable.rb +116 -0
- data/lib/rvg/text.rb +172 -0
- data/lib/rvg/transformable.rb +126 -0
- data/lib/rvg/units.rb +63 -0
- data/rmagick.gemspec +46 -0
- data/spec/rmagick/ImageList1_spec.rb +24 -0
- data/spec/rmagick/draw_spec.rb +156 -0
- data/spec/rmagick/image/blue_shift_spec.rb +16 -0
- data/spec/rmagick/image/composite_spec.rb +140 -0
- data/spec/rmagick/image/constitute_spec.rb +15 -0
- data/spec/rmagick/image/dispatch_spec.rb +18 -0
- data/spec/rmagick/image/from_blob_spec.rb +14 -0
- data/spec/rmagick/image/ping_spec.rb +14 -0
- data/spec/rmagick/image/properties_spec.rb +29 -0
- data/spec/spec_helper.rb +4 -0
- data/test/Image1.rb +565 -0
- data/test/Image2.rb +1304 -0
- data/test/Image3.rb +1030 -0
- data/test/ImageList1.rb +806 -0
- data/test/ImageList2.rb +385 -0
- data/test/Image_attributes.rb +697 -0
- data/test/Import_Export.rb +121 -0
- data/test/Info.rb +345 -0
- data/test/Magick.rb +321 -0
- data/test/Pixel.rb +116 -0
- data/test/Preview.rb +57 -0
- data/test/cmyk.icm +0 -0
- data/test/srgb.icm +0 -0
- data/test/test_all_basic.rb +38 -0
- data/test/tmpnam_test.rb +50 -0
- data/wercker.yml +10 -0
- 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
|
+
}
|