diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh | 197 |
1 files changed, 108 insertions, 89 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh index 7f1c2c420f..38302f5518 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh @@ -27,8 +27,7 @@ #ifndef HB_OT_POST_TABLE_HH #define HB_OT_POST_TABLE_HH -#include "hb-open-type-private.hh" -#include "hb-dsalgs.hh" +#include "hb-open-type.hh" #define HB_STRING_ARRAY_NAME format1_names #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh" @@ -38,113 +37,117 @@ #define NUM_FORMAT1_NAMES 258 -namespace OT { - - /* * post -- PostScript + * https://docs.microsoft.com/en-us/typography/opentype/spec/post */ - #define HB_OT_TAG_post HB_TAG('p','o','s','t') +namespace OT { + + struct postV2Tail { - inline bool sanitize (hb_sanitize_context_t *c) const + friend struct post; + + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (glyphNameIndex.sanitize (c)); } - ArrayOf<UINT16>glyphNameIndex; /* This is not an offset, but is the + protected: + ArrayOf<HBUINT16> glyphNameIndex; /* This is not an offset, but is the * ordinal number of the glyph in 'post' * string tables. */ - UINT8 namesX[VAR]; /* Glyph names with length bytes [variable] +/*UnsizedArrayOf<HBUINT8> + namesX;*/ /* Glyph names with length bytes [variable] * (a Pascal string). */ - DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX); + public: + DEFINE_SIZE_ARRAY (2, glyphNameIndex); }; struct post { - static const hb_tag_t tableTag = HB_OT_TAG_post; + static constexpr hb_tag_t tableTag = HB_OT_TAG_post; - inline bool sanitize (hb_sanitize_context_t *c) const + void serialize (hb_serialize_context_t *c) const { - TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); - if (version.to_int () == 0x00020000) - { - const postV2Tail &v2 = StructAfter<postV2Tail> (*this); - return_trace (v2.sanitize (c)); - } + post *post_prime = c->allocate_min<post> (); + if (unlikely (!post_prime)) return; + + memcpy (post_prime, this, post::min_size); + post_prime->version.major = 3; // Version 3 does not have any glyph names. + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + post *post_prime = c->serializer->start_embed<post> (); + if (unlikely (!post_prime)) return_trace (false); + + serialize (c->serializer); + if (c->serializer->in_error () || c->serializer->ran_out_of_room) return_trace (false); + return_trace (true); } struct accelerator_t { - inline void init (hb_face_t *face) + void init (hb_face_t *face) { - blob = Sanitizer<post>::sanitize (face->reference_table (HB_OT_TAG_post)); - const post *table = Sanitizer<post>::lock_instance (blob); - unsigned int table_length = hb_blob_get_length (blob); + index_to_offset.init (); + + table = hb_sanitize_context_t ().reference_table<post> (face); + unsigned int table_length = table.get_length (); version = table->version.to_int (); - index_to_offset.init (); - if (version != 0x00020000) - return; + if (version != 0x00020000) return; - const postV2Tail &v2 = StructAfter<postV2Tail> (*table); + const postV2Tail &v2 = table->v2X; glyphNameIndex = &v2.glyphNameIndex; pool = &StructAfter<uint8_t> (v2.glyphNameIndex); - const uint8_t *end = (uint8_t *) table + table_length; - for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data) - { - uint32_t *offset = index_to_offset.push (); - if (unlikely (!offset)) - break; - *offset = data - pool; - } + const uint8_t *end = (const uint8_t *) (const void *) table + table_length; + for (const uint8_t *data = pool; + index_to_offset.length < 65535 && data < end && data + *data < end; + data += 1 + *data) + index_to_offset.push (data - pool); } - inline void fini (void) + void fini () { - index_to_offset.finish (); - free (gids_sorted_by_name); + index_to_offset.fini (); + free (gids_sorted_by_name.get ()); + table.destroy (); } - inline bool get_glyph_name (hb_codepoint_t glyph, - char *buf, unsigned int buf_len) const + bool get_glyph_name (hb_codepoint_t glyph, + char *buf, unsigned int buf_len) const { - hb_string_t s = find_glyph_name (glyph); - if (!s.len) - return false; - if (!buf_len) - return true; - if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */ - return false; - strncpy (buf, s.bytes, s.len); - buf[s.len] = '\0'; + hb_bytes_t s = find_glyph_name (glyph); + if (!s.length) return false; + if (!buf_len) return true; + unsigned int len = hb_min (buf_len - 1, s.length); + strncpy (buf, s.arrayZ, len); + buf[len] = '\0'; return true; } - inline bool get_glyph_from_name (const char *name, int len, - hb_codepoint_t *glyph) const + bool get_glyph_from_name (const char *name, int len, + hb_codepoint_t *glyph) const { unsigned int count = get_glyph_count (); - if (unlikely (!count)) - return false; + if (unlikely (!count)) return false; - if (len < 0) - len = strlen (name); + if (len < 0) len = strlen (name); - if (unlikely (!len)) - return false; + if (unlikely (!len)) return false; retry: - uint16_t *gids = (uint16_t *) hb_atomic_ptr_get (&gids_sorted_by_name); + uint16_t *gids = gids_sorted_by_name.get (); if (unlikely (!gids)) { @@ -154,16 +157,18 @@ struct post for (unsigned int i = 0; i < count; i++) gids[i] = i; - hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this); + hb_qsort (gids, count, sizeof (gids[0]), cmp_gids, (void *) this); - if (!hb_atomic_ptr_cmpexch (&gids_sorted_by_name, nullptr, gids)) { + if (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids))) + { free (gids); goto retry; } } - hb_string_t st (name, len); - const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this); + hb_bytes_t st (name, len); + const uint16_t *gid = (const uint16_t *) hb_bsearch (hb_addressof (st), gids, count, + sizeof (gids[0]), cmp_key, (void *) this); if (gid) { *glyph = *gid; @@ -173,20 +178,22 @@ struct post return false; } + hb_blob_ptr_t<post> table; + protected: - inline unsigned int get_glyph_count (void) const + unsigned int get_glyph_count () const { if (version == 0x00010000) - return NUM_FORMAT1_NAMES; + return NUM_FORMAT1_NAMES; if (version == 0x00020000) - return glyphNameIndex->len; + return glyphNameIndex->len; return 0; } - static inline int cmp_gids (const void *pa, const void *pb, void *arg) + static int cmp_gids (const void *pa, const void *pb, void *arg) { const accelerator_t *thiz = (const accelerator_t *) arg; uint16_t a = * (const uint16_t *) pa; @@ -194,58 +201,68 @@ struct post return thiz->find_glyph_name (b).cmp (thiz->find_glyph_name (a)); } - static inline int cmp_key (const void *pk, const void *po, void *arg) + static int cmp_key (const void *pk, const void *po, void *arg) { const accelerator_t *thiz = (const accelerator_t *) arg; - const hb_string_t *key = (const hb_string_t *) pk; + const hb_bytes_t *key = (const hb_bytes_t *) pk; uint16_t o = * (const uint16_t *) po; return thiz->find_glyph_name (o).cmp (*key); } - inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const + hb_bytes_t find_glyph_name (hb_codepoint_t glyph) const { if (version == 0x00010000) { if (glyph >= NUM_FORMAT1_NAMES) - return hb_string_t (); + return hb_bytes_t (); return format1_names (glyph); } if (version != 0x00020000 || glyph >= glyphNameIndex->len) - return hb_string_t (); + return hb_bytes_t (); - unsigned int index = glyphNameIndex->array[glyph]; + unsigned int index = glyphNameIndex->arrayZ[glyph]; if (index < NUM_FORMAT1_NAMES) return format1_names (index); index -= NUM_FORMAT1_NAMES; - if (index >= index_to_offset.len) - return hb_string_t (); - unsigned int offset = index_to_offset.array[index]; + if (index >= index_to_offset.length) + return hb_bytes_t (); + unsigned int offset = index_to_offset[index]; const uint8_t *data = pool + offset; unsigned int name_length = *data; data++; - return hb_string_t ((const char *) data, name_length); + return hb_bytes_t ((const char *) data, name_length); } private: - hb_blob_t *blob; uint32_t version; - const ArrayOf<UINT16> *glyphNameIndex; - hb_prealloced_array_t<uint32_t, 1> index_to_offset; + const ArrayOf<HBUINT16> *glyphNameIndex; + hb_vector_t<uint32_t> index_to_offset; const uint8_t *pool; - mutable uint16_t *gids_sorted_by_name; + hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name; }; + bool has_data () const { return version.to_int (); } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (version.to_int () == 0x00010000 || + (version.to_int () == 0x00020000 && v2X.sanitize (c)) || + version.to_int () == 0x00030000))); + } + public: FixedVersion<>version; /* 0x00010000 for version 1.0 * 0x00020000 for version 2.0 * 0x00025000 for version 2.5 (deprecated) * 0x00030000 for version 3.0 */ - Fixed italicAngle; /* Italic angle in counter-clockwise degrees + HBFixed italicAngle; /* Italic angle in counter-clockwise degrees * from the vertical. Zero for upright text, * negative for text that leans to the right * (forward). */ @@ -261,21 +278,23 @@ struct post * from the value of this field. */ FWORD underlineThickness; /* Suggested values for the underline thickness. */ - UINT32 isFixedPitch; /* Set to 0 if the font is proportionally + HBUINT32 isFixedPitch; /* Set to 0 if the font is proportionally * spaced, non-zero if the font is not * proportionally spaced (i.e. monospaced). */ - UINT32 minMemType42; /* Minimum memory usage when an OpenType font + HBUINT32 minMemType42; /* Minimum memory usage when an OpenType font * is downloaded. */ - UINT32 maxMemType42; /* Maximum memory usage when an OpenType font + HBUINT32 maxMemType42; /* Maximum memory usage when an OpenType font * is downloaded. */ - UINT32 minMemType1; /* Minimum memory usage when an OpenType font + HBUINT32 minMemType1; /* Minimum memory usage when an OpenType font * is downloaded as a Type 1 font. */ - UINT32 maxMemType1; /* Maximum memory usage when an OpenType font + HBUINT32 maxMemType1; /* Maximum memory usage when an OpenType font * is downloaded as a Type 1 font. */ -/*postV2Tail v2[VAR];*/ - DEFINE_SIZE_STATIC (32); + postV2Tail v2X; + DEFINE_SIZE_MIN (32); }; +struct post_accelerator_t : post::accelerator_t {}; + } /* namespace OT */ |