Forum Bugs

Embedded fonts in SVG files not loaded

dmitry
When SVG file contains embedded font in the <defs> element using @font-face with the data URL, the font is not loaded and a substitute font is used instead.
This only happens when SVG image is included with the <img> tag. However, if the SVG code is embedded directly into HTML, the @font-face instructions within the SVG code are processed correctly.

Sample SVG File

Sample HTML:
<html>
<head><title>SVG Demo</title></head>
<body>
<p>Font embedded in the external SVG file and is loaded in the &lt;defs&gt; element of the SVG file</p>
<p><img src="https://test-dmitry.au.coredna.dev/assets/formulae_embedded.svg" width="120" height="120"></p>
</body>
</html>


Debug log:
prince: Preparing document...
prince: debug: [prefetch-1] loading https://test-dmitry.au.coredna.dev/assets/formulae_embedded.svg
prince: debug: stopping prefetch threads
prince: debug: [prefetch-1] loaded https://test-dmitry.au.coredna.dev/assets/formulae_embedded.svg
prince: Converting document...
prince: debug: pack
prince: debug: font request: serif
prince: debug: font scan: Times New Roman
prince: debug: font scan: Times New Roman, 4 matches
...
prince: debug: font scan: Garuda
prince: debug: font scan: Garuda, 0 matches
prince: loading font: /usr/share/fonts/webcore/times.ttf
prince: debug: loaded resource: /usr/share/fonts/webcore/times.ttf
prince: debug: loaded resource: type: no
prince: used font: Times New Roman, Regular
prince: debug: writing PDF to file: output.pdf
prince: Finished: success

It seems a reference to the 'my math font' in the SVG file is not even processed. There is nothing in the debug log about it.

Expected log:
prince: Preparing document...
prince: debug: stopping prefetch threads
prince: Converting document...
prince: debug: pack
...
prince: debug: font request: my math font
prince: loading font: data URL
prince: debug: loaded resource: data URL
prince: debug: loaded resource: type: yes(resource_type("font/truetype", ["charset" - "utf-8"], unknown, yes(utf8)))
prince: used font: Horizontal Font, Regular
...
prince: Finished: success

This is what happens when SVG is directly embedded in HTML, but not when it is loaded via the <img> tag.

Prince version: 13.6
mikeday
We have added support for @font-face rules in external SVG images to Prince 14.
dmitry
Thanks. Upgrading Prince to version 14 did fix the issue, indeed.

However, another issue started to occur in version 14.1 which did not occur in version 13.6

When a font is loaded in the HTML document and then referenced in the SVG file, it does not work (see screenshot attached).

HTML:
<html lang="en">
<head>
	<title>SVG Demo</title>
	<style>
        @font-face {
            font-family: "generic math font";
            src: url(data:font/truetype;charset=utf-8;base64,AAEAAAAMAIAAAwBAT1MvMlJxIOAAAADMAAAATmNtYXCwg0j/AAABHAAAADRjdnQgAAcAAAAAAVAAAAACZ2x5ZuwE1kUAAAFUAAAAO2hlYWQNciGiAAABkAAAADZoaGVhBusXCAAAAcgAAAAkaG10eGjtB6sAAAHsAAAACGxvY2EAAYSYAAAB9AAAAAxtYXhwBLEEbgAAAgAAAAAgbmFtZReja/8AAAIgAAAByXBvc3QB9wD6AAAD7AAAACBwcmVwu5WEAAAABAwAAAAHAAACRwGQAAUAAAQABAAAAAAABAAEAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAAACOv8xEDev96AAAD6ACWAAAAAAACAAEAAQAAABQAAwABAAAAFAAEACAAAAAEAAQAAQAAI6///wAAI6///9xSAAEAAAAAAAcAAAABAAABVQGrAasAAwAjGAGwBBCwATywARCwAtSwAhCwBTwAsAQQsAHUsAEQsADUMDERFSE1AasBq1ZWAAABAAAAAQAARVMXc18PPPUAAwQA/////9Wt7tH/////1a3u0QAAAAADAAMAAAAACgACAAEAAAAAAAEAAAPo/2oAABdwAAD//wMAAAEAAAAAAAAAAAAAAAAAAAACAyAAAAGrAAAAAAAAAAAAAAAAADsAAQAAAAIADQACAAAAAAACAIAEAAAAAAAEAABfAAAAAAAAABUBAgAAAAAAAAABAB4AAAAAAAAAAAACAA4AHgAAAAAAAAADADwALAAAAAAAAAAEAB4AaAAAAAAAAAAFABYAhgAAAAAAAAAGAA8AnAAAAAAAAAAIABwAqwABAAAAAAABAB4AAAABAAAAAAACAA4AHgABAAAAAAADADwALAABAAAAAAAEAB4AaAABAAAAAAAFABYAhgABAAAAAAAGAA8AnAABAAAAAAAIABwAqwADAAEECQABAB4AAAADAAEECQACAA4AHgADAAEECQADADwALAADAAEECQAEAB4AaAADAAEECQAFABYAhgADAAEECQAGAA8AnAADAAEECQAIABwAqwBIAG8AcgBpAHoAbwBuAHQAYQBsACAARgBvAG4AdABSAGUAZwB1AGwAYQByAE0AYQB0AGgAcwAgAEYAbwByACAATQBvAHIAZQAgAEgAbwByAGkAegBvAG4AdABhAGwAIABGAG8AbgB0AEgAbwByAGkAegBvAG4AdABhAGwAIABGAG8AbgB0AFYAZQByAHMAaQBvAG4AIAAxAC4AMEhvcml6b250YWxfRm9udABNAGEAdABoAHMAIABGAG8AcgAgAE0AbwByAGUAAAAAAwAAAAAAAAH0APoAAAAAAAAAAAAAAAAAAAAAAAAAALkH/wACjYUA)format('truetype');
            font-weight: normal; font-style: normal;
        }
	</style>
</head>
<body>
<p>1. Font loaded in the HTML code of the page itself:</p>
<p><img src="https://test-dmitry.au.coredna.dev/assets/formulae.svg" width="120" height="120"></p>
</body>
</html>


SVG:
<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20">
    <text font-family="generic math font" font-size="9" text-anchor="middle" x="15.5" y="7">&#x23AF;</text>
    <text font-family="sans-serif" font-size="12" text-anchor="middle" x="16.5" y="16">2</text>
</svg>


As I said, it was working fine in Prince 13.6.
  1. testing_svg_fonts.png106.6 kB
    three ways to load web fonts used in SVG
mikeday
Yes, the main document and external images have separate scopes for fonts now. You can use the same font in both by defining it in a user style sheet applied with the --style argument, or simply including the @font-face rule in both documents.

(This is for consistency with how browsers work, and also because it would be strange for an SVG image to be displayed differently depending on which document referenced it).
dmitry
Well, the problem is that it is not consistent with the browsers. This is an example HTML page where the fonts used in the SVGs are loaded in three different ways. All browsers render the page correctly with the horizontal line above the number, and this is how the page is rendered in Prince: PDF.
There is no requirement for SVGs to load all the fonts referenced in the file, especially, when a list of fonts is specified in the font-family attribute. This reduces the number of HTTP requests and makes SVG files smaller. Also, the fonts and the SVGs may have different licensing requirements.
At least this should be noted, as backward-incompatible change.
mikeday
I think this example is testing something else, that browsers have more complete font fallback than Prince does, as they can still display the same output even if the @font-face rule is removed from the HTML file entirely.