# Font

See also

Notifications:

  The Font object uses notifications to notify observers of changes.

External Changes:

  The Font object can observe the files within the UFO for external modifications.

## Tasks

### File Operations

- `Font`

- `save()`

- `path`

- `ufoFormatVersion`

- `testForExternalChanges()`

- `reloadInfo()`

- `reloadKerning()`

- `reloadGroups()`

- `reloadFeatures()`

- `reloadLib()`

### Sub-Objects

- `info`

- `kerning`

- `groups`

- `features`

- `layers`

- `lib`

- `unicodeData`

### Glyphs

- `Font`

- `newGlyph()`

- `insertGlyph()`

- `keys()`

### Layers

- `newLayer()`

### Reference Data

- `glyphsWithOutlines`

- `componentReferences`

- `bounds`

- `controlPointBounds`

### Changed State

- `dirty`

### Notifications

- `dispatcher`

- `addObserver()`

- `removeObserver()`

- `hasObserver()`

#### Font

class defcon.Font(path=None, kerningClass=None, infoClass=None, groupsClass=None, featuresClass=None, libClass=None, unicodeDataClass=None, layerSetClass=None, layerClass=None, imageSetClass=None, dataSetClass=None, guidelineClass=None, glyphClass=None, glyphContourClass=None, glyphPointClass=None, glyphComponentClass=None, glyphAnchorClass=None, glyphImageClass=None)

  If loading from an existing UFO, path should be the path to the UFO.

  If you subclass one of the sub objects, such as `Glyph`, the class must be registered when the font is created for defcon to know about it. The *Class arguments allow for individual ovverrides. If None is provided for an argument, the defcon appropriate class will be used.

  This object posts the following notifications:

  - Font.Changed

  - Font.ReloadedGlyphs

  - Font.GlyphOrderChanged

  - Font.GuidelinesChanged

  - Font.GuidelineWillBeDeleted

  - Font.GuidelineWillBeAdded

  The Font object has some dict like behavior. For example, to get a glyph:

      glyph = font["aGlyphName"]

  To iterate over all glyphs:

      for glyph in font:

  To get the number of glyphs:

      glyphCount = len(font)

  To find out if a font contains a particular glyph:

      exists = "aGlyphName" in font

  To remove a glyph:

      del font["aGlyphName"]

  addObserver(observer, methodName, notification, identifier=None)

    Add an observer to this object’s notification dispatcher.

    - observer An object that can be referenced with weakref.

    - methodName A string representing the method to be called when the notification is posted.

    - notification The notification that the observer should be notified of.

    - identifier None or a string identifying the observation. There is no requirement that the string be unique. A reverse domain naming scheme is recommended, but there are no requirements for the structure of the string.

    The method that will be called as a result of the action must accept a single notification argument. This will be a `defcon.tools.notifications.Notification` object.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.addObserver(observer=observer, methodName=methodName,
            notification=notification, observable=anObject, identifier=identifier)

  appendGuideline(guideline)

    Append guideline to the font. The guideline must be a defcon `Guideline` object or a subclass of that object. An error will be raised if the guideline’s identifier conflicts with any of the identifiers within the font.

    This will post Font.GuidelinesChanged and Font.Changed notifications.

  property bounds

    The bounds of all glyphs in the font’s main layer. This can be an expensive operation.

  canRedo()

    Returns a boolean indicating whether the undo manager is able to perform a redo.

  canUndo()

    Returns a boolean indicating whether the undo manager is able to perform an undo.

  clearGuidelines()

    Clear all guidelines from the font.

    This posts a Font.Changed notification.

  property componentReferences

    A dict of describing the component relationships in the font’s main layer. The dictionary is of form `{base glyph : [references]}`.

  property controlPointBounds

    The control bounds of all glyphs in the font’s main layer. This only measures the point positions, it does not measure curves. So, curves without points at the extrema will not be properly measured. This is an expensive operation.

  property data

    The font’s `DataSet` object.

  destroyAllRepresentations(notification=None)

    Destroy all representations.

  destroyRepresentation(name, **kwargs)

    Destroy the stored representation for name and **kwargs. If no kwargs are given, any representation with name will be destroyed regardless of the kwargs passed when the representation was created.

  property dirty

    The dirty state of the object. True if the object has been changed. False if not. Setting this to True will cause the base changed notification to be posted. The object will automatically maintain this attribute and update it as you change the object.

  disableNotifications(notification=None, observer=None)

    Disable this object’s notifications until told to resume them.

    - notification The specific notification to disable. This is optional. If no notification is given, all notifications will be disabled.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.disableNotifications(
            observable=anObject, notification=notification, observer=observer)

  property dispatcher

    The `defcon.tools.notifications.NotificationCenter` assigned to this font.

  enableNotifications(notification=None, observer=None)

    Enable this object’s notifications.

    - notification The specific notification to enable. This is optional.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.enableNotifications(
            observable=anObject, notification=notification, observer=observer)

  property features

    The font’s `Features` object.

  findObservations(observer=None, notification=None, observable=None, identifier=None)

    Find observations of this object matching the given arguments based on the values that were passed during addObserver. A value of None for any of these indicates that all should be considered to match the value. In the case of identifier, strings will be matched using fnmatch.fnmatchcase. The returned value will be a list of dictionaries with this format:

    > [
    >   {

    >     observer=<…> observable=<…> methodName=”…” notification=”…” identifier=”…”

    >   }

    > ]

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.findObservations(
            observer=observer, observable=anObject,
            notification=notification, identifier=identifier
        )

  getDataForSerialization(**kwargs)

    Return a dict of data that can be pickled.

  getRepresentation(name, **kwargs)

    Get a representation. name must be a registered representation name. **kwargs will be passed to the appropriate representation factory.

  getSaveProgressBarTickCount(formatVersion=None)

    Get the number of ticks that will be used by a progress bar in the save method. Subclasses may override this method to implement custom saving behavior.

  property glyphOrder

    The font’s glyph order. When setting the value must be a list of glyph names. There is no requirement, nor guarantee, that the list will contain only names of glyphs in the font. Setting this posts Font.GlyphOrderChanged and Font.Changed notifications.

  property glyphsWithOutlines

    A list of glyphs containing outlines in the font’s main layer.

  property groups

    The font’s `Groups` object.

  guidelineIndex(guideline)

    Get the index for guideline.

  property guidelines

    An ordered list of `Guideline` objects stored in the font. Setting this will post a Font.Changed notification along with any notifications posted by the `Font.appendGuideline()` and `Font.clearGuidelines()` methods.

  hasCachedRepresentation(name, **kwargs)

    Returns a boolean indicating if a representation for name and **kwargs is cached in the object.

  hasObserver(observer, notification)

    Returns a boolean indicating is the observer is registered for notification.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.hasObserver(observer=observer,
            notification=notification, observable=anObject)

  holdNotifications(notification=None, note=None)

    Hold this object’s notifications until told to release them.

    - notification The specific notification to hold. This is optional. If no notification is given, all notifications will be held.

    - note An arbitrary string containing information about why the hold has been requested, the requester, etc. This is used for reference only.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.holdNotifications(
            observable=anObject, notification=notification, note=note)

  property identifiers

    Set of identifiers for the info. This is primarily for internal use.

  property images

    The font’s `ImageSet` object.

  property info

    The font’s `Info` object.

  insertGlyph(glyph, name=None)

    Insert glyph into the font’s main layer. Optionally, the glyph can be renamed at the same time by providing name. If a glyph with the glyph name, or the name provided as name, already exists, the existing glyph will be replaced with the new glyph.

  insertGuideline(index, guideline)

    Insert guideline into the font at index. The guideline must be a defcon `Guideline` object or a subclass of that object. An error will be raised if the guideline’s identifier conflicts with any of the identifiers within the font.

    This will post Font.GuidelinesChanged and Font.Changed notifications.

  property kerning

    The font’s `Kerning` object.

  property kerningGroupConversionRenameMaps

    The kerning group rename map that will be used when writing UFO 1 and UFO 2. This follows the format defined in UFOReader. This will only not be None if it has been set or this object was loaded from a UFO 1 or UFO 2 file.

  property layers

    The font’s `LayerSet` object.

  property lib

    The font’s `Lib` object.

  newGlyph(name)

    Create a new glyph with name in the font’s main layer. If a glyph with that name already exists, the existing glyph will be replaced with the new glyph.

  newLayer(name)

    Create a new `Layer` and add it to the top of the layer order.

    This posts LayerSet.LayerAdded and LayerSet.Changed notifications.

  property path

    The location of the file on disk. Setting the path should only be done when the user has moved the file in the OS interface. Setting the path is not the same as a save operation.

  postNotification(notification, data=None)

    Post a notification through this object’s notification dispatcher.

    > - notification The name of the notification.

    > - data Arbitrary data that will be stored in the `Notification` object.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.postNotification(
            notification=notification, observable=anObject, data=data)

  redo()

    Perform a redo if possible, or return. If redo is performed, this will post BaseObject.BeginRedo and BaseObject.EndRedo notifications.

  releaseHeldNotifications(notification=None)

    Release this object’s held notifications.

    - notification The specific notification to hold. This is optional.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.releaseHeldNotifications(
            observable=anObject, notification=notification)

  reloadData(fileNames)

    Reload the data files listed in fileNames from the appropriate files within the UFO. When all of the loading is complete, a Font.ReloadedData notification will be posted.

  reloadFeatures()

    Reload the data in the `Features` object from the features.fea file in the UFO.

  reloadGlyphs(glyphNames)

    Deprecated! Use reloadLayers!

    Reload the glyphs listed in glyphNames from the appropriate files within the UFO. When all of the loading is complete, a Font.ReloadedGlyphs notification will be posted.

  reloadGroups()

    Reload the data in the `Groups` object from the groups.plist file in the UFO.

  reloadImages(fileNames)

    Reload the images listed in fileNames from the appropriate files within the UFO. When all of the loading is complete, a Font.ReloadedImages notification will be posted.

  reloadInfo()

    Reload the data in the `Info` object from the fontinfo.plist file in the UFO.

  reloadKerning()

    Reload the data in the `Kerning` object from the kerning.plist file in the UFO.

    This validates the kerning against the groups loaded into the font. If groups are being reloaded in the same pass, the groups should always be reloaded before reloading the kerning.

  reloadLayers(layerData)

    Reload the data in the layers specfied in layerData. When all of the loading is complete, Font.ReloadedLayers and Font.ReloadedGlyphs notifications will be posted. The layerData must be a dictionary following this format:

        {
            "order"   : bool, # True if you want the order releaded
            "default" : bool, # True if you want the default layer reset
            "layers"  : {
                "layer name" : {
                    "glyphNames" : ["glyph name 1", "glyph name 2"], # list of glyph names you want to reload
                    "info"       : bool, # True if you want the layer info reloaded
                }
            }
        }

  reloadLib()

    Reload the data in the `Lib` object from the lib.plist file in the UFO.

  removeGuideline(guideline)

    Remove guideline from the font.

    This will post Font.GuidelineWillBeDeleted, Font.GuidelinesChanged and Font.Changed notifications.

  removeObserver(observer, notification)

    Remove an observer from this object’s notification dispatcher.

    - observer A registered object.

    - notification The notification that the observer was registered to be notified of.

    This is a convenience method that does the same thing as:

        dispatcher = anObject.dispatcher
        dispatcher.removeObserver(observer=observer,
            notification=notification, observable=anObject)

  representationKeys()

    Get a list of all representation keys that are currently cached.

  save(path=None, formatVersion=None, removeUnreferencedImages=False, progressBar=None, structure=None)

    Save the font to path. If path is None, the path from the last save or when the font was first opened will be used.

    The UFO will be saved using the format found at `ufoFormatVersion`. This value is either the format version from the exising UFO or the format version specified in a previous save. If neither of these is available, the UFO will be written as format version 3. If you wish to specifiy the format version for saving, pass the desired number as the formatVersion argument.

    Optionally, the UFO can be purged of unreferenced images during this operation. To do this, pass `True` as the value for the removeUnreferencedImages argument.

    ‘structure’ can be either None, “zip” or “package”. If it’s None, the destination UFO will use the same structure as original, provided that is compatible with any previous UFO at the output path. If ‘structure’ is “zip” the UFO will be saved as compressed archive, else it is saved as a regular folder or “package”.

  saveData(writer, saveAs=False, progressBar=None)

    Save data. This method should not be called externally. Subclasses may override this method to implement custom saving behavior.

  saveFeatures(writer)

    Save features. This method should not be called externally. Subclasses may override this method to implement custom saving behavior.

  saveGroups(writer)

    Save groups. This method should not be called externally. Subclasses may override this method to implement custom saving behavior.

  saveImages(writer, removeUnreferencedImages=False, saveAs=False, progressBar=None)

    Save images. This method should not be called externally. Subclasses may override this method to implement custom saving behavior.

  saveInfo(writer)

    Save info. This method should not be called externally. Subclasses may override this method to implement custom saving behavior.

  saveKerning(writer)

    Save kerning. This method should not be called externally. Subclasses may override this method to implement custom saving behavior.

  saveLib(writer, saveAs=False, progressBar=None)

    Save lib. This method should not be called externally. Subclasses may override this method to implement custom saving behavior.

  setDataFromSerialization(data)

    Restore state from the provided data-dict.

  property tempLib

    The font’s `tempLib` object.

  testForExternalChanges()

    Test the UFO for changes that occured outside of this font’s tree of objects. This returns a dictionary describing the changes:

        {
            "info"     : bool, # True if changed, False if not changed
            "kerning"  : bool, # True if changed, False if not changed
            "groups"   : bool, # True if changed, False if not changed
            "features" : bool, # True if changed, False if not changed
            "lib"      : bool, # True if changed, False if not changed
            "layers"   : {
                "defaultLayer" : bool, # True if changed, False if not changed
                "order"        : bool, # True if changed, False if not changed
                "added"        : ["layer name 1", "layer name 2"],
                "deleted"      : ["layer name 1", "layer name 2"],
                "modified"     : {
                    "info"     : bool, # True if changed, False if not changed
                    "modified" : ["glyph name 1", "glyph name 2"],
                    "added"    : ["glyph name 1", "glyph name 2"],
                    "deleted"  : ["glyph name 1", "glyph name 2"]
                }
            },
            "images"   : {
                "modified" : ["image name 1", "image name 2"],
                "added"    : ["image name 1", "image name 2"],
                "deleted"  : ["image name 1", "image name 2"],
            },
            "data"     : {
                "modified" : ["file name 1", "file name 2"],
                "added"    : ["file name 1", "file name 2"],
                "deleted"  : ["file name 1", "file name 2"],
            }
        }

    It is important to keep in mind that the user could have created conflicting data outside of the font’s tree of objects. For example, say the user has set `font.info.unitsPerEm = 1000` inside of the font’s `Info` object and the user has not saved this change. In the the font’s fontinfo.plist file, the user sets the unitsPerEm value to 2000. Which value is current? Which value is right? defcon leaves this decision up to you.

  property ufoFileStructure

    The UFO file structure that will be used when saving. This is taken from a loaded UFO during __init__. If this font was not loaded from a UFO, this will return None until the font has been saved.

  property ufoFormatVersion

    The UFO format major version that will be used when saving. This is taken from a loaded UFO during __init__. If this font was not loaded from a UFO, this will return None until the font has been saved. Deprecated, use ufoFormatVersionTuple instead.

  property ufoFormatVersionTuple

    The UFO format (major, minor) version tuple that will be used when saving. This is taken from a loaded UFO during __init__. If this font was not loaded from a UFO, this will return None until the font has been saved.

  undo()

    Perform an undo if possible, or return. If undo is performed, this will post BaseObject.BeginUndo and BaseObject.EndUndo notifications.

  property undoManager

    The undo manager assigned to this object.

  property unicodeData

    The font’s `UnicodeData` object.

  updateGlyphOrder(addedGlyph=None, removedGlyph=None)

    This method tries to keep the glyph order in sync. This should not be called externally. It may be overriden by subclasses as needed.