
Libschrift: A lightweight TrueType font rendering library - zdw
https://github.com/tomolt/libschrift
======
pcr910303
Ok, this is a bit of a offtopic rant, but this project seems to be aiming
‘suckless’[0].

For me and a lot of users, that means that this project probably won’t be
useful for a lot of non-ASCII users, especially for CJK users like me. I’m
pretty sure CJK support will not get implemented or postponed to the future
until one day the maintainer decided the project is too ‘complex’ and not
‘suckless’.

Yes, I know that this is an open source project and I don’t need to use this…
but it just makes me sad to see essential features for some people will be
removed as the name of ‘complexity’. IMHO, this attitude of trying to rewrite
complex projects into simpler ones without careful planning of how the new
projects will handle complexity makes more inconsistent, divisioned
ecosystems.

Quoting the suckless philosophy[0]:

> Code complexity is the mother of bloated, hard to use, and totally
> inconsistent software.

> Ingenious ideas are simple. Ingenious software is simple. Simplicity is the
> heart of the Unix philosophy.

UNIX could be simple, because it was targeted for a very small group of
people, mostly always using ASCII. Trying to cater to a large group of people
will always be complex. And trying to cater to a large group of people is NOT
the definition of ‘bloated’.

[0]:
[https://www.suckless.org/philosophy/](https://www.suckless.org/philosophy/)

~~~
flohofwoe
Is CJK support any special compared to "Western" font rendering except that
the font files are much bigger?

In my experience, it gets interesting with languages like Arabic which need
special case handling for characters at the start and end of words, but those
conversions can be applied before handing the UTF-8 string down to rendering.
Oh, and the right-to-left rendering.

We have support for CJK and Arabic script in our game's text rendering, CJK
was straightforward (only the massive rasterized font bitmaps are a problem),
while Arabic was a lot more effort.

Other simple text rendering solutions also don't seem to have much of a
problem with CJK (e.g. stb_truetype + fontstash):

[https://floooh.github.io/sokol-html5/fontstash-
sapp.html](https://floooh.github.io/sokol-html5/fontstash-sapp.html)

~~~
pcr910303
> Is CJK support any special compared to "Western" font rendering except that
> the font files are much bigger?

I'm mostly thinking about the composing. For example, the character '한' is
composed with 'ㅎ', 'ㅏ', 'ㄴ'.

There are multiple unicode representations for each character, which means
there's a one code point '한' representation and it's also allowed to have a
'ㅎ+ㅏ+ㄴ' representation. If the program is just naively searching through the
code points the font is supporting, 'ㅎ+ㅏ+ㄴ' won't be rendered properly. (In
the real world, most non-Korean companies that implement custom text
rendering, even big ones like Adobe get this wrong.)

~~~
flohofwoe
Ah ok, IFIR for Korean we "prebaked" the required combinations offline needed
in our displayed text, and (I guess) the most common combinations needed for
user names.

This only works if the text is (mostly) known upfront of course.

As far as I know this isn't needed for the Chinese and Japanese writing
systems we are using though, only for Korean.

------
nathell
Another contender in the "alternatives to freetype" category: rusttype
[https://docs.rs/rusttype/0.9.0/rusttype/](https://docs.rs/rusttype/0.9.0/rusttype/)

------
kevingadd
One unfortunate lesson I've had to relearn a couple times is that once your
font rendering library is done, you get to start the unbearably complex task
of actually using it to render text, which means shaping - taking the text and
splitting it out into individual glyphs from one or more fonts and laying them
out. This task is simple enough for western character sets that you can ignore
it (and people often do) but the moment you've got customers overseas the risk
increases that you will suddenly have to do a ton of work.

Unfortunately, the main good shapers out there I'm aware of are either built
to be used with FreeType or are built for a specific OS and its platform-
specific font infrastructure. I'd love to see a lightweight shaper to go with
a library like libschrift. Anyone run across one before?

~~~
jchw
Don’t forget layout; Freetype + HarfBuzz + FreeBiDi seems to be the defacto
combination. Of all the things I want rewrite-it-in-Rust alternatives, these
are probably the things I want the most. (I am aware of RustType; certainly
it’s a start.)

~~~
floatboth
Also
[https://github.com/yeslogic/allsorts](https://github.com/yeslogic/allsorts)
[https://github.com/RazrFalcon/rustybuzz](https://github.com/RazrFalcon/rustybuzz)

------
davedx
"libschrift isn't ready for serious use yet.

Most notably, compound glyph support is still missing, so some characters like
Umlauts or accents will likely not work yet."

Isn't this necessary for quite a lot of non-Latin scripts?

~~~
outadoc
It's necessary for quite a lot of Latin scripts.

~~~
flohofwoe
At least umlauts also have their unique UNICODE code points and font glyphs,
and AFAIK that's true for all European languages at least, and can be handled
without special support down in the rendering engine as long as the input
string has been "preprocessed" accordingly.

~~~
HelloNurse
If by "preprocessing" the string you mean hoping that the input contains, say,
"LATIN CAPITAL LETTER U WITH GRAVE" instead of U and "COMBINING GRAVE ACCENT",
it is an unacceptable luck-based strategy. Moreover, in practice both
alternatives would be implemented in very similar ways (understanding tables
of how to adjust the accent for a given letter vs. understanding tables of how
the accented letter is decomposed into two glyphs): it's a safe assumption
that a "lightweight" library does neither.

~~~
flohofwoe
No, I mean that this replacement of U and "COMBINING GRAVE ACCENT" with a
single codepoint for "LATIN CAPITAL LETTER U WITH GRAVE" can happen in a
separate step in a separate library before that modified string is passed on
to the text rendering library. I'm not entirely sure whether this works for
"style ligatures", but it definitely works for umlauts and similar characters
in all European languages.

~~~
echeese
Yeah that sounds like something like Harfbuzz could do.

~~~
mmm_grayons
True, though at that point, you've left the domain of "lightweight" far
behind.

------
troughway
I’ve yet to see a library as easy to use and integrate as DirectWrite, and
produce output that looks that good. OS X has its own native library that is
also great but I haven’t played around with it as much.

FTs output looks so damn ugly by comparison. I have no idea why the Linux
world has accepted such terrible rendering, because it makes everything from
the OS down to every application look unprofessional.

------
bhaak
> Be reasonably secure, which especially means to not crash, leak memory /
> resources or expose major security vulnerabilities on corrupted / malicious
> / random input.

Valuable goals but getting them by using C in 2020 in a new project seems a
bit of an uphill battle.

------
maxnoe
Funny they chose a german name (Schrift = font or writing) but don't support
umlauts.

„Viele Grüße“ from Germany

------
qznc
No hinting?

Isn't that bound to be ugly? I read some stuff from Behdad Esfahbod [0],
author of Harfbuzz and thus one direct layer above Freetype. One article [1]
illustrates well how ugly "iiiiiiiiiiii" will look without hinting on LowDPI.
For HiDPI it says you need subpixel-positioned text which would be the job of
the layer above libschrift, I guess.

[0] [http://behdad.org/](http://behdad.org/) [1]
[https://docs.google.com/document/d/1wpzgGMqXgit6FBVaO76epnnF...](https://docs.google.com/document/d/1wpzgGMqXgit6FBVaO76epnnFC_rQPdVKswrDQWyqO1M/edit)

~~~
crazygringo
Hinting is only necessary on low-DPI displays and/or when there's no
antialiasing.

Given that people mostly own high-DPI displays these days with font libraries
that do antialiasing, there's essentially no need for hinting, and subpixel
rendering is more trouble than it's worth (which is why Apple removed it from
macOS once Retina displays became the norm). Supporting hinting in a new font
rendering library feels... pretty backwards-looking to me.

Granted this is a matter of subjective aesthetic opinion, but on high-DPI the
lack of hinting isn't even remotely "ugly". To the contrary, it ensures
greater fidelity to the letterform, while hinting necessarily distorts
proportions.

(Also, the example with the 'iii's has nothing to do with hinting or even
subpixel rendering [when edges of black text are in blue and red], but rather
subpixel _positioning_. Anti-aliasing alone handles subpixel positioning
perfectly well. But once again, physical subpixel positioning becomes less
important on high-DPI, though logical subpixel positioning is still very
important.)

------
jakearmitage
Do you have any performance benchmark comparing with FreeType or Blend2D?

Do you plan on adding a utility library to make working with XCB easier? e.g:
[https://venam.nixers.net/blog/unix/2018/09/02/fonts-
xcb.html](https://venam.nixers.net/blog/unix/2018/09/02/fonts-xcb.html)

------
amelius
What is wrong with freetype?

~~~
kevingadd
As a person who currently uses freetype: It's complicated, it's kinda slow,
it's buggy, and it's unsafe. It's the most popular choice for good reason but
there's definitely room for improvement. I have a couple TTF files here that
cause off-the-shelf freetype to crash in release builds but not in debug
builds...

Parts of it have aged poorly, as well - for example you might get the
impression that it offers kerning support, and while that is technically true
in practice it is not because most kerning data is not stored where FT thinks
it is, so you'll ask it for kerning data and get nothing. IIRC the solution
for kerning with freetype now is to have a shaper like harfbuzz do it for you
since the shapers understand the new kerning data.

~~~
kleiba
It's a common gut reaction to jump to a "rewrite from scratch!" because it's
more fun to start something new, but often times a serious refactoring is the
more sane alternative.

~~~
abainbridge
Libschrift is about 1000 lines of code. Freetype is about 200,000. I'm pretty
sure these projects have different aims. It is possible that refactoring
Freetype to make it meet the aims of Libschrift would be harder than starting
again.

~~~
kleiba
Yes, but note that at some point Freetype was only 1000 lines of code, too.

------
cerberusss
To compile and run on macOS:

Install XQuartz:

    
    
      $ brew cask install xquartz
    

Then run it from the terminal:

    
    
      $ open /Applications/Utilities/XQuartz.app
    

Clone libschrift from Github, then edit the file config.mk and update lines 14
and 15 as follows:

    
    
      X11INC = /opt/X11/include
      X11LIB = /opt/X11/lib
    

Then compile and run the demo:

    
    
      $ make
      $ export DISPLAY=":0"
      $ ./sftdemo
    

You should see a "Hello world" app.

------
shimst3r
I haven’t worked with C in quite a while, but this repository is beautiful and
wants me to look into the language again. Very readable to me and also well
formatted.

~~~
rkagerer
Think it's portable enough to use in embedded microcontroller environments?

~~~
userbinator
It looks like it maps the whole font file into memory and has a lot of
(probably unnecessary?) floating-point maths, both of which are going to be a
bad idea in a small embedded environment.

------
ggm
No hinting.

~~~
fsloth
Neither does OS X Quartz.

~~~
solarkraft
Does this mean Mac OS doesn't have it at all?

~~~
ggm
No, just not quartz. Microsoft and OSX have some share in hinting

------
mfabbri77
is there a small C library to read ttf glyphs geometry without the rendering
part?

~~~
flohofwoe
Check out stb_truetype.h, at the core it's a glyph rasterizer, but I guess the
code to get at the outline must be in there somewhere and would be easy to
extract (or by adding another API function).

[https://github.com/nothings/stb/blob/master/stb_truetype.h](https://github.com/nothings/stb/blob/master/stb_truetype.h)

PS: looks like it's here:

[https://github.com/nothings/stb/blob/f54acd4e13430c5122cab4c...](https://github.com/nothings/stb/blob/f54acd4e13430c5122cab4ca657705c84aa61b08/stb_truetype.h#L813-L842)

