예제 #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")))
예제 #3
0
파일: build.py 프로젝트: mustafa0x/qahiri
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)
예제 #4
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)
예제 #5
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)
예제 #6
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)
예제 #7
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
예제 #8
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)
예제 #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))
예제 #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 = []
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 = []
예제 #11
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
예제 #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")
예제 #13
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)
예제 #14
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,
예제 #15
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
예제 #16
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])