def test_updateGlyphOrder_rename(self): font = Font(getTestFontPath()) self.assertEqual(font.glyphOrder, []) font.glyphOrder = sorted(font.keys()) self.assertEqual(font.glyphOrder, ["A", "B", "C"]) font.updateGlyphOrder(addedGlyph="new", removedGlyph="B") self.assertEqual(font.glyphOrder, ["A", "new", "C"])
def test_glyph_dispatcher_inserted(self): font = Font() font.newGlyph("A") glyph = font["A"] pen = glyph.getPointPen() pen.beginPath() pen.addPoint((0, 0), segmentType="line") pen.addPoint((0, 100), segmentType="line") pen.addPoint((100, 100), segmentType="line") pen.addPoint((100, 0), segmentType="line") pen.endPath() contour = glyph[0] component = Component() glyph.appendComponent(component) anchor = Anchor() glyph.appendAnchor(anchor) guideline = Guideline() glyph.appendGuideline(guideline) sourceGlyph = glyph newFont = Font() insertedGlyph = newFont.insertGlyph(sourceGlyph) contour = insertedGlyph[0] self.assertTrue(contour.getParent(), insertedGlyph) self.assertTrue(contour.dispatcher, newFont.dispatcher) component = insertedGlyph.components[0] self.assertTrue(component.getParent(), insertedGlyph) self.assertTrue(component.dispatcher, newFont.dispatcher) anchor = insertedGlyph.anchors[0] self.assertTrue(anchor.getParent(), insertedGlyph) self.assertTrue(anchor.dispatcher, newFont.dispatcher) guideline = insertedGlyph.guidelines[0] self.assertTrue(guideline.getParent(), insertedGlyph) self.assertTrue(guideline.dispatcher, newFont.dispatcher)
def test_removeGuideline(self): font = Font(getTestFontPath()) guideline1 = Guideline(guidelineDict={"x": 100}) guideline2 = Guideline(guidelineDict={"y": 200}) font.guidelines = [guideline1, guideline2] font.removeGuideline(guideline1) self.assertEqual(font.guidelines, [guideline2])
def main(): parser = argparse.ArgumentParser(description="Build Mada slanted fonts.") parser.add_argument("file", metavar="FILE", help="input font to process") parser.add_argument("outfile", metavar="FILE", help="output font to write") parser.add_argument("angle", metavar="FILE", help="slant angle", type=float) args = parser.parse_args() matrix = Identity.skew(math.radians(-args.angle)) font = Font(args.file) info = font.info if args.angle < 0: style = "Italic" else: style = "Slanted" info.styleName += " " + style info.italicAngle = info.postscriptSlantAngle = args.angle for glyph in font: for contour in glyph: for point in contour: point.x, point.y = matrix.transformPoint((point.x, point.y)) for anchor in glyph.anchors: anchor.x, anchor.y = matrix.transformPoint((anchor.x, anchor.y)) font.save(args.outfile)
def test_updateGlyphOrder_remove(self): font = Font(getTestFontPath()) self.assertEqual(font.glyphOrder, []) font.glyphOrder = ["test"] self.assertEqual(font.glyphOrder, ["test"]) font.updateGlyphOrder(removedGlyph="test") self.assertEqual(font.glyphOrder, [])
def compileDecompileCompareDumps(features, expectedDump): # make the font font = Font() font.info.unitsPerEm = 1000 font.info.ascender = 750 font.info.descender = -250 font.info.xHeight = 500 font.info.capHeight = 750 font.info.familyName = "Test" font.info.styleName = "Regular" glyphNames = [i for i in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"] for glyphName in glyphNames: font.newGlyph(glyphName) glyph = font[glyphName] glyph.unicode = AGL2UV.get(glyphName) font.features.text = features # compile to OTF handle, path = tempfile.mkstemp() compiler = OTFCompiler() errors = compiler.compile(font, path)["makeotf"] # extract the features try: tables = decompileBinaryToObject(path, compress=True) # print compiler errors except TTLibError: print errors # get rid of the temp file finally: os.remove(path) # dump writer = DumpWriter() tables["GSUB"].write(writer) dump = writer.dump() # compare compareDumps(expectedDump, dump)
def test_delitem_glyph_dirty(self): for ufo in (u"TestExternalEditing.ufo", u"TestExternalEditing.ufoz"): path = getTestFontPath(ufo) path = makeTestFontCopy(path) font = Font(path) glyph = font["A"] glyph.dirty = True fileSystem = openTestFontAsFileSystem(path) glyphPath = fs.path.join("glyphs", "A_.glif") fileSystem.remove(glyphPath) contentsPath = fs.path.join("glyphs", "contents.plist") with fileSystem.open(contentsPath, "rb") as f: plist = load(f) del plist["A"] with fileSystem.open(contentsPath, "wb") as f: dump(plist, f) closeTestFontAsFileSystem(fileSystem, path) r = font.testForExternalChanges() self.assertEqual(r["deletedGlyphs"], ["A"]) del font["A"] font.save() fileSystem = openTestFontAsFileSystem(path) self.assertFalse(fileSystem.exists(glyphPath)) closeTestFontAsFileSystem(fileSystem, path) tearDownTestFontCopy(font.path)
def run(): (options, args) = parseOptions() if len(args) >= 1: if os.path.exists(args[0]) and os.path.exists(options.inpath): ufoPath = args[0] else: print "File does not exist." # main business try: with open(options.inpath, "r") as groupsfile: groups = eval(groupsfile.read()) font = Font(ufoPath) for name, content in groups.items(): if name not in font.groups: font.groups[name] = content else: for g in content: if g not in font.groups[name]: font.groups[name].append(g) font.save() except: print "Errors during processing." else: print "Add -h for help"
def interpolate(ufos, master_dir, out_dir, instance_data, debug=False): """Create MutatorMath designspace and generate instances. Returns instance UFOs, or unused instance data if debug is True. """ from defcon import Font from mutatorMath.ufo import build designspace_path, instance_files = build_designspace( ufos, master_dir, out_dir, instance_data) print('>>> Building instances') for path, _ in instance_files: clean_ufo(path) build(designspace_path, outputUFOFormatVersion=3) instance_ufos = [] for path, data in instance_files: ufo = Font(path) set_custom_params(ufo, data=data) set_redundant_data(ufo) ufo.save() instance_ufos.append(ufo) if debug: return clear_data(instance_data) return instance_ufos
def injectOS2TableToUFO(otfPath, ufoPath): otfFont = ttLib.TTFont(otfPath) os2Table = otfFont['OS/2'] ufo = Font(ufoPath) print 'Injecting OS/2 table into %s ...' % ufoPath ufo.info.ascender = os2Table.sTypoAscender ufo.info.capHeight = os2Table.sCapHeight ufo.info.descender = os2Table.sTypoDescender ufo.info.xHeight = os2Table.sxHeight ufo.info.openTypeOS2VendorID = os2Table.achVendID ufo.info.openTypeOS2TypoAscender = os2Table.sTypoAscender ufo.info.openTypeOS2TypoDescender = os2Table.sTypoDescender ufo.info.openTypeOS2TypoLineGap = os2Table.sTypoLineGap ufo.info.openTypeOS2StrikeoutPosition = os2Table.yStrikeoutPosition ufo.info.openTypeOS2StrikeoutSize = os2Table.yStrikeoutSize ufo.info.openTypeOS2SubscriptXOffset = os2Table.ySubscriptXOffset ufo.info.openTypeOS2SubscriptXSize = os2Table.ySubscriptXSize ufo.info.openTypeOS2SubscriptYOffset = os2Table.ySubscriptYOffset ufo.info.openTypeOS2SubscriptYSize = os2Table.ySubscriptYSize ufo.info.openTypeOS2SuperscriptXOffset = os2Table.ySuperscriptXOffset ufo.info.openTypeOS2SuperscriptXSize = os2Table.ySuperscriptXSize ufo.info.openTypeOS2SuperscriptYOffset = os2Table.ySuperscriptYOffset ufo.info.openTypeOS2SuperscriptYSize = os2Table.ySuperscriptYSize ufo.save()
def test_guidelineIndex(self): font = Font(getTestFontPath()) guideline1 = Guideline(guidelineDict={"x": 100}) guideline2 = Guideline(guidelineDict={"y": 200}) font.guidelines = [guideline1, guideline2] self.assertEqual(font.guidelineIndex(guideline1), 0) self.assertEqual(font.guidelineIndex(guideline2), 1)
def test_glyph_dispatcher_new(self): font = Font() font.newGlyph("A") glyph = font["A"] pen = glyph.getPointPen() pen.beginPath() pen.addPoint((0, 0), segmentType="line") pen.addPoint((0, 100), segmentType="line") pen.addPoint((100, 100), segmentType="line") pen.addPoint((100, 0), segmentType="line") pen.endPath() contour = glyph[0] self.assertEqual(contour.getParent(), glyph) self.assertEqual(contour.dispatcher, font.dispatcher) component = Component() glyph.appendComponent(component) self.assertEqual(component.getParent(), glyph) self.assertEqual(component.dispatcher, font.dispatcher) anchor = Anchor() glyph.appendAnchor(anchor) self.assertEqual(anchor.getParent(), glyph) self.assertEqual(anchor.dispatcher, font.dispatcher) guideline = Guideline() glyph.appendGuideline(guideline) self.assertEqual(guideline.getParent(), glyph) self.assertEqual(guideline.dispatcher, font.dispatcher)
def test_newGlyph(self): font = Font(getTestFontPath()) glyph = font.newGlyph("NewGlyphTest") self.assertEqual(glyph.name, "NewGlyphTest") self.assertTrue(glyph.dirty) self.assertTrue(font.dirty) self.assertEqual(sorted(font.keys()), ["A", "B", "C", "NewGlyphTest"])
def test_insertGlyph(self): font = Font(getTestFontPath()) glyph = Glyph() glyph.name = "NewGlyphTest" self.assertEqual(sorted(font.keys()), ["A", "B", "C"]) font.insertGlyph(glyph) self.assertEqual(sorted(font.keys()), ["A", "B", "C", "NewGlyphTest"])
def separate(fontPath, unicodeScript, DELETE=False): """ Takes a font and removes any kerning that isn't either a group kern or a kern with a glyph from the specified unicode script category. See http://www.unicode.org/Public/6.1.0/ucd/Scripts.txt for a list of possible values for the script. By default the script will not actually delete anything, but will list what it would delete. Set DELETE to True if you want the script to delete pairs. If DELETE is set to True, the input UFO will be modified, use with caution. """ font = Font(fontPath) for pair, value in sorted(font.kerning.items()): if pair[0].startswith("@") or pair[1].startswith("@"): pass elif font.unicodeData.scriptForGlyphName(pair[0]) != unicodeScript and font.unicodeData.scriptForGlyphName(pair[1]) != unicodeScript: if DELETE: print str(pair) + " deleted" del font.kerning[pair] else: print str(pair) + " would be deleted" if DELETE: font.save() print "Saved UFO."
def test_path_set(self): path1 = getTestFontPath() font = Font(path1) path2 = getTestFontPath("setPathTest.ufo") shutil.copytree(path1, path2) font.path = path2 self.assertEqual(font.path, path2) shutil.rmtree(path2)
def test_rename_default_layer(self): # https://github.com/unified-font-object/ufoLib/issues/123 path = getTestFontCopyPath() font = Font() font.save(path) font.layers.defaultLayer.name = "somethingElse" font.save() self.assertEqual(Font(path).layers.defaultLayer.name, "somethingElse")
def test_clearGuidelines(self): font = Font(getTestFontPath()) guideline1 = Guideline(guidelineDict={"x": 100}) guideline2 = Guideline(guidelineDict={"y": 200}) font.guidelines = [guideline1, guideline2] self.assertEqual(font.guidelines, [guideline1, guideline2]) font.clearGuidelines() self.assertEqual(font.guidelines, [])
def testDummyFont(): from defcon import Font font = Font() for i, glyphName in enumerate(("a", "grave", "f", "i", "agrave")): font.newGlyph(glyphName) testDummyGlyph(font[glyphName], i) font[glyphName].width = 60 + 10 * i return font
def injectKerningToUFO(ufoPath, groups, kerning): ufo = Font(ufoPath) ufo.kerning.clear() ufo.groups.clear() print 'Injecting OTF groups and kerning into %s ...' % ufoPath ufo.groups.update(groups) ufo.kerning.update(kerning) ufo.save()
def test_bottomMargin_get(self): font = Font(getTestFontPath()) glyph = font["A"] self.assertEqual(glyph.bottomMargin, 0) glyph = font["B"] self.assertEqual(glyph.bottomMargin, 0) # empty glyph glyph = font.newGlyph("D") self.assertIsNone(glyph.bottomMargin)
def test_topMargin_get(self): from defcon.test.testTools import getTestFontPath from defcon.objects.font import Font font = Font(getTestFontPath()) glyph = font["A"] self.assertEqual(glyph.topMargin, -200) # empty glyph glyph = font.newGlyph("D") self.assertIsNone(glyph.topMargin)
def test_beginSelfGuidelineNotificationObservation(self): font = Font(getTestFontPath()) guideline = font.instantiateGuideline() guideline.font = font self.assertFalse(guideline.dispatcher.hasObserver( font, "Guideline.Changed", guideline)) font.beginSelfGuidelineNotificationObservation(guideline) self.assertTrue(guideline.dispatcher.hasObserver( font, "Guideline.Changed", guideline))
def test_save(self): path = makeTestFontCopy() font = Font(path) for glyph in font: glyph.dirty = True font.save() fileNames = glob.glob(os.path.join(path, 'glyphs', '*.glif')) fileNames = [os.path.basename(fileName) for fileName in fileNames] self.assertEqual(sorted(fileNames), ["A_.glif", "B_.glif", "C_.glif"])
def test_endSelfLayerSetNotificationObservation(self): font = Font() font.endSelfLayerSetNotificationObservation() self.assertFalse(font.dispatcher.hasObserver( font, "LayerSet.Changed", font.layers)) self.assertFalse(font.dispatcher.hasObserver( font, "LayerSet.LayerAdded", font.layers)) self.assertFalse(font.dispatcher.hasObserver( font, "LayerSet.LayerWillBeDeleted", font.layers))
def test_save_as(self): path = getTestFontPath() font = Font(path) saveAsPath = getTestFontCopyPath(path) font.save(saveAsPath) fileNames = glob.glob(os.path.join(saveAsPath, 'glyphs', '*.glif')) fileNames = [os.path.basename(fileName) for fileName in fileNames] self.assertEqual(sorted(fileNames), ["A_.glif", "B_.glif", "C_.glif"]) self.assertEqual(font.path, saveAsPath) tearDownTestFontCopy(saveAsPath)
def test_newLayer(self): font = Font(getTestFontPath()) layers = font.layers layer = font.newLayer("Test") self.assertTrue(layer.dirty) self.assertTrue(layers.dirty) self.assertTrue(font.dirty) self.assertEqual( layers.layerOrder, ["public.default", "public.background", "Layer 1", "Test"])
def test_save_same_path_different_structure(self): for ufo in ("TestFont.ufo", "TestFont.ufoz"): path = getTestFontPath(ufo) isZip = zipfile.is_zipfile(path) font = Font(path) with self.assertRaisesRegex( DefconError, "Can't save font in-place with a different structure" ): font.save(path, structure="package" if isZip else "zip")
def test_save_new_font_to_exsisting_directory(self): for ufo in ("TestFont.ufo", "TestFont.ufoz"): path = makeTestFontCopy(getTestFontPath(ufo)) try: self.assertTrue(os.path.exists(path)) font = Font() font.save(path) self.assertTrue(os.path.isdir(path)) finally: tearDownTestFontCopy(path)
def test_name_set(self): font = Font(getTestFontPath()) glyph = font["A"] glyph.name = "RenamedGlyph" self.assertEqual(glyph.name, "RenamedGlyph") self.assertEqual(sorted(font.keys()), ["B", "C", "RenamedGlyph"]) font = Font(getTestFontPath()) glyph = font["A"] glyph.name = "A" self.assertFalse(glyph.dirty)
def test_testExternalChanges_modify_in_memory_and_scan(self): path = makeTestFontCopy() font = Font(path) font.images["image 1.png"] = pngSignature + b"blah" reader = UFOReader(path) self.assertEqual(font.images.testForExternalChanges(reader), ([], [], [])) tearDownTestFontCopy()
def test_testExternalChanges_remove_on_disk_and_scan(self): path = makeTestFontCopy() font = Font(path) os.remove(os.path.join(path, "images", "image 1.png")) reader = UFOReader(path) self.assertEqual(font.images.testForExternalChanges(reader), ([], [], ["image 1.png"])) tearDownTestFontCopy()
def test_testExternalChanges_remove_in_memory_and_scan(self): path = makeTestFontCopy() font = Font(path) del font.images["image 1.png"] reader = UFOReader(path) self.assertEqual(font.images.testForExternalChanges(reader), ([], [], [])) tearDownTestFontCopy()
def test_removeSegment_last_segment(self): font = Font(getTestFontPath()) glyph = font["A"] contour = glyph[0] contour.removeSegment(len(contour.segments) - 1) self.assertEqual( [simpleSegment(segment) for segment in contour.segments], [[(700, 700, "line")], [(0, 700, "line")], [(700, 0, "line")]])
def test_clockwise_set(self): font = Font(getTestFontPath()) contour = font["A"][0] contour.clockwise = False self.assertFalse(contour.clockwise) contour._clockwiseCache = None contour.clockwise = True self.assertTrue(contour.clockwise)
def test_add_classes(self): ufo = Font() glyph = ufo.newGlyph('grave') glyph.appendAnchor(glyph.anchorClass( anchorDict={'name': '_top', 'x': 100, 'y': 200})) glyph = ufo.newGlyph('cedilla') glyph.appendAnchor(glyph.anchorClass( anchorDict={'name': '_bottom', 'x': 100, 'y': 0})) lines = [] writer = MarkFeatureWriter( ufo, anchorList=(('bottom', '_bottom'),), mkmkAnchorList=(), ligaAnchorList=((('top_1', 'top_2'), '_top'),)) writer._addClasses(lines, doMark=True, doMkmk=True) self.assertEqual( '\n'.join(lines).strip(), 'markClass cedilla <anchor 100 0> @MC_bottom;\n\n' 'markClass grave <anchor 100 200> @MC_top;')
def test_bounds(self): font = Font(getTestFontPath()) glyph = font["A"] self.assertEqual(glyph.bounds, (0, 0, 700, 700)) glyph = font["B"] self.assertEqual(glyph.bounds, (0, 0, 700, 700)) glyph = font["C"] self.assertEqual(glyph.bounds, (0.0, 0.0, 700.0, 700.0))
def test_delitem_glyph_not_dirty(self): path = makeTestFontCopy() font = Font(path) font["A"] # glyph = font["A"] glyphPath = os.path.join(path, "glyphs", "A_.glif") os.remove(glyphPath) contentsPath = os.path.join(path, "glyphs", "contents.plist") with open(contentsPath, "rb") as f: plist = load(f) del plist["A"] with open(contentsPath, "wb") as f: dump(plist, f) r = font.testForExternalChanges() self.assertEqual(r["deletedGlyphs"], ["A"]) del font["A"] font.save() self.assertFalse(os.path.exists(glyphPath))
def test_defaultLayer(self): font = Font(getTestFontPath()) layers = font.layers layer = layers.defaultLayer self.assertEqual(layer, layers["public.default"]) layer = layers["Layer 1"] layers.defaultLayer = layer self.assertEqual(layer, layers.defaultLayer)
def test_componentReferences(self): font = Font(getTestFontPath()) layer = font.layers["public.default"] self.assertEqual(sorted(layer.componentReferences.items()), [("A", set(["C"])), ("B", set(["C"]))]) layer["C"] self.assertEqual(sorted(layer.componentReferences.items()), [("A", set(["C"])), ("B", set(["C"]))])
def test_lib(self): font = Font(getTestFontPath()) layer = font.layers["Layer 1"] self.assertEqual(layer.lib, {"com.typesupply.defcon.test": "1 2 3"}) layer.lib.dirty = False layer.lib["blah"] = "abc" self.assertEqual(layer.lib["blah"], "abc") self.assertTrue(layer.lib.dirty)
def font(request): font = Font() for param in request.param["glyphs"]: glyph = font.newGlyph(param["name"]) glyph.width = param.get("width", 0) pen = glyph.getPen() for operator, operands in param.get("outline", []): getattr(pen, operator)(*operands) glyph = font.newGlyph(param["name"] + ".reversed") glyph.width = param.get("width", 0) pen = glyph.getPen() for operator, operands in param.get("outline", []): getattr(pen, operator)(*operands) for c in glyph: c.reverse() return font
def test_newGlyph(self): font = Font(getTestFontPath()) layer = font.layers["public.default"] layer.newGlyph("NewGlyphTest") glyph = layer["NewGlyphTest"] self.assertEqual(glyph.name, "NewGlyphTest") self.assertTrue(glyph.dirty) self.assertTrue(font.dirty) self.assertEqual(sorted(layer.keys()), ["A", "B", "C", "NewGlyphTest"])
def test_rightMargin_set(self): from defcon.test.testTools import getTestFontPath from defcon.objects.font import Font font = Font(getTestFontPath()) glyph = font["A"] glyph.rightMargin = 100 self.assertEqual(glyph.rightMargin, 100) self.assertEqual(glyph.width, 800) self.assertTrue(glyph.dirty)
def test_area(self): font = Font() baseGlyph = font.newGlyph("baseGlyph") pointPen = baseGlyph.getPointPen() pointPen.beginPath() pointPen.addPoint((0, 0), "move") pointPen.addPoint((0, 100), "line") pointPen.addPoint((100, 100), "line") pointPen.addPoint((100, 0), "line") pointPen.addPoint((0, 0), "line") pointPen.endPath() self.assertEqual(baseGlyph.area, 10000) componentGlyph = font.newGlyph("componentGlyph") pointPen = componentGlyph.getPointPen() pointPen.addComponent("baseGlyph", [1, 0, 0, 1, 0, 0]) self.assertEqual(componentGlyph.area, 10000)
def __init__(self, font, subsetFile): self.font = Font(font) self.subsetFile = subsetFile with open(self.subsetFile, 'r') as ssfile: rawData = ssfile.read() self.subsetGlyphList = [ line.split()[0] for line in rawData.splitlines() ]
def test_write(self): path = makeTestFontCopy() font = Font(path) font.data[ "com.typesupply.defcon.test.newdirectory/file.txt"] = b"hello." del font.data[ "com.typesupply.defcon.test.directory/sub directory/file 2.txt"] font.save() p = os.path.join(path, "data", "com.typesupply.defcon.test.newdirectory", "file.txt") self.assertTrue(os.path.exists(p)) with open(p, "r") as f: t = f.read() self.assertEqual(t, "hello.") p = os.path.join(path, "data", "com.typesupply.defcon.test.directory", "sub directory", "file 2.txt") self.assertFalse(os.path.exists(p)) tearDownTestFontCopy()
def test_open(self): font = Font(getTestFontPath("TestOpenContour.ufo")) glyph = font["A"] self.assertTrue(glyph[0].open) self.assertFalse(glyph[1].open) self.assertTrue(glyph[2].open) self.assertFalse(glyph[3].open) contour = Contour() self.assertTrue(contour.open)
def test_reverse(self): font = Font(getTestFontPath()) contour = font["A"][0] contour.reverse() self.assertEqual([(point.x, point.y) for point in contour._points], [(0, 0), (0, 700), (700, 700), (700, 0)]) contour.reverse() self.assertEqual([(point.x, point.y) for point in contour._points], [(0, 0), (700, 0), (700, 700), (0, 700)])
def test_testExternalChanges_remove_in_memory_and_scan(self): for ufo in (u"TestExternalEditing.ufo", u"TestExternalEditing.ufoz"): path = getTestFontPath(ufo) path = makeTestFontCopy(path) with Font(path) as font, UFOReader(path) as reader: del font.images["image 1.png"] self.assertEqual(font.images.testForExternalChanges(reader), ([], [], [])) tearDownTestFontCopy(font.path)
def test_layers(self): font = Font(getTestFontPath()) self.assertIsInstance(font.layers, LayerSet) self.assertEqual(font.layers.layerOrder, ["public.default", "public.background", "Layer 1"]) self.assertTrue(font.layers.hasObserver(font, "LayerSet.Changed")) self.assertTrue(font.layers.hasObserver(font, "LayerSet.LayerAdded")) self.assertTrue( font.layers.hasObserver(font, "LayerSet.LayerWillBeDeleted"))
def test_testForExternalChanges(self): for ufo in (u"TestExternalEditing.ufo", u"TestExternalEditing.ufoz"): path = getTestFontPath(ufo) path = makeTestFontCopy(path) with Font(path) as font, UFOReader(path) as reader: self.assertEqual(font.layers.testForExternalChanges(reader), {"deleted": [], "added": [], "modified": {}, "defaultLayer": False, "order": False}) tearDownTestFontCopy(font.path)
def test_testForExternalChanges(self): path = getTestFontPath("TestExternalEditing.ufo") path = makeTestFontCopy(path) font = Font(path) reader = UFOReader(path) self.assertEqual(font.layers.testForExternalChanges(reader), {"deleted": [], "added": [], "modified": {}, "defaultLayer": False, "order": False}) tearDownTestFontCopy(font.path)
def doTask(fonts): totalFonts = len(fonts) print "%d fonts found" % totalFonts i = 1 for font in fonts: folderPath, fontFileName = os.path.split( font ) # path to the folder where the font is contained and the font's file name styleName = os.path.basename( folderPath) # name of the folder where the font is contained # Change current directory to the folder where the font is contained os.chdir(folderPath) print '\n*******************************' print 'Processing %s...(%d/%d)' % (styleName, i, totalFonts) # Read UFO font ufoFont = Font(fontFileName) # Assemble OTF & PFA file names fileNameNoExtension, fileExtension = os.path.splitext(fontFileName) otfPath = fileNameNoExtension + '.otf' pfaPath = fileNameNoExtension + '.pfa' txtPath = fileNameNoExtension + '.txt' # Generate OTF font compiler = OutlineOTFCompiler( ufoFont, otfPath, glyphOrder=ufoFont.lib['public.glyphOrder']) compiler.compile() # Convert OTF to PFA using tx cmd = 'tx -t1 "%s" > "%s"' % (otfPath, pfaPath) popen = Popen(cmd, shell=True, stdout=PIPE) popenout, popenerr = popen.communicate() if popenout: print popenout if popenerr: print popenerr # Convert PFA to TXT using detype1 cmd = 'detype1 "%s" > "%s"' % (pfaPath, txtPath) popen = Popen(cmd, shell=True, stdout=PIPE) popenout, popenerr = popen.communicate() if popenout: print popenout if popenerr: print popenerr # Delete OTF & PFA fonts if os.path.exists(otfPath): os.remove(otfPath) if os.path.exists(pfaPath): os.remove(pfaPath) i += 1
def test_collect_fea_classes(self): text = '@MMK_L_v = [v w y];' expected = {'@MMK_L_v': ['v', 'w', 'y']} ufo = Font() ufo.features.text = text writer = KernFeatureWriter(ufo) writer._collectFeaClasses() self.assertEquals(writer.leftFeaClasses, expected)
def postProcessInstance(fontPath, options): dFont = Font(fontPath) clearCustomLibs(dFont) if options.no_round: # '-r/--no-round' option was used but certain values (glyph widths, # kerning values, font info values) still need to be rounded because # of how they are stored in the final OTF roundSelectedFontInfo(dFont.info) roundGlyphWidths(dFont) roundKerningValues(dFont) else: # ufoProcessor does not round kerning values nor postscriptBlueScale # when 'roundGeometry' = False roundPostscriptBlueScale(dFont.info) roundKerningValues(dFont) dFont.save()
def test_save_as(self): for ufo in (u"TestFont.ufo", u"TestFont.ufoz"): path = getTestFontPath(ufo) font = Font(path) origFileStructure = font.ufoFileStructure saveAsPath = getTestFontCopyPath(path) self.assertFalse(os.path.exists(saveAsPath)) font.save(saveAsPath) try: fileNames = sorted([ fs.path.basename(m.path) for m in UFOReader(saveAsPath).fs.glob("glyphs/*.glif") ]) self.assertEqual(fileNames, ["A_.glif", "B_.glif", "C_.glif"]) self.assertEqual(font.path, saveAsPath) self.assertEqual(origFileStructure, font.ufoFileStructure) finally: tearDownTestFontCopy(saveAsPath)
def test_insertGuideline(self): font = Font(getTestFontPath()) guideline1 = Guideline(guidelineDict={"x": 100}) font.insertGuideline(0, guideline1) self.assertEqual(font.guidelines, [{'x': 100}]) guideline2 = Guideline(guidelineDict={"y": 200}) font.insertGuideline(0, guideline2) self.assertEqual(font.guidelines, [{'y': 200}, {'x': 100}]) guideline3 = Guideline(guidelineDict={"y": 100}) font.insertGuideline(2, guideline3) self.assertEqual(font.guidelines, [{'y': 200}, {'x': 100}, {'y': 100}])
def test_save_ufo3z_as_ufo2(self): # https://github.com/robotools/defcon/issues/296 font = Font() font.layers.defaultLayer.name = "a-custom-layer-name" font.newLayer("a-new-layer") with tempfile.TemporaryDirectory() as root: path_ufo3 = os.path.join(root, "three.ufo") font.save(path_ufo3, formatVersion=3, structure="zip") font.close() path_ufo2 = os.path.join(root, "two.ufo") with Font(path_ufo3) as font_ufo2: font_ufo2.save(path_ufo2, formatVersion=2)