1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##########################################################################
## # The Coq Proof Assistant / The Coq Development Team ##
## v # INRIA, CNRS and contributors - Copyright 1999-2018 ##
## <O___,, # (see CREDITS file for the list of authors) ##
## \VV/ ###############################################################
## // # This file is distributed under the terms of the ##
## # GNU Lesser General Public License Version 2.1 ##
## # (see LICENSE file for the text of the license) ##
##########################################################################
"""Transform a font to center each of its characters in square bounding boxes.
See https://stackoverflow.com/questions/37377476/ for background information.
"""
from collections import Counter
try:
import fontforge
import psMat
except ImportError:
print("This program requires FontForge's python bindings:")
print(" git clone https://github.com/fontforge/fontforge")
print(" cd fontforge")
print(" ./bootstrap")
print(" ./configure")
print(" make -j8")
print(" sudo make install")
raise
def glyph_height(glyph):
_, ylo, _, yhi = glyph.boundingBox()
return yhi - ylo
def scale_single_glyph(glyph, width, height):
"""Center glyph in a box of size width*height"""
# Some glyphs (such as ‘;’) contain references (‘.’ + ‘,’), and moving the
# referenced glyphs moves them in all glyphs that reference them.
# Unlinking copies references into this glyph
glyph.unlinkThisGlyph()
# Width
deltaw = width - glyph.width
glyph.left_side_bearing += deltaw / 2
glyph.right_side_bearing += deltaw - glyph.left_side_bearing
glyph.width = width
# Height
ylo = glyph.boundingBox()[1]
deltah = height - glyph_height(glyph)
glyph.transform(psMat.translate(0, deltah / 2.0 - ylo))
def avg(lst):
lst = list(lst)
return sum(lst) / float(len(lst))
def trim_font(fnt):
"""Remove characters codes beyond 191 front fnt"""
for g in fnt.glyphs():
if g.unicode >= 191:
fnt.removeGlyph(g)
return fnt
def center_glyphs(src_font_path, dst_font_path, dst_name):
fnt = trim_font(fontforge.open(src_font_path))
size = max(g.width for g in fnt.glyphs())
fnt.ascent, fnt.descent = size, 0
for glyph in fnt.glyphs():
scale_single_glyph(glyph, size, size)
fnt.sfnt_names = []
fnt.fontname = fnt.familyname = fnt.fullname = dst_name
fnt.generate(dst_font_path)
if __name__ == '__main__':
from os.path import dirname, join, abspath
curdir = dirname(abspath(__file__))
ubuntumono_path = join(curdir, "UbuntuMono-B.ttf")
ubuntumono_mod_path = join(curdir, "CoqNotations.ttf")
center_glyphs(ubuntumono_path, ubuntumono_mod_path, "CoqNotations")
|