1 /*
2 * gltt graphics library
3 * Copyright (C) 1998-1999 Stephane Rehel
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <stdio.h>
21
22 #include "GLTTFont.h"
23
24 #include "FTFont.h"
25 #include "FTInstance.h"
26 #include "FTGlyph.h"
27 #include "FTGlyphVectorizer.h"
28
29 #include "GLTTGlyphPolygonizer.h"
30
31 #ifdef WIN32
32 #include <windows.h>
33 #endif
34
35 #ifdef LOCAL_GL_HEADER
36 #include "local_gl.h"
37 #include "local_glu.h"
38 #else
39 #include <GL/gl.h>
40 #include <GL/glu.h>
41 #endif
42
43
44 /////////////////////////////////////////////////////////////////////////////
45
GLTTFont(FTFace * _face)46 GLTTFont::GLTTFont( FTFace* _face )
47 {
48 face= _face;
49
50 instance= 0;
51 font= 0;
52
53 loaded= 0;
54 list_base= 0;
55
56 precision= 4.;
57 }
58
59 /////////////////////////////////////////////////////////////////////////////
60
~GLTTFont()61 GLTTFont::~GLTTFont()
62 {
63 destroy();
64
65 face= 0;
66 }
67
68 /////////////////////////////////////////////////////////////////////////////
69
destroy()70 void GLTTFont::destroy()
71 {
72 delete[] loaded;
73 loaded= 0;
74
75 if( list_base != 0 )
76 {
77 glDeleteLists( list_base, 256 );
78 list_base= 0;
79 }
80
81 delete font;
82 font= 0;
83
84 delete instance;
85 instance= 0;
86 }
87
88 /////////////////////////////////////////////////////////////////////////////
89
setPrecision(double _precision)90 void GLTTFont::setPrecision( double _precision )
91 {
92 precision= _precision;
93 }
94
95 /////////////////////////////////////////////////////////////////////////////
96
create(int point_size)97 GLTTboolean GLTTFont::create( int point_size )
98 {
99 destroy();
100
101 if( point_size < 1 )
102 point_size= 1;
103
104 instance= new FTInstance(face);
105
106 if( ! instance->create() )
107 return GLTT_FALSE;
108
109 int resolution= 96;
110 if( ! instance->setResolutions(resolution,resolution) )
111 return GLTT_FALSE;
112
113 if( ! instance->setPointSize(point_size) )
114 return GLTT_FALSE;
115
116 font= new FTFont(instance);
117
118 if( ! font->create() )
119 return GLTT_FALSE;
120
121 list_base= glGenLists(256);
122 if( list_base == 0 )
123 return GLTT_FALSE;
124
125 loaded= new GLTTboolean [ 256 ];
126 for( int i= 0; i < 256; ++i )
127 loaded[i]= GLTT_FALSE;
128
129 return GLTT_TRUE;
130 }
131
132 /////////////////////////////////////////////////////////////////////////////
133
loadGlyph(int i)134 GLTTboolean GLTTFont::loadGlyph( int i )
135 {
136 if( i < 0 || i > 256 )
137 return GLTT_FALSE;
138
139 if( list_base == 0 || loaded == 0 )
140 return GLTT_FALSE;
141
142 if( loaded[i] )
143 return GLTT_TRUE;
144
145 loaded[i]= GLTT_TRUE;
146
147 GLTTGlyphPolygonizer polygonizer;
148
149 polygonizer.setPrecision(precision);
150
151 int list= list_base + i;
152 FTGlyph* glyph= font->getGlyph(i);
153
154 if( glyph == 0 )
155 {
156 err:
157 glNewList(list,GL_COMPILE);
158 glEndList();
159 return GLTT_TRUE;
160 }
161
162 if( ! polygonizer.init(glyph) )
163 goto err;
164
165 glNewList(list,GL_COMPILE);
166
167 polygonizer.polygonize();
168
169 glTranslatef( polygonizer.getAdvance(), 0., 0. );
170
171 glEndList();
172
173 return GLTT_TRUE;
174 }
175
176 /////////////////////////////////////////////////////////////////////////////
177
load(int from,int to)178 void GLTTFont::load( int from /* = 0 */, int to /* = 255 */ )
179 {
180 for( int i= from; i <= to; ++i )
181 loadGlyph(i);
182 }
183
184 /////////////////////////////////////////////////////////////////////////////
185
load(const char * text)186 void GLTTFont::load( const char* text )
187 {
188 if( text == 0 || list_base == 0 )
189 return;
190
191 for(;;)
192 {
193 int ch= (unsigned char)*text;
194 if( ch == 0 )
195 break;
196 ++text;
197
198 if( ! loaded[ch] )
199 loadGlyph(ch);
200 }
201 }
202
203 /////////////////////////////////////////////////////////////////////////////
204
output(const char * text)205 void GLTTFont::output( const char* text )
206 {
207 if( text == 0 || list_base == 0 || loaded == 0 )
208 return;
209
210 glPushMatrix();
211
212 for(;;)
213 {
214 int ch= (unsigned char)*text;
215 if( ch == 0 )
216 break;
217 ++text;
218
219 if( ! loaded[ch] )
220 loadGlyph(ch);
221
222 glCallList( list_base + ch );
223 }
224
225 // glPushAttrib( GL_LIST_BIT );
226 // glListBase(list_base);
227 // glCallLists( strlen(text), GL_UNSIGNED_BYTE, (GLubyte*)text );
228 // glPopAttrib();
229
230 glPopMatrix();
231 }
232
233 /////////////////////////////////////////////////////////////////////////////
234
getHeight()235 int GLTTFont::getHeight() const
236 {
237 if( font == 0 )
238 return 0;
239
240 return font->getHeight();
241 }
242
243 /////////////////////////////////////////////////////////////////////////////
244
getDescender()245 int GLTTFont::getDescender() const
246 {
247 if( font == 0 )
248 return 0;
249
250 return font->getDescender();
251 }
252
253 /////////////////////////////////////////////////////////////////////////////
254
getWidth(const char * text)255 int GLTTFont::getWidth( const char* text )
256 {
257 if( font == 0 )
258 return 0;
259
260 return font->getWidth(text);
261 }
262
263 /////////////////////////////////////////////////////////////////////////////
264
getBBox(const char * text,int & llx,int & lly,int & urx,int & ury)265 void GLTTFont::getBBox( const char* text,
266 int& llx, int& lly, int& urx, int& ury ) const
267 {
268 llx= lly= urx= ury= 0;
269
270 if( font == 0 )
271 return;
272
273 font->getBBox( text, llx, lly, urx, ury );
274 }
275
276 /////////////////////////////////////////////////////////////////////////////
277
278