Text
----
Text drawing is controlled by the <<text_style,gp_text_style>> structure. This
structure carries information about font, letter spacing and pixel
multiplication and spacing. (If no font is specified, the default mono-space
font is used.)

You may want to see the link:coordinate_system.html[coordinate system] first.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text.h>

/* Where the text should be drawn relatively to the specified point */
typedef enum gp_text_align {
        GP_ALIGN_LEFT = 0x01,           /* to the left from the point */
        GP_ALIGN_CENTER = 0x02,         /* centered on the point */
        GP_ALIGN_RIGHT = 0x03,          /* to the right from the point */
        GP_TEXT_BEARING = 0x04,         /* apply bearing at string start */
        GP_VALIGN_ABOVE = 0x10,         /* above the point */
        GP_VALIGN_CENTER = 0x20,        /* centered on the point */
        GP_VALIGN_BASELINE = 0x30,      /* baseline is on the point */
        GP_VALIGN_BELOW = 0x40          /* below the point */
} gp_text_align;

void gp_text(gp_pixmap *pixmap, const gp_text_style *style,
             gp_coord x, gp_coord y, int align,
             gp_pixel fg, gp_pixel bg, const char *str);


gp_size gp_print(gp_pixmap *pixmap, const gp_text_style *style,
                 gp_coord x, gp_coord y, int align,
                 gp_pixel fg, gp_pixel bg, const char *fmt, ...);

gp_size gp_vprint(gp_pixmap *pixmap, const gp_text_style *style,
                  gp_coord x, gp_coord y, int align,
                  gp_pixel fg, gp_pixel bg,
                  const char *fmt, va_list va);
--------------------------------------------------------------------------------

Draws text at the position x and y; the alignment of the text in relation
to the point is specified by alignment flags.

The 'GP_TEXT_BEARING', if passed, causes the text horizontal bearing to be
applied before we start to draw first letter.

If the 'style' argument is NULL, a default style is used.

The text size can be computed by following functions:

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

enum gp_text_len_type {
	/*
	 * Return bounding box, i.e. for the last letter return the greater of
	 * advance and letter width. This makes sure that the resulting size
	 * will fit the text.
	 */
	GP_TEXT_LEN_BBOX,
	/*
	 * Returns advance, i.e. where next letter would start after a string
	 * would have been printed. This may return slightly less than the
	 * GP_TEXT_LEN_BBOX.
	 */
	GP_TEXT_LEN_ADVANCE,
};

gp_size gp_text_width_len(const gp_text_style *style, enum gp_text_len_type type,
                          const char *str, size_t len);

gp_size gp_text_wbbox_len(const gp_text_style *style, const char *str, size_t len);

gp_size gp_text_width(const gp_text_style *style, enum gp_text_len_type type, const char *str);

gp_size gp_text_wbbox(const gp_text_style *style, const char *str)
--------------------------------------------------------------------------------

Returns the width (in pixels) that would be occupied by the string if rendered
using the specified style.

Computing a length of a given string is more complicated than it appears to
be. The first letter needs 'advance - bearing' pixels. The middle letters
needs 'advance' pixels and 'bearing' of the previous one. The last letter
needs different treatement based on if we need a bounding box, or advance i.e.
exact place where the next letter should start at.

See
link:images/fonts/glyph_metrics.png[Glyph Metrics] for a description of the
terms used in this paragraph.

The 'gp_text_wbbox*()' functions are shortand for 'gp_text_width*()' with
'GP_TEXT_LEN_BBOX'.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

gp_size gp_text_max_width(const gp_text_style *style, unsigned int len);
--------------------------------------------------------------------------------

Returns maximum text width, in pixels, for string with 'len' letters.

This call simply computes width of a string rendered with 'len' largest glyphs
(letters) in the font. Because of this the resulting size is often much larger
than needed.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

gp_size gp_text_max_width_chars(const gp_text_style *style, const char *chars, unsigned int len);
--------------------------------------------------------------------------------

Returns maximum text width, in pixels, for string composing letters only from
'chars' string with 'len' letters.

This call simply computes width of a string rendered with 'len' largest glyphs
(letters) from the chars string given a font.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

gp_size gp_text_avg_width(const gp_text_style *style, unsigned int len);
--------------------------------------------------------------------------------

Returns average text width, in pixels, for string with 'len' letters.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

gp_size gp_text_max_str_width(const gp_text_style *style, const char *str,
                              unsigned int len);
--------------------------------------------------------------------------------

Returns maximum text width, in pixels, for a string with 'len' letters that
are composed only of letters from 'str'.

This call simply computes width of a string rendered with largest letter from
'str' and with 'len' characters.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

unsigned int gp_text_ascent(const gp_text_style *style);
--------------------------------------------------------------------------------

The Ascent is the height in pixels from the top to the baseline.

The baseline is imaginary line that letters are positioned upon and the ascent
is usually height of capital letter, but it may be larger for certain fonts.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

unsigned int gp_text_descent(const gp_text_style *style);
--------------------------------------------------------------------------------

The Descent is the height in pixels from baseline to the bottom.

The baseline is imaginary line that letters are positioned upon and the
descent is usually height of upper part of the letter y that goes under the
baseline, but it may be larger for certain fonts.

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_metric.h>

unsigned int gp_text_height(const gp_text_style *style);
--------------------------------------------------------------------------------

The Height is size of the font from top to the bottom, i.e. equals exactly to
the sum of ascent and descent.

This simply returns height that is needed to draw a line of a text using a
certain font style (without the spacing between the lines).

[[TextStyle]]
TextStyle
~~~~~~~~~

[source,c]
--------------------------------------------------------------------------------
#include <gfxprim.h>
/* or */
#include <text/gp_text_style.h>

typedef struct gp_text_style {
	const struct gp_font_face *font;

	/* Spacing between pixels (0 is the default, no spacing). */
	int pixel_xspace, pixel_yspace;

	/* Multiplier of pixel width/height (1 is default). */
	int pixel_xmul, pixel_ymul;

	/* Extra spacing (in pixels) between characters. */
	int char_xspace;

} gp_text_style;
--------------------------------------------------------------------------------

The TextStyle structure describes the parameters for text rendering.

The first parameter is font being used.
TODO: link to font format and description.

The 'xspace' and 'yspace' parameters controls spacing between the pixels and
the 'xmul' and 'ymul' describes pixel multiplication in respective directions.

The 'char_xspace' is used to add additional space between letters.

.Default Console Font xmul=ymul=1 xspace=yspace=0
image::images/fonts/default_console_font.png["Default Console Font"]

.Default Console Font xmul=ymul=2 xspace=yspace=-1
image::images/fonts/default_console_font_embolding.png["Default Console Font"]

.Default Console Font xmul=ymul=2 xspace=yspace=1
image::images/fonts/default_console_font_big.png["Default Console Font"]


Compiled-in Fonts
~~~~~~~~~~~~~~~~~

There is a global constant pointer to each compiled-in font structure, see
'include/text/GP_Fonts.h'.

.Default Console Font
image::images/fonts/default_console_font.png["Default Console Font"]

.Default Proportional Font
image::images/fonts/default_proportional_font.png["Default Proportional Font"]

.Font Tiny Mono (gp_font_tiny_mono)
image::images/fonts/font_tiny_mono.png["Font Tiny Mono"]

.Font Tiny (gp_font_tiny)
image::images/fonts/font_tiny.png["Font Tiny"]

.Font C64 (gp_font_c64)
image::images/fonts/font_c64.png["Font C64"]

TrueType Fonts
~~~~~~~~~~~~~~

[source,c]
--------------------------------------------------------------------------------
/*
 * Load font face from file.
 */
gp_font_face *gp_font_face_load(const char *path, uint32_t width, uint32_t height);

/*
 * Free the font face.
 */
void gp_font_face_free(gp_font_face *self);
--------------------------------------------------------------------------------

The 'gp_font_face_load()' renders TrueType font using
link:http://www.freetype.org[FreeType] (currently printable ASCII only) into
GFXprim font structures.

One of the 'width' or 'height' may be zero, which means that the second value
should be computed accordingly.

NOTE: If you pass both 'width' and 'height' non-zero the resulting font may
      look strange as this action forced unnatural aspect ratio.

The 'gp_font_face_free()' frees memory taken up by the rendered font. If self is
NULL no operation is done.

TIP: For font and text_style handling see link:example_fonts.html[examples].

[source,c]
--------------------------------------------------------------------------------
/*
 * Load font face given Fontconfig font name
 */
gp_font_face *gp_font_face_fc_load(const char *family_name, uint32_t width, uint32_t height);
--------------------------------------------------------------------------------

Same as above but uses Fontconfig to get the path given a font family name.

Example names:

* "Mono:Bold" - default monospace bold font
* "Sans" - default sans font
* "LiberationSans:Italic" - liberation sans italic font

NOTE: The match may not be exact, if for example LiberationSans is not present
      on the system fontconfig will chose a different Sans font instead.


Advanced glyph drawing API
~~~~~~~~~~~~~~~~~~~~~~~~~~

[source,c]
--------------------------------------------------------------------------------
gp_size gp_glyph_draw(gp_pixmap *pixmap, const gp_text_style *style,
                      gp_coord x, gp_coord y, uint8_t flags,
                      gp_pixel fg_color, gp_pixel bg_color,
                      uint32_t glyph);
--------------------------------------------------------------------------------

In certain cases it's required to draw a line of text with a different glyph
colors or even with different fonts. In such cases text can be rendered a
glyph by glyph. See link:example_glyphs.html[example] on details how to
use the API.
