@@ -379,7 +379,7 @@ const char *PyFT2Font_init__doc__ = R"""(
379379)""" ;
380380
381381static 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
14781478PYBIND11_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