sammycage/lunasvg

[fonts] font not rendering if updateLayout is called in different thread

Closed this issue · 2 comments

Hey,

I'm just stumbled over this. I'm on latest master 6e138c0778b23964a33135e3015acb2a6ddec7d7.

In my test I've the following code

    CollageRenderer renderer{};

    renderer.loadDocument("/home/mathis/Pictures/Collage.svg");

    std::jthread test{[&]() {
        renderer.updateLayout();
        renderer.renderToFile("test.png");
    }};

The CollageRenderer is just a wrapper around lunasvg and registers the fonts etc.

But the interesting stuff is the

    std::jthread test{[&]() {
        renderer.updateLayout();
        renderer.renderToFile("test.png");
    }};

If I'm calling renderer.updateLayout(); the fonts are not rendered when calling

const auto bitmap = document_->renderToBitmap();
bitmap.writeToPng(image_path);

When I'm doing

    renderer.updateLayout();
    std::jthread test{[&]() {
        renderer.renderToFile("test.png");
    }};

The fonts are rendered as expected.

I'll now just call the updateLayout in the thread where the instance of the document is living in. But I think that it either should be documented that the updateLayout has to be called in the same thread or there is a bug. :D

Thanks for your observations! Just to clarify, there isn't an issue with updateLayout; the behavior you're seeing is due to the fact that fonts are cached per thread. Therefore, you need to add fonts in each thread where you're rendering.

But I think that it either should be documented that the updateLayout has to be called in the same thread or there is a bug. :D

This isn't a bug—PlutoVG font faces just aren't thread-safe. LunaSVG works around this by caching a font face for each thread, so you'll need to add fonts in every thread. I agree that documenting this behavior could be helpful!

Thats for clarifying this! A small note would be helpful.

From my point of view this issue could be closed.