diff --git a/Lib/ufo2ft/filters/scaleUPM.py b/Lib/ufo2ft/filters/scaleUPM.py new file mode 100644 index 000000000..4d72f7959 --- /dev/null +++ b/Lib/ufo2ft/filters/scaleUPM.py @@ -0,0 +1,146 @@ +from ufo2ft.filters import BaseFilter + + +class ScaleUPMFilter(BaseFilter): + + """ This filter scales the font to a new upm value. Set the target upm in + an UFO like this: + com.github.googlei18n.ufo2ft.filters + + + name + scaleUPM + kwargs + + unitsPerEm + 2048 + + + + """ + + _kwargs = { + "unitsPerEm": 1000, + } + + def _scaleGlyph(self, glyph): + """ + Scale a glyph + """ + for contour in glyph: + for point in contour.points: + point.x *= self.factor + point.y *= self.factor + + for anchor in glyph.anchors: + anchor.x *= self.factor + anchor.y *= self.factor + + glyph.width *= self.factor + + def _scaleList(self, obj, name): + """ + Scale a font info property that is a list, i.e. scale each value. + """ + lst = getattr(obj, name) + if lst is None: + return + + lst = [self.factor * v for v in lst] + setattr(obj, name, lst) + + def _scaleProperty(self, obj, name): + prop = getattr(obj, name) + if prop is None: + return + + setattr(obj, name, self.factor * prop) + + def __call__(self, font, glyphSet=None): + newUnitsPerEm = int(self.options.unitsPerEm) + if font.info.unitsPerEm == newUnitsPerEm: + return False + + self.factor = newUnitsPerEm / font.info.unitsPerEm + + # Scale glyphs + super(ScaleUPMFilter, self).__call__(font, glyphSet) + + # Scale kerning + for pair, value in font.kerning.items(): + font.kerning[pair] = value * self.factor + + # TODO: Change positioning feature code + + # Scale info values + for prop in ( + "descender", + "xHeight", + "capHeight", + "ascender", + "openTypeHheaAscender", + "openTypeHheaDescender", + "openTypeHheaLineGap", + "openTypeHheaCaretOffset", + "openTypeOS2TypoAscender", + "openTypeOS2TypoDescender", + "openTypeOS2TypoLineGap", + "openTypeOS2WinAscent", + "openTypeOS2WinDescent", + "openTypeOS2SubscriptXSize", + "openTypeOS2SubscriptYSize", + "openTypeOS2SubscriptXOffset", + "openTypeOS2SubscriptYOffset", + "openTypeOS2SuperscriptXSize", + "openTypeOS2SuperscriptYSize", + "openTypeOS2SuperscriptXOffset", + "openTypeOS2SuperscriptYOffset", + "openTypeOS2StrikeoutSize", + "openTypeOS2StrikeoutPosition", + "openTypeVheaVertTypoAscender", + "openTypeVheaVertTypoDescender", + "openTypeVheaVertTypoLineGap", + "openTypeVheaCaretOffset", + "postscriptUnderlineThickness", + "postscriptUnderlinePosition", + ): + self._scaleProperty(font.info, prop) + + for prop in ( + "postscriptBlueValues", + "postscriptOtherBlues", + "postscriptFamilyOtherBlues", + "postscriptStemSnapH", + "postscriptStemSnapV", + "postscriptBlueFuzz", + "postscriptBlueShift", + "postscriptBlueScale", + "postscriptDefaultWidthX", + "postscriptNominalWidthX", + ): + self._scaleList(font.info, prop) + + # Finally set new UPM + font.info.unitsPerEm = newUnitsPerEm + + return True + + def filter(self, glyph): + if getattr(self.context, "skipCurrentFont", False): + return False + + # Scale glyph + self._scaleGlyph(glyph) + + # scale component offsets + for i in range(len(glyph.components)): + comp = glyph.components[i] + xS, xyS, yxS, yS, xOff, yOff = comp.transformation + comp.transformation = ( + xS, + xyS, + yxS, + yS, + xOff * self.factor, + yOff * self.factor, + ) diff --git a/tests/data/UnitsPerEmTest.ufo/features.fea b/tests/data/UnitsPerEmTest.ufo/features.fea new file mode 100644 index 000000000..3d953b3c6 --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/features.fea @@ -0,0 +1,7 @@ +# automatic +@Uppercase = [ A O ]; + +feature cpsp { +pos @Uppercase <10 0 20 0>; +} cpsp; + diff --git a/tests/data/UnitsPerEmTest.ufo/fontinfo.plist b/tests/data/UnitsPerEmTest.ufo/fontinfo.plist new file mode 100644 index 000000000..859fac1c3 --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/fontinfo.plist @@ -0,0 +1,64 @@ + + + + + ascender + 800 + capHeight + 720 + descender + -160 + openTypeHeadCreated + 2020/12/01 11:22:55 + openTypeHheaAscender + 800 + openTypeHheaDescender + -160 + openTypeHheaLineGap + 240 + openTypeOS2TypoAscender + 800 + openTypeOS2TypoDescender + -160 + openTypeOS2TypoLineGap + 240 + openTypeOS2WinAscent + 800 + openTypeOS2WinDescent + 200 + postscriptBlueValues + + -14.0 + 0.0 + 560.0 + 574.0 + 720.0 + 734.0 + 800.0 + 814.0 + + postscriptOtherBlues + + -176.0 + -160.0 + + postscriptStemSnapH + + 70.0 + + postscriptStemSnapV + + 80.0 + + styleName + Regular + unitsPerEm + 1000 + versionMajor + 2 + versionMinor + 0 + xHeight + 560 + + diff --git a/tests/data/UnitsPerEmTest.ufo/glyphs.public.background/A_.glif b/tests/data/UnitsPerEmTest.ufo/glyphs.public.background/A_.glif new file mode 100644 index 000000000..54dc77da6 --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/glyphs.public.background/A_.glif @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/UnitsPerEmTest.ufo/glyphs.public.background/contents.plist b/tests/data/UnitsPerEmTest.ufo/glyphs.public.background/contents.plist new file mode 100644 index 000000000..43097d5cd --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/glyphs.public.background/contents.plist @@ -0,0 +1,8 @@ + + + + + A + A_.glif + + diff --git a/tests/data/UnitsPerEmTest.ufo/glyphs/A_.glif b/tests/data/UnitsPerEmTest.ufo/glyphs/A_.glif new file mode 100644 index 000000000..6b8bc01e8 --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/glyphs/A_.glif @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/UnitsPerEmTest.ufo/glyphs/O_.glif b/tests/data/UnitsPerEmTest.ufo/glyphs/O_.glif new file mode 100644 index 000000000..4484e17ed --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/glyphs/O_.glif @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/UnitsPerEmTest.ufo/glyphs/contents.plist b/tests/data/UnitsPerEmTest.ufo/glyphs/contents.plist new file mode 100644 index 000000000..84eb2372d --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/glyphs/contents.plist @@ -0,0 +1,10 @@ + + + + + A + A_.glif + O + O_.glif + + diff --git a/tests/data/UnitsPerEmTest.ufo/kerning.plist b/tests/data/UnitsPerEmTest.ufo/kerning.plist new file mode 100644 index 000000000..810fe4447 --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/kerning.plist @@ -0,0 +1,16 @@ + + + + + A + + O + -25 + + O + + A + -25 + + + diff --git a/tests/data/UnitsPerEmTest.ufo/layercontents.plist b/tests/data/UnitsPerEmTest.ufo/layercontents.plist new file mode 100644 index 000000000..b1e911588 --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/layercontents.plist @@ -0,0 +1,14 @@ + + + + + + public.default + glyphs + + + public.background + glyphs.public.background + + + diff --git a/tests/data/UnitsPerEmTest.ufo/lib.plist b/tests/data/UnitsPerEmTest.ufo/lib.plist new file mode 100644 index 000000000..3e9ac461b --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/lib.plist @@ -0,0 +1,46 @@ + + + + + com.github.googlei18n.ufo2ft.filters + + + name + scaleUPM + kwargs + + unitsPerEm + 2048 + + + + com.schriftgestaltung.disablesAutomaticAlignment + + com.schriftgestaltung.fontMaster.customParameters + + + name + Default Layer Width + value + 560 + + + com.schriftgestaltung.fontMasterID + 83692D61-586C-413E-9B5A-1AF652750951 + com.schriftgestaltung.glyphOrder + + com.schriftgestaltung.gridSize + 80 + com.schriftgestaltung.gridSubDivision + 80 + com.schriftgestaltung.useNiceNames + + com.schriftgestaltung.weightValue + 100 + public.glyphOrder + + A + O + + + diff --git a/tests/data/UnitsPerEmTest.ufo/metainfo.plist b/tests/data/UnitsPerEmTest.ufo/metainfo.plist new file mode 100644 index 000000000..74e4b3b4f --- /dev/null +++ b/tests/data/UnitsPerEmTest.ufo/metainfo.plist @@ -0,0 +1,10 @@ + + + + + creator + com.schriftgestaltung.GlyphsUFOExport + formatVersion + 3 + +