From 7eb0d92453b888728cb1b7b418afc04d3fb438e2 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 16 Aug 2021 00:17:06 +0200 Subject: Add post + fix indention in hdmx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 3 +- hdmx.c | 10 ++-- libparsesfnt.h | 57 ++++++++++++++++++- libparsesfnt_parse___.c | 1 + post.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 post.c diff --git a/Makefile b/Makefile index 874f5ec..dd8a360 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,8 @@ MODULES =\ gasp\ avar\ meta\ - hdmx + hdmx\ + post OBJ =\ libparsesfnt_parse___.o\ diff --git a/hdmx.c b/hdmx.c index 0fefa12..e4830c2 100644 --- a/hdmx.c +++ b/hdmx.c @@ -56,11 +56,11 @@ ebfont: 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) +libparsesfnt_parse_hdmx_v0_subentries( + 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; diff --git a/libparsesfnt.h b/libparsesfnt.h index f79ed03..fce6611 100644 --- a/libparsesfnt.h +++ b/libparsesfnt.h @@ -796,11 +796,66 @@ int libparsesfnt_parse_hdmx_v0_entries( const struct libparsesfnt_tabdir_entry *tag, const struct libparsesfnt_hdmx *hdmx, size_t first, size_t count); -int libparsesfnt_parse_hdmx_v0_subentry( +int libparsesfnt_parse_hdmx_v0_subentries( 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); + +/* === 'post' (glyph name and PostScript compatibility) === */ +/* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html */ + +struct libparsesfnt_post_format2_subtable { + uint16_t number_of_glyphs; +}; +#define LIBPARSESFNT_POST_FORMAT2__ "2" + +struct libparsesfnt_post { + uint32_t format; + int32_t italic_angle; + int16_t underline_position; + int16_t underline_thickness; + uint32_t is_fixed_pitch; + uint32_t min_mem_type_42; + uint32_t max_mem_type_42; + uint32_t min_mem_type_1; + uint32_t max_mem_type_1; + union { + struct libparsesfnt_post_format2_subtable v2; /* 2.x */ + } subtable; +}; +#define LIBPARSESFNT_POST__ "4-422+44444" + +int libparsesfnt_parse_post( + const char *data, size_t size, + struct libparsesfnt_post *infop, + const struct libparsesfnt_tabdir_entry *tag); + +int libparsesfnt_parse_post_format_2_0_indices( + const char *data, size_t size, + uint16_t *indexp, + const struct libparsesfnt_tabdir_entry *tag, + size_t first, size_t count); + +int libparsesfnt_parse_post_format_2_0_name( + const char *data, size_t size, + char namep[256], + const struct libparsesfnt_tabdir_entry *tag, const struct libparsesfnt_post *post, + size_t *offsetp /* start at 0 */); + +int libparsesfnt_parse_post_format_2_5_offsets( + const char *data, size_t size, + int16_t *offsetp, + const struct libparsesfnt_tabdir_entry *tag, + size_t first, size_t count); + +int libparsesfnt_parse_post_format_4_0_indices( + const char *data, size_t size, + uint16_t *indexp, + const struct libparsesfnt_tabdir_entry *tag, + size_t first, size_t count); + + #endif diff --git a/libparsesfnt_parse___.c b/libparsesfnt_parse___.c index 17ee018..6e89dc0 100644 --- a/libparsesfnt_parse___.c +++ b/libparsesfnt_parse___.c @@ -122,6 +122,7 @@ libparsesfnt_parse___(const char *data, size_t size, void *infop, size_t esize, if (offset + count * need > size || (tag && (tag->length < count * need || tag->length > size || + tag->offset > size - tag->length || tag_offset > tag->length || first + count > (tag->length - tag_offset) / need))) goto ebfont; diff --git a/post.c b/post.c new file mode 100644 index 0000000..18cafab --- /dev/null +++ b/post.c @@ -0,0 +1,143 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static uint16_t +post_parse16(const char *data) +{ + uint16_t b1 = (uint16_t)((const uint8_t *)data)[0]; + uint16_t b2 = (uint16_t)((const uint8_t *)data)[1]; + b1 = (uint16_t)(b1 << 8); + b2 = (uint16_t)(b2 << 0); + return (uint16_t)(b1 | b2); +} + +static void +post_sign16(union {uint16_t u; int16_t s;} *info) +{ + info->s = ((info->u >> 15) ? -(int16_t)(~info->u + 1) : (int16_t)info->u); +} + + +int +libparsesfnt_parse_post( + const char *data, size_t size, + struct libparsesfnt_post *infop, + const struct libparsesfnt_tabdir_entry *tag) +{ + int ret; + ret = PARSE(LIBPARSESFNT_POST__, tag->offset, 0, 0, 0, 1, tag); + if (!ret) { + if (infop->format >> 16 == 2) { + if (2 > tag->length - tag->offset) + goto ebfont; + infop->subtable.v2.number_of_glyphs = post_parse16(&data[tag->offset + 2]); + } + } + return ret; + +ebfont: + errno = EBFONT; + return -1; +} + + +static int +post_indices( + const char *data, size_t size, + uint16_t *indexp, + const struct libparsesfnt_tabdir_entry *tag, + size_t first, size_t count, + size_t offset) +{ + if (offset > tag->length || first > (tag->length - offset) / 2) + goto ebfont; + offset += first * 2; + if (count > (tag->length - offset) / 2) + goto ebfont; + if (tag->offset > size || offset > size - tag->offset) + goto ebfont; + offset += tag->offset; + + for (; count--; indexp++, offset += 2) + *indexp = post_parse16(&data[offset]); + + return 0; + +ebfont: + errno = EBFONT; + return -1; +} + + +int +libparsesfnt_parse_post_format_2_0_indices( + const char *data, size_t size, + uint16_t *indexp, + const struct libparsesfnt_tabdir_entry *tag, + size_t first, size_t count) +{ + return post_indices(data, size, indexp, tag, first, count, 34); +} + + +int +libparsesfnt_parse_post_format_2_0_name( + const char *data, size_t size, + char namep[256], + const struct libparsesfnt_tabdir_entry *tag, const struct libparsesfnt_post *post, + size_t *offsetp /* start at 0 */) +{ + size_t len; + + if (!*offsetp) { + if ((size_t)post->subtable.v2.number_of_glyphs > ((size_t)tag->length - 34) / 2) + goto ebfont; + *offsetp = 34 + (size_t)post->subtable.v2.number_of_glyphs / 2; + if ((size_t)tag->length > size - (size_t)tag->offset) + goto ebfont; + } + + if (*offsetp >= (size_t)tag->length) + goto ebfont; + len = (size_t)*(const uint8_t *)&data[*offsetp]; + *offsetp += 1; + + if (len > (size_t)tag->length - *offsetp) + goto ebfont; + memcpy(namep, &data[*offsetp], len); + namep[len] = 0; + *offsetp += len; + + return 0; + +ebfont: + errno = EBFONT; + return -1; +} + + +int +libparsesfnt_parse_post_format_2_5_offsets( + const char *data, size_t size, + int16_t *offsetp, + const struct libparsesfnt_tabdir_entry *tag, + size_t first, size_t count) +{ + if (post_indices(data, size, (uint16_t *)offsetp, tag, first, count, 34)) + return -1; + for (; count--; offsetp++) + post_sign16((void *)offsetp); + return 0; +} + + +int +libparsesfnt_parse_post_format_4_0_indices( + const char *data, size_t size, + uint16_t *indexp, + const struct libparsesfnt_tabdir_entry *tag, + size_t first, size_t count) +{ + return post_indices(data, size, indexp, tag, first, count, 32); +} -- cgit v1.2.3-70-g09d2