Exemplo n.º 1
0
	def addGlyphReport(self, reportString):
		lines = reportString.splitlines()
		for line in lines:
			tokenList = line.split()
			key = tokenList[0]
			x = eval(tokenList[3])
			y = eval(tokenList[5])
			hintpos = "%s %s" % (x ,y)
			if key == kCharZone:
				self.charZoneList[hintpos] = (x, y)
			elif key == kStemZone:
				self.stemZoneStemList[hintpos] = (x, y)
			elif key == kHStem:
				width = x - y
				if hintpos not in self.hStemPosList: # avoid counting duplicates
					count = self.hStemList.get(width, 0)
					self.hStemList[width] = count+1
					self.hStemPosList[hintpos] = width
			elif key == kVStem:
				width = x - y
				if hintpos not in self.vStemPosList: # avoid counting duplicates
					count = self.vStemList.get(width, 0)
					self.vStemList[width] = count+1
					self.vStemPosList[hintpos] = width
			else:
				raise ACFontError("Error: Found unknown keyword %s in report file for glyph %s." % (key, self.glyphName))
Exemplo n.º 2
0
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()))