451ab91e |
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 <cmath> |
27 | #include <map> |
28 | #include <list> |
29 | #include <vector> |
30 | #include <wchar.h> |
31 | |
32 | #define GL_GLEXT_PROTOTYPES |
33 | #ifdef PANDORA |
34 | #include <SDL_opengles2.h> |
35 | #else |
36 | #include <SDL_opengl.h> |
37 | #endif |
38 | #if defined(__MACOSX__) |
39 | #include <OpenGL/glu.h> |
40 | #elif defined(__MACOS__) |
41 | #include <glu.h> |
42 | #elif defined(PANDORA) |
43 | #include <GLES2/glu.h> |
44 | #else |
45 | #include <GL/glu.h> |
46 | #endif |
47 | |
48 | #include <ft2build.h> |
49 | #include FT_FREETYPE_H |
50 | #include FT_GLYPH_H |
51 | #include FT_OUTLINE_H |
52 | #include FT_TRIGONOMETRY_H |
53 | |
54 | namespace OGLFT |
55 | { |
56 | enum Coordinates |
57 | { |
58 | X, Y, Z, W |
59 | }; |
60 | |
61 | enum ColorSpace |
62 | { |
63 | R, G, B, A |
64 | }; |
65 | |
66 | // global library functions |
67 | bool Init_FT(void); |
68 | bool Uninit_FT(void); |
69 | |
70 | struct Advance |
71 | { |
72 | float dx_; |
73 | float dy_; |
74 | |
75 | Advance ( float dx = 0, float dy = 0 ) : dx_( dx ), dy_( dy ) |
76 | { |
77 | return; |
78 | } |
79 | |
80 | Advance ( FT_Vector v ) |
81 | { |
82 | dx_ = (float) (v.x / 64.); |
83 | dy_ = (float) (v.y / 64.); |
84 | } |
85 | |
86 | Advance& operator+= ( const FT_Vector v ) |
87 | { |
88 | dx_ += (float) (v.x / 64.); |
89 | dy_ += (float) (v.y / 64.); |
90 | return *this; |
91 | } |
92 | }; |
93 | |
94 | struct BBox |
95 | { |
96 | float x_min_; |
97 | float y_min_; |
98 | float x_max_; |
99 | float y_max_; |
100 | Advance advance_; |
101 | |
102 | BBox () : x_min_( 0 ), y_min_( 0 ), x_max_( 0 ), y_max_( 0 ) |
103 | { |
104 | return; |
105 | } |
106 | BBox ( FT_BBox ft_bbox ) |
107 | { |
108 | x_min_ = (float) (ft_bbox.xMin / 64.); |
109 | y_min_ = (float) (ft_bbox.yMin / 64.); |
110 | x_max_ = (float) (ft_bbox.xMax / 64.); |
111 | y_max_ = (float) (ft_bbox.yMax / 64.); |
112 | } |
113 | BBox& operator*= ( double k ) |
114 | { |
115 | x_min_ *= (float) k; |
116 | y_min_ *= (float) k; |
117 | x_max_ *= (float) k; |
118 | y_max_ *= (float) k; |
119 | advance_.dx_ *= (float) k; |
120 | advance_.dy_ *= (float) k; |
121 | |
122 | return *this; |
123 | } |
124 | BBox& operator+= ( const BBox& b ) |
125 | { |
126 | float new_value; |
127 | |
128 | new_value = b.x_min_ + advance_.dx_; |
129 | if ( new_value < x_min_ ) x_min_ = new_value; |
130 | new_value = b.y_min_ + advance_.dy_; |
131 | if ( new_value < y_min_ ) y_min_ = new_value; |
132 | new_value = b.x_max_ + advance_.dx_; |
133 | if ( new_value > x_max_ ) x_max_ = new_value; |
134 | new_value = b.y_max_ + advance_.dy_; |
135 | if ( new_value > y_max_ ) y_max_ = new_value; |
136 | |
137 | advance_.dx_ += b.advance_.dx_; |
138 | advance_.dy_ += b.advance_.dy_; |
139 | |
140 | return *this; |
141 | } |
142 | }; |
143 | typedef std::vector<GLuint> DisplayLists; |
144 | typedef DisplayLists::const_iterator DLCI; |
145 | typedef DisplayLists::iterator DLI; |
146 | class Face |
147 | { |
148 | public: |
149 | enum HorizontalJustification |
150 | { |
151 | LEFT, |
152 | ORIGIN, |
153 | CENTER, |
154 | RIGHT |
155 | }; |
156 | |
157 | enum VerticalJustification |
158 | { |
159 | BOTTOM, |
160 | BASELINE, |
161 | MIDDLE, |
162 | TOP |
163 | }; |
164 | |
165 | enum GlyphCompileMode |
166 | { |
167 | COMPILE, |
168 | IMMEDIATE |
169 | }; |
170 | |
171 | private: |
172 | struct FaceData |
173 | { |
174 | FT_Face face_; |
175 | bool free_on_exit_; |
176 | FaceData ( FT_Face face, bool free_on_exit = true ) |
177 | : face_( face ), free_on_exit_( free_on_exit ) |
178 | { |
179 | return; |
180 | } |
181 | }; |
182 | |
183 | protected: |
184 | std::vector< FaceData > faces_; |
185 | bool valid_; |
186 | enum GlyphCompileMode compile_mode_; |
187 | float point_size_; |
188 | FT_UInt resolution_; |
189 | bool advance_; |
190 | GLfloat foreground_color_[4]; |
191 | GLfloat background_color_[4]; |
192 | enum HorizontalJustification horizontal_justification_; |
193 | enum VerticalJustification vertical_justification_; |
194 | GLfloat string_rotation_; |
195 | FT_UInt rotation_reference_glyph_; |
196 | FT_Face rotation_reference_face_; |
197 | GLfloat rotation_offset_y_; |
198 | typedef std::map< FT_UInt, GLuint > GlyphDLists; |
199 | typedef GlyphDLists::const_iterator GDLCI; |
200 | typedef GlyphDLists::iterator GDLI; |
201 | GlyphDLists glyph_dlists_; |
202 | DisplayLists character_display_lists_; |
203 | |
204 | public: |
205 | Face ( const char* filename, float point_size = 12, FT_UInt resolution = 100 ); |
206 | Face ( FT_Face face, float point_size = 12, FT_UInt resolution = 100 ); |
207 | virtual ~Face ( void ); |
208 | bool isValid ( void ) const { return valid_; } |
209 | bool addAuxiliaryFace ( const char* filename ); |
210 | bool addAuxiliaryFace ( FT_Face face ); |
211 | void setCompileMode ( enum GlyphCompileMode compile_mode ) { compile_mode_ = compile_mode; } |
212 | enum GlyphCompileMode compileMode ( void ) const { return compile_mode_; } |
213 | void setPointSize ( float point_size ); |
214 | float pointSize ( void ) { return point_size_; } |
215 | void setResolution ( FT_UInt resolution ); |
216 | FT_UInt resolution ( void ) { return resolution_; } |
217 | void setAdvance ( bool advance ) { advance_ = advance; } |
218 | bool advance ( void ) const { return advance_; } |
219 | void setForegroundColor ( GLfloat red = 0.0, GLfloat green = 0.0, GLfloat blue = 0.0, GLfloat alpha = 1.0 ); |
220 | void setForegroundColor ( const GLfloat foreground_color[4] ); |
221 | GLfloat foregroundRed ( void ) const { return foreground_color_[R]; } |
222 | GLfloat foregroundGreen ( void ) const { return foreground_color_[G]; } |
223 | GLfloat foregroundBlue ( void ) const { return foreground_color_[B]; } |
224 | GLfloat foregroundAlpha ( void ) const { return foreground_color_[A]; } |
225 | void setBackgroundColor ( GLfloat red = 1.0, GLfloat green = 1.0, GLfloat blue = 1.0, GLfloat alpha = 0.0 ); |
226 | void setBackgroundColor ( const GLfloat background_color[4] ); |
227 | GLfloat backgroundRed ( void ) const { return background_color_[R]; } |
228 | GLfloat backgroundGreen ( void ) const { return background_color_[G]; } |
229 | GLfloat backgroundBlue ( void ) const { return background_color_[B]; } |
230 | GLfloat backgroundAlpha ( void ) const { return background_color_[A]; } |
231 | virtual void setCharacterRotationZ ( GLfloat character_rotation_z ) = 0; |
232 | virtual GLfloat characterRotationZ ( void ) const = 0; |
233 | void setCharacterRotationReference ( unsigned char c ); |
234 | void setStringRotation ( GLfloat string_rotation ); |
235 | GLfloat stringRotation ( void ) const { return string_rotation_; } |
236 | void setHorizontalJustification ( enum HorizontalJustification horizontal_justification ) |
237 | { |
238 | horizontal_justification_ = horizontal_justification; |
239 | } |
240 | enum HorizontalJustification horizontalJustification ( void ) const { return horizontal_justification_; } |
241 | void setVerticalJustification ( enum VerticalJustification vertical_justification ) |
242 | { |
243 | vertical_justification_ = vertical_justification; |
244 | } |
245 | |
246 | enum VerticalJustification verticaljustification ( void ) const { return vertical_justification_; } |
247 | void setCharacterDisplayLists ( const DisplayLists& character_display_lists ) { character_display_lists_ = character_display_lists; } |
248 | DisplayLists& characterDisplayLists ( void ) { return character_display_lists_; } |
249 | virtual double height ( void ) const = 0; |
250 | virtual BBox measure ( unsigned char c ) = 0; |
251 | virtual BBox measure ( wchar_t c ) = 0; |
252 | virtual BBox measure ( const char* s ); |
253 | virtual BBox measureRaw ( const char* s ); |
254 | virtual BBox measure ( const wchar_t* s ); |
255 | virtual BBox measure ( const wchar_t* format, double number ); |
256 | virtual BBox measureRaw ( const wchar_t* s ); |
257 | GLuint compile ( unsigned char c ); |
258 | GLuint compile ( const wchar_t c ); |
259 | void draw ( const char* s ); |
260 | void draw ( const wchar_t* s ); |
261 | void draw ( unsigned char c ); |
262 | void draw ( const wchar_t c ); |
263 | void draw ( GLfloat x, GLfloat y, unsigned char c ); |
264 | void draw ( GLfloat x, GLfloat y, GLfloat z, unsigned char c ); |
265 | void draw ( GLfloat x, GLfloat y, wchar_t c ); |
266 | void draw ( GLfloat x, GLfloat y, GLfloat z, wchar_t c ); |
267 | void draw ( GLfloat x, GLfloat y, const char* s, float *sizebox ); |
268 | void draw ( GLfloat x, GLfloat y, GLfloat z, const char* s ); |
269 | void draw ( GLfloat x, GLfloat y, const wchar_t* s ); |
270 | void draw ( GLfloat x, GLfloat y, GLfloat z, const wchar_t* s ); |
271 | int ascender ( void ) { return faces_.front().face_->ascender; } |
272 | int descender ( void ) { return faces_.front().face_->descender; } |
273 | BBox measure_nominal ( const char* s ); |
274 | BBox measure_nominal ( const wchar_t* s ); |
275 | |
276 | protected: |
277 | virtual GLuint compileGlyph ( FT_Face face, FT_UInt glyph_index ) = 0; |
278 | virtual void renderGlyph ( FT_Face face, FT_UInt glyph_index ) = 0; |
279 | virtual void setCharSize ( void ) = 0; |
280 | virtual void clearCaches ( void ) = 0; |
281 | virtual void setRotationOffset ( void ) = 0; |
282 | |
283 | private: |
284 | void init ( void ); |
285 | }; |
286 | |
287 | class Raster : public Face |
288 | { |
289 | protected: |
290 | GLfloat character_rotation_z_; |
291 | public: |
292 | Raster ( const char* filename, float point_size = 12, FT_UInt resolution = 100 ); |
293 | Raster ( FT_Face face, float point_size = 12, FT_UInt resolution = 100 ); |
294 | virtual ~Raster ( void ); |
295 | void setCharacterRotationZ ( GLfloat character_rotation_z ); |
296 | GLfloat characterRotationZ ( void ) const { return character_rotation_z_; } |
297 | double height ( void ) const; |
298 | BBox measure ( unsigned char c ); |
299 | BBox measure ( wchar_t c ); |
300 | BBox measure ( const char* s ) { return Face::measure( s ); } |
301 | BBox measure ( const wchar_t* format, double number ) { return Face::measure( format, number ); } |
302 | |
303 | private: |
304 | void init ( void ); |
305 | GLuint compileGlyph ( FT_Face face, FT_UInt glyph_index ); |
306 | void setCharSize ( void ); |
307 | void setRotationOffset ( void ); |
308 | void clearCaches ( void ); |
309 | }; |
310 | class Monochrome : public Raster |
311 | { |
312 | public: |
313 | Monochrome ( const char* filename, float point_size = 12, FT_UInt resolution = 100 ); |
314 | Monochrome ( FT_Face face, float point_size = 12, FT_UInt resolution = 100 ); |
315 | ~Monochrome ( void ); |
316 | |
317 | private: |
318 | GLubyte* invertBitmap ( const FT_Bitmap& bitmap ); |
319 | void renderGlyph ( FT_Face face, FT_UInt glyph_index ); |
320 | }; |
321 | |
322 | } |
323 | #endif /* OGLFT_H */ |
324 | |