NanoMichael / MicroTeX

A dynamic, cross-platform, and embeddable LaTeX rendering library
MIT License
399 stars 66 forks source link

How to make the Cairo renderer release all resources #172

Closed afalkenhahn closed 1 month ago

afalkenhahn commented 1 month ago

I'm having an issue with MicroTeX's Cairo backend. Even after calling MicroTeX::release() the Cairo renderer still seems to hold on to some resources. I can see this because I can't delete the otf font I'm using with MicroTeX because it's still in use by the Cairo backend.

My program saves the otf font to a temporary file, then renders the text using the Cairo renderer and then tries to delete the otf font saved to a temporary file but this doesn't succeed because the font is still in use by the Cairo renderer.

Is there any way to force the Cairo renderer to free all resources? Currently this only happens at program termination but that is too late for me. I need to find a way to make the Cairo renderer clean up before my program terminates so that I can delete the temporary otf font file first. But how can I do that?

sp1ritCS commented 1 month ago

This is a Windows issue, as on Linux you can "delete" a file, but as long as the gdt still holds an open descriptor to the file the inode ref counter isn't decremented.

Thus there is currently no way to do this (besides either having a wrapper processes or doing evil things with the c++ runtime), you'll have to modify the cairo backend.

afalkenhahn commented 1 month ago

Any idea what has to be modified in the cairo backend? I've already tried to manually clear the _cairoFtFaces map so that cairo_font_face_destroy is called on all fonts but that doesn't help because the reference count on the font face is still 5 when the cairo_font_face_deleter is called so something else must still have a hold on the font but I don't see what...

sp1ritCS commented 1 month ago

I've already tried to manually clear the _cairoFtFaces map

Thats what I also assumed. Maybe the platform factory doesn't get dropped when calling MicroTeX::Release?

Not sure if this works for you, but you could attempt to load a clm file with glyph data? This way you don't need to additionally provide a font file. (but it might not work with emoji?)

afalkenhahn commented 1 month ago

Actually, the reason why there were still references to the font lies in the fact that Cairo has a font cache which will keep fonts even after a context has been destroyed. cairo_debug_reset_static_data() can be used to flush the cache. Once I call cairo_debug_reset_static_data() all references to the font are dropped and I can delete the temp file.