summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJames Godfrey-Kittle <jamesgk@google.com>2015-04-27 17:40:58 -0700
committerJames Godfrey-Kittle <jamesgk19@gmail.com>2015-04-27 17:40:58 -0700
commit03caa4051360c9da77ae1208075526f5e24ee704 (patch)
tree9c3934a2a1fb8e91877a770ef347908583a6af9e /scripts
parent3153a554bf3686d51043b5c2631b1d1a8bcdc540 (diff)
parent727e3852355b8c00386d81138b41416b27c84bd1 (diff)
Merge pull request #9 from google/anchor-fix
Fix for dropped anchors
Diffstat (limited to 'scripts')
-rw-r--r--scripts/build-v2.py9
-rw-r--r--scripts/lib/fontbuild/kerning.py27
-rwxr-xr-xscripts/lib/fontbuild/markFeature.py6
-rw-r--r--scripts/lib/fontbuild/mix.py31
4 files changed, 53 insertions, 20 deletions
diff --git a/scripts/build-v2.py b/scripts/build-v2.py
index a861a76..58842d6 100644
--- a/scripts/build-v2.py
+++ b/scripts/build-v2.py
@@ -31,9 +31,12 @@ BASEDIR = os.path.abspath(
# Masters
-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)
+rg = Master("%s/src/v2/Roboto_Regular.ufo" % BASEDIR,
+ anchorPath="%s/res/anchors_regular.json" % BASEDIR)
+bd = Master("%s/src/v2/Roboto_Bold.ufo" % BASEDIR,
+ anchorPath="%s/res/anchors_bold.json" % BASEDIR)
+th = Master("%s/src/v2/Roboto_Thin.ufo" % BASEDIR,
+ anchorPath="%s/res/anchors_thin.json" % BASEDIR)
# build condensed masters
diff --git a/scripts/lib/fontbuild/kerning.py b/scripts/lib/fontbuild/kerning.py
index 816ca1d..302c330 100644
--- a/scripts/lib/fontbuild/kerning.py
+++ b/scripts/lib/fontbuild/kerning.py
@@ -29,6 +29,7 @@ class KernFeatureWriter(AbstractFeatureWriter):
self.kerning = font.kerning
self.leftClasses = []
self.rightClasses = []
+ self.classSizes = {}
def write(self, linesep="\n"):
"""Write kern feature."""
@@ -42,30 +43,30 @@ class KernFeatureWriter(AbstractFeatureWriter):
for rightName, rightContents in self.rightClasses:
rightKey = rightContents[0]
pair = leftKey, rightKey
- if not self.kerning.has_key(pair):
+ kerningVal = self.kerning[pair]
+ if kerningVal is None:
continue
- classPairKerning[leftName, rightName] = self.kerning[pair]
+ classPairKerning[leftName, rightName] = kerningVal
self.kerning.remove(pair)
# collect rules with left class and right glyph
- for pair, val in self.kerning.getLeft(leftKey):
- leftClassKerning[leftName, pair[1]] = self.kerning[pair]
+ for pair, kerningVal in self.kerning.getLeft(leftKey):
+ leftClassKerning[leftName, pair[1]] = kerningVal
self.kerning.remove(pair)
# collect rules with left glyph and right class
for rightName, rightContents in self.rightClasses:
rightKey = rightContents[0]
- for pair, val in self.kerning.getRight(rightKey):
- rightClassKerning[pair[0], rightName] = self.kerning[pair]
+ for pair, kerningVal in self.kerning.getRight(rightKey):
+ rightClassKerning[pair[0], rightName] = kerningVal
self.kerning.remove(pair)
# write the feature
+ self.ruleCount = 0
lines = ["feature kern {"]
lines.append(self._writeKerning(self.kerning, linesep))
lines.append(self._writeKerning(leftClassKerning, linesep, True))
- lines.append(" subtable;")
lines.append(self._writeKerning(rightClassKerning, linesep, True))
- lines.append(" subtable;")
lines.append(self._writeKerning(classPairKerning, linesep))
lines.append("} kern;")
return linesep.join(lines)
@@ -78,6 +79,15 @@ class KernFeatureWriter(AbstractFeatureWriter):
pairs = kerning.items()
pairs.sort()
for (left, right), val in pairs:
+ if enum:
+ rulesAdded = (self.classSizes.get(left, 1) *
+ self.classSizes.get(right, 1))
+ else:
+ rulesAdded = 1
+ self.ruleCount += rulesAdded
+ if self.ruleCount > 2048:
+ lines.append(" subtable;")
+ self.ruleCount = rulesAdded
lines.append(" %spos %s %s %d;" % (enum, left, right, val))
return linesep.join(lines)
@@ -91,6 +101,7 @@ class KernFeatureWriter(AbstractFeatureWriter):
self.leftClasses.append(info)
elif name.endswith("_R"):
self.rightClasses.append(info)
+ self.classSizes[name] = len(contents)
def makeKernFeature(font, text):
diff --git a/scripts/lib/fontbuild/markFeature.py b/scripts/lib/fontbuild/markFeature.py
index 30da7c3..b617ef6 100755
--- a/scripts/lib/fontbuild/markFeature.py
+++ b/scripts/lib/fontbuild/markFeature.py
@@ -108,12 +108,6 @@ def GenerateFeature_mark(font):
classname = "@MC_" + anchor_name
accent_name_list = CreateAccNameList(font, acc_anchor_name, comb_accent_only)
- if not accent_name_list:
- print (
- 'No glyph found with anchor "%s", skipping mark lookup for %s.' %
- (acc_anchor_name, classname))
- continue
-
accent_mark_list = CreateAccGlyphList(font, accent_name_list, acc_anchor_name)
base_mark_list = CreateGlyphList(font, accent_name_list, anchor_name)
text += Create_mark_lookup(accent_mark_list, base_mark_list, lookupname, classname, expand_to_composits)
diff --git a/scripts/lib/fontbuild/mix.py b/scripts/lib/fontbuild/mix.py
index 70d2e3a..bd396ed 100644
--- a/scripts/lib/fontbuild/mix.py
+++ b/scripts/lib/fontbuild/mix.py
@@ -15,6 +15,7 @@
from numpy import array, append
import copy
+import json
from robofab.objects.objectsRF import RPoint
from robofab.world import OpenFont
from decomposeGlyph import decomposeGlyph
@@ -214,12 +215,13 @@ class FGlyph:
class Master:
- def __init__(self, font=None, v=0, kernlist=None, overlay=None):
+ def __init__(self, font=None, v=0, kernlist=None, overlay=None,
+ anchorPath=None):
if isinstance(font, FFont):
self.font = None
self.ffont = font
elif isinstance(font,str):
- self.openFont(font,overlay)
+ self.openFont(font,overlay, anchorPath)
elif isinstance(font,Mix):
self.font = font
else:
@@ -238,7 +240,7 @@ class Master:
and not k[0] == ""]
#TODO implement class based kerning / external kerning file
- def openFont(self, path, overlayPath=None):
+ def openFont(self, path, overlayPath=None, anchorPath=None):
self.font = OpenFont(path)
for g in self.font:
size = len(g)
@@ -252,6 +254,29 @@ class Master:
for overlayGlyph in overlayFont:
font.insertGlyph(overlayGlyph)
+ # work around a bug with vfb2ufo in which anchors are dropped from
+ # glyphs containing components and no contours. "anchorPath" should
+ # point to the output of src/v2/get_dropped_anchors.py
+ if anchorPath:
+ anchorData = json.load(open(anchorPath))
+ for glyphName, anchors in anchorData.items():
+
+ # another bug: some entire glyphs are dropped during conversion.
+ # example: gbar_uni1ABE
+ try:
+ glyph = self.font[glyphName]
+ except KeyError:
+ continue
+
+ # another bug: some glyphs are decomposed during conversion, in
+ # which case they unexpectedly don't drop anchors.
+ # examples: uni04BA, Gbar (partially decomposed)
+ if glyph.anchors:
+ continue
+
+ for name, (x, y) in anchors.items():
+ glyph.appendAnchor(str(name), (x, y))
+
self.ffont = FFont(self.font)