summaryrefslogtreecommitdiff
path: root/misc/glyphs-scripts/fixup-vertical-metrics.py
blob: a7ad651e9bb6bf265158482b28376f69246ea456 (plain)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#MenuTitle: Fixup Vertical Metrics
# -*- coding: utf-8 -*-

font = Glyphs.font
caps = set(font.classes['Uppercase'].code.strip().split(' '))
lowercase = set(font.classes['Lowercase'].code.strip().split(' '))

print(font)

mainMaxDescent = 0
mainMaxDescentGlyph = ""
maxDescent = 0
mainMaxAscent = 0
mainMaxAscentGlyph = ""
maxAscent = 0
typoAscender = 0
typoDescender = 0

for master in font.masters:
  ta = max(master.ascender, master.capHeight)
  if typoAscender == 0:
    typoAscender = ta
  elif typoAscender != ta:
    raise Error('ascender or capHeight varies with masters; vertical metrics must be same in all masters')

  td = master.descender
  if typoDescender == 0:
    typoDescender = td
  elif typoDescender != td:
    raise Error('descender or capHeight varies with masters; vertical metrics must be same in all masters')

  for glyph in font.glyphs:
    if not glyph.export:
      continue

    layer = glyph.layers[master.id]

    # get descender of current layer
    descent = layer.bounds.origin.y
    
    # get ascender of current layer
    ascent = layer.bounds.size.height + descent  

    # if descent/ascent of current layer is greater than previous max descents/ascents, update the max descent/ascent
    if descent <= maxDescent:
      maxDescent = descent
      maxDescentGlyph = glyph.name
      
    if ascent >= maxAscent:
      maxAscent = ascent
      maxAscentGlyph = glyph.name

    # get descender of current layer
    descent = layer.bounds.origin.y
        
    # get ascender of current layer (total height of layer, subtracting value of descender)
    ascent = layer.bounds.size.height + descent

    # get maximums of only letters in list vars, for typo and hhea values
    if glyph.name in caps and ascent >= mainMaxAscent:
      mainMaxAscent = ascent
      mainMaxAscentGlyph = glyph.name

    if glyph.name in lowercase and descent <= mainMaxDescent:
      # if descent/ascent of current layer is greater than previous max descents/ascents, update the max descent/ascent
      mainMaxDescent = descent
      mainMaxDescentGlyph = glyph.name
      

# check values for sanity
# print(maxDescentGlyph, maxDescent, maxAscentGlyph, maxAscent)

# make lineGap so that the total of `ascent + descent + lineGap` equals 120% of UPM size
# UPM = font.upm
# totalSize = maxAscent + abs(maxDescent)
# lineGap = int((UPM * 1.2)) - totalSize
# print(UPM, UPM * 1.2, totalSize, lineGap)

## use highest/lowest points to set custom parameters for winAscent and winDescent
## following vertical metric schema from https://github.com/googlefonts/gf-docs/tree/master/VerticalMetrics

font.customParameters["Use Typo Metrics"] = True

# ascenderDelta = max(abs(typoAscender), abs(mainMaxAscent)) - min(abs(typoAscender), abs(mainMaxAscent))
descenderDelta = max(typoDescender, mainMaxDescent) - min(typoDescender, mainMaxDescent)

if descenderDelta == 0:
  print('descenderDelta is zero -- no change')
else:
  print('descenderDelta:', descenderDelta)

  for master in font.masters:

    # Win Ascent/Descent = Font bbox yMax/yMin
    master.customParameters["winAscent"] = maxAscent
    master.customParameters["winDescent"] = abs(maxDescent)

    # no/zero line gap
    # if "typoLineGap" in master.customParameters:
    #   del master.customParameters["typoLineGap"]
    # if "hheaLineGap" in master.customParameters:
    #   del master.customParameters["hheaLineGap"]
    master.customParameters["typoLineGap"] = 0
    master.customParameters["hheaLineGap"] = 0

    master.customParameters["typoDescender"] = typoDescender - descenderDelta
    master.customParameters["hheaDescender"] = typoDescender - descenderDelta

    master.customParameters["typoAscender"] = typoAscender + descenderDelta
    master.customParameters["hheaAscender"] = typoAscender + descenderDelta