layout/reftests/fonts/math/generate.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/reftests/fonts/math/generate.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,231 @@
     1.4 +#!/usr/bin/python
     1.5 +# vim: set shiftwidth=4 tabstop=8 autoindent expandtab:
     1.6 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.9 +
    1.10 +# For general fontforge documentation, see:
    1.11 +#   http://fontforge.sourceforge.net/
    1.12 +# For fontforge scripting documentation, see:
    1.13 +#   http://fontforge.sourceforge.net/scripting-tutorial.html
    1.14 +#   http://fontforge.sourceforge.net/scripting.html
    1.15 +# and most importantly:
    1.16 +#   http://fontforge.sourceforge.net/python.html
    1.17 +
    1.18 +# To install what you need, on Ubuntu,
    1.19 +#   sudo apt-get install python-fontforge
    1.20 +
    1.21 +from __future__ import print_function
    1.22 +import fontforge
    1.23 +
    1.24 +em = 1000
    1.25 +
    1.26 +def newMathFont(aName):
    1.27 +    print("Generating %s.otf..." % aName, end="")
    1.28 +    mathFont = fontforge.font()
    1.29 +    mathFont.fontname = aName
    1.30 +    mathFont.familyname = aName
    1.31 +    mathFont.fullname = aName
    1.32 +    mathFont.copyright = "Copyright (c) 2014 Mozilla Corporation"
    1.33 +    mathFont.encoding = "UnicodeFull"
    1.34 +
    1.35 +    # Create a space character. Also force the creation of some MATH subtables
    1.36 +    # so that OTS will not reject the MATH table.
    1.37 +    g = mathFont.createChar(ord(" "), "space")
    1.38 +    g.width = em
    1.39 +    g.italicCorrection = 0
    1.40 +    g.topaccent = 0
    1.41 +    g.mathKern.bottomLeft = tuple([(0,0)])
    1.42 +    g.mathKern.bottomRight = tuple([(0,0)])
    1.43 +    g.mathKern.topLeft = tuple([(0,0)])
    1.44 +    g.mathKern.topRight = tuple([(0,0)])
    1.45 +    mathFont[ord(" ")].horizontalVariants = "space"
    1.46 +    mathFont[ord(" ")].verticalVariants = "space"
    1.47 +    return mathFont
    1.48 +
    1.49 +def saveMathFont(aFont):
    1.50 +    aFont.em = em
    1.51 +    aFont.ascent = aFont.descent = em/2
    1.52 +    aFont.hhea_ascent = aFont.os2_typoascent = aFont.os2_winascent = em/2
    1.53 +    aFont.descent = aFont.hhea_descent = em/2
    1.54 +    aFont.os2_typodescent = aFont.os2_windescent = em/2
    1.55 +    aFont.hhea_ascent_add = aFont.hhea_descent_add = 0
    1.56 +    aFont.os2_typoascent_add = aFont.os2_typodescent_add = 0
    1.57 +    aFont.os2_winascent_add = aFont.os2_windescent_add = 0
    1.58 +    aFont.os2_use_typo_metrics = True
    1.59 +    aFont.generate(aFont.fontname + ".otf")
    1.60 +    print(" done.")
    1.61 +
    1.62 +################################################################################
    1.63 +# Glyph variants and constructions
    1.64 +f = newMathFont("stretchy")
    1.65 +nvariants = 3
    1.66 +
    1.67 +# Draw boxes for the size variants and glues
    1.68 +for i in range(0, nvariants):
    1.69 +    s = em * (i + 1)
    1.70 +
    1.71 +    g = f.createChar(-1, "h%d" % i)
    1.72 +    p = g.glyphPen()
    1.73 +    p.moveTo(0, -em)
    1.74 +    p.lineTo(0, em)
    1.75 +    p.lineTo(s, em)
    1.76 +    p.lineTo(s, -em)
    1.77 +    p.closePath()
    1.78 +    g.width = s
    1.79 +
    1.80 +    g = f.createChar(-1, "v%d" % i)
    1.81 +    p = g.glyphPen()
    1.82 +    p.moveTo(0, 0)
    1.83 +    p.lineTo(0, s)
    1.84 +    p.lineTo(2 * em, s)
    1.85 +    p.lineTo(2 * em, 0)
    1.86 +    p.closePath();
    1.87 +    g.width = 2 * em
    1.88 +
    1.89 +# Draw some pieces for stretchy operators
    1.90 +s = em * nvariants
    1.91 +
    1.92 +g = f.createChar(-1, "left")
    1.93 +p = g.glyphPen()
    1.94 +p.moveTo(0, -2 * em)
    1.95 +p.lineTo(0, 2 * em)
    1.96 +p.lineTo(s, em)
    1.97 +p.lineTo(s, -em)
    1.98 +p.closePath();
    1.99 +g.width = s
   1.100 +
   1.101 +g = f.createChar(-1, "right")
   1.102 +p = g.glyphPen()
   1.103 +p.moveTo(0, -em)
   1.104 +p.lineTo(0, em)
   1.105 +p.lineTo(s, 2 * em)
   1.106 +p.lineTo(s, -2 * em)
   1.107 +p.closePath();
   1.108 +g.width = s
   1.109 +
   1.110 +g = f.createChar(-1, "hmid")
   1.111 +p = g.glyphPen()
   1.112 +p.moveTo(0, -em)
   1.113 +p.lineTo(0, em)
   1.114 +p.lineTo(s, 2 * em)
   1.115 +p.lineTo(2 * s, em)
   1.116 +p.lineTo(2 * s, -em)
   1.117 +p.lineTo(s, -2 * em)
   1.118 +p.closePath();
   1.119 +g.width = 2 * s
   1.120 +
   1.121 +g = f.createChar(-1, "bottom")
   1.122 +p = g.glyphPen()
   1.123 +p.moveTo(0, 0)
   1.124 +p.lineTo(0, s)
   1.125 +p.lineTo(2 * em, s)
   1.126 +p.lineTo(4 * em, 0)
   1.127 +p.closePath();
   1.128 +g.width = 4 * em
   1.129 +
   1.130 +g = f.createChar(-1, "top")
   1.131 +p = g.glyphPen()
   1.132 +p.moveTo(0, 0)
   1.133 +p.lineTo(4 * em, 0)
   1.134 +p.lineTo(2 * em, -s)
   1.135 +p.lineTo(0, -s)
   1.136 +p.closePath();
   1.137 +g.width = 4 * em
   1.138 +
   1.139 +g = f.createChar(-1, "vmid")
   1.140 +p = g.glyphPen()
   1.141 +p.moveTo(0, s)
   1.142 +p.lineTo(2 * em, s)
   1.143 +p.lineTo(4 * em, 0)
   1.144 +p.lineTo(2 * em, -s)
   1.145 +p.lineTo(0, -s)
   1.146 +p.closePath();
   1.147 +g.width = 3 * em
   1.148 +
   1.149 +# Create small rectangle of various size for some exotic arrows that are
   1.150 +# unlikely to be stretchable with standard fonts.
   1.151 +hstretchy = [
   1.152 +    0x219C, # leftwards wave arrow
   1.153 +    0x219D, # rightwards wave arrow
   1.154 +    0x219E, # leftwards two headed arrow
   1.155 +    0x21A0, # rightwards two headed arrow
   1.156 +    0x21A2  # leftwards arrow with tail
   1.157 +]
   1.158 +vstretchy = [
   1.159 +    0x219F, # upwards two headed arrow
   1.160 +    0x21A1, # downwards two headed arrow
   1.161 +    0x21A5, # upwards arrow from bar
   1.162 +    0x21A7, # downwards arrow from bar
   1.163 +    0x21A8  # up down arrow with base
   1.164 +]
   1.165 +for i in range(0, 1 + nvariants + 1):
   1.166 +    s = (i + 1) * em/10
   1.167 +
   1.168 +    g = f.createChar(hstretchy[i])
   1.169 +    p = g.glyphPen()
   1.170 +    p.moveTo(0, -em/10)
   1.171 +    p.lineTo(0, em/10)
   1.172 +    p.lineTo(s, em/10)
   1.173 +    p.lineTo(s, -em/10)
   1.174 +    p.closePath()
   1.175 +    g.width = s
   1.176 +
   1.177 +    g = f.createChar(vstretchy[i])
   1.178 +    p = g.glyphPen()
   1.179 +    p.moveTo(0, 0)
   1.180 +    p.lineTo(0, s)
   1.181 +    p.lineTo(2 * em/10, s)
   1.182 +    p.lineTo(2 * em/10, 0)
   1.183 +    p.closePath();
   1.184 +    g.width = 2 * em/10
   1.185 +
   1.186 +# hstretchy[0] and vstretchy[0] have all the variants and the components. The others only have one of them.
   1.187 +s = em * nvariants
   1.188 +
   1.189 +f[hstretchy[0]].horizontalVariants = "uni219C h0 h1 h2"
   1.190 +f[hstretchy[0]].horizontalComponents = (("left", False, 0, 0, s), \
   1.191 +("h2", True, 0, 0, s), ("hmid", False, 0, 0, 2 * s), ("h2", True, 0, 0, s), \
   1.192 +("right", False, 0, 0, s))
   1.193 +
   1.194 +f[hstretchy[1]].horizontalVariants = "uni219D h0"
   1.195 +f[hstretchy[2]].horizontalVariants = "uni219E h1"
   1.196 +f[hstretchy[3]].horizontalVariants = "uni21A0 h2"
   1.197 +f[hstretchy[4]].horizontalVariants = "uni21A2 h2"
   1.198 +f[hstretchy[4]].horizontalComponents = f[hstretchy[0]].horizontalComponents
   1.199 +
   1.200 +f[vstretchy[0]].verticalVariants = "uni219F v0 v1 v2"
   1.201 +f[vstretchy[0]].verticalComponents = (("bottom", False, 0, 0, s), \
   1.202 +("v2", True, 0, 0, s), ("vmid", False, 0, 0, 2 * s), ("v2", True, 0, 0, s), \
   1.203 +("top", False, 0, 0, s))
   1.204 +
   1.205 +f[vstretchy[1]].verticalVariants = "uni21A1 v0"
   1.206 +f[vstretchy[2]].verticalVariants = "uni21A5 v1"
   1.207 +f[vstretchy[3]].verticalVariants = "uni21A7 v2"
   1.208 +f[vstretchy[4]].verticalVariants = "uni21A8"
   1.209 +f[vstretchy[4]].verticalComponents = f[vstretchy[0]].verticalComponents
   1.210 +
   1.211 +################################################################################
   1.212 +# Testing DisplayOperatorMinHeight
   1.213 +f.math.DisplayOperatorMinHeight =  8 * em
   1.214 +largeop = [0x2A1B, 0x2A1C] # integral with overbar/underbar
   1.215 +
   1.216 +# Draw boxes of size 1, 2, 7, 8, 9em.
   1.217 +for i in [1, 2, 7, 8, 9]:
   1.218 +    s = em * i
   1.219 +    if i == 1 or i == 2:
   1.220 +        g = f.createChar(largeop[i-1])
   1.221 +    else:
   1.222 +        g = f.createChar(-1, "L%d" % i)
   1.223 +    p = g.glyphPen()
   1.224 +    p.moveTo(0, 0)
   1.225 +    p.lineTo(0, s)
   1.226 +    p.lineTo(s, s)
   1.227 +    p.lineTo(s, 0)
   1.228 +    p.closePath();
   1.229 +    g.width = s
   1.230 +
   1.231 +f[largeop[0]].verticalVariants = "uni2A1B L7 L8 L9"
   1.232 +f[largeop[1]].verticalVariants = "uni2A1C L8"
   1.233 +
   1.234 +saveMathFont(f)

mercurial