Skip to content

Commit 629be3f

Browse files
committed
Make FreeType library tied to the module
This ensures that a new one will be created for each sub-interpreter, or if the module is reloaded.
1 parent ae5b8f9 commit 629be3f

File tree

3 files changed

+30
-13
lines changed

3 files changed

+30
-13
lines changed

src/ft2font.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
you have disabled hints).
4242
*/
4343

44-
FT_Library _ft2Library;
45-
4644
FT2Image::FT2Image(unsigned long width, unsigned long height)
4745
: m_buffer((unsigned char *)calloc(width * height, 1)), m_width(width), m_height(height)
4846
{
@@ -207,7 +205,7 @@ FT2Font::get_path(std::vector<double> &vertices, std::vector<unsigned char> &cod
207205
codes.push_back(CLOSEPOLY);
208206
}
209207

210-
FT2Font::FT2Font(FT_Open_Args &open_args,
208+
FT2Font::FT2Font(FT_Library ft2Library, FT_Open_Args &open_args,
211209
long hinting_factor_,
212210
std::vector<FT2Font *> &fallback_list,
213211
FT2Font::WarnFunc warn, bool warn_if_used)
@@ -217,7 +215,7 @@ FT2Font::FT2Font(FT_Open_Args &open_args,
217215
kerning_factor(0)
218216
{
219217
clear();
220-
FT_CHECK(FT_Open_Face, _ft2Library, &open_args, 0, &face);
218+
FT_CHECK(FT_Open_Face, ft2Library, &open_args, 0, &face);
221219
if (open_args.stream != nullptr) {
222220
face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
223221
}

src/ft2font.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,12 @@ class FT2Image
9292
FT2Image &operator=(const FT2Image &);
9393
};
9494

95-
extern FT_Library _ft2Library;
96-
9795
class FT2Font
9896
{
9997
typedef void (*WarnFunc)(FT_ULong charcode, std::set<FT_String*> family_names);
10098

10199
public:
102-
FT2Font(FT_Open_Args &open_args, long hinting_factor,
100+
FT2Font(FT_Library ft2Library, FT_Open_Args &open_args, long hinting_factor,
103101
std::vector<FT2Font *> &fallback_list,
104102
WarnFunc warn, bool warn_if_used);
105103
virtual ~FT2Font();

src/ft2font_wrapper.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ const char *PyFT2Font_init__doc__ = R"""(
379379
)""";
380380

381381
static PyFT2Font *
382-
PyFT2Font_init(py::object filename, long hinting_factor = 8,
382+
PyFT2Font_init(FT_Library ft2Library, py::object filename, long hinting_factor = 8,
383383
std::optional<std::vector<PyFT2Font *>> fallback_list = std::nullopt,
384384
int kerning_factor = 0, bool warn_if_used = false)
385385
{
@@ -430,8 +430,8 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8,
430430
self->stream.close = nullptr;
431431
}
432432

433-
self->x = new FT2Font(open_args, hinting_factor, fallback_fonts, ft_glyph_warn,
434-
warn_if_used);
433+
self->x = new FT2Font(ft2Library, open_args, hinting_factor, fallback_fonts,
434+
ft_glyph_warn, warn_if_used);
435435

436436
self->x->set_kerning_factor(kerning_factor);
437437

@@ -1477,12 +1477,14 @@ ft2font__getattr__(std::string name) {
14771477

14781478
PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
14791479
{
1480-
if (FT_Init_FreeType(&_ft2Library)) { // initialize library
1480+
FT_Library ft2Library = nullptr;
1481+
1482+
if (FT_Init_FreeType(&ft2Library)) { // initialize library
14811483
throw std::runtime_error("Could not initialize the freetype2 library");
14821484
}
14831485
FT_Int major, minor, patch;
14841486
char version_string[64];
1485-
FT_Library_Version(_ft2Library, &major, &minor, &patch);
1487+
FT_Library_Version(ft2Library, &major, &minor, &patch);
14861488
snprintf(version_string, sizeof(version_string), "%d.%d.%d", major, minor, patch);
14871489

14881490
py::native_enum<FT_Kerning_Mode>(m, "Kerning", "enum.Enum", Kerning__doc__)
@@ -1597,7 +1599,14 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
15971599

15981600
py::classh<PyFT2Font>(m, "FT2Font", py::is_final(), py::buffer_protocol(),
15991601
PyFT2Font__doc__)
1600-
.def(py::init(&PyFT2Font_init),
1602+
.def(py::init(
1603+
[ft2Library](py::object filename, long hinting_factor = 8,
1604+
std::optional<std::vector<PyFT2Font *>> fallback_list = std::nullopt,
1605+
int kerning_factor = 0, bool warn_if_used = false) -> PyFT2Font *
1606+
{
1607+
return PyFT2Font_init(ft2Library, filename, hinting_factor,
1608+
fallback_list, kerning_factor, warn_if_used);
1609+
}),
16011610
"filename"_a, "hinting_factor"_a=8, py::kw_only(),
16021611
"_fallback_list"_a=py::none(), "_kerning_factor"_a=0,
16031612
"_warn_if_used"_a=false,
@@ -1754,6 +1763,18 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
17541763
return self.x->get_image().request();
17551764
});
17561765

1766+
// Ensure FreeType library is closed after all instances of FT2Font are gone by
1767+
// tying a weak ref to the class itself.
1768+
(void)py::weakref(
1769+
m.attr("FT2Font"),
1770+
py::cpp_function(
1771+
[ft2Library](py::handle weakref) {
1772+
FT_Done_FreeType(ft2Library);
1773+
weakref.dec_ref();
1774+
}
1775+
)
1776+
).release();
1777+
17571778
m.attr("__freetype_version__") = version_string;
17581779
m.attr("__freetype_build_type__") = FREETYPE_BUILD_TYPE;
17591780
m.def("__getattr__", ft2font__getattr__);

0 commit comments

Comments
 (0)