@@ -246,16 +246,14 @@ GraphicsContextRenderer::GraphicsContextRenderer(
246
246
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
247
247
// May already have been set by cr_from_fileformat_args.
248
248
if (!cairo_get_user_data (cr, &detail::REFS_KEY)) {
249
- CAIRO_CHECK_SET_USER_DATA (
250
- cairo_set_user_data, cr, &detail::REFS_KEY,
251
- new std::vector<py::object>{},
252
- [](void * data) -> void {
253
- delete static_cast <std::vector<py::object>*>(data);
254
- });
249
+ CAIRO_CHECK_SET_USER_DATA_NEW (
250
+ cairo_set_user_data, cr, &detail::REFS_KEY, std::vector<py::object>{});
255
251
}
256
- CAIRO_CHECK_SET_USER_DATA (
252
+ CAIRO_CHECK_SET_USER_DATA_NEW (
257
253
cairo_set_user_data, cr, &detail::STATE_KEY,
258
- (new std::stack<AdditionalState>{{{
254
+ // Unfortunately cairo_set_user_data doesn't have stack semantics wrt.
255
+ // cairo_save/cairo_restore, so we must take care of that ourselves.
256
+ (std::stack<AdditionalState>{{{
259
257
/* width */ width,
260
258
/* height */ height,
261
259
/* dpi */ dpi,
@@ -269,19 +267,15 @@ GraphicsContextRenderer::GraphicsContextRenderer(
269
267
/* sketch */ {},
270
268
/* snap */ true , // Defaults to None, i.e. True for us.
271
269
/* url */ {}
272
- }}}),
273
- [](void * data) -> void {
274
- // Just calling operator delete would not invoke the destructor.
275
- delete static_cast <std::stack<AdditionalState>*>(data);
276
- });
270
+ }}}));
277
271
}
278
272
279
273
GraphicsContextRenderer::~GraphicsContextRenderer ()
280
274
{
281
275
if (detail::FONT_CACHE.size () > 64 ) { // font_manager._get_font cache size.
282
- for (auto & [pathspec, font_face ]: detail::FONT_CACHE) {
276
+ for (auto & [pathspec, face ]: detail::FONT_CACHE) {
283
277
(void )pathspec;
284
- cairo_font_face_destroy (font_face );
278
+ cairo_font_face_destroy (face );
285
279
}
286
280
detail::FONT_CACHE.clear (); // Naive cache mechanism.
287
281
}
@@ -346,9 +340,8 @@ cairo_t* GraphicsContextRenderer::cr_from_pycairo_ctx(
346
340
cairo_get_matrix (cr, mtx);
347
341
auto const & [sx, sy] = device_scales;
348
342
mtx->x0 *= sx; mtx->y0 *= sy;
349
- CAIRO_CHECK_SET_USER_DATA (
350
- cairo_set_user_data, cr, &detail::INIT_MATRIX_KEY, mtx,
351
- [](void * data) -> void { delete static_cast <cairo_matrix_t *>(data); });
343
+ CAIRO_CHECK_SET_USER_DATA_NEW (
344
+ cairo_set_user_data, cr, &detail::INIT_MATRIX_KEY, mtx);
352
345
return cr;
353
346
}
354
347
@@ -415,12 +408,9 @@ cairo_t* GraphicsContextRenderer::cr_from_fileformat_args(
415
408
cairo_surface_set_fallback_resolution (surface, dpi, dpi);
416
409
auto const & cr = cairo_create (surface);
417
410
cairo_surface_destroy (surface);
418
- CAIRO_CHECK_SET_USER_DATA (
411
+ CAIRO_CHECK_SET_USER_DATA_NEW (
419
412
cairo_set_user_data, cr, &detail::REFS_KEY,
420
- new std::vector<py::object>{{write }},
421
- [](void * data) -> void {
422
- delete static_cast <std::vector<py::object>*>(data);
423
- });
413
+ std::vector<py::object>{{write }});
424
414
if (type == StreamSurfaceType::EPS) {
425
415
// If cairo was built without PS support, we'd already have errored above.
426
416
detail::cairo_ps_surface_set_eps (surface, true );
@@ -1365,13 +1355,9 @@ void GraphicsContextRenderer::draw_path_collection(
1365
1355
1366
1356
maybe_multithread (cr_, n, [&](cairo_t * ctx, int start, int stop) {
1367
1357
if (ctx != cr_) {
1368
- CAIRO_CHECK_SET_USER_DATA (
1358
+ CAIRO_CHECK_SET_USER_DATA_NEW (
1369
1359
cairo_set_user_data, ctx, &detail::STATE_KEY,
1370
- (new std::stack<AdditionalState>{{get_additional_state ()}}),
1371
- [](void * data) -> void {
1372
- // Just calling operator delete would not invoke the destructor.
1373
- delete static_cast <std::stack<AdditionalState>*>(data);
1374
- });
1360
+ std::stack<AdditionalState>{{get_additional_state ()}});
1375
1361
}
1376
1362
auto cache = PatternCache{simplify_threshold};
1377
1363
for (auto i = start; i < stop; ++i) {
@@ -1582,9 +1568,8 @@ void GraphicsContextRenderer::draw_text(
1582
1568
}
1583
1569
mb.draw (*this , x, y, angle);
1584
1570
} else {
1585
- auto const & font_face = font_face_from_prop (prop);
1586
- cairo_set_font_face (cr_, font_face);
1587
- cairo_font_face_destroy (font_face);
1571
+ auto const & faces = font_faces_from_prop (prop);
1572
+ cairo_set_font_face (cr_, faces[0 ]);
1588
1573
auto const & font_size =
1589
1574
points_to_pixels (prop.attr (" get_size_in_points" )().cast <double >());
1590
1575
cairo_set_font_size (cr_, font_size);
@@ -1621,6 +1606,9 @@ void GraphicsContextRenderer::draw_text(
1621
1606
cr_, s.c_str (), s.size (),
1622
1607
gac.glyphs , gac.num_glyphs ,
1623
1608
gac.clusters , gac.num_clusters , gac.cluster_flags );
1609
+ for (auto const & face: faces) {
1610
+ cairo_font_face_destroy (face);
1611
+ }
1624
1612
}
1625
1613
}
1626
1614
@@ -1640,9 +1628,8 @@ GraphicsContextRenderer::get_text_width_height_descent(
1640
1628
.cast <std::tuple<double , double , double >>();
1641
1629
} else {
1642
1630
cairo_save (cr_);
1643
- auto const & font_face = font_face_from_prop (prop);
1644
- cairo_set_font_face (cr_, font_face);
1645
- cairo_font_face_destroy (font_face);
1631
+ auto const & faces = font_faces_from_prop (prop);
1632
+ cairo_set_font_face (cr_, faces[0 ]);
1646
1633
auto const & font_size =
1647
1634
points_to_pixels (prop.attr (" get_size_in_points" )().cast <double >());
1648
1635
cairo_set_font_size (cr_, font_size);
@@ -1651,6 +1638,9 @@ GraphicsContextRenderer::get_text_width_height_descent(
1651
1638
auto const & gac = text_to_glyphs_and_clusters (cr_, s);
1652
1639
cairo_glyph_extents (cr_, gac.glyphs , gac.num_glyphs , &extents);
1653
1640
cairo_restore (cr_);
1641
+ for (auto const & face: faces) {
1642
+ cairo_font_face_destroy (face);
1643
+ }
1654
1644
return {
1655
1645
// Max of inked portion and of current point advance (to also take
1656
1646
// whitespace into account).
@@ -1808,17 +1798,17 @@ void MathtextBackend::draw(
1808
1798
cairo_translate (cr, x, y);
1809
1799
cairo_rotate (cr, -angle * std::acos (-1 ) / 180 );
1810
1800
for (auto const & glyph: glyphs_) {
1811
- auto const & font_face = font_face_from_path (glyph.path );
1812
- cairo_set_font_face (cr, font_face );
1813
- cairo_font_face_destroy (font_face );
1801
+ auto const & face = font_face_from_path (glyph.path );
1802
+ cairo_set_font_face (cr, face );
1803
+ cairo_font_face_destroy (face );
1814
1804
auto const & size = glyph.size * dpi / 72 ;
1815
1805
auto const & mtx = cairo_matrix_t {
1816
1806
size * glyph.extend , 0 , -size * glyph.slant * glyph.extend , size, 0 , 0 };
1817
1807
cairo_set_font_matrix (cr, &mtx);
1818
1808
adjust_font_options (cr);
1819
1809
auto ft_face =
1820
1810
static_cast <FT_Face>(
1821
- cairo_font_face_get_user_data (font_face , &detail::FT_KEY));
1811
+ cairo_font_face_get_user_data (face , &detail::FT_KEY));
1822
1812
auto index = FT_UInt{};
1823
1813
std::visit (overloaded {
1824
1814
[&](char32_t codepoint) {
0 commit comments