From c7439d4e3a76d596845aad4e4bc860bd61ee47e3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 5 Jun 2019 12:13:49 -0700 Subject: [PATCH 01/32] Slightly massage buffer-messaging commit Saves a few bytes. --- src/hb-buffer.cc | 3 --- src/hb-buffer.hh | 8 +++++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index bbbbd227c..5dd83fc2c 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -2026,9 +2026,6 @@ hb_buffer_set_message_func (hb_buffer_t *buffer, bool hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap) { -#ifdef HB_NO_BUFFER_MESSAGE - return false; -#endif char buf[100]; vsnprintf (buf, sizeof (buf), fmt, ap); return (bool) this->message_func (this, font, buf, this->message_data); diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh index b2b190ace..9aae38dbb 100644 --- a/src/hb-buffer.hh +++ b/src/hb-buffer.hh @@ -347,7 +347,13 @@ struct hb_buffer_t HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)); - bool messaging () { return unlikely (message_func); } + bool messaging () + { +#ifdef HB_NO_BUFFER_MESSAGE + return false; +#endif + return unlikely (message_func); + } bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4) { if (!messaging ()) From d5e5f378329b6ce21944b79b568369ea7bc36cf3 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 5 Jun 2019 22:20:03 +0300 Subject: [PATCH 02/32] This makes minor changes to allow building HarfBuzz with mingw.org's MinGW. src/hb-algs.hh: Don't compile _BitScanForward and _BitScanReverse for GCC >= 4. mingw.org's MinGW doesn't have these functions. src/hb-atomic.hh: MemoryBarrier does exist in mingw.org's MinGW, but it is not a macro, it is an inline function. __MINGW32_VERSION is a macro that exists only in mingw.org's MinGW, so conditioning on it should not affect MinGW64, where MemoryBarrier is a macro. src/hb-uniscribe.cc: Define E_NOT_SUFFICIENT_BUFFER if it is not defined (mingw.org's MinGW doesn't). src/hb.hh: Don't include intrin.h for mingw.org's MinGW, since that header is not available; instead, include windows.h. Conditioned on __MINGW32_VERSION to avoid affecting MinGW64. --- src/hb-algs.hh | 4 ++-- src/hb-atomic.hh | 2 +- src/hb-uniscribe.cc | 4 ++++ src/hb.hh | 7 +++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 0b34f7106..fe716d0c0 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -400,7 +400,7 @@ hb_bit_storage (T v) return sizeof (unsigned long long) * 8 - __builtin_clzll (v); #endif -#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) +#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4)) if (sizeof (T) <= sizeof (unsigned int)) { unsigned long where; @@ -474,7 +474,7 @@ hb_ctz (T v) return __builtin_ctzll (v); #endif -#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) +#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4)) if (sizeof (T) <= sizeof (unsigned int)) { unsigned long where; diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 45413d5e7..09d88937c 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -107,7 +107,7 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) static inline void _hb_memory_barrier () { -#ifndef MemoryBarrier +#if !defined(MemoryBarrier) && !defined(__MINGW32_VERSION) /* MinGW has a convoluted history of supporting MemoryBarrier. */ LONG dummy = 0; InterlockedExchange (&dummy, 1); diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index f97ed91fc..69a1ae7e4 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -31,6 +31,10 @@ #include #include +#ifndef E_NOT_SUFFICIENT_BUFFER +#define E_NOT_SUFFICIENT_BUFFER HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER) +#endif + #include "hb-uniscribe.h" #include "hb-open-file.hh" diff --git a/src/hb.hh b/src/hb.hh index e6d22fe3b..afd9799ee 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -183,8 +183,15 @@ #include #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) +#ifdef __MINGW32_VERSION +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#else #include #endif +#endif #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b) From db938479d7b1e3ec35a39a9ad31c945e09e6d5e5 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Tue, 4 Jun 2019 10:30:53 -0700 Subject: [PATCH 03/32] [subset] maxp table to use _subset2 --- src/hb-ot-maxp-table.hh | 52 +++++++++++++++++++---------------------- src/hb-subset.cc | 2 +- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh index a2d9167c5..2ba2cf44d 100644 --- a/src/hb-ot-maxp-table.hh +++ b/src/hb-ot-maxp-table.hh @@ -94,39 +94,35 @@ struct maxp return_trace (likely (version.major == 0 && version.minor == 0x5000u)); } - bool subset (hb_subset_plan_t *plan) const + bool subset (hb_subset_context_t *c) const { - hb_blob_t *maxp_blob = hb_sanitize_context_t().reference_table (plan->source); - hb_blob_t *maxp_prime_blob = hb_blob_copy_writable_or_fail (maxp_blob); - hb_blob_destroy (maxp_blob); + TRACE_SUBSET (this); + maxp *maxp_prime = c->serializer->embed (this); + if (unlikely (!maxp_prime)) return_trace (false); - if (unlikely (!maxp_prime_blob)) { - return false; - } - maxp *maxp_prime = (maxp *) hb_blob_get_data (maxp_prime_blob, nullptr); - - maxp_prime->set_num_glyphs (plan->num_output_glyphs ()); - if (plan->drop_hints) - drop_hint_fields (plan, maxp_prime); - - bool result = plan->add_table (HB_OT_TAG_maxp, maxp_prime_blob); - hb_blob_destroy (maxp_prime_blob); - return result; - } - - static void drop_hint_fields (hb_subset_plan_t *plan HB_UNUSED, maxp *maxp_prime) - { + maxp_prime->numGlyphs = c->plan->num_output_glyphs (); if (maxp_prime->version.major == 1) { - maxpV1Tail &v1 = StructAfter (*maxp_prime); - v1.maxZones = 1; - v1.maxTwilightPoints = 0; - v1.maxStorage = 0; - v1.maxFunctionDefs = 0; - v1.maxInstructionDefs = 0; - v1.maxStackElements = 0; - v1.maxSizeOfInstructions = 0; + const maxpV1Tail *src_v1 = &StructAfter (*this); + maxpV1Tail *dest_v1 = c->serializer->embed (src_v1); + if (unlikely (!dest_v1)) return_trace (false); + + if (c->plan->drop_hints) + drop_hint_fields (dest_v1); } + + return_trace (true); + } + + static void drop_hint_fields (maxpV1Tail* dest_v1) + { + dest_v1->maxZones = 1; + dest_v1->maxTwilightPoints = 0; + dest_v1->maxStorage = 0; + dest_v1->maxFunctionDefs = 0; + dest_v1->maxInstructionDefs = 0; + dest_v1->maxStackElements = 0; + dest_v1->maxSizeOfInstructions = 0; } protected: diff --git a/src/hb-subset.cc b/src/hb-subset.cc index ddd88f7e3..233f3dc41 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -181,7 +181,7 @@ _subset_table (hb_subset_plan_t *plan, result = _subset2 (plan); break; case HB_OT_TAG_maxp: - result = _subset (plan); + result = _subset2 (plan); break; case HB_OT_TAG_loca: DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf"); From 93d592e0e181f436ea47038fef419134007208aa Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Wed, 5 Jun 2019 16:51:31 -0700 Subject: [PATCH 04/32] [subset] post table to use _subset2 --- src/hb-ot-post-table.hh | 31 +++++++++++++++---------------- src/hb-subset.cc | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 970bbe68a..9177a5393 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -73,26 +73,25 @@ struct post { static constexpr hb_tag_t tableTag = HB_OT_TAG_post; - bool subset (hb_subset_plan_t *plan) const + void serialize (hb_serialize_context_t *c) const { - unsigned int post_prime_length; - hb_blob_t *post_blob = hb_sanitize_context_t ().reference_table(plan->source); - hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::min_size); - post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length); - hb_blob_destroy (post_blob); - - if (unlikely (!post_prime || post_prime_length != post::min_size)) - { - hb_blob_destroy (post_prime_blob); - DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length); - return false; - } + post *post_prime = c->allocate_min (); + 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 result = plan->add_table (HB_OT_TAG_post, post_prime_blob); - hb_blob_destroy (post_prime_blob); + } - return result; + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + post *post_prime = c->serializer->start_embed (); + 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 diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 233f3dc41..a6140718e 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -193,7 +193,7 @@ _subset_table (hb_subset_plan_t *plan, result = _subset (plan); break; case HB_OT_TAG_post: - result = _subset (plan); + result = _subset2 (plan); break; #ifndef HB_NO_SUBSET_CFF From f9b1ae73360054d9f121a2d36820377909888b35 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 5 Jun 2019 17:40:59 -0700 Subject: [PATCH 05/32] [subset] Move OS/2 to subset2. --- src/hb-ot-os2-table.hh | 32 ++++++++++++++++---------------- src/hb-subset.cc | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh index 3b6a3727a..33fbb643c 100644 --- a/src/hb-ot-os2-table.hh +++ b/src/hb-ot-os2-table.hh @@ -145,29 +145,20 @@ struct OS2 } } - bool subset (hb_subset_plan_t *plan) const + bool subset (hb_subset_context_t *c) const { - hb_blob_t *os2_blob = hb_sanitize_context_t ().reference_table (plan->source); - hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1); - // TODO(grieger): move to hb_blob_copy_writable_or_fail - hb_blob_destroy (os2_blob); - - OS2 *os2_prime = (OS2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr); - if (unlikely (!os2_prime)) { - hb_blob_destroy (os2_prime_blob); - return false; - } + TRACE_SUBSET (this); + OS2 *os2_prime = c->serializer->embed (this); + if (unlikely (!os2_prime)) return_trace (false); uint16_t min_cp, max_cp; - find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp); + find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp); os2_prime->usFirstCharIndex = min_cp; os2_prime->usLastCharIndex = max_cp; - _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange); - bool result = plan->add_table (HB_OT_TAG_OS2, os2_prime_blob); + _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange); - hb_blob_destroy (os2_prime_blob); - return result; + return_trace (true); } void _update_unicode_ranges (const hb_set_t *codepoints, @@ -218,6 +209,15 @@ struct OS2 font_page_t get_font_page () const { return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); } + unsigned get_size () const + { + unsigned result = min_size; + if (version >= 1) result += v1X.get_size (); + if (version >= 2) result += v2X.get_size (); + if (version >= 5) result += v5X.get_size (); + return result; + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-subset.cc b/src/hb-subset.cc index a6140718e..3f4c2e40b 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -190,7 +190,7 @@ _subset_table (hb_subset_plan_t *plan, result = _subset (plan); break; case HB_OT_TAG_OS2: - result = _subset (plan); + result = _subset2 (plan); break; case HB_OT_TAG_post: result = _subset2 (plan); From 1bada656a86e9cb27d4a6b9fcc50748f0bd9c1d9 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 7 Jun 2019 02:01:27 +0430 Subject: [PATCH 06/32] Minor, remove unnecessary semicolon Causing -Wextra-semi-stmt build error when no primitive has chosen Interesting that nobody has noticed it yet. --- src/hb-mutex.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-mutex.hh b/src/hb-mutex.hh index cbbfa2681..e13626731 100644 --- a/src/hb-mutex.hh +++ b/src/hb-mutex.hh @@ -106,7 +106,7 @@ typedef volatile int hb_mutex_impl_t; #define HB_MUTEX_IMPL_INIT 0 #define hb_mutex_impl_init(M) *(M) = 0 #define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END -#define hb_mutex_impl_unlock(M) (*(M))--; +#define hb_mutex_impl_unlock(M) (*(M))-- #define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END From 385e436692e94588fc4cb3a7afbeb862035db09b Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 7 Jun 2019 10:44:53 -0700 Subject: [PATCH 07/32] Minor, fix gcc maybe-uninitialized complain I guess all of its field will be initialized anyway here but lets make it more defensive --- src/hb-ot-glyf-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 1ac9f6ba2..76efdc9b8 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -180,7 +180,7 @@ struct glyf + hb_range (plan->num_output_glyphs ()) | hb_map ([&] (hb_codepoint_t new_gid) { - SubsetGlyph subset_glyph; + SubsetGlyph subset_glyph = {0}; subset_glyph.new_gid = new_gid; // should never fail: all old gids should be mapped From 3c240bd3dc0aaca38154da555d0aef350da62ee6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 7 Jun 2019 10:56:24 -0700 Subject: [PATCH 08/32] Downgrade double-promotion from error to warning https://github.com/harfbuzz/harfbuzz/issues/1740 --- src/hb.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb.hh b/src/hb.hh index afd9799ee..33ad32311 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -66,7 +66,6 @@ #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" -#pragma GCC diagnostic error "-Wdouble-promotion" #pragma GCC diagnostic error "-Wextra-semi-stmt" #pragma GCC diagnostic error "-Wformat-security" #pragma GCC diagnostic error "-Wimplicit-function-declaration" @@ -99,6 +98,7 @@ #pragma GCC diagnostic warning "-Wbuiltin-macro-redefined" #pragma GCC diagnostic warning "-Wdeprecated" #pragma GCC diagnostic warning "-Wdisabled-optimization" +#pragma GCC diagnostic warning "-Wdouble-promotion" #pragma GCC diagnostic warning "-Wformat=2" #pragma GCC diagnostic warning "-Wignored-pragma-optimize" #pragma GCC diagnostic warning "-Wlogical-op" From e4e518f33d933a02058bad86a6aae714e59814db Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 7 Jun 2019 12:41:09 -0700 Subject: [PATCH 09/32] Fix build on gcc 4.8 Fixes https://github.com/harfbuzz/harfbuzz/issues/1724 --- src/hb-algs.hh | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index fe716d0c0..8229c5f39 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -167,14 +167,39 @@ template auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN (( hb_partial_t (a, v) )) -/* The following hacky replacement version is to make Visual Stuiod build:. */ \ -/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \ +/* The following, HB_PARTIALIZE, macro uses a particular corner-case + * of C++11 that is not particularly well-supported by all compilers. + * What's happening is that it's using "this" in a trailing return-type + * via decltype(). Broken compilers deduce the type of "this" pointer + * in that context differently from what it resolves to in the body + * of the function. + * + * One probable cause of this is that at the time of trailing return + * type declaration, "this" points to an incomplete type, whereas in + * the function body the type is complete. That doesn't justify the + * error in any way, but is probably what's happening. + * + * In the case of MSVC, we get around this by using C++14 "decltype(auto)" + * which deduces the type from the actual return statement. For gcc 4.8 + * we use "this+0" instead of "this" which produces an rvalue that seems + * to do be deduces as the same type with this particular compiler. Note + * that "this+0" is illegal in the trailing decltype position since at + * that point this points to incomplete type! But seems to do the trick. + */ #ifdef _MSC_VER +/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \ #define HB_PARTIALIZE(Pos) \ template \ decltype(auto) operator () (_T&& _v) const \ { return hb_partial (this, hb_forward<_T> (_v)); } \ static_assert (true, "") +#elif defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ <= 8) +/* https://github.com/harfbuzz/harfbuzz/issues/1724 */ +#define HB_PARTIALIZE(Pos) \ + template \ + auto operator () (_T&& _v) const HB_AUTO_RETURN \ + (hb_partial (this+0, hb_forward<_T> (_v))) \ + static_assert (true, "") #else #define HB_PARTIALIZE(Pos) \ template \ From 973699c49b905e142ecc5cefd1f4fa15aad8e309 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 7 Jun 2019 12:49:06 -0700 Subject: [PATCH 10/32] Disable clang gcc impersonator --- src/hb-algs.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 8229c5f39..39bb2f1ac 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -193,7 +193,7 @@ auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN decltype(auto) operator () (_T&& _v) const \ { return hb_partial (this, hb_forward<_T> (_v)); } \ static_assert (true, "") -#elif defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ <= 8) +#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ <= 8) /* https://github.com/harfbuzz/harfbuzz/issues/1724 */ #define HB_PARTIALIZE(Pos) \ template \ From 6d58b45782833f8c6c8efd9426e2785c78e6462a Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 8 Jun 2019 00:40:18 +0430 Subject: [PATCH 11/32] [ci] use trusty for its gcc 4.8 again --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d788263ef..703fac25c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ # Build Configuration for Travis -dist: xenial +dist: trusty language: cpp From 5074d665a8b0980f202a5986bda52808674cfb54 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 7 Jun 2019 14:20:45 -0700 Subject: [PATCH 12/32] [ucd] Save another 1.5kb https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/gen-ucd-table.py | 8 +++++--- src/hb-ucd-table.hh | 37 +++++++++++++++++++++---------------- src/hb-ucd.cc | 12 +++++++++--- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/gen-ucd-table.py b/src/gen-ucd-table.py index 3f821802d..967e000d4 100755 --- a/src/gen-ucd-table.py +++ b/src/gen-ucd-table.py @@ -31,14 +31,15 @@ ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'} assert not any(v for v in dm.values() if len(v) not in (1,2)) dm1 = sorted(set(v for v in dm.values() if len(v) == 1)) -dm1_array = ['0x%04Xu' % v for v in dm1] +dm1_u16_array = ['0x%04Xu' % v for v in dm1 if v[0] <= 0xFFFF] +dm1_u32_array = ['0x%04Xu' % v for v in dm1 if v[0] > 0xFFFF] dm1_order = {v:i+1 for i,v in enumerate(dm1)} dm2 = sorted((v, i) for i,v in dm.items() if len(v) == 2) dm2 = [("HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % (v+(i if i not in ce and not ccc[i] else 0,)), v) for v,i in dm2] dm2_array = [s for s,v in dm2] -l = 1 + len(dm1_array) +l = 1 + len(dm1_u16_array) + len(dm1_u32_array) dm2_order = {v[1]:i+l for i,v in enumerate(dm2)} dm_order = {None: 0} dm_order.update(dm1_order) @@ -89,7 +90,8 @@ print() code = packTab.Code('_hb_ucd') sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array) -dm1_array, _ = code.addArray('hb_codepoint_t', 'dm1_map', dm1_array) +dm1_16_array, _ = code.addArray('uint16_t', 'dm1_u16_map', dm1_u16_array) +dm1_32_array, _ = code.addArray('uint32_t', 'dm1_u32_map', dm1_u32_array) dm2_array, _ = code.addArray('uint64_t', 'dm2_map', dm2_array) code.print_c(linkage='static inline') diff --git a/src/hb-ucd-table.hh b/src/hb-ucd-table.hh index 95c4bf86e..ae339ec0c 100644 --- a/src/hb-ucd-table.hh +++ b/src/hb-ucd-table.hh @@ -86,8 +86,8 @@ _hb_ucd_sc_map[138] = HB_SCRIPT_MARCHEN, HB_SCRIPT_OSAGE, HB_SCRIPT_TANGUT, HB_SCRIPT_NEWA, }; -static const hb_codepoint_t -_hb_ucd_dm1_map[935] = +static const uint16_t +_hb_ucd_dm1_u16_map[825] = { 0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u, 0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu, @@ -192,20 +192,25 @@ _hb_ucd_dm1_map[935] = 0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u, 0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u, 0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu, - 0x9F9Cu,0x20122u,0x2051Cu,0x20525u,0x2054Bu,0x2063Au,0x20804u,0x208DEu, - 0x20A2Cu,0x20B63u,0x214E4u,0x216A8u,0x216EAu,0x219C8u,0x21B18u,0x21D0Bu, - 0x21DE4u,0x21DE6u,0x22183u,0x2219Fu,0x22331u,0x226D4u,0x22844u,0x2284Au, - 0x22B0Cu,0x22BF1u,0x2300Au,0x232B8u,0x2335Fu,0x23393u,0x2339Cu,0x233C3u, - 0x233D5u,0x2346Du,0x236A3u,0x238A7u,0x23A8Du,0x23AFAu,0x23CBCu,0x23D1Eu, - 0x23ED1u,0x23F5Eu,0x23F8Eu,0x24263u,0x242EEu,0x243ABu,0x24608u,0x24735u, - 0x24814u,0x24C36u,0x24C92u,0x24FA1u,0x24FB8u,0x25044u,0x250F2u,0x250F3u, - 0x25119u,0x25133u,0x25249u,0x2541Du,0x25626u,0x2569Au,0x256C5u,0x2597Cu, - 0x25AA7u,0x25BABu,0x25C80u,0x25CD0u,0x25F86u,0x261DAu,0x26228u,0x26247u, - 0x262D9u,0x2633Eu,0x264DAu,0x26523u,0x265A8u,0x267A7u,0x267B5u,0x26B3Cu, - 0x26C36u,0x26CD5u,0x26D6Bu,0x26F2Cu,0x26FB1u,0x270D2u,0x273CAu,0x27667u, - 0x278AEu,0x27966u,0x27CA8u,0x27ED3u,0x27F2Fu,0x285D2u,0x285EDu,0x2872Eu, - 0x28BFAu,0x28D77u,0x29145u,0x291DFu,0x2921Au,0x2940Au,0x29496u,0x295B6u, - 0x29B30u,0x2A0CEu,0x2A105u,0x2A20Eu,0x2A291u,0x2A392u,0x2A600u, + 0x9F9Cu, +}; +static const uint32_t +_hb_ucd_dm1_u32_map[110] = +{ + 0x20122u,0x2051Cu,0x20525u,0x2054Bu,0x2063Au,0x20804u,0x208DEu,0x20A2Cu, + 0x20B63u,0x214E4u,0x216A8u,0x216EAu,0x219C8u,0x21B18u,0x21D0Bu,0x21DE4u, + 0x21DE6u,0x22183u,0x2219Fu,0x22331u,0x226D4u,0x22844u,0x2284Au,0x22B0Cu, + 0x22BF1u,0x2300Au,0x232B8u,0x2335Fu,0x23393u,0x2339Cu,0x233C3u,0x233D5u, + 0x2346Du,0x236A3u,0x238A7u,0x23A8Du,0x23AFAu,0x23CBCu,0x23D1Eu,0x23ED1u, + 0x23F5Eu,0x23F8Eu,0x24263u,0x242EEu,0x243ABu,0x24608u,0x24735u,0x24814u, + 0x24C36u,0x24C92u,0x24FA1u,0x24FB8u,0x25044u,0x250F2u,0x250F3u,0x25119u, + 0x25133u,0x25249u,0x2541Du,0x25626u,0x2569Au,0x256C5u,0x2597Cu,0x25AA7u, + 0x25BABu,0x25C80u,0x25CD0u,0x25F86u,0x261DAu,0x26228u,0x26247u,0x262D9u, + 0x2633Eu,0x264DAu,0x26523u,0x265A8u,0x267A7u,0x267B5u,0x26B3Cu,0x26C36u, + 0x26CD5u,0x26D6Bu,0x26F2Cu,0x26FB1u,0x270D2u,0x273CAu,0x27667u,0x278AEu, + 0x27966u,0x27CA8u,0x27ED3u,0x27F2Fu,0x285D2u,0x285EDu,0x2872Eu,0x28BFAu, + 0x28D77u,0x29145u,0x291DFu,0x2921Au,0x2940Au,0x29496u,0x295B6u,0x29B30u, + 0x2A0CEu,0x2A105u,0x2A20Eu,0x2A291u,0x2A392u,0x2A600u, }; static const uint64_t _hb_ucd_dm2_map[1025] = diff --git a/src/hb-ucd.cc b/src/hb-ucd.cc index 134e043d8..4d35017a6 100644 --- a/src/hb-ucd.cc +++ b/src/hb-ucd.cc @@ -148,13 +148,19 @@ hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, if (likely (!i)) return false; i--; - if (i < ARRAY_LENGTH (_hb_ucd_dm1_map)) + if (i < ARRAY_LENGTH (_hb_ucd_dm1_u16_map) + ARRAY_LENGTH (_hb_ucd_dm1_u32_map)) { - *a = _hb_ucd_dm1_map[i]; + if (i < ARRAY_LENGTH (_hb_ucd_dm1_u16_map)) + *a = _hb_ucd_dm1_u16_map[i]; + else + { + i -= ARRAY_LENGTH (_hb_ucd_dm1_u16_map); + *a = _hb_ucd_dm1_u32_map[i]; + } *b = 0; return true; } - i -= ARRAY_LENGTH (_hb_ucd_dm1_map); + i -= ARRAY_LENGTH (_hb_ucd_dm1_u16_map) + ARRAY_LENGTH (_hb_ucd_dm1_u32_map); uint64_t v = _hb_ucd_dm2_map[i]; *a = HB_CODEPOINT_DECODE3_1 (v); From eff579f743a91c0b1c543f4b69ab33580cae6392 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 7 Jun 2019 12:58:09 +0430 Subject: [PATCH 13/32] Update and use internal qsort everywhere --- src/hb-algs.hh | 210 +++++++++++++++++++++++++++++----------- src/hb-array.hh | 6 +- src/hb-ot-post-table.hh | 2 +- 3 files changed, 158 insertions(+), 60 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 39bb2f1ac..07abffbcf 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -653,115 +653,213 @@ hb_bsearch (const void *key, const void *base, /* From https://github.com/noporpoise/sort_r - * With following modifications: - * - * 10 November 2018: - * https://github.com/noporpoise/sort_r/issues/7 - */ + Feb 5, 2019 (c8c65c1e) + Modified to support optional argument using templates */ /* Isaac Turner 29 April 2014 Public Domain */ /* - -hb_sort_r function to be exported. - +hb_qsort function to be exported. Parameters: base is the array to be sorted nel is the number of elements in the array width is the size in bytes of each element of the array compar is the comparison function - arg is a pointer to be passed to the comparison function + arg (optional) is a pointer to be passed to the comparison function -void hb_sort_r(void *base, size_t nel, size_t width, - int (*compar)(const void *_a, const void *_b, void *_arg), - void *arg); +void hb_sort(void *base, size_t nel, size_t width, + int (*compar)(const void *_a, const void *_b, [void *_arg]), + [void *arg]); */ +#define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp)) -/* swap a, b iff a>b */ -/* __restrict is same as restrict but better support on old machines */ -static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w, - int (*compar)(const void *_a, const void *_b, - void *_arg), - void *arg) +/* swap a and b */ +/* a and b must not be equal! */ +static inline void sort_r_swap(char *__restrict a, char *__restrict b, + size_t w) { char tmp, *end = a+w; - if(compar(a, b, arg) > 0) { - for(; a < end; a++, b++) { tmp = *a; *a = *b; *b = tmp; } + for(; a < end; a++, b++) { SORT_R_SWAP(*a, *b, tmp); } +} + +/* swap a, b iff a>b */ +/* a and b must not be equal! */ +/* __restrict is same as restrict but better support on old machines */ +template +static inline int sort_r_cmpswap(char *__restrict a, + char *__restrict b, size_t w, + int (*compar)(const void *_a, + const void *_b, + Ts... _ds), + Ts... ds) +{ + if(compar(a, b, ds...) > 0) { + sort_r_swap(a, b, w); return 1; } return 0; } +/* +Swap consecutive blocks of bytes of size na and nb starting at memory addr ptr, +with the smallest swap so that the blocks are in the opposite order. Blocks may +be internally re-ordered e.g. + 12345ab -> ab34512 + 123abc -> abc123 + 12abcde -> deabc12 +*/ +static inline void sort_r_swap_blocks(char *ptr, size_t na, size_t nb) +{ + if(na > 0 && nb > 0) { + if(na > nb) { sort_r_swap(ptr, ptr+na, nb); } + else { sort_r_swap(ptr, ptr+nb, na); } + } +} + +/* Implement recursive quicksort ourselves */ /* Note: quicksort is not stable, equivalent values may be swapped */ +template static inline void sort_r_simple(void *base, size_t nel, size_t w, - int (*compar)(const void *_a, const void *_b, - void *_arg), - void *arg) + int (*compar)(const void *_a, + const void *_b, + Ts... _ds), + Ts... ds) { char *b = (char *)base, *end = b + nel*w; - if(nel < 7) { + + /* for(size_t i=0; i b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {} + for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,ds...); pj -= w) {} } } else { - /* nel > 6; Quicksort */ + /* nel > 9; Quicksort */ - /* Use median of first, middle and last items as pivot */ - char *x, *y, *xend, ch; - char *pl, *pm, *pr; + int cmp; + char *pl, *ple, *pr, *pre, *pivot; char *last = b+w*(nel-1), *tmp; + + /* + Use median of second, middle and second-last items as pivot. + First and last may have been swapped with pivot and therefore be extreme + */ char *l[3]; - l[0] = b; + l[0] = b + w; l[1] = b+w*(nel/2); - l[2] = last; + l[2] = last - w; - if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; } - if(compar(l[1],l[2],arg) > 0) { - tmp=l[1]; l[1]=l[2]; l[2]=tmp; /* swap(l[1],l[2]) */ - if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; } + /* printf("pivots: %i, %i, %i\n", *(int*)l[0], *(int*)l[1], *(int*)l[2]); */ + + if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); } + if(compar(l[1],l[2],ds...) > 0) { + SORT_R_SWAP(l[1], l[2], tmp); + if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); } } - /* swap l[id], l[2] to put pivot as last element */ - for(x = l[1], y = last, xend = x+w; x>1); - for(; pl < pm; pl += w) { - if(sort_r_cmpswap(pl, pr, w, compar, arg)) { - pr -= w; /* pivot now at pl */ - break; + /* Move left hand items which are equal to the pivot to the far left. + break when we find an item that is greater than the pivot */ + for(; pl < pr; pl += w) { + cmp = compar(pl, pivot, ds...); + if(cmp > 0) { break; } + else if(cmp == 0) { + if(ple < pl) { sort_r_swap(ple, pl, w); } + ple += w; } } - pm = pl+((pr-pl)>>1); - for(; pm < pr; pr -= w) { - if(sort_r_cmpswap(pl, pr, w, compar, arg)) { - pl += w; /* pivot now at pr */ + /* break if last batch of left hand items were equal to pivot */ + if(pl >= pr) { break; } + /* Move right hand items which are equal to the pivot to the far right. + break when we find an item that is less than the pivot */ + for(; pl < pr; ) { + pr -= w; /* Move right pointer onto an unprocessed item */ + cmp = compar(pr, pivot, ds...); + if(cmp == 0) { + pre -= w; + if(pr < pre) { sort_r_swap(pr, pre, w); } + } + else if(cmp < 0) { + if(pl < pr) { sort_r_swap(pl, pr, w); } + pl += w; break; } } } - sort_r_simple(b, (pl-b)/w, w, compar, arg); - sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg); + pl = pr; /* pr may have gone below pl */ + + /* + Now we need to go from: EEELLLGGGGEEEE + to: LLLEEEEEEEGGGG + Pivot comparison key: + E = equal, L = less than, u = unknown, G = greater than, E = equal + */ + sort_r_swap_blocks(b, ple-b, pl-ple); + sort_r_swap_blocks(pr, pre-pr, end-pre); + + /*for(size_t i=0; i, Type&> hb_sorted_array_t qsort (int (*cmp_)(const void*, const void*)) { if (likely (length)) - ::qsort (arrayZ, length, this->item_size, cmp_); + hb_qsort (arrayZ, length, this->item_size, cmp_); return hb_sorted_array_t (*this); } hb_sorted_array_t qsort () { if (likely (length)) - ::qsort (arrayZ, length, this->item_size, Type::cmp); + hb_qsort (arrayZ, length, this->item_size, Type::cmp); return hb_sorted_array_t (*this); } void qsort (unsigned int start, unsigned int end) @@ -155,7 +155,7 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> end = hb_min (end, length); assert (start <= end); if (likely (start < end)) - ::qsort (arrayZ + start, end - start, this->item_size, Type::cmp); + hb_qsort (arrayZ + start, end - start, this->item_size, Type::cmp); } /* diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 9177a5393..720e03bac 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -157,7 +157,7 @@ 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 (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids))) { From 9b853f755dd05ccef3429d3d3d0d561a99cc4c2d Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 9 Jun 2019 11:49:25 +0430 Subject: [PATCH 14/32] [cff] Use switch on multi-format structs (#1762) --- src/hb-cff-interp-cs-common.hh | 4 +- src/hb-cff-interp-dict-common.hh | 12 +- src/hb-ot-cff-common.hh | 137 ++++++++++---------- src/hb-ot-cff1-table.hh | 215 +++++++++++++++++-------------- src/hb-ot-cff2-table.hh | 70 +++++----- src/hb-subset-cff1.cc | 2 +- src/hb-subset-cff2.cc | 2 +- 7 files changed, 235 insertions(+), 207 deletions(-) diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh index 61bdba5f5..1cfbba603 100644 --- a/src/hb-cff-interp-cs-common.hh +++ b/src/hb-cff-interp-cs-common.hh @@ -76,8 +76,8 @@ struct biased_subrs_t void fini () {} - unsigned int get_count () const { return (subrs == nullptr)? 0: subrs->count; } - unsigned int get_bias () const { return bias; } + unsigned int get_count () const { return (subrs == nullptr) ? 0 : subrs->count; } + unsigned int get_bias () const { return bias; } byte_str_t operator [] (unsigned int index) const { diff --git a/src/hb-cff-interp-dict-common.hh b/src/hb-cff-interp-dict-common.hh index 2c54909a1..ea0db13f8 100644 --- a/src/hb-cff-interp-dict-common.hh +++ b/src/hb-cff-interp-dict-common.hh @@ -134,10 +134,10 @@ struct dict_opset_t : opset_t return value; case END: - value = (double)(neg? -int_part: int_part); + value = (double) (neg ? -int_part : int_part); if (frac_count > 0) { - double frac = (frac_part / pow (10.0, (double)frac_count)); + double frac = (frac_part / pow (10.0, (double) frac_count)); if (neg) frac = -frac; value += frac; } @@ -146,16 +146,16 @@ struct dict_opset_t : opset_t if (value == 0.0) return value; if (exp_neg) - return neg? -DBL_MIN: DBL_MIN; + return neg ? -DBL_MIN : DBL_MIN; else - return neg? -DBL_MAX: DBL_MAX; + return neg ? -DBL_MAX : DBL_MAX; } if (exp_part != 0) { if (exp_neg) - value /= pow (10.0, (double)exp_part); + value /= pow (10.0, (double) exp_part); else - value *= pow (10.0, (double)exp_part); + value *= pow (10.0, (double) exp_part); } return value; diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh index 55ae10efe..919cb8150 100644 --- a/src/hb-ot-cff-common.hh +++ b/src/hb-ot-cff-common.hh @@ -82,22 +82,14 @@ struct str_buff_vec_t : hb_vector_t template struct CFFIndex { - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */ - (c->check_struct (this) && offSize >= 1 && offSize <= 4 && - c->check_array (offsets, offSize, count + 1) && - c->check_array ((const HBUINT8*)data_base (), 1, max_offset () - 1)))); - } - static unsigned int calculate_offset_array_size (unsigned int offSize, unsigned int count) { return offSize * (count + 1); } unsigned int offset_array_size () const { return calculate_offset_array_size (offSize, count); } - static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count, unsigned int dataSize) + static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count, + unsigned int dataSize) { if (count == 0) return COUNT::static_size; @@ -199,11 +191,11 @@ struct CFFIndex unsigned int length_at (unsigned int index) const { - if (likely ((offset_at (index + 1) >= offset_at (index)) && - (offset_at (index + 1) <= offset_at (count)))) - return offset_at (index + 1) - offset_at (index); - else - return 0; + if (likely ((offset_at (index + 1) >= offset_at (index)) && + (offset_at (index + 1) <= offset_at (count)))) + return offset_at (index + 1) - offset_at (index); + else + return 0; } const unsigned char *data_base () const @@ -216,12 +208,12 @@ struct CFFIndex if (likely (index < count)) return byte_str_t (data_base () + offset_at (index) - 1, length_at (index)); else - return Null(byte_str_t); + return Null (byte_str_t); } unsigned int get_size () const { - if (this != &Null(CFFIndex)) + if (this != &Null (CFFIndex)) { if (count > 0) return min_size + offset_array_size () + (offset_at (count) - 1); @@ -232,6 +224,15 @@ struct CFFIndex return 0; } + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */ + (c->check_struct (this) && offSize >= 1 && offSize <= 4 && + c->check_array (offsets, offSize, count + 1) && + c->check_array ((const HBUINT8*) data_base (), 1, max_offset () - 1)))); + } + protected: unsigned int max_offset () const { @@ -245,10 +246,10 @@ struct CFFIndex } public: - COUNT count; /* Number of object data. Note there are (count+1) offsets */ - HBUINT8 offSize; /* The byte size of each offset in the offsets array. */ - HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */ - /* HBUINT8 data[VAR]; Object data */ + COUNT count; /* Number of object data. Note there are (count+1) offsets */ + HBUINT8 offSize; /* The byte size of each offset in the offsets array. */ + HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */ + /* HBUINT8 data[VAR]; Object data */ public: DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets); }; @@ -293,7 +294,7 @@ struct CFFIndexOf : CFFIndex /* serialize data */ for (unsigned int i = 0; i < dataArrayLen; i++) { - TYPE *dest = c->start_embed (); + TYPE *dest = c->start_embed (); if (unlikely (dest == nullptr || !dest->serialize (c, dataArray[i], param1, param2))) return_trace (false); @@ -310,7 +311,7 @@ struct CFFIndexOf : CFFIndex const PARAM ¶m) { /* determine offset size */ - unsigned int totalDataSize = 0; + unsigned int totalDataSize = 0; for (unsigned int i = 0; i < dataArrayLen; i++) { unsigned int dataSize = TYPE::calculate_serialized_size (dataArray[i], param); @@ -334,10 +335,9 @@ struct Dict : UnsizedByteStr { TRACE_SERIALIZE (this); for (unsigned int i = 0; i < dictval.get_count (); i++) - { if (unlikely (!opszr.serialize (c, dictval[i], param))) return_trace (false); - } + return_trace (true); } @@ -391,14 +391,10 @@ struct Dict : UnsizedByteStr { return serialize_int_op (c, op, value, OpCode_shortint); } static bool serialize_offset4_op (hb_serialize_context_t *c, op_code_t op, int value) - { - return serialize_uint4_op (c, op, value); - } + { return serialize_uint4_op (c, op, value); } static bool serialize_offset2_op (hb_serialize_context_t *c, op_code_t op, int value) - { - return serialize_uint2_op (c, op, value); - } + { return serialize_uint2_op (c, op, value); } }; struct TopDict : Dict {}; @@ -483,7 +479,7 @@ struct FDArray : CFFIndexOf return_trace (false); /* serialize font dict offsets */ - unsigned int offset = 1; + unsigned int offset = 1; unsigned int fid = 0; for (; fid < fontDicts.length; fid++) { @@ -575,9 +571,7 @@ struct FDSelect0 { } hb_codepoint_t get_fd (hb_codepoint_t glyph) const - { - return (hb_codepoint_t)fds[glyph]; - } + { return (hb_codepoint_t) fds[glyph]; } unsigned int get_size (unsigned int num_glyphs) const { return HBUINT8::static_size * num_glyphs; } @@ -588,7 +582,8 @@ struct FDSelect0 { }; template -struct FDSelect3_4_Range { +struct FDSelect3_4_Range +{ bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const { TRACE_SANITIZE (this); @@ -597,12 +592,13 @@ struct FDSelect3_4_Range { GID_TYPE first; FD_TYPE fd; - + public: DEFINE_SIZE_STATIC (GID_TYPE::static_size + FD_TYPE::static_size); }; template -struct FDSelect3_4 { +struct FDSelect3_4 +{ unsigned int get_size () const { return GID_TYPE::static_size * 2 + ranges.get_size (); } @@ -614,10 +610,8 @@ struct FDSelect3_4 { return_trace (false); for (unsigned int i = 1; i < nRanges (); i++) - { if (unlikely (ranges[i - 1].first >= ranges[i].first)) - return_trace (false); - } + return_trace (false); if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ()))) return_trace (false); @@ -649,17 +643,8 @@ struct FDSelect3_4 { typedef FDSelect3_4 FDSelect3; typedef FDSelect3_4_Range FDSelect3_Range; -struct FDSelect { - bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const - { - TRACE_SANITIZE (this); - - return_trace (likely (c->check_struct (this) && (format == 0 || format == 3) && - ((format == 0)? - u.format0.sanitize (c, fdcount): - u.format3.sanitize (c, fdcount)))); - } - +struct FDSelect +{ bool serialize (hb_serialize_context_t *c, const FDSelect &src, unsigned int num_glyphs) { TRACE_SERIALIZE (this); @@ -675,30 +660,46 @@ struct FDSelect { unsigned int get_size (unsigned int num_glyphs) const { - unsigned int size = format.static_size; - if (format == 0) - size += u.format0.get_size (num_glyphs); - else - size += u.format3.get_size (); - return size; + switch (format) + { + case 0: return format.static_size + u.format0.get_size (num_glyphs); + case 3: return format.static_size + u.format3.get_size (); + default:return 0; + } } hb_codepoint_t get_fd (hb_codepoint_t glyph) const { - if (this == &Null(FDSelect)) + if (this == &Null (FDSelect)) return 0; - if (format == 0) - return u.format0.get_fd (glyph); - else - return u.format3.get_fd (glyph); + switch (format) + { + case 0: return u.format0.get_fd (glyph); + case 3: return u.format3.get_fd (glyph); + default:return 0; + } } - HBUINT8 format; - union { - FDSelect0 format0; - FDSelect3 format3; - } u; + bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return_trace (false); + switch (format) + { + case 0: return_trace (u.format0.sanitize (c, fdcount)); + case 3: return_trace (u.format3.sanitize (c, fdcount)); + default:return_trace (false); + } + } + + HBUINT8 format; + union { + FDSelect0 format0; + FDSelect3 format3; + } u; + public: DEFINE_SIZE_MIN (1); }; diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index 3a887d3d0..31d9d879d 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -161,21 +161,8 @@ struct CFF1SuppEncData { DEFINE_SIZE_ARRAY_SIZED (1, supps); }; -struct Encoding { - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - - if (unlikely (!c->check_struct (this))) - return_trace (false); - unsigned int fmt = format & 0x7F; - if (unlikely (fmt > 1)) - return_trace (false); - if (unlikely (!((fmt == 0)? u.format0.sanitize (c): u.format1.sanitize (c)))) - return_trace (false); - return_trace (((format & 0x80) == 0) || suppEncData ().sanitize (c)); - } - +struct Encoding +{ /* serialize a fullset Encoding */ bool serialize (hb_serialize_context_t *c, const Encoding &src) { @@ -197,11 +184,12 @@ struct Encoding { TRACE_SERIALIZE (this); Encoding *dest = c->extend_min (*this); if (unlikely (dest == nullptr)) return_trace (false); - dest->format = format | ((supp_codes.length > 0)? 0x80: 0); - if (format == 0) + dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0); + switch (format) { + case 0: { Encoding0 *fmt0 = c->allocate_size (Encoding0::min_size + HBUINT8::static_size * enc_count); - if (unlikely (fmt0 == nullptr)) return_trace (false); + if (unlikely (fmt0 == nullptr)) return_trace (false); fmt0->nCodes () = enc_count; unsigned int glyph = 0; for (unsigned int i = 0; i < code_ranges.length; i++) @@ -213,7 +201,9 @@ struct Encoding { return_trace (false); } } - else + break; + + case 1: { Encoding1 *fmt1 = c->allocate_size (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length); if (unlikely (fmt1 == nullptr)) return_trace (false); @@ -226,7 +216,11 @@ struct Encoding { fmt1->ranges[i].nLeft = code_ranges[i].glyph; } } - if (supp_codes.length > 0) + break; + + } + + if (supp_codes.length) { CFF1SuppEncData *suppData = c->allocate_size (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length); if (unlikely (suppData == nullptr)) return_trace (false); @@ -237,6 +231,7 @@ struct Encoding { suppData->supps[i].glyph = supp_codes[i].glyph; /* actually SID */ } } + return_trace (true); } @@ -245,11 +240,13 @@ struct Encoding { unsigned int enc_count, unsigned int supp_count) { - unsigned int size = min_size; - if (format == 0) - size += Encoding0::min_size + HBUINT8::static_size * enc_count; - else - size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; + unsigned int size = min_size; + switch (format) + { + case 0: size += Encoding0::min_size + HBUINT8::static_size * enc_count; break; + case 1: size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; break; + default:return 0; + } if (supp_count > 0) size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count; return size; @@ -258,10 +255,11 @@ struct Encoding { unsigned int get_size () const { unsigned int size = min_size; - if (table_format () == 0) - size += u.format0.get_size (); - else - size += u.format1.get_size (); + switch (table_format ()) + { + case 0: size += u.format0.get_size (); break; + case 1: size += u.format1.get_size (); break; + } if (has_supplement ()) size += suppEncData ().get_size (); return size; @@ -269,14 +267,16 @@ struct Encoding { hb_codepoint_t get_code (hb_codepoint_t glyph) const { - if (table_format () == 0) - return u.format0.get_code (glyph); - else - return u.format1.get_code (glyph); + switch (table_format ()) + { + case 0: return u.format0.get_code (glyph); + case 1: return u.format1.get_code (glyph); + default:return 0; + } } - uint8_t table_format () const { return (format & 0x7F); } - bool has_supplement () const { return (format & 0x80) != 0; } + uint8_t table_format () const { return format & 0x7F; } + bool has_supplement () const { return format & 0x80; } void get_supplement_codes (hb_codepoint_t sid, hb_vector_t &codes) const { @@ -285,21 +285,37 @@ struct Encoding { suppEncData().get_codes (sid, codes); } + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return_trace (false); + + switch (table_format ()) + { + case 0: if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break; + case 1: if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break; + default:return_trace (false); + } + return_trace (likely (!has_supplement () || suppEncData ().sanitize (c))); + } + protected: const CFF1SuppEncData &suppEncData () const { - if ((format & 0x7F) == 0) - return StructAfter (u.format0.codes[u.format0.nCodes ()-1]); - else - return StructAfter (u.format1.ranges[u.format1.nRanges ()-1]); + switch (table_format ()) + { + case 0: return StructAfter (u.format0.codes[u.format0.nCodes ()-1]); + case 1: return StructAfter (u.format1.ranges[u.format1.nRanges ()-1]); + default:return Null (CFF1SuppEncData); + } } public: - HBUINT8 format; - + HBUINT8 format; union { - Encoding0 format0; - Encoding1 format1; + Encoding0 format0; + Encoding1 format1; } u; /* CFF1SuppEncData suppEncData; */ @@ -433,23 +449,8 @@ typedef Charset1_2 Charset2; typedef Charset_Range Charset1_Range; typedef Charset_Range Charset2_Range; -struct Charset { - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - - if (unlikely (!c->check_struct (this))) - return_trace (false); - if (format == 0) - return_trace (u.format0.sanitize (c, c->get_num_glyphs ())); - else if (format == 1) - return_trace (u.format1.sanitize (c, c->get_num_glyphs ())); - else if (likely (format == 2)) - return_trace (u.format2.sanitize (c, c->get_num_glyphs ())); - else - return_trace (false); - } - +struct Charset +{ /* serialize a fullset Charset */ bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs) { @@ -471,10 +472,12 @@ struct Charset { Charset *dest = c->extend_min (*this); if (unlikely (dest == nullptr)) return_trace (false); dest->format = format; - if (format == 0) + switch (format) + { + case 0: { Charset0 *fmt0 = c->allocate_size (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1)); - if (unlikely (fmt0 == nullptr)) return_trace (false); + if (unlikely (fmt0 == nullptr)) return_trace (false); unsigned int glyph = 0; for (unsigned int i = 0; i < sid_ranges.length; i++) { @@ -483,7 +486,9 @@ struct Charset { fmt0->sids[glyph++] = sid++; } } - else if (format == 1) + break; + + case 1: { Charset1 *fmt1 = c->allocate_size (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length); if (unlikely (fmt1 == nullptr)) return_trace (false); @@ -495,7 +500,9 @@ struct Charset { fmt1->ranges[i].nLeft = sid_ranges[i].glyph; } } - else /* format 2 */ + break; + + case 2: { Charset2 *fmt2 = c->allocate_size (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length); if (unlikely (fmt2 == nullptr)) return_trace (false); @@ -506,56 +513,72 @@ struct Charset { fmt2->ranges[i].first = sid_ranges[i].code; fmt2->ranges[i].nLeft = sid_ranges[i].glyph; } + } + break; + } return_trace (true); } /* parallel to above: calculate the size of a subset Charset */ - static unsigned int calculate_serialized_size ( - uint8_t format, - unsigned int count) + static unsigned int calculate_serialized_size (uint8_t format, + unsigned int count) { - unsigned int size = min_size; - if (format == 0) - size += Charset0::min_size + HBUINT16::static_size * (count - 1); - else if (format == 1) - size += Charset1::min_size + Charset1_Range::static_size * count; - else - size += Charset2::min_size + Charset2_Range::static_size * count; - - return size; + switch (format) + { + case 0: return min_size + Charset0::min_size + HBUINT16::static_size * (count - 1); + case 1: return min_size + Charset1::min_size + Charset1_Range::static_size * count; + case 2: return min_size + Charset2::min_size + Charset2_Range::static_size * count; + default:return 0; + } } unsigned int get_size (unsigned int num_glyphs) const { - unsigned int size = min_size; - if (format == 0) - size += u.format0.get_size (num_glyphs); - else if (format == 1) - size += u.format1.get_size (num_glyphs); - else - size += u.format2.get_size (num_glyphs); - return size; + switch (format) + { + case 0: return min_size + u.format0.get_size (num_glyphs); + case 1: return min_size + u.format1.get_size (num_glyphs); + case 2: return min_size + u.format2.get_size (num_glyphs); + default:return 0; + } } hb_codepoint_t get_sid (hb_codepoint_t glyph) const { - if (format == 0) - return u.format0.get_sid (glyph); - else if (format == 1) - return u.format1.get_sid (glyph); - else - return u.format2.get_sid (glyph); + switch (format) + { + case 0: return u.format0.get_sid (glyph); + case 1: return u.format1.get_sid (glyph); + case 2: return u.format2.get_sid (glyph); + default:return 0; + } } hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const { - if (format == 0) - return u.format0.get_glyph (sid, num_glyphs); - else if (format == 1) - return u.format1.get_glyph (sid, num_glyphs); - else - return u.format2.get_glyph (sid, num_glyphs); + switch (format) + { + case 0: return u.format0.get_glyph (sid, num_glyphs); + case 1: return u.format1.get_glyph (sid, num_glyphs); + case 2: return u.format2.get_glyph (sid, num_glyphs); + default:return 0; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return_trace (false); + + switch (format) + { + case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ())); + case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ())); + case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ())); + default:return_trace (false); + } } HBUINT8 format; diff --git a/src/hb-ot-cff2-table.hh b/src/hb-ot-cff2-table.hh index 74acc771a..8646cde58 100644 --- a/src/hb-ot-cff2-table.hh +++ b/src/hb-ot-cff2-table.hh @@ -51,18 +51,6 @@ typedef FDSelect3_4_Range FDSelect4_Range; struct CFF2FDSelect { - bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const - { - TRACE_SANITIZE (this); - - return_trace (likely (c->check_struct (this) && (format == 0 || format == 3 || format == 4) && - ((format == 0)? - u.format0.sanitize (c, fdcount): - ((format == 3)? - u.format3.sanitize (c, fdcount): - u.format4.sanitize (c, fdcount))))); - } - bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs) { TRACE_SERIALIZE (this); @@ -78,35 +66,51 @@ struct CFF2FDSelect unsigned int get_size (unsigned int num_glyphs) const { - unsigned int size = format.static_size; - if (format == 0) - size += u.format0.get_size (num_glyphs); - else if (format == 3) - size += u.format3.get_size (); - else - size += u.format4.get_size (); - return size; + switch (format) + { + case 0: return format.static_size + u.format0.get_size (num_glyphs); + case 3: return format.static_size + u.format3.get_size (); + case 4: return format.static_size + u.format4.get_size (); + default:return 0; + } } hb_codepoint_t get_fd (hb_codepoint_t glyph) const { - if (this == &Null(CFF2FDSelect)) + if (this == &Null (CFF2FDSelect)) return 0; - if (format == 0) - return u.format0.get_fd (glyph); - else if (format == 3) - return u.format3.get_fd (glyph); - else - return u.format4.get_fd (glyph); + + switch (format) + { + case 0: return u.format0.get_fd (glyph); + case 3: return u.format3.get_fd (glyph); + case 4: return u.format4.get_fd (glyph); + default:return 0; + } } - HBUINT8 format; - union { - FDSelect0 format0; - FDSelect3 format3; - FDSelect4 format4; - } u; + bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return_trace (false); + switch (format) + { + case 0: return_trace (u.format0.sanitize (c, fdcount)); + case 3: return_trace (u.format3.sanitize (c, fdcount)); + case 4: return_trace (u.format4.sanitize (c, fdcount)); + default:return_trace (false); + } + } + + HBUINT8 format; + union { + FDSelect0 format0; + FDSelect3 format3; + FDSelect4 format4; + } u; + public: DEFINE_SIZE_MIN (2); }; diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index cfecab6ba..688f3f377 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -1040,7 +1040,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan, bool result; cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */ - unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0; + unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0; result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset); if (unlikely (!result)) { diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc index 5977b5669..78b8c05d4 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -547,7 +547,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan, bool result; cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints); /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */ - unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0; + unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0; result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset); if (unlikely (!result)) { From c4669fda7890bc741ef934ebc360e366eba94866 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 9 Jun 2019 11:50:36 +0430 Subject: [PATCH 15/32] [algs] minor --- src/hb-algs.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 07abffbcf..9a9d3f430 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -667,9 +667,9 @@ Parameters: compar is the comparison function arg (optional) is a pointer to be passed to the comparison function -void hb_sort(void *base, size_t nel, size_t width, - int (*compar)(const void *_a, const void *_b, [void *_arg]), - [void *arg]); +void hb_qsort(void *base, size_t nel, size_t width, + int (*compar)(const void *_a, const void *_b, [void *_arg]), + [void *arg]); */ #define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp)) From 2646c7149ce49d3b6cf90e354658df35254bcce0 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 9 Jun 2019 11:51:58 +0430 Subject: [PATCH 16/32] [stat] minor --- src/hb-ot-stat-table.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index 03604a0ad..e9592631d 100644 --- a/src/hb-ot-stat-table.hh +++ b/src/hb-ot-stat-table.hh @@ -191,10 +191,10 @@ struct AxisValue switch (u.format) { - case 1: return_trace (likely (u.format1.sanitize (c))); - case 2: return_trace (likely (u.format2.sanitize (c))); - case 3: return_trace (likely (u.format3.sanitize (c))); - case 4: return_trace (likely (u.format4.sanitize (c))); + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); default: return_trace (true); } } From 7dcfc5357df879491f847bd7d2941645e58f268c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 9 Jun 2019 11:58:08 +0430 Subject: [PATCH 17/32] [stat] minor format --- src/hb-ot-stat-table.hh | 74 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index e9592631d..98bdfa324 100644 --- a/src/hb-ot-stat-table.hh +++ b/src/hb-ot-stat-table.hh @@ -59,14 +59,14 @@ enum struct AxisValueFormat1 { + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this))); } - hb_ot_name_id_t get_value_name_id () const { return valueNameID; } - protected: HBUINT16 format; /* Format identifier — set to 1. */ HBUINT16 axisIndex; /* Zero-base index into the axis record array @@ -84,14 +84,14 @@ struct AxisValueFormat1 struct AxisValueFormat2 { + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this))); } - hb_ot_name_id_t get_value_name_id () const { return valueNameID; } - protected: HBUINT16 format; /* Format identifier — set to 2. */ HBUINT16 axisIndex; /* Zero-base index into the axis record array @@ -113,14 +113,14 @@ struct AxisValueFormat2 struct AxisValueFormat3 { + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this))); } - hb_ot_name_id_t get_value_name_id () const { return valueNameID; } - protected: HBUINT16 format; /* Format identifier — set to 3. */ HBUINT16 axisIndex; /* Zero-base index into the axis record array @@ -157,14 +157,14 @@ struct AxisValueRecord struct AxisValueFormat4 { + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this))); } - hb_ot_name_id_t get_value_name_id () const { return valueNameID; } - protected: HBUINT16 format; /* Format identifier — set to 4. */ HBUINT16 axisCount; /* The total number of axes contributing to @@ -183,6 +183,18 @@ struct AxisValueFormat4 struct AxisValue { + hb_ot_name_id_t get_value_name_id () const + { + switch (u.format) + { + case 1: return u.format1.get_value_name_id (); + case 2: return u.format2.get_value_name_id (); + case 3: return u.format3.get_value_name_id (); + case 4: return u.format4.get_value_name_id (); + default:return HB_OT_NAME_ID_INVALID; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -191,23 +203,11 @@ struct AxisValue switch (u.format) { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 3: return_trace (u.format3.sanitize (c)); - case 4: return_trace (u.format4.sanitize (c)); - default: return_trace (true); - } - } - - hb_ot_name_id_t get_value_name_id () const - { - switch (u.format) - { - case 1: return u.format1.get_value_name_id (); - case 2: return u.format2.get_value_name_id (); - case 3: return u.format3.get_value_name_id (); - case 4: return u.format4.get_value_name_id (); - default: return HB_OT_NAME_ID_INVALID; + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); + default:return_trace (true); } } @@ -226,14 +226,14 @@ struct AxisValue struct StatAxisRecord { + hb_ot_name_id_t get_name_id () const { return nameID; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this))); } - hb_ot_name_id_t get_name_id () const { return nameID; } - protected: Tag tag; /* A tag identifying the axis of design variation. */ NameID nameID; /* The name ID for entries in the 'name' table that @@ -249,16 +249,6 @@ struct STAT { static constexpr hb_tag_t tableTag = HB_OT_TAG_STAT; - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - version.major == 1 && - version.minor > 0 && - designAxesOffset.sanitize (c, this, designAxisCount) && - offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets)))); - } - bool has_data () const { return version.to_int (); } unsigned get_design_axis_count () const { return designAxisCount; } @@ -295,6 +285,16 @@ struct STAT ; } + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + version.major == 1 && + version.minor > 0 && + designAxesOffset.sanitize (c, this, designAxisCount) && + offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets)))); + } + protected: hb_array_t const get_design_axes () const { return (this+designAxesOffset).as_array (designAxisCount); } From 801d93fc58aa13082dea86fb2c3821bc6362f593 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 10 Jun 2019 14:53:14 +0430 Subject: [PATCH 18/32] [ci] remove wine from fedora bot We are not testing Windows exes in fedora mingw bot, we don't have to as probably won't go that smoothly and we have real Windows bots anyway and as wine installation itself is time taking let's remove it --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e81f187f7..9e104dcbe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -197,7 +197,7 @@ jobs: - image: fedora steps: - checkout - - run: dnf install -y pkg-config ragel gcc gcc-c++ automake autoconf libtool make which glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python wine mingw32-gcc-c++ mingw64-gcc-c++ mingw32-glib2 mingw32-cairo mingw32-freetype mingw64-glib2 mingw64-cairo mingw64-freetype glibc-devel.i686 || true + - run: dnf install -y pkg-config ragel gcc gcc-c++ automake autoconf libtool make which glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python mingw32-gcc-c++ mingw64-gcc-c++ mingw32-glib2 mingw32-cairo mingw32-freetype mingw64-glib2 mingw64-cairo mingw64-freetype glibc-devel.i686 || true - run: CFLAGS="-O0" CXXFLAGS="-O0" CPPFLAGS="-DHB_DEBUG" NOCONFIGURE=1 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 - run: mkdir build && cd build && ../configure && make -j32 && (make check || ../.ci/fail.sh) - run: pip install pefile From 9407ef8d4bb96346b1f8b07757d79d3f8cc61cf7 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 10 Jun 2019 15:17:43 +0430 Subject: [PATCH 19/32] minor, add HB_USE_INTERNAL_QSORT The only thing I need for a working wasm in a minimum libc, otherwise I have to provide the very same qsort inside that libc --- src/hb-algs.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 9a9d3f430..7b727f299 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -1,6 +1,6 @@ /* * Copyright © 2017 Google, Inc. - * Copyright © 2019 Google, Inc. + * Copyright © 2019 Facebook, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -843,7 +843,7 @@ static inline void hb_qsort (void *base, size_t nel, size_t width, int (*compar)(const void *_a, const void *_b)) { -#ifdef __OPTIMIZE_SIZE__ +#if defined(__OPTIMIZE_SIZE__) && !defined(HB_USE_INTERNAL_QSORT) qsort (base, nel, width, compar); #else sort_r_simple (base, nel, width, compar); From a228bb5f1d471a334bc9727f5d4f5b59dbe829ff Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 10 Jun 2019 15:56:36 +0430 Subject: [PATCH 20/32] [ci] Test -Os and optimize size in Alpine bot __OPTIMIZE_SIZE__ should be defined whenever -Os but some Internet thread indicate may not so lets do that ourselves as that is the main intention --- .circleci/config.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e104dcbe..5a8b8d73a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,7 +45,7 @@ jobs: - run: rm -rf harfbuzz-* - run: make distdir && cd harfbuzz-* && cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild && CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test && ninja -Cbuild install - alpine-O3-NOMMAP: + alpine-O3-Os-NOMMAP: docker: - image: alpine steps: @@ -55,6 +55,10 @@ jobs: - run: CFLAGS="-O3" CXXFLAGS="-O3 -DHB_NO_MMAP" ./autogen.sh - run: make -j32 - run: make check || .ci/fail.sh + - run: make clean + - run: CFLAGS="-Os -D__OPTIMIZE_SIZE__" CXXFLAGS="-Os -DHB_NO_MMAP -D__OPTIMIZE_SIZE__" ./autogen.sh + - run: make -j32 + - run: make check || .ci/fail.sh archlinux-py3-all: docker: @@ -307,7 +311,7 @@ workflows: - distcheck # autotools based builds - - alpine-O3-NOMMAP + - alpine-O3-Os-NOMMAP - archlinux-py3-all #- void-notest - gcc-valgrind From 4a2b58555f173b692b767c933d280a51142926dd Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 10 Jun 2019 08:16:51 -0700 Subject: [PATCH 21/32] [ci] Use HB_OPTIMIZE_SIZE instead of __OPTIMIZE_SIZE__ --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a8b8d73a..c1741a804 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -56,7 +56,7 @@ jobs: - run: make -j32 - run: make check || .ci/fail.sh - run: make clean - - run: CFLAGS="-Os -D__OPTIMIZE_SIZE__" CXXFLAGS="-Os -DHB_NO_MMAP -D__OPTIMIZE_SIZE__" ./autogen.sh + - run: CFLAGS="-Os -DHB_OPTIMIZE_SIZE" CXXFLAGS="-Os -DHB_NO_MMAP -DHB_OPTIMIZE_SIZE" ./autogen.sh - run: make -j32 - run: make check || .ci/fail.sh From a0c4900799c26e4ff34180842a5ff21048fe31a0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 10 Jun 2019 12:33:23 -0700 Subject: [PATCH 22/32] Test new solution for HB_PARTIALIZE Just testing bots. Will finish based on results. --- src/hb-algs.hh | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 7b727f299..401668a36 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -186,27 +186,11 @@ auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN * that "this+0" is illegal in the trailing decltype position since at * that point this points to incomplete type! But seems to do the trick. */ -#ifdef _MSC_VER -/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \ -#define HB_PARTIALIZE(Pos) \ - template \ - decltype(auto) operator () (_T&& _v) const \ - { return hb_partial (this, hb_forward<_T> (_v)); } \ - static_assert (true, "") -#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ <= 8) -/* https://github.com/harfbuzz/harfbuzz/issues/1724 */ #define HB_PARTIALIZE(Pos) \ template \ auto operator () (_T&& _v) const HB_AUTO_RETURN \ - (hb_partial (this+0, hb_forward<_T> (_v))) \ + (hb_partial (+this, hb_forward<_T> (_v))) \ static_assert (true, "") -#else -#define HB_PARTIALIZE(Pos) \ - template \ - auto operator () (_T&& _v) const HB_AUTO_RETURN \ - (hb_partial (this, hb_forward<_T> (_v))) \ - static_assert (true, "") -#endif struct From 451edbd4d063a4b43c1ca3d2b60c7392602ae7b7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 10 Jun 2019 12:46:54 -0700 Subject: [PATCH 23/32] Revert "Test new solution for HB_PARTIALIZE" This reverts commit a0c4900799c26e4ff34180842a5ff21048fe31a0. --- src/hb-algs.hh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 401668a36..7b727f299 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -186,11 +186,27 @@ auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN * that "this+0" is illegal in the trailing decltype position since at * that point this points to incomplete type! But seems to do the trick. */ +#ifdef _MSC_VER +/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \ +#define HB_PARTIALIZE(Pos) \ + template \ + decltype(auto) operator () (_T&& _v) const \ + { return hb_partial (this, hb_forward<_T> (_v)); } \ + static_assert (true, "") +#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ <= 8) +/* https://github.com/harfbuzz/harfbuzz/issues/1724 */ #define HB_PARTIALIZE(Pos) \ template \ auto operator () (_T&& _v) const HB_AUTO_RETURN \ - (hb_partial (+this, hb_forward<_T> (_v))) \ + (hb_partial (this+0, hb_forward<_T> (_v))) \ static_assert (true, "") +#else +#define HB_PARTIALIZE(Pos) \ + template \ + auto operator () (_T&& _v) const HB_AUTO_RETURN \ + (hb_partial (this, hb_forward<_T> (_v))) \ + static_assert (true, "") +#endif struct From ff9b9b1c89d5529fafc74ce84c0acb71b5d6031b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 10 Jun 2019 12:48:25 -0700 Subject: [PATCH 24/32] Simplify HB_PARTIALIZE impl +this works on gcc 4.8 as well as default code path. --- src/hb-algs.hh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 7b727f299..59eead4eb 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -181,10 +181,9 @@ auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN * * In the case of MSVC, we get around this by using C++14 "decltype(auto)" * which deduces the type from the actual return statement. For gcc 4.8 - * we use "this+0" instead of "this" which produces an rvalue that seems - * to do be deduces as the same type with this particular compiler. Note - * that "this+0" is illegal in the trailing decltype position since at - * that point this points to incomplete type! But seems to do the trick. + * we use "+this" instead of "this" which produces an rvalue that seems + * to be deduced as the same type with this particular compiler, and seem + * to be fine as default code path as well. */ #ifdef _MSC_VER /* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \ @@ -193,18 +192,12 @@ auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN decltype(auto) operator () (_T&& _v) const \ { return hb_partial (this, hb_forward<_T> (_v)); } \ static_assert (true, "") -#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ <= 8) +#else /* https://github.com/harfbuzz/harfbuzz/issues/1724 */ #define HB_PARTIALIZE(Pos) \ template \ auto operator () (_T&& _v) const HB_AUTO_RETURN \ - (hb_partial (this+0, hb_forward<_T> (_v))) \ - static_assert (true, "") -#else -#define HB_PARTIALIZE(Pos) \ - template \ - auto operator () (_T&& _v) const HB_AUTO_RETURN \ - (hb_partial (this, hb_forward<_T> (_v))) \ + (hb_partial (+this, hb_forward<_T> (_v))) \ static_assert (true, "") #endif From c4cae81a26a816979f3206418c47856b5ed2d8bb Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 10 Jun 2019 15:32:54 +0430 Subject: [PATCH 25/32] Remove round polyfill Added in 01dff1e and 19256bef, this was targeted at older msvc versions that don't support C99 but now as we require C++11 we don't target places those envs thus removing this. --- CMakeLists.txt | 2 +- configure.ac | 6 ------ src/hb.hh | 14 -------------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ffabad10..cbff81e95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,7 +108,7 @@ endmacro () if (UNIX) list(APPEND CMAKE_REQUIRED_LIBRARIES m) endif () -check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l round) +check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l) check_include_file(unistd.h HAVE_UNISTD_H) if (${HAVE_UNISTD_H}) add_definitions(-DHAVE_UNISTD_H) diff --git a/configure.ac b/configure.ac index 6a68df79e..d48823d25 100644 --- a/configure.ac +++ b/configure.ac @@ -78,12 +78,6 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl]) # Functions and headers AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l posix_memalign) - -save_libs="$LIBS" -LIBS="$LIBS -lm" -AC_CHECK_FUNCS([round], ,[AC_CHECK_DECLS([round], , ,[#include ])]) -LIBS="$save_libs" - AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h) # Compiler flags diff --git a/src/hb.hh b/src/hb.hh index 33ad32311..0ee8ff57d 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -515,20 +515,6 @@ typedef uint64_t hb_vector_size_impl_t; #define VAR 1 -/* fallback for round() */ -static inline double -_hb_round (double x) -{ - if (x >= 0) - return floor (x + 0.5); - else - return ceil (x - 0.5); -} -#if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND) -#define round(x) _hb_round(x) -#endif - - /* fallback for posix_memalign() */ static inline int _hb_memalign(void **memptr, size_t alignment, size_t size) From a36ff941710b5a5f7e464e6d72aff36cf5549a91 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 10 Jun 2019 15:48:28 +0430 Subject: [PATCH 26/32] Add HB_NO_SETLOCALE --- src/hb-config.hh | 1 + src/hb.hh | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index 8bdce3598..bcce15941 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -61,6 +61,7 @@ #define HB_NO_LAYOUT_UNUSED #define HB_NO_MATH #define HB_NO_NAME +#define HB_NO_SETLOCALE #define HB_NO_SUBSET_LAYOUT #endif diff --git a/src/hb.hh b/src/hb.hh index 0ee8ff57d..bf547708f 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -359,7 +359,7 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); # define HB_NO_GETENV # endif # if _WIN32_WCE < 0x800 -# define setlocale(Category, Locale) "C" +# define HB_NO_SETLOCALE static int errno = 0; /* Use something better? */ # endif # elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) @@ -372,6 +372,10 @@ static int errno = 0; /* Use something better? */ # endif #endif +#ifdef HB_NO_SETLOCALE +#define setlocale(Category, Locale) "C" +#endif + #ifdef HB_NO_GETENV #define getenv(Name) nullptr #endif From b4a5a69ad8625e3b90eb907a1b70e3ed24d4ff97 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 11 Jun 2019 01:33:09 +0430 Subject: [PATCH 27/32] Add HB_NO_OEPN (#1767) --- src/hb-blob.cc | 3 +++ src/hb-config.hh | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 5783fb294..0c562b770 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -543,6 +543,9 @@ _hb_mapped_file_destroy (void *file_) hb_blob_t * hb_blob_create_from_file (const char *file_name) { +#ifdef HB_NO_OEPN + return hb_blob_get_empty (); +#endif /* Adopted from glib's gmappedfile.c with Matthias Clasen and Allison Lortie permission but changed a lot to suit our need. */ #if defined(HAVE_MMAP) && !defined(HB_NO_MMAP) diff --git a/src/hb-config.hh b/src/hb-config.hh index bcce15941..19ceed863 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -60,7 +60,9 @@ #define HB_NO_GETENV #define HB_NO_LAYOUT_UNUSED #define HB_NO_MATH +#define HB_NO_MMAP #define HB_NO_NAME +#define HB_NO_OEPN #define HB_NO_SETLOCALE #define HB_NO_SUBSET_LAYOUT #endif From 19b8eb08e5457cd643aee5f9b9ad1c80b2243895 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 11 Jun 2019 01:33:30 +0430 Subject: [PATCH 28/32] Move HB_NO_SETLOCALE to closer place to its to unbreak HB_TINY build (#1768) --- src/hb-common.cc | 3 +++ src/hb.hh | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index 71791dba1..fb6377e39 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -35,6 +35,9 @@ #include #endif +#ifdef HB_NO_SETLOCALE +#define setlocale(Category, Locale) "C" +#endif /** * SECTION:hb-common diff --git a/src/hb.hh b/src/hb.hh index bf547708f..a2baa31d2 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -372,10 +372,6 @@ static int errno = 0; /* Use something better? */ # endif #endif -#ifdef HB_NO_SETLOCALE -#define setlocale(Category, Locale) "C" -#endif - #ifdef HB_NO_GETENV #define getenv(Name) nullptr #endif From 0c5da57d1aab91d7677a5c6517a3da254d53267f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 10 Jun 2019 14:06:25 -0700 Subject: [PATCH 29/32] Fix typo :) --- src/hb-blob.cc | 3 ++- src/hb-config.hh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 0c562b770..497df65fd 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -543,9 +543,10 @@ _hb_mapped_file_destroy (void *file_) hb_blob_t * hb_blob_create_from_file (const char *file_name) { -#ifdef HB_NO_OEPN +#ifdef HB_NO_OPEN return hb_blob_get_empty (); #endif + /* Adopted from glib's gmappedfile.c with Matthias Clasen and Allison Lortie permission but changed a lot to suit our need. */ #if defined(HAVE_MMAP) && !defined(HB_NO_MMAP) diff --git a/src/hb-config.hh b/src/hb-config.hh index 19ceed863..56c85a042 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -62,7 +62,7 @@ #define HB_NO_MATH #define HB_NO_MMAP #define HB_NO_NAME -#define HB_NO_OEPN +#define HB_NO_OPEN #define HB_NO_SETLOCALE #define HB_NO_SUBSET_LAYOUT #endif From 90872a29ee5d0bef6df1c2900f7001c11106c4da Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Tue, 11 Jun 2019 12:28:30 -0700 Subject: [PATCH 30/32] change assert(false) to failure --- src/hb-subset-cff-common.cc | 2 +- ...se-minimized-hb-subset-fuzzer-5680398559870976 | Bin 0 -> 145 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976 diff --git a/src/hb-subset-cff-common.cc b/src/hb-subset-cff-common.cc index aa5d27b36..223c6a821 100644 --- a/src/hb-subset-cff-common.cc +++ b/src/hb-subset-cff-common.cc @@ -226,7 +226,7 @@ hb_serialize_cff_fdselect (hb_serialize_context_t *c, fdselect_ranges); default: - assert(false); + return_trace (false); } return_trace (true); diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976 new file mode 100644 index 0000000000000000000000000000000000000000..5c7b6b50bd7f661b471b0d702bca7bdfdad0f1bd GIT binary patch literal 145 zcmZQzWME)mR=^6J-Q0{o5 Date: Tue, 11 Jun 2019 17:55:31 -0400 Subject: [PATCH 31/32] Remove 'mym3' --- src/hb-ot-tag.cc | 4 +++- test/api/test-ot-tag.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index ad3635bda..61b609d5e 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -145,7 +145,9 @@ hb_ot_all_tags_from_script (hb_script_t script, hb_tag_t new_tag = hb_ot_new_tag_from_script (script); if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) { - tags[i++] = new_tag | '3'; + /* HB_SCRIPT_MYANMAR maps to 'mym2', but there is no 'mym3'. */ + if (new_tag != HB_TAG('m','y','m','2')) + tags[i++] = new_tag | '3'; if (*count > i) tags[i++] = new_tag; } diff --git a/test/api/test-ot-tag.c b/test/api/test-ot-tag.c index 66c69caf7..d0334cd06 100644 --- a/test/api/test-ot-tag.c +++ b/test/api/test-ot-tag.c @@ -190,7 +190,6 @@ test_ot_tag_script_indic (void) test_indic_tags ("ory3", "ory2", "orya", HB_SCRIPT_ORIYA); test_indic_tags ("tml3", "tml2", "taml", HB_SCRIPT_TAMIL); test_indic_tags ("tel3", "tel2", "telu", HB_SCRIPT_TELUGU); - test_indic_tags ("mym3", "mym2", "mymr", HB_SCRIPT_MYANMAR); } @@ -506,6 +505,7 @@ test_ot_tag_full (void) test_tags (HB_SCRIPT_INVALID, "x-hbsc5678-hbot1234", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 1, 1, "5678", "1234"); test_tags (HB_SCRIPT_MALAYALAM, "ml", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 3, 2, "mlm3", "mlm2", "mlym", "MAL", "MLR"); test_tags (HB_SCRIPT_MALAYALAM, "ml", 1, 1, 1, 1, "mlm3", "MAL"); + test_tags (HB_SCRIPT_MYANMAR, "und", HB_OT_MAX_TAGS_PER_SCRIPT, 0, 2, 0, "mym2", "mymr"); test_tags (HB_SCRIPT_INVALID, "xyz", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 1, "XYZ"); test_tags (HB_SCRIPT_INVALID, "xy", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 0); } From 6bcbe495bff221169f8c0769dde1b4b2c165a211 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 13 Jun 2019 15:04:51 +0430 Subject: [PATCH 32/32] [cff] minor format (#1774) --- src/hb-subset-cff-common.cc | 100 +++++++++++++++++------------------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/src/hb-subset-cff-common.cc b/src/hb-subset-cff-common.cc index 223c6a821..2aa55b985 100644 --- a/src/hb-subset-cff-common.cc +++ b/src/hb-subset-cff-common.cc @@ -44,18 +44,18 @@ using namespace CFF; bool hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, - unsigned int fdCount, - const FDSelect &src, /* IN */ - unsigned int &subset_fd_count /* OUT */, - unsigned int &subset_fdselect_size /* OUT */, - unsigned int &subset_fdselect_format /* OUT */, - hb_vector_t &fdselect_ranges /* OUT */, - remap_t &fdmap /* OUT */) + unsigned int fdCount, + const FDSelect &src, /* IN */ + unsigned int &subset_fd_count /* OUT */, + unsigned int &subset_fdselect_size /* OUT */, + unsigned int &subset_fdselect_format /* OUT */, + hb_vector_t &fdselect_ranges /* OUT */, + remap_t &fdmap /* OUT */) { subset_fd_count = 0; subset_fdselect_size = 0; subset_fdselect_format = 0; - unsigned int num_ranges = 0; + unsigned int num_ranges = 0; unsigned int subset_num_glyphs = plan->num_output_glyphs (); if (subset_num_glyphs == 0) @@ -63,14 +63,14 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, { /* use hb_set to determine the subset of font dicts */ - hb_set_t *set = hb_set_create (); + hb_set_t *set = hb_set_create (); if (set == &Null (hb_set_t)) return false; - hb_codepoint_t prev_fd = CFF_UNDEF_CODE; + hb_codepoint_t prev_fd = CFF_UNDEF_CODE; for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++) { - hb_codepoint_t glyph; - hb_codepoint_t fd; + hb_codepoint_t glyph; + hb_codepoint_t fd; if (!plan->old_gid_for_new_gid (i, &glyph)) { /* fonttools retains FDSelect & font dicts for missing glyphs. do the same */ @@ -104,7 +104,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, return false; } - hb_codepoint_t fd = CFF_UNDEF_CODE; + hb_codepoint_t fd = CFF_UNDEF_CODE; while (set->next (&fd)) fdmap.add (fd); hb_set_destroy (set); @@ -152,10 +152,10 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, template static inline bool serialize_fdselect_3_4 (hb_serialize_context_t *c, - const unsigned int num_glyphs, - const FDSelect &src, - unsigned int size, - const hb_vector_t &fdselect_ranges) + const unsigned int num_glyphs, + const FDSelect &src, + unsigned int size, + const hb_vector_t &fdselect_ranges) { TRACE_SERIALIZE (this); FDSELECT3_4 *p = c->allocate_size (size); @@ -166,7 +166,7 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c, p->ranges[i].first = fdselect_ranges[i].glyph; p->ranges[i].fd = fdselect_ranges[i].code; } - p->sentinel() = num_glyphs; + p->sentinel () = num_glyphs; return_trace (true); } @@ -176,15 +176,15 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c, **/ bool hb_serialize_cff_fdselect (hb_serialize_context_t *c, - const unsigned int num_glyphs, - const FDSelect &src, - unsigned int fd_count, - unsigned int fdselect_format, - unsigned int size, - const hb_vector_t &fdselect_ranges) + const unsigned int num_glyphs, + const FDSelect &src, + unsigned int fd_count, + unsigned int fdselect_format, + unsigned int size, + const hb_vector_t &fdselect_ranges) { TRACE_SERIALIZE (this); - FDSelect *p = c->allocate_min (); + FDSelect *p = c->allocate_min (); if (unlikely (p == nullptr)) return_trace (false); p->format = fdselect_format; size -= FDSelect::min_size; @@ -192,42 +192,34 @@ hb_serialize_cff_fdselect (hb_serialize_context_t *c, switch (fdselect_format) { #if CFF_SERIALIZE_FDSELECT_0 - case 0: + case 0: + { + FDSelect0 *p = c->allocate_size (size); + if (unlikely (p == nullptr)) return_trace (false); + unsigned int range_index = 0; + unsigned int fd = fdselect_ranges[range_index++].code; + for (unsigned int i = 0; i < num_glyphs; i++) { - FDSelect0 *p = c->allocate_size (size); - if (unlikely (p == nullptr)) return_trace (false); - unsigned int range_index = 0; - unsigned int fd = fdselect_ranges[range_index++].code; - for (unsigned int i = 0; i < num_glyphs; i++) + if ((range_index < fdselect_ranges.len) && + (i >= fdselect_ranges[range_index].glyph)) { - if ((range_index < fdselect_ranges.len) && - (i >= fdselect_ranges[range_index].glyph)) - { - fd = fdselect_ranges[range_index++].code; - } - p->fds[i] = fd; + fd = fdselect_ranges[range_index++].code; } - break; + p->fds[i] = fd; } + return_trace (true); + } #endif /* CFF_SERIALIZE_FDSELECT_0 */ - case 3: - return serialize_fdselect_3_4 (c, - num_glyphs, - src, - size, - fdselect_ranges); + case 3: + return serialize_fdselect_3_4 (c, num_glyphs, src, + size, fdselect_ranges); - case 4: - return serialize_fdselect_3_4 (c, - num_glyphs, - src, - size, - fdselect_ranges); + case 4: + return serialize_fdselect_3_4 (c, num_glyphs, src, + size, fdselect_ranges); - default: - return_trace (false); + default: + return_trace (false); } - - return_trace (true); }