diff --git a/.circleci/config.yml b/.circleci/config.yml index e81f187f7..c1741a804 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 -DHB_OPTIMIZE_SIZE" CXXFLAGS="-Os -DHB_NO_MMAP -DHB_OPTIMIZE_SIZE" ./autogen.sh + - run: make -j32 + - run: make check || .ci/fail.sh archlinux-py3-all: docker: @@ -197,7 +201,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 @@ -307,7 +311,7 @@ workflows: - distcheck # autotools based builds - - alpine-O3-NOMMAP + - alpine-O3-Os-NOMMAP - archlinux-py3-all #- void-notest - gcc-valgrind 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 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/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-algs.hh b/src/hb-algs.hh index 0b34f7106..59eead4eb 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. * @@ -167,19 +167,37 @@ 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" 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 */ \ #define HB_PARTIALIZE(Pos) \ template \ decltype(auto) operator () (_T&& _v) const \ { return hb_partial (this, hb_forward<_T> (_v)); } \ static_assert (true, "") #else +/* 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, hb_forward<_T> (_v))) \ static_assert (true, "") #endif @@ -400,7 +418,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 +492,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; @@ -628,115 +646,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_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)) -/* 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-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-blob.cc b/src/hb-blob.cc index 5783fb294..497df65fd 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -543,6 +543,10 @@ _hb_mapped_file_destroy (void *file_) hb_blob_t * hb_blob_create_from_file (const char *file_name) { +#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-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 ()) 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-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-config.hh b/src/hb-config.hh index 8bdce3598..56c85a042 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -60,7 +60,10 @@ #define HB_NO_GETENV #define HB_NO_LAYOUT_UNUSED #define HB_NO_MATH +#define HB_NO_MMAP #define HB_NO_NAME +#define HB_NO_OPEN +#define HB_NO_SETLOCALE #define HB_NO_SUBSET_LAYOUT #endif 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 diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh index 555ade53e..2e6c0ef21 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 {}; @@ -432,7 +428,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++) { @@ -524,9 +520,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; } @@ -537,7 +531,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); @@ -546,12 +541,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 (); } @@ -563,10 +559,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); @@ -598,17 +592,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); @@ -624,30 +609,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 b1298b778..a38b39b1d 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-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 68ca973ee..a7f4a3642 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -185,7 +185,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 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-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-ot-post-table.hh b/src/hb-ot-post-table.hh index 970bbe68a..720e03bac 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 @@ -158,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))) { diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index 03604a0ad..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 (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))); - 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); } 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/src/hb-subset-cff-common.cc b/src/hb-subset-cff-common.cc index a130845bb..bae6a09ce 100644 --- a/src/hb-subset-cff-common.cc +++ b/src/hb-subset-cff-common.cc @@ -55,7 +55,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, 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 */ @@ -145,10 +145,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); @@ -159,7 +159,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); } @@ -169,15 +169,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; @@ -185,42 +185,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: - assert(false); + default: + return_trace (false); } - - return_trace (true); } diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index 97205948a..c4b923ab2 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -1037,7 +1037,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 400f19fcf..66d627ed2 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -545,7 +545,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)) { diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 19f46d16d..2b61df237 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -183,7 +183,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"); @@ -192,10 +192,10 @@ _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 = _subset (plan); + result = _subset2 (plan); break; #ifndef HB_NO_SUBSET_CFF 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); 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..a2baa31d2 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" @@ -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) @@ -352,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) @@ -508,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) 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); } 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 000000000..5c7b6b50b Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976 differ