sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
ft-hb.c
1/****************************************************************************
2 *
3 * ft-hb.c
4 *
5 * FreeType-HarfBuzz bridge (body).
6 *
7 * Copyright (C) 2025 by
8 * Behdad Esfahbod.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
19#if !defined( _WIN32 ) && !defined( _GNU_SOURCE )
20# define _GNU_SOURCE 1 /* for RTLD_DEFAULT */
21#endif
22
23#include <freetype/freetype.h>
25
26#include "afglobal.h"
27
28#include "ft-hb.h"
29
30
31#if defined( FT_CONFIG_OPTION_USE_HARFBUZZ ) && \
32 defined( FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC )
33
34#ifndef FT_LIBHARFBUZZ
35# ifdef _WIN32
36# define FT_LIBHARFBUZZ "libharfbuzz-0.dll"
37# else
38# ifdef __APPLE__
39# define FT_LIBHARFBUZZ "libharfbuzz.0.dylib"
40# else
41# define FT_LIBHARFBUZZ "libharfbuzz.so.0"
42# endif
43# endif
44#endif
45
46#ifdef _WIN32
47
48# include <windows.h>
49
50#else /* !_WIN32 */
51
52# include <dlfcn.h>
53
54 /* The GCC pragma suppresses the warning "ISO C forbids */
55 /* assignment between function pointer and 'void *'", which */
56 /* inevitably gets emitted with `-Wpedantic`; see the man */
57 /* page of function `dlsym` for more information. */
58# if defined( __GNUC__ )
59# pragma GCC diagnostic push
60# ifndef __cplusplus
61# pragma GCC diagnostic ignored "-Wpedantic"
62# endif
63# endif
64
65#endif /* !_WIN32 */
66
67
68 FT_LOCAL_DEF( void )
69 ft_hb_funcs_init( struct AF_ModuleRec_ *af_module )
70 {
71 FT_Memory memory = af_module->root.memory;
72 FT_Error error;
73
74 ft_hb_funcs_t *funcs = NULL;
75 ft_hb_version_atleast_func_t version_atleast = NULL;
76
77#ifdef _WIN32
78 HANDLE lib;
79# define DLSYM( lib, name ) \
80 (ft_ ## name ## _func_t)GetProcAddress( lib, #name )
81#else
82 void *lib;
83# define DLSYM( lib, name ) \
84 (ft_ ## name ## _func_t)dlsym( lib, #name )
85#endif
86
87
88 af_module->hb_funcs = NULL;
89
90 if ( FT_NEW( funcs ) )
91 return;
92 FT_ZERO( funcs );
93
94#ifdef _WIN32
95
96 lib = LoadLibraryA( FT_LIBHARFBUZZ );
97 if ( !lib )
98 goto Fail;
99 version_atleast = DLSYM( lib, hb_version_atleast );
100
101#else /* !_WIN32 */
102
103# ifdef RTLD_DEFAULT
104# define FT_RTLD_FLAGS RTLD_LAZY | RTLD_GLOBAL
105 lib = RTLD_DEFAULT;
106 version_atleast = DLSYM( lib, hb_version_atleast );
107# else
108# define FT_RTLD_FLAGS RTLD_LAZY
109# endif
110
111 if ( !version_atleast )
112 {
113 /* Load the HarfBuzz library.
114 *
115 * We never close the library, since we opened it with RTLD_GLOBAL.
116 * This is important for the case where we are using HarfBuzz as a
117 * shared library, and we want to use the symbols from the library in
118 * other shared libraries or clients. HarfBuzz holds onto global
119 * variables, and closing the library will cause them to be
120 * invalidated.
121 */
122 lib = dlopen( FT_LIBHARFBUZZ, FT_RTLD_FLAGS );
123 if ( !lib )
124 goto Fail;
125 version_atleast = DLSYM( lib, hb_version_atleast );
126 }
127
128#endif /* !_WIN32 */
129
130 if ( !version_atleast )
131 goto Fail;
132
133 /* Load all symbols we use. */
134#define HB_EXTERN( ret, name, args ) \
135 { \
136 funcs->name = DLSYM( lib, name ); \
137 if ( !funcs->name ) \
138 goto Fail; \
139 }
140#include "ft-hb-decls.h"
141#undef HB_EXTERN
142
143#undef DLSYM
144
145 af_module->hb_funcs = funcs;
146 return;
147
148 Fail:
149 if ( funcs )
150 FT_FREE( funcs );
151 }
152
153
154 FT_LOCAL_DEF( void )
155 ft_hb_funcs_done( struct AF_ModuleRec_ *af_module )
156 {
157 FT_Memory memory = af_module->root.memory;
158
159
160 if ( af_module->hb_funcs )
161 {
162 FT_FREE( af_module->hb_funcs );
163 af_module->hb_funcs = NULL;
164 }
165 }
166
167
168 FT_LOCAL_DEF( FT_Bool )
169 ft_hb_enabled( struct AF_FaceGlobalsRec_ *globals )
170 {
171 return globals->module->hb_funcs != NULL;
172 }
173
174#ifndef _WIN32
175# if defined( __GNUC__ )
176# pragma GCC diagnostic pop
177# endif
178#endif
179
180#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC */
181
182 FT_LOCAL_DEF( FT_Bool )
183 ft_hb_enabled( struct AF_FaceGlobalsRec_ *globals )
184 {
185 FT_UNUSED( globals );
186
187#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
188 return TRUE;
189#else
190 return FALSE;
191#endif
192 }
193
194#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC */
195
196
197/* END */