The FontoBene Font Format, Version 1.0.0
- 1. Introduction
- 2. Glyph Coordinate System
- 3. Format Description
- 4. Font Layouting
- 5. Format Versioning
- 6. Formal Specification
- 7. Example
FontoBene is a vector font format. It only uses strokes to form glyphs, in order for easy rendering in systems that cannot easily deal with more complex parts of formats like TTF or OTF, like Bézier curves.
FontoBene was designed with the use case of text on printed circuit boards (PCBs) in mind. PCBs are usually manufactured using the Gerber format as an exchange format to describe the etching layers, which does not support quadratic / cubic curves.
The main inspiration for this font format was the LFF font used by LibreCAD.
The coordinate system of glyphs starts at the lower left corner. Positive X coordinates point to the right. Positive Y coordinates point to the top. A value of 9 means 100% of the cap height (i.e. the coordinate system is scaled with factor 9). This system leads to more compact font files as many coordinates can be expressed by a single digit.
Y (0,9) + | | +-----+ X (0,0) (9,0)
Typical glyphs use the X axis (Y=0) as the baseline and are drawn mostly inside the area (0,0)..(9,9). Coordinates outside this area are allowed, e.g. for ascenders and descenders. In addition, typical glyphs are left aligned to the Y axis (X=0). Glyphs that are not aligned to the Y axis have an impact on letter spacing, see section "Letter Spacing" for details.
Following image illustrates where the baseline (Y=0) and cap height (Y=9) are located:
Every FontoBene font file consists of UTF-8 encoded text. The lines are separated by newlines (U+000A LINE FEED). It starts with a header, followed by glyph definitions.
Comments are allowed everywhere in the file. A comment line MUST start with a
number sign (
#). Everything on that line will be ignored by the parser.
Inline comments are not allowed.
The header consists of INI style sections with key-value pairs. Key and value
are separated by an equal sign (
=). Both keys and values are strings. All
whitespace around keys and values should be stripped. Sections are separated by
at least one empty line.
There are currently three sections defined:
[font] sections may only contain keys standardized in this
specification (see section "Formal Specification"). The
[user] section may
contain arbitrary key value pairs.
[format] format = FontoBene format_version = 1.0.0 [font] id = librepcb name = LibrePCB Font description = This is the default font of LibrePCB. author = Max Müller <email@example.com> version = 1.0.0 license = GPL-3.0+ letter_spacing = 1.8 line_spacing = 16 [user] last_modified = 2012-12-21 todo = Add U+03A9 (GREEK CAPITAL LETTER OMEGA) ---
The header is separated from the body by three hyphens (U+002D HYPHEN-MINUS) on
a single line (
---). The body consists of glyph definition blocks separated
by at least one empty line.
Every glyph definition starts with the glyph declaration, a unicode codepoint
in square brackets (e.g.
[1F4A9] for the pile of poo character). It may
optionally be followed by a UTF-8 representation of the character for easier
💩). However, that preview will be ignored by the parser.
The notation used inside the brackets follows the convention described in The Unicode Standard, Version 10.0, Appendix A, Notational Conventions, Code Points:
In running text, an individual Unicode code point is expressed as U+n, where n is four to six hexadecimal digits, using the digits 0–9 and uppercase letters A–F (for 10 through 15, respectively).
Leading zeros are omitted, unless the code point would have fewer than four hexadecimal digits—for example, U+0001, U+0012, U+0123, U+1234, U+12345, U+102345.
In contrast to the Unicode Standard, in FontoBene the
U+ prefix MUST NOT be
The glyph declaration is followed by a list of glyph references, polylines or whitespace definitions, each on a single line. The order and quantity of these three things MUST be as following:
- 0-n references (e.g.
- 0-n polylines (e.g.
- 0-1 whitespace definitions (e.g.
A polyline looks like this:
It consists of coordinate pairs, separated by semicolons (
;). The X and Y
coordinates are separated with a comma (
,). The coordinates are arbitrary
precision floating point numbers using the full stop (U+002E) as decimal mark.
If a coordinate is a whole number, the decimal mark and the fractional part of
the number may be omitted. If the integer part is zero and there is a fractional
part, the zero may be omitted (e.g.
-.5 instead of
Here is the complete definition of the glyph for the character "LATIN CAPITAL LETTER A (U+0041)":
 A 0.8333,2.5;5.1666,2.5 0,0;3,9;6,0
22.214.171.124. Circular Arc Segments
In addition to straight lines, polylines can contain circular arc segments. This is done by adding a third parameter, called bulge, to the start coordinate of the arc segment. It specifies the central angle of the circular arc segment. The bulge is a value from -9 to +9 and represents an angle in degrees from -180° to +180°. A positive angle describes a counter clockwise arc segment from the start point to the end point, while a negative angle describes a clockwise arc segment. If an arc segment with more than 180° is required, it must be split up into two smaller arc segments.
 f 1,0;1,7.5,-4.5;2.5,9;3,9 0,6;3,6
Because many glyphs are very similar, references may be used as "includes". References start with the "@" symbol (U+0040), followed by a codepoint. Here is the definition of the glyph for the character "LATIN CAPITAL LETTER A WITH CIRCUMFLEX (U+00C2)":
[00C2] Â @0041 1.5,11.5;3,13;4.5,11.5
An implementation would simply replace the "@0041" part with the expanded polylines from the referenced glyph.
Multiple references can be used in a single glyph definition, but they must all be on their own line.
To prevent reference loops and to facilitate single-pass parsers, only backward references are allowed. All references glyphs must have been previously defined.
Some glyphs need additional whitespace following the glyph, or even consist of
only whitespace (no polylines). The width of this whitespace can be specified
for every glyph with the
~ sign (U+007E TILDE), followed by the desired width
in the same unit as polylines.
The most important space glyph (which every font file should contain) is " " (U+0020 SPACE). A typical font may use a width of 3.6 (40% of font height):
 SPACE ~3.6
As global letter spacing is applied to every glyph (including whitespace glyphs), the total whitespace is the addition of both values (e.g. 3.6 + 1.8 = 5.4).
Whitespace definitions are also inherited when referencing other glyphs (with
"@", see above). If a glyph has multiple whitespace definitions (either direct
or via references), only the last definition will be used by the parser.
Inherited space definitions can be discarded by overriding them with
Generally, letter spacing (horizontal) and line spacing (vertical) depends on the specific use-case and thus it's up to the application's font layout engine to determine the exact spacing values.
But to support layout engines in determining suitable letter spacing and line spacing values, FontoBene allows to specify some spacing information directly in font files. This information helps to get nice looking texts with very low effort.
Both letter spacing and line spacing values are given in the same unit as polylines (9 = 100% of cap height).
4.1. Letter Spacing
Letter spacing is the horizontal space between two consecutive glyphs. There are three different options which allow to control letter spacing of proportional (=non-monospace) fonts:
Global Letter Spacing:
[font]section of the header defines the letter spacing which should be put after every letter. A typical font may use a letter spacing value of 1.8 (20% of font height).
Leading space of glyphs:
Typically every glyph should start on the X-coordinate 0 (i.e. the leftmost coordinate of every glyph is placed on X-coordinate 0). But if a specific glyph requires more or less spacing in front of it, the font designer can place such glyphs slightly more left or right to make the leftmost point of the glyph either slightly negative (reduce leading space) or slightly positive (increase leading space).
Trailing space of glyphs:
Glyphs can also adjust the trailing space by using the
~sign for specifying additional spacing (see section "Whitespaces" above).
4.1.1. Proportional Fonts
The total space between two letters of a proportional (non-monospace) font is calculated by the addition of these three parameters:
- Trailing space of first letter (
- Global letter spacing (
- Leading space (leftmost X-coordinate) of second letter
4.1.2. Monospace Fonts
If a font specifies the
monospace_width header (see subsection "Standardized
Headers"), then that font SHOULD be layouted as a monospace font. The value of
monospace_width header corresponds to the width of every glyph's bounding
box, excluding global spacing.
When rendering a monospace font, glyphs MUST be horizontally centered in the fixed-width bounding box. Leading and trailing space (as described in the subsection "Letter Spacing") MAY be used to horizontally offset the glyph in its bounding box. Glyphs that are wider than the bounding box SHOULD also be centered. Such glyphs SHOULD result in a warning being reported to the user.
Between the bounding boxes of monospace glyphs, global letter spacing applies.
When designing a monospace font, glyphs (including leading and trailing space)
SHOULD NOT be wider than the value defined by
4.2. Line Spacing
Line spacing is the vertical distance between the baselines of a multiline text.
It can be defined with the
line_spacing key in the header. A suitable value
depends on the height of ascenders and descenders to avoid vertically
overlapping characters. So the
line_spacing value should be set to a value
slightly greater than the addition of the cap height (9), highest ascender
height and highest descender height. For a typical font this may be around 16
(178% of cap height).
4.3. Stroke Width
Even if FontoBene is a stroke font, it doesn't specify the stroke width. It's up to the application to choose a suitable stroke width (typically between 0% and 30% of the text height). For the font designer it's important to always specify letter spacing and line spacing values for a stroke width of 0 to make fonts interchangeable. Applications may need to increase these spacing values accordingly when using thicker strokes.
The FontoBene format follows Semantic Versioning version 2.
6.1. Grammar (PEG)
6.2. Standardized Headers
|format||The string "FontoBene".||1||
|format_version||The version of the FontoBene format that this file adheres to.||1||
|id||The identifier of this font. MUST only contain lowercase letters and minus characters. MUST start and end with a lowercase letter.||1||
|name||The name of this font.||1||
|description||Short description about this font (optional).||0-1||
|version||The version of this font. SHOULD follow semantic versioning.||1||
|author||The name of the copyright owner, in the format
|license||The SPDX identifier for the license of this font. Create multiple
|letter_spacing||Global letter space width for every glyph. Same unit as for polylines. If not specified, 0 is assumed (no space).||0-1||
|line_spacing||Vertical baseline distance of multiline texts. Same unit as for polylines. If not specified, 9 is assumed (no space).||0-1||
|monospace_width||Specifying this header marks the font as a monospace font. The value specifies the width of all glyphs (excluding global spacing).||0-1||
This is a very simple example font with only 6 glyphs. Its purpose is to demonstrate the features of the FontoBene format. Of course nobody should form a "B" glyph by inheriting from the "I" glyph in a real font. If you're interested in realistic examples of FonotBene fonts, please take a look at the fontobene-fonts repository instead.
[format] format = FontoBene format_version = 1.0.0 [font] id = spec-example name = FontoBene Specification Example description = This is an example font with only 6 glyphs included to demonstrate the FontoBene format. version = 1.0.0 license = CC0-1.0 ---  Space # A space character is 3.6 units wide ~3.6  A # An "A" consists of two simple polylines 0,0;3,9;6,0 1.2,3.6;4.8;3.6  I # A sans-serif "I": Just a straight vertical line 0,0;0,9 # Add a little horizontal space following the glyph ~0.5  B # The B character can be constructed by inheriting the "I"... @0049 # ...and adding two arc segments with 155° angle (=7.75) on the right side. 0,4.5,7.75;0,0 0,4.5,-7.75;0,9 # Cancel out the whitespace from "I". ~0 [005F] _ # A simple underline and some whitespace 0,0;3,0 ~0.25 [004C] L # Inherit from both "I" and "_" @0049 @005F # Note that we inherit 0.25 units of whitespace as defined # by the "_", since it is listed after the "I".