@@ -379,7 +379,7 @@ const char *PyFT2Font_init__doc__ = R"""(
379
379
)""" ;
380
380
381
381
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 ,
383
383
std::optional<std::vector<PyFT2Font *>> fallback_list = std::nullopt,
384
384
int kerning_factor = 0 , bool warn_if_used = false )
385
385
{
@@ -430,8 +430,8 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8,
430
430
self->stream .close = nullptr ;
431
431
}
432
432
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);
435
435
436
436
self->x ->set_kerning_factor (kerning_factor);
437
437
@@ -1477,12 +1477,14 @@ ft2font__getattr__(std::string name) {
1477
1477
1478
1478
PYBIND11_MODULE (ft2font, m, py::mod_gil_not_used())
1479
1479
{
1480
- if (FT_Init_FreeType (&_ft2Library)) { // initialize library
1480
+ FT_Library ft2Library = nullptr ;
1481
+
1482
+ if (FT_Init_FreeType (&ft2Library)) { // initialize library
1481
1483
throw std::runtime_error (" Could not initialize the freetype2 library" );
1482
1484
}
1483
1485
FT_Int major, minor, patch;
1484
1486
char version_string[64 ];
1485
- FT_Library_Version (_ft2Library , &major, &minor, &patch);
1487
+ FT_Library_Version (ft2Library , &major, &minor, &patch);
1486
1488
snprintf (version_string, sizeof (version_string), " %d.%d.%d" , major, minor, patch);
1487
1489
1488
1490
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())
1597
1599
1598
1600
py::classh<PyFT2Font>(m, " FT2Font" , py::is_final (), py::buffer_protocol (),
1599
1601
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
+ }),
1601
1610
" filename" _a, " hinting_factor" _a=8 , py::kw_only (),
1602
1611
" _fallback_list" _a=py::none (), " _kerning_factor" _a=0 ,
1603
1612
" _warn_if_used" _a=false ,
@@ -1754,6 +1763,18 @@ PYBIND11_MODULE(ft2font, m, py::mod_gil_not_used())
1754
1763
return self.x ->get_image ().request ();
1755
1764
});
1756
1765
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
+
1757
1778
m.attr (" __freetype_version__" ) = version_string;
1758
1779
m.attr (" __freetype_build_type__" ) = FREETYPE_BUILD_TYPE;
1759
1780
m.def (" __getattr__" , ft2font__getattr__);
0 commit comments