rgd 0.4.1a-x86-mingw32
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.
- data/BSDL +22 -0
- data/COPYING +4 -0
- data/README +3 -0
- data/Rakefile +48 -0
- data/ext/rgd/extconf.rb +15 -0
- data/ext/rgd/gd_playground/bmp.h +114 -0
- data/ext/rgd/gd_playground/gd_bmp.c +1130 -0
- data/ext/rgd/gd_playground/gdhelpers.h +61 -0
- data/ext/rgd/rgd.c +2976 -0
- data/lib/rgd/1.8/rgd.so +0 -0
- data/lib/rgd/1.9/rgd.so +0 -0
- data/lib/rgd.rb +2 -0
- data/test/main.rb +22 -0
- data/test/mtest_stringft_cn.png +0 -0
- data/test/mtest_stringft_cn.rb +20 -0
- data/test/test_arc.png +0 -0
- data/test/test_arc.rb +10 -0
- data/test/test_color_closest.rb +32 -0
- data/test/test_color_exact.rb +37 -0
- data/test/test_color_resolve.rb +42 -0
- data/test/test_color_transparent.rb +16 -0
- data/test/test_copy.png +0 -0
- data/test/test_copy.rb +13 -0
- data/test/test_copy_rotated.png +0 -0
- data/test/test_copy_rotated.rb +14 -0
- data/test/test_fill_1.png +0 -0
- data/test/test_fill_1.rb +9 -0
- data/test/test_fill_2.png +0 -0
- data/test/test_fill_2.rb +30 -0
- data/test/test_fill_3.png +0 -0
- data/test/test_fill_3.rb +35 -0
- data/test/test_fill_4.png +0 -0
- data/test/test_fill_4.rb +25 -0
- data/test/test_fill_to_border.rb +14 -0
- data/test/test_filled_ellipse.png +0 -0
- data/test/test_filled_ellipse.rb +8 -0
- data/test/test_filled_rectangle.rb +46 -0
- data/test/test_line_1.png +0 -0
- data/test/test_line_1.rb +18 -0
- data/test/test_line_2.rb +18 -0
- data/test/test_line_3.rb +40 -0
- data/test/test_line_3_1.png +0 -0
- data/test/test_line_3_2.png +0 -0
- data/test/test_line_3_3.png +0 -0
- data/test/test_line_3_4.png +0 -0
- data/test/test_line_3_5.png +0 -0
- data/test/test_line_3_6.png +0 -0
- data/test/test_line_3_7.png +0 -0
- data/test/test_line_3_8.png +0 -0
- data/test/test_tiled.png +0 -0
- data/test/test_tiled.rb +15 -0
- metadata +117 -0
data/ext/rgd/rgd.c
ADDED
@@ -0,0 +1,2976 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#include "gd.h"
|
4
|
+
#include "gdfontg.h"
|
5
|
+
#include "gdfontl.h"
|
6
|
+
#include "gdfontmb.h"
|
7
|
+
#include "gdfonts.h"
|
8
|
+
#include "gdfontt.h"
|
9
|
+
#ifndef HAVE_GDIMAGECREATEFROMBMP
|
10
|
+
// get from https://svn.php.net/viewvc/gd/trunk/playground/gdbmp/
|
11
|
+
#include "gd_playground/gd_bmp.c"
|
12
|
+
#endif
|
13
|
+
|
14
|
+
#ifdef WIN32
|
15
|
+
#define GDFUNC __stdcall
|
16
|
+
#else
|
17
|
+
#define GDFUNC
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#ifdef _MSC_VER
|
21
|
+
#define strcasecmp stricmp
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#define SetIntIfQnil(v, i) if (v == Qnil) v = INT2NUM(i)
|
25
|
+
#define STR2SYM(v) ID2SYM(rb_intern(v))
|
26
|
+
|
27
|
+
typedef enum ImageFormat { FMT_UNKNOW, FMT_JPEG, FMT_PNG, FMT_GIF, FMT_GD, FMT_GD2, FMT_WBMP, FMT_XBM, FMT_XPM, FMT_BMP } ImageFormat;
|
28
|
+
|
29
|
+
static VALUE rb_mRGD, rb_eRGDError, rb_cFont, rb_cImage;
|
30
|
+
|
31
|
+
static ImageFormat m_image_detect_format_by_ext(const char* ext) {
|
32
|
+
if (strcasecmp(ext, "jpg") == 0 || strcasecmp(ext, "jpeg") == 0) {
|
33
|
+
return FMT_JPEG;
|
34
|
+
} else if (strcasecmp(ext, "png") == 0) {
|
35
|
+
return FMT_PNG;
|
36
|
+
} else if (strcasecmp(ext, "gif") == 0) {
|
37
|
+
return FMT_GIF;
|
38
|
+
} else if (strcasecmp(ext, "bmp") == 0) {
|
39
|
+
return FMT_BMP;
|
40
|
+
} else if (strcasecmp(ext, "gd2") == 0) {
|
41
|
+
return FMT_GD2;
|
42
|
+
} else if (strcasecmp(ext, "gd") == 0) {
|
43
|
+
return FMT_GD;
|
44
|
+
} else if (strcasecmp(ext, "wbmp") == 0) {
|
45
|
+
return FMT_WBMP;
|
46
|
+
} else if (strcasecmp(ext, "xbm") == 0) {
|
47
|
+
return FMT_XBM;
|
48
|
+
} else if (strcasecmp(ext, "xpm") == 0) {
|
49
|
+
return FMT_XPM;
|
50
|
+
} else {
|
51
|
+
return FMT_UNKNOW;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
static ImageFormat m_image_detect_format_by_magic(const char* buf) {
|
56
|
+
if (strncmp(buf, "\377\330\377\340", 4) == 0 || strncmp(buf, "\377\330\377\341", 4) == 0 || strncmp(buf, "\377\330\377\356", 4) == 0) {
|
57
|
+
return FMT_JPEG;
|
58
|
+
} else if (strncmp(buf, "\x89PNG", 4) == 0) {
|
59
|
+
return FMT_PNG;
|
60
|
+
} else if (strncmp(buf, "GIF89a", 6) == 0) {
|
61
|
+
return FMT_GIF;
|
62
|
+
} else if (strncmp(buf, "BM", 2) == 0 || strncmp(buf, "BA", 2) == 0 || strncmp(buf, "CI", 2) == 0 || strncmp(buf, "CP", 2) == 0 || strncmp(buf, "IC", 2) == 0 || strncmp(buf, "PT", 2) == 0) {
|
63
|
+
return FMT_BMP;
|
64
|
+
} else if (strncmp(buf, "gd2\0", 4) == 0) {
|
65
|
+
return FMT_GD2;
|
66
|
+
} else if (strncmp(buf, "\xFF\xFF", 2) == 0 || strncmp(buf, "\xFF\xFE", 2) == 0) {
|
67
|
+
return FMT_GD;
|
68
|
+
} else if (strncmp(buf, "/* XPM */", 9) == 0) {
|
69
|
+
return FMT_XPM;
|
70
|
+
} else if (strncmp(buf, "\0\0", 2) == 0) {
|
71
|
+
return FMT_WBMP;
|
72
|
+
} else {
|
73
|
+
return FMT_UNKNOW;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
static VALUE m_named_colors() {
|
78
|
+
VALUE h = rb_hash_new();
|
79
|
+
rb_hash_aset(h, rb_str_new2("aliceblue"), rb_ary_new3(4, INT2NUM(0xF0), INT2NUM(0xF8), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
80
|
+
rb_hash_aset(h, rb_str_new2("antiquewhite"), rb_ary_new3(4, INT2NUM(0xFA), INT2NUM(0xEB), INT2NUM(0xD7), INT2NUM(gdAlphaOpaque)));
|
81
|
+
rb_hash_aset(h, rb_str_new2("aqua"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
82
|
+
rb_hash_aset(h, rb_str_new2("aquamarine"), rb_ary_new3(4, INT2NUM(0x7F), INT2NUM(0xFF), INT2NUM(0xD4), INT2NUM(gdAlphaOpaque)));
|
83
|
+
rb_hash_aset(h, rb_str_new2("azure"), rb_ary_new3(4, INT2NUM(0xF0), INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
84
|
+
rb_hash_aset(h, rb_str_new2("beige"), rb_ary_new3(4, INT2NUM(0xF5), INT2NUM(0xF5), INT2NUM(0xDC), INT2NUM(gdAlphaOpaque)));
|
85
|
+
rb_hash_aset(h, rb_str_new2("bisque"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xE4), INT2NUM(0xC4), INT2NUM(gdAlphaOpaque)));
|
86
|
+
rb_hash_aset(h, rb_str_new2("black"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x00), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
87
|
+
rb_hash_aset(h, rb_str_new2("blanchedalmond"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xEB), INT2NUM(0xCD), INT2NUM(gdAlphaOpaque)));
|
88
|
+
rb_hash_aset(h, rb_str_new2("blue"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x00), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
89
|
+
rb_hash_aset(h, rb_str_new2("blueviolet"), rb_ary_new3(4, INT2NUM(0x8A), INT2NUM(0x2B), INT2NUM(0xE2), INT2NUM(gdAlphaOpaque)));
|
90
|
+
rb_hash_aset(h, rb_str_new2("brown"), rb_ary_new3(4, INT2NUM(0xA5), INT2NUM(0x2A), INT2NUM(0x2A), INT2NUM(gdAlphaOpaque)));
|
91
|
+
rb_hash_aset(h, rb_str_new2("burlywood"), rb_ary_new3(4, INT2NUM(0xDE), INT2NUM(0xB8), INT2NUM(0x87), INT2NUM(gdAlphaOpaque)));
|
92
|
+
rb_hash_aset(h, rb_str_new2("cadetblue"), rb_ary_new3(4, INT2NUM(0x5F), INT2NUM(0x9E), INT2NUM(0xA0), INT2NUM(gdAlphaOpaque)));
|
93
|
+
rb_hash_aset(h, rb_str_new2("chartreuse"), rb_ary_new3(4, INT2NUM(0x7F), INT2NUM(0xFF), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
94
|
+
rb_hash_aset(h, rb_str_new2("chocolate"), rb_ary_new3(4, INT2NUM(0xD2), INT2NUM(0x69), INT2NUM(0x1E), INT2NUM(gdAlphaOpaque)));
|
95
|
+
rb_hash_aset(h, rb_str_new2("coral"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x7F), INT2NUM(0x50), INT2NUM(gdAlphaOpaque)));
|
96
|
+
rb_hash_aset(h, rb_str_new2("cornflowerblue"), rb_ary_new3(4, INT2NUM(0x64), INT2NUM(0x95), INT2NUM(0xED), INT2NUM(gdAlphaOpaque)));
|
97
|
+
rb_hash_aset(h, rb_str_new2("cornsilk"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xF8), INT2NUM(0xDC), INT2NUM(gdAlphaOpaque)));
|
98
|
+
rb_hash_aset(h, rb_str_new2("crimson"), rb_ary_new3(4, INT2NUM(0xDC), INT2NUM(0x14), INT2NUM(0x3C), INT2NUM(gdAlphaOpaque)));
|
99
|
+
rb_hash_aset(h, rb_str_new2("cyan"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
100
|
+
rb_hash_aset(h, rb_str_new2("darkblue"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x00), INT2NUM(0x8B), INT2NUM(gdAlphaOpaque)));
|
101
|
+
rb_hash_aset(h, rb_str_new2("darkcyan"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x8B), INT2NUM(0x8B), INT2NUM(gdAlphaOpaque)));
|
102
|
+
rb_hash_aset(h, rb_str_new2("darkgoldenrod"), rb_ary_new3(4, INT2NUM(0xB8), INT2NUM(0x86), INT2NUM(0x0B), INT2NUM(gdAlphaOpaque)));
|
103
|
+
rb_hash_aset(h, rb_str_new2("darkgray"), rb_ary_new3(4, INT2NUM(0xA9), INT2NUM(0xA9), INT2NUM(0xA9), INT2NUM(gdAlphaOpaque)));
|
104
|
+
rb_hash_aset(h, rb_str_new2("darkgrey"), rb_ary_new3(4, INT2NUM(0xA9), INT2NUM(0xA9), INT2NUM(0xA9), INT2NUM(gdAlphaOpaque)));
|
105
|
+
rb_hash_aset(h, rb_str_new2("darkgreen"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x64), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
106
|
+
rb_hash_aset(h, rb_str_new2("darkkhaki"), rb_ary_new3(4, INT2NUM(0xBD), INT2NUM(0xB7), INT2NUM(0x6B), INT2NUM(gdAlphaOpaque)));
|
107
|
+
rb_hash_aset(h, rb_str_new2("darkmagenta"), rb_ary_new3(4, INT2NUM(0x8B), INT2NUM(0x00), INT2NUM(0x8B), INT2NUM(gdAlphaOpaque)));
|
108
|
+
rb_hash_aset(h, rb_str_new2("darkolivegreen"), rb_ary_new3(4, INT2NUM(0x55), INT2NUM(0x6B), INT2NUM(0x2F), INT2NUM(gdAlphaOpaque)));
|
109
|
+
rb_hash_aset(h, rb_str_new2("darkorange"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x8C), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
110
|
+
rb_hash_aset(h, rb_str_new2("darkorchid"), rb_ary_new3(4, INT2NUM(0x99), INT2NUM(0x32), INT2NUM(0xCC), INT2NUM(gdAlphaOpaque)));
|
111
|
+
rb_hash_aset(h, rb_str_new2("darkred"), rb_ary_new3(4, INT2NUM(0x8B), INT2NUM(0x00), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
112
|
+
rb_hash_aset(h, rb_str_new2("darksalmon"), rb_ary_new3(4, INT2NUM(0xE9), INT2NUM(0x96), INT2NUM(0x7A), INT2NUM(gdAlphaOpaque)));
|
113
|
+
rb_hash_aset(h, rb_str_new2("darkseagreen"), rb_ary_new3(4, INT2NUM(0x8F), INT2NUM(0xBC), INT2NUM(0x8F), INT2NUM(gdAlphaOpaque)));
|
114
|
+
rb_hash_aset(h, rb_str_new2("darkslateblue"), rb_ary_new3(4, INT2NUM(0x48), INT2NUM(0x3D), INT2NUM(0x8B), INT2NUM(gdAlphaOpaque)));
|
115
|
+
rb_hash_aset(h, rb_str_new2("darkslategray"), rb_ary_new3(4, INT2NUM(0x2F), INT2NUM(0x4F), INT2NUM(0x4F), INT2NUM(gdAlphaOpaque)));
|
116
|
+
rb_hash_aset(h, rb_str_new2("darkslategrey"), rb_ary_new3(4, INT2NUM(0x2F), INT2NUM(0x4F), INT2NUM(0x4F), INT2NUM(gdAlphaOpaque)));
|
117
|
+
rb_hash_aset(h, rb_str_new2("darkturquoise"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0xCE), INT2NUM(0xD1), INT2NUM(gdAlphaOpaque)));
|
118
|
+
rb_hash_aset(h, rb_str_new2("darkviolet"), rb_ary_new3(4, INT2NUM(0x94), INT2NUM(0x00), INT2NUM(0xD3), INT2NUM(gdAlphaOpaque)));
|
119
|
+
rb_hash_aset(h, rb_str_new2("deeppink"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x14), INT2NUM(0x93), INT2NUM(gdAlphaOpaque)));
|
120
|
+
rb_hash_aset(h, rb_str_new2("deepskyblue"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0xBF), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
121
|
+
rb_hash_aset(h, rb_str_new2("dimgray"), rb_ary_new3(4, INT2NUM(0x69), INT2NUM(0x69), INT2NUM(0x69), INT2NUM(gdAlphaOpaque)));
|
122
|
+
rb_hash_aset(h, rb_str_new2("dimgrey"), rb_ary_new3(4, INT2NUM(0x69), INT2NUM(0x69), INT2NUM(0x69), INT2NUM(gdAlphaOpaque)));
|
123
|
+
rb_hash_aset(h, rb_str_new2("dodgerblue"), rb_ary_new3(4, INT2NUM(0x1E), INT2NUM(0x90), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
124
|
+
rb_hash_aset(h, rb_str_new2("firebrick"), rb_ary_new3(4, INT2NUM(0xB2), INT2NUM(0x22), INT2NUM(0x22), INT2NUM(gdAlphaOpaque)));
|
125
|
+
rb_hash_aset(h, rb_str_new2("floralwhite"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xFA), INT2NUM(0xF0), INT2NUM(gdAlphaOpaque)));
|
126
|
+
rb_hash_aset(h, rb_str_new2("forestgreen"), rb_ary_new3(4, INT2NUM(0x22), INT2NUM(0x8B), INT2NUM(0x22), INT2NUM(gdAlphaOpaque)));
|
127
|
+
rb_hash_aset(h, rb_str_new2("fuchsia"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x00), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
128
|
+
rb_hash_aset(h, rb_str_new2("gainsboro"), rb_ary_new3(4, INT2NUM(0xDC), INT2NUM(0xDC), INT2NUM(0xDC), INT2NUM(gdAlphaOpaque)));
|
129
|
+
rb_hash_aset(h, rb_str_new2("ghostwhite"), rb_ary_new3(4, INT2NUM(0xF8), INT2NUM(0xF8), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
130
|
+
rb_hash_aset(h, rb_str_new2("gold"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xD7), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
131
|
+
rb_hash_aset(h, rb_str_new2("goldenrod"), rb_ary_new3(4, INT2NUM(0xDA), INT2NUM(0xA5), INT2NUM(0x20), INT2NUM(gdAlphaOpaque)));
|
132
|
+
rb_hash_aset(h, rb_str_new2("gray"), rb_ary_new3(4, INT2NUM(0x80), INT2NUM(0x80), INT2NUM(0x80), INT2NUM(gdAlphaOpaque)));
|
133
|
+
rb_hash_aset(h, rb_str_new2("grey"), rb_ary_new3(4, INT2NUM(0x80), INT2NUM(0x80), INT2NUM(0x80), INT2NUM(gdAlphaOpaque)));
|
134
|
+
rb_hash_aset(h, rb_str_new2("green"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x80), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
135
|
+
rb_hash_aset(h, rb_str_new2("greenyellow"), rb_ary_new3(4, INT2NUM(0xAD), INT2NUM(0xFF), INT2NUM(0x2F), INT2NUM(gdAlphaOpaque)));
|
136
|
+
rb_hash_aset(h, rb_str_new2("honeydew"), rb_ary_new3(4, INT2NUM(0xF0), INT2NUM(0xFF), INT2NUM(0xF0), INT2NUM(gdAlphaOpaque)));
|
137
|
+
rb_hash_aset(h, rb_str_new2("hotpink"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x69), INT2NUM(0xB4), INT2NUM(gdAlphaOpaque)));
|
138
|
+
rb_hash_aset(h, rb_str_new2("indianred"), rb_ary_new3(4, INT2NUM(0xCD), INT2NUM(0x5C), INT2NUM(0x5C), INT2NUM(gdAlphaOpaque)));
|
139
|
+
rb_hash_aset(h, rb_str_new2("indigo"), rb_ary_new3(4, INT2NUM(0x4B), INT2NUM(0x00), INT2NUM(0x82), INT2NUM(gdAlphaOpaque)));
|
140
|
+
rb_hash_aset(h, rb_str_new2("ivory"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(0xF0), INT2NUM(gdAlphaOpaque)));
|
141
|
+
rb_hash_aset(h, rb_str_new2("khaki"), rb_ary_new3(4, INT2NUM(0xF0), INT2NUM(0xE6), INT2NUM(0x8C), INT2NUM(gdAlphaOpaque)));
|
142
|
+
rb_hash_aset(h, rb_str_new2("lavender"), rb_ary_new3(4, INT2NUM(0xE6), INT2NUM(0xE6), INT2NUM(0xFA), INT2NUM(gdAlphaOpaque)));
|
143
|
+
rb_hash_aset(h, rb_str_new2("lavenderblush"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xF0), INT2NUM(0xF5), INT2NUM(gdAlphaOpaque)));
|
144
|
+
rb_hash_aset(h, rb_str_new2("lawngreen"), rb_ary_new3(4, INT2NUM(0x7C), INT2NUM(0xFC), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
145
|
+
rb_hash_aset(h, rb_str_new2("lemonchiffon"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xFA), INT2NUM(0xCD), INT2NUM(gdAlphaOpaque)));
|
146
|
+
rb_hash_aset(h, rb_str_new2("lightblue"), rb_ary_new3(4, INT2NUM(0xAD), INT2NUM(0xD8), INT2NUM(0xE6), INT2NUM(gdAlphaOpaque)));
|
147
|
+
rb_hash_aset(h, rb_str_new2("lightcoral"), rb_ary_new3(4, INT2NUM(0xF0), INT2NUM(0x80), INT2NUM(0x80), INT2NUM(gdAlphaOpaque)));
|
148
|
+
rb_hash_aset(h, rb_str_new2("lightcyan"), rb_ary_new3(4, INT2NUM(0xE0), INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
149
|
+
rb_hash_aset(h, rb_str_new2("lightgoldenrodyellow"), rb_ary_new3(4, INT2NUM(0xFA), INT2NUM(0xFA), INT2NUM(0xD2), INT2NUM(gdAlphaOpaque)));
|
150
|
+
rb_hash_aset(h, rb_str_new2("lightgray"), rb_ary_new3(4, INT2NUM(0xD3), INT2NUM(0xD3), INT2NUM(0xD3), INT2NUM(gdAlphaOpaque)));
|
151
|
+
rb_hash_aset(h, rb_str_new2("lightgrey"), rb_ary_new3(4, INT2NUM(0xD3), INT2NUM(0xD3), INT2NUM(0xD3), INT2NUM(gdAlphaOpaque)));
|
152
|
+
rb_hash_aset(h, rb_str_new2("lightgreen"), rb_ary_new3(4, INT2NUM(0x90), INT2NUM(0xEE), INT2NUM(0x90), INT2NUM(gdAlphaOpaque)));
|
153
|
+
rb_hash_aset(h, rb_str_new2("lightpink"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xB6), INT2NUM(0xC1), INT2NUM(gdAlphaOpaque)));
|
154
|
+
rb_hash_aset(h, rb_str_new2("lightsalmon"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xA0), INT2NUM(0x7A), INT2NUM(gdAlphaOpaque)));
|
155
|
+
rb_hash_aset(h, rb_str_new2("lightseagreen"), rb_ary_new3(4, INT2NUM(0x20), INT2NUM(0xB2), INT2NUM(0xAA), INT2NUM(gdAlphaOpaque)));
|
156
|
+
rb_hash_aset(h, rb_str_new2("lightskyblue"), rb_ary_new3(4, INT2NUM(0x87), INT2NUM(0xCE), INT2NUM(0xFA), INT2NUM(gdAlphaOpaque)));
|
157
|
+
rb_hash_aset(h, rb_str_new2("lightslategray"), rb_ary_new3(4, INT2NUM(0x77), INT2NUM(0x88), INT2NUM(0x99), INT2NUM(gdAlphaOpaque)));
|
158
|
+
rb_hash_aset(h, rb_str_new2("lightslategrey"), rb_ary_new3(4, INT2NUM(0x77), INT2NUM(0x88), INT2NUM(0x99), INT2NUM(gdAlphaOpaque)));
|
159
|
+
rb_hash_aset(h, rb_str_new2("lightsteelblue"), rb_ary_new3(4, INT2NUM(0xB0), INT2NUM(0xC4), INT2NUM(0xDE), INT2NUM(gdAlphaOpaque)));
|
160
|
+
rb_hash_aset(h, rb_str_new2("lightyellow"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(0xE0), INT2NUM(gdAlphaOpaque)));
|
161
|
+
rb_hash_aset(h, rb_str_new2("lime"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0xFF), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
162
|
+
rb_hash_aset(h, rb_str_new2("limegreen"), rb_ary_new3(4, INT2NUM(0x32), INT2NUM(0xCD), INT2NUM(0x32), INT2NUM(gdAlphaOpaque)));
|
163
|
+
rb_hash_aset(h, rb_str_new2("linen"), rb_ary_new3(4, INT2NUM(0xFA), INT2NUM(0xF0), INT2NUM(0xE6), INT2NUM(gdAlphaOpaque)));
|
164
|
+
rb_hash_aset(h, rb_str_new2("magenta"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x00), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
165
|
+
rb_hash_aset(h, rb_str_new2("maroon"), rb_ary_new3(4, INT2NUM(0x80), INT2NUM(0x00), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
166
|
+
rb_hash_aset(h, rb_str_new2("mediumaquamarine"), rb_ary_new3(4, INT2NUM(0x66), INT2NUM(0xCD), INT2NUM(0xAA), INT2NUM(gdAlphaOpaque)));
|
167
|
+
rb_hash_aset(h, rb_str_new2("mediumblue"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x00), INT2NUM(0xCD), INT2NUM(gdAlphaOpaque)));
|
168
|
+
rb_hash_aset(h, rb_str_new2("mediumorchid"), rb_ary_new3(4, INT2NUM(0xBA), INT2NUM(0x55), INT2NUM(0xD3), INT2NUM(gdAlphaOpaque)));
|
169
|
+
rb_hash_aset(h, rb_str_new2("mediumpurple"), rb_ary_new3(4, INT2NUM(0x93), INT2NUM(0x70), INT2NUM(0xD8), INT2NUM(gdAlphaOpaque)));
|
170
|
+
rb_hash_aset(h, rb_str_new2("mediumseagreen"), rb_ary_new3(4, INT2NUM(0x3C), INT2NUM(0xB3), INT2NUM(0x71), INT2NUM(gdAlphaOpaque)));
|
171
|
+
rb_hash_aset(h, rb_str_new2("mediumslateblue"), rb_ary_new3(4, INT2NUM(0x7B), INT2NUM(0x68), INT2NUM(0xEE), INT2NUM(gdAlphaOpaque)));
|
172
|
+
rb_hash_aset(h, rb_str_new2("mediumspringgreen"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0xFA), INT2NUM(0x9A), INT2NUM(gdAlphaOpaque)));
|
173
|
+
rb_hash_aset(h, rb_str_new2("mediumturquoise"), rb_ary_new3(4, INT2NUM(0x48), INT2NUM(0xD1), INT2NUM(0xCC), INT2NUM(gdAlphaOpaque)));
|
174
|
+
rb_hash_aset(h, rb_str_new2("mediumvioletred"), rb_ary_new3(4, INT2NUM(0xC7), INT2NUM(0x15), INT2NUM(0x85), INT2NUM(gdAlphaOpaque)));
|
175
|
+
rb_hash_aset(h, rb_str_new2("midnightblue"), rb_ary_new3(4, INT2NUM(0x19), INT2NUM(0x19), INT2NUM(0x70), INT2NUM(gdAlphaOpaque)));
|
176
|
+
rb_hash_aset(h, rb_str_new2("mintcream"), rb_ary_new3(4, INT2NUM(0xF5), INT2NUM(0xFF), INT2NUM(0xFA), INT2NUM(gdAlphaOpaque)));
|
177
|
+
rb_hash_aset(h, rb_str_new2("mistyrose"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xE4), INT2NUM(0xE1), INT2NUM(gdAlphaOpaque)));
|
178
|
+
rb_hash_aset(h, rb_str_new2("moccasin"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xE4), INT2NUM(0xB5), INT2NUM(gdAlphaOpaque)));
|
179
|
+
rb_hash_aset(h, rb_str_new2("navajowhite"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xDE), INT2NUM(0xAD), INT2NUM(gdAlphaOpaque)));
|
180
|
+
rb_hash_aset(h, rb_str_new2("navy"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x00), INT2NUM(0x80), INT2NUM(gdAlphaOpaque)));
|
181
|
+
rb_hash_aset(h, rb_str_new2("oldlace"), rb_ary_new3(4, INT2NUM(0xFD), INT2NUM(0xF5), INT2NUM(0xE6), INT2NUM(gdAlphaOpaque)));
|
182
|
+
rb_hash_aset(h, rb_str_new2("olive"), rb_ary_new3(4, INT2NUM(0x80), INT2NUM(0x80), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
183
|
+
rb_hash_aset(h, rb_str_new2("olivedrab"), rb_ary_new3(4, INT2NUM(0x6B), INT2NUM(0x8E), INT2NUM(0x23), INT2NUM(gdAlphaOpaque)));
|
184
|
+
rb_hash_aset(h, rb_str_new2("orange"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xA5), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
185
|
+
rb_hash_aset(h, rb_str_new2("orangered"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x45), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
186
|
+
rb_hash_aset(h, rb_str_new2("orchid"), rb_ary_new3(4, INT2NUM(0xDA), INT2NUM(0x70), INT2NUM(0xD6), INT2NUM(gdAlphaOpaque)));
|
187
|
+
rb_hash_aset(h, rb_str_new2("palegoldenrod"), rb_ary_new3(4, INT2NUM(0xEE), INT2NUM(0xE8), INT2NUM(0xAA), INT2NUM(gdAlphaOpaque)));
|
188
|
+
rb_hash_aset(h, rb_str_new2("palegreen"), rb_ary_new3(4, INT2NUM(0x98), INT2NUM(0xFB), INT2NUM(0x98), INT2NUM(gdAlphaOpaque)));
|
189
|
+
rb_hash_aset(h, rb_str_new2("paleturquoise"), rb_ary_new3(4, INT2NUM(0xAF), INT2NUM(0xEE), INT2NUM(0xEE), INT2NUM(gdAlphaOpaque)));
|
190
|
+
rb_hash_aset(h, rb_str_new2("palevioletred"), rb_ary_new3(4, INT2NUM(0xD8), INT2NUM(0x70), INT2NUM(0x93), INT2NUM(gdAlphaOpaque)));
|
191
|
+
rb_hash_aset(h, rb_str_new2("papayawhip"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xEF), INT2NUM(0xD5), INT2NUM(gdAlphaOpaque)));
|
192
|
+
rb_hash_aset(h, rb_str_new2("peachpuff"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xDA), INT2NUM(0xB9), INT2NUM(gdAlphaOpaque)));
|
193
|
+
rb_hash_aset(h, rb_str_new2("peru"), rb_ary_new3(4, INT2NUM(0xCD), INT2NUM(0x85), INT2NUM(0x3F), INT2NUM(gdAlphaOpaque)));
|
194
|
+
rb_hash_aset(h, rb_str_new2("pink"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xC0), INT2NUM(0xCB), INT2NUM(gdAlphaOpaque)));
|
195
|
+
rb_hash_aset(h, rb_str_new2("plum"), rb_ary_new3(4, INT2NUM(0xDD), INT2NUM(0xA0), INT2NUM(0xDD), INT2NUM(gdAlphaOpaque)));
|
196
|
+
rb_hash_aset(h, rb_str_new2("powderblue"), rb_ary_new3(4, INT2NUM(0xB0), INT2NUM(0xE0), INT2NUM(0xE6), INT2NUM(gdAlphaOpaque)));
|
197
|
+
rb_hash_aset(h, rb_str_new2("purple"), rb_ary_new3(4, INT2NUM(0x80), INT2NUM(0x00), INT2NUM(0x80), INT2NUM(gdAlphaOpaque)));
|
198
|
+
rb_hash_aset(h, rb_str_new2("red"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x00), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
199
|
+
rb_hash_aset(h, rb_str_new2("rosybrown"), rb_ary_new3(4, INT2NUM(0xBC), INT2NUM(0x8F), INT2NUM(0x8F), INT2NUM(gdAlphaOpaque)));
|
200
|
+
rb_hash_aset(h, rb_str_new2("royalblue"), rb_ary_new3(4, INT2NUM(0x41), INT2NUM(0x69), INT2NUM(0xE1), INT2NUM(gdAlphaOpaque)));
|
201
|
+
rb_hash_aset(h, rb_str_new2("saddlebrown"), rb_ary_new3(4, INT2NUM(0x8B), INT2NUM(0x45), INT2NUM(0x13), INT2NUM(gdAlphaOpaque)));
|
202
|
+
rb_hash_aset(h, rb_str_new2("salmon"), rb_ary_new3(4, INT2NUM(0xFA), INT2NUM(0x80), INT2NUM(0x72), INT2NUM(gdAlphaOpaque)));
|
203
|
+
rb_hash_aset(h, rb_str_new2("sandybrown"), rb_ary_new3(4, INT2NUM(0xF4), INT2NUM(0xA4), INT2NUM(0x60), INT2NUM(gdAlphaOpaque)));
|
204
|
+
rb_hash_aset(h, rb_str_new2("seagreen"), rb_ary_new3(4, INT2NUM(0x2E), INT2NUM(0x8B), INT2NUM(0x57), INT2NUM(gdAlphaOpaque)));
|
205
|
+
rb_hash_aset(h, rb_str_new2("seashell"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xF5), INT2NUM(0xEE), INT2NUM(gdAlphaOpaque)));
|
206
|
+
rb_hash_aset(h, rb_str_new2("sienna"), rb_ary_new3(4, INT2NUM(0xA0), INT2NUM(0x52), INT2NUM(0x2D), INT2NUM(gdAlphaOpaque)));
|
207
|
+
rb_hash_aset(h, rb_str_new2("silver"), rb_ary_new3(4, INT2NUM(0xC0), INT2NUM(0xC0), INT2NUM(0xC0), INT2NUM(gdAlphaOpaque)));
|
208
|
+
rb_hash_aset(h, rb_str_new2("skyblue"), rb_ary_new3(4, INT2NUM(0x87), INT2NUM(0xCE), INT2NUM(0xEB), INT2NUM(gdAlphaOpaque)));
|
209
|
+
rb_hash_aset(h, rb_str_new2("slateblue"), rb_ary_new3(4, INT2NUM(0x6A), INT2NUM(0x5A), INT2NUM(0xCD), INT2NUM(gdAlphaOpaque)));
|
210
|
+
rb_hash_aset(h, rb_str_new2("slategray"), rb_ary_new3(4, INT2NUM(0x70), INT2NUM(0x80), INT2NUM(0x90), INT2NUM(gdAlphaOpaque)));
|
211
|
+
rb_hash_aset(h, rb_str_new2("slategrey"), rb_ary_new3(4, INT2NUM(0x70), INT2NUM(0x80), INT2NUM(0x90), INT2NUM(gdAlphaOpaque)));
|
212
|
+
rb_hash_aset(h, rb_str_new2("snow"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xFA), INT2NUM(0xFA), INT2NUM(gdAlphaOpaque)));
|
213
|
+
rb_hash_aset(h, rb_str_new2("springgreen"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0xFF), INT2NUM(0x7F), INT2NUM(gdAlphaOpaque)));
|
214
|
+
rb_hash_aset(h, rb_str_new2("steelblue"), rb_ary_new3(4, INT2NUM(0x46), INT2NUM(0x82), INT2NUM(0xB4), INT2NUM(gdAlphaOpaque)));
|
215
|
+
rb_hash_aset(h, rb_str_new2("tan"), rb_ary_new3(4, INT2NUM(0xD2), INT2NUM(0xB4), INT2NUM(0x8C), INT2NUM(gdAlphaOpaque)));
|
216
|
+
rb_hash_aset(h, rb_str_new2("teal"), rb_ary_new3(4, INT2NUM(0x00), INT2NUM(0x80), INT2NUM(0x80), INT2NUM(gdAlphaOpaque)));
|
217
|
+
rb_hash_aset(h, rb_str_new2("thistle"), rb_ary_new3(4, INT2NUM(0xD8), INT2NUM(0xBF), INT2NUM(0xD8), INT2NUM(gdAlphaOpaque)));
|
218
|
+
rb_hash_aset(h, rb_str_new2("tomato"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0x63), INT2NUM(0x47), INT2NUM(gdAlphaOpaque)));
|
219
|
+
rb_hash_aset(h, rb_str_new2("turquoise"), rb_ary_new3(4, INT2NUM(0x40), INT2NUM(0xE0), INT2NUM(0xD0), INT2NUM(gdAlphaOpaque)));
|
220
|
+
rb_hash_aset(h, rb_str_new2("violet"), rb_ary_new3(4, INT2NUM(0xEE), INT2NUM(0x82), INT2NUM(0xEE), INT2NUM(gdAlphaOpaque)));
|
221
|
+
rb_hash_aset(h, rb_str_new2("wheat"), rb_ary_new3(4, INT2NUM(0xF5), INT2NUM(0xDE), INT2NUM(0xB3), INT2NUM(gdAlphaOpaque)));
|
222
|
+
rb_hash_aset(h, rb_str_new2("white"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(gdAlphaOpaque)));
|
223
|
+
rb_hash_aset(h, rb_str_new2("whitesmoke"), rb_ary_new3(4, INT2NUM(0xF5), INT2NUM(0xF5), INT2NUM(0xF5), INT2NUM(gdAlphaOpaque)));
|
224
|
+
rb_hash_aset(h, rb_str_new2("yellow"), rb_ary_new3(4, INT2NUM(0xFF), INT2NUM(0xFF), INT2NUM(0x00), INT2NUM(gdAlphaOpaque)));
|
225
|
+
rb_hash_aset(h, rb_str_new2("yellowgreen"), rb_ary_new3(4, INT2NUM(0x9A), INT2NUM(0xCD), INT2NUM(0x32), INT2NUM(gdAlphaOpaque)));
|
226
|
+
return h;
|
227
|
+
}
|
228
|
+
|
229
|
+
static VALUE m_scan_color_args(int argc, VALUE *argv) {
|
230
|
+
VALUE r, g, b, a;
|
231
|
+
int i;
|
232
|
+
if (argc == 1) {
|
233
|
+
i = TYPE(argv[0]);
|
234
|
+
if (i == T_STRING) {
|
235
|
+
a = rb_hash_aref(rb_cv_get(rb_cImage, "@@named_colors"), rb_funcall(argv[0], rb_intern("downcase"), 0));
|
236
|
+
if (TYPE(a) == T_ARRAY) {
|
237
|
+
return a;
|
238
|
+
} else {
|
239
|
+
rb_raise(rb_eArgError, "Unknow color name: %s", RSTRING_PTR(argv[0]));
|
240
|
+
}
|
241
|
+
} else if (i == T_FIXNUM) {
|
242
|
+
i = NUM2INT(argv[0]);
|
243
|
+
return rb_ary_new3(4, INT2NUM(gdTrueColorGetRed(i)), INT2NUM(gdTrueColorGetGreen(i)), INT2NUM(gdTrueColorGetBlue(i)), INT2NUM(gdTrueColorGetAlpha(i)));
|
244
|
+
} else {
|
245
|
+
rb_raise(rb_eArgError, "String or Fixnum expected");
|
246
|
+
}
|
247
|
+
} else if (argc == 3 || argc == 4) {
|
248
|
+
rb_scan_args(argc, argv, "31", &r, &g, &b, &a);
|
249
|
+
SetIntIfQnil(a, gdAlphaOpaque);
|
250
|
+
return rb_ary_new3(4, r, g, b, a);
|
251
|
+
} else {
|
252
|
+
rb_raise(rb_eArgError, "Wrong # of arguments (1 or 3 or 4 for %d)", argc);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
// gd_gfp__X
|
257
|
+
static VALUE gd_font_get(VALUE klass, gdFontPtr (GDFUNC *pfunc)(void)) {
|
258
|
+
gdFontPtr ft = (*pfunc)();
|
259
|
+
return Data_Wrap_Struct(klass, 0, 0, ft);
|
260
|
+
}
|
261
|
+
|
262
|
+
/*
|
263
|
+
* call-seq:
|
264
|
+
* Font.small()
|
265
|
+
*
|
266
|
+
* Returns the "small" gd font.
|
267
|
+
*
|
268
|
+
* See Image.string for more information, or Image.stringft for a
|
269
|
+
* freetype-based alternative that supports truetype fonts.
|
270
|
+
*/
|
271
|
+
static VALUE font_s_small(VALUE klass) {
|
272
|
+
return gd_font_get(klass, gdFontGetSmall);
|
273
|
+
}
|
274
|
+
|
275
|
+
/*
|
276
|
+
* call-seq:
|
277
|
+
* Font.large()
|
278
|
+
*
|
279
|
+
* Returns the "large" gd font.
|
280
|
+
*
|
281
|
+
* See Image.string for more information, or Image.stringft for a
|
282
|
+
* freetype-based alternative that supports truetype fonts.
|
283
|
+
*/
|
284
|
+
static VALUE font_s_large(VALUE klass) {
|
285
|
+
return gd_font_get(klass, gdFontGetLarge);
|
286
|
+
}
|
287
|
+
|
288
|
+
/*
|
289
|
+
* call-seq:
|
290
|
+
* Font.medium_bold()
|
291
|
+
*
|
292
|
+
* Returns the "medium bold" gd font.
|
293
|
+
*
|
294
|
+
* See Image.string for more information, or Image.stringft for a
|
295
|
+
* freetype-based alternative that supports truetype fonts.
|
296
|
+
*/
|
297
|
+
static VALUE font_s_medium_bold(VALUE klass) {
|
298
|
+
return gd_font_get(klass, gdFontGetMediumBold);
|
299
|
+
}
|
300
|
+
|
301
|
+
/*
|
302
|
+
* call-seq:
|
303
|
+
* Font.giant()
|
304
|
+
*
|
305
|
+
* Returns the "giant" gd font.
|
306
|
+
*
|
307
|
+
* See Image.string for more information, or Image.stringft for a
|
308
|
+
* freetype-based alternative that supports truetype fonts.
|
309
|
+
*/
|
310
|
+
static VALUE font_s_giant(VALUE klass) {
|
311
|
+
return gd_font_get(klass, gdFontGetGiant);
|
312
|
+
}
|
313
|
+
|
314
|
+
/*
|
315
|
+
* call-seq:
|
316
|
+
* Font.tiny()
|
317
|
+
*
|
318
|
+
* Returns the "tiny" gd font.
|
319
|
+
*
|
320
|
+
* See Image.string for more information, or Image.stringft for a
|
321
|
+
* freetype-based alternative that supports truetype fonts.
|
322
|
+
*/
|
323
|
+
static VALUE font_s_tiny(VALUE klass) {
|
324
|
+
return gd_font_get(klass, gdFontGetTiny);
|
325
|
+
}
|
326
|
+
|
327
|
+
// gd_H__H
|
328
|
+
/*
|
329
|
+
* call-seq:
|
330
|
+
* use_fontconfig = boolean
|
331
|
+
*
|
332
|
+
* GD 2.0.29 introduced the ability to use fontconfig patterns rather than font
|
333
|
+
* file names as parameters to Image.stringft, Image.stringft_circle. For
|
334
|
+
* backwards compatibility reasons, the fontlist parameter to those functions is
|
335
|
+
* still expected to be a full or partial font file path name or list thereof by
|
336
|
+
* default. However, as a convenience, when use_fontconfig=true configures
|
337
|
+
* gd to expect the fontlist parameter to be a fontconfig pattern.
|
338
|
+
*
|
339
|
+
* NOTE, if the fontconfig library is not available, use_fontconfig=true
|
340
|
+
* will raise an error.
|
341
|
+
*/
|
342
|
+
static VALUE image_s_use_fontconfig(VALUE klass, VALUE flag) {
|
343
|
+
if (!gdFTUseFontConfig(RTEST(flag) ? 1 : 0)) {
|
344
|
+
rb_raise(rb_eRGDError, "The FontConfig library is not available.");
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
// gd_H__H2
|
349
|
+
/*
|
350
|
+
* call-seq:
|
351
|
+
* alpha_blend(dst, src)
|
352
|
+
*
|
353
|
+
* Accepts truecolor pixel values only. The source color is composited with the
|
354
|
+
* destination color based on the alpha channel value of the source color.
|
355
|
+
*
|
356
|
+
* The resulting color is opaque.
|
357
|
+
*/
|
358
|
+
static VALUE image_s_alpha_blend(VALUE klass, VALUE dst, VALUE src) {
|
359
|
+
return INT2NUM(gdAlphaBlend(NUM2INT(dst), NUM2INT(src)));
|
360
|
+
}
|
361
|
+
|
362
|
+
// gd_H__H4
|
363
|
+
/*
|
364
|
+
* call-seq:
|
365
|
+
* truecolor(args)
|
366
|
+
*
|
367
|
+
* Returns an RGBA color value for use when drawing on a truecolor image.
|
368
|
+
*
|
369
|
+
* Usage:
|
370
|
+
*
|
371
|
+
* * truecolor(color_name)
|
372
|
+
* * truecolor(r, g, b, a = ALPHA_OPAQUE)
|
373
|
+
*
|
374
|
+
* _color_name_ can be any one of 147 color names are defined in the HTML and
|
375
|
+
* CSS color specification.
|
376
|
+
*
|
377
|
+
* Red, green, and blue are all in the range between 0 (off) and 255 (maximum).
|
378
|
+
* Alpha is in the range between ALPHA_OPAQUE (opaque) and ALPHA_TRANSPARENT
|
379
|
+
* (fully transparent). This method should not be used with palette-based
|
380
|
+
* images. If you need to write code which is compatible with both palette-based
|
381
|
+
* and truecolor images, use Image.color_resolve.
|
382
|
+
*/
|
383
|
+
static VALUE image_s_truecolor(int argc, VALUE *argv, VALUE klass) {
|
384
|
+
VALUE r = m_scan_color_args(argc, argv);
|
385
|
+
return INT2NUM(gdTrueColorAlpha(NUM2INT(rb_ary_entry(r, 0)), NUM2INT(rb_ary_entry(r, 1)), NUM2INT(rb_ary_entry(r, 2)), NUM2INT(rb_ary_entry(r, 3))));
|
386
|
+
}
|
387
|
+
|
388
|
+
static void gd_image_free(gdImagePtr im) {
|
389
|
+
if (im) gdImageDestroy(im);
|
390
|
+
}
|
391
|
+
|
392
|
+
// gd_gip__H2
|
393
|
+
static VALUE gd_image_create(VALUE klass, VALUE w, VALUE h, gdImagePtr (GDFUNC *pfunc)(int, int)) {
|
394
|
+
gdImagePtr im = (*pfunc)(NUM2INT(w), NUM2INT(h));
|
395
|
+
if (!im) rb_raise(rb_eRGDError, "unable to allocate the image");
|
396
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
397
|
+
}
|
398
|
+
|
399
|
+
/*
|
400
|
+
* call-seq:
|
401
|
+
* Image.create(width, height)
|
402
|
+
*
|
403
|
+
* Creates a palette-based image, with no more than 256 colors.
|
404
|
+
*/
|
405
|
+
static VALUE image_s_create(VALUE klass, VALUE width, VALUE height) {
|
406
|
+
return gd_image_create(klass, width, height, gdImageCreate);
|
407
|
+
}
|
408
|
+
|
409
|
+
/*
|
410
|
+
* call-seq:
|
411
|
+
* create_truecolor(width, height)
|
412
|
+
*
|
413
|
+
* Creates a truecolor image, with an essentially unlimited number of colors.
|
414
|
+
*/
|
415
|
+
static VALUE image_s_create_truecolor(VALUE klass, VALUE width, VALUE height) {
|
416
|
+
return gd_image_create(klass, width, height, gdImageCreateTrueColor);
|
417
|
+
}
|
418
|
+
|
419
|
+
// gd_gip__H_PAX
|
420
|
+
static VALUE gd_image_create_from_data(VALUE klass, VALUE data, gdImagePtr (GDFUNC *pfunc)(int, void*)) {
|
421
|
+
gdImagePtr im;
|
422
|
+
|
423
|
+
Check_Type(data, T_STRING);
|
424
|
+
im = (*pfunc)(RSTRING_LEN(data), RSTRING_PTR(data));
|
425
|
+
if (!im) rb_raise(rb_eRGDError, "Not valid Image data");
|
426
|
+
|
427
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
428
|
+
}
|
429
|
+
|
430
|
+
/*
|
431
|
+
* call-seq:
|
432
|
+
* from_jpeg_data(data)
|
433
|
+
*
|
434
|
+
* Creates a truecolor image from a JPEG format byte-string.
|
435
|
+
*/
|
436
|
+
static VALUE image_s_from_jpeg_data(VALUE klass, VALUE data) {
|
437
|
+
return gd_image_create_from_data(klass, data, gdImageCreateFromJpegPtr);
|
438
|
+
}
|
439
|
+
|
440
|
+
/*
|
441
|
+
* call-seq:
|
442
|
+
* from_png_data(data)
|
443
|
+
*
|
444
|
+
* Creates a image from a PNG format byte-string.
|
445
|
+
*
|
446
|
+
* If the PNG image being loaded is a truecolor image, the result will be a
|
447
|
+
* truecolor image. If the PNG image being loaded is a palette or grayscale
|
448
|
+
* image, the result will be a palette image. gd retains only 8 bits of
|
449
|
+
* resolution for each of the red, green and blue channels, and only 7 bits of
|
450
|
+
* resolution for the alpha channel. The former restriction affects only a
|
451
|
+
* handful of very rare 48-bit color and 16-bit grayscale PNG images. The second
|
452
|
+
* restriction affects all semitransparent PNG images, but the difference is
|
453
|
+
* essentially invisible to the eye. 7 bits of alpha channel resolution is, in
|
454
|
+
* practice, quite a lot.
|
455
|
+
*/
|
456
|
+
static VALUE image_s_from_png_data(VALUE klass, VALUE data) {
|
457
|
+
return gd_image_create_from_data(klass, data, gdImageCreateFromPngPtr);
|
458
|
+
}
|
459
|
+
|
460
|
+
/*
|
461
|
+
* call-seq:
|
462
|
+
* from_gif_data(data)
|
463
|
+
*
|
464
|
+
* Creates a image from a GIF format byte-string.
|
465
|
+
*/
|
466
|
+
static VALUE image_s_from_gif_data(VALUE klass, VALUE data) {
|
467
|
+
return gd_image_create_from_data(klass, data, gdImageCreateFromGifPtr);
|
468
|
+
}
|
469
|
+
|
470
|
+
/*
|
471
|
+
* call-seq:
|
472
|
+
* from_gd_data(data)
|
473
|
+
*
|
474
|
+
* Creates a image from a GD format byte-string.
|
475
|
+
*/
|
476
|
+
static VALUE image_s_from_gd_data(VALUE klass, VALUE data) {
|
477
|
+
return gd_image_create_from_data(klass, data, gdImageCreateFromGdPtr);
|
478
|
+
}
|
479
|
+
|
480
|
+
/*
|
481
|
+
* call-seq:
|
482
|
+
* from_gd2_data(data)
|
483
|
+
*
|
484
|
+
* Creates a image from a GD2 format byte-string.
|
485
|
+
*/
|
486
|
+
static VALUE image_s_from_gd2_data(VALUE klass, VALUE data) {
|
487
|
+
return gd_image_create_from_data(klass, data, gdImageCreateFromGd2Ptr);
|
488
|
+
}
|
489
|
+
|
490
|
+
/*
|
491
|
+
* call-seq:
|
492
|
+
* from_wbmp_data(data)
|
493
|
+
*
|
494
|
+
* Creates a image from a WBMP format byte-string.
|
495
|
+
*/
|
496
|
+
static VALUE image_s_from_wbmp_data(VALUE klass, VALUE data) {
|
497
|
+
return gd_image_create_from_data(klass, data, gdImageCreateFromWBMPPtr);
|
498
|
+
}
|
499
|
+
|
500
|
+
/*
|
501
|
+
* call-seq:
|
502
|
+
* from_bmp_data(data)
|
503
|
+
*
|
504
|
+
* Creates a image from a BMP format byte-string.
|
505
|
+
*/
|
506
|
+
static VALUE image_s_from_bmp_data(VALUE klass, VALUE data) {
|
507
|
+
return gd_image_create_from_data(klass, data, gdImageCreateFromBmpPtr);
|
508
|
+
}
|
509
|
+
|
510
|
+
// gd_gip__H_PAX_H4
|
511
|
+
/*
|
512
|
+
* call-seq:
|
513
|
+
* from_gd2_part_data(data, x, y, width, height)
|
514
|
+
*
|
515
|
+
* Create a image from a GD2 format byte-string, with extra parameters
|
516
|
+
* indicating the source (x, y) and width/height of the desired image.
|
517
|
+
*/
|
518
|
+
static VALUE image_s_from_gd2_part_data(VALUE klass, VALUE data, VALUE x, VALUE y, VALUE w, VALUE h) {
|
519
|
+
gdImagePtr im;
|
520
|
+
|
521
|
+
Check_Type(data, T_STRING);
|
522
|
+
Check_Type(x, T_FIXNUM);Check_Type(y, T_FIXNUM);
|
523
|
+
Check_Type(w, T_FIXNUM);Check_Type(h, T_FIXNUM);
|
524
|
+
im = gdImageCreateFromGd2PartPtr(RSTRING_LEN(data), RSTRING_PTR(data), NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h));
|
525
|
+
if (!im) rb_raise(rb_eRGDError, "Not valid Image data");
|
526
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
527
|
+
}
|
528
|
+
|
529
|
+
// gd_gip__PAD
|
530
|
+
/*
|
531
|
+
* call-seq:
|
532
|
+
* from_xpm(filename)
|
533
|
+
*
|
534
|
+
* Creates a image from a XPM file.
|
535
|
+
*/
|
536
|
+
static VALUE image_s_from_xpm(VALUE klass, VALUE filename) {
|
537
|
+
gdImagePtr im;
|
538
|
+
|
539
|
+
if (rb_funcall(rb_cFile, rb_intern("readable?"), 1, filename) != Qtrue)
|
540
|
+
rb_raise(rb_eIOError, "Cannot open %s for read", RSTRING_PTR(filename));
|
541
|
+
im = gdImageCreateFromXpm(RSTRING_PTR(filename));
|
542
|
+
if (!im) rb_raise(rb_eRGDError, "Not valid Image: %s", RSTRING_PTR(filename));
|
543
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
544
|
+
}
|
545
|
+
|
546
|
+
// gd_gip__fp
|
547
|
+
static VALUE gd_image_create_from_file(VALUE klass, VALUE filename, gdImagePtr (GDFUNC *pfunc)(FILE*)) {
|
548
|
+
gdImagePtr im;
|
549
|
+
FILE* fp;
|
550
|
+
|
551
|
+
fp = fopen(RSTRING_PTR(filename), "rb");
|
552
|
+
if (!fp) rb_raise(rb_eIOError, "Cannot open %s for read", RSTRING_PTR(filename));
|
553
|
+
|
554
|
+
im = (*pfunc)(fp);
|
555
|
+
fclose(fp);
|
556
|
+
if (!im) rb_raise(rb_eRGDError, "Not valid Image: %s", RSTRING_PTR(filename));
|
557
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
558
|
+
}
|
559
|
+
|
560
|
+
/*
|
561
|
+
* call-seq:
|
562
|
+
* from_jpeg(filename)
|
563
|
+
*
|
564
|
+
* Creates a truecolor image from a JPEG format file.
|
565
|
+
*/
|
566
|
+
static VALUE image_s_from_jpeg(VALUE klass, VALUE filename) {
|
567
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromJpeg);
|
568
|
+
}
|
569
|
+
|
570
|
+
/*
|
571
|
+
* call-seq:
|
572
|
+
* from_png(filename)
|
573
|
+
*
|
574
|
+
* Creates a image from a PNG format file.
|
575
|
+
*
|
576
|
+
* If the PNG image being loaded is a truecolor image, the result will be a
|
577
|
+
* truecolor image. If the PNG image being loaded is a palette or grayscale
|
578
|
+
* image, the result will be a palette image. gd retains only 8 bits of
|
579
|
+
* resolution for each of the red, green and blue channels, and only 7 bits of
|
580
|
+
* resolution for the alpha channel. The former restriction affects only a
|
581
|
+
* handful of very rare 48-bit color and 16-bit grayscale PNG images. The second
|
582
|
+
* restriction affects all semitransparent PNG images, but the difference is
|
583
|
+
* essentially invisible to the eye. 7 bits of alpha channel resolution is, in
|
584
|
+
* practice, quite a lot.
|
585
|
+
*/
|
586
|
+
static VALUE image_s_from_png(VALUE klass, VALUE filename) {
|
587
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromPng);
|
588
|
+
}
|
589
|
+
|
590
|
+
/*
|
591
|
+
* call-seq:
|
592
|
+
* from_gif(filename)
|
593
|
+
*
|
594
|
+
* Creates a image from a GIF format file.
|
595
|
+
*/
|
596
|
+
static VALUE image_s_from_gif(VALUE klass, VALUE filename) {
|
597
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromGif);
|
598
|
+
}
|
599
|
+
|
600
|
+
/*
|
601
|
+
* call-seq:
|
602
|
+
* from_gd(filename)
|
603
|
+
*
|
604
|
+
* Creates a image from a GD format file.
|
605
|
+
*/
|
606
|
+
static VALUE image_s_from_gd(VALUE klass, VALUE filename) {
|
607
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromGd);
|
608
|
+
}
|
609
|
+
|
610
|
+
/*
|
611
|
+
* call-seq:
|
612
|
+
* from_gd2(filename)
|
613
|
+
*
|
614
|
+
* Creates a image from a GD2 format file, with extra parameters indicating the
|
615
|
+
* source (x, y) and width/height of the desired image.
|
616
|
+
*/
|
617
|
+
static VALUE image_s_from_gd2(VALUE klass, VALUE filename) {
|
618
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromGd2);
|
619
|
+
}
|
620
|
+
|
621
|
+
/*
|
622
|
+
* call-seq:
|
623
|
+
* from_wbmp(filename)
|
624
|
+
*
|
625
|
+
* Creates a image from a WBMP format file.
|
626
|
+
*/
|
627
|
+
static VALUE image_s_from_wbmp(VALUE klass, VALUE filename) {
|
628
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromWBMP);
|
629
|
+
}
|
630
|
+
|
631
|
+
/*
|
632
|
+
* call-seq:
|
633
|
+
* from_xbm(filename)
|
634
|
+
*
|
635
|
+
* Creates a image from a XBM format file.
|
636
|
+
*/
|
637
|
+
static VALUE image_s_from_xbm(VALUE klass, VALUE filename) {
|
638
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromXbm);
|
639
|
+
}
|
640
|
+
|
641
|
+
/*
|
642
|
+
* call-seq:
|
643
|
+
* from_bmp(filename)
|
644
|
+
*
|
645
|
+
* Creates a image from a BMP format file.
|
646
|
+
*/
|
647
|
+
static VALUE image_s_from_bmp(VALUE klass, VALUE filename) {
|
648
|
+
return gd_image_create_from_file(klass, filename, gdImageCreateFromBmp);
|
649
|
+
}
|
650
|
+
|
651
|
+
// gd_gip__fp_H4
|
652
|
+
/*
|
653
|
+
* call-seq:
|
654
|
+
* from_gd2_part(filename, x, y, width, height)
|
655
|
+
*
|
656
|
+
* Create a image from a GD2 format file, with extra parameters indicating the
|
657
|
+
* source (x, y) and width/height of the desired image.
|
658
|
+
*/
|
659
|
+
static VALUE image_s_from_gd2_part(VALUE klass, VALUE filename, VALUE x, VALUE y, VALUE w, VALUE h) {
|
660
|
+
gdImagePtr im;
|
661
|
+
FILE* fp;
|
662
|
+
|
663
|
+
Check_Type(x, T_FIXNUM);Check_Type(y, T_FIXNUM);
|
664
|
+
Check_Type(w, T_FIXNUM);Check_Type(h, T_FIXNUM);
|
665
|
+
fp = fopen(RSTRING_PTR(filename), "rb");
|
666
|
+
if (!fp) rb_raise(rb_eIOError, "Cannot open %s for read", RSTRING_PTR(filename));
|
667
|
+
|
668
|
+
im = gdImageCreateFromGd2Part(fp, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h));
|
669
|
+
fclose(fp);
|
670
|
+
|
671
|
+
if (!im) rb_raise(rb_eRGDError, "Not valid Image: %s", RSTRING_PTR(filename));
|
672
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
673
|
+
}
|
674
|
+
|
675
|
+
// gd_gip__gip_H2
|
676
|
+
/*
|
677
|
+
* call-seq:
|
678
|
+
* create_palette_from_truecolor(img, dither = true, colors = MAX_COLORS)
|
679
|
+
*
|
680
|
+
* Create a new palette-based image from a truecolor image, by using a
|
681
|
+
* high-quality two-pass quantization routine. If _dither_ is true, the image
|
682
|
+
* will be dithered to approximate colors better, at the expense of some
|
683
|
+
* obvious "speckling." _colors_ can be anything up to 256. If the original
|
684
|
+
* source image includes photographic information or anything that came out of
|
685
|
+
* a JPEG, 256 is strongly recommended. 100% transparency of a single
|
686
|
+
* transparent color in the original truecolor image will be preserved. There is
|
687
|
+
* no other support for preservation of alpha channel or transparency in the
|
688
|
+
* destination image.
|
689
|
+
*/
|
690
|
+
static VALUE image_s_create_palette_from_truecolor(int argc, VALUE *argv, VALUE klass) {
|
691
|
+
gdImagePtr im, im2;
|
692
|
+
VALUE img2, dither, colors;
|
693
|
+
rb_scan_args(argc, argv, "12", &img2, &dither, &colors);
|
694
|
+
SetIntIfQnil(dither, Qtrue);
|
695
|
+
Data_Get_Struct(img2, gdImage, im2);
|
696
|
+
im = gdImageCreatePaletteFromTrueColor(im2, RTEST(dither) ? 1 : 0, RTEST(colors) ? NUM2INT(colors) : gdMaxColors);
|
697
|
+
if (!im) rb_raise(rb_eRGDError, "Not valid Image data");
|
698
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
699
|
+
}
|
700
|
+
|
701
|
+
// gd_gip__gip_H
|
702
|
+
/*
|
703
|
+
* call-seq:
|
704
|
+
* square_to_circle(img, radius)
|
705
|
+
*
|
706
|
+
* The argument _img_ MUST be square, but can have any size. Returns a new image
|
707
|
+
* of width and height radius * 2, in which the X axis of the original has been
|
708
|
+
* remapped to theta (angle) and the Y axis of the original has been remapped to
|
709
|
+
* rho (distance from center). This is known as a "polar coordinate transform."
|
710
|
+
*
|
711
|
+
* See also Image.stringft_circle, which uses this function internally.
|
712
|
+
*/
|
713
|
+
static VALUE image_s_square_to_circle(VALUE klass, VALUE img2, VALUE radius) {
|
714
|
+
gdImagePtr im, im2;
|
715
|
+
Data_Get_Struct(img2, gdImage, im2);
|
716
|
+
im = gdImageSquareToCircle(im2, NUM2INT(radius));
|
717
|
+
if (!im) rb_raise(rb_eRGDError, "Not valid Image data");
|
718
|
+
return Data_Wrap_Struct(klass, 0, gd_image_free, im);
|
719
|
+
}
|
720
|
+
|
721
|
+
// gd_X__gip_fp
|
722
|
+
static VALUE gd_image_to_file(VALUE klass, VALUE filename, void (GDFUNC *pfunc)(gdImagePtr, FILE*)) {
|
723
|
+
gdImagePtr im;
|
724
|
+
FILE* fp;
|
725
|
+
|
726
|
+
fp = fopen(RSTRING_PTR(filename), "wb");
|
727
|
+
if (!fp) rb_raise(rb_eIOError, "Cannot open %s for write", RSTRING_PTR(filename));
|
728
|
+
|
729
|
+
Data_Get_Struct(klass, gdImage, im);
|
730
|
+
(*pfunc)(im, fp);
|
731
|
+
fclose(fp);
|
732
|
+
return klass;
|
733
|
+
}
|
734
|
+
|
735
|
+
/*
|
736
|
+
* call-seq:
|
737
|
+
* gif(filename)
|
738
|
+
*
|
739
|
+
* Write the image to the specified file in GIF format.
|
740
|
+
*/
|
741
|
+
static VALUE image_gif(VALUE klass, VALUE filename) {
|
742
|
+
return gd_image_to_file(klass, filename, gdImageGif);
|
743
|
+
}
|
744
|
+
|
745
|
+
/*
|
746
|
+
* call-seq:
|
747
|
+
* gd(filename)
|
748
|
+
*
|
749
|
+
* Write the image to the specified file in GD format.
|
750
|
+
*/
|
751
|
+
static VALUE image_gd(VALUE klass, VALUE filename) {
|
752
|
+
return gd_image_to_file(klass, filename, gdImageGd);
|
753
|
+
}
|
754
|
+
|
755
|
+
// gd_X__gip_fp_H
|
756
|
+
// gd_X__gip_H_fp
|
757
|
+
static VALUE gd_image_to_file_H(VALUE klass, VALUE filename, VALUE a, void (GDFUNC *pfunc)(gdImagePtr, FILE*, int)) {
|
758
|
+
gdImagePtr im;
|
759
|
+
FILE* fp;
|
760
|
+
|
761
|
+
Check_Type(a, T_FIXNUM);
|
762
|
+
|
763
|
+
fp = fopen(RSTRING_PTR(filename), "wb");
|
764
|
+
if (!fp) rb_raise(rb_eIOError, "Cannot open %s for write", RSTRING_PTR(filename));
|
765
|
+
|
766
|
+
Data_Get_Struct(klass, gdImage, im);
|
767
|
+
(*pfunc)(im, fp, NUM2INT(a));
|
768
|
+
fclose(fp);
|
769
|
+
return klass;
|
770
|
+
}
|
771
|
+
|
772
|
+
/*
|
773
|
+
* call-seq:
|
774
|
+
* jpeg(filename, quality = -1)
|
775
|
+
*
|
776
|
+
* Write the image to the specified file in JPEG format.
|
777
|
+
*
|
778
|
+
* If quality is negative, the default IJG JPEG quality value (which should
|
779
|
+
* yield a good general quality / size tradeoff for most situations) is used.
|
780
|
+
* Otherwise, for practical purposes, quality should be a value in the range
|
781
|
+
* 0-95, higher quality values usually implying both higher quality and larger
|
782
|
+
* image sizes.
|
783
|
+
*/
|
784
|
+
static VALUE image_jpeg(int argc, VALUE *argv, VALUE klass) {
|
785
|
+
VALUE filename, quality;
|
786
|
+
rb_scan_args(argc, argv, "11", &filename, &quality);
|
787
|
+
SetIntIfQnil(quality, -1);
|
788
|
+
return gd_image_to_file_H(klass, filename, quality, gdImageJpeg);
|
789
|
+
}
|
790
|
+
|
791
|
+
/*
|
792
|
+
* call-seq:
|
793
|
+
* png(filename, level = -1)
|
794
|
+
*
|
795
|
+
* Write the image to the specified file in PNG format.
|
796
|
+
*
|
797
|
+
* _level_ specified the level of compression to be specified. A compression
|
798
|
+
* level of 0 means "no compression." A compression level of 1 means
|
799
|
+
* "compressed, but as quickly as possible." A compression level of 9 means
|
800
|
+
* "compressed as much as possible to produce the smallest possible file." A
|
801
|
+
* compression level of -1 will use the default compression level at the time
|
802
|
+
* zlib was compiled on your system.
|
803
|
+
*/
|
804
|
+
static VALUE image_png(int argc, VALUE *argv, VALUE klass) {
|
805
|
+
VALUE filename, level;
|
806
|
+
rb_scan_args(argc, argv, "11", &filename, &level);
|
807
|
+
SetIntIfQnil(level, -1);
|
808
|
+
return gd_image_to_file_H(klass, filename, level, gdImagePngEx);
|
809
|
+
}
|
810
|
+
|
811
|
+
/*
|
812
|
+
* call-seq:
|
813
|
+
* bmp(filename)
|
814
|
+
*
|
815
|
+
* Write the image to the specified file in BMP format.
|
816
|
+
*/
|
817
|
+
static VALUE image_bmp(VALUE klass, VALUE filename) {
|
818
|
+
return gd_image_to_file_H(klass, filename, 1, gdImageBmp);
|
819
|
+
}
|
820
|
+
|
821
|
+
void GDFUNC gd_gdImageWBMP(gdImagePtr im, FILE* out, int fg) {
|
822
|
+
gdImageWBMP(im, fg, out);
|
823
|
+
}
|
824
|
+
|
825
|
+
/*
|
826
|
+
* call-seq:
|
827
|
+
* wbmp(filename, fg = 1)
|
828
|
+
*
|
829
|
+
* Write the image to the specified file in WBMP format.
|
830
|
+
*
|
831
|
+
* WBMP file support is black and white only. The color index specified by
|
832
|
+
* the _fg_ argument is the "foreground," and only pixels of this color will be
|
833
|
+
* set in the WBMP file. All other pixels will be considered "background."
|
834
|
+
*/
|
835
|
+
static VALUE image_wbmp(int argc, VALUE *argv, VALUE klass) {
|
836
|
+
VALUE filename, fg;
|
837
|
+
rb_scan_args(argc, argv, "11", &filename, &fg);
|
838
|
+
SetIntIfQnil(fg, 1);
|
839
|
+
return gd_image_to_file_H(klass, filename, fg, gd_gdImageWBMP);
|
840
|
+
}
|
841
|
+
|
842
|
+
// gd_X__gip_fp_H2
|
843
|
+
/*
|
844
|
+
* call-seq:
|
845
|
+
* gd2(filename, chunk_size = 0, fmt = GD2_FMT_COMPRESSED)
|
846
|
+
*
|
847
|
+
* Write the image to the specified file in GD2 format.
|
848
|
+
*
|
849
|
+
* The gd2 image format is intended for fast reads and writes of parts of
|
850
|
+
* images. It is a compressed format (when _fmt_ is GD2_FMT_COMPRESSED), and
|
851
|
+
* well suited to retrieving smll sections of much larger images.
|
852
|
+
*
|
853
|
+
* The file is stored as a series of compressed subimages, and the _chunk_size_
|
854
|
+
* determines the sub-image size - a value of zero causes the GD library to use
|
855
|
+
* the default.
|
856
|
+
*
|
857
|
+
* It is also possible to store GD2 files in an uncompressed format, in which
|
858
|
+
* case _fmt_ should be GD2_FMT_RAW.
|
859
|
+
*/
|
860
|
+
static VALUE image_gd2(int argc, VALUE *argv, VALUE klass) {
|
861
|
+
VALUE filename, chunk_size, fmt;
|
862
|
+
gdImagePtr im;
|
863
|
+
FILE* fp;
|
864
|
+
|
865
|
+
rb_scan_args(argc, argv, "12", &filename, &chunk_size, &fmt);
|
866
|
+
SetIntIfQnil(chunk_size, 0);
|
867
|
+
SetIntIfQnil(fmt, GD2_FMT_COMPRESSED);
|
868
|
+
Check_Type(chunk_size, T_FIXNUM);
|
869
|
+
Check_Type(fmt, T_FIXNUM);
|
870
|
+
|
871
|
+
fp = fopen(RSTRING_PTR(filename), "wb");
|
872
|
+
if (!fp) rb_raise(rb_eIOError, "Cannot open %s for write", RSTRING_PTR(filename));
|
873
|
+
|
874
|
+
Data_Get_Struct(klass, gdImage, im);
|
875
|
+
gdImageGd2(im, fp, NUM2INT(chunk_size), NUM2INT(fmt));
|
876
|
+
fclose(fp);
|
877
|
+
return klass;
|
878
|
+
}
|
879
|
+
|
880
|
+
// gd_PAX__gip_PAH
|
881
|
+
static VALUE gd_image_to_data(VALUE klass, void* (GDFUNC *pfunc)(gdImagePtr, int*)) {
|
882
|
+
VALUE data;
|
883
|
+
gdImagePtr im;
|
884
|
+
char* buf;
|
885
|
+
int len;
|
886
|
+
|
887
|
+
Data_Get_Struct(klass, gdImage, im);
|
888
|
+
buf = (*pfunc)(im, &len);
|
889
|
+
data = rb_str_new(buf, len);
|
890
|
+
gdFree(buf);
|
891
|
+
return data;
|
892
|
+
}
|
893
|
+
|
894
|
+
/*
|
895
|
+
* call-seq:
|
896
|
+
* gif_data()
|
897
|
+
*
|
898
|
+
* Convert the image to a GIF format byte-string.
|
899
|
+
*/
|
900
|
+
static VALUE image_gif_data(VALUE klass) {
|
901
|
+
return gd_image_to_data(klass, gdImageGifPtr);
|
902
|
+
}
|
903
|
+
|
904
|
+
/*
|
905
|
+
* call-seq:
|
906
|
+
* gd_data()
|
907
|
+
*
|
908
|
+
* Convert the image to a GD format byte-string.
|
909
|
+
*/
|
910
|
+
static VALUE image_gd_data(VALUE klass) {
|
911
|
+
return gd_image_to_data(klass, gdImageGdPtr);
|
912
|
+
}
|
913
|
+
|
914
|
+
// gd_PAX__gip_PAH_H
|
915
|
+
static VALUE gd_image_to_data_H(VALUE klass, VALUE a, void* (GDFUNC *pfunc)(gdImagePtr, int*, int)) {
|
916
|
+
VALUE data;
|
917
|
+
gdImagePtr im;
|
918
|
+
char* buf;
|
919
|
+
int len;
|
920
|
+
|
921
|
+
Data_Get_Struct(klass, gdImage, im);
|
922
|
+
buf = (*pfunc)(im, &len, NUM2INT(a));
|
923
|
+
data = rb_str_new(buf, len);
|
924
|
+
gdFree(buf);
|
925
|
+
return data;
|
926
|
+
}
|
927
|
+
|
928
|
+
/*
|
929
|
+
* call-seq:
|
930
|
+
* jpeg_data(quality = -1)
|
931
|
+
*
|
932
|
+
* Convert the image to a JPEG format byte-string.
|
933
|
+
*
|
934
|
+
* Read Image.jpeg for more.
|
935
|
+
*/
|
936
|
+
static VALUE image_jpeg_data(int argc, VALUE *argv, VALUE klass) {
|
937
|
+
VALUE a;
|
938
|
+
rb_scan_args(argc, argv, "01", &a);
|
939
|
+
SetIntIfQnil(a, -1);
|
940
|
+
return gd_image_to_data_H(klass, a, gdImageJpegPtr);
|
941
|
+
}
|
942
|
+
|
943
|
+
/*
|
944
|
+
* call-seq:
|
945
|
+
* png_data(level = -1)
|
946
|
+
*
|
947
|
+
* Convert the image to a PNG format byte-string.
|
948
|
+
*
|
949
|
+
* Read Image.png for more.
|
950
|
+
*/
|
951
|
+
static VALUE image_png_data(int argc, VALUE *argv, VALUE klass) {
|
952
|
+
VALUE a;
|
953
|
+
rb_scan_args(argc, argv, "01", &a);
|
954
|
+
SetIntIfQnil(a, -1);
|
955
|
+
return gd_image_to_data_H(klass, a, gdImagePngPtrEx);
|
956
|
+
}
|
957
|
+
|
958
|
+
/*
|
959
|
+
* call-seq:
|
960
|
+
* wbmp_data(fg = 1)
|
961
|
+
*
|
962
|
+
* Convert the image to a WBMP format byte-string.
|
963
|
+
*
|
964
|
+
* Read Image.wbmp for more.
|
965
|
+
*/
|
966
|
+
static VALUE image_wbmp_data(int argc, VALUE *argv, VALUE klass) {
|
967
|
+
VALUE a;
|
968
|
+
rb_scan_args(argc, argv, "01", &a);
|
969
|
+
SetIntIfQnil(a, 1);
|
970
|
+
return gd_image_to_data_H(klass, a, gdImageWBMPPtr);
|
971
|
+
}
|
972
|
+
|
973
|
+
/*
|
974
|
+
* call-seq:
|
975
|
+
* bmp_data()
|
976
|
+
*
|
977
|
+
* Convert the image to a BMP format byte-string.
|
978
|
+
*/
|
979
|
+
static VALUE image_bmp_data(VALUE klass) {
|
980
|
+
return gd_image_to_data_H(klass, INT2NUM(1), gdImageBmpPtr);
|
981
|
+
}
|
982
|
+
|
983
|
+
// gd_PAX__gip_PAH_H2
|
984
|
+
// gd_PAX__gip_H2_PAH
|
985
|
+
static VALUE gd_image_to_data_H2(VALUE klass, VALUE a, VALUE b, void* (GDFUNC *pfunc)(gdImagePtr, int*, int, int)) {
|
986
|
+
VALUE data;
|
987
|
+
gdImagePtr im;
|
988
|
+
char* buf;
|
989
|
+
int len;
|
990
|
+
|
991
|
+
Data_Get_Struct(klass, gdImage, im);
|
992
|
+
buf = (*pfunc)(im, &len, NUM2INT(a), NUM2INT(b));
|
993
|
+
data = rb_str_new(buf, len);
|
994
|
+
gdFree(buf);
|
995
|
+
return data;
|
996
|
+
}
|
997
|
+
|
998
|
+
void* GDFUNC gd_gdImageGd2Ptr(gdImagePtr im, int *size, int cs, int fmt) {
|
999
|
+
gdImageGd2Ptr(im, cs, fmt, size);
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
/*
|
1003
|
+
* call-seq:
|
1004
|
+
* gd2_data(chunk_size = 0, fmt = GD2_FMT_COMPRESSED)
|
1005
|
+
*
|
1006
|
+
* Convert the image to a GD2 format byte-string.
|
1007
|
+
*
|
1008
|
+
* Read Image.gd2 for more.
|
1009
|
+
*/
|
1010
|
+
static VALUE image_gd2_data(int argc, VALUE *argv, VALUE klass) {
|
1011
|
+
VALUE a, b;
|
1012
|
+
rb_scan_args(argc, argv, "02", &a, &b);
|
1013
|
+
SetIntIfQnil(a, 0);
|
1014
|
+
SetIntIfQnil(b, GD2_FMT_COMPRESSED);
|
1015
|
+
return gd_image_to_data_H2(klass, a, b, gd_gdImageGd2Ptr);
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
/*
|
1019
|
+
* call-seq:
|
1020
|
+
* gif_anim_begin_data(global_cm = -1, loops = 0)
|
1021
|
+
*
|
1022
|
+
* This function must be called as the first function when creating a GIF
|
1023
|
+
* animation. It returns a byte-string for the correct GIF file headers,
|
1024
|
+
* and prepares for frames to be added for the animation. It's *NOT* used to
|
1025
|
+
* produce an image frame of GIF file, it is only used to establish the GIF
|
1026
|
+
* animation frame size, interlacing options and the color palette.
|
1027
|
+
* Image.gif_anim_add_data is used to make the first and subsequent frames
|
1028
|
+
* to the animation, and the animation must be terminated by writing a semicolon
|
1029
|
+
* character (;) to it or by using Image.gif_anim_end_data to get that.
|
1030
|
+
*
|
1031
|
+
* The global_cm flag indicates if a global color map (or palette) is used in
|
1032
|
+
* the GIF89A header. A nonzero value specifies that a global color map should
|
1033
|
+
* be used to reduce the size of the animation. Of course, if the color maps of
|
1034
|
+
* individual frames differ greatly, a global color map may not be a good idea.
|
1035
|
+
* global_cm=1 means write global color map, global_cm=0 means do not, and
|
1036
|
+
* global_cm=-1 means to do the default, which currently is to use a global
|
1037
|
+
* color map.
|
1038
|
+
*
|
1039
|
+
* If loops is 0 or greater, the Netscape 2.0 extension for animation loop count
|
1040
|
+
* is written. 0 means infinite loop count. -1 means that the extension is not
|
1041
|
+
* added which results in no looping.
|
1042
|
+
*/
|
1043
|
+
static VALUE image_gif_anim_begin_data(int argc, VALUE *argv, VALUE klass) {
|
1044
|
+
VALUE a, b;
|
1045
|
+
rb_scan_args(argc, argv, "02", &a, &b);
|
1046
|
+
SetIntIfQnil(a, -1);
|
1047
|
+
SetIntIfQnil(b, 0);
|
1048
|
+
return gd_image_to_data_H2(klass, a, b, gdImageGifAnimBeginPtr);
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
// gd_PAX__gip_PAzH_H5_gip
|
1052
|
+
/*
|
1053
|
+
* call-seq:
|
1054
|
+
* gif_anim_add_data(local_cm = 1, left = 0, top = 0, delay = 5, disposal = DISPOSAL_NONE, prev_image = nil)
|
1055
|
+
*
|
1056
|
+
* This function returns GIF animation frames to GIF animation, which was
|
1057
|
+
* initialized with Image.gif_anim_begin_data.
|
1058
|
+
*
|
1059
|
+
* With _left_ and _top_ you can place this frame in different offset than (0,0)
|
1060
|
+
* inside the image screen as defined in Image.gif_anim_begin_data.
|
1061
|
+
*
|
1062
|
+
* The argument _delay_ between the previous frame and this frame is in 1/100s
|
1063
|
+
* units.
|
1064
|
+
*
|
1065
|
+
* The argument _disposal_ is usually DISPOSAL_NONE, meaning that the pixels
|
1066
|
+
* changed by this frame should remain on the display when the next frame begins
|
1067
|
+
* to render, but can also be DISPOSAL_RESTORE_BACKGROUND (restores the first
|
1068
|
+
* allocated color of the global palette), or DISPOSAL_RESTORE_PREVIOUS
|
1069
|
+
* (restores the appearance of the affected area before the frame was rendered).
|
1070
|
+
* Only DISPOSAL_NONE is a sensible choice for the first frame.
|
1071
|
+
*
|
1072
|
+
* If _prev_im_ is not nil, the built-in GIF optimizer will always use
|
1073
|
+
* DISPOSAL_NONE regardless of the Disposal parameter.
|
1074
|
+
*/
|
1075
|
+
static VALUE image_gif_anim_add_data(int argc, VALUE *argv, VALUE klass) {
|
1076
|
+
VALUE data, local_cm, left, top, delay, disposal, prev_image;
|
1077
|
+
gdImagePtr im, im2 = NULL;
|
1078
|
+
char* buf;
|
1079
|
+
int len;
|
1080
|
+
|
1081
|
+
rb_scan_args(argc, argv, "06", &local_cm, &left, &top, &delay, &disposal, &prev_image);
|
1082
|
+
SetIntIfQnil(local_cm, 1);
|
1083
|
+
SetIntIfQnil(left, 0);
|
1084
|
+
SetIntIfQnil(top, 0);
|
1085
|
+
SetIntIfQnil(delay, 5);
|
1086
|
+
SetIntIfQnil(disposal, gdDisposalNone);
|
1087
|
+
if RTEST(prev_image) Data_Get_Struct(prev_image, gdImage, im2);
|
1088
|
+
|
1089
|
+
Data_Get_Struct(klass, gdImage, im);
|
1090
|
+
buf = gdImageGifAnimAddPtr(im, &len, NUM2INT(local_cm), NUM2INT(left), NUM2INT(top), NUM2INT(delay), NUM2INT(disposal), im2);
|
1091
|
+
data = rb_str_new(buf, len);
|
1092
|
+
gdFree(buf);
|
1093
|
+
return data;
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
// gd_PAX__PAH
|
1097
|
+
/*
|
1098
|
+
* call-seq:
|
1099
|
+
* gif_anim_end_data()
|
1100
|
+
*
|
1101
|
+
* Returns a one byte string containing the semicolon character (;). The string
|
1102
|
+
* ";" can be used in place of this function.
|
1103
|
+
*/
|
1104
|
+
static VALUE image_gif_anim_end_data(VALUE klass) {
|
1105
|
+
VALUE data;
|
1106
|
+
char* buf;
|
1107
|
+
int len;
|
1108
|
+
|
1109
|
+
buf = gdImageGifAnimEndPtr(&len);
|
1110
|
+
data = rb_str_new(buf, len);
|
1111
|
+
gdFree(buf);
|
1112
|
+
return data;
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
// gd_H__gip2
|
1116
|
+
/*
|
1117
|
+
* call-seq:
|
1118
|
+
* compare(image)
|
1119
|
+
*
|
1120
|
+
* Returns a bitmap indicating if the two images are different. The members of
|
1121
|
+
* the bitmap are defined as GD_CMP_*, but the most important is GD_CMP_IMAGE,
|
1122
|
+
* which indicated that the images will actually appear different when displayed.
|
1123
|
+
* Other, less important, differences relate to pallette entries. Any difference
|
1124
|
+
* in the transparent color is assumed to make images display differently, even
|
1125
|
+
* if the transparent color is not used.
|
1126
|
+
*/
|
1127
|
+
static VALUE image_compare(VALUE klass, VALUE image) {
|
1128
|
+
gdImagePtr im, im2;
|
1129
|
+
Data_Get_Struct(klass, gdImage, im);
|
1130
|
+
Data_Get_Struct(image, gdImage, im2);
|
1131
|
+
return INT2NUM(gdImageCompare(im, im2));
|
1132
|
+
}
|
1133
|
+
|
1134
|
+
/*
|
1135
|
+
* call-seq:
|
1136
|
+
* width()
|
1137
|
+
*
|
1138
|
+
* Get the width of the image in pixels.
|
1139
|
+
*/
|
1140
|
+
static VALUE image_sx(VALUE klass) {
|
1141
|
+
gdImagePtr im;
|
1142
|
+
Data_Get_Struct(klass, gdImage, im);
|
1143
|
+
return INT2NUM(gdImageSX(im));
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
/*
|
1147
|
+
* call-seq:
|
1148
|
+
* height()
|
1149
|
+
*
|
1150
|
+
* Get the height of the image in pixels.
|
1151
|
+
*/
|
1152
|
+
static VALUE image_sy(VALUE klass) {
|
1153
|
+
gdImagePtr im;
|
1154
|
+
Data_Get_Struct(klass, gdImage, im);
|
1155
|
+
return INT2NUM(gdImageSY(im));
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
/*
|
1159
|
+
* call-seq:
|
1160
|
+
* truecolor?()
|
1161
|
+
*
|
1162
|
+
* Return true if the image is a truecolor image, false for palette-based image.
|
1163
|
+
*/
|
1164
|
+
static VALUE image_is_truecolor(VALUE klass) {
|
1165
|
+
gdImagePtr im;
|
1166
|
+
Data_Get_Struct(klass, gdImage, im);
|
1167
|
+
return gdImageTrueColor(im) != 0 ? Qtrue : Qfalse;
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
/*
|
1171
|
+
* call-seq:
|
1172
|
+
* colors_total()
|
1173
|
+
*
|
1174
|
+
* Returns the number of colors currently allocated in a palette image.
|
1175
|
+
*/
|
1176
|
+
static VALUE image_colors_total(VALUE klass) {
|
1177
|
+
gdImagePtr im;
|
1178
|
+
Data_Get_Struct(klass, gdImage, im);
|
1179
|
+
return INT2NUM(gdImageColorsTotal(im));
|
1180
|
+
}
|
1181
|
+
|
1182
|
+
/*
|
1183
|
+
* call-seq:
|
1184
|
+
* interlace()
|
1185
|
+
*
|
1186
|
+
* Read Image.interlace= for details.
|
1187
|
+
*/
|
1188
|
+
static VALUE image_get_interlace(VALUE klass) {
|
1189
|
+
gdImagePtr im;
|
1190
|
+
Data_Get_Struct(klass, gdImage, im);
|
1191
|
+
return gdImageGetInterlaced(im) ? Qtrue : Qfalse;
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
/*
|
1195
|
+
* call-seq:
|
1196
|
+
* transparent()
|
1197
|
+
*
|
1198
|
+
* Returns the current transparent color index in the image. If there is no
|
1199
|
+
* transparent color returns -1.
|
1200
|
+
*
|
1201
|
+
*/
|
1202
|
+
static VALUE image_transparent_get(VALUE klass) {
|
1203
|
+
gdImagePtr im;
|
1204
|
+
Data_Get_Struct(klass, gdImage, im);
|
1205
|
+
return INT2NUM(gdImageGetTransparent(im));
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
// gd_H__gip_H
|
1209
|
+
/*
|
1210
|
+
* call-seq:
|
1211
|
+
* r, g, b, a = rgba(color)
|
1212
|
+
*
|
1213
|
+
* Returns a array containing the red, green, blue, alpha components of the
|
1214
|
+
* specified color (for truecolor image) or color index (for palette-based
|
1215
|
+
* image).
|
1216
|
+
*/
|
1217
|
+
static VALUE image_rgba(VALUE klass, VALUE color) {
|
1218
|
+
gdImagePtr im;
|
1219
|
+
int c = NUM2INT(color);
|
1220
|
+
Data_Get_Struct(klass, gdImage, im);
|
1221
|
+
return rb_ary_new3(4, INT2NUM(gdImageRed(im, c)), INT2NUM(gdImageGreen(im, c)), INT2NUM(gdImageBlue(im, c)), INT2NUM(gdImageAlpha(im, c)));
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
static VALUE gd_H__gip_H2(VALUE klass, VALUE a, VALUE b, int (GDFUNC *pfunc)(gdImagePtr, int, int)) {
|
1225
|
+
gdImagePtr im;
|
1226
|
+
Data_Get_Struct(klass, gdImage, im);
|
1227
|
+
return INT2NUM((*pfunc)(im, NUM2INT(a), NUM2INT(b)));
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
/*
|
1231
|
+
* call-seq:
|
1232
|
+
* slef[x, y]
|
1233
|
+
*
|
1234
|
+
* Get the color index or the color values of a particular pixel.
|
1235
|
+
*
|
1236
|
+
* A color index is returned when the image is palette based (created by
|
1237
|
+
* Image.create), the color value is returned when the image is a true
|
1238
|
+
* color image (created by Image.create_truecolor). To fetch the value of
|
1239
|
+
* each channel, you can use Image.rgba.
|
1240
|
+
*/
|
1241
|
+
static VALUE image_get_pixel(VALUE klass, VALUE x, VALUE y) {
|
1242
|
+
return gd_H__gip_H2(klass, x, y, gdImageGetPixel);
|
1243
|
+
}
|
1244
|
+
|
1245
|
+
/*
|
1246
|
+
* call-seq:
|
1247
|
+
* bounds_safe(x, y)
|
1248
|
+
*
|
1249
|
+
* Returns true if the specified point is within the current clipping rectangle,
|
1250
|
+
* false if not. The clipping rectangle is set by Image.clip= and defaults to
|
1251
|
+
* the entire image. This function is intended primarily for use by those who
|
1252
|
+
* wish to add functions to gd.
|
1253
|
+
*/
|
1254
|
+
static VALUE image_bounds_safe(VALUE klass, VALUE x, VALUE y) {
|
1255
|
+
return gd_H__gip_H2(klass, x, y, gdImageBoundsSafe) == INT2NUM(0) ? Qfalse : Qtrue;
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
// gd_H__gip_H3
|
1259
|
+
/*
|
1260
|
+
* call-seq:
|
1261
|
+
* color_closest_hwb(args)
|
1262
|
+
*
|
1263
|
+
* Usage:
|
1264
|
+
*
|
1265
|
+
* * color_closest_hwb(r, g, b)
|
1266
|
+
* * color_closest_hwb(integer)
|
1267
|
+
* * color_closest_hwb(color_name)
|
1268
|
+
*
|
1269
|
+
* Read Image.color_allocate for more about usage.
|
1270
|
+
*
|
1271
|
+
* Searches the colors which have been defined thus far in the image specified
|
1272
|
+
* and returns the index of the color with hue, whiteness and blackness closest
|
1273
|
+
* to the requested color. This scheme is typically superior to the Euclidian
|
1274
|
+
* distance scheme used by Image.color_closest.
|
1275
|
+
*
|
1276
|
+
* If no colors have yet been allocated in the image, this method returns -1.
|
1277
|
+
* When applied to a truecolor image, this function always succeeds in
|
1278
|
+
* returning the desired color.
|
1279
|
+
*
|
1280
|
+
* This function is most useful as a backup method for choosing a drawing color
|
1281
|
+
* when an image already contains MAX_COLORS (256) colors and no more can be
|
1282
|
+
* allocated. (This is not uncommon when working with existing PNG files that
|
1283
|
+
* already use many colors.) See Image.color_exact for a method of
|
1284
|
+
* locating exact matches only.
|
1285
|
+
*/
|
1286
|
+
static VALUE image_color_closest_hwb(int argc, VALUE *argv, VALUE klass) {
|
1287
|
+
gdImagePtr im;
|
1288
|
+
VALUE r = m_scan_color_args(argc, argv);
|
1289
|
+
Data_Get_Struct(klass, gdImage, im);
|
1290
|
+
return INT2NUM(gdImageColorClosestHWB(im, NUM2INT(rb_ary_entry(r, 0)), NUM2INT(rb_ary_entry(r, 1)), NUM2INT(rb_ary_entry(r, 2))));
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
// gd_H__gip_H4
|
1294
|
+
static VALUE gd_image_color_func_alpha(int argc, VALUE *argv, VALUE klass, int (GDFUNC *pfunc)(gdImagePtr, int, int, int, int)) {
|
1295
|
+
gdImagePtr im;
|
1296
|
+
VALUE r = m_scan_color_args(argc, argv);
|
1297
|
+
Data_Get_Struct(klass, gdImage, im);
|
1298
|
+
return INT2NUM((*pfunc)(im, NUM2INT(rb_ary_entry(r, 0)), NUM2INT(rb_ary_entry(r, 1)), NUM2INT(rb_ary_entry(r, 2)), NUM2INT(rb_ary_entry(r, 3))));
|
1299
|
+
}
|
1300
|
+
|
1301
|
+
/*
|
1302
|
+
* call-seq:
|
1303
|
+
* color_allocate(args)
|
1304
|
+
*
|
1305
|
+
* Usage:
|
1306
|
+
*
|
1307
|
+
* * color_allocate(r, g, b, a = ALPHA_OPAQUE)
|
1308
|
+
* * color_allocate(integer)
|
1309
|
+
* * color_allocate(color_name)
|
1310
|
+
*
|
1311
|
+
* Red, green and blue can be anything upto 255, and 127 represents full
|
1312
|
+
* transparency for alpha.
|
1313
|
+
*
|
1314
|
+
* _color_name_ can be any one of 147 color names are defined in the HTML and
|
1315
|
+
* CSS color specification.
|
1316
|
+
*
|
1317
|
+
* This method finds the first available color index in the image specified,
|
1318
|
+
* sets its RGBA values to those requested, and returns the index of the
|
1319
|
+
* new color table entry, or an RGBA value in the case of a truecolor image;
|
1320
|
+
* in either case you can then use the returned value as a parameter to drawing
|
1321
|
+
* functions. When creating a new palette-based image, the first time you
|
1322
|
+
* invoke this function, you are setting the background color for that image.
|
1323
|
+
*
|
1324
|
+
* In the event that all MAX_COLORS colors (256) have already been allocated,
|
1325
|
+
* this method will return -1 to indicate failure. (This is not uncommon when
|
1326
|
+
* working with existing palette-based PNG files that already use 256 colors.)
|
1327
|
+
* Note that this method does not check for existing colors that match your
|
1328
|
+
* request; see Image.color_exact and Image.color_closest
|
1329
|
+
* for ways to locate existing colors that approximate the color desired in
|
1330
|
+
* situations where a new color is not available.Also see
|
1331
|
+
* Image.color_resolve.
|
1332
|
+
*/
|
1333
|
+
static VALUE image_color_allocate(int argc, VALUE *argv, VALUE klass) {
|
1334
|
+
return gd_image_color_func_alpha(argc, argv, klass, gdImageColorAllocateAlpha);
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
/*
|
1338
|
+
* call-seq:
|
1339
|
+
* color_closest(args)
|
1340
|
+
*
|
1341
|
+
* Read Image.color_allocate for more about args.
|
1342
|
+
*
|
1343
|
+
* Searches the colors which have been defined thus far in the image specified
|
1344
|
+
* and returns the index of the color with RGB values closest to those of the
|
1345
|
+
* request. (Closeness is determined by Euclidian distance, which is used to
|
1346
|
+
* determine the distance in three-dimensional color space between colors.)
|
1347
|
+
*
|
1348
|
+
* If no colors have yet been allocated in the image, this method returns -1.
|
1349
|
+
* When applied to a truecolor image, this function always succeeds in
|
1350
|
+
* returning the desired color.
|
1351
|
+
*
|
1352
|
+
* This function is most useful as a backup method for choosing a drawing color
|
1353
|
+
* when an image already contains MAX_COLORS (256) colors and no more can be
|
1354
|
+
* allocated. (This is not uncommon when working with existing PNG files that
|
1355
|
+
* already use many colors.) See Image.color_exact for a method of
|
1356
|
+
* locating exact matches only.
|
1357
|
+
*
|
1358
|
+
*/
|
1359
|
+
static VALUE image_color_closest(int argc, VALUE *argv, VALUE klass) {
|
1360
|
+
return gd_image_color_func_alpha(argc, argv, klass, gdImageColorClosestAlpha);
|
1361
|
+
}
|
1362
|
+
|
1363
|
+
/*
|
1364
|
+
* call-seq:
|
1365
|
+
* color_exact(args)
|
1366
|
+
*
|
1367
|
+
* Read Image.color_allocate for more about args.
|
1368
|
+
*
|
1369
|
+
* Searches the colors which have been defined thus far in the image specified
|
1370
|
+
* and returns the index of the color with RGBA values closest to those of the
|
1371
|
+
* request. (Closeness is determined by Euclidian distance, which is used to
|
1372
|
+
* determine the distance in four-dimensional color/alpha space between colors.)
|
1373
|
+
*
|
1374
|
+
* If no colors have yet been allocated in the image, this method returns -1.
|
1375
|
+
* When applied to a truecolor image, this function always succeeds in returning
|
1376
|
+
* the desired color.
|
1377
|
+
*
|
1378
|
+
* This function is most useful as a backup method for choosing a drawing color
|
1379
|
+
* when a palette-based image already contains MAX_COLORS (256) colors and no
|
1380
|
+
* more can be allocated. (This is not uncommon when working with existing
|
1381
|
+
* palette-based PNG files that already use many colors.)
|
1382
|
+
*/
|
1383
|
+
static VALUE image_color_exact(int argc, VALUE *argv, VALUE klass) {
|
1384
|
+
return gd_image_color_func_alpha(argc, argv, klass, gdImageColorExactAlpha);
|
1385
|
+
}
|
1386
|
+
|
1387
|
+
/*
|
1388
|
+
* call-seq:
|
1389
|
+
* color_resolve(args)
|
1390
|
+
*
|
1391
|
+
* Read Image.color_allocate for more about args.
|
1392
|
+
*
|
1393
|
+
* Searches the colors which have been defined thus far in the image specified
|
1394
|
+
* and returns the index of the first color with RGBA values which exactly match
|
1395
|
+
* those of the request. If no allocated color matches the request precisely,
|
1396
|
+
* then thid medhos tries to allocate the exact color. If there is no space left
|
1397
|
+
* in the color table then this method returns the closest color (as in
|
1398
|
+
* Image.color_closest). This function always returns an index of a
|
1399
|
+
* color.
|
1400
|
+
*
|
1401
|
+
* When applied to a truecolor image, this function always succeeds in returning
|
1402
|
+
* the desired color.
|
1403
|
+
*/
|
1404
|
+
static VALUE image_color_resolve(int argc, VALUE *argv, VALUE klass) {
|
1405
|
+
return gd_image_color_func_alpha(argc, argv, klass, gdImageColorResolveAlpha);
|
1406
|
+
}
|
1407
|
+
|
1408
|
+
static VALUE gd_X__gip2(VALUE klass, VALUE img2, void (GDFUNC *pfunc)(gdImagePtr, gdImagePtr)) {
|
1409
|
+
gdImagePtr im, im2;
|
1410
|
+
Data_Get_Struct(klass, gdImage, im);
|
1411
|
+
Data_Get_Struct(img2, gdImage, im2);
|
1412
|
+
(*pfunc)(im, im2);
|
1413
|
+
return klass;
|
1414
|
+
}
|
1415
|
+
|
1416
|
+
/*
|
1417
|
+
* call-seq:
|
1418
|
+
* brush = img
|
1419
|
+
*
|
1420
|
+
* A "brush" is an image used to draw wide, shaped strokes in another image.
|
1421
|
+
* Just as a paintbrush is not a single point, a brush image need not be a
|
1422
|
+
* single pixel. Any gd image can be used as a brush, and by setting the
|
1423
|
+
* transparent color index of the brush image with Image.transparent=, a brush
|
1424
|
+
* of any shape can be created. All line-drawing functions, such as Image.line,
|
1425
|
+
* Image.open_polygon and Image.polygon, will use the current brush if the
|
1426
|
+
* special "color" COLOR_BRUSHED or COLOR_STYLED_BRUSHED is used when calling
|
1427
|
+
* them.
|
1428
|
+
*
|
1429
|
+
* This method is used to specify the brush to be used in a particular image.
|
1430
|
+
* You can set any image to be the brush. If the brush image does not have the
|
1431
|
+
* same color map as the first image, any colors missing from the first image
|
1432
|
+
* will be allocated. If not enough colors can be allocated, the closest colors
|
1433
|
+
* already available will be used. This allows arbitrary PNGs to be used as
|
1434
|
+
* brush images. It also means, however, that you should not set a brush unless
|
1435
|
+
* you will actually use it; if you set a rapid succession of different brush
|
1436
|
+
* images, you can quickly fill your color map, and the results will not be
|
1437
|
+
* optimal.
|
1438
|
+
*/
|
1439
|
+
static VALUE image_set_brush(VALUE klass, VALUE img2) {
|
1440
|
+
return gd_X__gip2(klass, img2, gdImageSetBrush);
|
1441
|
+
}
|
1442
|
+
|
1443
|
+
/*
|
1444
|
+
* call-seq:
|
1445
|
+
* tile = img
|
1446
|
+
*
|
1447
|
+
* A "tile" is an image used to fill an area with a repeated pattern. Any gd
|
1448
|
+
* image can be used as a tile, and by setting the transparent color index of
|
1449
|
+
* the tile image with Image.transparent=, a tile that allows certain parts of
|
1450
|
+
* the underlying area to shine through can be created. All region-filling
|
1451
|
+
* functions, such as Image.fill and Image.filled_polygon, will use the current
|
1452
|
+
* tile if the special "color" COLOR_TILED is used when calling them.
|
1453
|
+
*
|
1454
|
+
* This is method is used to specify the tile to be used in a particular image.
|
1455
|
+
* You can set any image to be the tile. If the tile image does not have the
|
1456
|
+
* same color map as the first image, any colors missing from the first image
|
1457
|
+
* will be allocated. If not enough colors can be allocated, the closest colors
|
1458
|
+
* already available will be used. This allows arbitrary PNGs to be used as tile
|
1459
|
+
* images. It also means, however, that you should not set a tile unless you
|
1460
|
+
* will actually use it; if you set a rapid succession of different tile images,
|
1461
|
+
* you can quickly fill your color map, and the results will not be optimal.
|
1462
|
+
*/
|
1463
|
+
static VALUE image_set_tile(VALUE klass, VALUE img2) {
|
1464
|
+
return gd_X__gip2(klass, img2, gdImageSetTile);
|
1465
|
+
}
|
1466
|
+
|
1467
|
+
/*
|
1468
|
+
* call-seq:
|
1469
|
+
* copy_palette(src)
|
1470
|
+
*
|
1471
|
+
* Copies a palette from an image, attempting to match the colors in the target
|
1472
|
+
* image to the colors in the source palette.
|
1473
|
+
*/
|
1474
|
+
static VALUE image_copy_palette(VALUE klass, VALUE img2) {
|
1475
|
+
return gd_X__gip2(klass, img2, gdImagePaletteCopy);
|
1476
|
+
}
|
1477
|
+
|
1478
|
+
// gd_X__gip2_H6
|
1479
|
+
/*
|
1480
|
+
* call-seq:
|
1481
|
+
* copy(src, dstX, dstY, srcX, srcY, w, h)
|
1482
|
+
*
|
1483
|
+
* Used to copy a rectangular portion of one image to another image. (For a way
|
1484
|
+
* of stretching or shrinking the image in the process, see
|
1485
|
+
* Image.copy_resized.)
|
1486
|
+
*
|
1487
|
+
* The dst argument is the destination image to which the region will be copied.
|
1488
|
+
* The src argument is the source image from which the region is copied. The
|
1489
|
+
* dstX and dstY arguments specify the point in the destination image to which
|
1490
|
+
* the region will be copied. The srcX and srcY arguments specify the upper left
|
1491
|
+
* corner of the region in the source image. The w and h arguments specify the
|
1492
|
+
* width and height of the region.
|
1493
|
+
*
|
1494
|
+
* When you copy a region from one location in an image to another location in
|
1495
|
+
* the same image, this method will perform as expected unless the regions
|
1496
|
+
* overlap, in which case the result is unpredictable.
|
1497
|
+
*
|
1498
|
+
* Important note on copying between images: since different images do not
|
1499
|
+
* necessarily have the same color tables, pixels are not simply set to the
|
1500
|
+
* same color index values to copy them. This method will attempt to find an
|
1501
|
+
* identical RGB value in the destination image for each pixel in the copied
|
1502
|
+
* portion of the source image by invoking Image.color_exact. If such a
|
1503
|
+
* value is not found, this method will attempt to allocate colors as needed
|
1504
|
+
* using Image.color_allocate. If both of these methods fail, this method
|
1505
|
+
* will invoke Image.color_closest to find the color in the destination
|
1506
|
+
* image which most closely approximates the color of the pixel being copied.
|
1507
|
+
*/
|
1508
|
+
static VALUE image_copy(VALUE klass, VALUE srcImg, VALUE dstX, VALUE dstY, VALUE srcX, VALUE srcY, VALUE w, VALUE h) {
|
1509
|
+
gdImagePtr dst, src;
|
1510
|
+
Data_Get_Struct(klass, gdImage, dst);
|
1511
|
+
Data_Get_Struct(srcImg, gdImage, src);
|
1512
|
+
gdImageCopy(dst, src, NUM2INT(dstX), NUM2INT(dstY), NUM2INT(srcX), NUM2INT(srcY), NUM2INT(w), NUM2INT(h));
|
1513
|
+
return klass;
|
1514
|
+
}
|
1515
|
+
|
1516
|
+
static VALUE gd_X__gip2_H7(VALUE klass, VALUE img2, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g, void (GDFUNC *pfunc)(gdImagePtr, gdImagePtr, int, int, int, int, int, int, int)) {
|
1517
|
+
gdImagePtr im, im2;
|
1518
|
+
Data_Get_Struct(klass, gdImage, im);
|
1519
|
+
Data_Get_Struct(img2, gdImage, im2);
|
1520
|
+
(*pfunc)(im, im2, NUM2INT(a), NUM2INT(b), NUM2INT(c), NUM2INT(d), NUM2INT(e), NUM2INT(f), NUM2INT(g));
|
1521
|
+
return klass;
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
/*
|
1525
|
+
* call-seq:
|
1526
|
+
* copy_merge(src, dstX, dstY, srcX, srcY, w, h, pct)
|
1527
|
+
*
|
1528
|
+
* This method is almost identical to GD::Image.copy, except that it 'merges'
|
1529
|
+
* the two images by an amount specified in the last parameter. If the last
|
1530
|
+
* parameter is 100, then it will function identically to GD::Image.copy - the
|
1531
|
+
* source image replaces the pixels in the destination.
|
1532
|
+
*
|
1533
|
+
* If, however, the pct parameter is less than 100, then the two images are
|
1534
|
+
* merged. With pct = 0, no action is taken.
|
1535
|
+
*
|
1536
|
+
* This feature is most useful to 'highlight' sections of an image by merging a
|
1537
|
+
* solid color with pct = 50:
|
1538
|
+
*
|
1539
|
+
* dst.copy_merge(src, 100, 200, 0, 0, 30, 50, 50)
|
1540
|
+
*/
|
1541
|
+
static VALUE image_copy_merge(VALUE klass, VALUE srcImg, VALUE dstX, VALUE dstY, VALUE srcX, VALUE srcY, VALUE w, VALUE h, VALUE pct) {
|
1542
|
+
return gd_X__gip2_H7(klass, srcImg, dstX, dstY, srcX, srcY, w, h, pct, gdImageCopyMerge);
|
1543
|
+
}
|
1544
|
+
|
1545
|
+
/*
|
1546
|
+
* call-seq:
|
1547
|
+
* copy_merge_gray(src, dstX, dstY, srcX, srcY, w, h, pct)
|
1548
|
+
*
|
1549
|
+
* This method is almost identical to GD::Image.copy_merge, except that when
|
1550
|
+
* merging images it preserves the hue of the source by converting the
|
1551
|
+
* destination pixels to grey scale before the copy operation.
|
1552
|
+
*/
|
1553
|
+
static VALUE image_copy_merge_gray(VALUE klass, VALUE srcImg, VALUE dstX, VALUE dstY, VALUE srcX, VALUE srcY, VALUE w, VALUE h, VALUE pct) {
|
1554
|
+
return gd_X__gip2_H7(klass, srcImg, dstX, dstY, srcX, srcY, w, h, pct, gdImageCopyMergeGray);
|
1555
|
+
}
|
1556
|
+
|
1557
|
+
static VALUE gd_X__gip2_H8(VALUE klass, VALUE img2, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, VALUE f, VALUE g, VALUE h, void (GDFUNC *pfunc)(gdImagePtr, gdImagePtr, int, int, int, int, int, int, int, int)) {
|
1558
|
+
gdImagePtr im, im2;
|
1559
|
+
Data_Get_Struct(klass, gdImage, im);
|
1560
|
+
Data_Get_Struct(img2, gdImage, im2);
|
1561
|
+
(*pfunc)(im, im2, NUM2INT(a), NUM2INT(b), NUM2INT(c), NUM2INT(d), NUM2INT(e), NUM2INT(f), NUM2INT(g), NUM2INT(h));
|
1562
|
+
return klass;
|
1563
|
+
}
|
1564
|
+
|
1565
|
+
/*
|
1566
|
+
* call-seq:
|
1567
|
+
* copy_resized(src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH)
|
1568
|
+
*
|
1569
|
+
* Used to copy a rectangular portion of one image to another image. The X and Y
|
1570
|
+
* dimensions of the original region and the destination region can vary,
|
1571
|
+
* resulting in stretching or shrinking of the region as appropriate. (For a
|
1572
|
+
* simpler version of this function which does not deal with resizing,
|
1573
|
+
* see Image.copy.)
|
1574
|
+
*
|
1575
|
+
* The dst argument is the destination image to which the region will be copied.
|
1576
|
+
* The src argument is the source image from which the region is copied. The
|
1577
|
+
* dstX and dstY arguments specify the point in the destination image to which
|
1578
|
+
* the region will be copied. The srcX and srcY arguments specify the upper left
|
1579
|
+
* corner of the region in the source image. The dstW and dstH arguments specify
|
1580
|
+
* the width and height of the destination region. The srcW and srcH arguments
|
1581
|
+
* specify the width and height of the source region and can differ from the
|
1582
|
+
* destination size, allowing a region to be scaled during the copying process.
|
1583
|
+
*
|
1584
|
+
* When you copy a region from one location in an image to another location in
|
1585
|
+
* the same image, Image.copy will perform as expected unless the regions
|
1586
|
+
* overlap, in which case the result is unpredictable. If this presents a
|
1587
|
+
* problem, create a scratch image in which to keep intermediate results.
|
1588
|
+
*
|
1589
|
+
* Important note on copying between images: since images do not necessarily
|
1590
|
+
* have the same color tables, pixels are not simply set to the same color index
|
1591
|
+
* values to copy them. Image.copy will attempt to find an identical RGB
|
1592
|
+
* value in the destination image for each pixel in the copied portion of the
|
1593
|
+
* source image by invoking Image.color_exact. If such a value is not
|
1594
|
+
* found, Image.copy will attempt to allocate colors as needed
|
1595
|
+
* using Image.color_allocate. If both of these methods fail,
|
1596
|
+
* Image.copy will invoke Image.color_closest to find the color in the
|
1597
|
+
* destination image which most closely approximates the color of the pixel
|
1598
|
+
* being copied.
|
1599
|
+
|
1600
|
+
*/
|
1601
|
+
static VALUE image_copy_resized(VALUE klass, VALUE srcImg, VALUE dstX, VALUE dstY, VALUE srcX, VALUE srcY, VALUE dstW, VALUE dstH, VALUE srcW, VALUE srcH) {
|
1602
|
+
return gd_X__gip2_H8(klass, srcImg, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH, gdImageCopyResized);
|
1603
|
+
}
|
1604
|
+
|
1605
|
+
/*
|
1606
|
+
* call-seq:
|
1607
|
+
* copy_resampled(src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH)
|
1608
|
+
*
|
1609
|
+
* Used to copy a rectangular portion of one image to another image, smoothly
|
1610
|
+
* interpolating pixel values so that, in particular, reducing the size of an
|
1611
|
+
* image still retains a great deal of clarity. The X and Y dimensions of the
|
1612
|
+
* original region and the destination region can vary, resulting in stretching
|
1613
|
+
* or shrinking of the region as appropriate. (For a simpler version of this
|
1614
|
+
* function which does not deal with resizing, see GD::Image.copy. For a version
|
1615
|
+
* which does not interpolate pixel values, see GD::Image.copy_resized.
|
1616
|
+
*
|
1617
|
+
* Pixel values are only interpolated if the destination image is a truecolor
|
1618
|
+
* image. Otherwise, GD::Image.copy_resized is automatically invoked.
|
1619
|
+
*
|
1620
|
+
* The dst argument is the destination image to which the region will be copied.
|
1621
|
+
* The src argument is the source image from which the region is copied. The
|
1622
|
+
* dstX and dstY arguments specify the point in the destination image to which
|
1623
|
+
* the region will be copied. The srcX and srcY arguments specify the upper left
|
1624
|
+
* corner of the region in the source image. The dstW and dstH arguments specify
|
1625
|
+
* the width and height of the destination region. The srcW and srcH arguments
|
1626
|
+
* specify the width and height of the source region and can differ from the
|
1627
|
+
* destination size, allowing a region to be scaled during the copying process.
|
1628
|
+
*
|
1629
|
+
* When you copy a region from one location in an image to another location in
|
1630
|
+
* the same image, GD::Image.copy will perform as expected unless the regions
|
1631
|
+
* overlap, in which case the result is unpredictable. If this presents a
|
1632
|
+
* problem, create a scratch image in which to keep intermediate results.
|
1633
|
+
*
|
1634
|
+
* Important note on copying between images: since images do not necessarily
|
1635
|
+
* have the same color tables, pixels are not simply set to the same color
|
1636
|
+
* index values to copy them. If the destination image is a palette image,
|
1637
|
+
* gd will use the Image.color_resolve function to determine the best color
|
1638
|
+
* available.
|
1639
|
+
*/
|
1640
|
+
static VALUE image_copy_resampled(VALUE klass, VALUE srcImg, VALUE dstX, VALUE dstY, VALUE srcX, VALUE srcY, VALUE dstW, VALUE dstH, VALUE srcW, VALUE srcH) {
|
1641
|
+
return gd_X__gip2_H8(klass, srcImg, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH, gdImageCopyResampled);
|
1642
|
+
}
|
1643
|
+
|
1644
|
+
// gd_X__gip2_N2_H5
|
1645
|
+
/*
|
1646
|
+
* call-seq:
|
1647
|
+
* copy_rotated(src, dstX, dstY, srcX, srcY, srcW, srcH, angle)
|
1648
|
+
*
|
1649
|
+
* Used to copy a rectangular portion of one image to another image, or to
|
1650
|
+
* another region of the same image. The srcX and srcY coordinates specify the
|
1651
|
+
* upper left corner of the source area; however, the dstX and dstY coordinates
|
1652
|
+
* specify the CENTER of the destination area. This important distinction is
|
1653
|
+
* made because the rotated rectangle may may or may not be parallel to the X
|
1654
|
+
* and Y axes. The destination coordinates may be floating point, as the center
|
1655
|
+
* of the desired destination area may lie at the center of a pixel (0.5 pixels)
|
1656
|
+
* rather than its upper left corner. The angle specified is an integer number
|
1657
|
+
* of degrees, between 0 and 360, with 0 degrees causing no change, and
|
1658
|
+
* counterclockwise rotation as the angle increases.
|
1659
|
+
*
|
1660
|
+
* When you copy a region from one location in an image to another location in
|
1661
|
+
* the same image, this method will perform as expected unless the regions
|
1662
|
+
* overlap, in which case the result is unpredictable. If this presents a
|
1663
|
+
* problem, create a scratch image in which to keep intermediate results.
|
1664
|
+
*
|
1665
|
+
* Important note on copying between images: since palette-based images do not
|
1666
|
+
* necessarily have the same color tables, pixels are not simply set to the same
|
1667
|
+
* color index values to copy them. If the destination image is not a truecolor
|
1668
|
+
* image, Image.color_resolve is used to choose the destination pixel.
|
1669
|
+
*/
|
1670
|
+
static VALUE image_copy_rotated(VALUE klass, VALUE srcImg, VALUE dstX, VALUE dstY, VALUE srcX, VALUE srcY, VALUE srcW, VALUE srcH, VALUE angle) {
|
1671
|
+
gdImagePtr dst, src;
|
1672
|
+
Data_Get_Struct(klass, gdImage, dst);
|
1673
|
+
Data_Get_Struct(srcImg, gdImage, src);
|
1674
|
+
gdImageCopyRotated(dst, src, NUM2DBL(dstX), NUM2DBL(dstY), NUM2INT(srcX), NUM2INT(srcY), NUM2INT(srcW), NUM2INT(srcH), NUM2INT(angle));
|
1675
|
+
return klass;
|
1676
|
+
}
|
1677
|
+
|
1678
|
+
static VALUE gd_X__gip_H(VALUE klass, VALUE a, void (GDFUNC *pfunc)(gdImagePtr, int)) {
|
1679
|
+
gdImagePtr im;
|
1680
|
+
Data_Get_Struct(klass, gdImage, im);
|
1681
|
+
(*pfunc)(im, NUM2INT(a));
|
1682
|
+
return a;
|
1683
|
+
}
|
1684
|
+
|
1685
|
+
/*
|
1686
|
+
* call-seq:
|
1687
|
+
* interlace = boolean
|
1688
|
+
*
|
1689
|
+
* Used to determine whether an image should be stored in a linear fashion, in
|
1690
|
+
* which lines will appear on the display from first to last, or in an
|
1691
|
+
* interlaced fashion, in which the image will "fade in" over several passes.
|
1692
|
+
* By default, images are not interlaced. (When writing JPEG images, interlacing
|
1693
|
+
* implies generating progressive JPEG files, which are represented as a series
|
1694
|
+
* of scans of increasing quality. Noninterlaced gd images result in regular
|
1695
|
+
* (sequential) JPEG data streams.)
|
1696
|
+
*
|
1697
|
+
* Note that interlace has no effect on other functions, and has no meaning
|
1698
|
+
* unless you save the image in PNG or JPEG format.
|
1699
|
+
*/
|
1700
|
+
static VALUE image_interlace_set(VALUE klass, VALUE interlace) {
|
1701
|
+
return gd_X__gip_H(klass, RTEST(interlace) ? INT2NUM(1) : INT2NUM(0), gdImageInterlace);
|
1702
|
+
}
|
1703
|
+
|
1704
|
+
/*
|
1705
|
+
* call-seq:
|
1706
|
+
* antialiased = color
|
1707
|
+
*
|
1708
|
+
* "Antialiasing" is a process by which jagged edges associated with line
|
1709
|
+
* drawing can be reduced by blending the foreground color with an appropriate
|
1710
|
+
* percentage of the background, depending on how much of the pixel in question
|
1711
|
+
* is actually within the boundaries of the line being drawn. All line-drawing
|
1712
|
+
* functions, such as Image.line, Image.open_polygon and Image.polygon, will
|
1713
|
+
* draw antialiased lines if the special "color" COLOR_ANTIALIASED is used when
|
1714
|
+
* calling them.
|
1715
|
+
*
|
1716
|
+
* this method is used to specify the actual foreground color to be used when
|
1717
|
+
* drawing antialiased lines. You may set any color to be the foreground,
|
1718
|
+
* however as of version 2.0.12 an alpha channel component is not supported.
|
1719
|
+
*
|
1720
|
+
* Antialiased lines can be drawn on both truecolor and palette-based images.
|
1721
|
+
* However, attempts to draw antialiased lines on highly complex palette-based
|
1722
|
+
* backgrounds may not give satisfactory results, due to the limited number of
|
1723
|
+
* colors available in the palette. Antialiased line-drawing on simple
|
1724
|
+
* backgrounds should work well with palette-based images; otherwise create or
|
1725
|
+
* fetch a truecolor image instead.
|
1726
|
+
*/
|
1727
|
+
static VALUE image_set_antialiased(VALUE klass, VALUE color){
|
1728
|
+
return gd_X__gip_H(klass, color, gdImageSetAntiAliased);
|
1729
|
+
}
|
1730
|
+
|
1731
|
+
/*
|
1732
|
+
* call-seq:
|
1733
|
+
* thickness = width
|
1734
|
+
*
|
1735
|
+
* This method determines the width of lines drawn by the Image.line,
|
1736
|
+
* Image.polygon, Image.open_polygon and related methods, in pixels.
|
1737
|
+
*/
|
1738
|
+
static VALUE image_set_thickness(VALUE klass, VALUE thickness) {
|
1739
|
+
return gd_X__gip_H(klass, thickness, gdImageSetThickness);
|
1740
|
+
}
|
1741
|
+
|
1742
|
+
/*
|
1743
|
+
* call-seq:
|
1744
|
+
* alpha_blending = boolean
|
1745
|
+
*
|
1746
|
+
* This method allows for two different modes of drawing on truecolor images. In
|
1747
|
+
* blending mode, which is on by default (gd 2.0.2 and above), the alpha channel
|
1748
|
+
* component of the color supplied to all drawing functions, such as
|
1749
|
+
* Image.pixels[]=, determines how much of the underlying color should be
|
1750
|
+
* allowed to shine through. As a result, gd automatically blends the existing
|
1751
|
+
* color at that point with the drawing color, and stores the result in the
|
1752
|
+
* image. The resulting pixel is opaque. In non-blending mode, the drawing color
|
1753
|
+
* is copied literally with its alpha channel information, replacing the
|
1754
|
+
* destination pixel. Blending mode is not available when drawing on palette
|
1755
|
+
* images.
|
1756
|
+
*/
|
1757
|
+
static VALUE image_set_alpha_blending(VALUE klass, VALUE blending) {
|
1758
|
+
return gd_X__gip_H(klass, RTEST(blending) ? INT2NUM(1) : INT2NUM(0) , gdImageAlphaBlending);
|
1759
|
+
}
|
1760
|
+
|
1761
|
+
/*
|
1762
|
+
* call-seq:
|
1763
|
+
* save_alpha = boolean
|
1764
|
+
*
|
1765
|
+
* By default, gd 2.0.2 and above do not attempt to save full alpha channel
|
1766
|
+
* information (as opposed to single-color transparency) when saving PNG images.
|
1767
|
+
* (PNG is currently the only output format supported by gd which can
|
1768
|
+
* accommodate alpa channel information.) This saves space in the output file.
|
1769
|
+
* If you wish to create an image with alpha channel information for use with
|
1770
|
+
* tools that support it, set save_alpha=true to turn on saving of such
|
1771
|
+
* information, and set alpha_blending=false to turn off alpha blending within
|
1772
|
+
* the library so that alpha channel information is actually stored in the image
|
1773
|
+
* rather than being composited immediately at the time that drawing functions
|
1774
|
+
* are invoked.
|
1775
|
+
*/
|
1776
|
+
static VALUE image_save_alpha(VALUE klass, VALUE save) {
|
1777
|
+
return gd_X__gip_H(klass, RTEST(save) ? INT2NUM(1) : INT2NUM(0), gdImageSaveAlpha);
|
1778
|
+
}
|
1779
|
+
|
1780
|
+
/*
|
1781
|
+
* call-seq:
|
1782
|
+
* transparent = color
|
1783
|
+
*
|
1784
|
+
* Set the transparent color index for the specified image to the specified
|
1785
|
+
* index. To indicate that there should be no transparent color, invoke this
|
1786
|
+
* method with a color index of -1. Note that JPEG images do not support
|
1787
|
+
* transparency, so this setting has no effect when writing JPEG images.
|
1788
|
+
*
|
1789
|
+
* The color index used should be an index allocated by Image.color_allocate,
|
1790
|
+
* whether explicitly invoked by your code or implicitly invoked by loading an
|
1791
|
+
* image. In order to ensure that your image has a reasonable appearance when
|
1792
|
+
* viewed by users who do not have transparent background capabilities (or when
|
1793
|
+
* you are writing a JPEG-format file, which does not support transparency), be
|
1794
|
+
* sure to give reasonable RGB values to the color you allocate for use as a
|
1795
|
+
* transparent color, even though it will be transparent on systems that support
|
1796
|
+
* PNG transparency.
|
1797
|
+
*/
|
1798
|
+
static VALUE image_color_transparent(VALUE klass, VALUE color) {
|
1799
|
+
return gd_X__gip_H(klass, color, gdImageColorTransparent);
|
1800
|
+
}
|
1801
|
+
|
1802
|
+
/*
|
1803
|
+
* call-seq:
|
1804
|
+
* color_deallocate(color)
|
1805
|
+
*
|
1806
|
+
* Marks the specified color as being available for reuse. It does not attempt
|
1807
|
+
* to determine whether the color index is still in use in the image. After a
|
1808
|
+
* call to this function, the next call to Image.color_allocate for the same
|
1809
|
+
* image will set new RGB values for that color index, changing the color of any
|
1810
|
+
* pixels which have that index as a result. If multiple calls to this method
|
1811
|
+
* are made consecutively, the lowest-numbered index among them will be reused
|
1812
|
+
* by the next Image.color_allocate call.
|
1813
|
+
*/
|
1814
|
+
static VALUE image_color_deallocate(VALUE klass, VALUE color) {
|
1815
|
+
return gd_X__gip_H(klass, color, gdImageColorDeallocate);
|
1816
|
+
}
|
1817
|
+
|
1818
|
+
/*
|
1819
|
+
* call-seq:
|
1820
|
+
* sharepen(pct)
|
1821
|
+
*
|
1822
|
+
* Sharpens the specified image. pct is a sharpening percentage, and can be
|
1823
|
+
* greater than 100. Silently does nothing to non-truecolor images. Silently
|
1824
|
+
* does nothing for pct<0. Transparency/alpha channel are not altered.
|
1825
|
+
*/
|
1826
|
+
static VALUE image_sharepen(VALUE klass, VALUE pct) {
|
1827
|
+
return gd_X__gip_H(klass, pct, gdImageSharpen);
|
1828
|
+
}
|
1829
|
+
|
1830
|
+
static VALUE gd_X__gip_H2(VALUE klass, VALUE a, VALUE b, void (GDFUNC *pfunc)(gdImagePtr, int, int)) {
|
1831
|
+
gdImagePtr im;
|
1832
|
+
Data_Get_Struct(klass, gdImage, im);
|
1833
|
+
(*pfunc)(im, NUM2INT(a), NUM2INT(b));
|
1834
|
+
return klass;
|
1835
|
+
}
|
1836
|
+
|
1837
|
+
/*
|
1838
|
+
* call-seq:
|
1839
|
+
* to_palette!(dither = true, colors = MAX_COLORS)
|
1840
|
+
*
|
1841
|
+
* Convert a truecolor image to a palette-based image, using a high-quality
|
1842
|
+
* two-pass quantization routine.
|
1843
|
+
*
|
1844
|
+
* If _dither_ is true, the image will be dithered to approximate colors better,
|
1845
|
+
* at the expense of some obvious "speckling." _colors_ can be anything up to 256.
|
1846
|
+
* If the original source image includes photographic information or
|
1847
|
+
* anything that came out of a JPEG, 256 is strongly recommended. 100%
|
1848
|
+
* transparency of a single transparent color in the original truecolor image
|
1849
|
+
* will be preserved. There is no other support for preservation of alpha
|
1850
|
+
* channel or transparency in the destination image.
|
1851
|
+
*/
|
1852
|
+
static VALUE image_truecolor_to_palette(int argc, VALUE* argv, VALUE klass) {
|
1853
|
+
VALUE dither, colors;
|
1854
|
+
|
1855
|
+
if (image_is_truecolor(klass) == Qfalse) return klass;
|
1856
|
+
|
1857
|
+
rb_scan_args(argc, argv, "02", &dither, &colors);
|
1858
|
+
return gd_X__gip_H2(klass,
|
1859
|
+
(dither == Qnil || dither == Qtrue ? INT2NUM(1) : INT2NUM(0)),
|
1860
|
+
(colors == Qnil ? INT2NUM(gdMaxColors) : colors),
|
1861
|
+
gdImageTrueColorToPalette);
|
1862
|
+
}
|
1863
|
+
|
1864
|
+
/*
|
1865
|
+
* call-seq:
|
1866
|
+
* antialiased_dont_blend(color, boolean)
|
1867
|
+
*
|
1868
|
+
* Normally, when drawing lines with the special COLOR_ANTIALIASED "color,"
|
1869
|
+
* blending with the background to reduce jagged edges is the desired behavior.
|
1870
|
+
* However, when it is desired that lines not be blended with one particular
|
1871
|
+
* color when it is encountered in the background, this method can be used to
|
1872
|
+
* indicate the special color that the foreground should stand out more clearly
|
1873
|
+
* against.
|
1874
|
+
*/
|
1875
|
+
static VALUE image_set_antialiased_dont_blend(VALUE klass, VALUE color, VALUE dont_blend) {
|
1876
|
+
return gd_X__gip_H2(klass, color, RTEST(dont_blend) ? INT2NUM(1) : INT2NUM(0), gdImageSetAntiAliasedDontBlend);
|
1877
|
+
}
|
1878
|
+
|
1879
|
+
static VALUE gd_X__gip_H3(VALUE klass, VALUE a, VALUE b, VALUE c, void (GDFUNC *pfunc)(gdImagePtr, int, int, int)) {
|
1880
|
+
gdImagePtr im;
|
1881
|
+
Data_Get_Struct(klass, gdImage, im);
|
1882
|
+
(*pfunc)(im, NUM2INT(a), NUM2INT(b), NUM2INT(c));
|
1883
|
+
return klass;
|
1884
|
+
}
|
1885
|
+
|
1886
|
+
/*
|
1887
|
+
* call-seq:
|
1888
|
+
* slef[x, y] = color
|
1889
|
+
*
|
1890
|
+
* Sets a pixel to a particular color index.
|
1891
|
+
*/
|
1892
|
+
static VALUE image_set_pixel(VALUE klass, VALUE x, VALUE y, VALUE color) {
|
1893
|
+
return gd_X__gip_H3(klass, x, y, color, gdImageSetPixel);
|
1894
|
+
}
|
1895
|
+
|
1896
|
+
/*
|
1897
|
+
* call-seq:
|
1898
|
+
* fill(x, y, color)
|
1899
|
+
*
|
1900
|
+
* Floods a portion of the image with the specified color, beginning at the
|
1901
|
+
* specified point and flooding the surrounding region of the same color as the
|
1902
|
+
* starting point. For a way of flooding a region defined by a specific border
|
1903
|
+
* color rather than by its interior color, see Image.fill_to_border.
|
1904
|
+
*
|
1905
|
+
* The fill color can be COLOR_TILED, resulting in a tile fill using another
|
1906
|
+
* image as the tile. However, the tile image cannot be transparent. If the
|
1907
|
+
* image you wish to fill with has a transparent color index, call
|
1908
|
+
* Image.transparent= and set the transparent color index to -1 to turn off its
|
1909
|
+
* transparency.
|
1910
|
+
*
|
1911
|
+
* Note, this method is recursive. It is not the most naive implementation
|
1912
|
+
* possible, and the implementation is expected to improve, but there will
|
1913
|
+
* always be degenerate cases in which the stack can become very deep. This can
|
1914
|
+
* be a problem in MSDOS and MS Windows environments. (Of course, in a Unix or
|
1915
|
+
* Windows 95/98/NT environment with a proper stack, this is not a problem at
|
1916
|
+
* all.)
|
1917
|
+
*/
|
1918
|
+
static VALUE image_fill(VALUE klass, VALUE x, VALUE y, VALUE color) {
|
1919
|
+
return gd_X__gip_H3(klass, x, y, color, gdImageFill);
|
1920
|
+
}
|
1921
|
+
|
1922
|
+
static VALUE gd_X__gip_H4(VALUE klass, VALUE a, VALUE b, VALUE c, VALUE d, void (GDFUNC *pfunc)(gdImagePtr, int, int, int, int)) {
|
1923
|
+
gdImagePtr im;
|
1924
|
+
Data_Get_Struct(klass, gdImage, im);
|
1925
|
+
(*pfunc)(im, NUM2INT(a), NUM2INT(b), NUM2INT(c), NUM2INT(d));
|
1926
|
+
return klass;
|
1927
|
+
}
|
1928
|
+
|
1929
|
+
/*
|
1930
|
+
* call-seq:
|
1931
|
+
* fill_to_border(x, y, border, color)
|
1932
|
+
*
|
1933
|
+
* Floods a portion of the image with the specified color, beginning at the
|
1934
|
+
* specified point and stopping at the specified border color. For a way of
|
1935
|
+
* flooding an area defined by the color of the starting point, see Image.fill.
|
1936
|
+
*
|
1937
|
+
* The border color cannot be a special color such as COLOR_TILED; it must be a
|
1938
|
+
* proper solid color. The fill color can be, however.
|
1939
|
+
*
|
1940
|
+
* Note, this method is recursive. It is not the most naive implementation
|
1941
|
+
* possible, and the implementation is expected to improve, but there will
|
1942
|
+
* always be degenerate cases in which the stack can become very deep. This can
|
1943
|
+
* be a problem in MSDOS and MS Windows 3.1 environments. (Of course, in a Unix
|
1944
|
+
* or Windows 95/98/NT environment with a proper stack, this is not a problem at
|
1945
|
+
* all.)
|
1946
|
+
*/
|
1947
|
+
static VALUE image_fill_to_border(VALUE klass, VALUE x, VALUE y, VALUE border, VALUE color) {
|
1948
|
+
return gd_X__gip_H4(klass, x, y, border, color, gdImageFillToBorder);
|
1949
|
+
}
|
1950
|
+
|
1951
|
+
/*
|
1952
|
+
* call-seq:
|
1953
|
+
* clip = x1, y1, x2, y2
|
1954
|
+
*
|
1955
|
+
* Establishes a clipping rectangle. Once this method has been called, all
|
1956
|
+
* future drawing operations will remain within the specified clipping area,
|
1957
|
+
* until a new call takes place. For instance, if a clipping rectangle
|
1958
|
+
* of 25, 25, 75, 75 has been set within a 100x100 image, a diagonal line
|
1959
|
+
* from 0,0 to 99,99 will appear only between 25,25 and 75,75.
|
1960
|
+
*
|
1961
|
+
* If this method is never called, the clipping area will be the entire image.
|
1962
|
+
*
|
1963
|
+
* The parameters passed in are checked against the dimensions of the image and
|
1964
|
+
* limited to "safe" values.
|
1965
|
+
*/
|
1966
|
+
static VALUE image_set_clip(VALUE klass, VALUE x1, VALUE y1, VALUE x2, VALUE y2) {
|
1967
|
+
return gd_X__gip_H4(klass, x1, y1, x2, y2, gdImageSetClip);
|
1968
|
+
}
|
1969
|
+
|
1970
|
+
static VALUE gd_X__gip_H5(VALUE klass, VALUE a, VALUE b, VALUE c, VALUE d, VALUE e, void (GDFUNC *pfunc)(gdImagePtr, int, int, int, int, int)) {
|
1971
|
+
gdImagePtr im;
|
1972
|
+
Data_Get_Struct(klass, gdImage, im);
|
1973
|
+
(*pfunc)(im, NUM2INT(a), NUM2INT(b), NUM2INT(c), NUM2INT(d), NUM2INT(e));
|
1974
|
+
return klass;
|
1975
|
+
}
|
1976
|
+
|
1977
|
+
/*
|
1978
|
+
* call-seq:
|
1979
|
+
* line(x1, y1, x2, y2, color)
|
1980
|
+
*
|
1981
|
+
* Used to draw a line between two endpoints (x1,y1 and x2, y2). The line is
|
1982
|
+
* drawn using the color index specified. Note that the color index can be an
|
1983
|
+
* actual color returned by Image.color_allocate or one of COLOR_STYLED,
|
1984
|
+
* COLOR_BRUSHED or COLOR_STYLED_BRUSHED.
|
1985
|
+
*/
|
1986
|
+
static VALUE image_line(VALUE klass, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE color) {
|
1987
|
+
return gd_X__gip_H5(klass, x1, y1, x2, y2, color, gdImageLine);
|
1988
|
+
}
|
1989
|
+
|
1990
|
+
/*
|
1991
|
+
* call-seq:
|
1992
|
+
* dashed_line(x1, y1, x2, y2, color)
|
1993
|
+
*
|
1994
|
+
* Provided solely for backwards compatibility with gd 1.0. New programs should
|
1995
|
+
* draw dashed lines using the normal Image.line and the new Image.set_style.
|
1996
|
+
*
|
1997
|
+
* This method is used to draw a dashed line between two endpoints (x1,y1 and
|
1998
|
+
* x2, y2). The line is drawn using the color index specified. The portions of
|
1999
|
+
* the line that are not drawn are left transparent so the background is
|
2000
|
+
* visible.
|
2001
|
+
*/
|
2002
|
+
static VALUE image_dashed_line(VALUE klass, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE color) {
|
2003
|
+
return gd_X__gip_H5(klass, x1, y1, x2, y2, color, gdImageDashedLine);
|
2004
|
+
}
|
2005
|
+
|
2006
|
+
/*
|
2007
|
+
* call-seq:
|
2008
|
+
* rectangle(x1, y1, x2, y2, color)
|
2009
|
+
*
|
2010
|
+
* Used to draw a rectangle with the two corners (upper left first, then lower
|
2011
|
+
* right) specified, using the color index specified.
|
2012
|
+
*/
|
2013
|
+
static VALUE image_rectangle(VALUE klass, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE color) {
|
2014
|
+
return gd_X__gip_H5(klass, x1, y1, x2, y2, color, gdImageRectangle);
|
2015
|
+
}
|
2016
|
+
|
2017
|
+
/*
|
2018
|
+
* call-seq:
|
2019
|
+
* filled_rectangle(x1, y1, x2, y2, color)
|
2020
|
+
*
|
2021
|
+
* Used to fill a polygon with the verticies (at least 3) specified, using the
|
2022
|
+
* color index specified. See also Image.polygon.
|
2023
|
+
*/
|
2024
|
+
static VALUE image_filled_rectangle(VALUE klass, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE color) {
|
2025
|
+
return gd_X__gip_H5(klass, x1, y1, x2, y2, color, gdImageFilledRectangle);
|
2026
|
+
}
|
2027
|
+
|
2028
|
+
/*
|
2029
|
+
* call-seq:
|
2030
|
+
* filled_ellipse(x1, y1, x2, y2, color)
|
2031
|
+
*
|
2032
|
+
* Used to draw an ellipse centered at the given point, with the specified width
|
2033
|
+
* and height in pixels. The ellipse is filled in the color specified by the
|
2034
|
+
* last argument.
|
2035
|
+
*/
|
2036
|
+
static VALUE image_filled_ellipse(VALUE klass, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE color) {
|
2037
|
+
return gd_X__gip_H5(klass, x1, y1, x2, y2, color, gdImageFilledEllipse);
|
2038
|
+
}
|
2039
|
+
|
2040
|
+
// gd_X__gip_H7
|
2041
|
+
/*
|
2042
|
+
* call-seq:
|
2043
|
+
* arc(cx, cy, w, h, s, e, color)
|
2044
|
+
*
|
2045
|
+
* Used to draw a partial ellipse centered at the given point, with the
|
2046
|
+
* specified width and height in pixels. The arc begins at the position in
|
2047
|
+
* degrees specified by _s_ and ends at the position specified by _e_. The arc
|
2048
|
+
* is drawn in the color specified by the last argument. A circle can be drawn
|
2049
|
+
* by beginning from 0 degrees and ending at 360 degrees, with width and height
|
2050
|
+
* being equal. _e_ must be greater than _s_. Values greater than 360 are
|
2051
|
+
* interpreted modulo 360.
|
2052
|
+
*/
|
2053
|
+
static VALUE image_arc(VALUE klass, VALUE cx, VALUE cy, VALUE w, VALUE h, VALUE s, VALUE e, VALUE color) {
|
2054
|
+
gdImagePtr im;
|
2055
|
+
Data_Get_Struct(klass, gdImage, im);
|
2056
|
+
gdImageArc(im, NUM2INT(cx), NUM2INT(cy), NUM2INT(w), NUM2INT(h), NUM2INT(s), NUM2INT(e), NUM2INT(color));
|
2057
|
+
}
|
2058
|
+
|
2059
|
+
// gd_X__gip_H8
|
2060
|
+
/*
|
2061
|
+
* call-seq:
|
2062
|
+
* filled_arc(cx, cy, w, h, s, e, color, style)
|
2063
|
+
*
|
2064
|
+
* Used to draw a partial ellipse centered at the given point, with the
|
2065
|
+
* specified width and height in pixels. The arc begins at the position in
|
2066
|
+
* degrees specified by _s_ and ends at the position specified by _e_. The arc
|
2067
|
+
* is filled in the color specified by the second to last argument. A circle can
|
2068
|
+
* be drawn by beginning from 0 degrees and ending at 360 degrees, with width
|
2069
|
+
* and height being equal. _e_ must be greater than _s_. Values greater than 360
|
2070
|
+
* are interpreted modulo 360. The last argument is a bitwise OR of the
|
2071
|
+
* following possibilities:
|
2072
|
+
*
|
2073
|
+
* * STYLE_ARC
|
2074
|
+
* * STYLE_CHORD
|
2075
|
+
* * STYLE_PIE (synonym for STYLE_CHORD)
|
2076
|
+
* * STYLE_NO_FILL
|
2077
|
+
* * STYLE_EDGED
|
2078
|
+
*
|
2079
|
+
* STYLE_ARC and STYLE_CHORD are mutually exclusive; STYLE_CHORD just connects
|
2080
|
+
* the starting and ending angles with a straight line, while STYLE_ARC produces
|
2081
|
+
* a rounded edge. STYLE_PIE is a synonym for STYLE_ARC. STYLE_NO_FILL indicates
|
2082
|
+
* that the arc or chord should be outlined, not filled. STYLE_EDGED, used
|
2083
|
+
* together with STYLE_NO_FILL, indicates that the beginning and ending angles
|
2084
|
+
* should be connected to the center; this is a good way to outline (rather than
|
2085
|
+
* fill) a 'pie slice'.
|
2086
|
+
*
|
2087
|
+
*/
|
2088
|
+
static VALUE image_filled_arc(VALUE klass, VALUE cx, VALUE cy, VALUE w, VALUE h, VALUE s, VALUE e, VALUE color, VALUE style) {
|
2089
|
+
gdImagePtr im;
|
2090
|
+
Data_Get_Struct(klass, gdImage, im);
|
2091
|
+
gdImageFilledArc(im, NUM2INT(cx), NUM2INT(cy), NUM2INT(w), NUM2INT(h), NUM2INT(s), NUM2INT(e), NUM2INT(color), NUM2INT(style));
|
2092
|
+
}
|
2093
|
+
|
2094
|
+
// gd_X__gip_PAH4
|
2095
|
+
/*
|
2096
|
+
* call-seq:
|
2097
|
+
* x1, y1, x2, y2 = clip
|
2098
|
+
*
|
2099
|
+
* Fetches the boundaries of the current clipping rectangle.
|
2100
|
+
*/
|
2101
|
+
static VALUE image_get_clip(VALUE klass) {
|
2102
|
+
int x1, y1, x2, y2;
|
2103
|
+
gdImagePtr im;
|
2104
|
+
Data_Get_Struct(klass, gdImage, im);
|
2105
|
+
gdImageGetClip(im, &x1, &y1, &x2, &y2);
|
2106
|
+
return rb_ary_new3(4, INT2NUM(x1), INT2NUM(y1), INT2NUM(x2), INT2NUM(y2));
|
2107
|
+
}
|
2108
|
+
|
2109
|
+
// gd_X__gip_PAH_H
|
2110
|
+
/*
|
2111
|
+
* call-seq:
|
2112
|
+
* styles = array
|
2113
|
+
*
|
2114
|
+
* It is often desirable to draw dashed lines, dotted lines, and other
|
2115
|
+
* variations on a broken line. This method can be used to set any desired
|
2116
|
+
* series of colors, including a special color that leaves the background
|
2117
|
+
* intact, to be repeated during the drawing of a line.
|
2118
|
+
*
|
2119
|
+
* To use this method, create an array of integers and assign them the desired
|
2120
|
+
* series of color values to be repeated. You can assign the special color value
|
2121
|
+
* COLOR_TRANSPARENT to indicate that the existing color should be left
|
2122
|
+
* unchanged for that particular pixel (allowing a dashed line to be
|
2123
|
+
* attractively drawn over an existing image).
|
2124
|
+
*
|
2125
|
+
* Then, to draw a line using the style, use the normal Image.line with the
|
2126
|
+
* special color value COLOR_STYLED.
|
2127
|
+
*
|
2128
|
+
* You can also combine styles and brushes to draw the brush image at intervals
|
2129
|
+
* instead of in a continuous stroke. When creating a style for use with a
|
2130
|
+
* brush, the style values are interpreted differently: zero (0) indicates
|
2131
|
+
* pixels at which the brush should not be drawn, while one (1) indicates pixels
|
2132
|
+
* at which the brush should be drawn. To draw a styled, brushed line, you must
|
2133
|
+
* use the special color value COLOR_STYLED_BRUSHED.
|
2134
|
+
*/
|
2135
|
+
static VALUE image_set_style(VALUE klass, VALUE styles) {
|
2136
|
+
gdImagePtr im;
|
2137
|
+
int *ary;
|
2138
|
+
int i, len;
|
2139
|
+
|
2140
|
+
Check_Type(styles, T_ARRAY);
|
2141
|
+
len = RARRAY_LEN(styles);
|
2142
|
+
ary = malloc(sizeof(int) * len);
|
2143
|
+
for (i=0;i<len;i++) ary[i] = NUM2INT(rb_ary_entry(styles, i));
|
2144
|
+
|
2145
|
+
Data_Get_Struct(klass, gdImage, im);
|
2146
|
+
gdImageSetStyle(im, ary, len);
|
2147
|
+
free(ary);
|
2148
|
+
return klass;
|
2149
|
+
}
|
2150
|
+
|
2151
|
+
static VALUE gd_X__gip_gptp_H2(VALUE klass, VALUE points, VALUE color, void (GDFUNC *pfunc)(gdImagePtr, gdPointPtr, int, int)) {
|
2152
|
+
gdImagePtr im;
|
2153
|
+
gdPointPtr ary;
|
2154
|
+
int i, len;
|
2155
|
+
VALUE t;
|
2156
|
+
|
2157
|
+
Check_Type(points, T_ARRAY);
|
2158
|
+
Check_Type(color, T_FIXNUM);
|
2159
|
+
Data_Get_Struct(klass, gdImage, im);
|
2160
|
+
len = RARRAY_LEN(points);
|
2161
|
+
ary = malloc(sizeof(gdPoint) * len);
|
2162
|
+
for (i=0;i<len;i++) {
|
2163
|
+
t = rb_ary_entry(points, i);
|
2164
|
+
if (TYPE(t) == T_ARRAY && RARRAY_LEN(t) >= 2 && TYPE(rb_ary_entry(t, 0)) == T_FIXNUM && TYPE(rb_ary_entry(t, 1)) == T_FIXNUM) {
|
2165
|
+
ary[i].x = NUM2INT(rb_ary_entry(t, 0));
|
2166
|
+
ary[i].y = NUM2INT(rb_ary_entry(t, 1));
|
2167
|
+
} else {
|
2168
|
+
free(ary);
|
2169
|
+
rb_raise(rb_eArgError, "array of points please.");
|
2170
|
+
}
|
2171
|
+
}
|
2172
|
+
(*pfunc)(im, ary, len, NUM2INT(color));
|
2173
|
+
free(ary);
|
2174
|
+
return klass;
|
2175
|
+
}
|
2176
|
+
|
2177
|
+
/*
|
2178
|
+
* call-seq:
|
2179
|
+
* polygon(points, color)
|
2180
|
+
*
|
2181
|
+
* Used to draw a polygon with the verticies (at least 3) specified, using the
|
2182
|
+
* color index specified. _points_ is an array looks like [[1, 1], [2, 2], [3, 3]].
|
2183
|
+
*
|
2184
|
+
* See also Image.filled_polygon.
|
2185
|
+
*/
|
2186
|
+
static VALUE image_polygon(VALUE klass, VALUE points, VALUE color) {
|
2187
|
+
return gd_X__gip_gptp_H2(klass, points, color, gdImagePolygon);
|
2188
|
+
}
|
2189
|
+
|
2190
|
+
/*
|
2191
|
+
* call-seq:
|
2192
|
+
* open_polygon(points, color)
|
2193
|
+
*
|
2194
|
+
* Used to draw a sequence of lines with the verticies (at least 3) specified,
|
2195
|
+
* using the color index specified. _points_ is an array looks
|
2196
|
+
* like [[1, 1], [2, 2], [3, 3]]. Unlike Image.polygon, the enpoints of the line
|
2197
|
+
* sequence are not connected to a closed polygon.
|
2198
|
+
*/
|
2199
|
+
static VALUE image_open_polygon(VALUE klass, VALUE points, VALUE color) {
|
2200
|
+
return gd_X__gip_gptp_H2(klass, points, color, gdImageOpenPolygon);
|
2201
|
+
}
|
2202
|
+
|
2203
|
+
/*
|
2204
|
+
* call-seq:
|
2205
|
+
* filled_polygon(points, color)
|
2206
|
+
*
|
2207
|
+
* Used to fill a polygon with the verticies (at least 3) specified, using the
|
2208
|
+
* color index specified. _points_ is an array looks like [[1, 1], [2, 2], [3, 3]].
|
2209
|
+
*
|
2210
|
+
* See also Image.polygon.
|
2211
|
+
*/
|
2212
|
+
static VALUE image_filled_polygon(VALUE klass, VALUE points, VALUE color) {
|
2213
|
+
return gd_X__gip_gptp_H2(klass, points, color, gdImageFilledPolygon);
|
2214
|
+
}
|
2215
|
+
|
2216
|
+
// gd_X__gip
|
2217
|
+
/*
|
2218
|
+
* call-seq:
|
2219
|
+
* aa_blend()
|
2220
|
+
*
|
2221
|
+
* TODO: document for aa_blend.
|
2222
|
+
*/
|
2223
|
+
static VALUE image_aa_blend(VALUE klass) {
|
2224
|
+
gdImagePtr im;
|
2225
|
+
Data_Get_Struct(klass, gdImage, im);
|
2226
|
+
gdImageAABlend(im);
|
2227
|
+
return klass;
|
2228
|
+
}
|
2229
|
+
|
2230
|
+
// gd_X__gip_gfp_H2_PAE_H
|
2231
|
+
// TODO: gdImageString16 and gdImageStringUp16
|
2232
|
+
static VALUE gd_image_string(VALUE klass, VALUE font, VALUE x, VALUE y, VALUE str, VALUE color, void (GDFUNC *pfunc)(gdImagePtr, gdFontPtr, int, int, unsigned char*, int)) {
|
2233
|
+
gdImagePtr im;
|
2234
|
+
gdFontPtr ft;
|
2235
|
+
Data_Get_Struct(klass, gdImage, im);
|
2236
|
+
Data_Get_Struct(font, gdFont, ft);
|
2237
|
+
(*pfunc)(im, ft, NUM2INT(x), NUM2INT(y), RSTRING_PTR(str), NUM2INT(color));
|
2238
|
+
return klass;
|
2239
|
+
}
|
2240
|
+
|
2241
|
+
/*
|
2242
|
+
* call-seq:
|
2243
|
+
* string(font, x, y, str, color)
|
2244
|
+
*
|
2245
|
+
* Used to draw multiple characters on the image. (To draw single characters,
|
2246
|
+
* use #char.)
|
2247
|
+
*
|
2248
|
+
* The string specified by the fifth argument _str_ is drawn from left to right
|
2249
|
+
* in the specified _color_. (See #string_up for a way of drawing vertical text.
|
2250
|
+
* See also #stringft for a high quality solution.) Pixels not set by a
|
2251
|
+
* particular character retain their previous color.
|
2252
|
+
*/
|
2253
|
+
static VALUE image_string(VALUE klass, VALUE font, VALUE x, VALUE y, VALUE str, VALUE color) {
|
2254
|
+
return gd_image_string(klass, font, x, y, str, color, gdImageString);
|
2255
|
+
}
|
2256
|
+
|
2257
|
+
/*
|
2258
|
+
* call-seq:
|
2259
|
+
* string_up(font, x, y, str, color)
|
2260
|
+
*
|
2261
|
+
* Used to draw multiple characters on the image, rotated 90 degrees. (To draw
|
2262
|
+
* single characters, use Image.char_up.)
|
2263
|
+
*
|
2264
|
+
* The argument _str_ is drawn from bottom to top (rotated 90 degrees) in the
|
2265
|
+
* specified color. (See Image.string for a way of drawing horizontal text.)
|
2266
|
+
* Pixels not set by a particular character retain their previous color.
|
2267
|
+
*/
|
2268
|
+
static VALUE image_string_up(VALUE klass, VALUE font, VALUE x, VALUE y, VALUE str, VALUE color) {
|
2269
|
+
return gd_image_string(klass, font, x, y, str, color, gdImageStringUp);
|
2270
|
+
}
|
2271
|
+
|
2272
|
+
// gd_X__gip_gfp_H4
|
2273
|
+
static VALUE gd_image_char(VALUE klass, VALUE font, VALUE x, VALUE y, VALUE c, VALUE color, void (GDFUNC *pfunc)(gdImagePtr, gdFontPtr, int, int, int, int)) {
|
2274
|
+
gdImagePtr im;
|
2275
|
+
gdFontPtr ft;
|
2276
|
+
Data_Get_Struct(klass, gdImage, im);
|
2277
|
+
Data_Get_Struct(font, gdFont, ft);
|
2278
|
+
(*pfunc)(im, ft, NUM2INT(x), NUM2INT(y), NUM2INT(rb_funcall(c, rb_intern("rnd"), 0)), NUM2INT(color));
|
2279
|
+
return klass;
|
2280
|
+
}
|
2281
|
+
|
2282
|
+
/*
|
2283
|
+
* call-seq:
|
2284
|
+
* char(font, x, y, c, color)
|
2285
|
+
*
|
2286
|
+
* Used to draw single characters on the image. (To draw multiple characters,
|
2287
|
+
* use Image.string. See also Image.stringft for a high quality solution.)
|
2288
|
+
*
|
2289
|
+
* The character specified by the fifth argument _c_ is drawn from left to right
|
2290
|
+
* in the specified color. (See Image.char_up for a way of drawing vertical
|
2291
|
+
* text.) Pixels not set by a particular character retain their previous color.
|
2292
|
+
*/
|
2293
|
+
static VALUE image_char(VALUE klass, VALUE font, VALUE x, VALUE y, VALUE c, VALUE color) {
|
2294
|
+
return gd_image_char(klass, font, x, y, c, color, gdImageChar);
|
2295
|
+
}
|
2296
|
+
|
2297
|
+
/*
|
2298
|
+
* call-seq:
|
2299
|
+
* char_up(font, x, y, c, color)
|
2300
|
+
*
|
2301
|
+
* Used to draw single characters on the image, rotated 90 degrees. (To draw
|
2302
|
+
* multiple characters, use Image.string_up.)
|
2303
|
+
*
|
2304
|
+
* The character specified by the fifth argument _c_ is drawn from bottom to
|
2305
|
+
* top, rotated at a 90-degree angle, in the specified color. (See Image.char
|
2306
|
+
* for a way of drawing horizontal text.) Pixels not set by a particular
|
2307
|
+
* character retain their previous color.
|
2308
|
+
*/
|
2309
|
+
static VALUE image_char_up(VALUE klass, VALUE font, VALUE x, VALUE y, VALUE c, VALUE color) {
|
2310
|
+
return gd_image_char(klass, font, x, y, c, color, gdImageCharUp);
|
2311
|
+
}
|
2312
|
+
|
2313
|
+
// gd_PAD__gip_PAH_H_PAD_N2_H2_PAD
|
2314
|
+
// gd_PAD__gip_PAH_H_PAD_N2_H2_PAD_gftexp
|
2315
|
+
/*
|
2316
|
+
* call-seq:
|
2317
|
+
* stringft(fg, fontname, ptsize, angle, x, y, str, opts = {})
|
2318
|
+
*
|
2319
|
+
* Draws a string of anti-aliased characters on the image using the FreeType
|
2320
|
+
* library to render user-supplied TrueType fonts. The string is anti-aliased,
|
2321
|
+
* meaning that there should be fewer "jaggies" visible. The fontname is the
|
2322
|
+
* full pathname to a TrueType font file, or a font face name if the GDFONTPATH
|
2323
|
+
* environment variable or the compiled-in DEFAULT_FONTPATH macro of gdft.c have
|
2324
|
+
* been set intelligently. In the absence of a full path, the font face name may
|
2325
|
+
* be presented with or without extension (2.0.26).
|
2326
|
+
*
|
2327
|
+
* The null-terminated string argument is considered to be encoded via
|
2328
|
+
* the UTF_8 standard; also, HTML entities are supported, including decimal,
|
2329
|
+
* hexadecimal, and named entities (2.0.26). Those who are passing ordinary
|
2330
|
+
* ASCII strings may have difficulty with the & character unless encoded
|
2331
|
+
* correctly as & but should have no other difficulties.
|
2332
|
+
*
|
2333
|
+
* The string may be arbitrarily scaled (_ptsize_) and rotated (_angle_ in
|
2334
|
+
* radians). The direction of rotation is counter-clockwise, with 0 radians (0
|
2335
|
+
* degrees) at 3 o'clock and PI/2 radians (90 degrees) at 12 o'clock.
|
2336
|
+
*
|
2337
|
+
* The string is rendered in the color indicated by the _fg_ color index. Use
|
2338
|
+
* the negative of the desired color index to disable anti-aliasing.
|
2339
|
+
*
|
2340
|
+
* The string may contain UTF-8 sequences like: "À"
|
2341
|
+
*
|
2342
|
+
* This method returns a hash object, and the element with key "brect" is an
|
2343
|
+
* array filled with 4 elements representing the 4 corner coordinates of the
|
2344
|
+
* bounding rectangle (the smallest rectangle that completely surrounds the
|
2345
|
+
* rendered string and does not intersect any pixel of the rendered string).
|
2346
|
+
*
|
2347
|
+
* [ [lower_left_X, lower_left_Y], [lower_right_X, lower_right_Y],
|
2348
|
+
* \[upper_right_X, upper_right_Y], [upper_left_X, upper_left_Y] ]
|
2349
|
+
*
|
2350
|
+
* Use Image::stringft to get the bounding rectangle without rendering. This is
|
2351
|
+
* a relatively cheap operation if followed by a rendering of the same string,
|
2352
|
+
* because of the caching of the partial rendering during bounding rectangle
|
2353
|
+
* calculation.
|
2354
|
+
*
|
2355
|
+
* Options:
|
2356
|
+
*
|
2357
|
+
* * :linespcing => double
|
2358
|
+
* * :charmap => CHARMAP_*
|
2359
|
+
* * :hdpi => integer
|
2360
|
+
* * :vdpi => integer
|
2361
|
+
* * :kerning => boolean
|
2362
|
+
* * :xshow => boolean
|
2363
|
+
* * :fontpath => boolean
|
2364
|
+
* * :fontconfig => boolean
|
2365
|
+
*
|
2366
|
+
* To output multiline text with a specific line spacing, set the option
|
2367
|
+
* _:linespacing_ to the desired spacing, expressed as a multiple of the font
|
2368
|
+
* height. Thus a line spacing of 1.0 is the minimum to guarantee that lines of
|
2369
|
+
* text do not collide. If _:linespacing_ is not present, linespacing defaults
|
2370
|
+
* to 1.05.
|
2371
|
+
*
|
2372
|
+
* To specify a preference for Unicode, Shift_JIS Big5 character encoding, set
|
2373
|
+
* the option _:charmap_ to CHARMAP_*. If you do not specify a preference,
|
2374
|
+
* Unicode will be tried first. If the preferred character mapping is not found
|
2375
|
+
* in the font, other character mappings are attempted.
|
2376
|
+
*
|
2377
|
+
* GD operates on the assumption that the output image will be rendered to a
|
2378
|
+
* computer screen. By default, gd passes a resolution of 96 dpi to the freetype
|
2379
|
+
* text rendering engine. This influences the "hinting" decisions made by the
|
2380
|
+
* renderer. To specify a different resolution, set _:hdpi_ and _:vdpi_
|
2381
|
+
* accordingly (in dots per inch).
|
2382
|
+
*
|
2383
|
+
* GD 2.0.29 and later will normally attempt to apply kerning tables, if
|
2384
|
+
* fontconfig is available, to adjust the relative positions of consecutive
|
2385
|
+
* characters more ideally for that pair of characters. This can be turn off by
|
2386
|
+
* set the option _:kerning_ to false;
|
2387
|
+
*
|
2388
|
+
* GD 2.0.29 and later can return a vector of individual character position
|
2389
|
+
* advances by set the option _:xshow_ to true, occasionally useful in
|
2390
|
+
* applications that must know exactly where each character begins. This is
|
2391
|
+
* returned in the element with key "xshow".
|
2392
|
+
*
|
2393
|
+
* GD 2.0.29 and later can also return the path to the actual font file used if
|
2394
|
+
* the option _:returnfontpath_ is true. This is useful because GD 2.0.29 and
|
2395
|
+
* above are capable of selecting a font automatically based on a fontconfig
|
2396
|
+
* font pattern when fontconfig is available. This information is returned in
|
2397
|
+
* the element with key "fontpath".
|
2398
|
+
*
|
2399
|
+
* GD 2.0.29 and later can use fontconfig to resolve font names, including
|
2400
|
+
* fontconfig patterns, if the option _:fontconfig_ is true. As a convenience,
|
2401
|
+
* this behavior can be made the default by calling Image.use_fontconfig=true.
|
2402
|
+
* In that situation it is not necessary to set the option _:fontconfig_ on
|
2403
|
+
* every call; however explicit font path names can still be used if the option
|
2404
|
+
* _:fontpathname_ is true.
|
2405
|
+
*
|
2406
|
+
* Unless Image.use_fontconfig=true has been called, GD 2.0.29 and later will
|
2407
|
+
* still expect the fontlist argument to the freetype text output functions to
|
2408
|
+
* be a font file name or list thereof as in previous versions. If you do not
|
2409
|
+
* wish to make fontconfig the default, it is still possible to force the use
|
2410
|
+
* of fontconfig for a single call to the freetype text output functions by
|
2411
|
+
* setting the option _:fontconfig_ to ture.
|
2412
|
+
*/
|
2413
|
+
static VALUE image_stringft(int argc, VALUE *argv, VALUE klass) {
|
2414
|
+
VALUE fg, fontname, ptsize, angle, x, y, str, opts;
|
2415
|
+
VALUE ret, m, n;
|
2416
|
+
gdImagePtr im = NULL;
|
2417
|
+
gdFTStringExtra ftex;
|
2418
|
+
int brect[8];
|
2419
|
+
char *err;
|
2420
|
+
|
2421
|
+
if (TYPE(klass) == T_DATA) Data_Get_Struct(klass, gdImage, im);
|
2422
|
+
memset(&ftex, 0, sizeof(gdFTStringExtra));
|
2423
|
+
if (rb_scan_args(argc, argv, "71", &fg, &fontname, &ptsize, &angle, &x, &y, &str, &opts) == 7) {
|
2424
|
+
err = gdImageStringFT(im, &brect[0], NUM2INT(fg), RSTRING_PTR(fontname), NUM2DBL(ptsize), NUM2DBL(angle), NUM2INT(x), NUM2INT(y), RSTRING_PTR(str));
|
2425
|
+
} else {
|
2426
|
+
Check_Type(opts, T_HASH);
|
2427
|
+
|
2428
|
+
m = rb_hash_aref(opts, STR2SYM("linespacing"));
|
2429
|
+
if (RTEST(m)) {
|
2430
|
+
ftex.flags |= gdFTEX_LINESPACE;
|
2431
|
+
ftex.linespacing = NUM2DBL(m);
|
2432
|
+
}
|
2433
|
+
|
2434
|
+
m = rb_hash_aref(opts, STR2SYM("charmp"));
|
2435
|
+
if (RTEST(m)) {
|
2436
|
+
ftex.flags |= gdFTEX_CHARMAP;
|
2437
|
+
ftex.charmap = NUM2INT(m);
|
2438
|
+
}
|
2439
|
+
|
2440
|
+
m = rb_hash_aref(opts, STR2SYM("hdpi"));
|
2441
|
+
n = rb_hash_aref(opts, STR2SYM("vdpi"));
|
2442
|
+
if (RTEST(m) && RTEST(n)) {
|
2443
|
+
ftex.flags |= gdFTEX_RESOLUTION;
|
2444
|
+
ftex.hdpi = NUM2INT(m);
|
2445
|
+
ftex.vdpi = NUM2INT(n);
|
2446
|
+
}
|
2447
|
+
|
2448
|
+
m = rb_hash_aref(opts, STR2SYM("kerning"));
|
2449
|
+
if (m == Qfalse) ftex.flags |= gdFTEX_DISABLE_KERNING;
|
2450
|
+
|
2451
|
+
m = rb_hash_aref(opts, STR2SYM("xshow"));
|
2452
|
+
if (RTEST(m)) ftex.flags |= gdFTEX_XSHOW;
|
2453
|
+
|
2454
|
+
m = rb_hash_aref(opts, STR2SYM("returnfontpath"));
|
2455
|
+
if (RTEST(m)) ftex.flags |= gdFTEX_RETURNFONTPATHNAME;
|
2456
|
+
|
2457
|
+
m = rb_hash_aref(opts, STR2SYM("fontpathname"));
|
2458
|
+
if (RTEST(m)) ftex.flags |= gdFTEX_FONTPATHNAME;
|
2459
|
+
|
2460
|
+
m = rb_hash_aref(opts, STR2SYM("fontconfig"));
|
2461
|
+
if (RTEST(m)) ftex.flags |= gdFTEX_FONTCONFIG;
|
2462
|
+
|
2463
|
+
err = gdImageStringFTEx(im, &brect[0], NUM2INT(fg), RSTRING_PTR(fontname), NUM2DBL(ptsize), NUM2DBL(angle), NUM2INT(x), NUM2INT(y), RSTRING_PTR(str), &ftex);
|
2464
|
+
}
|
2465
|
+
|
2466
|
+
if (err) rb_raise(rb_eRGDError, "%s", err);
|
2467
|
+
|
2468
|
+
ret = rb_hash_new();
|
2469
|
+
rb_hash_aset(ret, rb_str_new2("brect"),
|
2470
|
+
rb_ary_new3(4,
|
2471
|
+
rb_ary_new3(2, INT2NUM(brect[0]), INT2NUM(brect[1])),
|
2472
|
+
rb_ary_new3(2, INT2NUM(brect[2]), INT2NUM(brect[3])),
|
2473
|
+
rb_ary_new3(2, INT2NUM(brect[4]), INT2NUM(brect[5])),
|
2474
|
+
rb_ary_new3(2, INT2NUM(brect[6]), INT2NUM(brect[7]))
|
2475
|
+
));
|
2476
|
+
|
2477
|
+
if (ftex.flags != 0) {
|
2478
|
+
if (ftex.xshow) {
|
2479
|
+
rb_hash_aset(ret, rb_str_new2("xshow"), rb_str_new2(ftex.xshow));
|
2480
|
+
gdFree(ftex.xshow);
|
2481
|
+
}
|
2482
|
+
|
2483
|
+
if (ftex.fontpath) {
|
2484
|
+
rb_hash_aset(ret, rb_str_new2("fontpath"), rb_str_new2(ftex.fontpath));
|
2485
|
+
gdFree(ftex.fontpath);
|
2486
|
+
}
|
2487
|
+
}
|
2488
|
+
|
2489
|
+
return ret;
|
2490
|
+
}
|
2491
|
+
|
2492
|
+
// gd_PAD__gip_H2_N3_PAD_N_PAD2_H
|
2493
|
+
/*
|
2494
|
+
* call-seq:
|
2495
|
+
* stringft_circle(cx, cy, radius, textRadius, fillPortion, fontname, points, top, bottom, fg)
|
2496
|
+
*
|
2497
|
+
* Draws the text strings specified by _top_ and _bottom_ on the image, curved
|
2498
|
+
* along the edge of a circle of radius _radius_, with its center at _cx_
|
2499
|
+
* and _cy_. _top_ is written clockwise along the top; _bottom_ is written
|
2500
|
+
* counterclockwise along the bottom. _textRadius_ determines the "height" of
|
2501
|
+
* each character; if _textRadius_ is 1/2 of _radius_, characters extend halfway
|
2502
|
+
* from the edge to the center. _fillPortion_ varies from 0 to 1.0, with useful
|
2503
|
+
* values from about 0.4 to 0.9, and determines how much of the 180 degrees of
|
2504
|
+
* arc assigned to each section of text is actually occupied by text; 0.9 looks
|
2505
|
+
* better than 1.0 which is rather crowded. _fontname_ is a freetype font; see
|
2506
|
+
* Image.stringft. _points_ is passed to the freetype engine and has an effect
|
2507
|
+
* on hinting; although the size of the text is determined by _radius_,
|
2508
|
+
* _textRadius_, and _fillPortion_, you should pass a point size that "hints"
|
2509
|
+
* appropriately -- if you know the text will be large, pass a large point size
|
2510
|
+
* such as 24.0 to get the best results. _fg_ can be any color, and may have an
|
2511
|
+
* alpha component, do blending, etc.
|
2512
|
+
*/
|
2513
|
+
static VALUE image_stringft_circle(VALUE klass, VALUE cx, VALUE cy, VALUE radius, VALUE textRadius, VALUE fillPortion, VALUE fontname, VALUE points, VALUE top, VALUE bottom, VALUE fg) {
|
2514
|
+
gdImagePtr im;
|
2515
|
+
char *err;
|
2516
|
+
Data_Get_Struct(klass, gdImage, im);
|
2517
|
+
err = gdImageStringFTCircle(im, NUM2INT(cx), NUM2INT(cy), NUM2DBL(radius), NUM2DBL(textRadius), NUM2DBL(fillPortion), RSTRING_PTR(fontname), NUM2DBL(points), RSTRING_PTR(top), RSTRING_PTR(bottom), NUM2INT(fg));
|
2518
|
+
if (err) rb_raise(rb_eRGDError, "%s", err);
|
2519
|
+
return klass;
|
2520
|
+
}
|
2521
|
+
|
2522
|
+
/*
|
2523
|
+
* call-seq:
|
2524
|
+
* new(filename, format = nil)
|
2525
|
+
*
|
2526
|
+
* Create a new image from a file.
|
2527
|
+
*
|
2528
|
+
* The argument _format_ should be a image format name, like "jpeg", "png", etc.
|
2529
|
+
* If it's nil, the image type will be detected automatically by the extension
|
2530
|
+
* of _filename_.
|
2531
|
+
*/
|
2532
|
+
static VALUE image_s_new(int argc, VALUE* argv, VALUE klass) {
|
2533
|
+
VALUE filename, format;
|
2534
|
+
char *ext;
|
2535
|
+
ImageFormat i_fmt = FMT_UNKNOW;
|
2536
|
+
|
2537
|
+
if (rb_scan_args(argc, argv, "11", &filename, &format) == 2) Check_Type(format, T_STRING);
|
2538
|
+
Check_Type(filename, T_STRING);
|
2539
|
+
if (rb_funcall(rb_cFile, rb_intern("readable?"), 1, filename) != Qtrue) rb_raise(rb_eArgError, "%s is not readable", RSTRING_PTR(filename));
|
2540
|
+
|
2541
|
+
if (RTEST(format)) {
|
2542
|
+
i_fmt = m_image_detect_format_by_ext(RSTRING_PTR(format));
|
2543
|
+
} else {
|
2544
|
+
ext = strrchr(RSTRING_PTR(filename), '.');
|
2545
|
+
if (ext && ++ext) i_fmt = m_image_detect_format_by_ext(ext);
|
2546
|
+
}
|
2547
|
+
|
2548
|
+
switch (i_fmt) {
|
2549
|
+
case FMT_JPEG:
|
2550
|
+
return image_s_from_jpeg(klass, filename);
|
2551
|
+
case FMT_PNG:
|
2552
|
+
return image_s_from_png(klass, filename);
|
2553
|
+
case FMT_GIF:
|
2554
|
+
return image_s_from_gif(klass, filename);
|
2555
|
+
case FMT_BMP:
|
2556
|
+
return image_s_from_bmp(klass, filename);
|
2557
|
+
case FMT_GD2:
|
2558
|
+
return image_s_from_gd2(klass, filename);
|
2559
|
+
case FMT_GD:
|
2560
|
+
return image_s_from_gd(klass, filename);
|
2561
|
+
case FMT_WBMP:
|
2562
|
+
return image_s_from_wbmp(klass, filename);
|
2563
|
+
case FMT_XBM:
|
2564
|
+
return image_s_from_xbm(klass, filename);
|
2565
|
+
case FMT_XPM:
|
2566
|
+
return image_s_from_xpm(klass, filename);
|
2567
|
+
default:
|
2568
|
+
if (RTEST(format)) {
|
2569
|
+
rb_raise(rb_eRGDError, "Unknown image format: %s", RSTRING_PTR(format));
|
2570
|
+
} else {
|
2571
|
+
rb_raise(rb_eRGDError, "Cannot detect image format: %s", RSTRING_PTR(filename));
|
2572
|
+
}
|
2573
|
+
}
|
2574
|
+
}
|
2575
|
+
|
2576
|
+
/*
|
2577
|
+
* call-seq:
|
2578
|
+
* from_data(data, format = nil)
|
2579
|
+
*
|
2580
|
+
* Create a new image from a byte-string.
|
2581
|
+
*
|
2582
|
+
* The argument _format_ should be a image format name, like "jpeg", "png", etc.
|
2583
|
+
* If it's nil, the image type will be detected automatically by the MAGIC of
|
2584
|
+
* _data_ (work for JPEG, PNG, GIF, BMP, GD2 and GD).
|
2585
|
+
*/
|
2586
|
+
static VALUE image_s_from_data(int argc, VALUE* argv, VALUE klass) {
|
2587
|
+
VALUE data, format;
|
2588
|
+
char *ext;
|
2589
|
+
ImageFormat i_fmt = FMT_UNKNOW;
|
2590
|
+
|
2591
|
+
if (rb_scan_args(argc, argv, "11", &data, &format) == 2) Check_Type(format, T_STRING);
|
2592
|
+
Check_Type(data, T_STRING);
|
2593
|
+
|
2594
|
+
if (RTEST(format)) {
|
2595
|
+
i_fmt = m_image_detect_format_by_ext(RSTRING_PTR(format));
|
2596
|
+
} else {
|
2597
|
+
i_fmt = m_image_detect_format_by_magic(RSTRING_PTR(data));
|
2598
|
+
}
|
2599
|
+
|
2600
|
+
switch (i_fmt) {
|
2601
|
+
case FMT_JPEG:
|
2602
|
+
return image_s_from_jpeg_data(klass, data);
|
2603
|
+
case FMT_PNG:
|
2604
|
+
return image_s_from_png_data(klass, data);
|
2605
|
+
case FMT_GIF:
|
2606
|
+
return image_s_from_gif_data(klass, data);
|
2607
|
+
case FMT_BMP:
|
2608
|
+
return image_s_from_bmp_data(klass, data);
|
2609
|
+
case FMT_GD2:
|
2610
|
+
return image_s_from_gd2_data(klass, data);
|
2611
|
+
case FMT_GD:
|
2612
|
+
return image_s_from_gd_data(klass, data);
|
2613
|
+
case FMT_WBMP:
|
2614
|
+
return image_s_from_wbmp_data(klass, data);
|
2615
|
+
case FMT_XBM:
|
2616
|
+
rb_raise(rb_eRGDError, "Cannot load a XBM image from a byte-string.");
|
2617
|
+
case FMT_XPM:
|
2618
|
+
rb_raise(rb_eRGDError, "Cannot load a XPM image from a byte-string.");
|
2619
|
+
default:
|
2620
|
+
if (RTEST(format)) {
|
2621
|
+
rb_raise(rb_eRGDError, "Unknown image format: %s", RSTRING_PTR(format));
|
2622
|
+
} else {
|
2623
|
+
rb_raise(rb_eRGDError, "Cannot detect image format");
|
2624
|
+
}
|
2625
|
+
}
|
2626
|
+
}
|
2627
|
+
|
2628
|
+
|
2629
|
+
|
2630
|
+
/*
|
2631
|
+
* call-seq:
|
2632
|
+
* file(filename, format = nil, [more params])
|
2633
|
+
*
|
2634
|
+
* Write the image to _filename_ in specified _format_. If _format_ is nil, the
|
2635
|
+
* file format will be detected automatically by the extension of _filename_.
|
2636
|
+
*
|
2637
|
+
* Usage:
|
2638
|
+
*
|
2639
|
+
* * file(filename, "jpeg", quality = -1)
|
2640
|
+
* * file(filename, "png", level = -1)
|
2641
|
+
* * file(filename, "gif")
|
2642
|
+
* * file(filename, "bmp")
|
2643
|
+
* * file(filename, "gd2", chunk_size = 0, fmt = GD2_FMT_COMPRESSED)
|
2644
|
+
* * file(filename, "gd")
|
2645
|
+
* * file(filename, "wbmp", fg = 1)
|
2646
|
+
*/
|
2647
|
+
static VALUE image_file(int argc, VALUE* argv, VALUE klass) {
|
2648
|
+
VALUE filename, format, a1, a2;
|
2649
|
+
char *ext;
|
2650
|
+
ImageFormat i_fmt = FMT_UNKNOW;
|
2651
|
+
|
2652
|
+
rb_scan_args(argc, argv, "13", &filename, &format, &a1, &a2);
|
2653
|
+
Check_Type(filename, T_STRING);
|
2654
|
+
if (RTEST(a1)) Check_Type(a1, T_FIXNUM);
|
2655
|
+
if (RTEST(a2)) Check_Type(a2, T_FIXNUM);
|
2656
|
+
|
2657
|
+
if (RTEST(format)) {
|
2658
|
+
Check_Type(format, T_STRING);
|
2659
|
+
i_fmt = m_image_detect_format_by_ext(RSTRING_PTR(format));
|
2660
|
+
} else {
|
2661
|
+
ext = strrchr(RSTRING_PTR(filename), '.');
|
2662
|
+
if (ext && strlen(ext) > 1) {
|
2663
|
+
ext += 1;
|
2664
|
+
i_fmt = m_image_detect_format_by_ext(ext);
|
2665
|
+
}
|
2666
|
+
}
|
2667
|
+
|
2668
|
+
switch (i_fmt) {
|
2669
|
+
case FMT_JPEG:
|
2670
|
+
SetIntIfQnil(a1, -1);
|
2671
|
+
return rb_funcall(klass, rb_intern("jpeg"), 2, filename, a1);
|
2672
|
+
case FMT_GIF:
|
2673
|
+
return image_gif(klass, filename);
|
2674
|
+
case FMT_PNG:
|
2675
|
+
SetIntIfQnil(a1, -1);
|
2676
|
+
return rb_funcall(klass, rb_intern("png"), 2, filename, a1);
|
2677
|
+
case FMT_BMP:
|
2678
|
+
return image_bmp(klass, filename);
|
2679
|
+
case FMT_GD2:
|
2680
|
+
SetIntIfQnil(a1, 0);
|
2681
|
+
SetIntIfQnil(a2, GD2_FMT_COMPRESSED);
|
2682
|
+
return rb_funcall(klass, rb_intern("gd2"), 3, filename, a1, a2);
|
2683
|
+
case FMT_GD:
|
2684
|
+
return image_gd(klass, filename);
|
2685
|
+
case FMT_WBMP:
|
2686
|
+
SetIntIfQnil(a1, 1);
|
2687
|
+
return rb_funcall(klass, rb_intern("wbmp"), 2, filename, a1);
|
2688
|
+
case FMT_XBM:
|
2689
|
+
rb_raise(rb_eRGDError, "This method doesn't support XBM format");
|
2690
|
+
case FMT_XPM:
|
2691
|
+
rb_raise(rb_eRGDError, "This method doesn't support XPM format");
|
2692
|
+
default:
|
2693
|
+
rb_raise(rb_eRGDError, "Unknown image format.");
|
2694
|
+
}
|
2695
|
+
}
|
2696
|
+
|
2697
|
+
/*
|
2698
|
+
* call-seq:
|
2699
|
+
* data(format, [more params])
|
2700
|
+
*
|
2701
|
+
* Convert the image to a byte-string in specified _format_.
|
2702
|
+
*
|
2703
|
+
* Usage:
|
2704
|
+
*
|
2705
|
+
* * data("jpeg", quality = -1)
|
2706
|
+
* * data("png", level = -1)
|
2707
|
+
* * data("gif")
|
2708
|
+
* * data("bmp")
|
2709
|
+
* * data("gd2", chunk_size = 0, fmt = GD2_FMT_COMPRESSED)
|
2710
|
+
* * data("gd")
|
2711
|
+
* * data("wbmp", fg = 1)
|
2712
|
+
*/
|
2713
|
+
static VALUE image_data(int argc, VALUE* argv, VALUE klass) {
|
2714
|
+
VALUE format, a1, a2;
|
2715
|
+
ImageFormat i_fmt;
|
2716
|
+
|
2717
|
+
rb_scan_args(argc, argv, "12", &format, &a1, &a2);
|
2718
|
+
Check_Type(format, T_STRING);
|
2719
|
+
if (RTEST(a1)) Check_Type(a1, T_FIXNUM);
|
2720
|
+
if (RTEST(a2)) Check_Type(a2, T_FIXNUM);
|
2721
|
+
|
2722
|
+
i_fmt = m_image_detect_format_by_ext(RSTRING_PTR(format));
|
2723
|
+
switch (i_fmt) {
|
2724
|
+
case FMT_JPEG:
|
2725
|
+
SetIntIfQnil(a1, -1);
|
2726
|
+
return rb_funcall(klass, rb_intern("jpeg_data"), 1, a1);
|
2727
|
+
case FMT_GIF:
|
2728
|
+
return image_gif_data(klass);
|
2729
|
+
case FMT_PNG:
|
2730
|
+
SetIntIfQnil(a1, -1);
|
2731
|
+
return rb_funcall(klass, rb_intern("png_data"), 1, a1);
|
2732
|
+
case FMT_BMP:
|
2733
|
+
return image_bmp_data(klass);
|
2734
|
+
case FMT_GD2:
|
2735
|
+
SetIntIfQnil(a1, 0);
|
2736
|
+
SetIntIfQnil(a2, GD2_FMT_COMPRESSED);
|
2737
|
+
return rb_funcall(klass, rb_intern("gd2_data"), 2, a1, a2);
|
2738
|
+
case FMT_GD:
|
2739
|
+
return image_gd_data(klass);
|
2740
|
+
case FMT_WBMP:
|
2741
|
+
SetIntIfQnil(a1, 1);
|
2742
|
+
return rb_funcall(klass, rb_intern("wbmp_data"), 1, a1);
|
2743
|
+
case FMT_XBM:
|
2744
|
+
rb_raise(rb_eRGDError, "This method doesn't support XBM format");
|
2745
|
+
case FMT_XPM:
|
2746
|
+
rb_raise(rb_eRGDError, "This method doesn't support XPM format");
|
2747
|
+
default:
|
2748
|
+
rb_raise(rb_eRGDError, "Unknown image format.");
|
2749
|
+
}
|
2750
|
+
}
|
2751
|
+
|
2752
|
+
/*
|
2753
|
+
* call-seq:
|
2754
|
+
* clone()
|
2755
|
+
*
|
2756
|
+
* Return a new image clone from current.
|
2757
|
+
*/
|
2758
|
+
static VALUE image_clone(VALUE klass) {
|
2759
|
+
VALUE nimage, data;
|
2760
|
+
|
2761
|
+
data = image_gd2_data(klass, 0, GD2_FMT_RAW);
|
2762
|
+
nimage = rb_funcall(rb_cImage, rb_intern("from_gd2_data"), 1, data);
|
2763
|
+
|
2764
|
+
return nimage;
|
2765
|
+
}
|
2766
|
+
|
2767
|
+
/*
|
2768
|
+
* call-seq:
|
2769
|
+
* to_palette(dither = true, colors = MAX_COLORS)
|
2770
|
+
*
|
2771
|
+
* Create a new palette-based image from current. If the image is a
|
2772
|
+
* palette-based image already, this method equals to RGD::Image.clone.
|
2773
|
+
*/
|
2774
|
+
static VALUE image_to_palette(int argc, VALUE* argv, VALUE klass) {
|
2775
|
+
VALUE nimage = image_clone(klass);
|
2776
|
+
if (image_is_truecolor(nimage) == Qfalse) {
|
2777
|
+
return nimage;
|
2778
|
+
} else {
|
2779
|
+
return image_truecolor_to_palette(argc, argv, nimage);
|
2780
|
+
}
|
2781
|
+
}
|
2782
|
+
|
2783
|
+
void Init_rgd() {
|
2784
|
+
rb_mRGD = rb_define_module("RGD");
|
2785
|
+
|
2786
|
+
rb_eRGDError = rb_define_class_under(rb_mRGD, "RGDError", rb_eException);
|
2787
|
+
|
2788
|
+
rb_cFont = rb_define_class_under(rb_mRGD, "Font", rb_cObject);
|
2789
|
+
rb_define_singleton_method(rb_cFont, "small", font_s_small, 0);
|
2790
|
+
rb_define_singleton_method(rb_cFont, "large", font_s_large, 0);
|
2791
|
+
rb_define_singleton_method(rb_cFont, "medium_bold", font_s_medium_bold, 0);
|
2792
|
+
rb_define_singleton_method(rb_cFont, "giant", font_s_giant, 0);
|
2793
|
+
rb_define_singleton_method(rb_cFont, "tiny", font_s_tiny, 0);
|
2794
|
+
|
2795
|
+
rb_cImage = rb_define_class_under(rb_mRGD, "Image", rb_cObject);
|
2796
|
+
/* gdAlphaMax: Same as ALPHA_TRANSPARENT. */
|
2797
|
+
rb_define_const(rb_cImage, "ALPHA_MAX", INT2NUM(gdAlphaMax));
|
2798
|
+
/* gdAlphaOpaque: Does not blend at all with the background. */
|
2799
|
+
rb_define_const(rb_cImage, "ALPHA_OPAQUE", INT2NUM(gdAlphaOpaque));
|
2800
|
+
/* gdAlphaTransparent: Allows the background to shine through 100%. */
|
2801
|
+
rb_define_const(rb_cImage, "ALPHA_TRANSPARENT", INT2NUM(gdAlphaTransparent));
|
2802
|
+
/* gdMaxColors: Max colors can be used in palette-based image. */
|
2803
|
+
rb_define_const(rb_cImage, "MAX_COLORS", INT2NUM(gdMaxColors));
|
2804
|
+
/* GD2_FMT_RAW: Uncompressed \GD2 format. */
|
2805
|
+
rb_define_const(rb_cImage, "GD2_FMT_RAW", INT2NUM(GD2_FMT_RAW));
|
2806
|
+
/* GD2_FMT_COMPRESSED: Compressed \GD2 format. */
|
2807
|
+
rb_define_const(rb_cImage, "GD2_FMT_COMPRESSED", INT2NUM(GD2_FMT_COMPRESSED));
|
2808
|
+
//rb_define_const(rb_cImage, "DISPOSAL_UNKNOWN", INT2NUM(gdDisposalUnknown));
|
2809
|
+
/* gdDisposalNone: Restores the first allocated color of the global palette. */
|
2810
|
+
rb_define_const(rb_cImage, "DISPOSAL_NONE", INT2NUM(gdDisposalNone));
|
2811
|
+
/* gdDisposalRestoreBackground: Restores the appearance of the affected area before the frame was rendered. */
|
2812
|
+
rb_define_const(rb_cImage, "DISPOSAL_RESTORE_BACKGROUND", INT2NUM(gdDisposalRestoreBackground));
|
2813
|
+
/* gdDisposalRestorePrevious: The pixels changed by this frame should remain on the display when the next frame begins to render. */
|
2814
|
+
rb_define_const(rb_cImage, "DISPOSAL_RESTORE_PREVIOUS", INT2NUM(gdDisposalRestorePrevious));
|
2815
|
+
/* GD_CMP_IMAGE: Actual image IS different */
|
2816
|
+
rb_define_const(rb_cImage, "GD_CMP_IMAGE", INT2NUM(GD_CMP_IMAGE));
|
2817
|
+
/* GD_CMP_NUM_COLORS: Number of Colors in pallette differ */
|
2818
|
+
rb_define_const(rb_cImage, "GD_CMP_NUM_COLORS", INT2NUM(GD_CMP_NUM_COLORS));
|
2819
|
+
/* GD_CMP_COLOR: \Image Colors differ */
|
2820
|
+
rb_define_const(rb_cImage, "GD_CMP_COLOR", INT2NUM(GD_CMP_COLOR));
|
2821
|
+
/* GD_CMP_SIZE_X: \Image width differs */
|
2822
|
+
rb_define_const(rb_cImage, "GD_CMP_SIZE_X", INT2NUM(GD_CMP_SIZE_X));
|
2823
|
+
/* GD_CMP_SIZE_Y: \Image heights differ */
|
2824
|
+
rb_define_const(rb_cImage, "GD_CMP_SIZE_Y", INT2NUM(GD_CMP_SIZE_Y));
|
2825
|
+
/* GD_CMP_TRANSPARENT: Transparent color */
|
2826
|
+
rb_define_const(rb_cImage, "GD_CMP_TRANSPARENT", INT2NUM(GD_CMP_TRANSPARENT));
|
2827
|
+
/* GD_CMP_BACKGROUND: Background color */
|
2828
|
+
rb_define_const(rb_cImage, "GD_CMP_BACKGROUND", INT2NUM(GD_CMP_BACKGROUND));
|
2829
|
+
/* GD_CMP_INTERLACE: Interlaced setting */
|
2830
|
+
rb_define_const(rb_cImage, "GD_CMP_INTERLACE", INT2NUM(GD_CMP_INTERLACE));
|
2831
|
+
/* GD_CMP_TRUECOLOR: Truecolor vs palette differs */
|
2832
|
+
rb_define_const(rb_cImage, "GD_CMP_TRUECOLOR", INT2NUM(GD_CMP_TRUECOLOR));
|
2833
|
+
/* gdStyled: Special color. */
|
2834
|
+
rb_define_const(rb_cImage, "COLOR_STYLED", INT2NUM(gdStyled));
|
2835
|
+
/* gdBrushed: Special color. */
|
2836
|
+
rb_define_const(rb_cImage, "COLOR_BRUSHED", INT2NUM(gdBrushed));
|
2837
|
+
/* gdStyledBrushed: Special color. */
|
2838
|
+
rb_define_const(rb_cImage, "COLOR_STYLED_BRUSHED", INT2NUM(gdStyledBrushed));
|
2839
|
+
/* gdTiled: Special color. */
|
2840
|
+
rb_define_const(rb_cImage, "COLOR_TILED", INT2NUM(gdTiled));
|
2841
|
+
/* gdTransparent: Special color. NOT the same as the transparent color index. This is used in line styles only. */
|
2842
|
+
rb_define_const(rb_cImage, "COLOR_TRANSPARENT", INT2NUM(gdTransparent));
|
2843
|
+
/* gdAntiAliased: Special color. */
|
2844
|
+
rb_define_const(rb_cImage, "COLOR_ANTIALIASED", INT2NUM(gdAntiAliased));
|
2845
|
+
/* gdArc: See Image.filled_arc. */
|
2846
|
+
rb_define_const(rb_cImage, "STYLE_ARC", INT2NUM(gdArc));
|
2847
|
+
/* gdChord: See Image.filled_arc. */
|
2848
|
+
rb_define_const(rb_cImage, "STYLE_CHORD", INT2NUM(gdChord));
|
2849
|
+
/* gdPie: See Image.filled_arc. */
|
2850
|
+
rb_define_const(rb_cImage, "STYLE_PIE", INT2NUM(gdPie));
|
2851
|
+
/* gdNoFill: See Image.filled_arc. */
|
2852
|
+
rb_define_const(rb_cImage, "STYLE_NO_FILL", INT2NUM(gdNoFill));
|
2853
|
+
/* gdEdged: See Image.filled_arc. */
|
2854
|
+
rb_define_const(rb_cImage, "STYLE_EDGED", INT2NUM(gdEdged));
|
2855
|
+
/* gdFTEX_Unicode: See Image.stringft. */
|
2856
|
+
rb_define_const(rb_cImage, "CHARMAP_UNICODE", INT2NUM(gdFTEX_Unicode));
|
2857
|
+
/* gdFTEX_Shift_JIS: See Image.stringft. */
|
2858
|
+
rb_define_const(rb_cImage, "CHARMAP_SHIFT_JIS", INT2NUM(gdFTEX_Shift_JIS));
|
2859
|
+
/* gdFTEX_Big5: See Image.stringft. */
|
2860
|
+
rb_define_const(rb_cImage, "CHARMAP_BIG5", INT2NUM(gdFTEX_Big5));
|
2861
|
+
/* gdFTEX_Adobe_Custom: See Image.stringft. */
|
2862
|
+
rb_define_const(rb_cImage, "CHARMAP_ADOBE_CUSTOM", INT2NUM(gdFTEX_Adobe_Custom));
|
2863
|
+
rb_define_singleton_method(rb_cImage, "use_fontconfig=", image_s_use_fontconfig, 1);
|
2864
|
+
rb_define_singleton_method(rb_cImage, "alpha_blend", image_s_alpha_blend, 2);
|
2865
|
+
rb_define_singleton_method(rb_cImage, "truecolor", image_s_truecolor, -1);
|
2866
|
+
rb_define_singleton_method(rb_cImage, "create", image_s_create, 2);
|
2867
|
+
rb_define_singleton_method(rb_cImage, "create_truecolor", image_s_create_truecolor, 2);
|
2868
|
+
rb_define_singleton_method(rb_cImage, "from_jpeg_data", image_s_from_jpeg_data, 1);
|
2869
|
+
rb_define_singleton_method(rb_cImage, "from_png_data", image_s_from_png_data, 1);
|
2870
|
+
rb_define_singleton_method(rb_cImage, "from_gif_data", image_s_from_gif_data, 1);
|
2871
|
+
rb_define_singleton_method(rb_cImage, "from_gd_data", image_s_from_gd_data, 1);
|
2872
|
+
rb_define_singleton_method(rb_cImage, "from_gd2_data", image_s_from_gd2_data, 1);
|
2873
|
+
rb_define_singleton_method(rb_cImage, "from_wbmp_data", image_s_from_wbmp_data, 1);
|
2874
|
+
rb_define_singleton_method(rb_cImage, "from_bmp_data", image_s_from_bmp_data, 1);
|
2875
|
+
rb_define_singleton_method(rb_cImage, "from_gd2_part_data", image_s_from_gd2_part_data, 5);
|
2876
|
+
rb_define_singleton_method(rb_cImage, "from_xpm", image_s_from_xpm, 1);
|
2877
|
+
rb_define_singleton_method(rb_cImage, "from_jpeg", image_s_from_jpeg, 1);
|
2878
|
+
rb_define_singleton_method(rb_cImage, "from_png", image_s_from_png, 1);
|
2879
|
+
rb_define_singleton_method(rb_cImage, "from_gif", image_s_from_gif, 1);
|
2880
|
+
rb_define_singleton_method(rb_cImage, "from_gd", image_s_from_gd, 1);
|
2881
|
+
rb_define_singleton_method(rb_cImage, "from_gd2", image_s_from_gd2, 1);
|
2882
|
+
rb_define_singleton_method(rb_cImage, "from_wbmp", image_s_from_wbmp, 1);
|
2883
|
+
rb_define_singleton_method(rb_cImage, "from_xbm", image_s_from_xbm, 1);
|
2884
|
+
rb_define_singleton_method(rb_cImage, "from_bmp", image_s_from_bmp, 1);
|
2885
|
+
rb_define_singleton_method(rb_cImage, "from_gd2_part", image_s_from_gd2_part, 5);
|
2886
|
+
rb_define_singleton_method(rb_cImage, "create_palette_from_truecolor", image_s_create_palette_from_truecolor, -1);
|
2887
|
+
rb_define_singleton_method(rb_cImage, "square_to_circle", image_s_square_to_circle, 2);
|
2888
|
+
// TODO: document for Image.stringft, RDOC doesn't work.
|
2889
|
+
rb_define_singleton_method(rb_cImage, "stringft", image_stringft, -1);
|
2890
|
+
|
2891
|
+
rb_define_method(rb_cImage, "gif", image_gif, 1);
|
2892
|
+
rb_define_method(rb_cImage, "gd", image_gd, 1);
|
2893
|
+
rb_define_method(rb_cImage, "jpeg", image_jpeg, -1);
|
2894
|
+
rb_define_method(rb_cImage, "png", image_png, -1);
|
2895
|
+
rb_define_method(rb_cImage, "bmp", image_bmp, 1);
|
2896
|
+
rb_define_method(rb_cImage, "wbmp", image_wbmp, -1);
|
2897
|
+
rb_define_method(rb_cImage, "gif_data", image_gif_data, 0);
|
2898
|
+
rb_define_method(rb_cImage, "gd_data", image_gd_data, 1);
|
2899
|
+
rb_define_method(rb_cImage, "jpeg_data", image_jpeg_data, -1);
|
2900
|
+
rb_define_method(rb_cImage, "png_data", image_png_data, -1);
|
2901
|
+
rb_define_method(rb_cImage, "wbmp_data", image_wbmp_data, -1);
|
2902
|
+
rb_define_method(rb_cImage, "bmp_data", image_bmp_data, 0);
|
2903
|
+
rb_define_method(rb_cImage, "gd2_data", image_gd2_data, -1);
|
2904
|
+
rb_define_method(rb_cImage, "gif_anim_begin_data", image_gif_anim_begin_data, -1);
|
2905
|
+
rb_define_method(rb_cImage, "gif_anim_add_data", image_gif_anim_add_data, -1);
|
2906
|
+
rb_define_method(rb_cImage, "gif_anim_end_data", image_gif_anim_end_data, 0);
|
2907
|
+
rb_define_method(rb_cImage, "gd2", image_gd2, -1);
|
2908
|
+
rb_define_method(rb_cImage, "compare", image_compare, 1);
|
2909
|
+
rb_define_method(rb_cImage, "width", image_sx, 0);
|
2910
|
+
rb_define_method(rb_cImage, "height", image_sy, 0);
|
2911
|
+
rb_define_method(rb_cImage, "truecolor?", image_is_truecolor, 0);
|
2912
|
+
rb_define_method(rb_cImage, "colors_total", image_colors_total, 0);
|
2913
|
+
rb_define_method(rb_cImage, "interlace", image_get_interlace, 0);
|
2914
|
+
rb_define_method(rb_cImage, "transparent", image_transparent_get, 0);
|
2915
|
+
rb_define_method(rb_cImage, "rgba", image_rgba, 1);
|
2916
|
+
rb_define_method(rb_cImage, "[]", image_get_pixel, 2);
|
2917
|
+
rb_define_method(rb_cImage, "bounds_safe?", image_bounds_safe, 2);
|
2918
|
+
rb_define_method(rb_cImage, "color_closest_hwb", image_color_closest_hwb, -1);
|
2919
|
+
rb_define_method(rb_cImage, "color_allocate", image_color_allocate, -1);
|
2920
|
+
rb_define_method(rb_cImage, "color_closest", image_color_closest, -1);
|
2921
|
+
rb_define_method(rb_cImage, "color_exact", image_color_exact, -1);
|
2922
|
+
rb_define_method(rb_cImage, "color_resolve", image_color_resolve, -1);
|
2923
|
+
rb_define_method(rb_cImage, "brush=", image_set_brush, 1);
|
2924
|
+
rb_define_method(rb_cImage, "tile=", image_set_tile, 1);
|
2925
|
+
rb_define_method(rb_cImage, "copy_palette", image_copy_palette, 1);
|
2926
|
+
rb_define_method(rb_cImage, "copy", image_copy, 7);
|
2927
|
+
rb_define_method(rb_cImage, "copy_merge", image_copy_merge, 8);
|
2928
|
+
rb_define_method(rb_cImage, "copy_merge_gray", image_copy_merge_gray, 8);
|
2929
|
+
rb_define_method(rb_cImage, "copy_resized", image_copy_resized, 9);
|
2930
|
+
rb_define_method(rb_cImage, "copy_resampled", image_copy_resampled, 9);
|
2931
|
+
rb_define_method(rb_cImage, "copy_rotated", image_copy_rotated, 8);
|
2932
|
+
rb_define_method(rb_cImage, "interlace=", image_interlace_set, 1);
|
2933
|
+
rb_define_method(rb_cImage, "antialiased=", image_set_antialiased, 1);
|
2934
|
+
rb_define_method(rb_cImage, "thickness=", image_set_thickness, 1);
|
2935
|
+
rb_define_method(rb_cImage, "alpha_blending=", image_set_alpha_blending, 1);
|
2936
|
+
rb_define_method(rb_cImage, "save_alpha=", image_save_alpha, 1);
|
2937
|
+
rb_define_method(rb_cImage, "color_deallocate", image_color_deallocate, 1);
|
2938
|
+
rb_define_method(rb_cImage, "transparent=", image_color_transparent, 1);
|
2939
|
+
rb_define_method(rb_cImage, "sharepen", image_sharepen, 1);
|
2940
|
+
rb_define_method(rb_cImage, "to_palette!", image_truecolor_to_palette, -1);
|
2941
|
+
rb_define_method(rb_cImage, "antialiased_dont_blend", image_set_antialiased_dont_blend, 2);
|
2942
|
+
rb_define_method(rb_cImage, "[]=", image_set_pixel, 3);
|
2943
|
+
rb_define_method(rb_cImage, "fill", image_fill, 3);
|
2944
|
+
rb_define_method(rb_cImage, "fill_to_border", image_fill_to_border, 4);
|
2945
|
+
rb_define_method(rb_cImage, "clip=", image_set_clip, 4);
|
2946
|
+
rb_define_method(rb_cImage, "line", image_line, 5);
|
2947
|
+
rb_define_method(rb_cImage, "dashed_line", image_dashed_line, 5);
|
2948
|
+
rb_define_method(rb_cImage, "rectangle", image_rectangle, 5);
|
2949
|
+
rb_define_method(rb_cImage, "filled_rectangle", image_filled_rectangle, 5);
|
2950
|
+
rb_define_method(rb_cImage, "filled_ellipse", image_filled_ellipse, 5);
|
2951
|
+
rb_define_method(rb_cImage, "arc", image_arc, 7);
|
2952
|
+
rb_define_method(rb_cImage, "filled_arc", image_filled_arc, 8);
|
2953
|
+
rb_define_method(rb_cImage, "clip", image_get_clip, 0);
|
2954
|
+
rb_define_method(rb_cImage, "styles=", image_set_style, 1);
|
2955
|
+
rb_define_method(rb_cImage, "polygon", image_polygon, 2);
|
2956
|
+
rb_define_method(rb_cImage, "open_polygon", image_open_polygon, 2);
|
2957
|
+
rb_define_method(rb_cImage, "filled_polygon", image_filled_polygon, 2);
|
2958
|
+
rb_define_method(rb_cImage, "aa_blend", image_aa_blend, 0);
|
2959
|
+
rb_define_method(rb_cImage, "string", image_string, 5);
|
2960
|
+
rb_define_method(rb_cImage, "string_up", image_string_up, 5);
|
2961
|
+
rb_define_method(rb_cImage, "char", image_char, 5);
|
2962
|
+
rb_define_method(rb_cImage, "char_up", image_char_up, 5);
|
2963
|
+
rb_define_method(rb_cImage, "stringft", image_stringft, -1);
|
2964
|
+
rb_define_method(rb_cImage, "stringft_circle", image_stringft_circle, 10);
|
2965
|
+
|
2966
|
+
rb_define_class_variable(rb_cImage, "@@named_colors", m_named_colors());
|
2967
|
+
rb_define_singleton_method(rb_cImage, "new", image_s_new, -1);
|
2968
|
+
rb_define_singleton_method(rb_cImage, "from_data", image_s_from_data, -1);
|
2969
|
+
rb_define_method(rb_cImage, "file", image_file, -1);
|
2970
|
+
rb_define_method(rb_cImage, "data", image_data, -1);
|
2971
|
+
rb_define_method(rb_cImage, "clone", image_clone, 0);
|
2972
|
+
rb_define_method(rb_cImage, "to_palette", image_to_palette, -1);
|
2973
|
+
|
2974
|
+
// Init
|
2975
|
+
gdFontCacheSetup();
|
2976
|
+
}
|