def convertToOTF(ttfPath, dest, report): temp = tempfile.mkstemp(suffix=".otf")[1] font = RFont(ttfPath, document=False, showInterface=False) font.kerning.clear() for attr in font.info.asDict().keys(): if attr not in defaultFontInfoAttributes: setattr(font.info, attr, None) result = font.generate(path=temp, format="otf", decompose=False, checkOutlines=False, autohint=False, releaseMode=True, glyphOrder=font.glyphOrder) if not font.hasInterface(): font.close() report.write(result) sourceFont = TTFont(temp) sourceFontWithTables = TTFont(ttfPath) for table in ["loca", "OS/2", "cmap", "name", "GSUB", "GPOS", "GDEF", "kern"]: if table in sourceFontWithTables: sourceFont[table] = sourceFontWithTables[table] sourceFont.save(dest) result = OTFAutohint(dest) report.writeItems(result) os.remove(temp)
def rename_glyphs(self, names_list): print "renaming glyphs in space...\n" for ufo_path in self.ufos(): ufo = RFont(ufo_path, showUI=False) print "\trenaming glyphs in %s..." % get_full_name(ufo) rename_glyphs_from_list(ufo, names_list, overwrite=True, mark=False, verbose=False) ufo.save() print print "...done.\n"
def run(self, destDir, progress): paths = self.controller.get(["ufo"]) report = Report() tempDir = os.path.join(destDir, "temp") if not os.path.exists(tempDir): os.makedirs(tempDir) tempExportPaths = self._generateCallback(tempDir, progress, report) progress.update("Merging Tables...") report.writeTitle("Merged Fonts:") report.newLine() tableNames = [item["tableName"] for item in self.tableList if item["add"]] for fontIndex, path in enumerate(paths): font = RFont(path, document=False, showInterface=False) binarySourcepath = font.lib.get("com.typemytype.robofont.binarySource") tempExportPath = tempExportPaths[fontIndex] if binarySourcepath: binaryIs Type = os.path.splitext(binarySourcepath)[1].lower() in [".ttf", ".otf"] tempIsOpenType = os.path.splitext(tempExportPath)[1].lower() in [".ttf", ".otf"] if binaryIsOpenType and tempIsOpenType: if os.path.exists(binarySourcepath) and os.path.exists(tempExportPath): binarySource = TTFont(binarySourcepath) tempFont = TTFont(tempExportPath) fileName = os.path.basename(tempExportPath) if not self.controller.keepFileNames(): fileName = "%s-%s%s" % (font.info.familyName, font.info.styleName, os.path.splitext(tempExportPath)[1]) path = os.path.join(destDir, fileName) report.writeTitle(os.path.basename(path), "'") report.write("source: %s" % tempExportPath) report.write("binary source: %s" % binarySourcepath) report.newLine() report.indent() for table in tableNames: if table in binarySource: report.write("merge %s table" % table) tempFont[table] = binarySource[table] report.write("save to %s" % path) tempFont.save(path) report.dedent() report.newLine() tempFont.close() binarySource.close() if not font.hasInterface(): font.close() reportPath = os.path.join(destDir, "Binary Merge Report.txt") report.save(reportPath) if not getDefault("Batch.Debug", False): if os.path.exists(tempDir): shutil.rmtree(tempDir)
def apply_callback(self, sender): f = CurrentFont() if f is not None: # get layer name layer_name_option = self.w.layer_name.get() # mask layer if not layer_name_option: layer_name = 'background' # font name else: layer_name = os.path.split(self.ufo_path)[1] # import layer print 'importing .ufo...\n' print '\ttarget layer: %s\n' % layer_name ufo = RFont(self.ufo_path, showUI=False) for glyph_name in f.keys(): if ufo.has_key(glyph_name): layer_glyph = f[glyph_name].getLayer(layer_name) pen = layer_glyph.getPointPen() ufo[glyph_name].drawPoints(pen) f[glyph_name].update() f.update() print '...done.\n' # no font open else: print no_font_open
def scale_glyphs(self, factor, gstring=None, verbose=False): # get glyphs if gstring is None: glyph_names = self.project.all_glyphs() else: names = gstring.split(" ") groups = self.project.libs["groups"]["glyphs"] glyph_names = parse_glyphs_groups(names, groups) # scale glyphs print "scaling glyphs in space...\n" for ufo_path in self.ufos(): ufo = RFont(ufo_path, showUI=False) print "\tscaling %s by %s..." % (get_full_name(ufo), factor) if verbose: print "\t\t", for glyph_name in glyph_names: if verbose: print glyph_name, leftMargin, rightMargin = ufo[glyph_name].leftMargin, ufo[glyph_name].rightMargin ufo[glyph_name].scale((factor, factor)) ufo[glyph_name].leftMargin = leftMargin * factor ufo[glyph_name].rightMargin = rightMargin * factor # done with font if verbose: print ufo.save() print "\n...done.\n"
def generateOTF(ufoPath, dest, report): font = RFont(ufoPath, document=False, showInterface=False) result = font.generate(path=dest, format="otf", decompose=False, checkOutlines=True, autohint=False, releaseMode=True, glyphOrder=font.glyphOrder) if not font.hasInterface(): font.close() report.write(result) result = OTFAutohint(dest) report.writeItems(result)
def clear_kerning(self): print "batch deleting kerning...\n" for ufo_path in self.ufos(): ufo = RFont(ufo_path, showUI=False) amount_pairs = len(ufo.kerning) if amount_pairs > 0: print '\t deleting %s kerning pairs in %s %s...' % (amount_pairs, self.project.name, ufo.info.styleName) ufo.kerning.clear() ufo.save() else: print '\t no kerning pairs in %s %s...' % (self.project.name, ufo.info.styleName) print "\n...done.\n"
def get_font_at_location(self, location, showUI=False): #print("\nBuilding font at location %s" % location) i_font = RFont(showUI=showUI) # showUI=False if self.target_glyphset == []: glyphset = self.masters[0][1].glyphOrder else: glyphset = self.target_glyphset self.interpolate_font_info(location, self.masters, i_font) groups = self.masters[0][1].groups for k in groups.keys(): i_font.groups[k] = groups[k] self.interpolate_kerning(location, self.masters, i_font) self.interpolate_glyph_set(location, glyphset, self.masters, i_font) i_font.glyphOrder = glyphset return i_font
def apply_callback(self, sender): f = CurrentFont() if f is not None: print 'importing .ufo into layer...' ufo = RFont(self.ufo_path, showUI=False) layer_name = os.path.split(self.ufo_path)[1] for glyph_name in f.keys(): if ufo.has_key(glyph_name): layer_glyph = f[glyph_name].getLayer(layer_name) pen = layer_glyph.getPointPen() ufo[glyph_name].drawPoints(pen) f[glyph_name].update() f.update() print '...done.\n' else: print 'please open a font first.\n'
def button_apply_callback(self, sender): if self.ufos_folder is not None: _ufo_paths = walk(self.ufos_folder, 'ufo') if len(_ufo_paths) > 0: # set otfs folder if self.otfs_folder is None: self.otfs_folder = self.ufos_folder # get parameters _decompose = self.w._decompose.get() _overlaps = self.w._overlaps.get() _autohint = self.w._autohint.get() _release_mode = self.w._release_mode.get() # print settings boolstring = ("False", "True") print 'batch generating .otfs for all fonts in folder...\n' print '\tufos folder: %s' % self.ufos_folder print '\totfs folder: %s' % self.otfs_folder print '\tdecompose: %s' % boolstring[_decompose] print '\tremove overlaps: %s' % boolstring[_overlaps] print '\tautohint: %s' % boolstring[_autohint] print '\trelease mode: %s' % boolstring[_release_mode] print # batch generate self.w.bar.start() for ufo_path in _ufo_paths: print '\tgenerating .otf for %s...' % os.path.split(ufo_path)[1] ufo = RFont(ufo_path, showInterface=False) # generate otf otf_file = os.path.splitext(os.path.split(ufo_path)[1])[0] + '.otf' otf_path = os.path.join(self.otfs_folder, otf_file) ufo.generate(otf_path, 'otf', decompose=_decompose, autohint=_autohint, checkOutlines=_overlaps, releaseMode=_release_mode) # close ufo.close() print '\t\totf path: %s' % otf_path print '\t\tgeneration sucessful? %s\n' % os.path.exists(otf_path) # done self.w.bar.stop() print '...done.\n' # no font in folder else: print no_font_in_folder
def apply_callback(self, sender): ufo_paths = walk(self._ufos_folder, 'ufo') if len(ufo_paths) > 0: print 'transforming all fonts in folder...\n' self.w.bar.start() for ufo_path in ufo_paths: font = RFont(ufo_path, showUI=False) print '\ttransforming %s...' % get_full_name(font) if self._round: print '\t\trounding points...' font.round() if self._decompose: print '\t\tdecomposing...' decompose(font) if self._overlaps: print '\t\tremoving overlaps...' font.removeOverlap() if self._order: print '\t\tauto contour order...' auto_contour_order(font) if self._direction: print '\t\tauto contour direction...' auto_contour_direction(font) if self._extremes: print '\t\tadding extreme points...' add_extremes(font) if self._save: print '\t\tsaving font...' font.save() print '\t...done.\n' self.w.bar.stop() print '...done.\n' # no font open else: print 'the selected directory contains no .ufo font.\n'
def _get_folder_fonts(self): """collect all .ufo fonts in the selected folder""" # get font paths self._folder_font_paths = walk(self._folder, 'ufo') # open fonts for font_path in self._folder_font_paths: font = RFont(font_path, showUI=False) if font not in self._folder_fonts: self._folder_fonts.append(font)
def convertToOTF(ttfPath, dest, report): temp = tempfile.mkstemp(suffix=".otf")[1] font = RFont(ttfPath, document=False, showInterface=False) font.kerning.clear() for attr in font.info.asDict().keys(): if attr not in defaultFontInfoAttributes: setattr(font.info, attr, None) result = font.generate(path=temp, format="otf", decompose=False, checkOutlines=False, autohint=False, releaseMode=True, glyphOrder=font.glyphOrder) if not font.hasInterface(): font.close() report.write(result) sourceFont = TTFont(temp) sourceFontWithTables = TTFont(ttfPath) for table in [ "loca", "OS/2", "cmap", "name", "GSUB", "GPOS", "GDEF", "kern" ]: if table in sourceFontWithTables: sourceFont[table] = sourceFontWithTables[table] sourceFont.save(dest) result = OTFAutohint(dest) report.writeItems(result) os.remove(temp)
def create_glyphs(self, gstring=None, verbose=False): """Create all glyphs in all fonts in space.""" # get glyphs if gstring is None: glyph_names = self.project.all_glyphs() else: names = gstring.split(" ") groups = self.project.libs["groups"]["glyphs"] glyph_names = parse_glyphs_groups(names, groups) # create glyphs print "creating glyphs in space...\n" for ufo_path in self.ufos(): ufo = RFont(ufo_path, showUI=False) print "\tcreating glyphs in %s..." % get_full_name(ufo) if verbose: print "\t\t", for glyph_name in glyph_names: # create glyph in font if ufo.has_key(glyph_name) is False: if verbose: print glyph_name, ufo.newGlyph(glyph_name) # done with font ufo.save() if verbose: print "\n" # done print "\n...done.\n"
def move_glyphs(self, delta, gstring=None, verbose=False): # get glyphs if gstring is None: glyph_names = self.project.all_glyphs() else: names = gstring.split(' ') groups = self.project.libs['groups']['glyphs'] glyph_names = parse_glyphs_groups(names, groups) # move glyphs print 'moving glyphs in space...' print for ufo_path in self.ufos(): ufo = RFont(ufo_path, showUI=False) print '\tmoving glyphs in %s by %s...' % (get_full_name(ufo), delta) if verbose: print '\t\t', for glyph_name in glyph_names: if verbose: print glyph_name, ufo[glyph_name].move(delta) # done with font ufo.save() print print '...done.\n'
def shift_y(self, dest_height, gstring, transformations, verbose=True): print "batch y-shifting glyphs in hSpace...\n" # get glyphs names = gstring.split(" ") groups = self.project.libs["groups"]["glyphs"] glyph_names = parse_glyphs_groups(names, groups) # get base height source_width = str(self.parameters["height"][0]) # batch shift glyphs in fonts for src_path in self.ufos(): font = hFont(RFont(src_path, showUI=False)) # get dest font dest_parameters = font.parameters dest_parameters["height"] = dest_height dest_file = "%s_%s.ufo" % (font.project.name, font.name_from_parameters(separator="-")) dest_path = os.path.join(font.project.paths["ufos"], dest_file) # transform font if os.path.exists(dest_path): dest_font = RFont(dest_path, showUI=False) print "\ty-shifting glyphs from %s to %s...\n" % (get_full_name(font.ufo), get_full_name(dest_font)) if verbose: print "\t\t", for glyph_name in glyph_names: if font.ufo.has_key(glyph_name): if dest_font.has_key(glyph_name) is False: dest_font.newGlyph(glyph_name) if verbose: print glyph_name, # insert glyph dest_font.insertGlyph(font.ufo[glyph_name]) # shift points for t in transformations: pos, delta, side = t deselect_points(dest_font[glyph_name]) select_points_y(dest_font[glyph_name], pos, side=side) shift_selected_points_y(dest_font[glyph_name], delta) deselect_points(dest_font[glyph_name]) # save dest_font.save() if verbose: print print "...done.\n"
def convertToTTF(otfPath, dest, report): temp = tempfile.mkstemp(suffix=".ttf")[1] tempDest = tempfile.mkstemp(suffix=".ttf")[1] font = RFont(otfPath, document=False, showInterface=False) font.lib[shouldAddPointsInSplineConversionLibKey] = 1 font.kerning.clear() for attr in font.info.asDict().keys(): if attr not in defaultFontInfoAttributes: setattr(font.info, attr, None) result = font.generate(path=temp, format="ttf", decompose=False, checkOutlines=False, autohint=False, releaseMode=True, glyphOrder=font.glyphOrder) if not font.hasInterface(): font.close() report.write(result) sourceFont = TTFont(temp) sourceFontWithTables = TTFont(otfPath) for table in [ "loca", "OS/2", "cmap", "name", "GSUB", "GPOS", "GDEF", "kern" ]: if table in sourceFontWithTables: sourceFont[table] = sourceFontWithTables[table] fixMetrics(sourceFont) sourceFont.save(tempDest) sourceFont.close() del sourceFont sourceFontWithTables.close() del sourceFontWithTables autohintOptions = getExtensionDefault(settingsIdentifier, defaultOptions) result = TTFAutohint(tempDest, dest, autohintOptions) report.writeItems(result) os.remove(temp) os.remove(tempDest)
def shift_x(self, dest_width, gstring, pos, delta, side, verbose=True): print 'batch x-shifting glyphs in hSpace...\n' # get glyphs names = gstring.split(' ') groups = self.project.libs['groups']['glyphs'] glyph_names = parse_glyphs_groups(names, groups) # get base width source_width = str(self.parameters['width'][0]) # batch shift glyphs in fonts for src_path in self.ufos(): font = hFont(RFont(src_path, showUI=False)) # get dest font dest_parameters = font.parameters dest_parameters['width'] = dest_width dest_file = '%s_%s.ufo' % (font.project.name, font.name_from_parameters(separator='-')) dest_path = os.path.join(font.project.paths['ufos'], dest_file) # transform font if os.path.exists(dest_path): dest_font = RFont(dest_path, showUI=False) print "\tx-shifting glyphs from %s to %s...\n" % (get_full_name(font.ufo), get_full_name(dest_font)) if verbose: print '\t\t', for glyph_name in glyph_names: if font.ufo.has_key(glyph_name): if dest_font.has_key(glyph_name) is False: dest_font.newGlyph(glyph_name) if verbose: print glyph_name, # insert glyph dest_font.insertGlyph(font.ufo[glyph_name]) # shift points deselect_points(dest_font[glyph_name]) select_points_x(dest_font[glyph_name], pos, side=side) shift_selected_points_x(dest_font[glyph_name], delta) deselect_points(dest_font[glyph_name]) # increase width dest_font[glyph_name].width += delta # done dest_font.save() if verbose: print print '...done.\n'
def button_apply_callback(self, sender): if self.ufos_folder is not None: _ufo_paths = walk(self.ufos_folder, 'ufo') if len(_ufo_paths) > 0: # set otfs folder if self.otfs_folder is None: self.otfs_folder = self.ufos_folder # get parameters _decompose = self.w._decompose.get() _overlaps = self.w._overlaps.get() _autohint = self.w._autohint.get() _release_mode = self.w._release_mode.get() # print settings boolstring = ("False", "True") print 'batch generating .otfs for all fonts in folder...\n' print '\tufos folder: %s' % self.ufos_folder print '\totfs folder: %s' % self.otfs_folder print '\tdecompose: %s' % boolstring[_decompose] print '\tremove overlaps: %s' % boolstring[_overlaps] print '\tautohint: %s' % boolstring[_autohint] print '\trelease mode: %s' % boolstring[_release_mode] print # batch generate self.w.bar.start() for ufo_path in _ufo_paths: print '\tgenerating .otf for %s...' % os.path.split( ufo_path)[1] ufo = RFont(ufo_path, showUI=False) # generate otf otf_file = os.path.splitext( os.path.split(ufo_path)[1])[0] + '.otf' otf_path = os.path.join(self.otfs_folder, otf_file) ufo.generate(otf_path, 'otf', decompose=_decompose, autohint=_autohint, checkOutlines=_overlaps, releaseMode=_release_mode) # close ufo.close() print '\t\totf path: %s' % otf_path print '\t\tgeneration sucessful? %s\n' % os.path.exists( otf_path) # done self.w.bar.stop() print '...done.\n' # no font in folder else: print no_font_in_folder
def transfer_glyphs(self, gstring, var, verbose=False): axis, src, dest_list = var # define source space for param in self.parameters.keys(): if param == axis: self.parameters[param] = [ src ] self.build() # get glyphs names = gstring.split(' ') groups = self.project.libs['groups']['glyphs'] glyph_names = parse_glyphs_groups(names, groups) # batch copy print "batch transfering glyphs in %s..." % self.project.name for src_path in self.ufos(): font = hFont(RFont(src_path, showUI=False)) for dest in dest_list: dest_parameters = font.parameters dest_parameters[axis] = dest dest_file = '%s_%s.ufo' % (font.project.name, font.name_from_parameters(separator='-')) dest_path = os.path.join(font.project.paths['ufos'], dest_file) if os.path.exists(dest_path): dest_ufo = RFont(dest_path, showUI=False) print print "\tcopying glyphs from %s to %s..." % (get_full_name(font.ufo), get_full_name(dest_ufo)) if verbose: print '\t\t', for glyph_name in glyph_names: if font.ufo.has_key(glyph_name): if dest_ufo.has_key(glyph_name) is False: dest_ufo.newGlyph(glyph_name) # decompose first if len(font.ufo[glyph_name].components) > 0: font.ufo[glyph_name].decompose() if verbose: print glyph_name, # insert glyph dest_ufo.insertGlyph(font.ufo[glyph_name]) dest_ufo.save() if verbose: print print '\n...done.\n'
def apply_callback(self, sender): ufo_paths = walk(self.ufos_folder, 'ufo') if len(ufo_paths) > 0: print('transforming all fonts in folder...\n') self.w.bar.start() for ufo_path in ufo_paths: font = RFont(ufo_path, showUI=False) print('\ttransforming %s...' % get_full_name(font)) if self.round: print('\t\trounding points...') font.round() if self.decompose: print('\t\tdecomposing...') decompose(font) if self.overlaps: print('\t\tremoving overlaps...') font.removeOverlap() if self.order: print('\t\tauto contour order...') auto_contour_order(font) if self.direction: print('\t\tauto contour direction...') auto_contour_direction(font) if self.extremes: print('\t\tadding extreme points...') add_extremes(font) if self.remove_features: print('\t\tremoving all OpenType features...') clear_features(font) if self.save: print('\t\tsaving font...') font.save() print('\t...done.\n') self.w.bar.stop() print('...done.\n') # no font in folder else: print(no_font_in_folder)
def generate_instance(self, instance_name, verbose=False, folder=None): """Generate a ``.ufo`` instance with name ``instance_name``, using data from the project's interpol lib.""" _masters = self.masters() if self.libs["interpol"].has_key(instance_name): # get instance info master_1, master_2, interpol_factor = self.libs["interpol"][instance_name] # make file names master_1_filename = "%s_%s.ufo" % (self.name, master_1) master_2_filename = "%s_%s.ufo" % (self.name, master_2) # master masters master_1_path = os.path.join(self.paths["ufos"], master_1_filename) master_2_path = os.path.join(self.paths["ufos"], master_2_filename) # instance masters if master_1_path not in _masters: master_1_path = os.path.join(self.paths["instances"], master_1_filename) if master_2_path not in _masters: master_2_path = os.path.join(self.paths["instances"], master_2_filename) # generate instance if os.path.exists(master_1_path) and os.path.exists(master_2_path): if verbose: print "generating %s %s (factor: %s, %s)..." % ( self.name, instance_name, interpol_factor[0], interpol_factor[1], ), instance_filename = "%s_%s.ufo" % (self.name, instance_name) if folder is None: instance_path = os.path.join(self.paths["instances"], instance_filename) else: instance_path = os.path.join(folder, instance_filename) # open/create fonts f1 = RFont(master_1_path, showUI=False) f2 = RFont(master_2_path, showUI=False) f3 = NewFont(showUI=False) # interpolate f3.interpolate((interpol_factor[0], interpol_factor[1]), f1, f2) f3.update() f1.close() f2.close() f3.save(instance_path) f3.close() if verbose: print "done.\n" # instance not in lib else: if verbose: print "%s is not an instance.\n" % instance_name
def generateTTF(ufoPath, dest, report): tempDest = tempfile.mkstemp(suffix=".ttf")[1] font = RFont(ufoPath, document=False, showInterface=False) font.lib[shouldAddPointsInSplineConversionLibKey] = 1 result = font.generate(path=tempDest, format="ttf", decompose=False, checkOutlines=True, autohint=False, releaseMode=True, glyphOrder=font.glyphOrder) if not font.hasInterface(): font.close() report.write(result) autohintOptions = getExtensionDefault(settingsIdentifier, defaultOptions) result = TTFAutohint(tempDest, dest, autohintOptions) report.writeItems(result) os.remove(tempDest)
def transfer_anchors(self, var, gstring=None, clear=True, verbose=False): """Transfer anchors from one variable set of fonts to another.""" axis, src, dest_list = var # define source space for param in self.parameters.keys(): if param == axis: self.parameters[param] = [src] self.build() # parse gstring if gstring is None: glyph_names = self.project.all_glyphs() else: glyph_names = self.project.parse_gstring(gstring) # batch copy print "batch transfering anchors in %s..." % self.project.name for src_path in self.ufos(): font = hFont(RFont(src_path, showUI=False)) for dest in dest_list: dest_parameters = font.parameters dest_parameters[axis] = dest dest_file = "%s_%s.ufo" % (font.project.name, font.name_from_parameters(separator="-")) dest_path = os.path.join(font.project.paths["ufos"], dest_file) if os.path.exists(dest_path): dest_ufo = RFont(dest_path, showUI=False) print if clear: print "\tremoving anchors in %s..." % get_full_name(dest_ufo) dest_font = hFont(dest_ufo) dest_font.clear_anchors(gstring) print "\tcopying anchors from %s to %s..." % (get_full_name(font.ufo), get_full_name(dest_ufo)) if verbose: print "\t\t", for glyph_name in glyph_names: if font.ufo.has_key(glyph_name): if len(font.ufo[glyph_name].anchors) > 0: if dest_ufo.has_key(glyph_name) is False: dest_ufo.newGlyph(glyph_name) if verbose: print glyph_name, transfer_anchors(font.ufo[glyph_name], dest_ufo[glyph_name]) dest_ufo.save() if verbose: print print "\n...done.\n"
def apply_callback(self, sender): ufo_paths = walk(self.ufos_folder, 'ufo') if len(ufo_paths) > 0: print 'transforming all fonts in folder...\n' self.w.bar.start() for ufo_path in ufo_paths: font = RFont(ufo_path, showUI=False) print '\ttransforming %s...' % get_full_name(font) if self.round: print '\t\trounding points...' font.round() if self.decompose: print '\t\tdecomposing...' decompose(font) if self.overlaps: print '\t\tremoving overlaps...' font.removeOverlap() if self.order: print '\t\tauto contour order...' auto_contour_order(font) if self.direction: print '\t\tauto contour direction...' auto_contour_direction(font) if self.extremes: print '\t\tadding extreme points...' add_extremes(font) if self.remove_features: print '\t\tremoving all OpenType features...' clear_features(font) if self.save: print '\t\tsaving font...' font.save() print '\t...done.\n' self.w.bar.stop() print '...done.\n' # no font in folder else: print no_font_in_folder
def generate_instance(self, instance_name, verbose=False, folder=None): '''Generate a .ufo instance with name `instance_name`, using data from the project's interpol lib.''' if self.libs['interpol'].has_key(instance_name): # master 1 master_1 = self.libs['interpol'][instance_name][0] master_1_filename = '%s_%s.ufo' % (self.name, master_1) master_1_path = os.path.join(self.paths['ufos'], master_1_filename) # master 2 master_2 = self.libs['interpol'][instance_name][1] master_2_filename = '%s_%s.ufo' % (self.name, master_2) master_2_path = os.path.join(self.paths['ufos'], master_2_filename) # interpolation factor interpol_factor = self.libs['interpol'][instance_name][2] # if both masters exist, generate instance if os.path.exists(master_1_path) and os.path.exists(master_2_path): if verbose: print 'generating %s %s (factor: %s, %s)...' % (self.name, instance_name, interpol_factor[0], interpol_factor[1]), instance_filename = '%s_%s.ufo' % (self.name, instance_name) if folder is None: instance_path = os.path.join(self.paths['instances'], instance_filename) else: instance_path = os.path.join(folder, instance_filename) # open/create fonts f1 = RFont(master_1_path, showUI=False) f2 = RFont(master_2_path, showUI=False) f3 = NewFont(showUI=False) # interpolate f3.interpolate((interpol_factor[0], interpol_factor[1]), f2, f1) f3.update() f1.close() f2.close() f3.save(instance_path) f3.close() if verbose: print 'done.\n' # instance not in lib else: if verbose: print '%s is not an instance.\n' % instance_name
def convertToTTF(otfPath, dest, report): temp = tempfile.mkstemp(suffix=".ttf")[1] tempDest = tempfile.mkstemp(suffix=".ttf")[1] font = RFont(otfPath, document=False, showInterface=False) font.lib[shouldAddPointsInSplineConversionLibKey] = 1 font.kerning.clear() for attr in font.info.asDict().keys(): if attr not in defaultFontInfoAttributes: setattr(font.info, attr, None) result = font.generate(path=temp, format="ttf", decompose=False, checkOutlines=False, autohint=False, releaseMode=True, glyphOrder=font.glyphOrder) if not font.hasInterface(): font.close() report.write(result) sourceFont = TTFont(temp) sourceFontWithTables = TTFont(otfPath) for table in ["loca", "OS/2", "cmap", "name", "GSUB", "GPOS", "GDEF", "kern"]: if table in sourceFontWithTables: sourceFont[table] = sourceFontWithTables[table] fixMetrics(sourceFont) sourceFont.save(tempDest) sourceFont.close() del sourceFont sourceFontWithTables.close() del sourceFontWithTables autohintOptions = getExtensionDefault(settingsIdentifier, defaultOptions) result = TTFAutohint(tempDest, dest, autohintOptions) report.writeItems(result) os.remove(temp) os.remove(tempDest)
def transfer_glyphs(self, var, gstring, verbose=False): """Batch transfer glyphs from one set of fonts to another. ``gstring`` A string of glyph names and/or group names. ``var`` A tuple expressing the variable space for the transfer operation. The variation tuple must contain three items, representing in this order: :: (axis, source, (dest1, dest2, dest3)) 1. the name of the variation axis (the parameter) 2. the source value in this axis (from where the glyphs will be copied from) 3. a tuple with one or more destinations for the glyphs ``verbose`` A boolean to print/supress messages during execution. :: # set parameters project_name = 'Publica' gstring = '@lowercase' var = ( 'style', 'Sans', ( 'Slab', 'Serif', ) ) parameters = { 'weight' : [ 1, 5, 9 ], 'width' : [ 5 ], var[0] : [ var[1] ], } # run script s = hSpace(project_name) s.set_parameters(parameters) s.transfer_glyphs(gstring, var, verbose=False) """ axis, src, dest_list = var # define source space for param in self.parameters.keys(): if param == axis: self.parameters[param] = [src] self.build() # get glyphs names = gstring.split(" ") groups = self.project.libs["groups"]["glyphs"] glyph_names = parse_glyphs_groups(names, groups) # batch copy print "batch transfering glyphs in %s..." % self.project.name for src_path in self.ufos(): font = hFont(RFont(src_path, showUI=False)) for dest in dest_list: dest_parameters = font.parameters dest_parameters[axis] = dest dest_file = "%s_%s.ufo" % (font.project.name, font.name_from_parameters(separator="-")) dest_path = os.path.join(font.project.paths["ufos"], dest_file) if os.path.exists(dest_path): dest_ufo = RFont(dest_path, showUI=False) print print "\tcopying glyphs from %s to %s..." % (get_full_name(font.ufo), get_full_name(dest_ufo)) if verbose: print "\t\t", for glyph_name in glyph_names: if font.ufo.has_key(glyph_name): if dest_ufo.has_key(glyph_name) is False: dest_ufo.newGlyph(glyph_name) # decompose first if len(font.ufo[glyph_name].components) > 0: font.ufo[glyph_name].decompose() if verbose: print glyph_name, # insert glyph dest_ufo.insertGlyph(font.ufo[glyph_name]) dest_ufo.save() if verbose: print print "\n...done.\n"
def run(self, destDir, progress, report=None): paths = self.controller.get() decompose = self.decompose.get() removeOverlap = self.remove_overlap.get() autohint = self.autohint.get() releaseMode = self.release_mode.get() suffix = self.generateSuffix.get() suffix = time.strftime(suffix) formats = [i for i in doodleSupportedExportFileTypes if getattr(self, i).get()] if report is None: report = Report() report.writeTitle("Batch Generated Fonts:") report.newLine() progress.update("Collecting Data...") fonts = [] for path in paths: font = RFont(path, document=False, showInterface=False) # check font info requiredFontInfo = dict(descender=-250, xHeight=500, ascender=750, capHeight=750, unitsPerEm=1000) for attr, value in requiredFontInfo.items(): existingValue = getattr(font.info, attr) if existingValue is None: setattr(font.info, attr, value) fonts.append(font) if decompose: report.writeTitle("Decompose:") report.indent() progress.update("Decompose...") progress.setTickCount(len(fonts)) for font in fonts: report.write("%s %s" % (font.info.familyName, font.info.styleName)) progress.update() font.decompose() progress.setTickCount(None) report.dedent() report.newLine() decompose = False if removeOverlap: report.writeTitle("Remove Overlap:") progress.update("Remove Overlap...") report.indent() progress.setTickCount(len(fonts)) for font in fonts: report.write("%s %s" % (font.info.familyName, font.info.styleName)) progress.update() font.removeOverlap() progress.setTickCount(None) report.dedent() report.newLine() removeOverlap = False report.writeTitle("Generate:") exportPaths = [] for index, font in enumerate(fonts): report.writeTitle((os.path.basename(paths[index]))) report.newLine() report.write("source: %s" % paths[index]) report.newLine() for format in formats: report.writeTitle("Generate %s" % format, "'") report.indent() familyName = font.info.familyName or "familyName-%s" % index familyName = familyName.replace(" ", "") styleName = font.info.styleName or "styleName-%s" % index styleName = styleName.replace(" ", "") if not self.controller.keepFileNames(): fileName = "%s-%s%s.%s" % (familyName, styleName, suffix, format) else: fileName = os.path.basename(paths[index]) fileName, _ = os.path.splitext(fileName) fileName = "%s%s.%s" % (fileName, suffix, format) progress.update("Generating ... %s" % fileName) if self.controller.exportInFolders(): fontDir = os.path.join(destDir, format) else: fontDir = destDir buildTree(fontDir) path = os.path.join(fontDir, fileName) report.write("path: %s" % path) result = font.generate(path=path, format=format, decompose=decompose, checkOutlines=removeOverlap, autohint=autohint, releaseMode=releaseMode, progressBar=progress, glyphOrder=font.glyphOrder) report.indent() report.write(result) report.dedent() exportPaths.append(path) report.dedent() report.newLine() if not font.hasInterface(): font.close() reportPath = os.path.join(destDir, "Batch Generate Report.txt") report.save(reportPath) return exportPaths
def _convertPath(self, path, destDir, saveOTF=True, saveTTF=True, saveWOFF=True, saveWOFFFormat=WOFF_TTF_FORMAT, saveWOFF2=True, saveWOFF2Format=WOFF_TTF_FORMAT, saveEOT=True, saveSVG=False, suffix="", report=None, preserveTTFhints=False): fileName = os.path.basename(path) fileName, ext = os.path.splitext(fileName) ext = ext.lower() if ext in [".ttf", ".otf"]: font = CompositorFont(path) else: font = RFont(path, document=False, showInterface=False) familyName = font.info.familyName styleName = font.info.styleName if not self.controller.keepFileNames(): fileName = "%s-%s" % (familyName, styleName) fileName += suffix fileName = fileName.replace(" ", "_") if self.controller.exportInFolders(): fontDir = os.path.join(destDir, familyName.replace(" ", ""), styleName.replace(" ", "")) else: fontDir = destDir otfPath = os.path.join(fontDir, fileName + ".otf") ttfPath = os.path.join(fontDir, fileName + ".ttf") woffPath = os.path.join(fontDir, fileName + ".woff") woff2Path = os.path.join(fontDir, fileName + ".woff2") eotPath = os.path.join(fontDir, fileName + ".eot") svgPath = os.path.join(fontDir, fileName + ".svg") # save otf if saveOTF: report.writeTitle("Build OTF", "'") report.indent() report.write("path: %s" % otfPath) buildTree(fontDir) temp = self._getTempOTF(path, report=report, preserveTTFhints=preserveTTFhints) shutil.copyfile(temp, otfPath) report.dedent() report.newLine() # save ttf if saveTTF: report.writeTitle("Build TTF", "'") report.indent() report.write("path: %s" % ttfPath) buildTree(fontDir) temp = self._getTempTTF(path, report=report, preserveTTFhints=preserveTTFhints) shutil.copyfile(temp, ttfPath) report.dedent() report.newLine() # convert to woff if saveWOFF: if saveWOFFFormat == WOFF_TTF_FORMAT: func = self._getTempTTF reportFormat = "TTF" elif saveWOFFFormat == WOFF_OTF_FORMAT: func = self._getTempOTF reportFormat = "OTF" report.writeTitle("Build WOFF (%s)" % reportFormat, "'") report.indent() report.write("path: %s" % woffPath) buildTree(fontDir) temp = func(path, report=report, preserveTTFhints=preserveTTFhints) convertToWoff(temp, woffPath) report.dedent() report.newLine() # convert to woff2 if saveWOFF2: if saveWOFFFormat == WOFF_TTF_FORMAT: func = self._getTempTTF reportFormat = "TTF" elif saveWOFFFormat == WOFF_OTF_FORMAT: func = self._getTempOTF reportFormat = "OTF" report.writeTitle("Build WOFF2 (%s)" % reportFormat, "'") report.indent() report.write("path: %s" % woff2Path) buildTree(fontDir) temp = func(path, report=report, preserveTTFhints=preserveTTFhints) convertToWoff2(temp, woff2Path) report.dedent() report.newLine() # convert to eot if saveEOT: report.writeTitle("Build EOT", "'") report.indent() report.write("path: %s" % eotPath) buildTree(fontDir) temp = self._getTempTTF(path, report=report, preserveTTFhints=preserveTTFhints) convertToEot(temp, eotPath) report.dedent() report.newLine() # convert to svg if saveSVG: report.writeTitle("Build SVG", "'") report.indent() report.write("path: %s" % svgPath) buildTree(fontDir) convertToSVG(path, svgPath) report.dedent() report.newLine() self._removeTempFiles() self._writeHTMLPreview(report.html, report.css, fileName, familyName, styleName, saveTTF, saveWOFF, saveWOFF2, saveEOT, saveSVG)