The Complete RoboFont Guide

Welcome to RoboFont

RoboFont is a UFO-based font editor for Mac OS X.

RoboFont provides a simple-to-use environment to draw and modify typefaces in. It has the following main design features:

  • Is written from scratch in Python with scalability in mind.
  • Has full scripting access to objects and the application interface.
  • Can be used as a platform to build additional tools on.
  • Does not preform any ‘auto-magic’.
  • Does not overload the user with a multitude of options.
  • Uses the UFO format as it's native file format.

The operating philosophy behind RoboFont is:

The tools you choose influence your creative process.

Because of this, RoboFont provides many opportunities for the user to tailor the application to their design process. It is strict about not preforming ‘auto-magic’ on one’s font files, ‘auto-’ anything is avoided if possible. This means that it does not do and does not have some features of other font editing applications. Because the application is extensible, if a user finds a need in their design process for a feature that isn’t part of RoboFont, it can be added. This allows the user the control to design the application to their design process.

However, the core of RoboFont is a full featured drawing editor, containing all the basic tools a typeface designer needs for drawing and modifying a design.

RoboFont design principles

Motivation

A typeface designer (who does not want to do any scripting and has no means of letting someone else do that work), has to deal with the available user interface, tool set, feature set, and the list of bugs in the typeface design applications they use. This makes the designer a victim to the development of applications that are often merely production tools and not intended for design iterations. Not being (partly) the designer of your own tools puts a designer in a vulnerable position.

Specialized tools

Spreading functions over different tools reduces the need to buy them all at the same time, or pay for the development of a function you don’t require. Or you can do better yourself and write your own custom tool for a function. Functions can be added over time as they become available and technology changes.

Decentralized development also means that a group of people can work on the functions that they really do need and are extremely capable of making and maintaining.

The role of RoboFont

The idea behind RoboFont is to provide a sturdy framework where everyone can add their own functionalities with Python, rather than a program with hundreds of (often little needed) functions.

Constructing an open structure for RoboFont allows any developer to add new technologies to the overall functionality, without the need for the main developer(s) to put it on top of their list. It also allows competition between ideas and technologies, as any developer’s idea of how something should work can be part of RoboFont.

This is very different from having one application that can only do most of the things on a average level. It also means that upgrading a single function implies upgrading the entire application, which often is not attractive to a developer. This can result in a lag between the introduction of a new technology/upgraded function and the ability to use that technology/upgraded function. Lastly, one is locked into the developer’s idea of how a function should work, rather than being able to choose how the function should work for you.

No previous knowledge

An application shouldn’t design for a designer, as it is just a tool. Pencils do not illustrate, printing presses do not layout, and a typeface design application shouldn’t make autonomous decisions. The typeface designer should make the decisions and have the power to design their fonts.

Think of RoboFont as a second desktop for your typeface design work. Like your physical desk, it can be customized for different kinds of design work. For example, your settings can be very different if you are designing a headline typeface or working on a revival. RoboFont allows you to change and optimize your editor settings from project to project.

Full scripting support

RoboFont is programmed in Python from the ground up. The entire application is object oriented, allowing any user to dive into the deep functionality of RoboFont and overwrite/redefine/add functions —even at the core of the program— simply by inheriting the existing classes. This way there is a total melding between scripting and coding of the main application.

A platform for building custom tools and extensions

RoboFont is a rich environment for developing one’s own custom tools. The extensibility of it’s object model allows a designer to build whatever they can think of on the base of RoboFont. If a designer isn’t inclined to write additional tools for the RoboFont environment, one can see a near-term future for the sharing or sale of scripts and extension to RoboFont.

Working with UFOs

What is UFO?

UFO stands for Unified Font Object. It is a cross-platform, cross-application, human readable, future proof format for storing font data. The format is developed by Erik van Blokland, Tal Leming, and Just van Rossum. Because it is application neutral, several typeface design and font production applications use it natively; these are referred to as ‘UFO Tools’. UFO is a simple specification, one can rely on the ability to read/write the font data into the future, whatever the application landscape will look like then.

Advantages of UFO

  • An open and documented format
  • UFO is XML: standards-based, future proof, easy to read and write
  • Each glyph is stored separately – easy to access and track versions
  • One can import/export UFO’s from FontLab, Glyphs, and FontForge

Possible disadvantage:

  • Larger files (XML is verbose)

Converting font sources to UFO format

If you are switching to RoboFont from other applications, the first thing you’ll need to do is convert your font files to UFO.

From FontLab

The easiest way to export UFOs from FontLab (version 4 or version 5) is by using Tal Leming’s UFOCentral python script. If you don’t have RoboFab installed, do so first. Install the linked script into your user/Library/Application Support/FontLab/Studio 5/Macros folder. After doing so, restart FontLab if it was running, and go to the macros panel. You should see ‘UFOCentral’ as an option now. With a VFB(s) open, run the script, selecting the Export checkbox. Be sure to select the ‘Format 2’ option (it is the default). The script will then export your VFB(s).

From Glyphs

Go to File ⇢ Export. Select UFO as the export option.

From FontForge

Select the UFO option from File ⇢ Save As.

UFO Tools

Besides RoboFont, there are several other tools for working with UFO files, all doing different things. As of October 19th, 2011 here is a list:

  • MetricsMachine: Tool for kerning
  • Area51: Tool to inspect UFOs, generate fonts, and test features
  • Prepolator: Tool to check fonts for interpolation compatibility
  • Superpolator: Tool to Superpolate fonts
  • RoundingUFO: Tool to round the corners (and more) of glyphs
  • UFOStretch: Tool to transform, translate and interpolate a specific set of glyphs.

Technical specifications

RoboFont requires OSX version 10.6+. It is fully compatible with OSX 10.7+ (Lion) and 10.8+ (Mountain Lion).

RoboFont embeds the AdobeFDK version 2.5 change number 58732, but allows the user to use their own installed version of the AdobeFDK if desired. (see Preferences

What RoboFont can do:

  • drawing
  • editing
  • mastering font info
  • spacing
  • basic kerning
  • general PostScript hint settings
  • PostScript autohinting
  • TrueType autohinting if ttfautohint is installed on your system
  • OpenType feature code editing

What RoboFont cannot currently do:

  • PostScript hint editing
  • TrueType instructions editing
  • font mastering
These features can be done with an extension or a script, they are not part of the core application.

Workspace

RoboFont contains lots of different windows and views, each one connected to a specific function.

Editor environment

Different application windows can be displayed separately or collected into a single window. (Adjust in the Preferences.)

Window mode

Single-window mode

Multi-window mode

Multi-window mode

Font collection

 

Font collection window

Displays all glyphs in the font, allows sorting with groups, filters, smart lists, etc.

Read more: Font Collection

Glyph Editor

Displays one single glyph for editing.

Read more: Glyph Editor

Metrics

Both Space Center and Kern Center display a string of glyphs for testing words and working on spacing and kerning.

Read more: Space Center, Kern Center

Scripting Editor

The scripting editor is the place to write and run Python scripts.

Read more: Scripting

Extensions

 

RoboFont can easily be extended with additional features and add-ons. Developers can use the Extensions Builder to package RoboFont plugins.

Read more: Extensions

Preferences

RoboFont allows users to customize many aspects of its interface and behavior through the Preferences window.

Read more: Preferences

Additional sheets and assisting windows

All sheets and assisting windows will apply the changes with 'enter' down and close with 'esc' or 'command+.' down. If a 'close' or 'OK' / 'Apply' button is provided.

  • Jump to glyph
    Accessible in the Glyph Editor and Space Center with a hot key (set in the Preferences)
  • Jump to line
    Accessible in the Scripting code editor and Feature editor with 'command+j' 

Font Collection

Font collection window

The Font Collection displays an overview of all the glyphs contained the font. It has several tools and functions to create and manage glyph collections, and to order the glyphs in the window.

Users can define a preset character set to display ‘glyphs-still-to-draw’.
(see Preferences)

single click Select single glyph
single click + alt (multi window mode) Opens a new glyph window.
single click (single window mode) Select single glyph and send it to the glyph view
double click (single window mode) Send the glyph to the glyph view
click + drag

Drag the selection on the same Font Overview

  • drop between the glyph cells: reorder the glyph order of the font.
  • drop on a glyph cell: copy the dragged glyphs in the destination glyph cell, use alt down to copy as component.

 

Drag the selection to other views

  • other Font Collection View: add the glyphs to the other font and set the order of dropped between glyph cells.
  • Space Center: set the glyph names to as input for spacing, use alt to append the glyph names.
  • Smart sets: creates a new set with the dragged glyphs.
click + command + drag Alter the selection while moving the mouse.
copy Copies the selected glyphs to the clip board as glyph objects and the glyph names as string representation.
copy as component Copies the selected glyph as component, only if a single glyph is selected.
paste
  • If there is no selection it appends the copied glyphs to the font.
  • If amount of the selected glyphs is the same as the amount of copied glyphs, RoboFont will replace them with the copied glyphs.
undo/redo Undo or redo the selected glyph(s)
start typing a glyph name Tries to find and select that glyph
⌘ + J Opens a Jump To Glyph window.
delete Remove the glyph from the font
alt + delete Remove the glyph from the font and the template glyph from the Font Overview.

Adding and Deleting Glyphs

Adding Glyphs

An Add glyphs sheet will shown the place to append glyphs to a font 
(Application menu ⇢ Font ⇢ Add Glyphs)

Add glyphs

In the text editor users can type glyph names to add the font. It should be a space sperated list of glyph names

Glyph name formatting
  • <glyphName>

    a agrave

    Creates a glyph with the given glyph name.

  • <glyphName>=<baseGlyphName>+<baseGlyphName>…

    agrave=a+grave

    Creates a glyph with the given glyph name and adds a component referenced to glyph named ‘a’ and ‘grave’ to a glyph named ‘agrave’.

    (There are no spaces in the simple glyph math)

  • <glyphName>=<baseGlyphName>+<baseGlyphName>@<anchorName> …

    agrave=a+grave@top

    Creates a glyph with the given glyph name and adds a component referenced to a glyph named 'a' and 'grave' to a glyph named 'agrave'

    The position 'top' is a reference to an anchor to specify the offset. Both glyph must have an anchor with <anchorName> and <_anchorName>.

  • <glyphName>|<unicode>

    a|0061

    Creates a glyph with the givin glyph name and adds unicode value ‘0061’ to glyph named ‘a’.

  • <glyphName>=<baseGlyphName>+<baseGlyphName>…|<unicode>

    agrave=a+grave|00E0

    Combine all glyph name formating. Creates a glyph with the givin glyph name and adds a components referenced to glyph named ‘a’ and ‘grave’ to a glyph named ‘agrave’ and adds unicode value ‘00E0’ to glyph named ‘agrave’

    (There are no spaces in the simple glyph math)

Enable Add Unicode to generate unicodes for the newly created glyphs. Enable Sort Font to resort the font after glyphs has been added.

 
Deleting Glyphs

Select a glyph or range of glyphs (shift or option click) in the Font Collection. Press del or backspace to remove glyphs from the font. A warning will be shown because this action is not undoable. To remove both the glyph and template glyph alt + del or alt + backspace.

read more: Application Menu

Mark Glyphs

The Font Collection allows users to add a mark color to the selected glyphs. Just hit the toolbar ‘Mark’ icon, and a list of predefined colors will be shown.

The mark colors list can be edited in the Preferences dialog.

Mark glyphs

Marked glyphs

read more: Preferences

Sort

The Font Collection can sort glyphs. This sorting order will be used during the generation of font binaries.

Sort by character set

Custom sorting

  • Smart sort
  • Character Set
  • Custom:
    • Alphabetical
    • unicode
    • script
    • category
    • block
    • suffix
    • decompositionBase
    • weightedSuffix
    • ligature either ascending/descending and allow pseudo unicodes

Users can set the order locally in just the current font or create a general sorting option in the Preferences.

Sorting glyphs will sync to the public.GlyphOrder font lib key.

read more: Preferences

Smart Sets

The Font Collection can hold a number of Smart Sets. A Smart set is a list of saved search and find queries. Smart Sets can be organized in binders, ake groups.

Schermafbeelding 2013-01-15 om 11.49.51

There are two kind of smart sets:

Query-based smart sets

Displayed with a litle gear icon.

Based on a list of glyph names

Can display the amount of missing glyphs in the font.

Smart-sets based on glyph names are able to find missing glyphs, and create them by right-click on the smart set item. The counter indicates how many glyphs are missing from the total.

click Set the seleted smart set as sub.
double click Edit the smart set item, can either as a search query or as a list of glyph names.
right click (only for list based smart sets) A contextual menu pops up displaying all missing glyph names and an option to create the missing ones.
click + alt Set all glyphs in the smart set as selected.
click + drag Rearrange the order of the smart sets.
delete (del or backspace) Remove the selected smart set.
 
Smart set Options
Delete set Delete the selected set.
Export sets Export the sets to a *.roboFontSets file.
Load Sets Loads a *.roboFontSets file.
Export To Group Export the selected set to a group.
Create new set from glyph Names Pops up a sheet where you can create a smart set based on a list of glyph names. (see Adding and deleting Glyphs for how to format glyph names)
New Smart Group Create a new 'binder', Smart Group to store and sort Smart Sets
Schermafbeelding 2013-01-15 om 11.48.46
 
Right Click on a smart set

Right click on a list based smart set will pop up a contextual menu if not all glyph are represented in the font. The pop up menu will provide a quick access to add the missing glyphs to the font. Double click a single glyph in the list will only generate the selected glyph.

read more: Search and Find, Adding and deleting Glyphs

Search and Find

The Font Collection can search and find glyphs and save the search query.

Users can toggle the Search and Find bar in the toolbar of the Font Collection window in multi-window mode, or at the bottom of the window in single window mode, or use ⌘ + F.

Search and find

By clicking the ‘+’ in the top right of the font collection an advanced Search and Find will reveal.

Users can build queries based on glyph data you see by the collections view in Glyph List mode.

preview glyph thumbnail
name glyph name
left sidebearing glyph left sidebearing
right sidebearing glyph right sidebearing
width glyph width
unicode glyph unicode
contours amount of contours in the glyph
components amount of components in the glyph
amount of components in the glyph a comma seperated list of all components base glyph names
anchors amount of anchors
anchor names a comma seperated list of all anchor names
color the mark color of the glyph
empty a bool indicating if the glyph is empty
template a bool indicating if the glyph is a template glyph
glyph changed a bool indicating if the glyph has changed

The name matches option is able to use regular expression. Regex can help you to create smart search queries and smart sets later on.

Examples:

  • ([a-z])
    lists all lowercase glyphs.
  • ([A-Z][a-z]*) 
    lists all uppercase glyphs.
  • [A-z] 
    lists all 52 uppercase and lowercase glyphs.
  • [a-z](caron|cedilla|ogonek|commaaccent|grave|acute|dieresis)
    lists all lowercase with those accents.

Save Set

Users can save the query as a smart set. A smart set item will be created and will search the font dynamically based on the given query. The result will be adapted based on changes in the font.

Selection to Set

Save the selected glyphs in the Font Collection as smart set. This smart set will display glyphs based on a list of glyph names.

read more: Display modes, Preferences

Display Modes

The Font Collection View has two display modes, “Tiled glyphs” aka "glyph cells" and “Glyph list”. Users can switch between those two display options by clicking on the icons at the lower left of the Font Collection window.

Switch display modes

Tiled glyph mode

Tiled glyphs view

Depending on the size of the tile it will display more information about the glyph (name, metrics, layers).

The size can be adjusted by zooming in or out or by adjusting the slider in at the bottom.

Unsaved glyphs have their names highlighted until the font saved again.

Marked glyphs will display the mark color in the glyph cell.

A colored L at the bottom right indicates that the glyph contains more than one layer.

A gray N at the bottom right indicates that the glyph as a note.

 

Glyph list mode

List mode

The glyph list mode displays all glyphs as a big table, showing different kinds of glyph data.

This view makes it possible for users to perform search operations for different kinds of glyph data.

Right-clicking in the table header activates a contextual menu which lets users turn individual data columns on/off.

Available glyph data:

preview glyph thumbnail
name glyph name
left sidebearing glyph left sidebearing
right sidebearing glyph right sidebearing
width glyph width
unicode glyph unicode
contours amount of contours in the glyph
components amount of contours in the glyph
amount of components in the glyph a comma seperated list of all components base glyph names
anchors amount of anchors
anchor names a comma seperated list of all anchor names
color the mark color of the glyph
empty a bool indicating if the glyph is empty
template a bool indicating if the glyph is a template glyph
glyph changed a bool indicating if the glyph has changed

The displayed glyph data can be used to search and find glyphs or make smart sets.

read more: Search and Find, Smart Sets

Glyph Editor

Glyph editor

The place to add and edit glyph specific data such as contours, point, anchors, components, glyph level metrics, guides, image,…

The glyph editor always displays one glyph to edit, and allows the user to show/hide different layers of glyph data.

 

Global actions available for each tool

Menu bar ⇢ Glyph
Next Glyph display the next glyph for the selected set in the font collection (the behavior can be changed in the preferences)
Prev Glyph display the next glyph for the selected set in the font collection (the behavior can be changed in the preferences
Editing selects the editing tool
Drawing selects the drawing tool
Slice selects the slice tool
Transform set the current selection in transform mode, if there is no selection the whole glyph will be in in transform mode. (if a tool does not support transformation it will not be usable)
Lock Guides Locks the guides.
Lock Side Bearings Locks the side bearing of a glyph of being edited.
Lock Images Locks the images.
Show Measurement Info Toggles displaying measurement info in the glyph view.
Layers navigate through layers
Menu bar ⇢ Windows
Zoom In zooms in
Zoom Out zooms out
Zoom To Fit zooms the current glyph to fit the glyph view
Global Glyph view events (these are valid for all tools)
space click drag move the glyph view in the scroll view
command space click zooms in
command space drag zoom to marque rectangle
command space alt click zooms out
alt mouse scroll zooms in or out
dragging an image (png, jpeg, tiff) create an image object in the current glyph (there can only be 1 image for each layer)
Hot keys (set in the preferences)
Preview fill the glyph in the foreground color and hide all other display options
Zoom In hot key for zooming in
Zoom Out hot key for zooming out
Next Glyph hot key to display the next glyph for the selected set in the font collection (the behavior can be changed in the preferences
Previous Glyph hot key to display the previous glyph for the selected set in the font collection (the behavior can be changed in the preferences)  
Layer Up hot key for jumping up to an other layer
Layer Down hot key for jumping down to an other layer
Jump To Glyph hot key to a pop up jump to glyph window. Typing the glyph names will sorter the possible glyph names. Also possible to type unicode values. The input field will also trying to convert characters according their unicode value. Arrow keys will alter the selection.
Remove Overlap hot key to perform a remove overlap
Reverse Contours hot key to reverse contours
Auto Contour Order hot key to set the order of contours atomically
Correct Contour Direction hot key to correct the contour direction
Add Extreme Points hot key to add extreme points
Add Anchor hot key to add an anchor
Add Component hot key to an add (see components)
Decompose Component hot key to decompose components
Toggle Point Smoothness hot key to toggle the selected points smoothness
Toggle Transform hot key to toggle transform mode
Toggle Oncurve / Offcurve selection hot key to jump to the next point
Break Contour hot key to break the contour at the selected point(s)
Close Contour hot key to close the selected contour(s).
Toggle Show Fill hot key to toggle the display fill
Toggle Show Metrics hot key to toggle the display of metrics
Toggle Show On Curve Points hot key to toggle the display of on curve points 
Toggle Show Off Curve Points hot key to toggle the display of off curve points
Toggle Show Point Coordinates hot key to toggle the display of point coordinates
Toggle Show Point Indexes hot key to toggle the display of point indexes
Toggle Show Anchors hot key to toggle the display of anchors
Toggle Show Labels hot key to toggle the display of point labels
Toggle Show Curve Length hot key to toggle the display of contour curve length
Toggle Show Outline Errors hot key to toggle the display of outline errors
Toggle Show Blues hot key to toggle the display of blues values 
Toggle Show Family Blues hot key to toggle the display of family blues values
Toggle Rulers hot key to toggle the display of rulers
Toggle Bitmap hot key to toggle the display of bitmap representations
Toggle Lock Guides hot key to toggle to lock guides
Toggle Lock Sidebearings hot key to toggle to lock the sidebearings
Toggle Lock Image hot key to toggle to lock the image
Flip horizontal hot key to flip the selection horizontal
Flip vertical  hot key to flip the selection vertical
Rotate 90° clockwise hot key to rotate 90° clockwise
Rotate 90° counterclockwise hot key to rotate 90° counterclockwise
Rotate 45° clockwise hot key to rotate 45° clockwise 
Rotate 45° counterclockwise hot key to rotate 45° counterclockwise
Copy / Swap to layer hot key to a pop up copy / swap layer window
Test Install the Font hot key to test install the font

Editing Tool

A tool to edit existing glyph data.

Point Selection
click (no selection) deselect all
click drag (no selection) select all points in selection marque
click point select point
click shift toggle selected points
click drag moves the selected points
click drag shift moves the selected points on x, y or 45° axis
click drag alt if the points does not have a bcp it creates one other wise it will un-smooth the point and only move the on curve point
click drag control copies the selection while dragging
click drag alt (single bcp selection) bcp becomes not smooth
click drag alt command (single bcp selection) bcp becomes smooth and the bcp values are mirror on the other bcp is there is one.
command drag smooth point
  • if selection is an oncurve point it will be moved over the handles
  • if off curve point the handle will be moved in the same direction as the handle
join / close contour if contour is open and first or last on curve point is dragged on top of another first or last on curve point the contour are joined or close
tab jump to the next oncurve point
Segment Selection
click select segment
click shift add segment to selection 
click drag (single segment selection) move the selected segments around
click drag alt (single segment selection)
  • for line segment: create curve segment (adds two bcps)
  • for curve semgent: drag the handles around. (this will un-smooth your on curve points)
click drag command (single segment selection)
  • for line segment: move the selected segment around
  • for curve segments: the bcp are following the handle direction
click drag shift (single segment selection) all points fixed are on x, y or 45°, works also with alt and command down
click drag control copy the selected segment during drag
command alt (no selection) add point on contour
Contour Selection
double click select contour
click drag (in/on selection) move the selection
click drag shift (in/on selection) move the selection on x, y or 45°
Component Selection
click select the component
click shift toggles the component selection
drag move the components around
drag shift move the components on x, y or 45°
triple click (in the component) go to the base glyph to edit

 

Copy Paste

 

Copy
selection copies the selection from the current glyph
Paste
from glyph editor paste the copied selection into the current glyph
from font collection paste the copied selection into the current glyph
from illustrator paste the copied selection into the current glyph

 

 

Contextual Menus

 

Right Click no selection
Add Component Opens an Add Component sheet.
Add Anchors Opens an Add Anchor sheet.
Reverse Reverse the whole glyph.
Remove Overlap Removes overlaps the whole glyph.
Auto Contour order Tries to order the contours.
Add Extreme Points Adds extreme points.
Corrent Directions (PS) Corrects contour direction to postscript directions.
Corrent Directions (TT) + alt Corrects contour direction to truetype directions.
Lock Guides Locks all guides in RoboFont.
Lock Images Locks all images in RoboFont.
Copy To Layer List all available layers to copy to.
Copy To Layer + alt List all available layers to swap to.
Right Click with selection
Reverse Reverse the only the selected contours.
Remove Overlap Removes overlaps only the selected contours.
Labels Add labels to the selected points.
Right Click on point
Break Contour Breaks the contour at the selected point.
Reverse Reverse the whole glyph.
Set Start Point Set the selected point as starting point.
Right Click glyph contains a component
Component -> Go to Jump to glyph with.
Component -> Go to+ alt Decompose component with base glyph.
Component -> Decompose Selected Decompose selected components.
Component -> Decompose All Decompose all components.
Right Click on Anchor
Name Set name for the selected anchor.
Right Click on Guide (see guides)
Right Click on Image (see images)

 

Editing Examples

Bezier Tool

A tool to draw contours.

Mouse
click (no selection) add a point
alt click (no selection) add a line segment
click (on selection) when its the last point of an open contour the contour will become the main contour to add points
click shift adds point which is on the x, y or 45° of the previous on curve point
drag adds bcp, they are all smooth
drag shift move the bcps of the last added point on x, y or 45°
drag alt un-smooth the bcp
click alt command add a point on a contour
move over starting point can close the contour
double click add a point and close the the contour
Key board
arrow keys move last added point by 1 unit
arrow keys shift move last added point by 10 units
arrow keys shift command move last added point by 100 units

Slice Tool

Will add points on dragged slice line.

click add a starting point of a slice line
drag sets end point of slice line
drag shift adjust slice line on x, y or 45°
mouse up slice the glyph according the slice line

When the slice line has 2 intersection on the same contour it will cut the contour, otherwise is will just add points. 
(Guides can also slice see Guides)

Measurement Tool

Draws a measurement line over the glyph.

click add a starting point of a measurement line
click alt possible to add multiple measurement lines
click no drag will remove all measurement lines
drag sets end point of measurement line
drag shift adjust slice line on x, y or 45° or when started on a segment it will the angle from the point on that segment.
click drag start/end point modify the measurement line
Menu ⇢ Glyph
Show Measurement Info Toggles displaying measurement info in the glyph view.

 

Layers

RoboFont can handle layers inside a single UFO. The idea is to have it very flexible. Some will use it as a way to separate different stages of a font. Others will use it as way to collaborate and other others will use it like multiple master. 

Users can add, delete, reorder layers in the layer inspector pane.

There is no limit on the amount of layers in a glyph. 

Layers names are ASCII without spaces, slashes and semicolons.

Layers can have any color. Used to be displayed in the background of the glyph editor.

+ add layer
- remove layer
eye toggle the selected layer visibility when displayed in the background of the glyph editor
filled rectangle toggle the selected layer fill when displayed in the background of the glyph editor 
stroked rectangle toggle the selected layer stroke when displayed in the background of the glyph editor
point toggle the selected layer show points when displayed in the background of the glyph editor
coordinate toggle the selected layer show point coordinates when displayed in the background of the glyph editor 

 

Read more: Inspector 

 

Components

Components can be add to a glyph with the Add Components sheet.
(contextual menu of the Editing Tool

typing will make the possible options smaller
arrow keys (up and down) will move up or down in the selection
tab jumps from 'Starts With' to 'Contains' and back 
enter add the component 
Copy Metrics will change the metrics of the glyph based on the added component 

 

Contextual Edit menu with component options

 

 

Images

Each layer can contain a single image. Drag & drop any .png, .jpeg or .tiff file on the glyph view and an image will be created. Working with multiple layers is a way to add multiple images.

The Editing Tool can handle editing the image.

 

The image data is not stored in the UFO file, only the path is stored. But there as saving options ‘save image next to the UFO’ that allows you to collect all images in a assets folder next the UFO.

Contextual menu

 

Brigtness Set the brightness of the selected image.
Contrast Set the contrast of the selected image.
Saturation Set the saturation of the selected image.
Sharpness Set the Sharpness of the selected image.
Black & White Toggle the selected image to black & white.
Set Scale Opens a sheet that helps you to transform the image to the baseline, x-height. (see below)
Set Scale

The Set Scale sheet helps you to transform the image in 3 clicks to the font horizontal metrics.

Define the following points just by clicking on the image:

  • zero zero point
  • define a base line
  • define the height based either the x-height, cap-height, ascender or descender

The defined points are editable after the mouse down.

Guides

Guides can be dragged from the rulers (see Display Options)

 

drag from rulers  create a guide
drag from rulers command create a global guide (font level guide)
drag alt rotate guide 
mouse over cursor changed with guide values
drag over point in glyph stick to that point
drag out of the view delete the guide 
Contextual menu
Name name for the guide
Position center point of the guide x, y coordinate
Angle angle of the guide
Is Global Make the guide global (on font level) or local (only used in one glyph).
Display Measurements Display where the guides touches the glyph.
Magnetic Determine how fast a dragged selection should snap to the guide. 
Lock Guides Lock all guides
Lock Images Lock all images
Slice Glyph slice the glyph by the guide
Delete Guide Delete the guide

 

Transform

Transform let users transform selections or whole the glyph. Transform is available when the Editing Tool is active. To switch to transform mode can either be through the app menu bar 'Transform' or 'command-T' or you can create a Hot Key in the Preferences. Double click the selection will also switch into transform mode.

Double click outside the transform box will deactivate transform.

Once users switched into transform mode it possible to translate, scale, rotate and skew the selection.

Translate

Move the selection around. Translate is the default transform setting. (square corner points)

click + drag translate the selection
click + drag one of the four corners or their middle points scale the selection
drag + shift translate moves the selection on x, y or 45° axis
drag + shift one of the four corners of their middle points scale on x, y, 45° axis or proportional based on the transform box of the selection 

 

Scale

Scale the selection. Activated when ‘command' is down. (diamond corner points)

click + drag start scaling the selection
drag + shift scale on x, y, 45° axis or proportional based on the bounding box of the selection 

 

Rotate

Rotate the selection, Activated when 'alt' is down. (round corner points)

click + drag rotate around the mouse down point
drag + shift rotate on x, y or 45° axis

 

Skew 

Skew the selection. Activated when 'command + alt' is down. (triangular corner points)

click + drag skew around the mouse down point
drag + shift skew on x, y or 45° axis

 

Read more: Editing Tool, Inspector

Display options

Glyph display options

Display
Fill toggle display glyph fill
Stroke toggle display glyph stroke
Metrics toggle display metrics
On Curve Points toggle display on curve points
Off Curve Points toggle display off curve points
Point Coordinates toggle display point coordinates
Point Indexes toggle display point indexes
Contour Indexes toggle display contour indexes
Anchors toggle display anchors
Labels toggle display point labels
Curve Length toggle display curve length
Outline Errors toggle display outline errors
Blues toggle display blues
Family Blues toggle display family blues
Rulers toggle display rulers and guides
Grid toggle grid
Bitmap toggle bitmap representation
Scale
Fit fit the glyph to the current size of the glyph view
percentage scale value

Metrics

RoboFont metric editing is based on the idea that setting the white space around a glyph is an act of drawing, so spacing and kerning have their specific views.

Space Center

The Space Center view is the place to adjust and set metrics in a UFO. Undo / Redo is supported on the selected glyph.

Text Input Fields

The input text will be tried to match glyph names, unicode of glyph names. You can preset some input strings in the preferences.

 any text ("abc") tries to match glyph names ("a", "b", "c")
unicoded character (&é) tries to match the unicode values ("ampersand", "eacute")
/glyphName explicit name the glyphName
/? display the current active glyph
\n new line

Left and right input fields add control glyphs around the main input field.

Space Center View

Editing metrics with by selecting and dragging a glyph and with the arrow keys.

Mouse Editing
click (on a glyph) Select the glyph.
click (not on a glyph) Deselect the glyph.
click + drag left or right margin Move the left or right margin.
click + drag (on the glyph contours) Move the glyph in his white space, only horizontally.
click + alt + drag (on the glyph contours) Move the glyph vertically.
click + alt + command + drag (on the glyph contours) Move the glyph both horizontally or vertically.
Arrow Keys Editing (when a glyph is selected)
Arrow left or right Add one to the glyph width (aka adjusting the right margin).
Arrow left or right + shift Add ten to the glyph width (aka adjusting the right margin).
Arrow left or right + shift + command Add hundred to the glyph width (aka adjusting the right margin).
Arrow left or right + alt Add one to the glyph left margin.
Arrow left or right + alt + shift Add ten to the glyph left margin.
Arrow left or right + alt + shift + command Add hundred to the glyph left margin.
Hot Keys (see Preferences)
Multi Line Activate Multi Line.
X Height Cut Activate X Height Cut.
Water Fall Activate Water Fall. 
Toggle Inverse Color Toggle Inverse Color.
Toggle Show Metrics Toggle Show Metrics.
Toggle Right To Left Toggle Right To Left.
Toggle Beam Toggle Beam.
Toggle Fill Toggle Fill.
Toggle Stroke Toggle Stroke.

 

Value input fields

Width, Left and Right take a numeric value or they can be set to the corresponding value of a glyph.

any number ("123") Sets value to the number.
arrow up or down Add one to the selected input field.
arrow up or down + shift Add ten to the selected input field.
arrow up or down + shift + command Add hundred to the selected input field.
alt + arrows keys Jump to the next, previous, on top or below input field.
tab Jump to the next input field.
tab + shift Jump to the previous input field.
tab + alt Jump to the input field below.
equals followed by a glyphName (=a) Sets the value to the value of the corresponding glyph.
simple math like ‘=e+10-z*10′
or ‘-=10+a’
Sets the value to the evaluated expression.

Space Center Options

Show Kerning Toggle display of kerning. Only the kerning defined in the UFO is been used. Kerning defined in the "kern" feature will not be displayed.
Suffix Suffix will alter the glyph input names and add the selected suffix if the glyph is in the font. The suffix list is generated from all glyph names containing a "." (period). For example "ampersand.alt" will add "alt" as suffix.
Multi Line Display the glyphs with multiple lines.
Single Line Display the glyphs in a single line.
Water Fall Display a water fall.
xHeight Cut Cut off ascender and descenders.
Inverse Inverse colors.
Show Metrics Show metrics of the selected glyph.
Left To Right Display text from left to right.
Right To Left Display text from right to left. 
Beam Use a beam to measure left and right side bearings.
Fill Fill the glyphs.
Stroke Stroke the glyphs. 
Line Space Add line space between the lines.
Show Control Glyphs Hide the control glyphs in the input view of the Space Center.
Show Space Matrix Hide the space matrix input view at the bottom of the Space Center.

Kern Center

Kerning Sheet with basic support for kerning. You can access this sheet by clicking the toolbar icon or when Metrics Machine is installed by alt click the toolbar icon.

If you have Metrics Machine installed the Kerning toolbar item will as default send the UFO to Metrics Machine.

List
select a kerning pair Send the kerning pair to the input field and draw the glyphs.
enter Edit the value.
Kern preview view
click Select a kerning pair.
click drag Modify the kerning pair value.
arrow keys (left or right) Modify the kerning pair value.
arrow keys + shift Modify the kerning pair value with a multiple of 10.
arrow keys + shift + command Modify the kerning pair value with a multiple of 100.
tab Select next pair.
tab + shift Select previous pair.
Control Buttons
+ Add kerning pair.
- Remove kerning pair.
Kerning Apply kerning.
Left To Right Toggle left to right or right to left.
Prefer Group Kerning Tries to find the group for an edited glyph, otherwise it will just add a glyph glyph kerning pair.

Font Info

Font info sheet

The Font Info sheet is an interface to edit font naming fields, vertical metrics and other font meta-data. It also holds RoboFont specific defaults that are local to the UFO. Many of the fields have a default value that only needs to be overridden if you have a need to. This means that for a simple font, all you need to fill in is Family Name and Style Name to get a working font. You only need to set the values where the default doesn't match your needs. 

An example of this would be creating a eight weight font family where you want to style map the italics to the roman of each weight. To do so, you need to set four names in each font:

My Font Light

  • Family Name: My Font
  • Style Name: Light
  • Style Map Family Name: My Font Light
  • Style Map Style: Regular

My Font Light Italic

  • Family Name: My Font
  • Style Name: Light Italic
  • Style Map Family Name: My Font Light
  • Style Map Style: Italic

My Font Book

  • Family Name: My Font
  • Style Name: Book
  • Style Map Family Name: My Font Book
  • Style Map Style: Regular

My Font Book Italic

  • Family Name: My Font
  • Style Name: Book Italic
  • Style Map Family Name: My Font Book
  • Style Map Style: Italic

and so on.

Though RoboFont allows you to only set a few values, you have control of all values —down to setting FOND name info— if you need them:

These values are derived from the Font Info section of the UFO spec.

General

General font info settings. Most of the more specific values in other parts of the Font Info get defaults from these settings:

Identification

Option Default Description
Family Name None The font's family name. Required
Style Name None The font's style name. Required
Style Map Family Name Preferred Family Name followed by Preferred Subfamily Name Family name used for bold, italic and bold italic style mapping.
Style Map Style Regular The style map style. The possible values are Regular, Italic, Bold and Bold Italic.
Version Major 0 Major version.
Version Minor 0 Minor version.

 

Dimensions

Option Default Description
Units Per Em 1000 Units per em.
Descender -250 Descender value. This must be 0 or a negative number.
x-height 500 x-height value.
Cap-height 750 Cap height value.
Ascender 750 Ascender value.
Italic Angle 0 Italic angle.

 

Legal

Option Default Description
Copyright Not set Copyright statement. Corresponds to the OpenType name table name ID 0.
Trademark Not set Trademark statement. Corresponds to the OpenType name table name ID 7.
License Not set License text. Corresponds to the OpenType name table name ID 13.
License URL Not set URL for the license. Corresponds to the OpenType name table name ID 14.

 

Parties

Option Default Description
Designer Not set Designer name. Corresponds to the OpenType name table name ID 9.
Designer URL Not set URL for the designer. Corresponds to the OpenType name table name ID 12.
Manufacturer Not set Manufacturer name. Corresponds to the OpenType name table name ID 8.
Manufacturer URL Not set Manufacturer URL. Corresponds to the OpenType name table name ID 11.

 

Note

Option Default Description
Note Not set Arbitrary note about the font. This is not put into a generated font, but is there for the designer's use for keeping notes about the UFO (changes, thoughts, to-do list, etc.).

OpenType

OpenType specific font info. For further information on any of these options, consult the OpenType specification.

head table

Option Default Description
created Current date/time. The creation date of the font.
lowestRecPPEM 6 Smallest readable size in pixels. Corresponds to the OpenType head table lowestRecPPEM field.
flags Flag 0: Baseline for font at y=0
Flag 1: Left side-bearing point at x=0
A list of flags one can set based on the OpenType specification. Most of these flags, though not all, are for TrueType hinting. Options are:
Flag 0: Baseline for font at y=0
Flag 1: Left side-bearing point at x=0
Flag 2: Instructions may depend on point size
Flag 3: Force ppem to integer values for all internal scaler math
Flag 4: Instructions may alter advance width
Flag 11: Font data is "lossless"
Flag 12: Font converted (produce compatible metrics)
Flag 13: Font optimized for ClearType

 

name table

Option Default Description
Preferred Family Name Family Name Preferred family name. Corresponds to the OpenType name table name ID 16.
Preferred Subfamily Name Style Name Preferred subfamily name. Corresponds to the OpenType name table name ID 17.
Compatible Full Name Style Map Family Name followed by Style Map Style Name. If the Style Map Style Name is Regular, it is not used. Compatible full name. Corresponds to the OpenType name table name ID 18.
WWS Family Name Not Set WWS family name. Corresponds to the OpenType name table name ID 21.
WWS Subfamily Name Not set WWS Subfamily name. Corresponds to the OpenType name table name ID 22.
Version Version Major followed by Version Minor in the from of 0.000 Version string. Corresponds to the OpenType name table name ID 5.
Unique ID A string that is: OpenType Version;OS/2 Vender ID;Style Map Family Name followed by Style Map Style Name Unique ID string. Corresponds to the OpenType name table name ID 3.
Description Not set Description of the font. Corresponds to the OpenType name table name ID 10.
Sample Text Not set Sample text. Corresponds to the OpenType name table name ID 20.

 

hhea table

Option Default Description
Ascender Units Per Em value + Descender value Ascender value. Corresponds to the OpenType hhea table Ascender field.
Descender Descender value Descender value. Corresponds to the OpenType hhea table Descender field.
LineGap 200 Line gap value. Corresponds to the OpenType hhea table LineGap field.
caretSlopeRise 1 Used to set the slope of the text cursor (rise/run). Use 1 for vertical. Corresponds to the OpenType hhea table caretSlopeRise field.
caretSlopeRun 0 Used in conjunction with caretSlopeRise. Use 0 for vertical. Corresponds to the OpenType hhea table caretSlopeRun field.
caretOffset 0 The amount to shift a slanted highlight to produce the best appearance. Set to 0 for non-slanted fonts. Corresponds to the OpenType hhea table caretOffset field.

 

vhea table

Option Default Description
vertTypoAscender Not set Vertical ascender value. Distance from the centerline to the previous line's descent. Corresponds to the OpenType vhea table vertTypoAscender field.
vertTypoDescender Not set Vertical descender value. Distance from the centerline to the next line's ascent. Corresponds to the OpenType vhea table vertTypoDescender field.
vertTypoLineGap Not set Line gap value. Corresponds to the OpenType vhea table vertTypoLineGap field.
caretSlopeRise Not set Vertical caret slope rise value. A value of 0 for the rise and a value of 1 for the run specifies a horizontal caret. A value of 1 for the rise and a value of 0 for the run specifies a vertical caret. Corresponds to the OpenType vhea table caretSlopeRise field.
caretSlopeRun Not set Vertical caret slope run value. See the caretSlopeRise field. Corresponds to the OpenType vhea table caretSlopeRun field.
caretOffset Not set Vertical caret offset value. The amount to shift a slanted highlight to produce the best appearance. Set to 0 for non-slanted fonts. Corresponds to the OpenType vhea table caretOffset field.

 

OS/2 table

Option Default Description
usWidthClass   Width class value. Can be Ultra-condensed, Extra-condensed, Condensed, Semi-Condensed, Medium (normal), Semi-expanded, Expanded, Extra-expanded, or Ultra-expanded. Corresponds to the OpenType OS/2 table usWidthClass field.
usWeightClass   Weight class value. Must be a positive integer. Corresponds to the OpenType OS/2 table usWeightClass field.
fsSelection Nothing set Options are
1 UNDERSCORE: Characters are underscored
2 NEGATIVE: Characters have their foreground and background reversed
3 OUTLINED: Outlined characters
4 STRIKEOUT: Characters are over-struck
7 USE_TYPO_METRICS: Use OS/2 Typo values for ascender, descender, and line gap
8 WWS: Font has name table strings consistent with a weight/width/slope family without requiring the WWS name values
9 OBLIQUE: Font is oblique
achVendID   Four character identifier for the creator of the font. Corresponds to the OpenType OS/2 table achVendID field.
fsType No embedding restrictions The allowed type of embedding for the font. Options are:
No embedding restrictions
No embedding
Only preview and print embedding allowed
Editable embedding allowed
Additionally, one can choose if they wish to allow subsetting and/or only bitmap embedding.
ulUnicodeRange   A list of supported Unicode ranges in the font. Corresponds to the OpenType OS/2 table ulUnicodeRange1, ulUnicodeRange2, ulUnicodeRange3 and ulUnicodeRange4 fields.
ulCodePageRange   A list of supported code page ranges in the font. Corresponds to the OpenType OS/2 table ulCodePageRange1 and ulCodePageRange2 fields.
sTypoAscender Units Per Em value + Descender value Ascender value. Corresponds to the OpenType OS/2 table sTypoAscender field.
sTypoDescender Descender value Descender value. Must be 0 or a negative number. Corresponds to the OpenType OS/2 table sTypoDescender field.
sTypoLineGap 200 Line gap value. Corresponds to the OpenType OS/2 table sTypoLineGap field.
usWinAscent Maximum y value of the font. If not available, the Ascender value. Ascender value. Corresponds to the OpenType OS/2 table usWinAscent field.
usWinDescent Minimum y value of the font. If not available, the Descender value. Descender value. Must be 0 or a positive number. Corresponds to the OpenType OS/2 table usWinDescent field.
ySubscriptXSize Adobe FDK will calculate Subscript horizontal font size. Corresponds to the OpenType OS/2 table ySubscriptXSize field.
ySubscriptYSize Adobe FDK will calculate Subscript vertical font size. Corresponds to the OpenType OS/2 table ySubscriptYSize field.
ySubscriptXOffset Adobe FDK will calculate Subscript x offset. Corresponds to the OpenType OS/2 table ySubscriptXOffset field.
ySubscriptYOffset Adobe FDK will calculate Subscript y offset. Corresponds to the OpenType OS/2 table ySubscriptYOffset field.
ySuperscriptXSize Adobe FDK will calculate Superscript horizontal font size. Corresponds to the OpenType OS/2 table ySuperscriptXSize field.
ySuperscriptYSize Adobe FDK will calculate Superscript vertical font size. Corresponds to the OpenType OS/2 table ySuperscriptYSize field.
ySuperscriptXOffset Adobe FDK will calculate Superscript x offset. Corresponds to the OpenType OS/2 table ySuperscriptXOffset field.
ySuperscriptYOffset Adobe FDK will calculate Superscript y offset. Corresponds to the OpenType OS/2 table ySuperscriptYOffset field.
yStrikeoutSize Adobe FDK will calculate Strikeout size. Corresponds to the OpenType OS/2 table yStrikeoutSize field.
yStrikeoutPosition Adobe FDK will calculate Strikeout position. Corresponds to the OpenType OS/2 table yStrikeoutPosition field.
Panose Family kind: Any The Panose classification for the font.

Postscript

 The Postscript window allows you to set a variety of Postscript related settings:

These settings apply to various tables and functions of the Adobe FDK. For technical information on these values, see the Adobe Postscript Type 1 specification.

Identification

Font Info Postscript Identification

These are font name values for Postscript.

Option Default Description
FontName A combination of the OpenType Preferred Family Name and the OpenType Preferred Subfamily name, stripping out any invalid characters. Name to be used for the FontName field in Type 1/CFF table.
FullName A combination of the OpenType Preferred Family Name, a space, and the OpenType Preferred Subfamily name. Name to be used for the FullName field in Type 1/CFF table.
WeightName Looks at the OS/2 usWeightClass value and picks the description that best matches the value from the table below:

100 Thin
200 Extra-light
300 Light
400 Normal
500 Medium
600 Semi-bold
700 Bold
800 Extra-bold
900 Black
A text description of the weight of the font. It should correspond with the OS/2 usWeightClass value.
Unique ID Number Not set The Postscript Unique ID number.

 

Hinting

Font Info Postscript Hinting

These values control the output of the autohinter.

Option Default Description
BlueValues   A list of up to 14 space separated numbers (integers or floats) specifying the values that should be in the Type 1/CFF BlueValues field. This list must contain an even number of integers following the rules defined in the Type 1/CFF specification.

These values are a font's primary alignment zones.

OtherBlues   A list of up to 10 integers or floats specifying the values that should be in the Type 1/CFF OtherBlues field. This list must contain an even number of integers following the rules defined in the Type 1/CFF specification.

These values are a font's secondary alignment zones.

FamilyBlues   A list of up to 14 space separated numbers (integers or floats) specifying the values that should be in the Type 1/CFF FamilyBlues field. This list must contain an even number of integers following the rules defined in the Type 1/CFF specification. This sets BlueValues across a typeface family, and should be the same for each font in the family.
FamilyOtherBlues   A list of up to 10 space separated numbers (integers or floats) specifying the values that should be in the Type 1/CFF FamilyOtherBlues field. This list must contain an even number of integers following the rules defined in the Type 1/CFF specification. This sets OtherBlues values across a typeface family, and should be the same for each font in the family.
StemSnapH   List of horizontal stems sorted in increasing order. Up to 12 space separated numbers (integers or floats) are possible. This corresponds to the Type 1/CFF StemSnapH field.
StemSnapV   List of vertical stems sorted in increasing order. Up to 12 space separated numbers (integers or floats) are possible. This corresponds to the Type 1/CFF StemSnapV field.
BlueFuzz 1 The number of units to extend the effect of an alignment zone to compensate for slightly inaccurate point data.
BlueShift 7 Adjusts the point at which character features outside of an alignment zone will overshoot.
BlueScale .039625 (10pt at 300dpi) BlueScale value. This corresponds to the Type 1/CFF BlueScale field. This controls the point size at which overshoot suppression is turned off. The formula to determine BlueScale at 300dpi is: (pointsize - 0.49) / 240
ForceBold Off Turning this on this will instruct the font interpreter that it can thicken stems that would render at 1px on screen.

 

Dimensions

Font Info Postscript Dimensions

Option Default Description
SlantAngle The italic angle if set, otherwise 0. Artificial slant angle.
UnderlineThickness Not set Underline thickness value. Corresponds to the Type 1/CFF/post table UnderlineThickness field.
UnderlinePosition Not set Underline position value. Corresponds to the Type 1/CFF/post table UnderlinePosition field.
isFixedPitched Off Indicates if the font is monospaced. A compiler could calculate this automatically, but the designer may wish to override this setting. This corresponds to the Type 1/CFF isFixedPitched field
DefaultWidthX 200 Default width for glyphs.
NominalWidthX 0 Nominal width for glyphs.

 

Characters

Font Info Postscript Characters

Option Default Description
Default Character Not set The name of the glyph that should be used as the default character in PFM files. This is not used in OpenType.
Microsoft Character Set Not set The Windows character set. This is not used in OpenType

Miscellaneous

Font Info Miscellaneous

This allows you to set specific FOND data for the font if you wish.

Option Default Description
Font Name Not set Font name for the FOND resource.
Family ID Number Not set Family ID number. Corresponds to the ffFamID in the FOND resource.

You may wish to additionally consult the Adobe FOND Specification.  

RoboFont

Schermafbeelding 2013-01-22 om 14.42.03

This sets preferences for UFO in RoboFont to deal with defaults for generating a font file from the UFO.

Decompose If checked, the font's components will be decomposed when a font is generated.
Remove Overlap If checked, overlap will be removed when the font is generated.
Auto Hint If checked, the font will be auto hinted with the Adobe FDK autohinter (Postscript) or ttfautohint (TrueType–Only if installed in the system) using the settings from the Postscript hinting info.
Release Mode If checked, will set the Adobe FDK in release mode when generating the font. This will turn on subroutinization (makes final OTF file smaller), applies your desired glyph order, and removes the word Development from the font's version string.
Format Which format to generate the font as: OTF, TTF, or PFA
Italic Slant Offset Will shift your glyphs horizontally to the left during generating binaries. The number must have a negative value. This is mainly used during drawing italics with slanted metrics. 
Spline Conversion When changing between Cubic (Postscript) and Quadratic (TrueType) curves, the conversion can either preserve the number of points or preserve the curves (adding points as need be).
Template Character Set Set the default template character set for this font.

Features

Write your Open Type features using the Adobe feature syntax in the UFO file. See also Tal Leming's Open Type Cookbook.

Note: If you are using Kern center or MetricsMachine, your kerning is added automatically to the features, you should not define a kerning feature here. If you have defined a kern feature in the feature file, then this will be used instead of the kerning set in the UFO file.

A feature editor accepts drag and drop of .fea files. The dropped files will be inserted as include(path/of/the/dropped/feature/file.fea);.

External Feature Support

RoboFont support .fea as a file format. Double click a .fea file will open the feature file in a separate feature editor which is not connected to a UFO.

 

New Feature

Create a new feature document. This is feature document is not connected to a UFO file. It will be saved as .fea file.

Insert In Fonts Pop up a sheet to add the feature text to the selected fonts.
Save Save the feature file.
Reload Reload the feature file from disk.

Export Feature

Export the features from the current font to a .fea file.

Group editor

The group editor makes it possible to create groups of glyphs.

Groups can be used for several purposes: spacing, kerning, and organizing character sets. Groups, unlike some other font editors, are not used in the OpenType features window.

Group editor

Groups can be created by clicking on the + button at the bottom left of the window. The name of each group can be changed with a double-click.

To add glyphs to a group, simply drag them from the collection at the bottom of the window to the group contents area at the upper right.

The glyphs contained in each group can be visualized as normal glyph cells, or can be stacked on top of each other for easier comparison of the letter shapes. This feature is specially useful when creating spacing and kerning classes.

Stacked glyphs view

Inspector

 

Open the inspector form the application menu Windows or ⌘I

Glyph

Input for common glyph attributes of the current glyph.

Name Change the name of the current glyph. If the name changed a pop up sheet will assist in renaming the glyph in referenced components, groups and kerning as well as setting a new unicode value.
Unicode Change the unicode of the current glyph. Similarly as the name of a glyph a pop up sheet will assist you in re-unicoding the glyph.
Width Set the width of the current glyph.
Left Set the left margin of the current glyph.
Right Set the right marginof the current glyph.
Mark Set the mark color of the current glyph.

 

Preview

A live preview of the current glyph

Layers

A control pane to manage layers.

Select & Drag & drop Change layer order.
Click and hold Rename a layer.
+ - Add or remove a layer.
Display controls Control how the layer is being displayed in the Glyph View.

  • If the selected layer is the active layer the display controls will toggle the display of the active layer.
  • If the selected layer is not the active layer the display controls will toggle the display of the layer in the background.

Read more: layers

Transform

A transform pane.

Select origins to apply the transformation on. No selection will use the zero zero point as transformation origin.
Mirror horizontally.
Mirror vertically.
Align selected objects to the bottom.
Center selected objects horizontally.
Align selected objects to the top.
Align selected objects to the left.
Center selected objects vertically.
Align selected objects to the right.
Move Move selected objects according x, y settings. Optionally equalize x and y.
Scale Scale selected objects according x, y percentage settings. Optionally equalize x and y.
Rotate Rotate selected objects according an angle set in degrees.
Skew Skew selected objects according two angles α, β. Optionally equalize α and β.
Snap Snap selected objects to a grid.
Transform
Transform Apply all transformations on the current glyph. The transformation could be a combination of move, scale, skew and snap transformations.
Transform Selected Glyphs Apply all transformations on a glyph selection in the Font Overview.
Transform All Glyphs Apply all transformations on all glyph in the font.
Mirror Selected Glyphs Vertical Mirror all selected glyphs vertically in the Font Overview.
Mirror Selected Glyphs Horizontal Mirror all selected glyphs horizontally in the Font Overview.
Mirror All Glyphs Vertical Mirror all glyphs vertically in the font.
Mirror All Glyphs Horizontal Mirror all glyphs horizontally in the font.
Transform Again Apply the same transformation again on the current glyph. Handy if the transformation is being set from a transform action in the Glyph View.
Transform Again Selected Glyphs Apply the same transformation again on the selected glyphs in the Font Overview.
Transform Again All Glyphs Apply the same transformation again on all glyphs in the font.
Options
Transform Contours Apply transformations on contours.
Transform Metrics Apply transformation on metrics.
Transform Components Apply transformation on components.
Transform Anchors Apply transformation on anchors.
Transform Image Apply transformation on an image.
Align Off Curve Points Apply alignment transformation on off curve points.
Reset Panel Reset the panel to his default transformation.

 

Points

A list of all contours with points in the current glyph.

 ✓ Select the contour or point.
X The point x value, editable.
Y The point y value, editable.
 ∞ A boolean if the point is smooth.
Name The point name, editable.

 

Components

A list of all components in the current glyph.

 ✓ Select the component.
Base Glyph Name of the referenced glyph, editable.
Transfromation The transformation of the component, editable.

Anchors

A list of all anchors in the current glyph.

 ✓ Select the anchor.
X The point x value, editable.
Y The point y value, editable.
Name The anchor name, editable.

Note

Add a note to a glyph.

Scripting

A python editor to write and execute python files inside RoboFont. There are lots of embedded packages and tools to write code and extent RoboFont lots of possible features.

The code text editor is build for writing python code. Syntax highlights python specific tokens. 

You can browse your predefined scripting folder. Double click will set the selected file in the code editor.

 

Run run the current script
Comment comment the selected line(s)
Uncomment uncomment the selected line(s)
Indent indent the selected line(s)
Dedent decent the selected line(s)
Save save the file as a *.py file
Reload reload the file from disk 
New create a new python document
Open open a *.py file
Edit With... edit the file with the preferred python editor

 

Output Window

This window catches all print statements and tracebacks when a script is not running in the scripting window. 

Enable "Can hide" to hide the window when RoboFont is not the active app anymore. (It acts like a floating window). When disabled the window will still be visible when RoboFont is not active.

'Clear' will empty the all print statements and traceback from the Output window.

 

Command Line

RoboFont is accessible through command line. Install the command line tool in the Preferences.

The command line tool is using a very simple API:

Call RoboFont to execute python files:
roboFont [-h] [-p] [-c] [-o]
--help -h                               options
--pythonpath -p <path> <path> ...      .py files path(s) to run inside RoboFont
--pythoncode -c "print 5*5"             python code to run inside RoboFont
--openfile -o <path>                    files to open with RoboFont

Read more: API, Preferences

 

Preferences

A window collecting all User defaults. It is required to hit ‘Apply’ in the toolbar to tell RoboFont a default has changed so the related views can be changed.

If a change requires a restart it will be advising note will be displayed in the bottom of the window.

Preferences Options

Reset All Preferences Reset all preferences to the standard defaults.
Reset "Don't Show This" Warnings Reset all "Don't Show This" warnings.
Export Preferences Export user defined preferences to a .roboFontSettings file.
Import Preferences Import user defined preference from a .roboFontSettings file.

Glyph View

The Glyph View area of the Preferences window offers several settings related to the Glyph Editor for configuration by the user.

Glyph editor settings

The display of the Glyph Editor can be fully customized (colors, size of on-curve and off-curve points, stroke widths, background grid etc), as well as its behavior while editing (warning for outline errors, point insertion, slanted coordinates etc).

 

 

Artboard Width Width of the glyph view artboard.
Artboard Height Height of the glyph view artboard.
Oncurve Size Size of the oncurve point displayed in the glyph view.
Offcurve Size Size of the offcurve point displayed in the glyph view.
Grid X Size of the grid horizontally.
Grid Y Size of the grid vertically.
Snap Points To Snap all points while editing to a multiple of this value. If you set this value to zero point coordinates will be floating points. If you set this value to five all point coordinates will be a multiple of five.
Outline Errors Display a error line showing an outline error if the difference between the segment starting point and end point  is smaller then this value.
Selection Stroke Width Width of the selection path. If this value is zero the selection path will be drawn without anti-alias.
⇧ Increment The increment when using shift down.
⌘ ⇧ Increment The increment when using command and shift down.
Draw With The default drawing curve type when opening a new document. Can be either "Cubic Beziers (PostScript)" or "Quadratic Beziers (TrueType)"
Next Glyph The list used when hitting "Next Glyph" or "Previous Glyph". Can be either the "From Selected Set" or "From 'All Glyphs' set".
Preserve Curve on Deleting Point If a point get removed this value can decides if the curve should be preserved or not. 
Display Italic Angle   Use the Italic angle in the glyph view and space center.
Slant Point Coordinates Slant all point coordinates. This is only a display options, points will be stored in the UFO as absolute points coordinates.
Draw Dragging Cross Lines Display the dragging cross line while dragging objects in the glyph view. 
Draw Coordinates Background Color Draw a darker color in the back of the point coordinates. 
Measurement Show Glyph Metrics Use glyph metrics during measuring. (left and right margins)
Measurement Show Font Metrics Use font metrics during measuring. (descender, baseline, x height, ascender, cap height)
Contours can close by dragging An open contour can close while dragging the first or last point on the first or last point.
Contour Closing Snap Distance The snap distance used to snap the first or last point while closing an open contour..
Draw Strokes Using Antialias Use anti alias to draw strokes. This is an option for Retina displays where the device pixel is rather small.

 

Glyph Editor Color Settings

Hot Keys

The Glyph View Preferences also allows the user to create and configure his/her own customized keyboard shortcuts.

read more: Glyph Editor

Character Set

All User default setting related to the Character set and Font Collection.

 

Glyph names can be formatted as simple math with components and unicodes,
see Adding and deleting glyphs.

Users can add .enc files with import.

Deleting glyphs also removes glyph name from Remove glyph names from kerning and groups when the glyph is being deleted.
Template glyph preview font The font used to draw the template glyph cells. The font must be installed on your system.
Template glyphs missing unicode character If a glyph does not have an unicode value this characeter will be used as replacement.
New glyph width The default width for newly added glyphs.

 

read more: Font Collection, Sort

Space Center

All User default settings related to the Space Center.

Manage colors, input text and hot keys.

 

read more: Space Center

Sort

All User default settings related to sorting.

These are default that will be used for every new font. These settings can be overruled by setting from in a font (if the font has sorting settings)

read more: Sort

Python

 All default settings related to scripting.

By clicking on the drop-down menu on the top left corner, Users can choose the default folder for their Python scripts.

The Output window can be configured to open as a pop-up.

The code editor’s font and colors can be fully customized.

read more: Scripting

Extensions

All User default settings related to the extensions.

 

Manage your script that will be executed during start up and installed extensions.

Install RoboFont as a shell command.

 

read more: Extensions

Misc

The Misc section of the Preferences window collects all User default settings that are not related to a specific task.

Schermafbeelding 2013-01-22 om 14.46.57

Single Window Mode Switch between single window mode or multi window mode.
Maximum Tools in Toolbar Set the maximum amount of tools in the glyph view toolbar.
Mark Colors Manage mark colors.
Test Install Options Manage if test installed fonts are auto hinted and being remove overlapped.
Test Install Format Choose the test install format: otf or ttf
Use embedde FDK for font generation Switch between the embedded FDK or a local installed version of FDK.
Save FDK parst next to UFO Save all files used by FDK makeotf next the UFO, so they can be checked afterwards.
Auto save Auto save each 10 minutes into a chosen directory.
Automatically Check for updates Check automatically for updates during start up.
Warn when leaving RoboFont with unsaved fonts. Makes the RoboFont icon jump when there are unsaved fonts if RoboFont gets inactive.

Application menu

Robofont
About Show about window.
Preferences Show preferences window.
Hide RoboFont Hide RoboFont.
Hide Others Hide all other open applications except RoboFont.
Show All Bring all RoboFont windows to the front.
Quit RoboFont Quit RoboFont.
File
New Create a new working document.
Open Open a file that RoboFont can read. (see Opening fonts, Scripting)
Save Save the current document.
Save As... Save the current document with a different name.
Save All Save all open documents.
Close Close current document
Revert to saved Open a revert to saved sheet (see Saving Fonts)
Generate Font Generate a font binary (see Generating font files)
Test Install Test install the current document for the current user (see Generating font files)
Features ⇢ New Feature Opens a feature window to write OpenType features. The features aren't attached to any font. It can be exported to all ope
Features ⇢ Export Feature Export/save the features from the current font to a .fea file
Edit
Undo Undos the selected object(s)
Redo Redos the selected object(s)
Cut Cut the selected object(s)
Copy Copies the selected object(s)
Copy As Component Copies the selected glyph as component
Paste Paste into the selected view, object
Delete Deletes the selected object(s)
Select All Selete all possible objects
Font
Add Glyphs Shows an Add Glyphs sheet (see Adding and deleting Glyphs)
Font Info Shows the Font Info sheet (see Font Info)
Sort Shows the Sort sheet (see sort)
Glyph
Next Glyph Jumps to the next glyph
Previous Glyph Jumps to the previous glyph
Editing Makes the Editing tool active (see Editing Tool)
Drawing Makes the Drawing tool acitve (see Bezier Tool)
Slice Makes the Slice tool active (see Slice Tool)
Transform Toggles the selection of the whole glyph into transform mode
Lock Guides Locks guides
Lock Sidebearings Locks the side bearings
Lock Images Locks images
Show Measurement Info Enable visibility of the measurements info
layer ⇢ Layer Up Jumps layer up
Layer ⇢ Layer Down Jumps layer down
Layer ⇢ New Layer Create new layer
Python
Scripting Window Opens a new scripting window (see Scripting)
Jump to line Pops up a jump to line window
Output window Opens the output window
Run Executes the current python script
Comment Comment out the selected lines
Uncomment Uncomment the selected lines
Indent Indent the selected lines
Dedent Dedent the selected lines
Extensions builder Opens the extension builder (see Building Extensions)
Extensions
Write some scripts If you havent wrote a script of set the default python resource folder to an empty one you will see 'Write some Scripts', other wise it will create a menu of all *.py files in the selected folder. (see Preferences, Python)
Windows
Inspector Toggles Inspector (see Inspector)
Space center Toggles Space Center (see Space Center)
Minimize Minimize the current window
Full screen If possible use the current window in full screen
Zoom in Zoom in
Zoom out Zoom out
Zoom to fit Zoom to fit
Bring all to front Bring all Windows to the front
Help
Documentation A link to the Documentation ;)

Workflow

RoboFont can read, save and generate lots of different file formats. This section will go through some typical workflow scenes and tries not to generalize any kind of designers workflow.

Creating new fonts

How to create new fonts from scratch in a UFO format.

Read more: Creating fonts

Opening existing fonts

How to open existing UFO's, otf's, ttf's, ttx's, pfa's

Read more: Opening fonts

Saving fonts

How to save to UFO, otf, ttf, pfa and potential other formats.

Read more: Saving fonts

Test install

The power of directly testing fonts.

Read more: Test Install

Exchange with other UFO based apps

RoboFont can interact with other UFO base applications.

Read more: Exchange with UFO based apps

Opening fonts

RoboFont can read several file formats.

UFO files

RoboFont can read UFO1 and UFO2 font files.

Opening a UFO can either go by double clicking the file, only if RoboFont is the preferred UFO editor off course :) or drag the file on the app icon or through the 'Open' application menu.

Binary font files

RoboFont can read

  • otf
    OpenType CFF flavored font 
  • ttf
    TrueType OpenType font 
  • pfa
    PostScript ASCII font 
  • pfb
    PostScript binary font
  • WOFF
    Web Open Font Format
  • ttx
    fontTools xml font 
  • Font Suitecase
    Extremely Old mac font format

RoboFont will read all glyphs and their corresponding outlines and tries to read the font info. 

RoboFont will not read features from .otf and .ttf OpenType fonts.

Python files

RoboFont can be your preferred python editor. It opens all python files (*.py) in the scripting window.

A folder with several python files can be dropped on RoboFont's app icon to open the folder in a scripting window.

Feature files

RoboFont read and writes Adobe Feature files (.fea) natively. Opening a feature file will open a feature window. This Window is not attached to a specific font. 

To save feature files (.fea) from a font choose "Export Feature" from the file menu (see application menu)

Revert

It is possible to revert to a save data on disk with 'revert'. Users can select parts to revert, this ignore other data.

Import warnings

Groups with a ' (quote)

RoboFont will warn users when they have groups exported from FontLab with a ' (quote) master glyph.

Results are been printed in the output window.

Truetype font or font with quadratic curves

RoboFont can handle quadratic curves but with the limitation there are only two off curve points for each segment. During import RoboFont checks and converts all quadratic segments to two off curves points segments.

The warning sheet can be hidden for future display.

Mixed curve description

RoboFont doesn't not allow mixed curve descriptions. Mixing bezier curves and truetype splines is in general not a good idea. RoboFont provides a warning sheet that allows users to choose to which curve description they want to change.

Preferred curve description can be set in the Preferences.

Import errors

If something goes wrong during importing RoboFont show a nice traceback. This can either be the UFO is badly written or a font file isn't readable any more.

Read more: Preferences

Creating fonts

Users can create a new document with '⌘+N' or 'New' from the application menu

The document will have some predefined settings, those can be changed in the Preferences.

Character set

In the Preferences default template character sets can be predefined. Each new UFO document will have those glyphs as template glyphs. 

Set curve description

In the preferences you are able to switch between bezier curves and TrueType splines.

Read more: Preferences

Saving fonts

RoboFont can write several formats.

UFO files

RoboFont can write UFO1 and UFO2 font files. It's recommended to use UFO2.  

As an option is possible to save images next to the UFO. This makes it easier to exchange UFO with images.

Generating binary font files

RoboFont can write

  • otf
    OpenType CFF flavored font 
  • ttf
    TrueType OpenType font
  • pfa
    PostScript ASCII font

otf     pfa
Decompose An OpenType CFF flavored font is always decomposed
Remove Overlap Remove overlap during generating the font
Autohint Enable FDK autohint 
Release Mode Removes the word 'Development' from the name table Version (see MakeOTFUserGuide.pdf)
 ttf 
Decompse Enable to decompose components
Remove Overlap Remove overlap during generating the font
Autohint Will be enable if ttfautohint is installed on the users local computer.
Release Mode Removes the word 'Development' from the name table Version (see MakeOTFUserGuide.pdf)

Enable 'Use MacRoman as the start of the glyph order' will force MacRoman to start the encoding with, otherwise it will take the order from the font collection sort.

Python files

Saving python files from within the scripting window.

Exchange with UFO based apps

Exchange the UFO font with other applications that support UFO as native file format. There is a a "Edit With…" toolbar item that can send the active UFO file to a chosen applications.

Changes

If the UFO file is been changed by an other application outside RoboFont and the UFO file is still open, RoboFont will present you a message that there have been some changes.

Users can either:

  • Review their changes
  • Reject their changes, so the internal font data will not change
  • Update directly

Reviewing changes will present all changes made for each UFO that has been changed by an other application outside RoboFont.

Users can either:

  • Reject all changes
  • Update... all selected changes

Test Install

RoboFont can install a font directly in the OS. This font will be directly available for use in any other application. The font will be installed only for the current user and will be deactivated when the UFO document in RoboFont is closed, when the user quits RoboFont or when the user logs out.

Test install will always generate a *.otf. There are some setting you can alter in the Preferences like decompose, auto hint and remove overlap.

Test install can be found in the application menu.

Read more: Application menu

Glossary

bcp off curve point describing the curve
glyph a drawing of a character (see)
character a drawing (glyph) representing a character (see)
font the physical embodiment of a collection of letters, numbers, symbols, etc. (whether it’s a case of metal pieces or a computer file) is a font. When referring to the design of the collection (the way it looks) you call it a typeface. (Mark Simonson see)
UFO Unified Font Object
RoboFab python scripts for reading, writing UFO's and many more
typeface the physical embodiment of a collection of letters, numbers, symbols, etc. (whether it’s a case of metal pieces or a computer file) is a font. When referring to the design of the collection (the way it looks) you call it a typeface. (Mark Simonson see)
alt
control
command
shift
API Application Programming Interface (wikipedia entry)

API

RoboFont is highly extendable in any direction from subclassing existing classes to adding new features and functionality in a new tool.

There are many levels how to interact with RoboFont and how to handle various parts: font data, UI, user interaction, ...

Scripts

A tiny script using roboFab to add actions/features/functionalities to a menu item or key stroke.

# convert to monospace font
from robofab.interface.all.dialogs import AskString

value = AskString("Monospace width:")

try:
    value = int(value)
except ValueError:
    value = None

if value:
    font = CurrentFont()
    for glyph in font:
        glyph.width = value

Save this script in the default script folder to extend RoboFont Extensions menu. See the preferences to add a short cut to a specific script.

Observers & Tools

RoboFont is being build up around a core that is just sending out notifications. A script can subscribe to one or more notifications and perform an action based on the send notification.

There are three kinds of notifications inside RoboFont

  • Native Cocoa Notifications
    When the app opens, closes, hides; when a window resizes; when a text field changed, ...
  • Font Data Notifications
    Font data notifications are being send out when the font data is being changed. Those notifications are already natively in defcon and extended in RoboFont.
  • RoboFont Notifications
    RoboFont notifications are being send from several places: Glyph Editor, Space Centers, based on users interaction related to adjusting, changing font data.

There are two systems build in to subscribe to notifications:

  • As an Observer
    A class, the observer will subscribe to a specific notification. When the notification is being send it will receive a callback with additional info and objects related to the notification.
  • As a Tool
    A tools receives all the notifications RoboFont has, but it only can be activated when an user selected the tool from the toolbar in the glyph editor.  

Strings

Strings are objects representing text. A string is defined either with a single quote or a double quotes.

## this is a comment and will not be executed.

# define a string between quotes
# can be a single quote ' or a double quote "

print "this is a string"

print 'this is also a string'

print """this is a multi-line string
an other line in the string"""

print '''this is also a multi-line string
an other line in the string'''

print "a 'single quote' can be in a string declared with double quotes"

print 'a "double quote" can be in a string declared with a single quote'

Open this script in RoboFont.

Math

## Math

# math with numbers
print 10 + 5      # adding
print 10 - 5      # subtracting
print 10 * 5      # multiplying
print 10 / 5      # dividing

print 5 // 2      # integer division
print 5 % 2       # modulo

print 4 ** 2      # the power of

# math with strings
# (only adding string with a string and multiplying with a integer)
print "hello" + "world" 
print "hello" * 5 

# this will make an error and print out a traceback
print "hello" + 5

Open this script in RoboFont.

Lists

## Lists

# a list is always ordered 
myList = [1, 2, 3, 4]
print myList

# can contain a mixture of different sort of objects
myList = ["hello", 1, 2, 1, 3, "world"]

print myList
print myList[0]         # get the first item of the list
print myList[1]         # get the second item of the list

print myList[-1]        # get the last item of the list
print myList[-2]        # get the second last item of the list

# count
print myList.count(1)   # returns the number of times the item
                        # appears in the list 

# append an item
myList.append(865)      # add an item to the end of the list

# insert an item at a specific index
myList.insert(1, "Welcome")

# lenght of a list
print len(myList)       # count how many items are in the list
print myList

# strings also act as list
myString = "hello world"
print myString[0]

# slicing
print myList[2:6]       # subset the list from index to index

# creating lists
print range(10)         # a list of numbers going from 0 to 10
print range(2, 10)      # a list of numbers going from 2 to 10
print range(2, 10, 3)   # a list of numbers going from 2 to 10 in steps of 3

Open this script in RoboFont.

Dictionaries

## Dictionaries 

# A dictionary is a keyword assigned collections of objects
# keyword can be a string, number or an other kind of object

# create a dictionary with curly brackets
myDict = {"aKeyWord" : 6, "anOtherKeyWord" : "Hello World"}
print myDict

# retrive the value based on a keyword
# if the keyword is not a valid keyword it will raise an KeyWord error
print myDict["aKeyWord"]

# retrive the value based on a keyword with a fallback
print myDict.get("keyWordNotInTheDict", "myFallbackValue")

# add/change a keyword value
myDict["aKeyWord"] = 9
myDict["newKeyWord"] = "newValue"

# get all keywords from the dictionary
print myDict.keys()
# get all values from the dictionary
print myDict.values()
# get a combined list of keywords and values from the dictionary
print myDict.items()

Open this script in RoboFont.

Loops

## Loops

# Loops over lists:
# indentations is very important
# evertying on the same indentation level will be exectuded inside the loop

print "loop over a list"
myList = ["hello", 1, 2, 1, 5]

for item in myList:
    print item 

print "loop over a string"
for char in "Hello World":
    print char

print "loop over a range of numbers:"
for i in range(10):
    print i

print "a loop in a loop:"
for x in range(10):
    for y in range(10):
        print x, y

# loop over dictionaries

myDict = {"aKeyWord" : 6, "anOtherKeyWord" : "Hello World"}

print "a loop over all keys in a dictionary"
for key in myDict.keys():
    print key
    # get the value from the dictionary based on the keyword
    print myDict[key]

print "a loop over all values in a dictionary"
for value in myDict.values():
    print value

print "a loop over all keys and values in a dictionary"
for key, value in myDict.items():
    print key, value

Open this script in RoboFont.

Functions

# Functions

# a repeated action can be bundled into a single function

def myFunction():
    print "hello"
    
myFunction()
myFunction()

# arguments can be passed along

def myMathFunction(number):
    print number * 6

myMathFunction(9)
myMathFunction(60)


# function can also return a value

def myReturningFunction(number):
    return number * 6

print myReturningFunction(9)    # prints 54
print myReturningFunction(60)   # prints 360 

# compare
print myMathFunction(60)        # will print None, 
                                # cause the function is not returning anything

Open this script in RoboFont.

Classes

## Classes

# with a class it's possible to create custom objects
# with his own "special-powers"

class SimplePerson(object):
    pass
    
p = SimplePerson()

print p

p.firstName = "Fred"
p.familyName = "Flinstone"

print p.firstName
    
# add methods

class Person(object):
    
    def __init__(self):
        self.firstName = ""
        self.familyName = ""
        self.street = ""
        
    def fullName(self):
        return self.firstName + " " + self.familyName
    
    def info(self):
        return "%s\n%s" %(self.fullName(), self.street)
    
    def __len__(self):
        return len(self.firstName) + len(self.familyName)
    
p = Person()

print p.fullName()

p.firstName = "Fred"

print p.fullName()

p.familyName = "Flinstone"

print p.fullName()

p.street = "Road 4"
print p.info()
print len(p)


# inhert objects
class TypeDesigner(Person):
    
    def __init__(self):
        super(TypeDesigner, self).__init__()
        self.designed = []
    
    def info(self):
        info = super(TypeDesigner, self).info()
        return "%s\n%s" %(info, ", ".join(self.designed))
        
td = TypeDesigner()
td.firstName = "Fred"
td.familyName ="Flinstone"
td.street = "Road 4"

td.designed.append("Stone")
td.designed.append("Clay")

print td.info()

    
    
        
        

Open this script in RoboFont.

Conditional Statements

## conditional statements

# setup some variables
a = 5
b = 10

# is equal
print a == b

# is not equal
print a != b

# greater than
print a > b

# greater than or equal
print a >= b

# is less than
print a < b

# is less than or equal
print a <= b


# make conditional descisions 
# be carefull with the indetentation

if a < b:
    print "a is greater than b"

# if then else that    
if a > b:
    print "a is less than b"
else:
    print "a is greater than b"
    

# if that else if aht else that
if a > b:
    print "a is less than b"
elif a == b:
    print "a is equal to b"
else:
    print "a is greater than b"
    
# combine conditions with boolean operators
# and or not
if a > b and a == 5:
    print "a is greater than b and a is equal to 5"

elif a > b or a == 5:
    print "a is greater than b or a is equal to 5"

Open this script in RoboFont.

Import

## import

# import existing modules, functions, classes in to a script

# Importing modules 
import robofab
print robofab

# Importing all objects from a module
from robofab import *
print version            # a number 

# Importing a specific sub module
from robofab.pens.filterPen import halftoneGlyph
print halftoneGlyph      # a function

Open this script in RoboFont.

Custom Observers

An observer has to be subscribed to an specific event. When the event happens the observer will get a notification.

from mojo.events import addObserver

class myEventObserver:
    def __init__(self):
        addObserver(self, "myObserver", "mouseDown")

    def myObserver(self, info):
        print info #do something...

myEventObserver()

Real live example drawing a reference to the current glyph in the Glyph View using the unicode value of the glyph:

"""
An example script of adding an observers and do *something* 

It draws a simple unicode reference of an existing installed font.
"""

from mojo.events import addObserver
from mojo.drawingTools import *

class DrawReferenceGlyph(object):
    
    def __init__(self):
        addObserver(self, "drawReferenceGlyph", "draw")

    def drawReferenceGlyph(self, info):
        
        glyph = info["glyph"]
        
        r = 0
        g = 0
        b = 0
        a = .5
        
        if glyph is not None and glyph.unicode is not None:
            t = unichr(glyph.unicode)
            
            font("Georgia", 100)
            stroke(None)
            fill(r, g, b, a)
            text(t, (glyph.width + 10, 10))
            
            
DrawReferenceGlyph()

More observers examples.

Observers

  • addObserver(observer, method, event)
    Adds an observer for an event to the observer method.
  • removeObserver(observer, event)
    Removes the observer for an event.

Events

Any observer can subscriber to these events. The callback receives a dictionary object containing additional objects related to the send event.

All notification dictionaries contains the following keys:

glyph the current/edited/active glyph
tool the current tool
view the current glyph view

  • applicationDidFinishLaunching
    Send when RoboFont did finish launching.
  • applicationDidBecomeActive
    Send when RoboFont become the active application.
  • applicationWillResignActive
    Send when RoboFont resigns being the active application.
  • binaryFontWillOpen
    Send when a binary font will open.
    font  the font object
    source the fontTools source object
    format the format of the source font
  • fontWillSave
    Send when a font will save.
    font the font object
    path the path where the font will be saved
  • fontDidSave
    Send when a font is done saving.
    font the font object
    path the path where the font did save
  • fontWillClose
    Send when a font will close.
    font the font object
  • newFontWillOpen
    Send when a new font will open.
    font the font object
  • newFontDidOpen
    Send when a new font did open.
    font the font object
  • fontWillOpen
    Send when a font will open.
    font the font object
  • fontDidOpen
    Send when a font did open.
    font the font object
  • fontWillAutoSave
    Send when a font will auto save.
    font the font object
    path the path where the font did autosave
  • fontDidAutoSave
    Send when a font did auto save.
    font the font object
    path the path where the font did autosave
  • fontDidChangeExternally
    Send when a font did change externally, outside RoboFont.
    font the font object
  • fontWillGenerate
    Send when a font will generate.
    font the font object
    format the format of the generated font
    path the path where the binary font will save
  • fontDidGenerate
    Send when a font did generate.
    font the font object
    format the format of the generated font
    path the path where the binary font will save
  • currentGlyphChanged
    Send when the current glyph changed, this can be either in the glyph view or in the font overview.
  • viewWillChangeGlyph
    Send when the glyph view will switch to an other glyph.
  • viewDidChangeGlyph
    Send when the glyph view did switch to an other glyph.
  • glyphWindowWillOpen
    Send when a glyph window will open.
    window the glyph window that will open
  • glyphWindowDidOpen
    Send when a glyph window did open.
    window the glyph window that did open
  • glyphWindowWillClose
    Send when a glyph window will close.
    window the glyph window that will close
  • spaceCenterWillOpen
    Send when a space center will open.
    window the space center window that will open
  • spaceCenterDidOpen
    Send when a space center did open.
    window the space center window that did open
  • spaceCenterWillClose
    Send when a space center will close.
    window the space center window that will close
  • transformChanged
    Send when a transformation is applied to a glyph.
    scale
    translate
    rotate
    skew
    repeatMatrix
  • extensionDidGenerate
    Send when an extension did generate.
    path the path to the extension
  • spaceCenterDraw
    Send when a space center draws a glyph, this can happen a lot so be care full.
    scale the drawing scale
    spaceCenter the space center
    selected a bool if the glyph is selected in the space center
  • spaceCenterKeyDown
    Send on a key down in a space center.
    event the NSEvent object
    spaceCenter the space center
  • spaceCenterKeyUp
    Send on a key up in space center.
    event the NSEvent object
    spaceCenter the space center
  • drawPreview
    Send when the glyph view draws a preview.
    scale
  • drawBackground
    Send when the glyph view draws the background, before the actual glyph data.
    scale
  • draw
    Send when the glyph view draw the glyph data.
    scale
  • drawInactive
    Send when the glyph view draw when the glyph window is not the active one.
    scale
  • mouseDown
    Send on mouse down in the glyph view.
    point the point coordinates of the mouse in the glyph coordinate system
    clickCount the click count
    offset offset of the zero zero point in the glyph view
    event the NSEvent object
  • rightMouseDown
    Send on right mouse down in the glyph view.
    point the point coordinates of the mouse in the glyph coordinate system
    event the NSEvent object
  • mouseDragged
    Send on a mouse drag in the glyph view.
    point the point coordinates of the mouse in the glyph coordinate system
    offset offset of the zero zero point in the glyph view
    delta delta of the drag form the first click
    event the NSEvent object
  • rightMouseDragged
    Send on a right mouse drag in the glyph view.
    point the point coordinates of the mouse in the glyph coordinate system
    offset offset of the zero zero point in the glyph view
    event the NSEvent object
  • mouseUp
    Send on a mouse up in the glyph view.
    point the point coordinates of the mouse in the glyph coordinate system
    offset offset of the zero zero point in the glyph view
    event the NSEvent object
  • keyDown
    Send on a key down in the glyph view.
    event the NSEvent object
  • keyUp
    Send on a key up in the glyph view.
    event the NSEvent object
  • modifiersChanged
    Send when the modifier changed in the glyph view (command, alt, control and shift keys)
    event the NSEvent object
  • toggleTransformMode
    Send when the glyph view toggles from or out the transform mode.
  • acceptMenuEditCallbacks
    Send when a contextual menu is been build.
    item a menu item
  • selectAll
    Send on select all in the glyph view.
  • deselectAll
    Send on deselect all in the glyph view.
  • selectAllAlternate
    Send on select all alternate in the glyph view.
  • copy
    Send on copy in the glyph view.
  • copyAsComponent
    Send on copy as component in the glyph view.
  • cut
    Send on cut in the glyph view.
  • delete
    Send on delete in the glyph view.
  • paste
    Send on paste in the glyph view.

Custom Tools

You can add custom tools to RoboFont, by subclassing the BaseEventTool class or an existing core tool. RoboFont core tools are BezierDrawingTool, EditingTool, MeasurementTool and SliceTool. They are available through the mojo.events module.

from mojo.events import BaseEventTool 
## or subclassing a core tool
from mojo.events import BezierDrawingTool, EditingTool, MeasurementTool, SliceTool

This is an easy example, with most event callback. You need the installTool to tell RoboFont you want to install in a new tool.
Custom tools can also be activated at start up through the preferences.

example:

from mojo.events import BaseEventTool, installTool
from AppKit import *

class MyEvent(BaseEventTool):

    def becomeActive(self):
        print "active"

    def becomeInactive(self):
        print "inactive"

    def mouseDown(self, point, clickCount):
        # getGLyph returns the current glyph as robofab object
        print "mouseDown", self.getGlyph(), clickCount

    def rightMouseDown(self, point, event):
        print "rightMouseDown"

    def mouseDragged(self, point, delta):
        print "mousedragged"

    def rightMouseDragged(self, point, delta):
        print "rightMouseDragged"

    def mouseUp(self, point):
        print "mouseup"

    def keyDown(self, event):
        # a dict of all modifiers, shift, command, alt, option
        print "keyDown", self.getModifiers() 

    def keyUp(self, event):
        print "keyUp"

    def modifiersChanged(self):
        print "modifiersChanged"

    def draw(self, scale):
        print "draw", self.isDragging()
        if self.isDragging():
            ## draw a red dot when dragging
            r = 50
            NSColor.redColor().set()
            x, y = self.currentPoint
            NSBezierPath.bezierPathWithOvalInRect_(((x-r, y-r), (r*2, r*2))).fill()

    def drawBackground(self, scale):
        print "drawBackground here"

    #def getDefaultCursor(self):
    #   this will be the cursor default is an arrow
    #   return aNSCursor
    #def getToolbarIcon(self):
    #   this is setting the icon in the toolbar default is an arrow
    #   return aNSImage

    def getToolbarTip(self):
        return "My Event Tool Bar Tip"

    #notifications

    def viewDidChangeGlyph(self):
        print "view changed glyph"

    def preferencesChanged(self):
        print "prefs changed"

installTool(MyEvent())

Tools Methods

  • getGlyph()
    Returns the current glyph used by the tool 
  • getNSView()
    Returns the current glyph view 
  • getCurrentEvent()
    Returns the current NSEvent.
  • refreshView()
    updates the current glyph view
  • setCursor(cursor=None)
    Sets the cursor as current cursor (needs a NSCursor object), if None is given it will be return to default cursor of the tool
  • isDraggin()
    Returns a bool if the tool is draggin
  • zoomRect(offset=None)
    zoom to a given rect
  • toggleTransformMode()
    Toggle the transform
  • getDefaultCursor()
    returns the default cursor for the tool, this must be overwritten
  • getToolbarIcon()
    returns the toolbar icon for the tool, this must be overwritten
  • mouseDown(point, clickCount)
    send a mouse down notification to the tool, with the mouse point in the and the clickCount
  • rightMouseDown(point, clickCount)
    send a right mouse down notification to the tool, with the mouse point in the and the clickCount
  • modifyPoint(point)
    modify the point coordinates
    In the embedded tools this is used to modify the point when fe. on shiftDown
  • mouseMoved(point)
    send a mouse moved notification to the tool, be careful and optimize the code cause the mouse moves all the time
  • mouseDragged(point, delta)
    send a mouse dragged notification to the tool, the delta is the difference between the previous drag point
  • rightMouseDragged(point, delta)
    send a right mouse dragged notification to the tool, the delta is the difference between the previous drag point 
  • mouseUp(point)
    send a mouse up notification to the tool
  • isDragging()
    returns a bools if the tool is in a dragging event
  • keyDown(event)
    send a key down notification to the tool, possible to get the pressed characters by event.characters()
  • keyUp(event)
    send a key up notification to the tool 
  • modifiersChanged()
    send a modifiers changed notification to the tool, happens when shift, command, control, alt is changed
  • getModifiers()
    returns a dictionary with all the modifiers keys as bools. True when pressed down, keys are: shiftDowncommandDownoptionDowncontrolDown
  • getArrowsKeys()
    returns a dictionary with all the arrows keys as bools. True when pressed down, keys are: up, down, left, right

Tools Menu methods

  • acceptMenuEditCallbacks()
    Overwrite this if you want your tool to accept menu callbacks.
  • selectAll()
    perform a select all in your tool, don't overwrite it if you don't want to do anything with it
  • selecteAllAlternate()
    perform a select all in your tool with alt key down, don't overwrite it if you don't want to do anything with it
  • deselectAll()
    perform a deselect all in your tool, don't overwrite it if you don't want to do anything with it
  • copy()
  • copyAsComponent()
  • cut()
  • delete()
  • paste()
  • additionContectualMenuItems()
    called when a contextual menu is created, it is required to return a list of tuples with a title string and a callback function
    example [("additional stuff", myObject.myAdditionMenuCallback), ]

Tools Draw Methods

  • draw(scale)
    draw in the glyph
  • drawBackground(scale)
    draw in the background of the glyph view
  • drawPreview(scale)
    additional drawing in the glyph view while holding the glyph view preview key
  • drawInactive(scale, glyph, view)
    additional drawing in the glyph view when the glyph view is not active, the glyph will not be the current glyph, same for the view
  • drawBackgroundSelection(scale)
    draw in the background, should be related to a selection
  • drawSelection(scale, glyph, view)
    draw the selection for a glyph in a view

Space Center

  • spaceCenterDraw(glyph, scale, selected, spaceCenter)
    draw in the space center for given glyph
  • spaceCenterKeyDown(glyph, event, spaceCenter)
    send a key down notification to the tool, possible to get the pressed characters by event.characters()
  • spaceCenterKeyUp(glyph, event, spaceCenter)
    send a key up notification to the tool 

Tools Notifications Methods

  • viewWillChangeGlyph()
    the glyph in the current view will change
  • viewDidChangGlyph()
    the glyph in the current view did change
  • currentGlyphChanged()
    the current glyph in the app changed
  • preferencesChanged()
    the user defaults changed
  • becomeInactive()
    the tool becomes inactive
  • becomeActive()
    the tool becomes active
  • didUndo()
    a undo notification when the undo is already performed
  • glyphWindowWillOpen()
    a new glyph window will open
  • glyphWindowDidOpen()
    a new glyph window did open
  • glyphWindowWillClose()
    a glyph window will close
  • spaceCenterWillOpen()
    a new Space Center will open
  • spaceCenterDidOpen()
    a new Space Center did open
  • spaceCenterWillClose()
    a Space Center will close
  • fontWillOpen(font)
    a UFO will been opened
  • fontDidOpen(font)
    a UFO did open 
  • newFontWillOpen(font)
    a new UFO will been created
  • newFontDidOpen(font)
    a new UFO is been created 
  • binaryFontWillOpen(font, source, format)
    a binary font will open
    the source is the fontTools font object 
  • fontWillClose(font)
    a UFO is been closed
  • applicationDidFinishLauching() 
    the app is ready launching
  • applicationDidBecomeActive()
    the app becomes active
  • applicationWillResignActive()
    the app will resign being active
  • fontBecameCurrent(font)
    a font becomes active
  • fontResignCurrent(font) 
    a font resigns being active 
  • fontWillAutoSave(font)
    font will auto save
  • fontDidAutoSave(font)
    font did auto save
  • fontWillSave(font, path)
    font will save
  • fontDidSave(font, path)
    font did save
  • fontWillGenerate(font, format, path)
    font will generate to a binary format
  • fontDidGenerate(font, format, path) 
    font did generate to a binary format
  • fontDidChangeExternally(font)
    An external change to the font has happend 

Tools Attributes

  • allPointList
    A list of clicked and dragged points used by the tool
  • mouseDownPoints
    A list of clicked points used by the tool
  • shiftDown
    Bool if shift is down 
  • commandDown
    Bool if command is down 
  • optionDown
    Bool if option is down 
  • controlDown
    Bool if control is down 
  • spaceBarDown
    Bool if space is down 
  • arrowKeysDown
    a dictionary of bools with keys: up, down, left, right
  • currentPoint
    returns the last points from the allPointsList
  • selection
    returns the current glyph selection object 

RoboFab extras

See the RoboFab site for an extended object descriptions. There are some additional RoboFont specific methods and attributes added to some objects.

Base Objects

Allmost every class used has some additional attributes.

Methods

  • addObserver(observer, methodName, notification)
    adds an observer to the object that notifies the methodName of the observer for a given notification
  • removeObserver(observer, notification)
    removes the observer for a  given notification
 

 

Font Object

Create a new font object:

  • RFont(path=None, showUI=True)
    ShowUI will toggle the creating of all interface objects around a font.

Methods

  • document()
    returns the related NSDocument 
  • renameGlyph(oldName, newName, renameComponents=True, renameGroups=True, renameKerning=True)
    Rename a glyph in the font.
    Optionally the glyph can be renamed in all component references, groups and kerning. 
  • generate(path, format, decompose=False, checkOutlines=False, autohint=False, releaseMode=False, glyphOrder=None, progressBar=None)
    Generate a font binary to the given path with the given format ("otf", "ttf", "pfa") 
    Adding a progressBar object will show you the progress during compiling the font.
  • removeOverlap()
    removes all overlaps in every glyphs
  • extremePoints()
    adds extremes points for every glyph 
  • testInstall()
    test instals the font, it returns the ID of the installed font on the os.
  • removeLayer(layerName)
    removes a complete layer, to create a layer just ask any glyph.getLayer("myLayerName")
  • addGuide((x, y), angle, name="")
    adds a guide at point x, y with angle and name
    returning the created guide 
  • removeGuide(guide)
    gwill remove the guide from the font 
  • update()
    tell the UI that a font has changed directly
  • prepareUndo(undoTitle="")
    This marks to glyph to be ready that a action begins and it should be recorded to create an undo item when its done
  • performUndo()
    creates the undo item
  • setLayerDisplay(layerName, option, value)
    set display options for layers option: Fill, Stroke, Points, Coordinates

Attributes

  • glyphOrder
    returns a list of glyph names in a specific order, it is possible to set the a list with a specific order in a font
  • layerOrder
    returns a list of layernames
  • guides
    a list of all the guides in the glyph
  • templateSelection
    next to the font.selection, which only contains glyphs in the font there is also a selection of template glyphs
 

 

Glyph Object

Methods

  • addGuide((x, y), angle, name="")
    adds a guide at point x, y with angle and name
    returning the created guide 
  • removeGuide(guide)
    will remove the guide from the glyph 
  • addImage(path, offset=None)
    adds an image from path  with offset
    returning the created guide
  • clearImage()
    remove the image  
  • removeOverlap()
    removes all overlaps in every glyphs
  • extremePoints()
    adds extremes points for every glyph 
  • deselect()
    deselect everything 
  • getLayer(layerName, clear=True)
    return the glyph for that layer, create a layer new layer if the layerName doesn't exists 
  • copyToLayer(layerName, clear=True)
    copy the current layer to the a layer with the layerName
  • swapToLayer(layerName)
    swap current layer with the a layer with the layerName
  • flipLayers(layer1Name, layer2Name)
    flip layers
  • update()
    tell the UI that the glyph has changed directly 

Attributes

  • angledLeftMargin
    returns the angled left margin based on the italic angle in the font.info
  • angledRightMargin 
    returns the angled right margin based on the italic angle in the font.info 
  • mark
    a tuple of 4 (r, g, b, a)
  • image
    the image object, if no image is set it will be None 
  • guides
    a list of all the guides in the glyph 
  • selection
    a list of selected points 
  • selected
    returning True or False if yhe object is selected or not 

 Boolean Glyph

  • glyph | otherGlyph
    returns the union of the contours
  • glyph % otherGlyph
    returns the difference of the glyph contours
  • glyph & otherGlyph
    returns the intersection of the glyph contours
  • glyph ^ otherGlyph
    returns the xor of the glyph contours

 

Guide Object

Attributes

  • x
    The x of origin the guide.
  • y
    The y of origin the guide.
  • angle
    The angle of guide.   
  • name
    The name of the guide 
  • isGlobal
    returning if the guide is connected to a font object or glyph object
 

 

Image Object

Methods

  • transform(tranformation)
    Transform the image with a transform matrix (xy, yy, xx, yx, x, y) 
  • move((x, y))
    Move the image with a given x, y 
  • translate((x, y))
    Translate the image with a given x, y 
  • skew(angle, offset=None)
    Skew the image with a given angle, optionally with an offset (x, y) 
  • rotate(angle, offset=None)
    Rotate the image with a given angle, optionally with an offset (x, y)
  • scale((x, y), center=(0, 0))
    Scale the image with a given x, y, optionally with a center coordinate

Attributes

  • path
    path to the image 
  • bounds
    image bounding box 
  • brightness
    set brightness of the image (float)
  • contrast
    set contrast of the image (float)
  • saturation
    set saturation of the image (float)
  • sharpness
    set sharpness of the image (float)
  • blackAndWhite
    convert image to black and white (bool)
  • selected
 

 

Contour Object

Methods

  • join()
    will close an open contour
  • extremePoints()
    adds extremes points for every glyph 

Boolean Glyph

RoboFont makes it possible to perform common boolean path operations (difference, union, intersection and exclusive or) with glyph objects directly, using special characters as operators.

operation operator
difference %
union |
interesection &
exclusive or ^

Example

Here are the four boolean path operations in action. Note that, for the difference operation, the order of the operands matters.

glyph-booleans

f = CurrentFont()
g1 = f['A']
g2 = f['B']

# difference 1
r = g1 % g2
g = f.newGlyph('difference_1')
g.appendGlyph(r)

# difference 2
r = g2 % g1
g = f.newGlyph('difference_2')
g.appendGlyph(r)

# union
r = g2 | g1
g = f.newGlyph('union')
g.appendGlyph(r)

# intersection
r = g2 & g1
g = f.newGlyph('intersection')
g.appendGlyph(r)

# xor
r = g2 ^ g1
g = f.newGlyph('xor')
g.appendGlyph(r)

mojo.compile

from mojo.compile import *
  • FDKVersion
    Returns the version of the embedded FDK
  • makeotf(outputPath, outlineSourcePath=None, featuresPath=None, glyphOrderPath=None, menuNamePath=None, fontInfoPath=None, releaseMode=False)
    FDK makeotf
  • checkOutlines(fontPath, removeOverlap=True, correctContourDirection=True)
    FDK checkOutlines
  • otf2pfa(sourcePath, destinationPath)
    Convert a otf to pfa using FDK. 
  • otf2svg(sourcePath, destinationPath)
    Convert a otf to a svg font using FDK.
  • autohint(fontPath)
    Autohint a postscript flavored font. 
  • hasTTFAutoHint()
    Return a boolean if ttfautohint is installed. 
  • ttfautohint(fontPath)
    Use ttf autohint if its locally installed to autohint a ttf file. 
  • stemHist(fontPath, userCurves=None, blueZones=False)
    Use FDK stemhist on a binary font. See stemHist help for details.
  • setUseEmbeddedFDK(value)
    Set a boolean if RoboFont should use the embedded FDK. 
  • getUseEmbeddedFDK()
    Returns a boolean if RoboFont will use the embedded FDK.  
  • executeCommand(command, shell=False)
    Execute commands in the terminal. Commands must be a list of arguments.
    Optionally execute in the shell instead of inside RoboFont

mojo.extensions

from mojo.extensions import *

Classes

  • ExtensionBundle(name=None, path=None, libName="lib", htmlName="html", indexHTMLName="index.html", resourcesName="Resources")
    An extension bundle objects allowing access to different parts of an extension.
     
    initiate an ExtensionBundle object
    name: name of an extension (either name or path is required)
    path: path to an extension (either name or path is required) 
     
    version
    returns the version of the extension
    name
    returns the name of the extension
    developer
    returns the developer of the extension
    developerURL
    returns the developer URL of the extension
    requiresVersionMajor
    returns the required major version number of RoboFont
    requiresVersionMinor
    returns the required minor version number of RoboFont
    addToMenu
    returns a bool if the bundle should be added to the extension menu
    launchAtStartUp
    returns a bool if the bundle should be launched at start up
    mainScript
    returns the filename of the main script

    timeStamp
    returns the time stamp, stamped when the extension is build
     
    get(name, ext='*')
    returns the file within the extension, if its is an image it will return the NSImage object around that image.
    install()
    installs the extension
    deinstall()
    de-installs the extension 
    openHelp()
    Opens the help HTML in an HTMLHelpWindow
    validate()
    validates the extension
    validateErrors()
    returns a string of validation errors
    bundlePath()
    returns the path of the extension bundle
    libPath()
    returns the path of the lib folder inside the bundle
    HTMLPath()
    returns the path of the HTML folder inside the bundle
    resourcesPath()
    returns the path of the Resources folder inside the bundle
    infoDictionaryPath()
    returns the path of the info.plist inside the bundle
    mainScriptPath()
    returns the path of the main script
    hasHTML()
    returns a bool if the extension has HTML help
    HTMLIndexPath()
    returns the path of the index.html file
    bundleExists()
    returns if a bool if the extension bundle exists on disk  

    allExtensions()
    a class method returns all installed extensions

Methods

  • getExtensionDefault(key, fallback=None)
    returns the value for key from the extension user defaults
    if the key isn't used it returns the fallback
  • setExtensionDefault(key, value)
    set the value for key in the extensions user defaults
  • getExtensionDefaultColor(key, fallback=None)
    returns an NSColor object for key from the extension user defaults
  • setExtensionDefaultColor(key, fallback=None)
    set an NSColor for key in the extensions user defaults
  • registerExtensionsDefaults(defaults)
    register a dict with keys and values as defaults in the extension user defaults 

mojo.canvas

from mojo.canvas import Canvas

A vanilla object that sends all user input events to a given delegate.

Canvas(posSize,
       delegate=None,
       canvasSize=(1000, 1000),
       acceptsMouseMoved=False,
       hasHorizontalScroller=True,
       hasVerticalScroller=True,
       autohidesScrollers=False,
       backgroundColor=None,
       drawsBackground=True)

Methods

All events a delegate could have that can be used:

  • draw()
    Callback when the canvas get drawn.
  • becomeFirstResponder(event)
    Callback when the canvas becomes the first responder, when it starts to receive user interaction callbacks.
  • resignFirstResponder(event)
    Callback when the canvas resigns the first responder, when the canvas will not longer receive user interaction callbacks. 
  • mouseDown(event)
    Callback when the user hit the canvas with the mouse. 
  • mouseDragged(event)
    Callback when the user drag the mouse around in the canvas. 
  • mouseUp(event)
    Callback when the user lifts up the mouse from the canvas. 
  • mouseMoved(event)
    Callback when the user moves the mouse in de canvas. Be careful this is called frequently. (only when accepsMouseMoved is set True)
  • rightMouseDown(event)
    Callback when the user clicks inside the canvas with the right mouse button. 
  • rightMouseDragged(event)
    Callback when the users is dragging in the canvas with the right mouse button down.  
  • rightMouseUp(event)
    Callback when the users lift up the right mouse button from the canvas. 
  • keyDown(event)
    Callback when the users hits a key.
    The event object has a characters() method returns the pressed character key.
  • keyUp(event)
    Callback when the users lift up the key. 
  • flagChanged(event)
    Callback when the users changed a modifier flag:
    command  shift  control  alt

Example

from mojo.canvas import Canvas
from mojo.drawingTools import *
from vanilla import *

class ExampleWindow:

    def __init__(self):
        self.size = 50

        self.w = Window((400, 400), minSize=(200, 200))
        self.w.slider = Slider((10, 5, -10, 22),
                          value=self.size,
                          callback=self.sliderCallback)
        self.w.canvas = Canvas((0, 30, -0, -0), delegate=self)
        self.w.open()

    def sliderCallback(self, sender):
        self.size = sender.get()
        self.w.canvas.update()

    def draw(self):
        rect(10, 10, self.size, self.size)

ExampleWindow()

mojo.UI

from mojo.UI import *

Classes

  • AccordionView(posSize, descriptions, backgroundColor)
    A vanilla object hosting different kinds of other vanilla objects (like vanilla.List, vanilla.TextEditor, ....) in an accordion view.
     
    Initiate a AccordionView
    posSize: a tuple of four, setting the size
    descriptions: list of options for each item in the accordionView (see example) 
    backgroundColor: a NSColor object used as background color
     
    from mojo.UI import AccordionView
    from vanilla import *
    
    class MyInspector:
    
        def __init__(self):
    
            self.w = FloatingWindow((200, 600))
    
            self.firstItem = TextEditor((10, 10, -10, -10))
    
            self.secondItem = List((0, 0, -0, -0), ["a", "b", "c"])
    
            self.thirdItem = Tabs((10, 10, -10, -10), ["1", "2", "3"])
            
            self.fourthItem = Group((0, 0, -0, -0))
            
            self.fourthItem.checkBox = CheckBox((10, 10, 100, 22), "CheckBox")
            self.fourthItem.editText = EditText((10, 40, -10, 22))
            
    
            descriptions = [
                           dict(label="first item", view=self.firstItem, size=200, collapsed=False, canResize=False),
                           dict(label="second item", view=self.secondItem, minSize=100, size=140, collapsed=True, canResize=True),
                           dict(label="third item", view=self.thirdItem, minSize=100, size=140, collapsed=True, canResize=False),
                           dict(label="fourth item", view=self.fourthItem, size=140, collapsed=False, canResize=False)
                           ]
    
            self.w.accordionView = AccordionView((0, 0, -0, -0), descriptions)
    
            self.w.open()
    
    MyInspector()
  • HTMLView(posSize)
    Initiate a HTMLView
    posSize: a tuple of four, setting the size
     
    setHTMLPath(url)
    Set the url in the HTMLView
    goBack()
    Go forward in the history of the HTMLView
    goForward()
    Go forward in the history of the HTMLView
    clearHistory()
    Clear the history of the HTMLView 
  • HelpWindow(htmlPath, title="help", developer=None, developerURL=None)
    Initiate a HelpWindow
    htmlPath: html help path
    title: title of the help window
    developer: a string with the name of the developer, optionally
    developerURL: a URL link to the developer, optionally
     
    set(htmlPath)
    set a html path in the HTMLView of the HelpWindow 
     
    from mojo.UI import HelpWindow
    
    HelpWindow("http://robofont.com")
  • SmartSet(smartSet=dict())
    Initiate a smart set object
    smartSet: a dictionary containing smart set data
     
    name
    Set or get the smart set name. 
    glyphNames
    Set or get the a list of glyph names used by the smart set. 
    query
    Set or get a search query.
  • MultiLineView(posSize, pointSize=150, lineHeight=50, doubleClickCallbak=None, applyKerning=None, bordered=False, hasHorizontalScroller=False, hasVerticalScroller=True, displayOptions=None, selectionCallback=None, menuForEventCallback=None)
    A multi glyph line view vanilla object, this is the same objects that is used to build a Space Center.
    Initiate a multi line view object:
    posSize: a tuple of four, setting the size
    pointSize: the initial point size, optionally
    lineHeight: the initial lineHeight, , optionally
    doubleClickCallback: callback for a double click event
    applyKerning: enable kerning the view, optionally
    bordered: set a border around the view
    hasHorizontalScroller: set the horizontal scroller
    hasVerticalScroller: set the vertical scroller
    displayOptions: a dict with multi line view display options
    selectionCallback: callback when a glyph get selected
    menuForEventCallback: callback when a contextual menu will we used, required to return a NSMenu object

     
    get()
    Returns all glyphs in the line view
    set(glyphs)
    Sets a list of glyphs in the line view
    setFont(font)
    The glyph line view needs a font as fallback and for font metrics
    createNewLineGlyph()
    Returns a special glyph object that acts like a new line
    createEmptyGlyph(name)
    Returns a special glyph object that acts like an empty glyph (use this as fallback when a glyph is not in the font)
    setPointSize(pointSize)
    Sets the point size
    setLineHeight(lineHeight)
    Sets the line height
    setApplyKerning(value)
    Sets if kerning is applied in the line view
    getDisplayStates()
    Returns a dict with all display options
    setDisplayStates(options)
    Sets a dict of line view display options
    setLeftToRight(value)
    Sets the reading direction of the glyph line view
     

    from mojo.UI import MultiLineView
    from vanilla import *
        
    class MyOwnSpaceCenter:
    
        def __init__(self, font):
    
            self.w = Window((600, 400), minSize=(300, 300))
    
            self.w.lineView = MultiLineView((0, 0, -0, -0), 
                                                pointSize=30, 
                                                selectionCallback=self.lineViewSelectionCallback)
            self.w.lineView.setFont(font)
    
            glyphs = []
            for glyphName in font.glyphOrder:
                glyphs.append(font[glyphName])
    
            self.w.lineView.set(glyphs)
    
            self.w.open()
        
        def lineViewSelectionCallback(self, sender):
            print sender.getSelectedGlyph()
    
    MyOwnSpaceCenter(CurrentFont())

Methods

  • GlyphViewDisplaySettings(settings)
    Set display options for the current glyphview. Input as dict. These settings will be default for the glyphview. All options are: Fill, Stroke, Metrics, On Curve Points, Off Curve Points, Point Coordinates, Anchors, Curve Length, Blues, Family Blues, Rulers
  • AllSpaceCenters()
    Get all open space centers
  • CurrentSpaceCenter()
    methods:
    get()
    returns a list of glyph names in the space center
    getRaw()
    returns a string from the input of the space center
    set(glyphNames)
    sets the list of glyphNames in the space center
    setRaw(text)
    set a string in to the main input of the space center
    getTracking()
    returns the tracking used
    setTracking(value)
    set a tracking value between the glyphs
    getLeftToRight()
    returns the reading direction
    setLeftToRight(value)
    sets the reading direction
    getPointSize()
    returns the point size
    setPointSize(value)
    sets the points size
  • SpaceCenterToPDF(path, spaceCenter=None)
    Saves the Space Center to a pdf with vector data, if a spaceCenter is not provided the CurrentSpaceCenter() will be used.
  • AllGlyphWindows()
    Returns all open glyph windows.
  • CurrentGlyphWindow()
    Returns the current glyph window.
  • GlyphWindowToPDF(path, glyphWindow=None)
    Saves the Glyph Window to a pdf with vector data, if a Glyph Window is not provided the CurrentGlyphWindow() will be used.
  • AllFontWindows()
    Returns all open font windows. 
  • CurrentFontWindow()
    Returns the current font window. 
  • OpenGlyphWindow(glyph=None, newWindow=False)
    Opens a new glyph window
    glyph: a given glyph object
    newWindow: open a new window, even if there is already a glyph window open
  • OpenSpaceCenter(font, newWindow=False)
    Opens a new Space Center
    font: a given font object
    newWindow: open a new window, even if there is already a Space Center winow open
  • OutputWindow()
    Returns the output window
    write(text)
    Write a string in the output window
    clear()
    Clears the output window
  • SetCurrentGlyphByName(glyphName)
    Sets a glyph name in the current glyph editor
  • SetCurrentLayerByName(layerName)
    Sets the current layer by a layerName in the current glyph editor
  • UpdateCurrentGlyphView()
    Updates the current glyph editor
  • SetCurrentLayerByName(layerName)
    Sets the current layer by layer name 
  • addSmartSet(smartSet, index=-1)
    Add a smart set object. 
    Optionally set an index to insert the smart set object. 
  • removeSmartSet(smartSetName)
    Remove a smart set. 
  • getSmartSets()
    Get all current smart sets. 
  • setSmartSets(smartSets)
    Set a list of smart sets. 
  • setDefaultCharacterSet(characterSetName)
    Set the default character set by name as defined in the preferences. 
  • getDefaultCharacterSet()
    Get the current default character set name. 
  • addCharacterSet(characterSetName, glyphNames, useAsDefault=False)
    Add a character set with a name and a list of glyph names. 
  • removeCharacterSet(characterSetName)
    Remove a character set by name. 
  • getCharacterSets()
    Get all characeter sets as a dictionairy. 
  • setCharacterSets(characterSets)
    Set a dictionary of character sets. 
  • setMaxAmountOfVisibleTools(value)
    Set the maximum amount of visible tools in the toolbar.
    Must be in integer. 
  • getMaxAmountOfVisibleTools()
    Get the maximum amount of visible tools in the toolbar. 
  • setScriptingMenuNamingShortKey()
    Get the scripting menu names and shortkey dictionary. 
  • getScriptingMenuNamingShortKey(data)
    Set a scripting menu names and shortkey dictionary. 
  • setScriptingMenuNamingShortKeyForPath(path, preferredName, shortkey=None)
    Set the scripting menu names and shortkey dictionary. 
  • exportPreferences(path)
    Export all user preferences to a path. 
  • importPreferences(path)
    Import user preferences from a path. 

mojo.tools

from mojo.tools import IntersectGlyphWithLine
  • IntersectGlyphWithLine(glyph, ((sx, sy), (ex, ey)), canHaveComponent=False, addSideBearings=False)
    Returns a list of intersections of a glyph with a given line. 
  • union(glyph, subjectContours, clipContours, roundCoordinates=None)
    perform a union with subject contours and clip contours
    glyph: destination glyph
    subjectContours, clipContours: for union its not really important so you can mix both
    roundCoordinates: optionally round the result
  • intersect(glyph, subjectContours, clipContours, roundCoordinates=None)
    perform a intersection with subject contours and clip contours
    glyph: destination glyph
    subjectContours: the subject contours
    clipContours
    : the clip contours that will intersect with the subject contours
    roundCoordinates: optionally round the result
  • difference(glyph, subjectContours, clipContours, roundCoordinates=None)
    perform a difference with subject contours and clip contours
    glyph: destination glyph
    subjectContours: the subject contours
    clipContours: the clip contours that will difference with the subject contours
    roundCoordinates: optionally round the result
  • intersection(glyph, subjectContours, clipContours, roundCoordinates=None)
    perform a intersection with subject contours and clip contours
    glyph: destination glyph
    subjectContours: the subject contours
    clipContours: the clip contours that will intersection with the subject contours
    roundCoordinates: optionally round the result
  • xor(glyph, subjectContours, clipContours, roundCoordinates=None)
    perform a xor with subject contours and clip contours
    glyph: destination glyph
    subjectContours: the subject contours
    clipContours: the clip contours that will xor with the subject contours
    roundCoordinates: optionally round the result

Classes

  • BooleanGlyph(glyph, roundCoordinates=None)
    A object that can be used to perform simple math operations and acts like a glyph object. 
    union ⇢ BooleanGlyph(glyph) | BooleanGlyph(glyph2)
    difference ⇢ BooleanGlyph(glyph) - BooleanGlyph(glyph2)
    intersection ⇢ BooleanGlyph(glyph) & BooleanGlyph(glyph2)
    xor ⇢ BooleanGlyph(glyph) ^ BooleanGlyph(glyph2)
     
    Initiate a BooleanGlyph object
    glyph: the source glyph
    roundCoordinates: optionally round the result
     
    draw(pen)
    draws the booleanGlyph in a pen
    drawPoints(pointPen)
    draws the booleanGlyph in a pointPen
    union(other)
    performs an union operation
    difference(other)
    performs a difference operation
    intersection(other)
    performs a intersection operation
    xor(other)
    performs a xor operation
     
    width
    returns the width of the booleanGlyph

mojo.roboFont

from mojo.roboFont import *

Methods

  • AllFonts()
    returns a list of all open font objects, the list as some additional methods
    getFontsByStyleName(styleName)
    returns all fonts with the given styleName
    getFontsByFamilyName(familyName)
    returns all fonts with the given familyName
    getFontsByFamilyNameStyleName(familyName, styleName)
    returns the font with the given familyName and styleName 
  • CurrentFont()
    returns the current font, will be None if no font is opened
  • CurrentGlyph()
    returns the current glyph
  • NewFont(familyName=None, styleName=None, showUI=True)
    Creates a new font with the given familyName and styleName
    optionally you can create a new font without having a UI, this is much faster to do internal actions. 
  • OpenFont(path, showUI=True)
    opens a UFO with a given path
    optionally you can create a new font without having a UI, this is much faster to do internal actions. 
  • RFont(path=None, showUI=True)
    creates a new font with the given path
    optionally you can create a new font without having a UI, this is much faster to do internal actions.  
  • RGlyph()
  • RContour()
  • RInfo()
  • RAnchor()
  • RGroups()
  • RFeatures()
  • RComponent()
  • RKerning()
  • OpenWindow(controller, *args, **kwargs)
    opens a window from the controller objects with args, and kwargs
    use this if you want RoboFont to deal with already opened versions of your window controller 
  • CreateCursor(path, hotSpot=(4, 4))
    creates a cursor object for image path with the given hotSpot 

 Attributes

  • version
    Returns the version of RoboFont 

mojo.glyphPreview

from mojo.glyphPreview import GlyphPreview

A vanilla group subclass that previews a glyph.

  • GlyphPreview(posSize, contourColor=None, componentColor=None, selectionColor=None)

    posSize: tuple of 4 (left, top, right, bottom), those numbers can be negative
    contourColor: a NSColor object used to draw the contours, optionally
    componentColor: a NSColor object used to draw the components, optionally
    selectionColor: a NSColor object used to draw the selection
     
    setGlyph(glyph)
    set a glyph in the preview
    setSelection(points)
    sets a list of points to display

Example

from vanilla import Window
from mojo.glyphPreview import GlyphPreview
from mojo.events import addObserver, removeObserver
from mojo.roboFont import OpenWindow

class Preview:

    def __init__(self):
        ## create a window
        self.w = Window((400, 400), "Preview", minSize=(100, 100))

        ## add a GlyphPreview to the window
        self.w.preview = GlyphPreview((0, 0, -0, -0))

        ## set the currentGlyph
        self.setGlyph(CurrentGlyph())

        ## add an observer when the glyph changed in the glyph view
        addObserver(self, "_currentGlyphChanged", "currentGlyphChanged")
    
        ## bind a windows close callback to this object
        self.w.bind("close", self.windowClose)
        ## open the window
        self.w.open()

    def _currentGlyphChanged(self, info):
        ## notification callback when the glyph changed in the glyph view
        ## just set the new glyph in the glyph preview
        self.setGlyph(CurrentGlyph())

    def setGlyph(self, glyph):
        ## setting the glyph in the glyph Preview
        self.w.preview.setGlyph(glyph)

    def windowClose(self, sender):
        ## remove the observer if the window closes
        removeObserver(self, "_currentGlyphChanged")


## open the window with OpenWindow, so it can not be open twice
OpenWindow(Preview)

mojo.events

from mojo.events import *

Imports useful helpers when building extensions and scripts requiring app event callbacks.

When subclassing or building tools on top of other tools you can find some embedded tools here

  • installTool(tool)
    install tool
  • uninstallTool(tool)
    uninstall tool 
  • addObserver(observer, method, event)
    Add an observer for a specified event, callbacks will be send to the method of the observer.
  • removeObserver(observer, event)
    Removes an observer for a specific event.
  • BaseEventObserver
    The base class of an observer. 
  • BaseEventTool
    The base class of an Tool 
  • EditingTool
    A subclass-able EditingTool 
  • MeasurementTool
    A subclass-able MeasurementTool 
  • SliceTool
    A subclass-able SliceTool 
  • BezierDrawingTool
    A subclass-able BezierDrawingTool 

mojo.drawingTools

from mojo.drawingTools import *

Using similar tools to draw in Cocoa object like DrawBot. (see TinyDrawBot extension)

  • save()
    save the current graphic state 
  • restore()
    restore the current graphic state 
  • rect(x, y, width, height)
    draws a rectangle 
  • oval(x, y, width, height)
    draws an oval 
  • newPath()
    creates a new path 
  • moveTo((x, y))
    move to point
  • lineTo((x, y))
    line to point
  • curveTo((h1x, h1y), (h2x, h2y), (x, y))
    curve to point with bcps
  • closePath()
    close the path
  • drawPath()
    draws the path
  • fill(r, g, b, a=1)
    Set the fill color as RGB value.
  • stroke(r, g, b, a=1)
    Set the stroke color as RGB value.
  • strokeWidth(value)
    Set the stroke width for a path.
  • miterLimit(value)
    Set the miter limit for a path.
  • lineJoin(join)
    Set the line join for a path, possible join arguments are: "bevel", "miter" or "round"
  • dashLine(dash)
    dash is a list of of values 
  • translate(x, y)
    Translate the art board pane to "x", "y" 
  • rotate(angle)
    Rotate the art board by an angle.
  • scale(x, y)
    Scale the art board by "x", "y", if "y" is not set the art board will be scaled proportionally.
  • skew(a, b)
    Skew the art board by "a", "b", if "b" is not set the art board will be skew with "a" = "b"
  • font(fontName, fontSize=None)
    Set the font by PostScript name.
    Optionally set the font size. 
  • fontSize(fontSize)
    Set the font size.
  • text(textString, (x, y))
    Draw a text on position "x", "y".
  • image(filePath, (x, y), alpha=1)
    Draw an image on position "x", "y".
    Optionally set an alpha value.

Object browser

A developer helper tool to find out what is inside an object, module, class and find out how to use it.

import vanilla
import mojo

"""
Example usage of the vanilla objectBrowser.
"""


class ObjectBrowserController():

        def __init__(self, inspectObject):

            if inspectObject is None:
                raise TypeError, "can not inspect None value"

            self.w = vanilla.Window((400, 400),
                                   "inspect %s" %inspectObject,
                                   minSize=(100, 100))
            self.w.b = vanilla.ObjectBrowser((0, 0, -0, -0),
                                   inspectObject)
            self.w.open()


#obj = vanilla
#obj = mojo
obj = CurrentFont()

ObjectBrowserController(obj)

Drawing and AddObserver Example

from mojo.drawingTools import *
from mojo.events import addObserver

class DrawTest:
    def __init__(self):
        ## add an observer for the draw event
        addObserver(self, "drawSomething", "draw")

    def drawSomething(self, info):
        ## draw something the glyph view
        rect(100, 100, 100, 100)

DrawTest()
import vanilla
from defconAppKit.windows.baseWindow import BaseWindowController

from mojo.events import addObserver, removeObserver
from mojo.drawingTools import *

class SimpleWindowObserver(BaseWindowController):
    
    def __init__(self):
        # create a window        
        self.w = vanilla.Window((300, 45), "Simple Observer")
        # add a button with a title and a callback
        self.w.startStopButton = vanilla.Button((10, 10, -10, 22), "Start", callback=self.startStopButtonCallback)
        # setup basic windwo behavoir (this is an method from the BaseWindowController)
        self.setUpBaseWindowBehavior()
        # open the window
        self.w.open()
    
    
    def startStopButtonCallback(self, sender):
        # button callback, check the title
        if sender.getTitle() == "Start":
            # set "Stop" as title for the button
            sender.setTitle("Stop")
            # add an observer
            addObserver(self, "draw", "draw")
        else:
            # set "Start" as title for the button
            sender.setTitle("Start")
            # remove the observser
            removeObserver(self, "draw")            
    
    def draw(self, notification):
        # get the glyph
        glyph = notification["glyph"]
        # save the state of the canvas
        save()
        # translate the canvase
        translate(glyph.width * 2, 0)
        # scale (flip) the canvas
        scale(-1, 1)
        # set a fill color
        fill(0)
        # draw the glyph
        drawGlyph(glyph)
        # restore the canvas
        restore()
        
    def windowCloseCallback(self, sender):
        # this receives a notification whenever the window is closed
        # remove the observer
        removeObserver(self, "draw")
        # and send the notification to the super
        super(SimpleWindowObserver, self).windowCloseCallback(sender)
    
SimpleWindowObserver()
    


Shapes Tool

An example of subclassing the BaseEventTool (see custom tools)

This is used in the Shapes Tool Extensions.

from mojo.events import BaseEventTool, installTool
from AppKit import *
import os

from lib.tools.drawing import strokePixelPath

from dialogKit import ModalDialog, TextBox, EditText, PopUpButton
from vanilla import RadioGroup

from robofab.pens.reverseContourPointPen import ReverseContourPointPen

from mojo.extensions import ExtensionBundle


## collecting the image data for building cursors and toolbar icons

shapeBundle = ExtensionBundle("ShapeTool")
_cursorOval = CreateCursor(shapeBundle.get("cursorOval"), hotSpot=(6, 6))

_cursorRect = CreateCursor(shapeBundle.get("cursorRect"), hotSpot=(6, 6))

toolbarIcon = shapeBundle.get("toolbarIcon")


class GeometricShapesWindow(object):
    """
    The Modal window that allows numbers input to draw basic geometric shapes.
    """

    def __init__(self, glyph, callback, x, y):
        self.glyph = glyph
        self.callback = callback
        ## create the modal dialog (from dialogKit)
        self.w = ModalDialog((200, 150),
                            "Shapes Tool",
                            okCallback=self.okCallback,
                            cancelCallback=self.cancelCallback)

        ## add some text boxes
        self.w.xText = TextBox((10, 13, 100, 22), "x")
        self.w.yText = TextBox((10, 43, 100, 22), "y")
        self.w.wText = TextBox((100, 13, 100, 22), "w")
        self.w.hText = TextBox((100, 43, 100, 22), "h")

        ## adding input boxes
        self.w.xInput = EditText((30, 10, 50, 22), "%i" %x)
        self.w.yInput = EditText((30, 40, 50, 22), "%i" %y)
        self.w.wInput = EditText((120, 10, 50, 22))
        self.w.hInput = EditText((120, 40, 50, 22))

        ## a radio shape choice group
        ## (the RadioGroup isn't standaard in dialogKit, this is a vanilla object)
        self.shapes = ["rect", "oval"]
        self.w.shape = RadioGroup((10, 70, -10, 22), self.shapes, isVertical=False)
        self.w.shape.set(0)

        self.w.open()

    def okCallback(self, sender):
        ## draw the shape in the glyph
        ## get the shape from the radio group
        shape = self.shapes[self.w.shape.get()]
        ## try to get some integers from the input fields
        try:
            x = int(self.w.xInput.get())
            y = int(self.w.yInput.get())
            w = int(self.w.wInput.get())
            h = int(self.w.hInput.get())
        ## if this fails just do nothing and print a tiny traceback
        except:
            print "A number is required!"
            return
        ## draw the shape with the callback given on init
        self.callback(shape, (x, y, w, h), self.glyph)

    def cancelCallback(self, sender):
        ## do nothing :)
        pass

def _roundPoint(x, y):
    return int(round(x)), int(round(y))

class DrawGeometricShapesTool(BaseEventTool):

    def setup(self):
        ## setup is called when the tool gets active
        ## use this to initialize some attributes
        self.minPoint = None
        self.maxPoint = None
        self.shape = "rect"
        self.origin = "corner"
        self.moveShapeShift = None

    def getRect(self):
        ## return the rect between mouse down and mouse up
        x = self.minPoint.x
        y = self.minPoint.y
        w = self.maxPoint.x - self.minPoint.x
        h = self.maxPoint.y - self.minPoint.y

        ## handle the shift down and equalize width and height
        if self.shiftDown:
            sign = 1
            if abs(w) > abs(h):
                if h < 0:
                    sign = -1
                h = abs(w) * sign
            else:
                if w < 0:
                    sign = -1
                w = abs(h) * sign

        if self.origin == "center":
            ## if the orgin is centered substract the width and height
            x -= w
            y -= h
            w *= 2
            h *= 2

        ## optimize the retangle, so the width and height are always postive numbers
        if w < 0:
            w = abs(w)
            x -= w
        if h < 0:
            h = abs(h)
            y -= h

        return x, y, w, h

    def drawShapeWithRectInGlyph(self, shape, rect, glyph):
        ## draw the shape into the glyph
        ## tell the glyph something is going to happen (undo is going to be prepared)
        glyph.prepareUndo("Drawing Shapes")

        ## get the pen to draw with
        pen = glyph.getPointPen()
        if glyph.preferredSegmentType == "qcurve":
            pen = ReverseContourPointPen(pen)

        x, y, w, h = rect

        ## draw with the pen a rect in the glyph
        if shape == "rect":
            pen.beginPath()
            pen.addPoint(_roundPoint(x, y), "line")
            pen.addPoint(_roundPoint(x + w, y), "line")
            pen.addPoint(_roundPoint(x + w, y + h), "line")
            pen.addPoint(_roundPoint(x, y + h), "line")

            pen.endPath()

        ## draw with the pen an oval in the glyph
        elif shape == "oval":

            hw = w/2.
            hh = h/2.

            r = .55
            segmentType = glyph.preferredSegmentType
            if glyph.preferredSegmentType == "qcurve":
                r = .42

            pen.beginPath()
            pen.addPoint(_roundPoint(x + hw, y), segmentType, True)
            pen.addPoint(_roundPoint(x + hw + hw*r, y))
            pen.addPoint(_roundPoint(x + w, y + hh - hh*r))

            pen.addPoint(_roundPoint(x + w, y + hh), segmentType, True)
            pen.addPoint(_roundPoint(x + w, y + hh + hh*r))
            pen.addPoint(_roundPoint(x + hw + hw*r, y + h))

            pen.addPoint(_roundPoint(x + hw, y + h), segmentType, True)
            pen.addPoint(_roundPoint(x + hw - hw*r, y + h))
            pen.addPoint(_roundPoint(x, y + hh + hh*r))

            pen.addPoint(_roundPoint(x, y + hh), segmentType, True)
            pen.addPoint(_roundPoint(x, y + hh - hh*r))
            pen.addPoint(_roundPoint(x + hw - hw*r, y))

            pen.endPath()

        ## tell the glyph you are done with your actions so it can handle the undo properly
        glyph.performUndo()

    def mouseDown(self, point, clickCount):
        ## a mouse down, only save the mouse down point
        self.minPoint = point
        ## on double click pop up an modal dialog with inputs
        if clickCount == 2:
            ## create and open the modal dialog
            GeometricShapesWindow(self.getGlyph(),
                            callback=self.drawShapeWithRectInGlyph,
                            x=self.minPoint.x,
                            y=self.minPoint.y)

    def mouseDragged(self, point, delta):        
        ## record the draggin point
        self.maxPoint = point
        ## if shift the minPoint by the move shift
        if self.moveShapeShift:
            w, h = self.moveShapeShift
            self.minPoint.x = self.maxPoint.x - w
            self.minPoint.y = self.maxPoint.y - h

    def mouseUp(self, point):
        ## mouse up, if you have recorded the rect draw that into the glyph
        if self.minPoint and self.maxPoint:
            self.drawShapeWithRectInGlyph(self.shape, self.getRect(), self.getGlyph())
        ## reset the tool
        self.minPoint = None
        self.maxPoint = None

    def modifiersChanged(self):
        ## is been called when the modifiers changed (shift, alt, control, command)
        self.shape = "rect"
        self.origin = "corner"
        
        ## change the shape when option is down
        if self.optionDown:
            self.shape = "oval"
        ## change the origin when command is down
        if self.commandDown:
            self.origin = "center"
        ## record the current size of the shape and store it
        if self.controlDown and self.moveShapeShift is None and self.minPoint and self.maxPoint:
            w = self.maxPoint.x - self.minPoint.x
            h = self.maxPoint.y - self.minPoint.y
            self.moveShapeShift = w, h
        else:
            self.moveShapeShift = None
        ## refresh the current glyph view
        self.getNSView().refresh()

    def draw(self, scale):
        ## draw stuff in the current glyph view
        if self.isDragging() and self.minPoint and self.maxPoint:
            ## draw only during drag and when recorded some rect
            ## make the rect
            x, y, w, h = self.getRect()
            rect = NSMakeRect(x, y, w, h)
            ## set the color
            NSColor.redColor().set()

            if self.shape == "rect":
                ## create a rect path
                path = NSBezierPath.bezierPathWithRect_(rect)

            elif self.shape == "oval":
                ## create a oval path
                path = NSBezierPath.bezierPathWithOvalInRect_(rect)

            if self.origin == "center":
                ## draw a cross hair at the center point
                crossHairLength = 3 * scale
                ## get the center of the rectangle
                centerX = x + w * .5
                centerY = y + h * .5

                path.moveToPoint_((centerX, centerY - crossHairLength))
                path.lineToPoint_((centerX, centerY + crossHairLength))
                path.moveToPoint_((centerX - crossHairLength, centerY))
                path.lineToPoint_((centerX + crossHairLength, centerY))

            ## set the line width
            path.setLineWidth_(scale)
            ## draw without anti-alias
            strokePixelPath(path)

    def getDefaultCursor(self):
        ## returns the cursor
        if self.shape == "rect":
            return _cursorRect
        else:
            return _cursorOval

    def getToolbarIcon(self):
        ## return the toolbar icon
        return toolbarIcon

    def getToolbarTip(self):
        ## return the toolbar tool tip
        return "Shape Tool"

## install the tool!!
installTool(DrawGeometricShapesTool())


Simple move example

An extremely easy 'move-the-selected-glyph' window

from vanilla import *

class MoveGlyphWindow:
    def __init__(self, glyph):
        if glyph is None:
            print "There should be a glyph window selected!!"
            return
        self.glyph = glyph

        self.moveX = 0
        self.moveY = 0

        self.w = Window((200, 60), "Move %s" %self.glyph.name)

        self.w.hs = Slider((10, 10, -10, 22), value=0,
                                        maxValue=200,
                                        minValue=-200,
                                        callback=self.adjust)

        self.w.vs = Slider((10, 30, -10, 22), value=0,
                                        maxValue=200,
                                        minValue=-200,
                                        callback=self.adjust)

        self.w.open()

    def adjust(self, sender):
        hValue = self.w.hs.get()
        vValue = self.w.vs.get()

        x = self.moveX - hValue
        y = self.moveY - vValue

        self.moveX = hValue
        self.moveY = vValue

        self.glyph.move((x, y))

OpenWindow(MoveGlyphWindow, CurrentGlyph())

Extensions

RoboFont is highly customizable by installing extensions.

Mechanic

Mechanic from Jack Jennings is a RoboFont extension managing open sourced and githubbed extensions.

Download Mechanic

Mechanic code available on github.

Available Extensions:

Download All Available Extensions

Code is also available on github.

Third party extensions and scripts:

Installing Extensions

Double click the extension file :)

or install the extension in the preferences window.

Re-installing & De-installing Extensions

Double click the extension file and choose either re-install or de-install.

or re-install / de-install the extension in the preferences window.

Building Extensions

Create and build .roboFontExt files.

 

Plugin Name Name of the extension
Plugin Icon The file can have a custom icon, if set.
Version Version of the extension.
Developer Developer of the extension.
Developer's URL Developer URL of the extension.
HTML help root Root folder where the HTML help can be found. A index.html is required.
Resources root Root folder where all the resources can be found. Resources are all necessary files except Python files.
Script Root Root folder where all the necessary Python files can be found.

Launch during start up
A bool indicating if a script has to be run during start up of RoboFont.
Select a Python file from the list. This will be the Python file that will be executed during start up.

Add Script to main menu
Select which scripts will be added to the Extensions menu item. Additionally, a nice name and shortcut can be set for each Python file in the script root.

Requires RoboFont The minimum required versions of RoboFont.

Build

Build the extension in a given folder.

Import

Import an existing extension.

Clear

Empty all fields in the Extension Builder.

Close

Close the Extension Builder window.

Groups 2 Feature

A RoboFont Extension converting groups to feature syntax groups. RoboFont will not build groups atomically cause feature groups can be on several different levels.

Select some groups and copy paste the feature groups in to the feature editor. "Insert In Font" will add the selected groups at the top of the feature file.

Download

Outliner.roboFontExt

Code is available on git hub.

Extension file spec

RoboFont extensions are folders acting like files *.roboFontExt.

File Structure

info.plist

Info.plist is a XML property list. see A DTD is available.

key value
addToMenu list
a list of menu descriptions that should be added to the extension menu,
see menu item description 
required
developer string
name of the developer 
required
developerURL

string
site url of the developer
required

html integer
indicating it has a html folder. zero, 0 is False, one, 1 os True. 
index.html is required!
not required
launchAtStartUp

integer
indicating it should execute code during start up of RoboFont. zero, 0 is False, one, 1 os True. see mainScript
required

mainScript string
*.py filename path (relative to the lib folder) executed during start up of RoboFont.
can be an empty string.
required
name string
the name of the extensions. 
required
timeStamp float  
required
version string
version number of the extension 
required
requiresVersionMajor string
the required major number of RoboFont. To help extension builders which aren't supporting older versions of RoboFont. 
not required
requiresVersionMinor string
the required minor number of RoboFont. To help extension builders which aren't supporting older versions of RoboFont. 
not required

The info.plist can have custom keys if necessary for the extension. It is advised to use reverse domain name as keys (com.example.myExtension).

menu item description

Each menu item descriptions is a dictionary with the following keys

path string
*.py filename path (relative to the lib folder) this will be executed when the menu item is being clicked. 
required
preferredName string
the preferred name of the menu item, only be used during display of the menu item. 
required
shortKey

string or tuple

  • string: a single keystroke that can be attached to the menu item.
  • tuple: ( <modifierFlag> int, <keyStroke> string

can be an empty string
required

 

lib

A folder containing all the *.py script. If a developer prefers to send out only *.pyc files that should be possible but take note that the file should be made with python 2.7 (the build in python version)

This folder will be added to the sys.path so it can import all the other files and folders as modules.

html

An 'html' folder is not required. If such a folder is declared in the info.plist it should contain an 'index.html'. These is plain html that is rendered in the help window with WebKit.

Resources

Any additional file necessary for your extension. Commonly used for bitmap, *.png to build tool bar icons, cursors. Or additional compiled command-line tools.

Tutorials