sammycage / lunasvg

lunasvg is a standalone SVG rendering library in C++
MIT License
851 stars 124 forks source link

[font] callback of missing font of text #178

Open mathisloge opened 1 week ago

mathisloge commented 1 week ago

I am trying to get the text rendering to start and wonder if there is a way to access the fonts in the SVG? Specifically: I would like to know which font families were not found so that I can either load them from a file or check the system to see if they are available. Alternatively, I would like to go through the text elements and assign a specific font family to all of them.

Is there any way to do this?

sammycage commented 1 week ago

Currently, font face lookup callbacks are not supported. However, you can add your own custom font face using lunasvg_add_font_face_from_file or lunasvg_add_font_face_from_data. For example:

lunasvg_add_font_face_from_file("MyHelvetica", false, false, "/path/to/MyHelvetica.ttf");

If you'd like to modify the font family for specific text elements, you can use Document::getElementById to retrieve the desired text element, and then use Element::setAttribute to modify the font-family attribute. Don't forget to call Document::updateLayout before rendering to ensure the changes are applied.

Hope this helps! Feel free to ask if you need further clarification.

mathisloge commented 1 week ago

Thanks for the quick answer! :)

The API lunasvg_add_font_face_from_file was quite straightforward.

Do you have an query API e.g. getting all elements of tag text or an font callback API in mind?

With a font callback API, I have more of a callback in mind that is called when a font is missing. The callback then either tries to load the font or returns a string with an alternative font family.

Now the text just wont render if the font family is not added.

I just wanted to know so that I could take this into consideration, even if it would potentially take a while .

sammycage commented 1 week ago

Now the text just wont render if the font family is not added.

That's strange—text is supposed to render with the default fallback font for the major platforms. Could you let me know which platform you're using?

You can also add your own fallback font by setting the family to an empty string in lunasvg_add_font_face_from_file. For example:

lunasvg_add_font_face_from_file("", false, false, "/path/to/fallback-regular.ttf");
lunasvg_add_font_face_from_file("", true, false, "/path/to/fallback-bold.ttf");
lunasvg_add_font_face_from_file("", false, true, "/path/to/fallback-italic.ttf");
lunasvg_add_font_face_from_file("", true, true, "/path/to/fallback-bold-italic.ttf");

This will ensure a fallback font is used if the specified one isn't found.

sammycage commented 1 week ago

With a font callback API, I have more of a callback in mind that is called when a font is missing. The callback then either tries to load the font or returns a string with an alternative font family.

The way the LunaSVG face manager works is that when a specific font family isn't found, it will automatically try a fallback font (a font with no specific family set). Is this the behavior you're looking to achieve?

mathisloge commented 1 week ago

Ohh, yes that is the behavior I'm trying to achieve. Thanks for the hint!

Could you let me know which platform you're using?

I'm on linux 6.10.6-10-MANJARO

If you can give me some initial debugging hints, I could look into the loading problem.

You can also add your own fallback font by setting the family to an empty string

I think it would be a great, if this is one is just added to the doxygen description of the family argument of the function.

sammycage commented 1 week ago

@mathisloge Thank you for reporting this issue! I will work on fixing the default fallback font file path across all Linux distributions and will also update the documentation to include this detail for the family argument.