aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--demo.c42
-rw-r--r--libparsepcf.h109
-rw-r--r--libparsepcf_get_bitmaps.c4
-rw-r--r--libparsepcf_get_encoding.c8
5 files changed, 121 insertions, 45 deletions
diff --git a/Makefile b/Makefile
index 17ee3d3..cabef3f 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ OS = linux
include mk/$(OS).mk
-LIB_MAJOR = 1
+LIB_MAJOR = 2
LIB_MINOR = 0
LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR)
LIB_NAME = parsepcf
@@ -52,6 +52,7 @@ SRC = $(OBJ:.o=.c)
all: libparsepcf.a libparsepcf.$(LIBEXT) demo
$(OBJ): $(HDR)
$(LOBJ): $(HDR)
+demo.o: $(HDR)
demo: demo.o libparsepcf.a
$(CC) -o $@ demo.o libparsepcf.a $(LDFLAGS)
diff --git a/demo.c b/demo.c
index 80ac748..ff1e39f 100644
--- a/demo.c
+++ b/demo.c
@@ -165,8 +165,8 @@ print_bitmaps(void)
printf("\tsize: %zu\n", bitmaps.bitmap_size);
printf("\tpacking: %zu\n", bitmaps.bit_packing);
printf("\tpadding: %zu\n", bitmaps.row_padding);
- printf("\tlsbyte: %i\n", bitmaps.lsbyte);
- printf("\tlsbit: %i\n", bitmaps.lsbit);
+ printf("\tmsbyte_first: %i\n", bitmaps.msbyte_first);
+ printf("\tmsbit_first: %i\n", bitmaps.msbit_first);
if (!bitmaps.glyph_count)
return;
bitmaptab = calloc(bitmaps.glyph_count, sizeof(*bitmaptab));
@@ -205,17 +205,17 @@ print_bdf_encodings(void)
printf(" BDF ENCODINGS:\n");
printf("\trange2: [%u, %u]\n", encoding.min_byte2, encoding.max_byte2);
printf("\trange1: [%u, %u]\n", encoding.min_byte1, encoding.max_byte1);
- printf("\tdefault: %u\n", encoding.default_char);
- printf("\tnglyph: %zu\n", encoding.glyph_count);
- if (!encoding.glyph_count)
+ printf("\tdefault: %u\n", encoding.default_glyph);
+ printf("\tnchar: %zu\n", encoding.char_count);
+ if (!encoding.char_count)
return;
- indices = calloc(encoding.glyph_count, sizeof(*indices));
+ indices = calloc(encoding.char_count, sizeof(*indices));
if (libparsepcf_get_glyph_indices(file, len, &tables[table_i], &encoding,
- indices, 0, encoding.glyph_count)) {
+ indices, 0, encoding.char_count)) {
perror("libparsepcf_get_glyph_indices");
exit(1);
}
- for (index_i = 0; index_i < encoding.glyph_count; index_i++) {
+ for (index_i = 0; index_i < encoding.char_count; index_i++) {
if (indices[index_i] == LIBPARSEPCF_NOT_ENCODED)
printf("\t#%#zx: not encoded\n", index_i);
else
@@ -498,10 +498,10 @@ print_glyph(size_t glyph)
/* Draw glyph */
for (x = 0; x < width; x++) {
- bit = font.bitmaps.lsbit ? 7 - x % 8 : x % 8;
+ bit = font.bitmaps.msbit_first ? 7 - x % 8 : x % 8;
byte = x / 8;
- if (!font.bitmaps.lsbyte)
- byte = ((byte & ~packing) | (packing - (byte & packing)));
+ if (font.bitmaps.msbyte_first != font.bitmaps.msbit_first)
+ byte ^= packing;
/* Use <> to mark dots outside of the glyph box */
if (mtx.left_side_bearing < 0 &&
@@ -521,7 +521,7 @@ print_glyph(size_t glyph)
}
printf("\033[%sm%s\033[%sm",
- ((bitmap[byte] >> bit) & 1) ? "1;37" : "2;37", pixel,
+ (bitmap[byte] & (1 << bit)) ? "1;37" : "2;37", pixel,
(int64_t)y + 1 == (int64_t)mtx.character_ascent ? "0;4" : "0");
}
@@ -650,11 +650,11 @@ draw_glyph(size_t glyph, int32_t *xp, char ***linesp, int32_t *leftp, int32_t *r
ypos = (size_t)(*ascentp - mtx.character_ascent);
for (y = 0; y < height; y++, bitmap += row_size) {
for (x = 0; x < width; x++) {
- bit = font.bitmaps.lsbit ? 7 - x % 8 : x % 8;
+ bit = font.bitmaps.msbit_first ? 7 - x % 8 : x % 8;
byte = x / 8;
- if (!font.bitmaps.lsbyte)
- byte = ((byte & ~packing) | (packing - (byte & packing)));
- if ((bitmap[byte] >> bit) & 1)
+ if (font.bitmaps.msbyte_first != font.bitmaps.msbit_first)
+ byte ^= packing;
+ if (bitmap[byte] & (1 << bit))
(*linesp)[y + ypos][x + xpos] |= 1;
}
}
@@ -679,7 +679,7 @@ print_line(const char *str)
if (n) {
if ((*s & 0xC0) != 0x80) {
n = 0;
- glyph = (size_t)font.encoding.default_char;
+ glyph = (size_t)font.encoding.default_glyph;
goto have_glyph;
} else {
n -= 1;
@@ -687,7 +687,7 @@ print_line(const char *str)
codepoint |= *s++ & 0x3F;
}
} else if ((*s & 0xC0) == 0x80) {
- glyph = (size_t)font.encoding.default_char;
+ glyph = (size_t)font.encoding.default_glyph;
s++;
goto have_glyph;
} else if (*s & 0x80) {
@@ -709,7 +709,7 @@ print_line(const char *str)
if (codepoint > UINT32_C(0xFFFF) ||
codepoint < (uint32_t)font.encoding.min_byte2 ||
codepoint > (uint32_t)font.encoding.max_byte2) {
- glyph = (size_t)font.encoding.default_char;
+ glyph = (size_t)font.encoding.default_glyph;
goto have_glyph;
}
glyph = codepoint - (uint32_t)font.encoding.min_byte2;
@@ -721,7 +721,7 @@ print_line(const char *str)
hi > (uint32_t)font.encoding.max_byte1 ||
lo < (uint32_t)font.encoding.min_byte2 ||
lo > (uint32_t)font.encoding.max_byte2) {
- glyph = (size_t)font.encoding.default_char;
+ glyph = (size_t)font.encoding.default_glyph;
goto have_glyph;
}
glyph = (size_t)(uint16_t)(hi * k + lo - m);
@@ -734,7 +734,7 @@ print_line(const char *str)
have_glyph:
if (glyph == LIBPARSEPCF_NOT_ENCODED)
- glyph = (size_t)font.encoding.default_char;
+ glyph = (size_t)font.encoding.default_glyph;
draw_glyph(glyph, &xpos, &lines, &left, &right, &ascent, &descent);
}
diff --git a/libparsepcf.h b/libparsepcf.h
index eef98c8..f7e6941 100644
--- a/libparsepcf.h
+++ b/libparsepcf.h
@@ -9,7 +9,6 @@
/* Based on documentation from FontForge: https://fontforge.org/docs/techref/pcf-format.html */
-
/**
* Table metadata
*/
@@ -399,28 +398,113 @@ struct libparsepcf_bitmaps {
/**
* The size of `.bitmap_data`
+ *
+ * Used internally to detect corruption
*/
size_t bitmap_size;
+ /**
+ * For each row in a glyph, cells' ink status are
+ * encoded in bits that are packed into groups of
+ * units, and the bits are ordered according to
+ * `.msbit_first` within each group. This field
+ * specifies the number of bytes in each group.
+ *
+ * This will always be a power of two and
+ * no greater than `.row_padding`
+ */
size_t bit_packing;
/**
- * The number of bytes each row is
- * padded to align to
+ * 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;
+ /**
+ * This field specify the order of the bytes for
+ * each group of bits as described in the documentation
+ * of `.bit_packing`. The value will be either 0 or 1
+ *
+ * If 0, the bytes in each glyph cell group is ordered
+ * such that the least significant bit octet is stored
+ * in the first byte
+ *
+ * If 1, the bytes in each glyph cell group is ordered
+ * such that the least significant bit octet is stored
+ * in the first byte
+ */
+ int msbyte_first; /* called "lsbyte" in 1.0 */
+
+ /**
+ * Will either be 0 or 1
+ *
+ * If 0, glyph cells (left to right) are encoded from
+ * the least significant bit to the most significant
+ * bit within each byte
+ *
+ * If 1, glyph cells (left to right) are encoded from
+ * the most significant bit to the least significant
+ * bit within each byte
+ */
+ int msbit_first; /* called "lsbit" in 1.0 */
+
+ /**
+ * Bitmap data, `libparsepcf_get_bitmap_offsets` should be
+ * be used to find where in this buffer the bitmap for a
+ * particular glyph begins, and the `LIBPARSEPCF_INK_METRICS`
+ * table shall be used (along with information in this
+ * structure) to decode the bitmap data; if the table
+ * `LIBPARSEPCF_INK_METRICS` is missing the
+ * `LIBPARSEPCF_METRICS` (layout metrics) should be used
+ * instead
+ *
+ * Bitmaps are in row-major order, top to bottom,
+ * and in column-minor order, left to right
+ *
+ * Set bits represent ink-on, cleared bits represent ink-off
+ */
const uint8_t *bitmap_data;
};
+/**
+ * Get the bitmaps metadata for the glyphs in the file
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_BITMAPS`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta Output parameter for the glyph bitmap metadata
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
int libparsepcf_get_bitmaps(const void *, size_t,
const struct libparsepcf_table *,
struct libparsepcf_bitmaps *);
+/**
+ * Get the offsets to the bitmaps for glyphs in the file
+ *
+ * The first four arguments shall be the same as
+ * passed into `libparsepcf_get_bitmaps`
+ *
+ * @param file The file content
+ * @param size The file size
+ * @param table The table in the file with the `.type` `LIBPARSEPCF_BITMAPS`,
+ * extracted using the `libparsepcf_get_tables` function
+ * @param meta Glyph bitmap metadata
+ * @param offs Output parameter for the bitmap offsets
+ * @param first The index of the first glyph whose bitmap offset to store
+ * in `offs`, the first glyph in the file has the index 0
+ * @param count The number of glyphs whose bitmap offsets to store in `offs`;
+ * may not exceed the number of properties (`.glyph_count`)
+ * as retrieved by `libparsepcf_get_bitmaps` minus `first`
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EBFONT The file is not a properly formatted PCF file
+ */
int libparsepcf_get_bitmap_offsets(const void *, size_t,
const struct libparsepcf_table *,
const struct libparsepcf_bitmaps *,
@@ -501,25 +585,16 @@ struct libparsepcf_encoding {
* 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;
+ uint16_t default_glyph; /* called "default_char" in 1.0 */
/**
* 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`.
- *
- * 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"
+ * `.max_byte1 - .min_byte1 + 1`
*/
- size_t glyph_count;
+ size_t char_count; /* called "glyph_count" in 1.0 */
};
/**
diff --git a/libparsepcf_get_bitmaps.c b/libparsepcf_get_bitmaps.c
index cad51f3..8265db3 100644
--- a/libparsepcf_get_bitmaps.c
+++ b/libparsepcf_get_bitmaps.c
@@ -39,8 +39,8 @@ libparsepcf_get_bitmaps(const void *file, size_t size,
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);
+ meta->msbyte_first = !!(table->format & LIBPARSEPCF_BYTE);
+ meta->msbit_first = !!(table->format & LIBPARSEPCF_BIT);
if (meta->row_padding < meta->bit_packing)
goto ebfont;
diff --git a/libparsepcf_get_encoding.c b/libparsepcf_get_encoding.c
index 6c28c6a..86b790d 100644
--- a/libparsepcf_get_encoding.c
+++ b/libparsepcf_get_encoding.c
@@ -26,16 +26,16 @@ libparsepcf_get_encoding(const void *file, size_t size,
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);
+ meta->default_glyph = PARSE_UINT16(&text[pos + 8], msb);
pos += 10;
if (meta->min_byte2 > meta->max_byte2 || meta->max_byte2 > 255 ||
meta->min_byte1 > meta->max_byte1 || meta->max_byte1 > 255)
goto ebfont;
- 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)
+ meta->char_count = (size_t)(meta->max_byte2 - meta->min_byte2 + 1);
+ meta->char_count *= (size_t)(meta->max_byte1 - meta->min_byte1 + 1);
+ if (meta->char_count > table->size - (pos - table->offset) / 2)
goto ebfont;
return 0;