Hacker News new | past | comments | ask | show | jobs | submit login
Text rendering hates you (2019) (faultlore.com)
290 points by subset on June 26, 2023 | hide | past | favorite | 119 comments



(2019)

Previous discussions:

https://news.ycombinator.com/item?id=21105625 (29 September 2019, 542 points, 169 comments)

https://news.ycombinator.com/item?id=30330144 (14 February 2022, 399 points, 153 comments)

—⁂—

If you find this article interesting, you’ll probably also like the article someone else published a month later: “Text Editing Hates You Too” <https://lord.io/text-editing-hates-you-too/>. It has also been discussed here a couple of times:

https://news.ycombinator.com/item?id=21384158 (29 October 2019, 875 points, 282 comments)

https://news.ycombinator.com/item?id=27236874 (21 May 2021, 384 points, 182 comments)


This brings back memories for me. I’m retired now but I helped develop and implemented many of the algorithms for multilingual text and Unicode back in the 80s first at Xerox and later at Apple.

What this article misses is a lot of the complex formatting issues also with text rendering. For example even implementing tabs can be complex (remember that you have different tab types and conflicting constraints like keeping something decimal or left aligned but now having enough space to do that with out overlapping characters.) In languages like German if you have a computed or soft, hyphens the spelling of a word can change. Good paragraph breaking, widow orphan control, page breaking, computed header/footers that can change heights… are also complex issues that have to be dealt with.

Back when I worked on this stuff we also had much slower computers that made things even more difficult so that you could type anywhere in the paragraph and still have responsive and correct output (you can’t delay formatting if the chargers change on context although some formatting can be delayed.)


There's a group who're trying to get Mayan orthography into Unicode. Mayan has some challenges; the two I like best are:

1. Rendering is in pairs-of-columns, with a "Z" layout; and,

2. Glyphs have a concept of depth, and you must render subglyphs with the correct depth and occlusion to maintain meaning.

Mayan also has the same feature as Egyptian Hieroglpyhs (but not the same extent) of multiple glyphs per word/logograph/letter.

Here's a 2018 proposal, that covers all of this in more detail:

https://www.unicode.org/L2/L2018/18038-mayan.pdf


I see this as the canary in the coal mine in case our Alien Overlords™ turn up. At least we'll be able to glyph what they're saying.


Just what Unicode needs, Mayan orthography.


It is ultimately good that unicode is universal, it needs to be if it aims to be used in all domains and languages, not just English!


So it appears that Mayan orthography was strongly influenced by the act of carving the glyphs into stone, and therefore it looks like worldwide orthographies will be strongly influenced (and constrained) by the specifications of Unicode, going forward for decades or centuries.


Nice, must have been really painful at times.. btw. I just noticed that when I zoom in Safari I get a pixel wise zoom and then, just a brief moment later, the fonts are re-rendered sharply. And this is I think the fastest laptop they sell maxed out in specs. So still there are optimisations in place to make text appear smoothly.


Adobe takes text rendering very seriously, because all their products were at one time primarily about targeting high-end printing applications. Back when I was there, there was one dude who was "the text renderer guy" for all the applications products (e.g. not printers and systems stuff) and when things got gnarly and an application had a text-related ship-blocker, they'd call him in and he'd patiently fix the ways in which some noobs had fucked up text in their particular application by not knowing a lot of the stuff that's in this blog post.


I'm not sure about noe but for a very long time Adobe Photoshop did not support complex bidirectional text.


Thank you guys for your excellent RIP and Display Postscript on NeXT.


I accept these thanks on behalf of those who actually deserve it. :)


"Hey so what do you do?"

"I unfk other people's fonts"

that's funny af.


Have just skimmed it and this is a great intro to the weird and wonderful world of rendering text.

It gets even more wild as you descend down into the myriad ways this information is specified within fonts. For bonus points dig into how fonts are embedded within PDFs.

There’s definitely something wrong with me because I find the whole thing fascinating. Picking through the specs and existing open-source code feels more like an archaeological crusade than anything else.


I think this is true for most specs that are sufficiently old and sufficiently complex: there will be some parts that were specified, but never widely used, some parts that were once used, but are not relevant anymore, etc. etc. For an onlooker, these curiosities might seem fascinating. If you are setting out to implement the spec and don't have an infinite amount of time however, the multitude of corner cases, some important, some not (sometimes without an obvious way of distinguishing between the two) will get on your nerves pretty quickly...


One spec I've been diving into recently is emacs' skeleton auto typing engine. It has been in the codebase and documented for 30 years at this point but never saw widespread use. It was apparently was conceived as away to write not just snippets but also autoclose parenthesis and interactively fill in function or form data. I've been trying to figure out how I would go about using it as an alternative to tempel or yasnippet.


Recently at work we were testing a new font for the brand, won't mention the name, it's unimportant.

We couldn't get it to look right on Windows. Only at a few select font sizes and weights did it look OK, at every other setup it looked like somebody took random bites out of the glyphs, meaning the individual characters had inconsistent weights.

On Apple devices, we had no such issues. It seems their anti-aliasing algorithm intervenes more deeply, prioritizing a good and consistent result over theoretical integrity.

You might have this same issue with thin fonts (this wasn't a thin issue) looking good on Mac and unreadable on Windows. A simple way to put it is that Mac renders font thicker (more black).

I've faced the issues above for multiple custom fonts. It's why I no longer believe in the supposed best practice of fluid font sizes. I hardcode a limited set of font sizes and only those proven to look good across systems.

Oh, another fun one is the glyphs of fonts having internal padding or asymmetric padding. Which messes with line heights and vertical centering. Or how about needing to tweak letter-spacing as characters overlap.

I've come across all of this and more for some widely used fonts. Most are anything but ready-to-go.


I think the typical summary of the difference in Mac and Windows font rendering is that the Mac tries to get the fonts to look closer to the printed page and Windows tries to fit the lines to the pixel grid more exactly.

The Mac does it's job with no regard to the sharpness or fuzziness of the rendering - e.g. it will happily render you a "one-pixel line" as two gray lines just so that it ends up aligned beautifully with the rest of the letterform, but people without HiDPI displays will complain that this is "blurry".

Windows tries to fit the pixels more exactly into the pixel grid of the display to ensure sharpness and a 90's sensibility of readability. The problem here is that for any font that is not hand-hinted well at the required size, this often falls flat on its face and looks terrible. And the art of font hinting seems to have gotten lost in the 90's.


As display resolutions get higher, you get further away from needing pixel-level tweaks and hints, so it's arguable that the resolution-independent approach is better long-term. Tie yourself too closely to pixel sizes and you paint yourself into a corner so things like super-high-resolution displays (like retina) become a huge engineering problem. Back when Display PostScript was introduced, the idea of 300dpi monitors was almost ludicrous (300dpi being a standard laser printer back then), but here we are.


Well put!


The Raster Tragedy[1] creates the impression that mangling font outlines to the extent that they’re utterly unrecognizable is the fundamental mode of operation of Windows font hinting.

Granted, it’s a miracle you can meaningfully render vector fonts at 96 dpi at all. I just wish a closer look at that miracle did not reveal countless eyeballs and writhing tentacles.

[1] http://rastertragedy.com/


Offhand, this might be HiDPI stuff. I haven't interacted with it myself, but upscaling for unaware applications is the first thing I would think to look at.


This is one reason why I respect LaTeX so much, and why I can often spot documents written using MS Word a mile away. The idea that it doesn’t matter, that humans are not sensitive to or affected by these things, is plainly false. If I’m reading a long document, it matters. It may not matter ‘objectively’ but … I am human and it does affect me.

The corollary is, if I’m writing a document that I know others will be judging (e.g. a research grant application or a scientific publication) I will absolutely 100% do what I can to make it a more pleasant experience for the reader, including using LaTeX for text rendering. I may change (or not) the default font, but for text rendering and all the tiny decisions about spacing, kerning, etc, I will trust LaTeX over MS Turd any day.

Sure, “it shouldn’t matter”, a reader ought to judge my ideas and not be affected by this other stuff —- but, alas, the reader (for now ;) ) is human, and we are affected by this stuff.


> I may change (or not) the default font

Please do. Computer Modern is awful; its optical sizing is all wrong, far too thin and with too much stroke thickness variation. On some common system and rendering configurations, it’s genuinely not far off illegible at common sizes. Its shapes were designed for printers that (a) had much higher resolution than most screens do, and (b) exhibited at least a moderate degree of glyph dilation (e.g. ink bleed). These days, it’s OK in print (still too thin, since printers are more precise in this way than they used to, which essentially makes everything a bit thinner than it used to be; but not too troublesomely), but really bad on screen for many renderers.

Vaguely similar story on Courier New, which was badly digitised in a way that made it far thinner than it should be (due to not taking into account extra weight added by the typewriter’s ink ribbon), and so Windows includes all kinds of hacks to make it somewhat less intolerable (radical changes in hinting, and special-casing in ClearType), but half of those hacks don’t work any more (or work inconsistently) due to how things are done these days.

Before anyone jumps on me saying they love Computer Modern and it looks fine to them: I’m focusing on the objective parts. On some screens with some software, it looks tolerable, despite clearly not matching most fonts’ ideas of what a regular weight should be. But on more configurations, it’s dreadful. I’m not talking about the rigid shapes and weird curly bits and such, which I also incidentally dislike, because that’s more subjective. But the weight stuff and the extreme stroke thickness variation stuff, that’s objective.


> Computer Modern is awful; its optical sizing is all wrong, far too thin and with too much stroke thickness variation.

You are supposed to fine tune the font constants yourself for your specific printer when installing TeX and METAFONT on your system. If your pre-generated fonts look awful, try using them on a device similar to the ones which was used by the font packager.

The pre-defined modes can be found here: <ftp://ftp.tug.org/tex/modes.mf>

1. <https://news.ycombinator.com/item?id=27917366#27918650>


From a quick scan, it appears that file was last updated in September of 2020, but has been around since 1991. https://www.tug.org/applications/fontinst/mail/tex-fonts/199...


Do you have any recommendations for good LaTeX fonts?


\usepackage{libertine} will give you the font used by ACM journals/proceedings, which looks really nice to my eyes. It's less "severe"-looking than Computer Modern.


I really like the ADF fonts. My go-to are Gillius ADF, Tribun ADF Std. I also often use Bergamo and Arimo. Before this I used kpfonts.


For documents intended to be read on-screen, I've had very pleasant results with Merriweather, Merriweather Sans, and Cascadia Code (for monospacing). Mind you, I use XeLaTeX or LuaLaTeX, which make using arbitrary fonts easy. My math text is still in Computer Modern; I still have to go look at various pairings to see what I like the best.


I've been very happy with kpfonts in documents I've made with PDFLaTeX. Otherwise I use XeLaTeX and my choice of font.


cochineal for serif should cover most western languages https://tug.org/FontCatalogue/cochineal/; source sans pro for sans; inconsolata for code.


Concrete Roman solves almost all of those problems. Or at least improves on them.


My feelings about LaTeX are mixed. I think an abstract or a one page report in LaTeX looks great (I remember always getting a great grade for any homework I set w/ LaTeX as an undergrad.)

The thought of reading a whole book in Computer Modern Roman makes my eyes ache though. I think CMR has too many high spatial frequency details that tire me out after a while.

I appreciate the optimization algorithms that LaTex uses to lay out words into lines and lines into pages. I have my own program I’ve written that I use to draw the back side of “three sided cards” like

https://mastodon.social/@UP8/110409706406856531

Everything is manual with a few affordances that make common tasks simple, one interesting feature is layout for vertical CJK text which is less impressive than it sounds since CJK characters are all square. Sometimes I think about coupling a general purpose SMT optimizer to it, but it’s not the highest priority.


Computer Modern is an abomination, the Comic Sans of software engineering.

Well, that's not really fair to Comic Sans — at least it was designed by a professional for a very specific purpose. Computer Modern is an amateur creation from the stone age of digital typography, and the only reason it persists is the silly computer science education cargo cult around it. You won't find a professional type designer with kind words to say about Computer Modern (though they are generally too polite to say anything about it).


> You won't find a professional type designer with kind words to say about Computer Modern (though they are generally too polite to say anything about it).

“Everyone agrees with me, but nobody will say it publicly.”


I thin most people involved with type are pursuing other markets and don’t think a whole lot about the TeX universe.


> Sure, “it shouldn’t matter”, a reader ought to judge my ideas and not be affected by this other stuff —- but, alas, the reader (for now ;) ) is human, and we are affected by this stuff.

Reading this as a visually impaired person (legally blind but with some usable vision), I can't help but think that normal vision might actually be an impairment sometimes.

What if documents with high-stakes judging had to be submitted in strictly semantic HTML, with all styles or legacy presentational tags forbidden, and read by each reviewer with their preferred settings?


In high school I easily got all my writings and reports to have a higher-than-average grade despite an average quality of writing, just by having the best quality of typography with LaTeX.

Yes I did change the font, to some pirated Adobe Font Folio fonts. I loved full justification but hated hyphenation so much that I would rephrase my sentences to avoid hyphenation. I can't remember if the microtype package was a thing but I probably used it. I most definitely made the left and right margins different according to odd and even pages.


I wrote an openGL font renderer once. It was a lot of fun. Bezier curves are such an elegant technique. The difference between what I wrote and what you'd use in a proper environment is pretty big, but I recommend it sometime.

Fonts are pretty much just third or fourth degree beziers, plus a way to shade between the lines iirc (i may have my terminology wrong). Try it out sometime, I did my curves using tessellation shaders.

Btw, you'll never find a better guide on beziers than here:

https://pomax.github.io/bezierinfo/


I work for a major foundry and fonts are ludicrously complex for a ton of reasons, but for the most part TTFs use quadratics, but our designers exclusively use cubics (postscript outlines) at design time and there is a conversion process to fit them as quadratics. On ultra lowend devices, having quadratics renders faster and the hinting works better, but if you're a designer consuming fonts, you should stick with OTFs as it is what the designer intended.


I am an end-user, but I pay a lot of attention to rendering methods and hinting so I consider myself educated on the subject.

Saying OTF is tricky.. because OTF file format can be postscript outlines OR truetype outlines and you don't know what is inside until you check.

Sticking to what the designer intended is not always the right approach because in the end, it's about the end-user experience. If your output medium is a printing press, absolutely, every time what the designer intended. If your medium is a screen then the resolution and how the OS works matters. Using IBM Plex Sans on a standard definition screen as an example, the unhinted OTF will end up at some sizes squishing the letters into the wrong shapes and render lighter while the TTF will render the shapes better due to better grid fitting and darker. Basically and unfortunately, you have to test it for every environment and not assume that a given file is the best viewing experience.

I dislike AA in general as a blurry mess (and disable it on my desktop, which yes, does mean I have to hand-pick fonts that were hinted for no-AA), and fail to understand why as more and more high-DPI screens are used that AA is still being used seems redundant and counter-intuitive.


If you consider cjk, you need almost 4x dpi for really complex character like 龜 to actually looks like what it is intended.

If it is a phone with 6 inch 2k or 4k screen. Then probably you are right, you don't need AA.(Honestly I don't know if my phone have aa enabled or not, because I can't really see the pixel with bare eye) But for 27 inch 4k screen, it is still not enough.

BTW. It's really obvious for a CJK user when the AA went wrong for whatever reason. Take an example, this issue: https://github.com/marticliment/ElevenClock/issues/241


> for really complex character like 龜

*repeatedly zooms/unzooms Firefox* Aw man, and I just finished convincing myself that my new 3440x1440 screen had "enough" resolution too. :p

That said, perhaps this particular scenario actually embeds an implicit/unreliable assumption: That for some reason both "A" and "龜" ought to be viewed by humans at about the same size.

I mean, imagine a hypothetical language where the required display-size of a glyph is a square patch 4x the area of "Hello", but the larger size is justified by how it also contains 4x more information, like "greetings / very-respectful / spouse of my son." The writing system just has a different decisions about how to chunk/group detail.


> That said, perhaps this particular scenario actually embeds an implicit/unreliable assumption

Yes and No.

Yes, you can literally read a Chinese sentence even 50% of the stroke is blurry. (Or it is simply all blurry,assume you don't cover some key character to the point that it is completely unidentifiable.)

No, it's not really a pleasant reading experience.

After update the macos to that version using grey-scale AA by default.(It used to be subpixel AA) The first thing I noticed is every chinese character is blurry on the 1080p external screen. I really have no idea why apple think that will be a good idea. Is people don't use 1080p screen now? Or probably there isn't a CJK apple engineer at all?


I don't know CJK, but I enjoyed the tough example you showed me. First I looked at a hand-drawn calligraphy example of it so I could see what it is supposed to look like, then I looked at how some fonts render it on my system and it's pretty grievous for most (I can see strokes are missing, etc.)

Probably the best font for this character that is available on my system (AA is off and I don't have a hi-dpi display) is "MS Gothic". Strokes seem darker, present and clearly rendered. Do you like this font?


> for really complex character like 龜

This tells me that I need to change my CJK font fallback. I see a character, but depending on what font-renderer I use, changing the font-size either doesn't change the size of that glyph, or resizes the original glyph pixel-by-pixel. Clearly whatever font it is falling-back to is not a proper outline-font...

[edit]

Does anyone have a good way to determine what font is used to render a particular character in any linux application? The best I've come up with is grepping pmap for font files...


If you use a normal browser like Firefox or Chrome the settings for fonts are there in the browser settings. Firefox will let you override the page's choices, Chrome won't. Zoom works for both.

> Does anyone have a good way to determine what font is used to render a particular character in any linux application?

You could take a screen-snip and run it through a font type identifier.


FWIW, pmap showed me it was using unifont, and installing the Noto CJK makes the glyph much improved (though illegible at default sizes).


Firefox: dev tools, Inspector tab, Fonts panel, Fonts Used.


You're kind of cheating with this old, mostly unused character (it was simplified to 亀). But the point stands, because there are plenty of common characters that can be just as unreadable.


Even your `simplified` example (assume no one using 龜 now) can have trouble on a 4K screen. the horizontal line is the 田 structure of this character is somehow not vertically centered on my firefox. (given it should have enough space to)

https://i.imgur.com/You0nKL.pngA

BTW: I am a Taiwanese, so I literally use that character.


Your simplified variant of 龜 appear to be used in Japanese kanji, but the "old, moetly unused" version is still used in places using Traditional Chinese like Taiwan and Hong Kong.


Erf, I don't know why, but somehow I thought you were talking about Japanese specifically.


>Saying OTF is tricky.. because OTF file format can be postscript outlines OR truetype outlines and you don't know what is inside until you check.

it is true .ttf fonts. .otf is always cubic


No, OTF supports both TrueType font outlines [0] (quadratic only) and CFF/CFF2 outlines [1] (cubic or quadratic). In fact, CFF is relative rare in the wild.

[0] https://learn.microsoft.com/en-us/typography/opentype/spec/g...

[1] https://learn.microsoft.com/en-us/typography/opentype/spec/c...


If you're more video oriented, a quite nice overview can be found on YouTube:

https://www.youtube.com/watch?v=jvPPXbo87ds


One of the examples for Devanagari that is claimed to be broken is a nonsensical combination that really isn't supposed to work either as per any of the Devanagari script using languages or the Unicode standard.

Devanagari (roughly speaking) has Consonants (with an inherent vowel A), dependent vowels signs added to a consonant, and independent vowel letters. And a few other signs for aspiration, nasalization, and cancelling the inherent vowel to combine consonants.

न्हृे Starts with N (the consonant NA with the inherent vowel A cancelled and ends with the Devanagari Consonant HA with _two_ vowel signs added to it - DEVANAGARI VOWEL SIGN VOCALIC R and DEVANAGARI VOWEL SIGN E

CV is the standard for Devanagari "syllables". When you do want to write two vowels after each other, you would write CV, and then another independent Vowel letter, so it would look like

न्हृए (which would end with DEVANAGARI LETTER E instead of DEVANAGARI VOWEL SIGN E)

*These are syllables as per the script definition rather than linguistic syllables.

https://www.unicode.org/versions/Unicode15.0.0/UnicodeStanda... section 12.1 has more details on the specifics of implementing Devanagari script, but not necessarily all of the conjunct forms between consonants, which are used especially when rendering Sanskrit.


Another problem with text rendering that's not mentioned in TFA is hyphenation. I have a table on a webpage that can have some long text in some cells. I have 2 simple requirements: # If a word will fit by moving it to the next line, then move it to the next line and do not hyphenate i.e., do not break the word. # If the word is too long to fit in a single line, then break it up. Hyphenate at will.

There is no incantation combination of CSS properties word-break, word-wrap, overflow-wrap, hyphens and white-space that will do this. In 2023.

I believe word-break: break-word does #1 but it's not hyphenating for me. And MDN says word-break: break-word is deprecated.


What should be done with hyphenation and indeed breaking paragraphs into lines in general is largely just undefined. There are mild movements from time to time, but overall no one’s sufficiently interested in implementing the really good stuff, so we’re left with the simple, easy and bad that everyone has grown used to. I’m glad to say that Chromium has just shipped `text-wrap: balance`, which is at least one step in directions of goodness. I hold out hope that some day some browser will implement a `text-wrap: pretty` backed by something like Knuth-Plass. https://bugzilla.mozilla.org/show_bug.cgi?id=630181 is relevant, shows that some thought has gone into how it could be achieved in Firefox.

And while talking of hyphenation, what happens if you try to hyphenate in the middle of what would otherwise be a ligature? e.g. at “af-fable”. Alas, in this instance no one has got really enthusiastic about fixing it in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=479829, you get the ff glyph split in half, much like the mixed-colour handling shown in this article.


Amusingly, folks usually seem hesitant to go with justified due to fears of "rivers" in the text. I can't claim that won't happen, but it seems largely overblown in concerns.

Picking "affable" was an incredible nerd snipe! I would have split the syllables wrong on that, as I have yet to convince myself that I pronounce "fa" in the middle there.

Similar problems come in when you have words that hyphenate differently depending on their use.


Hyphenation points are a funny thing. People would commonly go for “aff-able” (aff-a-ble), but in such cases, you tend to get better results for reading by splitting in the middle of the repeated letter, or more generally the consonant sequence (af-fa-ble). I’m not certain if this is to do with phonemes (that is, the hyphenation matching how you speak) or to do with aiding with continuing (simply making it easier for you to pick up on the next line); I’ve thought about it a little, but not that much.

There’s a similar but more aggressive form of the problem in lyrics on sheet music, where you’re declaring a hyphenation point between all syllables (though good engraving will avoid placing unnecessary hyphens), and people often break syllables incorrectly or suboptimally. Pulling up one score I noticed this with when I received it last week or so, some examples: strang-ers, runn-ing, en-em-y, anch-or, surr-end-er. I’d split (or hyphenate) them as stran-gers, run-ning, en-e-my, an-chor, sur-ren-der. I’m not certain if I’d always hyphenate and lyrics-syllable-break in the same places, but in the cases I’ve contemplated I would, though I had to think about sur-ren-der versus sur-rend-er for a moment.

Also I can’t say exactly why my mind lighted on the word “affable” (it was the second word my mind came to, after I discarded “affiance”), but you made me think about it more deliberately and then I was curious to see what the first word in a dictionary would be. In my /usr/share/dict/words, the first (excluding proper nouns) is “affability”. (The last is “whiffs”, with “whiffletrees” as the last word I’d maybe consider hyphenating between the fs.)


Sounds like a use case for soft hyphens. If you don’t mind where the words break, you could sprinkle soft hyphens through the text to get it to break more often than the default renderer would otherwise.


Soft hyphens are no use in this case, because browsers take them as a break opportunity of equal standing with a space. In my experience, liberal sprinkling on soft hyphens makes things worse, not better, because you end up with loads of gratuitous hyphens. What’s needed is a different algorithm for breaking paragraphs into lines, something better than the greedy algorithm that all browsers use. Something like Knuth-Plass, which applies a penalty to hyphens so that it’ll use them if the alternatives are bad enough, but won’t be too eager about using them.


I definitely agree that soft hyphens are a simplistic workaround if used in the way I suggested, and are indeed inferior to a complex and well-thought out hyphenation system. Still, if someone is considering `word-wrap: break-word;` for narrow table columns, soft hyphens are worth knowing about.


I have learned this, forgotten it, and then stepped on this garden rake again a handful of times in my career.

HTML should treat hyphens as hints and nobody does.


Supple hyphens, then?


The closest I can think of is for you to insert one or multiple soft-hyphens.


I am convinced that this was one of the secrets to the USA’s rise to computing dominance:

It had a language and alphabet that was amenable to a relatively simple encoding combined with a massive market of people that didn’t care if anything else worked.

Thus even the very slow and limited memory computers of that time could actually do useful text manipulation (like sorting phone books) in a reasonable amount of time.


My perspective, from a non-native speaker: Latin alphabet has happened to overlap with majority of world capital and economy. That is all to it. It's a never-ending baroque timesink to learn English spelling properly, but it did not matter.

Computing based on Chinese or Arabic would be a hindrance. Computing based on Hebrew, Cyrillic, Greek or Hindi would not be in any way (although for Slavic languages I do find flexibility of word order and plethora of word forms a hindrance, but it's a linguistic one).


and Korean?


Actually, it took a long time to get to Unicode. Computers started with 7-but character encodings (and many rivals, including EBCDIC).

Thankfully, text processing became pretty critical so they formed ASCII, when they went from 7-bit encodings to 8-bit encodings things improved, but then committees realised Latin dialects together had more than 255 characters… hence for some time we were all in code page hell. That’s why you got ISO-8599 - the most famous of which is ISO-8599-1. The genius of Unicode was they took all this junk and mapper into character planes, with ISO-8599-1 plastered into the BMP.

I went into it in detail years ago: http://randomtechnicalstuff.blogspot.com/2009/05/unicode-and...


I think that’s right. In practice it just took time for memory to increase a bit and for statistical input methods to show up. Certainly actively bad writing systems delayed IT adoption.

In fact, famously, the underlying theory of the Fifth Generation Conputing Project was the belief that advanced intelligent machines were needed to provide a working word processor for Japanese.

No small amount of cultural supremacy was involved in that era, as well, now mostly forgotten.


> If you’re in Safari or Edge, this might still look ok! If you’re in Firefox or Chrome, it looks awful, like this:

I'm guessing this was written around when Edge still used its own rendering engine, and nowadays it looks like Firefox and Chrome.


If you sympathize with the travails of people working on text rendering in applications, please consider supporting (among other projects):

1. The LibreOffice project (libreoffice.org), the free office application suite. This is where the rubber hits the road and developers deal with the extreme complexities of everything regarding text - shaping, styling, multi-object interaction, multi-language, you name it. And - they/we absolutely need donations to manage a project with > 200 million users: https://www.libreoffice.org/donate

2. harfbuzz (https://harfbuzz.github.io), and specifically Behdad Esfahood the main contributor. Although, TBH, I've not quite figured out whether you can donate to that or to him. At least star the project on GitHub I guess.


Text rendering doesn't hate you as much as article implies, AFAICT.

1. "Retina displays really don’t need [subpixel AA]" So eventually that hack will be needed less often. Apple has already disabled subpixel AA on macOS AFAICT.

2. Style changes mid-ligature: "I’m not aware of any super-reasonable cases where this happens." So that doesn't matter.

3. Shaping is farmed out to another library (Harfbuzz)

4. "Oh also, what does it mean to italicize or bold an emoji? Should you ignore those styles? Should you synthesize them? Who knows." ... yes, you should ignore those styles.

5. "some fonts don’t provide [bold, italic] stylings, and so you need a simple algorithmic way to do those effects." Perhaps this should be called "Text Rendering for Web Browsers Hates You." TextEdit on macOS simply doesn't allow you to italicize a font that doesn't have that style. Pages does nothing. Affinity won't allow it.

6. Mixing RTL and LTR in the same selection also seems like a browser problem, but I guess it could maybe happen elsewhere.

7. "Firefox and Chrome don’t do [perfect rendering with transparency] because it’s expensive and usually unnecessary for the major western languages." Reasonable choice on their part. Translucent text is just a bad idea.

Probably could go on. It's a good discussion of the edge cases if you really need to support everything, I suppose.


Note that for (1), you're going to have to explain your logic there, because retina displays still need subpixel rendering. They're nowhere near the print industry's standard 300 dpi, they're (a little less than) 300 ppi. For a "three different colours arranged in in blocks of four" screen, you'd need closer to 1200ppi before "we don't need subpixel rendering" is actually true. Until then, the raster tragedy may become less noticeable to people who are used to reading simplistic orthographies (like English), but it's very much still there for more complex orthographies (like, say, almost every middle-eastern, asian, and east-asian orthography)


Was just quoting the author. But also it appears that Apple disagrees with you, since they seem to have turned off sub pixel AA five years ago in macOS Mojave. See [1]. Indeed when I screen-captured and scaled up the non-western script in the article, there was no sub pixel AA on my Mac.

[1] https://www.reddit.com/r/apple/comments/8wpk18/macos_mojave_...


Grayscale AA is still common on Retina screens, but subpixel AA is rare. Mostly because subpixel AA is difficult to do compositing with transparency with, but also because it's less necessary on Retina screens. The tradeoffs are just to the point that it's not considered worth it.


Well, "need" is subjective. But subpixel rendering has diminishing returns as DPI goes up and (as the article describes) it causes several performance and interoperability problems, so the appropriate DPI threshold to turn it off might reasonably be somewhere lower than parity with print. Everyone agrees it's a good idea on cheap low-dpi displays, but whether it's still worth the costs on so-called "retina" displays is a judgment call.


> Perhaps this should be called "Text Rendering for Web Browsers Hates You" because often you have control over the fonts you use (like in a typical app)

The article specified an assumption that this is about laying out editable rich text, where the user using the program is able to arbitrarily style the text as part of using the program.

Like writing HTML+CSS for a web browser, yes; but also like WordPad, or like a cell in a spreadsheet program, or like the contents of a label field in a view builder. And also like changing text display preferences in a terminal emulator.


Admittedly I missed that assumption in cutting to the meat of the article. However, does WordPad or a spreadsheet really need to synthesize styling when the font doesn't have it?

I just loaded a font without an italic style into TextEdit on macOS, and it won't let me italicize it. It doesn't synthesize italics. I'm assuming the same goes for the rest of Apple's apps.


>> because often you have control over the fonts you use

Good luck with that if you want to support non-Latin scripts. Now you're shipping 100s of MBs of fonts with your app.


No. You use the system fonts, which tend to be good


And then you no longer have control over the fonts you are using, and it’s worse if you want to write cross platform code. Web and iOS (as far as I can tell), don’t have any way of querying which fonts actually end up getting used to lay out text either, which makes rendering some entered text very difficult.

I will probably end up having to ship entire text layout, font handling, and itemization stack in my wok just to do this correctly. It’s pretty frustrating down in the weeds of it.


9 out of 10 designers disagree


On a related note, there's a proposal for a Unicode project to improve complex script support in terminals: https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf

Many layout and shaping issues are present even in monospace text, at least if you want to do anything beyond ASCII.


>> The shape of a character depends on its neighbours: you cannot correctly draw text character-by-character.

Well, for the languages used in newspapers for hundreds of years I'd say "sure you can". Just because we can do better than that with computers doesn't mean it's wrong.

Sure text rendering is very complex, but this is also a first world problem.


Ligatures were used centuries before computers were a thing.

How it was done on printing presses: <https://www.dreamstime.com/royalty-free-stock-photo-ligature...>.

Also, this problem applies more to countries outside of the first world.


That works great with Latin based scripts. Now try it with Indic scripts:

https://r12a.github.io/scripts/indic-overview/


I’ve got this suspicion that sans-serif fonts are fashionable because something happening to of kerning, maybe somebody got a patent that prevents common software from implementing good automatic kerning.

Today I can’t set a serif font for display in print and stand to look at the results if I don’t kern manually, this is true if I use Powerpoint, it is true if I use Adobe Illustrator and also on PC or Mac. I think most people just give up and use a sans-serif font. The thing is I don’t remember having the problem with desktop publishing in the 1990s, maybe I was less picky then but I’d say the results I get setting serif headlines today are so bad it is beyond being picky, also when I see posters that other people make people seem to just not use serif fonts anymore so I think they feel the same way.


Sans-serif fonts are clearer on low-resolution displays. This includes both conventional desktop displays, with a low pixel density (96 dpi was the standard for CRTs and LCDs until Apple disrupted the field with "Retina" at ~200 dpi+, though in colour, which reduces effective density by 1/3.

For mobile devices, DPI is typically high, but the overall display is small, and hence, individual glyphs tend to be small.

On a large e-ink display, with monochrome density of 200--300 DPI, serif fonts are far easier and more comfortable to read for me, as the serifs provide additional cues as to the glyph shape and form. In particular, difficult-to-distinguish ASCII glyphs, such as O0, lI1, 5S, gq t+, ji, 4A, are much easier to distinguish. That describes my principle mobile device of the past 2+ years.

I literally cannot see the individual pixels without a high-power magnifying glass. Though at lower-quality settings, font rendering remains somewhat glitchy. Those settings offer higher refresh rates and less flicker, so it's a bit of a trade-off.

For DTP, the end result was almost always paper, and so long as you were using a laserprinter at 300+ dpi, serif would have been a preferred font choice. The turn to the Web saw a huge increase in use of sans fonts. Including, inexplicably and to my great annoyance, in published books, I suspect because the font carried connotations of "online" or "modern".


Myself I set a lot of posters, but when I was thinking about this I found a book printed in the 1990s that claimed to be set in “Palatino” and the kerning was so good I could swear the serif on the lowercase “r” was making love to the curve of an “s” next to it. That inspired me to take a look at the “Palatino” font on my PC and, sure enough, the “Palatino” on my PC looks nothing like that “Palatino” on that book.


> I’ve got this suspicion that sans-serif fonts are fashionable because […]

As you call it out, it is fashion. Fashion is rarely rational. Designers like what they like and their trends are often based on things like whimsy or "what looks different from last generation's fads".

I think there's a likeliness the causality arrow points the other way: designers are deep in a sans-serif fad for a number of weird aesthetic reasons. Designers force "all" the designs to sans-serif fonts. Serif fonts don't get enough love in key places in software interfaces or desktop publishing. Serif fonts start to accidentally accumulate kerning bugs because they need more eyeballs.

I don't know for certain if that's the case, but it fits the general Razor when dealing with fashions of any sort. (I don't know if there's a name for this particular Razor like Occam's or Hanlon's. "Never attribute rationality to fashion.")



If this article made you think about how to get better text rendering here are a couple of suggestions for devs:

Many terminal emulators have greyscale anti-aliasing as an option or default, I know and have tested:

- Windows Terminal (Windows) where you can set it in settings.json

- kitty (linux) where it is default

- You can probably get it globally in Linux through fontconfig settings, but I've never loked into that.

If you're on a display at or above 200 ppi (4k at 27") you can also disable font anti-aliasing completely. The effect that has on letter shapes (esp. in Windows) is pretty striking.

In chromium-based browsers and firefox there is a changing collection of about:config setting that control their Direct

(edited to fix line breaks)


> Windows Terminal (Windows) where you can set it in settings.json

Wow thank you. I just switched from GrayScale antialiasing to ClearType, and the text quality seem to have improved.

For the people who are interested, in UI it is in Settings -> Defaults -> Advanced.


At this point I almost want to say that asking computers to render text in any way other than blitting pixmaps to a regular grid is a cruel treatment of the machine spirit.

Joking aside, I am one of those people that completely disagree with subpixel anti-aliasing. I wish I could turn it off completely everywhere on Windows. I can do it on GNU/Linux and macOS never had that. It always looks wrong to me, regardless of monitor used or settings I pick, like the letters have colour fringing. I hated it when Microsoft introduced Clear Type in Windows XP and I still can't stand it.


This fragment: <<So [emoji of a dark woman] may literally appear as [emoji of a person] [emoji of dark brown] [emoji of the female symbol]>>

the "may literally appear as" is actually EASIER TO UNDERSTAND

its a person, of colour, who is a female. The single emoji is almost unviewable on my monitor at any precision and I could not ascribe feminine qualities to it, I almost was unable to ascribe personhood qualities.

This to me is the central problem of emoji: They actually suck at conveying meaning, where alphabets and words do really really well.


Text rendering and transparency (not always together) torture me to often :(

Quite recently I noticed that Java2D text rendering cheats the same way as Firefox and Chrome described in the overlapping example.

The character Ø can be expressed in Unicode in two ways. Either as single code point U+00D8 or as an O + combining slash (U+0338). Since the first one is one code point Java2D renders it correctly with transparency but the second variant as two characters with notable overlap since Java is lazy on the 'combining' part.


When text rendering it goes through multiple stages. I remember going through the LibreOffice text rendering code. Text rendering basically goes through the following stages:

* segment up text into paragraphs. You’d think this would be easy, but Unicode has a lot of seperators. Heck in html you have break and paragraph tags, but Unicode has about half a dozen things that can count as paragraph seperators.

* parse text into style runs - each time text font, color slant, weight, or anything like this changes you add it to a seperate run

* parsing the text into bidirectional runs - the text must work out the points at which it shifts text direction and place them into a new run at each shift of direction

* you need to figure out how to reconcile the two types of runs into a single bidi and style run list.

Do t forget that you might need to handle vertical text! And Japanese writing has ruby characters that are characters between columns.

* fun bit of code - working out kashida length in Arabic. Took one of the real pros of the LO dev team to work out how to do this. Literally took them years!

* you then most work out what font you are actually going to use - commonly known as the itemisation stage.

This is a problem with Office suites when you don’t have the font installed. There is a complex font substitution and matching algorithm. Normally you get a stack of fonts to chose from and fallback to - everybody has their own font fallback algorithm. The PANOSE system is one such system when they literally take a bunch of text metrics and use distance algorithms to work out the best font to select. This is not universally adopted and most people have bolted on their own font selection stack, in general it’s some form of this.

LibreOffice has a buggy matching algorithm that frankly doesn’t actually work due to some problems with logical operators and a running font match calculation metric they have baked in. At one point I did extensive unit testing around this in an attempt to document and show existing behaviour, I submitted a bunch of patches and tests piecemeal but they only decided to accept half of them because they kept changing how they wanted the patches submitted and then eventually someone who didn’t understand the logic point blank refused to accept the code - I just gave up at this point and the code remains bug riddled and unclear.

On top of this, you need to take into account Unicode normalisation rules. Tricky.

* now you deal with script mapping. Here you take each character (usually a code point) and work out the glyph to use and where to place it. You get script runs - some languages have straight forward codepoint to glyph rules, others less so. By breaking it into script runs it makes it far easier to work out this conversion.

* now you get the shaping of the text into clusters. You’ll get situations where a glyph can be positioned and rendered in different ways. - in Latin-based languages and example is the “ff” - this can be two “f” characters but often it’s just a single character. It gets weirder with Indic characters which change based on the characters before and after… my mind was blown when I got to this point.

This gets complex, and fast - luckily there are plenty of great quality shaping engines that handle this for you. Most open source apps use HalfBuzz, which gets better and better with each iteration.

* now you take these text runs, and a lot of the job is done. However, paragraph separation is not line separation. You have a long enough paragraph of text and you must determine where to add breaks i lines of the text - basically word wrapping.

Whilst this seems very simple, it’s not because then you get text hyphenation. This can vary based on language and script.

A lot of this I worked out from reading LO code, but I did stumble onto an amazing primer here:

https://raphlinus.github.io/text/2020/10/26/text-layout.html

The LO guys are pretty amazing, for the record. They are dealing with multiple platforms and using each of the platforms text rendering subsystems where possible. Often they start to standardise - but certainly it’s not an easy feat. Hats off to them!


I spent a good portion of this weekend tracking down a minor text rendering issue I was having in WebKit. It is mind-boggling just the mountains of code that go into text rendering, and pretty amazing that they have managed to keep such a complex system so performant.

(the issue ended up involving harfbuzz, but it wasn't clear initially since it dealt with HTML whitespace collapse)


Thinking of writing a text editor from scratch scratch? Oh, sweet summer child.

Like seriously, font rednering is bonkers complicated.


Off-topic: Did any major OS successfully implement sub-pixel anti-aliasing on monitors that had been rotated by 90°?


I wish they all supported arbitrary pixel layouts. My QD-OLED has a triangular layout that leads poor looking text no matter what ClearType settings are selected. (Between GDI and DirectWrite, the font rendering system in Windows is a mess). WOLED has similar issues due an RWBG layout.


Not automatically, but in Linux at least you could set it FreeType for vertical RGB or BGR arrangement.


Which is useful, because the Steam Deck's panel is actually a portrait tablet RGB display rotated to landscape, which means when you are using the desktop mode of the Deck, the subpixel layout is actually V-BGR!

Of course, if you connect it to an external monitor, you need to change that back to RGB since there is no "if monitor then pixel layout" function.


In Windows you tweak sub-pixel anti-aliasing per monitor to whatever you like.


If only. There's a ticket open with Microsoft's PowerToys to improve the anti-aliasing situation:

https://github.com/microsoft/PowerToys/issues/25595

And heres an explanation from the dev of MacType about how DirectWrite can cause different applications to perform text rendering differently from each other:

https://github.com/snowie2000/mactype/wiki/DirectWrite-vs-GD...


Nice, hadn't thought of that issue!


Wow, this answered some questions I've wondered about for a while yet never thought of looking up. Especially the section on subpixel antialiasing; very neat. I didn't know that was an intentional thing, I figured it was just something that happened on its own.


specially google chrome (chromium and all the electron mess) on linux

https://github.com/ryuukk/linux-improvements/blob/main/chrom...


I made several bitmap non-monospace font with an online tool, I'm quite happy with them.

I use them in a few places, nothing more, and it's a bit difficult to make a good looking bitmap font, but it's an important part of having software that use simple things.


There's an irony in here, he's trying to demonstrate Firefox draws text wrong, but his example of "wrong" rendering doesn't match how Firefox actually renders it for me.


Bare in mind this article was written 4 years ago.


I thought it was current. That's a good point, thanks.


Not "he".


Not text rendering. Web. CSS still does not have proper support for kerning. Amazing how some things can be so bad for decades.


I often see people complaining about "it's just text, why is it so slow to render", you can render a high res 3d environment faster then you can render the same screen full of text. That said, the text rendering engines of today are very optimized. So it's relative fast considering the amount of work. And humans are very sensible when it comes to text, a human can notice if one pixel has the wrong color in text, but wont notice it in a 3d scene.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: