// UFOExport — write a UFO3 package from the current skeletons + axes. // Bakes weight/contrast/width/x-height/slant into the outlines; compile to // OTF/TTF with fontTools via bin/compile.sh. import Foundation import CoreGraphics enum UFOExport { static let order: [(name: String, ch: Character, uni: String)] = [ ("r", "r", "0072"), ("e", "e", "0065"), ("g", "g", "0067"), ("a", "a", "0061"), ("d", "d", "0064"), ("space", " ", "0020"), ] static func write(_ doc: Doc, to url: URL) throws { let fm = FileManager.default if fm.fileExists(atPath: url.path) { try fm.removeItem(at: url) } try fm.createDirectory(at: url, withIntermediateDirectories: true) let glyphsDir = url.appendingPathComponent("glyphs") try fm.createDirectory(at: glyphsDir, withIntermediateDirectories: true) try plist(metainfo).write(to: url.appendingPathComponent("metainfo.plist"), atomically: true, encoding: .utf8) try plist(fontinfo).write(to: url.appendingPathComponent("fontinfo.plist"), atomically: true, encoding: .utf8) try plist(layercontents).write(to: url.appendingPathComponent("layercontents.plist"), atomically: true, encoding: .utf8) var contents = "" for e in order { contents += " \(e.name)\n \(e.name).glif\n" } try plist("\n\(contents)").write(to: glyphsDir.appendingPathComponent("contents.plist"), atomically: true, encoding: .utf8) let ax = doc.axes let tanS = tan(ax.slant * .pi / 180) for e in order { guard let g = doc.glyphs[e.ch] else { continue } let advance = Int((g.advance * ax.width + ax.tracking).rounded()) var outline = "" for loop in Expander.contours(g, ax) { outline += " \n" for p in loop { let x = p.x * ax.width let y = p.y * ax.xHeight let sx = x + tanS * y outline += " \n" } outline += " \n" } let glif = """ \(outline) """ try glif.write(to: glyphsDir.appendingPathComponent("\(e.name).glif"), atomically: true, encoding: .utf8) } } private static func fmt(_ v: CGFloat) -> String { String(format: "%.1f", Double(v)) } private static func plist(_ body: String) -> String { "\n\n\n\(body)\n\n" } private static let metainfo = "\n creator\n computer.aesthetic.glyphwizard\n formatVersion\n 3\n" private static let layercontents = "\n \n public.default\n glyphs\n \n" private static let fontinfo = """ familyName Regarde styleName Regular unitsPerEm 1000 ascender 740 descender -210 capHeight 700 xHeight 520 """ }