Cross Platform Font Rendering

I’ve been working on a new interpreter for my games. It is modern, cross platform, and provides accessibility features for blind players.

But in development I’ve become a bit frustrated with the state of modern screen print layout. Most systems, like GTK4, do ok at best. Yeah, you can get decent lettering and anti-aliasing. But apparently these people have never heard of drop caps, decent line spacing, or non-hacky paragraph indenting. (Don’t use tabs and spaces… What are you, some kind of monster?)

I think most people kind of give up and use web technologies with CSS (electron, tauri, etc) for exactly that reason.

Is there some solution in missing here? Creating my own native markup display library the way Gargoyle did is becoming more interesting.

4 Likes

I’m pretty sure GTK, QT, Flutter, and many other UI frameworks support customizable line spacing (often under the name “line height”).

It’s common to support drop caps with the letter as an inline image, wrapping text around it. (That is also pretty widely supported.) Describe the image to screen readers as the entire first word, and exclude the suffix of the word from the accessibility tree; screen readers will read the first letter as the entire first word, followed by the rest of the paragraph.

Is that too hacky for you?

Overall, it sounds like you have a strong sense of taste around UI frameworks. Unfortunately, most popular cross-platform UI frameworks are so big and complicated that they can’t appeal to anyone with “good taste” in API design. It’s all hacks built on hacks that just barely manage to work with a tolerable amount of bugs.

Designing your own UI framework with a canvas-based graphics framework (Gargoyle uses SDL) might let you build something that you really love.

If there are a bunch of other specific text-rendering features you’re looking for, you’d have to list them out and check which cross-platform UI frameworks do/don’t support them, and how it feels to use them.

It would be surprising if anyone could tell you what UI frameworks implement the text-rendering features you care about with an API you prefer (or can tolerate).

2 Likes

Sorry, I don’t mean to come off as cranky, I’m just frustrated. A canvas-based solution might be the way. I’m just annoyed that good typography seems like such a second class citizen. Most people read stuff on screens, and I’ve not been successful finding a good (native) cross platform library for content rendering. My most recent project leverages tauri because Web based renderer is actually more efficient (in my tests) than any native display library.

I don’t think this varies a lot from platform to platform, either. I develop on Linux but I get similar results on Win11 and Mac. Tauri binaries are tiny and use whatever Web display kit the OS happens to have stock, so there’s almost no chance the user doesn’t already have everything they need to run the interpreter.

TeX - TeX - Wikipedia

It is frustrating! Sometimes it’s amazing that anything works at all.

FWIW, I have had pretty poor experiences with Tauri, because the webviews it provides tend to be very, very old and buggy, especially on macOS and Linux.

On macOS, the only way to upgrade your WebView is to upgrade your OS, which at least requires rebooting, but often requires replacing your hardware. Lots of people just don’t bother. You can upgrade to the latest Chrome or Firefox just by downloading it (assuming they support your macOS version), and they auto-upgrade themselves pretty aggressively.

On the web, very old versions of Safari (6+ years old) are a tiny fraction of a percent of your traffic; many web developers just ignore them. In a desktop app based on a WebView, ancient WebViews can be as high as 10-15% of your macOS user base. Ignoring them is not an option.

On Linux, it’s common for the major version of WebKitGTK to not upgrade at all except during major OS upgrades. Anyone on Ubuntu LTS 20 is going to have a 2020-vintage WebKitGTK with security patches. (And Ubuntu LTS 20’s WebKitGTK was buggier than macOS WebKit, even in 2020, because Apple has more dedicated full-time developers and testers making sure that macOS WebViews work end-to-end.) If you’re shipping an app based on WebKitGTK, you can expect to see double-digit percentages of your Linux users running really old WebKitGTK.

It’s common to ship Tauri apps with their own embedded copy of WebKitGTK for Linux, which IMO undermines the point of Tauri on Linux, (why didn’t you just use Electron if you’re gonna ship an entire browser engine?) but it at least keeps the binaries small on Windows and macOS.

A related problem from your perspective is that very old versions of Safari were buggier in their text-rendering features, which could force you to switch to Electron later in your development cycle.

Even in Electron, it’s common to do a lot of weird tricks to make text rendering work well. Visual Studio Code is built on Electron… its main text area is basically in a JS-based UI framework of its own. (It’s not a simple <textarea> I’ll tell you that.)

1 Like

Lectrote has not had to get into weird rendering tricks in Electron. I fully expect that VSCode, as a full editor, has to do a lot of work. But just displaying text (with a single input field) is fairly painless.

IIRC, one of the biggest features VS Code had to implement from scratch is scrolling through large documents. VS Code will let you scroll through documents that are hundreds of megabytes long, without dropping a frame.

Am I remembering correctly that Lectrote had to just cut off large transcripts to preserve scrollback performance…?

Also, Lectrote doesn’t support a lot of text-rendering features. No drop caps, no paragraph indentation, none of the sorts of things that spaceflounder is exploring. Lectrote offers users a menu of fonts and color schemes, zoom level, margins, and that’s about it.

(And that’s no complaint! Lectrote does everything I need except for author-defined colors, which I hope will be implemented when Dannii’s Glk CSS Basic proposal is finalized.)

1 Like

I’ve actually thought about this in connection with Lectrote. From a simple text rendering standpoint, Tauri should (on paper) do the job. I’m fairly certain zarf would have considered this early on in the implementation and decided on electron for a reason.

In fact, I had a similar issue with Tauri for a kiosk app I had to build; I couldn’t get Tauri to stop crashing (on Debian) but electron worked perfectly.

Maybe I should save myself some trouble and just skip to using electron now.

IMO, you should only use Tauri on macOS or Linux if you have a solid strategy for testing it on very old versions of macOS and Linux. For a hobby project, life’s too short to put in all that effort just to save a few megabytes of binary size.

Having said that, I’ve heard that new-ish versions of Tauri let you opt-in to bundling your own browser engine, including letting you opt-in to bundling on some OSes and not others. So perhaps you could “bring your own browser” on macOS and Linux, but use Edge WebView2 on Windows.

(Edge WebView2 is way better than macOS WKWebView, because WebView2 auto-updates itself without rebooting or upgrading Windows.)

1 Like

Lectrote is about 4 years older than Tauri.

I don’t know the details of Tauri, but if it could use the OSes package manager to depend on a renderer then that would be better that Electron where every app includes its own copy.

Our IF interpreters are also well suited to slightly stale web renderers as they’re already designed for the web with all its various browsers, compared to someone making an app from scratch with Tauri who designed it using their personal up to date renderer and then discovers that it doesn’t work on other OSes nearly as well.

Lastly CSS is pretty good and covers most of what a traditional IF interpreter has allowed (and a lot more as well). The one main difficulty I’ve had is with line heights for ASCII art (particularly with background colours). CSS is kind of too good at laying out text with different font metrics, but it means that background colours are hard to display seamlessly. And “reverse” mode, which can’t just be a CSS effect.

1 Like

I didn’t know that, Lectrote is a lot older than I thought.

Yes, but that’s extreme conservatism on my part, dating back to the 2010-era browsers where I first implemented Quixe. I haven’t tested long IF games on recent Chromium.

The question is about Electron, and Electron’s HTML/CSS supports all of that stuff without difficulty.

I did look at Tauri briefly, but I’m afraid I don’t remember the reason I went with Electron. Probably Electron was easier to set up.

1 Like