summaryrefslogtreecommitdiff
path: root/text.h
blob: 3fd603cc279240cd2fdb77ca9fb33920fa9af504 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/// \file
/// A text-rendering interface.
///
/// Example usage:
///
/// ```
/// Font *font = text_font_load("font.ttf", 18);
/// if (font) {
///     text_utf8(font, "Hello", 5, 5, 0xFF0000FF);
///     text_utf8(font, "Goodbye", 5, 100, 0x00FF00FF);
///     text_render(font);
/// }
/// ```

#ifndef TEXT_H_
#define TEXT_H_

#include "base.h"
#include "util.h"

/// a font
typedef struct Font Font;

/// text render state.
///
/// do not construct this directly instead use \ref text_render_state_default.
typedef struct {
	/// should the text actually be rendered (set to false to get text size)
	bool render;
	/// should the text wrap around to min_x when it reaches max_x? NOTE: this is character-by-character wrapping, not word wrap
	bool wrap;
	/// where to draw
	double x, y;
	/// points where the text should be cut off
	float min_x, max_x, min_y, max_y;
	/// `[0] = r, [1] = g, [2] = b, [3] = a`.
	float color[4];
	
	/// largest x achieved (for computing size)
	double x_largest;
	/// largest y achieved (for computing size)
	double y_largest;
	
	/// index of previous glyph rendered, or 0 if this is the first
	int prev_glyph;
	
	/// added to x for rendering
	/// this exists for complicated reasons
	/// basically we want a way of consistently getting the size
	/// of text without error from floating point imprecision
	float x_render_offset;
	
	/// used for forwards-compatibility
	char _reserved[64];
} TextRenderState;

/// text anchor
typedef enum {
	ANCHOR_TOP_LEFT,
	ANCHOR_TOP_MIDDLE,
	ANCHOR_TOP_RIGHT,
	ANCHOR_MIDDLE_LEFT,
	ANCHOR_MIDDLE,
	ANCHOR_MIDDLE_RIGHT,
	ANCHOR_BOTTOM_LEFT,
	ANCHOR_BOTTOM_MIDDLE,
	ANCHOR_BOTTOM_RIGHT,
} Anchor;

/// returns false on error.
bool text_init(void);
/// is there error?
bool text_has_err(void);
/// Get the current error. Errors will NOT be overwritten with newer errors.
const char *text_get_err(void);
/// Clear the current error.
void text_clear_err(void);
/// Load a TTF font found in ttf_filename with the given font size (character pixel height)
Font *text_font_load(const char *ttf_filename, float font_size);
/// Set a fallback font to use if a character is not defined by `font`.
///
/// You can pass `NULL` to clear any previous fallback.
/// Do not create a loop of fallback fonts.
void text_font_set_fallback(Font *font, Font *fallback);
/// Change size of font.
///
/// Avoid calling this function too often, since all font textures are trashed.
/// Also changes size of fallback fonts.
void text_font_change_size(Font *font, float new_size);
/// Height of a character of this font in pixels.
float text_font_char_height(Font *font);
/// Width of the given character in pixels.
float text_font_char_width(Font *font, char32_t c);
/// Force text to advance by text_font_char_width(font, ' ') pixels per character (actually, per code point).
void text_font_set_force_monospace(Font *font, bool force);
/// Get the dimensions of some text.
void text_get_size(Font *font, const char *text, float *width, float *height);
/// Get the dimensions of some text.
vec2 text_get_size_vec2(Font *font, const char *text);
/// Get the dimensions of some text.
void text_get_size32(Font *font, const char32_t *text, u64 len, float *width, float *height);
/// Draw some text.
void text_utf8(Font *font, const char *text, double x, double y, u32 color);
/// Draw some text with an anchor.
void text_utf8_anchored(Font *font, const char *text, double x, double y, u32 color, Anchor anchor);
/// Draw a single character.
void text_char_with_state(Font *font, TextRenderState *state, char32_t c);
/// Draw some UTF-8 text with a \ref TextRenderState.
void text_utf8_with_state(Font *font, TextRenderState *state, const char *str);
/// Used to indicate that the next character drawn should not
/// kern with the previous character.
///
/// Use this when you go to the next line or something.
void text_state_break_kerning(TextRenderState *state);
/// Free memory used by font.
///
/// Does NOT free the font's fallback.
void text_font_free(Font *font);
/// Render all text drawn with \ref text_utf8, etc.
///
/// This will render the fallback font and its fallback, and so on.
void text_render(Font *font);
/// The "default" text rendering state - everything you need to just render text normally.
/// This lets you do stuff like:
/// ```
/// TextRenderState state = text_render_state_default;
///    (set a few options)
/// text_render_with_state(font, &state, ...)
/// ```
extern const TextRenderState text_render_state_default;

#endif