summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile3
-rw-r--r--hdmx.c89
-rw-r--r--libparsesfnt.h35
3 files changed, 126 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 11982d0..874f5ec 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,8 @@ MODULES =\
fdsc\
gasp\
avar\
- meta
+ meta\
+ hdmx
OBJ =\
libparsesfnt_parse___.o\
diff --git a/hdmx.c b/hdmx.c
new file mode 100644
index 0000000..0fefa12
--- /dev/null
+++ b/hdmx.c
@@ -0,0 +1,89 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libparsesfnt_parse_hdmx(
+ const char *data, size_t size,
+ struct libparsesfnt_hdmx *infop,
+ const struct libparsesfnt_tabdir_entry *tag)
+{
+ int ret;
+ ret = PARSE(LIBPARSESFNT_HDMX__, tag->offset, 0, 0, 0, 1, tag);
+ if (!ret) {
+ if (!infop->record_size ||
+ (size_t)infop->num_records > (size_t)tag->length / (size_t)infop->record_size) {
+ errno = EBFONT;
+ return -1;
+ }
+ }
+ return ret;
+}
+
+
+int
+libparsesfnt_parse_hdmx_entries(
+ const char *data, size_t size,
+ struct libparsesfnt_hdmx_v0_entry *infop,
+ const struct libparsesfnt_tabdir_entry *tag, const struct libparsesfnt_hdmx *hdmx,
+ size_t first, size_t count)
+{
+ size_t off;
+
+ off = tag->offset;
+ if (off > size || 8 > size - off || hdmx->record_size < 2)
+ goto ebfont;
+ off += 8;
+ if (first > (size - off) / hdmx->record_size)
+ goto ebfont;
+ off += hdmx->record_size * first;
+ if (count > (size - off) / hdmx->record_size)
+ goto ebfont;
+
+ data = &data[off];
+ for (; count--; infop++) {
+ infop->pixel_size = ((const uint8_t *)data)[0];
+ infop->maximum_width = ((const uint8_t *)data)[1];
+ data = &data[2];
+ }
+
+ return 0;
+
+ebfont:
+ errno = EBFONT;
+ return -1;
+}
+
+
+int
+libparsesfnt_parse_hdmx_v0_subentry(
+ const char *data, size_t size,
+ uint8_t *widthp,
+ const struct libparsesfnt_tabdir_entry *tag, const struct libparsesfnt_hdmx *hdmx, size_t record,
+ size_t first, size_t count)
+{
+ size_t off;
+
+ off = tag->offset;
+ if (off > size || 10 > size - off)
+ goto ebfont;
+ off += 10;
+ if (record > (size - off) / hdmx->record_size)
+ goto ebfont;
+ off += hdmx->record_size * record;
+ if (first > size - off)
+ goto ebfont;
+ off += first;
+ if (count > size - off)
+ goto ebfont;
+
+ if (2 > hdmx->record_size || first + count > hdmx->record_size - 2)
+ goto ebfont;
+
+ memcpy(widthp, &data[off], count);
+ return 0;
+
+ebfont:
+ errno = EBFONT;
+ return -1;
+}
diff --git a/libparsesfnt.h b/libparsesfnt.h
index 809fad7..f79ed03 100644
--- a/libparsesfnt.h
+++ b/libparsesfnt.h
@@ -768,4 +768,39 @@ int libparsesfnt_parse_meta_entries(
size_t first, size_t count);
+
+/* === 'hdmx' (horizontal device metrics) === */
+/* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6hdmx.html */
+
+struct libparsesfnt_hdmx {
+ uint16_t version;
+ uint16_t num_records;
+ uint32_t record_size; /* includes alignment */
+};
+#define LIBPARSESFNT_HDMX__ "224"
+
+struct libparsesfnt_hdmx_v0_entry {
+ uint8_t pixel_size;
+ uint8_t maximum_width;
+};
+#define LIBPARSESFNT_HDMX_V0_ENTRY__ "11"
+
+int libparsesfnt_parse_hdmx(
+ const char *data, size_t size,
+ struct libparsesfnt_hdmx *infop,
+ const struct libparsesfnt_tabdir_entry *tag);
+
+int libparsesfnt_parse_hdmx_v0_entries(
+ const char *data, size_t size,
+ struct libparsesfnt_hdmx_v0_entry *infop,
+ const struct libparsesfnt_tabdir_entry *tag, const struct libparsesfnt_hdmx *hdmx,
+ size_t first, size_t count);
+
+int libparsesfnt_parse_hdmx_v0_subentry(
+ const char *data, size_t size,
+ uint8_t *widthp,
+ const struct libparsesfnt_tabdir_entry *tag, const struct libparsesfnt_hdmx *hdmx, size_t record,
+ size_t first, size_t count);
+
+
#endif