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