Slow text rendering in Scalable Screen Font
Slow text rendering in Scalable Screen Font
Hi.
I output many lines of text on my screen using Scalable Screen Font.
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.
I output many lines of text on my screen using Scalable Screen Font.
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.
Re: Slow text rendering in Scalable Screen Font
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.
I'd actually suggest that most of code should be tested and debugged this way until your own OS can do it too.
Re: Slow text rendering in Scalable Screen Font
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.
Re: Slow text rendering in Scalable Screen Font
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.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.
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.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.
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];
}
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
Re: Slow text rendering in Scalable Screen Font
Thanks. Now I cache the characters and they are drawn quickly.bzt wrote: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.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.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.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.
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.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.Code: Select all
if (glyphcache[idx] == NULL) { glyph = glyphcache[idx] = ssfn_render(&ctx, idx); } else { glyph = glyphcache[idx]; }
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
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.
Re: Slow text rendering in Scalable Screen Font
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.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.
The simplest is to have separate small raster fonts for each size.
Re: Slow text rendering in Scalable Screen Font
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.alexfru wrote: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.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.
The simplest is to have separate small raster fonts for each size.
Re: Slow text rendering in Scalable Screen Font
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.mrjbom wrote:Tell me, how can I improve the rendering quality?
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
Re: Slow text rendering in Scalable Screen Font
This helped me, now the small characters look much better.(Top line.)bzt wrote:One thing that would considerably improve quality is to render to alpha channel. That allows anti-aliasing, which results in better looking glyphs.mrjbom wrote:Tell me, how can I improve the rendering quality?
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.
Re: Slow text rendering in Scalable Screen Font
Are you drawing in white on black background only?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?
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:
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
Re: Slow text rendering in Scalable Screen Font
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.BenLunt wrote:Notice that there are other colored pixels around the black pixels. I don't remember what this is called
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.
Re: Slow text rendering in Scalable Screen Font
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.BenLunt wrote:Are you drawing in white on black background only?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?
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:
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
Re: Slow text rendering in Scalable Screen Font
I'm afraid you'll have to port freetype2 that Linux uses or you'll have to wait for SSFN 2.0.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.
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
Re: Slow text rendering in Scalable Screen Font
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.bzt wrote:I'm afraid you'll have to port freetype2 that Linux uses or you'll have to wait for SSFN 2.0.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.
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