3 ms·
I've always wondered why fonts are rendered programmatically... Usually, font renderers are Turing complete in some way, and usually this opens up security con
by peter_d_sherman 7y ago
I've always wondered why fonts are rendered programmatically...
Usually, font renderers are Turing complete in some way, and usually this opens up security concerns, and rightfully so...
One of the primary reasons why fonts are rendered programmatically is because there's a theoretically infinite set of sizes/styles that might be required...
Well... why not make fonts with glyphs that are say, 5000 x 5000 pixels... and then instead of rendering for a particular size, line by line, stroke by stroke, curve by curve, why not instead use an interpolation algorithm to shrink that 5000 x 5000 pixel glyph to the exact size you want?
If a font provider program were made to operate that way, then all that would be needed to audit the program for security - would be to audit the shrinking/interpolation algorithm -- which could be as simple as possible (it's just a function which shrinks a bitmap of size A to another bitmap of size B... not a Turing machine which ingests other programs...)
Yes, fonts would consume much more memory (I suppose they could be compressed), but doing things that way might make font-providing programs more secure. And yes, you'd need to provide extra glyphs for italic, bold, bold italic, etc. (much more memory), but you'd be making a trade-off for a simple, security auditable font-provider... (we assume it's open-source...)
- monadic2 7y ago> Usually, font renderers are Turing complete in some way, and usually this opens up security concerns, and rightfully so... Most of the features of which I am aware in fonts are modeled as FSMs, which can certainly be turing complete but do not need to be. Off the top of my head you could figure out a “sane” max time for a “script” to run without any loss of font quality, though it would not technically comply with the intended functionality. I am at a loss of words for why this was ever possible, although perhaps security didn’t matter until this past decade and I am too young to remember how low priority it used to be.... certainly, putting anything in kernel space for performance reasons of all things seems ridiculous for desktop computing. I’ll take a fucking massive performance hit to keep my data safer.
- beders 7y agoSlight correction: FSMs are not turing-complete. They may not hold though, which is not the same thing.
- monadic2 7y agoDerp, been too long since my theory class. I am fairly confident AAT tables are FSMs, so I am curious where the turing completeness comes from. I am certainly not familiar with all truetype/opentype features.
- monocasa 7y agoIt's the hinting that's normally referred to here as Turing complete, I think. https://en.wikipedia.org/wiki/TrueType#Hinting_language https://en.wikipedia.org/wiki/TrueType#Hinting_language
- monadic2 7y agoI know Mac OS X has ignored a lot of the hinting in fonts. Do they evaluate the entire script regardless?
- oefrha 7y agoA font can have hundreds or thousands (see CJK) of glyphs, plus variants. Good luck distributing thousands of 5000x5000 bitmaps (easily in the GB range).
- dvhh 7y agoFonts do have other features that were not much used in the programming/tehc world. but one example there would be support for ligatures, which could be a lot more complex depending of the language you want to support. And depending on the rendering speed you want, you might want to perform some JIT compilation, which unfortunately might not cover all edge cases.
- virgilp 7y agoYou're also forgetting things like ligatures. And, how would you even render your proposed fonts in embedded devices? The solution is not "huge bitmaps".
- jchw 7y agoWell if you just want static vector fonts alone you don’t need anything programmatic; vector images are not inherently code anymore than raster ones. For TrueType I’m pretty sure the VM is only for hinting. OpenType has more flexibility but I haven’t anecdotally seen many vulnerabilities around OpenType. I suspect Type 1 is subject of many vulnerabilities specifically because it’s old code that doesn’t get as much usage.
- peter_d_sherman 7y agoA bunch of interesting comments, to be sure. All I know is, the fonts (in ROM) in the original IBM-PC, or the Apple ][, or the C-64, or the Atari 800, or any other of the 64K computers of the 1980's -- never had a security issue with their (ROM bitmap) fonts. That, and: I challenge all of the naysayers to come up with a better solution than the one I have proposed... Not all font-renderer/language experts, here, are we? Neither am I. That's the whole point. A graphical shrink routine I can easily audit for security holes. A font description language (an entire language mind you!) with lots of nuances -- how is any normal human being (much less rockstar programmer) supposed to audit one of those, with all of its possibilities, for security holes, in a single human lifetime? We've seen some very subtle manipulation of these (evinced by this article), whether intentional or not... A simple graphical shrink routine -- is orders of magnitudes more transparent and auditable than font description languages, or their interpreters... You want a better solution? Come up with one and tell me what it is! I'm listening...
- peter_d_sherman 7y agoActually, I'll come up with a better option... don't render any fonts locally... instead, get them when/as you need them as precisely sized bitmaps, from a font server, somewhere else on the Internet... Now the security for the font server becomes the problem of the server its running on, not your local PC... and while the font server runs the risk of compromise, you, by only using pre-rendered bitmaps, should ideally not... Of course, the drawback to this approach is, what if you want to work offline and have not downloaded the necessary fonts?
- core-questions 7y ago> Actually, I'll come up with a better option... don't render any fonts locally... instead, get them when/as you need them as precisely sized bitmaps, from a font server, somewhere else on the Internet... This sounds like: - a latency nightmare - a performance nightmare - a privacy nightmare > Of course, the drawback to this approach is, what if you want to work offline and have not downloaded the necessary fonts? I'm calling Poe's Law on you, friend
- jstimpfle 7y agoFont rendering is a dark art at common resolutions of ~96dpi. These displays are not really suited to display resizable fonts (as opposed to hand-crafted bitmap fonts). To render half-way readable fonts at ~96dpi you cannot just pre-render at an extremely high resolution and then downsize using a generic algorithm. (Even ignoring the unacceptable cost). To the best of my knowledge most fonts are only readable at 96dpi because glyphs have manually picked control points to make sure that certain delicate points are aligned to the pixel grid.
- jstimpfle 7y agoWording amendment: ... that certain delicate features are aligned to the pixel grid. Addendum: It obviously depends on the display font size, or more easily, how many screen pixels are used for rendering. The dpi is only an indirect factor. For normal screens on laptops and desktops (< 1m distance) typical font size means low pixel density. For example, the character '9' as rendered in my comment on the HN website has 6 horizontal and 9 vertical visible (coloured) pixels. Which means that Antialiasing (grayscale) is absolutely needed. Which again means that the borders are somewhat washed out, causing eye-strain. The situation can be somewhat improved using subpixel rendering, improving the horizontal resolution by a factor of 3, optimistically speaking. Though subpixel rendering relies on the structure of display pixels, and that the monitor is not rotated, and it's hard to get right and some people will always complain about colour fringes.
- jonas21 7y agoWell, for starters, there's kerning [1], hinting [2] and subpixel rendering [3] so that your text stays legible, even at small sizes. Then, if you want to support a variety of languages, you need to handle diacritics, ligatures, contextual shaping, and bidirectional text [4]. A character's appearance can very based on what comes before and after it. Or the base character can change appearance depending on the diacritics that are added to it. Some languages have complex rules about how you combine things, for example Thai [5]. If you want to support Emoji (and of course you do), then there's things like skin tone modifiers [6] and the zero-width joiner [7] that lets you make all kinds of crazy combinations. Modern text rendering is, for better or worse, very complex. [1] https://en.wikipedia.org/wiki/Kerning https://en.wikipedia.org/wiki/Kerning [2] https://en.wikipedia.org/wiki/Font_hinting https://en.wikipedia.org/wiki/Font_hinting [3] https://en.wikipedia.org/wiki/Subpixel_rendering https://en.wikipedia.org/wiki/Subpixel_rendering [4] http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=CmplxRndExamples http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&ite... [5] https://www.unicode.org/L2/L2018/18216-thai-order.pdf https://www.unicode.org/L2/L2018/18216-thai-order.pdf [6] http://www.unicode.org/reports/tr51/tr51-16.html#Emoji_Modifiers_Table http://www.unicode.org/reports/tr51/tr51-16.html#Emoji_Modif... [7] http://www.unicode.org/reports/tr51/tr51-16.html#Emoji_ZWJ_Sequences http://www.unicode.org/reports/tr51/tr51-16.html#Emoji_ZWJ_S...
- EmilioMartinez 7y agoFor starters, small characters are not just sized-down versions of large characters. Ligatures et al further complicate things. When you actually try to deal with font management and image quality you'll realize why they went through the trouble of making it so.
- pcwalton 7y ago> Well... why not make fonts with glyphs that are say, 5000 x 5000 pixels... and then instead of rendering for a particular size, line by line, stroke by stroke, curve by curve, why not instead use an interpolation algorithm to shrink that 5000 x 5000 pixel glyph to the exact size you want? TrueType doesn't need a virtual machine to parse the vectors either, only to hint. Your proposal doesn't provide any hinting capability, so it doesn't solve the problems the VMs were created to solve. Moveto/lineto/curveto commands like TrueType uses are trivial and are not causing the issues here. Fonts are going to be complex no matter what, largely because of international text and advanced typographic features. The real solution is to move to memory-safe implementations.