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 "GLTTPixmapFont.h"
21 
22 #include "FTPixmapFont.h"
23 #include "FTInstance.h"
24 #include "FTGlyph.h"
25 #include "FTGlyphPixmap.h"
26 
27 #ifdef WIN32
28 #include <windows.h>
29 #endif
30 
31 #ifdef LOCAL_GL_HEADER
32   #include "local_gl.h"
33 #else
34   #include <GL/gl.h>
35 #endif
36 
37 /////////////////////////////////////////////////////////////////////////////
38 
GLTTPixmapFont(FTFace * _face)39 GLTTPixmapFont::GLTTPixmapFont( FTFace* _face )
40 {
41   face= _face;
42 
43   instance= 0;
44 
45   pixmaps= 0;
46   pixmaps= 0;
47 }
48 
49 /////////////////////////////////////////////////////////////////////////////
50 
~GLTTPixmapFont()51 GLTTPixmapFont::~GLTTPixmapFont()
52 {
53   destroy();
54 
55   face= 0;
56 }
57 
58 /////////////////////////////////////////////////////////////////////////////
59 
destroy()60 void GLTTPixmapFont::destroy()
61 {
62   delete pixmaps;
63   pixmaps= 0;
64 
65   delete pixmaps;
66   pixmaps= 0;
67 
68   delete instance;
69   instance= 0;
70 }
71 
72 /////////////////////////////////////////////////////////////////////////////
73 
create(int point_size)74 GLTTboolean GLTTPixmapFont::create( int point_size )
75 {
76   destroy();
77 
78   if( point_size < 1 )
79     point_size= 1;
80 
81   instance= new FTInstance(face);
82 
83   if( ! instance->create() )
84     return GLTT_FALSE;
85 
86   if( ! instance->setResolutions(96,96) )
87     return GLTT_FALSE;
88 
89   if( ! instance->setPointSize(point_size) )
90     return GLTT_FALSE;
91 
92   pixmaps= new FTPixmapFont(instance);
93 
94   if( ! pixmaps->create() )
95     return GLTT_FALSE;
96 
97   return GLTT_TRUE;
98 }
99 
100 /////////////////////////////////////////////////////////////////////////////
101 
output(int x,int y,const char * text)102 void GLTTPixmapFont::output( int x, int y, const char* text )
103 {
104   if( text == 0 || pixmaps == 0 )
105     return;
106 
107   glRasterPos2i( x, y );
108 
109   GLboolean position_valid;
110   glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &position_valid);
111   if( !position_valid )
112     {
113     glRasterPos2i(0,0);
114 
115     glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &position_valid);
116     if( !position_valid )
117       return;
118 
119     glBitmap(0, 0, 0, 0, x, y, (const GLubyte *)0);
120     }
121 
122   output(text);
123 }
124 
125 /////////////////////////////////////////////////////////////////////////////
126 
output(const char * text)127 void GLTTPixmapFont::output( const char* text )
128 {
129   if( text == 0 || pixmaps == 0 )
130     return;
131 
132   GLfloat color[4];
133   glGetFloatv( GL_CURRENT_COLOR, color );
134   unsigned char r= (unsigned char)(color[0] * 255.);
135   unsigned char g= (unsigned char)(color[1] * 255.);
136   unsigned char b= (unsigned char)(color[2] * 255.);
137   unsigned char a= (unsigned char)(color[3] * 255.);
138 
139   GLint swapbytes, lsbfirst, rowlength;
140   GLint skiprows, skippixels, alignment;
141 
142   // Save the current packing mode for bitmaps.
143   glGetIntegerv( GL_UNPACK_SWAP_BYTES, &swapbytes );
144   glGetIntegerv( GL_UNPACK_LSB_FIRST, &lsbfirst );
145   glGetIntegerv( GL_UNPACK_ROW_LENGTH, &rowlength );
146   glGetIntegerv( GL_UNPACK_SKIP_ROWS, &skiprows );
147   glGetIntegerv( GL_UNPACK_SKIP_PIXELS, &skippixels );
148   glGetIntegerv( GL_UNPACK_ALIGNMENT, &alignment );
149 
150   // Enforce a standard packing mode
151   glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
152   glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
153   glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
154   glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
155 
156   glPushAttrib(GL_ENABLE_BIT);
157   glPushAttrib(GL_PIXEL_MODE_BIT);
158 
159   glPixelZoom(1.,1.);
160   glPixelTransferf( GL_RED_SCALE,   1. );
161   glPixelTransferf( GL_GREEN_SCALE, 1. );
162   glPixelTransferf( GL_BLUE_SCALE,  1. );
163   glPixelTransferf( GL_ALPHA_SCALE, 1. );
164   glPixelTransferf( GL_RED_BIAS,    0. );
165   glPixelTransferf( GL_GREEN_BIAS,  0. );
166   glPixelTransferf( GL_BLUE_BIAS,   0. );
167   glPixelTransferf( GL_ALPHA_BIAS,  0. );
168 
169 //  glPushAttrib(GL_COLOR_BUFFER_BIT); // for glEnable(GL_ALPHA_TEST)
170 //  glEnable(GL_ALPHA_TEST);
171 //  glAlphaFunc( GL_GEQUAL, 0.1 );
172   glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
173 
174   for(;;)
175     {
176     int ch= (unsigned char)*text;
177     if( ch == 0 )
178       break;
179     ++text;
180 
181     FTGlyphPixmap* gpixmap= pixmaps->getPixmap(ch);
182     if( gpixmap == 0 )
183       continue;
184 
185     unsigned char* data= gpixmap->getPixmap(r,g,b,a);
186     glBitmap( 0, 0,
187               0.0, 0.0,
188               GLfloat(gpixmap->getDeltaX())/64.0,
189               GLfloat(gpixmap->getDeltaY())/64.0,
190               (const GLubyte *)0 );
191     if( data != 0 )
192       {
193       glPixelStorei( GL_UNPACK_ROW_LENGTH,
194                      gpixmap->getPixmapAllocatedWidth() );
195 
196       glDrawPixels( gpixmap->getPixmapWidth(),
197                     gpixmap->getPixmapHeight(),
198                     GL_RGBA,
199                     GL_UNSIGNED_BYTE,
200                     (const GLvoid*) data );
201       }
202 
203     glBitmap( 0, 0,
204               0.0, 0.0,
205               GLfloat(gpixmap->getAdvance()-gpixmap->getDeltaX())/64.0,
206               GLfloat(gpixmap->getDeltaY())/-64.0,
207               (const GLubyte *)0 );
208     }
209 
210 //  glPopAttrib(); // GL_COLOR_BUFFER_BIT
211   glPopAttrib(); // GL_PIXEL_MODE_BIT
212   glPopAttrib(); // GL_ENABLE_BIT
213 
214   // Restore saved packing modes.
215   glPixelStorei( GL_UNPACK_SWAP_BYTES, swapbytes );
216   glPixelStorei( GL_UNPACK_LSB_FIRST, lsbfirst );
217   glPixelStorei( GL_UNPACK_ROW_LENGTH, rowlength );
218   glPixelStorei( GL_UNPACK_SKIP_ROWS, skiprows );
219   glPixelStorei( GL_UNPACK_SKIP_PIXELS, skippixels );
220   glPixelStorei( GL_UNPACK_ALIGNMENT, alignment );
221 }
222 
223 /////////////////////////////////////////////////////////////////////////////
224 
getWidth(const char * text)225 int GLTTPixmapFont::getWidth( const char* text )
226 {
227   if( pixmaps == 0 )
228     return 0;
229 
230   return pixmaps->getWidth(text);
231 }
232 
233 /////////////////////////////////////////////////////////////////////////////
234 
getHeight()235 int GLTTPixmapFont::getHeight() const
236 {
237   if( instance == 0 )
238     return 0;
239 
240   return instance->getHeight();
241 }
242 
243 /////////////////////////////////////////////////////////////////////////////
244 
getDescender()245 int GLTTPixmapFont::getDescender() const
246 {
247   if( instance == 0 )
248     return 0;
249 
250   return instance->getDescender();
251 }
252 
253 /////////////////////////////////////////////////////////////////////////////
254