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 | |
49 | namespace 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 | |