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