Esempio n. 1
0
def main():
    global doNotSave

    start = time.time()

    doNotSave = False

    filename = sys.argv[-1]
    font = GSFont(filename)

    # Store classes and features
    classes = parseOpenType(font.classes, [], " ")
    features = parseOpenType(font.features, [], "\n")

    # Gets number of axes and stores in a dictionary
    fontAxes = getAxes(font)

    # Set origin master to determine which layers are used in the duplicate glyph
    VfOrigin = getVfOrigin(font)

    weightDict = {
        "Thin": 100,
        "ExtraLight": 200,
        "UltraLight": 200,
        "Light": 300,
        "Normal": 400,
        "Regular": 400,
        "Medium": 500,
        "DemiBold": 600,
        "SemiBold": 600,
        "Bold": 700,
        "UltraBold": 800,
        "ExtraBold": 800,
        "Black": 900,
        "Heavy": 900,
    }

    # Checks all masters and updates fontAxes dictionary min/max values
    # Checks all instances and stores scaled min/def/max values
    # TODO add ability to check virtual master ranges
    parseAxesValues(font, fontAxes, VfOrigin, weightDict)

    needsDup = []
    logged = {}
    noComponents = {}

    # Recursively goes through all glyphs and determines if they will need a duplicate glyph
    needsDup = getBracketGlyphs(font, needsDup, logged, noComponents)

    substitution = "import os\nimport sys\nimport fontTools\nfrom fontTools.ttLib import TTFont\nfrom fontTools.varLib.featureVars import addFeatureVariations\n\nfontPath = sys.argv[-1]\n\nf = TTFont(fontPath)\n\ncondSubst = [\n"

    substitution = setupBracketGlyphs(font, needsDup, features, classes,
                                      VfOrigin, logged, fontAxes, substitution)

    updateOpenType(font, font.classes, classes, " ")
    updateOpenType(font, font.features, features, "\n")

    saveFont(font, filename, start, substitution)
def main():
  args = parser.parse_args()

  for font_path in args.font:
      font = GSFont(font_path)
      print('Copyright: "{}"'.format(font.copyright))
      print('VendorID: "{}"'.format(customparam(font, "vendorID")))
      print('fsType: {}'.format(customparam(font, "fsType")))
      print('license: "{}"'.format(customparam(font, "license")))
      print('licenseURL: "{}"'.format(customparam(font, "licenseURL")))
Esempio n. 3
0
def main():
    parser = argparse.ArgumentParser(description="Build Rana Kufi.")
    parser.add_argument("glyphs", help="input Glyphs source file")
    parser.add_argument("version", help="font version")
    parser.add_argument("otf", help="output OTF file")
    args = parser.parse_args()

    font = GSFont(args.glyphs)
    prepare(font)
    instance = font.instances[0]  # XXX
    otf = build(instance, args)
    otf.save(args.otf)
Esempio n. 4
0
def build(args):
    font = GSFont(args.file)

    # Set metadata
    major, minor = args.version.split(".")
    font.versionMajor, font.versionMinor = int(major), int(minor)
    font.copyright = font.copyright.format(year=datetime.now().year)

    builder = UFOBuilder(
        font,
        propagate_anchors=False,
        write_skipexportglyphs=True,
        store_editor_state=False,
    )
    for master in builder.masters:
        if master.info.styleName == args.master:
            ufo = master
            break

    anchors = {}
    curs = []
    curs.append("lookupflag RightToLeft IgnoreMarks;")
    for glyph in ufo:
        for anchor in glyph.anchors:
            if anchor.name in ("entry", "exit"):
                anchors.setdefault(glyph.name, [None, None])
                anchors[glyph.name][0 if anchor.name ==
                                    "entry" else 1] = anchor
    for glyph, (entry, exit_) in anchors.items():
        curs.append(
            f"pos cursive {glyph} {_dumpAnchor(entry)} {_dumpAnchor(exit_)};")

    curs = "\n".join(curs) + "\n"
    ufo.features.text = ufo.features.text.replace("# Automatic Code Cursive",
                                                  curs)

    compileTTF(ufo,
               inplace=True,
               flattenComponents=True,
               useProductionNames=False).save(args.out_file)
Esempio n. 5
0
def main():
    parser = argparse.ArgumentParser(description="Build Rana Kufi.")
    parser.add_argument("glyphs", help="input Glyphs source file")
    parser.add_argument("otf", help="output OTF file")
    parser.add_argument("--debug",
                        help="Save debug files",
                        action="store_true")
    args = parser.parse_args()

    font = GSFont(args.glyphs)
    prepare(font)
    otf = buildVF(font, args)
    otf.save(args.otf)
Esempio n. 6
0
def main():
    parser = argparse.ArgumentParser(description="Build Rana Kufi.")
    parser.add_argument("glyphs", help="input Glyphs source file")
    parser.add_argument("version",help="font version")
    parser.add_argument("otf",    help="output OTF file")
    parser.add_argument("cidinfo",help="output CID info file")
    parser.add_argument("cidmap", help="output CID map file")
    args = parser.parse_args()

    font = GSFont(args.glyphs)
    prepare(font)
    instance = font.instances[0] # XXX
    otf, cidinfo, cidmap = build(instance, args)

    with open(args.cidinfo, "w") as fp:
        fp.write(cidinfo)
    with open(args.cidmap, "w") as fp:
        fp.write(cidmap)
    otf.save(args.otf)
Esempio n. 7
0
def main():
    from argparse import ArgumentParser
    from pathlib import Path

    parser = ArgumentParser(description="Build Qahiri font.")
    parser.add_argument("input", help="input Glyphs source file", type=Path)
    parser.add_argument("version", help="font version", type=float)
    parser.add_argument("output", help="output font file", type=Path)
    args = parser.parse_args()

    isTTF = False
    if args.output.suffix == ".ttf":
        isTTF = True

    font = GSFont(args.input)
    prepare(font, isTTF)
    instance = font.instances[0]  # XXX

    otf = build(instance, isTTF, args.version)
    otf.save(args.output)
Esempio n. 8
0
def buildVF(opts):
    font = GSFont(opts.glyphs)
    glyphOrder = buildAltGlyphs(font)
    prepare(font)

    for instance in font.instances:
        print(f" MASTER  {instance.name}")
        build(instance, opts, glyphOrder)
        if instance.name == "Regular":
            regular = instance

    ds = DesignSpaceDocument()

    for i, axisDef in enumerate(font.axes):
        axis = ds.newAxisDescriptor()
        axis.tag = axisDef.axisTag
        axis.name = axisDef.name
        axis.maximum = max(x.axes[i] for x in font.instances)
        axis.minimum = min(x.axes[i] for x in font.instances)
        axis.default = regular.axes[i]
        ds.addAxis(axis)

    for instance in font.instances:
        source = ds.newSourceDescriptor()
        source.font = instance.font
        source.familyName = instance.familyName
        source.styleName = instance.name
        source.name = instance.fullName
        source.location = {
            a.name: instance.axes[i]
            for i, a in enumerate(ds.axes)
        }
        ds.addSource(source)

    print(f" MERGE   {font.familyName}")
    otf, _, _ = merge(ds)
    subroutinize(otf)
    if not opts.debug:
        otf["post"].formatType = 3.0
    return otf
Esempio n. 9
0
def main():
    font = GSFont(SOURCE_PATH)
    glyph_list = []

    # parse definitions file, define ColorDefinitions object
    cfp = ColorFileParser(KEY_PATH)
    color_defs = cfp.parse()

    # parse source code for color settings
    # and create GlyphObj objects with color attributes
    for glyph in font.glyphs:
        # integer for GlyphsApp color if present
        # None if color is absent
        glyph_color = glyph.color

        # string
        glyph_name = glyph.name
        # list of strings
        glyph_unicode = glyph.unicode
        # date / time formatted as 2019-01-18 15:04:57 if present
        # None if no edits have been made to the glyph
        # glyph_changetime = glyph.lastChange

        if glyph_color is not None:
            color = Color(glyph_color)
            gco = GlyphColorObj(glyph_name, glyph_unicode, color, color_defs)
        else:
            # default state if no color detected is WHITE
            gco = GlyphColorObj(glyph_name, glyph_unicode, Color.WHITE,
                                color_defs)

        glyph_list.append(gco)

    for glyphobj in glyph_list:
        print("[{} {}] : {} {}".format(glyphobj.name, glyphobj.unicode_hex,
                                       glyphobj.color_name, glyphobj.value))
Esempio n. 10
0
import sys
import os
import re
import time
import copy
from glyphsLib import GSFont
from glyphsLib import GSGlyph
from glyphsLib import GSLayer

filename = sys.argv[-1]
font = GSFont(filename)

delMasters = []
delInstances = []

font.familyName = "Cabin Condensed"

i = 0
for master in font.masters:
    if re.match('.*Condensed.*', master.name) == None:
        for glyph in font.glyphs:
            for layer in glyph.layers:
                if layer.layerId == master.id or layer.associatedMasterId == master.id:
                    del glyph.layers[layer.layerId]
        font.kerning.pop(master.id)
        delMasters.append(i)
        i = i - 1
    else:
        master.name = re.sub(' *Condensed *', '', master.name)
    i = i + 1
# Make a .glyphs file with only brace glyphs, export these files in Glyphs App as variable fonts, and the build script will swap these out in the final VF

import sys
import re
from glyphsLib import GSFont
from glyphsLib import GSGlyph
from glyphsLib import GSLayer

file = sys.argv[1]
font = GSFont(file)
print "\tPreparing %s" % file

# Append Italic to font family naame if Italics
style = sys.argv[2]
if style == "Italic":
	font.familyName = "%s %s" % (font.familyName, style)

# Clear all features
font.features = []
font.classes = []
font.featurePrefixes = []

# Remove Rename Glyphs custom parameter
for instance in font.instances:
	for customParam in instance.customParameters:
		if customParam.name == "Rename Glyphs":
			del customParam

# Find brace glyphs
listOfBraceGlyphs = []
for eachGlyph in font.glyphs:
Esempio n. 12
0
#!/usr/bin/env python3
import sys
from glyphsLib import GSFont

font = GSFont(sys.argv[1])
glyphs = [g.layers[0] for g in font.glyphs if len(g.layers[0].anchors) > 0]
for g in glyphs:
    print("Anchors %s {" % g.parent.name)
    for a in g.anchors:
        print("   %s  <%i %i>" % (a.name, *a.position))
    print("};\n")
Esempio n. 13
0
import sys
from glyphsLib import GSFont

filename = sys.argv[-1]
font = GSFont(filename)

# get font name, remove spaces
varFontName = font.familyName.replace(' ', '') + '-VF'

print(varFontName)

sys.exit(0)
Esempio n. 14
0
"""
	Set metrics in all masters of a Glyphs source to easily adjust metrics with 
	a minimum of clicking and typing. Update values, then run once.

	USAGE:

	You must have glyphsLib installed, for instance via `pip install glyphsLib`.

	Then, run this via the terminal, adding the path to a Glyphs source:

	python3 sources/scripts/set-metrics.py sources/LibreCaslonText.glyphs
"""

from glyphsLib import GSFont
import sys

filepath = sys.argv[1]

font = GSFont(filepath)

for master in font.masters:
	master.customParameters["hheaAscender"] = 1940
	master.customParameters["hheaDescender"] = -520
	master.customParameters["hheaLineGap"] = 0
	master.customParameters["typoAscender"] = 1940
	master.customParameters["typoDescender"] = -520
	master.customParameters["typoLineGap"] = 0
	master.customParameters["winAscent"] = 1696
	master.customParameters["winDescent"] = 531

font.save(filepath)
Esempio n. 15
0
# Create build glyphs file :
# Turn on Export for Bracket Glyphs and disable non ttf instances
# Add extra opentype code for rvrn glyphs that are substituted by another feature as well so that there is a logical path to allow resubstitution, these are manually defined.

import sys
from glyphsLib import GSFont
from glyphsLib import GSGlyph

file = sys.argv[1]

font = GSFont(file)
print("\tPreparing %s" % file)

# List of Glyphs which should have export enabled - in the Glyphs App static fonts export these are not active but get swapped with a custom parameter, for the VFs though they needs to be exported
italicBracketGlyphs = [
    "cedi.rvrn", "colonsign.rvrn", "guarani.rvrn", "cent.rvrn", "dollar.rvrn",
    "dollar.tf.rvrn", "cent.tf.rvrn", "naira.rvrn", "peseta.rvrn", "won.rvrn",
    "peso.rvrn", "curvedStemParagraphSignOrnament.rvrn", "paragraph.rvrn"
]

uprightBracketGlyphs = italicBracketGlyphs + [
    "apple.rvrn",
    "Adieresis.rvrn",
    "Odieresis.rvrn",
    "Udieresis.rvrn",
    "Adieresis.titl.rvrn",
    "Odieresis.titl.rvrn",
    "Udieresis.titl.rvrn",
]

# Extra FEA code so that the glyphs swapped by rvrn can be substituted again by another opentype feature
Esempio n. 16
0
import sys
import os
import re
from glyphsLib import GSFont
from glyphsLib import GSGlyph

filename = sys.argv[-1]

font = GSFont(filename)

nonExportGlyphs = []
baseIndex = 0
for glyph in font.glyphs:
    for layer in glyph.layers:
        if re.match('.*\}.*', layer.name) != None:
            layer.name = 'Brace Off'
        elif re.match('.*\].*', layer.name) != None:
            layer.name = 'Bracket Off'

font.familyName = "Hepta Slab Hairline"

font.instances[0].active = True

del font.instances[1:]

font.save(filename)
# Make a .glyphs file with only brace glyphs, export these files in Glyphs App as variable fonts, and the build script will swap these out in the final VF

import sys
import re
from glyphsLib import GSFont
from glyphsLib import GSGlyph
from glyphsLib import GSLayer

file = sys.argv[1]
font = GSFont(file)
print("\tPreparing %s" % file)

# Append Italic to font family naame if Italics
style = sys.argv[2]
if style == "Italic":
    font.familyName = "%s %s" % (font.familyName, style)

# Clear all features
font.features = []
font.classes = []
font.featurePrefixes = []

# Remove Rename Glyphs custom parameter
for instance in font.instances:
    for customParam in instance.customParameters:
        if customParam.name == "Rename Glyphs":
            del customParam

# Find brace glyphs
listOfBraceGlyphs = []
for eachGlyph in font.glyphs:
Esempio n. 18
0
def main(args=None):
    """Test for interpolatability issues between fonts"""
    import argparse

    parser = argparse.ArgumentParser(
        "fonttools varLib.interpolatable",
        description=main.__doc__,
    )
    parser.add_argument(
        "--json",
        action="store_true",
        help="Output report in JSON format",
    )
    parser.add_argument("inputs",
                        metavar="FILE",
                        type=str,
                        nargs="+",
                        help="Input TTF/UFO files")

    args = parser.parse_args(args)
    glyphs = None
    # glyphs = ['uni08DB', 'uniFD76']
    # glyphs = ['uni08DE', 'uni0034']
    # glyphs = ['uni08DE', 'uni0034', 'uni0751', 'uni0753', 'uni0754', 'uni08A4', 'uni08A4.fina', 'uni08A5.fina']

    from os.path import basename

    fonts = []
    names = []

    if len(args.inputs) == 1:
        if args.inputs[0].endswith('.designspace'):
            from fontTools.designspaceLib import DesignSpaceDocument
            designspace = DesignSpaceDocument.fromfile(args.inputs[0])
            args.inputs = [master.path for master in designspace.sources]

        elif args.inputs[0].endswith('.glyphs'):
            from glyphsLib import GSFont, to_ufos
            gsfont = GSFont(args.inputs[0])
            fonts.extend(to_ufos(gsfont))
            names = [
                '%s-%s' % (f.info.familyName, f.info.styleName) for f in fonts
            ]
            args.inputs = []

        elif args.inputs[0].endswith('.ttf'):
            from fontTools.ttLib import TTFont
            font = TTFont(args.inputs[0])
            if 'gvar' in font:
                # Is variable font
                gvar = font['gvar']
                # Gather all "master" locations
                locs = set()
                for variations in gvar.variations.values():
                    for var in variations:
                        loc = []
                        for tag, val in sorted(var.axes.items()):
                            loc.append((tag, val[1]))
                        locs.add(tuple(loc))
                # Rebuild locs as dictionaries
                new_locs = [{}]
                for loc in sorted(locs, key=lambda v: (len(v), v)):
                    names.append(str(loc))
                    l = {}
                    for tag, val in loc:
                        l[tag] = val
                    new_locs.append(l)
                locs = new_locs
                del new_locs
                # locs is all master locations now

                for loc in locs:
                    fonts.append(
                        font.getGlyphSet(location=loc, normalized=True))

                args.inputs = []

    for filename in args.inputs:
        if filename.endswith(".ufo"):
            from fontTools.ufoLib import UFOReader
            fonts.append(UFOReader(filename))
        else:
            from fontTools.ttLib import TTFont
            fonts.append(TTFont(filename))

        names.append(basename(filename).rsplit(".", 1)[0])

    if hasattr(fonts[0], 'getGlyphSet'):
        glyphsets = [font.getGlyphSet() for font in fonts]
    else:
        glyphsets = fonts

    problems = test(glyphsets, glyphs=glyphs, names=names)
    if args.json:
        import json

        print(json.dumps(problems))
    else:
        for glyph, glyph_problems in problems.items():
            print(f"Glyph {glyph} was not compatible: ")
            for p in glyph_problems:
                if p["type"] == "missing":
                    print("    Glyph was missing in master %s" % p["master"])
                if p["type"] == "open_path":
                    print("    Glyph has an open path in master %s" %
                          p["master"])
                if p["type"] == "path_count":
                    print("    Path count differs: %i in %s, %i in %s" %
                          (p["value_1"], p["master_1"], p["value_2"],
                           p["master_2"]))
                if p["type"] == "node_count":
                    print(
                        "    Node count differs in path %i: %i in %s, %i in %s"
                        % (
                            p["path"],
                            p["value_1"],
                            p["master_1"],
                            p["value_2"],
                            p["master_2"],
                        ))
                if p["type"] == "node_incompatibility":
                    print(
                        "    Node %o incompatible in path %i: %s in %s, %s in %s"
                        % (
                            p["node"],
                            p["path"],
                            p["value_1"],
                            p["master_1"],
                            p["value_2"],
                            p["master_2"],
                        ))
                if p["type"] == "contour_order":
                    print("    Contour order differs: %s in %s, %s in %s" % (
                        p["value_1"],
                        p["master_1"],
                        p["value_2"],
                        p["master_2"],
                    ))
                if p["type"] == "wrong_start_point":
                    print("    Contour start point differs: %s, %s" % (
                        p["master_1"],
                        p["master_2"],
                    ))
    if problems:
        return problems
# Create build glyphs file :
# Turn on Export for Bracket Glyphs and disable non ttf instances
# Add extra opentype code for rvrn glyphs that are substituted by another feature as well so that there is a logical path to allow resubstitution, these are manually defined.

import sys
from glyphsLib import GSFont
from glyphsLib import GSGlyph

file = sys.argv[1]

font = GSFont(file)
print "\tPreparing %s" % file

# List of Glyphs which should have export enabled - in the Glyphs App static fonts export these are not active but get swapped with a custom parameter, for the VFs though they needs to be exported
italicBracketGlyphs = [
"cedi.rvrn",
"colonsign.rvrn",
"guarani.rvrn",
"cent.rvrn",
"dollar.rvrn",
"dollar.tf.rvrn",
"cent.tf.rvrn",
"naira.rvrn",
"peseta.rvrn",
"won.rvrn",
"peso.rvrn",
"curvedStemParagraphSignOrnament.rvrn",
"paragraph.rvrn"
]

uprightBracketGlyphs = italicBracketGlyphs + [
Esempio n. 20
0
# -*- coding: utf-8 -*-

#
# This script demonstrates how to iterate through glyphs in a GlyphsApp *.glyphs source file
# and parse glyph-specific metadata
#
# Dependencies for this script can be installed with:
#
#    $ pip3 install --upgrade glyphsLib
#

from glyphsLib import GSFont

SOURCE_PATH = "../glyphs_source/GenericSans-GreenHighlight.glyphs"

font = GSFont(SOURCE_PATH)

for glyph in font.glyphs:
    # integer for GlyphsApp color if present
    # None if color is absent
    glyph_color = glyph.color

    # string
    glyph_name = glyph.name
    # list of strings
    glyph_unicode = glyph.unicode
    # date / time formatted as 2019-01-18 15:04:57 if present
    # None if no edits have been made to the glyph
    glyph_changetime = glyph.lastChange

    print("{} - {} - {} - {}".format(glyph_name, glyph_unicode, glyph_color,
Esempio n. 21
0
import sys
import os
import re
import time
import copy
from glyphsLib import GSFont
from glyphsLib import GSGlyph
from glyphsLib import GSLayer

filename = sys.argv[-1]
font = GSFont(filename)

delMasters = []
delInstances = []
delAxes = []

i = 0
for master in font.masters:
    if re.match('.*Oblique.*', master.name) != None:
        for glyph in font.glyphs:
            delLayers = []
            for layer in glyph.layers:
                if layer.layerId == master.id or layer.associatedMasterId == master.id:
                    delLayers.append(layer.layerId)
            for layerId in delLayers:
                del glyph.layers[layerId]
        delMasters.append(i)
        i = i - 1
    else:
        for glyph in font.glyphs:
            delLayers = []
Esempio n. 22
0
import sys
from glyphsLib import GSFont


def settransformedcomponents(f):

    glyphs = []

    # Collect glyphs
    for glyph in f.glyphs:
        for layer in glyph.layers:
            for i, component in enumerate(layer.components):
                if component.transform[0] != 1 or component.transform[3] != 1:
                    if [glyph, len(layer.components), i] not in glyphs:
                        glyphs.append([glyph, len(layer.components), i])

    # Adjust transform
    for glyph, component_count, i in glyphs:
        for layer in glyph.layers:
            if component_count == len(layer.components):
                if layer.components[i].transform[0] == 1:
                    layer.components[i].transform[0] = 0.999
                if layer.components[i].transform[3] == 1:
                    layer.components[i].transform[3] = 0.999


if __name__ == "__main__":
    font = GSFont(sys.argv[-1])
    settransformedcomponents(font)
    font.save(sys.argv[-1])