Просмотр исходного кода

Merge pull request #198 from google/generate-glyph

generateGlyph improvement
James Godfrey-Kittle 8 лет назад
Родитель
Сommit
f966fa6d24
3 измененных файлов с 69 добавлено и 85 удалено
  1. 21 24
      scripts/build-v2.py
  2. 20 23
      scripts/lib/fontbuild/Build.py
  3. 28 38
      scripts/lib/fontbuild/generateGlyph.py

+ 21 - 24
scripts/build-v2.py

@@ -35,8 +35,6 @@ rg = Master("%s/src/v2/Roboto_Regular.ufo" % BASEDIR)
 bd = Master("%s/src/v2/Roboto_Bold.ufo" % BASEDIR)
 th = Master("%s/src/v2/Roboto_Thin.ufo" % BASEDIR)
 
-# build condensed masters
-
 lessCondensed = (
     "plusminus bracketleft bracketright dieresis macron "
     "percent multiply degree at i j "
@@ -62,7 +60,6 @@ def condenseFont(font, scale=.8, stemWidth=185):
     # for g in [f[name] for name in LC]:
     for g in f:
         if len(g) > 0:
-            # print g.name
             if g.name in lessCondensed:
                 scale = xscale * 1.1
             if g.name in uncondensed:
@@ -80,38 +77,38 @@ def condenseFont(font, scale=.8, stemWidth=185):
     return f
 
 
-proj = FontProject(rg.font, BASEDIR, "res/roboto.cfg", th.ffont)
+proj = FontProject(rg.font, BASEDIR, "res/roboto.cfg")
 
-# FAMILYNAME = "Roboto 2 DRAFT"
-# FAMILYNAME = "Roboto2"
 FAMILYNAME = "Roboto"
 
 proj.buildOTF = True
 #proj.compatible = True
 
-proj.generateFont(th.font, "%s/Thin/Regular/Th"%FAMILYNAME)
-proj.generateFont(Mix([th, rg], 0.45), "%s/Light/Regular/Lt"%FAMILYNAME)
+proj.generateFont(th.font, "%s/Thin/Regular/Th" % FAMILYNAME)
+proj.generateFont(Mix([th, rg], 0.45), "%s/Light/Regular/Lt" % FAMILYNAME)
 proj.generateFont(Mix([th, rg], RPoint(0.90, 0.92)),
-                  "%s/Regular/Regular/Rg"%FAMILYNAME)
-proj.generateFont(Mix([rg, bd], 0.35), "%s/Medium/Regular/Lt"%FAMILYNAME)
+                  "%s/Regular/Regular/Rg" % FAMILYNAME)
+proj.generateFont(Mix([rg, bd], 0.35), "%s/Medium/Regular/Lt" % FAMILYNAME)
 proj.generateFont(Mix([rg, bd], RPoint(0.73, 0.73)),
-                  "%s/Bold/Bold/Rg"%FAMILYNAME)
+                  "%s/Bold/Bold/Rg" % FAMILYNAME)
 proj.generateFont(Mix([rg, bd], RPoint(1.125, 1.0)),
-                  "%s/Black/Regular/Bk"%FAMILYNAME)
+                  "%s/Black/Regular/Bk" % FAMILYNAME)
 
-proj.generateFont(th.font, "%s/Thin Italic/Italic/Th"%FAMILYNAME,
+proj.generateFont(th.font, "%s/Thin Italic/Italic/Th" % FAMILYNAME,
                   italic=True, stemWidth=80)
-proj.generateFont(Mix([th, rg], 0.45), "%s/Light Italic/Italic/Lt"%FAMILYNAME,
+proj.generateFont(Mix([th, rg], 0.45), "%s/Light Italic/Italic/Lt" % FAMILYNAME,
                   italic=True, stemWidth=120)
 proj.generateFont(Mix([th, rg], RPoint(0.90, 0.92)),
-                  "%s/Italic/Italic/Rg"%FAMILYNAME, italic=True, stemWidth=185)
-proj.generateFont(Mix([rg, bd], 0.35), "%s/Medium Italic/Italic/Lt"%FAMILYNAME,
+                  "%s/Italic/Italic/Rg" % FAMILYNAME,
+                  italic=True, stemWidth=185)
+proj.generateFont(Mix([rg, bd], 0.35),
+                  "%s/Medium Italic/Italic/Lt" % FAMILYNAME,
                   italic=True, stemWidth=230)
 proj.generateFont(Mix([rg, bd], RPoint(0.73, 0.73)),
-                  "%s/Bold Italic/Bold Italic/Rg"%FAMILYNAME,
+                  "%s/Bold Italic/Bold Italic/Rg" % FAMILYNAME,
                   italic=True, stemWidth=290)
 proj.generateFont(Mix([rg, bd], RPoint(1.125, 1.0)),
-                  "%s/Black Italic/Italic/Bk"%FAMILYNAME,
+                  "%s/Black Italic/Italic/Bk" % FAMILYNAME,
                   italic=True, stemWidth=290)
 
 # unfortunately some condensed forms (*.cn) of glyphs are not compatible with
@@ -123,23 +120,23 @@ cn1 = Master(rg.ffont.addDiff(thcn1.ffont, th.ffont))
 bdcn1 = Master(bd.ffont.addDiff(thcn1.ffont, th.ffont))
 
 proj.generateFont(Mix([thcn1, cn1], RPoint(0.45, 0.47)),
-                  "%s Condensed/Light/Regular/Lt"%FAMILYNAME,
+                  "%s Condensed/Light/Regular/Lt" % FAMILYNAME,
                   swapSuffixes=[".cn"])
 proj.generateFont(Mix([thcn1, cn1], RPoint(0.9, 0.92)),
-                  "%s Condensed/Regular/Regular/Rg"%FAMILYNAME,
+                  "%s Condensed/Regular/Regular/Rg" % FAMILYNAME,
                   swapSuffixes=[".cn"])
 proj.generateFont(Mix([cn1, bdcn1], RPoint(0.75, 0.75)),
-                  "%s Condensed/Bold/Bold/Rg"%FAMILYNAME,
+                  "%s Condensed/Bold/Bold/Rg" % FAMILYNAME,
                   swapSuffixes=[".cn"])
 
 proj.generateFont(Mix([thcn1, cn1], RPoint(0.45, 0.47)),
-                  "%s Condensed/Light Italic/Italic/Lt"%FAMILYNAME,
+                  "%s Condensed/Light Italic/Italic/Lt" % FAMILYNAME,
                   italic=True, swapSuffixes=[".cn"], stemWidth=120)
 proj.generateFont(Mix([thcn1, cn1], RPoint(0.9, 0.92)),
-                  "%s Condensed/Italic/Italic/Rg"%FAMILYNAME,
+                  "%s Condensed/Italic/Italic/Rg" % FAMILYNAME,
                   italic=True, swapSuffixes=[".cn"], stemWidth=185)
 proj.generateFont(Mix([cn1, bdcn1], RPoint(0.75, 0.75)),
-                  "%s Condensed/Bold Italic/Bold Italic/Rg"%FAMILYNAME,
+                  "%s Condensed/Bold Italic/Bold Italic/Rg" % FAMILYNAME,
                   italic=True, swapSuffixes=[".cn"], stemWidth=240)
 
 proj.generateTTFs()

+ 20 - 23
scripts/lib/fontbuild/Build.py

@@ -34,22 +34,22 @@ from fontbuild.mix import Mix,Master,narrowFLGlyph
 
 
 class FontProject:
-    
-    def __init__(self, basefont, basedir, configfile, thinfont = None):
+
+    def __init__(self, basefont, basedir, configfile):
         self.basefont = basefont
-        self.thinfont = thinfont
         self.basedir = basedir
         self.config = ConfigParser.RawConfigParser()
-        self.configfile = self.basedir+"/"+configfile
+        self.configfile = os.path.join(self.basedir, configfile)
         self.config.read(self.configfile)
 
-        diacriticList = self.openResource("diacriticfile", splitlines=True)
-        self.diacriticList = [line.strip() for line in diacriticList if not line.startswith("#")]
-        adobeGlyphList = self.openResource("agl_glyphlistfile", splitlines=True)
-        self.adobeGlyphList = dict([line.split(";") for line in adobeGlyphList if not line.startswith("#")])
-        self.glyphOrder = self.openResource("glyphorder", splitlines=True)
-        self.thinGlyphOrder = self.openResource(
-            "glyphorder_thin", splitlines=True)
+        self.diacriticList = [
+            line.strip() for line in self.openResource("diacriticfile")
+            if not line.startswith("#")]
+        self.adobeGlyphList = dict(
+            line.split(";") for line in self.openResource("agl_glyphlistfile")
+            if not line.startswith("#"))
+        self.glyphOrder = self.openResource("glyphorder")
+        self.thinGlyphOrder = self.openResource("glyphorder_thin")
 
         # map exceptional glyph names in Roboto to names in the AGL
         roboNames = (
@@ -64,18 +64,16 @@ class FontProject:
         self.lessItalic = self.config.get("glyphs","lessitalic").split()
         self.deleteList = self.config.get("glyphs","delete").split()
         self.noItalic = self.config.get("glyphs","noitalic").split()
-        
+
         self.buildOTF = False
         self.compatible = False
         self.generatedFonts = []
 
-    def openResource(self, name, splitlines=False):
+    def openResource(self, name):
         with open(os.path.join(
                 self.basedir, self.config.get("res", name))) as resourceFile:
             resource = resourceFile.read()
-        if splitlines:
-            return resource.splitlines()
-        return resource
+        return resource.splitlines()
 
     def generateOutputPath(self, font, ext):
         family = font.info.familyName.replace(" ", "")
@@ -84,9 +82,9 @@ class FontProject:
         if not os.path.exists(path):
             os.makedirs(path)
         return os.path.join(path, "%s-%s.%s" % (family, style, ext))
-    
+
     def generateFont(self, mix, names, italic=False, swapSuffixes=None, stemWidth=185):
-        
+
         n = names.split("/")
         log("---------------------\n%s %s\n----------------------" %(n[0],n[1]))
         log(">> Mixing masters")
@@ -106,7 +104,7 @@ class FontProject:
             for g in f:
                 i += 1
                 if i % 10 == 0: print g.name
-                
+
                 if g.name == "uniFFFD":
                     continue
 
@@ -116,8 +114,6 @@ class FontProject:
                     italicizeGlyph(f, g, 9, stemWidth=stemWidth)
                 elif False == (g.name in self.noItalic):
                     italicizeGlyph(f, g, 10, stemWidth=stemWidth)
-                #elif g.name != ".notdef":
-                #    italicizeGlyph(g, 10, stemWidth=stemWidth)
                 if g.width != 0:
                     g.width += 10
 
@@ -211,6 +207,7 @@ def transformGlyphMembers(g, m):
         s.Transform(m)
         #c.scale = s
 
+
 def swapContours(f,gName1,gName2):
     try:
         g1 = f[gName1]
@@ -240,7 +237,7 @@ def log(msg):
 def generateGlyphs(f, glyphNames, glyphList={}):
     log(">> Generating diacritics")
     glyphnames = [gname for gname in glyphNames if not gname.startswith("#") and gname != ""]
-    
+
     for glyphName in glyphNames:
         generateGlyph(f, glyphName, glyphList)
 
@@ -252,7 +249,7 @@ def cleanCurves(f):
     # log(">> Mitring sharp corners")
     # for g in f:
     #     mitreGlyph(g, 3., .7)
-    
+
     # log(">> Converting curves to quadratic")
     # for g in f:
     #     glyphCurvesToQuadratic(g)

+ 28 - 38
scripts/lib/fontbuild/generateGlyph.py

@@ -14,59 +14,53 @@
 
 
 import re
-from anchors import alignComponentsToAnchors
 from string import find
 
+from anchors import alignComponentsToAnchors, getAnchorByName
+
+
 def parseComposite(composite):
     c = composite.split("=")
     d = c[1].split("/")
     glyphName = d[0]
     if len(d) == 1:
-        offset = [0,0]
+        offset = [0, 0]
     else:
         offset = [int(i) for i in d[1].split(",")]
     accentString = c[0]
     accents = accentString.split("+")
     baseName = accents.pop(0)
-    accentNames = [i.split(":") for i in accents ]
+    accentNames = [i.split(":") for i in accents]
     return (glyphName, baseName, accentNames, offset)
 
 
 def copyMarkAnchors(f, g, srcname, width):
-    unicode_range = set(
-        range(0x0030, 0x02B0) + range(0x1E00, 0x1EFF) +
-        [0x430, 0x435, 0x440, 0x441, 0x445, 0x455, 0x456, 0x471])
-
     for anchor in f[srcname].anchors:
-        if "top_dd" == anchor.name:
-            g.appendAnchor(anchor.name, (anchor.x + width, anchor.y))
-        if "bottom_dd" == anchor.name:
-            g.appendAnchor(anchor.name, (anchor.x + width, anchor.y))
-        if "top0315" == anchor.name:
+        if anchor.name in ("top_dd", "bottom_dd", "top0315"):
             g.appendAnchor(anchor.name, (anchor.x + width, anchor.y))
 
         if ("top" == anchor.name and
-                (g.unicode in unicode_range or
-                 g.name.endswith((".ccmp", ".smcp", ".NAV"))) and
-                not any(a.name == "parent_top" for a in g.anchors)):
+            not any(a.name == "parent_top" for a in g.anchors)):
             g.appendAnchor("parent_top", anchor.position)
 
         if ("bottom" == anchor.name and
-                (g.unicode in unicode_range or g.name.endswith(".smcp")) and
-                not any(a.name == "bottom" for a in g.anchors)):
+            not any(a.name == "bottom" for a in g.anchors)):
             g.appendAnchor("bottom", anchor.position)
 
     if any(a.name == "top" for a in g.anchors):
         return
 
-    anchor_parent_top = next(
-        (a for a in g.anchors if a.name == "parent_top"), None)
+    anchor_parent_top = getAnchorByName(g, "parent_top")
     if anchor_parent_top is not None:
         g.appendAnchor("top", anchor_parent_top.position)
 
 
 def generateGlyph(f,gname,glyphList={}):
     glyphName, baseName, accentNames, offset = parseComposite(gname)
+    if f.has_key(glyphName):
+        print('Existing glyph "%s" found in font, ignoring composition rule '
+              '"%s"' % (glyphName, gname))
+        return
 
     if baseName.find("_") != -1:
         g = f.newGlyph(glyphName)
@@ -75,25 +69,21 @@ def generateGlyph(f,gname,glyphList={}):
             g.width += f[componentName].width
             setUnicodeValue(g, glyphList)
 
-    else: 
-        if not f.has_key(glyphName):
-            try:
-                f.compileGlyph(glyphName, baseName, accentNames)
-            except KeyError as e:
-                print ("KeyError raised for composition rule '%s', likely %s "
-                    "anchor not found in glyph '%s'" % (gname, e, baseName))
-                return
-            g = f[glyphName]
-            setUnicodeValue(g, glyphList)
-            copyMarkAnchors(f, g, baseName, offset[1] + offset[0])
-            if len(accentNames) > 0:
-                alignComponentsToAnchors(f, glyphName, baseName, accentNames)
-            if offset[0] != 0 or offset[1] != 0:
-                g.width += offset[1] + offset[0]
-                g.move((offset[0], 0), anchors=False)
-        else:
-            print ("Existing glyph '%s' found in font, ignoring composition "
-                "rule '%s'" % (glyphName, gname))
+    else:
+        try:
+            f.compileGlyph(glyphName, baseName, accentNames)
+        except KeyError as e:
+            print('KeyError raised for composition rule "%s", likely "%s" '
+                  'anchor not found in glyph "%s"' % (gname, e, baseName))
+            return
+        g = f[glyphName]
+        setUnicodeValue(g, glyphList)
+        copyMarkAnchors(f, g, baseName, offset[1] + offset[0])
+        if len(accentNames) > 0:
+            alignComponentsToAnchors(f, glyphName, baseName, accentNames)
+        if offset[0] != 0 or offset[1] != 0:
+            g.width += offset[1] + offset[0]
+            g.move((offset[0], 0), anchors=False)
 
 
 def setUnicodeValue(glyph, glyphList):