def build_font(self, dir_name, familyname, fontname, fullname): '''Builds the font file.''' self.font = font = fontforge.font() # height = 32 font.descent = 4 * SQUARE_SIZE font.ascent = 8 * SQUARE_SIZE # font.em = 28 # font.design_size = 12 font.upos = -2 * SQUARE_SIZE font.uwidth = SQUARE_SIZE font.fontname = fontname font.familyname = familyname font.fullname = fullname font.encoding = 'unicode' if 'bold' in fontname.lower(): font.weight = 'Bold' if 'oblique' in fontname.lower(): font.italicangle = -10.0 if 'boldoblique' in fontname.lower(): font.appendSFNTName(0x0409, 'SubFamily', 'Bold Oblique') font.addLookup('Anchors', 'gpos_mark2base', (), ( ("mark", (("DFLT", ("dflt")),)), )) font.addLookupSubtable('Anchors', 'DiacriticTop') font.addAnchorClass('DiacriticTop', 'Top') font.addLookupSubtable('Anchors', 'DiacriticBottom') font.addAnchorClass('DiacriticBottom', 'Bottom') reader = Reader( *sorted(kitabyte.reader.get_font_def_filenames(dir_name))) deferred_glyph_defs = [] for glyph_def in kitabyte.reader.read_font_def(reader): if isinstance(glyph_def, Glyph): try: _logger.debug('Processing u+%x %s', glyph_def.char_code, fontforge.nameFromUnicode(glyph_def.char_code)) self._make_glyph(glyph_def) except (EnvironmentError, ValueError): _logger.debug('Deferring glyph u+%x %s', glyph_def.char_code, fontforge.nameFromUnicode(glyph_def.char_code)) deferred_glyph_defs.append(glyph_def) for glyph_def in deferred_glyph_defs: _logger.debug('Processing u+%x %s', glyph_def.char_code, fontforge.nameFromUnicode(glyph_def.char_code)) self._make_glyph(glyph_def) font.selection.all() font.removeOverlap() font.simplify() font.correctDirection() return font
def test(): font0 = fontforge.open('fonts/gbsn00lp.ttf') c0 = fontforge.nameFromUnicode(ord(u'艹')) c1 = fontforge.nameFromUnicode(ord(u'五')) cy = fontforge.nameFromUnicode(ord(u'\uE000')) g0 = font0[c0] g1 = font0[c1] l0 = g0.layers[1] l1 = g1.layers[1] l0.transform(psMat.scale(1,0.9)) l0.transform(psMat.translate(0,250)) l1.transform(psMat.scale(1, 0.5)) l1.transform(psMat.translate(0,-104)) #l1.transform(psMat.rotate(1.7)) g0.layers[1] = l0 + l1 font0.selection.select(c0) font0.copy() font0.selection.select(cy) font0.paste() font0.generate('output/out.ttf')
def str2glyphName(char): if char == ".point": char = "." codepoint = fontforge.unicodeFromName(char) if codepoint != -1: glyphName = fontforge.nameFromUnicode(codepoint) else: codes = codepoints.from_unicode(char) if len(codes) == 1: glyphName = fontforge.nameFromUnicode(codes[0]) else: glyphName = char return glyphName
def ligname_tuple(ligname): returns = {'name': None, 'parts': None, 'chars': None} for atom in ligname.split(' '): if atom.endswith('.liga'): returns['name'] = atom try: parts = atom.split('.')[0].split('_') chars = ''.join([chr(ff.unicodeFromName(c)) for c in parts]) if not returns['parts']: returns['parts'] = parts if not returns['chars']: returns['chars'] = chars except: pass else: returns['chars'] = atom try: parts = [ff.nameFromUnicode(ord(c)) for c in atom] ligname = '_'.join(parts) + '.liga' returns['parts'] = parts if not returns['name']: returns['name'] = ligname except: pass return tuple(returns.values())
def kerningFont(font): try: font.addLookup("table", "gpos_pair", (), (("liga", (("latn", ("dflt")), )), )) except EnvironmentError: print("Lookup Table already exists") try: font.addLookupSubtable("table", "subtable") except EnvironmentError: print("Lookup Subtable already exists") print(font.getLookupInfo("table")) for glyph in list(font.glyphs()): # charnum = fontforge.unicodeFromName # print(glyph) # glyph.addPosSub("subtable","f",-3) # print("ok") try: for glyphPair, rawKern in metrics["kerning"][ glyph.glyphname].items(): kern = rawKern * resize print(kern) print(glyph) glyphPairName = fontforge.nameFromUnicode(ord(glyphPair)) print(glyphPairName) glyph.addPosSub( "subtable", glyphPairName, int(kern)) #in fontforge, kerning value must be an integer except KeyError: print("metrics {} are not found".format(glyph))
def make_relevant_subset(cls): """ A string of all characters to be used for finding the glyph spacing. Glyphs that are wider than those listed here can be shrunk a little more. For example a capital 'W' might have space around it, because a some rarely used symbol, like 'Æ' needs more room. If by shrinking those rarely used glyphs a little more, we can reduce spacing around most characters without shrinking them, it is considered worthwhile. """ str_char_range = lambda start, end: \ "".join([chr(x) for x in range(ord(start), ord(end) + 1)]) ascii_lower = str_char_range('a','z') ascii_upper = str_char_range('A','Z') ascii_num = str_char_range('0','9') symbols = '$@(){}[]' unicode_extras = u"" relevant_chars = u"" + ascii_lower + ascii_upper + ascii_num + symbols + \ unicode_extras relevant_chars = relevant_chars.replace('W','') relevant_chars = relevant_chars.replace('w','') relevant_subset = [fontforge.nameFromUnicode(ord(c)) for c in relevant_chars] return relevant_subset
def _byValue(self, name): """Return a tuple of unicode codepoint and name if name is the string representation of the unicodepoint otherwise Retun False. Name is translated by fontforge.nameFromUnicode().""" try: uni = ord(name) return (uni, str(fontforge.nameFromUnicode(uni))) except TypeError, e: return False
def select_with_refs(font, unicode, newfont, pe = None, nam = None): newfont.selection.select(('more', 'unicode'), unicode) if nam: print >> nam, "0x%0.4X" % unicode, fontforge.nameFromUnicode(unicode) if pe: print >> pe, "SelectMore(%d)" % unicode try: for ref in font[unicode].references: #print unicode, ref newfont.selection.select(('more',), ref[0]) if nam: print >> nam, "0x%0.4X" % ref[0], fontforge.nameFromUnicode(ref[0]) if pe: print >> pe, 'SelectMore("%s")' % ref[0] except: print 'Resolving references on u+%04x failed' % unicode
def select_with_refs(font, unicode, newfont, pe=None, nam=None): newfont.selection.select(('more', 'unicode'), unicode) if nam: print >> nam, "0x%0.4X" % unicode, fontforge.nameFromUnicode(unicode) if pe: print >> pe, "SelectMore(%d)" % unicode try: for ref in font[unicode].references: #print unicode, ref newfont.selection.select(('more', ), ref[0]) if nam: print >> nam, "0x%0.4X" % ref[0], fontforge.nameFromUnicode( ref[0]) if pe: print >> pe, 'SelectMore("%s")' % ref[0] except: print 'Resolving references on u+%04x failed' % unicode
def _make_glyph(self, glyph_def): '''Creates a FontForge glyph using the given Glyph.''' font = self.font if glyph_def.char_code == -1: glyph = font.createChar(-1, '.notdef') else: glyph = font.createChar(glyph_def.char_code) glyph.clear() glyph.manualHints = True glyph_sizes = self._calc_glyph_sizes(glyph_def) self._draw_glyph_rows(glyph, glyph_def, glyph_sizes) self._add_anchors(glyph, glyph_def, glyph_sizes) for arg in glyph_def.args: if arg.startswith(u'reference:'): code = int(arg.split(u':', 1)[1].lstrip('uU+'), 16) glyph.addReference(fontforge.nameFromUnicode(code)) elif arg.startswith(u'diacritic:'): code = int(arg.split(u':', 1)[1].lstrip('uU+'), 16) glyph.appendAccent(fontforge.nameFromUnicode(code)) # if not ('oblique' in font.fontname.lower() or \ # 'bold' in font.fontname.lower()): # self._add_row_hints(glyph, glyph_def, glyph_sizes) # self._add_col_hints(glyph, glyph_def, glyph_sizes) if 'oblique' in font.fontname.lower(): glyph.transform(psMat.skew(math.pi / 180 * 10), ('partialRefs',)) if u'combining' in glyph_def.args: glyph.width = 0 else: glyph.width = glyph_sizes.square_size * 8
def subfont(origin_font, template_font, unicodes, output_path): font0 = origin_font font1 = template_font # 令字大一致 font1.em = font0.em font1.selection.all() font1.clear() for u in unicodes: try: uname = fontforge.nameFromUnicode(ord(u)) font0.selection.select(uname) font0.copy() font1.selection.select(uname) font1.paste() except ValueError: continue font1.generate(output_path + ".ttf") cmd = "./ttf2eot < %s.ttf > %s.eot" % (output_path, output_path) os.system(cmd) font1.generate(output_path + ".woff")
import sys import fontforge infile = sys.argv[1] feafile = sys.argv[2] hcr = fontforge.open(infile) family = hcr.familyname[4:] ### turn on vertical metrics hcr.hasvmetrics = 1 for gl in hcr.glyphs(): if gl.unicode >= 0: gl.glyphname = fontforge.nameFromUnicode(gl.unicode) gl.vwidth = 1050 else: if feafile.find("win") > 0: gl.vwidth = 1050 elif gl.width > 0: gl.vwidth = 1050 else: gl.vwidth = 0 hcr["space"].vwidth = 525 ### make jungseong/jongseong full-width for j in range(0x1100, 0x115F) + range(0xA960, 0xA97D): jamo = "uni%04X" % j hcr[jamo].left_side_bearing = (hcr[jamo].left_side_bearing +
font = fontforge.open(FONT) original = fontforge.open(BASE_FONT) #letters = "kK" letters = glob.glob("%s/*.svg" % LETTERS_DIR) for letter in letters: letter = letter.split("/")[-1].replace(".svg", "") print letter try: # Convert HTML entity to unicode name char = letter.replace("&#", "").replace(";", "") char = fontforge.nameFromUnicode(int(char)) print char expand(char, WEIGHT) except TypeError: # In case it still doesn't work, it passes. i.e: € print "%s was not expanded." % char pass # Gets space character from original font font.createMappedChar("space") font["space"].width = original["space"].width font.familyname = "%s" % (BASE_NAME) font.fontname = "%s-%s" % (BASE_NAME, WEIGHT) font.fullname = "%s %s" % (BASE_NAME, WEIGHT) font.weight = "%d" % WEIGHT
def log_namelist(nam, unicode): if nam and isinstance(unicode, int): print >> nam, "0x%0.4X" % unicode, fontforge.nameFromUnicode(unicode)
# print('DEBUG: svg', svgfile) try: src = svgfile.split('_')[0] uni = int(src, 16) except: print('ERROR: Invalid glyph unicode value in file name: %s' % (svgfile.split('_')[0])) exit(1) else: if uni in src_unis: # one design per glyph print('ERROR: Duplicate glyph name %s\t%06d\t%s' % (svgfile, uni, str(gname))) exit(1) else: src_unis.append(uni) gname = nameFromUnicode(uni) if font: glyph = font.createChar(uni, gname) glyph.clear() if src != '0020': #TODO test glyph.importOutlines(path.join(glyphDir, svgfile)) glyph.width = 725 #TODO how to set this globally? else: # Test run from outside of Fontforge print('INFO: found %s\t%06d\t%s' % (svgfile, uni, str(gname))) dst_unis = [] with open('/home/sander/workspace/neude/src/fonts/refs.tsv', 'r') as refs: for line in refs: line = line.strip() if '\t' in line and line[0] != '#':
font.weight = "Medium" # setting the width if args.width == None: font.os2_weight = 5 # default else: font.os2_weight = args.width # setting the font comment font.comment = "Created with mf2outline." if args.verbose: print "Importing glyphs and adding glyph metrics..." glyph_files = glob.glob(os.path.join(tempdir, "*.eps")) for eps in glyph_files: code = int(os.path.splitext(os.path.basename(eps))[0],16) # string is in hexadecimal if args.encoding == "unicode": glyph = font.createChar(code,fontforge.nameFromUnicode(code)) else: glyph = font.createMappedChar(code) if not ((args.encoding == "unicode") and (code == 32) or (args.encoding == "t1" and code == 23)): # do not read space/cwm (it will be empty) glyph.importOutlines(eps, ("toobigwarn", "correctdir")) with open(eps, "r") as epsfile: for line in epsfile: if line[0] == "%": # only look at comments words = line.split() if len(words) > 1 and words[1] == "mf2outline:": # we read only comments made by mpfont.mp if words[2] == "charwd": # the width of the current char glyph.width = round(float(words[3]) *1000 / args.designsize) elif words[2] == "charht": # the height of the current char glyph.texheight = round(float(words[3]) *1000 / args.designsize) elif words[2] == "chardp": # the depth of the current char glyph.texdepth = round(float(words[3]) *1000 / args.designsize)
def log_namelist(nam, unicode): if nam and isinstance(unicode, int): print(f"0x{unicode:04X}", fontforge.nameFromUnicode(unicode), file=nam)
font[char].importOutlines(f) font[char].autoTrace() # Set bearings to 0 font[char].left_side_bearing = 0 font[char].right_side_bearing = 0 # AutoWidth: separation, MinBearing, MaxBearing for f in files: letter = f.split("/")[-1].replace(".png", "") char = fontforge.unicodeFromName(letter) if char == -1: char = letter.replace("&#", "").replace(";", "") letter = fontforge.nameFromUnicode(int(char)) print "letter: %s" % letter print "char: %s" % char importGlyph(f, letter, int(char)) bottom = font["h"].boundingBox()[1] top = font["h"].boundingBox()[3] height = top - bottom scale_ratio = 780 / height scale_matrix = psMat.scale(scale_ratio) translate_matrix = psMat.translate(0, font.descent * scale_ratio) matrix = psMat.compose(scale_matrix, translate_matrix) print matrix # Series of transformations on all glyphs
def charname(char): # Give the fontforge name for the given character. return fontforge.nameFromUnicode(ord(char))
def resetGlyphNames ( font, names = 'AGL For New Fonts' ) : for glyph in font : if font[ glyph ].unicode != -1 : font[ glyph ].glyphname = fontforge.nameFromUnicode( font[ glyph ].unicode, names )
def glyph_name(unic): return fontforge.nameFromUnicode(ord(unic))
import sys import fontforge infile = sys.argv[1] feafile = sys.argv[2] hcr = fontforge.open(infile) family = hcr.familyname[4:] ### turn on vertical metrics hcr.hasvmetrics = 1 for gl in hcr.glyphs(): if gl.unicode >= 0: gl.glyphname = fontforge.nameFromUnicode(gl.unicode) gl.vwidth = 1050 else: if feafile.find("win") > 0: gl.vwidth = 1050 elif gl.width > 0: gl.vwidth = 1050 else: gl.vwidth = 0 hcr["space"].vwidth = 525 ### make jungseong/jongseong full-width for j in range(0x1100,0x115F)+range(0xA960,0xA97D): jamo = "uni%04X" % j hcr[jamo].left_side_bearing = (hcr[jamo].left_side_bearing + hcr[jamo].right_side_bearing) /2