1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #else /* No config.h? Hmm. Assume the freetype library is available for linking. */
36 #define FREETYPEGLUE_ASSUME_FREETYPE 1
37 #endif /* !HAVE_CONFIG_H */
38
39 #include <cassert>
40 #include <cstdlib>
41 #include <cstring>
42 #include <cstdio>
43
44 #include <cmath>
45 #include <cstddef>
46
47 #include <sys/stat.h>
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif /* HAVE_UNISTD_H */
51 #ifdef HAVE_SYS_TYPES_H
52 #include <sys/types.h>
53 #endif /* HAVE_SYS_TYPES_H */
54
55 #ifdef HAVE_FONTCONFIG
56 #include <fontconfig/fontconfig.h>
57 #endif
58
59 #ifdef HAVE_FREETYPE /* In case we're _not_ doing runtime linking. */
60 #define FREETYPEGLUE_ASSUME_FREETYPE 1
61 #include <ft2build.h>
62 #include <freetype/freetype.h>
63 #include <freetype/ftglyph.h>
64 #include <freetype/ftoutln.h>
65 #endif /* FREETYPEGLUE_ASSUME_FREETYPE */
66
67 #include <Inventor/C/basic.h>
68 #include <Inventor/C/glue/dl.h>
69 #include <Inventor/C/tidbits.h>
70 #include <Inventor/C/errors/debugerror.h>
71
72 #include "tidbitsp.h"
73 #include "glue/freetype.h"
74 #include "threads/threadsutilp.h"
75
76 typedef int (*cc_fcglue_FcGetVersion_t)(void);
77 typedef FcPattern * (*cc_fcglue_FcNameParse_t)(const unsigned char * name);
78 typedef int (*cc_fcglue_FcConfigSubstitute_t)(void * config, FcPattern * p, FcMatchKind kind);
79 typedef void (*cc_fcglue_FcDefaultSubstitute_t)(FcPattern *pattern);
80 typedef FcPattern * (*cc_fcglue_FcFontMatch_t)(void * config, FcPattern * p, FcResult * result);
81 typedef FcResult (*cc_fcglue_FcPatternGetString_t)(const FcPattern * p, const char * object, int n, unsigned char ** s);
82 typedef void (*cc_fcglue_FcPatternDestroy_t)(FcPattern * p);
83 typedef void (*cc_fcglue_FcPatternPrint_t)(const FcPattern * p);
84 typedef int (*cc_fcglue_FcPatternAddDouble_t)(FcPattern *p, const char *object, double d);
85
86 typedef struct {
87 int available;
88 cc_fcglue_FcGetVersion_t FcGetVersion;
89 cc_fcglue_FcNameParse_t FcNameParse;
90 cc_fcglue_FcConfigSubstitute_t FcConfigSubstitute;
91 cc_fcglue_FcDefaultSubstitute_t FcDefaultSubstitute;
92 cc_fcglue_FcFontMatch_t FcFontMatch;
93 cc_fcglue_FcPatternGetString_t FcPatternGetString;
94 cc_fcglue_FcPatternDestroy_t FcPatternDestroy;
95 cc_fcglue_FcPatternPrint_t FcPatternPrint;
96 cc_fcglue_FcPatternAddDouble_t FcPatternAddDouble;
97 } cc_fcglue_t;
98
99 typedef FT_Error (*cc_ftglue_FT_Init_FreeType_t)(FT_Library * library);
100 typedef void (*cc_ftglue_FT_Library_Version_t)(void * library, int * major, int * minor, int * patch);
101 typedef FT_Error (*cc_ftglue_FT_Done_FreeType_t)(void * library);
102 typedef FT_Error (*cc_ftglue_FT_New_Face_t)(void * library, const char * filepathname, long faceindex, FT_Face * face);
103 typedef FT_Error (*cc_ftglue_FT_Done_Face_t)(void * face);
104 typedef FT_Error (*cc_ftglue_FT_Select_Charmap_t)(FT_Face face, int encoding);
105 typedef FT_Error (*cc_ftglue_FT_Set_Char_Size_t)(FT_Face face, long width, long height, unsigned int hres, unsigned int vres);
106 typedef void (*cc_ftglue_FT_Set_Transform_t)(FT_Face face, FT_Matrix * matrix, FT_Vector * delta);
107 typedef FT_UInt (*cc_ftglue_FT_Get_Char_Index_t)(FT_Face face, unsigned long charidx);
108 typedef FT_Error (*cc_ftglue_FT_Load_Glyph_t)(FT_Face face, unsigned int glyph, int32_t loadflags);
109 typedef FT_Error (*cc_ftglue_FT_Get_Kerning_t)(FT_Face face, unsigned int left, unsigned int right, unsigned int kernmode, FT_Vector * akerning);
110 typedef FT_Error (*cc_ftglue_FT_Get_Glyph_t)(void * glyphslot, FT_Glyph * glyph);
111 typedef FT_Error (*cc_ftglue_FT_Glyph_To_Bitmap_t)(FT_Glyph * glyph, int rendermode, FT_Vector * origin, int destroy);
112 typedef void (*cc_ftglue_FT_Done_Glyph_t)(FT_Glyph glyph);
113 typedef FT_Error (*cc_ftglue_FT_Outline_Decompose_t)(FT_Outline * outline, const FT_Outline_Funcs * func_interface, void * user);
114 typedef FT_Error (*cc_ftglue_FT_Render_Glyph_t)(void * glyphslot, int rendermode);
115
116 typedef struct {
117 int available;
118 cc_ftglue_FT_Init_FreeType_t FT_Init_FreeType;
119 cc_ftglue_FT_Library_Version_t FT_Library_Version;
120 cc_ftglue_FT_Done_FreeType_t FT_Done_FreeType;
121 cc_ftglue_FT_New_Face_t FT_New_Face;
122 cc_ftglue_FT_Done_Face_t FT_Done_Face;
123 cc_ftglue_FT_Select_Charmap_t FT_Select_Charmap;
124 cc_ftglue_FT_Set_Char_Size_t FT_Set_Char_Size;
125 cc_ftglue_FT_Set_Transform_t FT_Set_Transform;
126 cc_ftglue_FT_Get_Char_Index_t FT_Get_Char_Index;
127 cc_ftglue_FT_Load_Glyph_t FT_Load_Glyph;
128 cc_ftglue_FT_Get_Kerning_t FT_Get_Kerning;
129 cc_ftglue_FT_Get_Glyph_t FT_Get_Glyph;
130 cc_ftglue_FT_Glyph_To_Bitmap_t FT_Glyph_To_Bitmap;
131 cc_ftglue_FT_Done_Glyph_t FT_Done_Glyph;
132 cc_ftglue_FT_Outline_Decompose_t FT_Outline_Decompose;
133 } cc_ftglue_t;
134
135 static cc_fcglue_t * fontconfig_instance = NULL;
136 static cc_libhandle fontconfig_libhandle = NULL;
137 static int fontconfig_failed_to_load = 0;
138
139 static cc_ftglue_t * freetype_instance = NULL;
140 static cc_libhandle freetype_libhandle = NULL;
141 static int freetype_failed_to_load = 0;
142
143 /* Cleans up fontconfig at exit. */
144 static void
fcglue_cleanup(void)145 fcglue_cleanup(void)
146 {
147 #ifdef FONTCONFIG_RUNTIME_LINKING
148 if (fontconfig_libhandle) {
149 cc_dl_close(fontconfig_libhandle);
150 fontconfig_libhandle = NULL;
151 }
152 #endif /* FONTCONFIG_RUNTIME_LINKING */
153 assert(fontconfig_instance);
154 free(fontconfig_instance);
155 fontconfig_instance = NULL;
156 fontconfig_failed_to_load = 0;
157 }
158
159 static const cc_fcglue_t *
fcglue_init(void)160 fcglue_init(void)
161 {
162 CC_SYNC_BEGIN(fcglue_init);
163
164 if (!fontconfig_instance && !fontconfig_failed_to_load) {
165 /* First invocation, do initializations. */
166 cc_fcglue_t * fi = (cc_fcglue_t *)malloc(sizeof(cc_fcglue_t));
167 (void)coin_atexit((coin_atexit_f *)fcglue_cleanup, CC_ATEXIT_DYNLIBS);
168
169 /* The common case is that fontconfig is either available from the
170 linking process or we're successfully going to link it in. */
171 fi->available = 1;
172
173 #ifdef FONTCONFIG_RUNTIME_LINKING
174 {
175 int idx;
176 /* FIXME: should we get the system shared library name from an
177 Autoconf check? 20000930 mortene. */
178 const char * possiblelibnames[] = {
179 NULL, /* is set below */
180 "fontconfig", "libfontconfig", "libfontconfig.so",
181 "libfontconfig.dylib",
182 NULL
183 };
184 possiblelibnames[0] = coin_getenv("COIN_FONTCONFIG_LIBNAME");
185 idx = possiblelibnames[0] ? 0 : 1;
186 while (!fontconfig_libhandle && possiblelibnames[idx]) {
187 fontconfig_libhandle = cc_dl_open(possiblelibnames[idx]);
188 idx++;
189 }
190
191 if (!fontconfig_libhandle) {
192 fi->available = 0;
193 fontconfig_failed_to_load = 1;
194 }
195 }
196 /* Define FCGLUE_REGISTER_FUNC macro. Casting the type is
197 necessary for this file to be compatible with C++ compilers. */
198 #define FCGLUE_REGISTER_FUNC(_funcsig_, _funcname_) \
199 do { \
200 fi->_funcname_ = (_funcsig_)cc_dl_sym(fontconfig_libhandle, SO__QUOTE(_funcname_)); \
201 if (fi->_funcname_ == NULL) fi->available = 0; \
202 } while (0)
203
204 #elif defined(FONTCONFIGGLUE_ASSUME_FONTCONFIG) /* !FONTCONFIG_RUNTIME_LINKING */
205
206 /* Define FCGLUE_REGISTER_FUNC macro. */
207 #define FCGLUE_REGISTER_FUNC(_funcsig_, _funcname_) \
208 fi->_funcname_ = (_funcsig_)_funcname_
209
210 #else /* !FONTCONFIGGLUE_ASSUME_FONTCONFIG */
211 fi->available = 0;
212 /* Define FCGLUE_REGISTER_FUNC macro. */
213 #define FCGLUE_REGISTER_FUNC(_funcsig_, _funcname_) \
214 fi->_funcname_ = NULL
215
216 #endif /* !FONTCONFIGGLUE_ASSUME_FONTCONFIG */
217
218 FCGLUE_REGISTER_FUNC(cc_fcglue_FcGetVersion_t, FcGetVersion);
219
220 if (fi->available && (!fi->FcGetVersion)) {
221 /* something is seriously wrong */
222 cc_debugerror_post("fontconfig glue",
223 "Loaded fontconfig DLL ok, but couldn't resolve some symbols.");
224 fi->available = 0;
225 fontconfig_failed_to_load = 1;
226 fontconfig_instance = fi;
227 }
228 else {
229 FCGLUE_REGISTER_FUNC(cc_fcglue_FcNameParse_t, FcNameParse);
230 FCGLUE_REGISTER_FUNC(cc_fcglue_FcConfigSubstitute_t, FcConfigSubstitute);
231 FCGLUE_REGISTER_FUNC(cc_fcglue_FcDefaultSubstitute_t, FcDefaultSubstitute);
232 FCGLUE_REGISTER_FUNC(cc_fcglue_FcFontMatch_t, FcFontMatch);
233 FCGLUE_REGISTER_FUNC(cc_fcglue_FcPatternGetString_t, FcPatternGetString);
234 FCGLUE_REGISTER_FUNC(cc_fcglue_FcPatternDestroy_t, FcPatternDestroy);
235 FCGLUE_REGISTER_FUNC(cc_fcglue_FcPatternPrint_t, FcPatternPrint);
236 FCGLUE_REGISTER_FUNC(cc_fcglue_FcPatternAddDouble_t, FcPatternAddDouble);
237
238 /* Do this late, so we can detect recursive calls to this function. */
239 fontconfig_instance = fi;
240 }
241 }
242 CC_SYNC_END(fcglue_init);
243 return fontconfig_instance;
244 }
245
246
247 int
cc_fcglue_FcGetVersion(void)248 cc_fcglue_FcGetVersion(void)
249 {
250 assert(fontconfig_instance && fontconfig_instance->available);
251 return fontconfig_instance->FcGetVersion();
252 }
253
254 FcPattern *
cc_fcglue_FcNameParse(const unsigned char * name)255 cc_fcglue_FcNameParse(const unsigned char * name)
256 {
257 assert(fontconfig_instance && fontconfig_instance->available);
258 return fontconfig_instance->FcNameParse(name);
259 }
260
261 int
cc_fcglue_FcConfigSubstitute(void * config,FcPattern * pattern,FcMatchKind kind)262 cc_fcglue_FcConfigSubstitute(void * config, FcPattern * pattern, FcMatchKind kind)
263 {
264 assert(fontconfig_instance && fontconfig_instance->available);
265 return fontconfig_instance->FcConfigSubstitute(config, pattern, kind);
266 }
267
268 void
cc_fcglue_FcDefaultSubstitute(FcPattern * pattern)269 cc_fcglue_FcDefaultSubstitute(FcPattern *pattern)
270 {
271 assert(fontconfig_instance && fontconfig_instance->available);
272 fontconfig_instance->FcDefaultSubstitute(pattern);
273 }
274
275 FcPattern *
cc_fcglue_FcFontMatch(void * config,FcPattern * pattern,FcResult * result)276 cc_fcglue_FcFontMatch(void * config, FcPattern * pattern, FcResult * result)
277 {
278 assert(fontconfig_instance && fontconfig_instance->available);
279 return fontconfig_instance->FcFontMatch(config, pattern, result);
280 }
281
282 FcResult
cc_fcglue_FcPatternGetString(const FcPattern * pattern,const char * object,int n,unsigned char ** s)283 cc_fcglue_FcPatternGetString(const FcPattern * pattern, const char * object, int n, unsigned char ** s)
284 {
285 assert(fontconfig_instance && fontconfig_instance->available);
286 return fontconfig_instance->FcPatternGetString(pattern, object, n, s);
287 }
288
289 void
cc_fcglue_FcPatternDestroy(FcPattern * pattern)290 cc_fcglue_FcPatternDestroy(FcPattern * pattern)
291 {
292 assert(fontconfig_instance && fontconfig_instance->available);
293 fontconfig_instance->FcPatternDestroy(pattern);
294 }
295
296 void
cc_fcglue_FcPatternPrint(const FcPattern * pattern)297 cc_fcglue_FcPatternPrint(const FcPattern * pattern)
298 {
299 assert(fontconfig_instance && fontconfig_instance->available);
300 fontconfig_instance->FcPatternPrint(pattern);
301 }
302
303 int
cc_fcglue_FcPatternAddDouble(FcPattern * p,const char * object,double d)304 cc_fcglue_FcPatternAddDouble(FcPattern *p, const char *object, double d)
305 {
306 assert(fontconfig_instance && fontconfig_instance->available);
307 return fontconfig_instance->FcPatternAddDouble(p, object, d);
308 }
309
310 int
cc_fcglue_available(void)311 cc_fcglue_available(void)
312 {
313 const char * env;
314
315 if (!((env = coin_getenv("COIN_FORCE_FONTCONFIG_OFF")) && (atoi(env) > 0))) {
316 fcglue_init();
317 }
318 return fontconfig_instance && fontconfig_instance->available;
319 }
320
321
322 /* Cleans up freetype at exit. */
323 static void
ftglue_cleanup(void)324 ftglue_cleanup(void)
325 {
326 #ifdef FREETYPE_RUNTIME_LINKING
327 if (freetype_libhandle) {
328 cc_dl_close(freetype_libhandle);
329 freetype_libhandle = NULL;
330 }
331 #endif /* FREETYPE_RUNTIME_LINKING */
332 assert(freetype_instance);
333 free(freetype_instance);
334 freetype_instance = NULL;
335 freetype_failed_to_load = 0;
336 }
337
338 static const cc_ftglue_t *
ftglue_init(void)339 ftglue_init(void)
340 {
341 CC_SYNC_BEGIN(ftglue_init);
342
343 if (!freetype_instance && !freetype_failed_to_load) {
344 /* First invocation, do initializations. */
345 cc_ftglue_t * fi = (cc_ftglue_t *)malloc(sizeof(cc_ftglue_t));
346 (void)coin_atexit((coin_atexit_f *)ftglue_cleanup, CC_ATEXIT_DYNLIBS);
347
348 /* The common case is that FreeType is either available from the
349 linking process or we're successfully going to link it in. */
350 fi->available = 1;
351
352 #ifdef FREETYPE_RUNTIME_LINKING
353 {
354 int idx;
355 /* FIXME: should we get the system shared library name from an
356 Autoconf check? 20000930 mortene. */
357 const char * possiblelibnames[] = {
358 NULL, /* is set below */
359 "freetype", "libfreetype", "libfreetype.so",
360 "libfreetype.dylib",
361 NULL
362 };
363 possiblelibnames[0] = coin_getenv("COIN_FREETYPE2_LIBNAME");
364 idx = possiblelibnames[0] ? 0 : 1;
365
366 while (!freetype_libhandle && possiblelibnames[idx]) {
367 freetype_libhandle = cc_dl_open(possiblelibnames[idx]);
368 idx++;
369 }
370
371 if (!freetype_libhandle) {
372 fi->available = 0;
373 freetype_failed_to_load = 1;
374 }
375 }
376 /* Define FTGLUE_REGISTER_FUNC macro. Casting the type is
377 necessary for this file to be compatible with C++ compilers. */
378 #define FTGLUE_REGISTER_FUNC(_funcsig_, _funcname_) \
379 do { \
380 fi->_funcname_ = (_funcsig_)cc_dl_sym(freetype_libhandle, SO__QUOTE(_funcname_)); \
381 if (fi->_funcname_ == NULL) fi->available = 0; \
382 } while (0)
383
384 #elif defined(FREETYPEGLUE_ASSUME_FREETYPE) /* !FREETYPE_RUNTIME_LINKING */
385
386 /* Define FTGLUE_REGISTER_FUNC macro. */
387 #define FTGLUE_REGISTER_FUNC(_funcsig_, _funcname_) \
388 fi->_funcname_ = (_funcsig_)_funcname_
389
390 #else /* !FREETYPEGLUE_ASSUME_FREETYPE */
391 fi->available = 0;
392 /* Define FTGLUE_REGISTER_FUNC macro. */
393 #define FTGLUE_REGISTER_FUNC(_funcsig_, _funcname_) \
394 fi->_funcname_ = NULL
395
396 #endif /* !FREETYPEGLUE_ASSUME_FREETYPE */
397
398 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Init_FreeType_t, FT_Init_FreeType);
399 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Library_Version_t, FT_Library_Version);
400 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Done_FreeType_t, FT_Done_FreeType);
401
402 if (fi->available && (!fi->FT_Init_FreeType ||
403 !fi->FT_Library_Version ||
404 !fi->FT_Done_FreeType)) {
405 /* something is seriously wrong */
406 cc_debugerror_post("freetype glue",
407 "Loaded freetype DLL ok, but couldn't resolve basic symbols.");
408 fi->available = 0;
409 freetype_failed_to_load = 1;
410 freetype_instance = fi;
411 }
412 else {
413 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_New_Face_t, FT_New_Face);
414 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Done_Face_t, FT_Done_Face);
415 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Select_Charmap_t, FT_Select_Charmap);
416 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Set_Char_Size_t, FT_Set_Char_Size);
417 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Set_Transform_t, FT_Set_Transform);
418 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Get_Char_Index_t, FT_Get_Char_Index);
419 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Load_Glyph_t, FT_Load_Glyph);
420 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Get_Kerning_t, FT_Get_Kerning);
421 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Get_Glyph_t, FT_Get_Glyph);
422 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Glyph_To_Bitmap_t, FT_Glyph_To_Bitmap);
423 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Done_Glyph_t, FT_Done_Glyph);
424 FTGLUE_REGISTER_FUNC(cc_ftglue_FT_Outline_Decompose_t, FT_Outline_Decompose);
425
426 /* Do this late, so we can detect recursive calls to this function. */
427 freetype_instance = fi;
428 }
429 }
430 CC_SYNC_END(ftglue_init);
431 return freetype_instance;
432 }
433
434
435 FT_Error
cc_ftglue_FT_Init_FreeType(FT_Library * library)436 cc_ftglue_FT_Init_FreeType(FT_Library * library)
437 {
438 assert(freetype_instance && freetype_instance->available);
439 return freetype_instance->FT_Init_FreeType(library);
440 }
441
442 void
cc_ftglue_FT_Library_Version(void * library,int * major,int * minor,int * patch)443 cc_ftglue_FT_Library_Version(void * library, int * major, int * minor, int * patch)
444 {
445 assert(freetype_instance && freetype_instance->available);
446 freetype_instance->FT_Library_Version(library, major, minor, patch);
447 }
448
449 void
cc_ftglue_FT_Done_FreeType(void * library)450 cc_ftglue_FT_Done_FreeType(void * library)
451 {
452 FT_Error err;
453 assert(freetype_instance && freetype_instance->available);
454 err = freetype_instance->FT_Done_FreeType(library);
455 assert(err == 0 && "something bad happened at FreeType exit");
456 }
457
458 FT_Error
cc_ftglue_FT_New_Face(void * library,const char * filepathname,long faceindex,FT_Face * face)459 cc_ftglue_FT_New_Face(void * library, const char * filepathname, long faceindex, FT_Face * face)
460 {
461 assert(freetype_instance && freetype_instance->available);
462 return freetype_instance->FT_New_Face(library, filepathname, faceindex, face);
463 }
464
465 FT_Error
cc_ftglue_FT_Done_Face(void * face)466 cc_ftglue_FT_Done_Face(void * face)
467 {
468 assert(freetype_instance && freetype_instance->available);
469 return freetype_instance->FT_Done_Face(face);
470 }
471
472 FT_Error
cc_ftglue_FT_Select_Charmap(FT_Face face,int encoding)473 cc_ftglue_FT_Select_Charmap(FT_Face face, int encoding)
474 {
475 assert(freetype_instance && freetype_instance->available);
476 return freetype_instance->FT_Select_Charmap(face, encoding);
477 }
478
479 FT_Error
cc_ftglue_FT_Set_Char_Size(FT_Face face,long width,long height,unsigned int hres,unsigned int vres)480 cc_ftglue_FT_Set_Char_Size(FT_Face face, long width, long height, unsigned int hres, unsigned int vres)
481 {
482 assert(freetype_instance && freetype_instance->available);
483 return freetype_instance->FT_Set_Char_Size(face, width, height, hres, vres);
484 }
485
486 void
cc_ftglue_FT_Set_Transform(FT_Face face,FT_Matrix * matrix,FT_Vector * delta)487 cc_ftglue_FT_Set_Transform(FT_Face face, FT_Matrix * matrix, FT_Vector * delta)
488 {
489 assert(freetype_instance && freetype_instance->available);
490 freetype_instance->FT_Set_Transform(face, matrix, delta);
491 }
492
493 FT_UInt
cc_ftglue_FT_Get_Char_Index(FT_Face face,unsigned long charidx)494 cc_ftglue_FT_Get_Char_Index(FT_Face face, unsigned long charidx)
495 {
496 assert(freetype_instance && freetype_instance->available);
497 return freetype_instance->FT_Get_Char_Index(face, charidx);
498 }
499
500 FT_Error
cc_ftglue_FT_Load_Glyph(FT_Face face,unsigned int glyph,int32_t loadflags)501 cc_ftglue_FT_Load_Glyph(FT_Face face, unsigned int glyph, int32_t loadflags)
502 {
503 assert(freetype_instance && freetype_instance->available);
504 return freetype_instance->FT_Load_Glyph(face, glyph, loadflags);
505 }
506
507 FT_Error
cc_ftglue_FT_Get_Kerning(FT_Face face,unsigned int left,unsigned int right,unsigned int kernmode,FT_Vector * akerning)508 cc_ftglue_FT_Get_Kerning(FT_Face face, unsigned int left, unsigned int right, unsigned int kernmode, FT_Vector * akerning)
509 {
510 assert(freetype_instance && freetype_instance->available);
511 return freetype_instance->FT_Get_Kerning(face, left, right, kernmode, akerning);
512 }
513
514 FT_Error
cc_ftglue_FT_Get_Glyph(void * glyphslot,FT_Glyph * glyph)515 cc_ftglue_FT_Get_Glyph(void * glyphslot, FT_Glyph * glyph)
516 {
517 assert(freetype_instance && freetype_instance->available);
518 return freetype_instance->FT_Get_Glyph(glyphslot, glyph);
519 }
520
521 FT_Error
cc_ftglue_FT_Glyph_To_Bitmap(FT_Glyph * glyph,int rendermode,FT_Vector * origin,int destroy)522 cc_ftglue_FT_Glyph_To_Bitmap(FT_Glyph * glyph, int rendermode, FT_Vector * origin, int destroy)
523 {
524 assert(freetype_instance && freetype_instance->available);
525 return freetype_instance->FT_Glyph_To_Bitmap(glyph, rendermode, origin, destroy);
526 }
527
528 void
cc_ftglue_FT_Done_Glyph(FT_Glyph glyph)529 cc_ftglue_FT_Done_Glyph(FT_Glyph glyph)
530 {
531 assert(freetype_instance && freetype_instance->available);
532 freetype_instance->FT_Done_Glyph(glyph);
533 }
534
535 int
cc_ftglue_available(void)536 cc_ftglue_available(void)
537 {
538 ftglue_init();
539 return freetype_instance && freetype_instance->available;
540 }
541
542 FT_Error
cc_ftglue_FT_Outline_Decompose(FT_Outline * outline,const FT_Outline_Funcs * func_interface,void * user)543 cc_ftglue_FT_Outline_Decompose(FT_Outline * outline, const FT_Outline_Funcs * func_interface, void * user)
544 {
545 assert(freetype_instance && freetype_instance->available);
546 return freetype_instance->FT_Outline_Decompose(outline, func_interface, user);
547 }
548