1 /* 2 pygame - Python Game Library 3 Copyright (C) 2009 Vicent Marti 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 21 #ifndef _PYGAME_FREETYPE_WRAP_H_ 22 #define _PYGAME_FREETYPE_WRAP_H_ 23 24 #define PYGAME_FREETYPE_INTERNAL 25 #include "../_pygame.h" 26 #include "../freetype.h" 27 28 29 /********************************************************** 30 * Internal module defines 31 **********************************************************/ 32 33 /* Fixed point (26.6) math macros */ 34 #define FX6_ONE 64L 35 #define FX16_ONE 65536L 36 #define FX6_MAX (0x7FFFFFFFL) 37 #define FX6_MIN (~FX6_MAX) 38 39 #define FX6_FLOOR(x) ((x) & -64L) 40 #define FX6_CEIL(x) (((x) + 63L) & -64L) 41 #define FX6_ROUND(x) (((x) + 32L) & -64L) 42 #define FX6_TRUNC(x) ((x) >> 6) 43 #define FX16_CEIL_TO_FX6(x) (((x) + 1023L) >> 10) 44 #define FX16_ROUND_TO_INT(x) (((x) + 32768L) >> 16) 45 #define INT_TO_FX6(i) ((FT_Fixed)((i) << 6)) 46 #define INT_TO_FX16(i) ((FT_Fixed)((i) << 16)) 47 #define FX16_TO_DBL(x) ((x) * 1.52587890625e-5 /* 2.0^-16 */) 48 #define DBL_TO_FX16(d) ((FT_Fixed)((d) * 65536.0)) 49 #define FX6_TO_DBL(x) ((x) * 1.5625e-2 /* 2.0^-6 */) 50 #define DBL_TO_FX6(d) ((FT_Fixed)((d) * 64.0)) 51 52 /* Internal configuration variables */ 53 #define PGFT_DEFAULT_CACHE_SIZE 64 54 #define PGFT_MIN_CACHE_SIZE 32 55 #if defined(PGFT_DEBUG_CACHE) 56 #undef PGFT_DEBUG_CACHE 57 #endif 58 #define PGFT_DEFAULT_RESOLUTION 72 /* dots per inch */ 59 60 #define PGFT_DBL_DEFAULT_STRENGTH (1.0 / 36.0) 61 62 /* Rendering styles unsupported for bitmap fonts */ 63 #define FT_STYLES_SCALABLE_ONLY (FT_STYLE_STRONG | FT_STYLE_OBLIQUE) 64 65 /********************************************************** 66 * Internal basic types 67 **********************************************************/ 68 69 typedef FT_UInt32 PGFT_char; 70 typedef FT_UInt GlyphIndex_t; 71 72 73 /********************************************************** 74 * Internal data structures 75 **********************************************************/ 76 77 /* FreeTypeInstance: the global freetype 2 library state. 78 * 79 * Instances of this struct are created by _PGFT_Init, and 80 * destroyed by _PGFT_Quit. The instances are reference counted. 81 * When adding a local reference, be sure to increment ref_count; 82 * _PTFT_Init returns an instance with ref_count equal one. 83 * When removing a reference, call _PGFT_Quit, which will decrement 84 * the reference count and free the resource if the count reaches 85 * zero. 86 */ 87 typedef struct freetypeinstance_ { 88 Py_ssize_t ref_count; 89 90 /* Internal */ 91 FT_Library library; 92 FTC_Manager cache_manager; 93 FTC_CMapCache cache_charmap; 94 95 int cache_size; 96 char _error_msg[1024]; 97 } FreeTypeInstance; 98 99 typedef struct fontcolor_ { 100 FT_Byte r; 101 FT_Byte g; 102 FT_Byte b; 103 FT_Byte a; 104 } FontColor; 105 106 typedef struct rendermode_ { 107 Scale_t face_size; 108 FT_Angle rotation_angle; 109 FT_UInt16 render_flags; 110 FT_UInt16 style; 111 112 /* All these are Fixed 16.16 */ 113 FT_Fixed strength; 114 FT_Fixed underline_adjustment; 115 FT_Matrix transform; 116 } FontRenderMode; 117 118 #if defined(Py_DEBUG) && !defined(PGFT_DEBUG_CACHE) 119 #define PGFT_DEBUG_CACHE 1 120 #endif 121 122 struct cachenode_; 123 124 typedef struct fontcache_ { 125 struct cachenode_ **nodes; 126 struct cachenode_ *free_nodes; 127 128 FT_Byte *depths; 129 130 #ifdef PGFT_DEBUG_CACHE 131 FT_UInt32 _debug_count; 132 FT_UInt32 _debug_delete_count; 133 FT_UInt32 _debug_access; 134 FT_UInt32 _debug_hit; 135 FT_UInt32 _debug_miss; 136 #endif 137 138 FT_UInt32 size_mask; 139 } FontCache; 140 141 typedef struct fontmetrics_ { 142 /* All these are 26.6 precision */ 143 FT_Pos bearing_x; 144 FT_Pos bearing_y; 145 FT_Vector bearing_rotated; 146 FT_Vector advance_rotated; 147 } FontMetrics; 148 149 typedef struct fontglyph_ { 150 FT_BitmapGlyph image; 151 152 FT_Pos width; /* 26.6 */ 153 FT_Pos height; /* 26.6 */ 154 FontMetrics h_metrics; 155 FontMetrics v_metrics; 156 } FontGlyph; 157 158 typedef struct glyphslot_ { 159 GlyphIndex_t id; 160 FontGlyph *glyph; 161 FT_Vector posn; 162 FT_Vector kerning; 163 } GlyphSlot; 164 165 typedef struct layout_ { 166 FontRenderMode mode; 167 168 int length; 169 170 int top; /* In pixels */ 171 int left; /* In pixels */ 172 173 FT_Pos min_x; 174 FT_Pos max_x; 175 FT_Pos min_y; 176 FT_Pos max_y; 177 FT_Vector offset; 178 FT_Vector advance; 179 FT_Pos ascender; 180 FT_Pos descender; 181 FT_Pos height; 182 FT_Pos max_advance; 183 FT_Fixed underline_size; 184 FT_Pos underline_pos; 185 186 int buffer_size; 187 GlyphSlot *glyphs; 188 } Layout; 189 190 struct fontsurface_; 191 192 typedef void (* FontRenderPtr)(int, int, struct fontsurface_ *, 193 const FT_Bitmap *, const FontColor *); 194 typedef void (* FontFillPtr)(FT_Fixed, FT_Fixed, FT_Fixed, FT_Fixed, 195 struct fontsurface_ *, const FontColor *); 196 197 typedef struct fontsurface_ { 198 void *buffer; 199 200 unsigned width; 201 unsigned height; 202 int item_stride; 203 int pitch; 204 205 SDL_PixelFormat *format; 206 207 FontRenderPtr render_gray; 208 FontRenderPtr render_mono; 209 FontFillPtr fill; 210 211 } FontSurface; 212 213 typedef struct fontinternals_ { 214 Layout active_text; 215 FontCache glyph_cache; 216 } FontInternals; 217 218 typedef struct PGFT_String_ { 219 Py_ssize_t length; 220 PGFT_char data[1]; 221 } PGFT_String; 222 223 #if defined(PGFT_DEBUG_CACHE) 224 #define PGFT_FONT_CACHE(f) ((f)->_internals->glyph_cache) 225 #endif 226 227 /********************************************************** 228 * Module state 229 **********************************************************/ 230 typedef struct { 231 FreeTypeInstance *freetype; 232 int cache_size; 233 FT_UInt resolution; 234 } _FreeTypeState; 235 236 #if !defined(PYPY_VERSION) 237 extern struct PyModuleDef _freetypemodule; 238 # define FREETYPE_MOD_STATE(mod) ((_FreeTypeState*)PyModule_GetState(mod)) 239 # define FREETYPE_STATE \ 240 FREETYPE_MOD_STATE(PyState_FindModule(&_freetypemodule)) 241 #else /* !PY3 || defined(PYPY_VERSION) */ 242 extern _FreeTypeState _modstate; 243 # define FREETYPE_MOD_STATE(mod) (&_modstate) 244 # define FREETYPE_STATE FREETYPE_MOD_STATE(0) 245 #endif /* !PY3 || defined(PYPY_VERSION) */ 246 247 #define ASSERT_GRAB_FREETYPE(ft_ptr, rvalue) \ 248 ft_ptr = FREETYPE_STATE->freetype; \ 249 if (!ft_ptr) { \ 250 PyErr_SetString(PyExc_RuntimeError, \ 251 "The FreeType 2 library hasn't been initialized"); \ 252 return (rvalue); \ 253 } 254 255 256 257 258 /********************************************************** 259 * Internal API 260 **********************************************************/ 261 262 /**************************************** General functions ******************/ 263 const char *_PGFT_GetError(FreeTypeInstance *); 264 void _PGFT_Quit(FreeTypeInstance *); 265 int _PGFT_Init(FreeTypeInstance **, int); 266 long _PGFT_Font_GetAscender(FreeTypeInstance *, pgFontObject *); 267 long _PGFT_Font_GetAscenderSized(FreeTypeInstance *, pgFontObject *, 268 Scale_t); 269 long _PGFT_Font_GetDescender(FreeTypeInstance *, pgFontObject *); 270 long _PGFT_Font_GetDescenderSized(FreeTypeInstance *, pgFontObject *, 271 Scale_t); 272 long _PGFT_Font_GetHeight(FreeTypeInstance *, pgFontObject *); 273 long _PGFT_Font_GetHeightSized(FreeTypeInstance *, pgFontObject *, 274 Scale_t); 275 long _PGFT_Font_GetGlyphHeightSized(FreeTypeInstance *, pgFontObject *, 276 Scale_t); 277 int _PGFT_Font_IsFixedWidth(FreeTypeInstance *, pgFontObject *); 278 int _PGFT_Font_NumFixedSizes(FreeTypeInstance *, pgFontObject *); 279 int _PGFT_Font_GetAvailableSize(FreeTypeInstance *, pgFontObject *, long, 280 long *, long *, long *, double *, double *); 281 const char *_PGFT_Font_GetName(FreeTypeInstance *, pgFontObject *); 282 int _PGFT_TryLoadFont_Filename(FreeTypeInstance *, 283 pgFontObject *, const char *, long); 284 #ifdef HAVE_PYGAME_SDL_RWOPS 285 int _PGFT_TryLoadFont_RWops(FreeTypeInstance *, 286 pgFontObject *, SDL_RWops *, long); 287 SDL_RWops* _PGFT_GetRWops(pgFontObject *fontobj); 288 #endif 289 void _PGFT_UnloadFont(FreeTypeInstance *, pgFontObject *); 290 291 292 /**************************************** Metrics management *****************/ 293 int _PGFT_GetTextRect(FreeTypeInstance *, pgFontObject *, 294 const FontRenderMode *, PGFT_String *, 295 SDL_Rect *); 296 int _PGFT_GetMetrics(FreeTypeInstance *, pgFontObject *, 297 PGFT_char, const FontRenderMode *, 298 FT_UInt *, long *, long *, long *, long *, 299 double *, double *); 300 void _PGFT_GetRenderMetrics(const FontRenderMode *, Layout *, 301 unsigned *, unsigned *, FT_Vector *, 302 FT_Pos *, FT_Fixed *); 303 304 305 /**************************************** Rendering **************************/ 306 PyObject *_PGFT_Render_PixelArray(FreeTypeInstance *, pgFontObject *, 307 const FontRenderMode *, 308 PGFT_String *, int, int *, int *); 309 SDL_Surface *_PGFT_Render_NewSurface(FreeTypeInstance *, pgFontObject *, 310 const FontRenderMode *, PGFT_String *, 311 FontColor *, FontColor *, SDL_Rect *); 312 int _PGFT_Render_ExistingSurface(FreeTypeInstance *, pgFontObject *, 313 const FontRenderMode *, PGFT_String *, 314 SDL_Surface *, int, int, 315 FontColor *, FontColor *, SDL_Rect *); 316 int _PGFT_Render_Array(FreeTypeInstance *, pgFontObject *, 317 const FontRenderMode *, PyObject *, 318 PGFT_String *, int, int, int, SDL_Rect *); 319 int _PGFT_BuildRenderMode(FreeTypeInstance *, pgFontObject *, 320 FontRenderMode *, Scale_t, int, Angle_t); 321 int _PGFT_CheckStyle(FT_UInt32); 322 323 324 /**************************************** Render callbacks *******************/ 325 void __fill_glyph_RGB1(FT_Fixed, FT_Fixed, FT_Fixed, FT_Fixed, 326 FontSurface *, const FontColor *); 327 void __fill_glyph_RGB2(FT_Fixed, FT_Fixed, FT_Fixed, FT_Fixed, 328 FontSurface *, const FontColor *); 329 void __fill_glyph_RGB3(FT_Fixed, FT_Fixed, FT_Fixed, FT_Fixed, 330 FontSurface *, const FontColor *); 331 void __fill_glyph_RGB4(FT_Fixed, FT_Fixed, FT_Fixed, FT_Fixed, 332 FontSurface *, const FontColor *); 333 334 void __fill_glyph_GRAY1(FT_Fixed, FT_Fixed, FT_Fixed, FT_Fixed, 335 FontSurface *, const FontColor *); 336 337 void __fill_glyph_INT(FT_Fixed, FT_Fixed, FT_Fixed, FT_Fixed, 338 FontSurface *, const FontColor *); 339 340 void __render_glyph_MONO1(int, int, FontSurface *, const FT_Bitmap *, 341 const FontColor *); 342 void __render_glyph_MONO2(int, int, FontSurface *, const FT_Bitmap *, 343 const FontColor *); 344 void __render_glyph_MONO3(int, int, FontSurface *, const FT_Bitmap *, 345 const FontColor *); 346 void __render_glyph_MONO4(int, int, FontSurface *, const FT_Bitmap *, 347 const FontColor *); 348 349 void __render_glyph_RGB1(int, int, FontSurface *, const FT_Bitmap *, 350 const FontColor *); 351 void __render_glyph_RGB2(int, int, FontSurface *, const FT_Bitmap *, 352 const FontColor *); 353 void __render_glyph_RGB3(int, int, FontSurface *, const FT_Bitmap *, 354 const FontColor *); 355 void __render_glyph_RGB4(int, int, FontSurface *, const FT_Bitmap *, 356 const FontColor *); 357 358 void __render_glyph_GRAY1(int, int, FontSurface *, const FT_Bitmap *, 359 const FontColor *); 360 void __render_glyph_MONO_as_GRAY1(int, int, FontSurface *, const FT_Bitmap *, 361 const FontColor *); 362 void __render_glyph_GRAY_as_MONO1(int, int, FontSurface *, const FT_Bitmap *, 363 const FontColor *); 364 365 void __render_glyph_INT(int, int, FontSurface *, const FT_Bitmap *, 366 const FontColor *); 367 void __render_glyph_MONO_as_INT(int, int, FontSurface *, const FT_Bitmap *, 368 const FontColor *); 369 370 371 /**************************************** Layout management ******************/ 372 int _PGFT_LayoutInit(FreeTypeInstance *, pgFontObject *); 373 void _PGFT_LayoutFree(pgFontObject *); 374 Layout *_PGFT_LoadLayout(FreeTypeInstance *, pgFontObject *, 375 const FontRenderMode *, PGFT_String *); 376 int _PGFT_LoadGlyph(FontGlyph *, GlyphIndex_t, const FontRenderMode *, void *); 377 378 379 /**************************************** Glyph cache management *************/ 380 int _PGFT_Cache_Init(FreeTypeInstance *, FontCache *); 381 void _PGFT_Cache_Destroy(FontCache *); 382 void _PGFT_Cache_Cleanup(FontCache *); 383 FontGlyph *_PGFT_Cache_FindGlyph(FT_UInt32, const FontRenderMode *, 384 FontCache *, void *); 385 386 387 /**************************************** Unicode ****************************/ 388 PGFT_String *_PGFT_EncodePyString(PyObject *, int); 389 #define PGFT_String_GET_DATA(s) ((s)->data) 390 #define PGFT_String_GET_LENGTH(s) ((s)->length) 391 #define _PGFT_FreeString _PGFT_free 392 393 394 /**************************************** Internals **************************/ 395 void _PGFT_SetError(FreeTypeInstance *, const char *, FT_Error); 396 FT_Face _PGFT_GetFont(FreeTypeInstance *, pgFontObject *); 397 FT_Face _PGFT_GetFontSized(FreeTypeInstance *, pgFontObject *, Scale_t); 398 void _PGFT_BuildScaler(pgFontObject *, FTC_Scaler, Scale_t); 399 #define _PGFT_malloc PyMem_Malloc 400 #define _PGFT_free PyMem_Free 401 402 #endif 403