aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2024-10-13 11:17:48 +0200
committerMattias Andrée <m@maandree.se>2024-10-13 11:17:48 +0200
commita81c96c0348af8caf6ae45e2d942a676792a2a31 (patch)
tree24cc725efa3eba381c98ebed7cb2cbf7e0e34f0c
parentUpdate e-mail (diff)
downloadlibparsepcf-a81c96c0348af8caf6ae45e2d942a676792a2a31.tar.gz
libparsepcf-a81c96c0348af8caf6ae45e2d942a676792a2a31.tar.bz2
libparsepcf-a81c96c0348af8caf6ae45e2d942a676792a2a31.tar.xz
Documentation and minor improvements
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--demo.c28
-rw-r--r--libparsepcf.h681
-rw-r--r--libparsepcf_destroy_preparsed_font.c6
-rw-r--r--libparsepcf_get_accelerators.c73
-rw-r--r--libparsepcf_get_bitmap_offsets.c9
-rw-r--r--libparsepcf_get_bitmaps.c29
-rw-r--r--libparsepcf_get_encoding.c26
-rw-r--r--libparsepcf_get_glyph_indices.c7
-rw-r--r--libparsepcf_get_glyph_name_subtable.c11
-rw-r--r--libparsepcf_get_glyph_names.c19
-rw-r--r--libparsepcf_get_metrics.c45
-rw-r--r--libparsepcf_get_metrics_count.c15
-rw-r--r--libparsepcf_get_properties.c21
-rw-r--r--libparsepcf_get_property_subtable.c13
-rw-r--r--libparsepcf_get_swidth_count.c11
-rw-r--r--libparsepcf_get_swidths.c7
-rw-r--r--libparsepcf_get_table_count.c7
-rw-r--r--libparsepcf_get_tables.c17
-rw-r--r--libparsepcf_preparse_font.c4
19 files changed, 833 insertions, 196 deletions
diff --git a/demo.c b/demo.c
index 4a6cf10..80ac748 100644
--- a/demo.c
+++ b/demo.c
@@ -180,10 +180,12 @@ print_bitmaps(void)
exit(1);
}
for (bitmap_i = 0; bitmap_i < bitmaps.glyph_count; bitmap_i++) {
+#if 0
printf("\t #%zu: %zu -> %p (maxsize=%zu)\n",
bitmap_i, bitmaptab[bitmap_i],
(const void *)&bitmaps.bitmap_data[bitmaptab[bitmap_i]],
bitmaps.bitmap_size - bitmaptab[bitmap_i]);
+#endif
}
free(bitmaptab);
}
@@ -296,8 +298,8 @@ print_font(void)
perror("libparsepcf_get_table_count");
exit(1);
}
- fprintf(stderr, "size: %zu\n", len);
- fprintf(stderr, "ntables: %zu\n", table_n);
+ printf("size: %zu\n", len);
+ printf("ntables: %zu\n", table_n);
tables = calloc(table_n, sizeof(*tables));
if (!tables) {
@@ -336,7 +338,7 @@ print_font(void)
print_glyph_names();
break;
#endif
-#if 0
+#if 1
case LIBPARSEPCF_BITMAPS:
print_bitmaps();
break;
@@ -518,7 +520,9 @@ print_glyph(size_t glyph)
pixel = "[]";
}
- printf("\033[%sm%s", ((bitmap[byte] >> bit) & 1) ? "1;37" : "2;37", pixel);
+ printf("\033[%sm%s\033[%sm",
+ ((bitmap[byte] >> bit) & 1) ? "1;37" : "2;37", pixel,
+ (int64_t)y + 1 == (int64_t)mtx.character_ascent ? "0;4" : "0");
}
/* If horizontal advance is larger than character width, print extent in black */
@@ -663,9 +667,13 @@ print_line(const char *str)
const uint8_t *s = (const void *)str;
int32_t xpos = 0, left = 0, right = 0, ascent = 0, descent = 0;
char **lines = NULL;
- uint32_t codepoint = 0, hi, lo;
+ uint32_t codepoint = 0;
+ uint16_t hi, lo, k, m;
size_t glyph, n = 0, y, x, width, height;
+ k = (uint16_t)(font.encoding.max_byte2 - font.encoding.min_byte2);
+ m = (uint16_t)(font.encoding.min_byte1 * k + font.encoding.min_byte2);
+
while (*s) {
/* Very sloppy UTF-8 decoding */
if (n) {
@@ -706,9 +714,9 @@ print_line(const char *str)
}
glyph = codepoint - (uint32_t)font.encoding.min_byte2;
} else {
- hi = (codepoint >> 8) & UINT32_C(0xFF);
- lo = (codepoint >> 0) & UINT32_C(0xFF);
- if (codepoint > UINT32_C(0xFF) ||
+ hi = (uint16_t)((codepoint >> 8) & 0xFFU);
+ lo = (uint16_t)((codepoint >> 0) & 0xFFU);
+ if (codepoint > UINT16_C(0xFF) ||
hi < (uint32_t)font.encoding.min_byte1 ||
hi > (uint32_t)font.encoding.max_byte1 ||
lo < (uint32_t)font.encoding.min_byte2 ||
@@ -716,9 +724,7 @@ print_line(const char *str)
glyph = (size_t)font.encoding.default_char;
goto have_glyph;
}
- hi -= (size_t)font.encoding.min_byte1;
- lo -= (size_t)font.encoding.min_byte2;
- glyph = hi * (size_t)(font.encoding.max_byte2 - font.encoding.min_byte2 + 1) + lo;
+ glyph = (size_t)(uint16_t)(hi * k + lo - m);
}
/* For the purpose of the demo we are assuming ASCII/UCS-2 */
if (libparsepcf_get_glyph_indices(file, len, font.enc_table, &font.encoding, &glyph, glyph, 1)) {
diff --git a/libparsepcf.h b/libparsepcf.h
index 6931898..eef98c8 100644
--- a/libparsepcf.h
+++ b/libparsepcf.h
@@ -34,7 +34,7 @@ struct libparsepcf_table {
/**
* How the data in the table is formatted
*
- * This is only unsed internally, and supported
+ * This is only used internally, and supported
* values are not exposed the the user
*/
uint32_t format;
@@ -74,7 +74,7 @@ struct libparsepcf_table {
*
* @throws EBFONT The file is not a properly formatted PCF file
*/
-int libparsepcf_get_table_count(const char *, size_t, size_t *);
+int libparsepcf_get_table_count(const void *, size_t, size_t *);
/**
* Get table metadata from the file
@@ -85,73 +85,302 @@ int libparsepcf_get_table_count(const char *, size_t, size_t *);
* @param first The index of the first table to store in `tables`,
* the first table in the file has the index 0
* @param count The number of tables to store in `tables`;
- * may not return the number of tables as retrieved
- * by `libparsepcf_get_table_count`
+ * may not exceed the number of tables as retrieved
+ * by `libparsepcf_get_table_count` minus `first`
* @return 0 on success, -1 on failure
*
* @throws EBFONT The file is not a properly formatted PCF file
*/
-int libparsepcf_get_tables(const char *, size_t, struct libparsepcf_table *, size_t, size_t);
+int libparsepcf_get_tables(const void *, size_t,
+ struct libparsepcf_table *,
+ size_t, size_t);
+/**
+ * Property list
+ */
struct libparsepcf_properties {
+ /**
+ * The number of properties available
+ */
size_t property_count;
+
+ /**
+ * The size of `.strings`
+ *
+ * Used internally to detect corruption
+ */
size_t strings_size;
+
+ /**
+ * Property names
+ *
+ * This is a buffer which requires an offset
+ * table, that is found in the file, to parse
+ *
+ * This is a pointer to data within the file
+ *
+ * Intended for internal use
+ */
const char *strings;
};
+/**
+ * Property name and value
+ */
struct libparsepcf_property_subtable {
+ /**
+ * The name of the property
+ */
const char *name;
+
+ /**
+ * 1 if the value is a string,
+ * 0 if the value is an integer
+ */
int is_string_property;
+
+ /**
+ * The value of the property,
+ * use `.value.signed_value` if `.is_string_property` is 0,
+ * use `.value.string_value` if `.is_string_property` is 1
+ */
union {
+ /**
+ * The value
+ *
+ * Used if `.is_string_property` is 0
+ * (if the value is signed integer)
+ */
int32_t signed_value;
+
+ /**
+ * The value
+ *
+ * Used if `.is_string_property` is 1
+ * (if the value is string)
+ */
const char *string_value;
} value;
};
-int libparsepcf_get_properties(const char *, size_t,
+/**
+ * Get the properties available in the file
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_PROPERTIES`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta Output parameter for the list of properties
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_properties(const void *, size_t,
const struct libparsepcf_table *,
struct libparsepcf_properties *);
-int libparsepcf_get_property_subtable(const char *, size_t,
+/**
+ * Get the names and values of properties in the file
+ *
+ * The first four arguments shall be the same as
+ * passed into `libparsepcf_get_properties`
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_PROPERTIES`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta List of properties
+ * @param props Output parameter for the properties
+ * @param first The index of the first property to store in `props`,
+ * the first property in the file has the index 0
+ * @param count The number of properties to store in `props`;
+ * may not exceed the number of properties (`.property_count`)
+ * as retrieved by `libparsepcf_get_properties` minus `first`
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_property_subtable(const void *, size_t,
const struct libparsepcf_table *,
const struct libparsepcf_properties *,
- struct libparsepcf_property_subtable *, size_t, size_t);
+ struct libparsepcf_property_subtable *,
+ size_t, size_t);
+/**
+ * Glyph metrics
+ */
struct libparsepcf_metrics {
+ /**
+ * The number of pixels right of (negative if left of)
+ * the origin (caret position) of the leftmost ink-on
+ * pixel in the glyph
+ */
int16_t left_side_bearing;
+
+ /**
+ * The number of pixels right of (negative if left of)
+ * the origin (caret position) of the rightmost ink-on
+ * pixel in the glyph
+ */
int16_t right_side_bearing;
+
+ /**
+ * The number of pixels the next characters origin shall
+ * be right of the current character's origin (that is
+ * the number of pixels the caret shall advance)
+ */
int16_t character_width;
+
+ /**
+ * The number of pixels the character ascend above
+ * the baseline (if non-positive, it's fully below
+ * the baseline)
+ */
int16_t character_ascent;
+
+ /**
+ * The number of pixels the character descend below
+ * the baseline (if non-positive, it's fully above
+ * the baseline)
+ */
int16_t character_descent;
+
+ /**
+ * Application-specific character attribute bits
+ */
uint16_t character_attributes;
};
-int libparsepcf_get_metrics_count(const char *, size_t, const struct libparsepcf_table *, size_t *);
+/**
+ * Get number of glyph metrics available in the file
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_METRICS`
+ * or `LIBPARSEPCF_INK_METRICS`, extracted using the
+ * `libparsepcf_get_tables` function
+ * @param count Output parameter for glyph metric count
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ *
+ * The `LIBPARSEPCF_METRICS` table is used for layout information,
+ * and the `LIBPARSEPCF_INK_METRICS` table is used for rendering
+ * information; that is `LIBPARSEPCF_METRICS` contains the size
+ * of the glyphs where as `LIBPARSEPCF_INK_METRICS` contains the
+ * size of the glyph bitmaps.
+ */
+int libparsepcf_get_metrics_count(const void *, size_t,
+ const struct libparsepcf_table *,
+ size_t *);
-int libparsepcf_get_metrics(const char *, size_t,
+/**
+ * Get the metrics for glyphs
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_METRICS`
+ * or `LIBPARSEPCF_INK_METRICS`, extracted using the
+ * `libparsepcf_get_tables` function
+ * @param metrics Output parameter for the glyph metrics
+ * @param first The index of the first glyph's metrics to store in
+ * `metrics`, the first glyph in the file has the index 0
+ * @param count The number of glyph's metrics to store in `metrics`;
+ * may not exceed the number of glyph as retrieved by
+ * `libparsepcf_get_metrics_count` (stored in it's last
+ * argument) minus `first`
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ *
+ * The `LIBPARSEPCF_METRICS` table is used for layout information,
+ * and the `LIBPARSEPCF_INK_METRICS` table is used for rendering
+ * information; that is `LIBPARSEPCF_METRICS` contains the size
+ * of the glyphs where as `LIBPARSEPCF_INK_METRICS` contains the
+ * size of the glyph bitmaps.
+ */
+int libparsepcf_get_metrics(const void *, size_t,
const struct libparsepcf_table *,
- struct libparsepcf_metrics *, size_t, size_t);
+ struct libparsepcf_metrics *,
+ size_t, size_t);
+/**
+ * Glyph name list
+ */
struct libparsepcf_glyph_names {
+ /**
+ * The number of glyphs available
+ */
size_t glyph_count;
+
+ /**
+ * The size of `.strings`
+ *
+ * Used internally to detect corruption
+ */
size_t strings_size;
+
+ /**
+ * Glyph names
+ *
+ * This is a buffer which requires an offset
+ * table, that is found in the file, to parse
+ *
+ * This is a pointer to data within the file
+ *
+ * Primarily for internal use
+ */
const char *strings;
};
-int libparsepcf_get_glyph_names(const char *, size_t,
+/**
+ * Get the PostScript glyph names available in the file
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_GLYPH_NAMES`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta Output parameter for the list of glyph names
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_glyph_names(const void *, size_t,
const struct libparsepcf_table *,
struct libparsepcf_glyph_names *);
-int libparsepcf_get_glyph_name_subtable(const char *, size_t,
+/**
+ * Get the PostScript glyph names available in the file
+ *
+ * The first four arguments shall be the same as
+ * passed into `libparsepcf_get_glyph_names`
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_GLYPH_NAMES`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta List of glyph names
+ * @param names Output parameter for the glyph names; each stored name
+ * will be the pointer `file` with an offset
+ * @param first The index of the first glyph's whose name to store in
+ * `names`, the first glyph in the file has the index 0
+ * @param count The number of glyph names to store in `names`;
+ * may not exceed the number of glyph (`.glyph_count`)
+ * as retrieved by `libparsepcf_get_glyph_names` minus `first`
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_glyph_name_subtable(const void *, size_t,
const struct libparsepcf_table *,
const struct libparsepcf_glyph_names *,
const char **, size_t, size_t);
@@ -159,21 +388,40 @@ int libparsepcf_get_glyph_name_subtable(const char *, size_t,
+/**
+ * Glyph bitmap metadata
+ */
struct libparsepcf_bitmaps {
+ /**
+ * The number of glyph available
+ */
size_t glyph_count;
+
+ /**
+ * The size of `.bitmap_data`
+ */
size_t bitmap_size;
+
size_t bit_packing;
+
+ /**
+ * The number of bytes each row is
+ * padded to align to
+ *
+ * This will always be a power of two
+ */
size_t row_padding;
+
int lsbyte;
int lsbit;
const uint8_t *bitmap_data;
};
-int libparsepcf_get_bitmaps(const char *, size_t,
+int libparsepcf_get_bitmaps(const void *, size_t,
const struct libparsepcf_table *,
struct libparsepcf_bitmaps *);
-int libparsepcf_get_bitmap_offsets(const char *, size_t,
+int libparsepcf_get_bitmap_offsets(const void *, size_t,
const struct libparsepcf_table *,
const struct libparsepcf_bitmaps *,
size_t *, size_t, size_t);
@@ -181,34 +429,146 @@ int libparsepcf_get_bitmap_offsets(const char *, size_t,
+/**
+ * Glyph index lookup data
+ *
+ * This structure describes how to lookup a glyph's index
+ * based on the character's encoding. The properties
+ * "CHARSET_REGISTRY" and "CHARSET_ENCODING" are used to
+ * determine which character encoding scheme is used in
+ * the font file.
+ *
+ * This structure contains information for how to calculate
+ * the codepoint (provided to `libparsepcf_get_glyph_indices`
+ * to look up the index of a character's glyph) for a character.
+ * The PCF font format support single-byte encodings and
+ * dual-byte encodings (variable byte encodings are not
+ * supported), if the fields `.min_byte1` and `.max_byte1`
+ * are both set to 0, the file uses single-byte encoding,
+ * otherwise it uses dual-byte encoding.
+ *
+ * For single-byte encodings, the codepoint is calculated
+ * by subtracting `.min_byte2` from the byte.
+ *
+ * For dual-byte encodings, if the first byte is `byte1` and the
+ * second byte is `byte2` for a character, the character's codepoint is
+ * `(byte1-.min_byte1) * (.max_byte2-.min_byte2+1) + (byte2-.min_byte2)`,
+ * or, using less operations, `byte1 * k + byte2 - m` where `k` and `m`
+ * are precalculated as `k = .max_byte2 - .min_byte2 + 1` and
+ * `m = .min_byte1 * k + .min_byte2`.
+ */
struct libparsepcf_encoding {
+ /**
+ * If the second byte (or only byte for single-byte
+ * encodings) is lower this value, this character
+ * has no glyph in the font
+ */
uint16_t min_byte2;
+
+ /**
+ * If the second byte (or only byte for single-byte
+ * encodings) is higher this value, this character
+ * has no glyph in the font
+ */
uint16_t max_byte2;
+
+ /**
+ * For dual-byte encodings, if the first byte is
+ * lower than this value, the character has no
+ * glyph in the font
+ *
+ * Unused for single-byte encoding
+ */
uint16_t min_byte1;
+
+ /**
+ * For dual-byte encodings, if the first byte is
+ * higher than this value, the character has no
+ * glyph in the font
+ *
+ * Unused for single-byte encoding
+ */
uint16_t max_byte1;
+
+ /**
+ * The index of the glyph to use when no glyph is
+ * available for a character
+ *
+ * It value should _not_ be looked up with
+ * `libparsepcf_get_glyph_indices` but used as if
+ * `libparsepcf_get_glyph_indices` has already been
+ * called. In fact, the glyph reference by this
+ * field does not necessarily correspond to a
+ * character and thus may not be available in the
+ * encoding table
+ *
+ * This name of this field is choosen for consistence
+ * with the documentation the implementation is based
+ * on, and is confusing, it ought to be called
+ * "default_glyph"
+ */
uint16_t default_char;
- size_t glyph_count;
- /* If min_byte1 == 0 and max_byte1 == 0 (single byte encoding):
- * glyph_index = glyph_indices[encoding - min_char_or_byte2]
- * not included if encoding > max_byte2 or glyph_index == 0xFFFF
+
+ /**
+ * The number of entries available in the index table,
+ * this is not number of glyphs in the file, but rather
+ * the product of `.max_byte2 - .min_byte2 + 1` and
+ * `.max_byte1 - .min_byte1 + 1`.
*
- * Otherwise (dual byte encoding):
- * [min_byte1, max_byte1] = allowed range of the more signficant of the 2 bytes (the first byte)
- * [min_byte2, max_byte2] = allowed range of the less signficant of the 2 bytes (the second byte)
- * e1 = encoding[0] - min_byte1
- * e2 = encoding[1] - min_byte2
- * glyph_index = glyph_indices[e1 * (max_byte2 - min_byte2 + 1) + e2]
- * not included if out of range or or glyph_index == 0xFFFF
+ * This name of this field is choosen for consistence
+ * with the documentation the implementation is based
+ * on, and is confusing, it ought to be called "char_count"
*/
+ size_t glyph_count;
};
+/**
+ * Glyph index returned when there is no glyph
+ * available for the character
+ */
#define LIBPARSEPCF_NOT_ENCODED ((size_t)0xFFFFUL)
-int libparsepcf_get_encoding(const char *, size_t,
+/**
+ * Get the glyph index lookup metadata for the file
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_BDF_ENCODINGS`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta Output parameter for the glyph index lookup metadata
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_encoding(const void *, size_t,
const struct libparsepcf_table *,
struct libparsepcf_encoding *);
-int libparsepcf_get_glyph_indices(const char *, size_t,
+/**
+ * Get the glyph index in the file for characters
+ *
+ * The first four arguments shall be the same as
+ * passed into `libparsepcf_get_properties`
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_PROPERTIES`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta Glyph index lookup metadata
+ * @param indices Output parameter for the glyph indices; for any character
+ * the index `LIBPARSEPCF_NOT_ENCODED` is stored, the character
+ * is not included in the font
+ * @param first The codepoint of the first character whose index to store in
+ * `indices`; see the description of `struct libparsepcf_encoding`
+ * for information on how to calculate a character's codepoint
+ * @param count The number of glyph indices to store in `indices`;
+ * may not exceed the number of characters (`.glyph_count`)
+ * as retrieved by `libparsepcf_get_encoding` minus `first`
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_glyph_indices(const void *, size_t,
const struct libparsepcf_table *,
const struct libparsepcf_encoding *,
size_t *, size_t, size_t);
@@ -216,87 +576,328 @@ int libparsepcf_get_glyph_indices(const char *, size_t,
+/**
+ * Information, available for optimisation, about the font
+ */
struct libparsepcf_accelerators {
/**
- * Whether metrics[i].right_side_bearing - metrics[i].character_width
- * less than or equal to .min_bounds.left_side_bearing for all i
+ * Whether `metrics[i].right_side_bearing - metrics[i].character_width`
+ * less than or equal to `.min_bounds.left_side_bearing` for all `i`
*/
uint8_t no_overlap : 1;
+
+ /**
+ * Whether all glyph use the same layout metrics
+ */
uint8_t constant_metrics : 1;
+
/**
- * .constant_metrics and, for all characters, left side bearing = 0,
- * right side bearing = character width, ascent = .font_ascent, and
- * descent = .font_descent
+ * `.constant_metrics` and, for all characters, left side bearing = 0,
+ * right side bearing = character width, ascent = `.font_ascent`, and
+ * descent = `.font_descent`
*/
uint8_t terminal_font : 1;
+
+ /**
+ * Whether all glyph have the same layout width
+ */
uint8_t constant_width : 1;
+
/**
* Whether all inked bits are inside the glyph's box
*/
uint8_t ink_inside : 1;
+
/**
* Whether the ink metrics differ from the metrics for some glyph
*/
uint8_t ink_metrics : 1;
+
+ /**
+ * Whether the font is a right-to-left font
+ */
uint8_t draw_rtl : 1;
+
/**
- * If 0, .ink_min_bounds and .ink_max_bounds are just copies of
- * .min_bounds and max_bounds
+ * If 0, `.ink_min_bounds` and `.ink_max_bounds` are just copies of
+ * `.min_bounds` and `.max_bounds`
*/
uint8_t have_ink_bounds : 1;
+
+ /**
+ * The number of pixels the font ascend above the baseline
+ */
int32_t font_ascent;
+
+ /**
+ * The number of pixels the font descend below the baseline
+ */
int32_t font_descent;
+
+ /**
+ * The maximum horizontal overlap, in pixels, of two glyphs
+ */
int32_t max_overlap;
+
+ /**
+ * The lower bounds, over each glyph, of the layout metrics
+ */
struct libparsepcf_metrics min_bounds;
+
+ /**
+ * The upper bounds, over each glyph, of the layout metrics
+ */
struct libparsepcf_metrics max_bounds;
+
+ /**
+ * The lower bounds, over each glyph, of the ink metrics
+ */
struct libparsepcf_metrics min_ink_bounds;
+
+ /**
+ * The upper bounds, over each glyph, of the ink metrics
+ */
struct libparsepcf_metrics max_ink_bounds;
};
-int libparsepcf_get_accelerators(const char *, size_t,
+/**
+ * Get information, available for optimisation, about the font
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_ACCELERATORS`
+ * or `LIBPARSEPCF_BDF_ACCELERATORS`, extracted using the
+ * `libparsepcf_get_tables` function
+ * @param meta Output parameter for the list of glyph names
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ *
+ * `LIBPARSEPCF_BDF_ACCELERATORS` shall be prefered over
+ * `LIBPARSEPCF_ACCELERATORS` of both tables are present.
+ * `LIBPARSEPCF_BDF_ACCELERATORS` is more accurate and refers
+ * only to the encoded characters in the font, whereas
+ * `LIBPARSEPCF_ACCELERATORS` includes all glyphs
+ */
+int libparsepcf_get_accelerators(const void *, size_t,
const struct libparsepcf_table *,
struct libparsepcf_accelerators *);
+
-int libparsepcf_get_swidth_count(const char *, size_t, const struct libparsepcf_table *, size_t *);
+/**
+ * Get number of scalable glyph widths available in the file
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_SWIDTHS`
+ * or `LIBPARSEPCF_SWIDTHS`, extracted using the
+ * `libparsepcf_get_tables` function
+ * @param count Output parameter for glyph metric count
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_swidth_count(const void *, size_t,
+ const struct libparsepcf_table *,
+ size_t *);
-int libparsepcf_get_swidths(const char *, size_t, const struct libparsepcf_table *, int32_t *, size_t, size_t);
+/**
+ * Get number of scalable glyph widths available in the file
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_SWIDTHS`
+ * or `LIBPARSEPCF_SWIDTHS`, extracted using the
+ * `libparsepcf_get_tables` function
+ * @param widths Output parameter for the glyph's widths; each width
+ * is encoded with the unit milli-em
+ * @param first The index of the first glyph's width to store in
+ * `width`, the first glyph in the file has the index 0
+ * @param count The number of glyph's widths to store in `widths`;
+ * may not exceed the number of glyph as retrieved by
+ * `libparsepcf_get_swidth_count` (stored in it's last
+ * argument) minus `first`
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_get_swidths(const void *, size_t,
+ const struct libparsepcf_table *,
+ int32_t *, size_t, size_t);
+/**
+ * The tables, in the file, and metadata available in the tables
+ */
struct libparsepcf_font {
+ /**
+ * The `LIBPARSEPCF_PROPERTIES` table,
+ * `NULL` if the table is missing
+ */
const struct libparsepcf_table *prob_table;
+
+ /**
+ * Data extracted for `LIBPARSEPCF_PROPERTIES`
+ * using `libparsepcf_get_properties`
+ *
+ * Only set if `.prob_table` is non-`NULL`
+ */
struct libparsepcf_properties props;
+
+ /**
+ * The `LIBPARSEPCF_BDF_ACCELERATORS` table,
+ * or if missing, the `LIBPARSEPCF_ACCELERATORS`
+ * table; `NULL` if both are missing
+ */
const struct libparsepcf_table *accel_table;
+
+ /**
+ * Data extracted for `LIBPARSEPCF_BDF_ACCELERATORS`
+ * or, if not present, `LIBPARSEPCF_ACCELERATORS`
+ * using `libparsepcf_get_accelerators`
+ *
+ * Only set if `.accel_table` is non-`NULL`
+ */
struct libparsepcf_accelerators accels;
+
+ /**
+ * The `LIBPARSEPCF_METRICS` table
+ *
+ * This will be non-`NULL` as `libparsepcf_preparse_font`
+ * fails with `EBFONT` if the table is missing
+ */
const struct libparsepcf_table *mtx_table;
+
+ /**
+ * The number of glyph layout metrics available in the font
+ *
+ * This will be the same as `.glyph_count`
+ */
size_t metrics;
+
+ /**
+ * The `LIBPARSEPCF_INK_METRICS` table, `NULL`
+ * if the table is missing
+ *
+ * If `NULL`, the ink metrics are the same as the
+ * layout metrics and `.mtx_table` should be used
+ * instead
+ */
const struct libparsepcf_table *inkmtx_table;
+
+ /**
+ * The number of glyph ink metrics available in the font
+ *
+ * This will be the same as `.glyph_count` provided
+ * that `.inkmtx_table` is non-`NULL`
+ *
+ * Only set if `.inkmtx_table` is non-`NULL`
+ */
size_t ink_metrics;
+
+ /**
+ * The `LIBPARSEPCF_BDF_ENCODINGS` table
+ *
+ * This will be non-`NULL` as `libparsepcf_preparse_font`
+ * fails with `EBFONT` if the table is missing
+ */
const struct libparsepcf_table *enc_table;
+
+ /**
+ * Data extracted for `LIBPARSEPCF_BDF_ENCODINGS`
+ * using `libparsepcf_get_encoding`
+ */
struct libparsepcf_encoding encoding;
+
+ /**
+ * The `LIBPARSEPCF_BITMAPS` table,
+ * `NULL` if the table is missing
+ */
const struct libparsepcf_table *bitmap_table;
+
+ /**
+ * Data extracted for `LIBPARSEPCF_BITMAPS`
+ * using `libparsepcf_get_bitmaps`
+ *
+ * Only set if `.bitmaps_table` is non-`NULL`
+ */
struct libparsepcf_bitmaps bitmaps;
+
+ /**
+ * The `LIBPARSEPCF_SWIDTHS` table,
+ * `NULL` if the table is missing
+ */
const struct libparsepcf_table *swidth_table;
+
+ /**
+ * The number of scalable glyph widths available
+ * in the font
+ *
+ * Only set if `.swidth_table` is non-`NULL`
+ */
size_t swidths;
-
+
+
+ /**
+ * The `LIBPARSEPCF_GLYPH_NAMES` table,
+ * `NULL` if the table is missing
+ */
const struct libparsepcf_table *name_table;
+
+ /**
+ * Data extracted for `LIBPARSEPCF_GLYPH_NAMES`
+ * using `libparsepcf_get_glyph_names`
+ *
+ * Only set if `.names_table` is non-`NULL`
+ */
struct libparsepcf_glyph_names names;
+
+ /**
+ * The number of glyphs available in the file
+ */
size_t glyph_count;
+
+
+ /**
+ * The array of all tables in the file
+ *
+ * For internal use
+ */
struct libparsepcf_table *_tables;
};
-int libparsepcf_preparse_font(const char *, size_t, struct libparsepcf_font *);
+/**
+ * Identify all tables in the file and extract the
+ * metadata in each table
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param font Output parameter for the table data
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
+int libparsepcf_preparse_font(const void *, size_t, struct libparsepcf_font *);
+/**
+ * Deallocate memory allocated by `libparsepcf_preparse_font`
+ * and erase the object's content
+ *
+ * @param font The object to erase, and allocations to deallocate;
+ * `font` itself will not be deallocated, only memory
+ * stored inside it
+ */
void libparsepcf_destroy_preparsed_font(struct libparsepcf_font *);
diff --git a/libparsepcf_destroy_preparsed_font.c b/libparsepcf_destroy_preparsed_font.c
index 36ec493..ded8cb7 100644
--- a/libparsepcf_destroy_preparsed_font.c
+++ b/libparsepcf_destroy_preparsed_font.c
@@ -5,6 +5,8 @@
void
libparsepcf_destroy_preparsed_font(struct libparsepcf_font *font)
{
- free(font->_tables);
- memset(font, 0, sizeof(*font));
+ if (font) {
+ free(font->_tables);
+ *font = (struct libparsepcf_font){0};
+ }
}
diff --git a/libparsepcf_get_accelerators.c b/libparsepcf_get_accelerators.c
index b9688b7..66c8f2f 100644
--- a/libparsepcf_get_accelerators.c
+++ b/libparsepcf_get_accelerators.c
@@ -3,10 +3,11 @@
int
-libparsepcf_get_accelerators(const char *file, size_t size,
+libparsepcf_get_accelerators(const void *file, size_t size,
const struct libparsepcf_table *table,
struct libparsepcf_accelerators *out)
{
+ const char *text = file;
int msb = table->format & LIBPARSEPCF_BYTE;
int with_ink_bounds = table->format & LIBPARSEPCF_ACCELERATOR_WITH_INK_BOUNDS;
size_t pos;
@@ -18,56 +19,56 @@ libparsepcf_get_accelerators(const char *file, size_t size,
pos = table->offset;
- if (table->format != libparsepcf_parse_lsb_uint32__(&file[pos]))
+ if (table->format != libparsepcf_parse_lsb_uint32__(&text[pos]))
goto ebfont;
pos += 4;
- out->no_overlap = !!file[pos + 0];
- out->constant_metrics = !!file[pos + 1];
- out->terminal_font = !!file[pos + 2];
- out->constant_width = !!file[pos + 3];
- out->ink_inside = !!file[pos + 4];
- out->ink_metrics = !!file[pos + 5];
- out->draw_rtl = !!file[pos + 6];
+ out->no_overlap = !!text[pos + 0];
+ out->constant_metrics = !!text[pos + 1];
+ out->terminal_font = !!text[pos + 2];
+ out->constant_width = !!text[pos + 3];
+ out->ink_inside = !!text[pos + 4];
+ out->ink_metrics = !!text[pos + 5];
+ out->draw_rtl = !!text[pos + 6];
out->have_ink_bounds = !!with_ink_bounds;
pos += 8;
- out->font_ascent = PARSE_INT32(&file[pos + 0], msb);
- out->font_descent = PARSE_INT32(&file[pos + 4], msb);
- out->max_overlap = PARSE_INT32(&file[pos + 8], msb);
+ out->font_ascent = PARSE_INT32(&text[pos + 0], msb);
+ out->font_descent = PARSE_INT32(&text[pos + 4], msb);
+ out->max_overlap = PARSE_INT32(&text[pos + 8], msb);
pos += 12;
- out->min_bounds.left_side_bearing = PARSE_INT16(&file[pos + 0], msb);
- out->min_bounds.right_side_bearing = PARSE_INT16(&file[pos + 2], msb);
- out->min_bounds.character_width = PARSE_INT16(&file[pos + 4], msb);
- out->min_bounds.character_ascent = PARSE_INT16(&file[pos + 6], msb);
- out->min_bounds.character_descent = PARSE_INT16(&file[pos + 8], msb);
- out->min_bounds.character_attributes = PARSE_UINT16(&file[pos + 10], msb);
+ out->min_bounds.left_side_bearing = PARSE_INT16(&text[pos + 0], msb);
+ out->min_bounds.right_side_bearing = PARSE_INT16(&text[pos + 2], msb);
+ out->min_bounds.character_width = PARSE_INT16(&text[pos + 4], msb);
+ out->min_bounds.character_ascent = PARSE_INT16(&text[pos + 6], msb);
+ out->min_bounds.character_descent = PARSE_INT16(&text[pos + 8], msb);
+ out->min_bounds.character_attributes = PARSE_UINT16(&text[pos + 10], msb);
pos += 12;
- out->max_bounds.left_side_bearing = PARSE_INT16(&file[pos + 0], msb);
- out->max_bounds.right_side_bearing = PARSE_INT16(&file[pos + 2], msb);
- out->max_bounds.character_width = PARSE_INT16(&file[pos + 4], msb);
- out->max_bounds.character_ascent = PARSE_INT16(&file[pos + 6], msb);
- out->max_bounds.character_descent = PARSE_INT16(&file[pos + 8], msb);
- out->max_bounds.character_attributes = PARSE_UINT16(&file[pos + 10], msb);
+ out->max_bounds.left_side_bearing = PARSE_INT16(&text[pos + 0], msb);
+ out->max_bounds.right_side_bearing = PARSE_INT16(&text[pos + 2], msb);
+ out->max_bounds.character_width = PARSE_INT16(&text[pos + 4], msb);
+ out->max_bounds.character_ascent = PARSE_INT16(&text[pos + 6], msb);
+ out->max_bounds.character_descent = PARSE_INT16(&text[pos + 8], msb);
+ out->max_bounds.character_attributes = PARSE_UINT16(&text[pos + 10], msb);
pos += 12;
if (with_ink_bounds) {
- out->min_ink_bounds.left_side_bearing = PARSE_INT16(&file[pos + 0], msb);
- out->min_ink_bounds.right_side_bearing = PARSE_INT16(&file[pos + 2], msb);
- out->min_ink_bounds.character_width = PARSE_INT16(&file[pos + 4], msb);
- out->min_ink_bounds.character_ascent = PARSE_INT16(&file[pos + 6], msb);
- out->min_ink_bounds.character_descent = PARSE_INT16(&file[pos + 8], msb);
- out->min_ink_bounds.character_attributes = PARSE_UINT16(&file[pos + 10], msb);
+ out->min_ink_bounds.left_side_bearing = PARSE_INT16(&text[pos + 0], msb);
+ out->min_ink_bounds.right_side_bearing = PARSE_INT16(&text[pos + 2], msb);
+ out->min_ink_bounds.character_width = PARSE_INT16(&text[pos + 4], msb);
+ out->min_ink_bounds.character_ascent = PARSE_INT16(&text[pos + 6], msb);
+ out->min_ink_bounds.character_descent = PARSE_INT16(&text[pos + 8], msb);
+ out->min_ink_bounds.character_attributes = PARSE_UINT16(&text[pos + 10], msb);
pos += 12;
- out->max_ink_bounds.left_side_bearing = PARSE_INT16(&file[pos + 0], msb);
- out->max_ink_bounds.right_side_bearing = PARSE_INT16(&file[pos + 2], msb);
- out->max_ink_bounds.character_width = PARSE_INT16(&file[pos + 4], msb);
- out->max_ink_bounds.character_ascent = PARSE_INT16(&file[pos + 6], msb);
- out->max_ink_bounds.character_descent = PARSE_INT16(&file[pos + 8], msb);
- out->max_ink_bounds.character_attributes = PARSE_UINT16(&file[pos + 10], msb);
+ out->max_ink_bounds.left_side_bearing = PARSE_INT16(&text[pos + 0], msb);
+ out->max_ink_bounds.right_side_bearing = PARSE_INT16(&text[pos + 2], msb);
+ out->max_ink_bounds.character_width = PARSE_INT16(&text[pos + 4], msb);
+ out->max_ink_bounds.character_ascent = PARSE_INT16(&text[pos + 6], msb);
+ out->max_ink_bounds.character_descent = PARSE_INT16(&text[pos + 8], msb);
+ out->max_ink_bounds.character_attributes = PARSE_UINT16(&text[pos + 10], msb);
pos += 12;
} else {
memcpy(&out->min_ink_bounds, &out->min_bounds, sizeof(out->min_bounds));
diff --git a/libparsepcf_get_bitmap_offsets.c b/libparsepcf_get_bitmap_offsets.c
index 192b07b..8f62f7e 100644
--- a/libparsepcf_get_bitmap_offsets.c
+++ b/libparsepcf_get_bitmap_offsets.c
@@ -3,11 +3,12 @@
int
-libparsepcf_get_bitmap_offsets(const char *file, size_t size,
+libparsepcf_get_bitmap_offsets(const void *file, size_t size,
const struct libparsepcf_table *table,
const struct libparsepcf_bitmaps *meta,
- size_t *out, size_t first, size_t count)
+ size_t *offs, size_t first, size_t count)
{
+ const char *text = file;
int msb = table->format & LIBPARSEPCF_BYTE;
size_t pos = table->offset + 8 + first * 4;
size_t i;
@@ -15,8 +16,8 @@ libparsepcf_get_bitmap_offsets(const char *file, size_t size,
(void) size;
for (i = 0; i < count; i++, pos += 4) {
- out[i] = (size_t)PARSE_UINT32(&file[pos + 0], msb);
- if (out[i] > meta->bitmap_size)
+ offs[i] = (size_t)PARSE_UINT32(&text[pos + 0], msb);
+ if (offs[i] > meta->bitmap_size)
goto ebfont;
}
diff --git a/libparsepcf_get_bitmaps.c b/libparsepcf_get_bitmaps.c
index 961da96..cad51f3 100644
--- a/libparsepcf_get_bitmaps.c
+++ b/libparsepcf_get_bitmaps.c
@@ -3,10 +3,11 @@
int
-libparsepcf_get_bitmaps(const char *file, size_t size,
+libparsepcf_get_bitmaps(const void *file, size_t size,
const struct libparsepcf_table *table,
- struct libparsepcf_bitmaps *out)
+ struct libparsepcf_bitmaps *meta)
{
+ const char *text = file;
size_t pos, glyph_pad;
int msb = table->format & LIBPARSEPCF_BYTE;
@@ -17,31 +18,31 @@ libparsepcf_get_bitmaps(const char *file, size_t size,
pos = table->offset;
- if (table->format != libparsepcf_parse_lsb_uint32__(&file[pos]))
+ if (table->format != libparsepcf_parse_lsb_uint32__(&text[pos]))
goto ebfont;
pos += 4;
- out->glyph_count = (size_t)PARSE_UINT32(&file[pos], msb);
+ meta->glyph_count = (size_t)PARSE_UINT32(&text[pos], msb);
pos += 4;
if (16 > table->size - (pos - table->offset) ||
- out->glyph_count > (table->size - (pos - table->offset) - 16) / 4)
+ meta->glyph_count > (table->size - (pos - table->offset) - 16) / 4)
goto ebfont;
- pos += out->glyph_count * 4;
+ pos += meta->glyph_count * 4;
glyph_pad = (size_t)(table->format & LIBPARSEPCF_GLYPH_PAD_MASK);
- out->bitmap_size = (size_t)PARSE_UINT32(&file[pos + 4 * glyph_pad], msb);
+ meta->bitmap_size = (size_t)PARSE_UINT32(&text[pos + 4 * glyph_pad], msb);
pos += 16;
- out->bitmap_data = (const void *)&file[pos];
- if (out->bitmap_size > table->size - (pos - table->offset))
+ meta->bitmap_data = (const void *)&text[pos];
+ if (meta->bitmap_size > table->size - (pos - table->offset))
goto ebfont;
- out->bit_packing = (size_t)1 << ((table->format & LIBPARSEPCF_SCAN_UNIT_MASK) >> 4);
- out->row_padding = (size_t)1 << ((table->format & LIBPARSEPCF_GLYPH_PAD_MASK) >> 0);
- out->lsbyte = !!(table->format & LIBPARSEPCF_BYTE);
- out->lsbit = !!(table->format & LIBPARSEPCF_BIT);
+ meta->bit_packing = (size_t)1 << ((table->format & LIBPARSEPCF_SCAN_UNIT_MASK) >> 4);
+ meta->row_padding = (size_t)1 << ((table->format & LIBPARSEPCF_GLYPH_PAD_MASK) >> 0);
+ meta->lsbyte = !!(table->format & LIBPARSEPCF_BYTE);
+ meta->lsbit = !!(table->format & LIBPARSEPCF_BIT);
- if (out->row_padding < out->bit_packing)
+ if (meta->row_padding < meta->bit_packing)
goto ebfont;
return 0;
diff --git a/libparsepcf_get_encoding.c b/libparsepcf_get_encoding.c
index 34ccd9b..6c28c6a 100644
--- a/libparsepcf_get_encoding.c
+++ b/libparsepcf_get_encoding.c
@@ -3,10 +3,11 @@
int
-libparsepcf_get_encoding(const char *file, size_t size,
+libparsepcf_get_encoding(const void *file, size_t size,
const struct libparsepcf_table *table,
- struct libparsepcf_encoding *out)
+ struct libparsepcf_encoding *meta)
{
+ const char *text = file;
int msb = table->format & LIBPARSEPCF_BYTE;
size_t pos;
@@ -17,23 +18,24 @@ libparsepcf_get_encoding(const char *file, size_t size,
pos = table->offset;
- if (table->format != libparsepcf_parse_lsb_uint32__(&file[pos]))
+ if (table->format != libparsepcf_parse_lsb_uint32__(&text[pos]))
goto ebfont;
pos += 4;
- out->min_byte2 = PARSE_UINT16(&file[pos + 0], msb);
- out->max_byte2 = PARSE_UINT16(&file[pos + 2], msb);
- out->min_byte1 = PARSE_UINT16(&file[pos + 4], msb);
- out->max_byte1 = PARSE_UINT16(&file[pos + 6], msb);
- out->default_char = PARSE_UINT16(&file[pos + 8], msb);
+ meta->min_byte2 = PARSE_UINT16(&text[pos + 0], msb);
+ meta->max_byte2 = PARSE_UINT16(&text[pos + 2], msb);
+ meta->min_byte1 = PARSE_UINT16(&text[pos + 4], msb);
+ meta->max_byte1 = PARSE_UINT16(&text[pos + 6], msb);
+ meta->default_char = PARSE_UINT16(&text[pos + 8], msb);
pos += 10;
- if (out->min_byte2 > out->max_byte2 || out->max_byte2 > 255 ||
- out->min_byte1 > out->max_byte1 || out->max_byte1 > 255)
+ if (meta->min_byte2 > meta->max_byte2 || meta->max_byte2 > 255 ||
+ meta->min_byte1 > meta->max_byte1 || meta->max_byte1 > 255)
goto ebfont;
- out->glyph_count = (size_t)(out->max_byte2 - out->min_byte2 + 1) * (size_t)(out->max_byte1 - out->min_byte1 + 1);
- if (out->glyph_count > table->size - (pos - table->offset) / 2)
+ meta->glyph_count = (size_t)(meta->max_byte2 - meta->min_byte2 + 1);
+ meta->glyph_count *= (size_t)(meta->max_byte1 - meta->min_byte1 + 1);
+ if (meta->glyph_count > table->size - (pos - table->offset) / 2)
goto ebfont;
return 0;
diff --git a/libparsepcf_get_glyph_indices.c b/libparsepcf_get_glyph_indices.c
index c30e148..bb95d3e 100644
--- a/libparsepcf_get_glyph_indices.c
+++ b/libparsepcf_get_glyph_indices.c
@@ -3,11 +3,12 @@
int
-libparsepcf_get_glyph_indices(const char *file, size_t size,
+libparsepcf_get_glyph_indices(const void *file, size_t size,
const struct libparsepcf_table *table,
const struct libparsepcf_encoding *meta,
- size_t *out, size_t first, size_t count)
+ size_t *indices, size_t first, size_t count)
{
+ const char *text = file;
int msb = table->format & LIBPARSEPCF_BYTE;
size_t pos = table->offset + 14 + first * 2;
size_t i;
@@ -16,7 +17,7 @@ libparsepcf_get_glyph_indices(const char *file, size_t size,
(void) meta;
for (i = 0; i < count; i++, pos += 2)
- out[i] = (size_t)PARSE_UINT16(&file[pos], msb);
+ indices[i] = (size_t)PARSE_UINT16(&text[pos], msb);
return 0;
}
diff --git a/libparsepcf_get_glyph_name_subtable.c b/libparsepcf_get_glyph_name_subtable.c
index 578bf87..56519bf 100644
--- a/libparsepcf_get_glyph_name_subtable.c
+++ b/libparsepcf_get_glyph_name_subtable.c
@@ -3,11 +3,12 @@
int
-libparsepcf_get_glyph_name_subtable(const char *file, size_t size,
+libparsepcf_get_glyph_name_subtable(const void *file, size_t size,
const struct libparsepcf_table *table,
const struct libparsepcf_glyph_names *meta,
- const char **out, size_t first, size_t count)
+ const char **names, size_t first, size_t count)
{
+ const char *text = file;
size_t pos, i, off;
int msb = table->format & LIBPARSEPCF_BYTE;
@@ -18,11 +19,11 @@ libparsepcf_get_glyph_name_subtable(const char *file, size_t size,
pos = table->offset + 8 + first * 4;
for (i = 0; i < count; i++, pos += 4) {
- off = (size_t)PARSE_UINT32(&file[pos], msb);
+ off = (size_t)PARSE_UINT32(&text[pos], msb);
if (off > meta->strings_size)
goto ebfont;
- out[i] = &meta->strings[off];
- if (!memchr(out[i], 0, meta->strings_size - off))
+ names[i] = &meta->strings[off];
+ if (!memchr(names[i], 0, meta->strings_size - off))
goto ebfont;
}
diff --git a/libparsepcf_get_glyph_names.c b/libparsepcf_get_glyph_names.c
index ca690a4..46d5173 100644
--- a/libparsepcf_get_glyph_names.c
+++ b/libparsepcf_get_glyph_names.c
@@ -3,10 +3,11 @@
int
-libparsepcf_get_glyph_names(const char *file, size_t size,
+libparsepcf_get_glyph_names(const void *file, size_t size,
const struct libparsepcf_table *table,
- struct libparsepcf_glyph_names *out)
+ struct libparsepcf_glyph_names *meta)
{
+ const char *text = file;
size_t pos;
int msb = table->format & LIBPARSEPCF_BYTE;
@@ -17,22 +18,22 @@ libparsepcf_get_glyph_names(const char *file, size_t size,
pos = table->offset;
- if (table->format != libparsepcf_parse_lsb_uint32__(&file[pos]))
+ if (table->format != libparsepcf_parse_lsb_uint32__(&text[pos]))
goto ebfont;
pos += 4;
- out->glyph_count = (size_t)PARSE_UINT32(&file[pos], msb);
+ meta->glyph_count = (size_t)PARSE_UINT32(&text[pos], msb);
pos += 4;
if (4 > table->size - (pos - table->offset) ||
- out->glyph_count > (table->size - (pos - table->offset) - 4) / 4)
+ meta->glyph_count > (table->size - (pos - table->offset) - 4) / 4)
goto ebfont;
- pos += out->glyph_count * 4;
- out->strings_size = (size_t)PARSE_UINT32(&file[pos], msb);
+ pos += meta->glyph_count * 4;
+ meta->strings_size = (size_t)PARSE_UINT32(&text[pos], msb);
pos += 4;
- out->strings = &file[pos];
- if (out->strings_size > table->size - (pos - table->offset))
+ meta->strings = &text[pos];
+ if (meta->strings_size > table->size - (pos - table->offset))
goto ebfont;
return 0;
diff --git a/libparsepcf_get_metrics.c b/libparsepcf_get_metrics.c
index 5e2fbe0..8994405 100644
--- a/libparsepcf_get_metrics.c
+++ b/libparsepcf_get_metrics.c
@@ -2,11 +2,16 @@
#include "common.h"
+#define PARSE_INT8(TEXT) ((int16_t)((int)*(const uint8_t *)(TEXT) - 128))
+
+
int
-libparsepcf_get_metrics(const char *file, size_t size,
+libparsepcf_get_metrics(const void *file, size_t size,
const struct libparsepcf_table *table,
- struct libparsepcf_metrics *out, size_t first, size_t count)
+ struct libparsepcf_metrics *metrics,
+ size_t first, size_t count)
{
+ const char *text = file;
size_t pos, i;
int msb = table->format & LIBPARSEPCF_BYTE;
int compressed = table->format & LIBPARSEPCF_COMPRESSED_METRICS;
@@ -18,30 +23,30 @@ libparsepcf_get_metrics(const char *file, size_t size,
if (compressed) {
for (i = 0; i < count; i++, pos += 5) {
- out[i].left_side_bearing = (int16_t)((int)((const uint8_t *)file)[pos + 0] - 128);
- out[i].right_side_bearing = (int16_t)((int)((const uint8_t *)file)[pos + 1] - 128);
- out[i].character_width = (int16_t)((int)((const uint8_t *)file)[pos + 2] - 128);
- out[i].character_ascent = (int16_t)((int)((const uint8_t *)file)[pos + 3] - 128);
- out[i].character_descent = (int16_t)((int)((const uint8_t *)file)[pos + 4] - 128);
- out[i].character_attributes = 0;
- if (out[i].left_side_bearing > out[i].right_side_bearing ||
- (int32_t)out[i].character_ascent < -(int32_t)out[i].character_descent)
- goto ebfont;
+ metrics[i].left_side_bearing = PARSE_INT8(&text[pos + 0]);
+ metrics[i].right_side_bearing = PARSE_INT8(&text[pos + 1]);
+ metrics[i].character_width = PARSE_INT8(&text[pos + 2]);
+ metrics[i].character_ascent = PARSE_INT8(&text[pos + 3]);
+ metrics[i].character_descent = PARSE_INT8(&text[pos + 4]);
+ metrics[i].character_attributes = 0;
}
} else {
for (i = 0; i < count; i++, pos += 12) {
- out[i].left_side_bearing = PARSE_INT16(&file[pos + 0], msb);
- out[i].right_side_bearing = PARSE_INT16(&file[pos + 2], msb);
- out[i].character_width = PARSE_INT16(&file[pos + 4], msb);
- out[i].character_ascent = PARSE_INT16(&file[pos + 6], msb);
- out[i].character_descent = PARSE_INT16(&file[pos + 8], msb);
- out[i].character_attributes = PARSE_UINT16(&file[pos + 10], msb);
- if (out[i].left_side_bearing > out[i].right_side_bearing ||
- (int32_t)out[i].character_ascent < -(int32_t)out[i].character_descent)
- goto ebfont;
+ metrics[i].left_side_bearing = PARSE_INT16(&text[pos + 0], msb);
+ metrics[i].right_side_bearing = PARSE_INT16(&text[pos + 2], msb);
+ metrics[i].character_width = PARSE_INT16(&text[pos + 4], msb);
+ metrics[i].character_ascent = PARSE_INT16(&text[pos + 6], msb);
+ metrics[i].character_descent = PARSE_INT16(&text[pos + 8], msb);
+ metrics[i].character_attributes = PARSE_UINT16(&text[pos + 10], msb);
}
}
+ for (i = 0; i < count; i++) {
+ if (metrics[i].left_side_bearing > metrics[i].right_side_bearing ||
+ (int32_t)metrics[i].character_ascent < -(int32_t)metrics[i].character_descent)
+ goto ebfont;
+ }
+
return 0;
ebfont:
diff --git a/libparsepcf_get_metrics_count.c b/libparsepcf_get_metrics_count.c
index fab5544..abaa542 100644
--- a/libparsepcf_get_metrics_count.c
+++ b/libparsepcf_get_metrics_count.c
@@ -3,8 +3,11 @@
int
-libparsepcf_get_metrics_count(const char *file, size_t size, const struct libparsepcf_table *table, size_t *countp)
+libparsepcf_get_metrics_count(const void *file, size_t size,
+ const struct libparsepcf_table *table,
+ size_t *count)
{
+ const char *text = file;
size_t pos;
int msb = table->format & LIBPARSEPCF_BYTE;
int compressed = table->format & LIBPARSEPCF_COMPRESSED_METRICS;
@@ -14,19 +17,19 @@ libparsepcf_get_metrics_count(const char *file, size_t size, const struct libpar
pos = table->offset;
- if (table->format != libparsepcf_parse_lsb_uint32__(&file[pos]))
+ if (table->format != libparsepcf_parse_lsb_uint32__(&text[pos]))
goto ebfont;
pos += 4;
if (compressed) {
- *countp = (size_t)PARSE_UINT16(&file[pos], msb);
+ *count = (size_t)PARSE_UINT16(&text[pos], msb);
pos += 2;
- if (*countp > (size - pos) / 5)
+ if (*count > (size - pos) / 5)
goto ebfont;
} else {
- *countp = (size_t)PARSE_UINT32(&file[pos], msb);
+ *count = (size_t)PARSE_UINT32(&text[pos], msb);
pos += 4;
- if (*countp > (size - pos) / 12)
+ if (*count > (size - pos) / 12)
goto ebfont;
}
diff --git a/libparsepcf_get_properties.c b/libparsepcf_get_properties.c
index f586a5c..9b7e383 100644
--- a/libparsepcf_get_properties.c
+++ b/libparsepcf_get_properties.c
@@ -3,10 +3,11 @@
int
-libparsepcf_get_properties(const char *file, size_t size,
+libparsepcf_get_properties(const void *file, size_t size,
const struct libparsepcf_table *table,
- struct libparsepcf_properties *out)
+ struct libparsepcf_properties *meta)
{
+ const char *text = file;
size_t pos;
int msb = table->format & LIBPARSEPCF_BYTE;
@@ -17,25 +18,25 @@ libparsepcf_get_properties(const char *file, size_t size,
pos = table->offset;
- if (table->format != libparsepcf_parse_lsb_uint32__(&file[pos]))
+ if (table->format != libparsepcf_parse_lsb_uint32__(&text[pos]))
goto ebfont;
pos += 4;
- out->property_count = (size_t)PARSE_UINT32(&file[pos], msb);
+ meta->property_count = (size_t)PARSE_UINT32(&text[pos], msb);
pos += 4;
if (4 > table->size - (pos - table->offset) ||
- out->property_count > (table->size - (pos - table->offset) - 4) / 9)
+ meta->property_count > (table->size - (pos - table->offset) - 4) / 9)
goto ebfont;
- pos += out->property_count * 9;
- pos += (4 - (out->property_count & 3)) & 3;
+ pos += meta->property_count * 9;
+ pos += (4 - (meta->property_count & 3)) & 3;
if (pos - table->offset > table->size - 4)
goto ebfont;
- out->strings_size = (size_t)PARSE_UINT32(&file[pos], msb);
+ meta->strings_size = (size_t)PARSE_UINT32(&text[pos], msb);
pos += 4;
- out->strings = &file[pos];
- if (out->strings_size > table->size - (pos - table->offset))
+ meta->strings = &text[pos];
+ if (meta->strings_size > table->size - (pos - table->offset))
goto ebfont;
return 0;
diff --git a/libparsepcf_get_property_subtable.c b/libparsepcf_get_property_subtable.c
index d19498c..5da1f56 100644
--- a/libparsepcf_get_property_subtable.c
+++ b/libparsepcf_get_property_subtable.c
@@ -3,12 +3,13 @@
int
-libparsepcf_get_property_subtable(const char *file, size_t size,
+libparsepcf_get_property_subtable(const void *file, size_t size,
const struct libparsepcf_table *table,
const struct libparsepcf_properties *meta,
struct libparsepcf_property_subtable *props,
- size_t first, size_t count)
+ size_t first, size_t count)
{
+ const char *text = file;
int msb = table->format & LIBPARSEPCF_BYTE;
size_t pos = table->offset + 8 + first * 9;
size_t i, off, maxlen;
@@ -16,7 +17,7 @@ libparsepcf_get_property_subtable(const char *file, size_t size,
(void) size;
for (i = 0; i < count; i++, pos += 9) {
- off = (size_t)PARSE_UINT32(&file[pos + 0], msb);
+ off = (size_t)PARSE_UINT32(&text[pos + 0], msb);
if (off > meta->strings_size)
goto ebfont;
maxlen = meta->strings_size - off;
@@ -24,10 +25,10 @@ libparsepcf_get_property_subtable(const char *file, size_t size,
if (!memchr(props[i].name, 0, maxlen))
goto ebfont;
- props[i].is_string_property = !!file[pos + 4];
+ props[i].is_string_property = !!text[pos + 4];
if (props[i].is_string_property) {
- off = (size_t)PARSE_UINT32(&file[pos + 5], msb);
+ off = (size_t)PARSE_UINT32(&text[pos + 5], msb);
if (off > meta->strings_size)
goto ebfont;
maxlen = meta->strings_size - off;
@@ -35,7 +36,7 @@ libparsepcf_get_property_subtable(const char *file, size_t size,
if (!memchr(props[i].value.string_value, 0, maxlen))
goto ebfont;
} else {
- props[i].value.signed_value = PARSE_INT32(&file[pos + 5], msb);
+ props[i].value.signed_value = PARSE_INT32(&text[pos + 5], msb);
}
}
diff --git a/libparsepcf_get_swidth_count.c b/libparsepcf_get_swidth_count.c
index 90a5f4a..f6010d0 100644
--- a/libparsepcf_get_swidth_count.c
+++ b/libparsepcf_get_swidth_count.c
@@ -3,8 +3,11 @@
int
-libparsepcf_get_swidth_count(const char *file, size_t size, const struct libparsepcf_table *table, size_t *countp)
+libparsepcf_get_swidth_count(const void *file, size_t size,
+ const struct libparsepcf_table *table,
+ size_t *count)
{
+ const char *text = file;
size_t pos;
int msb = table->format & LIBPARSEPCF_BYTE;
@@ -13,14 +16,14 @@ libparsepcf_get_swidth_count(const char *file, size_t size, const struct libpars
pos = table->offset;
- if (table->format != libparsepcf_parse_lsb_uint32__(&file[pos]))
+ if (table->format != libparsepcf_parse_lsb_uint32__(&text[pos]))
goto ebfont;
pos += 4;
- *countp = (size_t)PARSE_UINT32(&file[pos], msb);
+ *count = (size_t)PARSE_UINT32(&text[pos], msb);
pos += 4;
- if (*countp > (size - pos) / 4)
+ if (*count > (size - pos) / 4)
goto ebfont;
return 0;
diff --git a/libparsepcf_get_swidths.c b/libparsepcf_get_swidths.c
index d350b74..f96f14f 100644
--- a/libparsepcf_get_swidths.c
+++ b/libparsepcf_get_swidths.c
@@ -3,10 +3,11 @@
int
-libparsepcf_get_swidths(const char *file, size_t size,
+libparsepcf_get_swidths(const void *file, size_t size,
const struct libparsepcf_table *table,
- int32_t *out, size_t first, size_t count)
+ int32_t *widths, size_t first, size_t count)
{
+ const char *text = file;
int msb = table->format & LIBPARSEPCF_BYTE;
size_t pos = table->offset + 8 + 4 * first;
size_t i;
@@ -14,7 +15,7 @@ libparsepcf_get_swidths(const char *file, size_t size,
(void) size;
for (i = 0; i < count; i++, pos += 4)
- out[i] = PARSE_INT32(&file[pos], msb);
+ widths[i] = PARSE_INT32(&text[pos], msb);
return 0;
}
diff --git a/libparsepcf_get_table_count.c b/libparsepcf_get_table_count.c
index 0eb8741..a5ece0e 100644
--- a/libparsepcf_get_table_count.c
+++ b/libparsepcf_get_table_count.c
@@ -3,14 +3,15 @@
int
-libparsepcf_get_table_count(const char *file, size_t size, size_t *countp)
+libparsepcf_get_table_count(const void *file, size_t size, size_t *countp)
{
+ const char *text = file;
uint32_t count;
- if (size < 8 || file[0] != 1 || file[1] != 'f' || file[2] != 'c' || file[3] != 'p')
+ if (size < 8 || text[0] != 1 || text[1] != 'f' || text[2] != 'c' || text[3] != 'p')
goto ebfont;
- count = libparsepcf_parse_lsb_uint32__(&file[4]);
+ count = libparsepcf_parse_lsb_uint32__(&text[4]);
if (count > (size - 8) / 16)
goto ebfont;
diff --git a/libparsepcf_get_tables.c b/libparsepcf_get_tables.c
index 56cffc2..d1963e7 100644
--- a/libparsepcf_get_tables.c
+++ b/libparsepcf_get_tables.c
@@ -3,22 +3,25 @@
int
-libparsepcf_get_tables(const char *file, size_t size, struct libparsepcf_table *tables, size_t first, size_t count)
+libparsepcf_get_tables(const void *file, size_t size,
+ struct libparsepcf_table *tables,
+ size_t first, size_t count)
{
+ const char *text = file;
size_t pos = 8 + first * 16;
size_t i;
for (i = 0; i < count; i++, pos += 16) {
- tables[i].type = libparsepcf_parse_lsb_uint32__(&file[pos + 0]);
- tables[i].format = libparsepcf_parse_lsb_uint32__(&file[pos + 4]);
- tables[i].size = libparsepcf_parse_lsb_uint32__(&file[pos + 8]);
- tables[i].offset = libparsepcf_parse_lsb_uint32__(&file[pos + 12]);
+ tables[i].type = libparsepcf_parse_lsb_uint32__(&text[pos + 0]);
+ tables[i].format = libparsepcf_parse_lsb_uint32__(&text[pos + 4]);
+ tables[i].size = libparsepcf_parse_lsb_uint32__(&text[pos + 8]);
+ tables[i].offset = libparsepcf_parse_lsb_uint32__(&text[pos + 12]);
if ((size_t)tables[i].offset > size)
goto ebfont;
- /* For some reasons files specify table sizes such that they
- * actually except the boundary of the file, despite not using
+ /* For some reason files specify table sizes such that they
+ * actually exceed the boundary of the file, despite not using
* that much data. Don't including this fix, but instead check
* that the table size is not too large, will break your
* favourite fonts. */
diff --git a/libparsepcf_preparse_font.c b/libparsepcf_preparse_font.c
index 058365a..63c245e 100644
--- a/libparsepcf_preparse_font.c
+++ b/libparsepcf_preparse_font.c
@@ -3,11 +3,13 @@
int
-libparsepcf_preparse_font(const char *file, size_t size, struct libparsepcf_font *font)
+libparsepcf_preparse_font(const void *file, size_t size, struct libparsepcf_font *font)
{
size_t min = SIZE_MAX, max = 0, table_i, table_n;
struct libparsepcf_table *tables = NULL;
+ *font = (struct libparsepcf_font){0};
+
if (libparsepcf_get_table_count(file, size, &table_n))
goto fail;
tables = calloc(table_n, sizeof(*tables));