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.
- data/ChangeLog +32 -0
- data/MANIFEST +14 -0
- data/README +19 -0
- data/Rakefile +32 -0
- data/TODO +3 -0
- data/VERSION +1 -0
- data/examples/fonts/yudit.ttf +0 -0
- data/examples/name_list.rb +80 -0
- data/examples/test_ft2.rb +27 -0
- data/extconf.rb +10 -0
- data/ft2.c +3170 -0
- metadata +68 -0
data/ChangeLog
ADDED
|
@@ -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
|
data/MANIFEST
ADDED
|
@@ -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/
|
data/Rakefile
ADDED
|
@@ -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
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
|
+
}
|
data/extconf.rb
ADDED
|
@@ -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
|
+
}
|