# Font

Note

This section needs to contain the following:

- description of what this is ✓

- sub-object with basic usage ✓

- bridge to default layer for glyphs for backwards compatibility ✗

- glyph interaction with basic usage ✗

## Description

The `Font` object is the central part that connects all glyphs with font information like names, key dimensions etc.

`Font` objects behave like dictionaries: the glyph name is the key and the returned value is a `Glyph` object for that glyph. If the glyph does not exist, `Font` will raise an `IndexError`.

`Font` has a couple of important sub-objects which are worth checking out. The font’s kerning is stored in a `Kerning` object and can be reached as an attribute at `Font.kerning`. Fontnames, key dimensions, flags etc are stored in a `Info` object which is available through `Font.info`. The `Font.lib` is a `Lib` object which behaves as a dictionary.

## Overview

### Copy

`BaseFont.copy` | Copy the font into a new font. ::.

### File Operations

`BaseFont.path` | The path to the file this object represents. ::.
`BaseFont.save` | Save the font to path.
`BaseFont.generate` | Generate the font to another format.

### Sub-Objects

`BaseFont.info` | The font's `BaseInfo` object.
`BaseFont.groups` | The font's `BaseGroups` object.
`BaseFont.kerning` | The font's `BaseKerning` object.
`BaseFont.features` | The font's `BaseFeatures` object.
`BaseFont.lib` | The font's `BaseLib` object.
`BaseFont.tempLib` | The font's `BaseLib` object. ::.

### Layers

`BaseFont.layers` | The font's `BaseLayer` objects.
`BaseFont.layerOrder` | A list of layer names indicating order of the layers in the font.
`BaseFont.defaultLayer` | The font's default layer.
`BaseFont.getLayer` | Get the `BaseLayer` with name.
`BaseFont.newLayer` | Make a new layer with name and color.
`BaseFont.removeLayer` | Remove the layer with name from the font.
`BaseFont.insertLayer` | Insert layer into the font. ::.
`BaseFont.duplicateLayer` | Duplicate the layer with layerName, assign newLayerName to the new layer and insert the new layer into the font. ::.

### Glyphs

`BaseFont.__len__` | An `int` representing number of glyphs in the layer. ::.
`BaseFont.keys` | Get a list of all glyphs in the layer. ::.
`BaseFont.glyphOrder` | The preferred order of the glyphs in the font.
`BaseFont.__iter__` | Iterate through the `BaseGlyph` objects in the layer. ::.
`BaseFont.__contains__` | Test if the layer contains a glyph with name. ::.
`BaseFont.__getitem__` | Get the `BaseGlyph` with name from the layer. ::.
`BaseFont.newGlyph` | Make a new glyph with name in the layer. ::.
`BaseFont.insertGlyph` | Insert glyph into the layer. ::.
`BaseFont.removeGlyph` | Remove the glyph with name from the layer. ::.

## Reference

class fontParts.base.BaseFont(pathOrObject=None, showInterface=True)

  A font object. This object is almost always created with one of the font functions in fontparts-world.

  When constructing a font, the object can be created in a new file, from an existing file or from a native object. This is defined with the pathOrObjectArgument. If pathOrObject is a string, the string must represent an existing file. If pathOrObject is an instance of the environment’s unwrapped native font object, wrap it with FontParts. If pathOrObject is None, create a new, empty font. If showInterface is `False`, the font should be created without graphical interface. The default for showInterface is `True`.

### Copy

BaseFont.copy()

  Copy the font into a new font.

      >>> copiedFont = font.copy()

  This will copy:

  - info

  - groups

  - kerning

  - features

  - lib

  - layers

  - layerOrder

  - defaultLayerName

  - glyphOrder

  - guidelines

### File Operations

BaseFont.path

  The path to the file this object represents.

      >>> print font.path
      "/path/to/my/font.ufo"

BaseFont.save(path=None, showProgress=False, formatVersion=None, fileStructure=None)

  Save the font to path.

      >>> font.save()
      >>> font.save("/path/to/my/font-2.ufo")

  If path is None, use the font’s original location. The file type must be inferred from the file extension of the given path. If no file extension is given, the environment may fall back to the format of its choice. showProgress indicates if a progress indicator should be displayed during the operation. Environments may or may not implement this behavior. formatVersion indicates the format version that should be used for writing the given file type. For example, if 2 is given for formatVersion and the file type being written if UFO, the file is to be written in UFO 2 format. This value is not limited to UFO format versions. If no format version is given, the original format version of the file should be preserved. If there is no original format version it is implied that the format version is the latest version for the file type as supported by the environment. fileStructure indicates the file structure of the written ufo. The fileStructure can either be None, ‘zip’ or ‘package’, None will use the existing file strucure or the default one for unsaved font. ‘package’ is the default file structure and ‘zip’ will save the font to .ufoz.

  Note

  Environments may define their own rules governing when a file should be saved into its original location and when it should not. For example, a font opened from a compiled OpenType font may not be written back into the original OpenType font.

BaseFont.close(save=False)

  Close the font.

      >>> font.close()

  save is a boolean indicating if the font should be saved prior to closing. If save is `True`, the `BaseFont.save` method will be called. The default is `False`.

BaseFont.generate(format, path=None, **environmentOptions)

  Generate the font to another format.

      >>> font.generate("otfcff")
      >>> font.generate("otfcff", "/path/to/my/font.otf")

  format defines the file format to output. Standard format identifiers can be found in `BaseFont.generateFormatToExtension`:

  Environments are not required to support all of these and environments may define their own format types. path defines the location where the new file should be created. If a file already exists at that location, it will be overwritten by the new file. If path defines a directory, the file will be output as the current file name, with the appropriate suffix for the format, into the given directory. If no path is given, the file will be output into the same directory as the source font with the file named with the current file name, with the appropriate suffix for the format.

  Environments may allow unique keyword arguments in this method. For example, if a tool allows decomposing components during a generate routine it may allow this:

      >>> font.generate("otfcff", "/p/f.otf", decompose=True)

### Sub-Objects

BaseFont.info

  The font’s `BaseInfo` object.

      >>> font.info.familyName
      "My Family"

BaseFont.groups

  The font’s `BaseGroups` object.

      >>> font.groups["myGroup"]
      ["A", "B", "C"]

BaseFont.kerning

  The font’s `BaseKerning` object.

      >>> font.kerning["A", "B"]
      -100

BaseFont.features

  The font’s `BaseFeatures` object.

      >>> font.features.text
      "include(features/substitutions.fea);"

BaseFont.lib

  The font’s `BaseLib` object.

      >>> font.lib["org.robofab.hello"]
      "world"

### Layers

BaseFont.layers

  The font’s `BaseLayer` objects.

      >>> for layer in font.layers:
      ...     layer.name
      "My Layer 1"
      "My Layer 2"

BaseFont.layerOrder

  A list of layer names indicating order of the layers in the font.

      >>> font.layerOrder = ["My Layer 2", "My Layer 1"]
      >>> font.layerOrder
      ["My Layer 2", "My Layer 1"]

BaseFont.defaultLayer

  The font’s default layer.

      >>> layer = font.defaultLayer
      >>> font.defaultLayer = otherLayer

BaseFont.getLayer(name)

  Get the `BaseLayer` with name.

      >>> layer = font.getLayer("My Layer 2")

BaseFont.newLayer(name, color=None)

  Make a new layer with name and color. name must be a String and color must be a Color or `None`.

      >>> layer = font.newLayer("My Layer 3")

  The will return the newly created `BaseLayer`.

BaseFont.removeLayer(name)

  Remove the layer with name from the font.

      >>> font.removeLayer("My Layer 3")

BaseFont.insertLayer(layer, name=None)

  Insert layer into the font.

      >>> layer = font.insertLayer(otherLayer, name="layer 2")

  This will not insert the layer directly. Rather, a new layer will be created and the data from layer will be copied to to the new layer. name indicates the name that should be assigned to the layer after insertion. If name is not given, the layer’s original name must be used. If the layer does not have a name, an error must be raised. The data that will be inserted from layer is the same data as documented in `BaseLayer.copy`.

### Glyphs

Interacting with glyphs at the font level is a shortcut for interacting with glyphs in the default layer.

    >>> glyph = font.newGlyph("A")

Does the same thing as:

    >>> glyph = font.getLayer(font.defaultLayerName).newGlyph("A")

BaseFont.__len__()

  An `int` representing number of glyphs in the layer.

      >>> len(layer)
      256

BaseFont.keys()

  Get a list of all glyphs in the layer.

      >>> layer.keys()
      ["B", "C", "A"]

  The order of the glyphs is undefined.

BaseFont.glyphOrder

  The preferred order of the glyphs in the font.

      >>> font.glyphOrder
      ["C", "B", "A"]
      >>> font.glyphOrder = ["A", "B", "C"]

BaseFont.__iter__()

  Iterate through the `BaseGlyph` objects in the layer.

      >>> for glyph in layer:
      ...     glyph.name
      "A"
      "B"
      "C"

BaseFont.__contains__(name)

  Test if the layer contains a glyph with name.

      >>> "A" in layer
      True

BaseFont.__getitem__(name)

  Get the `BaseGlyph` with name from the layer.

      >>> glyph = layer["A"]

BaseFont.newGlyph(name, clear=True)

  Make a new glyph with name in the layer.

      >>> glyph = layer.newGlyph("A")

  The newly created `BaseGlyph` will be returned.

  If the glyph exists in the layer and clear is set to `False`, the existing glyph will be returned, otherwise the default behavior is to clear the exisiting glyph.

BaseFont.insertGlyph(glyph, name=None)

  Insert glyph into the layer.

      >>> glyph = layer.insertGlyph(otherGlyph, name="A")

  This will return the inserted glyph. This method is deprecated. `BaseFont.__setitem__` instead.

BaseFont.removeGlyph(name)

  Remove the glyph with name from the layer.

      >>> layer.removeGlyph("A")

  This method is deprecated. `BaseFont.__delitem__` instead.

### Guidelines

BaseFont.guidelines

  An Immutable List of font-level `BaseGuideline` objects.

      >>> for guideline in font.guidelines:
      ...     guideline.angle
      0
      45
      90

BaseFont.appendGuideline(position=None, angle=None, name=None, color=None, guideline=None)

  Append a new guideline to the font.

      >>> guideline = font.appendGuideline((50, 0), 90)
      >>> guideline = font.appendGuideline((0, 540), 0, name="overshoot",
      >>> color=(0, 0, 0, 0.2))

  position must be a Coordinate indicating the position of the guideline. angle indicates the Angle of the guideline. name indicates the name for the guideline. This must be a String or `None`. color indicates the color for the guideline. This must be a Color or `None`. This will return the newly created `BaseGuidline` object.

  `guideline` may be a `BaseGuideline` object from which attribute values will be copied. If `position`, `angle`, `name` or `color` are specified as arguments, those values will be used instead of the values in the given guideline object.

BaseFont.removeGuideline(guideline)

  Remove guideline from the font.

      >>> font.removeGuideline(guideline)
      >>> font.removeGuideline(2)

  guideline can be a guideline object or an integer representing the guideline index.

BaseFont.clearGuidelines()

  Clear all guidelines.

      >>> font.clearGuidelines()

### Interpolation

BaseFont.isCompatible(other)

  Evaluate interpolation compatibility with other.

      >>> compatible, report = self.isCompatible(otherFont)
      >>> compatible
      False
      >>> report
      [Fatal] Glyph: "test1" + "test2"
      [Fatal] Glyph: "test1" contains 1 contours | "test2" contains 2 contours

  This will return a `bool` indicating if the font is compatible for interpolation with other and a String of compatibility notes.

BaseFont.interpolate(factor, minFont, maxFont, round=True, suppressError=True)

  Interpolate all possible data in the font.

      >>> font.interpolate(0.5, otherFont1, otherFont2)
      >>> font.interpolate((0.5, 2.0), otherFont1, otherFont2, round=False)

  The interpolation occurs on a 0 to 1.0 range where minFont is located at 0 and maxFont is located at 1.0. factor is the interpolation value. It may be less than 0 and greater than 1.0. It may be a Integer/Float or a tuple of two Integer/Float. If it is a tuple, the first number indicates the x factor and the second number indicates the y factor. round indicates if the result should be rounded to integers. suppressError indicates if incompatible data should be ignored or if an error should be raised when such incompatibilities are found.

### Normalization

BaseFont.round()

  Round all approriate data to integers.

      >>> font.round()

  This is the equivalent of calling the round method on:

  - info

  - kerning

  - the default layer

  - font-level guidelines

  This applies only to the default layer.

BaseFont.autoUnicodes()

  Use heuristics to set Unicode values in all glyphs.

      >>> font.autoUnicodes()

  Environments will define their own heuristics for automatically determining values.

  This applies only to the default layer.

### Environment

BaseFont.naked()

  Return the environment’s native object that has been wrapped by this object.

      >>> loweLevelObj = obj.naked()

BaseFont.changed(*args, **kwargs)

  Tell the environment that something has changed in the object. The behavior of this method will vary from environment to environment.

      >>> obj.changed()

Previous

Objects

Next

Info