Merge branch 'master' into var-subset

This commit is contained in:
Michiharu Ariza 2019-04-16 11:35:07 -07:00
commit 6cde814a36
34 changed files with 1349 additions and 1184 deletions

View File

@ -28,7 +28,7 @@ jobs:
steps: steps:
- checkout - checkout
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget autoconf automake libtool pkg-config ragel freetype glib cairo icu4c graphite2 - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget autoconf automake libtool pkg-config ragel freetype glib cairo icu4c graphite2
- run: export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig" && ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-coretext --with-graphite2 - run: export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" && ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-coretext --with-graphite2
- run: make -j4 - run: make -j4
- run: make check || .ci/fail.sh - run: make check || .ci/fail.sh
@ -250,7 +250,7 @@ jobs:
steps: steps:
- checkout - checkout
- run: git clone https://github.com/vitasdk/vdpm && cd vdpm && ./bootstrap-vitasdk.sh - run: git clone https://github.com/vitasdk/vdpm && cd vdpm && ./bootstrap-vitasdk.sh
- run: echo "#""!""/bin/true" > /usr/bin/ragel && chmod +x /usr/bin/ragel - run: echo '#!/bin/true' > /usr/bin/ragel && chmod +x /usr/bin/ragel
- run: ./autogen.sh --prefix=/usr/local/vitasdk/arm-vita-eabi --host=arm-vita-eabi - run: ./autogen.sh --prefix=/usr/local/vitasdk/arm-vita-eabi --host=arm-vita-eabi
- run: make -j32 - run: make -j32

View File

@ -151,9 +151,9 @@
</para> </para>
<para> <para>
For example, in Tamil, when the letter &quot;TTA&quot; (ட) For example, in Tamil, when the letter &quot;TTA&quot; (ட)
letter is followed by &quot;U&quot; (உ), the pair letter is followed by the vowel sign &quot;U&quot; (ு), the pair
must be replaced by the single glyph &quot;டு&quot;. The must be replaced by the single glyph &quot;டு&quot;. The
sequence of Unicode characters &quot;&quot; needs to be sequence of Unicode characters &quot;,ு&quot; needs to be
substituted with a single &quot;டு&quot; glyph from the substituted with a single &quot;டு&quot; glyph from the
font. font.
</para> </para>

View File

@ -895,20 +895,11 @@ def language_name_intersection (a, b):
def get_matching_language_name (intersection, candidates): def get_matching_language_name (intersection, candidates):
return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c))))
maximum_tags = 0
for language, tags in sorted (ot.from_bcp_47.items ()): for language, tags in sorted (ot.from_bcp_47.items ()):
if language == '' or '-' in language: if language == '' or '-' in language:
continue continue
print (' {\"%s\",\t{' % language, end='')
maximum_tags = max (maximum_tags, len (tags))
tag_count = len (tags)
for i, tag in enumerate (tags, start=1): for i, tag in enumerate (tags, start=1):
if i > 1: print (' {\"%s\",\t%s},\t/* ' % (language, hb_tag (tag)), end='')
print ('\t\t ', end='')
print (hb_tag (tag), end='')
if i == tag_count:
print ('}}', end='')
print (',\t/* ', end='')
bcp_47_name = bcp_47.names.get (language, '') bcp_47_name = bcp_47.names.get (language, '')
bcp_47_name_candidates = bcp_47_name.split ('\n') bcp_47_name_candidates = bcp_47_name.split ('\n')
intersection = language_name_intersection (bcp_47_name, ot.names[tag]) intersection = language_name_intersection (bcp_47_name, ot.names[tag])
@ -923,8 +914,6 @@ for language, tags in sorted (ot.from_bcp_47.items ()):
print ('};') print ('};')
print () print ()
print ('static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == %iu, "");' % maximum_tags)
print ()
print ('/**') print ('/**')
print (' * hb_ot_tags_from_complex_language:') print (' * hb_ot_tags_from_complex_language:')

View File

@ -39,7 +39,7 @@ struct hb_aat_feature_mapping_t
hb_aat_layout_feature_selector_t selectorToEnable; hb_aat_layout_feature_selector_t selectorToEnable;
hb_aat_layout_feature_selector_t selectorToDisable; hb_aat_layout_feature_selector_t selectorToDisable;
static int cmp (const void *key_, const void *entry_) HB_INTERNAL static int cmp (const void *key_, const void *entry_)
{ {
hb_tag_t key = * (unsigned int *) key_; hb_tag_t key = * (unsigned int *) key_;
const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_;

View File

@ -66,7 +66,7 @@ struct hb_aat_map_builder_t
hb_aat_layout_feature_selector_t setting; hb_aat_layout_feature_selector_t setting;
unsigned seq; /* For stable sorting only. */ unsigned seq; /* For stable sorting only. */
static int cmp (const void *pa, const void *pb) HB_INTERNAL static int cmp (const void *pa, const void *pb)
{ {
const feature_info_t *a = (const feature_info_t *) pa; const feature_info_t *a = (const feature_info_t *) pa;
const feature_info_t *b = (const feature_info_t *) pb; const feature_info_t *b = (const feature_info_t *) pb;

View File

@ -1,5 +1,6 @@
/* /*
* Copyright © 2017 Google, Inc. * Copyright © 2017 Google, Inc.
* Copyright © 2019 Google, Inc.
* *
* This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
* *
@ -22,6 +23,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* Google Author(s): Behdad Esfahbod * Google Author(s): Behdad Esfahbod
* Facebook Author(s): Behdad Esfahbod
*/ */
#ifndef HB_ALGS_HH #ifndef HB_ALGS_HH
@ -32,7 +34,7 @@
#include "hb-null.hh" #include "hb-null.hh"
static const struct struct
{ {
/* Don't know how to set priority of following. Doesn't work right now. */ /* Don't know how to set priority of following. Doesn't work right now. */
//template <typename T> //template <typename T>
@ -54,19 +56,105 @@ static const struct
/* Knuth's multiplicative method: */ /* Knuth's multiplicative method: */
return (uint32_t) v * 2654435761u; return (uint32_t) v * 2654435761u;
} }
} hb_hash HB_UNUSED; } HB_FUNCOBJ (hb_hash);
static const struct struct
{ {
template <typename T> T template <typename T> T
operator () (const T& v) const { return v; } operator () (const T& v) const { return v; }
} hb_identity HB_UNUSED; } HB_FUNCOBJ (hb_identity);
static const struct struct
{ {
template <typename T> bool template <typename T> bool
operator () (const T& v) const { return bool (v); } operator () (const T& v) const { return bool (v); }
} hb_bool HB_UNUSED; } HB_FUNCOBJ (hb_bool);
struct
{
private:
/* Pointer-to-member-function. */
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v).*a ())
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v)->*a ())
/* Pointer-to-member. */
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v).*a)
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v)->*a)
/* Operator(). */
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (a (hb_forward<Val> (v)))
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ((*a) (hb_forward<Val> (v)))
public:
template <typename Appl, typename Val> auto
operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN_EXPR (
impl (hb_forward<Appl> (a),
hb_forward<Val> (v),
hb_prioritize)
)
} HB_FUNCOBJ (hb_invoke);
struct
{
private:
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (p->has (v))
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v))
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR (
hb_invoke (hb_forward<Pred> (p),
hb_forward<Val> (v))
)
public:
template <typename Pred, typename Val> auto
operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR (
(bool) impl (hb_forward<Pred> (p),
hb_forward<Val> (v),
hb_prioritize)
)
} HB_FUNCOBJ (hb_has);
struct
{
private:
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f->get (hb_forward<Val> (v)))
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward<Val> (v)))
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (
hb_invoke (hb_forward<Proj> (f),
hb_forward<Val> (v))
)
public:
template <typename Proj, typename Val> auto
operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR (
impl (hb_forward<Proj> (f),
hb_forward<Val> (v),
hb_prioritize)
)
} HB_FUNCOBJ (hb_get);
template <typename T1, typename T2> template <typename T1, typename T2>
struct hb_pair_t struct hb_pair_t
@ -86,28 +174,28 @@ struct hb_pair_t
template <typename T1, typename T2> static inline hb_pair_t<T1, T2> template <typename T1, typename T2> static inline hb_pair_t<T1, T2>
hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); } hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
static const struct struct
{ {
template <typename Pair> decltype (hb_declval (Pair).first) template <typename Pair> decltype (hb_declval (Pair).first)
operator () (const Pair& pair) const { return pair.first; } operator () (const Pair& pair) const { return pair.first; }
} hb_first HB_UNUSED; } HB_FUNCOBJ (hb_first);
static const struct struct
{ {
template <typename Pair> decltype (hb_declval (Pair).second) template <typename Pair> decltype (hb_declval (Pair).second)
operator () (const Pair& pair) const { return pair.second; } operator () (const Pair& pair) const { return pair.second; }
} hb_second HB_UNUSED; } HB_FUNCOBJ (hb_second);
static const struct struct
{ {
template <typename T, typename T2> T template <typename T, typename T2> T
operator () (const T& a, const T2& b) const { return a <= b ? a : b; } operator () (const T& a, const T2& b) const { return a <= b ? a : b; }
} hb_min HB_UNUSED; } HB_FUNCOBJ (hb_min);
static const struct struct
{ {
template <typename T, typename T2> T template <typename T, typename T2> T
operator () (const T& a, const T2& b) const { return a >= b ? a : b; } operator () (const T& a, const T2& b) const { return a >= b ? a : b; }
} hb_max HB_UNUSED; } HB_FUNCOBJ (hb_max);
/* /*

View File

@ -43,7 +43,9 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
* Constructors. * Constructors.
*/ */
hb_array_t () : arrayZ (nullptr), length (0) {} hb_array_t () : arrayZ (nullptr), length (0) {}
hb_array_t (const hb_array_t<Type> &o) : arrayZ (o.arrayZ), length (o.length) {} hb_array_t (const hb_array_t<Type> &o) :
hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
arrayZ (o.arrayZ), length (o.length) {}
template <typename U = Type, hb_enable_if (hb_is_const (U))> template <typename U = Type, hb_enable_if (hb_is_const (U))>
hb_array_t (const hb_array_t<hb_remove_const (Type)> &o) : arrayZ (o.arrayZ), length (o.length) {} hb_array_t (const hb_array_t<hb_remove_const (Type)> &o) : arrayZ (o.arrayZ), length (o.length) {}
@ -86,8 +88,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); } operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
template <typename T> operator T * () const { return arrayZ; } template <typename T> operator T * () const { return arrayZ; }
bool operator == (const hb_array_t &o) const; HB_INTERNAL bool operator == (const hb_array_t &o) const;
uint32_t hash () const; HB_INTERNAL uint32_t hash () const;
/* /*
* Compare, Sort, and Search. * Compare, Sort, and Search.
@ -100,7 +102,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
return (int) a.length - (int) length; return (int) a.length - (int) length;
return hb_memcmp (a.arrayZ, arrayZ, get_size ()); return hb_memcmp (a.arrayZ, arrayZ, get_size ());
} }
static int cmp (const void *pa, const void *pb) HB_INTERNAL static int cmp (const void *pa, const void *pb)
{ {
hb_array_t<Type> *a = (hb_array_t<Type> *) pa; hb_array_t<Type> *a = (hb_array_t<Type> *) pa;
hb_array_t<Type> *b = (hb_array_t<Type> *) pb; hb_array_t<Type> *b = (hb_array_t<Type> *) pb;

View File

@ -410,7 +410,7 @@ struct active_feature_t {
feature_record_t rec; feature_record_t rec;
unsigned int order; unsigned int order;
static int cmp (const void *pa, const void *pb) { HB_INTERNAL static int cmp (const void *pa, const void *pb) {
const active_feature_t *a = (const active_feature_t *) pa; const active_feature_t *a = (const active_feature_t *) pa;
const active_feature_t *b = (const active_feature_t *) pb; const active_feature_t *b = (const active_feature_t *) pb;
return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 : return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
@ -428,7 +428,7 @@ struct feature_event_t {
bool start; bool start;
active_feature_t feature; active_feature_t feature;
static int cmp (const void *pa, const void *pb) { HB_INTERNAL static int cmp (const void *pa, const void *pb) {
const feature_event_t *a = (const feature_event_t *) pa; const feature_event_t *a = (const feature_event_t *) pa;
const feature_event_t *b = (const feature_event_t *) pb; const feature_event_t *b = (const feature_event_t *) pb;
return a->index < b->index ? -1 : a->index > b->index ? 1 : return a->index < b->index ? -1 : a->index > b->index ? 1 :

View File

@ -63,6 +63,9 @@ extern HB_INTERNAL hb_atomic_int_t _hb_options;
static inline hb_options_t static inline hb_options_t
hb_options () hb_options ()
{ {
#if defined(HB_NO_OPTIONS)
return hb_options_t ();
#endif
/* Make a local copy, so we can access bitfield threadsafely. */ /* Make a local copy, so we can access bitfield threadsafely. */
hb_options_union_t u; hb_options_union_t u;
u.i = _hb_options.get_relaxed (); u.i = _hb_options.get_relaxed ();

View File

@ -1,5 +1,6 @@
/* /*
* Copyright © 2018 Google, Inc. * Copyright © 2018 Google, Inc.
* Copyright © 2019 Facebook, Inc.
* *
* This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
* *
@ -22,12 +23,14 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* Google Author(s): Behdad Esfahbod * Google Author(s): Behdad Esfahbod
* Facebook Author(s): Behdad Esfahbod
*/ */
#ifndef HB_ITER_HH #ifndef HB_ITER_HH
#define HB_ITER_HH #define HB_ITER_HH
#include "hb.hh" #include "hb.hh"
#include "hb-algs.hh"
#include "hb-meta.hh" #include "hb-meta.hh"
@ -130,7 +133,7 @@ struct hb_iter_t
template <typename> struct hb_array_t; template <typename> struct hb_array_t;
static const struct struct
{ {
template <typename T> template <typename T>
hb_iter_t (T) hb_iter_t (T)
@ -147,7 +150,7 @@ static const struct
operator () (Type (&array)[length]) const operator () (Type (&array)[length]) const
{ return hb_array_t<Type> (array, length); } { return hb_array_t<Type> (array, length); }
} hb_iter HB_UNUSED; } HB_FUNCOBJ (hb_iter);
/* Mixin to fill in what the subclass doesn't provide. */ /* Mixin to fill in what the subclass doesn't provide. */
@ -270,8 +273,8 @@ struct hb_map_iter_t :
typedef decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t))) __item_t__; typedef decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t))) __item_t__;
static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
__item_t__ __item__ () const { return f (*it); } __item_t__ __item__ () const { return hb_get (f, *it); }
__item_t__ __item_at__ (unsigned i) const { return f (it[i]); } __item_t__ __item_at__ (unsigned i) const { return hb_get (f, it[i]); }
bool __more__ () const { return bool (it); } bool __more__ () const { return bool (it); }
unsigned __len__ () const { return it.len (); } unsigned __len__ () const { return it.len (); }
void __next__ () { ++it; } void __next__ () { ++it; }
@ -298,13 +301,13 @@ struct hb_map_iter_factory_t
private: private:
Proj f; Proj f;
}; };
static const struct struct
{ {
template <typename Proj> template <typename Proj>
hb_map_iter_factory_t<Proj> hb_map_iter_factory_t<Proj>
operator () (Proj&& f) const operator () (Proj&& f) const
{ return hb_map_iter_factory_t<Proj> (f); } { return hb_map_iter_factory_t<Proj> (f); }
} hb_map HB_UNUSED; } HB_FUNCOBJ (hb_map);
template <typename Iter, typename Pred, typename Proj, template <typename Iter, typename Pred, typename Proj,
hb_enable_if (hb_is_iterator (Iter))> hb_enable_if (hb_is_iterator (Iter))>
@ -313,7 +316,7 @@ struct hb_filter_iter_t :
typename Iter::item_t> typename Iter::item_t>
{ {
hb_filter_iter_t (const Iter& it_, Pred p, Proj f) : it (it_), p (p), f (f) hb_filter_iter_t (const Iter& it_, Pred p, Proj f) : it (it_), p (p), f (f)
{ while (it && !p (f (*it))) ++it; } { while (it && !hb_has (p, hb_get (f, *it))) ++it; }
typedef typename Iter::item_t __item_t__; typedef typename Iter::item_t __item_t__;
static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
@ -342,14 +345,14 @@ struct hb_filter_iter_factory_t
Pred p; Pred p;
Proj f; Proj f;
}; };
static const struct struct
{ {
template <typename Pred = decltype ((hb_bool)), template <typename Pred = decltype ((hb_bool)),
typename Proj = decltype ((hb_identity))> typename Proj = decltype ((hb_identity))>
hb_filter_iter_factory_t<Pred, Proj> hb_filter_iter_factory_t<Pred, Proj>
operator () (Pred&& p = hb_bool, Proj&& f = hb_identity) const operator () (Pred&& p = hb_bool, Proj&& f = hb_identity) const
{ return hb_filter_iter_factory_t<Pred, Proj> (p, f); } { return hb_filter_iter_factory_t<Pred, Proj> (p, f); }
} hb_filter HB_UNUSED; } HB_FUNCOBJ (hb_filter);
template <typename Redu, typename InitT> template <typename Redu, typename InitT>
struct hb_reduce_t struct hb_reduce_t
@ -372,13 +375,13 @@ struct hb_reduce_t
Redu r; Redu r;
InitT init_value; InitT init_value;
}; };
static const struct struct
{ {
template <typename Redu, typename InitT> template <typename Redu, typename InitT>
hb_reduce_t<Redu, InitT> hb_reduce_t<Redu, InitT>
operator () (Redu&& r, InitT init_value) const operator () (Redu&& r, InitT init_value) const
{ return hb_reduce_t<Redu, InitT> (r, init_value); } { return hb_reduce_t<Redu, InitT> (r, init_value); }
} hb_reduce HB_UNUSED; } HB_FUNCOBJ (hb_reduce);
/* hb_zip() */ /* hb_zip() */
@ -411,14 +414,14 @@ struct hb_zip_iter_t :
A a; A a;
B b; B b;
}; };
static const struct struct
{ {
template <typename A, typename B, template <typename A, typename B,
hb_enable_if (hb_is_iterable (A) && hb_is_iterable (B))> hb_enable_if (hb_is_iterable (A) && hb_is_iterable (B))>
hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)> hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)>
operator () (A& a, B &b) const operator () (A& a, B &b) const
{ return hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)> (hb_iter (a), hb_iter (b)); } { return hb_zip_iter_t<hb_iter_t (A), hb_iter_t (B)> (hb_iter (a), hb_iter (b)); }
} hb_zip HB_UNUSED; } HB_FUNCOBJ (hb_zip);
/* hb_enumerate */ /* hb_enumerate */
@ -446,14 +449,14 @@ struct hb_enumerate_iter_t :
unsigned i; unsigned i;
Iter it; Iter it;
}; };
static const struct struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
hb_enumerate_iter_t<hb_iter_t (Iterable)> hb_enumerate_iter_t<hb_iter_t (Iterable)>
operator () (Iterable& it) const operator () (Iterable& it) const
{ return hb_enumerate_iter_t<hb_iter_t (Iterable)> (hb_iter (it)); } { return hb_enumerate_iter_t<hb_iter_t (Iterable)> (hb_iter (it)); }
} hb_enumerate HB_UNUSED; } HB_FUNCOBJ (hb_enumerate);
/* hb_apply() */ /* hb_apply() */
@ -468,13 +471,13 @@ struct hb_apply_t
operator () (Iter it) const operator () (Iter it) const
{ {
for (; it; ++it) for (; it; ++it)
a (*it); (void) hb_invoke (a, *it);
} }
private: private:
Appl a; Appl a;
}; };
static const struct struct
{ {
template <typename Appl> hb_apply_t<Appl> template <typename Appl> hb_apply_t<Appl>
operator () (Appl&& a) const operator () (Appl&& a) const
@ -483,7 +486,7 @@ static const struct
template <typename Appl> hb_apply_t<Appl&> template <typename Appl> hb_apply_t<Appl&>
operator () (Appl *a) const operator () (Appl *a) const
{ return hb_apply_t<Appl&> (*a); } { return hb_apply_t<Appl&> (*a); }
} hb_apply HB_UNUSED; } HB_FUNCOBJ (hb_apply);
/* hb_sink() */ /* hb_sink() */
@ -504,7 +507,7 @@ struct hb_sink_t
private: private:
Sink s; Sink s;
}; };
static const struct struct
{ {
template <typename Sink> hb_sink_t<Sink> template <typename Sink> hb_sink_t<Sink>
operator () (Sink&& s) const operator () (Sink&& s) const
@ -513,11 +516,11 @@ static const struct
template <typename Sink> hb_sink_t<Sink&> template <typename Sink> hb_sink_t<Sink&>
operator () (Sink *s) const operator () (Sink *s) const
{ return hb_sink_t<Sink&> (*s); } { return hb_sink_t<Sink&> (*s); }
} hb_sink HB_UNUSED; } HB_FUNCOBJ (hb_sink);
/* hb-drain: hb_sink to void / blackhole / /dev/null. */ /* hb-drain: hb_sink to void / blackhole / /dev/null. */
static const struct struct
{ {
template <typename Iter, template <typename Iter,
hb_enable_if (hb_is_iterator (Iter))> hb_enable_if (hb_is_iterator (Iter))>
@ -527,7 +530,7 @@ static const struct
for (; it; ++it) for (; it; ++it)
(void) *it; (void) *it;
} }
} hb_drain HB_UNUSED; } HB_FUNCOBJ (hb_drain);
/* hb_unzip(): unzip and sink to two sinks. */ /* hb_unzip(): unzip and sink to two sinks. */
@ -553,7 +556,7 @@ struct hb_unzip_t
Sink1 s1; Sink1 s1;
Sink2 s2; Sink2 s2;
}; };
static const struct struct
{ {
template <typename Sink1, typename Sink2> hb_unzip_t<Sink1, Sink2> template <typename Sink1, typename Sink2> hb_unzip_t<Sink1, Sink2>
operator () (Sink1&& s1, Sink2&& s2) const operator () (Sink1&& s1, Sink2&& s2) const
@ -562,12 +565,12 @@ static const struct
template <typename Sink1, typename Sink2> hb_unzip_t<Sink1&, Sink2&> template <typename Sink1, typename Sink2> hb_unzip_t<Sink1&, Sink2&>
operator () (Sink1 *s1, Sink2 *s2) const operator () (Sink1 *s1, Sink2 *s2) const
{ return hb_unzip_t<Sink1&, Sink2&> (*s1, *s2); } { return hb_unzip_t<Sink1&, Sink2&> (*s1, *s2); }
} hb_unzip HB_UNUSED; } HB_FUNCOBJ (hb_unzip);
/* hb-all, hb-any, hb-none. */ /* hb-all, hb-any, hb-none. */
static const struct struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
@ -579,9 +582,8 @@ static const struct
return false; return false;
return true; return true;
} }
} hb_all HB_UNUSED; } HB_FUNCOBJ (hb_all);
struct
static const struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
@ -593,9 +595,8 @@ static const struct
return true; return true;
return false; return false;
} }
} hb_any HB_UNUSED; } HB_FUNCOBJ (hb_any);
struct
static const struct
{ {
template <typename Iterable, template <typename Iterable,
hb_enable_if (hb_is_iterable (Iterable))> hb_enable_if (hb_is_iterable (Iterable))>
@ -607,7 +608,7 @@ static const struct
return false; return false;
return true; return true;
} }
} hb_none HB_UNUSED; } HB_FUNCOBJ (hb_none);
/* /*
* Algorithms operating on iterators. * Algorithms operating on iterators.

View File

@ -34,9 +34,12 @@
* C++ template meta-programming & fundamentals used with them. * C++ template meta-programming & fundamentals used with them.
*/ */
#define HB_FUNCOBJ(x) static_const x HB_UNUSED
template <typename T> static inline T* struct
hb_addressof (const T& arg) {
template <typename T>
T* operator () (const T& arg) const
{ {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wcast-align"
@ -46,6 +49,7 @@ hb_addressof (const T& arg)
reinterpret_cast<const volatile char&> (arg))); reinterpret_cast<const volatile char&> (arg)));
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
} }
} HB_FUNCOBJ (hb_addressof);
template <typename T> static inline T hb_declval (); template <typename T> static inline T hb_declval ();
#define hb_declval(T) (hb_declval<T> ()) #define hb_declval(T) (hb_declval<T> ())
@ -63,52 +67,48 @@ template <typename T> struct hb_match_pointer<T *> { typedef T type; enum { valu
#define hb_remove_pointer(T) typename hb_match_pointer<T>::type #define hb_remove_pointer(T) typename hb_match_pointer<T>::type
#define hb_is_pointer(T) hb_match_pointer<T>::value #define hb_is_pointer(T) hb_match_pointer<T>::value
static const struct struct
{ {
template <typename T> template <typename T>
T operator () (T v) const { return v; } T operator () (T v) const { return v; }
template <typename T> template <typename T>
T& operator () (T *v) const { return *v; } T& operator () (T *v) const { return *v; }
} hb_deref_pointer HB_UNUSED; } HB_FUNCOBJ (hb_deref_pointer);
/* std::move and std::forward */ /* std::move and std::forward */
template <typename T> template <typename T>
hb_remove_reference (T)&& hb_move (T&& t) { return (hb_remove_reference (T)&&) (t); } static hb_remove_reference (T)&& hb_move (T&& t) { return (hb_remove_reference (T)&&) (t); }
template <typename T> template <typename T>
T&& hb_forward (hb_remove_reference (T)& t) { return (T&&) t; } static T&& hb_forward (hb_remove_reference (T)& t) { return (T&&) t; }
template <typename T> template <typename T>
T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; } static T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; }
/* Void! For when we need a expression-type of void. */ /* Void! For when we need a expression-type of void. */
struct hb_void_t { typedef void value; }; struct hb_void_t { typedef void value; };
/* Void meta-function ala std::void_t
* https://en.cppreference.com/w/cpp/types/void_t */
template<typename... Ts> struct _hb_void_tt { typedef void type; };
template<typename... Ts> using hb_void_tt = typename _hb_void_tt<Ts...>::type;
/* Bool! For when we need to evaluate type-dependent expressions /* Bool! For when we need to evaluate type-dependent expressions
* in a template argument. */ * in a template argument. */
template <bool b> struct hb_bool_tt { enum { value = b }; }; template <bool b> struct hb_bool_tt { enum { value = b }; };
typedef hb_bool_tt<true> hb_true_t; typedef hb_bool_tt<true> hb_true_t;
typedef hb_bool_tt<false> hb_false_t; typedef hb_bool_tt<false> hb_false_t;
template<bool B, typename T = void> template<bool B, typename T = void> struct hb_enable_if {};
struct hb_enable_if {}; template<typename T> struct hb_enable_if<true, T> { typedef T type; };
template<typename T>
struct hb_enable_if<true, T> { typedef T type; };
#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr #define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
template <typename T, typename T2> template <typename T, typename T2> struct hb_is_same : hb_false_t {};
struct hb_is_same : hb_false_t {}; template <typename T> struct hb_is_same<T, T> : hb_true_t {};
template <typename T>
struct hb_is_same<T, T> : hb_true_t {};
#define hb_is_same(T, T2) hb_is_same<T, T2>::value #define hb_is_same(T, T2) hb_is_same<T, T2>::value
/*
* Meta-functions.
*/
template <typename T> struct hb_is_signed; template <typename T> struct hb_is_signed;
/* https://github.com/harfbuzz/harfbuzz/issues/1535 */ /* https://github.com/harfbuzz/harfbuzz/issues/1535 */
template <> struct hb_is_signed<int8_t> { enum { value = true }; }; template <> struct hb_is_signed<int8_t> { enum { value = true }; };
@ -140,5 +140,14 @@ template <> struct hb_is_integer<signed long long> { enum { value = true }; };
template <> struct hb_is_integer<unsigned long long> { enum { value = true }; }; template <> struct hb_is_integer<unsigned long long> { enum { value = true }; };
#define hb_is_integer(T) hb_is_integer<T>::value #define hb_is_integer(T) hb_is_integer<T>::value
/* Function overloading SFINAE and priority. */
#define HB_AUTO_RETURN_EXPR(E) -> decltype ((E)) { return (E); }
#define HB_VOID_RETURN_EXPR(E) -> hb_void_tt<decltype ((E))> { (E); }
template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
template <> struct hb_priority<0> {};
#define hb_prioritize hb_priority<16> ()
#endif /* HB_META_HH */ #endif /* HB_META_HH */

View File

@ -37,7 +37,7 @@
/* Global nul-content Null pool. Enlarge as necessary. */ /* Global nul-content Null pool. Enlarge as necessary. */
#define HB_NULL_POOL_SIZE 9880 #define HB_NULL_POOL_SIZE 384
/* Use SFINAE to sniff whether T has min_size; in which case return T::null_size, /* Use SFINAE to sniff whether T has min_size; in which case return T::null_size,
* otherwise return sizeof(T). */ * otherwise return sizeof(T). */

View File

@ -56,7 +56,7 @@ typedef struct TableRecord
{ {
int cmp (Tag t) const { return -t.cmp (tag); } int cmp (Tag t) const { return -t.cmp (tag); }
static int cmp (const void *pa, const void *pb) HB_INTERNAL static int cmp (const void *pa, const void *pb)
{ {
const TableRecord *a = (const TableRecord *) pa; const TableRecord *a = (const TableRecord *) pa;
const TableRecord *b = (const TableRecord *) pb; const TableRecord *b = (const TableRecord *) pb;

View File

@ -63,7 +63,8 @@ struct IntType
operator wide_type () const { return v; } operator wide_type () const { return v; }
bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; } bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); } bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
static int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); } HB_INTERNAL static int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b)
{ return b->cmp (*a); }
template <typename Type2> template <typename Type2>
int cmp (Type2 a) const int cmp (Type2 a) const
{ {
@ -262,6 +263,9 @@ struct _hb_has_null<Type, true>
template <typename Type, typename OffsetType=HBUINT16, bool has_null=true> template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
struct OffsetTo : Offset<OffsetType, has_null> struct OffsetTo : Offset<OffsetType, has_null>
{ {
HB_DELETE_COPY_ASSIGN (OffsetTo);
OffsetTo () = default;
OffsetTo& operator = (typename OffsetType::type i) { OffsetType::operator= (i); return *this; } OffsetTo& operator = (typename OffsetType::type i) { OffsetType::operator= (i); return *this; }
const Type& operator () (const void *base) const const Type& operator () (const void *base) const
@ -605,10 +609,16 @@ struct ArrayOf
* we do not need to call their sanitize() as we already did * we do not need to call their sanitize() as we already did
* a bound check on the aggregate array size. We just include * a bound check on the aggregate array size. We just include
* a small unreachable expression to make sure the structs * a small unreachable expression to make sure the structs
* pointed to do have a simple sanitize(), ie. they do not * pointed to do have a simple sanitize() as well as an
* assignment opreator. This ensures that they do not
* reference other structs via offsets. * reference other structs via offsets.
*/ */
(void) (false && arrayZ[0].sanitize (c)); if (false)
{
arrayZ[0].sanitize (c);
Type v;
v = arrayZ[0];
}
return_trace (true); return_trace (true);
} }

View File

@ -285,7 +285,7 @@ struct CmapSubtableFormat4
*glyph = gid; *glyph = gid;
return true; return true;
} }
static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
{ {
return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph);
} }
@ -904,7 +904,7 @@ struct cmap
// Write out format 4 sub table // Write out format 4 sub table
{ {
CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table); CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table);
format4_plat3_rec.subtable = format4_plat0_rec.subtable; format4_plat3_rec.subtable = (unsigned int) format4_plat0_rec.subtable;
subtable.u.format = 4; subtable.u.format = 4;
CmapSubtableFormat4 &format4 = subtable.u.format4; CmapSubtableFormat4 &format4 = subtable.u.format4;
@ -1096,7 +1096,7 @@ struct cmap
hb_codepoint_t *glyph); hb_codepoint_t *glyph);
template <typename Type> template <typename Type>
static bool get_glyph_from (const void *obj, HB_INTERNAL static bool get_glyph_from (const void *obj,
hb_codepoint_t codepoint, hb_codepoint_t codepoint,
hb_codepoint_t *glyph) hb_codepoint_t *glyph)
{ {
@ -1105,7 +1105,7 @@ struct cmap
} }
template <typename Type> template <typename Type>
static bool get_glyph_from_symbol (const void *obj, HB_INTERNAL static bool get_glyph_from_symbol (const void *obj,
hb_codepoint_t codepoint, hb_codepoint_t codepoint,
hb_codepoint_t *glyph) hb_codepoint_t *glyph)
{ {

View File

@ -184,12 +184,16 @@ hb_ot_get_glyph_extents (hb_font_t *font,
bool ret = ot_face->sbix->get_extents (font, glyph, extents); bool ret = ot_face->sbix->get_extents (font, glyph, extents);
if (!ret) if (!ret)
ret = ot_face->glyf->get_extents (font, glyph, extents); ret = ot_face->glyf->get_extents (font, glyph, extents);
#if !defined(HB_NO_OT_FONT_CFF)
if (!ret) if (!ret)
ret = ot_face->cff1->get_extents (glyph, extents); ret = ot_face->cff1->get_extents (glyph, extents);
if (!ret) if (!ret)
ret = ot_face->cff2->get_extents (font, glyph, extents); ret = ot_face->cff2->get_extents (font, glyph, extents);
#endif
#if !defined(HB_NO_OT_FONT_BITMAP)
if (!ret) if (!ret)
ret = ot_face->CBDT->get_extents (font, glyph, extents); ret = ot_face->CBDT->get_extents (font, glyph, extents);
#endif
// TODO Hook up side-bearings variations. // TODO Hook up side-bearings variations.
extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->x_bearing = font->em_scale_x (extents->x_bearing);
extents->y_bearing = font->em_scale_y (extents->y_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing);

View File

@ -153,7 +153,7 @@ struct BaseCoord
struct FeatMinMaxRecord struct FeatMinMaxRecord
{ {
static int cmp (const void *key_, const void *entry_) HB_INTERNAL static int cmp (const void *key_, const void *entry_)
{ {
hb_tag_t key = * (hb_tag_t *) key_; hb_tag_t key = * (hb_tag_t *) key_;
const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_; const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_;
@ -271,7 +271,7 @@ struct BaseValues
struct BaseLangSysRecord struct BaseLangSysRecord
{ {
static int cmp (const void *key_, const void *entry_) HB_INTERNAL static int cmp (const void *key_, const void *entry_)
{ {
hb_tag_t key = * (hb_tag_t *) key_; hb_tag_t key = * (hb_tag_t *) key_;
const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_; const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_;
@ -345,7 +345,7 @@ struct BaseScript
struct BaseScriptList; struct BaseScriptList;
struct BaseScriptRecord struct BaseScriptRecord
{ {
static int cmp (const void *key_, const void *entry_) HB_INTERNAL static int cmp (const void *key_, const void *entry_)
{ {
hb_tag_t key = * (hb_tag_t *) key_; hb_tag_t key = * (hb_tag_t *) key_;
const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_; const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_;

View File

@ -584,25 +584,25 @@ struct Feature
* Adobe tools, only the 'size' feature had FeatureParams defined. * Adobe tools, only the 'size' feature had FeatureParams defined.
*/ */
OffsetTo<FeatureParams> orig_offset = featureParams; if (likely (featureParams.is_null ()))
return_trace (true);
unsigned int orig_offset = featureParams;
if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
return_trace (false); return_trace (false);
if (likely (orig_offset.is_null ()))
return_trace (true);
if (featureParams == 0 && closure && if (featureParams == 0 && closure &&
closure->tag == HB_TAG ('s','i','z','e') && closure->tag == HB_TAG ('s','i','z','e') &&
closure->list_base && closure->list_base < this) closure->list_base && closure->list_base < this)
{ {
unsigned int new_offset_int = (unsigned int) orig_offset - unsigned int new_offset_int = orig_offset -
(((char *) this) - ((char *) closure->list_base)); (((char *) this) - ((char *) closure->list_base));
OffsetTo<FeatureParams> new_offset; OffsetTo<FeatureParams> new_offset;
/* Check that it did not overflow. */ /* Check that it would not overflow. */
new_offset = new_offset_int; new_offset = new_offset_int;
if (new_offset == new_offset_int && if (new_offset == new_offset_int &&
c->try_set (&featureParams, new_offset) && c->try_set (&featureParams, new_offset_int) &&
!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
return_trace (false); return_trace (false);
} }

View File

@ -173,15 +173,15 @@ struct ValueFormat : HBUINT16
return true; return true;
} }
static OffsetTo<Device>& get_device (Value* value) HB_INTERNAL static OffsetTo<Device>& get_device (Value* value)
{ return *CastP<OffsetTo<Device> > (value); } { return *CastP<OffsetTo<Device> > (value); }
static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr) HB_INTERNAL static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
{ {
if (worked) *worked |= bool (*value); if (worked) *worked |= bool (*value);
return *CastP<OffsetTo<Device> > (value); return *CastP<OffsetTo<Device> > (value);
} }
static const HBINT16& get_short (const Value* value, bool *worked=nullptr) HB_INTERNAL static const HBINT16& get_short (const Value* value, bool *worked=nullptr)
{ {
if (worked) *worked |= bool (*value); if (worked) *worked |= bool (*value);
return *CastP<HBINT16> (value); return *CastP<HBINT16> (value);
@ -1576,7 +1576,7 @@ struct PosLookup : Lookup
dispatch (&c); dispatch (&c);
} }
static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
template <typename context_t> template <typename context_t>
static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);

View File

@ -1194,7 +1194,7 @@ struct SubstLookup : Lookup
const SubTable& get_subtable (unsigned int i) const const SubTable& get_subtable (unsigned int i) const
{ return Lookup::get_subtable<SubTable> (i); } { return Lookup::get_subtable<SubTable> (i); }
static bool lookup_type_is_reverse (unsigned int lookup_type) HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type)
{ return lookup_type == SubTable::ReverseChainSingle; } { return lookup_type == SubTable::ReverseChainSingle; }
bool is_reverse () const bool is_reverse () const
@ -1252,7 +1252,7 @@ struct SubstLookup : Lookup
return dispatch (c); return dispatch (c);
} }
static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
SubTable& serialize_subtable (hb_serialize_context_t *c, SubTable& serialize_subtable (hb_serialize_context_t *c,
unsigned int i) unsigned int i)
@ -1315,9 +1315,9 @@ struct SubstLookup : Lookup
} }
template <typename context_t> template <typename context_t>
static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
{ {
if (!c->should_visit_lookup (lookup_index)) if (!c->should_visit_lookup (lookup_index))
return hb_void_t (); return hb_void_t ();

View File

@ -613,7 +613,7 @@ struct hb_get_subtables_context_t :
hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY> hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
{ {
template <typename Type> template <typename Type>
static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
{ {
const Type *typed_obj = (const Type *) obj; const Type *typed_obj = (const Type *) obj;
return typed_obj->apply (c); return typed_obj->apply (c);

View File

@ -138,6 +138,9 @@ bool
OT::GDEF::is_blacklisted (hb_blob_t *blob, OT::GDEF::is_blacklisted (hb_blob_t *blob,
hb_face_t *face) const hb_face_t *face) const
{ {
#if defined(HB_NO_OT_LAYOUT_BLACKLIST)
return false;
#endif
/* The ugly business of blacklisting individual fonts' tables happen here! /* The ugly business of blacklisting individual fonts' tables happen here!
* See this thread for why we finally had to bend in and do this: * See this thread for why we finally had to bend in and do this:
* https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
@ -381,6 +384,9 @@ bool
OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED, OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
hb_face_t *face) const hb_face_t *face) const
{ {
#if defined(HB_NO_OT_LAYOUT_BLACKLIST)
return false;
#endif
/* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts, /* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts,
* all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken * all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken
* GSUB/GPOS tables. Some have GSUB with zero scripts, those are ignored by * GSUB/GPOS tables. Some have GSUB with zero scripts, those are ignored by
@ -406,6 +412,9 @@ bool
OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED, OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED,
hb_face_t *face HB_UNUSED) const hb_face_t *face HB_UNUSED) const
{ {
#if defined(HB_NO_OT_LAYOUT_BLACKLIST)
return false;
#endif
return false; return false;
} }

View File

@ -68,7 +68,7 @@ struct hb_ot_map_t
unsigned short random : 1; unsigned short random : 1;
hb_mask_t mask; hb_mask_t mask;
static int cmp (const void *pa, const void *pb) HB_INTERNAL static int cmp (const void *pa, const void *pb)
{ {
const lookup_map_t *a = (const lookup_map_t *) pa; const lookup_map_t *a = (const lookup_map_t *) pa;
const lookup_map_t *b = (const lookup_map_t *) pb; const lookup_map_t *b = (const lookup_map_t *) pb;
@ -247,7 +247,7 @@ struct hb_ot_map_builder_t
unsigned int default_value; /* for non-global features, what should the unset glyphs take */ unsigned int default_value; /* for non-global features, what should the unset glyphs take */
unsigned int stage[2]; /* GSUB/GPOS */ unsigned int stage[2]; /* GSUB/GPOS */
static int cmp (const void *pa, const void *pb) HB_INTERNAL static int cmp (const void *pa, const void *pb)
{ {
const feature_info_t *a = (const feature_info_t *) pa; const feature_info_t *a = (const feature_info_t *) pa;
const feature_info_t *b = (const feature_info_t *) pb; const feature_info_t *b = (const feature_info_t *) pb;

View File

@ -60,8 +60,10 @@ struct NameRecord
if (p == 1) if (p == 1)
return _hb_ot_name_language_for_mac_code (l); return _hb_ot_name_language_for_mac_code (l);
#if !defined(HB_NO_NAME_TABLE_AAT)
if (p == 0) if (p == 0)
return _hb_aat_language_get (face, l); return _hb_aat_language_get (face, l);
#endif
return HB_LANGUAGE_INVALID; return HB_LANGUAGE_INVALID;
} }

View File

@ -70,6 +70,10 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
bool found = (bool) c->unicode->compose (a, b, ab); bool found = (bool) c->unicode->compose (a, b, ab);
#if defined(HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK)
return found;
#endif
if (!found && !c->plan->has_gpos_mark) if (!found && !c->plan->has_gpos_mark)
{ {
/* Special-case Hebrew presentation forms that are excluded from /* Special-case Hebrew presentation forms that are excluded from

View File

@ -218,6 +218,10 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer, hb_buffer_t *buffer,
hb_font_t *font) hb_font_t *font)
{ {
#if defined(HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK)
return;
#endif
thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT]; thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT]; thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
unsigned int base = 0; unsigned int base = 0;

View File

@ -34,6 +34,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer, hb_buffer_t *buffer,
hb_font_t *font HB_UNUSED) hb_font_t *font HB_UNUSED)
{ {
#if defined(HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS)
return;
#endif
if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)
return; return;

View File

@ -166,6 +166,10 @@ _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t
hb_font_t *font HB_UNUSED, hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer) hb_buffer_t *buffer)
{ {
#if defined(HB_NO_OT_SHAPE_FALLBACK)
return;
#endif
unsigned int count = buffer->len; unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
@ -434,6 +438,10 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer, hb_buffer_t *buffer,
bool adjust_offsets_when_zeroing) bool adjust_offsets_when_zeroing)
{ {
#if defined(HB_NO_OT_SHAPE_FALLBACK)
return;
#endif
_hb_buffer_assert_gsubgpos_vars (buffer); _hb_buffer_assert_gsubgpos_vars (buffer);
unsigned int start = 0; unsigned int start = 0;
@ -473,6 +481,10 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font, hb_font_t *font,
hb_buffer_t *buffer) hb_buffer_t *buffer)
{ {
#if defined(HB_NO_OT_SHAPE_FALLBACK)
return;
#endif
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ? if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
!font->has_glyph_h_kerning_func () : !font->has_glyph_h_kerning_func () :
!font->has_glyph_v_kerning_func ()) !font->has_glyph_v_kerning_func ())

File diff suppressed because it is too large Load Diff

View File

@ -198,7 +198,7 @@ lang_matches (const char *lang_str, const char *spec)
struct LangTag struct LangTag
{ {
char language[4]; char language[4];
hb_tag_t tags[HB_OT_MAX_TAGS_PER_LANGUAGE]; hb_tag_t tag;
int cmp (const char *a) const int cmp (const char *a) const
{ {
@ -246,6 +246,7 @@ hb_ot_tags_from_language (const char *lang_str,
hb_tag_t *tags) hb_tag_t *tags)
{ {
const char *s; const char *s;
unsigned int tag_idx;
/* Check for matches of multiple subtags. */ /* Check for matches of multiple subtags. */
if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags)) if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags))
@ -254,7 +255,6 @@ hb_ot_tags_from_language (const char *lang_str,
/* Find a language matching in the first component. */ /* Find a language matching in the first component. */
s = strchr (lang_str, '-'); s = strchr (lang_str, '-');
{ {
const LangTag *lang_tag;
if (s && limit - lang_str >= 6) if (s && limit - lang_str >= 6)
{ {
const char *extlang_end = strchr (s + 1, '-'); const char *extlang_end = strchr (s + 1, '-');
@ -263,12 +263,18 @@ hb_ot_tags_from_language (const char *lang_str,
ISALPHA (s[1])) ISALPHA (s[1]))
lang_str = s + 1; lang_str = s + 1;
} }
lang_tag = hb_sorted_array (ot_languages).bsearch (lang_str); if (hb_sorted_array (ot_languages).bfind (lang_str, &tag_idx))
if (lang_tag)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < *count && lang_tag->tags[i] != HB_TAG_NONE; i++) while (tag_idx != 0 &&
tags[i] = lang_tag->tags[i]; 0 == strcmp (ot_languages[tag_idx].language, ot_languages[tag_idx - 1].language))
tag_idx--;
for (i = 0;
i < *count &&
tag_idx + i < ARRAY_LENGTH (ot_languages) &&
0 == strcmp (ot_languages[tag_idx + i].language, ot_languages[tag_idx].language);
i++)
tags[i] = ot_languages[tag_idx + i].tag;
*count = i; *count = i;
return; return;
} }
@ -417,7 +423,7 @@ hb_ot_tag_to_language (hb_tag_t tag)
} }
for (i = 0; i < ARRAY_LENGTH (ot_languages); i++) for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
if (ot_languages[i].tags[0] == tag) if (ot_languages[i].tag == tag)
return hb_language_from_string (ot_languages[i].language, -1); return hb_language_from_string (ot_languages[i].language, -1);
/* Else return a custom language in the form of "x-hbotABCD" */ /* Else return a custom language in the form of "x-hbotABCD" */
@ -506,7 +512,7 @@ test_langs_sorted ()
for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages); i++) for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages); i++)
{ {
int c = ot_languages[i].cmp (&ot_languages[i - 1]); int c = ot_languages[i].cmp (&ot_languages[i - 1]);
if (c >= 0) if (c > 0)
{ {
fprintf (stderr, "ot_languages not sorted at index %d: %s %d %s\n", fprintf (stderr, "ot_languages not sorted at index %d: %s %d %s\n",
i, ot_languages[i-1].language, c, ot_languages[i].language); i, ot_languages[i-1].language, c, ot_languages[i].language);

View File

@ -49,7 +49,10 @@
#include "hb-ot-var-hvar-table.hh" #include "hb-ot-var-hvar-table.hh"
static unsigned int HB_UNUSED static inline unsigned int
_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
unsigned int table_len);
static inline unsigned int
_plan_estimate_subset_table_size (hb_subset_plan_t *plan, _plan_estimate_subset_table_size (hb_subset_plan_t *plan,
unsigned int table_len) unsigned int table_len)
{ {
@ -198,6 +201,8 @@ _subset_table (hb_subset_plan_t *plan,
case HB_OT_TAG_VORG: case HB_OT_TAG_VORG:
result = _subset<const OT::VORG> (plan); result = _subset<const OT::VORG> (plan);
break; break;
#if !defined(HB_NO_SUBSET_LAYOUT)
case HB_OT_TAG_GDEF: case HB_OT_TAG_GDEF:
result = _subset2<const OT::GDEF> (plan); result = _subset2<const OT::GDEF> (plan);
break; break;
@ -216,6 +221,7 @@ _subset_table (hb_subset_plan_t *plan,
case HB_OT_TAG_VVAR: case HB_OT_TAG_VVAR:
result = _subset2<const OT::VVAR> (plan); result = _subset2<const OT::VVAR> (plan);
break; break;
#endif
default: default:
hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
@ -241,11 +247,16 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */ case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */ case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
return plan->drop_hints; return plan->drop_hints;
// Drop Layout Tables if requested. // Drop Layout Tables if requested.
case HB_OT_TAG_GDEF: case HB_OT_TAG_GDEF:
case HB_OT_TAG_GPOS: case HB_OT_TAG_GPOS:
case HB_OT_TAG_GSUB: case HB_OT_TAG_GSUB:
#if defined(HB_NO_SUBSET_LAYOUT)
return true;
#endif
return plan->drop_layout; return plan->drop_layout;
// Drop these tables below by default, list pulled // Drop these tables below by default, list pulled
// from fontTools: // from fontTools:
case HB_TAG ('B', 'A', 'S', 'E'): case HB_TAG ('B', 'A', 'S', 'E'):

View File

@ -283,7 +283,7 @@ struct active_feature_t {
OPENTYPE_FEATURE_RECORD rec; OPENTYPE_FEATURE_RECORD rec;
unsigned int order; unsigned int order;
static int cmp (const void *pa, const void *pb) { HB_INTERNAL static int cmp (const void *pa, const void *pb) {
const active_feature_t *a = (const active_feature_t *) pa; const active_feature_t *a = (const active_feature_t *) pa;
const active_feature_t *b = (const active_feature_t *) pb; const active_feature_t *b = (const active_feature_t *) pb;
return a->rec.tagFeature < b->rec.tagFeature ? -1 : a->rec.tagFeature > b->rec.tagFeature ? 1 : return a->rec.tagFeature < b->rec.tagFeature ? -1 : a->rec.tagFeature > b->rec.tagFeature ? 1 :
@ -300,7 +300,7 @@ struct feature_event_t {
bool start; bool start;
active_feature_t feature; active_feature_t feature;
static int cmp (const void *pa, const void *pb) HB_INTERNAL static int cmp (const void *pa, const void *pb)
{ {
const feature_event_t *a = (const feature_event_t *) pa; const feature_event_t *a = (const feature_event_t *) pa;
const feature_event_t *b = (const feature_event_t *) pb; const feature_event_t *b = (const feature_event_t *) pb;

View File

@ -260,6 +260,13 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
# endif # endif
#endif #endif
/* https://github.com/harfbuzz/harfbuzz/issues/1651 */
#if defined(__clang__) && __clang_major__ < 10
#define static_const static
#else
#define static_const static const
#endif
#if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(__GNUC__) && (__GNUC__ >= 3)
#define HB_FUNC __PRETTY_FUNCTION__ #define HB_FUNC __PRETTY_FUNCTION__
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
@ -644,7 +651,7 @@ struct BEInt<Type, 4>
#include "hb-atomic.hh" // Requires: hb-meta #include "hb-atomic.hh" // Requires: hb-meta
#include "hb-null.hh" // Requires: hb-meta #include "hb-null.hh" // Requires: hb-meta
#include "hb-algs.hh" // Requires: hb-meta hb-null #include "hb-algs.hh" // Requires: hb-meta hb-null
#include "hb-iter.hh" // Requires: hb-meta #include "hb-iter.hh" // Requires: hb-algs hb-meta
#include "hb-debug.hh" // Requires: hb-algs hb-atomic #include "hb-debug.hh" // Requires: hb-algs hb-atomic
#include "hb-array.hh" // Requires: hb-algs hb-iter hb-null #include "hb-array.hh" // Requires: hb-algs hb-iter hb-null
#include "hb-vector.hh" // Requires: hb-array hb-null #include "hb-vector.hh" // Requires: hb-array hb-null

View File

@ -70,6 +70,9 @@ fails = 0
valgrind = None valgrind = None
if os.environ.get('RUN_VALGRIND', ''): if os.environ.get('RUN_VALGRIND', ''):
valgrind = which ('valgrind') valgrind = which ('valgrind')
if valgrind is None:
print ("""Valgrind requested but not found.""")
sys.exit (1)
parent_path = os.path.join (srcdir, "fonts") parent_path = os.path.join (srcdir, "fonts")
for file in os.listdir (parent_path): for file in os.listdir (parent_path):
@ -85,7 +88,7 @@ for file in os.listdir (parent_path):
failed = True failed = True
if valgrind: if valgrind:
text, returncode = cmd ([valgrind, '--error-exitcode=1', hb_shape_fuzzer, path]) text, returncode = cmd ([valgrind, '--error-exitcode=1', '--leak-check=full', hb_shape_fuzzer, path])
if returncode: if returncode:
print (text) print (text)
print ('failure on %s' % file) print ('failure on %s' % file)