SVG Fonts: How To

The SVG font format is defined in the SVG Specification in order to provide one format for fonts of which SVG content developers can be sure that it will be supported by all conforming SVG viewers, regardless what operating system they are used on; and which can be embedded in an SVG document. When saving an image as SVG, using the vector drawing application of your choice, there might be an option to embed used fonts. This is the easiest way to use SVG fonts, but not always the best. Read on, if you’d like to learn more about how to use SVG fonts. But note that Mozilla Firefox, probably the most widely used SVG supporting webbrowser, does not yet support SVG fonts.

Where To Get SVG Fonts

Font files in other formats than SVG can be converted to SVG fonts by opening them in the font editing software FontForge and then saving as SVG font. Fonts in the True Type format can also be converted with the Apache Batik SVG Font Converter. Other tools for font conversion exist, and maybe the vector drawing application you use has an option to embed fonts, which means that a font, or part of it, would be converted to the SVG format and written into the same SVG document in which it is used.

Apart from the technological task of converting fonts, there is the question of whether you’re allowed to do so. Most commercial fonts may not be used as web fonts, as this would constitute redistribution, which isn’t permitted by their licences. Even a lot of freely available fonts might be problematic legally. It’s not a widely used technology yet, so it often wasn’t even considered when a font’s license was written.

A good resource for liberally licensed fonts is the Open Font Library. All fonts hosted at the Open Font Library are distributed under licenses which definitely permit conversion to other formats and utilisation as web fonts, and more.

How to Use an External SVG Font

Once we’ve got a font in SVG format, we can use it in a graphic like this one:

At this place you should see an example image. If you don’t then maybe your webbrowser doesn’t support SVG or has some issues with the HTML object tag.

Remember that SVG fonts don’t work in Firefox. I recommend viewing this page in the Opera webbrowser. Even when you use Opera in a recent version, the text might get rendered in a system font before the SVG comic font Tomson Talks is downloaded. If the rendering doesn’t update after the correct font is available, selecting the text with the mouse might help.

Now let’s look at the source code for that image to understand, how it’s done:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 300">
<defs >
 <font-face font-family="Tomson Talks">
  <font-face-src>
   <font-face-uri xlink:href="../font/TomsonTalks.svg#TomsonTalks">
    <font-face-format string="svg"/>
   </font-face-uri>
  </font-face-src>
 </font-face>
</defs>
 <image xlink:href="Imp.jpg" width="400" height="300"/>
 <path fill="#fff" stroke="#000" stroke-width="3" stroke-miterlimit="50" d="M350 280a400 400 0 0 0 4 -150a100 60 0 1 0 -14 4a400 400 0 0 1 10 146z"/>
 <text font-family="'Tomson Talks',sans-serif" font-size="25">
  <tspan x="302" y="60" text-anchor="middle">You cause</tspan>
  <tspan x="302" y="85" text-anchor="middle">more trouble</tspan>
  <tspan x="302" y="110" text-anchor="middle">than good.</tspan>
 </text>
</svg>

There are two things to do, when you want to use an SVG font for text in an SVG image. The first thing is to include a reference to the font file, so an SVG viewer will know where to find it. In the code above this was done with the font-face element and its child elements. You can just copy that part, paste it into your graphics, and adapt some of the attributes. The font-family attribute should be changed to the name of the font family you would like to use, and the xlink:href attribute of the font-face-uri element is the reference to the font location. It is important to note that the URL does not just point to the font file. The last part, “#TomsonTalks”, references a specific node within the XML document located at ../font/TomsonTalks.svg . And that is the font node in which the font is defined. When you open the Tomson Talks file and view its source code you will find that there is a font element with an id attribute set to “TomsonTalks”. For any font you would like to use, you will have to find the id of the font element. This also makes it possible to store multiple fonts in one file. The string attribute of the font-face-format element must only be changed if you use a font in a different format, but SVG viewer software is not required to support any other font format than SVG fonts.

There is no strict rule on where the font-face element should be, but it’s good practice to place it inside a defs element at the beginning of the file, right after the title element and the first desc element, and before all shape elements.

Alternatively CSS Web Fonts syntax can be used to reference a font location, but that currently seems to be even less well supported by browsers than the syntax used above.

The second thing you need to do is to specify which font to use for which text elements. In our example this is done with the font-family attribute of the text element. Font family names which contain spaces must be put in additional quotation marks. Instead of just one font name, the attribute in the example holds a comma separated list. The second item is not a font name, but a generic font family. It tells the user agent to use a sans serif font if Tomson Talks is not available. Since we told the user agent where to find Tomson Talks, this should ideally not play any role. But the document can already be rendered, while the font file is still loading, and then of course there are SVG viewers in use which don’t support external SVG fonts. With a list of alternative fonts you can still have some control over the style in these cases.

Font selection can also be done with CSS, and CSS properties take precedence over XML attributes, which means you can’t overwrite existing CSS style definitions by adding the font-family attribute. If you need to change the font family of text in an existing SVG document without using a vector graphics editor, just with a text editor, then you should use the search and replace functionality to replace all occurences of the font name.

If you use a Font which you have only in SVG format then you probably won’t be able to select it in your vector drawing application. In this case it might be necessary to select a system font, and then replace the font name in a text editor.

How to Use an Embedded SVG Font

If you use a font only in one document then you might want to put the font definition directly into that document.

To do this you need to copy the font element from the font file into your SVG image. Everything from <font to </font> must be in the image file. Normally there will already be a font-face element inside the font element, so you won’t have to add one. If there’s no font-face element, double-check to be sure there really is none, and if so, you must add one. The font-face element should be placed inside the font element, because then the font-face-src element may be omitted. Only the font-family attribute is needed, so you can use it to refer to the font.

This will normally suffice to make the font available within the document, but there are exceptions. If the font makes use of entities defined in an internal subset DTD, you’d also have to copy the internal subset into your graphics document. This is not something you will encounter in fonts converted from other file formats, but I have created a font, named “spaceagedigital”, which makes use of entity definitions. This technique is practical when parts of glyphs are used multiple times, as is the case with digital display fonts or with accents. But since this is not commonly used, and my own usage is mainly experimental, I won’t go into details here about what would need to be copied to where.

Furthermore it needs to be considered that values of id attributes must be unique within a document, because of which copying together elements from multiple documents can be problematic. Browsers don’t necessarily report an error in case an id is used more than once, but it could cause problems with some software. The font elements needs to have an id so it can be referenced from other documents, but when the font is embedded, the id attribute will normally not be necessary and can be removed.

To reduce the file size glyphs which aren’t used can be removed. Especially for a font which is used in only one image there might be a lot of potential for minimization. Doing this by hand would obviously be cumbersome, and when texts are changed the font would need to be updated. If you want to include only necessary glyphs you should export from a vector graphics editor which offers such a feature.

There is no strict rule on where the font element should be, but it’s good practice to place it inside a defs element at the beginning of the file, right after the title element and the first desc element, and before all shape elements.

Step two, font selection, works just the same as with external fonts.