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
|
/* See LICENSE file for copyright and license details. */
#ifndef LIBPARSEPSF_H
#define LIBPARSEPSF_H
#include <stdint.h>
#include <stddef.h>
/**
* Glyph trie
*/
struct libparsepsf_unimap {
/**
* Mapping for next byte in a longer sequences
*/
struct libparsepsf_unimap *nonterminal[256];
/**
* Unless the byte index maps to 0, mapped to value
* less 1 is the glyph index to use for the sequence
* if there is no longer sequence
*/
size_t terminal[256];
};
/**
* Parsed PSF font structure
*/
struct libparsepsf_font {
/**
* The number of glyphs in the font
*/
size_t num_glyphs;
/**
* The bit-height of each glyph
*/
size_t height;
/**
* The bit-width of each glyph
*/
size_t width;
/**
* The glyph data
*
* Each glyph is `.height * (.width / 8 + (.width % 8 ? 1 : 0))`
* bytes large. Each glyph is right-padded to a multiple of 8 bits,
* and are oriented in row-major and most-signficant-bit-first order,
* meaning that the bit 0x80 in the first byte for a glyph represents
* the left-most, top-most bit in the, and 0x40 in the same byte
* represents the bit directly right to it. Bit on means ink on,
* bit off means ink off.
*/
uint8_t *glyph_data;
/**
* Glyph trie, maps from byte sequences to glyph indices;
* you can use `libparsepsf_get_glyph` to search it
* (enumeration has to be done manually); note that an
* entry can be multiple characters wide, for example
* to deal with context dependent glyphs and grapheme
* clusters
*
* `NULL` if unicode character points map directly
* (identity mapping) to glyph indices; and UTF-8 the
* assumed encoding
*/
struct libparsepsf_unimap *map;
};
/**
* Deallocate font
*
* @param font Pointer to the data to deallocate
*/
void libparsepsf_destroy_font(struct libparsepsf_font *font);
/**
* Parse a PSF font file
*
* @param data The font file content
* @param size The number of bytes in `data`
* @param fontp Output parameter for the font, should be deallocated
* using `libparsepsf_destroy_font` when no longer
* needed (only allocated on success completion)
* @param unrecognised_versionp Normally set to 0; set to the minor version in the
* font file if it is unrecognised (backwards-compatibility
* is assumed, so it will still be parsed as a supported
* font file)
* @return 0 on successful completion, -1 on failure
* @throws ENOMEM Failed to allocate enough memory
* @throws EBFONT Corrupt or unsupported font file
*/
int libparsepsf_parse_font(const void *data, size_t size, struct libparsepsf_font *fontp, uint32_t *unrecognised_versionp);
/**
* Get the next glyph to print for a text
*
* @param font The parsed font, created with `libparsepsf_parse_font`
* @param c The current position in the text (the text shall be
* completely loaded to guarantee multi-characters glyphs
* are properly printed)
* @param remp The number of bytes in `c`, will be updated to reflect
* the value it shall have when the function is called
* again, with `*next_cp` as `c` (that is, the number of
* bytes in the found byte sequence is subtracted);
* if `NULL`, the text ends when a NUL byte is found
* @param next_cp Output parameter for the next position in the text;
* may be `NULL`
* @return The index of the glyph, plus 1; 0 if the glyph if the
* end of the text is reached or if no glyph is found,
* or (only if `font->map` is `NULL`) if an illegal byte
* sequence was found. `*remp` and `*next_cp` are not
* updated if this function returns 0.
* @throws EILSEQ If an illegal byte sequence was found (only if
* `font->map` is `NULL`)
*/
size_t libparsepsf_get_glyph(const struct libparsepsf_font *font, const char *c, size_t *remp, const char **next_cp);
#endif
|