ft2-ruby 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ Thu Aug 15 09:39:24 2002, pabs <pabs@pablotron.org>
2
+ * created changelog.
3
+
4
+ Tue Nov 12 17:20:23 2002, pabs <pabs@pablotron.org
5
+ * made some changes according to the notes in the freetype2 headers:
6
+ * ft2.c: removed FT2::PixelMode::RGB and FT2::PixelMode::RGBA constants
7
+ * ft2.c: removed Ft2::PaletteMode
8
+ * compiles clean with -W -Wall -pedantic again
9
+
10
+ Fri Nov 15 03:27:50 2002, pabs <pabs@pablotron.org
11
+ * ft2.c: finished documentation for FT2::Face methods.
12
+
13
+ Fri Nov 15 03:52:46 2002, pabs <pabs@pablotron.org
14
+ * ft2.c: added FT2::Face#current_charmap
15
+
16
+ Fri Nov 15 15:15:37 2002, pabs <pabs@pablotron.org
17
+ * ft2.c: finished documentation for FT2::GlyphMetrics methods.
18
+
19
+ Sat Nov 16 01:45:42 2002, pabs <pabs@pablotron.org
20
+ * ft2.c: finished documentation for FT2::GlyphSlot methods.
21
+
22
+ Wed Nov 20 16:11:10 2002, pabs <pabs@pablotron.org
23
+ * ft2.c: finished documenting the FT2::SizeMetrics methods (had to
24
+ pull the documentation for them out of the second part of the
25
+ FreeType2 tutorial, since they're not available in the API
26
+ reference).
27
+
28
+ Thu Nov 21 15:18:26 2002, pabs <pabs@pablotron.org
29
+ * ft2.c: finished documenting and implementing FT2::Glyph,
30
+ FT2::BitmapGlyph, and FT2::OutlineGlyph.
31
+ * ft2.c: compiles clean with -W -Wall -pedantic again
32
+ * TODO: updated
@@ -0,0 +1,14 @@
1
+ ./README
2
+ ./ft2.c
3
+ ./extconf.rb
4
+ ./examples/name_list.rb
5
+ ./examples/test_ft2.rb
6
+ ./examples/fonts/CVS/Root
7
+ ./examples/fonts/CVS/Repository
8
+ ./examples/fonts/CVS/Entries
9
+ ./examples/fonts/yudit.ttf
10
+ ./examples/.test_ft2.rb.swp
11
+ ./MANIFEST
12
+ ./TODO
13
+ ./tags
14
+ ./ChangeLog
data/README ADDED
@@ -0,0 +1,19 @@
1
+ FT2-Ruby 0.1.0 README
2
+ =====================
3
+
4
+ This document was last updated on Sat Nov 16 17:51:41 2002. Please see
5
+ http://www.pablotron.org/software/ft2-ruby/ for the latest version of
6
+ this software.
7
+
8
+ Introduction
9
+ ============
10
+ hum de dum dum
11
+
12
+ Installing FT2-Ruby
13
+ ===================
14
+ blah de blah blah
15
+
16
+ About the Author
17
+ ================
18
+ Paul Duncan <pabs@pablotron.org>
19
+ http://www.pablotron.org/
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ft2-ruby"
8
+ gem.summary = %Q{Ruby libraries to FreeType2}
9
+ gem.email = "pabs@pablotron.org"
10
+ gem.homepage = "http://www.pablotron.org/"
11
+ gem.authors = ["Paul Duncan"]
12
+ gem.extensions = ["extconf.rb"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ #
21
+ # task :default => :test
22
+ #
23
+ require 'rake/rdoctask'
24
+ Rake::RDocTask.new do |rdoc|
25
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
26
+
27
+ rdoc.rdoc_dir = 'rdoc'
28
+ rdoc.title = "ft2-ruby #{version}"
29
+ rdoc.rdoc_files.include('README')
30
+ rdoc.rdoc_files.include('TODO')
31
+ rdoc.rdoc_files.include('ft2.c')
32
+ end
data/TODO ADDED
@@ -0,0 +1,3 @@
1
+ * fixed point data conversions
2
+ * face subglyph handling
3
+ * test test test test!
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
Binary file
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $FONTDIR = '/usr/X11R6/lib/X11/fonts/truetype'
4
+
5
+ require 'readline'
6
+ require 'ft2'
7
+
8
+ $commands = {
9
+ 'quit' => 'Quit program.',
10
+ 'list' => 'List all fonts.',
11
+ 'help' => 'Print this list of commands.',
12
+ }
13
+ $fonts = {}
14
+
15
+ def tab_complete(str)
16
+ ($commands.keys.map { |i| i =~ /^#{str}/i ? i : nil }.compact! || []) +
17
+ $fonts.keys.map { |i| i =~ /^#{str}/i ? i : nil }.compact!
18
+ end
19
+
20
+ def show_font_info(str)
21
+ path, face = $fonts[str]
22
+ if path and face
23
+ puts 'Name: ' << face.name,
24
+ 'Path: ' << path,
25
+ 'Family: ' << face.family,
26
+ 'Style: ' << face.style,
27
+ 'Bold: ' << face.bold?.to_s,
28
+ 'Italic: ' << face.italic?.to_s,
29
+ 'Scalable: ' << face.scalable?.to_s,
30
+ 'Horizontal: ' << face.horizontal?.to_s,
31
+ 'Vertical: ' << face.vertical?.to_s,
32
+ 'Kerning: ' << face.kerning?.to_s,
33
+ 'Fast Glyphs: ' << face.fast_glyphs?.to_s,
34
+ 'Num Glyphs: ' << face.num_glyphs.to_s,
35
+ 'Num Charmaps: ' << face.num_charmaps.to_s
36
+
37
+ else
38
+ $stderr.puts "Unknown font \"#{str}\""
39
+ end
40
+ end
41
+
42
+ count = 0
43
+ Dir["#$FONTDIR/*"].each { |i|
44
+ count += 1
45
+ next if i =~ /^\./
46
+ begin
47
+ face = FT2::Face.load(i)
48
+ rescue Exception
49
+ next
50
+ end
51
+ # puts [face, face.name, face.num_glyphs ].join ', '
52
+ $fonts[face.name] = [i, face]
53
+ }
54
+ puts "Loaded #{$fonts.keys.size} of #{count} fonts."
55
+
56
+ # Readline::completion_case_fold = true
57
+ Readline::completion_proc = Proc.new { |str| tab_complete(str) }
58
+
59
+ done = false
60
+ until done
61
+ line = Readline::readline '> ', true
62
+
63
+ case line
64
+ when %r|^q(uit)?|
65
+ done = true
66
+ when %r|^h(elp)?|
67
+ $commands.keys.sort { |a, b| a <=> b }.each { |key|
68
+ puts "#{key}: #{$commands[key]}"
69
+ }
70
+ when %r|^l(ist\|s)?|
71
+ $fonts.each { |key, val|
72
+ path, face = val
73
+ puts [key, face.num_glyphs].join ', '
74
+ }
75
+ when /^$/
76
+ next
77
+ else
78
+ show_font_info(line.strip)
79
+ end
80
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ft2'
4
+
5
+ puts FT2::version
6
+ puts FT2::VERSION
7
+
8
+ face = FT2::Face.new 'fonts/yudit.ttf'
9
+ puts "glyphs: #{face.glyphs}",
10
+ "charmaps: #{face.num_charmaps}",
11
+ "horiz: #{face.horizontal?}",
12
+ "vert: #{face.vertical?}"
13
+
14
+ # cycle through default charmap
15
+ puts 'listing character codes with first_char/next_char'
16
+ c_code, g_idx = face.first_char
17
+ while g_idx != 0
18
+ puts "#{c_code} => " << face.glyph_name(g_idx)
19
+ c_code, g_idx = face.next_char c_code
20
+ end
21
+
22
+ puts 'listing charcodes with current_charmap'
23
+
24
+ cmap = face.current_charmap
25
+ cmap.keys.sort.each { |c_code|
26
+ puts "#{c_code} => " << face.glyph_name(cmap[c_code])
27
+ }
@@ -0,0 +1,10 @@
1
+ require 'mkmf'
2
+
3
+ ft2_config = with_config("freetype-config", "freetype-config")
4
+
5
+ $CFLAGS << ' ' << `#{ft2_config} --cflags`.chomp
6
+ $LDFLAGS << ' ' << `#{ft2_config} --libs`.chomp
7
+
8
+ have_library("freetype", "FT_Init_FreeType") and
9
+ create_makefile("ft2")
10
+
data/ft2.c ADDED
@@ -0,0 +1,3170 @@
1
+ /************************************************************************/
2
+ /* Copyright (c) 2002 Paul Duncan */
3
+ /* */
4
+ /* Permission is hereby granted, free of charge, to any person */
5
+ /* obtaining a copy of this software and associated documentation files */
6
+ /* (the "Software"), to deal in the Software without restriction, */
7
+ /* including without limitation the rights to use, copy, modify, merge, */
8
+ /* publish, distribute, sublicense, and/or sell copies of the Software, */
9
+ /* and to permit persons to whom the Software is furnished to do so, */
10
+ /* subject to the following conditions: */
11
+ /* */
12
+ /* The above copyright notice and this permission notice shall be */
13
+ /* included in all copies of the Software, its documentation and */
14
+ /* marketing & publicity materials, and acknowledgment shall be given */
15
+ /* in the documentation, materials and software packages that this */
16
+ /* Software was used. */
17
+ /* */
18
+ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
19
+ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
20
+ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
21
+ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY */
22
+ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
23
+ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
24
+ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
25
+ /************************************************************************/
26
+
27
+ #include <ruby.h>
28
+ #include <ft2build.h>
29
+ #include FT_FREETYPE_H
30
+ #include FT_GLYPH_H
31
+
32
+ #define VERSION "0.1.0"
33
+ #define UNUSED(a) ((void) (a))
34
+ #define ABS(a) (((a) < 0) ? -(a) : (a))
35
+
36
+ /* convert to and from FT2 fixed values */
37
+ #define FTFIX2DBL(a) ((double) (a) / 0x10000)
38
+ #define DBL2FTFIX(a) ((double) (a) * 0x10000)
39
+
40
+ static FT_Library library;
41
+ static VALUE mFt2,
42
+ mBBox, /* GlyphBBox */
43
+ mEnc, /* encoding */
44
+ mGlyphFormat,
45
+ mKerningMode,
46
+ mLoad,
47
+ /* mPaletteMode, */
48
+ mPixelMode,
49
+ mRenderMode,
50
+
51
+ cBitmap,
52
+ cBitmapGlyph,
53
+ cCharMap,
54
+ cFace,
55
+ cGlyph,
56
+ cGlyphClass,
57
+ cGlyphSlot,
58
+ cGlyphMetrics,
59
+ cLibrary,
60
+ cMemory,
61
+ cOutline,
62
+ cOutlineGlyph,
63
+ /* cRaster, */
64
+ cSubGlyph,
65
+ cSize,
66
+ cSizeMetrics;
67
+
68
+ static void face_free(void *ptr);
69
+ static void glyph_free(void *ptr);
70
+
71
+ static void dont_free(void *ptr) { UNUSED(ptr); }
72
+
73
+ static void handle_error(FT_Error err) {
74
+ #undef __FTERRORS_H__
75
+ #define FT_ERRORDEF( e, v, s ) { e, s },
76
+ #define FT_ERROR_START_LIST {
77
+ #define FT_ERROR_END_LIST { 0, 0 } };
78
+ int i = 0;
79
+ static const struct {
80
+ int code;
81
+ const char *str;
82
+ } errors[] =
83
+ #include FT_ERRORS_H
84
+
85
+ for (i = 0; ((unsigned int) i) < sizeof(errors) / sizeof(errors[0]); i++)
86
+ if (err == errors[i].code)
87
+ rb_raise(rb_eException, "FreeType2 Error: %s.", errors[i].str);
88
+
89
+ rb_raise(rb_eException, "FreeType2 Error: Unknown error %d.", err);
90
+ }
91
+
92
+ static double ft_fixed_to_double(FT_Fixed fixed) {
93
+ return ((0xffff0000 & fixed) >> 16) +
94
+ ((double) (0xffff & fixed) / 0xffff);
95
+ }
96
+
97
+ static VALUE ft_version(VALUE klass) {
98
+ char buf[1024];
99
+ FT_Int ver[3];
100
+ UNUSED(klass);
101
+
102
+ FT_Library_Version(library, &(ver[0]), &(ver[1]), &(ver[2]));
103
+
104
+ snprintf(buf, sizeof(buf), "%d.%d.%d", ver[0], ver[1], ver[2]);
105
+ return rb_str_new2(buf);
106
+ }
107
+
108
+
109
+ /***********************/
110
+ /* FT2::Bitmap methods */
111
+ /***********************/
112
+
113
+ /*
114
+ * Constructor for FT2::Bitmap.
115
+ *
116
+ * This method is currently empty. You should never call this method
117
+ * directly unless you're instantiating a derived class (ie, you know
118
+ * what you're doing).
119
+ *
120
+ */
121
+ static VALUE ft_bitmap_init(VALUE self) {
122
+ return self;
123
+ }
124
+
125
+ /*
126
+ * Return the number of rows in a FT2::Bitmap object.
127
+ *
128
+ * Examples:
129
+ * rows = bitmap.rows
130
+ *
131
+ */
132
+ static VALUE ft_bitmap_rows(VALUE self) {
133
+ FT_Bitmap *bitmap;
134
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
135
+ return INT2FIX(bitmap->rows);
136
+ }
137
+
138
+ /*
139
+ * Return the width of an FT2::Bitmap object.
140
+ *
141
+ * Examples:
142
+ * width = bitmap.width
143
+ *
144
+ */
145
+ static VALUE ft_bitmap_width(VALUE self) {
146
+ FT_Bitmap *bitmap;
147
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
148
+ return INT2FIX(bitmap->width);
149
+ }
150
+
151
+ /*
152
+ * Return the pitch (bytes per row) of an FT2::Bitmap object.
153
+ *
154
+ * Return the pitch (bytes per row, including alignment padding) of an
155
+ * FT2::Bitmap object.
156
+ *
157
+ * Examples:
158
+ * width = bitmap.width
159
+ *
160
+ */
161
+ static VALUE ft_bitmap_pitch(VALUE self) {
162
+ FT_Bitmap *bitmap;
163
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
164
+ return INT2FIX(bitmap->pitch);
165
+ }
166
+
167
+ /*
168
+ * Return the buffer (e.g. raw pixel data) of an FT2::Bitmap object.
169
+ *
170
+ * Examples:
171
+ * # return the rendered pixels as a binary string
172
+ * buffer = bitmap.buffer
173
+ *
174
+ * # assume a render method called render_font(buffer, width, height)
175
+ * render_font(bitmap.buffer, bitmap.width, bitmap.rows)
176
+ *
177
+ */
178
+ static VALUE ft_bitmap_buffer(VALUE self) {
179
+ FT_Bitmap *bitmap;
180
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
181
+ return rb_str_new((char*) bitmap->buffer, ABS(bitmap->pitch) * bitmap->rows);
182
+ }
183
+
184
+ /*
185
+ * Return the number of grays in an FT2::Bitmap object.
186
+ *
187
+ * Note:
188
+ * Only used if Ft2::Bitmap#pixel_mode is FT2::PixelMode::GRAYS.
189
+ *
190
+ * Examples:
191
+ * depth = bitmap.num_grays
192
+ *
193
+ */
194
+ static VALUE ft_bitmap_num_grays(VALUE self) {
195
+ FT_Bitmap *bitmap;
196
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
197
+ return INT2FIX(bitmap->num_grays);
198
+ }
199
+
200
+ /*
201
+ * Return the pixel mode (e.g. bit depth) of an FT2::Bitmap object.
202
+ *
203
+ * Note:
204
+ * Always returns one of the values avaiable in FT2::PixelMode (for a
205
+ * full list, try the following code: "p FT2::PixelMode.constants.sort")
206
+ *
207
+ * Examples:
208
+ * case bitmap.pixel_mode
209
+ * when FT2::PixelMode::RGB32
210
+ * puts "wow that's a lot of colors!"
211
+ * when FT2::PixelMode::MONO
212
+ * puts "time to get a better monitor..."
213
+ * end
214
+ *
215
+ */
216
+ static VALUE ft_bitmap_pixel_mode(VALUE self) {
217
+ FT_Bitmap *bitmap;
218
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
219
+ return INT2FIX(bitmap->pixel_mode);
220
+ }
221
+
222
+ /*
223
+ * Return the palette mode of an FT2::Bitmap object.
224
+ *
225
+ * Note:
226
+ * Always returns one of the values avaiable in FT2::PaletteMode.
227
+ *
228
+ * Examples:
229
+ * case bitmap.palette_mode
230
+ * when FT2::PaletteMode::RGBA
231
+ * puts "we have an alpha channel!"
232
+ * when FT2::PaletteMode::RGB
233
+ * puts "no alpha channel for you"
234
+ * end
235
+ *
236
+ */
237
+ static VALUE ft_bitmap_palette_mode(VALUE self) {
238
+ FT_Bitmap *bitmap;
239
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
240
+ return INT2FIX(bitmap->palette_mode);
241
+ }
242
+
243
+ /*
244
+ * Return the palette of an FT2::Bitmap object.
245
+ *
246
+ * Note:
247
+ * Returns a binary string of RGB or RGBA elements (check
248
+ * FT2::Bitmap#palette_mode to determine which).
249
+ *
250
+ * Examples:
251
+ * case bitmap.palette_mode
252
+ * when FT2::PaletteMode::RGBA
253
+ * rgba_palette_string = bitmap.palette
254
+ * when FT2::PaletteMode::RGB
255
+ * rgb_palette_string = bitmap.palette
256
+ * end
257
+ *
258
+ */
259
+ static VALUE ft_bitmap_palette(VALUE self) {
260
+ FT_Bitmap *bitmap;
261
+ /* int size; */
262
+ Data_Get_Struct(self, FT_Bitmap, bitmap);
263
+
264
+ return Qnil;
265
+ /* FIXME i don't know how big the palette memory is, so i'll just
266
+ * assume it's 256 entries :/
267
+ *
268
+ * none of this shit compiles, so I'm disabling it for now.
269
+ if (bitmap->palette_mode == ft_palette_mode_rgb)
270
+ size = 3 * 256;
271
+ else if (bitmap->palette_mode == ft_palette_mode_rgba)
272
+ size = 4 * 256;
273
+ else
274
+ rb_raise(rb_eException, "Unknown palette mode: %d.",
275
+ INT2FIX(bitmap->palette_mode));
276
+
277
+ return rb_str_new(bitmap->palette, size); */
278
+ }
279
+
280
+ /*********************/
281
+ /* FT2::Face methods */
282
+ /*********************/
283
+ static void face_free(void *ptr) {
284
+ FT_Face face = *((FT_Face *) ptr);
285
+ FT_Error err;
286
+
287
+ if ((err = FT_Done_Face(face)) != FT_Err_Ok)
288
+ handle_error(err);
289
+ free(ptr);
290
+ }
291
+
292
+ /*
293
+ * Allocate and initialize a new FT2::Face object.
294
+ *
295
+ * Note:
296
+ * FreeType2-Ruby creates a new (hidden) FT2::Library instance at
297
+ * runtime, which FT2::Face objects are automatically initialized with
298
+ * if an a library is not specified.
299
+ *
300
+ * Aliases:
301
+ * FT2::Face.load
302
+ *
303
+ * Examples:
304
+ * # load font from file "yudit.ttf"
305
+ * face = FT2::Face.new 'yudit.ttf'
306
+ *
307
+ * # load second face from from file "yudit.ttf"
308
+ * face = FT2::Face.new 'yudit.ttf', 1
309
+ *
310
+ * # load font from file "yudit.ttf" under FT2::Library instance lib
311
+ * face = FT2::Face.new lib, 'yudit.ttf'
312
+ *
313
+ * # load second face from file "yudit.ttf" under FT2::Library instance lib
314
+ * face = FT2::Face.new lib, 'yudit.ttf', 1
315
+ */
316
+ VALUE ft_face_new(int argc, VALUE *argv, VALUE klass) {
317
+ VALUE self, path;
318
+ FT_Library *lib;
319
+ FT_Face *face;
320
+ FT_Error err;
321
+ FT_Long face_index;
322
+
323
+ lib = &library;
324
+ switch (argc) {
325
+ case 1:
326
+ path = argv[0];
327
+ face_index = 0;
328
+ break;
329
+ case 2:
330
+ if (rb_obj_is_kind_of(argv[0], rb_cString)) {
331
+ path = argv[0];
332
+ face_index = NUM2INT(argv[1]);
333
+ } else if (rb_obj_is_kind_of(argv[0], cLibrary)) {
334
+ Data_Get_Struct(argv[0], FT_Library, lib);
335
+ path = argv[0];
336
+ face_index = 0;
337
+ } else {
338
+ rb_raise(rb_eArgError, "Invalid first argument.");
339
+ }
340
+ break;
341
+ case 3:
342
+ Data_Get_Struct(argv[0], FT_Library, lib);
343
+ path = argv[1];
344
+ face_index = NUM2INT(argv[1]);
345
+ break;
346
+ default:
347
+ rb_raise(rb_eArgError, "Invalid argument count: %d.", argc);
348
+ }
349
+
350
+ face = malloc(sizeof(FT_Face));
351
+ err = FT_New_Face(*lib, RSTRING(path)->ptr, face_index, face);
352
+ if (err != FT_Err_Ok)
353
+ handle_error(err);
354
+
355
+ self = Data_Wrap_Struct(klass, 0, face_free, face);
356
+ rb_obj_call_init(self, 0, NULL);
357
+
358
+ return self;
359
+ }
360
+
361
+ /*
362
+ * Allocate and initialize a new FT2::Face object from in-memory buffer.
363
+ *
364
+ * Note:
365
+ * FreeType2-Ruby creates a new (hidden) FT2::Library instance at
366
+ * runtime, which FT2::Face objects are automatically initialized with
367
+ * if an a library is not specified.
368
+ *
369
+ * Examples:
370
+ * # load font from string _buffer_
371
+ * face = FT2::Face.new buffer, buffer_size
372
+ *
373
+ * # load second face from string _buffer_
374
+ * face = FT2::Face.new buffer, buffer_size, 1
375
+ *
376
+ * # load font from string _buffer_ under FT2::Library instance _lib_
377
+ * face = FT2::Face.new lib, buffer, buffer_size
378
+ *
379
+ * # load second face from string _buffer_ under FT2::Library instance _lib_
380
+ * face = FT2::Face.new lib, buffer, buffer_size, 1
381
+ */
382
+ VALUE ft_face_new_from_memory(int argc, VALUE *argv, VALUE klass) {
383
+ VALUE self;
384
+ FT_Library *lib;
385
+ FT_Face *face;
386
+ FT_Error err;
387
+ FT_Long face_index;
388
+ void *mem;
389
+ int len;
390
+
391
+ lib = &library;
392
+ switch (argc) {
393
+ case 2:
394
+ mem = RSTRING(argv[0])->ptr;
395
+ len = NUM2INT(argv[1]);
396
+ face_index = 0;
397
+ break;
398
+ case 3:
399
+ if (rb_obj_is_kind_of(argv[0], rb_cString)) {
400
+ mem = RSTRING(argv[0])->ptr;
401
+ len = NUM2INT(argv[1]);
402
+ face_index = NUM2INT(argv[2]);
403
+ } else if (rb_obj_is_kind_of(argv[0], cLibrary)) {
404
+ Data_Get_Struct(argv[0], FT_Library, lib);
405
+ mem = RSTRING(argv[1])->ptr;
406
+ len = NUM2INT(argv[2]);
407
+ face_index = 0;
408
+ } else {
409
+ rb_raise(rb_eArgError, "Invalid first argument.");
410
+ }
411
+ break;
412
+ case 4:
413
+ Data_Get_Struct(argv[0], FT_Library, lib);
414
+ mem = RSTRING(argv[1])->ptr;
415
+ len = NUM2INT(argv[2]);
416
+ face_index = NUM2INT(argv[3]);
417
+ break;
418
+ default:
419
+ rb_raise(rb_eArgError, "Invalid argument count: %d.", argc);
420
+ }
421
+
422
+ face = malloc(sizeof(FT_Face));
423
+ err = FT_New_Memory_Face(*lib, mem, len, face_index, face);
424
+ if (err != FT_Err_Ok)
425
+ handle_error(err);
426
+
427
+ self = Data_Wrap_Struct(klass, 0, face_free, face);
428
+ rb_obj_call_init(self, 0, NULL);
429
+
430
+ return self;
431
+ }
432
+
433
+ /*
434
+ * Constructor for FT2::Face.
435
+ *
436
+ * This method is currently empty. You should never call this method
437
+ * directly unless you're instantiating a derived class (ie, you know
438
+ * what you're doing).
439
+ *
440
+ */
441
+ static VALUE ft_face_init(VALUE self) {
442
+ return self;
443
+ }
444
+
445
+ /*
446
+ * Return the number of faces in an FT2::Face object.
447
+ *
448
+ * Aliases:
449
+ * FT2::Face#num_faces
450
+ *
451
+ * Examples:
452
+ * num_faces = face.faces
453
+ *
454
+ */
455
+ static VALUE ft_face_faces(VALUE self) {
456
+ FT_Face *face;
457
+ Data_Get_Struct(self, FT_Face, face);
458
+ return INT2FIX((int) (*face)->num_faces);
459
+ }
460
+
461
+ /*
462
+ * Return the index of an FT2::Face object in its font file.
463
+ *
464
+ * Note:
465
+ * This is almost always zero.
466
+ *
467
+ * Aliases:
468
+ * FT2::Face#face_index
469
+ *
470
+ * Examples:
471
+ * index = face.index
472
+ *
473
+ */
474
+ static VALUE ft_face_index(VALUE self) {
475
+ FT_Face *face;
476
+ Data_Get_Struct(self, FT_Face, face);
477
+ return INT2FIX((int) (*face)->face_index);
478
+ }
479
+
480
+ /*
481
+ * Return the face flags of an FT2::Face object.
482
+ *
483
+ * You can binary OR this with any of the following values to obtain the
484
+ * value of that flag (note that this is returned as an Integer and not
485
+ * as a boolean value; eg non-zero for true and zero for false).
486
+ *
487
+ * Face Flags:
488
+ * FT2::Face::SCALABLE
489
+ * FT2::Face::FIXED_SIZES
490
+ * FT2::Face::FIXED_WIDTH
491
+ * FT2::Face::FIXED_HORIZONTAL
492
+ * FT2::Face::FIXED_VERTICAL
493
+ * FT2::Face::SFNT
494
+ * FT2::Face::KERNING
495
+ * FT2::Face::MULTIPLE_MASTERS
496
+ * FT2::Face::GLYPH_NAMES
497
+ * FT2::Face::EXTERNAL_STREAM
498
+ * FT2::Face::FAST_GLYPHS
499
+ *
500
+ * Alternatively, if you're only checking one flag, it's slightly faster
501
+ * (and arguably more concise), to use the following flag methods, which
502
+ * DO return true or false.
503
+ *
504
+ * Individual Flag Methods:
505
+ * FT2::Face#scalable?
506
+ * FT2::Face#fixed_sizes?
507
+ * FT2::Face#fixed_width?
508
+ * FT2::Face#horizontal?
509
+ * FT2::Face#vertical?
510
+ * FT2::Face#sfnt?
511
+ * FT2::Face#kerning?
512
+ * FT2::Face#external_stream?
513
+ * FT2::Face#fast_glyphs?
514
+ *
515
+ * Aliases:
516
+ * FT2::Face#face_flags
517
+ *
518
+ * Examples:
519
+ * if (face.flags & (FT2::Face::FAST_GLYPHS | FT2::Face::KERNING) != 0)
520
+ * puts 'face contains fast glyphs and kerning information'
521
+ * end
522
+ *
523
+ */
524
+ static VALUE ft_face_flags(VALUE self) {
525
+ FT_Face *face;
526
+ Data_Get_Struct(self, FT_Face, face);
527
+ return INT2FIX((int) (*face)->face_flags);
528
+ }
529
+
530
+ /*
531
+ * Is this FT2::Face scalable?
532
+ *
533
+ * Examples:
534
+ * puts "is scalable" if face.scalable?
535
+ *
536
+ */
537
+ static VALUE ft_face_flag_scalable(VALUE self) {
538
+ FT_Face *face;
539
+ Data_Get_Struct(self, FT_Face, face);
540
+ return ((*face)->face_flags & FT_FACE_FLAG_SCALABLE) ? Qtrue : Qfalse;
541
+ }
542
+
543
+ /*
544
+ * Does this FT2::Face contain bitmap strikes for some pixel sizes?
545
+ *
546
+ * Examples:
547
+ * puts "contains fixed sized glyphs" if face.fixed_sizes?
548
+ *
549
+ */
550
+ static VALUE ft_face_flag_fixed_sizes(VALUE self) {
551
+ FT_Face *face;
552
+ Data_Get_Struct(self, FT_Face, face);
553
+ return ((*face)->face_flags & FT_FACE_FLAG_FIXED_SIZES) ? Qtrue : Qfalse;
554
+ }
555
+
556
+ /*
557
+ * Does this FT2::Face contain fixed with characters?
558
+ *
559
+ * Examples:
560
+ * puts "contains fixed width characters" if face.fixed_width?
561
+ *
562
+ */
563
+ static VALUE ft_face_flag_fixed_width(VALUE self) {
564
+ FT_Face *face;
565
+ Data_Get_Struct(self, FT_Face, face);
566
+ return ((*face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH) ? Qtrue : Qfalse;
567
+ }
568
+
569
+ /*
570
+ * Does this FT2::Face contain horizontal glyph metrics?
571
+ *
572
+ * Note:
573
+ * This flag is true for virtually all fonts.
574
+ *
575
+ * Examples:
576
+ * puts "contains horizontal glyph metrics" if face.horizontal?
577
+ *
578
+ */
579
+ static VALUE ft_face_flag_horizontal(VALUE self) {
580
+ FT_Face *face;
581
+ Data_Get_Struct(self, FT_Face, face);
582
+ return ((*face)->face_flags & FT_FACE_FLAG_HORIZONTAL) ? Qtrue : Qfalse;
583
+ }
584
+
585
+ /*
586
+ * Does this FT2::Face contain vertical glyph metrics?
587
+ *
588
+ * Note:
589
+ * If this flag is not set, the glyph loader will synthesize vertical
590
+ * metrics itself.
591
+ *
592
+ * Examples:
593
+ * puts "contains vertical glyph metrics" if face.vertical?
594
+ *
595
+ */
596
+ static VALUE ft_face_flag_vertical(VALUE self) {
597
+ FT_Face *face;
598
+ Data_Get_Struct(self, FT_Face, face);
599
+ return ((*face)->face_flags & FT_FACE_FLAG_VERTICAL) ? Qtrue : Qfalse;
600
+ }
601
+
602
+ /*
603
+ * Is this FT2::Face stored in the 'sfnt' storage format?
604
+ *
605
+ * Note:
606
+ * This currently means the file was either TrueType or OpenType.
607
+ *
608
+ * Examples:
609
+ * puts "sfnt format font" if face.sfnt?
610
+ *
611
+ */
612
+ static VALUE ft_face_flag_sfnt(VALUE self) {
613
+ FT_Face *face;
614
+ Data_Get_Struct(self, FT_Face, face);
615
+ return ((*face)->face_flags & FT_FACE_FLAG_SFNT) ? Qtrue : Qfalse;
616
+ }
617
+
618
+ /*
619
+ * Does this FT2::Face contain kerning information?
620
+ *
621
+ * Examples:
622
+ * puts "face contains kerning information" if face.kerning?
623
+ *
624
+ */
625
+ static VALUE ft_face_flag_kerning(VALUE self) {
626
+ FT_Face *face;
627
+ Data_Get_Struct(self, FT_Face, face);
628
+ return ((*face)->face_flags & FT_FACE_FLAG_KERNING) ? Qtrue : Qfalse;
629
+ }
630
+
631
+ /*
632
+ * Was this FT2::Face loaded from an external stream?
633
+ *
634
+ * Examples:
635
+ * puts "face loaded from external stream" if face.external_stream?
636
+ *
637
+ */
638
+ static VALUE ft_face_flag_external_stream(VALUE self) {
639
+ FT_Face *face;
640
+ Data_Get_Struct(self, FT_Face, face);
641
+ return ((*face)->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM) ? Qtrue : Qfalse;
642
+ }
643
+
644
+ /*
645
+ * Does this FT2::Face contain fast glyphs?
646
+ *
647
+ * Note:
648
+ * This flag is usually set for fixed-size formats like FNT.
649
+ *
650
+ * Examples:
651
+ * puts "face contains fast glyphs" if face.fast_glyphs?
652
+ *
653
+ */
654
+ static VALUE ft_face_flag_fast_glyphs(VALUE self) {
655
+ FT_Face *face;
656
+ Data_Get_Struct(self, FT_Face, face);
657
+ return ((*face)->face_flags & FT_FACE_FLAG_FAST_GLYPHS) ? Qtrue : Qfalse;
658
+ }
659
+
660
+ /*
661
+ * Return the style flags of an FT2::Face object.
662
+ *
663
+ * You can binary OR this with any of the following values to obtain the
664
+ * value of that style flag (note that this is returned as an Integer
665
+ * and not as a boolean value; eg non-zero for true and zero for false).
666
+ *
667
+ * Style Flags:
668
+ * FT2::Face::BOLD
669
+ * FT2::Face::ITALIC
670
+ *
671
+ * Alternatively, if you're only checking one style flag, it's slightly
672
+ * faster (and arguably more concise), to use the following style flag
673
+ * methods, which DO return true or false.
674
+ *
675
+ * Individual Style Flag Methods:
676
+ * FT2::Face#bold?
677
+ * FT2::Face#italic?
678
+ *
679
+ * Examples:
680
+ * style = face.style_flags
681
+ *
682
+ */
683
+ static VALUE ft_face_style_flags(VALUE self) {
684
+ FT_Face *face;
685
+ Data_Get_Struct(self, FT_Face, face);
686
+ return INT2FIX((int) (*face)->style_flags);
687
+ }
688
+
689
+ /*
690
+ * Is this a bold FT2::Face?
691
+ *
692
+ * Examples:
693
+ * puts "bold face" if face.bold?
694
+ *
695
+ */
696
+ static VALUE ft_face_flag_bold(VALUE self) {
697
+ FT_Face *face;
698
+ Data_Get_Struct(self, FT_Face, face);
699
+ return ((*face)->style_flags & FT_STYLE_FLAG_BOLD) ? Qtrue : Qfalse;
700
+ }
701
+
702
+ /*
703
+ * Is this an italic FT2::Face?
704
+ *
705
+ * Examples:
706
+ * puts "italic face" if face.italic?
707
+ *
708
+ */
709
+ static VALUE ft_face_flag_italic(VALUE self) {
710
+ FT_Face *face;
711
+ Data_Get_Struct(self, FT_Face, face);
712
+ return ((*face)->style_flags & FT_STYLE_FLAG_ITALIC) ? Qtrue : Qfalse;
713
+ }
714
+
715
+ /*
716
+ * Return the number of glyphs in an FT2::Face object.
717
+ *
718
+ * Aliases:
719
+ * FT2::Face#num_glyphs
720
+ *
721
+ * Examples:
722
+ * count = face.glyphs
723
+ * puts "face has #{count.to_str} glyphs"
724
+ *
725
+ */
726
+ static VALUE ft_face_glyphs(VALUE self) {
727
+ FT_Face *face;
728
+ Data_Get_Struct(self, FT_Face, face);
729
+ return INT2FIX((int) (*face)->num_glyphs);
730
+ }
731
+
732
+ /*
733
+ * Return the family name of an FT2::Face object.
734
+ *
735
+ * Description:
736
+ * This is an ASCII string, usually in English, which describes the
737
+ * FT2::Face object's family (eg "Times New Roman" or "Geneva"). Some
738
+ * formats (eg Truetype and OpenType) provide localized and Unicode
739
+ * versions of this string, which are accessable via the format specific
740
+ * interfaces.
741
+ *
742
+ * Examples:
743
+ * puts 'family: ' << face.family
744
+ *
745
+ */
746
+ static VALUE ft_face_family(VALUE self) {
747
+ FT_Face *face;
748
+ Data_Get_Struct(self, FT_Face, face);
749
+ return rb_str_new2((*face)->family_name);
750
+ }
751
+
752
+ /*
753
+ * Return the style name of an FT2::Face object.
754
+ *
755
+ * Description:
756
+ * This is an ASCII string, usually in English, which describes the
757
+ * FT2::Face object's style (eg "Bold", "Italic", "Condensed", etc).
758
+ * This field is optional and may be set to nil.
759
+ *
760
+ * Examples:
761
+ * puts 'style: ' << face.style if face.style
762
+ *
763
+ */
764
+ static VALUE ft_face_style(VALUE self) {
765
+ FT_Face *face;
766
+ Data_Get_Struct(self, FT_Face, face);
767
+ if (!(*face)->style_name)
768
+ return Qnil;
769
+ return rb_str_new2((*face)->style_name);
770
+ }
771
+
772
+ /*
773
+ * Return the number of fixed sizes in an FT2::Face object.
774
+ *
775
+ * Note:
776
+ * This should be set to 0 for scalable fonts, unless the FT2::Face
777
+ * object contains a complete set of glyphs for the specified size.
778
+ *
779
+ * Aliases:
780
+ * FT2::Face#num_fixed_sizes
781
+ *
782
+ * Examples:
783
+ * puts 'fized sizes count: ' << face.fixed_sizes
784
+ *
785
+ */
786
+ static VALUE ft_face_fixed_sizes(VALUE self) {
787
+ FT_Face *face;
788
+ Data_Get_Struct(self, FT_Face, face);
789
+ return INT2FIX((int) (*face)->num_fixed_sizes);
790
+ }
791
+
792
+ /*
793
+ * Return an array of sizes in an FT2::Face object.
794
+ *
795
+ * Note:
796
+ * This method does not currently work..
797
+ *
798
+ * Examples:
799
+ * face.available_sizesdflksjaflksdjf FIXME
800
+ *
801
+ */
802
+ static VALUE ft_face_available_sizes(VALUE self) {
803
+ FT_Face *face;
804
+ Data_Get_Struct(self, FT_Face, face);
805
+ /* FIXME!! */
806
+ return INT2FIX((int) (*face)->available_sizes);
807
+ }
808
+
809
+ /*
810
+ * Return the number of charmaps in an FT2::Face object.
811
+ *
812
+ * Examples:
813
+ * puts 'number of charmaps: ' << face.num_charmaps
814
+ *
815
+ */
816
+ static VALUE ft_face_num_charmaps(VALUE self) {
817
+ FT_Face *face;
818
+ Data_Get_Struct(self, FT_Face, face);
819
+ return INT2FIX((int) (*face)->num_charmaps);
820
+ }
821
+
822
+ /*
823
+ * Return an array of charmaps in an FT2::Face object.
824
+ *
825
+ * Note:
826
+ * This method may not work correctly at the moment (FIXME).
827
+ *
828
+ * Examples:
829
+ * face.charmaps.each { |map| puts map.to_str }
830
+ *
831
+ */
832
+ static VALUE ft_face_charmaps(VALUE self) {
833
+ FT_Face *face;
834
+ VALUE ary;
835
+ int i;
836
+ Data_Get_Struct(self, FT_Face, face);
837
+
838
+ /* FIXME */
839
+ rb_bug("not implemented yet");
840
+ ary = rb_ary_new();
841
+ for (i = 0; i < (*face)->num_charmaps; i++)
842
+ rb_ary_push(ary, INT2FIX(i));
843
+
844
+ return ary;
845
+ }
846
+
847
+ /*
848
+ * Return the bounding box of an FT2::Face object.
849
+ *
850
+ * Note:
851
+ * This method is not currently implemented (FIXME).
852
+ *
853
+ * Examples:
854
+ * FIXME
855
+ *
856
+ */
857
+ static VALUE ft_face_bbox(VALUE self) {
858
+ UNUSED(self);
859
+ /* FIXME */
860
+ rb_bug("not implemented yet");
861
+ return Qnil;
862
+ }
863
+
864
+ /*
865
+ * Return the number of font units per EM for this FT2::Face object.
866
+ *
867
+ * Description:
868
+ * This value is typically 2048 for TrueType fonts, 1000 for Type1
869
+ * fonts, and should be set to the (unrealistic) value 1 for
870
+ * fixed-size fonts.
871
+ *
872
+ * Aliases:
873
+ * FT2::Face#units_per_EM
874
+ *
875
+ * Examples:
876
+ * em = face.units_per_em
877
+ *
878
+ */
879
+ static VALUE ft_face_units_per_em(VALUE self) {
880
+ FT_Face *face;
881
+ Data_Get_Struct(self, FT_Face, face);
882
+ return INT2FIX((int) (*face)->units_per_EM);
883
+ }
884
+
885
+ /*
886
+ * Return the ascender for this FT2::Face object.
887
+ *
888
+ * Description:
889
+ * An FT2::Face object's ascender is the vertical distance, in font
890
+ * units, from the baseline to the topmost point of any glyph in the
891
+ * face.
892
+ *
893
+ * Examples:
894
+ * asc = face.ascender
895
+ *
896
+ */
897
+ static VALUE ft_face_ascender(VALUE self) {
898
+ FT_Face *face;
899
+ Data_Get_Struct(self, FT_Face, face);
900
+ return INT2FIX((int) (*face)->ascender);
901
+ }
902
+
903
+ /*
904
+ * Return the descender for this FT2::Face object.
905
+ *
906
+ * Description:
907
+ * An FT2::Face object's descender is the vertical distance, in font
908
+ * units, from the baseline to the bottommost point of any glyph in
909
+ * the face.
910
+ *
911
+ * Examples:
912
+ * asc = face.descender
913
+ *
914
+ */
915
+ static VALUE ft_face_descender(VALUE self) {
916
+ FT_Face *face;
917
+ Data_Get_Struct(self, FT_Face, face);
918
+ return INT2FIX((int) (*face)->descender);
919
+ }
920
+
921
+ /*
922
+ * Return the height of this FT2::Face object.
923
+ *
924
+ * Description:
925
+ * An FT2::Face object's height is the vertical distance, in font
926
+ * units, from the baseline of one line to the baseline of the next.
927
+ * The value can be computed as 'ascender + descender + line_gap',
928
+ * where 'line_gap' is also called 'external leading'.
929
+ *
930
+ * Examples:
931
+ * h = face.height
932
+ *
933
+ */
934
+ static VALUE ft_face_height(VALUE self) {
935
+ FT_Face *face;
936
+ Data_Get_Struct(self, FT_Face, face);
937
+ return INT2FIX((int) (*face)->height);
938
+ }
939
+
940
+ /*
941
+ * Return the maximal advance width of this FT2::Face object.
942
+ *
943
+ * Description:
944
+ * The maximal advance width, in font units, for all glyphs in this
945
+ * FT2::Face object. This can be used to make word-wrapping
946
+ * computations faster. Only relevant for scalable formats.
947
+ *
948
+ * Examples:
949
+ * maw = face.max_advance_width
950
+ *
951
+ */
952
+ static VALUE ft_face_max_advance_width(VALUE self) {
953
+ FT_Face *face;
954
+ Data_Get_Struct(self, FT_Face, face);
955
+ return INT2FIX((int) (*face)->max_advance_width);
956
+ }
957
+
958
+ /*
959
+ * Return the maximal advance height of this FT2::Face object.
960
+ *
961
+ * Description:
962
+ * The maximal advance height, in font units, for all glyphs in this
963
+ * FT2::Face object. This can be used to make word-wrapping
964
+ * computations faster. Only relevant for scalable formats.
965
+ *
966
+ * Examples:
967
+ * mah = face.max_advance_height
968
+ *
969
+ */
970
+ static VALUE ft_face_max_advance_height(VALUE self) {
971
+ FT_Face *face;
972
+ Data_Get_Struct(self, FT_Face, face);
973
+ return INT2FIX((int) (*face)->max_advance_height);
974
+ }
975
+
976
+ /*
977
+ * Return the underline position of this FT2::Face object.
978
+ *
979
+ * Description:
980
+ * The position, in font units, of the underline line for this face.
981
+ * It's the center of the underlining stem. Only relevant for scalable
982
+ * formats.
983
+ *
984
+ * Examples:
985
+ * uh = face.underline_position
986
+ *
987
+ */
988
+ static VALUE ft_face_underline_position(VALUE self) {
989
+ FT_Face *face;
990
+ Data_Get_Struct(self, FT_Face, face);
991
+ return INT2FIX((int) (*face)->underline_position);
992
+ }
993
+
994
+ /*
995
+ * Return the underline thickness of this FT2::Face object.
996
+ *
997
+ * Description:
998
+ * The thickness, in font units, of the underline for this face. Only
999
+ * relevant for scalable formats.
1000
+ *
1001
+ * Examples:
1002
+ * ut = face.underline_thickness
1003
+ *
1004
+ */
1005
+ static VALUE ft_face_underline_thickness(VALUE self) {
1006
+ FT_Face *face;
1007
+ Data_Get_Struct(self, FT_Face, face);
1008
+ return INT2FIX((int) (*face)->underline_thickness);
1009
+ }
1010
+ /*
1011
+ * Return the glyph slot associated with this FT2::Face object.
1012
+ *
1013
+ * Description:
1014
+ * The face's associated glyph slot(s) (a FT2::GlyphSlot). This object
1015
+ * is created automatically with a new FT2::Face object. However,
1016
+ * certain kinds of applications (mainly tools like converters) can
1017
+ * need more than one slot to ease their task.
1018
+ *
1019
+ * Examples:
1020
+ * glyph = face.glyph
1021
+ *
1022
+ */
1023
+ static VALUE ft_face_glyph(VALUE self) {
1024
+ FT_Face *face;
1025
+ Data_Get_Struct(self, FT_Face, face);
1026
+
1027
+ if ((*face)->glyph)
1028
+ return Data_Wrap_Struct(cGlyphSlot, 0, dont_free, (*face)->glyph);
1029
+ else
1030
+ return Qnil;
1031
+ }
1032
+
1033
+ /*
1034
+ * Return the current active size of this FT2::Face object.
1035
+ *
1036
+ * Examples:
1037
+ * size = face.size
1038
+ *
1039
+ */
1040
+ static VALUE ft_face_size(VALUE self) {
1041
+ FT_Face *face;
1042
+ Data_Get_Struct(self, FT_Face, face);
1043
+
1044
+ if ((*face)->size)
1045
+ return Data_Wrap_Struct(cSize, 0, dont_free, (*face)->size);
1046
+ else
1047
+ return Qnil;
1048
+ }
1049
+
1050
+ /*
1051
+ * Return the current active FT2::CharMap of this FT2::Face object.
1052
+ *
1053
+ * Examples:
1054
+ * size = face.size
1055
+ *
1056
+ */
1057
+ static VALUE ft_face_charmap(VALUE self) {
1058
+ FT_Face *face;
1059
+ Data_Get_Struct(self, FT_Face, face);
1060
+
1061
+ if ((*face)->charmap)
1062
+ return Data_Wrap_Struct(cCharMap, 0, dont_free, (*face)->charmap);
1063
+ else
1064
+ return Qnil;
1065
+ }
1066
+
1067
+ /*
1068
+ * Attach a font file to this FT2::Face object.
1069
+ *
1070
+ * Description:
1071
+ * This is usually to read additional information for a single face
1072
+ * object. For example, it is used to read the AFM files that come
1073
+ * with Type 1 fonts in order to add kerning data and other metrics.
1074
+ * Throws an exception if the font file could not be loaded.
1075
+ * FreeType2 also supports loading from an input stream, but this
1076
+ * feature is not implemented in FT2-Ruby.
1077
+ *
1078
+ * Examples:
1079
+ * path = 'fonts'yudit.ttf'
1080
+ * begin
1081
+ * face.attach path # attach file "fonts/yudit.ttf"
1082
+ * rescue Exception
1083
+ * $stderr.puts "Couldn't open font file \"#{path}\": " << $!
1084
+ * end
1085
+ *
1086
+ */
1087
+ static VALUE ft_face_attach(VALUE self, VALUE path) {
1088
+ FT_Face *face;
1089
+ FT_Error err;
1090
+ Data_Get_Struct(self, FT_Face, face);
1091
+ if ((err = FT_Attach_File(*face, RSTRING(path)->ptr)) != FT_Err_Ok)
1092
+ handle_error(err);
1093
+ return self;
1094
+ }
1095
+
1096
+ /*
1097
+ * Set the character dimensions of this FT2::Face object.
1098
+ *
1099
+ * Description:
1100
+ * Sets the character dimensions of a FT2::Face object. The
1101
+ * `char_width' and `char_height' values are used for the width and
1102
+ * height, respectively, expressed in 26.6 fractional points.
1103
+ *
1104
+ * If the horizontal or vertical resolution values are zero, a default
1105
+ * value of 72dpi is used. Similarly, if one of the character
1106
+ * dimensions is zero, its value is set equal to the other.
1107
+ *
1108
+ * When dealing with fixed-size faces (i.e., non-scalable formats),
1109
+ * use the function FT2::Face#set_pixel_sizes .
1110
+ *
1111
+ * Examples:
1112
+ * face.set_char_size char_width, char_height, horiz_res, vert_res
1113
+ *
1114
+ */
1115
+ static VALUE ft_face_set_char_size(VALUE self, VALUE c_w, VALUE c_h, VALUE h_r, VALUE v_r) {
1116
+ FT_Face *face;
1117
+ FT_Error err;
1118
+ Data_Get_Struct(self, FT_Face, face);
1119
+ err = FT_Set_Char_Size(*face, NUM2DBL(c_w), NUM2DBL(c_h), NUM2INT(h_r), NUM2INT(v_r));
1120
+ if (err != FT_Err_Ok)
1121
+ handle_error(err);
1122
+ return self;
1123
+ }
1124
+
1125
+ /*
1126
+ * Set the character dimensions of this FT2::Face object.
1127
+ *
1128
+ * Description:
1129
+ * Sets the character dimensions of a FT2::Face object. The width and
1130
+ * height are expressed in integer pixels.
1131
+ *
1132
+ * If one of the character dimensions is zero, its value is set equal
1133
+ * to the other.
1134
+ *
1135
+ * The values of `pixel_width' and `pixel_height' correspond to the
1136
+ * pixel values of the typographic character size, which are NOT
1137
+ * necessarily the same as the dimensions of the glyph `bitmap cells'.
1138
+ *
1139
+ * The `character size' is really the size of an abstract square
1140
+ * called the `EM', used to design the font. However, depending on the
1141
+ * font design, glyphs will be smaller or greater than the EM.
1142
+ *
1143
+ * This means that setting the pixel size to, say, 8x8 doesn't
1144
+ * guarantee in any way that you will get glyph bitmaps that all fit
1145
+ * within an 8x8 cell (sometimes even far from it).
1146
+ *
1147
+ * Examples:
1148
+ * face.set_pixel_sizes pixel_width, pixel_height
1149
+ *
1150
+ */
1151
+ static VALUE ft_face_set_pixel_sizes(VALUE self, VALUE pixel_w, VALUE pixel_h) {
1152
+ FT_Face *face;
1153
+ FT_Error err;
1154
+ Data_Get_Struct(self, FT_Face, face);
1155
+ err = FT_Set_Pixel_Sizes(*face, NUM2INT(pixel_w), NUM2INT(pixel_h));
1156
+ if (err != FT_Err_Ok)
1157
+ handle_error(err);
1158
+ return self;
1159
+ }
1160
+
1161
+ /*
1162
+ * Set the pre-render transoformation matrix and vector of a FT2::Face object.
1163
+ *
1164
+ * Description:
1165
+ * Used to set the transformation that is applied to glyph images just
1166
+ * before they are converted to bitmaps in a FT2::GlyphSlot when
1167
+ * FT2::GlyphSlot#render is called.
1168
+ *
1169
+ * matrix: The transformation's 2x2 matrix. Use nil for the identity
1170
+ * matrix.
1171
+ * delta: The translation vector. Use nil for the null vector.
1172
+ *
1173
+ * Note:
1174
+ * The transformation is only applied to scalable image formats after
1175
+ * the glyph has been loaded. It means that hinting is unaltered by
1176
+ * the transformation and is performed on the character size given in
1177
+ * the last call to FT2::Face#set_char_sizes or
1178
+ * FT2::Face#set_pixel_sizes.
1179
+ *
1180
+ * Examples:
1181
+ * matrix = [[0, 1],
1182
+ * [0, 1]]
1183
+ * vector = nil
1184
+ *
1185
+ * face.set_transform matrix, vector
1186
+ *
1187
+ */
1188
+ static VALUE ft_face_set_transform(VALUE self, VALUE matrix, VALUE delta) {
1189
+ FT_Face *face;
1190
+ FT_Matrix m;
1191
+ FT_Vector v;
1192
+
1193
+ Data_Get_Struct(self, FT_Face, face);
1194
+
1195
+ if (matrix != Qnil) {
1196
+ /* FIXME: do I have these reversed? */
1197
+ m.xx = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix, 0), 0)));
1198
+ m.xy = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix, 1), 0)));
1199
+ m.yx = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix, 0), 1)));
1200
+ m.yy = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix, 1), 1)));
1201
+ }
1202
+
1203
+ if (delta != Qnil) {
1204
+ v.x = NUM2INT(rb_ary_entry(delta, 0));
1205
+ v.y = NUM2INT(rb_ary_entry(delta, 1));
1206
+ }
1207
+
1208
+ if (matrix != Qnil && delta != Qnil)
1209
+ FT_Set_Transform(*face, &m, &v);
1210
+ else if (matrix == Qnil && delta != Qnil)
1211
+ FT_Set_Transform(*face, NULL, &v);
1212
+ else if (matrix != Qnil && delta == Qnil)
1213
+ FT_Set_Transform(*face, &m, NULL);
1214
+ else
1215
+ FT_Set_Transform(*face, NULL, NULL);
1216
+
1217
+ return self;
1218
+ }
1219
+
1220
+ /*
1221
+ * Load a glyph at a given size into a glyph slot of a FT2::Face object.
1222
+ *
1223
+ * Description:
1224
+ * Load a glyph at a given size into a glyph slot of a FT2::Face
1225
+ * object.
1226
+ *
1227
+ * glyph_index: The index of the glyph in the font file.
1228
+ * load_flags: A flag indicating what to load for this glyph. The
1229
+ * FT2::Load::XXXX constants can be used to control the
1230
+ * glyph loading process (e.g., whether the outline should
1231
+ * be scaled, whether to load bitmaps or not, whether to
1232
+ * hint the outline, etc).
1233
+ *
1234
+ * Note:
1235
+ * If the glyph image is not a bitmap, and if the bit flag
1236
+ * FT2::Load::IGNORE_TRANSFORM is unset, the glyph image will be
1237
+ * transformed with the information passed to a previous call to
1238
+ * FT2::Face#set_transform
1239
+ *
1240
+ * Note that this also transforms the `face.glyph.advance' field, but
1241
+ * not the values in `face.glyph.metrics'.
1242
+ *
1243
+ * Load Flags:
1244
+ * FT2::Load::DEFAULT
1245
+ * FT2::Load::RENDER
1246
+ * FT2::Load::MONOCHROME
1247
+ * FT2::Load::LINEAR_DESIGN
1248
+ * FT2::Load::NO_SCALE
1249
+ * FT2::Load::NO_HINTING
1250
+ * FT2::Load::NO_BITMAP
1251
+ * FT2::Load::CROP_BITMAP
1252
+ * FT2::Load::VERTICAL_LAYOUT
1253
+ * FT2::Load::IGNORE_TRANSFORM
1254
+ * FT2::Load::IGNORE_GLOBAL_ADVANCE_WIDTH
1255
+ * FT2::Load::FORCE_AUTOHINT
1256
+ * FT2::Load::NO_RECURSE
1257
+ * FT2::Load::PEDANTIC
1258
+ *
1259
+ * Examples:
1260
+ * face.load_glyph 5, FT2::Load::DEFAULT
1261
+ *
1262
+ */
1263
+ static VALUE ft_face_load_glyph(VALUE self, VALUE glyph_index, VALUE flags) {
1264
+ FT_Face *face;
1265
+ FT_Error err;
1266
+
1267
+ Data_Get_Struct(self, FT_Face, face);
1268
+ if (flags == Qnil)
1269
+ flags = INT2FIX(FT_LOAD_DEFAULT);
1270
+
1271
+ err = FT_Load_Glyph(*face, NUM2INT(glyph_index), NUM2INT(flags));
1272
+ if (err != FT_Err_Ok)
1273
+ handle_error(err);
1274
+
1275
+ return self;
1276
+ }
1277
+
1278
+ /*
1279
+ * Load a glyph at a given size into a glyph slot of a FT2::Face object.
1280
+ *
1281
+ * Description:
1282
+ * Load a glyph at a given size into a glyph slot of a FT2::Face
1283
+ * object according to its character code.
1284
+ *
1285
+ * char_code: The glyph's character code, according to the current
1286
+ * charmap used in the FT2::Face object.
1287
+ * load_flags: A flag indicating what to load for this glyph. The
1288
+ * FT2::Load::XXXX constants can be used to control the
1289
+ * glyph loading process (e.g., whether the outline should
1290
+ * be scaled, whether to load bitmaps or not, whether to
1291
+ * hint the outline, etc).
1292
+ *
1293
+ * Note:
1294
+ * If the face has no current charmap, or if the character code is not
1295
+ * defined in the charmap, this function will return an error.
1296
+ *
1297
+ * If the glyph image is not a bitmap, and if the bit flag
1298
+ * FT2::Load::IGNORE_TRANSFORM is unset, the glyph image will be
1299
+ * transformed with the information passed to a previous call to
1300
+ * FT2::Face#set_transform
1301
+ *
1302
+ * Note that this also transforms the `face.glyph.advance' field, but
1303
+ * not the values in `face.glyph.metrics'.
1304
+ *
1305
+ * Load Flags:
1306
+ * FT2::Load::DEFAULT
1307
+ * FT2::Load::RENDER
1308
+ * FT2::Load::MONOCHROME
1309
+ * FT2::Load::LINEAR_DESIGN
1310
+ * FT2::Load::NO_SCALE
1311
+ * FT2::Load::NO_HINTING
1312
+ * FT2::Load::NO_BITMAP
1313
+ * FT2::Load::CROP_BITMAP
1314
+ * FT2::Load::VERTICAL_LAYOUT
1315
+ * FT2::Load::IGNORE_TRANSFORM
1316
+ * FT2::Load::IGNORE_GLOBAL_ADVANCE_WIDTH
1317
+ * FT2::Load::FORCE_AUTOHINT
1318
+ * FT2::Load::NO_RECURSE
1319
+ * FT2::Load::PEDANTIC
1320
+ *
1321
+ * Examples:
1322
+ * face.load_char 5, FT2::Load::DEFAULT
1323
+ *
1324
+ */
1325
+ static VALUE ft_face_load_char(VALUE self, VALUE char_code, VALUE flags) {
1326
+ FT_Face *face;
1327
+ FT_Error err;
1328
+ Data_Get_Struct(self, FT_Face, face);
1329
+ err = FT_Load_Char(*face, NUM2INT(char_code), NUM2INT(flags));
1330
+ if (err != FT_Err_Ok)
1331
+ handle_error(err);
1332
+ return self;
1333
+ }
1334
+
1335
+ /*
1336
+ * Get the glyph index of a character code.
1337
+ *
1338
+ * Note:
1339
+ * This function uses a charmap object in order to do the translation.
1340
+ *
1341
+ * FreeType computes its own glyph indices which are not necessarily
1342
+ * the same as used in the font in case the font is based on glyph
1343
+ * indices. Reason for this behaviour is to assure that index 0 is
1344
+ * never used, representing the missing glyph.
1345
+ *
1346
+ * A return value of 0 means `undefined character code'.
1347
+ *
1348
+ * Examples:
1349
+ * index = face.char_index 65
1350
+ * puts 'undefined character code' if index == 0
1351
+ *
1352
+ */
1353
+ static VALUE ft_face_char_index(VALUE self, VALUE char_code) {
1354
+ FT_Face *face;
1355
+ Data_Get_Struct(self, FT_Face, face);
1356
+ return INT2FIX(FT_Get_Char_Index(*face, NUM2INT(char_code)));
1357
+ }
1358
+
1359
+ /*
1360
+ * Get the glyph index of a given glyph name.
1361
+ *
1362
+ * Note:
1363
+ * This method uses driver specific objects to do the translation.
1364
+ *
1365
+ * A return value of 0 means `undefined character code'.
1366
+ *
1367
+ * Examples:
1368
+ * index = face.name_index glyph_name
1369
+ *
1370
+ */
1371
+ static VALUE ft_face_name_index(VALUE self, VALUE glyph_name) {
1372
+ FT_Face *face;
1373
+ Data_Get_Struct(self, FT_Face, face);
1374
+ return INT2FIX(FT_Get_Name_Index(*face, RSTRING(glyph_name)->ptr));
1375
+ }
1376
+
1377
+ /*
1378
+ * Get the kerning vector between two glyphs of a FT2::Face object.
1379
+ *
1380
+ * Description:
1381
+ * Get the kerning vector between two glyphs of a FT2::Face object.
1382
+ *
1383
+ * left_glyph: The index of the left glyph in the kern pair.
1384
+ * right_glyph: The index of the right glyph in the kern pair.
1385
+ * kern_mode: One of the FT2::KerningMode::XXXX constants. Determines
1386
+ * the scale/dimension of the returned kerning vector.
1387
+ *
1388
+ * Passing kern_mode == nil is the same as FT2::KerningMode::DEFAULT.
1389
+ *
1390
+ * Returns a kerning vector (actually a two-element array). This is in
1391
+ * font units for scalable formats, and in pixels for fixed-sizes
1392
+ * formats.
1393
+ *
1394
+ * Kerning Modes:
1395
+ * FT2::KerningMode::DEFAULT
1396
+ * FT2::KerningMode::UNFITTED
1397
+ * FT2::KerningMode::UNSCALED
1398
+ *
1399
+ * Examples:
1400
+ * left_glyph = 10
1401
+ * left_glyph = 11
1402
+ * k_v = face.kerning left_glyph, right_glyph, nil
1403
+ *
1404
+ * # another example, w/o default options
1405
+ * k_v = face.get_kerning 12, 13, FT2::KerningMode::UNFITTED
1406
+ *
1407
+ */
1408
+ static VALUE ft_face_kerning(VALUE self, VALUE left_glyph, VALUE right_glyph, VALUE kern_mode) {
1409
+ FT_Face *face;
1410
+ FT_Error err;
1411
+ FT_Vector v;
1412
+ VALUE ary;
1413
+
1414
+ Data_Get_Struct(self, FT_Face, face);
1415
+ ary = rb_ary_new();
1416
+
1417
+ if (kern_mode == Qnil)
1418
+ kern_mode = NUM2INT(ft_kerning_default);
1419
+
1420
+ err = FT_Get_Kerning(*face, NUM2INT(left_glyph), NUM2INT(right_glyph), NUM2INT(kern_mode), &v);
1421
+ if (err != FT_Err_Ok)
1422
+ handle_error(err);
1423
+
1424
+ rb_ary_push(ary, INT2FIX(v.x));
1425
+ rb_ary_push(ary, INT2FIX(v.y));
1426
+
1427
+ return ary;
1428
+ }
1429
+
1430
+ /*
1431
+ * Get the ASCII name of a glyph in a FT2::Face object.
1432
+ *
1433
+ * Note:
1434
+ * If the face doesn't provide glyph names or if the glyph index is
1435
+ * invalid, nil is returned. The glyph name is truncated if it is
1436
+ * longer than 1024 characters.
1437
+ *
1438
+ * Examples:
1439
+ * glyph_index = 45
1440
+ * glyph_name = face.glyph_name glyph_index
1441
+ *
1442
+ */
1443
+ static VALUE ft_face_glyph_name(VALUE self, VALUE glyph_index) {
1444
+ FT_Face *face;
1445
+ FT_Error err;
1446
+ char buf[1024];
1447
+ Data_Get_Struct(self, FT_Face, face);
1448
+ err = FT_Get_Glyph_Name(*face, NUM2INT(glyph_index), buf, sizeof(buf));
1449
+ if (err != FT_Err_Ok)
1450
+ handle_error(err);
1451
+
1452
+ return (buf && strlen(buf)) ? rb_str_new2(buf) : Qnil;
1453
+ }
1454
+
1455
+ /*
1456
+ * Get the ASCII Postscript name of a FT2::Face object.
1457
+ *
1458
+ * Note:
1459
+ * This should only work with Postscript and TrueType fonts. If the
1460
+ * PostScript name is un-avaialble, nil is returned.
1461
+ *
1462
+ * Examples:
1463
+ * ps_name = face.postscript_name
1464
+ * name = face.name
1465
+ *
1466
+ */
1467
+ static VALUE ft_face_ps_name(VALUE self) {
1468
+ FT_Face *face;
1469
+ const char *str;
1470
+ Data_Get_Struct(self, FT_Face, face);
1471
+
1472
+ if ((str = FT_Get_Postscript_Name(*face)) != NULL)
1473
+ return rb_str_new2(str);
1474
+ else
1475
+ return Qnil;
1476
+ }
1477
+
1478
+ /*
1479
+ * Select a FT2::Face object's charmap by its encoding tag.
1480
+ *
1481
+ * Encoding Tags:
1482
+ * FT2::Encoding::NONE
1483
+ * FT2::Encoding::SYMBOL
1484
+ * FT2::Encoding::UNICODE
1485
+ * FT2::Encoding::LATIN_1
1486
+ *
1487
+ * Examples:
1488
+ * face.select_charmap FT2::Encoding::UNICODE
1489
+ *
1490
+ */
1491
+ static VALUE ft_face_select_charmap(VALUE self, VALUE encoding) {
1492
+ FT_Face *face;
1493
+ FT_Error err;
1494
+ Data_Get_Struct(self, FT_Face, face);
1495
+ err = FT_Select_Charmap(*face, NUM2INT(encoding));
1496
+ if (err != FT_Err_Ok)
1497
+ handle_error(err);
1498
+ return self;
1499
+ }
1500
+
1501
+ /*
1502
+ * Select the FT2::Face object's charmap for character code to glyph index decoding.
1503
+ *
1504
+ * Examples:
1505
+ * charmap = face.charmaps[0]
1506
+ * face.set_charmap charmap
1507
+ *
1508
+ * charmap = face.charmaps[0]
1509
+ * face.charmap = charmap
1510
+ *
1511
+ */
1512
+ static VALUE ft_face_set_charmap(VALUE self, VALUE charmap) {
1513
+ FT_Face *face;
1514
+ FT_CharMap *cm;
1515
+ FT_Error err;
1516
+ Data_Get_Struct(self, FT_Face, face);
1517
+ Data_Get_Struct(charmap, FT_CharMap, cm);
1518
+ err = FT_Set_Charmap(*face, *cm);
1519
+ if (err != FT_Err_Ok)
1520
+ handle_error(err);
1521
+ return self;
1522
+ }
1523
+
1524
+ /*
1525
+ * Return the first character code of the selected charmap and corresponding glyph index of a FT2::Face object.
1526
+ *
1527
+ * Note:
1528
+ * Using this with FT2::Face#next_char will allow you to iterate
1529
+ * through the charmap => glyph index mapping for the selected
1530
+ * charmap.
1531
+ *
1532
+ * You should probably use the method FT2::Face#current_charmap
1533
+ * instead.
1534
+ *
1535
+ * Examples:
1536
+ * c_code, g_idx = face.first_char
1537
+ * while g_idx != 0
1538
+ * puts "#{c_code} => #{g_idx}"
1539
+ * c_code, g_idx = face.next_char
1540
+ * end
1541
+ *
1542
+ */
1543
+ static VALUE ft_face_first_char(VALUE self) {
1544
+ FT_Face *face;
1545
+ VALUE ary;
1546
+ FT_ULong char_code;
1547
+ FT_UInt glyph_index;
1548
+ Data_Get_Struct(self, FT_Face, face);
1549
+ ary = rb_ary_new();
1550
+
1551
+ char_code = FT_Get_First_Char(*face, &glyph_index);
1552
+ rb_ary_push(ary, UINT2NUM(char_code));
1553
+ rb_ary_push(ary, UINT2NUM(glyph_index));
1554
+
1555
+ return ary;
1556
+ }
1557
+
1558
+ /*
1559
+ * Return the next character code of the selected charmap and corresponding glyph index of a FT2::Face object.
1560
+ *
1561
+ * Note:
1562
+ * Using this with FT2::Face#first_char will allow you to iterate
1563
+ * through the charmap => glyph index mapping for the selected
1564
+ * charmap. Returns 0 if the charmap is empty, or if there are no
1565
+ * more codes in the charmap.
1566
+ *
1567
+ * You should probably use the method FT2::Face#current_charmap
1568
+ * instead.
1569
+ *
1570
+ * Examples:
1571
+ * c_code, g_idx = face.first_char
1572
+ * while g_idx != 0
1573
+ * puts "#{c_code} => #{g_idx}"
1574
+ * c_code, g_idx = face.next_char
1575
+ * end
1576
+ *
1577
+ */
1578
+ static VALUE ft_face_next_char(VALUE self, VALUE char_code) {
1579
+ FT_Face *face;
1580
+ VALUE ary;
1581
+ FT_ULong ret_char_code;
1582
+ FT_UInt glyph_index;
1583
+ Data_Get_Struct(self, FT_Face, face);
1584
+ ary = rb_ary_new();
1585
+
1586
+ ret_char_code = FT_Get_Next_Char(*face, char_code, &glyph_index);
1587
+ rb_ary_push(ary, UINT2NUM(ret_char_code));
1588
+ rb_ary_push(ary, UINT2NUM(glyph_index));
1589
+
1590
+ return ary;
1591
+ }
1592
+
1593
+ /*
1594
+ * Return the character code to glyph index map of the selected charmap of a FT2::Face object.
1595
+ *
1596
+ * Note:
1597
+ * Returns nil if the selected charmap is empty.
1598
+ *
1599
+ * Examples:
1600
+ * mapping = face.charmap
1601
+ *
1602
+ */
1603
+ static VALUE ft_face_current_charmap(VALUE self) {
1604
+ FT_Face *face;
1605
+ FT_ULong c_code;
1606
+ FT_UInt g_idx;
1607
+ VALUE rtn;
1608
+
1609
+ rtn = Qnil;
1610
+ Data_Get_Struct(self, FT_Face, face);
1611
+
1612
+ c_code = FT_Get_First_Char(*face, &g_idx);
1613
+ if (!g_idx || !c_code)
1614
+ return rtn;
1615
+
1616
+ rtn = rb_hash_new();
1617
+ while (c_code != 0) {
1618
+ rb_hash_aset(rtn, UINT2NUM(c_code), UINT2NUM(g_idx));
1619
+ c_code = FT_Get_Next_Char(*face, c_code, &g_idx);
1620
+ }
1621
+
1622
+ return rtn;
1623
+ }
1624
+
1625
+
1626
+ /*****************************/
1627
+ /* FT2::GlyphMetrics methods */
1628
+ /*****************************/
1629
+
1630
+ /*
1631
+ * Constructor for FT2::GlyphMetrics
1632
+ *
1633
+ * This method is currently empty. You should never call this method
1634
+ * directly unless you're instantiating a derived class (ie, you know
1635
+ * what you're doing).
1636
+ *
1637
+ */
1638
+ static VALUE ft_glyphmetrics_init(VALUE self) {
1639
+ return self;
1640
+ }
1641
+
1642
+ /*
1643
+ * Get the glyph's width.
1644
+ *
1645
+ * Note:
1646
+ * Values are expressed in 26.6 fractional pixel format or in font
1647
+ * units, depending on context.
1648
+ *
1649
+ * Aliases:
1650
+ * FT2::GlyphMetrics#w
1651
+ *
1652
+ * Examples:
1653
+ * w = slot.metrics.width
1654
+ * w = slot.metrics.w
1655
+ *
1656
+ */
1657
+ static VALUE ft_glyphmetrics_width(VALUE self) {
1658
+ FT_Glyph_Metrics *glyph;
1659
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1660
+ return INT2NUM(glyph->width);
1661
+ }
1662
+
1663
+ /*
1664
+ * Get the glyph's height.
1665
+ *
1666
+ * Note:
1667
+ * Values are expressed in 26.6 fractional pixel format or in font
1668
+ * units, depending on context.
1669
+ *
1670
+ * Aliases:
1671
+ * FT2::GlyphMetrics#h
1672
+ *
1673
+ * Examples:
1674
+ * h = slot.metrics.height
1675
+ * h = slot.metrics.h
1676
+ *
1677
+ */
1678
+ static VALUE ft_glyphmetrics_height(VALUE self) {
1679
+ FT_Glyph_Metrics *glyph;
1680
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1681
+ return INT2NUM(glyph->height);
1682
+ }
1683
+
1684
+ /*
1685
+ * Get the glyph's left side bearing in horizontal layouts.
1686
+ *
1687
+ * Note:
1688
+ * Values are expressed in 26.6 fractional pixel format or in font
1689
+ * units, depending on context.
1690
+ *
1691
+ * Aliases:
1692
+ * FT2::GlyphMetrics#horiBearingX
1693
+ * FT2::GlyphMetrics#h_bear_x
1694
+ * FT2::GlyphMetrics#hbx
1695
+ *
1696
+ * Examples:
1697
+ * hbx = slot.metrics.h_bearing_x
1698
+ * hbx = slot.metrics.horiBearingX
1699
+ * hbx = slot.metrics.h_bear_x
1700
+ * hbx = slot.metrics.hbx
1701
+ *
1702
+ */
1703
+ static VALUE ft_glyphmetrics_h_bear_x(VALUE self) {
1704
+ FT_Glyph_Metrics *glyph;
1705
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1706
+ return INT2NUM(glyph->horiBearingX);
1707
+ }
1708
+
1709
+ /*
1710
+ * Get the glyph's top side bearing in horizontal layouts.
1711
+ *
1712
+ * Note:
1713
+ * Values are expressed in 26.6 fractional pixel format or in font
1714
+ * units, depending on context.
1715
+ *
1716
+ * Aliases:
1717
+ * FT2::GlyphMetrics#horiBearingY
1718
+ * FT2::GlyphMetrics#h_bear_y
1719
+ * FT2::GlyphMetrics#hby
1720
+ *
1721
+ * Examples:
1722
+ * hby = slot.metrics.h_bearing_y
1723
+ * hby = slot.metrics.horiBearingY
1724
+ * hby = slot.metrics.h_bear_y
1725
+ * hby = slot.metrics.hby
1726
+ *
1727
+ */
1728
+ static VALUE ft_glyphmetrics_h_bear_y(VALUE self) {
1729
+ FT_Glyph_Metrics *glyph;
1730
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1731
+ return INT2NUM(glyph->horiBearingY);
1732
+ }
1733
+
1734
+ /*
1735
+ * Get the glyph's advance width for horizontal layouts.
1736
+ *
1737
+ * Note:
1738
+ * Values are expressed in 26.6 fractional pixel format or in font
1739
+ * units, depending on context.
1740
+ *
1741
+ * Aliases:
1742
+ * FT2::GlyphMetrics#horiAdvance
1743
+ * FT2::GlyphMetrics#ha
1744
+ *
1745
+ * Examples:
1746
+ * ha = slot.metrics.h_advance
1747
+ * ha = slot.metrics.horiAdvance
1748
+ * ha = slot.metrics.ha
1749
+ *
1750
+ */
1751
+ static VALUE ft_glyphmetrics_h_advance(VALUE self) {
1752
+ FT_Glyph_Metrics *glyph;
1753
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1754
+ return INT2NUM(glyph->horiAdvance);
1755
+ }
1756
+
1757
+ /*
1758
+ * Get the glyph's left side bearing in vertical layouts.
1759
+ *
1760
+ * Note:
1761
+ * Values are expressed in 26.6 fractional pixel format or in font
1762
+ * units, depending on context.
1763
+ *
1764
+ * Aliases:
1765
+ * FT2::GlyphMetrics#vertBearingX
1766
+ * FT2::GlyphMetrics#v_bear_x
1767
+ * FT2::GlyphMetrics#vbx
1768
+ *
1769
+ * Examples:
1770
+ * vbx = slot.metrics.v_bearing_x
1771
+ * vbx = slot.metrics.vertBearingX
1772
+ * vbx = slot.metrics.v_bear_x
1773
+ * vbx = slot.metrics.vbx
1774
+ *
1775
+ */
1776
+ static VALUE ft_glyphmetrics_v_bear_x(VALUE self) {
1777
+ FT_Glyph_Metrics *glyph;
1778
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1779
+ return INT2NUM(glyph->vertBearingX);
1780
+ }
1781
+
1782
+ /*
1783
+ * Get the glyph's top side bearing in vertical layouts.
1784
+ *
1785
+ * Note:
1786
+ * Values are expressed in 26.6 fractional pixel format or in font
1787
+ * units, depending on context.
1788
+ *
1789
+ * Aliases:
1790
+ * FT2::GlyphMetrics#vertBearingY
1791
+ * FT2::GlyphMetrics#v_bear_y
1792
+ * FT2::GlyphMetrics#vby
1793
+ *
1794
+ * Examples:
1795
+ * vby = slot.metrics.v_bearing_y
1796
+ * vby = slot.metrics.vertBearingY
1797
+ * vby = slot.metrics.v_bear_y
1798
+ * vby = slot.metrics.vby
1799
+ *
1800
+ */
1801
+ static VALUE ft_glyphmetrics_v_bear_y(VALUE self) {
1802
+ FT_Glyph_Metrics *glyph;
1803
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1804
+ return INT2NUM(glyph->vertBearingY);
1805
+ }
1806
+
1807
+ /*
1808
+ * Get the glyph's advance width for vertical layouts.
1809
+ *
1810
+ * Note:
1811
+ * Values are expressed in 26.6 fractional pixel format or in font
1812
+ * units, depending on context.
1813
+ *
1814
+ * Aliases:
1815
+ * FT2::GlyphMetrics#vertAdvance
1816
+ * FT2::GlyphMetrics#va
1817
+ *
1818
+ * Examples:
1819
+ * va = slot.metrics.v_advance
1820
+ * va = slot.metrics.vertAdvance
1821
+ * va = slot.metrics.va
1822
+ *
1823
+ */
1824
+ static VALUE ft_glyphmetrics_v_advance(VALUE self) {
1825
+ FT_Glyph_Metrics *glyph;
1826
+ Data_Get_Struct(self, FT_Glyph_Metrics, glyph);
1827
+ return INT2NUM(glyph->vertAdvance);
1828
+ }
1829
+
1830
+
1831
+ /**************************/
1832
+ /* FT2::GlyphSlot methods */
1833
+ /**************************/
1834
+
1835
+ /*
1836
+ * Constructor for FT2::GlyphSlot class.
1837
+ *
1838
+ * This method is currently empty. You should never call this method
1839
+ * directly unless you're instantiating a derived class (ie, you know
1840
+ * what you're doing).
1841
+ *
1842
+ */
1843
+ static VALUE ft_glyphslot_init(VALUE self) {
1844
+ return self;
1845
+ }
1846
+
1847
+ /*
1848
+ * Convert a FT2::GlyphSlot object to a bitmap.
1849
+ *
1850
+ * Description:
1851
+ * Converts a given FT2::GlyphSlot to a bitmap. It does so by
1852
+ * $inspecting the FT2::GlyphSlot format, finding the relevant
1853
+ * renderer, and invoking it.
1854
+ *
1855
+ * render_mode: This is the render mode used to render the glyph image
1856
+ * into a bitmap. See below for a list of possible
1857
+ * values. If render_mode is nil, then it defaults to
1858
+ * FT2::RenderMode::NORMAL.
1859
+ *
1860
+ * Aliases:
1861
+ * FT2::GlyphSlot#render_glyph
1862
+ *
1863
+ * Render Modes:
1864
+ * FT2::RenderMode::NORMAL
1865
+ * FT2::RenderMode::MONO
1866
+ *
1867
+ * Examples:
1868
+ * slot.render FT2::RenderMode::NORMAL
1869
+ *
1870
+ */
1871
+ static VALUE ft_glyphslot_render(VALUE self, VALUE render_mode) {
1872
+ FT_Error err;
1873
+ FT_GlyphSlot *glyph;
1874
+
1875
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
1876
+ if (render_mode == Qnil)
1877
+ render_mode = INT2FIX(ft_render_mode_normal);
1878
+
1879
+ err = FT_Render_Glyph(*glyph, NUM2INT(render_mode));
1880
+ if (err != FT_Err_Ok)
1881
+ handle_error(err);
1882
+
1883
+ return self;
1884
+ }
1885
+
1886
+ static VALUE ft_glyphslot_glyph(VALUE self) {
1887
+ FT_Error err;
1888
+ FT_GlyphSlot *slot;
1889
+ FT_Glyph *glyph;
1890
+
1891
+ glyph = malloc(sizeof(FT_Glyph));
1892
+ Data_Get_Struct(self, FT_GlyphSlot, slot);
1893
+ err = FT_Get_Glyph(*slot, glyph);
1894
+ if (err != FT_Err_Ok) {
1895
+ free(glyph);
1896
+ handle_error(err);
1897
+ }
1898
+
1899
+ return Data_Wrap_Struct(cGlyph, 0, glyph_free, glyph);
1900
+ }
1901
+
1902
+ /*
1903
+ * Get the FT2::Library instance this FT2::GlyphSlot object belongs to.
1904
+ *
1905
+ * Examples:
1906
+ * lib = slot.library
1907
+ *
1908
+ */
1909
+ static VALUE ft_glyphslot_library(VALUE self) {
1910
+ FT_GlyphSlot *glyph;
1911
+ FT_Library *lib;
1912
+
1913
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
1914
+ lib = malloc(sizeof(FT_Library));
1915
+ *lib = (*glyph)->library;
1916
+
1917
+ return Data_Wrap_Struct(cLibrary, 0, dont_free, lib);
1918
+ }
1919
+
1920
+ /*
1921
+ * Get the FT2::Face object this FT2::GlyphSlot object belongs to.
1922
+ *
1923
+ * Examples:
1924
+ * face = slot.face
1925
+ *
1926
+ */
1927
+ static VALUE ft_glyphslot_face(VALUE self) {
1928
+ FT_GlyphSlot *glyph;
1929
+ FT_Face *face;
1930
+
1931
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
1932
+ face = malloc(sizeof(FT_Face));
1933
+ *face = (*glyph)->face;
1934
+
1935
+ /* do we really want to dont_free() cb here? */
1936
+ return Data_Wrap_Struct(cFace, 0, dont_free, face);
1937
+ }
1938
+
1939
+ /*
1940
+ * Get the next FT2::GlyphSlot object.
1941
+ *
1942
+ * Description:
1943
+ * In some cases (like some font tools), several FT2::GlyphSlot s per
1944
+ * FT2::Face object can be a good thing. As this is rare, the
1945
+ * FT2::GlyphSlot s are listed through a direct, single-linked list
1946
+ * using its `next' field.
1947
+ *
1948
+ * Examples:
1949
+ * next_slot = slot.next
1950
+ *
1951
+ */
1952
+ static VALUE ft_glyphslot_next(VALUE self) {
1953
+ FT_GlyphSlot *glyph;
1954
+ FT_GlyphSlot *next;
1955
+
1956
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
1957
+ next = malloc(sizeof(FT_GlyphSlot));
1958
+ *next = (*glyph)->next;
1959
+
1960
+ /* do we really want to dont_free() cb here? */
1961
+ return Data_Wrap_Struct(cGlyphSlot, 0, dont_free, next);
1962
+ }
1963
+
1964
+ /*
1965
+ * Get the flags of a FT2::GlyphSlot.
1966
+ *
1967
+ * Examples:
1968
+ * flags = slot.flags
1969
+ *
1970
+ */
1971
+ static VALUE ft_glyphslot_flags(VALUE self) {
1972
+ FT_GlyphSlot *glyph;
1973
+
1974
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
1975
+ return INT2NUM(0); //XXX: we don't use this, and it was causing a compiler error
1976
+ }
1977
+
1978
+ /*
1979
+ * Get the FT2::GlyphMetrics of a FT2::GlyphSlot object.
1980
+ *
1981
+ * Examples:
1982
+ * metrics = slot.metrics
1983
+ *
1984
+ */
1985
+ static VALUE ft_glyphslot_metrics(VALUE self) {
1986
+ FT_GlyphSlot *glyph;
1987
+ FT_Glyph_Metrics *metrics;
1988
+
1989
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
1990
+ metrics = malloc(sizeof(FT_Glyph_Metrics));
1991
+ *metrics = (*glyph)->metrics;
1992
+
1993
+ return Data_Wrap_Struct(cGlyphMetrics, 0, dont_free, metrics);
1994
+ }
1995
+
1996
+ /*
1997
+ * Get the linearly scaled horizontal advance width of a FT2::GlyphSlot object.
1998
+ *
1999
+ * Description:
2000
+ * For scalable formats only, this field holds the linearly scaled
2001
+ * horizontal advance width for the FT2:GlyphSlot (i.e. the scaled and
2002
+ * unhinted value of the hori advance). This can be important to
2003
+ * perform correct WYSIWYG layout.
2004
+ *
2005
+ * Note:
2006
+ * The return value is expressed by default in 16.16 pixels. However,
2007
+ * when the FT2::GlyphSlot is loaded with the FT2::Load::LINEAR_DESIGN
2008
+ * flag, this field contains simply the value of the advance in
2009
+ * original font units.
2010
+ *
2011
+ * Aliases:
2012
+ * FT2::GlyphSlot#linearHoriAdvance
2013
+ * FT2::GlyphSlot#h_adv
2014
+ * FT2::GlyphSlot#ha
2015
+ *
2016
+ * Examples:
2017
+ * h_adv = slot.h_advance
2018
+ *
2019
+ */
2020
+ static VALUE ft_glyphslot_h_advance(VALUE self) {
2021
+ FT_GlyphSlot *glyph;
2022
+
2023
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2024
+ return rb_float_new(FTFIX2DBL((*glyph)->linearHoriAdvance));
2025
+ }
2026
+
2027
+ /*
2028
+ * Get the linearly scaled vertical advance height of a FT2::GlyphSlot object.
2029
+ *
2030
+ * Description:
2031
+ * For scalable formats only, this field holds the linearly scaled
2032
+ * vertical advance height for the FT2:GlyphSlot (i.e. the scaled and
2033
+ * unhinted value of the hori advance). This can be important to
2034
+ * perform correct WYSIWYG layout.
2035
+ *
2036
+ * Note:
2037
+ * The return value is expressed by default in 16.16 pixels. However,
2038
+ * when the FT2::GlyphSlot is loaded with the FT2::Load::LINEAR_DESIGN
2039
+ * flag, this field contains simply the value of the advance in
2040
+ * original font units.
2041
+ *
2042
+ * Aliases:
2043
+ * FT2::GlyphSlot#linearVertAdvance
2044
+ * FT2::GlyphSlot#v_adv
2045
+ * FT2::GlyphSlot#va
2046
+ *
2047
+ * Examples:
2048
+ * v_adv = slot.v_advance
2049
+ *
2050
+ */
2051
+ static VALUE ft_glyphslot_v_advance(VALUE self) {
2052
+ FT_GlyphSlot *glyph;
2053
+
2054
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2055
+ return rb_float_new(ft_fixed_to_double((*glyph)->linearVertAdvance));
2056
+ }
2057
+
2058
+ /*
2059
+ * Get the transformed advance width for a FT2::GlyphSlot object.
2060
+ *
2061
+ * Examples:
2062
+ * adv = slot.advance
2063
+ *
2064
+ */
2065
+ static VALUE ft_glyphslot_advance(VALUE self) {
2066
+ FT_GlyphSlot *glyph;
2067
+ VALUE ary;
2068
+
2069
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2070
+ ary = rb_ary_new();
2071
+
2072
+ rb_ary_push(ary, INT2NUM((*glyph)->advance.x));
2073
+ rb_ary_push(ary, INT2NUM((*glyph)->advance.y));
2074
+ return ary;
2075
+ }
2076
+
2077
+ /*
2078
+ * Get the format of a FT2::GlyphSlot object.
2079
+ *
2080
+ * Glyph Formats:
2081
+ * FT2::GlyphFormat::COMPOSITE
2082
+ * FT2::GlyphFormat::BITMAP
2083
+ * FT2::GlyphFormat::OUTLINE
2084
+ * FT2::GlyphFormat::PLOTTER
2085
+ *
2086
+ * Examples:
2087
+ * fmt = slot.format
2088
+ *
2089
+ */
2090
+ static VALUE ft_glyphslot_format(VALUE self) {
2091
+ FT_GlyphSlot *glyph;
2092
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2093
+ return INT2NUM((*glyph)->format);
2094
+ }
2095
+
2096
+ /*
2097
+ * Get the bitmap of a bitmap format FT2::GlyphSlot object.
2098
+ *
2099
+ * Examples:
2100
+ * bmap = slot.bitmap
2101
+ *
2102
+ */
2103
+ static VALUE ft_glyphslot_bitmap(VALUE self) {
2104
+ FT_GlyphSlot *glyph;
2105
+ FT_Bitmap *bitmap;
2106
+
2107
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2108
+ bitmap = malloc(sizeof(FT_Bitmap));
2109
+ *bitmap = (*glyph)->bitmap;
2110
+
2111
+ return Data_Wrap_Struct(cBitmap, 0, dont_free, bitmap);
2112
+ }
2113
+
2114
+ /*
2115
+ * Get the left bearing (in pixels) of a bitmap format FT2::GlyphSlot object.
2116
+ *
2117
+ * Note:
2118
+ * Only valid if the format is FT2::GlyphFormat::BITMAP.
2119
+ *
2120
+ * Examples:
2121
+ * left = slot.bitmap_left
2122
+ *
2123
+ */
2124
+ static VALUE ft_glyphslot_bitmap_left(VALUE self) {
2125
+ FT_GlyphSlot *glyph;
2126
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2127
+ return INT2NUM((*glyph)->bitmap_left);
2128
+ }
2129
+
2130
+ /*
2131
+ * Get the top bearing (in pixels) of a bitmap format FT2::GlyphSlot object.
2132
+ *
2133
+ * Note:
2134
+ * Only valid if the format is FT2::GlyphFormat::BITMAP. The value
2135
+ * returned is the distance from the baseline to the topmost glyph
2136
+ * scanline, upwards y-coordinates being positive.
2137
+ *
2138
+ * Examples:
2139
+ * top = slot.bitmap_top
2140
+ *
2141
+ */
2142
+ static VALUE ft_glyphslot_bitmap_top(VALUE self) {
2143
+ FT_GlyphSlot *glyph;
2144
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2145
+ return INT2NUM((*glyph)->bitmap_top);
2146
+ }
2147
+
2148
+ /*
2149
+ * Get the outline of a bitmap outline format FT2::GlyphSlot object.
2150
+ *
2151
+ * Note:
2152
+ * Only valid if the format is FT2::GlyphFormat::OUTLINE.
2153
+ *
2154
+ * Examples:
2155
+ * outline = slot.outline
2156
+ *
2157
+ */
2158
+ static VALUE ft_glyphslot_outline(VALUE self) {
2159
+ FT_GlyphSlot *glyph;
2160
+ FT_Outline *outline;
2161
+
2162
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2163
+ outline = malloc(sizeof(FT_Outline));
2164
+ *outline = (*glyph)->outline;
2165
+
2166
+ return Data_Wrap_Struct(cOutline, 0, dont_free, outline);
2167
+ }
2168
+
2169
+ /*
2170
+ * Get the number of subglyphs of a FT2::GlyphSlot object.
2171
+ *
2172
+ * Note:
2173
+ * Only valid if the format is FT2::GlyphFormat::COMPOSITE.
2174
+ *
2175
+ * Examples:
2176
+ * outline = slot.outline
2177
+ *
2178
+ */
2179
+ static VALUE ft_glyphslot_num_subglyphs(VALUE self) {
2180
+ FT_GlyphSlot *glyph;
2181
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2182
+ return INT2NUM((*glyph)->num_subglyphs);
2183
+ }
2184
+
2185
+ /*
2186
+ * Get a list of subglyphs of a composite format FT2::GlyphSlot object.
2187
+ *
2188
+ * Note:
2189
+ * Only valid if the format is FT2::GlyphFormat::COMPOSITE. FIXME:
2190
+ * this method may not work correctly at the moment.
2191
+ *
2192
+ * Examples:
2193
+ * sub_glyphs = slot.subglyphs
2194
+ *
2195
+ */
2196
+ static VALUE ft_glyphslot_subglyphs(VALUE self) {
2197
+ FT_GlyphSlot *glyph;
2198
+ VALUE rtn;
2199
+ int num;
2200
+
2201
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2202
+ if ((num = (*glyph)->num_subglyphs) < 1)
2203
+ return Qnil;
2204
+
2205
+ /* FIXME: this probably doesn't work */
2206
+ rtn = rb_ary_new();
2207
+ /*
2208
+ * for (i = 0; i < num; i++)
2209
+ * rb_ary_push(rtn, Data_Wrap_Struct(cSubGlyph, 0,
2210
+ * dont_free,
2211
+ * (*glyph)->subglyphs[i]));
2212
+ */
2213
+ return rtn;
2214
+ }
2215
+
2216
+ /*
2217
+ * Get optional control data for a FT2::GlyphSlot object.
2218
+ *
2219
+ * Description:
2220
+ * Certain font drivers can also return the control data for a given
2221
+ * FT2::GlyphSlot (e.g. TrueType bytecode, Type 1 charstrings, etc.).
2222
+ * This field is a pointer to such data.
2223
+ *
2224
+ * Examples:
2225
+ * data = slot.control_data
2226
+ *
2227
+ */
2228
+ static VALUE ft_glyphslot_control_data(VALUE self) {
2229
+ FT_GlyphSlot *glyph;
2230
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2231
+ return rb_str_new((*glyph)->control_data, (*glyph)->control_len);
2232
+ }
2233
+
2234
+ /*
2235
+ * Get the length of the optional control data for a FT2::GlyphSlot object.
2236
+ *
2237
+ * Examples:
2238
+ * len = slot.control_len
2239
+ *
2240
+ */
2241
+ static VALUE ft_glyphslot_control_len(VALUE self) {
2242
+ FT_GlyphSlot *glyph;
2243
+ Data_Get_Struct(self, FT_GlyphSlot, glyph);
2244
+ return INT2NUM((*glyph)->control_len);
2245
+ }
2246
+
2247
+
2248
+ /*********************/
2249
+ /* FT2::Size methods */
2250
+ /*********************/
2251
+
2252
+ /*
2253
+ * Constructor for FT2::Size class.
2254
+ *
2255
+ * This method is currently empty. You should never call this method
2256
+ * directly unless you're instantiating a derived class (ie, you know
2257
+ * what you're doing).
2258
+ *
2259
+ */
2260
+ static VALUE ft_size_init(VALUE self) {
2261
+ return self;
2262
+ }
2263
+
2264
+ /*
2265
+ * Get the FT2::Face object this FT2::Size object is associated with.
2266
+ *
2267
+ * Examples:
2268
+ * face = size.face
2269
+ *
2270
+ */
2271
+ static VALUE ft_size_face(VALUE self) {
2272
+ FT_Size *size;
2273
+ FT_Face *face;
2274
+
2275
+ Data_Get_Struct(self, FT_Size, size);
2276
+ face = malloc(sizeof(FT_Face));
2277
+ *face = (*size)->face;
2278
+
2279
+ return Data_Wrap_Struct(cFace, 0, dont_free, face);
2280
+ }
2281
+
2282
+ /*
2283
+ * Get the FT2::SizeMetrics associated with a FT2::Size object.
2284
+ *
2285
+ * Examples:
2286
+ * s_metrics = size.metrics
2287
+ *
2288
+ */
2289
+ static VALUE ft_size_metrics(VALUE self) {
2290
+ FT_Size *size;
2291
+ FT_Size_Metrics *metrics;
2292
+
2293
+ Data_Get_Struct(self, FT_Size, size);
2294
+ metrics = malloc(sizeof(FT_Size_Metrics));
2295
+ *metrics = (*size)->metrics;
2296
+
2297
+ return Data_Wrap_Struct(cSizeMetrics, 0, dont_free, metrics);
2298
+ }
2299
+
2300
+
2301
+ /****************************/
2302
+ /* FT2::SizeMetrics methods */
2303
+ /****************************/
2304
+
2305
+ /*
2306
+ * Constructor for FT2::SizeMetrics class.
2307
+ *
2308
+ * This method is currently empty. You should never call this method
2309
+ * directly unless you're instantiating a derived class (ie, you know
2310
+ * what you're doing).
2311
+ *
2312
+ */
2313
+ static VALUE ft_size_metrics_init(VALUE self) {
2314
+ return self;
2315
+ }
2316
+
2317
+ /*
2318
+ * Get the X pixels per EM of this FT2::SizeMetrics object.
2319
+ *
2320
+ * Description:
2321
+ * x_ppem stands for the size in integer pixels of the EM square.
2322
+ * which also is the horizontal character pixel size.
2323
+ *
2324
+ * Examples:
2325
+ * x_ppem = face.size.metrics.x_ppem
2326
+ *
2327
+ */
2328
+ static VALUE ft_size_metrics_x_ppem(VALUE self) {
2329
+ FT_Size_Metrics *size_metrics;
2330
+ Data_Get_Struct(self, FT_Size_Metrics, size_metrics);
2331
+ return INT2FIX((int) (*size_metrics).x_ppem);
2332
+ }
2333
+
2334
+ /*
2335
+ * Get the Y pixels per EM of this FT2::SizeMetrics object.
2336
+ *
2337
+ * Description:
2338
+ * y_ppem stands for the size in integer pixels of the EM square.
2339
+ * which also is the vertical character pixel size.
2340
+ *
2341
+ * Examples:
2342
+ * y_ppem = face.size.metrics.y_ppem
2343
+ *
2344
+ */
2345
+ static VALUE ft_size_metrics_y_ppem(VALUE self) {
2346
+ FT_Size_Metrics *size_metrics;
2347
+ Data_Get_Struct(self, FT_Size_Metrics, size_metrics);
2348
+ return INT2FIX((int) (*size_metrics).y_ppem);
2349
+ }
2350
+
2351
+ /*
2352
+ * Get the horizontal scale of a FT2::SizeMetrics object.
2353
+ *
2354
+ * Description:
2355
+ * Scale that is used to directly scale horizontal distances from
2356
+ * design space to 1/64th of device pixels.
2357
+ *
2358
+ * Examples:
2359
+ * x_scale = face.size.metrics.x_scale
2360
+ *
2361
+ */
2362
+ static VALUE ft_size_metrics_x_scale(VALUE self) {
2363
+ FT_Size_Metrics *size_metrics;
2364
+ Data_Get_Struct(self, FT_Size_Metrics, size_metrics);
2365
+ return INT2FIX((int) (*size_metrics).x_scale);
2366
+ }
2367
+
2368
+ /*
2369
+ * Get the vertical scale of a FT2::SizeMetrics object.
2370
+ *
2371
+ * Description:
2372
+ * Scale that is used to directly scale vertical distances from
2373
+ * design space to 1/64th of device pixels.
2374
+ *
2375
+ * Examples:
2376
+ * y_scale = face.size.metrics.y_scale
2377
+ *
2378
+ */
2379
+ static VALUE ft_size_metrics_y_scale(VALUE self) {
2380
+ FT_Size_Metrics *size_metrics;
2381
+ Data_Get_Struct(self, FT_Size_Metrics, size_metrics);
2382
+ return INT2FIX((int) (*size_metrics).y_scale);
2383
+ }
2384
+
2385
+
2386
+ /**********************/
2387
+ /* FT2::Glyph methods */
2388
+ /**********************/
2389
+ static void glyph_free(void *ptr) {
2390
+ FT_Glyph glyph = *((FT_Glyph *) ptr);
2391
+ FT_Done_Glyph(glyph);
2392
+ free(ptr);
2393
+ }
2394
+
2395
+
2396
+ /*
2397
+ * Constructor for FT2::Glyph class.
2398
+ *
2399
+ * This method is currently empty. You should never call this method
2400
+ * directly unless you're instantiating a derived class (ie, you know
2401
+ * what you're doing).
2402
+ *
2403
+ */
2404
+ static VALUE ft_glyph_init(VALUE self) {
2405
+ return self;
2406
+ }
2407
+
2408
+ /*
2409
+ * Get the library of a FT2::Glyph object.
2410
+ *
2411
+ * Note:
2412
+ * Glyph objects are not owned or tracked by the library.
2413
+ *
2414
+ * Examples:
2415
+ * lib = glyph.library
2416
+ *
2417
+ */
2418
+ static VALUE ft_glyph_library(VALUE self) {
2419
+ FT_Glyph *glyph;
2420
+ Data_Get_Struct(self, FT_Glyph, glyph);
2421
+ return Data_Wrap_Struct(cLibrary, 0, dont_free, (*glyph)->library);
2422
+ }
2423
+
2424
+ /*
2425
+ * Get the FreeType2 class of a FT2::Glyph object.
2426
+ *
2427
+ * Note:
2428
+ * This is _not_ the Ruby class of the object.
2429
+ *
2430
+ * Aliases:
2431
+ * FT2::Glyph#clazz
2432
+ *
2433
+ * Examples:
2434
+ * c = glyph.class
2435
+ *
2436
+ */
2437
+ static VALUE ft_glyph_class(VALUE self) {
2438
+ FT_Glyph *glyph;
2439
+ Data_Get_Struct(self, FT_Glyph, glyph);
2440
+ return Data_Wrap_Struct(cGlyphClass, 0, dont_free, &(*glyph)->clazz);
2441
+ }
2442
+
2443
+ /*
2444
+ * Get the format of a FT2::Glyph object's image.
2445
+ *
2446
+ * Glyph Formats:
2447
+ * FT2::GlyphFormat::COMPOSITE
2448
+ * FT2::GlyphFormat::BITMAP
2449
+ * FT2::GlyphFormat::OUTLINE
2450
+ * FT2::GlyphFormat::PLOTTER
2451
+ *
2452
+ * Examples:
2453
+ * format = glyph.format
2454
+ *
2455
+ */
2456
+ static VALUE ft_glyph_format(VALUE self) {
2457
+ FT_Glyph *glyph;
2458
+ Data_Get_Struct(self, FT_Glyph, glyph);
2459
+ return INT2FIX((*glyph)->format);
2460
+ }
2461
+
2462
+ /*
2463
+ * Get the advance of a FT2::Glyph object.
2464
+ *
2465
+ * Description:
2466
+ * This vector gives the FT2::Glyph object's advance width.
2467
+ *
2468
+ * Examples:
2469
+ * advance = glyph.advance
2470
+ *
2471
+ */
2472
+ static VALUE ft_glyph_advance(VALUE self) {
2473
+ FT_Glyph *glyph;
2474
+ VALUE ary;
2475
+
2476
+ Data_Get_Struct(self, FT_Glyph, glyph);
2477
+ ary = rb_ary_new();
2478
+ rb_ary_push(ary, INT2FIX((*glyph)->advance.x));
2479
+ rb_ary_push(ary, INT2FIX((*glyph)->advance.y));
2480
+
2481
+ return ary;
2482
+ }
2483
+
2484
+ /*
2485
+ * Duplicate a FT2::Glyph object.
2486
+ *
2487
+ * Aliases:
2488
+ * FT2::Glyph#copy
2489
+ *
2490
+ * Examples:
2491
+ * new_glyph = glyph.dup
2492
+ *
2493
+ */
2494
+ static VALUE ft_glyph_dup(VALUE self) {
2495
+ FT_Error err;
2496
+ FT_Glyph *glyph, *new_glyph;
2497
+
2498
+ new_glyph = malloc(sizeof(FT_Glyph));
2499
+ Data_Get_Struct(self, FT_Glyph, glyph);
2500
+ err = FT_Glyph_Copy(*glyph, new_glyph);
2501
+ if (err != FT_Err_Ok)
2502
+ handle_error(err);
2503
+
2504
+ return Data_Wrap_Struct(cGlyph, 0, glyph_free, new_glyph);
2505
+ }
2506
+
2507
+ /*
2508
+ * Transform a FT2::Glyph object if it's format is scalable.
2509
+ *
2510
+ * Description:
2511
+ * matrix: A pointer to a 2x2 matrix to apply.
2512
+ * delta: A pointer to a 2d vector to apply. Coordinates are
2513
+ * expressed in 1/64th of a pixel.
2514
+ *
2515
+ * Note:
2516
+ * The transformation matrix is also applied to the glyph's advance
2517
+ * vector. This method returns an error if the glyph format is not
2518
+ * scalable (eg, if it's not equal to zero).
2519
+ *
2520
+ * Examples:
2521
+ * matrix = [[1, 0],
2522
+ * [0, 1]]
2523
+ * delta = [1, 1]
2524
+ * transform = glyph.transform matrix, delta
2525
+ *
2526
+ */
2527
+ static VALUE ft_glyph_transform(VALUE self, VALUE matrix_ary, VALUE delta_ary) {
2528
+ FT_Error err;
2529
+ FT_Glyph *glyph;
2530
+ FT_Matrix matrix;
2531
+ FT_Vector delta;
2532
+
2533
+ matrix.xx = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix_ary, 0), 0)));
2534
+ matrix.xy = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix_ary, 0), 1)));
2535
+ matrix.yx = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix_ary, 1), 0)));
2536
+ matrix.yy = DBL2FTFIX(NUM2DBL(rb_ary_entry(rb_ary_entry(matrix_ary, 1), 1)));
2537
+
2538
+ delta.x = NUM2INT(rb_ary_entry(delta_ary, 0));
2539
+ delta.y = NUM2INT(rb_ary_entry(delta_ary, 1));
2540
+
2541
+ Data_Get_Struct(self, FT_Glyph, glyph);
2542
+ err = FT_Glyph_Transform(*glyph, &matrix, &delta);
2543
+ if (err != FT_Err_Ok)
2544
+ handle_error(err);
2545
+
2546
+ return self;
2547
+ }
2548
+
2549
+ /*
2550
+ * Get the control box of a FT2::Glyph object.
2551
+ *
2552
+ * Description:
2553
+ * Returns a FT2::Glyph object's `control box'. The control box
2554
+ * encloses all the outline's points, including Bezier control points.
2555
+ * Though it coincides with the exact bounding box for most FT2::Glyph
2556
+ * objects, it can be slightly larger in some situations (like when
2557
+ * rotating an outline which contains Bezier outside arcs).
2558
+ *
2559
+ * Computing the control box is very fast, while getting the bounding
2560
+ * box can take much more time as it needs to walk over all segments
2561
+ * and arcs in the outline. To get the latter, you can use the
2562
+ * `ftbbox' component which is dedicated to this single task.
2563
+ *
2564
+ * Notes:
2565
+ * Coordinates are relative to the FT2::Glyph object's origin, using
2566
+ * the Y-upwards convention.
2567
+ *
2568
+ * If the FT2::Glyph object has been loaded with FT2::Load::NO_SCALE,
2569
+ * `bbox_mode' must be set to FT2::GlyphBBox::UNSCALED to get unscaled
2570
+ * font units.
2571
+ *
2572
+ * If `bbox_mode' is set to FT2::GlyphBBox::SUBPIXELS the
2573
+ * bbox coordinates are returned in 26.6 pixels (i.e. 1/64th of
2574
+ * pixels).
2575
+ *
2576
+ * Note that the maximum coordinates are exclusive, which means that
2577
+ * one can compute the width and height of the FT2::Glyph object image
2578
+ * (be it in integer or 26.6 pixels) as:
2579
+ *
2580
+ * width = bbox.xMax - bbox.xMin; height = bbox.yMax - bbox.yMin;
2581
+ *
2582
+ * Note also that for 26.6 coordinates, if `bbox_mode' is set to
2583
+ * FT2::GlyphBBox::GRIDFIT, the coordinates will also be
2584
+ * grid-fitted, which corresponds to:
2585
+ *
2586
+ * bbox.xMin = FLOOR(bbox.xMin); bbox.yMin = FLOOR(bbox.yMin);
2587
+ * bbox.xMax = CEILING(bbox.xMax); bbox.yMax = CEILING(bbox.yMax);
2588
+ *
2589
+ * To get the bbox in pixel coordinates, set `bbox_mode' to
2590
+ * FT2::GlyphBBox::TRUNCATE.
2591
+ *
2592
+ * To get the bbox in grid-fitted pixel coordinates, set `bbox_mode'
2593
+ * to FT2::GlyphBBox::PIXELS.
2594
+ *
2595
+ * The default value for `bbox_mode' is FT2::GlyphBBox::PIXELS.
2596
+ *
2597
+ * Aliases:
2598
+ * FT2::Glyph#control_box
2599
+ *
2600
+ * Examples:
2601
+ * bbox_mode = FT2::GlyphBBox::PIXELS
2602
+ * x_min, y_min, x_max, y_max = glyph.cbox bbox_mode
2603
+ *
2604
+ */
2605
+ static VALUE ft_glyph_cbox(VALUE self, VALUE bbox_mode) {
2606
+ FT_Glyph *glyph;
2607
+ FT_BBox bbox;
2608
+ VALUE ary;
2609
+
2610
+ Data_Get_Struct(self, FT_Glyph, glyph);
2611
+ FT_Glyph_Get_CBox(*glyph, FIX2INT(bbox_mode), &bbox);
2612
+
2613
+ ary = rb_ary_new();
2614
+ rb_ary_push(ary, INT2FIX(bbox.xMin));
2615
+ rb_ary_push(ary, INT2FIX(bbox.yMin));
2616
+ rb_ary_push(ary, INT2FIX(bbox.xMax));
2617
+ rb_ary_push(ary, INT2FIX(bbox.yMax));
2618
+
2619
+ return ary;
2620
+ }
2621
+
2622
+ /*
2623
+ * Render a FT2::Glyph object as a FT2::BitmapGlyph object.
2624
+ *
2625
+ * Description:
2626
+ * Converts a FT2::Glyph object to a FT2::BitmapGlyph object.
2627
+ *
2628
+ * render_mode: A set of bit flags that describe how the data is.
2629
+ * origin: A vector used to translate the glyph image before
2630
+ * rendering. Can be nil (if no translation). The
2631
+ * origin is expressed in 26.6 pixels.
2632
+ * destroy: A boolean that indicates that the original glyph
2633
+ * image should be destroyed by this function. It is
2634
+ * never destroyed in case of error.
2635
+ *
2636
+ * Aliases:
2637
+ * FT2::Glyph#to_bitmap
2638
+ *
2639
+ * Examples:
2640
+ * glyph_to_bmap = glyph.glyph_to_bmap
2641
+ *
2642
+ */
2643
+ static VALUE ft_glyph_to_bmap(VALUE self, VALUE render_mode, VALUE origin, VALUE destroy) {
2644
+ FT_Error err;
2645
+ FT_Glyph *glyph;
2646
+ FT_Vector v;
2647
+ FT_Bool d;
2648
+
2649
+ Data_Get_Struct(self, FT_Glyph, glyph);
2650
+ v.x = NUM2INT(rb_ary_entry(origin, 0));
2651
+ v.y = NUM2INT(rb_ary_entry(origin, 1));
2652
+ d = (destroy != Qnil) ? 1 : 0;
2653
+
2654
+ err = FT_Glyph_To_Bitmap(glyph, FIX2INT(render_mode), &v, d);
2655
+ if (err != FT_Err_Ok)
2656
+ handle_error(err);
2657
+
2658
+ return self;
2659
+ }
2660
+
2661
+
2662
+ /****************************/
2663
+ /* FT2::BitmapGlyph methods */
2664
+ /****************************/
2665
+
2666
+ /*
2667
+ * Constructor for FT2::BitmapGlyph class.
2668
+ *
2669
+ * This method is currently empty. You should never call this method
2670
+ * directly unless you're instantiating a derived class (ie, you know
2671
+ * what you're doing).
2672
+ *
2673
+ */
2674
+ static VALUE ft_bmapglyph_init(VALUE self) {
2675
+ return self;
2676
+ }
2677
+
2678
+ /*
2679
+ * Get the top-side bearing of a BitmapGlyph object.
2680
+ *
2681
+ * Description:
2682
+ * The top-side bearing, i.e., the vertical distance from the current
2683
+ * pen position to the top border of the glyph bitmap. This distance
2684
+ * is positive for upwards-y.
2685
+ *
2686
+ * Note:
2687
+ * FT2::BitmapGlyph is a subclass of FT2::Glyph.
2688
+ *
2689
+ * Examples:
2690
+ * y = bmap_glyph.top
2691
+ *
2692
+ */
2693
+ static VALUE ft_bmapglyph_top(VALUE self) {
2694
+ FT_BitmapGlyph *glyph;
2695
+ Data_Get_Struct(self, FT_BitmapGlyph, glyph);
2696
+ return INT2FIX((*glyph)->top);
2697
+ }
2698
+
2699
+ /*
2700
+ * Get the left-side bearing of a BitmapGlyph object.
2701
+ *
2702
+ * Description:
2703
+ * The left-side bearing, i.e., the horizontal distance from the
2704
+ * current pen position to the left border of the glyph bitmap.
2705
+ *
2706
+ * Note:
2707
+ * FT2::BitmapGlyph is a subclass of FT2::Glyph.
2708
+ *
2709
+ * Examples:
2710
+ * x = bmap_glyph.left
2711
+ *
2712
+ */
2713
+ static VALUE ft_bmapglyph_left(VALUE self) {
2714
+ FT_BitmapGlyph *glyph;
2715
+ Data_Get_Struct(self, FT_BitmapGlyph, glyph);
2716
+ return INT2FIX((*glyph)->left);
2717
+ }
2718
+
2719
+ /*
2720
+ * Get the FT2::Bitmap of a FT2::BitmapGlyph object.
2721
+ *
2722
+ * Examples:
2723
+ * bmap = bmap_glyph.bitmap
2724
+ *
2725
+ */
2726
+ static VALUE ft_bmapglyph_bitmap(VALUE self) {
2727
+ FT_BitmapGlyph *glyph;
2728
+ Data_Get_Struct(self, FT_BitmapGlyph, glyph);
2729
+ return Data_Wrap_Struct(cBitmapGlyph, 0, glyph_free, &(*glyph)->bitmap);
2730
+ }
2731
+
2732
+
2733
+ /*****************************/
2734
+ /* FT2::OutlineGlyph methods */
2735
+ /*****************************/
2736
+
2737
+ /*
2738
+ * Constructor for FT2::OutlineGlyph class.
2739
+ *
2740
+ * This method is currently empty. You should never call this method
2741
+ * directly unless you're instantiating a derived class (ie, you know
2742
+ * what you're doing).
2743
+ *
2744
+ */
2745
+ static VALUE ft_outlineglyph_init(VALUE self) {
2746
+ return self;
2747
+ }
2748
+
2749
+ /*
2750
+ * Get the outline of a FT2::OutlineGlyph object.
2751
+ *
2752
+ * Note:
2753
+ * FT2::OutlineGlyph is a subclass of FT2::Glyph.
2754
+ *
2755
+ * Examples:
2756
+ * outline = oline.outline
2757
+ *
2758
+ */
2759
+ static VALUE ft_outlineglyph_outline(VALUE self) {
2760
+ FT_OutlineGlyph *glyph;
2761
+ Data_Get_Struct(self, FT_OutlineGlyph, glyph);
2762
+ return Data_Wrap_Struct(cOutline, 0, dont_free, &(*glyph)->outline);
2763
+ }
2764
+ static void define_constants(void) {
2765
+ /***********************************/
2766
+ /* define FT2::PixelMode constants */
2767
+ /***********************************/
2768
+ mPixelMode = rb_define_module_under(mFt2, "PixelMode");
2769
+ rb_define_const(mPixelMode, "NONE", INT2FIX(FT_PIXEL_MODE_NONE));
2770
+ rb_define_const(mPixelMode, "MONO", INT2FIX(FT_PIXEL_MODE_MONO));
2771
+ rb_define_const(mPixelMode, "GRAY2", INT2FIX(FT_PIXEL_MODE_GRAY2));
2772
+ rb_define_const(mPixelMode, "GRAY4", INT2FIX(FT_PIXEL_MODE_GRAY4));
2773
+ rb_define_const(mPixelMode, "LCD", INT2FIX(FT_PIXEL_MODE_LCD));
2774
+ rb_define_const(mPixelMode, "LCD_V", INT2FIX(FT_PIXEL_MODE_LCD_V));
2775
+ rb_define_const(mPixelMode, "MAX", INT2FIX(FT_PIXEL_MODE_MAX));
2776
+
2777
+ /* old pixel mode stuff (according to tutorial)
2778
+ rb_define_const(mPixelMode, "NONE", INT2FIX(ft_pixel_mode_none));
2779
+ rb_define_const(mPixelMode, "MONO", INT2FIX(ft_pixel_mode_mono));
2780
+ rb_define_const(mPixelMode, "GRAYS", INT2FIX(ft_pixel_mode_grays));
2781
+ rb_define_const(mPixelMode, "PAL2", INT2FIX(ft_pixel_mode_pal2));
2782
+ rb_define_const(mPixelMode, "PAL4", INT2FIX(ft_pixel_mode_pal4));
2783
+ rb_define_const(mPixelMode, "PAL8", INT2FIX(ft_pixel_mode_pal8));
2784
+ rb_define_const(mPixelMode, "RGB15", INT2FIX(ft_pixel_mode_rgb15));
2785
+ rb_define_const(mPixelMode, "RGB16", INT2FIX(ft_pixel_mode_rgb16));
2786
+ rb_define_const(mPixelMode, "RGB24", INT2FIX(ft_pixel_mode_rgb24));
2787
+ rb_define_const(mPixelMode, "RGB32", INT2FIX(ft_pixel_mode_rgb32));
2788
+ */
2789
+
2790
+ /*************************************/
2791
+ /* define FT2::PaletteMode constants */
2792
+ /*************************************/
2793
+ /* FIXME: doesn't compile, so I'm disabling it for now
2794
+ mPaletteMode = rb_define_module_under(mFt2, "PaletteMode");
2795
+ rb_define_const(mPaletteMode, "RGB", INT2FIX(ft_palette_mode_rgb));
2796
+ rb_define_const(mPaletteMode, "RGBA", INT2FIX(ft_palette_mode_rgba));
2797
+ */
2798
+
2799
+ /*************************************/
2800
+ /* define FT2::GlyphFormat constants */
2801
+ /*************************************/
2802
+ mGlyphFormat = rb_define_module_under(mFt2, "GlyphFormat");
2803
+ rb_define_const(mGlyphFormat, "COMPOSITE", INT2FIX(ft_glyph_format_composite));
2804
+ rb_define_const(mGlyphFormat, "BITMAP", INT2FIX(ft_glyph_format_bitmap));
2805
+ rb_define_const(mGlyphFormat, "OUTLINE", INT2FIX(ft_glyph_format_outline));
2806
+ rb_define_const(mGlyphFormat, "PLOTTER", INT2FIX(ft_glyph_format_plotter));
2807
+
2808
+ /**********************************/
2809
+ /* define FT2::Encoding constants */
2810
+ /**********************************/
2811
+ mEnc = rb_define_module_under(mFt2, "Encoding");
2812
+ rb_define_const(mEnc, "NONE", INT2FIX(ft_encoding_none));
2813
+ rb_define_const(mEnc, "SYMBOL", INT2FIX(ft_encoding_symbol));
2814
+ rb_define_const(mEnc, "UNICODE", INT2FIX(ft_encoding_unicode));
2815
+ rb_define_const(mEnc, "LATIN_1", INT2FIX(ft_encoding_latin_1));
2816
+ /* disabled as per the ft2 header documentation */
2817
+ /* rb_define_const(mEnc, "LATIN_2", INT2FIX(ft_encoding_latin_2)); */
2818
+ rb_define_const(mEnc, "SJIS", INT2FIX(ft_encoding_sjis));
2819
+ rb_define_const(mEnc, "GB2312", INT2FIX(ft_encoding_gb2312));
2820
+ rb_define_const(mEnc, "BIG5", INT2FIX(ft_encoding_big5));
2821
+ rb_define_const(mEnc, "WANSUNG", INT2FIX(ft_encoding_wansung));
2822
+ rb_define_const(mEnc, "JOHAB", INT2FIX(ft_encoding_johab));
2823
+ rb_define_const(mEnc, "ADOBE_STANDARD", INT2FIX(ft_encoding_adobe_standard));
2824
+ rb_define_const(mEnc, "ADOBE_EXPERT", INT2FIX(ft_encoding_adobe_expert));
2825
+ rb_define_const(mEnc, "ADOBE_CUSTOM", INT2FIX(ft_encoding_adobe_custom));
2826
+ rb_define_const(mEnc, "APPLE_ROMAN", INT2FIX(ft_encoding_apple_roman));
2827
+
2828
+ /************************************/
2829
+ /* define FT2::RenderMode constants */
2830
+ /************************************/
2831
+ mRenderMode = rb_define_module_under(mFt2, "RenderMode");
2832
+ rb_define_const(mRenderMode, "NORMAL", INT2FIX(ft_render_mode_normal));
2833
+ rb_define_const(mRenderMode, "MONO", INT2FIX(ft_render_mode_mono));
2834
+
2835
+ /*************************************/
2836
+ /* define FT2::KerningMode constants */
2837
+ /*************************************/
2838
+ mKerningMode = rb_define_module_under(mFt2, "KerningMode");
2839
+ rb_define_const(mKerningMode, "DEFAULT", INT2FIX(ft_kerning_default));
2840
+ rb_define_const(mKerningMode, "UNFITTED", INT2FIX(ft_kerning_unfitted));
2841
+ rb_define_const(mKerningMode, "UNSCALED", INT2FIX(ft_kerning_unscaled));
2842
+
2843
+ /******************************/
2844
+ /* define FT2::Load constants */
2845
+ /******************************/
2846
+ mLoad = rb_define_module_under(mFt2, "Load");
2847
+ rb_define_const(mLoad, "DEFAULT", INT2NUM(FT_LOAD_DEFAULT));
2848
+ rb_define_const(mLoad, "RENDER", INT2NUM(FT_LOAD_RENDER));
2849
+ rb_define_const(mLoad, "MONOCHROME", INT2NUM(FT_LOAD_MONOCHROME));
2850
+ rb_define_const(mLoad, "LINEAR_DESIGN", INT2NUM(FT_LOAD_LINEAR_DESIGN));
2851
+ rb_define_const(mLoad, "NO_SCALE", INT2NUM(FT_LOAD_NO_SCALE));
2852
+ rb_define_const(mLoad, "NO_HINTING", INT2NUM(FT_LOAD_NO_HINTING));
2853
+ rb_define_const(mLoad, "NO_BITMAP", INT2NUM(FT_LOAD_NO_BITMAP));
2854
+ rb_define_const(mLoad, "CROP_BITMAP", INT2NUM(FT_LOAD_CROP_BITMAP));
2855
+ rb_define_const(mLoad, "VERTICAL_LAYOUT", INT2NUM(FT_LOAD_VERTICAL_LAYOUT));
2856
+ rb_define_const(mLoad, "IGNORE_TRANSFORM", INT2NUM(FT_LOAD_IGNORE_TRANSFORM));
2857
+ rb_define_const(mLoad, "IGNORE_GLOBAL_ADVANCE_WIDTH", INT2NUM(FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH));
2858
+ rb_define_const(mLoad, "FORCE_AUTOHINT", INT2NUM(FT_LOAD_FORCE_AUTOHINT));
2859
+ rb_define_const(mLoad, "NO_RECURSE", INT2NUM(FT_LOAD_NO_RECURSE));
2860
+ rb_define_const(mLoad, "PEDANTIC", INT2NUM(FT_LOAD_PEDANTIC));
2861
+
2862
+ /***********************************/
2863
+ /* define FT2::GlyphBBox constants */
2864
+ /***********************************/
2865
+ mBBox = rb_define_module_under(mFt2, "GlyphBBox");
2866
+ rb_define_const(mBBox, "UNSCALED", INT2NUM(ft_glyph_bbox_unscaled));
2867
+ rb_define_const(mBBox, "SUBPIXELS", INT2NUM(ft_glyph_bbox_subpixels));
2868
+ rb_define_const(mBBox, "GRIDFIT", INT2NUM(ft_glyph_bbox_gridfit));
2869
+ rb_define_const(mBBox, "TRUNCATE", INT2NUM(ft_glyph_bbox_truncate));
2870
+ rb_define_const(mBBox, "PIXELS", INT2NUM(ft_glyph_bbox_pixels));
2871
+ }
2872
+
2873
+ void Init_ft2(void) {
2874
+ FT_Error err;
2875
+
2876
+ if ((err = FT_Init_FreeType(&library)) != FT_Err_Ok)
2877
+ handle_error(err);
2878
+
2879
+ /* define top-level FT2 module */
2880
+ mFt2 = rb_define_module("FT2");
2881
+
2882
+ /* define FT2::VERSION */
2883
+ rb_define_const(mFt2, "VERSION", rb_str_new2(VERSION));
2884
+ rb_define_singleton_method(mFt2, "version", ft_version, 0);
2885
+
2886
+ define_constants();
2887
+
2888
+ /****************************/
2889
+ /* define FT2::Bitmap class */
2890
+ /****************************/
2891
+ cBitmap = rb_define_class_under(mFt2, "Bitmap", rb_cObject);
2892
+ rb_define_singleton_method(cBitmap, "initialize", ft_bitmap_init, 0);
2893
+ rb_define_method(cBitmap, "rows", ft_bitmap_rows, 0);
2894
+ rb_define_method(cBitmap, "width", ft_bitmap_width, 0);
2895
+ rb_define_method(cBitmap, "pitch", ft_bitmap_pitch, 0);
2896
+ rb_define_method(cBitmap, "buffer", ft_bitmap_buffer, 0);
2897
+ rb_define_method(cBitmap, "num_grays", ft_bitmap_num_grays, 0);
2898
+ rb_define_method(cBitmap, "pixel_mode", ft_bitmap_pixel_mode, 0);
2899
+ rb_define_method(cBitmap, "palette_mode", ft_bitmap_palette_mode, 0);
2900
+ rb_define_method(cBitmap, "palette", ft_bitmap_palette, 0);
2901
+
2902
+ /*****************************/
2903
+ /* define FT2::CharMap class */
2904
+ /*****************************/
2905
+ cCharMap = rb_define_class_under(mFt2, "CharMap", rb_cObject);
2906
+
2907
+ /**************************/
2908
+ /* define FT2::Face class */
2909
+ /**************************/
2910
+ cFace = rb_define_class_under(mFt2, "Face", rb_cObject);
2911
+ rb_define_singleton_method(cFace, "new", ft_face_new, -1);
2912
+ rb_define_singleton_method(cFace, "load", ft_face_new, -1);
2913
+ rb_define_singleton_method(cFace, "new_from_memory", ft_face_new_from_memory, -1);
2914
+
2915
+ rb_define_singleton_method(cFace, "initialize", ft_face_init, 0);
2916
+
2917
+ rb_define_method(cFace, "faces", ft_face_faces, 0);
2918
+ rb_define_alias(cFace, "num_faces", "faces");
2919
+
2920
+ rb_define_method(cFace, "index", ft_face_index, 0);
2921
+ rb_define_alias(cFace, "face_index", "index");
2922
+
2923
+ rb_define_method(cFace, "flags", ft_face_flags, 0);
2924
+ rb_define_alias(cFace, "face_flags", "flags");
2925
+
2926
+ rb_define_const(cFace, "SCALABLE", INT2FIX(FT_FACE_FLAG_SCALABLE));
2927
+ rb_define_const(cFace, "FIXED_SIZES", INT2FIX(FT_FACE_FLAG_FIXED_SIZES));
2928
+ rb_define_const(cFace, "FIXED_WIDTH", INT2FIX(FT_FACE_FLAG_FIXED_WIDTH));
2929
+ rb_define_const(cFace, "FIXED_HORIZONTAL", INT2FIX(FT_FACE_FLAG_HORIZONTAL));
2930
+ rb_define_const(cFace, "FIXED_VERTICAL", INT2FIX(FT_FACE_FLAG_VERTICAL));
2931
+ rb_define_const(cFace, "SFNT", INT2FIX(FT_FACE_FLAG_SFNT));
2932
+ rb_define_const(cFace, "KERNING", INT2FIX(FT_FACE_FLAG_KERNING));
2933
+ rb_define_const(cFace, "MULTIPLE_MASTERS", INT2FIX(FT_FACE_FLAG_MULTIPLE_MASTERS));
2934
+ rb_define_const(cFace, "GLYPH_NAMES", INT2FIX(FT_FACE_FLAG_GLYPH_NAMES));
2935
+ rb_define_const(cFace, "EXTERNAL_STREAM", INT2FIX(FT_FACE_FLAG_EXTERNAL_STREAM));
2936
+ rb_define_const(cFace, "FAST_GLYPHS", INT2FIX(FT_FACE_FLAG_FAST_GLYPHS));
2937
+
2938
+ rb_define_method(cFace, "scalable?", ft_face_flag_scalable, 0);
2939
+ rb_define_method(cFace, "fixed_sizes?", ft_face_flag_fixed_sizes, 0);
2940
+ rb_define_method(cFace, "fixed_width?", ft_face_flag_fixed_width, 0);
2941
+ rb_define_method(cFace, "horizontal?", ft_face_flag_horizontal, 0);
2942
+ rb_define_method(cFace, "vertical?", ft_face_flag_vertical, 0);
2943
+ rb_define_method(cFace, "sfnt?", ft_face_flag_sfnt, 0);
2944
+ rb_define_method(cFace, "kerning?", ft_face_flag_kerning, 0);
2945
+ rb_define_method(cFace, "external_stream?", ft_face_flag_external_stream, 0);
2946
+ rb_define_method(cFace, "fast_glyphs?", ft_face_flag_fast_glyphs, 0);
2947
+
2948
+ rb_define_method(cFace, "style_flags", ft_face_style_flags, 0);
2949
+
2950
+ rb_define_const(cFace, "BOLD", INT2FIX(FT_STYLE_FLAG_BOLD));
2951
+ rb_define_const(cFace, "ITALIC", INT2FIX(FT_STYLE_FLAG_ITALIC));
2952
+
2953
+ rb_define_method(cFace, "bold?", ft_face_flag_bold, 0);
2954
+ rb_define_method(cFace, "italic?", ft_face_flag_italic, 0);
2955
+
2956
+ rb_define_method(cFace, "glyphs", ft_face_glyphs, 0);
2957
+ rb_define_alias(cFace, "num_glyphs", "glyphs");
2958
+
2959
+ rb_define_method(cFace, "family", ft_face_family, 0);
2960
+ rb_define_method(cFace, "style", ft_face_style, 0);
2961
+
2962
+ rb_define_method(cFace, "fixed_sizes", ft_face_fixed_sizes, 0);
2963
+ rb_define_alias(cFace, "num_fixed_sizes", "fixed_sizes");
2964
+
2965
+ rb_define_method(cFace, "available_sizes", ft_face_available_sizes, 0);
2966
+ rb_define_alias(cFace, "num_available_sizes", "available_sizes");
2967
+
2968
+ rb_define_method(cFace, "num_charmaps", ft_face_num_charmaps, 0);
2969
+ rb_define_method(cFace, "charmaps", ft_face_charmaps, 0);
2970
+
2971
+ rb_define_method(cFace, "bbox", ft_face_bbox, 0);
2972
+
2973
+ rb_define_method(cFace, "units_per_em", ft_face_units_per_em, 0);
2974
+ rb_define_alias(cFace, "units_per_EM", "units_per_em");
2975
+
2976
+ rb_define_method(cFace, "ascender", ft_face_ascender, 0);
2977
+ rb_define_method(cFace, "descender", ft_face_descender, 0);
2978
+ rb_define_method(cFace, "height", ft_face_height, 0);
2979
+ rb_define_method(cFace, "max_advance_width", ft_face_max_advance_width, 0);
2980
+ rb_define_method(cFace, "max_advance_height", ft_face_max_advance_height, 0);
2981
+ rb_define_method(cFace, "underline_position", ft_face_underline_position, 0);
2982
+ rb_define_method(cFace, "underline_thickness", ft_face_underline_thickness, 0);
2983
+ rb_define_method(cFace, "glyph", ft_face_glyph, 0);
2984
+ rb_define_method(cFace, "size", ft_face_size, 0);
2985
+ rb_define_method(cFace, "charmap", ft_face_charmap, 0);
2986
+
2987
+ rb_define_method(cFace, "attach", ft_face_attach, 1);
2988
+ rb_define_alias(cFace, "attach_file", "attach");
2989
+
2990
+ rb_define_method(cFace, "load_glyph", ft_face_load_glyph, 2);
2991
+ rb_define_method(cFace, "load_char", ft_face_load_char, 2);
2992
+
2993
+ rb_define_method(cFace, "char_index", ft_face_char_index, 1);
2994
+ rb_define_method(cFace, "name_index", ft_face_name_index, 1);
2995
+
2996
+ rb_define_method(cFace, "kerning", ft_face_kerning, 3);
2997
+ rb_define_alias(cFace, "get_kerning", "kerning");
2998
+
2999
+ rb_define_method(cFace, "glyph_name", ft_face_glyph_name, 1);
3000
+ rb_define_method(cFace, "postscript_name", ft_face_ps_name, 0);
3001
+ rb_define_alias(cFace, "name", "postscript_name");
3002
+
3003
+ rb_define_method(cFace, "select_charmap", ft_face_select_charmap, 1);
3004
+ rb_define_method(cFace, "set_charmap", ft_face_set_charmap, 1);
3005
+ rb_define_alias(cFace, "charmap=", "set_charmap");
3006
+
3007
+ rb_define_method(cFace, "first_char", ft_face_first_char, 0);
3008
+ rb_define_method(cFace, "next_char", ft_face_next_char, 1);
3009
+
3010
+ rb_define_method(cFace, "current_charmap", ft_face_current_charmap, 0);
3011
+
3012
+ rb_define_method(cFace, "set_char_size", ft_face_set_char_size, 4);
3013
+ rb_define_method(cFace, "set_pixel_sizes", ft_face_set_pixel_sizes, 2);
3014
+ rb_define_method(cFace, "set_transform", ft_face_set_transform, 2);
3015
+
3016
+ /**********************************/
3017
+ /* define FT2::GlyphMetrics class */
3018
+ /**********************************/
3019
+ cGlyphMetrics = rb_define_class_under(mFt2, "GlyphMetrics", rb_cObject);
3020
+ rb_define_singleton_method(cGlyphMetrics, "initialize", ft_glyphmetrics_init, 0);
3021
+
3022
+ rb_define_method(cGlyphMetrics, "width", ft_glyphmetrics_width, 0);
3023
+ rb_define_alias(cGlyphMetrics, "w", "width");
3024
+ rb_define_method(cGlyphMetrics, "height", ft_glyphmetrics_height, 0);
3025
+ rb_define_alias(cGlyphMetrics, "h", "height");
3026
+
3027
+ rb_define_method(cGlyphMetrics, "h_bearing_x", ft_glyphmetrics_h_bear_x, 0);
3028
+ rb_define_alias(cGlyphMetrics, "horiBearingX", "h_bearing_x");
3029
+ rb_define_alias(cGlyphMetrics, "h_bear_x", "h_bearing_x");
3030
+ rb_define_alias(cGlyphMetrics, "hbx", "h_bearing_x");
3031
+ rb_define_method(cGlyphMetrics, "h_bearing_y", ft_glyphmetrics_h_bear_y, 0);
3032
+ rb_define_alias(cGlyphMetrics, "horiBearingY", "h_bearing_y");
3033
+ rb_define_alias(cGlyphMetrics, "h_bear_y", "h_bearing_y");
3034
+ rb_define_alias(cGlyphMetrics, "hby", "h_bearing_y");
3035
+ rb_define_method(cGlyphMetrics, "h_advance", ft_glyphmetrics_h_advance, 0);
3036
+ rb_define_alias(cGlyphMetrics, "horiAdvance", "h_advance");
3037
+ rb_define_alias(cGlyphMetrics, "ha", "h_advance");
3038
+
3039
+ rb_define_method(cGlyphMetrics, "v_bearing_x", ft_glyphmetrics_v_bear_x, 0);
3040
+ rb_define_alias(cGlyphMetrics, "vertBearingX", "v_bearing_x");
3041
+ rb_define_alias(cGlyphMetrics, "v_bear_x", "v_bearing_x");
3042
+ rb_define_alias(cGlyphMetrics, "vbx", "v_bearing_x");
3043
+ rb_define_method(cGlyphMetrics, "v_bearing_y", ft_glyphmetrics_v_bear_y, 0);
3044
+ rb_define_alias(cGlyphMetrics, "vertBearingY", "v_bearing_y");
3045
+ rb_define_alias(cGlyphMetrics, "v_bear_y", "v_bearing_y");
3046
+ rb_define_alias(cGlyphMetrics, "vby", "v_bearing_y");
3047
+ rb_define_method(cGlyphMetrics, "v_advance", ft_glyphmetrics_v_advance, 0);
3048
+ rb_define_alias(cGlyphMetrics, "vertAdvance", "v_advance");
3049
+ rb_define_alias(cGlyphMetrics, "va", "v_advance");
3050
+
3051
+ /*******************************/
3052
+ /* define FT2::GlyphSlot class */
3053
+ /*******************************/
3054
+ cGlyphSlot = rb_define_class_under(mFt2, "GlyphSlot", rb_cObject);
3055
+ rb_define_singleton_method(cGlyphSlot, "initialize", ft_glyphslot_init, 0);
3056
+
3057
+ rb_define_method(cGlyphSlot, "library", ft_glyphslot_library, 0);
3058
+ rb_define_method(cGlyphSlot, "face", ft_glyphslot_face, 0);
3059
+ rb_define_method(cGlyphSlot, "next", ft_glyphslot_next, 0);
3060
+ rb_define_method(cGlyphSlot, "flags", ft_glyphslot_flags, 0);
3061
+ rb_define_method(cGlyphSlot, "metrics", ft_glyphslot_metrics, 0);
3062
+
3063
+ rb_define_method(cGlyphSlot, "h_advance", ft_glyphslot_h_advance, 0);
3064
+ rb_define_alias(cGlyphSlot, "linearHoriAdvance", "h_advance");
3065
+ rb_define_alias(cGlyphSlot, "h_adv", "h_advance");
3066
+ rb_define_alias(cGlyphSlot, "ha", "h_advance");
3067
+
3068
+ rb_define_method(cGlyphSlot, "v_advance", ft_glyphslot_v_advance, 0);
3069
+ rb_define_alias(cGlyphSlot, "linearVertAdvance", "h_advance");
3070
+ rb_define_alias(cGlyphSlot, "v_adv", "h_advance");
3071
+ rb_define_alias(cGlyphSlot, "va", "h_advance");
3072
+
3073
+ rb_define_method(cGlyphSlot, "advance", ft_glyphslot_advance, 0);
3074
+ rb_define_method(cGlyphSlot, "format", ft_glyphslot_format, 0);
3075
+ rb_define_method(cGlyphSlot, "bitmap", ft_glyphslot_bitmap, 0);
3076
+ rb_define_method(cGlyphSlot, "bitmap_left", ft_glyphslot_bitmap_left, 0);
3077
+ rb_define_method(cGlyphSlot, "bitmap_top", ft_glyphslot_bitmap_top, 0);
3078
+ rb_define_method(cGlyphSlot, "outline", ft_glyphslot_outline, 0);
3079
+ rb_define_method(cGlyphSlot, "num_subglyphs", ft_glyphslot_num_subglyphs, 0);
3080
+ rb_define_method(cGlyphSlot, "subglyphs", ft_glyphslot_subglyphs, 0);
3081
+ rb_define_method(cGlyphSlot, "control_data", ft_glyphslot_control_data, 0);
3082
+ rb_define_method(cGlyphSlot, "control_len", ft_glyphslot_control_len, 0);
3083
+
3084
+ rb_define_method(cGlyphSlot, "render", ft_glyphslot_render, 1);
3085
+ rb_define_alias(cGlyphSlot, "render_glyph", "render");
3086
+
3087
+ rb_define_method(cGlyphSlot, "glyph", ft_glyphslot_glyph, 0);
3088
+ rb_define_alias(cGlyphSlot, "get_glyph", "glyph");
3089
+
3090
+ /*****************************/
3091
+ /* define FT2::Library class */
3092
+ /*****************************/
3093
+ cLibrary = rb_define_class_under(mFt2, "Library", rb_cObject);
3094
+
3095
+ /****************************/
3096
+ /* define FT2::Memory class */
3097
+ /****************************/
3098
+ cMemory = rb_define_class_under(mFt2, "Memory", rb_cObject);
3099
+
3100
+ /*****************************/
3101
+ /* define FT2::Outline class */
3102
+ /*****************************/
3103
+ cOutline = rb_define_class_under(mFt2, "Outline", rb_cObject);
3104
+
3105
+ /**************************/
3106
+ /* define FT2::Size class */
3107
+ /**************************/
3108
+ cSize = rb_define_class_under(mFt2, "Size", rb_cObject);
3109
+ rb_define_singleton_method(cSize, "initialize", ft_size_init, 0);
3110
+ rb_define_method(cSize, "face", ft_size_face, 0);
3111
+ rb_define_method(cSize, "metrics", ft_size_metrics, 0);
3112
+
3113
+ /*********************************/
3114
+ /* define FT2::SizeMetrics class */
3115
+ /*********************************/
3116
+ cSizeMetrics = rb_define_class_under(mFt2, "SizeMetrics", rb_cObject);
3117
+ rb_define_singleton_method(cSizeMetrics, "initialize", ft_size_metrics_init, 0);
3118
+ rb_define_method(cSizeMetrics, "x_ppem", ft_size_metrics_x_ppem, 0);
3119
+ rb_define_method(cSizeMetrics, "y_ppem", ft_size_metrics_y_ppem, 0);
3120
+ rb_define_method(cSizeMetrics, "x_scale", ft_size_metrics_x_scale, 0);
3121
+ rb_define_method(cSizeMetrics, "y_scale", ft_size_metrics_y_scale, 0);
3122
+
3123
+ /***************************/
3124
+ /* define FT2::Glyph class */
3125
+ /***************************/
3126
+ cGlyph = rb_define_class_under(mFt2, "Glyph", rb_cObject);
3127
+ rb_define_singleton_method(cGlyph, "initialize", ft_glyph_init, 0);
3128
+ rb_define_method(cGlyph, "library", ft_glyph_library, 0);
3129
+ rb_define_method(cGlyph, "class", ft_glyph_class, 0);
3130
+ rb_define_alias(cGlyph, "clazz", "class");
3131
+ rb_define_method(cGlyph, "format", ft_glyph_format, 0);
3132
+ rb_define_method(cGlyph, "advance", ft_glyph_advance, 0);
3133
+
3134
+ rb_define_method(cGlyph, "dup", ft_glyph_dup, 0);
3135
+ rb_define_alias(cGlyph, "copy", "dup");
3136
+
3137
+ rb_define_method(cGlyph, "transform", ft_glyph_transform, 2);
3138
+
3139
+ rb_define_method(cGlyph, "cbox", ft_glyph_cbox, 2);
3140
+ rb_define_alias(cGlyph, "control_box", "cbox");
3141
+
3142
+ rb_define_method(cGlyph, "to_bmap", ft_glyph_to_bmap, 3);
3143
+ rb_define_alias(cGlyph, "to_bitmap", "to_bmap");
3144
+
3145
+ /*********************************/
3146
+ /* define FT2::BitmapGlyph class */
3147
+ /*********************************/
3148
+ cBitmapGlyph = rb_define_class_under(mFt2, "BitmapGlyph", cGlyph);
3149
+ rb_define_singleton_method(cBitmapGlyph, "initialize", ft_bmapglyph_init, 0);
3150
+
3151
+ rb_define_method(cBitmapGlyph, "left", ft_bmapglyph_left, 0);
3152
+ rb_define_method(cBitmapGlyph, "top", ft_bmapglyph_top, 0);
3153
+ rb_define_method(cBitmapGlyph, "bitmap", ft_bmapglyph_bitmap, 0);
3154
+
3155
+ /*********************************/
3156
+ /* define FT2::OutlineGlyph class */
3157
+ /*********************************/
3158
+ cOutlineGlyph = rb_define_class_under(mFt2, "OutlineGlyph", cGlyph);
3159
+ rb_define_singleton_method(cOutlineGlyph, "initialize", ft_outlineglyph_init, 0);
3160
+
3161
+ /********************************/
3162
+ /* define FT2::GlyphClass class */
3163
+ /********************************/
3164
+ cGlyphClass = rb_define_class_under(mFt2, "GlyphClass", rb_cObject);
3165
+
3166
+ /******************************/
3167
+ /* define FT2::SubGlyph class */
3168
+ /******************************/
3169
+ cSubGlyph = rb_define_class_under(mFt2, "SubGlyph", rb_cObject);
3170
+ }