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 c.installFont(outFile), outFile
"wdth": 1000 }, 'PromisePageBot-Black': { "wght": 800, "wdth": 800 }, 'PromisePageBot-UltraBlack': { "wght": 1000, "wdth": 1000 }, } FONTS = {} VFONT_PATH = 'PromisePageBot-GX.ttf' # Install the test V-font if not 'PromisePageBot-Bold' in c.installedFonts(): c.installFont(FONT_PATH + VFONT_PATH) for name, location in FONT_LOCATIONS.items(): fontName, fontPath = generateInstance(FONT_PATH + VFONT_PATH, location, targetDirectory=FONT_PATH + 'instances') FONTS[ name] = fontName #fontPath # Instead of fontName, no need to uninstall. LIGHT_CONDENSED = FONTS['PromisePageBot-LightCondensed'] LIGHT = FONTS['PromisePageBot-Light'] BOOK = FONTS['PromisePageBot-Book'] BOOK_ITALIC = FONTS['PromisePageBot-Book'] MEDIUM = FONTS['PromisePageBot-Medium'] SEMIBOLD = FONTS['PromisePageBot-Semibold'] SEMIBOLD_CONDENSED = FONTS['PromisePageBot-SemiboldCondensed'] BOLD = FONTS['PromisePageBot-Bold']
from pagebot.elements import newRect, newTextBox # For clarity, most of the MakeABookCover.py example document is setup # as a sequential excecution of Python functions. For complex documents # this is not the best method. More functions and classes will be used in the # real templates, which are available from the PageBotTemplates repository. W, H = B4 W -= 48 # Make a bit more narrow format. # Export in folder that does not commit to Git. Force to export PDF. EXPORT_PATH = '_export/ABookCover.pdf' family = findFamilyByName('Roboto') fontRegular = family.fontStyles['Regular'][0] context.installFont(fontRegular.path) print(fontRegular.info.styleName, fontRegular.path) fontBold = family.fontStyles['Bold'][0] print(fontBold.info.styleName, fontBold.path) fontItalic = family.fontStyles['Italic'][0] print(fontItalic.info.styleName, fontItalic.path) def makeDocument(): u"""Demo random book cover generator.""" # Create new document with (w,h) and fixed amount of pages. # Make number of pages with default document size. # Initially make all pages default with template doc = Document(w=W, h=H,
from pagebot.contexts import defaultContext as context from pagebot.elements.pbpage import Template from pagebot.fonttoolbox.objects.font import Font from pagebot.publications.typespecimen import TypeSpecimen from pagebot.elements.variablefonts.variableglyphs import VariableGlyphs DEBUG = False # Make True to see grid and element frames. OUTPUT_FILE = 'DecovarAxes.pdf' FONT_PATH = pagebot.getFontPath() DecovarPath = FONT_PATH + 'fontbureau/Decovar-VF_2017-02-06.ttf' #DecovarPath = u"/Users/petr/git/PageBotTYPETR/src/fonts/BitcountVar/BitcountGrid-GX.ttf" decovarName = context.installFont(DecovarPath) varFont = Font(DecovarPath) s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789' TERMINALS = ('trmA', 'trmB', 'trmC', 'trmD', 'trmE', 'trmF', 'trmG', 'trmF', 'trmG', 'trmK', 'trmL',) SKL = ('sklA', 'sklB', 'sklD') BLD = ('bldA', 'bldB') WMX = ('wmx2',) axes = varFont.axes trmA = axes['trmA'][0] trmB = axes['trmB'][0] trmC = axes['trmC'][0]