Ejemplo n.º 1
0
def generateInstance(variableFontPath, location, targetDirectory, normalize=True):
    u"""
    Instantiate an instance of a variable font at the specified location.
    Keyword arguments:
        varfilename -- a variable font file path
        location -- a dictionary of axis tag and value {"wght": 0.75, "wdth": -0.5}
    """
    # make a custom file name from the location e.g. VariableFont-wghtXXX-wdthXXX.ttf
    instanceName = ""

    for k, v in sorted(location.items()):
        # TODO better way to normalize the location name to (0, 1000)
        v = min(v, 1000)
        v = max(v, 0)
        instanceName += "-%s%s" % (k, v)
    targetFileName = '.'.join(variableFontPath.split('/')[-1].split('.')[:-1]) + instanceName + '.ttf'

    if not targetDirectory.endswith('/'):
        targetDirectory += '/'
    if not os.path.exists(targetDirectory):
        os.makedirs(targetDirectory)
    outFile = targetDirectory + targetFileName

    if not os.path.exists(outFile):
        # Instance does not exist as file. Create it.

        # print("Loading GX font")
        varFont = TTFont(variableFontPath)

        # Set the instance name IDs in the name table
        platforms=((1, 0, 0), (3, 1, 0x409)) # Macintosh and Windows
        for platformID, platEncID, langID in platforms:
            familyName = varFont['name'].getName(1, platformID, platEncID, langID) # 1 Font Family name
            if not familyName:
                continue
            familyName = familyName.toUnicode() # NameRecord to unicode string
            styleName = unicode(instanceName) # TODO make sure this works in any case
            fullFontName = " ".join([familyName, styleName])
            postscriptName = fullFontName.replace(" ", "-")
            varFont['name'].setName(styleName, 2, platformID, platEncID, langID) # 2 Font Subfamily name
            varFont['name'].setName(fullFontName, 4, platformID, platEncID, langID) # 4 Full font name
            varFont['name'].setName(postscriptName, 6, platformID, platEncID, langID) # 6 Postscript name for the font
            # Other important name IDs
            # 3 Unique font identifier (e.g. Version 0.000;NONE;Promise Bold Regular)
            # 25 Variables PostScript Name Prefix

        fvar = varFont['fvar']
        axes = {a.axisTag: (a.minValue, a.defaultValue, a.maxValue) for a in fvar.axes}
        # TODO Round to F2Dot14?
        if normalize:
            normalizedLoc = normalizeLocation(location, axes)
        else:
            normalizedLoc = location
        # Location is normalized now
        if DEBUG:
            print("Normalized location:", varFileName, normalizedLoc)

        gvar = varFont['gvar']
        for glyphName, variations in gvar.variations.items():
            coordinates, _ = _GetCoordinates(varFont, glyphName)
            for var in variations:
                scalar = supportScalar(normalizedLoc, var.axes)
                if not scalar: continue
                # TODO Do IUP / handle None items
                varCoords = []
                for coord in var.coordinates:
                    # TODO temp hack to avoid NoneType
                    if coord is None:
                        varCoords.append((0, 0))
                    else:
                        varCoords.append(coord)
                coordinates += GlyphCoordinates(varCoords) * scalar
                # coordinates += GlyphCoordinates(var.coordinates) * scalar
            _SetCoordinates(varFont, glyphName, coordinates)

        # print("Removing GX tables")
        for tag in ('fvar', 'avar', 'gvar'):
            if tag in varFont:
                del varFont[tag]

        # Fix leading bug in drawbot by setting lineGap to 0
        varFont['hhea'].lineGap = 0

        if DEBUG:
            print("Saving instance font", outFile)
        varFont.save(outFile)

    # Installing the font in DrawBot. Answer font name and path.
    return installFont(outFile), outFile
Ejemplo n.º 2
0
def generateInstance(variableFontPath,
                     location,
                     targetDirectory,
                     normalize=False,
                     force=False):

    instanceName = ""

    for k, v in sorted(location.items()):
        # TODO better way to normalize the location name to (0, 1000)
        v = min(v, 1000)
        v = max(v, 0)
        instanceName += "-%s%s" % (k, v)
    targetFileName = '.'.join(variableFontPath.split('/')[-1].split('.')
                              [:-1]) + instanceName + '.ttf'

    if not targetDirectory.endswith('/'):
        targetDirectory += '/'
    if not os.path.exists(targetDirectory):
        os.makedirs(targetDirectory)
    outFile = targetDirectory + targetFileName

    if force or not os.path.exists(outFile):
        #print location
        #print("Loading variable font")
        varFont = TTFont(variableFontPath)

        fvar = varFont['fvar']
        axes = {
            a.axisTag: (a.minValue, a.defaultValue, a.maxValue)
            for a in fvar.axes
        }
        # TODO Apply avar
        # TODO Round to F2Dot14?
        loc = normalizeLocation(location, axes)
        # Location is normalized now
        #print("Normalized location:", loc, 'from', location)

        # Set the instance name IDs in the name table
        platforms = ((1, 0, 0), (3, 1, 0x409))  # Macintosh and Windows
        for platformID, platEncID, langID in platforms:
            familyName = varFont['name'].getName(1, platformID, platEncID,
                                                 langID)  # 1 Font Family name
            if not familyName:
                continue
            familyName = familyName.toUnicode()  # NameRecord to unicode string
            styleName = unicode(
                instanceName)  # TODO make sure this works in any case
            fullFontName = " ".join([familyName, styleName])
            postscriptName = fullFontName.replace(" ", "-")
            varFont['name'].setName(styleName, 2, platformID, platEncID,
                                    langID)  # 2 Font Subfamily name
            varFont['name'].setName(fullFontName, 4, platformID, platEncID,
                                    langID)  # 4 Full font name
            varFont['name'].setName(postscriptName, 6, platformID, platEncID,
                                    langID)  # 6 Postscript name for the font
            # Other important name IDs
            # 3 Unique font identifier (e.g. Version 0.000;NONE;Promise Bold Regular)
            # 25 Variables PostScript Name Prefix

        gvar = varFont['gvar']
        glyf = varFont['glyf']
        # get list of glyph names in gvar sorted by component depth
        glyphnames = sorted(
            gvar.variations.keys(),
            key=lambda name:
            (glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth
             if glyf[name].isComposite() else 0, name))
        for glyphname in glyphnames:
            variations = gvar.variations[glyphname]
            coordinates, _ = _GetCoordinates(varFont, glyphname)
            origCoords, endPts = None, None
            for var in variations:
                scalar = supportScalar(loc, var.axes)  #, ot=True)
                if not scalar: continue
                delta = var.coordinates
                if None in delta:
                    if origCoords is None:
                        origCoords, control = _GetCoordinates(
                            varFont, glyphname)
                        endPts = control[1] if control[0] >= 1 else list(
                            range(len(control[1])))
                    delta = _iup_delta(delta, origCoords, endPts)
                coordinates += GlyphCoordinates(delta) * scalar
            _SetCoordinates(varFont, glyphname, coordinates)

        #print("Removing variable tables")
        for tag in ('avar', 'cvar', 'fvar', 'gvar', 'HVAR', 'MVAR', 'VVAR',
                    'STAT'):
            if tag in varFont:
                del varFont[tag]

        #print("Saving instance font", outFile)
        varFont.save(outFile)

    # Installing the font in DrawBot. Answer font name and path.
    return installFont(outFile), outFile
Ejemplo n.º 3
0
 def install(self):
     u"""Install the font in DrawBot, if not already there. Answer the
     DrawBot name."""
     self.installedName = installFont(self.path)
     return self.installedName
d.newPage(paperSize)  # blank page

# 4 Typeset text using the glyphs file as if the instance is already installed
d.newPage(paperSize)
d.fill(0, 0, 0, 1)
tempFolder = os.path.expanduser("~/Library/Application Support/Glyphs/Temp")
ins = f.instances[
    0]  # the index of the instance you want. First instance is 0.

f.instances[insIndex].generate(
    FontPath=tempFolder)  # generates the instance in the "Temp" folder.

fontPath = "%s/%s" % (tempFolder, ins.fileName())
txt = d.FormattedString()
fontName = d.installFont(
    fontPath
)  # Drawbot installes the generated font temporalily. You need to uninstall later in the script.
txt.font(fontName)
string = """Mary had a little lamb,
Its fleece was white as snow,
And every where that Mary went
The lamb was sure to go."""
fontSize = 48
txt.fontSize(fontSize)
txt.lineHeight(fontSize * 1.5)
txt.append(string)
d.textBox(txt, (margin, margin, d.width() - margin * 2, d.height() - margin))

d.uninstallFont(fontPath)  # uninstalls the font from Drawbot

filePath = "~/Desktop/aaaaaaa.pdf"
Ejemplo n.º 5
0
 def installFont(self, path):
     u"""Install a font with a given path and the postscript font name will be returned. The postscript
     font name can be used to set the font as the active font. Fonts are installed only for the current
     process. Fonts will not be accessible outside the scope of drawBot.
     All installed fonts will automatically be uninstalled when the script is done."""
     return installFont(path)
Ejemplo n.º 6
0
            txt = drawTwoColumnsLayout(txt, postscriptFontName)
        else:
            txt = drawOneColumnLayout(txt, postscriptFontName)
        drawHeaderFooter(postscriptFontName, fileName)


# --- Instructions ------------------------------------------------------------- #
if __name__ == '__main__':
    # store fonts and txt files in a variable
    allFonts = sortFonts(collectFilesPaths(FONT_FOLDER, ('ttf', 'otf')))
    alltxtFiles = collectFilesPaths(TXT_FOLDER, 'txt')

    # iterate over all fonts and text files and draw the pages
    for eachFontPath in allFonts:
        for fileName in alltxtFiles:
            postscriptFontName = installFont(eachFontPath)
            proofSet = readStringsFromFile(fileName)
            drawProof(proofSet, postscriptFontName)

    # get all pages
    allPages = pages()
    # count how many pages are available
    totalPages = len(allPages)
    # loop over allpages
    for page in allPages:
        # set the page as current context
        with page:
            # draw the total pagecount in each of them
            typeAttributes()
            text(f'{totalPages}',
                 (270 * FROM_MM_TO_PT, height() - 14 * FROM_MM_TO_PT),