Slow text rendering in Scalable Screen Font

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Slow text rendering in Scalable Screen Font

Post by mrjbom »

Hi.
I output many lines of text on my screen using Scalable Screen Font.
Image

I noticed that when trying to draw a few lines of text, it is drawn very slowly. And this is present on all emulators, as well as on a real computer.
I also noticed that memory functions are called more than 7000 times, is this normal for the library?
I can't quite figure out if I need to look for problems in the memory manager or somewhere else.
Thanks.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Slow text rendering in Scalable Screen Font

Post by alexfru »

How about you make it portable and profile in your regular OS with regular tools?
I'd actually suggest that most of code should be tested and debugged this way until your own OS can do it too.
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Slow text rendering in Scalable Screen Font

Post by mrjbom »

Absolutely this is a problem with my self-written memory Manager. Well, I'm not capable of writing such complex things. You will have to use someone else's memory manager, maybe so it will work as it should.
Last edited by mrjbom on Wed Apr 29, 2020 7:51 am, edited 1 time in total.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Slow text rendering in Scalable Screen Font

Post by bzt »

alexfru wrote:How about you make it portable and profile in your regular OS with regular tools?
I'd actually suggest that most of code should be tested and debugged this way until your own OS can do it too.
A big plus on this! SSFN was made portable (relies on a pixel buffer and libc only) and there are several tests for this very reason. I ran those tests through valgrind, strace etc. on a Linux box, I suggest you to do the same with your code.
mrjbom wrote:I noticed that when trying to draw a few lines of text, it is drawn very slowly. And this is present on all emulators, as well as on a real computer.
I also noticed that memory functions are called more than 7000 times, is this normal for the library?
I can't quite figure out if I need to look for problems in the memory manager or somewhere else.
Thanks.
Yes. I have tried to minimize (re)allocation of memory, but there are many arrays to be kept track of when rasterising vector images. Outlines, even-odd pairs, one array per raster line, coloumns for counting pixels to detect hinting grid etc. For this reason you should cache the returned glyph and reuse whenever you can.

If you're using the same style and size for the font, you only need to render each glyph once. You should clear the glyph cache when you call ssfn_select to change the typeface, otherwise reuse them as much as possible. The API is designed in a way to make this easy: the returned glyph is a single byte array without pointers, contains only bitmap or alpha channel (without the actual foreground color), and kerning is implemented in a separate function, independently to the rasterizer etc.

For example, you could have an array of pointers to the glyphs, indexed by the UNICODE code point.

Code: Select all

if (glyphcache[idx] == NULL) {
    glyph = glyphcache[idx] = ssfn_render(&ctx, idx);
} else {
    glyph = glyphcache[idx];
}
Of course this is the simplest method. With 16 bit code points on 32 bit arch, this would require 256k additional memory. If that's too much, or if you want to handle all the more than one million code points, then you can implement a b-tree or a hash bucket list, etc. to look up the cached glyphs.

Another solution would be to use a font with bitmap glyphs and render that with ssfn_putc. That simple renderer was designed to be called many many times repeatedly, and it does not allocate any extra memory at all. The price for speed is that it cannot scale glyphs.

Cheers,
bzt
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Slow text rendering in Scalable Screen Font

Post by mrjbom »

bzt wrote:
alexfru wrote:How about you make it portable and profile in your regular OS with regular tools?
I'd actually suggest that most of code should be tested and debugged this way until your own OS can do it too.
A big plus on this! SSFN was made portable (relies on a pixel buffer and libc only) and there are several tests for this very reason. I ran those tests through valgrind, strace etc. on a Linux box, I suggest you to do the same with your code.
mrjbom wrote:I noticed that when trying to draw a few lines of text, it is drawn very slowly. And this is present on all emulators, as well as on a real computer.
I also noticed that memory functions are called more than 7000 times, is this normal for the library?
I can't quite figure out if I need to look for problems in the memory manager or somewhere else.
Thanks.
Yes. I have tried to minimize (re)allocation of memory, but there are many arrays to be kept track of when rasterising vector images. Outlines, even-odd pairs, one array per raster line, coloumns for counting pixels to detect hinting grid etc. For this reason you should cache the returned glyph and reuse whenever you can.

If you're using the same style and size for the font, you only need to render each glyph once. You should clear the glyph cache when you call ssfn_select to change the typeface, otherwise reuse them as much as possible. The API is designed in a way to make this easy: the returned glyph is a single byte array without pointers, contains only bitmap or alpha channel (without the actual foreground color), and kerning is implemented in a separate function, independently to the rasterizer etc.

For example, you could have an array of pointers to the glyphs, indexed by the UNICODE code point.

Code: Select all

if (glyphcache[idx] == NULL) {
    glyph = glyphcache[idx] = ssfn_render(&ctx, idx);
} else {
    glyph = glyphcache[idx];
}
Of course this is the simplest method. With 16 bit code points on 32 bit arch, this would require 256k additional memory. If that's too much, or if you want to handle all the more than one million code points, then you can implement a b-tree or a hash bucket list, etc. to look up the cached glyphs.

Another solution would be to use a font with bitmap glyphs and render that with ssfn_putc. That simple renderer was designed to be called many many times repeatedly, and it does not allocate any extra memory at all. The price for speed is that it cannot scale glyphs.

Cheers,
bzt
Thanks. Now I cache the characters and they are drawn quickly.

I don't want to create a new topic for this question.
Tell me, how can I improve the rendering quality?
For example, I draw text size 24 on a screen size 1280 * 1024, but to get the text of normal quality, you have to draw large characters (from 32), and this takes up a lot of space on the screen.
Image
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Slow text rendering in Scalable Screen Font

Post by alexfru »

mrjbom wrote: Tell me, how can I improve the rendering quality?
For example, I draw text size 24 on a screen size 1280 * 1024, but to get the text of normal quality, you have to draw large characters (from 32), and this takes up a lot of space on the screen.
AFAIR, with TrueType and similar vector fonts, it's very tricky to render characters of small size that look reasonably good, not just unambiguous. Also, some of the methods for that have been patented.
The simplest is to have separate small raster fonts for each size.
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Slow text rendering in Scalable Screen Font

Post by mrjbom »

alexfru wrote:
mrjbom wrote: Tell me, how can I improve the rendering quality?
For example, I draw text size 24 on a screen size 1280 * 1024, but to get the text of normal quality, you have to draw large characters (from 32), and this takes up a lot of space on the screen.
AFAIR, with TrueType and similar vector fonts, it's very tricky to render characters of small size that look reasonably good, not just unambiguous. Also, some of the methods for that have been patented.
The simplest is to have separate small raster fonts for each size.
This is bad. Not that I can't draw small letters that don't look so bad? Making a separate font for each size is extremely expensive. What can I do to get smooth small letters? Like in linux.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Slow text rendering in Scalable Screen Font

Post by bzt »

mrjbom wrote:Tell me, how can I improve the rendering quality?
One thing that would considerably improve quality is to render to alpha channel. That allows anti-aliasing, which results in better looking glyphs. But as @alexfru said, rendering into really small (less than 24 pixels) is tricky, no reasonable Open Source solution exists, and even worse, good algorithms are patented :-( SSFN tries to solve this by auto-hinting, aka. stretching the vector coordinate system of the curves so that all non-control points fit on a discrete point of the grid system. This is a very simple and straightforward solution, easy to implement in 20k of code, but does not yield as good looking glyphs as the Microsoft patented Cleartype algorithm.

Another solution, also mentioned by @alexfru, is to use bitmap fonts for small text. Using bit2sfn you can convert any PSFU/PSF2 font or BDF X11 Bitmap font into SSFN out-of-the-box. On a Linux system, you can find PSF2 fonts under /usr/share/kbd/consolefonts (used by the Linux Console typically on tty1-tty6), and X11 fonts under /usr/share/fonts. It worth noting that X11 uses an endianness-native binary for the fonts, so called PCF format (.pcf.gz). You can convert those to the architecture-independent distribution format using pcf2bdf which typically can be found in the x11-fonts package. When you download fonts from the internet (for example from here or here), then it is more than likely you will download bdf files. Industry-grade font editors (like FontForge) can also import/export bdf. The command line otf2bdf tool can rasterize a vector font in a given pixel size into bdf.

Cheers,
bzt
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Slow text rendering in Scalable Screen Font

Post by mrjbom »

bzt wrote:
mrjbom wrote:Tell me, how can I improve the rendering quality?
One thing that would considerably improve quality is to render to alpha channel. That allows anti-aliasing, which results in better looking glyphs.
This helped me, now the small characters look much better.(Top line.)
Image
But it still doesn't look as good as in other systems. How can I make the text even better? Can I replace the font or something?

In addition, glyph->h is still extremely large compared to glyph->w, so using \n is not possible, because the new line will be moved too far down.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: Slow text rendering in Scalable Screen Font

Post by BenLunt »

mrjbom wrote:But it still doesn't look as good as in other systems. How can I make the text even better? Can I replace the font or something?
Are you drawing in white on black background only?

Here is a very good example of how to make your fonts look better:

Go to https://fonts.google.com/specimen/Space ... ype=custom and zoom in.
(The best way to zoom in is to grab a screen shot and then zoom in on the screen shot.)

Here is a quick zoom of part of that screen:
Image

Notice that there are other colored pixels around the black pixels. I don't remember what this is called, @bzt should be able to tell you, but this is why the fonts look better on these kind of systems.

A quick research should remind me what this is called, dithering, or something like that, but don't have the time to go look.

Ben
- http://www.fysnet.net/osdesign_book_series.htm
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: Slow text rendering in Scalable Screen Font

Post by klange »

BenLunt wrote:Notice that there are other colored pixels around the black pixels. I don't remember what this is called
This is subpixel antialiasing, and whether it looks better or not will depend on your display. Subpixel antialiasing can easily lead to color fringing, suffers from a lot of complication with different subpixel layouts (especially with modern displays that aren't linearly arranged RGB/BGR pixels) and fails when pre-rasterized text is scaled (such as when displaying screen animations or zooming with a magnification tool). Apple notably abandoned subpixel antialiasing in recent versions of macOS.

The biggest problem with mrjbom's text is that it has no antiliasing and isn't using fonts specifically designed to be rasterized fully-aliased like those that shipped with Windows. Even just grayscale antialiasing should produce a notable improvement in the visual quality of the text, though from bzt's sample images for ssfn I get the feeling its antialiasing may still look a bit rough.
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Slow text rendering in Scalable Screen Font

Post by mrjbom »

BenLunt wrote:
mrjbom wrote:But it still doesn't look as good as in other systems. How can I make the text even better? Can I replace the font or something?
Are you drawing in white on black background only?

Here is a very good example of how to make your fonts look better:

Go to https://fonts.google.com/specimen/Space ... ype=custom and zoom in.
(The best way to zoom in is to grab a screen shot and then zoom in on the screen shot.)

Here is a quick zoom of part of that screen:
Image

Notice that there are other colored pixels around the black pixels. I don't remember what this is called, @bzt should be able to tell you, but this is why the fonts look better on these kind of systems.

A quick research should remind me what this is called, dithering, or something like that, but don't have the time to go look.

Ben
- http://www.fysnet.net/osdesign_book_series.htm
I understand you're talking about smoothing. bzt has already advised me to use pixels with an alpha channel so that their edges are smoothed. I have successfully used this modality, it has improved the quality of the text, but it still lags far behind those used in linux. I hope that bzt will tell me how I can make the text even more beautiful.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Slow text rendering in Scalable Screen Font

Post by bzt »

mrjbom wrote:I have successfully used this modality, it has improved the quality of the text, but it still lags far behind those used in linux. I hope that bzt will tell me how I can make the text even more beautiful.
I'm afraid you'll have to port freetype2 that Linux uses or you'll have to wait for SSFN 2.0.

Please note that freetype2 is huge (1M in size), and contains lots of complicated and dependency-heavy solutions (requires libm, libpng, libpthread, libgraphite, libbz2, libpcre etc. etc. etc). You'll have to have floating-point support in your kernel and port all of these library dependencies as well if you want to use freetype2.

SSFN on the other hand is targeted at embedded systems and therefore approx. 20k in size, uses integer-arithmetic only and has one single libc dependency. Obviously for these restrictions it must have a much much simpler algorithm than freetype2. But I'm not satisfied with this, so right now I'm experimenting with better looking rasterization methods without significantly increasing the complexity and the memory requirement. Hopefully there'll be a new version available soon which you can try.

Cheers,
bzt
User avatar
mrjbom
Member
Member
Posts: 317
Joined: Sun Jul 21, 2019 7:34 am

Re: Slow text rendering in Scalable Screen Font

Post by mrjbom »

bzt wrote:
mrjbom wrote:I have successfully used this modality, it has improved the quality of the text, but it still lags far behind those used in linux. I hope that bzt will tell me how I can make the text even more beautiful.
I'm afraid you'll have to port freetype2 that Linux uses or you'll have to wait for SSFN 2.0.

Please note that freetype2 is huge (1M in size), and contains lots of complicated and dependency-heavy solutions (requires libm, libpng, libpthread, libgraphite, libbz2, libpcre etc. etc. etc). You'll have to have floating-point support in your kernel and port all of these library dependencies as well if you want to use freetype2.

SSFN on the other hand is targeted at embedded systems and therefore approx. 20k in size, uses integer-arithmetic only and has one single libc dependency. Obviously for these restrictions it must have a much much simpler algorithm than freetype2. But I'm not satisfied with this, so right now I'm experimenting with better looking rasterization methods without significantly increasing the complexity and the memory requirement. Hopefully there'll be a new version available soon which you can try.

Cheers,
bzt
I will wait for SSFN 2.0, I hope you will succeed. I would also like you to check this issue in your gitlab. Thanks.
Post Reply