Glyph Interchange Format
The Glyph Interchange Format (or GLIF) is a simple and clear XML representation of a single glyph. It is a major part of the RoboFab project, and it is the foundation of the Unified Font Object. GLIF files typically have a ”.glif” extension.
Here is an example:
<?xml version=“1.0” encoding=“UTF-8”?> <glyph name=“period” format=“1”> <advance width=“268”/> <unicode hex=“002E”/> <outline> <contour> <point x=“237” y=“152”/> <point x=“193” y=“187”/> <point x=“134” y=“187” type=“curve” smooth=“yes”/> <point x=“74” y=“187”/> <point x=“30” y=“150”/> <point x=“30” y=“88” type=“curve” smooth=“yes”/> <point x=“30” y=“23”/> <point x=“74” y=”-10”/> <point x=“134” y=”-10” type=“curve” smooth=“yes”/> <point x=“193” y=”-10”/> <point x=“237” y=“25”/> <point x=“237” y=“88” type=“curve” smooth=“yes”/> </contour> </outline> <lib> <dict> <key>com.letterror.somestuff</key> <string>arbitrary custom data!</string> </dict> </lib> </glyph> </xml>
glyph is the top level element.
<glyph name="aGlyphName" format="1" >...<glyph>
|name||the name of the glyph|
|The “name” attribute is currently fairly useless. The contents.plist file maps glyph names to file names, and one of the reasons to do this is to avoid having to parse all files just to get at a list of available glyph names. So. When reading .glif files, the “name” attribute is probably best ignored, since manual editing may have caused a mismatch with the glyph name as stored in contents.plist, as well as with the file name, which is an algorithmic transformation of the glyph name. Yet the “name” attribute will become crucial once we implement our plan to allow multiple glyphs in one .glif file, which is slated for version 2 of the Glyph Interchange Format.|
|format||The format version, currently “1”.|
|advance||May occur at most once.|
|unicode||May occur any number of times.|
|outline||May occur at most once.|
|lib||May occur at most once.|
The advance element stores horizontal and vertical metrics. This element has no child elements.
<advance width="268"> <advance height="1000">
|width||An integer or a float; The advance width.|
|height||An integer or a float; The vertical advance (not yet implemented by us).|
The unicode element stores the Unicode code point for the glyph. This element has no child elements. The first occurance of this element defines the primary unicode value for this glyph.
|hex||A unicode code point as a hexadecimal number.|
Outline description. The outline element can contain a number of component or contour elements. This element has no attributes.
|component||May occur any number of times.|
|contour||May occur any number of times.|
The component element inserts another glyph as part of the outline. xScale, xyScale, yxScale, yScale, xOffset, yOffset taken together inthat order form an Affine transformation matrix, to be used to transform the base glyph. The default matrix is [1 0 0 1 0 0], the identity transformation. This element has no child elements.
<component base="a"/> <component base="acute" vOffset="20"/>
|base||name of the base glyph|
|xScale||int or float||1|
|xyScale||int or float||0|
|yxScale||int or float||0|
|yScale||int or float||1|
|xOffset||int or float||0|
|yOffset||int or float||0|
Contour description. This element can contain any number of point elements,
|point||May occur any number of times.|
An attributed coordinate pair. This element has no child elements. (See also SegmentsVersusPoints and PointPen, for discussions about how outlines work here.
<point x=“134” y=“187” type=“curve” smooth=“yes”/>
|x||int or float, The ‘x’ coordinate.|
|y||int or float, The ‘y’ coordinate.|
|“offcurve” The point and/or segment type, see below.||“offcurve”|
|The “smooth” attribute can only be given when “type” indicates the point is on-curve. When set to “yes”, it signifies that a smooth curvature should be maintained at this point, either as a “curve point” or a “tangent point” in Fontographer terms.|
|name||arbitrary name or label for this point. This attribute may contain an arbitrary string, to be used to label points. A point “name” does not have to be unique within a contour, nor within an outline.|
We have defined a basic set of possible values for the type attribute, with specific semantics (GLIF outlines have an API counterpart in the PointPen protocol, they’re designed to be very symmetrical with each other), yet different values may be used for alternative outline descriptions. The basic set is defined as follows:
|move||A point of this type MUST be the first in a contour. The reverse is not true: a contour does not neccesarily start with a “move” point. When a contour DOES start with a “move” point, it signifies the beginning of an OPEN contour. A CLOSED contour does NOT start with a “move” and is defined as a cyclic list of points, with no predominant start point. There is always a “next point” and a “previous point”. For this purpose the list of points can be seen as endless in both directions. The actual list of points can be rotated arbitrarily (by removing the first N points and appending them at the end) while still describing the same outline. The PointPen page discusses some of the issues involved when turning a list of points into segments.|
|line||Draw a straight line from the previous point to this point. The previous point may be a “move”, a “line”, a “curve” or a “qcurve”, but not an “offcurve”.|
|offcurve||This point is part of a curve segment, that goes up to the next point that is either a “curve” or a “qcurve”.|
|curve||Draw a cubic bezier curve from the last non-“offcurve” point to this point. If the number of “offcurve” points is zero, a straight line is drawn. If it is one, a quadratic curve is drawn. If it is two, a regular cubic bezier is drawn. If it is larger than 2, a series of cubic bezier segments are drawn, as defined by the SuperBezier algorithm.|
|qcurve||Similar to curve, but uses quadratic curves, using the TrueType “implied on-curve points” principle.|
<lib> <dict> <key>com.letterror.somestuff</key> <string>arbitrary custom data!</string> </dict> </lib>
Custom data storage, a.k.a. GlyphLib. No attributes, contents/child elements follow the "Property List":ufo/plist.html format. This element may occur at most once. *lib* has exactly one child, which must be *dict*. To avoid naming conflicts, keys must use ReverseDomainName-prefixed keys at the top level of this dictionary, for example "com.letterror.ourspecialdata".