libdragon
Loading...
Searching...
No Matches
Data Structures | Enumerations | Functions

Text layout engine. More...

Go to the source code of this file.

Data Structures

struct  rdpq_textparms_t
 Print formatting parameters. More...
 
struct  rdpq_textmetrics_t
 Metrics of formatted text. More...
 

Enumerations

enum  rdpq_textwrap_t { WRAP_NONE = 0 , WRAP_ELLIPSES = 1 , WRAP_CHAR = 2 , WRAP_WORD = 3 }
 Print formatting parameters: wrapping modes. More...
 
enum  rdpq_align_t { ALIGN_LEFT = 0 , ALIGN_CENTER = 1 , ALIGN_RIGHT = 2 }
 Print formatting parameters: horizontal alignment. More...
 
enum  rdpq_valign_t { VALIGN_TOP = 0 , VALIGN_CENTER = 1 , VALIGN_BOTTOM = 2 }
 Print formatting parameters: horizontal alignment. More...
 

Functions

void rdpq_text_register_font (uint8_t font_id, const rdpq_font_t *font)
 Register a new font into the text engine.
 
void rdpq_text_unregister_font (uint8_t font_id)
 Unregister a font from the text engine.
 
const rdpq_font_trdpq_text_get_font (uint8_t font_id)
 Get a registered font by its ID.
 
rdpq_textmetrics_t rdpq_text_printn (const rdpq_textparms_t *parms, uint8_t font_id, float x0, float y0, const char *utf8_text, int nbytes)
 Layout and render a text in a single call.
 
rdpq_textmetrics_t rdpq_text_printf (const rdpq_textparms_t *parms, uint8_t font_id, float x0, float y0, const char *utf8_fmt,...)
 Layout and render a formatted text in a single call.
 
rdpq_textmetrics_t rdpq_text_vprintf (const rdpq_textparms_t *parms, uint8_t font_id, float x0, float y0, const char *utf8_fmt, va_list va)
 Layout and render a formatted text in a single call.
 
rdpq_textmetrics_t rdpq_text_print (const rdpq_textparms_t *parms, uint8_t font_id, float x0, float y0, const char *utf8_text)
 Layout and render a text in a single call.
 

Detailed Description

Text layout engine.

Author
Giovanni Bajo giova.nosp@m.nnib.nosp@m.ajo@g.nosp@m.mail.nosp@m..com

This module contains the higher-level text printing engine. It allows to print text using multiple fonts, with different styles, and different layout rules.

There are three different modules that work together:

The most basic example requires to load and register one font, and them draw using it:

#include <libdragon.h>
enum {
FONT_ARIAL = 1
} FONTS;
int main(void) {
// Load the font and register it into the text layout engine with ID 1.
rdpq_text_register_font(FONT_ARIAL, rdpq_font_load("rom:/Arial.font64"));
while (1) {
rdpq_text_print(NULL, FONT_ARIAL, 20, 20, "Hello, world");
}
}
int dfs_init(uint32_t base_fs_loc)
Initialize the filesystem.
Definition dragonfs.c:1347
#define DFS_DEFAULT_LOCATION
Default filesystem location.
Definition dragonfs.h:62
void display_init(resolution_t res, bitdepth_t bit, uint32_t num_buffers, gamma_t gamma, filter_options_t filters)
Initialize the display to a particular resolution and bit depth.
Definition display.c:93
const resolution_t RESOLUTION_320x240
320x240 mode
Definition display.h:71
surface_t * display_get(void)
Get a display buffer for rendering.
Definition display.c:328
@ GAMMA_NONE
Uncorrected gamma, should be used by default and with assets built by libdragon tools.
Definition display.h:95
@ DEPTH_16_BPP
16 bits per pixel (5-5-5-1)
Definition display.h:86
Main include file for programs seeking to link against libdragon.
void rdpq_init()
Initialize the RDPQ library.
Definition rdpq.c:447
void rdpq_detach_show(void)
Detach the RDP from the current framebuffer, and show it on screen.
Definition rdpq_attach.c:132
void rdpq_attach_clear(const surface_t *surf_color, const surface_t *surf_z)
Attach the RDP to a surface and clear it.
Definition rdpq_attach.c:83
rdpq_font_t * rdpq_font_load(const char *fn)
Load a font from a file (.font64 format).
Definition rdpq_font.c:274
rdpq_textmetrics_t rdpq_text_print(const rdpq_textparms_t *parms, uint8_t font_id, float x0, float y0, const char *utf8_text)
Layout and render a text in a single call.
Definition rdpq_text.h:389
void rdpq_text_register_font(uint8_t font_id, const rdpq_font_t *font)
Register a new font into the text engine.
Definition rdpq_text.c:16
A surface buffer for graphics.
Definition surface.h:140

In this case, no styling or formatting rules are provided, so the text is drawn using the default style of the font (which is full white). The text is drawn starting at position (20, 20) in the screen.

The whole text engine has been designed around the UTF-8 encoding format, and only supports that encoding. If you have text in a different encoding make sure to convert it to UTF-8 before feeding it to rdpq_text_print functions.

There are three main functions to print text:

Wrapping lines

To draw longer texts that don't fit in a single line, you can use the advanced layout rules provided by rdpq_textparms_t. For instance, this will draw a text with a maximum width of 200 pixels, and will perform word-wrapping:

char *text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
.width = 200, // maximum width of the paragraph
.wrap = WRAP_WORD // wrap at word boundaries
}, FONT_ARIAL, 20, 20, text);
@ WRAP_WORD
Wrap at word boundaries.
Definition rdpq_text.h:199
Print formatting parameters.
Definition rdpq_text.h:221

There are four wrapping modes available:

Wrapping modes require a maximum width to be specified in the parameters, otherwise the layout engine will not know where to wrap the text.

Print functions will also respect embedded newlines (
); in this case, specifying a width is not required.

Multi-style text

It is possible to change font and/or style within a text using escape codes. Escape codes are sequences of the form:

$xx Select font "xx", where "xx" is the hexadecimal ID of the font For instance, $04 will switch to font 4. The current style is reset to 0. ^xx Switch to style "xx" of the current font, where "xx" is the hexadecimal ID of the style. For instance, ^02 will switch to style 2. A "style" is an font-dependent rendering style, which can be anything (a color, a faux-italic variant, etc.). The styles available for each font can be configured via rdpq_font_style.

See also rdpq_text_printn for more information.

Example 4: multi-color text

.color = .RGBA32(255, 255, 255, 255),
});
.color = .RGBA32(255, 0, 0, 255),
});
.color = .RGBA32(0, 255, 0, 255),
});
.color = .RGBA32(0, 0, 255, 255),
});
.color = .RGBA32(255, 0, 255, 255),
});
rdpq_text_print(NULL, FONT_ARIAL, 20, 20,
"Hello, ^01world^00! ^02This^00 is ^03a^00 ^04test^00.");
void rdpq_font_style(rdpq_font_t *fnt, uint8_t style_id, const rdpq_fontstyle_t *style)
Create a style for a font.
Definition rdpq_font.c:399
A style for a font.
Definition rdpq_font.h:121

Other examples

Example 3: draw the text with a transparent box behind it

// First, calculate the layout of the text
rdpq_paragraph_t *layout = rdpq_text_layout(&(text_parms_t) {
.width = 200, // maximum width of the paragraph
.height = 150, // maximum height of the paragraph
.wrap = WRAP_WORD // wrap at word boundaries
}, FONT_ARIAL, text);
// Draw the box
const int margin = 10;
const float x0 = 20;
const float y0 = 20;
rdpq_set_fill_color(RGBA32(120, 63, 32, 255));
rdpq_set_fog_color(RGBA32(255, 255, 255, 128));
rdpq_mode_blender(RDPQ_BLEND_MULTIPLY_CONST);
x0 - margin - layout->bbox.x0,
y0 - margin - layout->bbox.y0,
x0 + margin + layout->bbox.x1,
y0 + margin + layout->bbox.y1
);
// Render the text
rdpq_text_layout_render(layout, x0, y0);
// Free the layout
rdpq_text_layout_free(layout);
#define RGBA32(rx, gx, bx, ax)
Create a color_t from the R,G,B,A components in the RGBA32 range (0-255).
Definition graphics.h:96
void rdpq_set_fill_color(color_t color)
Enqueue a SET_FILL_COLOR RDP command.
Definition rdpq.h:839
void rdpq_set_fog_color(color_t color)
Set the RDP FOG blender register.
Definition rdpq.h:891
void rdpq_mode_blender(rdpq_blender_t blend)
Configure the formula to use for blending.
Definition rdpq_mode.h:602
void rdpq_set_mode_standard(void)
Reset render mode to standard.
Definition rdpq_mode.c:98
float y0
Alignment offset of the text.
Definition rdpq_paragraph.h:85
struct rdpq_paragraph_t::@65 bbox
Bounding box of the text, relative to the drawing position.
A paragraph of text, fully laid out.
Definition rdpq_paragraph.h:73
#define rdpq_fill_rectangle(x0, y0, x1, y1)
Draw a filled rectangle (RDP command: FILL_RECTANGLE)
Definition rdpq_rect.h:251

Data Structure Documentation

◆ rdpq_textparms_t

struct rdpq_textparms_t

Print formatting parameters.

Data Fields
int16_t style_id Initial style ID for the text.
int16_t width Maximum horizontal width of the paragraph, in pixels (0 if unbounded)
int16_t height Maximum vertical height of the paragraph, in pixels (0 if unbounded)
rdpq_align_t align Horizontal alignment (0=left, 1=center, 2=right)
rdpq_valign_t valign Vertical alignment (0=top, 1=center, 2=bottom)
int16_t indent Indentation of the first line, in pixels (only valid for left alignment)
int16_t max_chars Maximum number of characters to print (0 if unbounded), useful for typewriting effect.
int16_t char_spacing Extra spacing between chars (in addition to glyph width and kerning)
int16_t line_spacing Extra spacing between lines (in addition to font height)
rdpq_textwrap_t wrap Wrap mode.
int16_t * tabstops Array of tab stops, in pixels (0-terminated). If NULL, tab stops are every 32 pixels.
bool disable_aa_fix Obtain a small rendering speedup by disabling the anti-aliasing fix. Can be enabled when anti-alias is disabled in display_init. (see RDPQ_PARAGRAPH_FLAG_ANTIALIAS_FIX for more details).
bool preserve_overlap Preserve overlapping glyphs when rendering. Notice that this might have a strong performance impact because it forces left-to-right rendering, which means that texture loading can't be optimized.

◆ rdpq_textmetrics_t

struct rdpq_textmetrics_t

Metrics of formatted text.

Data Fields
float advance_x X pen advance after rendering the text.
float advance_y Y pen advance after rendering the text.
int utf8_text_advance Number of bytes rendered in the UTF-8 text.
int nlines Number of lines rendered (including wrapped lines)

Enumeration Type Documentation

◆ rdpq_textwrap_t

Print formatting parameters: wrapping modes.

These modes take effect on each line that doesn't fit the width provided in rdpq_textparms_t. If no width is specified, the text is never wrapped, not even on the border of the screen.

Enumerator
WRAP_NONE 

Truncate the text (if any)

WRAP_ELLIPSES 

Truncate the text adding ellipsis (if any)

WRAP_CHAR 

Wrap at character boundaries.

WRAP_WORD 

Wrap at word boundaries.

◆ rdpq_align_t

Print formatting parameters: horizontal alignment.

Enumerator
ALIGN_LEFT 

Left alignment.

ALIGN_CENTER 

Center alignment.

ALIGN_RIGHT 

Right alignment.

◆ rdpq_valign_t

Print formatting parameters: horizontal alignment.

Enumerator
VALIGN_TOP 

Top alignment.

VALIGN_CENTER 

Center alignment.

VALIGN_BOTTOM 

Vertical alignment.

Function Documentation

◆ rdpq_text_register_font()

void rdpq_text_register_font ( uint8_t  font_id,
const rdpq_font_t font 
)

Register a new font into the text engine.

After this call, the font is available to be used by the text engine for layout and render. If font_id is already registered, this function will fail by asserting.

Parameters
font_idFont ID
fontFont to register
Note
Font ID 0 is reserved and cannot be used.

◆ rdpq_text_unregister_font()

void rdpq_text_unregister_font ( uint8_t  font_id)

Unregister a font from the text engine.

This call will remove the font that was previously registered with font_id from the text engine. Afterwards, font_id can be used again to register other fonts. If font_id is not registered, this function will fail by asserting.

Parameters
font_idFont ID
Note
Font ID 0 is reserved and cannot be used.

◆ rdpq_text_get_font()

const rdpq_font_t * rdpq_text_get_font ( uint8_t  font_id)

Get a registered font by its ID.

Parameters
font_idFont ID
Returns
const rdpq_font_t* Registered font or NULL

◆ rdpq_text_printn()

rdpq_textmetrics_t rdpq_text_printn ( const rdpq_textparms_t parms,
uint8_t  font_id,
float  x0,
float  y0,
const char *  utf8_text,
int  nbytes 
)

Layout and render a text in a single call.

This function accepts UTF-8 encoded text. It will layout the text according to the parameters provided in rdpq_textparms_t, and then render it at the specified coordinates.

The text is layout and rendered using the specified font by default (using its default style 0), but it can contain special escape codes to change the font or its style.

Escape codes are sequences of the form:

$xx Select font "xx", where "xx" is the hexadecimal ID of the font For instance, $04 will switch to font 4. The current style is reset to 0. ^xx Switch to style "xx" of the current font, where "xx" is the hexadecimal ID of the style. For instance, ^02 will switch to style 2. A "style" is an font-dependent rendering style, which can be anything (a color, a faux-italic variant, etc.). It is up the the font to define what styles are available.

To use a stray "$" or "^" character in the text, you can escape it by repeating them twice: "$$" or "^^".

The specified position refers to the "baseline" of the text. This is the line upon which the various glyphs are laid out (just like the line on a handwriting paper); each glyph will extend above or even below the baseline, depending on how the font has been designed.

The return value is the number of bytes printed, and can be useful to provide a pagination system (as the caller will be able to know where the next page would start). Notice that if you ask for horizontal line truncation (via WRAP_NONE or WRAP_ELLIPSES), those lines will be counted as fully printed anyway (so that pagination works as expected).

Parameters
parmsLayout parameters (see rdpq_textparms_t)
font_idFont ID to use to render the text (at least initially; it can modified via escape codes). The initial style will be style 0.
x0X coordinate where to start rendering the text (baseline)
y0Y coordinate where to start rendering the text (baseline)
utf8_textText to render, in UTF-8 encoding. Does not need to be NULL terminated.
nbytesNumber of bytes in the text to render
Returns
int Number of bytes printed
See also
rdpq_text_printf
rdpq_text_print
rdpq_textparms_t

◆ rdpq_text_printf()

rdpq_textmetrics_t rdpq_text_printf ( const rdpq_textparms_t parms,
uint8_t  font_id,
float  x0,
float  y0,
const char *  utf8_fmt,
  ... 
)

Layout and render a formatted text in a single call.

This function is similar to rdpq_text_print, but it accepts a printf-like format string. The format string is expected to be UTF-8 encoded.

Parameters
parmsLayout parameters
font_idFont ID to use to render the text (at least initially; it can modified via escape codes). The initial style will be style 0.
x0X coordinate where to start rendering the text
y0Y coordinate where to start rendering the text
utf8_fmtFormat string, in UTF-8 encoding
Returns
int Number of bytes printed

◆ rdpq_text_vprintf()

rdpq_textmetrics_t rdpq_text_vprintf ( const rdpq_textparms_t parms,
uint8_t  font_id,
float  x0,
float  y0,
const char *  utf8_fmt,
va_list  va 
)

Layout and render a formatted text in a single call.

This function is similar to rdpq_text_printf, but it accepts a va_list argument list, similar to vsprintf. The format string is expected to be UTF-8 encoded.

Parameters
parmsLayout parameters
font_idFont ID to use to render the text (at least initially; it can modified via escape codes). The initial style will be style 0.
x0X coordinate where to start rendering the text
y0Y coordinate where to start rendering the text
utf8_fmtFormat string, in UTF-8 encoding
vaArgument list
Returns
rdpq_textmetrics_t Metrics of the text

◆ rdpq_text_print()

rdpq_textmetrics_t rdpq_text_print ( const rdpq_textparms_t parms,
uint8_t  font_id,
float  x0,
float  y0,
const char *  utf8_text 
)
inline

Layout and render a text in a single call.

This function is similar to rdpq_text_print, but it accepts a UTF-8 encoded, NULL-terminated string.

Parameters
parmsLayout parameters
font_idFont ID to use to render the text (at least initially; it can modified via escape codes). The initial style will be style 0.
x0X coordinate where to start rendering the text
y0Y coordinate where to start rendering the text
utf8_textText to render, in UTF-8 encoding, NULL terminated.
Returns
int Number of bytes printed