Adapting small bitmap fonts to TTF

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Adapting small bitmap fonts to TTF
by on (#116110)
Yesterday I made SVG versions of all the glyphs in Base Seven, the font seen on the previous page. I did my best to smooth out the glyphs while keeping them faithful to the pixel grid. Then I converted the glyphs to a TTF in FontForge.

The quick brown firefox jumps over
the lazy-ass dog.
THE QUICK BROWN FIREFOX JUMPS OVER
THE LAZY-ASS DOG.
Score: 8675 Time: 3:09 Cash: 142

I even had time to make a few alternate glyphs:

variant character bragging rights yeſterday
vɑriɑnt chɑrɑcter brɑɡɡinɡ riɡhts ɥesterdɑɥ

A ꝼew chɑꞃɑcꞇeꞃs hɑve ɑlꞇeꞃnɑꞇe Gɑelic ꝼoꞃms, which ɑꞃe uꞅeꝼul ꝼoꞃ hiꝺinᵹ ꞇhinᵹs ꝼꞃom Coweꞃinᵹ.

So do any glyphs rub you the wrong way?
Re: community fonts for NES Dev
by on (#116114)
This is very odd. A lot of the requirements for small pixel fonts break many of the standard rules of thumb when blown up to full size.

For example, the top end of the stroke (below the dot) in "i" and "j" don't meet the mean line. All the letters with descenders don't reach the baseline. The lack of an "fi" ligature is unfortunate given the specific shape of f here. The closed two-story "g" without a link is unusual. It feels like ":" shouldn't be a full x-height. None of the curved letters use any overshoot. The strokes in the "v" have less weight than almost all the others.

All of these make perfect sense, given that you're trying to be faithful to the original bitmap font.

As an aside, I personally really dislike one-story "a"s. The alternate "y" is more congruous with how curvy the rest of the font is.
Re: community fonts for NES Dev
by on (#116138)
That lowercase g is so nasty
Re: Adapting small bitmap fonts to TTF
by on (#116153)
Could they be made in METAFONT too?
Re: Adapting small bitmap fonts to TTF
by on (#116159)
I thought of some reasons to make a scalable version of a pixel font:

  1. Making screenshot mockups in a paint program before implementing them in code
  2. Making large text that appears occasionally, such as "Press Start Button" or "How to Play", consistent with the rest of the design
  3. Typesetting the game's manual or promotional materials
  4. Porting a game to a high-definition platform, such as a PC, tablet, retina smartphone, or modern console

So I split it off into a separate topic because if we get the design process for one bitmap-to-outline adaptation on record, others will be able to learn from the compromises and reasons behind them when making their own adaptations.

Now back to Base Seven in particular. I know I need to fix these things:

  • Design fi, fl, ſi, and ſl ligatures and import them to FontForge
  • Add overshoot to bowls
  • Slightly increase weight of 'v'
  • Add a slight curve to the tail of the straight version of 'y'

I haven't got around to designing the ligatures yet, but I've made a rough mock-up of what it might look like with either of two changes made: vertical overshoot by 1/8 pixel (1/40 of x-height) or reducing the thickness of horizontal strokes by 1/4 pixel.
Attachment:
base7_0807_options.png
base7_0807_options.png [ 3.77 KiB | Viewed 6027 times ]


Colons at or very near x-height appear common among other faces that I looked at; I guess I don't really have an eye for that. Could you explain?

The International Phonetic Alphabet assigns different meanings to 2-story 'a' (open front vowel) and 1-story 'ɑ' (open back vowel), and it prefers open 'ɡ' to looptail 'g'. There exist "infant versions" of fonts where 'g', 'a', and 'y' all have the alternate forms, but these don't especially affect children's reading performance.

As for METAFONT: Its model of modeling a glyph as a curve traced with a brush appears to be falling out of favor in favor of describing the outlines.

Get a load of this.
Re: Adapting small bitmap fonts to TTF
by on (#116165)
Sorry, but it doesn't look like the same font at all to me. Probably because a vector font is something very different from a pixel font.
Re: Adapting small bitmap fonts to TTF
by on (#116167)
Hm. It looks what I said about the ":" is my opinion rather than generally-held rule of thumb.
Attachment:
lines.png
lines.png [ 8.18 KiB | Viewed 6016 times ]

So, of fonts that have square dots in the ":", both "top of top dot is at meanline, bottom of bottom dot is at baseline" and "top of top dot is slightly below meanline" are well-represented.

Of fonts that have round dots, it's all over the field:
About an equal number seem to
- aligns the top dot to the meanline and the bottom dot uses a standard overshoot below the baseline.
- try to use the same amount of overshoot on both dots of a colon as any other curvy letter.
- something else significantly different

Many typographers seem to think that round dots should use a standard overshoot. I think I disagree, and prefer a shorter-seeming :.

For some reason, the vector font feels too heavy in comparison to the original bitmap font. I'm not certain why; when I expand the bitmap font to match it looks fine.
I remember reading someone say that fonts in general should become slightly lower weight when larger? (But not as much as TeX's default font)
Re: Adapting small bitmap fonts to TTF
by on (#116179)
I think I know why it got heavier when I vectorized it.

The outline in a TrueType glyph is a quadratic Bézier spline, which consists of alternating[1] "on-curve" and "off-curve" points. The rasterizer draws parabola segments from each on-curve point to the next, with the parabola inscribed in the triangle formed by the two on-curve points and the off-curve point between them. A bit of integral calculus shows that the area of the parabola is exactly two-thirds that of the triangle. So to compute the area within an outline, you need to compute the area inside the polygon formed by the on-curve points, then add the area within the parabolas (or subtract it in a counter).

Here's a simplified glyph drawn as a 4-parabola curve minus a 4-parabola curve. The O marks represent on-curve points, the X's off-curve points. I've drawn one of the triangles in blue.

Attachment:
on and off curve.png
on and off curve.png [ 3.25 KiB | Viewed 6007 times ]


Let's assume that the glyph is 4 units tall. This means the polygon formed by the outer area covers 8 u² and each triangle 2 u². So the area of each parabolic segment is 4/3 u², for a total of 8 + 4 * 4/3 = 40/3 = 13 1/3 u². The counter is half the diameter and thus one-fourth the area, so subtract a fourth of that: 40/3 - (40/3)/4 = 30/3 = 10 u². Now compare this to the bitmap glyph that covers only 8 u². Overshooting the bowl would only increase this discrepancy. A possible mitigation would be to make the counter bigger.

Now a four-segment curve is slightly "fatter" at the corners than a true circle, with a radius varying from 2 units at the top, bottom, and sides to 3√2/2 ≈ 2.12 units at the diagonals. (An eight-segment curve is a nearly perfect fit to a circle.) If the were drawn with circular arcs instead of parabolas, the outer area would be πr² = 4π ≈ 12.57 u², and the total glyph would cover 3π ≈ 9.42 u², still much greater than the bitmap glyph.

In any case, how much is standard overshoot? Doing 1/8 pixel, as I had planned, would produce a 2.5% overshoot.


[1] Technically, they're allowed to not alternate in the font, but the rasterizer acts as if an on-curve point is placed halfway between consecutive off-curve points and vice versa. Two consecutive off-curve points thus form a straight line segment.
Re: Adapting small bitmap fonts to TTF
by on (#116184)
Do the results look the same ("too thick") using cubic splines (e.g. in CFF) instead of quadratic splines? Reference -- I wonder if simply changing the OpenType format would be sufficient.

P.S. -- Bitmap to vector is a major/serious time sink. A friend of mine ""maintains"" (for lack of better term) a TTF version of the UCS 6x13 "fixed" font (part of any X11 installation) which took him almost 3 full months of messing about in FontForge to get working correctly -- and still only works correctly on Windows (will not work on OS X, neither of us are sure why). The intention was to get the absolutely gorgeous font (perfect for terminals) but with Unicode glyph mapping, so that the end result allows for Unicode characters and UTF-8 encoding to work properly. There is a .fon version floating around but UTF-8 breaks horribly if you use that. I really wish native bitmap fonts were still supported in Windows and other mainstream OSes -- rephrased, I wish OpenType would have allowed for pure native bitmap fonts.

Edit: Meant 6x13, not 8x16. (Too many NES/SNES tiles/sprites on the brain!)
Re: Adapting small bitmap fonts to TTF
by on (#116187)
(Tangenting wildly)
<_< 7x13B is still my favorite non-proportional font in the world. The VT 220 and 320 fonts are a close second place, without any fake scanlines
Re: Adapting small bitmap fonts to TTF
by on (#116188)
It's not a question of the kind of spline as much as the type design. I could match the shape of a CFF cubic spline almost exactly by bisecting each segment and using a quadratic segment for each half. I'd bet font editors do the same thing when the user imports an SVG whose paths use cubic or arc segments into a TrueType font. But as I wrote above, a perfect circle would still have more weight than the bitmap circle of the same diameter.

The fundamental issue is that in bitmap fonts, anything that's diagonal tends to be 30% underweight in the first place because it takes n dark pixels to cover a diagonal distance of √2n pixels. Round parts of small bitmap fonts suffer especially because they're made almost entirely out of diagonals.

Attachment:
File comment: Notice the width difference between straight, diagonal, and a curve including diagonals. I took pains to ensure that the curve's weight matched that of the tiny bitmap it was based on.
underweight_diagonal.png
underweight_diagonal.png [ 646 Bytes | Viewed 5993 times ]


One solution would be to declare this the bold and just lose some weight across the board.
Re: Adapting small bitmap fonts to TTF
by on (#116218)
tepples wrote:
As for METAFONT: Its model of modeling a glyph as a curve traced with a brush appears to be falling out of favor in favor of describing the outlines.
METAFONT can do outlines too, not only brushes. By defining macros, it could probably even do hinting and other things to compensate for the output device and for rounding and whatever. METAFONT can do kerning and ligatures, too.
Re: Adapting small bitmap fonts to TTF
by on (#116311)
So this time, I made all strokes lighter (3/4px instead of 1px), tweaked the 'y', made a ligature for 'fi', and overshot all bowls at the cap, mean, and baselines by 1/8px. I didn't overshoot the sides yet, and I didn't see a need for an 'fl' ligature.

Attachment:
File comment: Sample from Rackham's translation of a famous passage from Cicero. From top to bottom: original bitmap font, AA without hinting, monochrome with FontForge autoinstruct.
with reference.png
with reference.png [ 9.36 KiB | Viewed 5916 times ]


Here's what I have so far. From top to bottom:

  1. Original (with scanlines effect)
  2. Antialiased without hinting
  3. Monochrome with FontForge automatic hints (which incidentally take as much space in the .ttf as the rest of the font combined)

Ultimately what I want to do is either figure out how to capture the spirit of the bitmap font or demonstrate why that's not possible. Compare to Apple's conversions of Chicago, Geneva, and Monaco to TrueType for System 7.
Re: Adapting small bitmap fonts to TTF
by on (#116322)
I think it does a pretty good job now of representing the original font.

A few thoughts, but I'm not certain whether they should be addressed:
* The bitmap 's' necessarily has straight tails, but the vector doesn't
* 'a' (the bitmap loop is square on the right side; the vector's is an oval and a line)
* 't' and 'l' (the arc of stem is longer in the vector version),
* 'w' (I feel like the bitmap version implies something curvy on the sides)

A few more strident points:
* 'g' isn't remotely the same
- as far as I can tell, the bitmap version is open, and has no ear; the vector version is closed, has a ear
- and IMNSHO a closed g without a visible link looks terrible
* the 'fi' ligature's kerning is substantially tighter than other letter pairings
Re: Adapting small bitmap fonts to TTF
by on (#116327)
Thank you for your feedback.

lidnariq wrote:
'a' (the bitmap loop is square on the right side; the vector's is an oval and a line)

Compare 'd' or 'ɡ' or 'q'. For 'a', I took 'ɡ' and flipped it.

Quote:
't' and 'l' (the arc of stem is longer in the vector version)

Probably the same phenomenon as overshoot: I need to make them longer to eat up the space between the letter and the following letter.

Quote:
'w' (I feel like the bitmap version implies something curvy on the sides)

Sketch out the curves you see and I'll play with that.

Quote:
'g' isn't remotely the same

Copy and paste this into a new document: "Are you struɡɡlinɡ with debuɡɡinɡ eɡɡ throwinɡ?" To type the alternate ɡ (Latin small letter script g, U+0261) into a Gtk+ application, press Ctrl+Shift+U 2 6 1 Enter. One problem is not all programs are aware of OpenType alternate glyphs. I could try playing with OpenType stylistic sets and CSS font-feature-settings and just endure the ensuing prefix hell and complete lack of support in IE pre-10 and Safari.

Quote:
a closed g without a visible link looks terrible

The page you linked states that the "link" is also called a "neck". Guess what a lot of classic video game characters lack due to graphical limitations, especially in sprite-based overhead adventures and RPGs. (ObNES: Does Link in The Legend of Zelda have a neck?) Here's the bitmap glyph I was trying to represent, along with an alternate solution inspired by another typeface that lacks descenders:
Code:
      ██          ██
  ████        ████
██    ██    ██    ██
██    ██    ██    ██
  ████        ████
██    ██    ██
  ████        ██████
Linkless      Hobo
closed g    style g


Quote:
the 'fi' ligature's kerning is substantially tighter than other letter pairings

That's one of the problems with working with quantized advance widths. If I widened 'fi' by one pixel, it would appear no different from fi with no ligature.
Re: Adapting small bitmap fonts to TTF
by on (#116339)
tepples wrote:
Quote:
'w' (I feel like the bitmap version implies something curvy on the sides)
Sketch out the curves you see and I'll play with that.
Here's the w I see when I look at the bitmap:
Attachment:
w.png
w.png [ 896 Bytes | Viewed 813 times ]


Quote:
Ctrl+Shift+U 2 6 1 Enter
Neither firefox, abiword, nor gimp obey that. rxvt-unicode does honor C-S-261, though.

Quote:
Here's the bitmap glyph I was trying to represent
But in the previews you give of the bitmap form of Base Seven, you don't use the closed g.

Quote:
Quote:
the 'fi' ligature's kerning is substantially tighter than other letter pairings
That's one of the problems with working with quantized advance widths. If I widened 'fi' by one pixel, it would appear no different from fi with no ligature.
I was pointing out how the f's hook extends so far into the next letter that the place where it touched the dot of the i, there was this little chasm. I was hoping for a more deliberate touching there.