aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2022-07-17 16:35:42 +0200
committerMattias Andrée <maandree@kth.se>2022-07-17 16:35:42 +0200
commit4325ec3bbc1e06200d91bc79686051bd1b0b9ddb (patch)
treef18be234e0f31caa1f97cdfd6d8e9c88942a8492
parentUpdate copyright year (diff)
downloadlibparsepsf-4325ec3bbc1e06200d91bc79686051bd1b0b9ddb.tar.gz
libparsepsf-4325ec3bbc1e06200d91bc79686051bd1b0b9ddb.tar.bz2
libparsepsf-4325ec3bbc1e06200d91bc79686051bd1b0b9ddb.tar.xz
Fix two bugs and add documentation
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--libparsepsf.c4
-rw-r--r--libparsepsf.h99
2 files changed, 100 insertions, 3 deletions
diff --git a/libparsepsf.c b/libparsepsf.c
index 9649f63..485cce1 100644
--- a/libparsepsf.c
+++ b/libparsepsf.c
@@ -326,7 +326,7 @@ libparsepsf_parse_font(const void *data, size_t size, struct libparsepsf_font *f
if (header.psf2.height * ((header.psf2.width + 7) / 8) != header.psf2.charsize)
goto ebfont;
if (header.psf2.version > PSF2_MAXVERSION)
- *unrecognised_versionp = 0;
+ *unrecognised_versionp = 1;
fontp->num_glyphs = (size_t)header.psf2.num_glyphs;
fontp->height = (size_t)header.psf2.height;
fontp->width = (size_t)header.psf2.width;
@@ -423,7 +423,7 @@ libparsepsf_get_glyph(const struct libparsepsf_font *font, const char *c, size_t
glyph = (size_t)cp;
if (glyph >= font->num_glyphs)
return 0;
- glyph -= 1;
+ glyph += 1;
goto out;
} else if (remp) {
diff --git a/libparsepsf.h b/libparsepsf.h
index b1984b4..d13c062 100644
--- a/libparsepsf.h
+++ b/libparsepsf.h
@@ -6,22 +6,119 @@
#include <stddef.h>
+/**
+ * Glyph trie
+ */
struct libparsepsf_unimap {
+
+ /**
+ * Mapping for next byte in a longer sequences
+ */
struct libparsepsf_unimap *nonterminal[256];
- size_t terminal[256]; /* index + 1, 0 if not used */
+
+ /**
+ * 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); not 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 1 if the minor version in
+ * the font file 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
+ * @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