Usage

Start by importing Ziafont and loading a font from a file:

import ziafont
font = ziafont.Font('NotoSerif-Regular.ttf')

The font name may be a path to a ttf or otf font file. It may also be the name of a font installed in the OS system font path. If no font name is specified, a built-in font will be used.

Strings can be converted to SVG using ziafont.font.Text objects.

font.text('Example')
_images/usage_1_0.svg

This object provides a Jupyter representation of the string drawn as SVG, so when run in a Jupyter cell the rendered text is displayed automatically.

The Text object also has methods for getting the SVG as text or as an XML element. Use the .svg() method to get a standalone SVG data as a string, which can then be saved to a file:

s = font.text('Example').svg()
print(s[:80])  # Just show 80 characters here...
<svg xmlns="http://www.w3.org/2000/svg" width="200.062" height="48" viewBox="0 -

Or .svgxml() to get the SVG as an XML Element Tree:

font.text('Example').svgxml()
<Element 'svg' at 0x71f89d65adb0>

Size

The font size is set with the size parameter:

font.text('small', size=12)
_images/usage_4_0.svg
font.text('large', size=72)
_images/usage_5_0.svg

Color

The color of text is set using any valid CSS color, either a named color (such as ‘red’, ‘blue’) or hex (such as ‘#FF0000’).

font.text('medium slate blue', color='mediumslateblue')
_images/usage_6_0.svg

Rotation

Text can be rotated by providing an angle in degrees. The rotation_mode parameter matches Matplotlib anchor or default behavior for specifying the center of rotation.

font.text('Rotated', rotation=30)
_images/usage_7_0.svg

Multi-line strings

Multi-line strings (containing \n characters) can be drawn. Use halign to set horizontal alignment (‘left’, ‘center’, or ‘right’), and linespacing to control the spacing between lines as a multiplier to the normal font-specified line spacing.

font.text('Two\nLines', halign='center', linespacing=.8)
_images/usage_8_0.svg

Features

The ziafont.Font.features attribute is used to enable certain typesetting features, such as kerning adjustment and ligature replacement.

The features attribute provides a lits of available features for the font and their enabled status.

font = ziafont.Font()
font.features
{'kern': True,
 'aalt': False,
 'case': False,
 'dlig': False,
 'hlig': False,
 'liga': True,
 'salt': False}

Here’s the default rendering of a word:

font.text('apple')
_images/usage_10_0.svg

and with the salt (Stylistic Alternatives) feature enabled, this font substitues different glyphs for a and l, among others:

font.features['salt'] = True
font.text('apple')
_images/usage_11_0.svg

The feature attribute names correspond to user-configurable Open Type font features.

Kerning

If the font contains a “GPOS” table, with pair-positioning adjustment, kerning adjustment will be applied to control spacing between individual glyphs. This can be disabled by turning off the kern feature. See the difference in this example:

font = ziafont.Font()
font.features['kern'] = False
font.text('Type')
_images/usage_12_0.svg
font.features['kern'] = True
font.text('Type')
_images/usage_13_0.svg

Ligatures

In some fonts, multiple glyphs may be drawn with a single ligature glyph, common in combinations such as “ff” or “fl”. Ligature substitution will be applied by default if the font contains ligature data in a “GSUB” table. It can be disabled by setting the liga feature to False.

font.features['liga'] = False
font.text('waffle')
_images/usage_14_0.svg
font.features['liga'] = True
font.text('waffle')
_images/usage_15_0.svg

Drawing on an existing SVG

To draw the string onto an existing SVG, use the ziafont.font.Text.drawon() method. Create an SVG XML structure as an XML ElementTree, and pass it as the svg parameter along with an xy position within the SVG canvas.

from IPython.display import SVG
from xml.etree import ElementTree as ET

svg = ET.Element('svg')
svg.set('width', '100')
svg.set('height', '50')
svg.set('xmlns', 'http://www.w3.org/2000/svg')
svg.set('viewBox', '0 0 100 50')
circ = ET.SubElement(svg, 'circle')
circ.set('cx', '50')
circ.set('cy', '25')
circ.set('r', '25')
circ.set('fill', 'orange')

font.text('Hello', size=18).drawon(svg, 50, 25)
font.text('123', size=14).drawon(svg, 75, 40)

SVG(ET.tostring(svg))
_images/usage_16_0.svg

The halign parameter specifies the typical horizontal alignment of left, right, or center. Vertical alignment is set with the valign parameter, and may be top, center, bottom, or base. A base alignment will align with the baseline of the first row of text in the string, while bottom alignment aligns with the bottom of the entire block of text.

ziafont.config.fontsize = 16
ziafont.config.debug = True  # Show bounding box and origin
svg = ET.Element('svg')
svg.attrib['xmlns'] = 'http://www.w3.org/2000/svg'
svg.attrib['xmlns:xlink'] = 'http://www.w3.org/1999/xlink'
svg.attrib['width'] = '300'
svg.attrib['height'] = '100'
svg.attrib['viewBox'] = '0 0 300 100'

font.text('align\ntop', valign='top').drawon(svg, 50, 50)
font.text('align\ncenter', valign='center').drawon(svg, 100, 50)
font.text('align\nbase', valign='base').drawon(svg, 160, 50)
font.text('align\nbottom', valign='bottom').drawon(svg, 210, 50)

SVG(ET.tostring(svg))
_images/usage_17_0.svg

Glyphs

At a lower level, Ziafont can also draw individual glyphs. The glyph for a string character can be obtained from ziafont.font.Font.glyph(). Similar to ziafont.font.Text(), this method returns a Glyph object with methods for returning SVG as a string or as an SVG XML element.

font.glyph('D')
_images/usage_19_0.svg
font.glyph('D').svgxml()
<Element 'svg' at 0x71f8961bc630>

The above svg and svgxml methods both return the glyph in a standalone SVG. Often, however, the glyph should be added to an existing drawing or used elsewhere. The svgpath method returns the glyph as an SVG <path> element that can be inserted in an existing SVG. Alternatively, the svgsymbol method wraps the <path> in an SVG <symbol> element that can be reused multiple times in the same drawing.

Glyph Indexes

The glyph index refers to its position within the font file, not necessarily the unicode representation of the character. The index for a given character in the font can be obtained:

font.glyphindex('&')
9
font.glyph_fromid(9)
_images/usage_22_0.svg

Calculating string size

The method ziafont.font.Text.getsize() can be used to calculate the pixel width and height of a string without drawing it.

font.text('How wide is this string?').getsize()
(567.5390625, 46.453125)

Configuration Options

The ziafont.config object provides some global configuration options.


Default Font Size

The default font size can be specified with:

ziafont.config.fontsize = 36

SVG Version Compatibility

Some SVG renderers, including recent versions of Inkscape and some OS built-in image viewers, are not fully compatible with the SVG 2.0 specification. Set the svg2 configuration parameter to False for better compatibility. This may result in larger file sizes as each glyph is included as its own <path> element rather than being reused with <symbol> and <use> elements.

ziafont.config.svg2 = False

SVG decimal precision

The decimal precision of coordinates in SVG tags can be set using ziafont.config.precision. Lower precision saves space in the SVG string, but may reduce quality of the image.

ziafont.config.precision = 6
# ...
... 31 L 2.496094 -3.228516 L 5.712891 -3.228516 Z M 3.433594 -8.748047 L 3.43
ziafont.config.precision = 2
# ...
... 23 Z M 3.43 -8.75 L 3.43 -8.75 L 4.78 -8.75 L 8.

Limitations

Ziafont does not currently support right-to-left scripts, or scripts that require advanced Complex Text Layout rules that are not defined in the font file itself.

GSUB Lookup types 5 and 8, and GPOS lookup types 3, 5, 7, and 8 are not currently implemented, along with many script-specific features.