LGM 2013: ZeroMQ and Real Time Collaborative Font Design

LGM 2013: ZeroMQ and Real Time Collaborative Font Design

Dr. Ben Martin

Font design involves using at least two applications in unison, a font editor and a page layout application: to draw letters, and to read them. Real time collaboration features have been added to the libre font editor FontForge, and we now need corresponding features in libre graphics applications. This Interactivos workshop aims to address this need with two goals: to implement support in libre graphics applications for live fonts, and in addition, to draft a spec for the future of font collaboration.

Real time collaboration has been implemented for FontForge using the zeroMQ library. zmq was initially developed for financial service corporations who must share a lot of data to a lot of people very fast, such as in stock trading systems. It provides concurrency by passing information as messages rather than a true shared state. The current network protocol for sharing font data in FontForge could become more like an interchange file format, to open up the possibility for specialised font editor tools that are focused on only some particular aspects of type design.

For example, a program for kerning with a tactile UI does not need to understand anything about altering the shapes of glyphs, but can still be part of the process.

I dove into the network protocol that currently powers collaboration in FontForge, and set out my agenda for the Interactivos workshop.


Dave Crossland

April 11, 2013


  1. 1.

    ZeroMQ and Real Time Collaborative Font Design Dr. Ben Martin

    monkeyiq@users.sourceforge.org github.com/fontforge
  2. 2.
  3. 3.

    Ultimate Goals Jump in to see & help other designers

    Enable task specific tools Live previews in typesetting environments Session lifetime → freedom
  4. 4.

    How? • Currently assume low latency (local) network • Reuse

    undo/redo mechanism to distill change tracking messages • (De)serialize “undo” objects: – Push undo state Push undo state – perform XYZ – call collab code
  5. 5.

    Start Session • Start server process • Starting client sends

    whole SFD font file • Each client sends each change to server • Server sends each change to all clients (including the one that initiated the change)
  6. 6.

    Join Session • Connect to server • Load most recent

    SFD snapshot • Subscribe to new change • Request all prior changes in proper order • Apply each change to SFD snapshot in order
  7. 7.

    Call Collab Code • Previous state is “top” undo •

    Changes exist as program state in memory • Perform undo to make the changed state the top redo • Avoid screen redraw during undo • Send redo to server, and forget it (races!)
  8. 8.

    Call Collab Code • Server sends redo to all clients

    • Initiating client gets the redo, adds it to the redo stack, then performs the redo • (Its back into its original state) • Goal: Sync undo/redo stacks over all clients
  9. 9.

    How to handle menu/edit/undo? 1. U 5,4,3 R 7,8 2.

    Perform undo 3. U 4,3 R 7,8 → Send U instead of R 4. Msg back (5) 5. U 4,3 R 5,7,8 → call redo() 6. U 5,4,3 R 7,8 → same as 1! 7. U 4,3 R 5,7,8 → needs marker on 4 (avoid bistable hole)
  10. 10.

    What Works Today • Editing Glyphs – Point creation +

    movement (all tools) – Contour direction (counters) – Add shapes (Ellipses, Rectangles) – All transformations (Scale, Rotate, etc) • Editing Metrics – Side bearings
  11. 11.

    Challenges • Multiple undos per semantic action – Add chained

    undos so undo/redo works normally • Clicking glyph background is an action... – Add 'nothing changed' NOOP • Undo & Redo system doesn't cover every user action – Micro undos (eg, changes to the points in selection) • Sync undo/redo stacks in high latency networks • Message format is FontForge only (SFD syntax, not UFO) • SFD fragments distillation
  12. 12.

    SFD fragments distillation • Enable 2 elements changing without overwriting

    each other • O = Have old state (top undo) • N = Have current state (perform undo, so its the top redo) • Distill a “diff” between O + N • Changes with simple semantic definition but complex data representation – Change LBearing means affine transform of all SplineSets to shift them
  13. 13.

    Next • Moving Bezier Control Points – fixed, not yet

    pushed • Knife tool – partial working • Metrics – Widths
  14. 14.

    Next • Editing Lookups – Kerning – OpenType Features •

    Layers – Add, remove, rename, F/B, C/Q • Spiro mode
  15. 15.

    Add Collaboration to your App • Your app has undo/redo

    • ZeroMQ is straightforward – www.zeromq.org • Lets make real time collaboration common in ALL libre graphics applications