├── Slabikar.otf
├── examples
├── tex
│ ├── example.pdf
│ ├── reference
│ │ ├── example1.png
│ │ └── example2.png
│ ├── compare.py
│ └── example.tex
├── python
│ └── example.py
└── html
│ └── example.html
├── update_gh_pages.sh
├── environment.yml
├── font.ufo
├── metainfo.plist
├── layercontents.plist
├── fontinfo.plist
└── features.fea
├── gen
├── glif2svg.py
├── svg2glif.py
├── bezier.py
├── glif.py
└── svg.py
├── LICENSE
├── README.md
└── .github
└── workflows
└── CI.yml
/Slabikar.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/certik/slabikar-otf/HEAD/Slabikar.otf
--------------------------------------------------------------------------------
/examples/tex/example.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/certik/slabikar-otf/HEAD/examples/tex/example.pdf
--------------------------------------------------------------------------------
/examples/tex/reference/example1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/certik/slabikar-otf/HEAD/examples/tex/reference/example1.png
--------------------------------------------------------------------------------
/examples/tex/reference/example2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/certik/slabikar-otf/HEAD/examples/tex/reference/example2.png
--------------------------------------------------------------------------------
/update_gh_pages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -ex
4 |
5 | mkdir docs2
6 | cp Slabikar.otf docs2/
7 | cp examples/html/example.html docs2/index.html
8 | git checkout gh-pages
9 | rm -rf docs
10 | mv docs2 docs
11 |
--------------------------------------------------------------------------------
/environment.yml:
--------------------------------------------------------------------------------
1 | name: fonts
2 | channels:
3 | - conda-forge
4 | dependencies:
5 | - python=3.10
6 | - pip
7 | - tectonic=0.9.0
8 | - numpy=1.23.2
9 | - pillow=9.2.0
10 | - ghostscript=9.54.0
11 | - pip:
12 | - afdko==3.9.1
13 |
--------------------------------------------------------------------------------
/font.ufo/metainfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | formatVersion
6 | 3
7 |
8 |
9 |
--------------------------------------------------------------------------------
/font.ufo/layercontents.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | public.default
7 | glyphs
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/gen/glif2svg.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | from glif import parse_glif, glif2svg
4 |
5 | if len(sys.argv) != 2:
6 | print("glif2svg filename")
7 | sys.exit(1)
8 |
9 | filename_in = sys.argv[1]
10 | filename_out_svg = os.path.splitext(os.path.basename(filename_in))[0] + ".svg"
11 | print(f"{filename_in} -> {filename_out_svg}")
12 | g = parse_glif(open(filename_in).read())
13 | open(filename_out_svg, "w").write(glif2svg(g, False, True, 0.0))
14 |
--------------------------------------------------------------------------------
/gen/svg2glif.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | from glif import parse_svg, glif2svg, glif2glif
4 |
5 | if len(sys.argv) != 2:
6 | print("svg2glif filename")
7 | sys.exit(1)
8 |
9 | filename_in = sys.argv[1]
10 | filename_out_svg = os.path.splitext(os.path.basename(filename_in))[0] + "_out3.svg"
11 | print(f"{filename_in} -> {filename_out_svg}")
12 | g = parse_svg(open(filename_in).read())
13 | open(filename_out_svg, "w").write(glif2svg(g, False, True, 0.0))
14 |
15 | filename_out_glif = os.path.splitext(os.path.basename(filename_in))[0] + "_out3.glif"
16 | print(f"{filename_in} -> {filename_out_glif}")
17 | g = parse_svg(open(filename_in).read())
18 | open(filename_out_glif, "w").write(glif2glif(g))
19 |
--------------------------------------------------------------------------------
/examples/tex/compare.py:
--------------------------------------------------------------------------------
1 | from PIL.Image import open
2 | from PIL.ImageChops import difference
3 |
4 | def images_equal(img1, img2, diff):
5 | d = difference(open(img1), open(img2))
6 | if d.getbbox():
7 | d.save(diff)
8 | # Images not equal
9 | return False
10 | else:
11 | # Images equal
12 | return True
13 |
14 | if __name__ == '__main__':
15 | r1 = images_equal("example1.png", "reference/example1.png", "diff1.png")
16 | r2 = images_equal("example2.png", "reference/example2.png", "diff2.png")
17 | if r1 and r2:
18 | print("Images equal")
19 | else:
20 | print("Images NOT equal")
21 | raise Exception("Images not equal")
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Ondřej Čertík
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Slabikář Font
2 |
3 | This is an OpenType font (OTF) version of the Slabikář font from Petr Olšák:
4 |
5 | http://petr.olsak.net/ftp/olsak/slabikar/
6 |
7 | The `Slabikar.otf` font works in LaTeX, HTML, system-wide and it should work on
8 | any system and program that works with OTF fonts.
9 |
10 | # Examples
11 |
12 | * LaTeX: [example.tex](./examples/tex/example.tex) ([example.pdf](./examples/tex/example.pdf))
13 | * Online demo: https://certik.github.io/slabikar-otf/
14 |
15 | # Build Instructions
16 |
17 | To build the `Slabikar.otf` font from source:
18 | ```
19 | conda env create -f environment.yml
20 | conda activate fonts
21 | ./build.sh
22 | ```
23 |
24 | To install system-wide on macOS, do:
25 | ```
26 | cp Slabikar.otf ~/Library/Fonts
27 | ```
28 | Then open up some text editor, such as Pages, and select the font
29 | "Slabikář" and use it. Similarly on other systems.
30 |
31 |
32 | # License
33 |
34 | The Slabikář font shapes were created by Petr Olšák in Metafont and copyrighted
35 | by him.
36 |
37 | All the files in this repository were created by Ondřej Čertík and are licensed
38 | under the MIT license, see [LICENSE](./LICENSE) file for more information.
39 |
--------------------------------------------------------------------------------
/examples/python/example.py:
--------------------------------------------------------------------------------
1 | """
2 | Pillow has ImageFont for rendering text:
3 |
4 | https://pillow.readthedocs.io/en/stable/reference/ImageFont.html
5 |
6 | If Pillow is compiled without "RAQM" support, it can only print the glyphs from
7 | `Slabikar.otf`, but does not execute/interpret the GSUB/GPOS tables, so the
8 | beginning, end and middle connections are missing.
9 |
10 | In order to get the proper text, we have to use Pillow with RAQM. To be
11 | specific, the FreeType [1] library only handles glyph drawing, the HarfBuzz
12 | library handles "text shaping" (the GSUB/GPOS tables in the OTF font) and
13 | finally the RAQM [3] library provides a convenient API to FreeType+HarfBuzz.
14 |
15 | [1] https://freetype.org/
16 | [2] https://harfbuzz.github.io/
17 | [3] https://github.com/HOST-Oman/libraqm
18 | """
19 | import PIL.features
20 | if not PIL.features.check_feature("raqm"):
21 | print("Warning: RAQM support is missing, the font will be incorrectly connected")
22 | from PIL import Image, ImageFont, ImageDraw
23 | antialiasing = True
24 | scale=1
25 | image = Image.new(mode="L" if antialiasing else "1",
26 | size=(80*scale, 33*scale), color="white")
27 | draw = ImageDraw.Draw(image)
28 | font = ImageFont.truetype("../../Slabikar.otf", 50*scale)
29 | draw.text((3*scale, 2*scale), "Psát", font=font, fill='black')
30 | image.save("font.png")
31 |
--------------------------------------------------------------------------------
/gen/bezier.py:
--------------------------------------------------------------------------------
1 | from numpy import array, sqrt, arctan2, sin, cos
2 |
3 | def arg(z):
4 | # NumPy's arctan2(y,x) is equal to the arg(x,y) before equation (2) in [1]
5 | return arctan2(z[1], z[0])
6 |
7 | def compute_control_points(z1, z2, w1, w2, tau):
8 | """
9 | z1, z2 ... the Bezier nodes (1st and 4th control point)
10 | w1, w2 ... tangent vectors (do not have to be unit vectors), just direction
11 | tau ... tension (0.75 .. oo)
12 |
13 | The formulas are implemented from [1], equations (3) and (10).
14 |
15 | Note: the unit tangent vector always points along the direction of the
16 | curve, so the first point "in" the curve, but the second points "out".
17 |
18 | [1] John D. Hobby: Smooth, Easy to Compute Interpolating Splines. 1985. CS-TR-85-1047.
19 | Online link: http://i.stanford.edu/pub/cstr/reports/cs/tr/85/1047/CS-TR-85-1047.pdf
20 | """
21 | z1 = array(z1)
22 | z2 = array(z2)
23 | tau1 = tau2 = tau
24 |
25 | # Metafont parameters, paragraph after (10) in [1]
26 | a = sqrt(2)
27 | b = 1/16
28 | c = (3-sqrt(5))/2
29 |
30 | # Paragraph above equation (2) in [1]
31 | theta = arg(w1) - arg(z2-z1)
32 | phi = arg(z2-z1) - arg(w2)
33 |
34 | # Equations (10) in [1]
35 | alpha = a * (sin(theta) - b*sin(phi)) * (sin(phi) - b*sin(theta)) \
36 | * (cos(theta) - cos(phi))
37 | rho = (2 + alpha) / (1 + (1-c)*cos(theta) + c*cos(phi ))
38 | sigma = (2 - alpha) / (1 + (1-c)*cos(phi ) + c*cos(theta))
39 |
40 | # Paragraph above equation (3) in [1]
41 | c1 = rho/(3*tau1) * array([cos(theta), sin(theta)])
42 | c2 = array([1 - sigma/(3*tau2) * cos(phi), sigma/(3*tau2) * sin(phi)])
43 |
44 | # Shift and rotate the control points from (0,0)-(1,0) to z1-z2; equation (2) in [1]
45 | c1 = z1 + array([
46 | (z2[0]-z1[0])*c1[0]+(z1[1]-z2[1])*c1[1],
47 | (z2[1]-z1[1])*c1[0]+(z2[0]-z1[0])*c1[1]
48 | ])
49 | c2 = z1 + array([
50 | (z2[0]-z1[0])*c2[0]+(z1[1]-z2[1])*c2[1],
51 | (z2[1]-z1[1])*c2[0]+(z2[0]-z1[0])*c2[1]
52 | ])
53 |
54 | return c1, c2
55 |
--------------------------------------------------------------------------------
/examples/tex/example.tex:
--------------------------------------------------------------------------------
1 | \documentclass{article}
2 | \usepackage[a4paper, margin=1in]{geometry}
3 | \usepackage{fontspec}
4 |
5 |
6 | \begin{document}
7 |
8 | \fontsize{25pt}{30pt}
9 | \fontspec{Slabikar.otf}
10 |
11 | \noindent A--- písmeno pro tebe,\\
12 | anděl letí do nebe,\\
13 | Andělka mu štěstí přála\\
14 | a šátečkem zamávala,\\
15 | aby neulét\\
16 | a vrátil se zpět.\\
17 |
18 | \noindent Digits: 1234567890\\
19 | Punctuation: !?,.:;'" a-a a--a a---a\\
20 | Other: +-×*=/\textbackslash <>@()[]\{\}\%\&\$\#\^{}|\~{}\_‰\\
21 | "x" 'x' „x“\\
22 | aáäbcčdďeéěfghiíjklĺľmnňoóôpqrřŕsštťuúůvwxyýzž\\
23 | AÁÄBCČDĎEÉĚFGHIÍJKLĹĽMNŇOÓÔPQRŘŔSŠTŤUÚŮVWXYÝZŽ\\
24 | As Ás Äs Bs Cs Čs Ds Ďs Es És Ěs Fs Gs Hs Is Ís Js Ks Ls Ĺs Ľs Ms Ns Ňs Os Ós Ôs Ps Qs Rs Řs Ŕs Ss Šs Ts Ťs Us Ús Ůs Vs Ws Xs Ys Ýs Zs Žs\\
25 |
26 |
27 | \def\TeX{T\kern-.28em\lower.7ex\hbox{E}\kern-.17emX}
28 | \righthyphenmin=2 \emergencystretch=2em
29 | \hbadness=2900
30 |
31 | Toto písmo je potřeba brát spíš jako příklad, co všechno \TeX{} dovede.
32 | Nepředpokládám velké nasazení tohoto písma pro sazbu příštích
33 | slabikářů. Dokonce takovou věc ani nedoporučuji.
34 |
35 | Všechny ukázky ve slabikáři a v~písankách, které jsem měl možnost vidět,
36 | jsou psány lidskou rukou a ne strojem. Samozřejmě smekám před kaligrafem,
37 | který ty ukázky vytvořil. Člověk má na první pohled dojem, že to je
38 | „jak když tiskne“. Fušoval jsem také do kaligrafického řemesla, a proto
39 | dobře vím, že pokud písmo neobsahuje žádné ozdobné prvky, musí to napsat
40 | skutečně profesionál. Každá chybička, která by se třeba skryla za ozdobným
41 | prvkem, je totiž vidět.
42 |
43 | Důležité ale je, že písmo v~dnešním slabikáři bylo skutečně napsáno jen
44 | „jak“ když tiskne a nikoli tištěno doopravdy. Písmu tak neschází
45 | lidský rozměr, který ten prvňák podvědomě z~toho písma asi cítí. Kdyby se
46 | pro sazbu ukázek použil stroj (třebaže~\TeX), písmo by tento rozměr
47 | ztratilo. Takové písmo by bylo chladné, stále stejné, bez výrazu,
48 | tedy vlastně mrtvé. Nepřeji prvňákům, aby se někdy v~budoucnu
49 | s~takovým chladným písmem setkali.
50 |
51 | \medskip
52 | \hfill Petr Olšák
53 |
54 |
55 | \end{document}
56 |
--------------------------------------------------------------------------------
/examples/html/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
26 |
27 | Slabikář Font
28 | Download: Slabikar.otf
29 | Source code: https://github.com/certik/slabikar-otf
30 | You can edit the text below to play with the font:
31 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | tags:
8 | - 'v*'
9 | pull_request:
10 | branches:
11 | - main
12 |
13 |
14 | jobs:
15 | Build:
16 | name: Tectonic
17 | runs-on: ubuntu-latest
18 | strategy:
19 | fail-fast: false
20 | steps:
21 | - uses: actions/checkout@v2
22 | with:
23 | fetch-depth: 0
24 |
25 | - name: Install Inkscape in Ubuntu
26 | run: |
27 | sudo add-apt-repository ppa:inkscape.dev/stable
28 | sudo apt update
29 | sudo apt -y install inkscape
30 | sudo touch /var/lib/cloud/instance/locale-check.skip
31 |
32 | - uses: mamba-org/provision-with-micromamba@main
33 | with:
34 | environment-file: environment.yml
35 | extra-specs: |
36 | python=3.10
37 |
38 | - uses: hendrikmuhs/ccache-action@main
39 | with:
40 | variant: sccache
41 | key: ${{ github.job }}
42 |
43 | - name: Build
44 | shell: bash -l {0}
45 | run: |
46 | ./build.sh
47 |
48 | - name: Archive artifacts
49 | if: always()
50 | uses: actions/upload-artifact@v3
51 | with:
52 | name: results
53 | path: |
54 | Slabikar.otf
55 | examples/tex/example.pdf
56 | examples/tex/example1.png
57 | examples/tex/example2.png
58 | examples/tex/diff1.png
59 | examples/tex/diff2.png
60 |
61 | xelatex:
62 | name: xelatex
63 | runs-on: ubuntu-latest
64 | strategy:
65 | fail-fast: false
66 | steps:
67 | - uses: actions/checkout@v2
68 | with:
69 | fetch-depth: 0
70 |
71 | - name: Install Inkscape in Ubuntu
72 | run: |
73 | sudo add-apt-repository ppa:inkscape.dev/stable
74 | sudo apt update
75 | sudo apt -y install inkscape texlive-latex-extra texlive-xetex
76 | sudo touch /var/lib/cloud/instance/locale-check.skip
77 |
78 | - uses: mamba-org/provision-with-micromamba@main
79 | with:
80 | environment-file: environment.yml
81 | extra-specs: |
82 | python=3.10
83 |
84 | - uses: hendrikmuhs/ccache-action@main
85 | with:
86 | variant: sccache
87 | key: ${{ github.job }}
88 |
89 | - name: Build
90 | shell: bash -l {0}
91 | run: |
92 | ./build.sh
93 |
94 | - name: LaTeX
95 | shell: bash -l {0}
96 | run: |
97 | cd examples/tex
98 | rm example.pdf
99 | xelatex example.tex
100 |
101 | - name: Archive example.pdf
102 | if: always()
103 | uses: actions/upload-artifact@v3
104 | with:
105 | name: example_xelatex.pdf
106 | path: examples/tex/example.pdf
107 |
--------------------------------------------------------------------------------
/font.ufo/fontinfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ascender
6 | 712
7 | capHeight
8 | 656
9 | copyright
10 | Copyright 2022 Ondřej Čertík, Petr Olšák
11 | descender
12 | -205
13 | familyName
14 | Slabikář
15 | guidelines
16 |
17 |
18 | italicAngle
19 | 0
20 | openTypeHheaAscender
21 | 1024
22 | openTypeHheaDescender
23 | -400
24 | openTypeHheaLineGap
25 | 0
26 | openTypeNameDesigner
27 | Petr Olšák
28 | openTypeNameLicense
29 | All files are licensed under the MIT license.
30 | openTypeNameLicenseURL
31 | https://opensource.org/licenses/MIT
32 | openTypeOS2CodePageRanges
33 |
34 | 0
35 | 1
36 | 2
37 | 3
38 | 4
39 | 7
40 | 8
41 | 29
42 |
43 | openTypeOS2Panose
44 |
45 | 2
46 | 11
47 | 5
48 | 3
49 | 3
50 | 4
51 | 3
52 | 2
53 | 2
54 | 4
55 |
56 | openTypeOS2TypoAscender
57 | 750
58 | openTypeOS2TypoDescender
59 | -250
60 | openTypeOS2TypoLineGap
61 | 0
62 | openTypeOS2UnicodeRanges
63 |
64 | 0
65 | 1
66 | 2
67 | 4
68 | 5
69 | 6
70 | 7
71 | 9
72 | 29
73 | 30
74 | 32
75 | 57
76 |
77 | openTypeOS2WinAscent
78 | 984
79 | openTypeOS2WinDescent
80 | 273
81 | postscriptBlueFuzz
82 | 0
83 | postscriptBlueScale
84 | 0.0625
85 | postscriptBlueValues
86 |
87 | -12
88 | 0
89 | 486
90 | 498
91 | 518
92 | 530
93 | 574
94 | 586
95 | 638
96 | 650
97 | 656
98 | 668
99 | 712
100 | 724
101 |
102 | postscriptFamilyBlues
103 |
104 | -12
105 | 0
106 | 486
107 | 498
108 | 518
109 | 530
110 | 574
111 | 586
112 | 638
113 | 650
114 | 656
115 | 668
116 | 712
117 | 724
118 |
119 | postscriptFamilyOtherBlues
120 |
121 | -217
122 | -205
123 |
124 | postscriptFontName
125 | Slabikar
126 | postscriptOtherBlues
127 |
128 | -217
129 | -205
130 |
131 | postscriptStemSnapH
132 |
133 | 67
134 | 78
135 |
136 | postscriptStemSnapV
137 |
138 | 84
139 | 95
140 |
141 | postscriptUnderlinePosition
142 | -75
143 | postscriptUnderlineThickness
144 | 50
145 | styleName
146 | Regular
147 | unitsPerEm
148 | 1000
149 | versionMajor
150 | 1
151 | versionMinor
152 | 0
153 | xHeight
154 | 486
155 |
156 |
157 |
--------------------------------------------------------------------------------
/gen/glif.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 | from xml.etree.ElementTree import Element, tostring, fromstring, indent
3 |
4 | # Abstract Semantic Representation of the Glif format:
5 |
6 | @dataclass
7 | class Point:
8 | x: int
9 | y: int
10 | type: str
11 | smooth: bool
12 |
13 | @dataclass
14 | class Anchor:
15 | x: int
16 | y: int
17 | name: str
18 |
19 | @dataclass
20 | class Glif:
21 | name: str
22 | unicode_hex: str
23 | w: int
24 | contours: list[list[Point]]
25 | anchors: list[Anchor]
26 |
27 | # Verify
28 |
29 | def require(cond, msg):
30 | if not cond:
31 | raise Exception(msg)
32 |
33 | # TODO: verify "smooth" for each point as well. Give an error for
34 | # smooth=yes that is not smooth; and a warning for not defined smooth parameter
35 | # if it is smooth
36 | def verify_contour(contour: list[Point]):
37 | debug_print = False
38 | for n, point in enumerate(contour):
39 | require(isinstance(point.x, (int,float)), "Point.x must be integer")
40 | require(isinstance(point.y, (int,float)), "Point.y must be integer")
41 | require(point.type in ["curve", "offcurve", "line", "move"],
42 | "Point.type is not correct")
43 | if n > 0:
44 | require(point.type != "move",
45 | "Point.type cannot be move for n > 0")
46 | if len(contour) > 0:
47 | p = contour[0]
48 | # UFO 3 allows to start with any point (even offcurve), but we further
49 | # restrict it to always start with a line or curve, which simplifies
50 | # the writers.
51 | require(p.type in ["curve", "line", "move"],
52 | "The contour must start with a curve or line")
53 | if p.type == "move":
54 | require(contour[-1].type in ["curve", "line"],
55 | "Open contour must end with curve or line")
56 | else:
57 | contour = contour + [p]
58 | # The previous point type:
59 | # 0 ... line node (line)
60 | # 1 ... 1st curve point (offcurve)
61 | # 2 ... 2nd curve point (offcurve)
62 | # 3 ... 3rd curve point (curve)
63 | if p.type in ["line", "move"]:
64 | last_point_type = 0
65 | else:
66 | assert p.type == "curve"
67 | last_point_type = 3
68 | if debug_print:
69 | print(p, "'first point'")
70 | for p in contour[1:]:
71 | if debug_print:
72 | print(p, last_point_type)
73 | if p.type == "line":
74 | require(last_point_type in [0,3],
75 | "the last point before line must be line or curve")
76 | last_point_type = 0
77 | elif p.type == "curve":
78 | require(last_point_type == 2,
79 | "the last point before curve must be second offcurve point")
80 | last_point_type = 3
81 | else:
82 | assert p.type == "offcurve"
83 | require(last_point_type != 2,
84 | "three offcurve points in a row are not allowed")
85 | if last_point_type in [0, 3]:
86 | # First offcurve point
87 | last_point_type = 1
88 | else:
89 | # Second offcurve point
90 | assert last_point_type == 1
91 | last_point_type = 2
92 |
93 |
94 | def verify(glif: Glif):
95 | if glif.w is not None:
96 | require(isinstance(glif.w, (int,float)), "w must be integer")
97 | require(isinstance(glif.name, str), "name must be str")
98 | for contour in glif.contours:
99 | verify_contour(contour)
100 |
101 | # Reader for Glif:
102 |
103 | def num(x):
104 | try:
105 | return int(x)
106 | except ValueError:
107 | return float(x)
108 |
109 | def parse_glif(glif: str) -> Glif:
110 | glif = fromstring(glif)
111 | name = glif.get("name")
112 | if glif.find("advance") is not None:
113 | w = int(glif.find("advance").get("width"))
114 | else:
115 | w = None
116 | if glif.find("unicode") is not None:
117 | unicode_hex = glif.find("unicode").get("hex")
118 | else:
119 | unicode_hex = None
120 | contours = []
121 | if glif.find("outline") is not None:
122 | for contour in glif.find("outline"):
123 | if contour.tag == "contour":
124 | c = []
125 | for p in contour:
126 | x = num(p.get("x"))
127 | y = num(p.get("y"))
128 | type = p.get("type")
129 | if type is None:
130 | type = "offcurve"
131 | smooth = p.get("smooth") == "yes"
132 | c.append(Point(x, y, type, smooth))
133 | contours.append(c)
134 | anchors = []
135 | for a in glif:
136 | if a.tag == "anchor":
137 | x = int(a.get("x"))
138 | y = int(a.get("y"))
139 | anchor_name = a.get("name")
140 | anchors.append(Anchor(x, y, anchor_name))
141 | g = Glif(name, unicode_hex, w, contours, anchors)
142 | verify(g)
143 | return g
144 |
145 | def parse_points(x, scale, height):
146 | points = []
147 | for p in x:
148 | if p.find(",") != -1:
149 | x, y = p.split(",")
150 | points.append([
151 | (float(x)*scale),
152 | ((height-float(y))*scale)
153 | ])
154 | else:
155 | break
156 | return points
157 |
158 | def parse_svg(svg_str: str) -> Glif:
159 | #scale = 1/18 * 1000
160 | scale = 1.0
161 | svg = fromstring(svg_str)
162 | # FIXME:
163 | name = "a"
164 | width = float(svg.get("width"))
165 | height = float(svg.get("height"))
166 | w = round(width * scale)
167 | h = round(height * scale)
168 | unicode_hex = None
169 |
170 | contours = []
171 | path = svg[2]
172 | if path.get("id") != "path0":
173 | print("Path ID differs:", path.get("id"))
174 | p = path.get("d")
175 | x = p.split()
176 |
177 | i = 0
178 | contour = []
179 | current_x = 0
180 | current_y = h
181 | while True:
182 | if i >= len(x):
183 | break
184 | if x[i] == "m":
185 | points = parse_points(x[i+1:], scale, 0)
186 | p = points[0]
187 | current_x += p[0]
188 | current_y += p[1]
189 | contour.append(Point(
190 | x=current_x,
191 | y=current_y,
192 | type="move", smooth=False))
193 | for p in points[1:]:
194 | contour.append(Point(
195 | x=current_x+p[0],
196 | y=current_y+p[1],
197 | type="line", smooth=False))
198 | current_x = contour[-1].x
199 | current_y = contour[-1].y
200 | i += len(points) + 1
201 | elif x[i] == "M":
202 | points = parse_points(x[i+1:], scale, height)
203 | p = points[0]
204 | current_x = p[0]
205 | current_y = p[1]
206 | contour.append(Point(
207 | x=current_x,
208 | y=current_y,
209 | type="move", smooth=False))
210 | for p in points[1:]:
211 | contour.append(Point(
212 | x=p[0],
213 | y=p[1],
214 | type="line", smooth=False))
215 | current_x = contour[-1].x
216 | current_y = contour[-1].y
217 | i += len(points) + 1
218 | elif x[i] == "c":
219 | points = parse_points(x[i+1:], scale, 0)
220 | assert len(points) % 3 == 0
221 | for j in range(len(points) // 3):
222 | contour.append(Point(
223 | x=current_x+points[3*j][0],
224 | y=current_y+points[3*j][1],
225 | type="offcurve", smooth=False))
226 | contour.append(Point(
227 | x=current_x+points[3*j+1][0],
228 | y=current_y+points[3*j+1][1],
229 | type="offcurve", smooth=False))
230 | contour.append(Point(
231 | x=current_x+points[3*j+2][0],
232 | y=current_y+points[3*j+2][1],
233 | type="curve", smooth=False))
234 | current_x = contour[-1].x
235 | current_y = contour[-1].y
236 | i += len(points) + 1
237 | elif x[i] == "C":
238 | points = parse_points(x[i+1:], scale, height)
239 | assert len(points) % 3 == 0
240 | for j in range(len(points) // 3):
241 | contour.append(Point(
242 | x=points[3*j][0],
243 | y=points[3*j][1],
244 | type="offcurve", smooth=False))
245 | contour.append(Point(
246 | x=points[3*j+1][0],
247 | y=points[3*j+1][1],
248 | type="offcurve", smooth=False))
249 | contour.append(Point(
250 | x=points[3*j+2][0],
251 | y=points[3*j+2][1],
252 | type="curve", smooth=False))
253 | current_x = contour[-1].x
254 | current_y = contour[-1].y
255 | i += len(points) + 1
256 | elif x[i] == "l":
257 | points = parse_points(x[i+1:], scale, 0)
258 | for p in points:
259 | contour.append(Point(
260 | x=current_x+p[0],
261 | y=current_y+p[1],
262 | type="line", smooth=False))
263 | current_x = contour[-1].x
264 | current_y = contour[-1].y
265 | i += len(points) + 1
266 | elif x[i] == "L":
267 | points = parse_points(x[i+1:], scale, height)
268 | for p in points:
269 | contour.append(Point(x=p[0], y=p[1], type="line", smooth=False))
270 | current_x = contour[-1].x
271 | current_y = contour[-1].y
272 | i += len(points) + 1
273 | elif x[i] == "h":
274 | points = [(float(x[i+1]))*scale]
275 | for p in points:
276 | contour.append(Point(x=current_x+p, y=current_y, type="line", smooth=False))
277 | current_x = contour[-1].x
278 | current_y = contour[-1].y
279 | i += len(points) + 1
280 | elif x[i] == "H":
281 | points = [(float(x[i+1]))*scale]
282 | for p in points:
283 | contour.append(Point(x=p, y=current_y, type="line", smooth=False))
284 | current_x = contour[-1].x
285 | current_y = contour[-1].y
286 | i += len(points) + 1
287 | elif x[i] == "v":
288 | points = [(-float(x[i+1]))*scale]
289 | for p in points:
290 | contour.append(Point(x=current_x, y=current_y+p, type="line", smooth=False))
291 | current_x = contour[-1].x
292 | current_y = contour[-1].y
293 | i += len(points) + 1
294 | elif x[i] == "V":
295 | points = [(height-float(x[i+1]))*scale]
296 | for p in points:
297 | contour.append(Point(x=current_x, y=p, type="line", smooth=False))
298 | current_x = contour[-1].x
299 | current_y = contour[-1].y
300 | i += len(points) + 1
301 | elif x[i] in ["A", "a"]:
302 | print(x[i])
303 | raise Exception("Elliptical Arc Curve (A, a) not supported")
304 | elif x[i] in ["z", "Z"]:
305 | contour[0].type = "line"
306 | contours.append(contour)
307 | current_x = contour[0].x
308 | current_y = contour[0].y
309 | contour = []
310 | i += 1
311 | else:
312 | print(x[i])
313 | raise Exception("Not supported")
314 |
315 | anchors = []
316 | g = Glif(name, unicode_hex, w, contours, anchors)
317 | verify(g)
318 | return g
319 |
320 | # Glif -> SVG:
321 |
322 | def glif2svg(glif: Glif, separate_paths: bool, fill: bool,
323 | stroke_width: int) -> str:
324 | h = 800
325 | svg = Element('svg', width=str(glif.w), height=str(h), version='1.1',
326 | xmlns='http://www.w3.org/2000/svg')
327 |
328 | path_str = ""
329 |
330 | for n, contour in enumerate(glif.contours):
331 | p0 = contour[0]
332 | assert p0.type != "offcurve"
333 | assert p0.type in ["curve", "line", "move"]
334 | is_curve = (contour[1].type in ["offcurve", "curve"])
335 | if is_curve:
336 | path_str += "M {},{} C".format(p0.x, h-p0.y)
337 | else:
338 | path_str += "M {},{} L".format(p0.x, h-p0.y)
339 | if p0.type != "move":
340 | contour = contour + [p0]
341 | for point in contour[1:]:
342 | if point.type in ["offcurve", "curve"]:
343 | if is_curve:
344 | path_str += " {},{}".format(point.x, h-point.y)
345 | else:
346 | is_curve = True
347 | path_str += " C {},{}".format(point.x, h-point.y)
348 | else:
349 | assert point.type == "line"
350 | if is_curve:
351 | is_curve = False
352 | path_str += " L {},{}".format(point.x, h-point.y)
353 | else:
354 | path_str += " {},{}".format(point.x, h-point.y)
355 | if p0.type != "move":
356 | path_str += " Z"
357 | if separate_paths:
358 | p = Element('path', d=path_str, fill='none', stroke="black",
359 | style="stroke-linecap:butt;stroke-linejoin:mitter",
360 | id=f"path{n}",
361 | attrib={"stroke-width": str(stroke_width)})
362 | svg.append(p)
363 | path_str = ""
364 | else:
365 | path_str += " "
366 | if not separate_paths:
367 | if fill:
368 | p = Element('path', d=path_str, fill="black", stroke="black",
369 | style="stroke-linecap:butt;stroke-linejoin:round",
370 | id="path0",
371 | attrib={"stroke-width": "0.0"})
372 | else:
373 | p = Element('path', d=path_str, fill="none", stroke="black",
374 | style="stroke-linecap:butt;stroke-linejoin:mitter",
375 | id="path0",
376 | attrib={"stroke-width": str(stroke_width)})
377 | svg.append(p)
378 |
379 | for anchor in glif.anchors:
380 | p = Element('circle', cx=str(anchor.x), cy=str(h-anchor.y),
381 | stroke="black", r="10", id=f"{anchor.name}",
382 | attrib={"stroke-width": "2.0"})
383 | svg.append(p)
384 |
385 | svg_out = '\n'
386 | indent(svg, space=" ")
387 | svg_out += tostring(svg).decode() + "\n"
388 | return svg_out
389 |
390 | # Glif -> Glif:
391 |
392 | def glif2glif(glif: Glif) -> str:
393 | attrib = {}
394 | svg = Element('glyph', name=glif.name, format="2")
395 |
396 | advance = Element("advance", width=str(glif.w))
397 | svg.append(advance)
398 |
399 | if len(glif.contours) > 0:
400 | outline = Element('outline')
401 | for contour in glif.contours:
402 | contour_ = Element("contour")
403 | for point in contour:
404 | attrib = {}
405 | if point.smooth:
406 | attrib["smooth"] = "yes"
407 | if point.type != "offcurve":
408 | attrib["type"] = point.type
409 | point_ = Element("point", x=str(point.x), y=str(point.y),
410 | attrib=attrib)
411 | contour_.append(point_)
412 | outline.append(contour_)
413 | svg.append(outline)
414 |
415 | # for anchor in glif.anchors:
416 | # p = Element('circle', cx=str(anchor.x), cy=str(h-anchor.y),
417 | # stroke="black", r="10", id=f"{anchor.name}",
418 | # attrib={"stroke-width": "2.0"})
419 | # svg.append(p)
420 |
421 | svg_out = '\n'
422 | indent(svg, space=" ")
423 | svg_out += tostring(svg).decode() + "\n"
424 | return svg_out
425 |
--------------------------------------------------------------------------------
/font.ufo/features.fea:
--------------------------------------------------------------------------------
1 | # # Documentation
2 | #
3 | # This file's syntax and semantics is documented at:
4 | #
5 | # http://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html
6 | #
7 | # The asdfo library then compiles it to an OTF font, the glyph substitution
8 | # part creates GSUB tables in the OTF font. The general documentation how the
9 | # Glyph Substitution table (GSUB) works is described at:
10 | #
11 | # https://docs.microsoft.com/en-us/typography/opentype/spec/gsub
12 | #
13 | # Roughly speaking, the GSUB mechanism is composed of substitution lookups
14 | # (LookupList) tables, each is one of 7 kinds:
15 | # * GSUB LookupType 1: single (a -> x)
16 | # * GSUB LookupType 2: multiple (a -> x y z)
17 | # * GSUB LookupType 3: alternate (a -> x, where x is one of several glyphs)
18 | # * GSUB LookupType 4: ligature (a b c -> x)
19 | # * GSUB LookupType 5: context (a b' d -> x)
20 | # * GSUB LookupType 6: chaining context (chain multiple "context" substitutions)
21 | # * GSUB LookupType 7: extension (use 32-bit offsets instead of 16-bit)
22 | # * GSUB LookupType 8: reverse chaining context (applied from right to left)
23 | #
24 | # The `features.fea` file compiles into these tables, but allows to specify the
25 | # rules in a higher level / simpler language.
26 | #
27 | # # Single
28 | #
29 | # substitute by ; # format A
30 | # substitute by ; # format B
31 | # substitute by ; # format C
32 | #
33 | # E.g.:
34 | #
35 | # substitute a by A.sc;
36 | #
37 | # # Multiple
38 | #
39 | # substitute by ;
40 | #
41 | # E.g.:
42 | #
43 | # substitute f_f_i by f f i;
44 | # sub ka by ka.pas_cakra ka;
45 | #
46 | # # Alternate
47 | #
48 | # substitute from ;
49 | #
50 | # E.g.:
51 | #
52 | # substitute ampersand from [ampersand.1 ampersand.2 ampersand.3];
53 | #
54 | # # Ligature
55 | #
56 | # substitute by ;
57 | #
58 | # E.g.:
59 | #
60 | # sub f i by f_i;
61 | # sub f f i by f_f_i;
62 | # sub ka ka.pas_cakra.ns by ka;
63 | #
64 | # The order does not matter, the rendering engine sorts from longest to
65 | # shortest.
66 | #
67 | # # Context
68 | #
69 | # E.g.:
70 | #
71 | # substitute a b c' d' e f by x y
72 | # substitute c' by x y
73 | #
74 | # The rule has three parts: backtrack (a b), input (c' d'),
75 | # and lookahead (e f) glyph sequences. The input is required,
76 | # backtrack/lookahead is optional.
77 | #
78 | # The order matters, the first takes priority.
79 | #
80 | #
81 | # # Chaining Context
82 | #
83 | # E.g.:
84 | #
85 | # sub ka' lookup REMOVE_CAKRA lookup REORDER_CAKRA ka.pas_cakra.ns' ;
86 | # substitute [ a e i o u] f' lookup CNTXT_LIGS i' n' lookup CNTXT_SUB;
87 | #
88 | # The order matters, the first takes priority.
89 | #
90 | # The lookup can only be called for "input" part, and the lookup substitution
91 | # is applied for each position (so CNTXT_LIGS for f' and CNTXT_SUB for n').
92 | #
93 | # Within each lookup, either exactly one rule will apply (and the new sequence
94 | # is passed to the next lookup) or no rule will apply (and the original
95 | # sequence is passed).
96 | #
97 | # The rule is first matched, for example `ka' ka.pas_cakra.ns'` or
98 | # `[ a e i o u] f' i' n'`, and if it matches, then the lookup subsitutions are
99 | # performed in order from left to right at the given position.
100 | #
101 | # Worked out example:
102 | #
103 | # lookup CNTXT_LIGS {
104 | # substitute f i by f_i;
105 | # substitute c t by c_t;
106 | # } CNTXT_LIGS;
107 | #
108 | # lookup CNTXT_SUB {
109 | # substitute n by n.end;
110 | # substitute s by s.end;
111 | # } CNTXT_SUB;
112 | #
113 | # feature test {
114 | # substitute [ a e i o u] f' lookup CNTXT_LIGS i' n' lookup CNTXT_SUB;
115 | # substitute [ a e i o u] c' lookup CNTXT_LIGS t' s' lookup CNTXT_SUB;
116 | # } test;
117 | #
118 | # Here are the steps:
119 | #
120 | # a f i n -> a f_i n -> a f_i n.end
121 | # e c t s -> a c_t s -> a c_t s.end
122 | # e c t n -> e c t n # no match
123 | #
124 | #
125 |
126 | languagesystem DFLT dflt;
127 | languagesystem latn dflt;
128 |
129 | # Basic letters from unicode input (no connections, no begin/end)
130 | @LETTER_LC = [a-z
131 | aacute adieresis ccaron dcaron eacute ecaron iacute lacute lcaron ncaron
132 | oacute ocircumflex racute rcaron scaron tcaron uacute uring yacute zcaron];
133 |
134 | @LETTER_UC = [A-Z
135 | Aacute Adieresis Ccaron Dcaron Eacute Ecaron Iacute Lacute Lcaron Ncaron
136 | Oacute Ocircumflex Racute Rcaron Scaron Tcaron Uacute Uring Yacute Zcaron];
137 |
138 | @LETTER0 = [@LETTER_LC @LETTER_UC];
139 |
140 | # Our custom versions of letters, cannot be input directly
141 | @LETTER1 = [sleft sdepth scaronleft scarondepth bnarrow onarrow oacutenarrow ocircumflexnarrow vnarrow wnarrow];
142 |
143 | # All inner word connections (no begin/end), cannot be input directly
144 | @CONN = [conn_s conn_sv conn_P];
145 |
146 | # All letters including connecting paths (conn_s, conn_sv, ...), but no begin
147 | # and end glyphs
148 | @LETTER = [@LETTER0 @LETTER1 @CONN];
149 |
150 | @BCONN_LETTERS = [m n ncaron v w y yacute];
151 | @SCONN_LETTERS = [@BCONN_LETTERS t tcaron z zcaron];
152 |
153 | # All lower case letters and variations and internal connections
154 | @LCLETTERS = [@LETTER_LC @LETTER1 @CONN];
155 |
156 |
157 | lookup LETTER_BEGIN {
158 | # beginning of the word
159 | ignore substitute @LETTER b';
160 | substitute b' by begin b;
161 | ignore substitute @LETTER e';
162 | substitute e' by begin e;
163 | ignore substitute @LETTER eacute';
164 | substitute eacute' by begin eacute;
165 | ignore substitute @LETTER ecaron';
166 | substitute ecaron' by begin ecaron;
167 | ignore substitute @LETTER f';
168 | substitute f' by begin f;
169 | ignore substitute @LETTER h';
170 | substitute h' by begin h;
171 | ignore substitute @LETTER i';
172 | substitute i' by begin i;
173 | ignore substitute @LETTER iacute';
174 | substitute iacute' by begin iacute;
175 | ignore substitute @LETTER j';
176 | substitute j' by begin j;
177 | ignore substitute @LETTER k';
178 | substitute k' by begin k;
179 | ignore substitute @LETTER l';
180 | substitute l' by begin l;
181 | ignore substitute @LETTER lacute';
182 | substitute lacute' by begin lacute;
183 | ignore substitute @LETTER lcaron';
184 | substitute lcaron' by begin lcaron;
185 | ignore substitute @LETTER m';
186 | substitute m' by begin_straight m;
187 | ignore substitute @LETTER n';
188 | substitute n' by begin_straight n;
189 | ignore substitute @LETTER ncaron';
190 | substitute ncaron' by begin_straight ncaron;
191 | ignore substitute @LETTER p';
192 | substitute p' by begin p;
193 | ignore substitute @LETTER r';
194 | substitute r' by begin r;
195 | ignore substitute @LETTER rcaron';
196 | substitute rcaron' by begin rcaron;
197 | ignore substitute @LETTER racute';
198 | substitute racute' by begin racute;
199 | ignore substitute @LETTER s';
200 | substitute s' by begin s;
201 | ignore substitute @LETTER scaron';
202 | substitute scaron' by begin scaron;
203 | ignore substitute @LETTER t';
204 | substitute t' by begin t;
205 | ignore substitute @LETTER tcaron';
206 | substitute tcaron' by begin tcaron;
207 | ignore substitute @LETTER u';
208 | substitute u' by begin u;
209 | ignore substitute @LETTER uacute';
210 | substitute uacute' by begin uacute;
211 | ignore substitute @LETTER uring';
212 | substitute uring' by begin uring;
213 | ignore substitute @LETTER v';
214 | substitute v' by begin_straight v;
215 | ignore substitute @LETTER w';
216 | substitute w' by begin_straight w;
217 | ignore substitute @LETTER x';
218 | substitute x' by begin_x x;
219 | ignore substitute @LETTER y';
220 | substitute y' by begin_straight y;
221 | ignore substitute @LETTER yacute';
222 | substitute yacute' by begin_straight yacute;
223 | ignore substitute @LETTER z';
224 | substitute z' by begin_straight z;
225 | ignore substitute @LETTER zcaron';
226 | substitute zcaron' by begin_straight zcaron;
227 | } LETTER_BEGIN;
228 |
229 | lookup LETTER_END {
230 | # end of the word
231 | ignore substitute a' @LETTER;
232 | substitute a' by a end;
233 | ignore substitute aacute' @LETTER;
234 | substitute aacute' by aacute end;
235 | ignore substitute adieresis' @LETTER;
236 | substitute adieresis' by adieresis end;
237 | ignore substitute b' @LETTER;
238 | substitute b' by b end;
239 | ignore substitute c' @LETTER;
240 | substitute c' by c end;
241 | ignore substitute ccaron' @LETTER;
242 | substitute ccaron' by ccaron end;
243 | ignore substitute d' @LETTER;
244 | substitute d' by d end;
245 | ignore substitute dcaron' @LETTER;
246 | substitute dcaron' by dcaron end;
247 | ignore substitute e' @LETTER;
248 | substitute e' by e end;
249 | ignore substitute eacute' @LETTER;
250 | substitute eacute' by eacute end;
251 | ignore substitute ecaron' @LETTER;
252 | substitute ecaron' by ecaron end;
253 | ignore substitute f' @LETTER;
254 | substitute f' by f end;
255 | ignore substitute g' @LETTER;
256 | substitute g' by g end;
257 | ignore substitute h' @LETTER;
258 | substitute h' by h end;
259 | ignore substitute i' @LETTER;
260 | substitute i' by i end;
261 | ignore substitute iacute' @LETTER;
262 | substitute iacute' by iacute end;
263 | ignore substitute j' @LETTER;
264 | substitute j' by j end;
265 | ignore substitute k' @LETTER;
266 | substitute k' by k end;
267 | ignore substitute l' @LETTER;
268 | substitute l' by l end;
269 | ignore substitute lacute' @LETTER;
270 | substitute lacute' by lacute end;
271 | ignore substitute lcaron' @LETTER;
272 | substitute lcaron' by lcaron end;
273 | ignore substitute m' @LETTER;
274 | substitute m' by m end;
275 | ignore substitute n' @LETTER;
276 | substitute n' by n end;
277 | ignore substitute ncaron' @LETTER;
278 | substitute ncaron' by ncaron end;
279 | ignore substitute o' @LETTER;
280 | substitute o' by o end;
281 | ignore substitute oacute' @LETTER;
282 | substitute oacute' by oacute end;
283 | ignore substitute ocircumflex' @LETTER;
284 | substitute ocircumflex' by ocircumflex end;
285 | ignore substitute p' @LETTER;
286 | substitute p' by p end;
287 | ignore substitute q' @LETTER;
288 | substitute q' by q end;
289 | ignore substitute r' @LETTER;
290 | substitute r' by r end;
291 | ignore substitute racute' @LETTER;
292 | substitute racute' by racute end;
293 | ignore substitute rcaron' @LETTER;
294 | substitute rcaron' by rcaron end;
295 | ignore substitute t' @LETTER;
296 | substitute t' by t end;
297 | ignore substitute tcaron' @LETTER;
298 | substitute tcaron' by tcaron end;
299 | ignore substitute u' @LETTER;
300 | substitute u' by u end;
301 | ignore substitute uacute' @LETTER;
302 | substitute uacute' by uacute end;
303 | ignore substitute uring' @LETTER;
304 | substitute uring' by uring end;
305 | ignore substitute v' @LETTER;
306 | substitute v' by v end;
307 | ignore substitute w' @LETTER;
308 | substitute w' by w end;
309 | ignore substitute x' @LETTER;
310 | substitute x' by x end;
311 | ignore substitute y' @LETTER;
312 | substitute y' by y end;
313 | ignore substitute yacute' @LETTER;
314 | substitute yacute' by yacute end;
315 | ignore substitute z' @LETTER;
316 | substitute z' by z end;
317 | ignore substitute zcaron' @LETTER;
318 | substitute zcaron' by zcaron end;
319 |
320 | ignore substitute A' @LETTER;
321 | substitute A' by A end;
322 | ignore substitute Aacute' @LETTER;
323 | substitute Aacute' by Aacute end;
324 | ignore substitute Adieresis' @LETTER;
325 | substitute Adieresis' by Adieresis end;
326 | ignore substitute C' @LETTER;
327 | substitute C' by C end;
328 | ignore substitute Ccaron' @LETTER;
329 | substitute Ccaron' by Ccaron end;
330 | ignore substitute E' @LETTER;
331 | substitute E' by E end;
332 | ignore substitute Eacute' @LETTER;
333 | substitute Eacute' by Eacute end;
334 | ignore substitute Ecaron' @LETTER;
335 | substitute Ecaron' by Ecaron end;
336 | ignore substitute G' @LETTER;
337 | substitute G' by G end;
338 | ignore substitute H' @LETTER;
339 | substitute H' by H end;
340 | ignore substitute J' @LETTER;
341 | substitute J' by J end;
342 | ignore substitute K' @LETTER;
343 | substitute K' by K end;
344 | ignore substitute L' @LETTER;
345 | substitute L' by L end;
346 | ignore substitute Lacute' @LETTER;
347 | substitute Lacute' by Lacute end;
348 | ignore substitute Lcaron' @LETTER;
349 | substitute Lcaron' by Lcaron end;
350 | ignore substitute M' @LETTER;
351 | substitute M' by M end;
352 | ignore substitute N' @LETTER;
353 | substitute N' by N end;
354 | ignore substitute Q' @LETTER;
355 | substitute Q' by Q end;
356 | ignore substitute Ncaron' @LETTER;
357 | substitute Ncaron' by Ncaron end;
358 | ignore substitute R' @LETTER;
359 | substitute R' by R end;
360 | ignore substitute Racute' @LETTER;
361 | substitute Racute' by Racute end;
362 | ignore substitute Rcaron' @LETTER;
363 | substitute Rcaron' by Rcaron end;
364 | ignore substitute U' @LETTER;
365 | substitute U' by U end;
366 | ignore substitute Uacute' @LETTER;
367 | substitute Uacute' by Uacute end;
368 | ignore substitute Uring' @LETTER;
369 | substitute Uring' by Uring end;
370 | ignore substitute Y' @LETTER;
371 | substitute Y' by Y end;
372 | ignore substitute Yacute' @LETTER;
373 | substitute Yacute' by Yacute end;
374 | ignore substitute Z' @LETTER;
375 | substitute Z' by Z end;
376 | ignore substitute Zcaron' @LETTER;
377 | substitute Zcaron' by Zcaron end;
378 | } LETTER_END;
379 |
380 | lookup SLEFT {
381 | ignore substitute @LETTER s';
382 | substitute s' by sleft;
383 | ignore substitute @LETTER scaron';
384 | substitute scaron' by scaronleft;
385 | } SLEFT;
386 |
387 | lookup SDEPTH {
388 | substitute [g j q y yacute Y Yacute] s' by sdepth;
389 | substitute [g j q y yacute Y Yacute] scaron' by scarondepth;
390 | } SDEPTH;
391 |
392 | lookup SCONN {
393 | substitute s' @SCONN_LETTERS by s conn_sv;
394 | substitute s' @LETTER by s conn_s;
395 | substitute scaron' @SCONN_LETTERS by scaron conn_sv;
396 | substitute scaron' @LETTER by scaron conn_s;
397 | substitute sleft' @SCONN_LETTERS by sleft conn_sv;
398 | substitute sleft' @LETTER by sleft conn_s;
399 | substitute sdepth' @SCONN_LETTERS by sdepth conn_sv;
400 | substitute sdepth' @LETTER by sdepth conn_s;
401 | substitute scaronleft' @SCONN_LETTERS by scaronleft conn_sv;
402 | substitute scaronleft' @LETTER by scaronleft conn_s;
403 | substitute scarondepth' @SCONN_LETTERS by scarondepth conn_sv;
404 | substitute scarondepth' @LETTER by scarondepth conn_s;
405 | } SCONN;
406 |
407 | lookup BCONN {
408 | substitute b' @BCONN_LETTERS by bnarrow;
409 | substitute begin' b' @BCONN_LETTERS by subs_token;
410 | } BCONN;
411 | lookup BCONN2 {
412 | substitute subs_token by begin bnarrow;
413 | } BCONN2;
414 |
415 | lookup OCONN {
416 | substitute o' @BCONN_LETTERS by onarrow;
417 | substitute oacute' @BCONN_LETTERS by oacutenarrow;
418 | substitute ocircumflex' @BCONN_LETTERS by ocircumflexnarrow;
419 | } OCONN;
420 |
421 | lookup VCONN {
422 | substitute v' @BCONN_LETTERS by vnarrow;
423 | substitute begin_straight' v' @BCONN_LETTERS by subs_token;
424 | } VCONN;
425 | lookup VCONN2 {
426 | substitute subs_token by begin_straight vnarrow;
427 | } VCONN2;
428 |
429 | lookup WCONN {
430 | substitute w' @BCONN_LETTERS by wnarrow;
431 | substitute begin_straight' w' @BCONN_LETTERS by subs_token;
432 | } WCONN;
433 | lookup WCONN2 {
434 | substitute subs_token by begin_straight wnarrow;
435 | } WCONN2;
436 |
437 | lookup BUCCONN {
438 | substitute B' @LETTER_LC by B conn_s;
439 | substitute D' @LETTER_LC by D conn_s;
440 | substitute Dcaron' @LETTER_LC by Dcaron conn_s;
441 | substitute F' @LETTER_LC by F conn_s;
442 | substitute I' @LETTER_LC by I conn_s;
443 | substitute Iacute' @LETTER_LC by Iacute conn_s;
444 | substitute O' @LETTER_LC by O conn_s;
445 | substitute Oacute' @LETTER_LC by Oacute conn_s;
446 | substitute Ocircumflex' @LETTER_LC by Ocircumflex conn_s;
447 | substitute S' @LETTER_LC by S conn_s;
448 | substitute Scaron' @LETTER_LC by Scaron conn_s;
449 | substitute T' @LETTER_LC by T conn_s;
450 | substitute Tcaron' @LETTER_LC by Tcaron conn_s;
451 | substitute V' @LETTER_LC by V conn_s;
452 | substitute W' @LETTER_LC by W conn_s;
453 | } BUCCONN;
454 |
455 | lookup PCONN {
456 | substitute P' @LETTER_LC by P conn_P;
457 | } PCONN;
458 |
459 | # the kern is 2u, where u=40 (using our scale=40), so total 80
460 | feature kern {
461 | ignore position @LETTER a';
462 | position a' <80 0 80 0>;
463 | ignore position @LETTER aacute';
464 | position aacute' <80 0 80 0>;
465 | ignore position @LETTER adieresis';
466 | position adieresis' <80 0 80 0>;
467 | ignore position @LETTER c';
468 | position c' <80 0 80 0>;
469 | ignore position @LETTER ccaron';
470 | position ccaron' <80 0 80 0>;
471 | ignore position @LETTER d';
472 | position d' <80 0 80 0>;
473 | ignore position @LETTER dcaron';
474 | position dcaron' <80 0 80 0>;
475 | ignore position @LETTER g';
476 | position g' <80 0 80 0>;
477 | ignore position @LETTER o';
478 | position o' <80 0 80 0>;
479 | ignore position @LETTER oacute';
480 | position oacute' <80 0 80 0>;
481 | ignore position @LETTER ocircumflex';
482 | position ocircumflex' <80 0 80 0>;
483 | ignore position @LETTER onarrow';
484 | position onarrow' <80 0 80 0>;
485 | ignore position @LETTER oacutenarrow';
486 | position oacutenarrow' <80 0 80 0>;
487 | ignore position @LETTER ocircumflexnarrow';
488 | position ocircumflexnarrow' <80 0 80 0>;
489 | ignore position @LETTER q';
490 | position q' <80 0 80 0>;
491 |
492 | ignore position B' @LCLETTERS;
493 | position B' <0 0 80 0>;
494 | ignore position D' @LCLETTERS;
495 | position D' <0 0 80 0>;
496 | ignore position Dcaron' @LCLETTERS;
497 | position Dcaron' <0 0 80 0>;
498 | ignore position F' @LCLETTERS;
499 | position F' <0 0 240 0>;
500 | ignore position I' @LCLETTERS;
501 | position I' <0 0 40 0>;
502 | ignore position Iacute' @LCLETTERS;
503 | position Iacute' <0 0 40 0>;
504 | ignore position O' @LCLETTERS;
505 | position O' <0 0 160 0>;
506 | ignore position Oacute' @LCLETTERS;
507 | position Oacute' <0 0 160 0>;
508 | ignore position Ocircumflex' @LCLETTERS;
509 | position Ocircumflex' <0 0 160 0>;
510 | ignore position P' @LCLETTERS;
511 | position P' <0 0 280 0>;
512 | ignore position S' @LCLETTERS;
513 | position S' <0 0 160 0>;
514 | ignore position Scaron' @LCLETTERS;
515 | position Scaron' <0 0 160 0>;
516 | ignore position T' @LCLETTERS;
517 | position T' <0 0 280 0>;
518 | ignore position Tcaron' @LCLETTERS;
519 | position Tcaron' <0 0 280 0>;
520 | ignore position V' @LCLETTERS;
521 | position V' <0 0 240 0>;
522 | ignore position W' @LCLETTERS;
523 | position W' <0 0 240 0>;
524 | } kern;
525 |
526 | feature liga {
527 | substitute s' lookup SLEFT lookup SDEPTH lookup SCONN;
528 | substitute scaron' lookup SLEFT lookup SDEPTH lookup SCONN;
529 | substitute b' lookup LETTER_END lookup LETTER_BEGIN lookup BCONN lookup BCONN2;
530 | substitute o' lookup LETTER_END lookup OCONN;
531 | substitute oacute' lookup LETTER_END lookup OCONN;
532 | substitute ocircumflex' lookup LETTER_END lookup OCONN;
533 | substitute v' lookup LETTER_END lookup LETTER_BEGIN lookup VCONN lookup VCONN2;
534 | substitute w' lookup LETTER_END lookup LETTER_BEGIN lookup WCONN lookup WCONN2;
535 | substitute [B D Dcaron F I Iacute O Oacute Ocircumflex S Scaron
536 | T Tcaron V W]' lookup BUCCONN;
537 | substitute P' lookup PCONN;
538 | substitute @LETTER0' lookup LETTER_END lookup LETTER_BEGIN;
539 | } liga;
540 |
--------------------------------------------------------------------------------
/gen/svg.py:
--------------------------------------------------------------------------------
1 | """
2 | This file creates SVG files for each glyph in the font specified using the
3 | Metafont approach.
4 |
5 | The actual shapes are taken from the Slabikář font by Petr Olšák, and the
6 | original metafont source code is copied here for each glyph as a comment for
7 | reference.
8 |
9 | The metafont path is represented by nodes, optional tangents and tensions. From
10 | this information one can obtain bezier control points. We implemented the
11 | tangent+tension -> bezier control points calculation exactly. We currently
12 | require all tangents to be specified explicitly. The original Metafont source
13 | has some implicit tangents, so we have estimated those by trial and error by
14 | hand. In the future we could implement the Metafont's algorithm for tangents as
15 | well.
16 |
17 | The generated SVG files contain the path of the cursive font. The files are
18 | then processed using Inkscape to produce outlines. We read them in, and convert
19 | to the UFO glif format, which is then used to construct the OTF font.
20 |
21 |
22 |
23 | # Documentation for SVG:
24 | # https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path_commands
25 | #
26 | # One can check the generated svg document at:
27 | # https://validator.w3.org
28 |
29 |
30 | The otf design units are 1000x1000 pixels EM box.
31 |
32 | 72 pt = 1 inch
33 | 1 em = 11.95517 pt
34 |
35 | The metafont design units are 1pt = 0.083645em = 83.6458 px (pixels).
36 |
37 | It seems we have roughly 1pt = 40px. Why?
38 | """
39 |
40 | # scale=70 lines up the lowercase letters with Source-Sans
41 | # scale=50 lines up the uppercase letters with Helvetica Neue and most other
42 | # fonts, so it is probably a better option to be consistent.
43 | # scale=40 agress with Metafont's Slabikar
44 | scale = 40
45 | stroke_width = 0.4 * scale
46 |
47 | # 1 .. original
48 | # 2 .. U.S.
49 | # 3 .. alternate "z" (for z_style only), like z_style=1, but with a loop
50 | # 4 .. alternate "z" (for z_style only), like "r", but with a loop
51 | z_style = 1
52 | t_style = 1
53 |
54 |
55 | import os
56 | from bezier import compute_control_points
57 | from math import sin, cos, pi
58 | from numpy import array
59 | from glif import Glif, verify, glif2svg, Point
60 |
61 | def shift(contour, s):
62 | p = []
63 | for x in contour:
64 | p.append(Point(x=x.x+s[0], y=x.y+s[1], type=x.type, smooth=x.smooth))
65 | return p
66 |
67 | #path = [z1,
68 | # [left, 1, z1p_tangent, z1p],
69 | # [z1p_tangent, 1, -sklon2, z0],
70 | # [-sklon2, 1.5, right, z2],
71 | # [right, 1.2, -sklon1, z1],
72 | # [sklon1, 1, sklon1, z3],
73 | # ]
74 | def _draw(path):
75 | contour = [
76 | Point(x=path[0][0], y=path[0][1], type="move", smooth=False)
77 | ]
78 | for t1, tension, t2, z in path[1:]:
79 | if t1 is None:
80 | contour.append(Point(x=z[0], y=z[1], type="line", smooth=False))
81 | else:
82 | z0 = [contour[-1].x, contour[-1].y]
83 | c1, c2 = compute_control_points(z0, z, t1, t2, tension)
84 | contour.extend([
85 | Point(x=c1[0], y=c1[1], type="offcurve", smooth=False),
86 | Point(x=c2[0], y=c2[1], type="offcurve", smooth=False),
87 | Point(x=z[0], y=z[1], type="curve", smooth=False),
88 | ])
89 | return contour
90 |
91 | #path = [(z1,left),1,(z1p,z1p_tangent),1,(z0,-sklon2),1.5,
92 | # (z2,right),1.2,(-sklon1,z1,sklon1),1,(z3,sklon1)]
93 | def _draw2(path):
94 | assert len(path) % 2 == 1
95 | p2 = [path[0][0]]
96 | for i in range((len(path)-1)//2):
97 | node1 = path[2*i]; tension = path[2*i+1]; node2 = path[2*i+2]
98 | if (len(node2) == 2):
99 | if tension is None:
100 | p2.append([None, None, None, node2[0]])
101 | else:
102 | p2.append([node1[-1], tension, node2[1], node2[0]])
103 | else:
104 | assert len(node2) == 3
105 | if tension is None:
106 | p2.append([None, None, None, node2[1]])
107 | else:
108 | p2.append([node1[-1], tension, node2[0], node2[1]])
109 | return _draw(p2)
110 |
111 |
112 | def create_glif(contours, w, scale):
113 | for contour in contours:
114 | for p in contour:
115 | p.x = float(p.x * scale)
116 | p.y = float(p.y * scale)
117 | w = float(w * scale)
118 |
119 | name = "a"
120 | unicode_hex = None
121 | anchors = []
122 | g = Glif(name, unicode_hex, w, contours, anchors)
123 | verify(g)
124 | return g
125 |
126 | def add_char(charname, width, contours):
127 | g = create_glif(contours, width, scale)
128 | f = open(f'letter_{charname}.svg', 'w')
129 | f.write(glif2svg(g, False, False, stroke_width))
130 | f.close()
131 |
132 | def whatever_y(z0, vec, zy):
133 | """
134 | solves the equation z-z0=whatever*vec under the condition of z.y = zy
135 | """
136 | w = (zy-z0[1]) / vec[1]
137 | zx = vec[0] * w + z0[0]
138 | z = [zx, zy]
139 | return z
140 |
141 | def dir_(angle_deg):
142 | a = angle_deg * pi/180
143 | return array([cos(a), sin(a)])
144 |
145 | def run(cmd):
146 | print(cmd)
147 | r = os.system(cmd)
148 | if (r != 0):
149 | raise Exception("Command failed.")
150 |
151 | right=array([1,0])
152 | left=array([-1,0])
153 | down=array([0,-1])
154 | up=array([0,1])
155 | # add a curve: first point, and (control-point1, control-point2, node)*n points.
156 | # sklon1:=-(1.5,6); sklon2:=(5,6);
157 | sklon1=-array([1.5,6]); sklon2=array([5,6]);
158 |
159 | #def dotah =
160 | # draw ((0,1){sklon1}..(1,0){right}..{sklon2}(8,6))
161 | #enddef;
162 | dotah = _draw2([((0,1),sklon1),1,((1,0),right),1,((8,6),sklon2)])
163 | eps = stroke_width/2 / scale
164 | z1 = (eps,0); z2 = (0,eps); z3 = (-eps,0); z4=(0,-eps)
165 | dot = _draw2([(z1,up), 1, (z2,left), 1, (z3,down), 1, (z4, right), 1,
166 | (z1, up)])
167 |
168 | #def smycka =
169 | # draw ((0,7){sklon1}..{sklon1}(-2,0)..{sklon1}(-3.1,-4)..
170 | # {left}(-5.3,-7)..{-sklon1}(-5.5,-5)..
171 | # (-2,0)..{sklon2}(5.5,6))
172 | #enddef;
173 | smycka = _draw2([((0,7),sklon1),1,((-2,0),sklon1),1,((-3.1,-4),sklon1),1,
174 | ((-5.3,-7),left),1,((-5.5,-5),-sklon1),1,
175 | ((-2,0),(6,5)),1,((5.5,6),sklon2)])
176 |
177 | carka = _draw2([((0,9),None),None,((1.5,13),None)])
178 | capcarka = _draw2([((0,15),None),None,((1.5,18),None)])
179 | #def krouzek =
180 | # draw ((0,9){right}..(0,11){left}..cycle)
181 | #enddef;
182 | eps = 1.0
183 | z1 = (eps,0); z2 = (0,eps); z3 = (-eps,0); z4=(0,-eps)
184 | krouzek = shift(_draw2([(z1,up), 1, (z2,left), 1, (z3,down), 1, (z4, right), 1,
185 | (z1, up)]), (0, 10))
186 | vokan = _draw2([((0,9),(1,1)),1,((3,11),right),1,((4,9),dir_(-105))])
187 |
188 |
189 | #def dvetecky (expr a, b) =
190 | # pickup pencircle scaled (dotkoef*thin);
191 | # drawdot (2 + a, 10 + b);
192 | # drawdot (4.4 + a, 10 + b);
193 | # pickup pencircle scaled thin
194 | #enddef;
195 | def dvetecky(x,y):
196 | #return [
197 | # _draw2([((2+x-0.5,9+y),None),None,((2+1.5+x-0.5,12+y),None)]),
198 | # _draw2([((4.4+x-0.5,9+y),None),None,((4.4+1.5+x-0.5,12+y),None)]),
199 | #]
200 | return [
201 | shift(dot, (2+x,10+y)),
202 | shift(dot, (4.4+x,10+y)),
203 | ]
204 |
205 |
206 | #def hacek =
207 | # draw ((0,12)..{sklon1}(-.3,10)..{right}(.8,9)..tension2..{sklon2}(5,12))
208 | #enddef;
209 | # Note: (0.2,12) looks better
210 | hacek = _draw2([((0,12),sklon1),1,((-.3,10),sklon1),1,((.8,9),right),2,((5,12),sklon2)])
211 | #def hacekl =
212 | # draw ((0,12)..{sklon1}(-.3,10)..{right}(.8,9)..tension2..{sklon2}(3.5,12))
213 | #enddef;
214 | hacekl = _draw2([((0,12),sklon1),1,((-.3,10),sklon1),1,((.8,9),right),2,((3.5,12),sklon2)])
215 |
216 |
217 |
218 | # Special characters
219 |
220 | # End of the character
221 | #beginchar(1, .7u#, 7u#, 0); %% pravy konec znaku
222 | # draw (0,6)..(.7,7);
223 | #endchar;
224 | # Original:
225 | # end_w = 0.7
226 | # New fix:
227 | end_w = sklon2[0]/sklon2[1] # =5/6=0.833...
228 | add_char("end", end_w, [
229 | _draw2([((0,6),None), None, ((end_w,7),None)]),
230 | ])
231 |
232 | # Beginning of the character
233 | #beginchar(2, 5u#, 7u#, 0); %% levy rovny zacatek znaku
234 | # draw (0,0)..(5,6);
235 | #endchar;
236 | add_char("begin_straight", 5, [
237 | _draw2([((0,0),sklon2), 1, ((5,6),sklon2)]),
238 | ])
239 |
240 | #beginchar(3, 6u#, 7u#, 0); %% levy prohnuty zacatek znaku
241 | # draw (0,0){(3,2)}..{sklon2}(6,6);
242 | #endchar;
243 | add_char("begin", 6, [
244 | _draw2([((0,0),(3,2)), 1, ((6,6),sklon2)]),
245 | ])
246 |
247 | #beginchar(4, 5u#, 7u#, 0); %% obecna konvexni spojka za verzalkou a s
248 | # draw (-4,0){right}..{sklon2}(5,6);
249 | #endchar;
250 | add_char("conn_s", 5, [
251 | _draw2([((-4,0),right), 1, ((5,6),sklon2)]),
252 | ])
253 |
254 | #beginchar(5, 7u#, 7u#, 0); %% delsi konvexni spojka za verzalkou P
255 | # draw (-4,0){right}..{sklon2}(7,6);
256 | #endchar;
257 | add_char("conn_P", 7, [
258 | _draw2([((-4,0),right), 1, ((7,6),sklon2)]),
259 | ])
260 |
261 | #beginchar(6, 3u#, 7u#, 0); %% kratsi konvexni spojka pro dvojice sv sn
262 | # draw (-4,0){right}..{sklon2}(3,6);
263 | #endchar;
264 | add_char("conn_sv", 3, [
265 | _draw2([((-4,0),right), 1, ((3,6),sklon2)]),
266 | ])
267 |
268 | #beginchar(7, 8u#, 7u#, 0); %% nabehova carka pro male x
269 | # draw (0,2){down}..(2,0){right}..tension2..{sklon2}(8,6);
270 | #endchar;
271 | add_char("begin_x", 8, [
272 | _draw2([((0,2),down), 1, ((2,0),right), 2, ((8,6),sklon2)]),
273 | ])
274 |
275 |
276 | ################################################################################
277 |
278 | # Character definitions
279 |
280 | #beginchar("a", 9.4u#, 7u#, 0);
281 | # z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
282 | # z1p=(1.5,6.9);
283 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
284 | # z2{right}..tension1.2..{-sklon1}z1{sklon1}..z3{sklon1};
285 | # dotah shifted (x3,0);
286 | #endchar;
287 | z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
288 | z1p=(1.5,6.9); z1p_tangent=(-4, -1)
289 | add_char("a", 9.4, [
290 | _draw2([(z1,left),1,(z1p,z1p_tangent),1,(z0,-sklon2),1.5,
291 | (z2,right),1.2,(-sklon1,z1,sklon1),1,(z3,sklon1)]),
292 | shift(dotah, (z3[0],0))
293 | ])
294 |
295 | #beginchar(adiaeresis, 9.4u#, 7u#, 0); %% \"a
296 | # z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
297 | # z1p=(1.5,6.9);
298 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
299 | # z2{right}..tension1.2..{-sklon1}z1{sklon1}..z3{sklon1};
300 | # dotah shifted (x3,0);
301 | #% dvetecky (0,0); %%% Change 18. 5. 2020 to:
302 | # dvetecky (-0.5,0);
303 | #endchar;
304 | z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
305 | z1p=(1.5,6.9); z1p_tangent=(-4, -1)
306 | add_char("adieresis", 9.4, [
307 | _draw2([(z1,left),1,(z1p,z1p_tangent),1,(z0,-sklon2),1.5,
308 | (z2,right),1.2,(-sklon1,z1,sklon1),1,(z3,sklon1)]),
309 | shift(dotah, (z3[0],0))] +
310 | dvetecky(-0.5,0)
311 | )
312 |
313 | #beginchar(aacute, 9.4u#, 13u#, 0); %% \'a
314 | # z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
315 | # z1p=(1.5,6.9);
316 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
317 | # z2{right}..tension1.5..{-sklon1}z1{sklon1}..z3{sklon1};
318 | # dotah shifted (x3,0);
319 | # carka shifted (3,0);
320 | #endchar;
321 | z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
322 | z1p=(1.5,6.9); z1p_tangent=(-4, -1)
323 | # FIXME: the second tension is 1.5 in aacute in slabikar.mf, a bug
324 | add_char("aacute", 9.4, [
325 | _draw2([(z1,left),1,(z1p,z1p_tangent),1,(z0,-sklon2),1.5,
326 | (z2,right),1.2,(-sklon1,z1,sklon1),1,(z3,sklon1)]),
327 | shift(dotah, (z3[0],0)),
328 | shift(carka, (3,0))
329 | ])
330 |
331 |
332 | #beginchar("b", 9u#, 14u#, 0);
333 | # z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1,1);
334 | # z4=(0,0); z5=(3,7); z6=(9,6);
335 | # z1p=(4,12); z5p=(2.5,6);
336 | # draw z0{sklon2}..z1p..tension1.5..z1{left}..z2{sklon1}..
337 | # z3{sklon1}..z4{right}..tension3..z5{left}..z5p{down}..
338 | # tension2..{sklon2}z6;
339 | #endchar;
340 | z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1,1);
341 | z4=(0,0); z5=(3,7); z6=(9,6);
342 | z1p=(4,12); z1p_tangent=(3,6); z5p=(2.5,6);
343 | add_char("b", 9, [
344 | _draw2([(z0,sklon2),1,(z1p,z1p_tangent),1.5,(z1,left),1,(z2,sklon1),1,
345 | (z3,sklon1),1,(z4,right),3,(z5,left),1,(z5p,down),
346 | 2,(z6,sklon2)]),
347 | ])
348 |
349 | #beginchar(bnarrow, 7u#, 14u#, 0);
350 | # z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1,1);
351 | # z4=(0,0); z5=(3,7); z6=(7,6);
352 | # z1p=(4,12); z5p=(2.5,6);
353 | # draw z0{sklon2}..z1p..tension1.5..z1{left}..z2{sklon1}..
354 | # z3{sklon1}..z4{right}..tension3..z5{left}..z5p{down}..
355 | # tension2..{sklon2}z6;
356 | #endchar;
357 | z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1,1);
358 | z4=(0,0); z5=(3,7); z6=(7,6);
359 | z1p=(4,12); z1p_tangent=(3,6); z5p=(2.5,6);
360 | add_char("bnarrow", 7, [
361 | _draw2([(z0,sklon2),1,(z1p,z1p_tangent),1.5,(z1,left),1,(z2,sklon1),1,
362 | (z3,sklon1),1,(z4,right),3,(z5,left),1,(z5p,down),
363 | 2,(z6,sklon2)]),
364 | ])
365 |
366 |
367 | #beginchar("c", 8u#, 7u#, 0);
368 | # z0=(0,6); z1=(1.5,7); z2=(2.5,6); z3=(0,0); z4=(8,6);
369 | # draw z2..z1{left}..z0{-sklon2}..z3{right}..{sklon2}z4;
370 | #endchar;
371 | z0=(0,6); z1=(1.5,7); z2=(2.5,6); z3=(0,0); z4=(8,6); z2t=(-4,1)
372 | add_char("c", 8, [
373 | _draw2([(z2,up),1,(z1,left),1,(z0,-sklon2),1,(z3,right),1,(z4,sklon2)])
374 | ])
375 |
376 | #beginchar(ccaron, 8u#, 12u#, 0);
377 | # z0=(0,6); z1=(1.5,7); z2=(2.5,6); z3=(0,0); z4=(8,6);
378 | # draw z2..z1{left}..z0{-sklon2}..z3{right}..{sklon2}z4;
379 | # hacek shifted (2,0);
380 | #endchar;
381 | z0=(0,6); z1=(1.5,7); z2=(2.5,6); z3=(0,0); z4=(8,6); z2t=(-4,1)
382 | add_char("ccaron", 8, [
383 | _draw2([(z2,up),1,(z1,left),1,(z0,-sklon2),1,(z3,right),1,(z4,sklon2)]),
384 | shift(hacek, (2,0))
385 | ])
386 |
387 | #beginchar("d", 9.4u#, 14u#, 0);
388 | # z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
389 | # z1p=(1.5,6.9);
390 | # z1n-z3 = whatever * (z1-z3); y1n=14;
391 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
392 | # z2{right}..tension1.5..{-sklon1}z1--z1n{sklon1}..z3{sklon1};
393 | # dotah shifted (x3,0);
394 | #endchar;
395 | z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
396 | z1p=(1.5,6.9);z1pt=(-4,-1) # roughly: z0-z1, but adjusted
397 | z1n = whatever_y(z3, array(z1)-array(z3), 14)
398 | add_char("d", 9.4, [
399 | _draw2([(z1,left),1,(z1p,z1pt),1,(z0,-sklon2),1.5,
400 | (z2,right),1.5,(z1,-sklon1),None,(z1n,sklon1),1,(z3,sklon1)]),
401 | shift(dotah, (z3[0],0))
402 | ])
403 | add_char("dcaron", 9.4, [
404 | _draw2([(z1,left),1,(z1p,z1pt),1,(z0,-sklon2),1.5,
405 | (z2,right),1.5,(z1,-sklon1),None,(z1n,sklon1),1,(z3,sklon1)]),
406 | shift(dotah, (z3[0],0)),
407 | shift(hacek, (6,2)),
408 | ])
409 |
410 | #beginchar("e", 5u#, 7u#, 0);
411 | # z0=(0,6); z1=(-1,7); z2=(-2,5); z3=(-3,1);
412 | # draw z0{sklon2}..z1{left}..z2{sklon1}..{sklon1}z3;
413 | # dotah shifted (x3,0);
414 | #endchar;
415 | z0=(0,6); z1=(-1,7); z2=(-2,5); z3=(-3,1);
416 | add_char("e", 5, [
417 | _draw2([(z0,sklon2),1,(z1,left),1,(z2,sklon1),1,(z3,sklon1)]),
418 | shift(dotah, (z3[0],0))
419 | ])
420 | add_char("eacute", 5, [
421 | _draw2([(z0,sklon2),1,(z1,left),1,(z2,sklon1),1,(z3,sklon1)]),
422 | shift(dotah, (z3[0],0)),
423 | shift(carka, (0,0)),
424 | ])
425 | add_char("ecaron", 5, [
426 | _draw2([(z0,sklon2),1,(z1,left),1,(z2,sklon1),1,(z3,sklon1)]),
427 | shift(dotah, (z3[0],0)),
428 | shift(hacek, (-0.5,0)),
429 | ])
430 |
431 | #beginchar("f", 7u#, 14u#, 7u#);
432 | # z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1.2,0);
433 | # z1p=(4,12);
434 | # z3r=(-.8,0); z3l=(-1.6,.3);
435 | # z4=(-3,-6); z5=(-2.3,-7); z6=(7,6);
436 | # draw z0{sklon2}..z1p..tension1.5..z1{left}..z2{sklon1}..z3{sklon1}
437 | # ..z4{sklon1}..z5{right}..tension3..
438 | # {(-2,1)}z3r..z3l{down}..z3r{right}..{sklon2}z6;
439 | #endchar;
440 | z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1.2,0);
441 | z1p=(4,12);z1p_t=(3,6)
442 | z3r=(-.8,0); z3l=(-1.6,.3);
443 | z4=(-3,-6); z5=(-2.3,-7); z6=(7,6);
444 | add_char("f", 7, [
445 | _draw2([(z0,sklon2),1,(z1p,z1p_t),1.5,(z1,left),1,(z2,sklon1),1,(z3,sklon1),
446 | 1,(z4,sklon1),1,(z5,right),3,(z3r,(-2,1)),1,(z3l,down),1,(z3r,right),1,
447 | (z6,sklon2)])
448 | ])
449 |
450 | #beginchar("g", 8.5u#, 7u#, 7u#);
451 | # z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
452 | # z1p=(1.5,6.9);
453 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
454 | # z2{right}..tension1.5..{-sklon1}z1;
455 | # smycka shifted (x1,0);
456 | #endchar;
457 | z0=(0,6); z1=(3,7); z2=(-1,0); z3=(1.4,1);
458 | z1p=(1.5,6.9);z1pt=(-4,-1)
459 | add_char("g", 8.5, [
460 | _draw2([(z1,left),1,(z1p,z1pt),1,(z0,-sklon2),1.5,
461 | (z2,right),1.5,(z1,-sklon1)]),
462 | shift(smycka, (z1[0],0))
463 | ])
464 |
465 | #beginchar("h", 9.85u#, 14u#, 0);
466 | # z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1.2,0);
467 | # z1p=(4,12);
468 | # z4=(0.15,5);
469 | # z5n=(x4+2.5,7); z5=(x4+3,6); z6=(x4+1.7,1);
470 | # draw z0{sklon2}..z1p..tension1.5..z1{left}..z2{sklon1}..z3{sklon1};
471 | # draw z4{-sklon1}..z5n{right}..z5{sklon1}..{sklon1}z6;
472 | # dotah shifted (x6,0);
473 | #endchar;
474 | z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1.2,0);
475 | z1p=(4,12);z1pt=(1,2)
476 | z4=(0.15,5);
477 | z5n=(z4[0]+2.5,7); z5=(z4[0]+3,6); z6=(z4[0]+1.7,1);
478 | add_char("h", 9.85, [
479 | _draw2([(z0,sklon2),1,(z1p,z1pt),1.5,(z1,left),1,(z2,sklon1),1,
480 | (z3,sklon1)]),
481 | _draw2([(z4,-sklon1),1,(z5n,right),1,(z5,sklon1),1,(z6,sklon1)]),
482 | shift(dotah, (z6[0],0))
483 | ])
484 |
485 | #beginchar("i", 7u#, 11u#, 0);
486 | # z0=(0,6); z1=(.5,7); z2=(-1,1); z3-z1=whatever*sklon1; y3=11;
487 | # pickup pencircle scaled (dotkoef*thin);
488 | # drawdot z3;
489 | # pickup pencircle scaled thin;
490 | # draw z0{sklon2}..{-sklon1}z1{sklon1}..{sklon1}z2;
491 | # dotah shifted (x2,0);
492 | #endchar;
493 | z0=(0,6); z1=(.5,7); z2=(-1,1); z3 = whatever_y(z1, sklon1, 11)
494 | add_char("i", 7, [
495 | _draw2([(z0,sklon2),1,(-sklon1,z1,sklon1),1,(z2,sklon1)]),
496 | shift(dot, z3),
497 | shift(dotah, (z2[0],0))
498 | ])
499 | z3 = whatever_y(z1, sklon1, 9)
500 | add_char("iacute", 7, [
501 | _draw2([(z0,sklon2),1,(-sklon1,z1,sklon1),1,(z2,sklon1)]),
502 | shift(dotah, (z2[0],0)),
503 | shift(carka, (z3[0],0))
504 | ])
505 |
506 | #beginchar("j", 6u#, 11u#, 7u#);
507 | # z0=(0,6); z1=(.5,7);
508 | # z3-z1=whatever*sklon1; y3=11;
509 | # pickup pencircle scaled (dotkoef*thin);
510 | # drawdot z3;
511 | # pickup pencircle scaled thin;
512 | # draw z0{sklon2}..{-sklon1}z1;
513 | # smycka shifted (x1,0);
514 | #endchar;
515 | z0=(0,6); z1=(.5,7); z3 = whatever_y(z1, sklon1, 11)
516 | add_char("j", 6, [
517 | _draw2([(z0,sklon2),1,(z1,-sklon1)]),
518 | shift(dot, z3),
519 | shift(smycka, (z1[0],0))
520 | ])
521 |
522 | #beginchar("k", 10u#, 14u#, 0);
523 | # z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1.2,0);
524 | # z1p=(4,12);
525 | # (z4-z3) = whatever*(z2-z3); y4=5;
526 | # z5=(2.3,7); z6=(2,4.5); z7=(1,y6); z8=(4,0); z9=(10,6);
527 | # draw z0{sklon2}..z1p..tension1.5..z1{left}..z2{sklon1}..z3{sklon1};
528 | # draw z4{-sklon1}..z5{right}..z6..z7{up}..z6..
529 | # z8{right}..tension3..{sklon2}z9;
530 | #endchar;
531 | z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1.2,0);
532 | z1p=(4,12);z1pt=(1,2)
533 | z4 = whatever_y(z3, array(z2)-array(z3), 5)
534 | z5=(2.3,7); z6=(2,4.5); z7=(1,z6[1]); z8=(4,0); z9=(10,6);
535 | z6t = (-1,-1)
536 | z6t2 = (1,-1)
537 | add_char("k", 10, [
538 | _draw2([(z0,sklon2),1,(z1p,z1pt),1.5,(z1,left),1,(z2,sklon1),1,(z3,sklon1)]),
539 | _draw2([(z4,-sklon1),1,(z5,right),1,(z6,z6t),1,(z7,up),1,(z6,z6t2),1,
540 | (z8,right),3,(z9,sklon2)]),
541 | ])
542 |
543 |
544 | #beginchar("l", 7u#, 14u#, 0);
545 | # z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1,1);
546 | # z1p=(4,12);
547 | # draw z0{sklon2}..z1p..tension1.5..z1{left}..z2{sklon1}..z3{sklon1};
548 | # dotah shifted (x3,0);
549 | #endchar;
550 | z0=(0,6); z1=(4,14); z2=(1.5,10); z3=(-1,1);
551 | z1p=(4,12);z1pt=(1,2)
552 | add_char("l", 7, [
553 | _draw2([(z0,sklon2),1,(z1p,z1pt),1.5,(z1,left),1,(z2,sklon1),1,(z3,sklon1)]),
554 | shift(dotah, (z3[0],0))
555 | ])
556 | add_char("lcaron", 7, [
557 | _draw2([(z0,sklon2),1,(z1p,z1pt),1.5,(z1,left),1,(z2,sklon1),1,(z3,sklon1)]),
558 | shift(dotah, (z3[0],0)),
559 | shift(hacekl, (5.5, 2))
560 | ])
561 | add_char("lacute", 7, [
562 | _draw2([(z0,sklon2),1,(z1p,z1pt),1.5,(z1,left),1,(z2,sklon1),1,(z3,sklon1)]),
563 | shift(dotah, (z3[0],0)),
564 | shift(capcarka, (4, 0))
565 | ])
566 |
567 |
568 |
569 | #beginchar("m", 15.7u#, 7u#, 0);
570 | # z0=(0,6); z1=(3,5); z1d=(1.5,0); z2=(6,5); z2d=(4.5,0);
571 | # z3=(9,5); z4=(7.7,1);
572 | # z1n=(2.5,7); z2n=(5.5,7); z3n=(8.5,7);
573 | # draw z0{sklon2}..z1n{right}..z1{sklon1}..{sklon1}z1d;
574 | # draw z1{-sklon1}..z2n{right}..z2{sklon1}..{sklon1}z2d;
575 | # draw z2{-sklon1}..z3n{right}..z3{sklon1}..{sklon1}z4;
576 | # dotah shifted (x4,0);
577 | #endchar;
578 | z0=(0,6); z1=(3,5); z1d=(1.5,0); z2=(6,5); z2d=(4.5,0);
579 | z3=(9,5); z4=(7.7,1);
580 | z1n=(2.5,7); z2n=(5.5,7); z3n=(8.5,7);
581 | add_char("m", 15.7, [
582 | _draw2([(z0, sklon2),1,(z1n,right),1,(z1,sklon1),1,(z1d,sklon1)]),
583 | _draw2([(z1,-sklon1),1,(z2n,right),1,(z2,sklon1),1,(z2d,sklon1)]),
584 | _draw2([(z2,-sklon1),1,(z3n,right),1,(z3,sklon1),1,(z4 ,sklon1)]),
585 | shift(dotah, (z4[0],0))
586 | ])
587 |
588 |
589 | #beginchar("n", 12.7u#, 7u#, 0);
590 | # z0=(0,6); z1=(3,5); z1d=(1.5,0); z2=(6,5); z3=(4.7,1);
591 | # z1n=(2.5,7); z2n=(5.5,7);
592 | # draw z0{sklon2}..z1n{right}..z1{sklon1}..{sklon1}z1d;
593 | # draw z1{-sklon1}..z2n{right}..z2{sklon1}..{sklon1}z3;
594 | # dotah shifted (x3,0);
595 | #endchar;
596 | z0=(0,6); z1=(3,5); z1d=(1.5,0); z2=(6,5); z3=(4.7,1);
597 | z1n=(2.5,7); z2n=(5.5,7);
598 | add_char("n", 12.7, [
599 | _draw2([(z0, sklon2),1,(z1n,right),1,(z1,sklon1),1,(z1d,sklon1)]),
600 | _draw2([(z1,-sklon1),1,(z2n,right),1,(z2,sklon1),1,(z3,sklon1)]),
601 | shift(dotah, (z3[0],0))
602 | ])
603 | add_char("ncaron", 12.7, [
604 | _draw2([(z0, sklon2),1,(z1n,right),1,(z1,sklon1),1,(z1d,sklon1)]),
605 | _draw2([(z1,-sklon1),1,(z2n,right),1,(z2,sklon1),1,(z3,sklon1)]),
606 | shift(dotah, (z3[0],0)),
607 | shift(hacek, (4,0))
608 | ])
609 |
610 | #beginchar("o", 8u#, 7u#, 0);
611 | # z0=(0,6); z1=(3,7); z2=(-1,0); z3=(8,6);
612 | # z1p=(1.5,6.9); z2p=(2,6);
613 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
614 | # z2{right}..tension1.5..{-sklon1}z1{left}..z2p{down}..{sklon2}z3;
615 | #endchar;
616 | z0=(0,6); z1=(3,7); z2=(-1,0); z3=(8,6);
617 | z1p=(1.5,6.9); z2p=(2,6); z1t=(-4,-1)
618 | add_char("o", 8, [
619 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,-sklon2),1.5,
620 | (z2,right),1.5,(-sklon1,z1,left),1,(z2p,down),1,(z3,sklon2)]),
621 | ])
622 | add_char("oacute", 8, [
623 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,-sklon2),1.5,
624 | (z2,right),1.5,(-sklon1,z1,left),1,(z2p,down),1,(z3,sklon2)]),
625 | shift(carka, (3,0))
626 | ])
627 | add_char("ocircumflex", 8, [
628 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,-sklon2),1.5,
629 | (z2,right),1.5,(-sklon1,z1,left),1,(z2p,down),1,(z3,sklon2)]),
630 | shift(vokan, (0,0))
631 | ])
632 |
633 | #beginchar(onarrow, 6u#, 7u#, 0);
634 | # z0=(0,6); z1=(3,7); z2=(-1,0); z3=(6,6);
635 | # z1p=(1.5,6.9); z2p=(2,6);
636 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
637 | # z2{right}..tension1.5..{-sklon1}z1{left}..z2p{down}..{sklon2}z3;
638 | #endchar;
639 | z0=(0,6); z1=(3,7); z2=(-1,0); z3=(6,6);
640 | z1p=(1.5,6.9); z2p=(2,6); z1t=(-4,-1)
641 | add_char("onarrow", 6, [
642 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,-sklon2),1.5,
643 | (z2,right),1.5,(-sklon1,z1,left),1,(z2p,down),1,(z3,sklon2)]),
644 | ])
645 | add_char("oacutenarrow", 6, [
646 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,-sklon2),1.5,
647 | (z2,right),1.5,(-sklon1,z1,left),1,(z2p,down),1,(z3,sklon2)]),
648 | shift(carka, (3,0))
649 | ])
650 | # FIXME: slabikar.mf has otoceny_hacek instead of vokan, a bug
651 | add_char("ocircumflexnarrow", 6, [
652 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,-sklon2),1.5,
653 | (z2,right),1.5,(-sklon1,z1,left),1,(z2p,down),1,(z3,sklon2)]),
654 | shift(vokan, (0,0))
655 | ])
656 |
657 |
658 | #beginchar("p", 10.2u#, 8u#, 7u#);
659 | # z0=(0,6);
660 | # z1=(.5,4); z2n=(3,7); z2=(3.5,6); z3=(2.2,1);
661 | # z5=(-2.5,-7);
662 | # (z1-z4)=whatever*(z1-z5); y4=8;
663 | # draw z0{sklon2}..{-sklon1}z4{sklon1}--z5;
664 | # draw z1{-sklon1}..z2n{right}..z2{sklon1}..{sklon1}z3;
665 | # dotah shifted (x3,0);
666 | #endchar;
667 | z0=(0,6);
668 | z1=(.5,4); z2n=(3,7); z2=(3.5,6); z3=(2.2,1);
669 | z5=(-2.5,-7);
670 | z4 = whatever_y(z1, array(z1)-array(z5), 8)
671 | add_char("p", 10.2, [
672 | _draw2([(z0, sklon2),1,(-sklon1,z4,sklon1),None,(z5,None)]),
673 | _draw2([(z1,-sklon1),1,(z2n,right),1,(z2,sklon1),1,(z3,sklon1)]),
674 | shift(dotah, (z3[0],0))
675 | ])
676 |
677 | #beginchar("q", 9u#, 7u#, 7u#);
678 | # z0=(0,6); z1=(3,7); z2=(-1,0);
679 | # z1p=(1.5,6.9);
680 | # z3=(1.1,-.5); z4-z1 = whatever*(z3-z1); y4=-7;
681 | # z5=(9,6);
682 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
683 | # z2{right}..tension1.5..{-sklon1}z1{sklon1}..{sklon1}z3..{sklon1}z4;
684 | # draw z3{-sklon1}..tension2..{sklon2}z5;
685 | #endchar;
686 | z0=(0,6); z1=(3,7); z2=(-1,0);
687 | z1p=(1.5,6.9);z1pt=(-4,-1)
688 | z3=(1.1,-.5); z4 = whatever_y(z1, array(z3)-array(z1), -7)
689 | z5=(9,6);
690 | add_char("q", 9, [
691 | _draw2([(z1,left),1,(z1p,z1pt),1,(z0,-sklon2),1.5,
692 | (z2,right),1.5,(-sklon1,z1,sklon1),1,(z3,sklon1),1,(z4,sklon1)]),
693 | _draw2([(z3,-sklon1),2,(z5,sklon2)]),
694 | ])
695 |
696 | #beginchar("r", 8.4u#, 7u#, 0);
697 | # z0=(0,6); z1=(.5,7); z2=(2,7); z3=(.4,1);
698 | # draw z0{sklon2}..{-sklon1}z1{sklon1}..{-sklon1}z2{sklon1}..{sklon1}z3;
699 | # dotah shifted (x3,0);
700 | #endchar;
701 | z0=(0,6); z1=(.5,7); z2=(2,7); z3=(.4,1);
702 | add_char("r", 8.4, [
703 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(-sklon1,z2,sklon1),1,
704 | (z3,sklon1)]),
705 | shift(dotah, (z3[0],0))
706 | ])
707 | add_char("rcaron", 8.4, [
708 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(-sklon1,z2,sklon1),1,
709 | (z3,sklon1)]),
710 | shift(dotah, (z3[0],0)),
711 | shift(hacek, (1.4,0))
712 | ])
713 | add_char("racute", 8.4, [
714 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(-sklon1,z2,sklon1),1,
715 | (z3,sklon1)]),
716 | shift(dotah, (z3[0],0)),
717 | shift(carka, (1.4,0))
718 | ])
719 |
720 | #beginchar("s", 2u#, 7u#, 0);
721 | # z0=(0,6); z1=(.5,7); z2=(-.5,1); z3=(-2,0); z4=(-3,2); z5=(7,6);
722 | # draw z0{sklon2}..{-sklon1}z1{sklon1}..z2{-sklon2}..z3{left}..{(-1,3)}z4;
723 | #endchar;
724 | z0=(0,6); z1=(.5,7); z2=(-.5,1); z3=(-2,0); z4=(-3,2); z5=(7,6);
725 | add_char("s", 2, [
726 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(z2,-sklon2),1,
727 | (z3,left), 1, (z4,(-1,3))]),
728 | ])
729 | add_char("scaron", 2, [
730 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(z2,-sklon2),1,
731 | (z3,left), 1, (z4,(-1,3))]),
732 | shift(hacek, (0,0))
733 | ])
734 |
735 | #beginchar(sleft, 9u#, 7u#, 0); %% koncove s
736 | # z0=(0,0); z1=(7.5,7); z2=(6.5,1); z3=(5,0); z4=(3.5,3);
737 | # draw z0..{sklon2}z1{-sklon2}..z2{-sklon2}..z3{left}..{(-1,3)}z4;
738 | #endchar;
739 | # FIXME: the z0t here seems correct; slabikar.mf is bent, and the end of `s`
740 | # ends up being across the line, which seems like a bug
741 | z0=(0,0); z1=(7.5,7); z2=(6.5,1); z3=(5,0); z4=(3.5,3);
742 | z0t=array(z4)-array(z0)
743 | add_char("sleft", 9, [
744 | _draw2([(z0, z0t),1,(sklon2,z1,-sklon2),1,(z2,-sklon2),1,
745 | (z3,left), 1, (z4,(-1,3))]),
746 | ])
747 | add_char("scaronleft", 9, [
748 | _draw2([(z0, z0t),1,(sklon2,z1,-sklon2),1,(z2,-sklon2),1,
749 | (z3,left), 1, (z4,(-1,3))]),
750 | shift(hacek, (8,0))
751 | ])
752 |
753 | #beginchar(sdepth, 2u#, 7u#, 0);
754 | # z0=(0,6); z1=(.5,7); z2=(-.5,1); z3=(-2,0); z4=(-3.5,2.5); z5=(7,6);
755 | # draw z0{sklon2}..{-sklon1}z1{sklon1}..z2{-sklon2}..z3{left}..{(-1,3)}z4;
756 | #endchar;
757 | z0=(0,6); z1=(.5,7); z2=(-.5,1); z3=(-2,0); z4=(-3.5,2.5); z5=(7,6);
758 | add_char("sdepth", 2, [
759 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(z2,-sklon2),1,
760 | (z3,left), 1, (z4,(-1,3))]),
761 | ])
762 | add_char("scarondepth", 2, [
763 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(z2,-sklon2),1,
764 | (z3,left), 1, (z4,(-1,3))]),
765 | shift(hacek, (0,0))
766 | ])
767 |
768 | if t_style == 1:
769 | #beginchar("t", 9u#, 14u#, 0);
770 | # z0=(0,6); z1=(4.5,14); z2=(1,0); z3=(9,6);
771 | # z10=(0,1);
772 | # draw z0{sklon2}..tension2..{-sklon1}z1--z2{-sklon1}..
773 | # z10..z2{right}..z3{sklon2};
774 | #endchar;
775 | z0=(0,6); z1=(4.5,14); z2=(1,0); z3=(9,6);
776 | z10=(0,1);z10t=(-5,-6)
777 | add_char("t", 9, [
778 | _draw2([(z0,sklon2),2,(z1,-sklon1),None,(z2,-sklon1),1,
779 | (z10,z10t),1,(z2,right),1,(z3,sklon2)])
780 | ])
781 | add_char("tcaron", 9, [
782 | _draw2([(z0,sklon2),2,(z1,-sklon1),None,(z2,-sklon1),1,
783 | (z10,z10t),1,(z2,right),1,(z3,sklon2)]),
784 | shift(hacek, (5.5,2))
785 | ])
786 | elif t_style == 2:
787 | z0=(0,6); z1=(4.5,14); z2=(1.25,1);
788 | letter = _draw2([(z0,sklon2),2,(z1,-sklon1),None,(z2,-sklon1)])
789 | z3=(-2.5,7); z4=(9.25+z3[0], z3[1])
790 | add_char("t", 9.25, [
791 | shift(letter, (0,0)),
792 | shift(dotah, (z2[0],0)),
793 | _draw2([(z3,None),None,(z4,None)]),
794 | ])
795 | add_char("tcaron", 9.25, [
796 | shift(letter, (0,0)),
797 | shift(dotah, (z2[0],0)),
798 | _draw2([(z3,None),None,(z4,None)]),
799 | shift(hacek, (5.5,2))
800 | ])
801 | else:
802 | raise Exception("Unsupported style")
803 |
804 | #beginchar("u", 10u#, 7u#, 0);
805 | # z0=(0,6); z1=(.5,7); z2=(-1,1); z3=(0,0); z4=(3.5,7); z5=(2,1);
806 | # draw z0{sklon2}..{-sklon1}z1{sklon1}..z2{sklon1}..z3{right}..tension2..
807 | # {-sklon1}z4{sklon1}..{sklon1}z5;
808 | # dotah shifted (x5,0);
809 | #endchar;
810 | z0=(0,6); z1=(.5,7); z2=(-1,1); z3=(0,0); z4=(3.5,7); z5=(2,1);
811 | add_char("u", 10, [
812 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(z2,sklon1),1,
813 | (z3,right),2,(-sklon1,z4,sklon1),1,(z5,sklon1)]),
814 | shift(dotah, (z5[0],0))
815 | ])
816 | add_char("uacute", 10, [
817 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(z2,sklon1),1,
818 | (z3,right),2,(-sklon1,z4,sklon1),1,(z5,sklon1)]),
819 | shift(dotah, (z5[0],0)),
820 | shift(carka, (2.5,0))
821 | ])
822 | add_char("uring", 10, [
823 | _draw2([(z0, sklon2),1,(-sklon1,z1,sklon1),1,(z2,sklon1),1,
824 | (z3,right),2,(-sklon1,z4,sklon1),1,(z5,sklon1)]),
825 | shift(dotah, (z5[0],0)),
826 | shift(krouzek, (2.5,0))
827 | ])
828 |
829 | #beginchar("v", 11u#, 7u#, 0);
830 | # z0=(0,6); z1=(2.5,6); z11=(2,7); z2=(1,1);
831 | # z4=(2,0); z5=(5,7); z6=(11,6);
832 | # z5p=(4.5,6);
833 | # draw z0{sklon2}..z11{right}..z1{sklon1}..z2{sklon1}..
834 | # z4{right}..tension3..z5{left}..z5p{down}..
835 | # tension2..{sklon2}z6
836 | #endchar;
837 | z0=(0,6); z1=(2.5,6); z11=(2,7); z2=(1,1);
838 | z4=(2,0); z5=(5,7); z6=(11,6);
839 | z5p=(4.5,6);
840 | add_char("v", 11, [
841 | _draw2([(z0,sklon2),1,(z11,right),1,(z1,sklon1),1,(z2,sklon1),1,
842 | (z4,right),3,(z5,left),1,(z5p,down),2,(z6,sklon2)])
843 | ])
844 |
845 | #beginchar(vnarrow, 9u#, 7u#, 0);
846 | # z0=(0,6); z1=(2.5,6); z11=(2,7); z2=(1,1);
847 | # z4=(2,0); z5=(5,7); z6=(9,6);
848 | # z5p=(4.5,6);
849 | # draw z0{sklon2}..z11{right}..z1{sklon1}..z2{sklon1}..
850 | # z4{right}..tension3..z5{left}..z5p{down}..
851 | # tension2..{sklon2}z6
852 | #endchar;
853 | z0=(0,6); z1=(2.5,6); z11=(2,7); z2=(1,1);
854 | z4=(2,0); z5=(5,7); z6=(9,6);
855 | z5p=(4.5,6);
856 | add_char("vnarrow", 9, [
857 | _draw2([(z0,sklon2),1,(z11,right),1,(z1,sklon1),1,(z2,sklon1),1,
858 | (z4,right),3,(z5,left),1,(z5p,down),2,(z6,sklon2)])
859 | ])
860 |
861 |
862 | #beginchar("w", 14u#, 7u#, 0);
863 | # z0=(0,6); z1=(2.5,6); z11=(2,7);
864 | # z2=(1,1); z3=(2,0); z4=(5.5,7);
865 | # z5=(4,1); z6=(5,0); z7=(8,7); z8=(14,6);
866 | # z7p=(7.5,6);
867 | # draw z0{sklon2}..z11{right}..z1{sklon1}..z2{sklon1}..
868 | # z3{right}..tension2..{-sklon1}z4{sklon1}..
869 | # z5{sklon1}..z6{right}..tension3..z7{left}..z7p{down}..
870 | # tension2..{sklon2}z8
871 | #endchar;
872 | z0=(0,6); z1=(2.5,6); z11=(2,7);
873 | z2=(1,1); z3=(2,0); z4=(5.5,7);
874 | z5=(4,1); z6=(5,0); z7=(8,7); z8=(14,6);
875 | z7p=(7.5,6);
876 | add_char("w", 14, [
877 | _draw2([(z0,sklon2),1,(z11,right),1,(z1,sklon1),1,(z2,sklon1),1,
878 | (z3,right),2,(-sklon1,z4,sklon1),1,
879 | (z5,sklon1),1,(z6,right),3,(z7,left),1,(z7p,down),2,(z8,sklon2)])
880 | ])
881 |
882 | #beginchar(wnarrow, 12u#, 7u#, 0);
883 | # z0=(0,6); z1=(2.5,6); z11=(2,7);
884 | # z2=(1,1); z3=(2,0); z4=(5.5,7);
885 | # z5=(4,1); z6=(5,0); z7=(8,7); z8=(12,6);
886 | # z7p=(7.5,6);
887 | # draw z0{sklon2}..z11{right}..z1{sklon1}..z2{sklon1}..
888 | # z3{right}..tension2..{-sklon1}z4{sklon1}..
889 | # z5{sklon1}..z6{right}..tension3..z7{left}..z7p{down}..
890 | # tension2..{sklon2}z8
891 | #endchar;
892 | z0=(0,6); z1=(2.5,6); z11=(2,7);
893 | z2=(1,1); z3=(2,0); z4=(5.5,7);
894 | z5=(4,1); z6=(5,0); z7=(8,7); z8=(12,6);
895 | z7p=(7.5,6);
896 | add_char("wnarrow", 12, [
897 | _draw2([(z0,sklon2),1,(z11,right),1,(z1,sklon1),1,(z2,sklon1),1,
898 | (z3,right),2,(-sklon1,z4,sklon1),1,
899 | (z5,sklon1),1,(z6,right),3,(z7,left),1,(z7p,down),2,(z8,sklon2)])
900 | ])
901 |
902 |
903 | #beginchar("x", 5u#, 7u#, 0);
904 | # z0=(0,6); z1=(1,7);
905 | # z2=(-1.5,7); z3=(-3,1);
906 | # draw z0{sklon2}..z1;
907 | # draw z2{sklon1}..{sklon1}z3;
908 | # dotah shifted (x3,0);
909 | #endchar;
910 | z0=(0,6); z1=(1,7);
911 | z2=(-1.5,7); z3=(-3,1);
912 | add_char("x", 5, [
913 | _draw2([(z0,sklon2),1,(z1,sklon2)]),
914 | _draw2([(z2,sklon1),1,(z3,sklon1)]),
915 | shift(dotah, (z3[0],0))
916 | ])
917 |
918 | #beginchar("y", 11u#, 7u#, 7u#);
919 | # z0=(0,6); z1=(2.5,6); z11=(2,7);
920 | # z2=(1,1); z3=(2,0); z4=(5.5,7);
921 | # draw z0{sklon2}..z11{right}..z1{sklon1}..z2{sklon1}..
922 | # z3{right}..tension2..{-sklon1}z4;
923 | # smycka shifted (x4,0);
924 | #endchar;
925 | z0=(0,6); z1=(2.5,6); z11=(2,7);
926 | z2=(1,1); z3=(2,0); z4=(5.5,7);
927 | add_char("y", 11, [
928 | _draw2([(z0,sklon2),1,(z11,right),1,(z1,sklon1),1,(z2,sklon1),1,
929 | (z3,right),2,(z4,-sklon1)]),
930 | shift(smycka, (z4[0],0))
931 | ])
932 | add_char("yacute", 11, [
933 | _draw2([(z0,sklon2),1,(z11,right),1,(z1,sklon1),1,(z2,sklon1),1,
934 | (z3,right),2,(z4,-sklon1)]),
935 | shift(smycka, (z4[0],0)),
936 | shift(carka, (4.5,0))
937 | ])
938 |
939 | def svg2mf(x):
940 | h = 800
941 | return (x[0]/scale, (h-x[1])/scale)
942 |
943 |
944 | if z_style == 1:
945 | #beginchar("z", 11u#, 7u#, 0);
946 | # z0=(0,6); z1=(1.5,7); z2=(4,7); z3=(1,0);
947 | # z4=(4,0); z5=(11,6);
948 | # draw z0{sklon2}..z1{right}..{-sklon1}z2{sklon1}..
949 | # {sklon1}z3{-sklon1}..z4{right}..tension1.5..{sklon2}z5;
950 | #endchar;
951 | z0=(0,6); z1=(1.5,7); z2=(4,7); z3=(1,0);
952 | z4=(4,0); z5=(11,6);
953 | add_char("z", 11, [
954 | _draw2([(z0,sklon2),1,(z1,right),1,(-sklon1,z2,sklon1),1,
955 | (sklon1,z3,-sklon1),1,(z4,right),1.5,(z5,sklon2)]),
956 | ])
957 | add_char("zcaron", 11, [
958 | _draw2([(z0,sklon2),1,(z1,right),1,(-sklon1,z2,sklon1),1,
959 | (sklon1,z3,-sklon1),1,(z4,right),1.5,(z5,sklon2)]),
960 | shift(hacek, (2.5,0))
961 | ])
962 | elif z_style == 2:
963 | z0=(0,6); z1=(1.5,7); z2=svg2mf((138,575)); z3=(1,0);
964 | z4=svg2mf((130, 800)); z5=(11,6);
965 | smycka2 = _draw2([((-2,0),sklon1),1,((-3.1,-4),sklon1),1,
966 | ((-5.3,-7),left),1,((-5.5,-5),-sklon1),1,
967 | ((-2,0),(6,5)),1,((5.5,6),sklon2)])
968 | letter = _draw2([(z0,sklon2),1,(z1,right),1,(z2,sklon1),1,
969 | (sklon1,z3,dir_(-330)),1,(z4,sklon1)])
970 | add_char("z", z4[0]+7.5, [
971 | shift(letter, (0,0)),
972 | shift(smycka2, (z4[0]+2,0))
973 | ])
974 | add_char("zcaron", z4[0]+7.5, [
975 | shift(letter, (0,0)),
976 | shift(smycka2, (z4[0]+2,0)),
977 | shift(hacek, (2.5,0))
978 | ])
979 | elif z_style == 3:
980 | z0=(0,6); z1=(1.5,7); z2=(4,7); z2b=(1,1); z3=(-0.5,0); z3b=(-0.5, 1)
981 | z4=(4,0); z5=(11,6);
982 | z2bt=array(z2b)-array(z2)
983 | letter = _draw2([(z0,sklon2),1,(z1,right),1,(-z2bt,z2,None),None,
984 | (z2b,z2bt),1,
985 | (z3,left),1,(z3b,right),1,(z4,right),1.5,(z5,sklon2)])
986 | add_char("z", 11, [
987 | shift(letter, (0,0)),
988 | ])
989 | add_char("zcaron", 11, [
990 | shift(letter, (0,0)),
991 | shift(hacek, (2.5,0))
992 | ])
993 | elif z_style == 4:
994 | z0=(0,6); z1=(0.5,7); z2=(4,7); z2b=(1,1); z3=(-0.5,0); z3b=(-0.5, 1)
995 | z4=(4,0); z5=(11,6);
996 | z2bt=array(z2b)-array(z2)
997 | letter = _draw2([(z0,sklon2),1,(-sklon1,z1,sklon1),1,(-z2bt,z2,None),None,
998 | (z2b,z2bt),1,
999 | (z3,left),1,(z3b,right),1,(z4,right),1.5,(z5,sklon2)])
1000 | add_char("z", 11, [
1001 | shift(letter, (0,0)),
1002 | ])
1003 | add_char("zcaron", 11, [
1004 | shift(letter, (0,0)),
1005 | shift(hacek, (2.5,0))
1006 | ])
1007 | else:
1008 | raise Exception("Unsupported style")
1009 |
1010 | ################################################################################
1011 | # Uppercase
1012 |
1013 | #beginchar("A", 11.4u#, 14u#, 0);
1014 | # z0=(0,6); z1=(7,14); z2=(1,0); z3=(3.4,1);
1015 | # z1p=(6,13.9);
1016 | # draw z1{left}..z1p..z0{sklon1}..
1017 | # z2{right}..tension2.5..{-sklon1}z1{sklon1}..z3{sklon1};
1018 | # dotah shifted (x3,0);
1019 | #endchar;
1020 | z0=(0,6); z1=(7,14); z2=(1,0); z3=(3.4,1);
1021 | z1p=(6,13.9);z1t=(-4,-1)
1022 | add_char("A_", 11.4, [
1023 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,sklon1),1,
1024 | (z2,right),2.5,(-sklon1,z1,sklon1),1,(z3,sklon1)]),
1025 | shift(dotah, (z3[0],0))
1026 | ])
1027 | add_char("A_acute", 11.4, [
1028 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,sklon1),1,
1029 | (z2,right),2.5,(-sklon1,z1,sklon1),1,(z3,sklon1)]),
1030 | shift(dotah, (z3[0],0)),
1031 | shift(capcarka, (6,0))
1032 | ])
1033 | add_char("A_dieresis", 11.4, [
1034 | _draw2([(z1,left),1,(z1p,z1t),1,(z0,sklon1),1,
1035 | (z2,right),2.5,(-sklon1,z1,sklon1),1,(z3,sklon1)]),
1036 | shift(dotah, (z3[0],0))] +
1037 | dvetecky(3,6)
1038 | )
1039 |
1040 | #beginchar("B", 9u#, 14u#, 0);
1041 | # z0=(0,6); z1=(8,14); z2=(1,0); z2p=(3,3);
1042 | # z3=(0,4); z4=(6,8); z4l=(x4-1,y4);
1043 | # z5=(8.5,4); z6=(5,0); z7=(3.5,2);
1044 | # draw z1{left}..z2p{sklon1}..z2{left}..z0{-sklon1}..
1045 | # z1{right}..{dir190}z4..z4l{up}..z4{dir-20}..z5{sklon1}..z6{left}..z7;
1046 | #endchar;
1047 | z0=(0,6); z1=(8,14); z2=(1,0); z2p=(3,3);
1048 | z3=(0,4); z4=(6,8); z4l=(z4[0]-1,z4[1]);
1049 | z5=(8.5,4); z6=(5,0); z7=(3.5,2); z7t=(1,2)
1050 | add_char("B_", 9, [
1051 | _draw2([(z1,left),1,(z2p,sklon1),1,(z2,left),1,(z0,-sklon1),1,
1052 | (z1,right),1,(z4,dir_(190)),1,(z4l,up),1,(z4,dir_(-20)),1,(z5,sklon1),
1053 | 1,(z6,left),1,(z7,z7t)])
1054 | ])
1055 |
1056 | #beginchar("C", 9.5u#, 14u#, 0);
1057 | # z0=(0,6); z1=(5,12.5); z2=(x1+.3,11); z3=(x1+.1,14);
1058 | # z4=(1.5,0); z5=(x4+8,6);
1059 | # draw z1{sklon1}..z2{right}..tension1.5..z3{left}..tension2..
1060 | # z0{sklon1}..z4{right}..tension1.5..{sklon2}z5;
1061 | #endchar;
1062 | z0=(0,6); z1=(5,12.5); z2=(z1[0]+.3,11); z3=(z1[0]+.1,14);
1063 | z4=(1.5,0); z5=(z4[0]+8,6);
1064 | add_char("C_", 9.5, [
1065 | _draw2([(z1,sklon1),1,(z2,right),1.5,(z3,left),2,
1066 | (z0,sklon1),1,(z4,right),1.5,(z5,sklon2)])
1067 | ])
1068 | add_char("C_caron", 9.5, [
1069 | _draw2([(z1,sklon1),1,(z2,right),1.5,(z3,left),2,
1070 | (z0,sklon1),1,(z4,right),1.5,(z5,sklon2)]),
1071 | shift(hacek, (5,6))
1072 | ])
1073 |
1074 | #beginchar("D", 8u#, 14u#, 0);
1075 | # z1=(9,14); z2=(3,3); z3=(1,0); z4=(.5,0); z4n=(x4,1);
1076 | # z5=(4,0); z6=(7,4); z7=(6,14); z8=(3.5,13); z9=(3.5,9);
1077 | # z10=(5.5,12);
1078 | # draw z1{-sklon2}..z2{sklon1}..z3..z4{left}..z4n{right}..
1079 | # z5{right}..z6{-sklon1}..z7{left}..
1080 | # z8{-sklon2}..z9{right}..{-sklon1}z10;
1081 | #endchar;
1082 | z1=(9,14); z2=(3,3); z3=(1,0); z4=(.5,0); z4n=(z4[0],1);
1083 | z5=(4,0); z6=(7,4); z7=(6,14); z8=(3.5,13); z9=(3.5,9);
1084 | z10=(5.5,12);
1085 | z3t=(-4,-1)
1086 | add_char("D_", 8, [
1087 | _draw2([(z1,-sklon2),1,(z2,sklon1),1,(z3,z3t),1,(z4,left),1,(z4n,right),1,
1088 | (z5,right),1,(z6,-sklon1),1,(z7,left),1,
1089 | (z8,-sklon2),1,(z9,right),1,(z10,-sklon1)]),
1090 | ])
1091 | add_char("D_caron", 8, [
1092 | _draw2([(z1,-sklon2),1,(z2,sklon1),1,(z3,z3t),1,(z4,left),1,(z4n,right),1,
1093 | (z5,right),1,(z6,-sklon1),1,(z7,left),1,
1094 | (z8,-sklon2),1,(z9,right),1,(z10,-sklon1)]),
1095 | shift(hacek, (7,6))
1096 | ])
1097 |
1098 | #beginchar("E", 9.5u#, 14u#, 0);
1099 | # z0=(0,6); z1=(4,12.5); z2=(x1+.3,11); z3=(x1+.1,14);
1100 | # z6=(2,8.5); z6n=(x6+1,y6);
1101 | # z4=(1.5,0); z5=(x4+8,6);
1102 | # draw z1{sklon1}..z2{right}..tension1.5..z3{left}..tension2..
1103 | # z6..z6n{up}..z6..
1104 | # z0..tension1.5and1..z4{right}..tension1.5..{sklon2}z5;
1105 | #endchar;
1106 | z0=(0,6); z1=(4,12.5); z2=(z1[0]+.3,11); z3=(z1[0]+.1,14);
1107 | z6=(2,8.5); z6n=(z6[0]+1,z6[1]);
1108 | z4=(1.5,0); z5=(z4[0]+8,6);
1109 | z6t=(1,-3); z6t2=(-1,-1); z0t=(-4,-7)
1110 | add_char("E_", 9.5, [
1111 | _draw2([(z1,sklon1),1,(z2,right),1.5,(z3,left),2,
1112 | (z6,z6t),1,(z6n,up),1,(z6,z6t2),1,
1113 | (z0,z0t),1.3,(z4,right),1.5,(z5,sklon2)]),
1114 | ])
1115 | add_char("E_acute", 9.5, [
1116 | _draw2([(z1,sklon1),1,(z2,right),1.5,(z3,left),2,
1117 | (z6,z6t),1,(z6n,up),1,(z6,z6t2),1,
1118 | (z0,z0t),1.3,(z4,right),1.5,(z5,sklon2)]),
1119 | shift(capcarka, (5,0))
1120 | ])
1121 | add_char("E_caron", 9.5, [
1122 | _draw2([(z1,sklon1),1,(z2,right),1.5,(z3,left),2,
1123 | (z6,z6t),1,(z6n,up),1,(z6,z6t2),1,
1124 | (z0,z0t),1.3,(z4,right),1.5,(z5,sklon2)]),
1125 | shift(hacek, (4.5,6))
1126 | ])
1127 |
1128 | #beginchar("F", 5u#, 14u#, 0); charic := 7u#;
1129 | # z1=(4,12.5); z2=(3,10); z3=(2.3,12.5); z4=(4,14);
1130 | # z5=(7,13.5); z6=(12,14);
1131 | # z7=(4,4); z8=(1,0); z9=(0,3);
1132 | # z10=(2,7); z11=(6,9); z12=(6.5,7);
1133 | # draw z1{sklon1}..z2..z3{-sklon1}..z4{right}..z5..{right}z6;
1134 | # draw z5{-sklon2}..z7{sklon1}..z8{left}..{-sklon1}z9;
1135 | # draw z10..z11{right}..{sklon1}z12;
1136 | #endchar;
1137 | z1=(4,12.5); z2=(3,10); z3=(2.3,12.5); z4=(4,14);
1138 | z5=(7,13.5); z6=(12,14);
1139 | z7=(4,4); z8=(1,0); z9=(0,3);
1140 | z10=(2,7); z11=(6,9); z12=(6.5,7);
1141 | z2t=(-1,0); z5t=(4,-1); z10t=(1,1)
1142 | add_char("F_", 5, [
1143 | _draw2([(z1,sklon1),1,(z2,z2t),1,(z3,-sklon1),1,(z4,right),1,(z5,z5t),1,
1144 | (z6,right)]),
1145 | _draw2([(z5,-sklon2),1,(z7,sklon1),1,(z8,left),1,(z9,-sklon1)]),
1146 | _draw2([(z10,z10t),1,(z11,right),1,(z12,sklon1)])
1147 | ])
1148 |
1149 | #beginchar("G", 10.5u#, 14u#, 7u#);
1150 | # z0=(0,6); z1=(5,12.5); z2=(x1+.3,11); z3=(x1+.1,14);
1151 | # z4=(1,0); z5=(x4+4,7);
1152 | # draw z1{sklon1}..z2{right}..tension1.5..z3{left}..tension2..
1153 | # z0{sklon1}..z4{right}..tension1.5..{-sklon1}z5;
1154 | # smycka shifted (x5,0);
1155 | #endchar;
1156 | z0=(0,6); z1=(5,12.5); z2=(z1[0]+.3,11); z3=(z1[0]+.1,14);
1157 | z4=(1,0); z5=(z4[0]+4,7);
1158 | add_char("G_", 10.5, [
1159 | _draw2([(z1,sklon1),1,(z2,right),1.5,(z3,left),2,
1160 | (z0,sklon1),1,(z4,right),1.5,(z5,-sklon1)]),
1161 | shift(smycka, (z5[0],0))
1162 | ])
1163 |
1164 | #beginchar("H", 13u#, 14u#, 0);
1165 | # z1=(1.5,11); z2=(4.5,14); z3=(5,12); z4=(2,1);
1166 | # z5=(1,0); z6=(0.5,3); z7=(6,8);
1167 | # z8=(9.5,11.5); z9=(9,14); z10=(8,13); z11=(5,1);
1168 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4..
1169 | # z5{left}..z6{-sklon1}..tension1.5..z7..z8{-sklon1}..
1170 | # z9{left}..z10{sklon1}..{sklon1}z11;
1171 | # dotah shifted (x11,0);
1172 | #endchar;
1173 | z1=(1.5,11); z2=(4.5,14); z3=(5,12); z4=(2,1);
1174 | z5=(1,0); z6=(0.5,3); z7=(6,8);
1175 | z8=(9.5,11.5); z9=(9,14); z10=(8,13); z11=(5,1);
1176 | z7t=(1,1)
1177 | add_char("H_", 13, [
1178 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1179 | (z5,left),1,(z6,-sklon1),1.5,(z7,z7t),1,(z8,-sklon1),1,
1180 | (z9,left),1,(z10,sklon1),1,(z11,sklon1)]),
1181 | shift(dotah, (z11[0],0))
1182 | ])
1183 |
1184 | #beginchar("I", 5u#, 14u#, 0);
1185 | # z1=(2.5,11); z2=(5.5,14); z3=(6,12); z4=(3.2,2);
1186 | # z5=(1,0); z6=(-.5,3);
1187 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4..
1188 | # z5{left}..{up}z6;
1189 | #endchar;
1190 | z1=(2.5,11); z2=(5.5,14); z3=(6,12); z4=(3.2,2);
1191 | z5=(1,0); z6=(-.5,3);
1192 | add_char("I_", 5, [
1193 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1194 | (z5,left),1,(z6,up)]),
1195 | ])
1196 | add_char("I_acute", 5, [
1197 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1198 | (z5,left),1,(z6,up)]),
1199 | shift(capcarka, (6,0))
1200 | ])
1201 |
1202 | #beginchar("J", 10.1u#, 14u#, 7u#);
1203 | # z1=(2.5,11); z2=(5.5,14); z3=(6,12); z4=(4.6,7);
1204 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4;
1205 | # smycka shifted (x4,0);
1206 | #endchar;
1207 | z1=(2.5,11); z2=(5.5,14); z3=(6,12); z4=(4.6,7);
1208 | add_char("J_", 10.1, [
1209 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1)]),
1210 | shift(smycka, (z4[0],0))
1211 | ])
1212 |
1213 | #beginchar("K", 15u#, 14u#, 0);
1214 | # z1=(2.5,11); z2=(5.5,14); z3=(6,12); z4=(3.2,2);
1215 | # z5=(1,0); z6=(-.5,3);
1216 | # z7=(12,11); z8=(10,14); z9=(5,8); z9p=(x9+1,y9);
1217 | # z10=(9,0); z11=(15,6);
1218 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4..
1219 | # z5{left}..{up}z6;
1220 | # draw z7{dir110}..z8{left}..tension2..
1221 | # z9p{dir215}..z9{up}..z9p{dir-35}..
1222 | # tension1.5..z10{right}..tension3..{sklon2}z11;
1223 | #endchar;
1224 | z1=(2.5,11); z2=(5.5,14); z3=(6,12); z4=(3.2,2);
1225 | z5=(1,0); z6=(-.5,3);
1226 | z7=(12,11); z8=(10,14); z9=(5,8); z9p=(z9[0]+1,z9[1]);
1227 | z10=(9,0); z11=(15,6);
1228 | add_char("K_", 15, [
1229 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1230 | (z5,left),1,(z6,up)]),
1231 | _draw2([(z7,dir_(110)),1,(z8,left),2,(z9p,dir_(215)),1,(z9,up),1,
1232 | (z9p,dir_(-35)),1.5,(z10,right),3,(z11,sklon2)]),
1233 | ])
1234 |
1235 | #beginchar("L", 12u#, 14u#, 0);
1236 | # z1=(4,14); z2=(6,9); z3=(9,14); z4=(7,12);
1237 | # z5=(2,1); z5d=(.5,0); z5p=(-.5,.8); z6=(6,0); z7=(12,6);
1238 | # draw z1..z2{right}..tension1.7..z3{left}..z4{sklon1}..
1239 | # z5..z5d{left}..z5p{up}..z5..z6{right}..tension2..{sklon2}z7;
1240 | #endchar;
1241 | z1=(4,14); z2=(6,9); z3=(9,14); z4=(7,12);
1242 | z5=(2,1); z5d=(.5,0); z5p=(-.5,.8); z6=(6,0); z7=(12,6);
1243 | z1t=(-1,-1); z5t=(-3,-4); z5t2=(8,-5)
1244 | add_char("L_", 12, [
1245 | _draw2([(z1,z1t),1,(z2,right),1.7,(z3,left),1,(z4,sklon1),1,
1246 | (z5,z5t),1,(z5d,left),1,(z5p,up),1,(z5,z5t2),1,(z6,right),2,
1247 | (z7,sklon2)]),
1248 | ])
1249 | add_char("L_acute", 12, [
1250 | _draw2([(z1,z1t),1,(z2,right),1.7,(z3,left),1,(z4,sklon1),1,
1251 | (z5,z5t),1,(z5d,left),1,(z5p,up),1,(z5,z5t2),1,(z6,right),2,
1252 | (z7,sklon2)]),
1253 | shift(capcarka, (7,0))
1254 | ])
1255 | add_char("L_caron", 12, [
1256 | _draw2([(z1,z1t),1,(z2,right),1.7,(z3,left),1,(z4,sklon1),1,
1257 | (z5,z5t),1,(z5d,left),1,(z5p,up),1,(z5,z5t2),1,(z6,right),2,
1258 | (z7,sklon2)]),
1259 | shift(hacek, (6,6))
1260 | ])
1261 |
1262 | #beginchar("M", 15u#, 14u#, 0);
1263 | # z1=(0.5,11); z2=(3.5,14); z3=(4,12); z4=(0.8,0);
1264 | # z5=(6.5,14); z6=(7,12); z7=(3.8,0);
1265 | # z8=(9.5,14); z9=(10,12); z10=(7,1);
1266 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4;
1267 | # draw z3{-sklon1}..tension1.5..z5{right}..z6{sklon1}..{sklon1}z7;
1268 | # draw z6{-sklon1}..tension1.5..z8{right}..z9{sklon1}..{sklon1}z10;
1269 | # dotah shifted (x10,0);
1270 | #endchar;
1271 | z1=(0.5,11); z2=(3.5,14); z3=(4,12); z4=(0.8,0);
1272 | z5=(6.5,14); z6=(7,12); z7=(3.8,0);
1273 | z8=(9.5,14); z9=(10,12); z10=(7,1);
1274 | add_char("M_", 15, [
1275 | _draw2([(z1, sklon2),1 ,(z2,right),1,(z3,sklon1),1,(z4,sklon1)]),
1276 | _draw2([(z3,-sklon1),1.5,(z5,right),1,(z6,sklon1),1,(z7,sklon1)]),
1277 | _draw2([(z6,-sklon1),1.5,(z8,right),1,(z9,sklon1),1,(z10,sklon1)]),
1278 | shift(dotah, (z10[0],0))
1279 | ])
1280 |
1281 | #beginchar("N", 12u#, 14u#, 0);
1282 | # z1=(0.5,11); z2=(3.5,14); z3=(4,12); z4=(0.8,0);
1283 | # z5=(6.5,14); z6=(7,12); z7=(4,1);
1284 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4;
1285 | # draw z3{-sklon1}..tension1.5..z5{right}..z6{sklon1}..{sklon1}z7;
1286 | # dotah shifted (x7,0);
1287 | #endchar;
1288 | z1=(0.5,11); z2=(3.5,14); z3=(4,12); z4=(0.8,0);
1289 | z5=(6.5,14); z6=(7,12); z7=(4,1);
1290 | add_char("N_", 12, [
1291 | _draw2([(z1, sklon2),1 ,(z2,right),1,(z3,sklon1),1,(z4,sklon1)]),
1292 | _draw2([(z3,-sklon1),1.5,(z5,right),1,(z6,sklon1),1,(z7,sklon1)]),
1293 | shift(dotah, (z7[0],0))
1294 | ])
1295 | add_char("N_caron", 12, [
1296 | _draw2([(z1, sklon2),1 ,(z2,right),1,(z3,sklon1),1,(z4,sklon1)]),
1297 | _draw2([(z3,-sklon1),1.5,(z5,right),1,(z6,sklon1),1,(z7,sklon1)]),
1298 | shift(dotah, (z7[0],0)),
1299 | shift(hacek, (5,7))
1300 | ])
1301 |
1302 | #beginchar("O", 5u#, 14u#, 0); charic := 2u#;
1303 | # z0=(0,6); z1=(6,14); z2=(1,0); z3=(10,14);
1304 | # z1p=(4.5,13.9); z2p=(5.5,13); z1d=(6.5,13);
1305 | # draw z1{left}..z1p..tension1.5and1..z0{sklon1}..tension1.5..
1306 | # z2{right}..tension2..z1d..z1{left}..z2p{down}..{sklon2}z3;
1307 | #endchar;
1308 | z0=(0,6); z1=(6,14); z2=(1,0); z3=(10,14);
1309 | z1p=(4.5,13.9); z2p=(5.5,13); z1d=(6.5,13);
1310 | z1pt=(-3,-1); z1dt=(0,1)
1311 | add_char("O_", 5, [
1312 | _draw2([(z1,left),1,(z1p,z1pt),1.25,(z0,sklon1),1.5,
1313 | (z2,right),2,(z1d,z1dt),1,(z1,left),1,(z2p,down),1,(z3,sklon2)]),
1314 | ])
1315 | add_char("O_acute", 5, [
1316 | _draw2([(z1,left),1,(z1p,z1pt),1.25,(z0,sklon1),1.5,
1317 | (z2,right),2,(z1d,z1dt),1,(z1,left),1,(z2p,down),1,(z3,sklon2)]),
1318 | shift(capcarka, (6,0))
1319 | ])
1320 | add_char("O_circumflex", 5, [
1321 | _draw2([(z1,left),1,(z1p,z1pt),1.25,(z0,sklon1),1.5,
1322 | (z2,right),2,(z1d,z1dt),1,(z1,left),1,(z2p,down),1,(z3,sklon2)]),
1323 | shift(vokan, (3.6,7))
1324 | ])
1325 |
1326 | #beginchar("P", 4u#, 14u#, 0); charic := 5u#;
1327 | # z0=(0,6); z1=(8,14); z2=(1,0); z2p=(3,3);
1328 | # z3=(0,4); z4=(5,8);
1329 | # draw z1{left}..z2p{sklon1}..z2{left}..z0{-sklon1}..
1330 | # z1{right}..{left}z4;
1331 | #endchar;
1332 | z0=(0,6); z1=(8,14); z2=(1,0); z2p=(3,3);
1333 | z3=(0,4); z4=(5,8);
1334 | add_char("P_", 4, [
1335 | _draw2([(z1,left),1,(z2p,sklon1),1,(z2,left),1,(z0,-sklon1),1,
1336 | (z1,right),1,(z4,left)]),
1337 | ])
1338 |
1339 | #beginchar("Q", 10.9u#, 14u#, 7u#);
1340 | # z0=(0,6); z1=(5,12.5); z2=(x1+.3,11); z3=(x1+.1,14);
1341 | # z4=(1,0); z5=(5,7);
1342 | # z6=(3,-.5); z7-z6 = whatever*(z5-z6); y7=-7;
1343 | # z8=(x6+7.9,6);
1344 | # draw z1{sklon1}..z2{right}..tension1.5..z3{left}..tension2..
1345 | # z0{sklon1}..z4{right}..tension1.5..
1346 | # {-sklon1}z5{sklon1}..z6{sklon1}..{sklon1}z7;
1347 | # draw z6{-sklon1}..tension2..{sklon2}z8;
1348 | #endchar;
1349 | z0=(0,6); z1=(5,12.5); z2=(z1[0]+.3,11); z3=(z1[0]+.1,14);
1350 | z4=(1,0); z5=(5,7);
1351 | z6=(3,-.5); z7 = whatever_y(z6, array(z5)-array(z6), -7);
1352 | z8=(z6[0]+7.9,6);
1353 | add_char("Q_", 10.9, [
1354 | _draw2([(z1,sklon1),1,(z2,right),1.5,(z3,left),2,
1355 | (z0,sklon1),1,(z4,right),1.5,
1356 | (-sklon1,z5,sklon1),1,(z6,sklon1),1,(z7,sklon1)]),
1357 | _draw2([(z6,-sklon1),2,(z8,sklon2)])
1358 | ])
1359 |
1360 | #beginchar("R", 14u#, 14u#, 0);
1361 | # z0=(0,6); z1=(8,14); z2=(1,0); z2p=(3,3);
1362 | # z3=(0,4); z4=(6,8); z4l=(x4-1,y4);
1363 | # z10=(8,0); z11=(14,6);
1364 | # draw z1{left}..z2p{sklon1}..z2{left}..z0{-sklon1}..
1365 | # z1{right}..{dir215}z4..z4l{up}..z4{dir-35}..
1366 | # tension1.5..z10{right}..tension3..{sklon2}z11;
1367 | #endchar;
1368 | z0=(0,6); z1=(8,14); z2=(1,0); z2p=(3,3);
1369 | z3=(0,4); z4=(6,8); z4l=(z4[0]-1,z4[1]);
1370 | z10=(8,0); z11=(14,6);
1371 | add_char("R_", 14, [
1372 | _draw2([(z1,left),1,(z2p,sklon1),1,(z2,left),1,(z0,-sklon1),1,
1373 | (z1,right),1,(z4,dir_(215)),1,(z4l,up),1,(z4,dir_(-35)),
1374 | 1.5,(z10,right),3,(z11,sklon2)]),
1375 | ])
1376 | add_char("R_caron", 14, [
1377 | _draw2([(z1,left),1,(z2p,sklon1),1,(z2,left),1,(z0,-sklon1),1,
1378 | (z1,right),1,(z4,dir_(215)),1,(z4l,up),1,(z4,dir_(-35)),
1379 | 1.5,(z10,right),3,(z11,sklon2)]),
1380 | shift(hacek, (7,6))
1381 | ])
1382 | add_char("R_acute", 14, [
1383 | _draw2([(z1,left),1,(z2p,sklon1),1,(z2,left),1,(z0,-sklon1),1,
1384 | (z1,right),1,(z4,dir_(215)),1,(z4l,up),1,(z4,dir_(-35)),
1385 | 1.5,(z10,right),3,(z11,sklon2)]),
1386 | shift(capcarka, (8,0))
1387 | ])
1388 |
1389 | #beginchar("S", 6u#, 14u#, 0); charic := 3u#;
1390 | # z1=(4,14); z2=(6,9); z3=(9,14); z4=(7,12);
1391 | # z5=(4.2,2); z6=(x5-2.2,0); z7=(x6-1.5,3);
1392 | # draw z1..z2{right}..tension1.7..z3{left}..z4{sklon1}..{sklon1}z5..
1393 | # z6{left}..{up}z7;
1394 | #endchar;
1395 | z1=(4,14); z2=(6,9); z3=(9,14); z4=(7,12);
1396 | z5=(4.2,2); z6=(z5[0]-2.2,0); z7=(z6[0]-1.5,3);
1397 | z1t=(-1,-1)
1398 | add_char("S_", 6, [
1399 | _draw2([(z1,z1t),1,(z2,right),1.7,(z3,left),1,(z4,sklon1),1,(z5,sklon1),1,
1400 | (z6,left),1,(z7,up)]),
1401 | ])
1402 | add_char("S_caron", 6, [
1403 | _draw2([(z1,z1t),1,(z2,right),1.7,(z3,left),1,(z4,sklon1),1,(z5,sklon1),1,
1404 | (z6,left),1,(z7,up)]),
1405 | shift(hacek, (7,6))
1406 | ])
1407 |
1408 | #beginchar("T", 5u#, 14u#, 0); charic := 7u#;
1409 | # z1=(4,12.5); z2=(3,10); z3=(2.3,12.5); z4=(4,14);
1410 | # z5=(7,13.5); z6=(12,14);
1411 | # z7=(4,4); z8=(1,0); z9=(0,3);
1412 | # draw z1{sklon1}..z2..z3{-sklon1}..z4{right}..z5..{right}z6;
1413 | # draw z5{-sklon2}..z7{sklon1}..z8{left}..{-sklon1}z9;
1414 | #endchar;
1415 | z1=(4,12.5); z2=(3,10); z3=(2.3,12.5); z4=(4,14);
1416 | z5=(7,13.5); z6=(12,14);
1417 | z7=(4,4); z8=(1,0); z9=(0,3);
1418 | z2t=(-1,0); z5t=(4,-1);
1419 | add_char("T_", 5, [
1420 | _draw2([(z1,sklon1),1,(z2,z2t),1,(z3,-sklon1),1,(z4,right),1,(z5,z5t),1,
1421 | (z6,right)]),
1422 | _draw2([(z5,-sklon2),1,(z7,sklon1),1,(z8,left),1,(z9,-sklon1)])
1423 | ])
1424 | add_char("T_caron", 5, [
1425 | _draw2([(z1,sklon1),1,(z2,z2t),1,(z3,-sklon1),1,(z4,right),1,(z5,z5t),1,
1426 | (z6,right)]),
1427 | _draw2([(z5,-sklon2),1,(z7,sklon1),1,(z8,left),1,(z9,-sklon1)]),
1428 | shift(hacek, (7,6))
1429 | ])
1430 |
1431 | #beginchar("U", 11.7u#, 14u#, 0);
1432 | # z1=(-.5,11); z2=(2.5,14); z3=(3,12); z4=(0,1);
1433 | # z5=(0.5,0); z6=(7,14); z7=(3.7,1);
1434 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4..
1435 | # z5{right}..tension1.7..{-sklon1}z6--z7;
1436 | # dotah shifted (x7,0);
1437 | #endchar;
1438 | z1=(-.5,11); z2=(2.5,14); z3=(3,12); z4=(0,1);
1439 | z5=(0.5,0); z6=(7,14); z7=(3.7,1);
1440 | add_char("U_", 11.7, [
1441 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1442 | (z5,right),1.7,(z6,-sklon1),None,(z7,None)]),
1443 | shift(dotah, (z7[0],0))
1444 | ])
1445 | add_char("U_acute", 11.7, [
1446 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1447 | (z5,right),1.7,(z6,-sklon1),None,(z7,None)]),
1448 | shift(dotah, (z7[0],0)),
1449 | shift(capcarka, (5.5,0))
1450 | ])
1451 | add_char("U_ring", 11.7, [
1452 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1453 | (z5,right),1.7,(z6,-sklon1),None,(z7,None)]),
1454 | shift(dotah, (z7[0],0)),
1455 | shift(krouzek, (5.5,6))
1456 | ])
1457 |
1458 | #beginchar("V", 5.5u#, 14u#, 0); charic := 5u#;
1459 | # z1=(-.5,11); z2=(2.5,14); z3=(3,12); z4=(0,1);
1460 | # z5=(0.5,0); z9=(6.5,14); z9d=(x9+.5,y9-1); z9p=(x9-.5,y9-1);
1461 | # z10=(10.5,14);
1462 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4..
1463 | # z5{right}..tension1.7..{-sklon1}z9d..
1464 | # z9{left}..z9p{down}..{sklon2}z10;
1465 | #endchar;
1466 | z1=(-.5,11); z2=(2.5,14); z3=(3,12); z4=(0,1);
1467 | z5=(0.5,0); z9=(6.5,14); z9d=(z9[0]+.5,z9[1]-1); z9p=(z9[0]-.5,z9[1]-1);
1468 | z10=(10.5,14);
1469 | add_char("V_", 5.5, [
1470 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1471 | (z5,right),1.7,(z9d,-sklon1),1,
1472 | (z9,left),1,(z9p,down),1,(z10,sklon2)]),
1473 | ])
1474 |
1475 | #beginchar("W", 8.3u#, 14u#, 0); charic := 5u#;
1476 | # z1=(-.5,11); z2=(2.5,14); z3=(3,12);
1477 | # z4=(0,1); z5=(0.5,0); z6=(7,14);
1478 | # z7=(3.8,1); z8=(4.3,0);
1479 | # z9=(10.3,14); z9d=(x9+.5,y9-1); z9p=(x9-.5,y9-1);
1480 | # z10=(14.7,14);
1481 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4..
1482 | # z5{right}..tension1.7..{-sklon1}z6{sklon1}..
1483 | # {sklon1}z7..z8{right}..tension1.7..{-sklon1}z9d..
1484 | # z9{left}..z9p{down}..{sklon2}z10;
1485 | #endchar;
1486 | z1=(-.5,11); z2=(2.5,14); z3=(3,12);
1487 | z4=(0,1); z5=(0.5,0); z6=(7,14);
1488 | z7=(3.8,1); z8=(4.3,0);
1489 | z9=(10.3,14); z9d=(z9[0]+.5,z9[1]-1); z9p=(z9[0]-.5,z9[1]-1);
1490 | z10=(14.7,14);
1491 | add_char("W_", 8.3, [
1492 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1493 | (z5,right),1.7,(-sklon1,z6,sklon1),1,
1494 | (z7,sklon1),1,(z8,right),1.7,(z9d,-sklon1),1,
1495 | (z9,left),1,(z9p,down),1,(z10,sklon2)]),
1496 | ])
1497 |
1498 | #beginchar("X", 15.1u#, 14u#, 0);
1499 | # z1=(2.5,11); z2=(5.5,14); z3=(7,12); z4=(7.1,1);
1500 | # z7=(14,11); z8=(12,14); z10=(7,8); z9=(1,0); z6=(-.5,3);
1501 | # draw z1{sklon2}..z2{right}..z3--z4;
1502 | # draw z7{dir110}..z8{left}..tension2..z10..tension1.5..{left}z9..{up}z6;
1503 | # dotah shifted (x4,0);
1504 | #endchar;
1505 | z1=(2.5,11); z2=(5.5,14); z3=(7,12); z4=(7.1,1);
1506 | z7=(14,11); z8=(12,14); z10=(7,8); z9=(1,0); z6=(-.5,3);
1507 | z3t=array(z4)-array(z3); z10t=(-1,-2)
1508 | add_char("X_", 15.1, [
1509 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,z3t),None,(z4,None)]),
1510 | _draw2([(z7,dir_(110)),1,(z8,left),2,(z10,z10t),1.5,(z9,left),1,(z6,up)]),
1511 | shift(dotah, (z4[0],0))
1512 | ])
1513 |
1514 |
1515 | #beginchar("Y", 10.7u#, 14u#, 7u#);
1516 | # z1=(-.5,11); z2=(2.5,14); z3=(3,12); z4=(0,1);
1517 | # z5=(0.5,0); z6=(7,14); z7=(5.2,7);
1518 | # draw z1{sklon2}..z2{right}..z3{sklon1}..{sklon1}z4..
1519 | # z5{right}..tension1.7..{-sklon1}z6--z7;
1520 | # smycka shifted (x7, 0);
1521 | #endchar;
1522 | z1=(-.5,11); z2=(2.5,14); z3=(3,12); z4=(0,1);
1523 | z5=(0.5,0); z6=(7,14); z7=(5.2,7);
1524 | add_char("Y_", 10.7, [
1525 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1526 | (z5,right),1.7,(z6,-sklon1),None,(z7,None)]),
1527 | shift(smycka, (z7[0],0))
1528 | ])
1529 | add_char("Y_acute", 10.7, [
1530 | _draw2([(z1,sklon2),1,(z2,right),1,(z3,sklon1),1,(z4,sklon1),1,
1531 | (z5,right),1.7,(z6,-sklon1),None,(z7,None)]),
1532 | shift(smycka, (z7[0],0)),
1533 | shift(capcarka, (5.5,0))
1534 | ])
1535 |
1536 | #beginchar("Z", 12u#, 14u#, 0);
1537 | # z1=(1,12); z2=(4,14); z3=(7.5,13); z4=(9,14); z4p=(x4+1,y4-.5);
1538 | # z5=(2,1); z5d=(.5,0); z5p=(-.5,.8); z6=(6,0); z7=(12,6);
1539 | # draw z1..z2{right}..z3..z4p{up}..z4{left}..z3..
1540 | # z5..z5d{left}..z5p{up}..z5..z6{right}..tension2..{sklon2}z7;
1541 | #endchar;
1542 | z1=(1,12); z2=(4,14); z3=(7.5,13); z4=(9,14); z4p=(z4[0]+1,z4[1]-.5);
1543 | z5=(2,1); z5d=(.5,0); z5p=(-.5,.8); z6=(6,0); z7=(12,6);
1544 | z1t=(1,1); z3t=(1,-1); z3t2=(-1,-2); z5t=(-1,-2); z5t2=(2,-1)
1545 | add_char("Z_", 12, [
1546 | _draw2([(z1,z1t),1,(z2,right),1,(z3,z3t),1,(z4p,up),1,(z4,left),1,(z3,z3t2),1,
1547 | (z5,z5t),1,(z5d,left),1,(z5p,up),1,(z5,z5t2),1,(z6,right),2,(z7,sklon2)]),
1548 | ])
1549 | add_char("Z_caron", 12, [
1550 | _draw2([(z1,z1t),1,(z2,right),1,(z3,z3t),1,(z4p,up),1,(z4,left),1,(z3,z3t2),1,
1551 | (z5,z5t),1,(z5d,left),1,(z5p,up),1,(z5,z5t2),1,(z6,right),2,(z7,sklon2)]),
1552 | shift(hacek, (6,6))
1553 | ])
1554 |
1555 | ################################################################################
1556 | # Digits
1557 |
1558 | #beginchar("1", 8u#, 14u#, 0);
1559 | # z1=(1.5,9); z2=(5.5,14); z3=(2.5,0);
1560 | # draw z1..{dir60}z2--z3;
1561 | #endchar;
1562 | z1=(1.5,9); z2=(5.5,14); z3=(2.5,0);
1563 | z1t=(1,1)
1564 | add_char("one", 8, [
1565 | _draw2([(z1,z1t),1,(z2,dir_(60)),None,(z3,None)]),
1566 | ])
1567 |
1568 | #beginchar("2", 8u#, 14u#, 0);
1569 | # z1=(1.5,11); z2=(4,14); z3=(6,11); z4=(0,0); z5=(5,0);
1570 | # draw z1..z2{right}..z3{-dir80}..{-dir65}z4--z5;
1571 | #endchar;
1572 | z1=(1.5,11); z2=(4,14); z3=(6,11); z4=(0,0); z5=(5,0);
1573 | z1t=(0,1)
1574 | add_char("two", 8, [
1575 | _draw2([(z1,z1t),1,(z2,right),1,(z3,-dir_(80)),1,
1576 | (z4,-dir_(65)),None,(z5,None)]),
1577 | ])
1578 |
1579 | #beginchar("3", 8u#, 14u#, 0);
1580 | # z1=(1.5,11); z2=(4,14); z3=(6,11); z4=(3,8); z5=(2,0); z6=(-.5,3);
1581 | # draw z1..z2{right}..z3{-dir80}..z4&z4..tension1.5..z5{left}..z6{up};
1582 | #endchar;
1583 | z1=(1.5,11); z2=(4,14); z3=(6,11); z4=(3,8); z5=(2,0); z6=(-.5,3);
1584 | z1t=(0,1)
1585 | add_char("three", 8, [
1586 | _draw2([(z1,z1t),1,(z2,right),1,(z3,-dir_(80)),1,(z4,(-1,0))]),
1587 | _draw2([(z4,(4,-1)),1.5,(z5,left),1,(z6,up)]),
1588 | ])
1589 |
1590 | #beginchar("4", 8u#, 14u#, 0);
1591 | # z1=(5,14); z2=(0,6); z3=(6,6); z4=(4.5,9); z5=(2.5,0);
1592 | # draw z1--z2--z3;
1593 | # draw z4--z5;
1594 | #endchar;
1595 | z1=(5,14); z2=(0,6); z3=(6,6); z4=(4.5,9); z5=(2.5,0);
1596 | add_char("four", 8, [
1597 | _draw2([(z1,None),None,(z2,None),None,(z3,None)]),
1598 | _draw2([(z4,None),None,(z5,None)]),
1599 | ])
1600 |
1601 | #beginchar("5", 8u#, 14u#, 0);
1602 | # z1=(6,14); z2=(2.5,14); z3=(1,8); z4=(4,9); z5=(2,0); z6=(-.5,3);
1603 | # draw z1--z2--z3&z3..z4..tension1.5..z5{left}..z6{up};
1604 | #endchar;
1605 | z1=(6,14); z2=(2.5,14); z3=(1,8); z4=(4,9); z5=(2,0); z6=(-.5,3);
1606 | z3t=array(z2)-array(z3); z4t=dir_(-42)
1607 | add_char("five", 8, [
1608 | _draw2([(z1,None),None,(z2,None),None,(z3,None)]),
1609 | _draw2([(z3,z3t),1,(z4,z4t),1.5,(z5,left),1,(z6,up)]),
1610 | ])
1611 |
1612 | #beginchar("6", 8u#, 14u#, 0);
1613 | # z1=(6,14); z3=(.5,5); z4=(4,8); z5=(2,0); z6=(-.5,3);
1614 | # draw z1{-dir35}..z3{sklon1}&z3{-sklon1}..z4..tension1.5..z5{left}..
1615 | # z3{-sklon1};
1616 | #endchar;
1617 | z1=(6,14); z3=(.5,5); z4=(4,8); z5=(2,0); z6=(-.5,3);
1618 | z4t=dir_(-38)
1619 | add_char("six", 8, [
1620 | _draw2([(z1,-dir_(35)),1,(z3,sklon1)]),
1621 | _draw2([(z3,-sklon1),1,(z4,z4t),1.5,(z5,left),1,(z3,-sklon1)]),
1622 | ])
1623 |
1624 | #beginchar("7", 8u#, 14u#, 0);
1625 | # z1=(0.5,14); z2=(6,14); z3=(0,0); z4=(1.5,7); z5=(4.5,7);
1626 | # draw z1--z2--z3;
1627 | # draw z4--z5;
1628 | #endchar;
1629 | z1=(0.5,14); z2=(6,14); z3=(0,0); z4=(1.5,7); z5=(4.5,7);
1630 | add_char("seven", 8, [
1631 | _draw2([(z1,None),None,(z2,None),None,(z3,None)]),
1632 | _draw2([(z4,None),None,(z5,None)]),
1633 | ])
1634 |
1635 | #beginchar("8", 8u#, 14u#, 0);
1636 | # z1=(4,14); z2=(3.2,8); z3=(2,0);
1637 | # draw z1{left}..z2..z3{left}..z2..{left}z1;
1638 | #endchar;
1639 | z1=(4,14); z2=(3.2,8); z3=(2,0);
1640 | z2t=dir_(-57.8); z2t2=dir_(-326)
1641 | add_char("eight", 8, [
1642 | _draw2([(z1,left),1,(z2,z2t),1,(z3,left),1,(z2,z2t2),1,(z1,left)]),
1643 | ])
1644 |
1645 | #beginchar("9", 8u#, 14u#, 0);
1646 | # z0=(2,13); z1=(6,14); z2=(1,7); z3=(2.5,0);
1647 | # z1p=(4,13.9);
1648 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
1649 | # z2{right}..tension1.2..{-sklon1}z1{sklon1}..z3{sklon1};
1650 | #endchar;
1651 | z0=(2,13); z1=(6,14); z2=(1,7); z3=(2.5,0);
1652 | z1p=(4,13.9);z1pt=dir_(-168)
1653 | add_char("nine", 8, [
1654 | _draw2([(z1,left),1,(z1p,z1pt),1,(z0,-sklon2),1.5,
1655 | (z2,right),1.2,(-sklon1,z1,sklon1),1,(z3,sklon1)]),
1656 | ])
1657 |
1658 | #beginchar("0", 8u#, 14u#, 0);
1659 | # z1=(4,14); z3=(1,0);
1660 | # draw z1{left}..tension2.9..z3{right}..tension2.9..{left}z1;
1661 | #endchar;
1662 | z1=(4,14); z3=(1,0);
1663 | add_char("zero", 8, [
1664 | _draw2([(z1,left),2.9,(z3,right),2.9,(z1,left)]),
1665 | ])
1666 |
1667 | ################################################################################
1668 | # Others
1669 |
1670 | # .notdef
1671 | z1=(0.5,14); z2=(15,14); z3=(15,0); z4=(0.5,0);
1672 | add_char("_notdef", 15, [
1673 | _draw2([(z1,None),None,(z2,None),None,(z3,None),None,(z4,None),None,
1674 | (z1,None)]),
1675 | _draw2([(z1,None),None,(z3,None)]),
1676 | _draw2([(z2,None),None,(z4,None)]),
1677 | ])
1678 |
1679 | # space
1680 | add_char("space", 115/40, [])
1681 |
1682 | # subs_token
1683 | add_char("subs_token", 10/40, [])
1684 |
1685 | #beginchar("+", 8u#, 9u#, 0);
1686 | # z1=(1,7); z2=(6,7); z3=(3.3,4.5); z4=(3.7,9.5);
1687 | # draw z1--z2;
1688 | # draw z3--z4;
1689 | #endchar;
1690 | z1=(1,7); z2=(6,7); z3=(3.3,4.5); z4=(3.7,9.5);
1691 | add_char("plus", 8, [
1692 | _draw2([(z1,None),None,(z2,None)]),
1693 | _draw2([(z3,None),None,(z4,None)]),
1694 | ])
1695 |
1696 | #beginchar(minus, 8u#, 7u#, 0);
1697 | # z1=(1,7); z2=(6,7);
1698 | # draw z1--z2;
1699 | #endchar;
1700 | z1=(1,7); z2=(6,7);
1701 | add_char("minus", 8, [
1702 | _draw2([(z1,None),None,(z2,None)]),
1703 | ])
1704 |
1705 | #beginchar(times, 8u#, 9u#, 0);
1706 | # z1=(1.7,9); z2=(5.7,9); z3=(1.3,5); z4=(5.3,5);
1707 | # draw z1--z4;
1708 | # draw z2--z3;
1709 | #endchar;
1710 | z1=(1.7,9); z2=(5.7,9); z3=(1.3,5); z4=(5.3,5);
1711 | add_char("multiply", 8, [
1712 | _draw2([(z1,None),None,(z4,None)]),
1713 | _draw2([(z2,None),None,(z3,None)]),
1714 | ])
1715 |
1716 | #beginchar("*", 8u#, 9u#, 0);
1717 | # z1=(1.7,10); z2=(5.7,10); z3=(1.3,4); z4=(5.3,4);
1718 | # draw z1--z4;
1719 | # draw z2--z3;
1720 | # draw (0,7)--(7,7);
1721 | #endchar;
1722 | z1=(1.7,10); z2=(5.7,10); z3=(1.3,4); z4=(5.3,4);
1723 | add_char("asterisk", 8, [
1724 | _draw2([(z1,None),None,(z4,None)]),
1725 | _draw2([(z2,None),None,(z3,None)]),
1726 | _draw2([((0,7),None),None,((7,7),None)]),
1727 | ])
1728 |
1729 | #beginchar("=", 8u#, 9u#, 0);
1730 | # z1=(1,6); z2=(6,6); z3=(1.2,8); z4=(6.2,8);
1731 | # draw z1--z2;
1732 | # draw z3--z4;
1733 | #endchar;
1734 | z1=(1,6); z2=(6,6); z3=(1.2,8); z4=(6.2,8);
1735 | add_char("equal", 8, [
1736 | _draw2([(z1,None),None,(z2,None)]),
1737 | _draw2([(z3,None),None,(z4,None)]),
1738 | ])
1739 |
1740 | #beginchar(slash, 8u#, 14u#, 0);
1741 | # z1=(0,0); z2=(9,14);
1742 | # draw z1--z2;
1743 | #endchar;
1744 | z1=(0,0); z2=(9,14);
1745 | add_char("slash", 8, [
1746 | _draw2([(z1,None),None,(z2,None)]),
1747 | ])
1748 |
1749 | #beginchar(backslash, 6u#, 14u#, 0);
1750 | # z1=(0,14); z2=(6,0);
1751 | # draw z1--z2;
1752 | #endchar;
1753 | z1=(0,14); z2=(6,0);
1754 | add_char("backslash", 6, [
1755 | _draw2([(z1,None),None,(z2,None)]),
1756 | ])
1757 |
1758 | #beginchar("<", 8u#, 14u#, 0);
1759 | # z1=(1,7); z2=(7,10); z3=(6,4);
1760 | # draw z3--z1--z2;
1761 | #endchar;
1762 | z1=(1,7); z2=(7,10); z3=(6,4);
1763 | add_char("less", 8, [
1764 | _draw2([(z3,None),None,(z1,None),None,(z2,None)]),
1765 | ])
1766 |
1767 | #beginchar(">", 8u#, 14u#, 0);
1768 | # z1=(7,7); z2=(2,10); z3=(1,4);
1769 | # draw z3--z1--z2;
1770 | #endchar;
1771 | z1=(7,7); z2=(2,10); z3=(1,4);
1772 | add_char("greater", 8, [
1773 | _draw2([(z3,None),None,(z1,None),None,(z2,None)]),
1774 | ])
1775 |
1776 | #beginchar("@", 9u#, 9u#, 2u#);
1777 | # z0=(4,6); z1=(7,7); z2=(3,0); z3=(5.4,1);
1778 | # z1p=(5.5,6.9);
1779 | # z4=(6,0); z5=(9,4); z6=(7,9); z7=(1,0); z8=(7,-1);
1780 | # draw z1{left}..z1p..z0{-sklon2}..tension1.5..
1781 | # z2{right}..tension1.2..{-sklon1}z1{sklon1}..z3{sklon1}..
1782 | # z4{right}..z5..z6..z7{dir-60}..z8;
1783 | #endchar;
1784 | z0=(4,6); z1=(7,7); z2=(3,0); z3=(5.4,1);
1785 | z1p=(5.5,6.9);
1786 | z4=(6,0); z5=(9,4); z6=(7,9); z7=(1,0); z8=(7,-1);
1787 | z1pt=(-4,-1); z5t=dir_(-285); z6t=dir_(-190); z8t=(1,1)
1788 | add_char("at", 9, [
1789 | _draw2([(z1,left),1,(z1p,z1pt),1,(z0,-sklon2),1.5,
1790 | (z2,right),1.2,(-sklon1,z1,sklon1),1,(z3,sklon1),1,
1791 | (z4,right),1,(z5,z5t),1,(z6,z6t),1,(z7,dir_(-60)),1,(z8,z8t)]),
1792 | ])
1793 |
1794 | #beginchar("(", 8u#, 16u#, 2u#);
1795 | # z1=(7,16); z2=(2,7); z3=(5,-2);
1796 | # draw z1..z2..z3;
1797 | #endchar;
1798 | z1=(7,16); z2=(2,7); z3=(5,-2);
1799 | z1t=(-1,-1); z2t=(0,-1); z3t=(1,-1)
1800 | add_char("parenleft", 8, [
1801 | _draw2([(z1,z1t),1,(z2,z2t),1,(z3,z3t)]),
1802 | ])
1803 |
1804 | #beginchar(")", 8u#, 16u#, 2u#);
1805 | # z1=(3,16); z2=(6,7); z3=(1,-2);
1806 | # draw z1..z2..z3;
1807 | #endchar;
1808 | z1=(3,16); z2=(6,7); z3=(1,-2);
1809 | z1t=(1,-1); z2t=(0,-1); z3t=(-1,-1)
1810 | add_char("parenright", 8, [
1811 | _draw2([(z1,z1t),1,(z2,z2t),1,(z3,z3t)]),
1812 | ])
1813 |
1814 | #beginchar("[", 8u#, 14u#, 2u#);
1815 | # z1=(7,14); z1a=(4,14); z2a=(2,0); z2=(5,0);
1816 | # draw z1--z1a--z2a--z2;
1817 | #endchar;
1818 | z1=(7,14); z1a=(4,14); z2a=(2,0); z2=(5,0);
1819 | add_char("bracketleft", 8, [
1820 | _draw2([(z1,None),None,(z1a,None),None,(z2a,None),None,(z2,None)]),
1821 | ])
1822 |
1823 | #beginchar("]", 8u#, 14u#, 2u#);
1824 | # z1=(6,14); z1a=(3,14); z2a=(1,0); z2=(4,0);
1825 | # draw z1a--z1--z2--z2a;
1826 | #endchar;
1827 | z1=(6,14); z1a=(3,14); z2a=(1,0); z2=(4,0);
1828 | add_char("bracketright", 8, [
1829 | _draw2([(z1a,None),None,(z1,None),None,(z2,None),None,(z2a,None)]),
1830 | ])
1831 |
1832 | #beginchar("{", 8u#, 14u#, 0);
1833 | # z1=(7,14); z7=(5.5,0); z1a=(5,14); z2a=(3,0);
1834 | # z2-z1a = whatever*(z2a-z1a); y2=12;
1835 | # z3-z1a = whatever*(z2a-z1a); y3=9;
1836 | # z4 = (2,7);
1837 | # z5-z1a = whatever*(z2a-z1a); y5=5;
1838 | # z6-z1a = whatever*(z2a-z1a); y6=2;
1839 | # draw z1{left}..z2..z3..z4&z4..z5..z6..{right}z7;
1840 | #endchar;
1841 | z1=(7,14); z7=(5.5,0); z1a=(5,14); z2a=(3,0);
1842 | z2 = whatever_y(z1a, array(z2a)-array(z1a), 12)
1843 | z3 = whatever_y(z1a, array(z2a)-array(z1a), 9)
1844 | z4 = (2,7);
1845 | z5 = whatever_y(z1a, array(z2a)-array(z1a), 5)
1846 | z6 = whatever_y(z1a, array(z2a)-array(z1a), 2)
1847 | z2t=sklon1;z3t=sklon1;z5t=sklon1;z6t=sklon1
1848 | add_char("braceleft", 8, [
1849 | _draw2([(z1,left),1,(z2,z2t),1,(z3,z3t),1,(z4,left)]),
1850 | _draw2([(z4,right),1,(z5,z5t),1,(z6,z6t),1,(z7,right)]),
1851 | ])
1852 |
1853 | #beginchar("}", 8u#, 14u#, 0);
1854 | # z1=(2.5,14); z7=(1,0); z1a=(5,14); z2a=(3,0);
1855 | # z2-z1a = whatever*(z2a-z1a); y2=12;
1856 | # z3-z1a = whatever*(z2a-z1a); y3=9;
1857 | # z4 = (7,7);
1858 | # z5-z1a = whatever*(z2a-z1a); y5=5;
1859 | # z6-z1a = whatever*(z2a-z1a); y6=2;
1860 | # draw z1{right}..z2..z3..z4&z4..z5..z6..{left}z7;
1861 | #endchar;
1862 | z1=(2.5,14); z7=(1,0); z1a=(5,14); z2a=(3,0);
1863 | z2 = whatever_y(z1a, array(z2a)-array(z1a), 12)
1864 | z3 = whatever_y(z1a, array(z2a)-array(z1a), 9)
1865 | z4 = (7,7);
1866 | z5 = whatever_y(z1a, array(z2a)-array(z1a), 5)
1867 | z6 = whatever_y(z1a, array(z2a)-array(z1a), 2)
1868 | z2t=sklon1;z3t=sklon1;z5t=sklon1;z6t=sklon1
1869 | add_char("braceright", 8, [
1870 | _draw2([(z1,right),1,(z2,z2t),1,(z3,z3t),1,(z4,right)]),
1871 | _draw2([(z4,left),1,(z5,z5t),1,(z6,z6t),1,(z7,left)]),
1872 | ])
1873 |
1874 | #beginchar(percent, 10u#, 14u#, 0);
1875 | # z1=(0,0); z2=(9,14); z3=(3,14); z4=(2,9);
1876 | # draw z1--z2;
1877 | # draw z3..tension2..z4..tension2..cycle;
1878 | # draw (z3..tension2..z4..tension2..cycle) shifted (4,-y4);
1879 | #endchar;
1880 | z1=(0,0); z2=(9,14); z3=(3,14); z4=(2,9);
1881 | add_char("percent", 10, [
1882 | _draw2([(z1,None),None,(z2,None)]),
1883 | _draw2([(z3,right),2,(z4,left),2,(z3,right)]),
1884 | shift(_draw2([(z3,right),2,(z4,left),2,(z3,right)]), (4,-z4[1])),
1885 | ])
1886 |
1887 | #beginchar(promile, 13u#, 14u#, 0);
1888 | # z1=(0,0); z2=(9,14); z3=(3,14); z4=(2,9);
1889 | # draw z1--z2;
1890 | # draw z3..tension2..z4..tension2..cycle;
1891 | # draw (z3..tension2..z4..tension2..cycle) shifted (4,-y4);
1892 | # draw (z3..tension2..z4..tension2..cycle) shifted (8,-y4);
1893 | #endchar;
1894 | z1=(0,0); z2=(9,14); z3=(3,14); z4=(2,9);
1895 | add_char("perthousand", 13, [
1896 | _draw2([(z1,None),None,(z2,None)]),
1897 | _draw2([(z3,right),2,(z4,left),2,(z3,right)]),
1898 | shift(_draw2([(z3,right),2,(z4,left),2,(z3,right)]), (4,-z4[1])),
1899 | shift(_draw2([(z3,right),2,(z4,left),2,(z3,right)]), (8,-z4[1])),
1900 | ])
1901 |
1902 | #beginchar("&", 7u#, 11u#, 0);
1903 | # z1=(5,0); z2=(3,7); z3=(4,11); z4=(0,1.5); z5=(1,0); z6=(7,7);
1904 | # draw z1..z2..z3{right}..z2..tension2..z4{sklon1}..z5{right}..tension2..
1905 | # {sklon2}z6;
1906 | #endchar;
1907 | z1=(5,0); z2=(3,7); z3=(4,11); z4=(0,1.5); z5=(1,0); z6=(7,7);
1908 | z1t=dir_(-253); z2t=dir_(-254); z2t2=dir_(-120);
1909 | add_char("ampersand", 7, [
1910 | _draw2([(z1,z1t),1,(z2,z2t),1,(z3,right),1,(z2,z2t2),2,(z4,sklon1),1,
1911 | (z5,right),2,(z6,sklon2)]),
1912 | ])
1913 |
1914 | #beginchar("$", 8u#, 15u#, 1u#);
1915 | # z1=(8,10.5); z2=(4.5,14); z2a=(1,10.5);
1916 | # z3=(4,7);
1917 | # z4=(3.5,0); z4a=(7,3.5); z5=(0,3.5);
1918 | # draw z1..z2{left}..z2a..z3..z4a..z4{left}..z5;
1919 | # draw (2.5,-1)--(3.5,15);
1920 | # draw (4.5,-1)--(5.5,15);
1921 | #endchar;
1922 | z1=(8,10.5); z2=(4.5,14); z2a=(1,10.5);
1923 | z3=(4,7);
1924 | z4=(3.5,0); z4a=(7,3.5); z5=(0,3.5);
1925 | z1t=(0,1); z2at=(0,-1); z3t=dir_(-30); z4at=(0,-1); z5t=(0,1)
1926 | add_char("dollar", 8, [
1927 | _draw2([(z1,z1t),1,(z2,left),1,(z2a,z2at),1,(z3,z3t),1,(z4a,z4at),1,
1928 | (z4,left),1,(z5,z5t)]),
1929 | _draw2([((2.5,-1),None),None,((3.5,15),None)]),
1930 | _draw2([((4.5,-1),None),None,((5.5,15),None)]),
1931 | ])
1932 |
1933 | #beginchar("#", 11.5u#, 14u#, 0);
1934 | # z1=(0,0); z2=(4,14); z3=(10.5,0);
1935 | # draw (z1--z2) shifted (2,0);
1936 | # draw (z1--z2) shifted (6,0);
1937 | # draw (z1--z3) shifted (.5,5);
1938 | # draw (z1--z3) shifted (1.3,9);
1939 | #endchar;
1940 | z1=(0,0); z2=(4,14); z3=(10.5,0);
1941 | add_char("numbersign", 11.5, [
1942 | shift(_draw2([(z1,None),None,(z2,None)]), (2,0)),
1943 | shift(_draw2([(z1,None),None,(z2,None)]), (6,0)),
1944 | shift(_draw2([(z1,None),None,(z3,None)]), (0.5,5)),
1945 | shift(_draw2([(z1,None),None,(z3,None)]), (1.3,9)),
1946 | ])
1947 |
1948 | #beginchar("|", 2u#, 14u#, 0);
1949 | # z1=(0,0); z2=(2,14);
1950 | # draw (z1--z2)
1951 | #endchar;
1952 | z1=(0,0); z2=(2,14);
1953 | add_char("bar", 2, [
1954 | _draw2([(z1,None),None,(z2,None)]),
1955 | ])
1956 |
1957 | #beginchar("~", 8u#, 9u#, 0);
1958 | # z1=(0,6); z2=(3,8); z3=(5,6); z4=(8,8);
1959 | # draw z1..z2..z3..z4;
1960 | #endchar;
1961 | z1=(0,6); z2=(3,8); z3=(5,6); z4=(8,8);
1962 | z1t=(0,1); z2t=dir_(-27); z3t=dir_(-27); z4t=(0,1);
1963 | add_char("asciitilde", 8, [
1964 | _draw2([(z1,z1t),1,(z2,z2t),1,(z3,z3t),1,(z4,z4t)]),
1965 | ])
1966 |
1967 | #beginchar(inch, 4u#, 15u#, 0);
1968 | # draw (1.8,15)--(1.5,12);
1969 | # draw (3.8,15)--(3.5,12);
1970 | #endchar;
1971 | add_char("quotedbl.sc", 4, [
1972 | _draw2([((1.8,15),None),None,((1.5,12),None)]),
1973 | _draw2([((3.8,15),None),None,((3.5,12),None)]),
1974 | ])
1975 |
1976 | #beginchar("^", 6u#, 14u#, 0);
1977 | # draw (2,12)--(4,14)--(6,12);
1978 | #endchar;
1979 | add_char("asciicircum", 6, [
1980 | _draw2([((2,12),None),None,((4,14),None),None,((6,12),None)]),
1981 | ])
1982 |
1983 | #beginchar("_", 8u#, 0, 7u#);
1984 | # draw (0,-7)--(8,-7);
1985 | #endchar;
1986 | add_char("underscore", 8, [
1987 | _draw2([((0,-7),None),None,((8,-7),None)]),
1988 | ])
1989 |
1990 |
1991 |
1992 | ################################################################################
1993 | # Punctuation
1994 |
1995 | #beginchar("-", 3u#, 7u#, 0);
1996 | # draw (0,4)--(3,4);
1997 | #endchar;
1998 | add_char("hyphen", 3, [
1999 | _draw2([((0,4),None),None,((3,4),None)]),
2000 | ])
2001 |
2002 | #beginchar(dash, 12u#, 7u#, 0);
2003 | # z1=(1,7); z2=(10,7);
2004 | # draw z1--z2;
2005 | #endchar;
2006 | # TODO: the font has emdash, twoemdash, threeemdash, endash, but none
2007 | # of them seem to work; but latex puts two and three hyphens instead.
2008 | # We generate the `letter_dash.svg`, but we do not copy it into glyphs.
2009 | add_char("dash", 12, [
2010 | _draw2([((1,7),None),None,((10,7),None)]),
2011 | ])
2012 |
2013 | #beginchar("!", 6u#, 14u#, 0);
2014 | # pickup pencircle scaled (dotkoef*thin);
2015 | # drawdot (2,0);
2016 | # pickup pencircle scaled thin;
2017 | # draw (2.6, 4)..(5,14);
2018 | #endchar;
2019 | add_char("exclam", 12, [
2020 | shift(dot, (2,0)),
2021 | _draw2([((2.6,4),None),None,((5,14),None)]),
2022 | ])
2023 |
2024 | #beginchar("?", 8u#, 14u#, 0);
2025 | # pickup pencircle scaled (dotkoef*thin);
2026 | # drawdot (4,0);
2027 | # pickup pencircle scaled thin;
2028 | # z1=(3,12); z2=(6,14); z3=(5,8.5); z4=(4.5,3); z5=(7,5);
2029 | # draw z1..z2{right}..z3..z4{right}..z5;
2030 | #endchar;
2031 | z1=(3,12); z2=(6,14); z3=(5,8.5); z4=(4.5,3); z5=(7,5);
2032 | z1t=up; z3t=(-1,-1); z5t=up
2033 | add_char("question", 8, [
2034 | shift(dot, (4,0)),
2035 | _draw2([(z1,z1t),1,(z2,right),1,(z3,z3t),1,(z4,right),1,(z5,z5t)]),
2036 | ])
2037 |
2038 | #beginchar(",", 3u#, 1u#, 0);
2039 | # draw (0,1)--(-1,-2);
2040 | #endchar;
2041 | add_char("comma", 3, [
2042 | _draw2([((0,1),None),None,((-1,-2),None)]),
2043 | ])
2044 |
2045 | #beginchar(".", 3u#, 1u#, 0);
2046 | # pickup pencircle scaled (dotkoef*thin);
2047 | # drawdot (0,0);
2048 | # pickup pencircle scaled thin;
2049 | #endchar;
2050 | add_char("period", 3, [
2051 | shift(dot, (0,0)),
2052 | ])
2053 |
2054 | #beginchar(":", 4u#, 7u#, 0);
2055 | # pickup pencircle scaled (dotkoef*thin);
2056 | # drawdot (1,0); drawdot (2,7);
2057 | # pickup pencircle scaled thin;
2058 | #endchar;
2059 | add_char("colon", 4, [
2060 | shift(dot, (1,0)),
2061 | shift(dot, (2,7)),
2062 | ])
2063 |
2064 | #beginchar(";", 4u#, 7u#, 0);
2065 | # pickup pencircle scaled (dotkoef*thin);
2066 | # drawdot (2,7);
2067 | # pickup pencircle scaled thin;
2068 | # draw (1,1)--(0,-2);
2069 | #endchar;
2070 | add_char("semicolon", 4, [
2071 | shift(dot, (2,7)),
2072 | _draw2([((1,1),None),None,((0,-2),None)]),
2073 | ])
2074 |
2075 | #beginchar(clqq, 4u#, 1u#, 0);
2076 | # draw (0,1)--(-1,-2);
2077 | # draw (2,1)--(1,-2);
2078 | #endchar;
2079 | add_char("quotedblbase", 4, [
2080 | _draw2([((0,1),None),None,((-1,-2),None)]),
2081 | _draw2([((2,1),None),None,((1,-2),None)]),
2082 | ])
2083 |
2084 | #beginchar(crqq, 4u#, 15u#, 0);
2085 | # draw (2,15)--(1.5,12);
2086 | # draw (4,15)--(3.5,12);
2087 | #endchar;
2088 | add_char("quotedblright", 4, [
2089 | _draw2([((2,15),None),None,((1.5,12),None)]),
2090 | _draw2([((4,15),None),None,((3.5,12),None)]),
2091 | ])
2092 | add_char("quotedblleft", 4, [
2093 | _draw2([((2,15),None),None,((1.5,12),None)]),
2094 | _draw2([((4,15),None),None,((3.5,12),None)]),
2095 | ])
2096 | add_char("quotedbl", 4, [
2097 | _draw2([((2,15),None),None,((1.5,12),None)]),
2098 | _draw2([((4,15),None),None,((3.5,12),None)]),
2099 | ])
2100 |
2101 | #beginchar(leftquota, 4u#, 15u#, 0);
2102 | # draw (0,15){down}..(1,12);
2103 | #endchar;
2104 | add_char("quoteleft", 4, [
2105 | _draw2([((0,15),down),1,((1,12),(1,-1))]),
2106 | ])
2107 |
2108 | #beginchar(rightquota, 4u#, 15u#, 0);
2109 | # draw (4,15){down}..(2,12);
2110 | #endchar;
2111 | add_char("quoteright", 4, [
2112 | _draw2([((4,15),down),1,((2,12),(-1,-1))]),
2113 | ])
2114 | add_char("quotesingle", 4, [
2115 | _draw2([((4,15),down),1,((2,12),(-1,-1))]),
2116 | ])
2117 |
2118 |
2119 |
2120 | ################################################################################
2121 |
2122 | # Save
2123 |
2124 | unicode = {
2125 | "space": ["uni0020", "uni00A0"],
2126 | "asciitilde": ["uni007E", "uni223C"],
2127 | "hyphen": ["uni002D", "uni00AD", "uni2010", "uni2011"],
2128 | "quoteleft": ["uni2018"],
2129 | "quoteright": ["uni2019"],
2130 | }
2131 |
2132 | glyphs = [
2133 | ".notdef",
2134 | "space",
2135 |
2136 | "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
2137 | "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
2138 |
2139 | "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
2140 | "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
2141 |
2142 | "Aacute", "Adieresis", "Ccaron", "Dcaron", "Eacute", "Ecaron", "Iacute",
2143 | "Lacute", "Lcaron", "Ncaron", "Oacute", "Ocircumflex", "Racute", "Rcaron",
2144 | "Scaron", "Tcaron", "Uacute", "Uring", "Yacute", "Zcaron",
2145 |
2146 | "aacute", "adieresis", "ccaron", "dcaron", "eacute", "ecaron", "iacute",
2147 | "lacute", "lcaron", "ncaron", "oacute", "ocircumflex", "racute", "rcaron",
2148 | "scaron", "tcaron", "uacute", "uring", "yacute", "zcaron",
2149 |
2150 | "ampersand",
2151 |
2152 | "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
2153 | "nine",
2154 |
2155 | "period", "comma", "colon", "semicolon", "exclam", "question",
2156 | "quotesingle", "quotedbl", "quoteleft", "quoteright", "quotedblleft",
2157 | "quotedblright", "quotedblbase", "hyphen",
2158 |
2159 | "underscore", "parenleft", "parenright", "bracketleft", "bracketright",
2160 | "braceleft", "braceright", "slash", "bar", "backslash", "asterisk", "at",
2161 | "numbersign",
2162 |
2163 | "quotedbl.sc",
2164 |
2165 | "dollar",
2166 |
2167 | "percent", "perthousand",
2168 |
2169 | "plus", "minus", "multiply", "equal", "less", "greater", "asciicircum",
2170 | "asciitilde",
2171 |
2172 |
2173 | # Our specific glyphs, not in unicode:
2174 |
2175 | # Connecting curves
2176 | "begin", "begin_straight", "begin_x", "conn_s", "conn_sv", "conn_P", "end",
2177 | # Alternative versions
2178 | "sleft", "sdepth", "scaronleft", "scarondepth", "bnarrow", "onarrow",
2179 | "oacutenarrow", "ocircumflexnarrow", "vnarrow", "wnarrow",
2180 | # Helper token for OTF glyph substitution
2181 | "subs_token",
2182 | ]
2183 |
2184 | def fix_name(x):
2185 | """
2186 | Take AGL name and create a filename that works on case insensitive
2187 | filesystems (macOS).
2188 | """
2189 | if x[0] >= "A" and x[0] <= "Z":
2190 | x = x[0] + "_" + x[1:]
2191 | if x[0] == ".":
2192 | x = "_" + x[1:]
2193 | return x
2194 |
2195 | letters = [fix_name(x) for x in glyphs]
2196 |
2197 | current_dir = os.path.dirname(os.path.abspath(__file__))
2198 | glyphs_dir = "../font.ufo/glyphs"
2199 | run(f"mkdir -p {glyphs_dir}")
2200 | s = ""
2201 | for letter in letters:
2202 | s += f"file-open:letter_{letter}.svg; select-by-id: path0; object-stroke-to-path; export-type:svg; export-do\n"
2203 | open("commands.txt", "w").write(s)
2204 | run("inkscape --shell < commands.txt")
2205 | for letter in letters:
2206 | run(f"python svg2glif.py letter_{letter}_out.svg")
2207 | run(f"cp letter_{letter}_out_out3.glif {glyphs_dir}/{letter}.glif")
2208 |
2209 | s = """\
2210 |
2211 |
2212 |
2213 | \t
2214 | """
2215 | for name in glyphs:
2216 | filename = fix_name(name) + ".glif"
2217 | s += f"\t\t{name}\n"
2218 | s += f"\t\t{filename}\n"
2219 | s += """\
2220 | \t
2221 |
2222 | """
2223 | open(f"{glyphs_dir}/contents.plist", "w").write(s)
2224 |
2225 | s = """\
2226 |
2227 |
2228 |
2229 | \t
2230 | \t\tpublic.glyphOrder
2231 | \t\t
2232 | """
2233 | for name in glyphs:
2234 | s += f"\t\t\t{name}\n"
2235 | s += """\
2236 | \t\t
2237 | \t
2238 |
2239 | """
2240 | open(f"{glyphs_dir}/../lib.plist", "w").write(s)
2241 |
2242 | s = ""
2243 | for name in glyphs:
2244 | s += f"{name}\t{name}"
2245 | if name in unicode:
2246 | s += "\t" + ",".join(unicode[name])
2247 | s += "\n"
2248 | open(f"{glyphs_dir}/../../GlyphOrderAndAliasDB", "w").write(s)
2249 |
--------------------------------------------------------------------------------