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