Beispiel #1
0
 def test_setStartPoint(self):
     font = Font(getTestFontPath())
     contour = font["B"][0]
     start = [(point.segmentType, point.x, point.y) for point in contour]
     contour.setStartPoint(6)
     self.assertTrue(contour.dirty)
     contour.setStartPoint(6)
     end = [(point.segmentType, point.x, point.y) for point in contour]
     self.assertEqual(start, end)
     contour = font["A"][0]
     start = [(point.segmentType, point.x, point.y) for point in contour]
     contour.setStartPoint(2)
     contour.setStartPoint(2)
     end = [(point.segmentType, point.x, point.y) for point in contour]
     self.assertEqual(start, end)
     contour = font["B"][0]
     start = [(point.segmentType, point.x, point.y) for point in contour]
     contour.setStartPoint(3)
     contour.setStartPoint(9)
     end = [(point.segmentType, point.x, point.y) for point in contour]
     self.assertEqual(start, end)
Beispiel #2
0
 def test_save_ufoz(self):
     path = getTestFontPath()
     tmpdir = tempfile.mkdtemp()
     dest = os.path.join(tmpdir, "TestFont.ufoz")
     font = Font(path)
     try:
         self.assertFalse(os.path.exists(dest))
         self.assertEqual(font.path, path)
         font.save(dest, structure="zip")
         self.assertTrue(os.path.exists(dest))
         self.assertTrue(zipfile.is_zipfile(dest))
         self.assertEqual(font.path, dest)
         self.assertEqual(font.ufoFileStructure, UFOFileStructure.ZIP)
         fileNames = sorted([
             fs.path.basename(m.path)
             for m in UFOReader(dest).fs.glob("glyphs/*.glif")
         ])
         self.assertEqual(fileNames, ["A_.glif", "B_.glif", "C_.glif"])
     finally:
         font.close()
         shutil.rmtree(tmpdir)
 def test_read(self):
     path = getTestFontPath()
     font = Font(path)
     fileNames = [
         "com.typesupply.defcon.test.directory/file 1.txt",
         "com.typesupply.defcon.test.directory/sub directory/file 2.txt",
         "com.typesupply.defcon.test.file"
     ]
     for i, fileName in enumerate(sorted(font.data.fileNames)):
         if True in [j.startswith(".") for j in fileName.split(os.sep)]:
             continue
         self.assertEqual(fileName, fileNames[i])
     self.assertEqual(
         font.data["com.typesupply.defcon.test.directory/file 1.txt"],
         b"This is file 1.")
     self.assertEqual(
         font.data[
             "com.typesupply.defcon.test.directory/sub directory/file 2.txt"],
         b"This is file 2.")
     self.assertEqual(font.data["com.typesupply.defcon.test.file"],
                      b"This is a top level test file.")
Beispiel #4
0
    def test_testForExternalChanges_change_default_layer(self):
        for ufo in (u"TestExternalEditing.ufo", u"TestExternalEditing.ufoz"):
            path = getTestFontPath(ufo)
            path = makeTestFontCopy(path)

            fileSystem = openTestFontAsFileSystem(path)
            fs.copy.copy_dir(fileSystem, "glyphs", fileSystem, "glyphs.test")
            contents = [("foo", "glyphs"), ("test", "glyphs.test")]
            with fileSystem.open(u"layercontents.plist", "wb") as f:
                dump(contents, f)
            closeTestFontAsFileSystem(fileSystem, path)
            with Font(path) as font:
                fileSystem = openTestFontAsFileSystem(path)
                contents = [("foo", "glyphs.test"), ("test", "glyphs")]
                with fileSystem.open(u"layercontents.plist", "wb") as f:
                    dump(contents, f)
                closeTestFontAsFileSystem(fileSystem, path)
                with UFOReader(path) as reader:
                    self.assertEqual(font.layers.testForExternalChanges(reader),
                                     {"deleted": [], "added": [], "modified": {},
                                      "defaultLayer": True, "order": False})
            tearDownTestFontCopy(font.path)
Beispiel #5
0
    def get_family_name(self):
        """Ensure that all source files have the same family name"""
        names = set()
        for fp in self.config["sources"]:
            if fp.endswith("glyphs"):
                src = glyphsLib.GSFont(fp)
                names.add(src.familyName)
            elif fp.endswith("ufo"):
                src = Font(fp)
                names.add(src.info.familyName)
            elif fp.endswith("designspace"):
                ds = designspaceLib.DesignSpaceDocument.fromfile(
                    self.config["sources"][0])
                names.add(ds.sources[0].familyName)
            else:
                raise ValueError(f"{fp} not a supported source file!")

        if len(names) > 1:
            raise ValueError(
                f"Inconsistent family names in sources {names}. Set familyName in config instead"
            )
        return list(names)[0]
Beispiel #6
0
 def test_delitem_glyph_not_dirty(self):
     for ufo in (u"TestExternalEditing.ufo", u"TestExternalEditing.ufoz"):
         path = getTestFontPath(ufo)
         path = makeTestFontCopy(path)
         font = Font(path)
         font["A"]  # glyph = font["A"]
         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()
         self.assertFalse(os.path.exists(glyphPath))
         tearDownTestFontCopy(font.path)
Beispiel #7
0
def doTask(fonts):
    totalFonts = len(fonts)
    print "%d fonts found\n" % totalFonts
    i = 0

    for font in fonts:
        i += 1
        folderPath, fontFileName = os.path.split(
            os.path.realpath(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 '*******************************'
        print 'Kerning for %s...(%d/%d)' % (styleName, i, totalFonts)

        ufoFont = Font(fontFileName)
        WriteFeaturesKernFDK.KernDataClass(ufoFont, folderPath, minKern,
                                           writeTrimmed, writeSubtables)
Beispiel #8
0
    def test_reloadGroups(self):
        path = getTestFontPath(u"TestExternalEditing.ufo")
        font = Font(path)
        groups = font.groups

        path = os.path.join(font.path, "groups.plist")
        f = open(path, "r")
        t = f.read()
        f.close()
        t = t.replace("<key>TestGroup</key>", "<key>XXX</key>")
        f = open(path, "w")
        f.write(t)
        f.close()

        self.assertEqual(list(groups.keys()), ["TestGroup"])
        font.reloadGroups()
        self.assertEqual(list(groups.keys()), ["XXX"])

        t = t.replace("<key>XXX</key>", "<key>TestGroup</key>")
        f = open(path, "w")
        f.write(t)
        f.close()
Beispiel #9
0
    def test_reloadKerning(self):
        path = getTestFontPath(u"TestExternalEditing.ufo")
        font = Font(path)
        kerning = font.kerning

        path = os.path.join(font.path, "kerning.plist")
        f = open(path, "r")
        t = f.read()
        f.close()
        t = t.replace("<integer>-100</integer>", "<integer>-101</integer>")
        f = open(path, "w")
        f.write(t)
        f.close()

        self.assertEqual(list(kerning.items()), [(("A", "A"), -100)])
        font.reloadKerning()
        self.assertEqual(list(kerning.items()), [(("A", "A"), -101)])

        t = t.replace("<integer>-101</integer>", "<integer>-100</integer>")
        f = open(path, "w")
        f.write(t)
        f.close()
Beispiel #10
0
 def test_bottomMargin_set(self):
     font = Font(getTestFontPath())
     glyph = font["A"]
     glyph.bottomMargin = 100
     self.assertEqual(glyph.bottomMargin, 100)
     self.assertEqual(glyph.height, 600)
     self.assertEqual(glyph.verticalOrigin, 500)
     self.assertTrue(glyph.dirty)
     # now glyph.verticalOrigin is defined
     glyph.bottomMargin = 50
     self.assertEqual(glyph.bottomMargin, 50)
     self.assertEqual(glyph.height, 550)
     self.assertEqual(glyph.verticalOrigin, 500)
     self.assertTrue(glyph.dirty)
     # empty glyph
     glyph = font.newGlyph("D")
     glyph.dirty = False
     glyph.bottomMargin = 10
     self.assertIsNone(glyph.bottomMargin)
     self.assertEqual(glyph.height, 0)
     self.assertIsNone(glyph.verticalOrigin)
     self.assertFalse(glyph.dirty)
Beispiel #11
0
    def _determine_which_masters_to_generate(self, ds_path, master_list):
        """'ds_path' is the path to a designspace file.
           Returns a list of integers representing the indexes
           of the temp masters to generate.
        """
        # Make a set of the glyphsets of all the masters while collecting each
        # glyphset. Glyph order is ignored.
        all_gsets = set()
        each_gset = []
        for master in master_list:
            master_path = master.attrib['filename']
            ufo_path = os.path.join(os.path.dirname(ds_path), master_path)
            gset = set(Font(ufo_path).keys())
            all_gsets.update(gset)
            each_gset.append(gset)

        master_indexes = []
        for i, gset in enumerate(each_gset):
            if gset != all_gsets:
                master_indexes.append(i)

        return master_indexes
Beispiel #12
0
    def test_reloadInfo(self):
        path = getTestFontPath(u"TestExternalEditing.ufo")
        font = Font(path)
        info = font.info

        path = os.path.join(font.path, "fontinfo.plist")
        f = open(path, "r")
        t = f.read()
        f.close()
        t = t.replace("<integer>750</integer>", "<integer>751</integer>")
        f = open(path, "w")
        f.write(t)
        f.close()

        self.assertEqual(info.ascender, 750)
        font.reloadInfo()
        self.assertEqual(info.ascender, 751)

        t = t.replace("<integer>751</integer>", "<integer>750</integer>")
        f = open(path, "w")
        f.write(t)
        f.close()
Beispiel #13
0
    def test_skip_empty_feature(self):
        ufo = Font()
        glyph = ufo.newGlyph('a')
        glyph.appendAnchor(
            glyph.anchorClass(anchorDict={
                'name': 'top',
                'x': 100,
                'y': 200
            }))
        glyph = ufo.newGlyph('acutecomb')
        glyph.appendAnchor(
            glyph.anchorClass(anchorDict={
                'name': '_top',
                'x': 100,
                'y': 200
            }))

        writer = MarkFeatureWriter(ufo)
        fea = writer.write()

        self.assertIn("feature mark", fea)
        self.assertNotIn("feature mkmk", fea)
Beispiel #14
0
    def buildStatic(
            self,
            ufo,  # input UFO as filename string or defcon.Font object
            outputFilename,  # output filename string
            cff=True,  # true = makes CFF outlines. false = makes TTF outlines.
            **kwargs,  # passed along to ufo2ft.compile*()
    ):
        if isinstance(ufo, str):
            ufo = Font(ufo)

        # update version to actual, real version. Must come after any call to setFontInfo.
        updateFontVersion(ufo, dummy=False, isVF=False)

        # decompose some glyphs
        glyphNamesToDecompose = set()
        for g in ufo:
            directives = findGlyphDirectives(g.note)
            if 'decompose' in directives or (g.components and
                                             not composedGlyphIsTrivial(g)):
                glyphNamesToDecompose.add(g.name)
        self._decompose([ufo], glyphNamesToDecompose)

        compilerOptions = dict(
            useProductionNames=True,
            inplace=True,  # avoid extra copy
            removeOverlaps=True,
            overlapsBackend='pathops',  # use Skia's pathops
        )

        log.info("compiling %s -> %s (%s)", _LazyFontName(ufo), outputFilename,
                 "OTF/CFF-2" if cff else "TTF")

        if cff:
            font = ufo2ft.compileOTF(ufo, **compilerOptions)
        else:  # ttf
            font = ufo2ft.compileTTF(ufo, **compilerOptions)

        log.debug("writing %s", outputFilename)
        font.save(outputFilename)
Beispiel #15
0
    def test_clear(self):
        font = Font(getTestFontPath())
        glyph = font["A"]
        contour = glyph[0]
        anchor = glyph.anchors[0]
        glyph.clear()
        self.assertEqual(len(glyph), 0)
        self.assertEqual(len(glyph.anchors), 0)
        glyph = font["C"]
        component = glyph.components[0]
        glyph.clear()
        self.assertEqual(len(glyph.components), 0)
        glyph = font.layers["Layer 1"]["A"]
        guideline = glyph.guidelines[0]
        glyph.clear()
        self.assertEqual(len(glyph.guidelines), 0)

        self.assertEqual((contour.getParent(), component.getParent(),
                          anchor.getParent(), guideline.getParent()),
                         (None, None, None, None))
        self.assertEqual((contour.dispatcher, component.dispatcher,
                          anchor.dispatcher, guideline.dispatcher),
                         (None, None, None, None))
Beispiel #16
0
    def test__cleanupMissingGlyphs(self):
        groups = {
            "public.kern1.A": ["A", "Aacute", "Abreve", "Acircumflex"],
            "public.kern2.B": ["B", "D", "E", "F"],
        }
        ufo = Font()
        for glyphs in groups.values():
            for glyph in glyphs:
                ufo.newGlyph(glyph)
        ufo.groups.update(groups)
        del ufo["Abreve"]
        del ufo["D"]

        writer = KernFeatureWriter()
        writer.set_context(ufo)
        self.assertEquals(writer.context.groups, groups)

        writer._cleanupMissingGlyphs()
        self.assertEquals(
            writer.context.groups, {
                "public.kern1.A": ["A", "Aacute", "Acircumflex"],
                "public.kern2.B": ["B", "E", "F"]
            })
Beispiel #17
0
 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 = PrebuiltMarkFeatureWriter(ufo)
     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;')
Beispiel #18
0
    def test_only_write_one(self):
        ufo = Font()
        ufo.newGlyph('a').appendAnchor({'name': 'top', 'x': 100, 'y': 200})
        ufo.newGlyph('acutecomb').appendAnchor({
            'name': '_top',
            'x': 100,
            'y': 200
        })
        glyph = ufo.newGlyph('tildecomb')
        glyph.appendAnchor({'name': '_top', 'x': 100, 'y': 200})
        glyph.appendAnchor({'name': 'top', 'x': 100, 'y': 300})

        writer = MarkFeatureWriter()  # by default both mark + mkmk are built
        fea = writer.write(ufo)

        self.assertIn("feature mark", fea)
        self.assertIn("feature mkmk", fea)

        writer = MarkFeatureWriter(features=["mkmk"])  # only builds "mkmk"
        fea = writer.write(ufo)

        self.assertNotIn("feature mark", fea)
        self.assertIn("feature mkmk", fea)
Beispiel #19
0
 def test_testForExternalChanges_change_default_layer(self):
     path = getTestFontPath("TestExternalEditing.ufo")
     path = makeTestFontCopy(path)
     shutil.copytree(os.path.join(path, "glyphs"),
                     os.path.join(path, "glyphs.test"))
     contents = [("foo", "glyphs"), ("test", "glyphs.test")]
     with open(os.path.join(path, "layercontents.plist"), "wb") as f:
         dump(contents, f)
     font = Font(path)
     contents = [("test", "glyphs"), ("foo", "glyphs.test")]
     contents.reverse()
     with open(os.path.join(path, "layercontents.plist"), "wb") as f:
         dump(contents, f)
     reader = UFOReader(path)
     self.assertEqual(
         font.layers.testForExternalChanges(reader), {
             "deleted": [],
             "added": [],
             "modified": {},
             "defaultLayer": True,
             "order": False
         })
     tearDownTestFontCopy(font.path)
def doTask(fonts, startpath):
    totalFonts = len(fonts)
    print "%d fonts found\n" % totalFonts
    i = 0

    for font in fonts:
        i += 1
        folderPath, fontFileName = os.path.split(os.path.realpath(font))
        styleName = os.path.basename(folderPath)

        # Change current directory to the folder where the font is contained
        os.chdir(folderPath)
        exportMessage = 'Exporting mark files for %s...(%d/%d)' % (
            styleName, i, totalFonts)
        print '*' * len(exportMessage)
        print exportMessage

        ufoFont = Font(fontFileName)
        WriteFeaturesMarkFDK.MarkDataClass(ufoFont, folderPath, trimCasingTags,
                                           genMkmkFeature, writeClassesFile,
                                           indianScriptsFormat)
        # go back to the start
        os.chdir(startpath)
Beispiel #21
0
    def test_decomposeComponent(self):
        font = Font()

        font.newGlyph("baseGlyph")
        baseGlyph = font["baseGlyph"]
        pointPen = baseGlyph.getPointPen()
        pointPen.beginPath(identifier="contour1")
        pointPen.addPoint((0, 0), "move", identifier="point1")
        pointPen.addPoint((0, 100), "line")
        pointPen.addPoint((100, 100), "line")
        pointPen.addPoint((100, 0), "line")
        pointPen.addPoint((0, 0), "line")
        pointPen.endPath()

        font.newGlyph("referenceGlyph")
        referenceGlyph = font["referenceGlyph"]
        pointPen = referenceGlyph.getPointPen()
        pointPen.addComponent("baseGlyph", (1, 0, 0, 1, 0, 0))
        self.assertEqual(len(referenceGlyph.components), 1)
        self.assertEqual(len(referenceGlyph), 0)
        referenceGlyph.decomposeAllComponents()
        self.assertEqual(len(referenceGlyph.components), 0)
        self.assertEqual(len(referenceGlyph), 1)
        self.assertEqual(referenceGlyph[0].identifier, "contour1")
        self.assertEqual(referenceGlyph[0][0].identifier, "point1")

        pointPen.addComponent("baseGlyph", (1, 0, 0, 1, 100, 100))
        self.assertEqual(len(referenceGlyph.components), 1)
        self.assertEqual(len(referenceGlyph), 1)
        component = referenceGlyph.components[0]
        referenceGlyph.decomposeComponent(component)
        self.assertEqual(len(referenceGlyph.components), 0)
        self.assertEqual(len(referenceGlyph), 2)
        self.assertEqual(referenceGlyph[0].identifier, "contour1")
        self.assertEqual(referenceGlyph[0][0].identifier, "point1")
        referenceGlyph[1].identifier
        referenceGlyph[1][0].identifier
Beispiel #22
0
 def test_save_as(self):
     path = getTestFontPath()
     font = Font(path)
     saveAsPath = getTestFontCopyPath(path)
     font.save(saveAsPath)
     dataDirectory = os.path.join(saveAsPath, "data")
     self.assertTrue(os.path.exists(dataDirectory))
     self.assertTrue(
         os.path.exists(
             os.path.join(
                 dataDirectory,
                 os.path.join("com.typesupply.defcon.test.directory",
                              "file 1.txt"))))
     self.assertTrue(
         os.path.exists(
             os.path.join(
                 dataDirectory,
                 os.path.join("com.typesupply.defcon.test.directory",
                              "sub directory", "file 2.txt"))))
     self.assertTrue(
         os.path.exists(
             os.path.join(dataDirectory,
                          "com.typesupply.defcon.test.file")))
     tearDownTestFontCopy(saveAsPath)
Beispiel #23
0
 def test_topMargin_set(self):
     from defcon.test.testTools import getTestFontPath
     from defcon.objects.font import Font
     font = Font(getTestFontPath())
     glyph = font["A"]
     glyph.topMargin = 100
     self.assertEqual(glyph.topMargin, 100)
     self.assertEqual(glyph.height, 800)
     self.assertEqual(glyph.verticalOrigin, 800)
     self.assertTrue(glyph.dirty)
     # now glyph.verticalOrigin is defined
     glyph.topMargin = 50
     self.assertEqual(glyph.topMargin, 50)
     self.assertEqual(glyph.height, 750)
     self.assertEqual(glyph.verticalOrigin, 750)
     self.assertTrue(glyph.dirty)
     # empty glyph
     glyph = font.newGlyph("D")
     glyph.dirty = False
     glyph.topMargin = 10
     self.assertIsNone(glyph.topMargin)
     self.assertEqual(glyph.height, 0)
     self.assertIsNone(glyph.verticalOrigin)
     self.assertFalse(glyph.dirty)
Beispiel #24
0
    def test_reloadGlyphs(self):
        path = getTestFontPath(u"TestExternalEditing.ufo")
        font = Font(path)
        glyph = font["A"]

        path = os.path.join(font.path, "glyphs", "A_.glif")
        f = open(path, "r")
        t = f.read()
        f.close()
        t = t.replace('<advance width="700"/>', '<advance width="701"/>')
        f = open(path, "w")
        f.write(t)
        f.close()

        self.assertEqual(glyph.width, 700)
        self.assertEqual(len(glyph), 2)
        font.reloadGlyphs(["A"])
        self.assertEqual(glyph.width, 701)
        self.assertEqual(len(glyph), 2)

        t = t.replace('<advance width="701"/>', '<advance width="700"/>')
        f = open(path, "w")
        f.write(t)
        f.close()
Beispiel #25
0
    def test_reloadLib(self):
        path = getTestFontPath(u"TestExternalEditing.ufo")
        font = Font(path)
        lib = font.lib

        path = os.path.join(font.path, "lib.plist")
        f = open(path, "r")
        t = f.read()
        f.close()
        t = t.replace("<key>org.robofab.glyphOrder</key>",
                      "<key>org.robofab.glyphOrder.XXX</key>")
        f = open(path, "w")
        f.write(t)
        f.close()

        self.assertEqual(list(lib.keys()), ["org.robofab.glyphOrder"])
        font.reloadLib()
        self.assertEqual(list(lib.keys()), ["org.robofab.glyphOrder.XXX"])

        t = t.replace("<key>org.robofab.glyphOrder.XXX</key>",
                      "<key>org.robofab.glyphOrder</key>")
        f = open(path, "w")
        f.write(t)
        f.close()
def doTask(fonts):
    totalFonts = len(fonts)
    print "%d fonts found\n" % totalFonts
    i = 0

    for font in fonts:
        i += 1
        folderPath, fontFileName = os.path.split(
            os.path.realpath(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 '*******************************'
        print 'Exporting mark files for %s...(%d/%d)' % (styleName, i,
                                                         totalFonts)

        ufoFont = Font(fontFileName)
        WriteFeaturesMarkFDK.MarkDataClass(ufoFont, folderPath, trimCasingTags,
                                           genMkmkFeature, writeClassesFile,
                                           indianScriptsFormat)
Beispiel #27
0
    def test_beginSelfLayerSetNotificationObservation(self):
        font = Font()
        self.assertTrue(font.dispatcher.hasObserver(
            font, "LayerSet.Changed", font.layers))
        self.assertTrue(font.dispatcher.hasObserver(
            font, "LayerSet.LayerAdded", font.layers))
        self.assertTrue(font.dispatcher.hasObserver(
            font, "LayerSet.LayerWillBeDeleted", font.layers))

        font.layers.removeObserver(
            observer=self, notification="LayerSet.Changed")
        font.layers.removeObserver(
            observer=self, notification="LayerSet.LayerAdded")
        font.layers.removeObserver(
            observer=self, notification="LayerSet.LayerWillBeDeleted")
        font.layers.endSelfNotificationObservation()

        font.beginSelfLayerSetNotificationObservation()
        self.assertTrue(font.dispatcher.hasObserver(
            font, "LayerSet.Changed", font.layers))
        self.assertTrue(font.dispatcher.hasObserver(
            font, "LayerSet.LayerAdded", font.layers))
        self.assertTrue(font.dispatcher.hasObserver(
            font, "LayerSet.LayerWillBeDeleted", font.layers))
Beispiel #28
0
def main():
    argparser = ArgumentParser(
        description=
        'Generate info on name, unicodes and color mark for all glyphs')

    argparser.add_argument(
        '-ucd',
        dest='ucdFile',
        metavar='<file>',
        type=str,
        help='UnicodeData.txt file from http://www.unicode.org/')

    argparser.add_argument('fontPaths',
                           metavar='<ufofile>',
                           type=str,
                           nargs='+',
                           help='UFO fonts to update')

    args = argparser.parse_args()

    fontPaths = []
    for fontPath in args.fontPaths:
        fontPath = fontPath.rstrip('/ ')
        if 'regular' or 'Regular' in fontPath:
            fontPaths = [fontPath] + fontPaths
        else:
            fontPaths.append(fontPath)

    fonts = [Font(fontPath) for fontPath in args.fontPaths]

    ucd = {}
    if args.ucdFile:
        ucd = parseUnicodeDataFile(args.ucdFile)

    glyphs = []  # contains final glyph data printed as JSON
    visitedGlyphNames = set()

    for font in fonts:
        glyphorder = font.lib['public.glyphOrder']
        for name in glyphorder:
            if name in visitedGlyphNames:
                continue

            if name not in font:
                print(
                    "warning: %r in public.glyphOrder but doesn't exist in font"
                    % name,
                    file=sys.stderr)
                continue

            g = font[name]

            # color
            color = None
            if 'public.markColor' in g.lib:
                rgba = [
                    float(c.strip())
                    for c in g.lib['public.markColor'].strip().split(',')
                ]
                color = rgbaToCSSColor(*rgba)

            # mtime
            mtime = None
            if 'com.schriftgestaltung.Glyphs.lastChange' in g.lib:
                datetimestr = g.lib['com.schriftgestaltung.Glyphs.lastChange']
                mtime = localDateTimeToUTCStr(datetimestr)

            # name[, unicode[, unicodeName[, color]]]
            glyph = None
            ucs = g.unicodes
            if len(ucs):
                for uc in ucs:
                    ucName = unicodeName(ucd.get(uc))
                    if not ucName and uc >= 0xE000 and uc <= 0xF8FF:
                        ucName = '[private use %04X]' % uc

                    if color:
                        glyph = [name, uc, ucName, mtime, color]
                    elif mtime:
                        glyph = [name, uc, ucName, mtime]
                    elif ucName:
                        glyph = [name, uc, ucName]
                    else:
                        glyph = [name, uc]
            else:
                if color:
                    glyph = [name, None, None, mtime, color]
                elif mtime:
                    glyph = [name, None, None, mtime]
                else:
                    glyph = [name]

            glyphs.append(glyph)
            visitedGlyphNames.add(name)

    print('{"glyphs":[')
    prefix = '  '
    for g in glyphs:
        print(prefix + json.dumps(g))
        if prefix == '  ':
            prefix = ', '
    print(']}')
Beispiel #29
0
def getTestUFO():
    dirname = os.path.dirname(__file__)
    return Font(os.path.join(dirname, 'data', 'TestFont.ufo'))
Beispiel #30
0
 def setUp(self):
     self.ufo = Font()