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 "GLTTOutlineFont.h"
21
22 #include "FTFont.h"
23 #include "FTInstance.h"
24 #include "FTGlyphVectorizer.h"
25
26 #ifdef WIN32
27 #include <windows.h>
28 #endif
29
30 #ifdef LOCAL_GL_HEADER
31 #include "local_gl.h"
32 #else
33 #include <GL/gl.h>
34 #endif
35
36 /////////////////////////////////////////////////////////////////////////////
37
GLTTOutlineFont(FTFace * _face)38 GLTTOutlineFont::GLTTOutlineFont( FTFace* _face )
39 {
40 face= _face;
41
42 instance= 0;
43 font= 0;
44
45 loaded= 0;
46 list_base= 0;
47
48 precision= 4.;
49 }
50
51 /////////////////////////////////////////////////////////////////////////////
52
~GLTTOutlineFont()53 GLTTOutlineFont::~GLTTOutlineFont()
54 {
55 destroy();
56
57 face= 0;
58 }
59
60 /////////////////////////////////////////////////////////////////////////////
61
destroy()62 void GLTTOutlineFont::destroy()
63 {
64 delete[] loaded;
65 loaded= 0;
66
67 if( list_base != 0 )
68 {
69 glDeleteLists( list_base, 256 );
70 list_base= 0;
71 }
72
73 delete font;
74 font= 0;
75
76 delete instance;
77 instance= 0;
78 }
79
80 /////////////////////////////////////////////////////////////////////////////
81
setPrecision(double _precision)82 void GLTTOutlineFont::setPrecision( double _precision )
83 {
84 precision= _precision;
85 }
86
87 /////////////////////////////////////////////////////////////////////////////
88
create(int point_size)89 GLTTboolean GLTTOutlineFont::create( int point_size )
90 {
91 destroy();
92
93 if( point_size < 1 )
94 point_size= 1;
95
96 instance= new FTInstance(face);
97
98 if( ! instance->create() )
99 return GLTT_FALSE;
100
101 int resolution= 96;
102 if( ! instance->setResolutions(resolution,resolution) )
103 return GLTT_FALSE;
104
105 if( ! instance->setPointSize(point_size) )
106 return GLTT_FALSE;
107
108 // int pixel_size= resolution * point_size / 72;
109
110 font= new FTFont(instance);
111
112 if( ! font->create() )
113 return GLTT_FALSE;
114
115 list_base= glGenLists(256);
116 if( list_base == 0 )
117 return GLTT_FALSE;
118
119 loaded= new GLTTboolean [ 256 ];
120 for( int i= 0; i < 256; ++i )
121 loaded[i]= GLTT_FALSE;
122
123 return GLTT_TRUE;
124 }
125
126 /////////////////////////////////////////////////////////////////////////////
127
loadGlyph(int i)128 GLTTboolean GLTTOutlineFont::loadGlyph( int i )
129 {
130 if( i < 0 || i > 256 )
131 return GLTT_FALSE;
132 if( font == 0 || loaded == 0 )
133 return GLTT_FALSE;
134
135 if( loaded[i] )
136 return GLTT_TRUE;
137
138 loaded[i]= GLTT_TRUE;
139
140 FTGlyphVectorizer vectorizer;
141 vectorizer.setPrecision(precision);
142
143 int list= list_base + i;
144 FTGlyph* glyph= font->getGlyph(i);
145 if( glyph == 0 )
146 {
147 err:
148 glNewList(list,GL_COMPILE);
149 glEndList();
150 return GLTT_TRUE;
151 }
152
153 if( ! vectorizer.init(glyph) )
154 goto err;
155
156 vectorizer.vectorize();
157
158 glNewList(list,GL_COMPILE);
159
160 for( int j= 0; j < vectorizer.getNContours(); ++j )
161 {
162 FTGlyphVectorizer::Contour* contour= vectorizer.getContour(j);
163 if( contour == 0 )
164 continue;
165
166 if( contour->nPoints <= 0 )
167 continue;
168
169 glBegin(GL_LINE_LOOP);
170
171 for( int k= 0; k < contour->nPoints; ++k )
172 {
173 FTGlyphVectorizer::POINT& p= contour->points[k];
174
175 glVertex2f( p.x, p.y );
176 }
177
178 glEnd();
179 }
180
181 glTranslatef( vectorizer.getAdvance(), 0., 0. );
182 glEndList();
183
184 return GLTT_TRUE;
185 }
186
187 /////////////////////////////////////////////////////////////////////////////
188
load(int from,int to)189 void GLTTOutlineFont::load( int from /* = 0 */, int to /* = 255 */ )
190 {
191 for( int i= from; i <= to; ++i )
192 loadGlyph(i);
193 }
194
195 /////////////////////////////////////////////////////////////////////////////
196
load(const char * text)197 void GLTTOutlineFont::load( const char* text )
198 {
199 if( text == 0 || list_base == 0 )
200 return;
201
202 for(;;)
203 {
204 int ch= (unsigned char)*text;
205 if( ch == 0 )
206 break;
207 ++text;
208
209 if( ! loaded[ch] )
210 loadGlyph(ch);
211 }
212 }
213
214 /////////////////////////////////////////////////////////////////////////////
215
output(const char * text)216 void GLTTOutlineFont::output( const char* text )
217 {
218 if( text == 0 || list_base == 0 )
219 return;
220
221 glPushMatrix();
222
223 for(;;)
224 {
225 int ch= (unsigned char)*text;
226 if( ch == 0 )
227 break;
228 ++text;
229
230 if( ! loaded[ch] )
231 loadGlyph(ch);
232
233 glCallList( list_base + ch );
234 }
235
236 // glPushAttrib( GL_LIST_BIT );
237 // glListBase(list_base);
238 // glCallLists( strlen(text), GL_UNSIGNED_BYTE, (GLubyte*)text );
239 // glPopAttrib();
240
241 glPopMatrix();
242 }
243
244 /////////////////////////////////////////////////////////////////////////////
245
getHeight()246 int GLTTOutlineFont::getHeight() const
247 {
248 if( font == 0 )
249 return 0;
250
251 return font->getHeight();
252 }
253
254 /////////////////////////////////////////////////////////////////////////////
255
getDescender()256 int GLTTOutlineFont::getDescender() const
257 {
258 if( font == 0 )
259 return 0;
260
261 return font->getDescender();
262 }
263
264 /////////////////////////////////////////////////////////////////////////////
265
getWidth(const char * text)266 int GLTTOutlineFont::getWidth( const char* text )
267 {
268 if( font == 0 )
269 return 0;
270
271 return font->getWidth(text);
272 }
273
274 /////////////////////////////////////////////////////////////////////////////
275