tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

generate.py (8616B)


      1 #!/usr/bin/python
      2 # vim: set shiftwidth=4 tabstop=8 autoindent expandtab:
      3 # This Source Code Form is subject to the terms of the Mozilla Public
      4 # License, v. 2.0. If a copy of the MPL was not distributed with this
      5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      6 
      7 # For general fontforge documentation, see:
      8 #   http://fontforge.sourceforge.net/
      9 # For fontforge scripting documentation, see:
     10 #   http://fontforge.sourceforge.net/scripting-tutorial.html
     11 #   http://fontforge.sourceforge.net/scripting.html
     12 # and most importantly:
     13 #   http://fontforge.sourceforge.net/python.html
     14 
     15 # To install what you need, on Ubuntu,
     16 #   sudo apt-get install python-fontforge
     17 
     18 import fontforge
     19 
     20 em = 1000
     21 
     22 
     23 def newMathFont(aName):
     24    print("Generating %s.otf..." % aName, end="")
     25    mathFont = fontforge.font()
     26    mathFont.fontname = aName
     27    mathFont.familyname = aName
     28    mathFont.fullname = aName
     29    mathFont.copyright = "Copyright (c) 2014 Mozilla Corporation"
     30    mathFont.encoding = "UnicodeFull"
     31 
     32    # Create a space character. Also force the creation of some MATH subtables
     33    # so that OTS will not reject the MATH table.
     34    g = mathFont.createChar(ord(" "), "space")
     35    g.width = em
     36    g.italicCorrection = 0
     37    g.topaccent = 0
     38    g.mathKern.bottomLeft = tuple([(0, 0)])
     39    g.mathKern.bottomRight = tuple([(0, 0)])
     40    g.mathKern.topLeft = tuple([(0, 0)])
     41    g.mathKern.topRight = tuple([(0, 0)])
     42    mathFont[ord(" ")].horizontalVariants = "space"
     43    mathFont[ord(" ")].verticalVariants = "space"
     44    return mathFont
     45 
     46 
     47 def saveMathFont(aFont):
     48    aFont.em = em
     49    aFont.ascent = aFont.descent = em / 2
     50    aFont.hhea_ascent = aFont.os2_typoascent = aFont.os2_winascent = em / 2
     51    aFont.descent = aFont.hhea_descent = em / 2
     52    aFont.os2_typodescent = aFont.os2_windescent = em / 2
     53    aFont.hhea_ascent_add = aFont.hhea_descent_add = 0
     54    aFont.os2_typoascent_add = aFont.os2_typodescent_add = 0
     55    aFont.os2_winascent_add = aFont.os2_windescent_add = 0
     56    aFont.os2_use_typo_metrics = True
     57    aFont.generate(aFont.fontname + ".otf")
     58    print(" done.")
     59 
     60 
     61 def createSquareGlyph(aFont, aCodePoint):
     62    g = aFont.createChar(aCodePoint)
     63    p = g.glyphPen()
     64    p.moveTo(0, 0)
     65    p.lineTo(em, 0)
     66    p.lineTo(em, em)
     67    p.lineTo(0, em)
     68    p.closePath()
     69 
     70 
     71 def createLLTriangleGlyph(aFont, aCodePoint):
     72    g = aFont.createChar(aCodePoint)
     73    p = g.glyphPen()
     74    p.moveTo(0, 0)
     75    p.lineTo(em, 0)
     76    p.lineTo(0, em)
     77    p.closePath()
     78 
     79 
     80 def createURTriangleGlyph(aFont, aCodePoint):
     81    g = aFont.createChar(aCodePoint)
     82    p = g.glyphPen()
     83    p.moveTo(em, 0)
     84    p.lineTo(em, em)
     85    p.lineTo(0, em)
     86    p.closePath()
     87 
     88 
     89 def createDiamondGlyph(aFont, aCodePoint):
     90    g = aFont.createChar(aCodePoint)
     91    p = g.glyphPen()
     92    p.moveTo(0, em / 2)
     93    p.lineTo(em / 2, 0)
     94    p.lineTo(em, em / 2)
     95    p.lineTo(em / 2, em)
     96    p.closePath()
     97 
     98 
     99 ################################################################################
    100 # Glyph variants and constructions
    101 f = newMathFont("stretchy")
    102 nvariants = 3
    103 
    104 # Draw boxes for the size variants and glues
    105 for i in range(0, nvariants):
    106    s = em * (i + 1)
    107 
    108    g = f.createChar(-1, "h%d" % i)
    109    p = g.glyphPen()
    110    p.moveTo(0, -em)
    111    p.lineTo(0, em)
    112    p.lineTo(s, em)
    113    p.lineTo(s, -em)
    114    p.closePath()
    115    g.width = s
    116 
    117    g = f.createChar(-1, "v%d" % i)
    118    p = g.glyphPen()
    119    p.moveTo(0, 0)
    120    p.lineTo(0, s)
    121    p.lineTo(2 * em, s)
    122    p.lineTo(2 * em, 0)
    123    p.closePath()
    124    g.width = 2 * em
    125 
    126 # Draw some pieces for stretchy operators
    127 s = em * nvariants
    128 
    129 g = f.createChar(-1, "left")
    130 p = g.glyphPen()
    131 p.moveTo(0, -2 * em)
    132 p.lineTo(0, 2 * em)
    133 p.lineTo(s, em)
    134 p.lineTo(s, -em)
    135 p.closePath()
    136 g.width = s
    137 
    138 g = f.createChar(-1, "right")
    139 p = g.glyphPen()
    140 p.moveTo(0, -em)
    141 p.lineTo(0, em)
    142 p.lineTo(s, 2 * em)
    143 p.lineTo(s, -2 * em)
    144 p.closePath()
    145 g.width = s
    146 
    147 g = f.createChar(-1, "hmid")
    148 p = g.glyphPen()
    149 p.moveTo(0, -em)
    150 p.lineTo(0, em)
    151 p.lineTo(s, 2 * em)
    152 p.lineTo(2 * s, em)
    153 p.lineTo(2 * s, -em)
    154 p.lineTo(s, -2 * em)
    155 p.closePath()
    156 g.width = 2 * s
    157 
    158 g = f.createChar(-1, "bottom")
    159 p = g.glyphPen()
    160 p.moveTo(0, 0)
    161 p.lineTo(0, s)
    162 p.lineTo(2 * em, s)
    163 p.lineTo(4 * em, 0)
    164 p.closePath()
    165 g.width = 4 * em
    166 
    167 g = f.createChar(-1, "top")
    168 p = g.glyphPen()
    169 p.moveTo(0, 0)
    170 p.lineTo(4 * em, 0)
    171 p.lineTo(2 * em, -s)
    172 p.lineTo(0, -s)
    173 p.closePath()
    174 g.width = 4 * em
    175 
    176 g = f.createChar(-1, "vmid")
    177 p = g.glyphPen()
    178 p.moveTo(0, s)
    179 p.lineTo(2 * em, s)
    180 p.lineTo(4 * em, 0)
    181 p.lineTo(2 * em, -s)
    182 p.lineTo(0, -s)
    183 p.closePath()
    184 g.width = 3 * em
    185 
    186 # Create small rectangle of various size for some exotic arrows that are
    187 # unlikely to be stretchable with standard fonts.
    188 hstretchy = [
    189    0x219C,  # leftwards wave arrow
    190    0x219D,  # rightwards wave arrow
    191    0x219E,  # leftwards two headed arrow
    192    0x21A0,  # rightwards two headed arrow
    193    0x21A2,  # leftwards arrow with tail
    194 ]
    195 vstretchy = [
    196    0x219F,  # upwards two headed arrow
    197    0x21A1,  # downwards two headed arrow
    198    0x21A5,  # upwards arrow from bar
    199    0x21A7,  # downwards arrow from bar
    200    0x21A8,  # up down arrow with base
    201 ]
    202 for i in range(0, 1 + nvariants + 1):
    203    s = (i + 1) * em / 10
    204 
    205    g = f.createChar(hstretchy[i])
    206    p = g.glyphPen()
    207    p.moveTo(0, -em / 10)
    208    p.lineTo(0, em / 10)
    209    p.lineTo(s, em / 10)
    210    p.lineTo(s, -em / 10)
    211    p.closePath()
    212    g.width = s
    213 
    214    g = f.createChar(vstretchy[i])
    215    p = g.glyphPen()
    216    p.moveTo(0, 0)
    217    p.lineTo(0, s)
    218    p.lineTo(2 * em / 10, s)
    219    p.lineTo(2 * em / 10, 0)
    220    p.closePath()
    221    g.width = 2 * em / 10
    222 
    223 # hstretchy[0] and vstretchy[0] have all the variants and the components. The others only have one of them.
    224 s = em * nvariants
    225 
    226 f[hstretchy[0]].horizontalVariants = "uni219C h0 h1 h2"
    227 f[hstretchy[0]].horizontalComponents = (
    228    ("left", False, 0, 0, s),
    229    ("h2", True, 0, 0, s),
    230    ("hmid", False, 0, 0, 2 * s),
    231    ("h2", True, 0, 0, s),
    232    ("right", False, 0, 0, s),
    233 )
    234 
    235 f[hstretchy[1]].horizontalVariants = "uni219D h0"
    236 f[hstretchy[2]].horizontalVariants = "uni219E h1"
    237 f[hstretchy[3]].horizontalVariants = "uni21A0 h2"
    238 f[hstretchy[4]].horizontalVariants = "uni21A2 h2"
    239 f[hstretchy[4]].horizontalComponents = f[hstretchy[0]].horizontalComponents
    240 
    241 f[vstretchy[0]].verticalVariants = "uni219F v0 v1 v2"
    242 f[vstretchy[0]].verticalComponents = (
    243    ("bottom", False, 0, 0, s),
    244    ("v2", True, 0, 0, s),
    245    ("vmid", False, 0, 0, 2 * s),
    246    ("v2", True, 0, 0, s),
    247    ("top", False, 0, 0, s),
    248 )
    249 
    250 f[vstretchy[1]].verticalVariants = "uni21A1 v0"
    251 f[vstretchy[2]].verticalVariants = "uni21A5 v1"
    252 f[vstretchy[3]].verticalVariants = "uni21A7 v2"
    253 f[vstretchy[4]].verticalVariants = "uni21A8"
    254 f[vstretchy[4]].verticalComponents = f[vstretchy[0]].verticalComponents
    255 
    256 ################################################################################
    257 # Testing DisplayOperatorMinHeight
    258 f.math.DisplayOperatorMinHeight = 8 * em
    259 largeop = [0x2A1B, 0x2A1C]  # integral with overbar/underbar
    260 
    261 # Draw boxes of size 1, 2, 7, 8, 9em.
    262 for i in [1, 2, 7, 8, 9]:
    263    s = em * i
    264    if i in {1, 2}:
    265        g = f.createChar(largeop[i - 1])
    266    else:
    267        g = f.createChar(-1, "L%d" % i)
    268    p = g.glyphPen()
    269    p.moveTo(0, 0)
    270    p.lineTo(0, s)
    271    p.lineTo(s, s)
    272    p.lineTo(s, 0)
    273    p.closePath()
    274    g.width = s
    275 
    276 f[largeop[0]].verticalVariants = "uni2A1B L7 L8 L9"
    277 f[largeop[1]].verticalVariants = "uni2A1C L8"
    278 
    279 saveMathFont(f)
    280 
    281 ################################################################################
    282 # Testing AxisHeight
    283 f = newMathFont("axis-height-1")
    284 f.math.AxisHeight = 0
    285 createSquareGlyph(f, ord("+"))
    286 saveMathFont(f)
    287 
    288 f = newMathFont("axis-height-2")
    289 f.math.AxisHeight = 20 * em
    290 createSquareGlyph(f, ord("+"))
    291 saveMathFont(f)
    292 
    293 ################################################################################
    294 # Testing Limits Parameters
    295 f = newMathFont("limits-5")
    296 f.math.UpperLimitGapMin = 0
    297 f.math.UpperLimitBaselineRiseMin = 0
    298 f.math.LowerLimitGapMin = 0
    299 f.math.LowerLimitBaselineDropMin = 0
    300 f.math.AccentBaseHeight = 6 * em
    301 f.math.FlattenedAccentBaseHeight = 3 * em
    302 createSquareGlyph(f, ord("~"))
    303 saveMathFont(f)
    304 
    305 f = newMathFont("dtls-1")
    306 createSquareGlyph(f, ord("a"))
    307 createLLTriangleGlyph(f, ord("b"))
    308 createSquareGlyph(f, ord("c"))
    309 createDiamondGlyph(f, 0x1D51E)  # mathvariant=fraktur a
    310 createURTriangleGlyph(f, 0x1D51F)  # mathvariant=fraktur b
    311 createDiamondGlyph(f, 0x1D520)  # mathvariant=fraktur c
    312 f.addLookup("gsub", "gsub_single", (), (("dtls", (("latn", ("dflt")),)),))
    313 f.addLookupSubtable("gsub", "gsub_n")
    314 glyph = f["a"]
    315 glyph.addPosSub("gsub_n", "b")
    316 glyph2 = f[0x1D51F]
    317 glyph2.glyphname = "urtriangle"
    318 glyph3 = f[0x1D51E]
    319 glyph3.addPosSub("gsub_n", "urtriangle")
    320 saveMathFont(f)