@@ -17,6 +17,8 @@ namespace mplcairo {
17
17
18
18
using namespace pybind11 ::literals;
19
19
20
+ py::object GraphicsContextRenderer::mathtext_parser_{};
21
+
20
22
Region::Region (cairo_rectangle_int_t bbox, std::unique_ptr<uint8_t []> buf) :
21
23
bbox{bbox}, buf{std::move (buf)}
22
24
{}
@@ -108,12 +110,7 @@ GraphicsContextRenderer::additional_context()
108
110
GraphicsContextRenderer::GraphicsContextRenderer (
109
111
cairo_t * cr, double width, double height, double dpi) :
110
112
// This does *not* incref the cairo_t, but the destructor *will* decref it.
111
- cr_{cr},
112
- mathtext_parser_{
113
- py::module::import (" matplotlib.mathtext" )
114
- .attr (" MathTextParser" )(" mplcairo" )},
115
- texmanager_{py::none ()},
116
- text2path_{py::module::import (" matplotlib.textpath" ).attr (" TextToPath" )()}
113
+ cr_{cr}
117
114
{
118
115
if (auto const & status = cairo_status (cr);
119
116
status == CAIRO_STATUS_INVALID_SIZE) {
@@ -1474,18 +1471,29 @@ PYBIND11_MODULE(_mplcairo, m)
1474
1471
#undef LOAD_PTR
1475
1472
#endif
1476
1473
1474
+ FT_CHECK (FT_Init_FreeType, &detail::ft_library);
1475
+
1477
1476
detail::UNIT_CIRCLE =
1478
1477
py::module::import (" matplotlib.path" ).attr (" Path" ).attr (" unit_circle" )();
1479
1478
detail::PIXEL_MARKER =
1480
1479
py::module::import (" matplotlib.markers" ).attr (" MarkerStyle" )(" ," );
1480
+ GraphicsContextRenderer::mathtext_parser_ =
1481
+ py::module::import (" matplotlib.mathtext" )
1482
+ .attr (" MathTextParser" )(" mplcairo" );
1481
1483
1482
- FT_CHECK (FT_Init_FreeType, &detail::ft_library);
1483
- auto ft_cleanup = py::cpp_function{
1484
- [&](py::handle /* weakref */ ) -> void {
1484
+ auto cleanup = py::cpp_function{
1485
+ [&](py::handle weakref) -> void {
1485
1486
FT_Done_FreeType (detail::ft_library);
1487
+
1488
+ // Make sure that these objects don't outlive the Python interpreter.
1489
+ detail::UNIT_CIRCLE = {};
1490
+ detail::PIXEL_MARKER = {};
1491
+ GraphicsContextRenderer::mathtext_parser_ = {};
1492
+
1493
+ weakref.dec_ref ();
1486
1494
}
1487
1495
};
1488
- py::weakref (m, ft_cleanup ).release ();
1496
+ py::weakref (m, cleanup ).release ();
1489
1497
1490
1498
// Export symbols.
1491
1499
@@ -1647,9 +1655,19 @@ PYBIND11_MODULE(_mplcairo, m)
1647
1655
[](GraphicsContextRenderer& gcr) -> double {
1648
1656
return gcr.get_additional_state ().dpi ;
1649
1657
})
1650
- // Needed for usetex and patheffects.
1651
- .def_readwrite (" _texmanager" , &GraphicsContextRenderer::texmanager_)
1652
- .def_readonly (" _text2path" , &GraphicsContextRenderer::text2path_)
1658
+ // Needed for usetex and patheffects. These actually return constants.
1659
+ .def_property_readonly (
1660
+ " _texmanager" , // No need to instantiate *another* texmanager.
1661
+ [](GraphicsContextRenderer& /* gcr */ ) -> py::object {
1662
+ return
1663
+ py::module::import (" matplotlib.textpath" )
1664
+ .attr (" text_to_path" ).attr (" get_texmanager" )();
1665
+ })
1666
+ .def_property_readonly (
1667
+ " _text2path" ,
1668
+ [](GraphicsContextRenderer& /* gcr */ ) -> py::object {
1669
+ return py::module::import (" matplotlib.textpath" ).attr (" text_to_path" );
1670
+ })
1653
1671
1654
1672
.def (
1655
1673
" get_canvas_width_height" ,
0 commit comments