phpcsssvgembedded-fontsdynamic-image-generation

PHP - Dynamically creating a svg with embedded fonts


I want to dynamically create an svg that I can use in an <img/> tag. This in itself is easy; create an svg, set the header and echo the generated parts in their correct place.

The problem is, I want to be able to embed fonts in the svg. I've tried using the @font-face rule in the css of the svg, but that didn't work (MDN says that it only works on Android and Safari).

Is there any cross-browser way to do this?

Solutions I've Considered:

Possible Solution #01:

The solution:

In my main file, create an svg file which uses the @font-face css rule, and then use exec() to use inkscape to convert that svg into another svg, which converts all letters into paths. I then could use echo file_get_contents($inkscape_file) with the correct headers to output it as a svg which can be used with an <img/> tag.

The problem with this:

This creates 2 additional files, so seems very inefficient. Furthermore, since each user will end up generating several images, the space it takes up would grow phenomenally.

Possible Solution #02:

The solution:

Make a template in illustrator, then save it as svg, and tick the embed all glyphs option. Then replace the text & the styles with the options from the PHP script. Use the correct header and output this.

The problem with this:

This severely limits the amount of fonts that can be used, as it is limited to only those which I create a template for. My desired behaviour was to add the option for users to upload their own fonts and use them. This solution does not allow for that.

Additional information that may be of some relevance:

  1. My development server runs fedora, and the production server uses redhat.
  2. The @font-face rule I am currently using is as follows:

    @font-face { font-family: Potato; src: url("/fonts/potato.otf"); }


Solution

  • You can't load any external resources declared in the svg from the <img> tag.

    The only solutions would be some crappy ways to append the glyphs or the fonts into the svg file itself.
    Actually there is a not so crappy way to do it as you found in this answer by lèse-majesté.

    The best way is then still IMO to not use an <img> tag to display the svg documents, but rather use an <iframe> or an <object> tag, with the @font-face declared inside the svg file, or even directly include an inline version into the document. These methods do allow the loading of external resources such as fonts.

    Then you just have to save the fonts on your server or just an url to the font in the @font-face declaration.