Example #1
0
def main():
    global newfont, oldfont, fontName
    newfont = fontforge.font()
#    newfont.em = 2048
    oldfont = fontforge.open("Gregoria.otf")
    fontName = "gregoria"
    newfont.encoding="ISO10646-1"
    newfont.fontname="gregoriao"
    newfont.fullname="gregoriao"
    newfont.familyname="gregoriao"
    newfont.weight=oldfont.weight
    newfont.copyright=oldfont.copyright
    first_step()
    adjustAdditionalGlyphs()
    oldfont.close()
    oldfont = fontforge.open("Gregoria-Deminutae.otf")
    fontName="gregoria-deminutae"
    first_step()
    adjustAdditionalGlyphs()
    oldfont.close()
    oldfont = fontforge.open("Gregoria-Auctae.otf")
    fontName="gregoria-auctae"
    first_step()
    adjustAdditionalGlyphs()
    oldfont.close()
    newfont.em = 2048
    newfont.generate("gregoriao.ttf")
    newfont.close()
Example #2
0
def generate_lettering(se_path, om_path, le_path, weight, version):
    # Oradana明朝 を開く
    font = fontforge.open(om_path)

    # EMの大きさを2048に設定する
    font.em = 2048

    # SpecialElite を開く
    sefont = fontforge.open(se_path)

    # SpecialElite に含まれるグリフを削除する
    font.selection.none()
    sefont.selection.all()
    for glyph in sefont.selection.byGlyphs:
        if glyph.glyphname in font:
            font.selection.select(("more",), glyph.glyphname)
    font.clear()
        
    # SpecialElite をマージする
    font.mergeFonts(se_path)

    # フォント情報の設定
    font.sfnt_names = lettering_sfnt_names(weight, version)
    font.os2_vendor = "ltrg"

    # Grid Fittingの設定
    font.gasp = lettering_gasp()

    # TTF の生成
    font.generate(le_path, '', ('short-post', 'opentype', 'PfEd-lookups'))
Example #3
0
def main():
    os.makedirs('generated/', exist_ok = True)

    # Merge math-upright (which contains U+1D53D, a double-struck F)
    # into Calluna Sans.
    calluna_sans = fontforge.open('original/calluna-sans.otf')
    calluna_sans.mergeFonts('extra/math-upright.sfd')
    calluna_sans.generate('generated/calluna-sans.otf', flags = 'opentype')
    calluna_sans.close()

    prune_font('generated/calluna-sans.otf', 'generated/')

    # Merge math-italic (which contains a sigma) into Calluna Sans Italic.
    calluna_sansi = fontforge.open('original/calluna-sans-italic.otf')
    calluna_sansi.mergeFonts('extra/math-italic.sfd')
    calluna_sansi.generate('generated/calluna-sans-italic.otf', flags = 'opentype')
    calluna_sansi.close()

    prune_font('generated/calluna-sans-italic.otf', 'generated/')

    # Just copy over the other fonts, prune them in the process.
    prune_font('original/calluna-bold.otf',      'generated/')
    prune_font('original/calluna-italic.otf',    'generated/')
    prune_font('original/calluna.otf',           'generated/')
    prune_font('original/calluna-sans-bold.otf', 'generated/')
    prune_font('original/inconsolata.otf',       'generated/')
Example #4
0
def modFont(fontFile, style, outDir, newFamilyName, changeHints, legacyKern, addWeight, stripPanose, modBearings,
            nameHack):
    # Open font file and immediately save as a fontforge file
    f = fontforge.open(fontFile.strip())
    newFontFile = os.path.normpath(outDir+"/"+newFamilyName+"-"+style+".sfd")
    newFontTTF = os.path.normpath(outDir+"/"+newFamilyName+"-"+style+".ttf")

    f.save(newFontFile)
    f.close()

    # Open new fontforge file
    f = fontforge.open(newFontFile)

    # Set the font names in the SFNT names table
    setNames(f, newFamilyName, style)

    # Replace PANOSE Data with "Any", or 0
    if stripPanose:
        f.os2_panose = (0,0,0,0,0,0,0,0,0,0)

    # Iterate over all glyphs in font, and darken regular and italic fonts only
    allGlyphs=f.glyphs()
    for glyph in allGlyphs:
        if style in (FNT_REGULAR, FNT_ITALIC) and addWeight:
            changeWeight(glyph, addWeight, modBearings)
        # Make some modifications to better suit truetype outlines
        modLayer(glyph)
        # Autohint glyph
        if changeHints == "auto":
            glyph.autoHint()

    # If I've understood things correctly, this should be the same as setting the curves in the
    # font information screen of the GUI
    for l in range(0, f.layer_cnt):
        if not f.layers[l].is_quadratic:
            f.layers[l].is_quadratic = True
            print("The curves in the "+f.layers[l].name+" layer were converted to be quadratic")

    print("\nSaving "+newFontTTF+". . .\n")

    flagsTTF = generateFlags(changeHints, legacyKern)
    f.generate(newFontTTF, flags=flagsTTF)

    f.save(newFontFile)
    f.close()

    try:
        os.remove(newFontFile)
    except:
        print('There was an error removing the file!')
    """
    This is an ugly workaround to the font renaming issue some fonts seem to have
    One day, I hope to find a proper fix, or a more elegent workaround
    """
    if nameHack:
        f = fontforge.open(newFontTTF)
        setNames(f, newFamilyName, style)
        f.generate(newFontTTF, flags=flagsTTF)
        f.close()
Example #5
0
def reset_config(origin_font, tpl_font):
    global c_font, c_tpl_font, c_emsize, c_halfsize, c_descent, c_middle
    c_font = fontforge.open(origin_font)
    c_tpl_font = fontforge.open(tpl_font)
    c_emsize = c_font.em - 100
    c_halfsize = c_emsize / 2
    c_descent = c_font.descent - 50
    c_middle = c_halfsize - c_descent
Example #6
0
def prepare_font():
    global BASE_FONT
    global TMP_FONT
    global FONT
    fontbase = fontforge.open(BASE_FONT)
    # Delta char has conflict by otf generation, so delete it
    fontbase["Delta"].clear()
    fontbase.generate(TMP_FONT)
    FONT = fontforge.open(TMP_FONT)
def patch_fonts(source_file, target_files, rename_font=True):
	source_font = fontforge.open(source_file.name)
	for target_file in target_files:
		target_font = fontforge.open(target_file.name)
		try:
			patch_one_font(source_font, target_font, rename_font)
		finally:
			target_font.close()
	return 0
Example #8
0
 def load_font(self, fontpath):
   if fontpath.find('/') >= 0 and cadmium._abs_fontpath_allowed_:
     return fontforge.open(fontpath)
   else:
     # Lookup in fonts directory
     if os.path.exists(cadmium._font_dir_):
       available_fonts = os.listdir(cadmium._font_dir_)
       if fontpath in available_fonts:
         return fontforge.open(os.path.join(cadmium._font_dir_, fontpath))
   raise Exception('Font not found')
Example #9
0
def main():
    args = parse_args()
    source_font = fontforge.open(args.source_font.name)
    target_font = fontforge.open(args.target_font.name)
    new_font = args.new_font
    glyphs = source_font.glyphs() if args.all_glyphs else args.glyphs
    new_suffix = args.new_suffix if args.new_suffix else ''
    overwrite = args.overwrite
    copy_glyphs(glyphs, source_font, target_font, new_font,
                new_suffix, overwrite)
    args.source_font.close()
    args.target_font.close()
Example #10
0
def featureChange(Font, Feature, ResultFont, FontName):
    font1 = fontforge.open(Font)
    font1.save(TMP_FONT)
    font = fontforge.open(TMP_FONT)
    for l in font.gsub_lookups:
        font.removeLookup(l)
    font.mergeFeature(Feature)
    font.fullname = FontName
    font.familyname = FontName
    font.fontname = FontName
    font.version = "1.0"
    font.generate(ResultFont)
Example #11
0
    def __init__(self, aFontFamily, aFontDir, aConfig):
        self.mFontFamily = aFontFamily

        self.mDelimiters = aConfig.DELIMITERS
        self.mDelimitersExtra = aConfig.DELIMITERS_EXTRA
        self.mFontSplittingExtra = aConfig.FONTSPLITTING_EXTRA

        # Open the fonts
        self.mMathFont = fontforge.open("%s/%s" % (aFontDir, aConfig.MATHFONT))
        self.mMainFonts = {}
        for key in aConfig.MAINFONTS:
            self.mMainFonts[key] = \
                fontforge.open("%s/%s" % (aFontDir, aConfig.MAINFONTS[key]))

        # Pointer to the PUA to store the horizontal/vertical components
        self.mPUAPointer=0xE000
        self.mPUAContent=dict()

        self.mMovedNonUnicodeGlyphs=dict()

        # Lists of stretchy operators
        self.mStretchyOperators=dict()

        # List of normal size glyphs
        self.mNormalSize=[]

        # Determine the maximum size
        self.mMaxSize = 0
        for glyph in self.mMathFont.glyphs():
            if (glyph.unicode == -1):
                continue

            if (glyph.horizontalVariants is not None):
                variants = glyph.horizontalVariants.split()
            elif (glyph.verticalVariants is not None):
                variants = glyph.verticalVariants.split()
            else:
                continue

            n = len(variants)
            if variants[0] == glyph.glyphname:
                n -= 1 # ignore the normal size variant
            self.mMaxSize = max(self.mMaxSize, n)

        # Create a new font for each size
        self.mMathSize=[]
        for i in range(0, self.mMaxSize):
            self.mMathSize.append(newFont(self.mFontFamily,
                                          "%s/%s" % (aFontDir,
                                                     aConfig.MATHFONT),
                                          aConfig,
                                          "Size%d" % (i+1), "Regular"))
Example #12
0
def featureChange(Font, Feature, ResultFont):
    font1 = fontforge.open(Font)
    font1.save(TMP_FONT)
    font = fontforge.open(TMP_FONT)
    for l in font.gsub_lookups:
        font.removeLookup(l)
    font.mergeFeature(Feature)
    resultName = ResultFont.split(".ttf")[0]
    font.fullname = resultName
    font.familyname = resultName
    font.fontname = resultName
    font.version = "7.7"
    font.generate(resultName+".ttf")
Example #13
0
def deobliqize(outfont, infont):
	glyphs = ("parenleft", "parenright", "exclam",
			"bracketleft", "bracketright",
			"braceleft", "braceright",)
	font = fontforge.open(infont)
	for glyph in glyphs:
		font.selection.select(("more", "singletons"), glyph)
	font.copy()

	font2 = fontforge.open(outfont)
	for glyph in glyphs:
		font2.selection.select(("more", "singletons"), glyph)
	font2.paste()
	font.close()
	font2.save(outfont)
Example #14
0
    def testGlyphConsistency(self):
        cm = GlyphConsistency()
        testfont = fontforge.open("unittests/lohit.ttf")
        test1 = cm.glyph_basicConsistency(testfont,(0x900,0x97f))
        testfont = fontforge.open("unittests/lohit.ttf")
        test2 = cm.glyph_basicset_consistency(testfont,(0x900,0x97f))
        testfont = fontforge.open("unittests/lohit.ttf")
        test3 = cm.glyph_round_consistency(testfont,(0x900,0x97f),50)

        test = (0 <= test1[0][1] <= 10)
        self.failUnless(test)
        test2 = (0 <= test2 <= 10)
        self.failUnless(test2)
        test3 = (0 <= test3 <= 10)
        self.failUnless(test3)
Example #15
0
def process_fonts(ref_paths, fnt_paths, save_to, merge, copy_metrics):
    for ref in ref_paths:
        reference = fontforge.open(ref)
        ref_width = FontScaler.most_common_width(reference)
        print(">>> For reference font {}:".format(reference.familyname))
        for fnt in fnt_paths:
            fallback = fontforge.open(fnt)
            print(">>> - Monospacifying {}".format(fallback.familyname))
            gscaler = StretchingGlyphScaler(ref_width, FontScaler.average_width(fallback))
            path = make_monospace(reference, fallback, gscaler, save_to, copy_metrics)
            if merge:
                monospacified = fontforge.open(path)
                print(">>> - Merging with {}".format(monospacified.familyname))
                path = merge_fonts(reference, monospacified, save_to)
            yield (reference.familyname, fallback.familyname, path)
def print_private( fontPath ):
	font = fontforge.open( fontPath )

	print  '<div style="font-family: \'' + font.familyname + '\'; ' \
			 '\">'
	print  '<h2>Private Use Area in  ' + font.fontname + '</h2>'

	font.selection.select(("ranges",None),0xe000,0xf8ff)
	print  '<table>'
	for g in font.selection.byGlyphs:
		print  '<tr><td>'
		print '%s%0.4x%s' %( "0x", g.encoding, "" )
		print  '</td><td>'
		print  '' + g.glyphname
		print  '</td><td>'
		if g.getPosSub( '*' ):
			print "is ligature"
		if g.references:
			print "has references"
		print  '</td><td>'
		print  '</td></tr>'
		
	print  '</table>'
	print  '</div>'
	sys.stdout.flush()
Example #17
0
    def fontDownloader(self, destinationFolder = False):

      if destinationFolder:
        self.fontfaceFolder = destinationFolder
      else:
        self.fontfaceFolder = self.fontName


      fontsFolder = self.fontfaceFolder + '/' + 'fonts'
      if not os.path.exists(fontsFolder):
        os.makedirs(fontsFolder)

      css = self.fontfaceFolder + '/' + self.fontName + '.css'  
      opener = build_opener()
      opener.addheaders = {('Referer', self.typekitUrl)}


      for item in self.fontInfo:

        alias = item['preview']['alias']
        fvd = item['preview']['fvd']
        subset = item['preview']['subset']

        fontUrl = baseUrl % (alias, fvd, subset, self.token)
        print fontUrl
        
        otf = opener.open(fontUrl).read()

        dump = fontsFolder + '/' + self.fontSlug +'-'+ item['name'].lower() + '.font'
        open(dump,'w+').write(otf)

        fontfactory = fontforge.open(dump, 1)
        fontfactory.fontname = self.fontName.replace(" ", "") + item["name"].replace(" ", "")
        fontfactory.familyname = self.fontName
        fontfactory.fullname = self.fontName + ' ' + item["name"]
        extensions = ['.eot', '.ttf', '.otf', '.svg', '.woff']
        for ext in extensions:

          fontfactory.generate(fontsFolder + '/' + fontfactory.fullname + ext)
        
        try:
          os.remove(dump)
          # for some reason, probably an error during conversion, an .afm file in created
          # the code bellow removes the .afm file if it does exists.
          os.remove(fontsFolder + '/' + fontfactory.fullname + '.afm')
        except:
          pass

        template = "@font-face {\
          \n\tfont-family: '" + fontfactory.fullname + "';\
          \n\tsrc: url('fonts/" + fontfactory.fullname + ".eot');\
          \n\tsrc: url('fonts/" + fontfactory.fullname + ".eot?#iefix') format('embedded-opentype'),\
          \n\turl('fonts/" + fontfactory.fullname + ".woff') format('woff'),\
          \n\turl('fonts/" + fontfactory.fullname + ".ttf') format('truetype'),\
          \n\turl('fonts/" + fontfactory.fullname + ".svg#ywftsvg') format('svg');\
          \n\tfont-style: normal;\
          \n\tfont-weight: normal;\
          \n}\n\n"

        open(css, 'a').writelines(template)
Example #18
0
def process_font(filename, n=-1, chars=None):
    font = fontforge.open(filename)
    if n <= 0:
        n = len(font) 
    for i, name in enumerate(font):
        if i >= n:
            break
        print "process  [%s - %d/%d]" % (name, i, n)
        glyph = font[name]
        glyph_new = process_glyph(glyph)
        pen = glyph.glyphPen(True)

        for layer in glyph_new:
            for c in layer:
                x0, y0, f = c[0]
                pen.moveTo((x0, y0))
                i = 1
                nr = len(c)
                while i < nr:
                    x1, y1, f1 = c[i]
                    if f1:
                        pen.lineTo((x1, y1))
                        i += 1
                    else:
                        x2, y2, f2 = c[i + 1]
                        pen.curveTo((x1, y1), (x2, y2))
                        i += 2
                pen.closePath()
        pen = None
    font.generate("new.ttf")
Example #19
0
def setFontInfo(source,family,feature):
  font = fontforge.open(source)
  font.familyname = family
  font.fontname = family + '-' + feature
  font.fullname = family + ' ' + feature
  font.version = version
  font.copyright = copyright
def checkGlyphNumbers( fontDir, fontFile ):
	if isinstance( fontFile, ( list, tuple ) ):
		print( "In directory " + fontDir )
		for fontName in fontFile:
			checkGlyphNumbers( fontDir, fontName )
		return

	print( "Checking slot numbers in " + fontFile )
	font = fontforge.open( path.join( fontDir, fontFile ) )

	g = font.selection.all()
	g = font.selection.byGlyphs

	valid = True
	for glyph in g:
		if isSpecialTrueType( glyph ):
			# FIXME really should complain if it DOESNT exist
			pass
		elif inPrivateUseRange( glyph ):
			if glyph.unicode != -1:
				print( "Glyph at slot " + str( glyph.encoding )
					+ " is Private Use but has Unicode" )
				problem = True
		else:
			if glyph.encoding != glyph.unicode:
				print( "Glyph at slot " + str( glyph.encoding )
					+ " has wrong Unicode" )
				problem = True
 def _count_font_glyphs(self, font_file):
     f = fontforge.open(font_file)
     i = 0
     for glyph in f.glyphs():
         i += 1
     f.close()
     return i
def generate_fonts():
    print 'Generating fonts...\n'
    for f in fonts:
        font_filename = f.get('rescaled', f['orig'])
        infont_path = '%s/%s' % (srcfont_rescaled_dir, font_filename)
        infont_basename, infont_ext = os.path.splitext(font_filename)
        print 'in:  %s' % infont_path
        font = fontforge.open(infont_path)
        for ext in formats:
            outfont_path = '%s/%s%s' % (outfont_dir, infont_basename, ext)
            if ext == '.eot':
                continue
            elif infont_ext == ext:
                print 'out: copying to %s' % outfont_path
                subprocess.call(['cp', infont_path, outfont_path])
                continue
            print 'out: %s' % outfont_path
            font.generate(outfont_path)
        if '.eot' in formats:
            infont_path = '%s/%s%s' % (outfont_dir, infont_basename, '.ttf')
            outfont_path = '%s/%s%s' % (outfont_dir, infont_basename, '.eot')
            print 'out: ttf2eot to %s' % outfont_path
            subprocess.call(['sh', '-c', '%s < %s > %s' % 
                (ttf2eot, infont_path, outfont_path)])
        print
    print 'done\n'
Example #23
0
    def optimize(self, builddir):
        filename = self.postscript_fontname
        # convert the ttf to a ttx file - this may fail
        font = fontforge.open(op.join(builddir, filename) + '.ttf')
        glyphs = []
        for g in font.glyphs():
            if not g.codepoint:
                continue
            glyphs.append(g.codepoint)

        from fontTools import subset
        args = [op.join(builddir, filename) + '.ttf'] + glyphs
        args += ['--layout-features="*"']
        subset.main(args)

        self.stdout_pipe.write('$ pyftsubset %s' % ' '.join(args))

        # compare filesizes TODO print analysis of this :)
        comment = "# look at the size savings of that subset process"
        cmd = "ls -l '%s.ttf'* %s" % (filename, comment)
        run(cmd, cwd=builddir, log=self.stdout_pipe)

        # move ttx files to src
        shutil.move(op.join(builddir, filename + '.ttf.subset'),
                    op.join(builddir, filename + '.ttf'),
                    log=self.stdout_pipe)
Example #24
0
def _build(dstdir, font, permutations):
    # Ensure that the destination directory exists
    try:
        mkdir(dstdir)
    except OSError:
        pass

    for prcnt, opts in permutations:
        # Open the original font
        fnt = fontforge.open(font)

        # Get the base name for the font
        name = join(dstdir, fnt.fontname)

        for opt in opts:
            # Append this option to the font name
            name += '-' + str(opt)
            # Run all the operations for this option
            for oper in option.operations[opt]:
                oper(fnt)

        # Add the extension
        name += ".ttf"

        # Output the file and cleanup
        fnt.generate(name)
        fnt.close()

        # Log progress to prevent timeoout
        print(str(prcnt) + '%.. ' + name)
def rescale_font(infont_path, outfont_path):
    def calc_bbox(glyphs):
        def get_outer_bbox(a, b):
            x = min(a[0], b[0])
            y = min(a[1], b[1])
            w = max(a[0] + a[2], b[0] + b[2]) - x
            h = max(a[1] + a[3], b[1] + b[3]) - y
            return (x, y, w, h)
        return reduce(get_outer_bbox, glyphs)

    font = fontforge.open(infont_path)

    #ScaleToEm(800, 200);
    font.ascent = 800
    font.descent = 200

    #bbox=GetFontBoundingBox()
    bbox = calc_bbox([g.boundingBox() for g in font.glyphs()])
    #print "bbox=", bbox

    #SelectAll();
    font.selection.all()

    #Move(-bbox[0], -bbox[1]);
    #Scale(100*1000/(bbox[3]-bbox[1]), 0, 0);
    #Move(0, -200);
    matrix1 = psMat.translate(-bbox[0], -bbox[1])
    matrix2 = psMat.scale(1000.0/(bbox[3]-bbox[1]))
    matrix3 = psMat.translate(0, -200)
    transform_matrix = psMat.compose(psMat.compose(matrix1, matrix2), matrix3)
    font.transform(transform_matrix)

    font.generate(outfont_path)
 def test_stylename_less_than_32_chars(self):
     """ <Style Name> limitation is 32 chars """
     font = fontforge.open(self.operator.path)
     length = len(font.sfnt_names[2][2])
     self.assertLess(length, 32,
                     msg=('`Style Name` limitation is < 32 chars.'
                          ' Now: %s') % length)
 def test_postscriptname_less_than_30_chars(self):
     """ <Postscript name> limitation is < 30 chars """
     font = fontforge.open(self.operator.path)
     length = len(font.sfnt_names[6][2])
     self.assertLess(length, 30,
                     msg=('`PostScript Name` limitation is less'
                          ' than 30 chars. Now: %s') % length)
Example #28
0
	def __init__( self, fontPath, short ):
		font = fontforge.open( fontPath )
		self.name = font.fontname
		self.short = short
		self.myInfos = {}
		self.totalGlyphs = 0
		self.fontTotalGlyphs = 0
		self.privateUseGlyphs = 0

		r = font.os2_unicoderanges

		# print >> stderr, font.fontname, hex( r[0] ), hex( r[1] ),hex( r[2] ),hex( r[3] );

		nRanges = len( ulUnicodeRange )

		for index in range( 0, nRanges ):
			byte = index / 32
			bit = index % 32

			self.collectRangeInfo( font, r[byte], bit, index )

		for g in font.glyphs():
			self.fontTotalGlyphs += 1
			cp = g.encoding
			if ( not codepointIsInSomeRange( cp )
				and not codepointIsSpecialTT( cp ) ):
				print( font.fontname, 
					"no range for", hex( cp ), file=stderr )

		""" '''Would like to check that special TT slots are
Example #29
0
def main(aDirectory, aFont):
    testfile = open("./%s/index.html" % aDirectory, "w+")
    print("\
<!doctype html>\n\
<html><head><title>%s</title><meta charset=\"utf-8\"/>\n\
  <link rel=\"stylesheet\" type=\"text/css\" href=\"./mathfonts.css\"/>\n\
  %s\n\
  <body class=\"htmlmathparagraph\">\n\
    <h1>%s</h1>\n\
    <a href=\"./CheckFontLog.txt\">CheckFontLog.txt</a> - \
    <a href=\"./CheckFontError.txt\">CheckFontError.txt</a>" %
          (aFont, kStyle, aFont), file=testfile)

    font = fontforge.open("%s/%s" % (aDirectory, aFont))
    printBasicFontInfo(testfile, font)
    printMathConstants(testfile, font)
    printMathVariants(testfile, font)
    printLargeOp(testfile, font)
    printMathematicalAlphanumericCharacters(testfile, font)
    printScriptedOperators(testfile, font)
    printUnicodeCoverage(testfile, font)
    font.close()

    print("\
  </body>\n\
</html>", file=testfile)
Example #30
0
def main():
    "Main function."
    try:
        opts, args = getopt.gnu_getopt(sys.argv[1:], "h", ["help"])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    outputfile = None
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
    if len(args) == 0:
        usage()
        sys.exit(2)
    if args[0][-3:] == "sfd":
        outputfile = "%s.ttf" % args[0][:-4]
        inputfile = args[0]
    else:
        usage()
        sys.exit(2)
    font = fontforge.open(inputfile)
    font.generate(outputfile)
    font.close()
Example #31
0
def main():
    try:
        assert len(argv) > 1
    except AssertionError:
        usage_info = '[Usage] python2 %s <fontFile>' % __file__
        print(usage_info)
        exit(1)

    with ff.open(argv[1]) as font:

        font_name = get_font_name(font)
        full_name = get_full_name(font)
        family = get_family(font)
        preferred_family = get_preferred_family(font)
        weight = get_weight(font)

        print('font name: %s\n'
              'full name: %s\n'
              'family: %s\n'
              'preferred family: %s\n'
              'weight: %s\n' %
              (font_name, full_name, family, preferred_family, weight))
Example #32
0
def main():
    "Main function."
    try:
        opts, args = getopt.gnu_getopt(sys.argv[1:], "h", ["help"])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    outputfile = None
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
    if len(args) == 0:
        usage()
        sys.exit(2)
    fontfile = args[0]
    font = fontforge.open(fontfile)
    font.selection.all()
    font.simplify(0.1, ('mergelines','ignoreslopes','setstarttoextremum'))
    font.generate(fontfile)
    font.close()
Example #33
0
def finish_fonts(blocks):
    """Create several font formats from an SVG font DOM tree"""
    for blk in blocks:
        block = blk[0]
        cache = '{}cache/font_{}.tmp'.format(TARGET_DIR, block)
        if not op.isfile(cache) or \
           not os.stat(cache).st_size:
            logger.debug('No font created for block {}...'.format(block))
            continue
        else:
            logger.info('Creating font for block {}...'.format(block))
        with open(TARGET_DIR + 'fonts/' + block + '.svg', 'w') as svgfile:
            with open(cache) as _cache:
                svgfile.write(svg_font_skeleton.format(block, _cache.read()))
        font = fontforge.open(TARGET_DIR + 'fonts/' + block + '.svg')
        font.generate(TARGET_DIR + 'fonts/' + block + '.woff')
        font.generate(TARGET_DIR + 'fonts/' + block + '.ttf')
        font.close()
        with open(TARGET_DIR + 'fonts/' + block + '.eot', 'w') as eotfile:
            subprocess.call(
                ['ttf2eot', TARGET_DIR + 'fonts/' + block + '.ttf'],
                stdout=eotfile)
Example #34
0
def main():
    scp = fontforge.open(scpFile)
    dejavu = fontforge.open(dejavuFile)
    noto = fontforge.open(notoFile)
    bbold = fontforge.open(bboldFile)
    felipa = fontforge.open(felipaFile)
    unifracktur = fontforge.open(unifrackturFile)
    amateur = fontforge.open(amateurFile)

    out = scp
    out.copyright = "Copyright (c) 2021 Zankoku Okuno, with Reserved Font Name 'Eexpr Reference'."
    out.familyname = "Eexpr Reference Mono"
    out.fontname = "EexprReferenceMono-Regular"
    out.fullname = "Eexpr Reference Mono"
    out.version = "0.001"
    out.sfntRevision = None

    dozenal(out, scp)
    script(out, felipa)
    fraktur(out, unifracktur)
    blackboard(out, bbold)
    subscripts(out, scp)
    hebrew(out, noto)
    customGlyphs(out, amateur)
    relations(out)
    setTheory(out, dejavu, amateur)
    operators(out, dejavu)
    nAry(out)
    arrows(out, dejavu)
    misc(out, noto)

    checkSizes(out)

    print(f"copyright: {out.copyright}")
    print(f"familyname: {out.familyname}")
    print(f"fondname: {out.fondname}")
    print(f"fontname: {out.fontname}")
    print(f"fullname: {out.fullname}")
    print(f"uniqueid: {out.uniqueid}")
    print(f"version: {out.version}")
    out.save(outFile)
Example #35
0
def display_unicode_utf8(ctx, fd=sys.stdout):
    """display unicode characters as UTF-8
    :param MergingContext ctx: a merging font context
    :param file fd: display target"""
    font = fontforge.open(ctx.filename)
    unicode_range = ctx.unicode_range
    start = 0
    end = 0
    if len(unicode_range) >= 1:
        start = int(unicode_range[0], 16)
    if len(unicode_range) >= 2:
        end = int(unicode_range[1], 16)
    remap_start_point = ctx.remap_start_point
    delta = 0
    if remap_start_point is not None:
        delta = int(remap_start_point, 16) - start
    if start is 0:
        font.selection.all()
    else:
        font.selection.select(('ranges', 'unicode'), start, end)
    length = 0
    line = ''
    fd.write('{0:-^80}\n'.format(' ' + ctx.id + ' '))
    for glyph in list(font.selection.byGlyphs):
        line += unichr(glyph.encoding + delta)
        info = get_glyph_size_info(glyph)
        if info.width <= font.em / 2:
            # half width
            line += ' '
        length += 1
        if length is 40:
            fd.write(line.encode('utf-8') + '\n')
            length = 0
            line = ''
    if length > 0:
        fd.write(line.encode('utf-8') + '\n')
    fd.flush()
    font.close()
Example #36
0
def generate_font(sfdfile, type=FT_OTF, outdir=None):
    font = fontforge.open(sfdfile)
    if outdir is None:
        fontprefix = os.path.splitext(sfdfile)[0]
    else:
        fontprefix = os.path.join(
            outdir, os.path.basename(os.path.splitext(sfdfile)[0]))

    if type == FT_TTF:
        font.familyname = font.familyname + " TT"
        splitname = font.fullname.split()
        splitname.insert(-1, "TT")
        font.fullname = " ".join(splitname)
        splitname = font.fontname.split("-")
        splitname.insert(-1, "TT-")
        font.fontname = "".join(splitname)
        try:
            font.generate(fontprefix + ".ttf",
                          flags=("opentype", "old-kern", "PfEd-colors",
                                 "PfEd-lookups"))
        except EnvironmentError, e:
            print("!!! %s" % e, file=sys.stderr)
            sys.exit(EX_GENFAIL)
Example #37
0
def convert_truetype_svg():
    fontfile = sys.argv[1]

    try:
        font = fontforge.open(fontfile)
    except EnvironmentError:
        sys.exit(1)

    font.selection.all()
    font.correctDirection()
    font.removeOverlap()
    font.simplify()
    font.round()

    for glyph in font:
        file_name = '{:x}'.format(font[glyph].unicode).upper()
        file_path = 'exports/{}.svg'.format(file_name)

        if font[glyph].unicode < 0:
            continue

        font[glyph].export(file_path, True)
        print(file_path)
Example #38
0
def merge_fonts(reference, fallback, save_to, renames):
    fontname = "{}_extended_with_{}".format(
        cleanup_font_name(reference.fontname, renames),
        cleanup_font_name(fallback.fontname, renames))
    familyname = "{} extended with {}".format(
        cleanup_font_name(reference.familyname, renames),
        cleanup_font_name(fallback.familyname, renames))
    fullname = "{} extended with {}".format(
        cleanup_font_name(reference.fullname, renames),
        cleanup_font_name(fallback.fullname, renames))

    destination = os.path.join(save_to, fontname + ".ttf")
    shutil.copy(reference.path, destination)
    merged = fontforge.open(destination)
    merged.sfnt_names = []
    merged.fontname = fontname
    merged.familyname = familyname
    merged.fullname = fullname

    merged.mergeFonts(fallback.path)
    merged.generate(destination)

    return destination
Example #39
0
def main():
    start_json = json.load(sys.stdin)

    for font, chars in metrics_to_extract.iteritems():
        fontInfo = fontforge.open("../static/fonts/KaTeX_" + font + ".ttf")

        for glyph in fontInfo.glyphs():
            try:
                char = unichr(glyph.unicode)
            except ValueError:
                continue

            if char in chars:
                _, depth, _, height = glyph.boundingBox()

                depth = -depth

                base_char = chars[char]
                if base_char:
                    base_char_str = str(ord(base_char))
                    base_metrics = start_json[font][base_char_str]

                    italic = base_metrics["italic"]
                    skew = base_metrics["skew"]
                else:
                    italic = 0
                    skew = 0

                start_json[font][ord(char)] = {
                    "height": height / fontInfo.em,
                    "depth": depth / fontInfo.em,
                    "italic": italic,
                    "skew": skew,
                }

    sys.stdout.write(
        json.dumps(start_json, separators=(',', ':'), sort_keys=True))
Example #40
0
def generate_subset(chars, fontpath):
    '''
    >>> font = generate_subset('abc', 'Love Letter Typewriter.ttf')
    >>> font.generate('./hogehoge.ttf')
    '''
    import fontforge
    _logger.info('========================')
    _logger.info('load font file')
    font = fontforge.open(fontpath)
    _logger.info('========================')
    fontname = _get_fontname(font)
    _logger.info('reducing font name is ' + fontname)

    chars_append = chars.append
    for i in range(0, len(chars)):
        sample_char = chars[i]
        try:
            char_in_fontfile = font[sample_char]
        except TypeError:
            _logger.info(unichr(sample_char) + ' is missing font code')
            continue
        else:
            uni = char_in_fontfile.unicode
            if uni != sample_char:
                chars_append(uni)
            alts = char_in_fontfile.altuni
            if alts is None:
                continue
            for alt in alts:
                if alt[0] != sample_char:
                    chars_append(alt[0])
    for c in chars:
        font.selection.select((b"more", None), c)
    font.selection.invert()
    font.clear()
    return font
Example #41
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("font")
    parser.add_argument("name")
    parser.add_argument("out")

    args = parser.parse_args()

    font = fontforge.open(args.font)

    sys.stdin.reconfigure(encoding="utf-8")
    for i in sys.stdin.read():
        font.selection[ord(i)] = True

    font.selection.invert()

    for i in font.selection.byGlyphs:
        font.removeGlyph(i)

    postscript_font_name = args.name.replace(" ", "")

    style = None

    for s in font.sfnt_names:
        if s[1] == "SubFamily":
            style = s[2]
            break

    assert style

    font.familyname = args.name
    font.fullname = f"{postscript_font_name}-{style.replace(' ', '')}"
    font.fontname = f"{postscript_font_name}-{style.replace(' ', '')}"

    font.generate(args.out)
    print("saved to", args.out)
Example #42
0
def main():
  for f in sys.argv[1:] :
    font = fontforge.open(f)

  gsub_tables = []

  for gsub in font.gsub_lookups:

    subtables = []
    for sub in font.getLookupSubtables(gsub):

      glyphs = []
      for g in font.glyphs():
        pos = g.getPosSub(sub)
        if pos:
          glyphs.append({
            'name': g.glyphname,
            'glyphclass': g.glyphclass,
            'script': g.script,
            'encoding': g.encoding,
            'unicode': g.unicode,
            'pos': pos
          })

      subtables.append({
        'name': sub,
        'glyphs': glyphs
      })

    gsub_tables.append({
      'name': gsub,
      'info': font.getLookupInfo(gsub),
      'subtables': subtables
    })

  print(json.dumps(gsub_tables))
Example #43
0
def convert_fonts(base):
	desired_ext = ('woff', 'svg', 'eot', 'ttf')
	for font in os.listdir(base):
		if not is_font(font):
			continue

		font = base / font
		(name, ext) = font.name.split('.')
		ff = fontforge.open(str(font))
		for convert_to in desired_ext:
			target_name = base / '{}.{}'.format(name, convert_to)
			if target_name.is_file():
				continue
			print('Generating {}'.format(target_name))
			ff.generate(str(target_name))

			if not target_name.is_file():
				print('Tried to generate {} but failed'.format(target_name))
			
			afm = base / '{}.afm'.format(name)
			try:
				afm.unlink()
			except OSError:
				pass
Example #44
0
  def __init__(self, char, thickness, font=None, fontpath=None, center=False):
    if font:
      self.font = font
    elif fontpath:
      self.font = fontforge.open(fontpath)

    self.char = char
    self.center = center
    glyph = self.font[str(char)]

    self.thickness = thickness
    self.bbox = glyph.boundingBox()
    self.left_side_bearing = glyph.left_side_bearing
    self.right_side_bearing = glyph.right_side_bearing

    if cadmium._brep_caching_enabled_:
      breppath = os.path.join(cadmium._brep_cache_path_,
        self.get_signature(char,self.font.path,thickness,center))
      if os.path.exists(breppath):
        Solid.__init__(self, None)
        self.fromBREP(breppath)
      else:
        Solid.__init__(self, self.char_to_solid(glyph), center=center)
        self.toBREP(breppath)
Example #45
0
def print_private(fontPath):
    font = fontforge.open(fontPath)

    print('<div style="font-family: \'%s\'; ">' % (font.familyname))
    print('<h2>Private Use Area in  ' + font.fontname + '</h2>')

    font.selection.select(("ranges", None), 0xe000, 0xf8ff)
    print('<table>')
    for g in font.selection.byGlyphs:
        print('<tr><td>')
        print('%s%0.4x%s' % ("0x", g.encoding, ""))
        print('</td><td>')
        print('' + g.glyphname)
        print('</td><td>')
        if g.getPosSub('*'):
            print("is ligature")
        if g.references:
            print("has references")
        print('</td><td>')
        print('</td></tr>')

    print('</table>')
    print('</div>')
    stdout.flush()
Example #46
0
def get_font_id_split_name(opts):
    """Verfiying every downloaded fonts, and get font_id, split, font_name"""
    alphabet_chars = opts.alphabet
    valid_fonts_urls = open(opts.downloaded_fonts_urls_file, 'r').readlines()
    font_id_split_name = open(opts.font_id_split_name_file, 'w')
    fonts_file_path = opts.ttf_path

    font_id = 0
    for font_line in valid_fonts_urls:
        font_name = font_line.strip().split(', ')[-1].split('/')[-1]
        split = font_line.strip().split(', ')[1]

        font_file_path = os.path.join(fonts_file_path, split, font_name)
        try:
            # open a font
            cur_font = fontforge.open(font_file_path)
        except Exception as e:
            print('Cannot open', font_name)
            print(e)
            continue

        try:
            # select all the 52 chars
            for char in alphabet_chars:
                cur_font.selection.select(char)
        except Exception as e:
            print(font_name, 'does not have all chars')
            print(e)
            continue

        font_id_split_name.write("{:06d}".format(font_id) + ', ' + split +
                                 ', ' + font_name + '\n')

        font_id += 1

    font_id_split_name.close()
Example #47
0
        outname = conf.get('main', 'ap')
        if os.path.exists(outname) : readAP(font, outname)
        mergeAPInfo(font)
        myFfFont = FfFont(font)
        buildGraphite(conf, None, myFfFont, outputfont)
    else :
        buildGraphite(conf, None, None, outputfont)
    writecfg(conf, cfg)
    os.chdir(cwd)

def loadFont(font) :
    if getcfg(font) :
        if 'initScriptString' not in font.persistent : font.persistent['initScriptString'] = None
        if not font.temporary : font.temporary = {}
        font.temporary['generateFontPostHook'] = doGenerate

if fontforge.hasUserInterface() :
    fontforge.hooks['loadFontHook'] = loadFont
    fontforge.registerMenuItem(loadConfig, None, None, "Font", None, "Graide", "Load configuration")
    fontforge.registerMenuItem(editConfig, None, None, "Font", None, "Graide", "Edit configuration")
else:
    f = fontforge.open(os.path.abspath(sys.argv[1]))
    cfg = getcfg(f)
    if not cfg :
        print "No configuration, can't build"
        sys.exit(1)
    conf = RawConfigParser()
    conf.read(cfg)
    f.generate(conf.get('main', 'font'), flags = ('opentype',))
    sys.exit(0)
Example #48
0
def build(fontdir: Path, outdir: Path, bold=False):
    # フォントをロード
    hack_path = fontdir / f"Hack-{'Bold' if bold else 'Regular'}.ttf"
    mplus_path = fontdir / f"mplus-1m-{'bold' if bold else 'regular'}.ttf"
    hack: ff.font = ff.open(str(hack_path))
    mplus: ff.font = ff.open(str(mplus_path))

    # フォントのサイズ調整用に「M」の字でサイズ比と差を計算。
    # ただし Hack と M+1M は文字の縦横比が違うため、単純な拡縮ではマッチしない。
    # ここでは、まず高さを一致させ、横幅の拡大率を高さの 1.1 倍を超えない程度に
    # 抑え、かつ不足する横幅を記録しておく(これを元にパディング量を調整し、
    # いわゆる全角文字の幅が英数字のちょうど 2 倍になるようにする)
    vert_ratio = hack[0x4d].vwidth / mplus[0x4d].vwidth
    horiz_ratio = min(hack[0x4d].width / mplus[0x4d].width, vert_ratio * 1.1)
    horiz_pad = int(hack[0x4d].width - mplus[0x4d].width * horiz_ratio)
    scaling_ratio = psMat.scale(horiz_ratio, vert_ratio)
    _logger.info("scaling ratio: %s", scaling_ratio)
    _logger.info("horizontal padding: %s", horiz_pad)

    # Hack に無く M+ にあるコードポイントを列挙する
    font_code_points = set(g.encoding for g in hack.glyphs())
    mplus_code_points = set(g.encoding for g in mplus.glyphs())
    for code_point in mplus_code_points - font_code_points:
        # BMP の外にある文字は無視する
        if 0xffff < code_point:
            continue

        try:
            # この M+ のグリフを Hack に合うよう拡縮とパディング挿入を行う
            g = mplus[code_point]
            g.transform(scaling_ratio)
            g.left_side_bearing = int(g.left_side_bearing + horiz_pad / 2)
            g.right_side_bearing = int(g.right_side_bearing + horiz_pad / 2)
            g.width = int(g.width + horiz_pad)

            # このグリフを Hack の方にコピー
            mplus.selection.select(code_point)
            mplus.copy()
            hack.selection.select(code_point)
            hack.paste()
        except Exception as e:
            _logger.warning("Error on copying %s (%s): %s", mplus[code_point],
                            f"u{code_point:x}", e)

    # オリジナルから合成して引き継ぐべきメタデータを準備
    # 字体のデザイン特性はコンセプト上の主体である Hack のそれを踏襲する。
    # サポートする文字集合は、両フォントのそれの和集合とする。
    _logger.info("[os2_version]")
    _logger.info("hack:  %s", hack.os2_version)
    _logger.info("mplus: %s", mplus.os2_version)
    hack.os2_version = 1  # OS/2 table version number
    _logger.info("hm:    %s", hack.os2_version)
    _logger.info("[os2_weight]")
    _logger.info("hack:  %s", hack.os2_weight)
    _logger.info("mplus: %s", mplus.os2_weight)
    hack.os2_weight = 400  # Regular
    _logger.info("hm:    %s", hack.os2_weight)
    _logger.info("[os2_width]")
    _logger.info("hack:  %s", hack.os2_width)
    _logger.info("mplus: %s", mplus.os2_width)
    hack.os2_width = 5  # Medium (normal)
    _logger.info("hm:    %s", hack.os2_width)
    _logger.info("[os2_fstype]")
    _logger.info("hack:  %s", hack.os2_fstype)
    _logger.info("mplus: %s", mplus.os2_fstype)
    hack.os2_fstype = 0  # Installable Embedding
    _logger.info("hm:    %s", hack.os2_fstype)
    _logger.info("[os2_vendor]")
    _logger.info("hack:  %s", hack.os2_vendor)
    _logger.info("mplus: %s", mplus.os2_vendor)
    hack.os2_vendor = ""
    _logger.info("hm:    %s", hack.os2_vendor)
    # https://monotype.github.io/panose/pan2.htm
    _logger.info("[os2_panose]")
    _logger.info("hack:  %s", hack.os2_panose)
    _logger.info("mplus: %s", mplus.os2_panose)
    hack.os2_panose = (
        2,  # (Faimly Kind) Latin Text
        11,  # (Serif Style Classification) Normal Sans
        6,  # (Weight) Medium
        9,  # (Propotion) Monospaced
        3,  # (Contrast) Very Low
        2,  # (Stroke Variation) No Variation
        2,  # (Arm Style) Straight Arms/Horizontal
        2,  # (Letterform) Normal/Contact
        2,  # (Midline) Standard/Trimmed
        4,  # (X-height) Constant/Large
    )
    _logger.info("hm:    %s", hack.os2_panose)
    # https://docs.microsoft.com/en-us/typography/opentype/otspec140/os2ver1#ur
    _logger.info("[os2_unicoderanges]")
    _logger.info("hack:  %s", bits_repr(*hack.os2_unicoderanges))
    _logger.info("mplus: %s", bits_repr(*mplus.os2_unicoderanges))
    hack.os2_unicoderanges = tuple(
        h | m for h, m in zip(hack.os2_unicoderanges, mplus.os2_unicoderanges))
    _logger.info("hm:    %s", bits_repr(*hack.os2_unicoderanges))
    _logger.info("[os2_os2_codepages]")
    _logger.info("hack:  %s", bits_repr(*hack.os2_codepages))
    _logger.info("mplus: %s", bits_repr(*mplus.os2_codepages))
    hack.os2_codepages = tuple(
        h | m for h, m in zip(hack.os2_codepages, mplus.os2_codepages))
    _logger.info("hm:    %s", bits_repr(*hack.os2_codepages))

    # フォントのメタ情報を生成
    try:
        hack_version = hack.sfnt_names[5][2].split(";")[0].lower()
    except Exception as e:
        _logger.error("Failed to extrace Hack version: %s\n\n%s", e,
                      hack.sfnt_names)
        sys.exit(2)
    try:
        mplus_version = mplus.sfnt_names[5][2].lower()
    except Exception as e:
        _logger.error("Failed to extrace M+ version: %s\n\n%s", e,
                      mplus.sfnt_names)
        sys.exit(2)
    version_string = ("Version {}; derivative of Hack {} and M+1m {}".format(
        __version__, hack_version, mplus_version))
    license_text = Path("LICENSE").read_text()

    # フォントに設定
    family_name = "HM"
    subfamily_name = "Bold" if bold else "Regular"
    hack.fontname = f"{family_name}-{subfamily_name}"
    hack.familyname = family_name
    hack.fullname = f"{family_name} {subfamily_name}"
    locale = "English (US)"
    license_url = "https://github.com/sgryjp/hm-font/blob/master/LICENSE"
    meta = (
        __copyright__,  # 0:Copyright
        family_name,  # 1:Family
        subfamily_name,  # 2:SubFamily
        f"{family_name}-{subfamily_name}-{__version__}",  # 3:UniqueID
        hack.fullname,  # 4:Fullname
        version_string,  # 5:Version
        f"{family_name}-{subfamily_name}",  # 6:PostScriptName
        "",  # 7:Trademark
        "",  # 8:Manufacturer
        "",  # 9:Designer
        "",  # 10:Descriptor
        "",  # 11:Vendor URL
        "",  # 12:Designer URL
        license_text,  # 13:License
        license_url,  # 14:License URL
        None,  # 15:N/A
        family_name,  # 16:Preferred Family
        subfamily_name,  # 17:Preferred Styles
    )
    for i, value in enumerate(meta):
        if value is not None:
            hack.appendSFNTName(locale, i, value)

    # デバッグ用に設定したメタ情報を表示
    for _, k, v in hack.sfnt_names:
        if k != "License":
            _logger.debug("[%s]", k)
            _logger.debug("%s", v)

    # フォントを出力
    os.makedirs(outdir, exist_ok=True)
    hack.generate(str(outdir / f"hm-{'bold' if bold else 'regular'}.ttf"))
Example #49
0
    def generate(filename):
        f.generate(filename)


# TTF
generate(fontfile + '.ttf')

# Hint the TTF file
# ttfautohint is optional
if find_executable('ttfautohint'):
    call(
        "ttfautohint --symbol --fallback-script=latn --windows-compatibility --no-info '"
        + fontfile + ".ttf' '" + fontfile + "-hinted.ttf' && mv '" + fontfile +
        "-hinted.ttf' '" + fontfile + ".ttf'",
        shell=True)
    f = fontforge.open(fontfile + '.ttf')

# SVG
if 'svg' in args.types:
    generate(fontfile + '.svg')

    # Fix SVG header for webkit (from: https://github.com/fontello/font-builder/blob/master/bin/fontconvert.py)
    svgfile = open(fontfile + '.svg', 'r+')
    svgtext = svgfile.read()
    svgfile.seek(0)
    svgfile.write(
        svgtext.replace('<svg>', '<svg xmlns="http://www.w3.org/2000/svg">'))
    svgfile.close()

scriptPath = os.path.dirname(os.path.realpath(__file__))
Example #50
0
]

glyphs_set = " ".join(glyphs)


def adjust_space():
    for glyph in glyphs_set.split(" "):
        glyphname = "uni0C%s" % glyph
        if not glyphname in font:
            continue

        left_space = font[glyphname].left_side_bearing
        right_space = font[glyphname].right_side_bearing
        print("%s,%s,%s,%s,%s" %
              (glyphname, left_space, LSPACE, right_space, RSPACE))
        font[glyphname].left_side_bearing = LSPACE
        font[glyphname].right_side_bearing = RSPACE


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print "USAGE: python adjust_spacing.py <sfd file>"
        sys.exit(1)

    sfd_name = sys.argv[1]
    font = fontforge.open(sfd_name)
    print("name,left_old,left_new,right_old,right_new")
    adjust_space()
    font.save()
    font.close()
Example #51
0
import fontforge

##
## THIS FILE IS A FONTFORGE SCRIPT THAT GENERATES THE HIRMOS PONOMAR FONT FAMILY
##
##

base_name = "IndictionUnicode"
full_name = "Indiction Unicode"

#fontforge.setPrefs ("AutoHint", False)
#fontforge.setPrefs ("ClearInstrsBigChanges",False )
#fontforge.setPrefs ( "CopyTTFInstrs",False )

## open up the font
font = fontforge.open(base_name + ".sfd")

## Evidently, this can break Evince, so it may need to be commented out
font.head_optimized_for_cleartype = True

## not sure if we need this
#font.encoding = "mac"

ttnames = list(font.sfnt_names)
for ttname in ttnames:
    if ttname[1] == 'SubFamil':
        ttnames.append(
            (ttname[0], 'Fullname', "%s %s" % (full_name, ttname[2])))
font.sfnt_names = tuple(ttnames)

font.generate(base_name + ".otf",
Example #52
0
#!/usr/bin/python
import os
import fontforge

fontFileName = os.sys.argv[1]
path = fontFileName
try:
    font = fontforge.open(path)
    font.generate(os.path.splitext(fontFileName)[0] + ".ttf")
    font.generate(os.path.splitext(fontFileName)[0] + ".otf")
    font.generate(os.path.splitext(fontFileName)[0] + ".svg")
    font.generate(os.path.splitext(fontFileName)[0] + ".woff")

except EnvironmentError:
    print("Error opening font file %s!" % fontFileName)
    os.sys.exit(1)
Example #53
0
# prepare config to view:
# [(from_code1, to_code1), (from_code2, to_code2), ...]
remap_config = [(glyph.get('from', glyph['code']), glyph['code'])
                    for glyph in config['glyphs']]

# validate config: fetcy duplicate 'from' codes
src_codes = zip(*remap_config)[0]
if len(src_codes) != len(set(src_codes)):
    stderr.write("Error in file %s: glyph codes aren't unique:\n" % args.config)
    for code in set(src_codes):
        if src_codes.count(code) > 1:
            stderr.write("Duplicate 'from:' 0x%04x\n" % code)
    sys.exit(1)

try:
    font = fontforge.open(args.src_font)
    # set font encoding so we can select any unicode code point
    font.encoding = 'UnicodeFull'
except:
    stderr.write("Error: Fontforge can't open source %s" % args.src_font)
    sys.exit(1)

new_font = fontforge.font()
new_font.encoding = 'UnicodeFull'

# load font properties from config
for key, value in config.get('font', {}).items():
    setattr(new_font, key, value)


for from_code, to_code in remap_config:
Example #54
0
 def set_font(self, fontfile):
     self.tt = truetype(fontfile, self.size[1])
     self.ff = fontforge.open(fontfile)
Example #55
0
##
## THIS FILE IS A FONTFORGE SCRIPT THAT GENERATES WEB FONTS FAMILY
##
##

base_name = "FiraSlav"

fontforge.setPrefs("AutoHint", False)
fontforge.setPrefs("ClearInstrsBigChanges", False)
fontforge.setPrefs("CopyTTFInstrs", True)
flavor = ("Regular", "Bold")

for i in range(0, len(flavor)):
    ## open up the font
    font = fontforge.open(base_name + "-" + flavor[i] + ".sfd")
    font.head_optimized_for_cleartype = True

    # generate TTF fonts
    font.em = 1024
    font.generate(base_name + "-" + flavor[i] + ".ttf",
                  flags=("opentype", "old-kern", "PfEd-colors", "PfEd-lookups",
                         "dummy-dsig"),
                  layer="Fore")

    #generate WOFF fonts
    woff_meta = base_name + "-WOFF-metadata.xml"
    f = file(woff_meta, 'r')
    lines = f.readlines()
    f.close()
    font.woffMetadata = "".join(lines)
Example #56
0
if args.i is None or args.k is None:
    parser.print_help()
    exit(1)
src_path = args.i[0]

if args.o is None:
    dest_path = args.i[0][:-4] + "-kerned.otf"
else:
    dest_path = args.o[0]

spec = json.load(open(args.k[0], "r", encoding="utf-8"))
r = spec["config"]["r"]
gap = spec["config"]["gap"][0]

print("processing font:", src_path)
font = fontforge.open(src_path)

print("cleaning glyphs...")
font.selection.all()
font.removeOverlap()
font.simplify()
font.correctDirection()

font.addLookup(
    "kern",
    "gpos_pair",
    (
        "ignore_ligatures",
        "ignore_marks",
    ),
    (("kern", (("DFLT", ("dflt")), )), ),
Example #57
0
),
charZKKana = list(
    u"ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ"
),
charHKKana = list(
    u"、。・ー゙゚「」アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ")
charZEisu = list(
    u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")

########################################
# modified ReplaceParts
########################################

print()
print("Open " + srcfont_MyricaReplaceParts)
fRp = fontforge.open(srcfont_MyricaReplaceParts)

# modify em
fRp.em = newfont_em
fRp.ascent = newfont_ascent
fRp.descent = newfont_descent

# post-process
fRp.selection.all()
fRp.round()

########################################
# modified Inconsolata
########################################

print()
#!/usr/bin/env python2

import fontforge

import sys

if len(sys.argv) < 4:
    print "Usage: %s <font file> <ascent> <descent>" % sys.argv[0]
    sys.exit(1)

font_file = sys.argv[1]
ascent = int(sys.argv[2])
descent = int(sys.argv[3])

font = fontforge.open(font_file)

font.os2_winascent = ascent
font.os2_windescent = descent

font.hhea_ascent = ascent
font.hhea_descent = -descent

font.generate(font_file, flags=("TeX-table"))
Example #59
0
#!/usr/local/bin/fontforge
#Needs: fonts/nuvo-medium-woff-demo.woff

import fontforge
woff = fontforge.open("fonts/nuvo-medium-woff-demo.woff")
if (woff.woffMajor != 7):
    raise ValueError, "Wrong return from woffMajor"
if (woff.woffMinor != 504):
    raise ValueError, "Wrong return from woffMinor"
if (len(woff.woffMetadata) != 959):
    raise ValueError, "Wrong return from woffMetadata"

woff.woffMajor = 8

woff.generate("results/Foo.woff")

wofftest = fontforge.open("results/Foo.woff")
if (wofftest.woffMajor != 8 | wofftest.woffMinor != 504):
    raise ValueError, "Wrong return from woffMajor woffMinor after saving"
if (len(wofftest.woffMetadata) != 959):
    raise ValueError, "Wrong return from woffMetadata after saving"
Example #60
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import sys
import fontforge


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print "USAGE: python apply_featurefile.py <sfd file> <featurefile>"
    else:
        font = fontforge.open(sys.argv[1])

        # Remove all GSUB lookups
        for lookup in font.gsub_lookups:
            font.removeLookup(lookup)

        # Remove all GPOS lookups 
        # These lines are disable since gpos tables are font specific and simply importing from lohit will not help it.
        # for lookup in font.gpos_lookups:
        #    font.removeLookup(lookup)        

        # Merge the new featurefile 
        font.mergeFeature(sys.argv[2])
        font.save()
        font.close()
        print "[SUCCESS]", sys.argv[2], "feature file applied"