-
Notifications
You must be signed in to change notification settings - Fork 0
/
rudl_ttf.c
317 lines (264 loc) · 8.24 KB
/
rudl_ttf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/*
RUDL - a C library wrapping SDL for use in Ruby.
Copyright (C) 2001-2003 Danny van Bruggen
Copyright (C) 2003-2004 Danny van Bruggen and Renne Nissinen
*/
/**
@file Fonts
@class TrueTypeFont
Using TrueTypeFonts is easy. You open a TTF file with @new specifying
its filename and size. You render text with it by calling @render, and you get a new
surface containing the image. If you use antialiasing and no background color, the
returned surface will have per-pixel alpha values, to retain the antialiasing after blitting
to a target surface.
*/
#include "rudl_ttf.h"
#ifdef HAVE_SDL_TTF_H
#include "rudl_video.h"
#endif
#define TTF_RAISE {rb_raise(classSDLError, TTF_GetError());}
void initTTF()
{
#ifdef HAVE_SDL_TTF_H
if(!TTF_WasInit()){
DEBUG_S("Starting TTF");
if(TTF_Init()) TTF_RAISE;
}
#endif
}
void quitTTF()
{
#ifdef HAVE_SDL_TTF_H
if(TTF_WasInit()){
DEBUG_S("Stopping TTF");
TTF_Quit();
}
#endif
}
void VALUE2SDL_COLOR(VALUE colorObject, SDL_Color* color)
{
VALUE tmp;
if(rb_obj_is_kind_of(colorObject, rb_cArray)){
switch(RARRAY(colorObject)->len){
case 4:
case 3:
tmp=rb_ary_entry(colorObject, 0);
color->r=(Uint8)NUM2UINT(tmp),
tmp=rb_ary_entry(colorObject, 1);
color->g=(Uint8)NUM2UINT(tmp),
tmp=rb_ary_entry(colorObject, 2);
color->b=(Uint8)NUM2UINT(tmp);
break;
default:
rb_raise(rb_eTypeError, "Need colorarray with 3 or 4 elements");
}
}else{
rb_raise(rb_eTypeError, "Need a color array");
}
}
#ifdef HAVE_SDL_TTF_H
/**
@section Class Methods
@method new( filename, size ) -> TrueTypeFont
Creates a new TrueTypeFont object.
@filename is the filename of a TTF file.
@size is the desired height of the font in pixels.
*/
static VALUE truetypefont_new(VALUE self, VALUE filename, VALUE size)
{
TTF_Font *font;
initTTF();
font=TTF_OpenFont(STR2CSTR(filename), NUM2INT(size));
if(!font)TTF_RAISE;
return Data_Wrap_Struct(classTTF, 0, TTF_CloseFont, font);
}
TTF_Font* retrieveTTFPointer(VALUE obj)
{
TTF_Font* font;
Data_Get_Struct(obj, TTF_Font, font);
return font;
}
/**
@section Instance Methods
@method render( text, antialias, foreground ) -> Surface
@method render( text, antialias, foreground, background ) -> Surface
Render the given @text onto a new image surface.
If @antialias is true, the edges of the font will be smoothed for a much cleaner look.
The @foreground and @background colors are both RGBA, but the alpha component is ignored if given.
If the background color is omitted, the text will have a transparent background.
*/
static VALUE truetypefont_render(int argc, VALUE* argv, VALUE self)
{
TTF_Font* font = retrieveTTFPointer(self);
bool aa;
SDL_Surface* surf;
SDL_Color foreg, backg;
char* string;
VALUE textValue, aaValue, fg_rgbaValue, bg_rgbaValue;
switch(rb_scan_args(argc, argv, "31", &textValue, &aaValue, &fg_rgbaValue, &bg_rgbaValue)){
case 4: VALUE2SDL_COLOR(bg_rgbaValue, &backg);
}
VALUE2SDL_COLOR(fg_rgbaValue, &foreg);
aa=NUM2BOOL(aaValue);
string=STR2CSTR(textValue);
if(aa){
if(argc==3){
surf = TTF_RenderText_Blended(font, string, foreg);
}else{
surf = TTF_RenderText_Shaded(font, string, foreg, backg);
}
}else{
surf = TTF_RenderText_Solid(font, string, foreg);
}
if(!surf) SDL_RAISE;
if(!aa && argc==4) /*turn off transparancy*/
{
SDL_SetColorKey(surf, 0, 0);
surf->format->palette->colors[0].r = backg.r;
surf->format->palette->colors[0].g = backg.g;
surf->format->palette->colors[0].b = backg.b;
}
return createSurfaceObject(surf);
}
/**
@method ascent -> Number
Returns the ascent for the font.
The ascent is the number of pixels from the font baseline to the top of the font.
*/
static VALUE truetypefont_ascent(VALUE self)
{
return INT2NUM(TTF_FontAscent(retrieveTTFPointer(self)));
}
/**
@method bold? -> boolean
@method bold=( onOrOff ) -> self
Controls the bold attribute for the font.
Making the font bold does not work as well as you would expect.
*/
static VALUE truetypefont_bold_(VALUE self)
{
return INT2BOOL((TTF_GetFontStyle(retrieveTTFPointer(self))&&TTF_STYLE_BOLD)!=0);
}
static VALUE truetypefont_bold__(VALUE self, VALUE onOrOff)
{
TTF_Font* font = retrieveTTFPointer(self);
int style;
style = TTF_GetFontStyle(font);
if(NUM2BOOL(onOrOff)){
style |= TTF_STYLE_BOLD;
}else{
style &= ~TTF_STYLE_BOLD;
}
TTF_SetFontStyle(font, style);
return self;
}
/**
@method italic? -> boolean
@method italic=( onOrOff ) -> self
Controls the italics attribute of the font.
*/
static VALUE truetypefont_italic_(VALUE self)
{
return INT2BOOL((TTF_GetFontStyle(retrieveTTFPointer(self))&&TTF_STYLE_ITALIC)!=0);
}
static VALUE truetypefont_italic__(VALUE self, VALUE onOrOff)
{
TTF_Font* font = retrieveTTFPointer(self);
int style;
style = TTF_GetFontStyle(font);
if(NUM2BOOL(onOrOff)){
style |= TTF_STYLE_ITALIC;
}else{
style &= ~TTF_STYLE_ITALIC;
}
TTF_SetFontStyle(font, style);
return self;
}
/**
@method descent -> Number
Returns the descent for the font.
The descent is the number of pixels from the font baseline to the bottom of the font.
*/
static VALUE truetypefont_descent(VALUE self)
{
return INT2NUM(TTF_FontDescent(retrieveTTFPointer(self)));
}
/**
@method h -> Number
Returns the average size of each glyph in the font.
*/
static VALUE truetypefont_h(VALUE self)
{
return INT2NUM(TTF_FontHeight(retrieveTTFPointer(self)));
}
/**
@method linesize -> Number
Returns the linesize for the font.
Each font comes with its own recommendation for the number of spacing pixels between
each line of the font.
*/
static VALUE truetypefont_linesize(VALUE self)
{
return INT2NUM(TTF_FontLineSkip(retrieveTTFPointer(self)));
}
/**
@method underline? -> boolean
@method underline=( onOrOff ) -> self
Controls the underline attribute of the font.
*/
static VALUE truetypefont_underline_(VALUE self)
{
return INT2BOOL((TTF_GetFontStyle(retrieveTTFPointer(self))&&TTF_STYLE_UNDERLINE)!=0);
}
static VALUE truetypefont_underline__(VALUE self, VALUE onOrOff)
{
TTF_Font* font = retrieveTTFPointer(self);
int style;
style = TTF_GetFontStyle(font);
if(NUM2BOOL(onOrOff)){
style |= TTF_STYLE_UNDERLINE;
}else{
style &= ~TTF_STYLE_UNDERLINE;
}
TTF_SetFontStyle(font, style);
return self;
}
/**
@method size( text ) -> [w, h]
Returns the size in pixels that this text would need.
*/
static VALUE truetypefont_size(VALUE self, VALUE text)
{
int w, h;
TTF_SizeText(retrieveTTFPointer(self), STR2CSTR(text), &w, &h);
return rb_ary_new3(2, INT2NUM(w), INT2NUM(h));
}
#endif
void initTrueTypeFontClasses()
{
#ifdef HAVE_SDL_TTF_H
classTTF=rb_define_class_under(moduleRUDL, "TrueTypeFont", rb_cObject);
rb_define_singleton_method(classTTF, "new", truetypefont_new, 2);
rb_define_method(classTTF, "ascent", truetypefont_ascent, 0);
rb_define_method(classTTF, "bold?", truetypefont_bold_, 0);
rb_define_method(classTTF, "italic?", truetypefont_italic_, 0);
rb_define_method(classTTF, "descent", truetypefont_descent, 0);
rb_define_method(classTTF, "h", truetypefont_h, 0);
rb_define_method(classTTF, "linesize", truetypefont_linesize, 0);
rb_define_method(classTTF, "underline?", truetypefont_underline_, 0);
rb_define_method(classTTF, "render", truetypefont_render, -1);
rb_define_method(classTTF, "bold=", truetypefont_bold__, 1);
rb_define_method(classTTF, "italic=", truetypefont_italic__, 1);
rb_define_method(classTTF, "underline=", truetypefont_underline__, 1);
rb_define_method(classTTF, "size", truetypefont_size, 1);
// Backward compatability:
rb_alias(classTTF, rb_intern("height"), rb_intern("h"));
rb_eval_string(
"module RUDL class TrueTypeFont \n"
" def inspect \n"
" \"<TrueTypeFont: #{h}pix>\" \n"
" end \n"
"end end \n"
);
#endif
}