Merge branch 'master' into var-subset
This commit is contained in:
commit
c87488b46d
|
@ -895,11 +895,18 @@ def language_name_intersection (a, b):
|
|||
def get_matching_language_name (intersection, candidates):
|
||||
return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c))))
|
||||
|
||||
def same_tag (bcp_47_tag, ot_tags):
|
||||
return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower ()
|
||||
|
||||
for language, tags in sorted (ot.from_bcp_47.items ()):
|
||||
if language == '' or '-' in language:
|
||||
continue
|
||||
commented_out = same_tag (language, tags)
|
||||
for i, tag in enumerate (tags, start=1):
|
||||
print (' {\"%s\",\t%s},\t/* ' % (language, hb_tag (tag)), end='')
|
||||
print ('%s{\"%s\",\t%s},' % ('/*' if commented_out else ' ', language, hb_tag (tag)), end='')
|
||||
if commented_out:
|
||||
print ('*/', end='')
|
||||
print ('\t/* ', end='')
|
||||
bcp_47_name = bcp_47.names.get (language, '')
|
||||
bcp_47_name_candidates = bcp_47_name.split ('\n')
|
||||
intersection = language_name_intersection (bcp_47_name, ot.names[tag])
|
||||
|
@ -1040,7 +1047,8 @@ print (' * @tag: A language tag.')
|
|||
print (' *')
|
||||
print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to')
|
||||
print (' * many language tags) and the best tag is not the alphabetically first, or if')
|
||||
print (' * the best tag consists of multiple subtags.')
|
||||
print (' * the best tag consists of multiple subtags, or if the best tag does not appear')
|
||||
print (' * in #ot_languages.')
|
||||
print (' *')
|
||||
print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,')
|
||||
print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.')
|
||||
|
@ -1091,7 +1099,8 @@ def verify_disambiguation_dict ():
|
|||
'%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag))
|
||||
elif ot_tag not in disambiguation:
|
||||
disambiguation[ot_tag] = macrolanguages[0]
|
||||
if disambiguation[ot_tag] == sorted (primary_tags)[0] and '-' not in disambiguation[ot_tag]:
|
||||
different_primary_tags = sorted (t for t in primary_tags if not same_tag (t, ot.from_bcp_47.get (t)))
|
||||
if different_primary_tags and disambiguation[ot_tag] == different_primary_tags[0] and '-' not in disambiguation[ot_tag]:
|
||||
del disambiguation[ot_tag]
|
||||
for ot_tag in disambiguation.keys ():
|
||||
expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag)
|
||||
|
|
106
src/hb-algs.hh
106
src/hb-algs.hh
|
@ -34,30 +34,6 @@
|
|||
#include "hb-null.hh"
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
/* Don't know how to set priority of following. Doesn't work right now. */
|
||||
//template <typename T>
|
||||
//uint32_t operator () (const T& v) const
|
||||
//{ return hb_deref_pointer (v).hash (); }
|
||||
/* Instead, the following ugly soution: */
|
||||
template <typename T,
|
||||
hb_enable_if (!hb_is_integer (hb_remove_const (hb_remove_reference (T))) && !hb_is_pointer (T))>
|
||||
uint32_t operator () (T&& v) const { return v.hash (); }
|
||||
|
||||
template <typename T>
|
||||
uint32_t operator () (const T *v) const
|
||||
{ return operator() (*v); }
|
||||
|
||||
template <typename T,
|
||||
hb_enable_if (hb_is_integer (T))>
|
||||
uint32_t operator () (T v) const
|
||||
{
|
||||
/* Knuth's multiplicative method: */
|
||||
return (uint32_t) v * 2654435761u;
|
||||
}
|
||||
} HB_FUNCOBJ (hb_hash);
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T> T
|
||||
|
@ -70,6 +46,25 @@ struct
|
|||
operator () (const T& v) const { return bool (v); }
|
||||
} HB_FUNCOBJ (hb_bool);
|
||||
|
||||
struct
|
||||
{
|
||||
private:
|
||||
template <typename T> auto
|
||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref_pointer (v).hash ())
|
||||
|
||||
template <typename T,
|
||||
hb_enable_if (hb_is_integer (T))> auto
|
||||
impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
|
||||
(
|
||||
/* Knuth's multiplicative method: */
|
||||
(uint32_t) v * 2654435761u
|
||||
)
|
||||
|
||||
public:
|
||||
|
||||
template <typename T> auto
|
||||
operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
|
||||
} HB_FUNCOBJ (hb_hash);
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -77,26 +72,24 @@ struct
|
|||
|
||||
/* 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 ())
|
||||
impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
|
||||
(hb_forward<Val> (hb_deref_pointer (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)
|
||||
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
|
||||
(hb_forward<Val> (hb_deref_pointer (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)))
|
||||
impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
|
||||
(hb_deref_pointer (a) (hb_forward<Val> (v)))
|
||||
|
||||
public:
|
||||
|
||||
template <typename Appl, typename Val> auto
|
||||
operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN_EXPR (
|
||||
operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN
|
||||
(
|
||||
impl (hb_forward<Appl> (a),
|
||||
hb_forward<Val> (v),
|
||||
hb_prioritize)
|
||||
|
@ -108,13 +101,12 @@ struct
|
|||
private:
|
||||
|
||||
template <typename Pred, typename Val> auto
|
||||
impl (Pred&& p, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (p->has (v))
|
||||
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
|
||||
(hb_deref_pointer (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 (
|
||||
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
|
||||
(
|
||||
hb_invoke (hb_forward<Pred> (p),
|
||||
hb_forward<Val> (v))
|
||||
)
|
||||
|
@ -122,10 +114,10 @@ struct
|
|||
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)
|
||||
operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
|
||||
impl (hb_forward<Pred> (p),
|
||||
hb_forward<Val> (v),
|
||||
hb_prioritize)
|
||||
)
|
||||
} HB_FUNCOBJ (hb_has);
|
||||
|
||||
|
@ -134,13 +126,12 @@ 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)))
|
||||
impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
|
||||
(hb_deref_pointer (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 (
|
||||
impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
|
||||
(
|
||||
hb_invoke (hb_forward<Proj> (f),
|
||||
hb_forward<Val> (v))
|
||||
)
|
||||
|
@ -148,7 +139,8 @@ struct
|
|||
public:
|
||||
|
||||
template <typename Proj, typename Val> auto
|
||||
operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR (
|
||||
operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
|
||||
(
|
||||
impl (hb_forward<Proj> (f),
|
||||
hb_forward<Val> (v),
|
||||
hb_prioritize)
|
||||
|
@ -176,25 +168,25 @@ hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
|
|||
|
||||
struct
|
||||
{
|
||||
template <typename Pair> decltype (hb_declval (Pair).first)
|
||||
operator () (const Pair& pair) const { return pair.first; }
|
||||
template <typename Pair> auto
|
||||
operator () (const Pair& pair) const HB_AUTO_RETURN (pair.first)
|
||||
} HB_FUNCOBJ (hb_first);
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename Pair> decltype (hb_declval (Pair).second)
|
||||
operator () (const Pair& pair) const { return pair.second; }
|
||||
template <typename Pair> auto
|
||||
operator () (const Pair& pair) const HB_AUTO_RETURN (pair.second)
|
||||
} HB_FUNCOBJ (hb_second);
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T, typename T2> T
|
||||
operator () (const T& a, const T2& b) const { return a <= b ? a : b; }
|
||||
template <typename T, typename T2> auto
|
||||
operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a <= b ? a : b)
|
||||
} HB_FUNCOBJ (hb_min);
|
||||
struct
|
||||
{
|
||||
template <typename T, typename T2> T
|
||||
operator () (const T& a, const T2& b) const { return a >= b ? a : b; }
|
||||
template <typename T, typename T2> auto
|
||||
operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a >= b ? a : b)
|
||||
} HB_FUNCOBJ (hb_max);
|
||||
|
||||
|
||||
|
|
|
@ -47,13 +47,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
|||
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))>
|
||||
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) {}
|
||||
|
||||
hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
|
||||
template <unsigned int length_> hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {}
|
||||
|
||||
template <typename U = Type, hb_enable_if (hb_is_const (U))>
|
||||
hb_array_t& operator = (const hb_array_t<hb_remove_const (Type)> &o)
|
||||
hb_array_t& operator = (const hb_array_t<hb_remove_const<Type> > &o)
|
||||
{ arrayZ = o.arrayZ; length = o.length; return *this; }
|
||||
hb_array_t& operator = (const hb_array_t &o)
|
||||
{ arrayZ = o.arrayZ; length = o.length; return *this; }
|
||||
|
@ -214,7 +214,7 @@ struct hb_sorted_array_t :
|
|||
hb_sorted_array_t () : hb_array_t<Type> () {}
|
||||
hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {}
|
||||
template <typename U = Type, hb_enable_if (hb_is_const (U))>
|
||||
hb_sorted_array_t (const hb_sorted_array_t<hb_remove_const (Type)> &o) : hb_array_t<Type> (o) {}
|
||||
hb_sorted_array_t (const hb_sorted_array_t<hb_remove_const<Type> > &o) : hb_array_t<Type> (o) {}
|
||||
hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
|
||||
template <unsigned int length_> hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
|
||||
|
||||
|
|
|
@ -283,7 +283,7 @@ struct hb_atomic_int_t
|
|||
template <typename P>
|
||||
struct hb_atomic_ptr_t
|
||||
{
|
||||
typedef hb_remove_pointer (P) T;
|
||||
typedef hb_remove_pointer<P> T;
|
||||
|
||||
void init (T* v_ = nullptr) { set_relaxed (v_); }
|
||||
void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
|
||||
|
|
|
@ -81,7 +81,7 @@ struct hb_blob_t
|
|||
template <typename P>
|
||||
struct hb_blob_ptr_t
|
||||
{
|
||||
typedef hb_remove_pointer (P) T;
|
||||
typedef hb_remove_pointer<P> T;
|
||||
|
||||
hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {}
|
||||
hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; }
|
||||
|
|
|
@ -488,7 +488,7 @@ hb_script_from_string (const char *str, int len)
|
|||
|
||||
/**
|
||||
* hb_script_to_iso15924_tag:
|
||||
* @script: an #hb_script_ to convert.
|
||||
* @script: an #hb_script_t to convert.
|
||||
*
|
||||
* See hb_script_from_iso15924_tag().
|
||||
*
|
||||
|
@ -783,7 +783,7 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv)
|
|||
static void free_static_C_locale ();
|
||||
#endif
|
||||
|
||||
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (HB_LOCALE_T),
|
||||
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
|
||||
hb_C_locale_lazy_loader_t>
|
||||
{
|
||||
static HB_LOCALE_T create ()
|
||||
|
|
|
@ -748,7 +748,7 @@ hb_ft_font_create_referenced (FT_Face ft_face)
|
|||
static void free_static_ft_library ();
|
||||
#endif
|
||||
|
||||
static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (FT_Library),
|
||||
static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<FT_Library>,
|
||||
hb_ft_library_lazy_loader_t>
|
||||
{
|
||||
static FT_Library create ()
|
||||
|
|
|
@ -78,7 +78,7 @@ struct hb_iter_t
|
|||
* it will be returning pointer to temporary rvalue. */
|
||||
template <typename T = item_t,
|
||||
hb_enable_if (hb_is_reference (T))>
|
||||
hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); }
|
||||
hb_remove_reference<item_t>* operator -> () const { return hb_addressof (**thiz()); }
|
||||
item_t operator * () const { return thiz()->__item__ (); }
|
||||
item_t operator * () { return thiz()->__item__ (); }
|
||||
item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); }
|
||||
|
@ -258,8 +258,8 @@ struct hb_is_iterator_of { enum {
|
|||
|
||||
template <typename Lhs, typename Rhs,
|
||||
hb_enable_if (hb_is_iterator (Lhs))>
|
||||
static inline decltype (hb_declval (Rhs) (hb_declval (Lhs)))
|
||||
operator | (Lhs lhs, const Rhs &rhs) { return rhs (lhs); }
|
||||
static inline auto
|
||||
operator | (Lhs lhs, const Rhs &rhs) HB_AUTO_RETURN (rhs (lhs))
|
||||
|
||||
/* hb_map(), hb_filter(), hb_reduce() */
|
||||
|
||||
|
|
|
@ -34,8 +34,37 @@
|
|||
* C++ template meta-programming & fundamentals used with them.
|
||||
*/
|
||||
|
||||
/* Void! For when we need a expression-type of void. */
|
||||
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;
|
||||
|
||||
template<typename Head, typename... Ts> struct _hb_head_tt { typedef Head type; };
|
||||
template<typename... Ts> using hb_head_tt = typename _hb_head_tt<Ts...>::type;
|
||||
|
||||
/* Bool! For when we need to evaluate type-dependent expressions
|
||||
* in a template argument. */
|
||||
template <bool b> struct hb_bool_tt { enum { value = b }; };
|
||||
typedef hb_bool_tt<true> hb_true_t;
|
||||
typedef hb_bool_tt<false> hb_false_t;
|
||||
|
||||
|
||||
/* Function overloading SFINAE and priority. */
|
||||
|
||||
#define HB_RETURN(Ret, E) -> hb_head_tt<Ret, decltype ((E))> { return (E); }
|
||||
#define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
|
||||
#define HB_VOID_RETURN(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> ()
|
||||
|
||||
#define HB_FUNCOBJ(x) static_const x HB_UNUSED
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T>
|
||||
|
@ -56,50 +85,38 @@ template <typename T> static inline T hb_declval ();
|
|||
|
||||
template <typename T> struct hb_match_const { typedef T type; enum { value = false }; };
|
||||
template <typename T> struct hb_match_const<const T> { typedef T type; enum { value = true }; };
|
||||
#define hb_remove_const(T) typename hb_match_const<T>::type
|
||||
template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
|
||||
#define hb_is_const(T) hb_match_const<T>::value
|
||||
template <typename T> struct hb_match_reference { typedef T type; enum { value = false }; };
|
||||
template <typename T> struct hb_match_reference<T &> { typedef T type; enum { value = true }; };
|
||||
#define hb_remove_reference(T) typename hb_match_reference<T>::type
|
||||
template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type;
|
||||
#define hb_is_reference(T) hb_match_reference<T>::value
|
||||
template <typename T> struct hb_match_pointer { typedef T type; enum { value = false }; };
|
||||
template <typename T> struct hb_match_pointer<T *> { typedef T type; enum { value = true }; };
|
||||
#define hb_remove_pointer(T) typename hb_match_pointer<T>::type
|
||||
template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
|
||||
#define hb_is_pointer(T) hb_match_pointer<T>::value
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T>
|
||||
T operator () (T v) const { return v; }
|
||||
template <typename T>
|
||||
T& operator () (T *v) const { return *v; }
|
||||
} HB_FUNCOBJ (hb_deref_pointer);
|
||||
|
||||
|
||||
/* std::move and std::forward */
|
||||
|
||||
template <typename T>
|
||||
static 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>
|
||||
static 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>
|
||||
static T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; }
|
||||
static T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T> auto
|
||||
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
|
||||
|
||||
/* Void! For when we need a expression-type of void. */
|
||||
struct hb_void_t { typedef void value; };
|
||||
template <typename T> auto
|
||||
operator () (T *v) const HB_AUTO_RETURN (*v)
|
||||
|
||||
/* 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;
|
||||
} HB_FUNCOBJ (hb_deref_pointer);
|
||||
|
||||
/* Bool! For when we need to evaluate type-dependent expressions
|
||||
* in a template argument. */
|
||||
template <bool b> struct hb_bool_tt { enum { value = b }; };
|
||||
typedef hb_bool_tt<true> hb_true_t;
|
||||
typedef hb_bool_tt<false> hb_false_t;
|
||||
|
||||
template<bool B, typename T = void> struct hb_enable_if {};
|
||||
template<typename T> struct hb_enable_if<true, T> { typedef T type; };
|
||||
|
@ -140,14 +157,5 @@ template <> struct hb_is_integer<signed 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
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -95,7 +95,7 @@ struct Null {
|
|||
template <typename QType>
|
||||
struct NullHelper
|
||||
{
|
||||
typedef hb_remove_const (hb_remove_reference (QType)) Type;
|
||||
typedef hb_remove_const<hb_remove_reference<QType> > Type;
|
||||
static const Type & get_null () { return Null<Type>::get_null (); }
|
||||
};
|
||||
#define Null(Type) NullHelper<Type>::get_null ()
|
||||
|
@ -148,7 +148,7 @@ static inline Type& Crap () {
|
|||
template <typename QType>
|
||||
struct CrapHelper
|
||||
{
|
||||
typedef hb_remove_const (hb_remove_reference (QType)) Type;
|
||||
typedef hb_remove_const<hb_remove_reference<QType> > Type;
|
||||
static Type & get_crap () { return Crap<Type> (); }
|
||||
};
|
||||
#define Crap(Type) CrapHelper<Type>::get_crap ()
|
||||
|
@ -171,7 +171,7 @@ struct CrapOrNullHelper<const Type> {
|
|||
template <typename P>
|
||||
struct hb_nonnull_ptr_t
|
||||
{
|
||||
typedef hb_remove_pointer (P) T;
|
||||
typedef hb_remove_pointer<P> T;
|
||||
|
||||
hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {}
|
||||
T * operator = (T *v_) { return v = v_; }
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -426,17 +426,30 @@ hb_ot_tag_to_language (hb_tag_t tag)
|
|||
if (ot_languages[i].tag == tag)
|
||||
return hb_language_from_string (ot_languages[i].language, -1);
|
||||
|
||||
/* Else return a custom language in the form of "x-hbotABCD" */
|
||||
/* If it's three letters long, assume it's ISO 639-3 and lower-case and use it
|
||||
* (if it's not a registered tag, calling hb_ot_tag_from_language on the
|
||||
* result might not return the same tag as the original tag).
|
||||
* Else return a custom language in the form of "x-hbotABCD". */
|
||||
{
|
||||
unsigned char buf[11] = "x-hbot";
|
||||
char buf[11] = "x-hbot";
|
||||
char *str = buf;
|
||||
buf[6] = tag >> 24;
|
||||
buf[7] = (tag >> 16) & 0xFF;
|
||||
buf[8] = (tag >> 8) & 0xFF;
|
||||
buf[9] = tag & 0xFF;
|
||||
if (buf[9] == 0x20)
|
||||
{
|
||||
buf[9] = '\0';
|
||||
if (ISALPHA (buf[6]) && ISALPHA (buf[7]) && ISALPHA (buf[8]))
|
||||
{
|
||||
buf[6] = TOLOWER (buf[6]);
|
||||
buf[7] = TOLOWER (buf[7]);
|
||||
buf[8] = TOLOWER (buf[8]);
|
||||
str += 6;
|
||||
}
|
||||
}
|
||||
buf[10] = '\0';
|
||||
return hb_language_from_string ((char *) buf, -1);
|
||||
return hb_language_from_string (str, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -281,6 +281,8 @@ test_ot_tag_language (void)
|
|||
g_assert_cmphex (HB_TAG_CHAR4 ("dflt"), ==, HB_OT_TAG_DEFAULT_LANGUAGE);
|
||||
test_language_two_way ("dflt", NULL);
|
||||
|
||||
test_language_two_way ("ALT", "alt");
|
||||
|
||||
test_language_two_way ("ARA", "ar");
|
||||
|
||||
test_language_two_way ("AZE", "az");
|
||||
|
@ -353,7 +355,8 @@ test_ot_tag_language (void)
|
|||
test_tag_from_language ("ZHS", "zh"); /* Chinese */
|
||||
test_tag_from_language ("ZHS", "zh-xx");
|
||||
|
||||
test_language_two_way ("ABC", "x-hbotabc");
|
||||
test_language_two_way ("ABC", "abc");
|
||||
test_language_two_way ("ABCD", "x-hbotabcd");
|
||||
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
|
||||
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc");
|
||||
test_tag_from_language ("ABCD", "asdf-asdf-wer-x-hbotabcd");
|
||||
|
|
Loading…
Reference in New Issue