1// -*- c++ -*-
2/*
3 * OGLFT: A library for drawing text with OpenGL using the FreeType library
4 * Copyright (C) 2002 lignum Computing, Inc. <oglft@lignumcomputing.com>
5 * $Id: OGLFT.h,v 1.15 2003/10/01 14:41:09 allen Exp $
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write
19 * Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#ifndef OGLFT_H
24#define OGLFT_H
25
26#include <wchar.h>
27#include <cmath>
28#include <list>
29#include <map>
30#include <vector>
31
32#define GL_GLEXT_PROTOTYPES
33#include <SDL_opengl.h>
34#if defined(__MACOSX__)
35#include <OpenGL/glu.h>
36#elif defined(__MACOS__)
37#include <glu.h>
38#else
39#include <GL/glu.h>
40#endif
41
42#include <ft2build.h>
43
44#include FT_FREETYPE_H
45#include FT_GLYPH_H
46#include FT_OUTLINE_H
47#include FT_TRIGONOMETRY_H
48
49namespace OGLFT
50{
51 enum Coordinates
52 {
53 X, Y, Z, W
54 };
55
56 enum ColorSpace
57 {
58 R, G, B, A
59 };
60
61 // global library functions
62 bool Init_FT(void);
63 bool Uninit_FT(void);
64
65 struct Advance
66 {
67 float dx_;
68 float dy_;
69
70 Advance ( float dx = 0, float dy = 0 ) : dx_( dx ), dy_( dy )
71 {
72 return;
73 }
74
75 Advance ( FT_Vector v )
76 {
77 dx_ = (float) (v.x / 64.);
78 dy_ = (float) (v.y / 64.);
79 }
80
81 Advance& operator+= ( const FT_Vector v )
82 {
83 dx_ += (float) (v.x / 64.);
84 dy_ += (float) (v.y / 64.);
85 return *this;
86 }
87 };
88
89 struct BBox
90 {
91 float x_min_;
92 float y_min_;
93 float x_max_;
94 float y_max_;
95 Advance advance_;
96
97 BBox () : x_min_( 0 ), y_min_( 0 ), x_max_( 0 ), y_max_( 0 )
98 {
99 return;
100 }
101 BBox ( FT_BBox ft_bbox )
102 {
103 x_min_ = (float) (ft_bbox.xMin / 64.);
104 y_min_ = (float) (ft_bbox.yMin / 64.);
105 x_max_ = (float) (ft_bbox.xMax / 64.);
106 y_max_ = (float) (ft_bbox.yMax / 64.);
107 }
108 BBox& operator*= ( double k )
109 {
110 x_min_ *= (float) k;
111 y_min_ *= (float) k;
112 x_max_ *= (float) k;
113 y_max_ *= (float) k;
114 advance_.dx_ *= (float) k;
115 advance_.dy_ *= (float) k;
116
117 return *this;
118 }
119 BBox& operator+= ( const BBox& b )
120 {
121 float new_value;
122
123 new_value = b.x_min_ + advance_.dx_;
124 if ( new_value < x_min_ ) x_min_ = new_value;
125 new_value = b.y_min_ + advance_.dy_;
126 if ( new_value < y_min_ ) y_min_ = new_value;
127 new_value = b.x_max_ + advance_.dx_;
128 if ( new_value > x_max_ ) x_max_ = new_value;
129 new_value = b.y_max_ + advance_.dy_;
130 if ( new_value > y_max_ ) y_max_ = new_value;
131
132 advance_.dx_ += b.advance_.dx_;
133 advance_.dy_ += b.advance_.dy_;
134
135 return *this;
136 }
137 };
138 typedef std::vector<GLuint> DisplayLists;
139 typedef DisplayLists::const_iterator DLCI;
140 typedef DisplayLists::iterator DLI;
141 class Face
142 {
143 public:
144 enum HorizontalJustification
145 {
146 LEFT,
147 ORIGIN,
148 CENTER,
149 RIGHT
150 };
151
152 enum VerticalJustification
153 {
154 BOTTOM,
155 BASELINE,
156 MIDDLE,
157 TOP
158 };
159
160 enum GlyphCompileMode
161 {
162 COMPILE,
163 IMMEDIATE
164 };
165
166 private:
167 struct FaceData
168 {
169 FT_Face face_;
170 bool free_on_exit_;
171 FaceData ( FT_Face face, bool free_on_exit = true )
172 : face_( face ), free_on_exit_( free_on_exit )
173 {
174 return;
175 }
176 };
177
178 protected:
179 std::vector< FaceData > faces_;
180 bool valid_;
181 enum GlyphCompileMode compile_mode_;
182 float point_size_;
183 FT_UInt resolution_;
184 bool advance_;
185 GLfloat foreground_color_[4];
186 GLfloat background_color_[4];
187 enum HorizontalJustification horizontal_justification_;
188 enum VerticalJustification vertical_justification_;
189 GLfloat string_rotation_;
190 FT_UInt rotation_reference_glyph_;
191 FT_Face rotation_reference_face_;
192 GLfloat rotation_offset_y_;
193 typedef std::map< FT_UInt, GLuint > GlyphDLists;
194 typedef GlyphDLists::const_iterator GDLCI;
195 typedef GlyphDLists::iterator GDLI;
196 GlyphDLists glyph_dlists_;
197 DisplayLists character_display_lists_;
198
199 public:
200 Face ( const char* filename, float point_size = 12, FT_UInt resolution = 100 );
201 Face ( FT_Face face, float point_size = 12, FT_UInt resolution = 100 );
202 virtual ~Face ( void );
203 bool isValid ( void ) const { return valid_; }
204 bool addAuxiliaryFace ( const char* filename );
205 bool addAuxiliaryFace ( FT_Face face );
206 void setCompileMode ( enum GlyphCompileMode compile_mode ) { compile_mode_ = compile_mode; }
207 enum GlyphCompileMode compileMode ( void ) const { return compile_mode_; }
208 void setPointSize ( float point_size );
209 float pointSize ( void ) { return point_size_; }
210 void setResolution ( FT_UInt resolution );
211 FT_UInt resolution ( void ) { return resolution_; }
212 void setAdvance ( bool advance ) { advance_ = advance; }
213 bool advance ( void ) const { return advance_; }
214 void setForegroundColor ( GLfloat red = 0.0, GLfloat green = 0.0, GLfloat blue = 0.0, GLfloat alpha = 1.0 );
215 void setForegroundColor ( const GLfloat foreground_color[4] );
216 GLfloat foregroundRed ( void ) const { return foreground_color_[R]; }
217 GLfloat foregroundGreen ( void ) const { return foreground_color_[G]; }
218 GLfloat foregroundBlue ( void ) const { return foreground_color_[B]; }
219 GLfloat foregroundAlpha ( void ) const { return foreground_color_[A]; }
220 void setBackgroundColor ( GLfloat red = 1.0, GLfloat green = 1.0, GLfloat blue = 1.0, GLfloat alpha = 0.0 );
221 void setBackgroundColor ( const GLfloat background_color[4] );
222 GLfloat backgroundRed ( void ) const { return background_color_[R]; }
223 GLfloat backgroundGreen ( void ) const { return background_color_[G]; }
224 GLfloat backgroundBlue ( void ) const { return background_color_[B]; }
225 GLfloat backgroundAlpha ( void ) const { return background_color_[A]; }
226 virtual void setCharacterRotationZ ( GLfloat character_rotation_z ) = 0;
227 virtual GLfloat characterRotationZ ( void ) const = 0;
228 void setCharacterRotationReference ( unsigned char c );
229 void setStringRotation ( GLfloat string_rotation );
230 GLfloat stringRotation ( void ) const { return string_rotation_; }
231 void setHorizontalJustification ( enum HorizontalJustification horizontal_justification )
232 {
233 horizontal_justification_ = horizontal_justification;
234 }
235 enum HorizontalJustification horizontalJustification ( void ) const { return horizontal_justification_; }
236 void setVerticalJustification ( enum VerticalJustification vertical_justification )
237 {
238 vertical_justification_ = vertical_justification;
239 }
240
241 enum VerticalJustification verticaljustification ( void ) const { return vertical_justification_; }
242 void setCharacterDisplayLists ( const DisplayLists& character_display_lists ) { character_display_lists_ = character_display_lists; }
243 DisplayLists& characterDisplayLists ( void ) { return character_display_lists_; }
244 virtual double height ( void ) const = 0;
245 virtual BBox measure ( unsigned char c ) = 0;
246 virtual BBox measure ( wchar_t c ) = 0;
247 virtual BBox measure ( const char* s );
248 virtual BBox measureRaw ( const char* s );
249 virtual BBox measure ( const wchar_t* s );
250 virtual BBox measureRaw ( const wchar_t* s );
251 GLuint compile ( unsigned char c );
252 GLuint compile ( const wchar_t c );
253 void draw ( const char* s );
254 void draw ( const wchar_t* s );
255 void draw ( unsigned char c );
256 void draw ( const wchar_t c );
257 void draw ( GLfloat x, GLfloat y, unsigned char c );
258 void draw ( GLfloat x, GLfloat y, GLfloat z, unsigned char c );
259 void draw ( GLfloat x, GLfloat y, wchar_t c );
260 void draw ( GLfloat x, GLfloat y, GLfloat z, wchar_t c );
261 void draw ( GLfloat x, GLfloat y, const char* s, float *sizebox );
262 void draw ( GLfloat x, GLfloat y, GLfloat z, const char* s );
263 void draw ( GLfloat x, GLfloat y, const wchar_t* s );
264 void draw ( GLfloat x, GLfloat y, GLfloat z, const wchar_t* s );
265 int ascender ( void ) { return faces_.front().face_->ascender; }
266 int descender ( void ) { return faces_.front().face_->descender; }
267 BBox measure_nominal ( const char* s );
268 BBox measure_nominal ( const wchar_t* s );
269
270 protected:
271 virtual GLuint compileGlyph ( FT_Face face, FT_UInt glyph_index ) = 0;
272 virtual void renderGlyph ( FT_Face face, FT_UInt glyph_index ) = 0;
273 virtual void setCharSize ( void ) = 0;
274 virtual void clearCaches ( void ) = 0;
275 virtual void setRotationOffset ( void ) = 0;
276
277 private:
278 void init ( void );
279 };
280
281 class Raster : public Face
282 {
283 protected:
284 GLfloat character_rotation_z_;
285 public:
286 Raster ( const char* filename, float point_size = 12, FT_UInt resolution = 100 );
287 Raster ( FT_Face face, float point_size = 12, FT_UInt resolution = 100 );
288 virtual ~Raster ( void );
289 void setCharacterRotationZ ( GLfloat character_rotation_z );
290 GLfloat characterRotationZ ( void ) const { return character_rotation_z_; }
291 double height ( void ) const;
292 BBox measure ( unsigned char c );
293 BBox measure ( wchar_t c );
294 BBox measure ( const char* s ) { return Face::measure( s ); }
295
296 private:
297 void init ( void );
298 GLuint compileGlyph ( FT_Face face, FT_UInt glyph_index );
299 void setCharSize ( void );
300 void setRotationOffset ( void );
301 void clearCaches ( void );
302 };
303 class Monochrome : public Raster
304 {
305 public:
306 Monochrome ( const char* filename, float point_size = 12, FT_UInt resolution = 100 );
307 Monochrome ( FT_Face face, float point_size = 12, FT_UInt resolution = 100 );
308 ~Monochrome ( void );
309
310 private:
311 GLubyte* invertBitmap ( const FT_Bitmap& bitmap );
312 void renderGlyph ( FT_Face face, FT_UInt glyph_index );
313 };
314
315}
316#endif /* OGLFT_H */
317
318