README.md 7.73 KB
Newer Older
1
2
FONS
====
3
4
5
6
7
8
9
10
11
12
13
14
15
16

A recipe to make fonts out of bitmap images.


A little bit of history
-----------------------

In 2011, Pierre Marchand made with his own hands, in the laboratory of OSP, a creature called Fonzie. 
Besides being cool, Fonzie was able to make a typeface out of scanned letters.
In his childhood, Fonzie asked for letters to behave well and to organize themselves. 
They had to not hold hands and ordered themselves by the order of the Unicode.
The [Univers Else](http://osp.kitchen/foundry/universelse/) family was born.
In his teenage years, in 2013, Fonzie got more and more experienced. 
He could decipher letters from a scanned page of a book by using OCR (Optical Character Recognition).
svilayphiou's avatar
svilayphiou committed
17
18
Fonzie could then read nice stories. But Fonzie is so cool that he’s going even further.
With all those *a*’s or all those *z*’s, he was drawing an average shape of all those instances of letters.
19
20
Fonzie collaborated with [ScanBot](https://hackerspace.be/ScanBot), a coarse book scanner, 
product of the Dr. Michael Korntheuer, which could suck the pages with a vacuum cleaner to read the next page.
svilayphiou's avatar
svilayphiou committed
21
22
But ScanBot couldn’t make it through the winter, and Fonzie kind of got stuck in his sweet sixteen 
and didn’t follow the new trends in the libraries of code. Today, it is rare to see Fonzie around; 
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
nor Pierre Marchand whose new lazy landscape is made in [waend](http://waend.com/).

Fons is the spiritual son of Fonzie. He does not have much ambition (like to read novels and such). 
He just wants to learn the alphabet, to be able to recognize the letters when we point at them.
He got [GlyphTracer 1.3](https://launchpad.net/glyphtracer) of Jussi Pakkanen, as a master. 
GlyphTracer shouts glyphs and we would point at the letters on a scanned page. 
When done, he autotraces in the command line limbo and generates a nicely wrapped .sfd font. 
GlyphTracer went a step ahead and now autotraces the font with the Fontforge toolbox so that we keep
the history of the scan with the glyphs.

But Fons knew this was not enough. He has a good eye! 
If you feed him with an unripe scan, GlyphTracer would give you marshmallow. 
Fons then got trained by Pierre Huyghebaert, the bitmap master, and took good note. 
This is the recipe that you have in your screen.





42

43
44
45
46
Tools needed
------------
- Gimp
- Autotrace
svilayphiou's avatar
svilayphiou committed
47
- python-fontforge
48
- Fontforge with Autotrace
49
- GlyphTracer (included with this package)
50
51
52



53
54
Preparing the image
-------------------
55
56


svilayphiou's avatar
svilayphiou committed
57
### Get a bitmap image of characters (crop unnecessary white parts for a faster process, you can use Gimp’s automatic crop for that).
58

59
<div>
svilayphiou's avatar
svilayphiou committed
60
    <figure style="float: left; margin: 0.5em; width: 45%;">
61
62
63
        <img src="http://osp.kitchen/api/osp.tools.fons/raw/input/scan_bitmap.jpg" />
        <footer>A scan in bitmap</footer>
    </figure>
svilayphiou's avatar
svilayphiou committed
64

svilayphiou's avatar
svilayphiou committed
65
    <figure style="float: left; margin: 0.5em; width: 45%;">
66
67
68
        <img src="http://osp.kitchen/api/osp.tools.fons/raw/input/scan_gray_1200dpi.jpg" />
        <footer>A scan in gray levels</footer>
    </figure>
svilayphiou's avatar
svilayphiou committed
69
70
    <span style="clear: both;"></span>
</div>
71

svilayphiou's avatar
svilayphiou committed
72
<figure>
svilayphiou's avatar
svilayphiou committed
73
74
75
    <img src="http://osp.kitchen/api/osp.tools.fons/raw/input/characters-table.png" />
    <footer>A rasterized font: to typeset it, you can use the template `characters-table.svg` in the `/input/` folder</footer>
</figure>
76
77
78



79
### Levels (have a white background, black characters but still shades of gray)
80

81
![](http://osp.kitchen/api/osp.tools.fons/raw/documentation/01-bitmap_levels.png)
82
83
84



85
### Small boost 
86

svilayphiou's avatar
svilayphiou committed
87
Scale up the image to something like 254% with the “Sinc (Lanczos 3)” algorithm. We choose on purpose a non-round number of scaling to break the bitmap patterns.
88

89
![](http://osp.kitchen/api/osp.tools.fons/raw/documentation/02-scale-254percent.png)
90
91
92



svilayphiou's avatar
svilayphiou committed
93
### Sharpen with “Unsharp mask”
94

svilayphiou's avatar
svilayphiou committed
95
Put the amount to the maximum and then search for the point where you don’t see 
96

97
<div>
svilayphiou's avatar
svilayphiou committed
98
    <figure style="float: left; margin: 0.5em; width: 30%;">
99
100
101
        <img src="http://osp.kitchen/api/osp.tools.fons/raw/documentation/03-sharpen-too_few.png" />
        <footer>Radius too small</footer>
    </figure>
102

svilayphiou's avatar
svilayphiou committed
103
    <figure style="float: left; margin: 0.5em; width: 30%;">
104
105
106
        <img src="http://osp.kitchen/api/osp.tools.fons/raw/documentation/03-sharpen-ok.png" />
        <footer>OK</footer>
    </figure>
107

svilayphiou's avatar
svilayphiou committed
108
    <figure style="float: left; margin: 0.5em; width: 30%;">
109
110
111
112
113
        <img src="http://osp.kitchen/api/osp.tools.fons/raw/documentation/03-sharpen-too_much.png" />
            <footer>Radius too big</footer>
    </figure>
    <span style="clear: both;"></span>
</div>
114
115
116



117
### Big boost
118

119
Scale up to 403%.
120

121
![](http://osp.kitchen/api/osp.tools.fons/raw/documentation/04-big_boost.png)
122
123
124



125
### Threshold
svilayphiou's avatar
svilayphiou committed
126

127

128
<div>
svilayphiou's avatar
svilayphiou committed
129
    <figure style="float: left; margin: 0.5em; width: 45%;">
svilayphiou's avatar
svilayphiou committed
130
        <img src="http://osp.kitchen/api/osp.tools.fons/raw/documentation/05-threshold-bad.png" />
131
132
        <footer>Bad</footer>
    </figure>
svilayphiou's avatar
svilayphiou committed
133
    <figure style="float: left; margin: 0.5em; width: 45%;">
134
135
136
137
138
        <img src="http://osp.kitchen/api/osp.tools.fons/raw/documentation/05-threshold-ok.png" />
        <footer>OK</footer>
    </figure>
    <span style="clear: both;"></span>
</div>
139

svilayphiou's avatar
svilayphiou committed
140
141


142
### Baseline
143
144
145
146
147
148

When importing a bitmap, Fontforge scales up/down the bitmap so that it fits into the glyph box. If we use GlyphTracer 1.4, this ends up with different scales of glyphs. In order to prevent this, we can put a black rectangle of the height of the maximum ascendant and maximum descendant.

![baseline](http://osp.kitchen/api/osp.tools.fons/raw/documentation/06-baseline.png)


149
150

### Bitmap
151
152
153

- Change the color mode to Indexed mode with 1 black/white bit.
- Save as a .bmp file.
svilayphiou's avatar
svilayphiou committed
154

155

156
157
158
159
160
161




Vectorizing with GlyphTracer
----------------------------
162

svilayphiou's avatar
svilayphiou committed
163
164
165
166
- To launch GlyphTracer, there are two possibilities:
    - from your file manager, double-click on the file `glyphtracer` inside the `glyphtracer-1.4` folder
    - from the terminal, go to the `glyphtracer-1.4` folder and run `./glyphtracer`. This will let you know more output in case of errors.
- Feed in the .bmp image in 1 bit (otherwise it will complain).
167
168
- For each given glyph, click on the letter you want to use.
- Change the characters subset in the bottom left dropdown menu to select more glyphs.
169

170
![glyphtracer](http://osp.kitchen/api/osp.tools.fons/raw/iceberg/glyphtracer.png)
171
172
173



174
175
176
177
178
179
180



Post-production
---------------

### Merging fonts
181
182
183
184
185
186

In case you want to complete an existing font, you can use the script `mergeFonts.py`.

    python mergeFonts.py fonte1.ufo fonte2.ufo ...  fonte17.ufo fonte-out.ufo


187
### Metrics and kernings
188
189
190
191
192

A big part of type design is about managing the white space around the letters (metrics) and exceptions for specific couples of letters (kernings).

- For the metrics, we make an auto-spacing while generating the .sfd file with GlyphTracer.
- For the kernings, you can try the tool (Kernagic)[https://github.com/hodefoting/kernagic].
193

194
But if you want to get back metric and kerning data from an existing font, you can use the script `mergeSpacing.py`. It can be any font format than `.otf`.
svilayphiou's avatar
svilayphiou committed
195

196
   python mergeSpacing.py font.otf original-font.otf spaced-font.otf
svilayphiou's avatar
svilayphiou committed
197
198
199



200
201
202



svilayphiou's avatar
svilayphiou committed
203
Troubleshooting
204
---------------
svilayphiou's avatar
svilayphiou committed
205

206
207
208
### My image is too big to manipulate it.
Split it into several images and generate several .sfd files. Then you can merge the fonts with the script `mergeFonts.py`.

svilayphiou's avatar
svilayphiou committed
209

svilayphiou's avatar
svilayphiou committed
210
### From the terminal, I have the following error:
svilayphiou's avatar
svilayphiou committed
211

svilayphiou's avatar
svilayphiou committed
212
213
    File "./glyphtracer", line 415
        except Exception, e:
svilayphiou's avatar
svilayphiou committed
214
                          ^
svilayphiou's avatar
svilayphiou committed
215
    SyntaxError: invalid syntax
svilayphiou's avatar
svilayphiou committed
216

svilayphiou's avatar
svilayphiou committed
217
This means your fontforge runs with python3, whereas the majority of installs run still with python2. I didn’t find a convenient way yet to maintain both versions at the same time. Let me know and I send you the version for python3 which I use.
218
219
220
221


### I have several shapes overlapping on the same glyph

svilayphiou's avatar
svilayphiou committed
222
This is probably because you generated twice the font. I’m afraid you’d have to close and restart GlyphTracer.
223
224
225