Scalable Screen Font: Difference between revisions

Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
m Added text directions
Line 37: Line 37:
== Normal Renderer ==
== Normal Renderer ==


There's another for user space applications. This one can render all three types of fonts, it can scale, antialias, autohint and kern glyphs. Has minimal libc dependencies (memset, memcmp, realloc, free) and compiles to about 21 kilobytes of code.
There's another for user space applications. This one can render all three types of fonts, it can scale, antialias, autohint and kern glyphs. Has minimal libc dependencies (memset, memcmp, realloc, free) and compiles to about 22 kilobytes of code.


<source lang="c">
<source lang="c">
Line 77: Line 77:
free(glyph); /* no special treatment for freeing glyphs */
free(glyph); /* no special treatment for freeing glyphs */
ssfn_free(&ctx); /* free the renderer context's internal buffers */
ssfn_free(&ctx); /* free the renderer context's internal buffers */
</source>

=== Left-to-right text ===

This is the default. Left to right requires nothing special, only to subtract baseline and add the advance value to your current pen position.
<source lang="c">
my_draw_glyph(pen_x, pen_y - glyph->baseline, ...); /* position the glyph vertically */

pen_x += glyph->adv_x; /* adjust X for the next glyph */
</source>

=== Vertical text ===

To display vertical fonts properly, you should subtract the baseline from the X coordinate before you draw.
<source lang="c">
my_draw_glyph(pen_x - glyph->baseline, pen_y, ...); /* position the glyph horizontally */

pen_y += glyph->adv_y; /* adjust the Y coordinate this time */
</source>

=== Right-to-left text ===

It is not as simple as one would think, because it's not enough to know if the given UNICODE character belongs to a right-to-left scripting system, BiDi requires a minimal state machine too. That has to be implemented in the text renderer (or text shaping library) that's built on top of the low level rasterizer. The [http://www.unicode.org/reports/tr9/ algorithm to properly display bidirectional texts] is specified by UNICODE. But once you have decided that you need to draw a glyph in right-to-left direction, these are the required steps:
<source lang="c">
my_draw_glyph(pen_x - glyph->w, pen_y, ...); /* subtract the glyph's width first */

pen_x -= glyph->adv_x; /* and subtract the advance instead of adding */
</source>

Putting every direction variations all together:
<source lang="c">
if(glyph->adv_y) { /* things to temporarily adjust before drawing */
x = pen_x - glyph->baseline;
y = pen_y;
} else {
x = pen_x;
y = pen_y - glyph->baseline;
}
if(rtl)
x -= glyph->w;

my_draw_glyph(x, y, ...);

if(rtl) /* set up cursor position for the next glyph */
pen_x -= glyph->adv_x;
else
pen_x += glyph->adv_x;
pen_y += glyph->adv_y;
</source>
</source>