def getOptions(): options = ACOptions() i = 1 numOptions = len(sys.argv) while i < numOptions: arg = sys.argv[i] if options.fileList and arg[0] == "-": raise ACOptionParseError("Option Error: All file names must follow all other options <%s>." % arg) if arg == "-h": logMsg(__help__) sys.exit(0) elif arg == "-u": logMsg(__usage__) sys.exit(0) elif arg == "-all": options.allStems = 1 elif arg == "-a": options.doAlign = 1 elif arg == "-d": options.debug = 1 elif arg == "-q": options.verbose = 0 elif arg == "-o": i = i +1 options.reportPath = sys.argv[i] elif arg == "-new": options.new = 1 elif arg in ["-xg", "-g"]: if arg == "-xg": options.excludeGlyphList = 1 i = i +1 glyphString = sys.argv[i] if glyphString[0] == "-": raise ACOptionParseError("Option Error: it looks like the first item in the glyph list following '-g' is another option.") options.glyphList += parseGlyphListArg(glyphString) elif arg in ["-xgf", "-gf"]: if arg == "-xgf": options.excludeGlyphList = 1 i = i +1 filePath = sys.argv[i] if filePath[0] == "-": raise ACOptionParseError("Option Error: it looks like the the glyph list file following '-gf' is another option.") try: with open(filePath, "r", encoding='utf-8') as gf: glyphString = gf.read() except (IOError,OSError): raise ACOptionParseError("Option Error: could not open glyph list file <%s>." % filePath) options.glyphList += parseGlyphListArg(glyphString) elif arg[0] == "-": raise ACOptionParseError("Option Error: Unknown option <%s>." % arg) else: arg = arg.rstrip(os.sep) # might be a UFO font. auto completion in some shells adds a dir separator, which then causes problems with os.path.dirname(). options.fileList += [arg] i += 1 if not options.fileList: raise ACOptionParseError("Option Error: You must provide at least one font file path.") return options
def main(): try: options = getOptions() except ACOptionParseError as e: logMsg(e) return 1 # verify that all files exist. haveFiles = True for path in options.fileList: if not os.path.exists(path): logMsg( "File does not exist: <%s>." % path) haveFiles = False if not haveFiles: return 1 for path in options.fileList: if options.new: if options.reportPath: reportPath = options.reportPath else: reportPath = path foundOne = checkReportExists(reportPath, options.doAlign) if foundOne: logMsg( "Skipping %s, as a report already exists." % (path)) continue try: collectStemsFont(path, options) except (ACFontError, ufotools.UFOParseError) as e: logMsg( "\t%s" % e) return 1 if options.debug: with open("rawdata.txt", "w") as fp: fp.write('\n'.join(rawData))
def main(): try: options = getOptions() except ACOptionParseError as e: logMsg(e) return 1 # verify that all files exist. haveFiles = True for path in options.fileList: if not os.path.exists(path): logMsg( "File does not exist: <%s>." % path) haveFiles = False if not haveFiles: return 1 for path in options.fileList: if options.new: if options.reportPath: reportPath = options.reportPath else: reportPath = path foundOne = checkReportExists(reportPath, options.doAlign) if foundOne: logMsg( "Skipping %s, as a report already exists." % (path)) continue try: collectStemsFont(path, options) except (ACFontError, ufotools.UFOParseError) as e: logMsg( "\t%s" % e) return 1 if options.debug: with open("rawdata.txt", "w") as fp: fp.write(tounicode('\n'.join(rawData)))
def collectStemsFont(path, options): # use fontTools library to open font and extract CFF table. # If error, skip font and report error. fontFileName = os.path.basename(path) logMsg("") if options.doAlign: logMsg( "Collecting alignment zones for font %s. Start time: %s." % (path, time.asctime())) else: logMsg( "Collecting stems for font %s. Start time: %s." % (path, time.asctime())) try: fontData = openFile(path) except (IOError, OSError): logMsg( traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1])[-1]) raise ACFontError("Error opening or reading from font file <%s>." % fontFileName) except: logMsg( traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1])[-1]) raise ACFontError("Error parsing font file <%s>." % fontFileName) # filter specified list, if any, with font list. fontGlyphList = fontData.getGlyphList() glyphList = filterGlyphList(options, fontGlyphList, fontFileName) if not glyphList: raise ACFontError("Error: selected glyph list is empty for font <%s>." % fontFileName) tempBez = fdkutils.get_temp_file_path() tempReport = f'{tempBez}.rpt' tempFI = fdkutils.get_temp_file_path() # open font plist file, if any. If not, create empty font plist. psName = fontData.getPSName() # build alignment zone string allow_no_blues = 1 noFlex = 0 vCounterGlyphs = hCounterGlyphs = [] fdGlyphDict, fontDictList = fontData.getfdInfo(psName, path, allow_no_blues, noFlex, vCounterGlyphs, hCounterGlyphs, glyphList) if fdGlyphDict == None: fdDict = fontDictList[0] with open(tempFI, "w") as fp: fp.write(fdDict.getFontInfo()) else: if not options.verbose: logMsg("Note: Using alternate FDDict global values from fontinfo file for some glyphs. Remove option '-q' to see which dict is used for which glyphs.") removeHints = 1 isCID = fontData.isCID() lastFDIndex = None glyphReports = GlyphReports() if not options.verbose: dotCount = 0 curTime = time.time() for name in glyphList: if name == ".notdef": continue if options.verbose: logMsg("Checking %s." %name) else: newTime = time.time() if (newTime - curTime) > 1: print(".", end=' ') sys.stdout.flush() curTime = newTime dotCount +=1 if dotCount > 40: dotCount = 0 print("") # Convert to bez format bezString, width, hasHints = fontData.convertToBez(name, removeHints, options.verbose) if bezString == None: continue if "mt" not in bezString: # skip empty glyphs. continue # get new fontinfo string if FD array index has changed, as # as each FontDict has different alignment zones. gid = fontData.getGlyphID(name) if isCID: # fdIndex = fontData.getfdIndex(gid) if not fdIndex == lastFDIndex: lastFDIndex = fdIndex fdDict = fontData.getFontInfo(psName, path, options.allow_no_blues, options.noFlex, options.vCounterGlyphs, options.hCounterGlyphs, fdIndex) with open(tempFI, "w") as fp: fp.write(fdDict.getFontInfo()) else: if (fdGlyphDict != None): try: fdIndex = fdGlyphDict[name][0] except KeyError: # use default dict. fdIndex = 0 if lastFDIndex != fdIndex: lastFDIndex = fdIndex fdDict = fontDictList[fdIndex] with open(tempFI, "w") as fp: fp.write(fdDict.getFontInfo()) glyphReports.startGlyphName(name) # Call auto-hint library on bez string. with open(tempBez, "w") as bp: bp.write(bezString) if options.doAlign: doAlign = "-ra" else: doAlign = "-rs" if options.allStems: allStems = "-a" else: allStems = "" command = AUTOHINTEXE + " -q %s %s -f \"%s\" \"%s\" 2>&1" % (doAlign, allStems, tempFI, tempBez) if options.debug: print(command) log = fdkutils.runShellCmd(command) if log: print(log) if "number terminator while" in log: print(tempBez) sys.exit() if os.path.exists(tempReport): with open(tempReport, "r", encoding='utf-8') as bp: report = bp.read() if options.debug: print("Wrote AC fontinfo data file to", tempFI) print("Wrote AC output rpt file to", tempReport) report.strip() if report: glyphReports.addGlyphReport(report) if options.debug: rawData.append(report) else: print("Error - failure in processing outline data") report = None h_stem_list, v_stem_list, top_zone_list, bot_zone_list = glyphReports.getReportLists() if options.reportPath: reportPath = options.reportPath else: reportPath = path PrintReports(reportPath, h_stem_list, v_stem_list, top_zone_list, bot_zone_list) fontData.close() logMsg( "Done with font %s. End time: %s." % (path, time.asctime()))
def collectStemsFont(path, options): # use fontTools library to open font and extract CFF table. # If error, skip font and report error. fontFileName = os.path.basename(path) logMsg("") if options.doAlign: logMsg( "Collecting alignment zones for font %s. Start time: %s." % (path, time.asctime())) else: logMsg( "Collecting stems for font %s. Start time: %s." % (path, time.asctime())) try: fontData = openFile(path) except (IOError, OSError): logMsg( traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1])[-1]) raise ACFontError("Error opening or reading from font file <%s>." % fontFileName) except: logMsg( traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1])[-1]) raise ACFontError("Error parsing font file <%s>." % fontFileName) # filter specified list, if any, with font list. fontGlyphList = fontData.getGlyphList() glyphList = filterGlyphList(options, fontGlyphList, fontFileName) if not glyphList: raise ACFontError("Error: selected glyph list is empty for font <%s>." % fontFileName) tempBez = fdkutils.get_temp_file_path() tempReport = '{}{}'.format(tempBez, ".rpt") tempFI = fdkutils.get_temp_file_path() # open font plist file, if any. If not, create empty font plist. psName = fontData.getPSName() # build alignment zone string allow_no_blues = 1 noFlex = 0 vCounterGlyphs = hCounterGlyphs = [] fdGlyphDict, fontDictList = fontData.getfdInfo(psName, path, allow_no_blues, noFlex, vCounterGlyphs, hCounterGlyphs, glyphList) if fdGlyphDict == None: fdDict = fontDictList[0] with open(tempFI, "w") as fp: fp.write(tounicode(fdDict.getFontInfo())) else: if not options.verbose: logMsg("Note: Using alternate FDDict global values from fontinfo file for some glyphs. Remove option '-q' to see which dict is used for which glyphs.") removeHints = 1 isCID = fontData.isCID() lastFDIndex = None glyphReports = GlyphReports() if not options.verbose: dotCount = 0 curTime = time.time() for name in glyphList: if name == ".notdef": continue if options.verbose: logMsg("Checking %s." %name) else: newTime = time.time() if (newTime - curTime) > 1: print(".", end=' ') sys.stdout.flush() curTime = newTime dotCount +=1 if dotCount > 40: dotCount = 0 print("") # Convert to bez format bezString, width, hasHints = fontData.convertToBez(name, removeHints, options.verbose) if bezString == None: continue if "mt" not in bezString: # skip empty glyphs. continue # get new fontinfo string if FD array index has changed, as # as each FontDict has different alignment zones. gid = fontData.getGlyphID(name) if isCID: # fdIndex = fontData.getfdIndex(gid) if not fdIndex == lastFDIndex: lastFDIndex = fdIndex fdDict = fontData.getFontInfo(psName, path, options.allow_no_blues, options.noFlex, options.vCounterGlyphs, options.hCounterGlyphs, fdIndex) with open(tempFI, "w") as fp: fp.write(tounicode(fdDict.getFontInfo())) else: if (fdGlyphDict != None): try: fdIndex = fdGlyphDict[name][0] except KeyError: # use default dict. fdIndex = 0 if lastFDIndex != fdIndex: lastFDIndex = fdIndex fdDict = fontDictList[fdIndex] with open(tempFI, "w") as fp: fp.write(tounicode(fdDict.getFontInfo())) glyphReports.startGlyphName(name) # Call auto-hint library on bez string. with open(tempBez, "w") as bp: bp.write(tounicode(bezString)) if options.doAlign: doAlign = "-ra" else: doAlign = "-rs" if options.allStems: allStems = "-a" else: allStems = "" command = AUTOHINTEXE + " -q %s %s -f \"%s\" \"%s\" 2>&1" % (doAlign, allStems, tempFI, tempBez) if options.debug: print(command) log = fdkutils.runShellCmd(command) if log: print(log) if "number terminator while" in log: print(tempBez) sys.exit() if os.path.exists(tempReport): with open(tempReport, "r", encoding='utf-8') as bp: report = bp.read() if options.debug: print("Wrote AC fontinfo data file to", tempFI) print("Wrote AC output rpt file to", tempReport) report.strip() if report: glyphReports.addGlyphReport(report) if options.debug: rawData.append(report) else: print("Error - failure in processing outline data") report = None h_stem_list, v_stem_list, top_zone_list, bot_zone_list = glyphReports.getReportLists() if options.reportPath: reportPath = options.reportPath else: reportPath = path PrintReports(reportPath, h_stem_list, v_stem_list, top_zone_list, bot_zone_list) fontData.close() logMsg( "Done with font %s. End time: %s." % (path, time.asctime()))