Merge pull request #57563 from bruvzg/hb331
This commit is contained in:
commit
5f3f0b5e00
@ -62,7 +62,6 @@ if env["builtin_harfbuzz"]:
|
||||
#'src/hb-gobject-structs.cc',
|
||||
"src/hb-icu.cc",
|
||||
"src/hb-map.cc",
|
||||
"src/hb-ms-feature-ranges.cc",
|
||||
"src/hb-number.cc",
|
||||
"src/hb-ot-cff1-table.cc",
|
||||
"src/hb-ot-cff2-table.cc",
|
||||
|
2
thirdparty/README.md
vendored
2
thirdparty/README.md
vendored
@ -206,7 +206,7 @@ Files extracted from upstream source:
|
||||
## harfbuzz
|
||||
|
||||
- Upstream: https://github.com/harfbuzz/harfbuzz
|
||||
- Version: 3.2.0 (be91d2917d9860326cb5fd1d03ffe1042a72f6d3, 2021)
|
||||
- Version: 3.3.1 (45df259538c204540819d74456d30ffb40df488a, 2022)
|
||||
- License: MIT
|
||||
|
||||
Files extracted from upstream source:
|
||||
|
@ -839,7 +839,7 @@ struct StateTableDriver
|
||||
}
|
||||
|
||||
if (!c->in_place)
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -146,7 +146,7 @@ struct DuctileGlyphAction
|
||||
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
|
||||
* This would normally be 0x64756374 ('duct'),
|
||||
* but you may use any axis the font contains. */
|
||||
HBFixed minimumLimit; /* The lowest value for the ductility axis tha
|
||||
HBFixed minimumLimit; /* The lowest value for the ductility axis that
|
||||
* still yields an acceptable appearance. Normally
|
||||
* this will be 1.0. */
|
||||
HBFixed noStretchValue; /* This is the default value that corresponds to
|
||||
|
32
thirdparty/harfbuzz/src/hb-algs.hh
vendored
32
thirdparty/harfbuzz/src/hb-algs.hh
vendored
@ -36,6 +36,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
#include <functional>
|
||||
#include <new>
|
||||
|
||||
/*
|
||||
@ -210,12 +211,23 @@ struct
|
||||
}
|
||||
HB_FUNCOBJ (hb_bool);
|
||||
|
||||
template <typename T>
|
||||
static inline
|
||||
T hb_coerce (const T v) { return v; }
|
||||
template <typename T, typename V,
|
||||
hb_enable_if (!hb_is_same (hb_decay<T>, hb_decay<V>) && std::is_pointer<V>::value)>
|
||||
static inline
|
||||
T hb_coerce (const V v) { return *v; }
|
||||
|
||||
struct
|
||||
{
|
||||
private:
|
||||
|
||||
template <typename T> constexpr auto
|
||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
|
||||
impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
|
||||
|
||||
template <typename T> constexpr auto
|
||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
|
||||
|
||||
template <typename T,
|
||||
hb_enable_if (std::is_integral<T>::value)> constexpr auto
|
||||
@ -435,23 +447,29 @@ struct
|
||||
private:
|
||||
|
||||
template <typename T1, typename T2> auto
|
||||
impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
|
||||
impl (T1&& v1, T2 &&v2, hb_priority<3>) const HB_AUTO_RETURN
|
||||
(
|
||||
std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0
|
||||
)
|
||||
|
||||
template <typename T1, typename T2> auto
|
||||
impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
|
||||
impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
|
||||
(
|
||||
std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0
|
||||
)
|
||||
|
||||
template <typename T1, typename T2> auto
|
||||
impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
|
||||
impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
|
||||
(
|
||||
std::forward<T1> (v1) == std::forward<T2> (v2)
|
||||
)
|
||||
|
||||
template <typename T1, typename T2> auto
|
||||
impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
|
||||
(
|
||||
std::forward<T2> (v2) == std::forward<T1> (v1)
|
||||
)
|
||||
|
||||
public:
|
||||
|
||||
template <typename T1, typename T2> auto
|
||||
@ -472,6 +490,10 @@ struct hb_pair_t
|
||||
typedef T2 second_t;
|
||||
typedef hb_pair_t<T1, T2> pair_t;
|
||||
|
||||
template <typename U1 = T1, typename U2 = T2,
|
||||
hb_enable_if (std::is_default_constructible<U1>::value &&
|
||||
std::is_default_constructible<U2>::value)>
|
||||
hb_pair_t () : first (), second () {}
|
||||
hb_pair_t (T1 a, T2 b) : first (a), second (b) {}
|
||||
|
||||
template <typename Q1, typename Q2,
|
||||
@ -870,7 +892,7 @@ hb_bsearch_impl (unsigned *pos, /* Out */
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
V* p = (V*) (((const char *) base) + (mid * stride));
|
||||
#pragma GCC diagnostic pop
|
||||
int c = compar ((const void *) hb_addressof (key), (const void *) p, ds...);
|
||||
int c = compar ((const void *) std::addressof (key), (const void *) p, ds...);
|
||||
if (c < 0)
|
||||
max = mid - 1;
|
||||
else if (c > 0)
|
||||
|
2
thirdparty/harfbuzz/src/hb-array.hh
vendored
2
thirdparty/harfbuzz/src/hb-array.hh
vendored
@ -412,7 +412,7 @@ bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
|
||||
return true;
|
||||
}
|
||||
|
||||
/* TODO Specialize opeator== for hb_bytes_t and hb_ubytes_t. */
|
||||
/* TODO Specialize operator== for hb_bytes_t and hb_ubytes_t. */
|
||||
|
||||
template <>
|
||||
inline uint32_t hb_array_t<const char>::hash () const {
|
||||
|
14
thirdparty/harfbuzz/src/hb-bimap.hh
vendored
14
thirdparty/harfbuzz/src/hb-bimap.hh
vendored
@ -33,20 +33,6 @@
|
||||
/* Bi-directional map */
|
||||
struct hb_bimap_t
|
||||
{
|
||||
/* XXX(remove) */
|
||||
void init ()
|
||||
{
|
||||
forw_map.init ();
|
||||
back_map.init ();
|
||||
}
|
||||
|
||||
/* XXX(remove) */
|
||||
void fini ()
|
||||
{
|
||||
forw_map.fini ();
|
||||
back_map.fini ();
|
||||
}
|
||||
|
||||
void reset ()
|
||||
{
|
||||
forw_map.reset ();
|
||||
|
185
thirdparty/harfbuzz/src/hb-buffer.cc
vendored
185
thirdparty/harfbuzz/src/hb-buffer.cc
vendored
@ -86,7 +86,46 @@ hb_segment_properties_hash (const hb_segment_properties_t *p)
|
||||
(intptr_t) (p->language);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_segment_properties_overlay:
|
||||
* @p: #hb_segment_properties_t to fill in.
|
||||
* @src: #hb_segment_properties_t to fill in from.
|
||||
*
|
||||
* Fills in missing fields of @p from @src in a considered manner.
|
||||
*
|
||||
* First, if @p does not have direction set, direction is copied from @src.
|
||||
*
|
||||
* Next, if @p and @src have the same direction (which can be unset), if @p
|
||||
* does not have script set, script is copied from @src.
|
||||
*
|
||||
* Finally, if @p and @src have the same direction and script (which either
|
||||
* can be unset), if @p does not have language set, language is copied from
|
||||
* @src.
|
||||
*
|
||||
* Since: 3.3.0
|
||||
**/
|
||||
void
|
||||
hb_segment_properties_overlay (hb_segment_properties_t *p,
|
||||
const hb_segment_properties_t *src)
|
||||
{
|
||||
if (unlikely (!p || !src))
|
||||
return;
|
||||
|
||||
if (!p->direction)
|
||||
p->direction = src->direction;
|
||||
|
||||
if (p->direction != src->direction)
|
||||
return;
|
||||
|
||||
if (!p->script)
|
||||
p->script = src->script;
|
||||
|
||||
if (p->script != src->script)
|
||||
return;
|
||||
|
||||
if (!p->language)
|
||||
p->language = src->language;
|
||||
}
|
||||
|
||||
/* Here is how the buffer works internally:
|
||||
*
|
||||
@ -96,14 +135,14 @@ hb_segment_properties_hash (const hb_segment_properties_t *p)
|
||||
* As an optimization, both info and out_info may point to the
|
||||
* same piece of memory, which is owned by info. This remains the
|
||||
* case as long as out_len doesn't exceed i at any time.
|
||||
* In that case, swap_buffers() is mostly no-op and the glyph operations
|
||||
* In that case, sync() is mostly no-op and the glyph operations
|
||||
* operate mostly in-place.
|
||||
*
|
||||
* As soon as out_info gets longer than info, out_info is moved over
|
||||
* to an alternate buffer (which we reuse the pos buffer for), and its
|
||||
* current contents (out_len entries) are copied to the new place.
|
||||
*
|
||||
* This should all remain transparent to the user. swap_buffers() then
|
||||
* This should all remain transparent to the user. sync() then
|
||||
* switches info over to out_info and does housekeeping.
|
||||
*/
|
||||
|
||||
@ -216,12 +255,25 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
|
||||
|
||||
/* HarfBuzz-Internal API */
|
||||
|
||||
void
|
||||
hb_buffer_t::similar (const hb_buffer_t &src)
|
||||
{
|
||||
hb_unicode_funcs_destroy (unicode);
|
||||
unicode = hb_unicode_funcs_reference (src.unicode);
|
||||
flags = src.flags;
|
||||
cluster_level = src.cluster_level;
|
||||
replacement = src.invisible;
|
||||
invisible = src.invisible;
|
||||
not_found = src.not_found;
|
||||
}
|
||||
|
||||
void
|
||||
hb_buffer_t::reset ()
|
||||
{
|
||||
hb_unicode_funcs_destroy (unicode);
|
||||
unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ());
|
||||
flags = HB_BUFFER_FLAG_DEFAULT;
|
||||
cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT;
|
||||
replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
|
||||
invisible = 0;
|
||||
not_found = 0;
|
||||
@ -232,11 +284,10 @@ hb_buffer_t::reset ()
|
||||
void
|
||||
hb_buffer_t::clear ()
|
||||
{
|
||||
content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
|
||||
hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
|
||||
props = default_props;
|
||||
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
|
||||
|
||||
content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
|
||||
successful = true;
|
||||
have_output = false;
|
||||
have_positions = false;
|
||||
@ -244,16 +295,44 @@ hb_buffer_t::clear ()
|
||||
idx = 0;
|
||||
len = 0;
|
||||
out_len = 0;
|
||||
out_info = info;
|
||||
|
||||
serial = 0;
|
||||
out_info = info;
|
||||
|
||||
memset (context, 0, sizeof context);
|
||||
memset (context_len, 0, sizeof context_len);
|
||||
|
||||
deallocate_var_all ();
|
||||
serial = 0;
|
||||
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
|
||||
}
|
||||
|
||||
void
|
||||
hb_buffer_t::enter ()
|
||||
{
|
||||
deallocate_var_all ();
|
||||
serial = 0;
|
||||
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
|
||||
if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR)))
|
||||
{
|
||||
max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR,
|
||||
(unsigned) HB_BUFFER_MAX_LEN_MIN);
|
||||
}
|
||||
if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR)))
|
||||
{
|
||||
max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR,
|
||||
(unsigned) HB_BUFFER_MAX_OPS_MIN);
|
||||
}
|
||||
}
|
||||
void
|
||||
hb_buffer_t::leave ()
|
||||
{
|
||||
max_len = HB_BUFFER_MAX_LEN_DEFAULT;
|
||||
max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
|
||||
deallocate_var_all ();
|
||||
serial = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb_buffer_t::add (hb_codepoint_t codepoint,
|
||||
unsigned int cluster)
|
||||
@ -307,7 +386,7 @@ hb_buffer_t::clear_positions ()
|
||||
}
|
||||
|
||||
void
|
||||
hb_buffer_t::swap_buffers ()
|
||||
hb_buffer_t::sync ()
|
||||
{
|
||||
assert (have_output);
|
||||
|
||||
@ -493,33 +572,6 @@ done:
|
||||
skip_glyph ();
|
||||
}
|
||||
|
||||
void
|
||||
hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
|
||||
{
|
||||
unsigned int cluster = UINT_MAX;
|
||||
cluster = _infos_find_min_cluster (info, start, end, cluster);
|
||||
_unsafe_to_break_set_mask (info, start, end, cluster);
|
||||
}
|
||||
void
|
||||
hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end)
|
||||
{
|
||||
if (!have_output)
|
||||
{
|
||||
unsafe_to_break_impl (start, end);
|
||||
return;
|
||||
}
|
||||
|
||||
assert (start <= out_len);
|
||||
assert (idx <= end);
|
||||
|
||||
unsigned int cluster = UINT_MAX;
|
||||
cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
|
||||
cluster = _infos_find_min_cluster (info, idx, end, cluster);
|
||||
|
||||
_unsafe_to_break_set_mask (out_info, start, out_len, cluster);
|
||||
_unsafe_to_break_set_mask (info, idx, end, cluster);
|
||||
}
|
||||
|
||||
void
|
||||
hb_buffer_t::guess_segment_properties ()
|
||||
{
|
||||
@ -565,12 +617,11 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) =
|
||||
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
|
||||
0, /* invisible */
|
||||
0, /* not_found */
|
||||
HB_BUFFER_SCRATCH_FLAG_DEFAULT,
|
||||
HB_BUFFER_MAX_LEN_DEFAULT,
|
||||
HB_BUFFER_MAX_OPS_DEFAULT,
|
||||
|
||||
|
||||
HB_BUFFER_CONTENT_TYPE_INVALID,
|
||||
HB_SEGMENT_PROPERTIES_DEFAULT,
|
||||
|
||||
false, /* successful */
|
||||
false, /* have_output */
|
||||
true /* have_positions */
|
||||
@ -609,6 +660,46 @@ hb_buffer_create ()
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_buffer_create_similar:
|
||||
* @src: An #hb_buffer_t
|
||||
*
|
||||
* Creates a new #hb_buffer_t, similar to hb_buffer_create(). The only
|
||||
* difference is that the buffer is configured similarly to @src.
|
||||
*
|
||||
* Return value: (transfer full):
|
||||
* A newly allocated #hb_buffer_t, similar to hb_buffer_create().
|
||||
*
|
||||
* Since: 3.3.0
|
||||
**/
|
||||
hb_buffer_t *
|
||||
hb_buffer_create_similar (const hb_buffer_t *src)
|
||||
{
|
||||
hb_buffer_t *buffer = hb_buffer_create ();
|
||||
|
||||
buffer->similar (*src);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_buffer_reset:
|
||||
* @buffer: An #hb_buffer_t
|
||||
*
|
||||
* Resets the buffer to its initial status, as if it was just newly created
|
||||
* with hb_buffer_create().
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_buffer_reset (hb_buffer_t *buffer)
|
||||
{
|
||||
if (unlikely (hb_object_is_immutable (buffer)))
|
||||
return;
|
||||
|
||||
buffer->reset ();
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_buffer_get_empty:
|
||||
*
|
||||
@ -1156,24 +1247,6 @@ hb_buffer_get_not_found_glyph (hb_buffer_t *buffer)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_buffer_reset:
|
||||
* @buffer: An #hb_buffer_t
|
||||
*
|
||||
* Resets the buffer to its initial status, as if it was just newly created
|
||||
* with hb_buffer_create().
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_buffer_reset (hb_buffer_t *buffer)
|
||||
{
|
||||
if (unlikely (hb_object_is_immutable (buffer)))
|
||||
return;
|
||||
|
||||
buffer->reset ();
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_buffer_clear_contents:
|
||||
* @buffer: An #hb_buffer_t
|
||||
@ -1749,6 +1822,8 @@ hb_buffer_append (hb_buffer_t *buffer,
|
||||
if (!buffer->have_positions && source->have_positions)
|
||||
buffer->clear_positions ();
|
||||
|
||||
hb_segment_properties_overlay (&buffer->props, &source->props);
|
||||
|
||||
memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
|
||||
if (buffer->have_positions)
|
||||
memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
|
||||
|
92
thirdparty/harfbuzz/src/hb-buffer.h
vendored
92
thirdparty/harfbuzz/src/hb-buffer.h
vendored
@ -76,18 +76,68 @@ typedef struct hb_glyph_info_t {
|
||||
* @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the
|
||||
* beginning of the cluster this glyph is part of,
|
||||
* then both sides need to be re-shaped, as the
|
||||
* result might be different. On the flip side,
|
||||
* it means that when this flag is not present,
|
||||
* then it's safe to break the glyph-run at the
|
||||
* beginning of this cluster, and the two sides
|
||||
* represent the exact same result one would get
|
||||
* if breaking input text at the beginning of
|
||||
* this cluster and shaping the two sides
|
||||
* separately. This can be used to optimize
|
||||
* paragraph layout, by avoiding re-shaping
|
||||
* of each line after line-breaking, or limiting
|
||||
* the reshaping to a small piece around the
|
||||
* breaking point only.
|
||||
* result might be different.
|
||||
* On the flip side, it means that when this
|
||||
* flag is not present, then it is safe to break
|
||||
* the glyph-run at the beginning of this
|
||||
* cluster, and the two sides will represent the
|
||||
* exact same result one would get if breaking
|
||||
* input text at the beginning of this cluster
|
||||
* and shaping the two sides separately.
|
||||
* This can be used to optimize paragraph
|
||||
* layout, by avoiding re-shaping of each line
|
||||
* after line-breaking.
|
||||
* @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT: Indicates that if input text is changed on one
|
||||
* side of the beginning of the cluster this glyph
|
||||
* is part of, then the shaping results for the
|
||||
* other side might change.
|
||||
* Note that the absence of this flag will NOT by
|
||||
* itself mean that it IS safe to concat text.
|
||||
* Only two pieces of text both of which clear of
|
||||
* this flag can be concatenated safely.
|
||||
* This can be used to optimize paragraph
|
||||
* layout, by avoiding re-shaping of each line
|
||||
* after line-breaking, by limiting the
|
||||
* reshaping to a small piece around the
|
||||
* breaking positin only, even if the breaking
|
||||
* position carries the
|
||||
* #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when
|
||||
* hyphenation or other text transformation
|
||||
* happens at line-break position, in the following
|
||||
* way:
|
||||
* 1. Iterate back from the line-break position
|
||||
* until the first cluster start position that is
|
||||
* NOT unsafe-to-concat, 2. shape the segment from
|
||||
* there till the end of line, 3. check whether the
|
||||
* resulting glyph-run also is clear of the
|
||||
* unsafe-to-concat at its start-of-text position;
|
||||
* if it is, just splice it into place and the line
|
||||
* is shaped; If not, move on to a position further
|
||||
* back that is clear of unsafe-to-concat and retry
|
||||
* from there, and repeat.
|
||||
* At the start of next line a similar algorithm can
|
||||
* be implemented. That is: 1. Iterate forward from
|
||||
* the line-break position untill the first cluster
|
||||
* start position that is NOT unsafe-to-concat, 2.
|
||||
* shape the segment from beginning of the line to
|
||||
* that position, 3. check whether the resulting
|
||||
* glyph-run also is clear of the unsafe-to-concat
|
||||
* at its end-of-text position; if it is, just splice
|
||||
* it into place and the beginning is shaped; If not,
|
||||
* move on to a position further forward that is clear
|
||||
* of unsafe-to-concat and retry up to there, and repeat.
|
||||
* A slight complication will arise in the
|
||||
* implementation of the algorithm above,
|
||||
* because while our buffer API has a way to
|
||||
* return flags for position corresponding to
|
||||
* start-of-text, there is currently no position
|
||||
* corresponding to end-of-text. This limitation
|
||||
* can be alleviated by shaping more text than needed
|
||||
* and looking for unsafe-to-concat flag within text
|
||||
* clusters.
|
||||
* The #HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag will
|
||||
* always imply this flag.
|
||||
* Since: 3.3.0
|
||||
* @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
|
||||
*
|
||||
* Flags for #hb_glyph_info_t.
|
||||
@ -96,8 +146,9 @@ typedef struct hb_glyph_info_t {
|
||||
*/
|
||||
typedef enum { /*< flags >*/
|
||||
HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001,
|
||||
HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002,
|
||||
|
||||
HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */
|
||||
HB_GLYPH_FLAG_DEFINED = 0x00000003 /* OR of all defined flags */
|
||||
} hb_glyph_flags_t;
|
||||
|
||||
HB_EXTERN hb_glyph_flags_t
|
||||
@ -170,6 +221,9 @@ hb_segment_properties_equal (const hb_segment_properties_t *a,
|
||||
HB_EXTERN unsigned int
|
||||
hb_segment_properties_hash (const hb_segment_properties_t *p);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_segment_properties_overlay (hb_segment_properties_t *p,
|
||||
const hb_segment_properties_t *src);
|
||||
|
||||
|
||||
/**
|
||||
@ -184,6 +238,13 @@ typedef struct hb_buffer_t hb_buffer_t;
|
||||
HB_EXTERN hb_buffer_t *
|
||||
hb_buffer_create (void);
|
||||
|
||||
HB_EXTERN hb_buffer_t *
|
||||
hb_buffer_create_similar (const hb_buffer_t *src);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_reset (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
HB_EXTERN hb_buffer_t *
|
||||
hb_buffer_get_empty (void);
|
||||
|
||||
@ -391,8 +452,9 @@ HB_EXTERN hb_codepoint_t
|
||||
hb_buffer_get_not_found_glyph (hb_buffer_t *buffer);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_reset (hb_buffer_t *buffer);
|
||||
/*
|
||||
* Content API.
|
||||
*/
|
||||
|
||||
HB_EXTERN void
|
||||
hb_buffer_clear_contents (hb_buffer_t *buffer);
|
||||
|
167
thirdparty/harfbuzz/src/hb-buffer.hh
vendored
167
thirdparty/harfbuzz/src/hb-buffer.hh
vendored
@ -67,8 +67,8 @@ enum hb_buffer_scratch_flags_t {
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000020u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u,
|
||||
|
||||
/* Reserved for complex shapers' internal use. */
|
||||
HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
|
||||
@ -87,18 +87,21 @@ struct hb_buffer_t
|
||||
{
|
||||
hb_object_header_t header;
|
||||
|
||||
/* Information about how the text in the buffer should be treated */
|
||||
/*
|
||||
* Information about how the text in the buffer should be treated.
|
||||
*/
|
||||
|
||||
hb_unicode_funcs_t *unicode; /* Unicode functions */
|
||||
hb_buffer_flags_t flags; /* BOT / EOT / etc. */
|
||||
hb_buffer_cluster_level_t cluster_level;
|
||||
hb_codepoint_t replacement; /* U+FFFD or something else. */
|
||||
hb_codepoint_t invisible; /* 0 or something else. */
|
||||
hb_codepoint_t not_found; /* 0 or something else. */
|
||||
hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
|
||||
unsigned int max_len; /* Maximum allowed len. */
|
||||
int max_ops; /* Maximum allowed operations. */
|
||||
|
||||
/* Buffer contents */
|
||||
/*
|
||||
* Buffer contents
|
||||
*/
|
||||
|
||||
hb_buffer_content_type_t content_type;
|
||||
hb_segment_properties_t props; /* Script, language, direction */
|
||||
|
||||
@ -115,8 +118,6 @@ struct hb_buffer_t
|
||||
hb_glyph_info_t *out_info;
|
||||
hb_glyph_position_t *pos;
|
||||
|
||||
unsigned int serial;
|
||||
|
||||
/* Text before / after the main buffer contents.
|
||||
* Always in Unicode, and ordered outward.
|
||||
* Index 0 is for "pre-context", 1 for "post-context". */
|
||||
@ -124,7 +125,25 @@ struct hb_buffer_t
|
||||
hb_codepoint_t context[2][CONTEXT_LENGTH];
|
||||
unsigned int context_len[2];
|
||||
|
||||
/* Debugging API */
|
||||
|
||||
/*
|
||||
* Managed by enter / leave
|
||||
*/
|
||||
|
||||
#ifndef HB_NDEBUG
|
||||
uint8_t allocated_var_bits;
|
||||
#endif
|
||||
uint8_t serial;
|
||||
hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
|
||||
unsigned int max_len; /* Maximum allowed len. */
|
||||
int max_ops; /* Maximum allowed operations. */
|
||||
/* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
|
||||
|
||||
|
||||
/*
|
||||
* Messaging callback
|
||||
*/
|
||||
|
||||
#ifndef HB_NO_BUFFER_MESSAGE
|
||||
hb_buffer_message_func_t message_func;
|
||||
void *message_data;
|
||||
@ -134,11 +153,6 @@ struct hb_buffer_t
|
||||
static constexpr unsigned message_depth = 0u;
|
||||
#endif
|
||||
|
||||
/* Internal debugging. */
|
||||
/* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
|
||||
#ifndef HB_NDEBUG
|
||||
uint8_t allocated_var_bits;
|
||||
#endif
|
||||
|
||||
|
||||
/* Methods */
|
||||
@ -190,12 +204,17 @@ struct hb_buffer_t
|
||||
hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; }
|
||||
hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
|
||||
|
||||
HB_INTERNAL void similar (const hb_buffer_t &src);
|
||||
HB_INTERNAL void reset ();
|
||||
HB_INTERNAL void clear ();
|
||||
|
||||
/* Called around shape() */
|
||||
HB_INTERNAL void enter ();
|
||||
HB_INTERNAL void leave ();
|
||||
|
||||
unsigned int backtrack_len () const { return have_output ? out_len : idx; }
|
||||
unsigned int lookahead_len () const { return len - idx; }
|
||||
unsigned int next_serial () { return serial++; }
|
||||
uint8_t next_serial () { return ++serial ? serial : ++serial; }
|
||||
|
||||
HB_INTERNAL void add (hb_codepoint_t codepoint,
|
||||
unsigned int cluster);
|
||||
@ -252,7 +271,7 @@ struct hb_buffer_t
|
||||
|
||||
HB_INTERNAL void guess_segment_properties ();
|
||||
|
||||
HB_INTERNAL void swap_buffers ();
|
||||
HB_INTERNAL void sync ();
|
||||
HB_INTERNAL void clear_output ();
|
||||
HB_INTERNAL void clear_positions ();
|
||||
|
||||
@ -366,15 +385,80 @@ struct hb_buffer_t
|
||||
/* Merge clusters for deleting current glyph, and skip it. */
|
||||
HB_INTERNAL void delete_glyph ();
|
||||
|
||||
void unsafe_to_break (unsigned int start,
|
||||
unsigned int end)
|
||||
|
||||
void set_glyph_flags (hb_mask_t mask,
|
||||
unsigned start = 0,
|
||||
unsigned end = (unsigned) -1,
|
||||
bool interior = false,
|
||||
bool from_out_buffer = false)
|
||||
{
|
||||
if (end - start < 2)
|
||||
end = hb_min (end, len);
|
||||
|
||||
if (interior && !from_out_buffer && end - start < 2)
|
||||
return;
|
||||
unsafe_to_break_impl (start, end);
|
||||
|
||||
scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
|
||||
|
||||
if (!from_out_buffer || !have_output)
|
||||
{
|
||||
if (!interior)
|
||||
{
|
||||
for (unsigned i = start; i < end; i++)
|
||||
info[i].mask |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned cluster = _infos_find_min_cluster (info, start, end);
|
||||
_infos_set_glyph_flags (info, start, end, cluster, mask);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (start <= out_len);
|
||||
assert (idx <= end);
|
||||
|
||||
if (!interior)
|
||||
{
|
||||
for (unsigned i = start; i < out_len; i++)
|
||||
out_info[i].mask |= mask;
|
||||
for (unsigned i = idx; i < end; i++)
|
||||
info[i].mask |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned cluster = _infos_find_min_cluster (info, idx, end);
|
||||
cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
|
||||
|
||||
_infos_set_glyph_flags (out_info, start, out_len, cluster, mask);
|
||||
_infos_set_glyph_flags (info, idx, end, cluster, mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unsafe_to_break (unsigned int start = 0, unsigned int end = -1)
|
||||
{
|
||||
set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
|
||||
start, end,
|
||||
true);
|
||||
}
|
||||
void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
|
||||
{
|
||||
set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
|
||||
start, end,
|
||||
true);
|
||||
}
|
||||
void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
|
||||
{
|
||||
set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
|
||||
start, end,
|
||||
true, true);
|
||||
}
|
||||
void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
|
||||
{
|
||||
set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
|
||||
start, end,
|
||||
false, true);
|
||||
}
|
||||
HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end);
|
||||
HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end);
|
||||
|
||||
|
||||
/* Internal methods */
|
||||
@ -465,36 +549,31 @@ struct hb_buffer_t
|
||||
set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
|
||||
{
|
||||
if (inf.cluster != cluster)
|
||||
{
|
||||
if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
|
||||
inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
|
||||
else
|
||||
inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
|
||||
}
|
||||
inf.mask = (inf.mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
|
||||
inf.cluster = cluster;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
_infos_find_min_cluster (const hb_glyph_info_t *infos,
|
||||
unsigned start, unsigned end,
|
||||
unsigned cluster)
|
||||
{
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
cluster = hb_min (cluster, infos[i].cluster);
|
||||
return cluster;
|
||||
}
|
||||
void
|
||||
_unsafe_to_break_set_mask (hb_glyph_info_t *infos,
|
||||
unsigned int start, unsigned int end,
|
||||
unsigned int cluster)
|
||||
_infos_set_glyph_flags (hb_glyph_info_t *infos,
|
||||
unsigned int start, unsigned int end,
|
||||
unsigned int cluster,
|
||||
hb_mask_t mask)
|
||||
{
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
if (cluster != infos[i].cluster)
|
||||
{
|
||||
scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
|
||||
infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
|
||||
scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
|
||||
infos[i].mask |= mask;
|
||||
}
|
||||
}
|
||||
static unsigned
|
||||
_infos_find_min_cluster (const hb_glyph_info_t *infos,
|
||||
unsigned start, unsigned end,
|
||||
unsigned cluster = UINT_MAX)
|
||||
{
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
cluster = hb_min (cluster, infos[i].cluster);
|
||||
return cluster;
|
||||
}
|
||||
|
||||
void clear_glyph_flags (hb_mask_t mask = 0)
|
||||
{
|
||||
|
14
thirdparty/harfbuzz/src/hb-cff-interp-common.hh
vendored
14
thirdparty/harfbuzz/src/hb-cff-interp-common.hh
vendored
@ -217,9 +217,6 @@ inline unsigned int OpCode_Size (op_code_t op) { return Is_OpCode_ESC (op) ? 2:
|
||||
|
||||
struct number_t
|
||||
{
|
||||
void init () { set_real (0.0); }
|
||||
void fini () {}
|
||||
|
||||
void set_int (int v) { value = v; }
|
||||
int to_int () const { return value; }
|
||||
|
||||
@ -245,7 +242,7 @@ struct number_t
|
||||
}
|
||||
|
||||
protected:
|
||||
double value;
|
||||
double value = 0.;
|
||||
};
|
||||
|
||||
/* byte string */
|
||||
@ -380,10 +377,8 @@ struct cff_stack_t
|
||||
count = 0;
|
||||
elements.init ();
|
||||
elements.resize (kSizeLimit);
|
||||
for (unsigned int i = 0; i < elements.length; i++)
|
||||
elements[i].init ();
|
||||
}
|
||||
void fini () { elements.fini_deep (); }
|
||||
void fini () { elements.fini (); }
|
||||
|
||||
ELEM& operator [] (unsigned int i)
|
||||
{
|
||||
@ -523,9 +518,6 @@ struct arg_stack_t : cff_stack_t<ARG, 513>
|
||||
/* an operator prefixed by its operands in a byte string */
|
||||
struct op_str_t
|
||||
{
|
||||
void init () {}
|
||||
void fini () {}
|
||||
|
||||
op_code_t op;
|
||||
byte_str_t str;
|
||||
};
|
||||
@ -553,7 +545,7 @@ struct parsed_values_t
|
||||
opStart = 0;
|
||||
values.init ();
|
||||
}
|
||||
void fini () { values.fini_deep (); }
|
||||
void fini () { values.fini (); }
|
||||
|
||||
void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t ())
|
||||
{
|
||||
|
@ -94,12 +94,6 @@ struct biased_subrs_t
|
||||
|
||||
struct point_t
|
||||
{
|
||||
void init ()
|
||||
{
|
||||
x.init ();
|
||||
y.init ();
|
||||
}
|
||||
|
||||
void set_int (int _x, int _y)
|
||||
{
|
||||
x.set_int (_x);
|
||||
@ -128,7 +122,7 @@ struct cs_interp_env_t : interp_env_t<ARG>
|
||||
hstem_count = 0;
|
||||
vstem_count = 0;
|
||||
hintmask_size = 0;
|
||||
pt.init ();
|
||||
pt.set_int (0, 0);
|
||||
callStack.init ();
|
||||
globalSubrs.init (globalSubrs_);
|
||||
localSubrs.init (localSubrs_);
|
||||
@ -841,7 +835,6 @@ struct path_procs_t
|
||||
if (likely (env.argStack.get_count () == 11))
|
||||
{
|
||||
point_t d;
|
||||
d.init ();
|
||||
for (unsigned int i = 0; i < 10; i += 2)
|
||||
d.move (env.eval_arg (i), env.eval_arg (i+1));
|
||||
|
||||
|
14
thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh
vendored
14
thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh
vendored
@ -35,18 +35,6 @@ using namespace OT;
|
||||
|
||||
struct blend_arg_t : number_t
|
||||
{
|
||||
void init ()
|
||||
{
|
||||
number_t::init ();
|
||||
deltas.init ();
|
||||
}
|
||||
|
||||
void fini ()
|
||||
{
|
||||
number_t::fini ();
|
||||
deltas.fini_deep ();
|
||||
}
|
||||
|
||||
void set_int (int v) { reset_blends (); number_t::set_int (v); }
|
||||
void set_fixed (int32_t v) { reset_blends (); number_t::set_fixed (v); }
|
||||
void set_real (double v) { reset_blends (); number_t::set_real (v); }
|
||||
@ -202,7 +190,7 @@ struct cff2_cs_opset_t : cs_opset_t<blend_arg_t, OPSET, cff2_cs_interp_env_t, PA
|
||||
switch (op) {
|
||||
case OpCode_callsubr:
|
||||
case OpCode_callgsubr:
|
||||
/* a subroutine number shoudln't be a blended value */
|
||||
/* a subroutine number shouldn't be a blended value */
|
||||
if (unlikely (env.argStack.peek ().blending ()))
|
||||
{
|
||||
env.set_error ();
|
||||
|
80
thirdparty/harfbuzz/src/hb-common.cc
vendored
80
thirdparty/harfbuzz/src/hb-common.cc
vendored
@ -29,10 +29,31 @@
|
||||
#include "hb.hh"
|
||||
#include "hb-machinery.hh"
|
||||
|
||||
#include <locale.h>
|
||||
#if !defined(HB_NO_SETLOCALE) && (!defined(HAVE_NEWLOCALE) || !defined(HAVE_USELOCALE))
|
||||
#define HB_NO_SETLOCALE 1
|
||||
#endif
|
||||
|
||||
#ifndef HB_NO_SETLOCALE
|
||||
|
||||
#include <locale.h>
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h> // Needed on BSD/OS X for uselocale
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define hb_locale_t _locale_t
|
||||
#else
|
||||
#define hb_locale_t locale_t
|
||||
#endif
|
||||
#define hb_setlocale setlocale
|
||||
#define hb_uselocale uselocale
|
||||
|
||||
#else
|
||||
|
||||
#define hb_locale_t void *
|
||||
#define hb_setlocale(Category, Locale) "C"
|
||||
#define hb_uselocale(Locale) ((hb_locale_t) 0)
|
||||
|
||||
#ifdef HB_NO_SETLOCALE
|
||||
#define setlocale(Category, Locale) "C"
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -122,7 +143,7 @@ hb_tag_from_string (const char *str, int len)
|
||||
* @tag: #hb_tag_t to convert
|
||||
* @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string
|
||||
*
|
||||
* Converts an #hb_tag_t to a string and returns it in @buf.
|
||||
* Converts an #hb_tag_t to a string and returns it in @buf.
|
||||
* Strings will be four characters long.
|
||||
*
|
||||
* Since: 0.9.5
|
||||
@ -151,13 +172,13 @@ const char direction_strings[][4] = {
|
||||
* @str: (array length=len) (element-type uint8_t): String to convert
|
||||
* @len: Length of @str, or -1 if it is %NULL-terminated
|
||||
*
|
||||
* Converts a string to an #hb_direction_t.
|
||||
* Converts a string to an #hb_direction_t.
|
||||
*
|
||||
* Matching is loose and applies only to the first letter. For
|
||||
* examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR.
|
||||
*
|
||||
* Unmatched strings will return #HB_DIRECTION_INVALID.
|
||||
*
|
||||
*
|
||||
* Return value: The #hb_direction_t matching @str
|
||||
*
|
||||
* Since: 0.9.2
|
||||
@ -413,7 +434,7 @@ hb_language_get_default ()
|
||||
hb_language_t language = default_language;
|
||||
if (unlikely (language == HB_LANGUAGE_INVALID))
|
||||
{
|
||||
language = hb_language_from_string (setlocale (LC_CTYPE, nullptr), -1);
|
||||
language = hb_language_from_string (hb_setlocale (LC_CTYPE, nullptr), -1);
|
||||
(void) default_language.cmpexch (HB_LANGUAGE_INVALID, language);
|
||||
}
|
||||
|
||||
@ -1039,6 +1060,47 @@ hb_variation_from_string (const char *str, int len,
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef HB_NO_SETLOCALE
|
||||
|
||||
static inline void free_static_C_locale ();
|
||||
|
||||
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 ()
|
||||
{
|
||||
hb_locale_t l = newlocale (LC_ALL_MASK, "C", NULL);
|
||||
if (!l)
|
||||
return l;
|
||||
|
||||
hb_atexit (free_static_C_locale);
|
||||
|
||||
return l;
|
||||
}
|
||||
static void destroy (hb_locale_t l)
|
||||
{
|
||||
freelocale (l);
|
||||
}
|
||||
static hb_locale_t get_null ()
|
||||
{
|
||||
return (hb_locale_t) 0;
|
||||
}
|
||||
} static_C_locale;
|
||||
|
||||
static inline
|
||||
void free_static_C_locale ()
|
||||
{
|
||||
static_C_locale.free_instance ();
|
||||
}
|
||||
|
||||
static hb_locale_t
|
||||
get_C_locale ()
|
||||
{
|
||||
return static_C_locale.get_unconst ();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hb_variation_to_string:
|
||||
* @variation: an #hb_variation_t to convert
|
||||
@ -1064,7 +1126,11 @@ hb_variation_to_string (hb_variation_t *variation,
|
||||
while (len && s[len - 1] == ' ')
|
||||
len--;
|
||||
s[len++] = '=';
|
||||
|
||||
hb_locale_t oldlocale HB_UNUSED;
|
||||
oldlocale = hb_uselocale (get_C_locale ());
|
||||
len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
|
||||
(void) hb_uselocale (oldlocale);
|
||||
|
||||
assert (len < ARRAY_LENGTH (s));
|
||||
len = hb_min (len, size - 1);
|
||||
|
9
thirdparty/harfbuzz/src/hb-coretext.cc
vendored
9
thirdparty/harfbuzz/src/hb-coretext.cc
vendored
@ -481,8 +481,8 @@ struct active_feature_t {
|
||||
a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
|
||||
0;
|
||||
}
|
||||
bool operator== (const active_feature_t *f) {
|
||||
return cmp (this, f) == 0;
|
||||
bool operator== (const active_feature_t& f) const {
|
||||
return cmp (this, &f) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -677,7 +677,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
||||
{
|
||||
active_features.push (event->feature);
|
||||
} else {
|
||||
active_feature_t *feature = active_features.find (&event->feature);
|
||||
active_feature_t *feature = active_features.lsearch (event->feature);
|
||||
if (feature)
|
||||
active_features.remove (feature - active_features.arrayZ);
|
||||
}
|
||||
@ -1213,7 +1213,8 @@ resize_and_retry:
|
||||
}
|
||||
}
|
||||
|
||||
buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
|
||||
buffer->clear_glyph_flags ();
|
||||
buffer->unsafe_to_break ();
|
||||
|
||||
#undef FAIL
|
||||
|
||||
|
3
thirdparty/harfbuzz/src/hb-directwrite.cc
vendored
3
thirdparty/harfbuzz/src/hb-directwrite.cc
vendored
@ -762,7 +762,8 @@ retry_getglyphs:
|
||||
|
||||
if (isRightToLeft) hb_buffer_reverse (buffer);
|
||||
|
||||
buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
|
||||
buffer->clear_glyph_flags ();
|
||||
buffer->unsafe_to_break ();
|
||||
|
||||
delete [] clusterMap;
|
||||
delete [] glyphIndices;
|
||||
|
2
thirdparty/harfbuzz/src/hb-draw.h
vendored
2
thirdparty/harfbuzz/src/hb-draw.h
vendored
@ -50,7 +50,7 @@ typedef void (*hb_draw_close_path_func_t) (void *user_data);
|
||||
*
|
||||
* Glyph draw callbacks.
|
||||
*
|
||||
* _move_to, _line_to and _cubic_to calls are nessecary to be defined but we
|
||||
* _move_to, _line_to and _cubic_to calls are necessary to be defined but we
|
||||
* translate _quadratic_to calls to _cubic_to if the callback isn't defined.
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
|
23
thirdparty/harfbuzz/src/hb-face.cc
vendored
23
thirdparty/harfbuzz/src/hb-face.cc
vendored
@ -143,7 +143,7 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
|
||||
|
||||
typedef struct hb_face_for_data_closure_t {
|
||||
hb_blob_t *blob;
|
||||
unsigned int index;
|
||||
uint16_t index;
|
||||
} hb_face_for_data_closure_t;
|
||||
|
||||
static hb_face_for_data_closure_t *
|
||||
@ -156,7 +156,7 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
|
||||
return nullptr;
|
||||
|
||||
closure->blob = blob;
|
||||
closure->index = index;
|
||||
closure->index = (uint16_t) (index & 0xFFFFu);
|
||||
|
||||
return closure;
|
||||
}
|
||||
@ -195,9 +195,19 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
|
||||
* @index: The index of the face within @blob
|
||||
*
|
||||
* Constructs a new face object from the specified blob and
|
||||
* a face index into that blob. This is used for blobs of
|
||||
* file formats such as Dfont and TTC that can contain more
|
||||
* than one face.
|
||||
* a face index into that blob.
|
||||
*
|
||||
* The face index is used for blobs of file formats such as TTC and
|
||||
* and DFont that can contain more than one face. Face indices within
|
||||
* such collections are zero-based.
|
||||
*
|
||||
* <note>Note: If the blob font format is not a collection, @index
|
||||
* is ignored. Otherwise, only the lower 16-bits of @index are used.
|
||||
* The unmodified @index can be accessed via hb_face_get_index().</note>
|
||||
*
|
||||
* <note>Note: The high 16-bits of @index, if non-zero, are used by
|
||||
* hb_font_create() to load named-instances in variable fonts. See
|
||||
* hb_font_create() for details.</note>
|
||||
*
|
||||
* Return value: (transfer full): The new face object
|
||||
*
|
||||
@ -420,7 +430,8 @@ hb_face_reference_blob (hb_face_t *face)
|
||||
* Assigns the specified face-index to @face. Fails if the
|
||||
* face is immutable.
|
||||
*
|
||||
* <note>Note: face indices within a collection are zero-based.</note>
|
||||
* <note>Note: changing the index has no effect on the face itself
|
||||
* This only changes the value returned by hb_face_get_index().</note>
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
114
thirdparty/harfbuzz/src/hb-font.cc
vendored
114
thirdparty/harfbuzz/src/hb-font.cc
vendored
@ -631,7 +631,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
|
||||
* @destroy: (nullable): A callback to call when @data is not needed anymore
|
||||
* @replace: Whether to replace an existing data with the same key
|
||||
*
|
||||
* Attaches a user-data key/data pair to the specified font-functions structure.
|
||||
* Attaches a user-data key/data pair to the specified font-functions structure.
|
||||
*
|
||||
* Return value: %true if success, %false otherwise
|
||||
*
|
||||
@ -821,7 +821,7 @@ hb_font_get_glyph (hb_font_t *font,
|
||||
* @glyph: (out): The glyph ID retrieved
|
||||
*
|
||||
* Fetches the nominal glyph ID for a Unicode code point in the
|
||||
* specified font.
|
||||
* specified font.
|
||||
*
|
||||
* This version of the function should not be used to fetch glyph IDs
|
||||
* for code points modified by variation selectors. For variation-selector
|
||||
@ -940,7 +940,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
|
||||
* @advance_stride: The stride between successive advances
|
||||
*
|
||||
* Fetches the advances for a sequence of glyph IDs in the specified
|
||||
* font, for horizontal text segments.
|
||||
* font, for horizontal text segments.
|
||||
*
|
||||
* Since: 1.8.6
|
||||
**/
|
||||
@ -964,7 +964,7 @@ hb_font_get_glyph_h_advances (hb_font_t* font,
|
||||
* @advance_stride: (out): The stride between successive advances
|
||||
*
|
||||
* Fetches the advances for a sequence of glyph IDs in the specified
|
||||
* font, for vertical text segments.
|
||||
* font, for vertical text segments.
|
||||
*
|
||||
* Since: 1.8.6
|
||||
**/
|
||||
@ -1278,7 +1278,7 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
|
||||
* @font: #hb_font_t to work upon
|
||||
* @glyph: The glyph ID to query
|
||||
* @direction: The direction of the text segment
|
||||
* @x: (inout): Input = The original X coordinate
|
||||
* @x: (inout): Input = The original X coordinate
|
||||
* Output = The X coordinate plus the X-coordinate of the origin
|
||||
* @y: (inout): Input = The original Y coordinate
|
||||
* Output = The Y coordinate plus the Y-coordinate of the origin
|
||||
@ -1306,7 +1306,7 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font,
|
||||
* @font: #hb_font_t to work upon
|
||||
* @glyph: The glyph ID to query
|
||||
* @direction: The direction of the text segment
|
||||
* @x: (inout): Input = The original X coordinate
|
||||
* @x: (inout): Input = The original X coordinate
|
||||
* Output = The X coordinate minus the X-coordinate of the origin
|
||||
* @y: (inout): Input = The original Y coordinate
|
||||
* Output = The Y coordinate minus the Y-coordinate of the origin
|
||||
@ -1477,6 +1477,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
|
||||
|
||||
1000, /* x_scale */
|
||||
1000, /* y_scale */
|
||||
0., /* slant */
|
||||
0., /* slant_xy; */
|
||||
1<<16, /* x_mult */
|
||||
1<<16, /* y_mult */
|
||||
|
||||
@ -1521,6 +1523,13 @@ _hb_font_create (hb_face_t *face)
|
||||
*
|
||||
* Constructs a new font object from the specified face.
|
||||
*
|
||||
* <note>Note: If @face's index value (as passed to hb_face_create()
|
||||
* has non-zero top 16-bits, those bits minus one are passed to
|
||||
* hb_font_set_var_named_instance(), effectively loading a named-instance
|
||||
* of a variable font, instead of the default-instance. This allows
|
||||
* specifying which named-instance to load by default when creating the
|
||||
* face.</note>
|
||||
*
|
||||
* Return value: (transfer full): The new font object
|
||||
*
|
||||
* Since: 0.9.2
|
||||
@ -1535,6 +1544,11 @@ hb_font_create (hb_face_t *face)
|
||||
hb_ot_font_set_funcs (font);
|
||||
#endif
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
if (face && face->index >> 16)
|
||||
hb_font_set_var_named_instance (font, (face->index >> 16) - 1);
|
||||
#endif
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
@ -1578,6 +1592,7 @@ hb_font_create_sub_font (hb_font_t *parent)
|
||||
|
||||
font->x_scale = parent->x_scale;
|
||||
font->y_scale = parent->y_scale;
|
||||
font->slant = parent->slant;
|
||||
font->mults_changed ();
|
||||
font->x_ppem = parent->x_ppem;
|
||||
font->y_ppem = parent->y_ppem;
|
||||
@ -1668,12 +1683,12 @@ hb_font_destroy (hb_font_t *font)
|
||||
/**
|
||||
* hb_font_set_user_data: (skip)
|
||||
* @font: #hb_font_t to work upon
|
||||
* @key: The user-data key
|
||||
* @key: The user-data key
|
||||
* @data: A pointer to the user data
|
||||
* @destroy: (nullable): A callback to call when @data is not needed anymore
|
||||
* @replace: Whether to replace an existing data with the same key
|
||||
*
|
||||
* Attaches a user-data key/data pair to the specified font object.
|
||||
* Attaches a user-data key/data pair to the specified font object.
|
||||
*
|
||||
* Return value: %true if success, %false otherwise
|
||||
*
|
||||
@ -1875,7 +1890,7 @@ hb_font_set_funcs (hb_font_t *font,
|
||||
* @font_data: (destroy destroy) (scope notified): Data to attach to @font
|
||||
* @destroy: (nullable): The function to call when @font_data is not needed anymore
|
||||
*
|
||||
* Replaces the user data attached to a font, updating the font's
|
||||
* Replaces the user data attached to a font, updating the font's
|
||||
* @destroy callback.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
@ -1949,7 +1964,7 @@ hb_font_get_scale (hb_font_t *font,
|
||||
* @x_ppem: Horizontal ppem value to assign
|
||||
* @y_ppem: Vertical ppem value to assign
|
||||
*
|
||||
* Sets the horizontal and vertical pixels-per-em (ppem) of a font.
|
||||
* Sets the horizontal and vertical pixels-per-em (ppem) of a font.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
@ -1971,7 +1986,7 @@ hb_font_set_ppem (hb_font_t *font,
|
||||
* @x_ppem: (out): Horizontal ppem value
|
||||
* @y_ppem: (out): Vertical ppem value
|
||||
*
|
||||
* Fetches the horizontal and vertical points-per-em (ppem) of a font.
|
||||
* Fetches the horizontal and vertical points-per-em (ppem) of a font.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
@ -2015,7 +2030,7 @@ hb_font_set_ptem (hb_font_t *font,
|
||||
*
|
||||
* Return value: Point size. A value of zero means "not set."
|
||||
*
|
||||
* Since: 0.9.2
|
||||
* Since: 1.6.0
|
||||
**/
|
||||
float
|
||||
hb_font_get_ptem (hb_font_t *font)
|
||||
@ -2023,6 +2038,49 @@ hb_font_get_ptem (hb_font_t *font)
|
||||
return font->ptem;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_font_set_synthetic_slant:
|
||||
* @font: #hb_font_t to work upon
|
||||
* @slant: synthetic slant value.
|
||||
*
|
||||
* Sets the "synthetic slant" of a font. By default is zero.
|
||||
* Synthetic slant is the graphical skew that the renderer
|
||||
* applies to the font at rendering time.
|
||||
*
|
||||
* HarfBuzz needs to know this value to adjust shaping results,
|
||||
* metrics, and style values to match the slanted rendering.
|
||||
*
|
||||
* <note>Note: The slant value is a ratio. For example, a
|
||||
* 20% slant would be represented as a 0.2 value.</note>
|
||||
*
|
||||
* Since: 3.3.0
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_font_set_synthetic_slant (hb_font_t *font, float slant)
|
||||
{
|
||||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
font->slant = slant;
|
||||
font->mults_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_font_get_synthetic_slant:
|
||||
* @font: #hb_font_t to work upon
|
||||
*
|
||||
* Fetches the "synthetic slant" of a font.
|
||||
*
|
||||
* Return value: Synthetic slant. By default is zero.
|
||||
*
|
||||
* Since: 3.3.0
|
||||
**/
|
||||
HB_EXTERN float
|
||||
hb_font_get_synthetic_slant (hb_font_t *font)
|
||||
{
|
||||
return font->slant;
|
||||
}
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
/*
|
||||
* Variations
|
||||
@ -2036,6 +2094,10 @@ hb_font_get_ptem (hb_font_t *font)
|
||||
*
|
||||
* Applies a list of font-variation settings to a font.
|
||||
*
|
||||
* Note that this overrides all existing variations set on @font.
|
||||
* Axes not included in @variations will be effectively set to their
|
||||
* default values.
|
||||
*
|
||||
* Since: 1.4.2
|
||||
*/
|
||||
void
|
||||
@ -2091,6 +2153,10 @@ hb_font_set_variations (hb_font_t *font,
|
||||
* Applies a list of variation coordinates (in design-space units)
|
||||
* to a font.
|
||||
*
|
||||
* Note that this overrides all existing variations set on @font.
|
||||
* Axes not included in @coords will be effectively set to their
|
||||
* default values.
|
||||
*
|
||||
* Since: 1.4.2
|
||||
*/
|
||||
void
|
||||
@ -2154,6 +2220,10 @@ hb_font_set_var_named_instance (hb_font_t *font,
|
||||
* Applies a list of variation coordinates (in normalized units)
|
||||
* to a font.
|
||||
*
|
||||
* Note that this overrides all existing variations set on @font.
|
||||
* Axes not included in @coords will be effectively set to their
|
||||
* default values.
|
||||
*
|
||||
* <note>Note: Coordinates should be normalized to 2.14.</note>
|
||||
*
|
||||
* Since: 1.4.2
|
||||
@ -2196,14 +2266,19 @@ hb_font_set_var_coords_normalized (hb_font_t *font,
|
||||
/**
|
||||
* hb_font_get_var_coords_normalized:
|
||||
* @font: #hb_font_t to work upon
|
||||
* @length: Number of coordinates retrieved
|
||||
* @length: (out): Number of coordinates retrieved
|
||||
*
|
||||
* Fetches the list of normalized variation coordinates currently
|
||||
* set on a font.
|
||||
*
|
||||
* Note that this returned array may only contain values for some
|
||||
* (or none) of the axes; omitted axes effectively have zero values.
|
||||
*
|
||||
* Return value is valid as long as variation coordinates of the font
|
||||
* are not modified.
|
||||
*
|
||||
* Return value: coordinates array
|
||||
*
|
||||
* Since: 1.4.2
|
||||
*/
|
||||
const int *
|
||||
@ -2216,18 +2291,24 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
|
||||
return font->coords;
|
||||
}
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
/**
|
||||
* hb_font_get_var_coords_design:
|
||||
* @font: #hb_font_t to work upon
|
||||
* @length: (out): number of coordinates
|
||||
* @length: (out): Number of coordinates retrieved
|
||||
*
|
||||
* Fetches the list of variation coordinates (in design-space units) currently
|
||||
* set on a font.
|
||||
*
|
||||
* Note that this returned array may only contain values for some
|
||||
* (or none) of the axes; omitted axes effectively have their default
|
||||
* values.
|
||||
*
|
||||
* Return value is valid as long as variation coordinates of the font
|
||||
* are not modified.
|
||||
*
|
||||
* Return value: coordinates array
|
||||
*
|
||||
* Since: EXPERIMENTAL
|
||||
* Since: 3.3.0
|
||||
*/
|
||||
const float *
|
||||
hb_font_get_var_coords_design (hb_font_t *font,
|
||||
@ -2239,7 +2320,6 @@ hb_font_get_var_coords_design (hb_font_t *font,
|
||||
return font->design_coords;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HB_DISABLE_DEPRECATED
|
||||
/*
|
||||
|
8
thirdparty/harfbuzz/src/hb-font.h
vendored
8
thirdparty/harfbuzz/src/hb-font.h
vendored
@ -1023,6 +1023,12 @@ hb_font_set_ptem (hb_font_t *font, float ptem);
|
||||
HB_EXTERN float
|
||||
hb_font_get_ptem (hb_font_t *font);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_synthetic_slant (hb_font_t *font, float slant);
|
||||
|
||||
HB_EXTERN float
|
||||
hb_font_get_synthetic_slant (hb_font_t *font);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_variations (hb_font_t *font,
|
||||
const hb_variation_t *variations,
|
||||
@ -1033,11 +1039,9 @@ hb_font_set_var_coords_design (hb_font_t *font,
|
||||
const float *coords,
|
||||
unsigned int coords_length);
|
||||
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
HB_EXTERN const float *
|
||||
hb_font_get_var_coords_design (hb_font_t *font,
|
||||
unsigned int *length);
|
||||
#endif
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_var_coords_normalized (hb_font_t *font,
|
||||
|
3
thirdparty/harfbuzz/src/hb-font.hh
vendored
3
thirdparty/harfbuzz/src/hb-font.hh
vendored
@ -109,6 +109,8 @@ struct hb_font_t
|
||||
|
||||
int32_t x_scale;
|
||||
int32_t y_scale;
|
||||
float slant;
|
||||
float slant_xy;
|
||||
int64_t x_mult;
|
||||
int64_t y_mult;
|
||||
|
||||
@ -617,6 +619,7 @@ struct hb_font_t
|
||||
signed upem = face->get_upem ();
|
||||
x_mult = ((int64_t) x_scale << 16) / upem;
|
||||
y_mult = ((int64_t) y_scale << 16) / upem;
|
||||
slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
|
||||
}
|
||||
|
||||
hb_position_t em_mult (int16_t v, int64_t mult)
|
||||
|
3
thirdparty/harfbuzz/src/hb-graphite2.cc
vendored
3
thirdparty/harfbuzz/src/hb-graphite2.cc
vendored
@ -439,7 +439,8 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
if (feats) gr_featureval_destroy (feats);
|
||||
gr_seg_destroy (seg);
|
||||
|
||||
buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
|
||||
buffer->clear_glyph_flags ();
|
||||
buffer->unsafe_to_break ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
6
thirdparty/harfbuzz/src/hb-iter.hh
vendored
6
thirdparty/harfbuzz/src/hb-iter.hh
vendored
@ -90,8 +90,8 @@ struct hb_iter_t
|
||||
* it will be returning pointer to temporary rvalue.
|
||||
* TODO Use a wrapper return type to fix for non-reference type. */
|
||||
template <typename T = item_t,
|
||||
hb_enable_if (hb_is_reference (T))>
|
||||
hb_remove_reference<item_t>* operator -> () const { return hb_addressof (**thiz()); }
|
||||
hb_enable_if (std::is_reference<T>::value)>
|
||||
hb_remove_reference<item_t>* operator -> () const { return std::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); }
|
||||
@ -289,7 +289,7 @@ struct hb_is_source_of
|
||||
{
|
||||
private:
|
||||
template <typename Iter2 = Iter,
|
||||
hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<hb_add_const<Item>>))>
|
||||
hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<const Item>))>
|
||||
static hb_true_type impl (hb_priority<2>);
|
||||
template <typename Iter2 = Iter>
|
||||
static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ());
|
||||
|
9
thirdparty/harfbuzz/src/hb-kern.hh
vendored
9
thirdparty/harfbuzz/src/hb-kern.hh
vendored
@ -49,6 +49,10 @@ struct hb_kern_machine_t
|
||||
hb_mask_t kern_mask,
|
||||
bool scale = true) const
|
||||
{
|
||||
if (!buffer->message (font, "start kern"))
|
||||
return;
|
||||
|
||||
buffer->unsafe_to_concat ();
|
||||
OT::hb_ot_apply_context_t c (1, font, buffer);
|
||||
c.set_lookup_mask (kern_mask);
|
||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||
@ -67,7 +71,8 @@ struct hb_kern_machine_t
|
||||
}
|
||||
|
||||
skippy_iter.reset (idx, 1);
|
||||
if (!skippy_iter.next ())
|
||||
unsigned unsafe_to;
|
||||
if (!skippy_iter.next (&unsafe_to))
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
@ -125,6 +130,8 @@ struct hb_kern_machine_t
|
||||
skip:
|
||||
idx = skippy_iter.idx;
|
||||
}
|
||||
|
||||
(void) buffer->message (font, "end kern");
|
||||
}
|
||||
|
||||
const Driver &driver;
|
||||
|
6
thirdparty/harfbuzz/src/hb-machinery.hh
vendored
6
thirdparty/harfbuzz/src/hb-machinery.hh
vendored
@ -244,19 +244,19 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
||||
{
|
||||
Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
|
||||
if (likely (p))
|
||||
p->init (data);
|
||||
p = new (p) Stored (data);
|
||||
return p;
|
||||
}
|
||||
static Stored *create ()
|
||||
{
|
||||
Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
|
||||
if (likely (p))
|
||||
p->init ();
|
||||
p = new (p) Stored ();
|
||||
return p;
|
||||
}
|
||||
static void destroy (Stored *p)
|
||||
{
|
||||
p->fini ();
|
||||
p->~Stored ();
|
||||
hb_free (p);
|
||||
}
|
||||
|
||||
|
71
thirdparty/harfbuzz/src/hb-map.hh
vendored
71
thirdparty/harfbuzz/src/hb-map.hh
vendored
@ -37,13 +37,10 @@
|
||||
template <typename K, typename V,
|
||||
typename k_invalid_t = K,
|
||||
typename v_invalid_t = V,
|
||||
k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
|
||||
v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
|
||||
k_invalid_t kINVALID = std::is_pointer<K>::value ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
|
||||
v_invalid_t vINVALID = std::is_pointer<V>::value ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
|
||||
struct hb_hashmap_t
|
||||
{
|
||||
static constexpr K INVALID_KEY = kINVALID;
|
||||
static constexpr V INVALID_VALUE = vINVALID;
|
||||
|
||||
hb_hashmap_t () { init (); }
|
||||
~hb_hashmap_t () { fini (); }
|
||||
|
||||
@ -64,24 +61,40 @@ struct hb_hashmap_t
|
||||
hb_copy (o, *this);
|
||||
}
|
||||
|
||||
static_assert (std::is_trivially_copyable<K>::value, "");
|
||||
static_assert (std::is_trivially_copyable<V>::value, "");
|
||||
static_assert (std::is_trivially_destructible<K>::value, "");
|
||||
static_assert (std::is_trivially_destructible<V>::value, "");
|
||||
|
||||
struct item_t
|
||||
{
|
||||
K key;
|
||||
V value;
|
||||
uint32_t hash;
|
||||
|
||||
void clear () { key = kINVALID; value = vINVALID; hash = 0; }
|
||||
void clear ()
|
||||
{
|
||||
new (std::addressof (key)) K ();
|
||||
key = hb_coerce<K> (kINVALID);
|
||||
new (std::addressof (value)) V ();
|
||||
value = hb_coerce<V> (vINVALID);
|
||||
hash = 0;
|
||||
}
|
||||
|
||||
bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); }
|
||||
bool operator == (const item_t &o) { return *this == o.key; }
|
||||
bool is_unused () const { return key == kINVALID; }
|
||||
bool is_tombstone () const { return key != kINVALID && value == vINVALID; }
|
||||
bool is_real () const { return key != kINVALID && value != vINVALID; }
|
||||
bool is_unused () const
|
||||
{
|
||||
const K inv = hb_coerce<K> (kINVALID);
|
||||
return key == inv;
|
||||
}
|
||||
bool is_tombstone () const
|
||||
{
|
||||
const K kinv = hb_coerce<K> (kINVALID);
|
||||
const V vinv = hb_coerce<V> (vINVALID);
|
||||
return key != kinv && value == vinv;
|
||||
}
|
||||
bool is_real () const
|
||||
{
|
||||
const K kinv = hb_coerce<K> (kINVALID);
|
||||
const V vinv = hb_coerce<V> (vINVALID);
|
||||
return key != kinv && value != vinv;
|
||||
}
|
||||
hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
|
||||
};
|
||||
|
||||
@ -118,8 +131,13 @@ struct hb_hashmap_t
|
||||
}
|
||||
void fini_shallow ()
|
||||
{
|
||||
hb_free (items);
|
||||
items = nullptr;
|
||||
if (likely (items)) {
|
||||
unsigned size = mask + 1;
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
items[i].~item_t ();
|
||||
hb_free (items);
|
||||
items = nullptr;
|
||||
}
|
||||
population = occupancy = 0;
|
||||
}
|
||||
void fini ()
|
||||
@ -163,10 +181,15 @@ struct hb_hashmap_t
|
||||
/* Insert back old items. */
|
||||
if (old_items)
|
||||
for (unsigned int i = 0; i < old_size; i++)
|
||||
{
|
||||
if (old_items[i].is_real ())
|
||||
{
|
||||
set_with_hash (old_items[i].key,
|
||||
old_items[i].hash,
|
||||
std::move (old_items[i].value));
|
||||
}
|
||||
old_items[i].~item_t ();
|
||||
}
|
||||
|
||||
hb_free (old_items);
|
||||
|
||||
@ -178,22 +201,22 @@ struct hb_hashmap_t
|
||||
|
||||
V get (K key) const
|
||||
{
|
||||
if (unlikely (!items)) return vINVALID;
|
||||
if (unlikely (!items)) return hb_coerce<V> (vINVALID);
|
||||
unsigned int i = bucket_for (key);
|
||||
return items[i].is_real () && items[i] == key ? items[i].value : vINVALID;
|
||||
return items[i].is_real () && items[i] == key ? items[i].value : hb_coerce<V> (vINVALID);
|
||||
}
|
||||
|
||||
void del (K key) { set (key, vINVALID); }
|
||||
void del (K key) { set (key, hb_coerce<V> (vINVALID)); }
|
||||
|
||||
/* Has interface. */
|
||||
static constexpr V SENTINEL = vINVALID;
|
||||
typedef V value_t;
|
||||
value_t operator [] (K k) const { return get (k); }
|
||||
bool has (K k, V *vp = nullptr) const
|
||||
{
|
||||
V v = (*this)[k];
|
||||
if (vp) *vp = v;
|
||||
return v != SENTINEL;
|
||||
const V vinv = hb_coerce<V> (vINVALID);
|
||||
return v != vinv;
|
||||
}
|
||||
/* Projection. */
|
||||
V operator () (K k) const { return get (k); }
|
||||
@ -248,11 +271,13 @@ struct hb_hashmap_t
|
||||
bool set_with_hash (K key, uint32_t hash, VV&& value)
|
||||
{
|
||||
if (unlikely (!successful)) return false;
|
||||
if (unlikely (key == kINVALID)) return true;
|
||||
const K kinv = hb_coerce<K> (kINVALID);
|
||||
if (unlikely (key == kinv)) return true;
|
||||
if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
|
||||
unsigned int i = bucket_for_hash (key, hash);
|
||||
|
||||
if (value == vINVALID && items[i].key != key)
|
||||
const V vinv = hb_coerce<V> (vINVALID);
|
||||
if (value == vinv && items[i].key != key)
|
||||
return true; /* Trying to delete non-existent key. */
|
||||
|
||||
if (!items[i].is_unused ())
|
||||
|
39
thirdparty/harfbuzz/src/hb-meta.hh
vendored
39
thirdparty/harfbuzz/src/hb-meta.hh
vendored
@ -29,6 +29,7 @@
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@ -85,30 +86,13 @@ template <> struct hb_priority<0> {};
|
||||
template <typename T> struct hb_type_identity_t { typedef T type; };
|
||||
template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::type;
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T> constexpr T*
|
||||
operator () (T& arg) const
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
/* https://en.cppreference.com/w/cpp/memory/addressof */
|
||||
return reinterpret_cast<T*> (
|
||||
&const_cast<char&> (
|
||||
reinterpret_cast<const volatile char&> (arg)));
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
}
|
||||
HB_FUNCOBJ (hb_addressof);
|
||||
|
||||
template <typename T> static inline T hb_declval ();
|
||||
#define hb_declval(T) (hb_declval<T> ())
|
||||
|
||||
template <typename T> struct hb_match_const : hb_type_identity_t<T>, hb_false_type {};
|
||||
template <typename T> struct hb_match_const<const T> : hb_type_identity_t<T>, hb_true_type {};
|
||||
template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
|
||||
template <typename T> using hb_add_const = const T;
|
||||
#define hb_is_const(T) hb_match_const<T>::value
|
||||
|
||||
template <typename T> struct hb_match_reference : hb_type_identity_t<T>, hb_false_type {};
|
||||
template <typename T> struct hb_match_reference<T &> : hb_type_identity_t<T>, hb_true_type {};
|
||||
template <typename T> struct hb_match_reference<T &&> : hb_type_identity_t<T>, hb_true_type {};
|
||||
@ -119,14 +103,13 @@ template <typename T> using hb_add_lvalue_reference = decltype (_hb_try_add_lval
|
||||
template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity<T&&>;
|
||||
template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
|
||||
template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize));
|
||||
#define hb_is_reference(T) hb_match_reference<T>::value
|
||||
|
||||
template <typename T> struct hb_match_pointer : hb_type_identity_t<T>, hb_false_type {};
|
||||
template <typename T> struct hb_match_pointer<T *> : hb_type_identity_t<T>, hb_true_type {};
|
||||
template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
|
||||
template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>;
|
||||
template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>;
|
||||
template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
|
||||
#define hb_is_pointer(T) hb_match_pointer<T>::value
|
||||
|
||||
|
||||
/* TODO Add feature-parity to std::decay. */
|
||||
@ -137,8 +120,8 @@ template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
|
||||
template <typename From, typename To>
|
||||
using hb_is_cr_convertible = hb_bool_constant<
|
||||
hb_is_same (hb_decay<From>, hb_decay<To>) &&
|
||||
(!hb_is_const (From) || hb_is_const (To)) &&
|
||||
(!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To))
|
||||
(!std::is_const<From>::value || std::is_const<To>::value) &&
|
||||
(!std::is_reference<To>::value || std::is_const<To>::value || std::is_reference<To>::value)
|
||||
>;
|
||||
#define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
|
||||
|
||||
@ -153,16 +136,6 @@ struct
|
||||
}
|
||||
HB_FUNCOBJ (hb_deref);
|
||||
|
||||
struct
|
||||
{
|
||||
template <typename T> constexpr auto
|
||||
operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
|
||||
|
||||
template <typename T> constexpr auto
|
||||
operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
|
||||
}
|
||||
HB_FUNCOBJ (hb_ref);
|
||||
|
||||
template <typename T>
|
||||
struct hb_reference_wrapper
|
||||
{
|
||||
@ -176,7 +149,7 @@ struct hb_reference_wrapper
|
||||
template <typename T>
|
||||
struct hb_reference_wrapper<T&>
|
||||
{
|
||||
hb_reference_wrapper (T& v) : v (hb_addressof (v)) {}
|
||||
hb_reference_wrapper (T& v) : v (std::addressof (v)) {}
|
||||
bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
|
||||
bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
|
||||
operator T& () const { return *v; }
|
||||
|
177
thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc
vendored
177
thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc
vendored
@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2011,2012,2013 Google, Inc.
|
||||
* Copyright © 2021 Khaled Hosny
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-ms-feature-ranges.hh"
|
||||
|
||||
bool
|
||||
hb_ms_setup_features (const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
hb_vector_t<hb_ms_feature_t> &feature_records, /* OUT */
|
||||
hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */)
|
||||
{
|
||||
feature_records.shrink(0);
|
||||
range_records.shrink(0);
|
||||
|
||||
/* Sort features by start/end events. */
|
||||
hb_vector_t<hb_ms_feature_event_t> feature_events;
|
||||
for (unsigned int i = 0; i < num_features; i++)
|
||||
{
|
||||
hb_ms_active_feature_t feature;
|
||||
feature.fea.tag_le = hb_uint32_swap (features[i].tag);
|
||||
feature.fea.value = features[i].value;
|
||||
feature.order = i;
|
||||
|
||||
hb_ms_feature_event_t *event;
|
||||
|
||||
event = feature_events.push ();
|
||||
event->index = features[i].start;
|
||||
event->start = true;
|
||||
event->feature = feature;
|
||||
|
||||
event = feature_events.push ();
|
||||
event->index = features[i].end;
|
||||
event->start = false;
|
||||
event->feature = feature;
|
||||
}
|
||||
feature_events.qsort ();
|
||||
/* Add a strategic final event. */
|
||||
{
|
||||
hb_ms_active_feature_t feature;
|
||||
feature.fea.tag_le = 0;
|
||||
feature.fea.value = 0;
|
||||
feature.order = num_features + 1;
|
||||
|
||||
auto *event = feature_events.push ();
|
||||
event->index = 0; /* This value does magic. */
|
||||
event->start = false;
|
||||
event->feature = feature;
|
||||
}
|
||||
|
||||
/* Scan events and save features for each range. */
|
||||
hb_vector_t<hb_ms_active_feature_t> active_features;
|
||||
unsigned int last_index = 0;
|
||||
for (unsigned int i = 0; i < feature_events.length; i++)
|
||||
{
|
||||
auto *event = &feature_events[i];
|
||||
|
||||
if (event->index != last_index)
|
||||
{
|
||||
/* Save a snapshot of active features and the range. */
|
||||
auto *range = range_records.push ();
|
||||
auto offset = feature_records.length;
|
||||
|
||||
active_features.qsort ();
|
||||
for (unsigned int j = 0; j < active_features.length; j++)
|
||||
{
|
||||
if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le)
|
||||
{
|
||||
feature_records.push (active_features[j].fea);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Overrides value for existing feature. */
|
||||
feature_records[feature_records.length - 1].value = active_features[j].fea.value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Will convert to pointer after all is ready, since feature_records.array
|
||||
* may move as we grow it. */
|
||||
range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset);
|
||||
range->features.num_features = feature_records.length - offset;
|
||||
range->index_first = last_index;
|
||||
range->index_last = event->index - 1;
|
||||
|
||||
last_index = event->index;
|
||||
}
|
||||
|
||||
if (event->start)
|
||||
{
|
||||
active_features.push (event->feature);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto *feature = active_features.find (&event->feature);
|
||||
if (feature)
|
||||
active_features.remove (feature - active_features.arrayZ);
|
||||
}
|
||||
}
|
||||
|
||||
if (!range_records.length) /* No active feature found. */
|
||||
num_features = 0;
|
||||
|
||||
/* Fixup the pointers. */
|
||||
for (unsigned int i = 0; i < range_records.length; i++)
|
||||
{
|
||||
auto *range = &range_records[i];
|
||||
range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features);
|
||||
}
|
||||
|
||||
return !!num_features;
|
||||
}
|
||||
|
||||
void
|
||||
hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t> &feature_records,
|
||||
hb_vector_t<hb_ms_range_record_t> &range_records,
|
||||
unsigned int chars_offset,
|
||||
unsigned int chars_len,
|
||||
uint16_t *log_clusters,
|
||||
hb_vector_t<hb_ms_features_t*> &range_features, /* OUT */
|
||||
hb_vector_t<uint32_t> &range_counts /* OUT */)
|
||||
{
|
||||
range_features.shrink (0);
|
||||
range_counts.shrink (0);
|
||||
|
||||
auto *last_range = &range_records[0];
|
||||
for (unsigned int i = chars_offset; i < chars_len; i++)
|
||||
{
|
||||
auto *range = last_range;
|
||||
while (log_clusters[i] < range->index_first)
|
||||
range--;
|
||||
while (log_clusters[i] > range->index_last)
|
||||
range++;
|
||||
if (!range_features.length ||
|
||||
&range->features != range_features[range_features.length - 1])
|
||||
{
|
||||
auto **features = range_features.push ();
|
||||
auto *c = range_counts.push ();
|
||||
if (unlikely (!features || !c))
|
||||
{
|
||||
range_features.shrink (0);
|
||||
range_counts.shrink (0);
|
||||
break;
|
||||
}
|
||||
*features = &range->features;
|
||||
*c = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
range_counts[range_counts.length - 1]++;
|
||||
}
|
||||
|
||||
last_range = range;
|
||||
}
|
||||
}
|
145
thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh
vendored
145
thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh
vendored
@ -52,8 +52,8 @@ struct hb_ms_active_feature_t {
|
||||
a->fea.value < b->fea.value ? -1 : a->fea.value > b->fea.value ? 1 :
|
||||
0;
|
||||
}
|
||||
bool operator== (const hb_ms_active_feature_t *f)
|
||||
{ return cmp (this, f) == 0; }
|
||||
bool operator== (const hb_ms_active_feature_t& f) const
|
||||
{ return cmp (this, &f) == 0; }
|
||||
};
|
||||
|
||||
struct hb_ms_feature_event_t {
|
||||
@ -77,20 +77,153 @@ struct hb_ms_range_record_t {
|
||||
unsigned int index_last; /* == end - 1 */
|
||||
};
|
||||
|
||||
HB_INTERNAL bool
|
||||
static inline bool
|
||||
hb_ms_setup_features (const hb_feature_t *features,
|
||||
unsigned int num_features,
|
||||
hb_vector_t<hb_ms_feature_t> &feature_records, /* OUT */
|
||||
hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */);
|
||||
hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */)
|
||||
{
|
||||
feature_records.shrink(0);
|
||||
range_records.shrink(0);
|
||||
|
||||
/* Sort features by start/end events. */
|
||||
hb_vector_t<hb_ms_feature_event_t> feature_events;
|
||||
for (unsigned int i = 0; i < num_features; i++)
|
||||
{
|
||||
hb_ms_active_feature_t feature;
|
||||
feature.fea.tag_le = hb_uint32_swap (features[i].tag);
|
||||
feature.fea.value = features[i].value;
|
||||
feature.order = i;
|
||||
|
||||
HB_INTERNAL void
|
||||
hb_ms_feature_event_t *event;
|
||||
|
||||
event = feature_events.push ();
|
||||
event->index = features[i].start;
|
||||
event->start = true;
|
||||
event->feature = feature;
|
||||
|
||||
event = feature_events.push ();
|
||||
event->index = features[i].end;
|
||||
event->start = false;
|
||||
event->feature = feature;
|
||||
}
|
||||
feature_events.qsort ();
|
||||
/* Add a strategic final event. */
|
||||
{
|
||||
hb_ms_active_feature_t feature;
|
||||
feature.fea.tag_le = 0;
|
||||
feature.fea.value = 0;
|
||||
feature.order = num_features + 1;
|
||||
|
||||
auto *event = feature_events.push ();
|
||||
event->index = 0; /* This value does magic. */
|
||||
event->start = false;
|
||||
event->feature = feature;
|
||||
}
|
||||
|
||||
/* Scan events and save features for each range. */
|
||||
hb_vector_t<hb_ms_active_feature_t> active_features;
|
||||
unsigned int last_index = 0;
|
||||
for (unsigned int i = 0; i < feature_events.length; i++)
|
||||
{
|
||||
auto *event = &feature_events[i];
|
||||
|
||||
if (event->index != last_index)
|
||||
{
|
||||
/* Save a snapshot of active features and the range. */
|
||||
auto *range = range_records.push ();
|
||||
auto offset = feature_records.length;
|
||||
|
||||
active_features.qsort ();
|
||||
for (unsigned int j = 0; j < active_features.length; j++)
|
||||
{
|
||||
if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le)
|
||||
{
|
||||
feature_records.push (active_features[j].fea);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Overrides value for existing feature. */
|
||||
feature_records[feature_records.length - 1].value = active_features[j].fea.value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Will convert to pointer after all is ready, since feature_records.array
|
||||
* may move as we grow it. */
|
||||
range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset);
|
||||
range->features.num_features = feature_records.length - offset;
|
||||
range->index_first = last_index;
|
||||
range->index_last = event->index - 1;
|
||||
|
||||
last_index = event->index;
|
||||
}
|
||||
|
||||
if (event->start)
|
||||
{
|
||||
active_features.push (event->feature);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto *feature = active_features.lsearch (event->feature);
|
||||
if (feature)
|
||||
active_features.remove (feature - active_features.arrayZ);
|
||||
}
|
||||
}
|
||||
|
||||
if (!range_records.length) /* No active feature found. */
|
||||
num_features = 0;
|
||||
|
||||
/* Fixup the pointers. */
|
||||
for (unsigned int i = 0; i < range_records.length; i++)
|
||||
{
|
||||
auto *range = &range_records[i];
|
||||
range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features);
|
||||
}
|
||||
|
||||
return !!num_features;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t> &feature_records,
|
||||
hb_vector_t<hb_ms_range_record_t> &range_records,
|
||||
unsigned int chars_offset,
|
||||
unsigned int chars_len,
|
||||
uint16_t *log_clusters,
|
||||
hb_vector_t<hb_ms_features_t*> &range_features, /* OUT */
|
||||
hb_vector_t<uint32_t> &range_counts /* OUT */);
|
||||
hb_vector_t<uint32_t> &range_counts /* OUT */)
|
||||
{
|
||||
range_features.shrink (0);
|
||||
range_counts.shrink (0);
|
||||
|
||||
auto *last_range = &range_records[0];
|
||||
for (unsigned int i = chars_offset; i < chars_len; i++)
|
||||
{
|
||||
auto *range = last_range;
|
||||
while (log_clusters[i] < range->index_first)
|
||||
range--;
|
||||
while (log_clusters[i] > range->index_last)
|
||||
range++;
|
||||
if (!range_features.length ||
|
||||
&range->features != range_features[range_features.length - 1])
|
||||
{
|
||||
auto **features = range_features.push ();
|
||||
auto *c = range_counts.push ();
|
||||
if (unlikely (!features || !c))
|
||||
{
|
||||
range_features.shrink (0);
|
||||
range_counts.shrink (0);
|
||||
break;
|
||||
}
|
||||
*features = &range->features;
|
||||
*c = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
range_counts[range_counts.length - 1]++;
|
||||
}
|
||||
|
||||
last_range = range;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HB_MS_FEATURE_RANGES_HH */
|
||||
|
6
thirdparty/harfbuzz/src/hb-object.hh
vendored
6
thirdparty/harfbuzz/src/hb-object.hh
vendored
@ -53,7 +53,7 @@ struct hb_lockable_set_t
|
||||
item_t *replace_or_insert (T v, lock_t &l, bool replace)
|
||||
{
|
||||
l.lock ();
|
||||
item_t *item = items.find (v);
|
||||
item_t *item = items.lsearch (v);
|
||||
if (item) {
|
||||
if (replace) {
|
||||
item_t old = *item;
|
||||
@ -76,7 +76,7 @@ struct hb_lockable_set_t
|
||||
void remove (T v, lock_t &l)
|
||||
{
|
||||
l.lock ();
|
||||
item_t *item = items.find (v);
|
||||
item_t *item = items.lsearch (v);
|
||||
if (item)
|
||||
{
|
||||
item_t old = *item;
|
||||
@ -93,7 +93,7 @@ struct hb_lockable_set_t
|
||||
bool find (T v, item_t *i, lock_t &l)
|
||||
{
|
||||
l.lock ();
|
||||
item_t *item = items.find (v);
|
||||
item_t *item = items.lsearch (v);
|
||||
if (item)
|
||||
*i = *item;
|
||||
l.unlock ();
|
||||
|
2
thirdparty/harfbuzz/src/hb-ot-cff-common.hh
vendored
2
thirdparty/harfbuzz/src/hb-ot-cff-common.hh
vendored
@ -68,8 +68,6 @@ struct code_pair_t
|
||||
typedef hb_vector_t<unsigned char> str_buff_t;
|
||||
struct str_buff_vec_t : hb_vector_t<str_buff_t>
|
||||
{
|
||||
void fini () { SUPER::fini_deep (); }
|
||||
|
||||
unsigned int total_size () const
|
||||
{
|
||||
unsigned int size = 0;
|
||||
|
38
thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
vendored
38
thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
vendored
@ -1144,8 +1144,8 @@ struct cff1
|
||||
{
|
||||
sc.end_processing ();
|
||||
topDict.fini ();
|
||||
fontDicts.fini_deep ();
|
||||
privateDicts.fini_deep ();
|
||||
fontDicts.fini ();
|
||||
privateDicts.fini ();
|
||||
hb_blob_destroy (blob);
|
||||
blob = nullptr;
|
||||
}
|
||||
@ -1245,32 +1245,32 @@ struct cff1
|
||||
}
|
||||
|
||||
protected:
|
||||
hb_blob_t *blob;
|
||||
hb_blob_t *blob = nullptr;
|
||||
hb_sanitize_context_t sc;
|
||||
|
||||
public:
|
||||
const Encoding *encoding;
|
||||
const Charset *charset;
|
||||
const CFF1NameIndex *nameIndex;
|
||||
const CFF1TopDictIndex *topDictIndex;
|
||||
const CFF1StringIndex *stringIndex;
|
||||
const CFF1Subrs *globalSubrs;
|
||||
const CFF1CharStrings *charStrings;
|
||||
const CFF1FDArray *fdArray;
|
||||
const CFF1FDSelect *fdSelect;
|
||||
unsigned int fdCount;
|
||||
const Encoding *encoding = nullptr;
|
||||
const Charset *charset = nullptr;
|
||||
const CFF1NameIndex *nameIndex = nullptr;
|
||||
const CFF1TopDictIndex *topDictIndex = nullptr;
|
||||
const CFF1StringIndex *stringIndex = nullptr;
|
||||
const CFF1Subrs *globalSubrs = nullptr;
|
||||
const CFF1CharStrings *charStrings = nullptr;
|
||||
const CFF1FDArray *fdArray = nullptr;
|
||||
const CFF1FDSelect *fdSelect = nullptr;
|
||||
unsigned int fdCount = 0;
|
||||
|
||||
cff1_top_dict_values_t topDict;
|
||||
hb_vector_t<cff1_font_dict_values_t>
|
||||
fontDicts;
|
||||
hb_vector_t<PRIVDICTVAL> privateDicts;
|
||||
|
||||
unsigned int num_glyphs;
|
||||
unsigned int num_glyphs = 0;
|
||||
};
|
||||
|
||||
struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
SUPER::init (face);
|
||||
|
||||
@ -1295,8 +1295,7 @@ struct cff1
|
||||
}
|
||||
glyph_names.qsort ();
|
||||
}
|
||||
|
||||
void fini ()
|
||||
~accelerator_t ()
|
||||
{
|
||||
glyph_names.fini ();
|
||||
|
||||
@ -1398,7 +1397,10 @@ struct cff1
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct cff1_accelerator_t : cff1::accelerator_t {};
|
||||
struct cff1_accelerator_t : cff1::accelerator_t {
|
||||
cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
#endif /* HB_OT_CFF1_TABLE_HH */
|
||||
|
63
thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
vendored
63
thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
vendored
@ -397,7 +397,7 @@ struct cff2
|
||||
template <typename PRIVOPSET, typename PRIVDICTVAL>
|
||||
struct accelerator_templ_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_templ_t (hb_face_t *face)
|
||||
{
|
||||
topDict.init ();
|
||||
fontDicts.init ();
|
||||
@ -412,15 +412,15 @@ struct cff2
|
||||
const OT::cff2 *cff2 = this->blob->template as<OT::cff2> ();
|
||||
|
||||
if (cff2 == &Null (OT::cff2))
|
||||
{ fini (); return; }
|
||||
goto fail;
|
||||
|
||||
{ /* parse top dict */
|
||||
byte_str_t topDictStr (cff2 + cff2->topDict, cff2->topDictSize);
|
||||
if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
|
||||
if (unlikely (!topDictStr.sanitize (&sc))) goto fail;
|
||||
cff2_top_dict_interpreter_t top_interp;
|
||||
top_interp.env.init (topDictStr);
|
||||
topDict.init ();
|
||||
if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
|
||||
if (unlikely (!top_interp.interpret (topDict))) goto fail;
|
||||
}
|
||||
|
||||
globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize);
|
||||
@ -434,49 +434,55 @@ struct cff2
|
||||
(globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) ||
|
||||
(fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
|
||||
(((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count)))))
|
||||
{ fini (); return; }
|
||||
goto fail;
|
||||
|
||||
num_glyphs = charStrings->count;
|
||||
if (num_glyphs != sc.get_num_glyphs ())
|
||||
{ fini (); return; }
|
||||
goto fail;
|
||||
|
||||
fdCount = fdArray->count;
|
||||
if (!privateDicts.resize (fdCount))
|
||||
{ fini (); return; }
|
||||
goto fail;
|
||||
|
||||
/* parse font dicts and gather private dicts */
|
||||
for (unsigned int i = 0; i < fdCount; i++)
|
||||
{
|
||||
const byte_str_t fontDictStr = (*fdArray)[i];
|
||||
if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
|
||||
if (unlikely (!fontDictStr.sanitize (&sc))) goto fail;
|
||||
cff2_font_dict_values_t *font;
|
||||
cff2_font_dict_interpreter_t font_interp;
|
||||
font_interp.env.init (fontDictStr);
|
||||
font = fontDicts.push ();
|
||||
if (unlikely (font == &Crap (cff2_font_dict_values_t))) { fini (); return; }
|
||||
if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail;
|
||||
font->init ();
|
||||
if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
|
||||
if (unlikely (!font_interp.interpret (*font))) goto fail;
|
||||
|
||||
const byte_str_t privDictStr (StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset), font->privateDictInfo.size);
|
||||
if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
|
||||
if (unlikely (!privDictStr.sanitize (&sc))) goto fail;
|
||||
dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp;
|
||||
priv_interp.env.init(privDictStr);
|
||||
privateDicts[i].init ();
|
||||
if (unlikely (!priv_interp.interpret (privateDicts[i]))) { fini (); return; }
|
||||
if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail;
|
||||
|
||||
privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset);
|
||||
if (privateDicts[i].localSubrs != &Null (CFF2Subrs) &&
|
||||
unlikely (!privateDicts[i].localSubrs->sanitize (&sc)))
|
||||
{ fini (); return; }
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
void fini ()
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
_fini ();
|
||||
}
|
||||
~accelerator_templ_t () { _fini (); }
|
||||
void _fini ()
|
||||
{
|
||||
sc.end_processing ();
|
||||
topDict.fini ();
|
||||
fontDicts.fini_deep ();
|
||||
privateDicts.fini_deep ();
|
||||
fontDicts.fini ();
|
||||
privateDicts.fini ();
|
||||
hb_blob_destroy (blob);
|
||||
blob = nullptr;
|
||||
}
|
||||
@ -484,26 +490,28 @@ struct cff2
|
||||
bool is_valid () const { return blob; }
|
||||
|
||||
protected:
|
||||
hb_blob_t *blob;
|
||||
hb_blob_t *blob = nullptr;
|
||||
hb_sanitize_context_t sc;
|
||||
|
||||
public:
|
||||
cff2_top_dict_values_t topDict;
|
||||
const CFF2Subrs *globalSubrs;
|
||||
const CFF2VariationStore *varStore;
|
||||
const CFF2CharStrings *charStrings;
|
||||
const CFF2FDArray *fdArray;
|
||||
const CFF2FDSelect *fdSelect;
|
||||
unsigned int fdCount;
|
||||
const CFF2Subrs *globalSubrs = nullptr;
|
||||
const CFF2VariationStore *varStore = nullptr;
|
||||
const CFF2CharStrings *charStrings = nullptr;
|
||||
const CFF2FDArray *fdArray = nullptr;
|
||||
const CFF2FDSelect *fdSelect = nullptr;
|
||||
unsigned int fdCount = 0;
|
||||
|
||||
hb_vector_t<cff2_font_dict_values_t> fontDicts;
|
||||
hb_vector_t<PRIVDICTVAL> privateDicts;
|
||||
|
||||
unsigned int num_glyphs;
|
||||
unsigned int num_glyphs = 0;
|
||||
};
|
||||
|
||||
struct accelerator_t : accelerator_templ_t<cff2_private_dict_opset_t, cff2_private_dict_values_t>
|
||||
{
|
||||
accelerator_t (hb_face_t *face) : accelerator_templ_t (face) {}
|
||||
|
||||
HB_INTERNAL bool get_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents) const;
|
||||
@ -525,7 +533,10 @@ struct cff2
|
||||
DEFINE_SIZE_STATIC (5);
|
||||
};
|
||||
|
||||
struct cff2_accelerator_t : cff2::accelerator_t {};
|
||||
struct cff2_accelerator_t : cff2::accelerator_t {
|
||||
cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
#endif /* HB_OT_CFF2_TABLE_HH */
|
||||
|
13
thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
vendored
13
thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
vendored
@ -369,7 +369,6 @@ struct CmapSubtableFormat4
|
||||
{
|
||||
accelerator_t () {}
|
||||
accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); }
|
||||
~accelerator_t () { fini (); }
|
||||
|
||||
void init (const CmapSubtableFormat4 *subtable)
|
||||
{
|
||||
@ -381,7 +380,6 @@ struct CmapSubtableFormat4
|
||||
glyphIdArray = idRangeOffset + segCount;
|
||||
glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
|
||||
}
|
||||
void fini () {}
|
||||
|
||||
bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||
{
|
||||
@ -1607,7 +1605,7 @@ struct cmap
|
||||
unsigned format = (this + _.subtable).u.format;
|
||||
if (format == 12) has_format12 = true;
|
||||
|
||||
const EncodingRecord *table = hb_addressof (_);
|
||||
const EncodingRecord *table = std::addressof (_);
|
||||
if (_.platformID == 0 && _.encodingID == 3) unicode_bmp = table;
|
||||
else if (_.platformID == 0 && _.encodingID == 4) unicode_ucs4 = table;
|
||||
else if (_.platformID == 3 && _.encodingID == 1) ms_bmp = table;
|
||||
@ -1665,7 +1663,7 @@ struct cmap
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
|
||||
bool symbol;
|
||||
@ -1700,8 +1698,7 @@ struct cmap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fini () { this->table.destroy (); }
|
||||
~accelerator_t () { this->table.destroy (); }
|
||||
|
||||
bool get_nominal_glyph (hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph) const
|
||||
@ -1863,7 +1860,9 @@ struct cmap
|
||||
DEFINE_SIZE_ARRAY (4, encodingRecord);
|
||||
};
|
||||
|
||||
struct cmap_accelerator_t : cmap::accelerator_t {};
|
||||
struct cmap_accelerator_t : cmap::accelerator_t {
|
||||
cmap_accelerator_t (hb_face_t *face) : cmap::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
@ -360,6 +360,16 @@ struct IndexSubtable
|
||||
|
||||
struct IndexSubtableRecord
|
||||
{
|
||||
/* XXX Remove this and fix by not inserting it into vector. */
|
||||
IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
|
||||
{
|
||||
firstGlyphIndex = o.firstGlyphIndex;
|
||||
lastGlyphIndex = o.lastGlyphIndex;
|
||||
offsetToSubtable = (unsigned) o.offsetToSubtable;
|
||||
assert (offsetToSubtable.is_null ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
@ -809,15 +819,14 @@ struct CBDT
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
|
||||
cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
|
||||
this->cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
|
||||
this->cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
|
||||
|
||||
upem = hb_face_get_upem (face);
|
||||
}
|
||||
|
||||
void fini ()
|
||||
~accelerator_t ()
|
||||
{
|
||||
this->cblc.destroy ();
|
||||
this->cbdt.destroy ();
|
||||
@ -978,7 +987,10 @@ CBLC::subset (hb_subset_context_t *c) const
|
||||
return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
|
||||
}
|
||||
|
||||
struct CBDT_accelerator_t : CBDT::accelerator_t {};
|
||||
struct CBDT_accelerator_t : CBDT::accelerator_t {
|
||||
CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
@ -71,7 +71,7 @@ struct hb_colrv1_closure_context_t :
|
||||
bool paint_visited (const void *paint)
|
||||
{
|
||||
hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
|
||||
if (visited_paint.has (delta))
|
||||
if (visited_paint.in_error() || visited_paint.has (delta))
|
||||
return true;
|
||||
|
||||
visited_paint.add (delta);
|
||||
@ -1270,13 +1270,9 @@ struct COLR
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
accelerator_t () {}
|
||||
~accelerator_t () { fini (); }
|
||||
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{ colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
|
||||
|
||||
void fini () { this->colr.destroy (); }
|
||||
~accelerator_t () { this->colr.destroy (); }
|
||||
|
||||
bool is_valid () { return colr.get_blob ()->length; }
|
||||
|
||||
@ -1535,6 +1531,10 @@ struct COLR
|
||||
DEFINE_SIZE_MIN (14);
|
||||
};
|
||||
|
||||
struct COLR_accelerator_t : COLR::accelerator_t {
|
||||
COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) con
|
||||
const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
|
||||
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
|
||||
{
|
||||
const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i];
|
||||
const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
|
||||
paint.dispatch (c);
|
||||
}
|
||||
}
|
||||
|
@ -202,12 +202,12 @@ struct sbix
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
table = hb_sanitize_context_t ().reference_table<sbix> (face);
|
||||
num_glyphs = face->get_num_glyphs ();
|
||||
}
|
||||
void fini () { table.destroy (); }
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
bool has_data () const { return table->has_data (); }
|
||||
|
||||
@ -407,7 +407,10 @@ struct sbix
|
||||
DEFINE_SIZE_ARRAY (8, strikes);
|
||||
};
|
||||
|
||||
struct sbix_accelerator_t : sbix::accelerator_t {};
|
||||
struct sbix_accelerator_t : sbix::accelerator_t {
|
||||
sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
@ -79,9 +79,9 @@ struct SVG
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{ table = hb_sanitize_context_t ().reference_table<SVG> (face); }
|
||||
void fini () { table.destroy (); }
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
|
||||
{
|
||||
@ -116,7 +116,9 @@ struct SVG
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
};
|
||||
|
||||
struct SVG_accelerator_t : SVG::accelerator_t {};
|
||||
struct SVG_accelerator_t : SVG::accelerator_t {
|
||||
SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
12
thirdparty/harfbuzz/src/hb-ot-color.cc
vendored
12
thirdparty/harfbuzz/src/hb-ot-color.cc
vendored
@ -90,15 +90,15 @@ hb_ot_color_palette_get_count (hb_face_t *face)
|
||||
/**
|
||||
* hb_ot_color_palette_get_name_id:
|
||||
* @face: #hb_face_t to work upon
|
||||
* @palette_index: The index of the color palette
|
||||
* @palette_index: The index of the color palette
|
||||
*
|
||||
* Fetches the `name` table Name ID that provides display names for
|
||||
* a `CPAL` color palette.
|
||||
* a `CPAL` color palette.
|
||||
*
|
||||
* Palette display names can be generic (e.g., "Default") or provide
|
||||
* specific, themed names (e.g., "Spring", "Summer", "Fall", and "Winter").
|
||||
*
|
||||
* Return value: the Named ID found for the palette.
|
||||
* Return value: the Named ID found for the palette.
|
||||
* If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID.
|
||||
*
|
||||
* Since: 2.1.0
|
||||
@ -116,7 +116,7 @@ hb_ot_color_palette_get_name_id (hb_face_t *face,
|
||||
* @color_index: The index of the color
|
||||
*
|
||||
* Fetches the `name` table Name ID that provides display names for
|
||||
* the specificed color in a face's `CPAL` color palette.
|
||||
* the specified color in a face's `CPAL` color palette.
|
||||
*
|
||||
* Display names can be generic (e.g., "Background") or specific
|
||||
* (e.g., "Eye color").
|
||||
@ -256,6 +256,8 @@ hb_ot_color_has_svg (hb_face_t *face)
|
||||
*
|
||||
* Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.
|
||||
*
|
||||
* If the glyph has no SVG document, the singleton empty blob is returned.
|
||||
*
|
||||
* Return value: (transfer full): An #hb_blob_t containing the SVG document of the glyph, if available
|
||||
*
|
||||
* Since: 2.1.0
|
||||
@ -296,6 +298,8 @@ hb_ot_color_has_png (hb_face_t *face)
|
||||
* as input. To get an optimally sized PNG blob, the UPEM value must be set on the @font
|
||||
* object. If UPEM is unset, the blob returned will be the largest PNG available.
|
||||
*
|
||||
* If the glyph has no PNG image, the singleton empty blob is returned.
|
||||
*
|
||||
* Return value: (transfer full): An #hb_blob_t containing the PNG image for the glyph, if available
|
||||
*
|
||||
* Since: 2.1.0
|
||||
|
17
thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
vendored
17
thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
vendored
@ -207,8 +207,7 @@ struct glyf
|
||||
_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
||||
hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const
|
||||
{
|
||||
OT::glyf::accelerator_t glyf;
|
||||
glyf.init (plan->source);
|
||||
OT::glyf::accelerator_t glyf (plan->source);
|
||||
|
||||
+ hb_range (plan->num_output_glyphs ())
|
||||
| hb_map ([&] (hb_codepoint_t new_gid)
|
||||
@ -233,8 +232,6 @@ struct glyf
|
||||
})
|
||||
| hb_sink (glyphs)
|
||||
;
|
||||
|
||||
glyf.fini ();
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -595,7 +592,7 @@ struct glyf
|
||||
if (unlikely (!header.numberOfContours)) return;
|
||||
|
||||
unsigned flags_offset = length (instructions_length ());
|
||||
if (unlikely (length (flags_offset + 1) > bytes.length)) return;
|
||||
if (unlikely (flags_offset + 1 > bytes.length)) return;
|
||||
|
||||
HBUINT8 &first_flag = (HBUINT8 &) StructAtOffset<HBUINT16> (&bytes, flags_offset);
|
||||
first_flag = (uint8_t) first_flag | FLAG_OVERLAP_SIMPLE;
|
||||
@ -920,7 +917,7 @@ struct glyf
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face_)
|
||||
accelerator_t (hb_face_t *face_)
|
||||
{
|
||||
short_offset = false;
|
||||
num_glyphs = 0;
|
||||
@ -953,8 +950,7 @@ struct glyf
|
||||
num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
|
||||
num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
|
||||
}
|
||||
|
||||
void fini ()
|
||||
~accelerator_t ()
|
||||
{
|
||||
loca_table.destroy ();
|
||||
glyf_table.destroy ();
|
||||
@ -1358,7 +1354,10 @@ struct glyf
|
||||
* defining it _MIN instead. */
|
||||
};
|
||||
|
||||
struct glyf_accelerator_t : glyf::accelerator_t {};
|
||||
struct glyf_accelerator_t : glyf::accelerator_t {
|
||||
glyf_accelerator_t (hb_face_t *face) : glyf::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
20
thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
vendored
20
thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
vendored
@ -127,8 +127,7 @@ struct hmtxvmtx
|
||||
T *table_prime = c->serializer->start_embed <T> ();
|
||||
if (unlikely (!table_prime)) return_trace (false);
|
||||
|
||||
accelerator_t _mtx;
|
||||
_mtx.init (c->plan->source);
|
||||
accelerator_t _mtx (c->plan->source);
|
||||
unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
|
||||
|
||||
auto it =
|
||||
@ -144,8 +143,6 @@ struct hmtxvmtx
|
||||
|
||||
table_prime->serialize (c->serializer, it, num_advances);
|
||||
|
||||
_mtx.fini ();
|
||||
|
||||
if (unlikely (c->serializer->in_error ()))
|
||||
return_trace (false);
|
||||
|
||||
@ -160,8 +157,8 @@ struct hmtxvmtx
|
||||
{
|
||||
friend struct hmtxvmtx;
|
||||
|
||||
void init (hb_face_t *face,
|
||||
unsigned int default_advance_ = 0)
|
||||
accelerator_t (hb_face_t *face,
|
||||
unsigned int default_advance_ = 0)
|
||||
{
|
||||
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
|
||||
|
||||
@ -193,8 +190,7 @@ struct hmtxvmtx
|
||||
|
||||
var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
|
||||
}
|
||||
|
||||
void fini ()
|
||||
~accelerator_t ()
|
||||
{
|
||||
table.destroy ();
|
||||
var_table.destroy ();
|
||||
@ -338,8 +334,12 @@ struct vmtx : hmtxvmtx<vmtx, vhea> {
|
||||
static constexpr bool is_horizontal = false;
|
||||
};
|
||||
|
||||
struct hmtx_accelerator_t : hmtx::accelerator_t {};
|
||||
struct vmtx_accelerator_t : vmtx::accelerator_t {};
|
||||
struct hmtx_accelerator_t : hmtx::accelerator_t {
|
||||
hmtx_accelerator_t (hb_face_t *face) : hmtx::accelerator_t (face) {}
|
||||
};
|
||||
struct vmtx_accelerator_t : vmtx::accelerator_t {
|
||||
vmtx_accelerator_t (hb_face_t *face) : vmtx::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
21
thirdparty/harfbuzz/src/hb-ot-layout-common.hh
vendored
21
thirdparty/harfbuzz/src/hb-ot-layout-common.hh
vendored
@ -128,7 +128,7 @@ struct hb_prune_langsys_context_t
|
||||
bool visited (const T *p, hb_set_t &visited_set)
|
||||
{
|
||||
hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table);
|
||||
if (visited_set.has (delta))
|
||||
if (visited_set.in_error () || visited_set.has (delta))
|
||||
return true;
|
||||
|
||||
visited_set.add (delta);
|
||||
@ -655,7 +655,6 @@ struct LangSys
|
||||
void collect_features (hb_prune_langsys_context_t *c) const
|
||||
{
|
||||
if (!has_required_feature () && !get_feature_count ()) return;
|
||||
if (c->visitedLangsys (this)) return;
|
||||
if (has_required_feature () &&
|
||||
c->duplicate_feature_map->has (reqFeatureIndex))
|
||||
c->new_feature_indexes->add (get_required_feature_index ());
|
||||
@ -750,11 +749,15 @@ struct Script
|
||||
{
|
||||
//only collect features from non-redundant langsys
|
||||
const LangSys& d = get_default_lang_sys ();
|
||||
d.collect_features (c);
|
||||
if (!c->visitedLangsys (&d)) {
|
||||
d.collect_features (c);
|
||||
}
|
||||
|
||||
for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
|
||||
{
|
||||
|
||||
const LangSys& l = this+_.first.offset;
|
||||
if (c->visitedLangsys (&l)) continue;
|
||||
if (l.compare (d, c->duplicate_feature_map)) continue;
|
||||
|
||||
l.collect_features (c);
|
||||
@ -766,6 +769,7 @@ struct Script
|
||||
for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
|
||||
{
|
||||
const LangSys& l = this+_.first.offset;
|
||||
if (c->visitedLangsys (&l)) continue;
|
||||
l.collect_features (c);
|
||||
c->script_langsys_map->get (script_index)->add (_.second);
|
||||
}
|
||||
@ -845,7 +849,7 @@ struct FeatureParamsSize
|
||||
if (unlikely (!c->check_struct (this))) return_trace (false);
|
||||
|
||||
/* This subtable has some "history", if you will. Some earlier versions of
|
||||
* Adobe tools calculated the offset of the FeatureParams sutable from the
|
||||
* Adobe tools calculated the offset of the FeatureParams subtable from the
|
||||
* beginning of the FeatureList table! Now, that is dealt with in the
|
||||
* Feature implementation. But we still need to be able to tell junk from
|
||||
* real data. Note: We don't check that the nameID actually exists.
|
||||
@ -2926,8 +2930,6 @@ struct VariationStore
|
||||
|
||||
hb_vector_t<hb_inc_bimap_t> inner_maps;
|
||||
inner_maps.resize ((unsigned) dataSets.len);
|
||||
for (unsigned i = 0; i < inner_maps.length; i++)
|
||||
inner_maps[i].init ();
|
||||
|
||||
for (unsigned idx : c->plan->layout_variation_indices->iter ())
|
||||
{
|
||||
@ -2935,18 +2937,11 @@ struct VariationStore
|
||||
uint16_t minor = idx & 0xFFFF;
|
||||
|
||||
if (major >= inner_maps.length)
|
||||
{
|
||||
for (unsigned i = 0; i < inner_maps.length; i++)
|
||||
inner_maps[i].fini ();
|
||||
return_trace (false);
|
||||
}
|
||||
inner_maps[major].add (minor);
|
||||
}
|
||||
varstore_prime->serialize (c->serializer, this, inner_maps.as_array ());
|
||||
|
||||
for (unsigned i = 0; i < inner_maps.length; i++)
|
||||
inner_maps[i].fini ();
|
||||
|
||||
return_trace (
|
||||
!c->serializer->in_error()
|
||||
&& varstore_prime->dataSets);
|
||||
|
@ -585,17 +585,16 @@ struct GDEF
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
this->table = hb_sanitize_context_t ().reference_table<GDEF> (face);
|
||||
if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
|
||||
table = hb_sanitize_context_t ().reference_table<GDEF> (face);
|
||||
if (unlikely (table->is_blocklisted (table.get_blob (), face)))
|
||||
{
|
||||
hb_blob_destroy (this->table.get_blob ());
|
||||
this->table = hb_blob_get_empty ();
|
||||
hb_blob_destroy (table.get_blob ());
|
||||
table = hb_blob_get_empty ();
|
||||
}
|
||||
}
|
||||
|
||||
void fini () { this->table.destroy (); }
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
hb_blob_ptr_t<GDEF> table;
|
||||
};
|
||||
@ -715,7 +714,9 @@ struct GDEF
|
||||
DEFINE_SIZE_MIN (12);
|
||||
};
|
||||
|
||||
struct GDEF_accelerator_t : GDEF::accelerator_t {};
|
||||
struct GDEF_accelerator_t : GDEF::accelerator_t {
|
||||
GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
172
thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
vendored
172
thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
vendored
@ -706,7 +706,7 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Coverage or
|
||||
|
||||
float mark_x, mark_y, base_x, base_y;
|
||||
|
||||
buffer->unsafe_to_break (glyph_pos, buffer->idx);
|
||||
buffer->unsafe_to_break (glyph_pos, buffer->idx + 1);
|
||||
mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
|
||||
glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
|
||||
|
||||
@ -1235,6 +1235,7 @@ struct PairSet
|
||||
buffer->idx = pos;
|
||||
return_trace (true);
|
||||
}
|
||||
buffer->unsafe_to_concat (buffer->idx, pos + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
@ -1362,7 +1363,12 @@ struct PairPosFormat1
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
if (!skippy_iter.next ()) return_trace (false);
|
||||
unsigned unsafe_to;
|
||||
if (!skippy_iter.next (&unsafe_to))
|
||||
{
|
||||
buffer->unsafe_to_concat (buffer->idx, unsafe_to);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx));
|
||||
}
|
||||
@ -1555,7 +1561,12 @@ struct PairPosFormat2
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
if (!skippy_iter.next ()) return_trace (false);
|
||||
unsigned unsafe_to;
|
||||
if (!skippy_iter.next (&unsafe_to))
|
||||
{
|
||||
buffer->unsafe_to_concat (buffer->idx, unsafe_to);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned int len1 = valueFormat1.get_len ();
|
||||
unsigned int len2 = valueFormat2.get_len ();
|
||||
@ -1563,13 +1574,81 @@ struct PairPosFormat2
|
||||
|
||||
unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
|
||||
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
|
||||
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
|
||||
if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
|
||||
{
|
||||
buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
|
||||
bool applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
|
||||
bool applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
|
||||
|
||||
bool applied_first = false, applied_second = false;
|
||||
|
||||
|
||||
/* Isolate simple kerning and apply it half to each side.
|
||||
* Results in better cursor positinoing / underline drawing. */
|
||||
{
|
||||
if (!len2)
|
||||
{
|
||||
const hb_direction_t dir = buffer->props.direction;
|
||||
const bool horizontal = HB_DIRECTION_IS_HORIZONTAL (dir);
|
||||
const bool backward = HB_DIRECTION_IS_BACKWARD (dir);
|
||||
unsigned mask = horizontal ? ValueFormat::xAdvance : ValueFormat::yAdvance;
|
||||
if (backward)
|
||||
mask |= mask >> 2; /* Add eg. xPlacement in RTL. */
|
||||
/* Add Devices. */
|
||||
mask |= mask << 4;
|
||||
|
||||
if (valueFormat1 & ~mask)
|
||||
goto bail;
|
||||
|
||||
/* Is simple kern. Apply value on an empty position slot,
|
||||
* then split it between sides. */
|
||||
|
||||
hb_glyph_position_t pos{};
|
||||
if (valueFormat1.apply_value (c, this, v, pos))
|
||||
{
|
||||
hb_position_t *src = &pos.x_advance;
|
||||
hb_position_t *dst1 = &buffer->cur_pos().x_advance;
|
||||
hb_position_t *dst2 = &buffer->pos[skippy_iter.idx].x_advance;
|
||||
unsigned i = horizontal ? 0 : 1;
|
||||
|
||||
hb_position_t kern = src[i];
|
||||
hb_position_t kern1 = kern >> 1;
|
||||
hb_position_t kern2 = kern - kern1;
|
||||
|
||||
if (!backward)
|
||||
{
|
||||
dst1[i] += kern1;
|
||||
dst2[i] += kern2;
|
||||
dst2[i + 2] += kern2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst1[i] += kern1;
|
||||
dst1[i + 2] += src[i + 2] - kern2;
|
||||
dst2[i] += kern2;
|
||||
}
|
||||
|
||||
applied_first = applied_second = kern != 0;
|
||||
goto success;
|
||||
}
|
||||
goto boring;
|
||||
}
|
||||
}
|
||||
bail:
|
||||
|
||||
|
||||
applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
|
||||
applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
|
||||
|
||||
success:
|
||||
if (applied_first || applied_second)
|
||||
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
|
||||
else
|
||||
boring:
|
||||
buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
|
||||
|
||||
|
||||
buffer->idx = skippy_iter.idx;
|
||||
if (len2)
|
||||
@ -1799,10 +1878,19 @@ struct CursivePosFormat1
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
if (!skippy_iter.prev ()) return_trace (false);
|
||||
unsigned unsafe_from;
|
||||
if (!skippy_iter.prev (&unsafe_from))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
|
||||
if (!prev_record.exitAnchor) return_trace (false);
|
||||
if (!prev_record.exitAnchor)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned int i = skippy_iter.idx;
|
||||
unsigned int j = buffer->idx;
|
||||
@ -2066,7 +2154,13 @@ struct MarkBasePosFormat1
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
|
||||
do {
|
||||
if (!skippy_iter.prev ()) return_trace (false);
|
||||
unsigned unsafe_from;
|
||||
if (!skippy_iter.prev (&unsafe_from))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
/* We only want to attach to the first of a MultipleSubst sequence.
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/740
|
||||
* Reject others...
|
||||
@ -2089,7 +2183,11 @@ struct MarkBasePosFormat1
|
||||
//if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); }
|
||||
|
||||
unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint);
|
||||
if (base_index == NOT_COVERED) return_trace (false);
|
||||
if (base_index == NOT_COVERED)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
|
||||
}
|
||||
@ -2320,21 +2418,34 @@ struct MarkLigPosFormat1
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
|
||||
if (!skippy_iter.prev ()) return_trace (false);
|
||||
unsigned unsafe_from;
|
||||
if (!skippy_iter.prev (&unsafe_from))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
/* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
|
||||
//if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); }
|
||||
|
||||
unsigned int j = skippy_iter.idx;
|
||||
unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint);
|
||||
if (lig_index == NOT_COVERED) return_trace (false);
|
||||
if (lig_index == NOT_COVERED)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
const LigatureArray& lig_array = this+ligatureArray;
|
||||
const LigatureAttach& lig_attach = lig_array[lig_index];
|
||||
|
||||
/* Find component to attach to */
|
||||
unsigned int comp_count = lig_attach.rows;
|
||||
if (unlikely (!comp_count)) return_trace (false);
|
||||
if (unlikely (!comp_count))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
/* We must now check whether the ligature ID of the current mark glyph
|
||||
* is identical to the ligature ID of the found ligature. If yes, we
|
||||
@ -2517,9 +2628,18 @@ struct MarkMarkPosFormat1
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
|
||||
if (!skippy_iter.prev ()) return_trace (false);
|
||||
unsigned unsafe_from;
|
||||
if (!skippy_iter.prev (&unsafe_from))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); }
|
||||
if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned int j = skippy_iter.idx;
|
||||
|
||||
@ -2544,11 +2664,16 @@ struct MarkMarkPosFormat1
|
||||
}
|
||||
|
||||
/* Didn't match. */
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
|
||||
good:
|
||||
unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint);
|
||||
if (mark2_index == NOT_COVERED) return_trace (false);
|
||||
if (mark2_index == NOT_COVERED)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
|
||||
}
|
||||
@ -2951,7 +3076,7 @@ GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer H
|
||||
}
|
||||
|
||||
void
|
||||
GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||
GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
_hb_buffer_assert_gsubgpos_vars (buffer);
|
||||
|
||||
@ -2961,12 +3086,21 @@ GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||
|
||||
/* Handle attachments */
|
||||
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
propagate_attachment_offsets (pos, len, i, direction);
|
||||
|
||||
if (unlikely (font->slant))
|
||||
{
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if (unlikely (pos[i].y_offset))
|
||||
pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct GPOS_accelerator_t : GPOS::accelerator_t {};
|
||||
struct GPOS_accelerator_t : GPOS::accelerator_t {
|
||||
GPOS_accelerator_t (hb_face_t *face) : GPOS::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
/* Out-of-class implementation for methods recursing */
|
||||
|
@ -826,22 +826,25 @@ struct Ligature
|
||||
|
||||
unsigned int total_component_count = 0;
|
||||
|
||||
unsigned int match_length = 0;
|
||||
unsigned int match_end = 0;
|
||||
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
|
||||
|
||||
if (likely (!match_input (c, count,
|
||||
&component[1],
|
||||
match_glyph,
|
||||
nullptr,
|
||||
&match_length,
|
||||
&match_end,
|
||||
match_positions,
|
||||
&total_component_count)))
|
||||
{
|
||||
c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
ligate_input (c,
|
||||
count,
|
||||
match_positions,
|
||||
match_length,
|
||||
match_end,
|
||||
ligGlyph,
|
||||
total_component_count);
|
||||
|
||||
@ -1296,7 +1299,7 @@ struct ReverseChainSingleSubstFormat1
|
||||
match_lookahead (c,
|
||||
lookahead.len, (HBUINT16 *) lookahead.arrayZ,
|
||||
match_coverage, this,
|
||||
1, &end_index))
|
||||
c->buffer->idx + 1, &end_index))
|
||||
{
|
||||
c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
|
||||
c->replace_glyph_inplace (substitute[index]);
|
||||
@ -1305,8 +1308,11 @@ struct ReverseChainSingleSubstFormat1
|
||||
* calls us through a Context lookup. */
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
return_trace (false);
|
||||
else
|
||||
{
|
||||
c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Iterator,
|
||||
@ -1739,7 +1745,9 @@ struct GSUB : GSUBGPOS
|
||||
};
|
||||
|
||||
|
||||
struct GSUB_accelerator_t : GSUB::accelerator_t {};
|
||||
struct GSUB_accelerator_t : GSUB::accelerator_t {
|
||||
GSUB_accelerator_t (hb_face_t *face) : GSUB::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
/* Out-of-class implementation for methods recursing */
|
||||
|
304
thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
vendored
304
thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
vendored
@ -125,24 +125,31 @@ struct hb_closure_context_t :
|
||||
hb_set_t *covered_glyph_set = done_lookups_glyph_set->get (lookup_index);
|
||||
if (unlikely (covered_glyph_set->in_error ()))
|
||||
return true;
|
||||
if (parent_active_glyphs ()->is_subset (*covered_glyph_set))
|
||||
if (parent_active_glyphs ().is_subset (*covered_glyph_set))
|
||||
return true;
|
||||
|
||||
hb_set_union (covered_glyph_set, parent_active_glyphs ());
|
||||
covered_glyph_set->union_ (parent_active_glyphs ());
|
||||
return false;
|
||||
}
|
||||
|
||||
hb_set_t* parent_active_glyphs ()
|
||||
const hb_set_t& previous_parent_active_glyphs () {
|
||||
if (active_glyphs_stack.length <= 1)
|
||||
return *glyphs;
|
||||
|
||||
return active_glyphs_stack[active_glyphs_stack.length - 2];
|
||||
}
|
||||
|
||||
const hb_set_t& parent_active_glyphs ()
|
||||
{
|
||||
if (active_glyphs_stack.length < 1)
|
||||
return glyphs;
|
||||
if (!active_glyphs_stack)
|
||||
return *glyphs;
|
||||
|
||||
return active_glyphs_stack.tail ();
|
||||
}
|
||||
|
||||
void push_cur_active_glyphs (hb_set_t* cur_active_glyph_set)
|
||||
hb_set_t& push_cur_active_glyphs ()
|
||||
{
|
||||
active_glyphs_stack.push (cur_active_glyph_set);
|
||||
return *active_glyphs_stack.push ();
|
||||
}
|
||||
|
||||
bool pop_cur_done_glyphs ()
|
||||
@ -156,29 +163,24 @@ struct hb_closure_context_t :
|
||||
|
||||
hb_face_t *face;
|
||||
hb_set_t *glyphs;
|
||||
hb_set_t *cur_intersected_glyphs;
|
||||
hb_set_t output[1];
|
||||
hb_vector_t<hb_set_t *> active_glyphs_stack;
|
||||
hb_vector_t<hb_set_t> active_glyphs_stack;
|
||||
recurse_func_t recurse_func;
|
||||
unsigned int nesting_level_left;
|
||||
|
||||
hb_closure_context_t (hb_face_t *face_,
|
||||
hb_set_t *glyphs_,
|
||||
hb_set_t *cur_intersected_glyphs_,
|
||||
hb_map_t *done_lookups_glyph_count_,
|
||||
hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_,
|
||||
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
|
||||
face (face_),
|
||||
glyphs (glyphs_),
|
||||
cur_intersected_glyphs (cur_intersected_glyphs_),
|
||||
recurse_func (nullptr),
|
||||
nesting_level_left (nesting_level_left_),
|
||||
done_lookups_glyph_count (done_lookups_glyph_count_),
|
||||
done_lookups_glyph_set (done_lookups_glyph_set_),
|
||||
lookup_count (0)
|
||||
{
|
||||
push_cur_active_glyphs (glyphs_);
|
||||
}
|
||||
{}
|
||||
|
||||
~hb_closure_context_t () { flush (); }
|
||||
|
||||
@ -186,11 +188,11 @@ struct hb_closure_context_t :
|
||||
|
||||
void flush ()
|
||||
{
|
||||
hb_set_del_range (output, face->get_num_glyphs (), HB_SET_VALUE_INVALID); /* Remove invalid glyphs. */
|
||||
hb_set_union (glyphs, output);
|
||||
hb_set_clear (output);
|
||||
output->del_range (face->get_num_glyphs (), HB_SET_VALUE_INVALID); /* Remove invalid glyphs. */
|
||||
glyphs->union_ (*output);
|
||||
output->clear ();
|
||||
active_glyphs_stack.pop ();
|
||||
active_glyphs_stack.fini ();
|
||||
active_glyphs_stack.reset ();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -520,7 +522,7 @@ struct hb_ot_apply_context_t :
|
||||
may_skip (const hb_glyph_info_t &info) const
|
||||
{ return matcher.may_skip (c, info); }
|
||||
|
||||
bool next ()
|
||||
bool next (unsigned *unsafe_to = nullptr)
|
||||
{
|
||||
assert (num_items > 0);
|
||||
while (idx + num_items < end)
|
||||
@ -543,11 +545,17 @@ struct hb_ot_apply_context_t :
|
||||
}
|
||||
|
||||
if (skip == matcher_t::SKIP_NO)
|
||||
{
|
||||
if (unsafe_to)
|
||||
*unsafe_to = idx + 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (unsafe_to)
|
||||
*unsafe_to = end;
|
||||
return false;
|
||||
}
|
||||
bool prev ()
|
||||
bool prev (unsigned *unsafe_from = nullptr)
|
||||
{
|
||||
assert (num_items > 0);
|
||||
while (idx > num_items - 1)
|
||||
@ -570,8 +578,14 @@ struct hb_ot_apply_context_t :
|
||||
}
|
||||
|
||||
if (skip == matcher_t::SKIP_NO)
|
||||
{
|
||||
if (unsafe_from)
|
||||
*unsafe_from = hb_max (1u, idx) - 1u;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (unsafe_from)
|
||||
*unsafe_from = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -712,53 +726,60 @@ struct hb_ot_apply_context_t :
|
||||
return true;
|
||||
}
|
||||
|
||||
void _set_glyph_props (hb_codepoint_t glyph_index,
|
||||
void _set_glyph_class (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess = 0,
|
||||
bool ligature = false,
|
||||
bool component = false) const
|
||||
{
|
||||
unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
|
||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
|
||||
unsigned int props = _hb_glyph_info_get_glyph_props (&buffer->cur());
|
||||
props |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
|
||||
if (ligature)
|
||||
{
|
||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
|
||||
props |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
|
||||
/* In the only place that the MULTIPLIED bit is used, Uniscribe
|
||||
* seems to only care about the "last" transformation between
|
||||
* Ligature and Multiple substitutions. Ie. if you ligate, expand,
|
||||
* and ligate again, it forgives the multiplication and acts as
|
||||
* if only ligation happened. As such, clear MULTIPLIED bit.
|
||||
*/
|
||||
add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||
props &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||
}
|
||||
if (component)
|
||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||
props |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||
if (likely (has_glyph_classes))
|
||||
_hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
|
||||
{
|
||||
props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
|
||||
_hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef.get_glyph_props (glyph_index));
|
||||
}
|
||||
else if (class_guess)
|
||||
_hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
|
||||
{
|
||||
props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
|
||||
_hb_glyph_info_set_glyph_props (&buffer->cur(), props | class_guess);
|
||||
}
|
||||
else
|
||||
_hb_glyph_info_set_glyph_props (&buffer->cur(), props);
|
||||
}
|
||||
|
||||
void replace_glyph (hb_codepoint_t glyph_index) const
|
||||
{
|
||||
_set_glyph_props (glyph_index);
|
||||
_set_glyph_class (glyph_index);
|
||||
(void) buffer->replace_glyph (glyph_index);
|
||||
}
|
||||
void replace_glyph_inplace (hb_codepoint_t glyph_index) const
|
||||
{
|
||||
_set_glyph_props (glyph_index);
|
||||
_set_glyph_class (glyph_index);
|
||||
buffer->cur().codepoint = glyph_index;
|
||||
}
|
||||
void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess) const
|
||||
{
|
||||
_set_glyph_props (glyph_index, class_guess, true);
|
||||
_set_glyph_class (glyph_index, class_guess, true);
|
||||
(void) buffer->replace_glyph (glyph_index);
|
||||
}
|
||||
void output_glyph_for_component (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess) const
|
||||
{
|
||||
_set_glyph_props (glyph_index, class_guess, false, true);
|
||||
_set_glyph_class (glyph_index, class_guess, false, true);
|
||||
(void) buffer->output_glyph (glyph_index);
|
||||
}
|
||||
};
|
||||
@ -948,7 +969,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
|
||||
const HBUINT16 input[], /* Array of input values--start with second glyph */
|
||||
match_func_t match_func,
|
||||
const void *match_data,
|
||||
unsigned int *end_offset,
|
||||
unsigned int *end_position,
|
||||
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
|
||||
unsigned int *p_total_component_count = nullptr)
|
||||
{
|
||||
@ -1001,7 +1022,12 @@ static inline bool match_input (hb_ot_apply_context_t *c,
|
||||
match_positions[0] = buffer->idx;
|
||||
for (unsigned int i = 1; i < count; i++)
|
||||
{
|
||||
if (!skippy_iter.next ()) return_trace (false);
|
||||
unsigned unsafe_to;
|
||||
if (!skippy_iter.next (&unsafe_to))
|
||||
{
|
||||
*end_position = unsafe_to;
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
match_positions[i] = skippy_iter.idx;
|
||||
|
||||
@ -1055,7 +1081,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
|
||||
total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
|
||||
}
|
||||
|
||||
*end_offset = skippy_iter.idx - buffer->idx + 1;
|
||||
*end_position = skippy_iter.idx + 1;
|
||||
|
||||
if (p_total_component_count)
|
||||
*p_total_component_count = total_component_count;
|
||||
@ -1065,7 +1091,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
|
||||
static inline bool ligate_input (hb_ot_apply_context_t *c,
|
||||
unsigned int count, /* Including the first glyph */
|
||||
const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
|
||||
unsigned int match_length,
|
||||
unsigned int match_end,
|
||||
hb_codepoint_t lig_glyph,
|
||||
unsigned int total_component_count)
|
||||
{
|
||||
@ -1073,7 +1099,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
|
||||
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
|
||||
buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
|
||||
buffer->merge_clusters (buffer->idx, match_end);
|
||||
|
||||
/* - If a base and one or more marks ligate, consider that as a base, NOT
|
||||
* ligature, such that all following marks can still attach to it.
|
||||
@ -1190,11 +1216,16 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c,
|
||||
skippy_iter.set_match_func (match_func, match_data, backtrack);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!skippy_iter.prev ())
|
||||
{
|
||||
unsigned unsafe_from;
|
||||
if (!skippy_iter.prev (&unsafe_from))
|
||||
{
|
||||
*match_start = unsafe_from;
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
*match_start = skippy_iter.idx;
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
@ -1203,21 +1234,26 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c,
|
||||
const HBUINT16 lookahead[],
|
||||
match_func_t match_func,
|
||||
const void *match_data,
|
||||
unsigned int offset,
|
||||
unsigned int start_index,
|
||||
unsigned int *end_index)
|
||||
{
|
||||
TRACE_APPLY (nullptr);
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
|
||||
skippy_iter.reset (c->buffer->idx + offset - 1, count);
|
||||
skippy_iter.reset (start_index - 1, count);
|
||||
skippy_iter.set_match_func (match_func, match_data, lookahead);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!skippy_iter.next ())
|
||||
{
|
||||
unsigned unsafe_to;
|
||||
if (!skippy_iter.next (&unsafe_to))
|
||||
{
|
||||
*end_index = unsafe_to;
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
*end_index = skippy_iter.idx + 1;
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
@ -1284,22 +1320,23 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
|
||||
unsigned seqIndex = lookupRecord[i].sequenceIndex;
|
||||
if (seqIndex >= inputCount) continue;
|
||||
|
||||
hb_set_t *pos_glyphs = nullptr;
|
||||
bool has_pos_glyphs = false;
|
||||
hb_set_t pos_glyphs;
|
||||
|
||||
if (hb_set_is_empty (covered_seq_indicies) || !hb_set_has (covered_seq_indicies, seqIndex))
|
||||
{
|
||||
pos_glyphs = hb_set_create ();
|
||||
has_pos_glyphs = true;
|
||||
if (seqIndex == 0)
|
||||
{
|
||||
switch (context_format) {
|
||||
case ContextFormat::SimpleContext:
|
||||
pos_glyphs->add (value);
|
||||
pos_glyphs.add (value);
|
||||
break;
|
||||
case ContextFormat::ClassBasedContext:
|
||||
intersected_glyphs_func (c->cur_intersected_glyphs, data, value, pos_glyphs);
|
||||
intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs);
|
||||
break;
|
||||
case ContextFormat::CoverageBasedContext:
|
||||
hb_set_set (pos_glyphs, c->cur_intersected_glyphs);
|
||||
pos_glyphs.set (c->parent_active_glyphs ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1313,12 +1350,16 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
|
||||
input_value = input[seqIndex - 1];
|
||||
}
|
||||
|
||||
intersected_glyphs_func (c->glyphs, input_data, input_value, pos_glyphs);
|
||||
intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs);
|
||||
}
|
||||
}
|
||||
|
||||
hb_set_add (covered_seq_indicies, seqIndex);
|
||||
c->push_cur_active_glyphs (pos_glyphs ? pos_glyphs : c->glyphs);
|
||||
covered_seq_indicies->add (seqIndex);
|
||||
if (has_pos_glyphs) {
|
||||
c->push_cur_active_glyphs () = pos_glyphs;
|
||||
} else {
|
||||
c->push_cur_active_glyphs ().set (*c->glyphs);
|
||||
}
|
||||
|
||||
unsigned endIndex = inputCount;
|
||||
if (context_format == ContextFormat::CoverageBasedContext)
|
||||
@ -1327,8 +1368,6 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
|
||||
c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex);
|
||||
|
||||
c->pop_cur_done_glyphs ();
|
||||
if (pos_glyphs)
|
||||
hb_set_destroy (pos_glyphs);
|
||||
}
|
||||
|
||||
hb_set_destroy (covered_seq_indicies);
|
||||
@ -1343,15 +1382,13 @@ static inline void recurse_lookups (context_t *c,
|
||||
c->recurse (lookupRecord[i].lookupListIndex);
|
||||
}
|
||||
|
||||
static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
||||
static inline void apply_lookup (hb_ot_apply_context_t *c,
|
||||
unsigned int count, /* Including the first glyph */
|
||||
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
|
||||
unsigned int lookupCount,
|
||||
const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
|
||||
unsigned int match_length)
|
||||
unsigned int match_end)
|
||||
{
|
||||
TRACE_APPLY (nullptr);
|
||||
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
int end;
|
||||
|
||||
@ -1359,7 +1396,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
||||
* Adjust. */
|
||||
{
|
||||
unsigned int bl = buffer->backtrack_len ();
|
||||
end = bl + match_length;
|
||||
end = bl + match_end - buffer->idx;
|
||||
|
||||
int delta = bl - buffer->idx;
|
||||
/* Convert positions to new indexing. */
|
||||
@ -1461,8 +1498,6 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
||||
}
|
||||
|
||||
(void) buffer->move_to (end);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
||||
@ -1550,17 +1585,25 @@ static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
|
||||
const LookupRecord lookupRecord[],
|
||||
ContextApplyLookupContext &lookup_context)
|
||||
{
|
||||
unsigned int match_length = 0;
|
||||
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
|
||||
return match_input (c,
|
||||
inputCount, input,
|
||||
lookup_context.funcs.match, lookup_context.match_data,
|
||||
&match_length, match_positions)
|
||||
&& (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length),
|
||||
apply_lookup (c,
|
||||
inputCount, match_positions,
|
||||
lookupCount, lookupRecord,
|
||||
match_length));
|
||||
unsigned match_end = 0;
|
||||
unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
|
||||
if (match_input (c,
|
||||
inputCount, input,
|
||||
lookup_context.funcs.match, lookup_context.match_data,
|
||||
&match_end, match_positions))
|
||||
{
|
||||
c->buffer->unsafe_to_break (c->buffer->idx, match_end);
|
||||
apply_lookup (c,
|
||||
inputCount, match_positions,
|
||||
lookupCount, lookupRecord,
|
||||
match_end);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct Rule
|
||||
@ -1828,8 +1871,9 @@ struct ContextFormat1
|
||||
|
||||
void closure (hb_closure_context_t *c) const
|
||||
{
|
||||
c->cur_intersected_glyphs->clear ();
|
||||
get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
|
||||
hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
|
||||
get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
|
||||
cur_active_glyphs);
|
||||
|
||||
struct ContextClosureLookupContext lookup_context = {
|
||||
{intersects_glyph, intersected_glyph},
|
||||
@ -1838,10 +1882,14 @@ struct ContextFormat1
|
||||
};
|
||||
|
||||
+ hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
|
||||
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||
| hb_filter ([&] (hb_codepoint_t _) {
|
||||
return c->previous_parent_active_glyphs ().has (_);
|
||||
}, hb_first)
|
||||
| hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const RuleSet&> (_.first, this+ruleSet[_.second]); })
|
||||
| hb_apply ([&] (const hb_pair_t<unsigned, const RuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
|
||||
;
|
||||
|
||||
c->pop_cur_done_glyphs ();
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||
@ -1989,8 +2037,9 @@ struct ContextFormat2
|
||||
if (!(this+coverage).intersects (c->glyphs))
|
||||
return;
|
||||
|
||||
c->cur_intersected_glyphs->clear ();
|
||||
get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
|
||||
hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
|
||||
get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
|
||||
cur_active_glyphs);
|
||||
|
||||
const ClassDef &class_def = this+classDef;
|
||||
|
||||
@ -2000,10 +2049,9 @@ struct ContextFormat2
|
||||
&class_def
|
||||
};
|
||||
|
||||
return
|
||||
+ hb_enumerate (ruleSet)
|
||||
| hb_filter ([&] (unsigned _)
|
||||
{ return class_def.intersects_class (c->cur_intersected_glyphs, _); },
|
||||
{ return class_def.intersects_class (&c->parent_active_glyphs (), _); },
|
||||
hb_first)
|
||||
| hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<RuleSet>&> _)
|
||||
{
|
||||
@ -2011,6 +2059,8 @@ struct ContextFormat2
|
||||
rule_set.closure (c, _.first, lookup_context);
|
||||
})
|
||||
;
|
||||
|
||||
c->pop_cur_done_glyphs ();
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||
@ -2183,8 +2233,10 @@ struct ContextFormat3
|
||||
if (!(this+coverageZ[0]).intersects (c->glyphs))
|
||||
return;
|
||||
|
||||
c->cur_intersected_glyphs->clear ();
|
||||
get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
|
||||
hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
|
||||
get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
|
||||
cur_active_glyphs);
|
||||
|
||||
|
||||
const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
|
||||
struct ContextClosureLookupContext lookup_context = {
|
||||
@ -2196,6 +2248,8 @@ struct ContextFormat3
|
||||
glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
|
||||
lookupCount, lookupRecord,
|
||||
0, lookup_context);
|
||||
|
||||
c->pop_cur_done_glyphs ();
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||
@ -2452,25 +2506,38 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
|
||||
const LookupRecord lookupRecord[],
|
||||
ChainContextApplyLookupContext &lookup_context)
|
||||
{
|
||||
unsigned int start_index = 0, match_length = 0, end_index = 0;
|
||||
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
|
||||
return match_input (c,
|
||||
inputCount, input,
|
||||
lookup_context.funcs.match, lookup_context.match_data[1],
|
||||
&match_length, match_positions)
|
||||
&& match_backtrack (c,
|
||||
backtrackCount, backtrack,
|
||||
lookup_context.funcs.match, lookup_context.match_data[0],
|
||||
&start_index)
|
||||
&& match_lookahead (c,
|
||||
lookaheadCount, lookahead,
|
||||
lookup_context.funcs.match, lookup_context.match_data[2],
|
||||
match_length, &end_index)
|
||||
&& (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
|
||||
apply_lookup (c,
|
||||
inputCount, match_positions,
|
||||
lookupCount, lookupRecord,
|
||||
match_length));
|
||||
unsigned end_index = c->buffer->idx;
|
||||
unsigned match_end = 0;
|
||||
unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
|
||||
if (!(match_input (c,
|
||||
inputCount, input,
|
||||
lookup_context.funcs.match, lookup_context.match_data[1],
|
||||
&match_end, match_positions) && (end_index = match_end)
|
||||
&& match_lookahead (c,
|
||||
lookaheadCount, lookahead,
|
||||
lookup_context.funcs.match, lookup_context.match_data[2],
|
||||
match_end, &end_index)))
|
||||
{
|
||||
c->buffer->unsafe_to_concat (c->buffer->idx, end_index);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned start_index = c->buffer->out_len;
|
||||
if (!match_backtrack (c,
|
||||
backtrackCount, backtrack,
|
||||
lookup_context.funcs.match, lookup_context.match_data[0],
|
||||
&start_index))
|
||||
{
|
||||
c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
|
||||
return false;
|
||||
}
|
||||
|
||||
c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
|
||||
apply_lookup (c,
|
||||
inputCount, match_positions,
|
||||
lookupCount, lookupRecord,
|
||||
match_end);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct ChainRule
|
||||
@ -2802,8 +2869,9 @@ struct ChainContextFormat1
|
||||
|
||||
void closure (hb_closure_context_t *c) const
|
||||
{
|
||||
c->cur_intersected_glyphs->clear ();
|
||||
get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
|
||||
hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
|
||||
get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
|
||||
cur_active_glyphs);
|
||||
|
||||
struct ChainContextClosureLookupContext lookup_context = {
|
||||
{intersects_glyph, intersected_glyph},
|
||||
@ -2812,10 +2880,14 @@ struct ChainContextFormat1
|
||||
};
|
||||
|
||||
+ hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
|
||||
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||
| hb_filter ([&] (hb_codepoint_t _) {
|
||||
return c->previous_parent_active_glyphs ().has (_);
|
||||
}, hb_first)
|
||||
| hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const ChainRuleSet&> (_.first, this+ruleSet[_.second]); })
|
||||
| hb_apply ([&] (const hb_pair_t<unsigned, const ChainRuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
|
||||
;
|
||||
|
||||
c->pop_cur_done_glyphs ();
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||
@ -2964,8 +3036,10 @@ struct ChainContextFormat2
|
||||
if (!(this+coverage).intersects (c->glyphs))
|
||||
return;
|
||||
|
||||
c->cur_intersected_glyphs->clear ();
|
||||
get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
|
||||
hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
|
||||
get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
|
||||
cur_active_glyphs);
|
||||
|
||||
|
||||
const ClassDef &backtrack_class_def = this+backtrackClassDef;
|
||||
const ClassDef &input_class_def = this+inputClassDef;
|
||||
@ -2979,10 +3053,9 @@ struct ChainContextFormat2
|
||||
&lookahead_class_def}
|
||||
};
|
||||
|
||||
return
|
||||
+ hb_enumerate (ruleSet)
|
||||
| hb_filter ([&] (unsigned _)
|
||||
{ return input_class_def.intersects_class (c->cur_intersected_glyphs, _); },
|
||||
{ return input_class_def.intersects_class (&c->parent_active_glyphs (), _); },
|
||||
hb_first)
|
||||
| hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<ChainRuleSet>&> _)
|
||||
{
|
||||
@ -2990,6 +3063,8 @@ struct ChainContextFormat2
|
||||
chainrule_set.closure (c, _.first, lookup_context);
|
||||
})
|
||||
;
|
||||
|
||||
c->pop_cur_done_glyphs ();
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||
@ -3216,8 +3291,10 @@ struct ChainContextFormat3
|
||||
if (!(this+input[0]).intersects (c->glyphs))
|
||||
return;
|
||||
|
||||
c->cur_intersected_glyphs->clear ();
|
||||
get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
|
||||
hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
|
||||
get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
|
||||
cur_active_glyphs);
|
||||
|
||||
|
||||
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input);
|
||||
const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead);
|
||||
@ -3232,6 +3309,8 @@ struct ChainContextFormat3
|
||||
lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
|
||||
lookup.len, lookup.arrayZ,
|
||||
0, lookup_context);
|
||||
|
||||
c->pop_cur_done_glyphs ();
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||
@ -3706,7 +3785,7 @@ struct GSUBGPOS
|
||||
for (unsigned i : feature_indices->iter ())
|
||||
{
|
||||
hb_tag_t t = get_feature_tag (i);
|
||||
if (t == unique_features.INVALID_KEY) continue;
|
||||
if (t == HB_MAP_VALUE_INVALID) continue;
|
||||
if (!unique_features.has (t))
|
||||
{
|
||||
hb_set_t* indices = hb_set_create ();
|
||||
@ -3839,7 +3918,7 @@ struct GSUBGPOS
|
||||
template <typename T>
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
this->table = hb_sanitize_context_t ().reference_table<T> (face);
|
||||
if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
|
||||
@ -3861,8 +3940,7 @@ struct GSUBGPOS
|
||||
for (unsigned int i = 0; i < this->lookup_count; i++)
|
||||
this->accels[i].init (table->get_lookup (i));
|
||||
}
|
||||
|
||||
void fini ()
|
||||
~accelerator_t ()
|
||||
{
|
||||
for (unsigned int i = 0; i < this->lookup_count; i++)
|
||||
this->accels[i].fini ();
|
||||
|
8
thirdparty/harfbuzz/src/hb-ot-layout.cc
vendored
8
thirdparty/harfbuzz/src/hb-ot-layout.cc
vendored
@ -1491,10 +1491,9 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs /* OUT */)
|
||||
{
|
||||
hb_set_t cur_intersected_glyphs;
|
||||
hb_map_t done_lookups_glyph_count;
|
||||
hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
|
||||
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
|
||||
OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
|
||||
|
||||
const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
|
||||
|
||||
@ -1520,10 +1519,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
|
||||
const hb_set_t *lookups,
|
||||
hb_set_t *glyphs /* OUT */)
|
||||
{
|
||||
hb_set_t cur_intersected_glyphs;
|
||||
hb_map_t done_lookups_glyph_count;
|
||||
hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
|
||||
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
|
||||
OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
|
||||
const OT::GSUB& gsub = *face->table.GSUB->table;
|
||||
|
||||
unsigned int iteration_count = 0;
|
||||
@ -1890,7 +1888,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
||||
apply_forward (c, accel);
|
||||
|
||||
if (!Proxy::inplace)
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
5
thirdparty/harfbuzz/src/hb-ot-layout.hh
vendored
5
thirdparty/harfbuzz/src/hb-ot-layout.hh
vendored
@ -482,10 +482,9 @@ _hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
_hb_allocate_lig_id (hb_buffer_t *buffer) {
|
||||
_hb_allocate_lig_id (hb_buffer_t *buffer)
|
||||
{
|
||||
uint8_t lig_id = buffer->next_serial () & 0x07;
|
||||
if (unlikely (!lig_id))
|
||||
lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
|
||||
return lig_id;
|
||||
}
|
||||
|
||||
|
8
thirdparty/harfbuzz/src/hb-ot-meta-table.hh
vendored
8
thirdparty/harfbuzz/src/hb-ot-meta-table.hh
vendored
@ -71,9 +71,9 @@ struct meta
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{ table = hb_sanitize_context_t ().reference_table<meta> (face); }
|
||||
void fini () { table.destroy (); }
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
hb_blob_t *reference_entry (hb_tag_t tag) const
|
||||
{ return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
|
||||
@ -119,7 +119,9 @@ struct meta
|
||||
DEFINE_SIZE_ARRAY (16, dataMaps);
|
||||
};
|
||||
|
||||
struct meta_accelerator_t : meta::accelerator_t {};
|
||||
struct meta_accelerator_t : meta::accelerator_t {
|
||||
meta_accelerator_t (hb_face_t *face) : meta::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
45
thirdparty/harfbuzz/src/hb-ot-metrics.cc
vendored
45
thirdparty/harfbuzz/src/hb-ot-metrics.cc
vendored
@ -160,9 +160,50 @@ hb_ot_metrics_get_position (hb_font_t *font,
|
||||
(position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent);
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise);
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun);
|
||||
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
|
||||
{
|
||||
unsigned mult = 1u;
|
||||
|
||||
if (font->slant)
|
||||
{
|
||||
unsigned rise = face->table.hhea->caretSlopeRise;
|
||||
unsigned upem = face->get_upem ();
|
||||
mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u;
|
||||
}
|
||||
|
||||
if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE)
|
||||
{
|
||||
bool ret = GET_METRIC_Y (hhea, caretSlopeRise);
|
||||
|
||||
if (position)
|
||||
*position *= mult;
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_position_t rise = 0;
|
||||
|
||||
if (font->slant && position && GET_METRIC_Y (hhea, caretSlopeRise))
|
||||
rise = *position;
|
||||
|
||||
bool ret = GET_METRIC_X (hhea, caretSlopeRun);
|
||||
|
||||
if (position)
|
||||
{
|
||||
*position *= mult;
|
||||
|
||||
if (font->slant)
|
||||
*position += _hb_roundf (mult * font->slant_xy * rise);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
|
||||
|
||||
#ifndef HB_NO_VERTICAL
|
||||
case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
|
||||
case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);
|
||||
|
13
thirdparty/harfbuzz/src/hb-ot-name-table.hh
vendored
13
thirdparty/harfbuzz/src/hb-ot-name-table.hh
vendored
@ -256,7 +256,7 @@ struct name
|
||||
})
|
||||
;
|
||||
|
||||
name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset));
|
||||
name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset));
|
||||
return_trace (name_prime->count);
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ struct name
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
this->table = hb_sanitize_context_t ().reference_table<name> (face);
|
||||
assert (this->table.get_length () >= this->table->stringOffset);
|
||||
@ -288,7 +288,6 @@ struct name
|
||||
const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
|
||||
this->table->count);
|
||||
|
||||
this->names.init ();
|
||||
this->names.alloc (all_names.length);
|
||||
|
||||
for (unsigned int i = 0; i < all_names.length; i++)
|
||||
@ -318,10 +317,8 @@ struct name
|
||||
}
|
||||
this->names.resize (j);
|
||||
}
|
||||
|
||||
void fini ()
|
||||
~accelerator_t ()
|
||||
{
|
||||
this->names.fini ();
|
||||
this->table.destroy ();
|
||||
}
|
||||
|
||||
@ -373,7 +370,9 @@ struct name
|
||||
#undef entry_index
|
||||
#undef entry_score
|
||||
|
||||
struct name_accelerator_t : name::accelerator_t {};
|
||||
struct name_accelerator_t : name::accelerator_t {
|
||||
name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
@ -76,8 +76,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
|
||||
hb_map_t old_new_index_map, old_gid_new_index_map;
|
||||
unsigned i = 0;
|
||||
|
||||
post::accelerator_t _post;
|
||||
_post.init (c->plan->source);
|
||||
post::accelerator_t _post (c->plan->source);
|
||||
|
||||
hb_hashmap_t<hb_bytes_t, unsigned, std::nullptr_t, unsigned, nullptr, (unsigned)-1> glyph_name_to_new_index;
|
||||
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
|
||||
@ -128,9 +127,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
|
||||
})
|
||||
;
|
||||
|
||||
bool ret = serialize (c->serializer, index_iter, &_post);
|
||||
_post.fini ();
|
||||
return_trace (ret);
|
||||
return_trace (serialize (c->serializer, index_iter, &_post));
|
||||
}
|
||||
|
||||
} /* namespace OT */
|
||||
|
17
thirdparty/harfbuzz/src/hb-ot-post-table.hh
vendored
17
thirdparty/harfbuzz/src/hb-ot-post-table.hh
vendored
@ -111,10 +111,9 @@ struct post
|
||||
struct accelerator_t
|
||||
{
|
||||
friend struct postV2Tail;
|
||||
void init (hb_face_t *face)
|
||||
{
|
||||
index_to_offset.init ();
|
||||
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
table = hb_sanitize_context_t ().reference_table<post> (face);
|
||||
unsigned int table_length = table.get_length ();
|
||||
|
||||
@ -132,9 +131,8 @@ struct post
|
||||
data += 1 + *data)
|
||||
index_to_offset.push (data - pool);
|
||||
}
|
||||
void fini ()
|
||||
~accelerator_t ()
|
||||
{
|
||||
index_to_offset.fini ();
|
||||
hb_free (gids_sorted_by_name.get ());
|
||||
table.destroy ();
|
||||
}
|
||||
@ -254,9 +252,9 @@ struct post
|
||||
|
||||
private:
|
||||
uint32_t version;
|
||||
const Array16Of<HBUINT16> *glyphNameIndex;
|
||||
const Array16Of<HBUINT16> *glyphNameIndex = nullptr;
|
||||
hb_vector_t<uint32_t> index_to_offset;
|
||||
const uint8_t *pool;
|
||||
const uint8_t *pool = nullptr;
|
||||
hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
|
||||
};
|
||||
|
||||
@ -307,7 +305,10 @@ struct post
|
||||
DEFINE_SIZE_MIN (32);
|
||||
};
|
||||
|
||||
struct post_accelerator_t : post::accelerator_t {};
|
||||
struct post_accelerator_t : post::accelerator_t {
|
||||
post_accelerator_t (hb_face_t *face) : post::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
@ -87,6 +87,8 @@
|
||||
|
||||
#define OT_GLYPHID /* GlyphID */ \
|
||||
OT_UINT16
|
||||
/* Shorthand. */
|
||||
#define G OT_GLYPHID
|
||||
|
||||
#define OT_UARRAY(Name, Items) \
|
||||
OT_LABEL_START(Name) \
|
||||
@ -183,8 +185,6 @@
|
||||
Tag \
|
||||
OT_OFFSET(manifest, Name)
|
||||
|
||||
/* Shorthand. */
|
||||
#define G OT_GLYPHID
|
||||
|
||||
/*
|
||||
* Table Start
|
||||
@ -300,14 +300,40 @@ OT_TABLE_END
|
||||
/*
|
||||
* Clean up
|
||||
*/
|
||||
|
||||
#undef MANIFEST
|
||||
#undef MANIFEST_LOOKUP
|
||||
|
||||
#undef OT_TABLE_START
|
||||
#undef OT_TABLE_END
|
||||
#undef OT_LABEL_START
|
||||
#undef OT_LABEL_END
|
||||
#undef OT_UINT8
|
||||
#undef OT_UINT16
|
||||
#undef OT_DISTANCE
|
||||
#undef OT_COUNT
|
||||
#undef OT_DISTANCE
|
||||
|
||||
#undef OT_LABEL
|
||||
#undef OT_LIST
|
||||
|
||||
#undef OT_TAG
|
||||
#undef OT_OFFSET
|
||||
#undef OT_GLYPHID
|
||||
#undef G
|
||||
#undef OT_UARRAY
|
||||
#undef OT_UHEADLESSARRAY
|
||||
|
||||
#undef OT_LOOKUP_FLAG_IGNORE_MARKS
|
||||
#undef OT_LOOKUP
|
||||
#undef OT_SUBLOOKUP
|
||||
#undef OT_COVERAGE1
|
||||
#undef OT_LOOKUP_TYPE_SUBST_SINGLE
|
||||
#undef OT_LOOKUP_TYPE_SUBST_LIGATURE
|
||||
#undef OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2
|
||||
#undef OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1
|
||||
#undef OT_LIGATURE_SET
|
||||
#undef OT_LIGATURE
|
||||
|
||||
|
||||
/*
|
||||
* Include a second time to get the table data...
|
||||
|
@ -321,6 +321,20 @@ arabic_joining (hb_buffer_t *buffer)
|
||||
info[prev].arabic_shaping_action() = entry->prev_action;
|
||||
buffer->unsafe_to_break (prev, i + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prev == UINT_MAX)
|
||||
{
|
||||
if (this_type >= JOINING_TYPE_R)
|
||||
buffer->unsafe_to_concat_from_outbuffer (0, i + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this_type >= JOINING_TYPE_R ||
|
||||
(2 <= state && state <= 5) /* States that have a possible prev_action. */)
|
||||
buffer->unsafe_to_concat (prev, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
info[i].arabic_shaping_action() = entry->curr_action;
|
||||
|
||||
@ -337,7 +351,14 @@ arabic_joining (hb_buffer_t *buffer)
|
||||
|
||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||
if (entry->prev_action != NONE && prev != UINT_MAX)
|
||||
{
|
||||
info[prev].arabic_shaping_action() = entry->prev_action;
|
||||
buffer->unsafe_to_break (prev, buffer->len);
|
||||
}
|
||||
else if (2 <= state && state <= 5) /* States that have a possible prev_action. */
|
||||
{
|
||||
buffer->unsafe_to_concat (prev, buffer->len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
*
|
||||
* - LV can be precomposed, or decomposed. Lets call those
|
||||
* <LV> and <L,V>,
|
||||
* - LVT can be fully precomposed, partically precomposed, or
|
||||
* - LVT can be fully precomposed, partially precomposed, or
|
||||
* fully decomposed. Ie. <LVT>, <LV,T>, or <L,V,T>.
|
||||
*
|
||||
* The composition / decomposition is mechanical. However, not
|
||||
@ -392,7 +392,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
*/
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -96,7 +96,7 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
|
||||
else
|
||||
(void) buffer->next_glyph ();
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -364,7 +364,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
|
||||
buffer->merge_out_clusters (start - 1, end);
|
||||
}
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
|
||||
/* If font has Thai GSUB, we are done. */
|
||||
if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
|
||||
|
@ -435,7 +435,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
|
||||
|
||||
|
19
thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
vendored
19
thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
vendored
@ -446,6 +446,9 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!buffer->message (font, "start fallback mark"))
|
||||
return;
|
||||
|
||||
_hb_buffer_assert_gsubgpos_vars (buffer);
|
||||
|
||||
unsigned int start = 0;
|
||||
@ -457,6 +460,8 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
|
||||
start = i;
|
||||
}
|
||||
position_cluster (plan, font, buffer, start, count, adjust_offsets_when_zeroing);
|
||||
|
||||
(void) buffer->message (font, "end fallback mark");
|
||||
}
|
||||
|
||||
|
||||
@ -492,6 +497,9 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||
#endif
|
||||
|
||||
#ifndef HB_DISABLE_DEPRECATED
|
||||
if (!buffer->message (font, "start fallback kern"))
|
||||
return;
|
||||
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
|
||||
!font->has_glyph_h_kerning_func () :
|
||||
!font->has_glyph_v_kerning_func ())
|
||||
@ -508,6 +516,8 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||
|
||||
if (reverse)
|
||||
buffer->reverse ();
|
||||
|
||||
(void) buffer->message (font, "end fallback kern");
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -525,6 +535,15 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&info[i]))
|
||||
{
|
||||
/* If font had no ASCII space and we used the invisible glyph, give it a 1/4 EM default advance. */
|
||||
if (buffer->invisible && info[i].codepoint == buffer->invisible)
|
||||
{
|
||||
if (horizontal)
|
||||
pos[i].x_advance = +font->x_scale / 4;
|
||||
else
|
||||
pos[i].y_advance = -font->y_scale / 4;
|
||||
}
|
||||
|
||||
hb_unicode_funcs_t::space_t space_type = _hb_glyph_info_get_unicode_space_fallback_type (&info[i]);
|
||||
hb_codepoint_t glyph;
|
||||
typedef hb_unicode_funcs_t t;
|
||||
|
@ -193,7 +193,8 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
|
||||
{
|
||||
hb_codepoint_t space_glyph;
|
||||
hb_unicode_funcs_t::space_t space_type = buffer->unicode->space_fallback_type (u);
|
||||
if (space_type != hb_unicode_funcs_t::NOT_SPACE && c->font->get_nominal_glyph (0x0020u, &space_glyph))
|
||||
if (space_type != hb_unicode_funcs_t::NOT_SPACE &&
|
||||
(c->font->get_nominal_glyph (0x0020, &space_glyph) || (space_glyph = buffer->invisible)))
|
||||
{
|
||||
_hb_glyph_info_set_unicode_space_fallback_type (&buffer->cur(), space_type);
|
||||
next_char (buffer, space_glyph);
|
||||
@ -374,7 +375,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||
decompose_multi_char_cluster (&c, end, always_short_circuit);
|
||||
}
|
||||
while (buffer->idx < count && buffer->successful);
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
|
||||
|
||||
@ -477,7 +478,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||
if (info_cc (buffer->prev()) == 0)
|
||||
starter = buffer->out_len - 1;
|
||||
}
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
}
|
||||
|
||||
|
29
thirdparty/harfbuzz/src/hb-ot-shape.cc
vendored
29
thirdparty/harfbuzz/src/hb-ot-shape.cc
vendored
@ -566,7 +566,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
|
||||
info.mask = buffer->cur().mask;
|
||||
(void) buffer->output_info (info);
|
||||
|
||||
buffer->swap_buffers ();
|
||||
buffer->sync ();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1034,7 +1034,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
|
||||
* hanging over the next glyph after the final reordering.
|
||||
*
|
||||
* Note: If fallback positinoing happens, we don't care about
|
||||
* this as it will be overriden.
|
||||
* this as it will be overridden.
|
||||
*/
|
||||
bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
|
||||
HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
|
||||
@ -1120,7 +1120,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
|
||||
/* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
|
||||
* Simplifies using them. */
|
||||
|
||||
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK))
|
||||
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS))
|
||||
return;
|
||||
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
@ -1129,11 +1129,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
|
||||
{
|
||||
mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
|
||||
break;
|
||||
}
|
||||
mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED;
|
||||
if (mask)
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
info[i].mask |= mask;
|
||||
@ -1145,18 +1141,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
|
||||
static void
|
||||
hb_ot_shape_internal (hb_ot_shape_context_t *c)
|
||||
{
|
||||
c->buffer->deallocate_var_all ();
|
||||
c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
|
||||
if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR)))
|
||||
{
|
||||
c->buffer->max_len = hb_max (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
|
||||
(unsigned) HB_BUFFER_MAX_LEN_MIN);
|
||||
}
|
||||
if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR)))
|
||||
{
|
||||
c->buffer->max_ops = hb_max (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
|
||||
(unsigned) HB_BUFFER_MAX_OPS_MIN);
|
||||
}
|
||||
c->buffer->enter ();
|
||||
|
||||
/* Save the original direction, we use it later. */
|
||||
c->target_direction = c->buffer->props.direction;
|
||||
@ -1188,9 +1173,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
|
||||
|
||||
c->buffer->props.direction = c->target_direction;
|
||||
|
||||
c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
|
||||
c->buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
|
||||
c->buffer->deallocate_var_all ();
|
||||
c->buffer->leave ();
|
||||
}
|
||||
|
||||
|
||||
|
97
thirdparty/harfbuzz/src/hb-ot-tag-table.hh
vendored
97
thirdparty/harfbuzz/src/hb-ot-tag-table.hh
vendored
@ -6,8 +6,8 @@
|
||||
*
|
||||
* on files with these headers:
|
||||
*
|
||||
* <meta name="updated_at" content="2021-12-09 12:01 AM" />
|
||||
* File-Date: 2021-08-06
|
||||
* <meta name="updated_at" content="2022-01-28 10:00 PM" />
|
||||
* File-Date: 2021-12-29
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_TAG_TABLE_HH
|
||||
@ -66,7 +66,7 @@ static const LangTag ot_languages[] = {
|
||||
{"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
|
||||
/*{"ang", HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */
|
||||
{"aoa", HB_TAG('C','P','P',' ')}, /* Angolar -> Creoles */
|
||||
{"apa", HB_TAG('A','T','H',' ')}, /* Apache [family] -> Athapaskan */
|
||||
{"apa", HB_TAG('A','T','H',' ')}, /* Apache [collection] -> Athapaskan */
|
||||
{"apc", HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */
|
||||
{"apd", HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */
|
||||
{"apj", HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */
|
||||
@ -86,7 +86,7 @@ static const LangTag ot_languages[] = {
|
||||
{"arz", HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */
|
||||
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
|
||||
/*{"ast", HB_TAG('A','S','T',' ')},*/ /* Asturian */
|
||||
/*{"ath", HB_TAG('A','T','H',' ')},*/ /* Athapascan [family] -> Athapaskan */
|
||||
/*{"ath", HB_TAG('A','T','H',' ')},*/ /* Athapascan [collection] -> Athapaskan */
|
||||
{"atj", HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */
|
||||
{"atv", HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */
|
||||
{"auj", HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */
|
||||
@ -110,10 +110,10 @@ static const LangTag ot_languages[] = {
|
||||
{"azn", HB_TAG('N','A','H',' ')}, /* Western Durango Nahuatl -> Nahuatl */
|
||||
{"azz", HB_TAG('N','A','H',' ')}, /* Highland Puebla Nahuatl -> Nahuatl */
|
||||
{"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
|
||||
{"bad", HB_TAG('B','A','D','0')}, /* Banda [family] */
|
||||
{"bad", HB_TAG('B','A','D','0')}, /* Banda [collection] */
|
||||
{"bag", HB_TAG_NONE }, /* Tuki != Baghelkhandi */
|
||||
{"bah", HB_TAG('C','P','P',' ')}, /* Bahamas Creole English -> Creoles */
|
||||
{"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
|
||||
{"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [collection] */
|
||||
{"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */
|
||||
/*{"ban", HB_TAG('B','A','N',' ')},*/ /* Balinese */
|
||||
/*{"bar", HB_TAG('B','A','R',' ')},*/ /* Bavarian */
|
||||
@ -135,7 +135,7 @@ static const LangTag ot_languages[] = {
|
||||
{"bea", HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */
|
||||
{"beb", HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */
|
||||
/*{"bem", HB_TAG('B','E','M',' ')},*/ /* Bemba (Zambia) */
|
||||
{"ber", HB_TAG('B','B','R',' ')}, /* Berber [family] */
|
||||
{"ber", HB_TAG('B','B','R',' ')}, /* Berber [collection] */
|
||||
{"bew", HB_TAG('C','P','P',' ')}, /* Betawi -> Creoles */
|
||||
{"bfl", HB_TAG('B','A','D','0')}, /* Banda-Ndélé -> Banda */
|
||||
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
|
||||
@ -203,7 +203,7 @@ static const LangTag ot_languages[] = {
|
||||
{"btd", HB_TAG('B','T','K',' ')}, /* Batak Dairi -> Batak */
|
||||
{"bti", HB_TAG_NONE }, /* Burate != Beti */
|
||||
{"btj", HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */
|
||||
/*{"btk", HB_TAG('B','T','K',' ')},*/ /* Batak [family] */
|
||||
/*{"btk", HB_TAG('B','T','K',' ')},*/ /* Batak [collection] */
|
||||
{"btm", HB_TAG('B','T','M',' ')}, /* Batak Mandailing */
|
||||
{"btm", HB_TAG('B','T','K',' ')}, /* Batak Mandailing -> Batak */
|
||||
{"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */
|
||||
@ -256,6 +256,8 @@ static const LangTag ot_languages[] = {
|
||||
{"chh", HB_TAG_NONE }, /* Chinook != Chattisgarhi */
|
||||
{"chj", HB_TAG('C','C','H','N')}, /* Ojitlán Chinantec -> Chinantec */
|
||||
{"chk", HB_TAG('C','H','K','0')}, /* Chuukese */
|
||||
{"chm", HB_TAG('H','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> High Mari */
|
||||
{"chm", HB_TAG('L','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> Low Mari */
|
||||
{"chn", HB_TAG('C','P','P',' ')}, /* Chinook jargon -> Creoles */
|
||||
/*{"cho", HB_TAG('C','H','O',' ')},*/ /* Choctaw */
|
||||
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
|
||||
@ -297,10 +299,10 @@ static const LangTag ot_languages[] = {
|
||||
/*{"cop", HB_TAG('C','O','P',' ')},*/ /* Coptic */
|
||||
{"coq", HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */
|
||||
{"cpa", HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */
|
||||
{"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [family] -> Creoles */
|
||||
{"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [family] -> Creoles */
|
||||
{"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [collection] -> Creoles */
|
||||
{"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [collection] -> Creoles */
|
||||
{"cpi", HB_TAG('C','P','P',' ')}, /* Chinese Pidgin English -> Creoles */
|
||||
/*{"cpp", HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [family] -> Creoles */
|
||||
/*{"cpp", HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [collection] -> Creoles */
|
||||
{"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese, Simplified */
|
||||
{"cqd", HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */
|
||||
{"cqu", HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */
|
||||
@ -320,7 +322,7 @@ static const LangTag ot_languages[] = {
|
||||
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
|
||||
{"crm", HB_TAG('L','C','R',' ')}, /* Moose Cree -> L-Cree */
|
||||
{"crm", HB_TAG('C','R','E',' ')}, /* Moose Cree -> Cree */
|
||||
{"crp", HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [family] -> Creoles */
|
||||
{"crp", HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [collection] -> Creoles */
|
||||
{"crr", HB_TAG_NONE }, /* Carolina Algonquian != Carrier */
|
||||
{"crs", HB_TAG('C','P','P',' ')}, /* Seselwa Creole French -> Creoles */
|
||||
{"crt", HB_TAG_NONE }, /* Iyojwa'ja Chorote != Crimean Tatar */
|
||||
@ -431,7 +433,7 @@ static const LangTag ot_languages[] = {
|
||||
{"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
|
||||
{"eto", HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */
|
||||
{"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
|
||||
{"euq", HB_TAG_NONE }, /* Basque [family] != Basque */
|
||||
{"euq", HB_TAG_NONE }, /* Basque [collection] != Basque */
|
||||
{"eve", HB_TAG('E','V','N',' ')}, /* Even */
|
||||
{"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
|
||||
{"ewo", HB_TAG('B','T','I',' ')}, /* Ewondo -> Beti */
|
||||
@ -620,10 +622,11 @@ static const LangTag ot_languages[] = {
|
||||
{"ijc", HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */
|
||||
{"ije", HB_TAG('I','J','O',' ')}, /* Biseni -> Ijo */
|
||||
{"ijn", HB_TAG('I','J','O',' ')}, /* Kalabari -> Ijo */
|
||||
/*{"ijo", HB_TAG('I','J','O',' ')},*/ /* Ijo [family] */
|
||||
/*{"ijo", HB_TAG('I','J','O',' ')},*/ /* Ijo [collection] */
|
||||
{"ijs", HB_TAG('I','J','O',' ')}, /* Southeast Ijo -> Ijo */
|
||||
{"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] -> Inupiat */
|
||||
{"ike", HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */
|
||||
{"ike", HB_TAG('I','N','U','K')}, /* Eastern Canadian Inuktitut -> Nunavik Inuktitut */
|
||||
{"ikt", HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */
|
||||
/*{"ilo", HB_TAG('I','L','O',' ')},*/ /* Iloko -> Ilokano */
|
||||
{"in", HB_TAG('I','N','D',' ')}, /* Indonesian (retired code) */
|
||||
@ -638,6 +641,7 @@ static const LangTag ot_languages[] = {
|
||||
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
|
||||
{"itz", HB_TAG('M','Y','N',' ')}, /* Itzá -> Mayan */
|
||||
{"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
|
||||
{"iu", HB_TAG('I','N','U','K')}, /* Inuktitut [macrolanguage] -> Nunavik Inuktitut */
|
||||
{"iw", HB_TAG('I','W','R',' ')}, /* Hebrew (retired code) */
|
||||
{"ixl", HB_TAG('M','Y','N',' ')}, /* Ixil -> Mayan */
|
||||
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
|
||||
@ -667,7 +671,7 @@ static const LangTag ot_languages[] = {
|
||||
{"kab", HB_TAG('B','B','R',' ')}, /* Kabyle -> Berber */
|
||||
{"kac", HB_TAG_NONE }, /* Kachin != Kachchi */
|
||||
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
|
||||
{"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
|
||||
{"kar", HB_TAG('K','R','N',' ')}, /* Karen [collection] */
|
||||
/*{"kaw", HB_TAG('K','A','W',' ')},*/ /* Kawi (Old Javanese) */
|
||||
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
|
||||
{"kby", HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */
|
||||
@ -876,7 +880,7 @@ static const LangTag ot_languages[] = {
|
||||
{"mam", HB_TAG('M','A','M',' ')}, /* Mam */
|
||||
{"mam", HB_TAG('M','Y','N',' ')}, /* Mam -> Mayan */
|
||||
{"man", HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */
|
||||
{"map", HB_TAG_NONE }, /* Austronesian [family] != Mapudungun */
|
||||
{"map", HB_TAG_NONE }, /* Austronesian [collection] != Mapudungun */
|
||||
{"maw", HB_TAG_NONE }, /* Mampruli != Marwari */
|
||||
{"max", HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */
|
||||
{"max", HB_TAG('C','P','P',' ')}, /* North Moluccan Malay -> Creoles */
|
||||
@ -936,6 +940,7 @@ static const LangTag ot_languages[] = {
|
||||
{"mnw", HB_TAG('M','O','N','T')}, /* Mon -> Thailand Mon */
|
||||
{"mnx", HB_TAG_NONE }, /* Manikion != Manx */
|
||||
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */
|
||||
{"mo", HB_TAG('R','O','M',' ')}, /* Moldavian (retired code) -> Romanian */
|
||||
{"mod", HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */
|
||||
/*{"moh", HB_TAG('M','O','H',' ')},*/ /* Mohawk */
|
||||
{"mok", HB_TAG_NONE }, /* Morori != Moksha */
|
||||
@ -958,7 +963,7 @@ static const LangTag ot_languages[] = {
|
||||
{"mts", HB_TAG_NONE }, /* Yora != Maltese */
|
||||
{"mud", HB_TAG('C','P','P',' ')}, /* Mednyj Aleut -> Creoles */
|
||||
{"mui", HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */
|
||||
{"mun", HB_TAG_NONE }, /* Munda [family] != Mundari */
|
||||
{"mun", HB_TAG_NONE }, /* Munda [collection] != Mundari */
|
||||
{"mup", HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */
|
||||
{"muq", HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */
|
||||
/*{"mus", HB_TAG('M','U','S',' ')},*/ /* Creek -> Muscogee */
|
||||
@ -973,7 +978,7 @@ static const LangTag ot_languages[] = {
|
||||
{"mww", HB_TAG('H','M','N',' ')}, /* Hmong Daw -> Hmong */
|
||||
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
|
||||
{"mym", HB_TAG('M','E','N',' ')}, /* Me’en */
|
||||
/*{"myn", HB_TAG('M','Y','N',' ')},*/ /* Mayan [family] */
|
||||
/*{"myn", HB_TAG('M','Y','N',' ')},*/ /* Mayan [collection] */
|
||||
{"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */
|
||||
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
|
||||
{"mzb", HB_TAG('B','B','R',' ')}, /* Tumzabt -> Berber */
|
||||
@ -982,7 +987,7 @@ static const LangTag ot_languages[] = {
|
||||
{"na", HB_TAG('N','A','U',' ')}, /* Nauru -> Nauruan */
|
||||
{"nag", HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */
|
||||
{"nag", HB_TAG('C','P','P',' ')}, /* Naga Pidgin -> Creoles */
|
||||
/*{"nah", HB_TAG('N','A','H',' ')},*/ /* Nahuatl [family] */
|
||||
/*{"nah", HB_TAG('N','A','H',' ')},*/ /* Nahuatl [collection] */
|
||||
{"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese, Simplified */
|
||||
/*{"nap", HB_TAG('N','A','P',' ')},*/ /* Neapolitan */
|
||||
{"nas", HB_TAG_NONE }, /* Naasioi != Naskapi */
|
||||
@ -1039,7 +1044,6 @@ static const LangTag ot_languages[] = {
|
||||
{"nln", HB_TAG('N','A','H',' ')}, /* Durango Nahuatl (retired code) -> Nahuatl */
|
||||
{"nlv", HB_TAG('N','A','H',' ')}, /* Orizaba Nahuatl -> Nahuatl */
|
||||
{"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */
|
||||
{"nn", HB_TAG('N','O','R',' ')}, /* Norwegian Nynorsk -> Norwegian */
|
||||
{"nnh", HB_TAG('B','M','L',' ')}, /* Ngiemboon -> Bamileke */
|
||||
{"nnz", HB_TAG('B','M','L',' ')}, /* Nda'nda' -> Bamileke */
|
||||
{"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
|
||||
@ -1093,7 +1097,7 @@ static const LangTag ot_languages[] = {
|
||||
{"otw", HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */
|
||||
{"oua", HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */
|
||||
{"pa", HB_TAG('P','A','N',' ')}, /* Punjabi */
|
||||
{"paa", HB_TAG_NONE }, /* Papuan [family] != Palestinian Aramaic */
|
||||
{"paa", HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */
|
||||
/*{"pag", HB_TAG('P','A','G',' ')},*/ /* Pangasinan */
|
||||
{"pal", HB_TAG_NONE }, /* Pahlavi != Pali */
|
||||
/*{"pam", HB_TAG('P','A','M',' ')},*/ /* Pampanga -> Pampangan */
|
||||
@ -1308,6 +1312,9 @@ static const LangTag ot_languages[] = {
|
||||
{"sgo", HB_TAG_NONE }, /* Songa (retired code) != Sango */
|
||||
/*{"sgs", HB_TAG('S','G','S',' ')},*/ /* Samogitian */
|
||||
{"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */
|
||||
{"sh", HB_TAG('B','O','S',' ')}, /* Serbo-Croatian [macrolanguage] -> Bosnian */
|
||||
{"sh", HB_TAG('H','R','V',' ')}, /* Serbo-Croatian [macrolanguage] -> Croatian */
|
||||
{"sh", HB_TAG('S','R','B',' ')}, /* Serbo-Croatian [macrolanguage] -> Serbian */
|
||||
{"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */
|
||||
{"shi", HB_TAG('B','B','R',' ')}, /* Tachelhit -> Berber */
|
||||
{"shl", HB_TAG('Q','I','N',' ')}, /* Shendu -> Chin */
|
||||
@ -1329,7 +1336,7 @@ static const LangTag ot_languages[] = {
|
||||
{"skw", HB_TAG('C','P','P',' ')}, /* Skepi Creole Dutch -> Creoles */
|
||||
{"sky", HB_TAG_NONE }, /* Sikaiana != Slovak */
|
||||
{"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
|
||||
{"sla", HB_TAG_NONE }, /* Slavic [family] != Slavey */
|
||||
{"sla", HB_TAG_NONE }, /* Slavic [collection] != Slavey */
|
||||
{"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
|
||||
{"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
|
||||
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
|
||||
@ -1451,7 +1458,7 @@ static const LangTag ot_languages[] = {
|
||||
{"tpi", HB_TAG('C','P','P',' ')}, /* Tok Pisin -> Creoles */
|
||||
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
|
||||
{"trf", HB_TAG('C','P','P',' ')}, /* Trinidadian Creole English -> Creoles */
|
||||
{"trk", HB_TAG_NONE }, /* Turkic [family] != Turkish */
|
||||
{"trk", HB_TAG_NONE }, /* Turkic [collection] != Turkish */
|
||||
{"tru", HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */
|
||||
{"tru", HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */
|
||||
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
|
||||
@ -1593,7 +1600,7 @@ static const LangTag ot_languages[] = {
|
||||
{"zlq", HB_TAG('Z','H','A',' ')}, /* Liuqian Zhuang -> Zhuang */
|
||||
{"zmi", HB_TAG('M','L','Y',' ')}, /* Negeri Sembilan Malay -> Malay */
|
||||
{"zmz", HB_TAG('B','A','D','0')}, /* Mbandja -> Banda */
|
||||
{"znd", HB_TAG_NONE }, /* Zande [family] != Zande */
|
||||
{"znd", HB_TAG_NONE }, /* Zande [collection] != Zande */
|
||||
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
|
||||
{"zom", HB_TAG('Q','I','N',' ')}, /* Zou -> Chin */
|
||||
{"zqe", HB_TAG('Z','H','A',' ')}, /* Qiubei Zhuang -> Zhuang */
|
||||
@ -2607,14 +2614,8 @@ hb_ot_tags_from_complex_language (const char *lang_str,
|
||||
if (0 == strcmp (&lang_str[1], "o-nyn"))
|
||||
{
|
||||
/* Norwegian Nynorsk (retired code) */
|
||||
unsigned int i;
|
||||
hb_tag_t possible_tags[] = {
|
||||
HB_TAG('N','Y','N',' '), /* Norwegian Nynorsk (Nynorsk, Norwegian) */
|
||||
HB_TAG('N','O','R',' '), /* Norwegian */
|
||||
};
|
||||
for (i = 0; i < 2 && i < *count; i++)
|
||||
tags[i] = possible_tags[i];
|
||||
*count = i;
|
||||
tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */
|
||||
*count = 1;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -2623,8 +2624,14 @@ hb_ot_tags_from_complex_language (const char *lang_str,
|
||||
&& subtag_matches (lang_str, limit, "-md"))
|
||||
{
|
||||
/* Romanian; Moldova */
|
||||
tags[0] = HB_TAG('M','O','L',' '); /* Moldavian */
|
||||
*count = 1;
|
||||
unsigned int i;
|
||||
hb_tag_t possible_tags[] = {
|
||||
HB_TAG('M','O','L',' '), /* Moldavian */
|
||||
HB_TAG('R','O','M',' '), /* Romanian */
|
||||
};
|
||||
for (i = 0; i < 2 && i < *count; i++)
|
||||
tags[i] = possible_tags[i];
|
||||
*count = i;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -2813,15 +2820,15 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
|
||||
case HB_TAG('A','R','K',' '): /* Rakhine */
|
||||
return hb_language_from_string ("rki", -1); /* Rakhine */
|
||||
case HB_TAG('A','T','H',' '): /* Athapaskan */
|
||||
return hb_language_from_string ("ath", -1); /* Athapascan [family] */
|
||||
return hb_language_from_string ("ath", -1); /* Athapascan [collection] */
|
||||
case HB_TAG('B','B','R',' '): /* Berber */
|
||||
return hb_language_from_string ("ber", -1); /* Berber [family] */
|
||||
return hb_language_from_string ("ber", -1); /* Berber [collection] */
|
||||
case HB_TAG('B','I','K',' '): /* Bikol */
|
||||
return hb_language_from_string ("bik", -1); /* Bikol [macrolanguage] */
|
||||
case HB_TAG('B','T','K',' '): /* Batak */
|
||||
return hb_language_from_string ("btk", -1); /* Batak [family] */
|
||||
return hb_language_from_string ("btk", -1); /* Batak [collection] */
|
||||
case HB_TAG('C','P','P',' '): /* Creoles */
|
||||
return hb_language_from_string ("crp", -1); /* Creoles and pidgins [family] */
|
||||
return hb_language_from_string ("crp", -1); /* Creoles and pidgins [collection] */
|
||||
case HB_TAG('C','R','R',' '): /* Carrier */
|
||||
return hb_language_from_string ("crx", -1); /* Carrier */
|
||||
case HB_TAG('D','G','R',' '): /* Dogri (macrolanguage) */
|
||||
@ -2838,6 +2845,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
|
||||
return hb_language_from_string ("fa", -1); /* Persian [macrolanguage] */
|
||||
case HB_TAG('G','O','N',' '): /* Gondi */
|
||||
return hb_language_from_string ("gon", -1); /* Gondi [macrolanguage] */
|
||||
case HB_TAG('H','M','A',' '): /* High Mari */
|
||||
return hb_language_from_string ("mrj", -1); /* Western Mari */
|
||||
case HB_TAG('H','M','N',' '): /* Hmong */
|
||||
return hb_language_from_string ("hmn", -1); /* Hmong [macrolanguage] */
|
||||
case HB_TAG('H','N','D',' '): /* Hindko */
|
||||
@ -2847,7 +2856,7 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
|
||||
case HB_TAG('I','B','A',' '): /* Iban */
|
||||
return hb_language_from_string ("iba", -1); /* Iban */
|
||||
case HB_TAG('I','J','O',' '): /* Ijo */
|
||||
return hb_language_from_string ("ijo", -1); /* Ijo [family] */
|
||||
return hb_language_from_string ("ijo", -1); /* Ijo [collection] */
|
||||
case HB_TAG('I','N','U',' '): /* Inuktitut */
|
||||
return hb_language_from_string ("iu", -1); /* Inuktitut [macrolanguage] */
|
||||
case HB_TAG('I','P','K',' '): /* Inupiat */
|
||||
@ -2873,11 +2882,13 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
|
||||
case HB_TAG('K','P','L',' '): /* Kpelle */
|
||||
return hb_language_from_string ("kpe", -1); /* Kpelle [macrolanguage] */
|
||||
case HB_TAG('K','R','N',' '): /* Karen */
|
||||
return hb_language_from_string ("kar", -1); /* Karen [family] */
|
||||
return hb_language_from_string ("kar", -1); /* Karen [collection] */
|
||||
case HB_TAG('K','U','I',' '): /* Kui */
|
||||
return hb_language_from_string ("uki", -1); /* Kui (India) */
|
||||
case HB_TAG('K','U','R',' '): /* Kurdish */
|
||||
return hb_language_from_string ("ku", -1); /* Kurdish [macrolanguage] */
|
||||
case HB_TAG('L','M','A',' '): /* Low Mari */
|
||||
return hb_language_from_string ("mhr", -1); /* Eastern Mari */
|
||||
case HB_TAG('L','U','H',' '): /* Luyia */
|
||||
return hb_language_from_string ("luy", -1); /* Luyia [macrolanguage] */
|
||||
case HB_TAG('L','V','I',' '): /* Latvian */
|
||||
@ -2897,9 +2908,9 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
|
||||
case HB_TAG('M','O','N','T'): /* Thailand Mon */
|
||||
return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */
|
||||
case HB_TAG('M','Y','N',' '): /* Mayan */
|
||||
return hb_language_from_string ("myn", -1); /* Mayan [family] */
|
||||
return hb_language_from_string ("myn", -1); /* Mayan [collection] */
|
||||
case HB_TAG('N','A','H',' '): /* Nahuatl */
|
||||
return hb_language_from_string ("nah", -1); /* Nahuatl [family] */
|
||||
return hb_language_from_string ("nah", -1); /* Nahuatl [collection] */
|
||||
case HB_TAG('N','E','P',' '): /* Nepali */
|
||||
return hb_language_from_string ("ne", -1); /* Nepali [macrolanguage] */
|
||||
case HB_TAG('N','I','S',' '): /* Nisi */
|
||||
@ -2926,6 +2937,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
|
||||
return hb_language_from_string ("qwh", -1); /* Huaylas Ancash Quechua */
|
||||
case HB_TAG('R','A','J',' '): /* Rajasthani */
|
||||
return hb_language_from_string ("raj", -1); /* Rajasthani [macrolanguage] */
|
||||
case HB_TAG('R','O','M',' '): /* Romanian */
|
||||
return hb_language_from_string ("ro", -1); /* Romanian */
|
||||
case HB_TAG('R','O','Y',' '): /* Romany */
|
||||
return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */
|
||||
case HB_TAG('S','Q','I',' '): /* Albanian */
|
||||
|
@ -263,7 +263,7 @@ struct fvar
|
||||
if (coords_length && *coords_length)
|
||||
{
|
||||
hb_array_t<const HBFixed> instanceCoords = instance->get_coordinates (axisCount)
|
||||
.sub_array (0, *coords_length);
|
||||
.sub_array (0, coords_length);
|
||||
for (unsigned int i = 0; i < instanceCoords.length; i++)
|
||||
coords[i] = instanceCoords.arrayZ[i].to_float ();
|
||||
}
|
||||
|
10
thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
vendored
10
thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
vendored
@ -399,7 +399,7 @@ struct gvar
|
||||
get_offset (glyphCount) - get_offset (0)));
|
||||
}
|
||||
|
||||
/* GlyphVariationData not sanitized here; must be checked while accessing each glyph varation data */
|
||||
/* GlyphVariationData not sanitized here; must be checked while accessing each glyph variation data */
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{ return sanitize_shallow (c); }
|
||||
|
||||
@ -498,9 +498,9 @@ struct gvar
|
||||
public:
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
accelerator_t (hb_face_t *face)
|
||||
{ table = hb_sanitize_context_t ().reference_table<gvar> (face); }
|
||||
void fini () { table.destroy (); }
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
private:
|
||||
struct x_getter { static float get (const contour_point_t &p) { return p.x; } };
|
||||
@ -698,7 +698,9 @@ no_more_gaps:
|
||||
DEFINE_SIZE_MIN (20);
|
||||
};
|
||||
|
||||
struct gvar_accelerator_t : gvar::accelerator_t {};
|
||||
struct gvar_accelerator_t : gvar::accelerator_t {
|
||||
gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
@ -177,9 +177,6 @@ struct hvarvvar_subset_plan_t
|
||||
|
||||
inner_maps.resize (var_store->get_sub_table_count ());
|
||||
|
||||
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||
inner_maps[i].init ();
|
||||
|
||||
if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
|
||||
|
||||
bool retain_adv_map = false;
|
||||
@ -229,8 +226,8 @@ struct hvarvvar_subset_plan_t
|
||||
for (unsigned int i = 0; i < inner_sets.length; i++)
|
||||
hb_set_destroy (inner_sets[i]);
|
||||
hb_set_destroy (adv_set);
|
||||
inner_maps.fini_deep ();
|
||||
index_map_plans.fini_deep ();
|
||||
inner_maps.fini ();
|
||||
index_map_plans.fini ();
|
||||
}
|
||||
|
||||
hb_inc_bimap_t outer_map;
|
||||
|
3
thirdparty/harfbuzz/src/hb-ot-var.cc
vendored
3
thirdparty/harfbuzz/src/hb-ot-var.cc
vendored
@ -303,6 +303,9 @@ hb_ot_var_normalize_variations (hb_face_t *face,
|
||||
* values for the axis are mapped to the interval [-1,1], with the default
|
||||
* axis value mapped to 0.
|
||||
*
|
||||
* The normalized values have 14 bits of fixed-point sub-integer precision as per
|
||||
* OpenType specification.
|
||||
*
|
||||
* Any additional scaling defined in the face's `avar` table is also
|
||||
* applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar
|
||||
*
|
||||
|
2
thirdparty/harfbuzz/src/hb-ot-var.h
vendored
2
thirdparty/harfbuzz/src/hb-ot-var.h
vendored
@ -109,7 +109,7 @@ typedef enum { /*< flags >*/
|
||||
* @tag: The #hb_tag_t tag identifying the design variation of the axis
|
||||
* @name_id: The `name` table Name ID that provides display names for the axis
|
||||
* @flags: The #hb_ot_var_axis_flags_t flags for the axis
|
||||
* @min_value: The mininum value on the variation axis that the font covers
|
||||
* @min_value: The minimum value on the variation axis that the font covers
|
||||
* @default_value: The position on the variation axis corresponding to the font's defaults
|
||||
* @max_value: The maximum value on the variation axis that the font covers
|
||||
*
|
||||
|
38
thirdparty/harfbuzz/src/hb-repacker.hh
vendored
38
thirdparty/harfbuzz/src/hb-repacker.hh
vendored
@ -42,26 +42,13 @@ struct graph_t
|
||||
{
|
||||
struct vertex_t
|
||||
{
|
||||
vertex_t () :
|
||||
distance (0),
|
||||
space (0),
|
||||
parents (),
|
||||
start (0),
|
||||
end (0),
|
||||
priority(0) {}
|
||||
|
||||
void fini () {
|
||||
obj.fini ();
|
||||
parents.fini ();
|
||||
}
|
||||
|
||||
hb_serialize_context_t::object_t obj;
|
||||
int64_t distance;
|
||||
int64_t space;
|
||||
int64_t distance = 0 ;
|
||||
int64_t space = 0 ;
|
||||
hb_vector_t<unsigned> parents;
|
||||
unsigned start;
|
||||
unsigned end;
|
||||
unsigned priority;
|
||||
unsigned start = 0;
|
||||
unsigned end = 0;
|
||||
unsigned priority = 0;
|
||||
|
||||
bool is_shared () const
|
||||
{
|
||||
@ -186,7 +173,7 @@ struct graph_t
|
||||
|
||||
~graph_t ()
|
||||
{
|
||||
vertices_.fini_deep ();
|
||||
vertices_.fini ();
|
||||
}
|
||||
|
||||
bool in_error () const
|
||||
@ -309,7 +296,7 @@ struct graph_t
|
||||
remap_all_obj_indices (id_map, &sorted_graph);
|
||||
|
||||
hb_swap (vertices_, sorted_graph);
|
||||
sorted_graph.fini_deep ();
|
||||
sorted_graph.fini ();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -369,7 +356,7 @@ struct graph_t
|
||||
remap_all_obj_indices (id_map, &sorted_graph);
|
||||
|
||||
hb_swap (vertices_, sorted_graph);
|
||||
sorted_graph.fini_deep ();
|
||||
sorted_graph.fini ();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -402,11 +389,15 @@ struct graph_t
|
||||
while (roots)
|
||||
{
|
||||
unsigned next = HB_SET_VALUE_INVALID;
|
||||
if (unlikely (!check_success (!roots.in_error ()))) break;
|
||||
if (!roots.next (&next)) break;
|
||||
|
||||
hb_set_t connected_roots;
|
||||
find_connected_nodes (next, roots, visited, connected_roots);
|
||||
if (unlikely (!check_success (!connected_roots.in_error ()))) break;
|
||||
|
||||
isolate_subgraph (connected_roots);
|
||||
if (unlikely (!check_success (!connected_roots.in_error ()))) break;
|
||||
|
||||
unsigned next_space = this->next_space ();
|
||||
num_roots_for_space_.push (0);
|
||||
@ -423,6 +414,8 @@ struct graph_t
|
||||
// into the 32 bit space as needed, instead of using isolation.
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -865,7 +858,7 @@ struct graph_t
|
||||
// Redundant ones are filtered out later on by the visited set.
|
||||
// According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
|
||||
// for practical performance this is faster then using a more advanced queue
|
||||
// (such as a fibonaacci queue) with a fast decrease priority.
|
||||
// (such as a fibonacci queue) with a fast decrease priority.
|
||||
for (unsigned i = 0; i < vertices_.length; i++)
|
||||
{
|
||||
if (i == vertices_.length - 1)
|
||||
@ -1074,6 +1067,7 @@ struct graph_t
|
||||
hb_set_t& visited,
|
||||
hb_set_t& connected)
|
||||
{
|
||||
if (unlikely (!check_success (!visited.in_error ()))) return;
|
||||
if (visited.has (start_idx)) return;
|
||||
visited.add (start_idx);
|
||||
|
||||
|
14
thirdparty/harfbuzz/src/hb-serialize.hh
vendored
14
thirdparty/harfbuzz/src/hb-serialize.hh
vendored
@ -279,7 +279,7 @@ struct hb_serialize_context_t
|
||||
object_pool.release (obj);
|
||||
}
|
||||
|
||||
/* Set share to false when an object is unlikely sharable with others
|
||||
/* Set share to false when an object is unlikely shareable with others
|
||||
* so not worth an attempt, or a contiguous table is serialized as
|
||||
* multiple consecutive objects in the reverse order so can't be shared.
|
||||
*/
|
||||
@ -381,7 +381,7 @@ struct hb_serialize_context_t
|
||||
// Adding a virtual link from object a to object b will ensure that object b is always packed after
|
||||
// object a in the final serialized order.
|
||||
//
|
||||
// This is useful in certain situtations where there needs to be a specific ordering in the
|
||||
// This is useful in certain situations where there needs to be a specific ordering in the
|
||||
// final serialization. Such as when platform bugs require certain orderings, or to provide
|
||||
// guidance to the repacker for better offset overflow resolution.
|
||||
void add_virtual_link (objidx_t objidx)
|
||||
@ -510,7 +510,7 @@ struct hb_serialize_context_t
|
||||
{ return reinterpret_cast<Type *> (this->head); }
|
||||
template <typename Type>
|
||||
Type *start_embed (const Type &obj) const
|
||||
{ return start_embed (hb_addressof (obj)); }
|
||||
{ return start_embed (std::addressof (obj)); }
|
||||
|
||||
bool err (hb_serialize_error_t err_type)
|
||||
{
|
||||
@ -548,7 +548,7 @@ struct hb_serialize_context_t
|
||||
}
|
||||
template <typename Type>
|
||||
Type *embed (const Type &obj)
|
||||
{ return embed (hb_addressof (obj)); }
|
||||
{ return embed (std::addressof (obj)); }
|
||||
|
||||
template <typename Type, typename ...Ts> auto
|
||||
_copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
|
||||
@ -595,19 +595,19 @@ struct hb_serialize_context_t
|
||||
}
|
||||
template <typename Type>
|
||||
Type *extend_size (Type &obj, size_t size)
|
||||
{ return extend_size (hb_addressof (obj), size); }
|
||||
{ return extend_size (std::addressof (obj), size); }
|
||||
|
||||
template <typename Type>
|
||||
Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
|
||||
template <typename Type>
|
||||
Type *extend_min (Type &obj) { return extend_min (hb_addressof (obj)); }
|
||||
Type *extend_min (Type &obj) { return extend_min (std::addressof (obj)); }
|
||||
|
||||
template <typename Type, typename ...Ts>
|
||||
Type *extend (Type *obj, Ts&&... ds)
|
||||
{ return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); }
|
||||
template <typename Type, typename ...Ts>
|
||||
Type *extend (Type &obj, Ts&&... ds)
|
||||
{ return extend (hb_addressof (obj), std::forward<Ts> (ds)...); }
|
||||
{ return extend (std::addressof (obj), std::forward<Ts> (ds)...); }
|
||||
|
||||
/* Output routines. */
|
||||
hb_bytes_t copy_bytes () const
|
||||
|
15
thirdparty/harfbuzz/src/hb-style.cc
vendored
15
thirdparty/harfbuzz/src/hb-style.cc
vendored
@ -48,13 +48,12 @@ _hb_angle_to_ratio (float a)
|
||||
{
|
||||
return tanf (a * float (M_PI / 180.));
|
||||
}
|
||||
#if 0
|
||||
|
||||
static inline float
|
||||
_hb_ratio_to_angle (float r)
|
||||
{
|
||||
return atanf (r) * float (180. / M_PI);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hb_style_get_value:
|
||||
@ -73,7 +72,8 @@ float
|
||||
hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
|
||||
{
|
||||
if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO))
|
||||
return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE));
|
||||
return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE))
|
||||
+ font->slant;
|
||||
|
||||
hb_face_t *face = font->face;
|
||||
|
||||
@ -109,7 +109,14 @@ hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
|
||||
: 12.f;
|
||||
}
|
||||
case HB_STYLE_TAG_SLANT_ANGLE:
|
||||
return face->table.post->table->italicAngle.to_float ();
|
||||
{
|
||||
float angle = face->table.post->table->italicAngle.to_float ();
|
||||
|
||||
if (font->slant)
|
||||
angle = _hb_ratio_to_angle (font->slant + _hb_angle_to_ratio (angle));
|
||||
|
||||
return angle;
|
||||
}
|
||||
case HB_STYLE_TAG_WIDTH:
|
||||
return face->table.OS2->has_data ()
|
||||
? face->table.OS2->get_width ()
|
||||
|
102
thirdparty/harfbuzz/src/hb-subset-cff-common.hh
vendored
102
thirdparty/harfbuzz/src/hb-subset-cff-common.hh
vendored
@ -275,60 +275,36 @@ struct subr_flattener_t
|
||||
|
||||
struct subr_closures_t
|
||||
{
|
||||
subr_closures_t () : valid (false), global_closure (nullptr)
|
||||
{ local_closures.init (); }
|
||||
|
||||
void init (unsigned int fd_count)
|
||||
subr_closures_t (unsigned int fd_count) : valid (false), global_closure (), local_closures ()
|
||||
{
|
||||
valid = true;
|
||||
global_closure = hb_set_create ();
|
||||
if (global_closure == hb_set_get_empty ())
|
||||
valid = false;
|
||||
if (!local_closures.resize (fd_count))
|
||||
valid = false;
|
||||
|
||||
for (unsigned int i = 0; i < local_closures.length; i++)
|
||||
{
|
||||
local_closures[i] = hb_set_create ();
|
||||
if (local_closures[i] == hb_set_get_empty ())
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
void fini ()
|
||||
{
|
||||
hb_set_destroy (global_closure);
|
||||
for (unsigned int i = 0; i < local_closures.length; i++)
|
||||
hb_set_destroy (local_closures[i]);
|
||||
local_closures.fini ();
|
||||
}
|
||||
|
||||
void reset ()
|
||||
{
|
||||
hb_set_clear (global_closure);
|
||||
global_closure.clear();
|
||||
for (unsigned int i = 0; i < local_closures.length; i++)
|
||||
hb_set_clear (local_closures[i]);
|
||||
local_closures[i].clear();
|
||||
}
|
||||
|
||||
bool is_valid () const { return valid; }
|
||||
bool valid;
|
||||
hb_set_t *global_closure;
|
||||
hb_vector_t<hb_set_t *> local_closures;
|
||||
hb_set_t global_closure;
|
||||
hb_vector_t<hb_set_t> local_closures;
|
||||
};
|
||||
|
||||
struct parsed_cs_op_t : op_str_t
|
||||
{
|
||||
void init (unsigned int subr_num_ = 0)
|
||||
{
|
||||
op_str_t::init ();
|
||||
subr_num = subr_num_;
|
||||
drop_flag = false;
|
||||
keep_flag = false;
|
||||
skip_flag = false;
|
||||
}
|
||||
|
||||
void fini () { op_str_t::fini (); }
|
||||
|
||||
bool for_drop () const { return drop_flag; }
|
||||
void set_drop () { if (!for_keep ()) drop_flag = true; }
|
||||
|
||||
@ -416,16 +392,6 @@ struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t>
|
||||
|
||||
struct parsed_cs_str_vec_t : hb_vector_t<parsed_cs_str_t>
|
||||
{
|
||||
void init (unsigned int len_ = 0)
|
||||
{
|
||||
SUPER::init ();
|
||||
if (unlikely (!resize (len_)))
|
||||
return;
|
||||
for (unsigned int i = 0; i < length; i++)
|
||||
(*this)[i].init ();
|
||||
}
|
||||
void fini () { SUPER::fini_deep (); }
|
||||
|
||||
private:
|
||||
typedef hb_vector_t<parsed_cs_str_t> SUPER;
|
||||
};
|
||||
@ -496,7 +462,7 @@ struct subr_subset_param_t
|
||||
|
||||
struct subr_remap_t : hb_inc_bimap_t
|
||||
{
|
||||
void create (hb_set_t *closure)
|
||||
void create (const hb_set_t *closure)
|
||||
{
|
||||
/* create a remapping of subroutine numbers from old to new.
|
||||
* no optimization based on usage counts. fonttools doesn't appear doing that either.
|
||||
@ -526,19 +492,9 @@ struct subr_remap_t : hb_inc_bimap_t
|
||||
|
||||
struct subr_remaps_t
|
||||
{
|
||||
subr_remaps_t ()
|
||||
subr_remaps_t (unsigned int fdCount)
|
||||
{
|
||||
global_remap.init ();
|
||||
local_remaps.init ();
|
||||
}
|
||||
|
||||
~subr_remaps_t () { fini (); }
|
||||
|
||||
void init (unsigned int fdCount)
|
||||
{
|
||||
if (unlikely (!local_remaps.resize (fdCount))) return;
|
||||
for (unsigned int i = 0; i < fdCount; i++)
|
||||
local_remaps[i].init ();
|
||||
local_remaps.resize (fdCount);
|
||||
}
|
||||
|
||||
bool in_error()
|
||||
@ -548,15 +504,9 @@ struct subr_remaps_t
|
||||
|
||||
void create (subr_closures_t& closures)
|
||||
{
|
||||
global_remap.create (closures.global_closure);
|
||||
global_remap.create (&closures.global_closure);
|
||||
for (unsigned int i = 0; i < local_remaps.length; i++)
|
||||
local_remaps[i].create (closures.local_closures[i]);
|
||||
}
|
||||
|
||||
void fini ()
|
||||
{
|
||||
global_remap.fini ();
|
||||
local_remaps.fini_deep ();
|
||||
local_remaps[i].create (&closures.local_closures[i]);
|
||||
}
|
||||
|
||||
subr_remap_t global_remap;
|
||||
@ -567,21 +517,8 @@ template <typename SUBSETTER, typename SUBRS, typename ACC, typename ENV, typena
|
||||
struct subr_subsetter_t
|
||||
{
|
||||
subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_)
|
||||
: acc (acc_), plan (plan_)
|
||||
{
|
||||
parsed_charstrings.init ();
|
||||
parsed_global_subrs.init ();
|
||||
parsed_local_subrs.init ();
|
||||
}
|
||||
|
||||
~subr_subsetter_t ()
|
||||
{
|
||||
closures.fini ();
|
||||
remaps.fini ();
|
||||
parsed_charstrings.fini_deep ();
|
||||
parsed_global_subrs.fini_deep ();
|
||||
parsed_local_subrs.fini_deep ();
|
||||
}
|
||||
: acc (acc_), plan (plan_), closures(acc_.fdCount), remaps(acc_.fdCount)
|
||||
{}
|
||||
|
||||
/* Subroutine subsetting with --no-desubroutinize runs in phases:
|
||||
*
|
||||
@ -599,11 +536,8 @@ struct subr_subsetter_t
|
||||
*/
|
||||
bool subset (void)
|
||||
{
|
||||
closures.init (acc.fdCount);
|
||||
remaps.init (acc.fdCount);
|
||||
|
||||
parsed_charstrings.init (plan->num_output_glyphs ());
|
||||
parsed_global_subrs.init (acc.globalSubrs->count);
|
||||
parsed_charstrings.resize (plan->num_output_glyphs ());
|
||||
parsed_global_subrs.resize (acc.globalSubrs->count);
|
||||
|
||||
if (unlikely (remaps.in_error()
|
||||
|| parsed_charstrings.in_error ()
|
||||
@ -615,7 +549,7 @@ struct subr_subsetter_t
|
||||
|
||||
for (unsigned int i = 0; i < acc.fdCount; i++)
|
||||
{
|
||||
parsed_local_subrs[i].init (acc.privateDicts[i].localSubrs->count);
|
||||
parsed_local_subrs[i].resize (acc.privateDicts[i].localSubrs->count);
|
||||
if (unlikely (parsed_local_subrs[i].in_error ())) return false;
|
||||
}
|
||||
if (unlikely (!closures.valid))
|
||||
@ -638,7 +572,7 @@ struct subr_subsetter_t
|
||||
subr_subset_param_t param;
|
||||
param.init (&parsed_charstrings[i],
|
||||
&parsed_global_subrs, &parsed_local_subrs[fd],
|
||||
closures.global_closure, closures.local_closures[fd],
|
||||
&closures.global_closure, &closures.local_closures[fd],
|
||||
plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
|
||||
|
||||
if (unlikely (!interp.interpret (param)))
|
||||
@ -662,7 +596,7 @@ struct subr_subsetter_t
|
||||
subr_subset_param_t param;
|
||||
param.init (&parsed_charstrings[i],
|
||||
&parsed_global_subrs, &parsed_local_subrs[fd],
|
||||
closures.global_closure, closures.local_closures[fd],
|
||||
&closures.global_closure, &closures.local_closures[fd],
|
||||
plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
|
||||
|
||||
drop_hints_param_t drop;
|
||||
@ -687,7 +621,7 @@ struct subr_subsetter_t
|
||||
subr_subset_param_t param;
|
||||
param.init (&parsed_charstrings[i],
|
||||
&parsed_global_subrs, &parsed_local_subrs[fd],
|
||||
closures.global_closure, closures.local_closures[fd],
|
||||
&closures.global_closure, &closures.local_closures[fd],
|
||||
plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
|
||||
collect_subr_refs_in_str (parsed_charstrings[i], param);
|
||||
}
|
||||
|
42
thirdparty/harfbuzz/src/hb-subset-cff1.cc
vendored
42
thirdparty/harfbuzz/src/hb-subset-cff1.cc
vendored
@ -362,43 +362,11 @@ struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs
|
||||
|
||||
struct cff_subset_plan {
|
||||
cff_subset_plan ()
|
||||
: info (),
|
||||
orig_fdcount (0),
|
||||
subset_fdcount (1),
|
||||
subset_fdselect_format (0),
|
||||
drop_hints (false),
|
||||
desubroutinize(false)
|
||||
{
|
||||
topdict_mod.init ();
|
||||
subset_fdselect_ranges.init ();
|
||||
fdmap.init ();
|
||||
subset_charstrings.init ();
|
||||
subset_globalsubrs.init ();
|
||||
subset_localsubrs.init ();
|
||||
fontdicts_mod.init ();
|
||||
subset_enc_code_ranges.init ();
|
||||
subset_enc_supp_codes.init ();
|
||||
subset_charset_ranges.init ();
|
||||
sidmap.init ();
|
||||
for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
|
||||
topDictModSIDs[i] = CFF_UNDEF_SID;
|
||||
}
|
||||
|
||||
~cff_subset_plan ()
|
||||
{
|
||||
topdict_mod.fini ();
|
||||
subset_fdselect_ranges.fini ();
|
||||
fdmap.fini ();
|
||||
subset_charstrings.fini_deep ();
|
||||
subset_globalsubrs.fini_deep ();
|
||||
subset_localsubrs.fini_deep ();
|
||||
fontdicts_mod.fini ();
|
||||
subset_enc_code_ranges.fini ();
|
||||
subset_enc_supp_codes.fini ();
|
||||
subset_charset_ranges.fini ();
|
||||
sidmap.fini ();
|
||||
}
|
||||
|
||||
void plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
|
||||
{
|
||||
const Encoding *encoding = acc.encoding;
|
||||
@ -672,9 +640,9 @@ struct cff_subset_plan {
|
||||
cff1_sub_table_info_t info;
|
||||
|
||||
unsigned int num_glyphs;
|
||||
unsigned int orig_fdcount;
|
||||
unsigned int subset_fdcount;
|
||||
unsigned int subset_fdselect_format;
|
||||
unsigned int orig_fdcount = 0;
|
||||
unsigned int subset_fdcount = 1;
|
||||
unsigned int subset_fdselect_format = 0;
|
||||
hb_vector_t<code_pair_t> subset_fdselect_ranges;
|
||||
|
||||
/* font dict index remap table from fullset FDArray to subset FDArray.
|
||||
@ -686,7 +654,7 @@ struct cff_subset_plan {
|
||||
hb_vector_t<str_buff_vec_t> subset_localsubrs;
|
||||
hb_vector_t<cff1_font_dict_values_mod_t> fontdicts_mod;
|
||||
|
||||
bool drop_hints;
|
||||
bool drop_hints = false;
|
||||
|
||||
bool gid_renum;
|
||||
bool subset_encoding;
|
||||
@ -702,7 +670,7 @@ struct cff_subset_plan {
|
||||
remap_sid_t sidmap;
|
||||
unsigned int topDictModSIDs[name_dict_values_t::ValCount];
|
||||
|
||||
bool desubroutinize;
|
||||
bool desubroutinize = false;
|
||||
};
|
||||
|
||||
static bool _serialize_cff1 (hb_serialize_context_t *c,
|
||||
|
43
thirdparty/harfbuzz/src/hb-subset-cff2.cc
vendored
43
thirdparty/harfbuzz/src/hb-subset-cff2.cc
vendored
@ -233,29 +233,6 @@ struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs
|
||||
};
|
||||
|
||||
struct cff2_subset_plan {
|
||||
cff2_subset_plan ()
|
||||
: orig_fdcount (0),
|
||||
subset_fdcount(1),
|
||||
subset_fdselect_size (0),
|
||||
subset_fdselect_format (0),
|
||||
drop_hints (false),
|
||||
desubroutinize (false)
|
||||
{
|
||||
subset_fdselect_ranges.init ();
|
||||
fdmap.init ();
|
||||
subset_charstrings.init ();
|
||||
subset_globalsubrs.init ();
|
||||
subset_localsubrs.init ();
|
||||
}
|
||||
|
||||
~cff2_subset_plan ()
|
||||
{
|
||||
subset_fdselect_ranges.fini ();
|
||||
fdmap.fini ();
|
||||
subset_charstrings.fini_deep ();
|
||||
subset_globalsubrs.fini_deep ();
|
||||
subset_localsubrs.fini_deep ();
|
||||
}
|
||||
|
||||
bool create (const OT::cff2::accelerator_subset_t &acc,
|
||||
hb_subset_plan_t *plan)
|
||||
@ -320,10 +297,10 @@ struct cff2_subset_plan {
|
||||
|
||||
cff2_sub_table_info_t info;
|
||||
|
||||
unsigned int orig_fdcount;
|
||||
unsigned int subset_fdcount;
|
||||
unsigned int subset_fdselect_size;
|
||||
unsigned int subset_fdselect_format;
|
||||
unsigned int orig_fdcount = 0;
|
||||
unsigned int subset_fdcount = 1;
|
||||
unsigned int subset_fdselect_size = 0;
|
||||
unsigned int subset_fdselect_format = 0;
|
||||
hb_vector_t<code_pair_t> subset_fdselect_ranges;
|
||||
|
||||
hb_inc_bimap_t fdmap;
|
||||
@ -332,8 +309,8 @@ struct cff2_subset_plan {
|
||||
str_buff_vec_t subset_globalsubrs;
|
||||
hb_vector_t<str_buff_vec_t> subset_localsubrs;
|
||||
|
||||
bool drop_hints;
|
||||
bool desubroutinize;
|
||||
bool drop_hints = false;
|
||||
bool desubroutinize = false;
|
||||
};
|
||||
|
||||
static bool _serialize_cff2 (hb_serialize_context_t *c,
|
||||
@ -473,12 +450,8 @@ _hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc,
|
||||
bool
|
||||
hb_subset_cff2 (hb_subset_context_t *c)
|
||||
{
|
||||
OT::cff2::accelerator_subset_t acc;
|
||||
acc.init (c->plan->source);
|
||||
bool result = likely (acc.is_valid ()) && _hb_subset_cff2 (acc, c);
|
||||
acc.fini ();
|
||||
|
||||
return result;
|
||||
OT::cff2::accelerator_subset_t acc (c->plan->source);
|
||||
return acc.is_valid () && _hb_subset_cff2 (acc, c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
26
thirdparty/harfbuzz/src/hb-subset-plan.cc
vendored
26
thirdparty/harfbuzz/src/hb-subset-plan.cc
vendored
@ -228,10 +228,8 @@ _cmap_closure (hb_face_t *face,
|
||||
const hb_set_t *unicodes,
|
||||
hb_set_t *glyphset)
|
||||
{
|
||||
OT::cmap::accelerator_t cmap;
|
||||
cmap.init (face);
|
||||
OT::cmap::accelerator_t cmap (face);
|
||||
cmap.table->closure_glyphs (unicodes, glyphset);
|
||||
cmap.fini ();
|
||||
}
|
||||
|
||||
static void _colr_closure (hb_face_t *face,
|
||||
@ -239,8 +237,7 @@ static void _colr_closure (hb_face_t *face,
|
||||
hb_map_t *palettes_map,
|
||||
hb_set_t *glyphs_colred)
|
||||
{
|
||||
OT::COLR::accelerator_t colr;
|
||||
colr.init (face);
|
||||
OT::COLR::accelerator_t colr (face);
|
||||
if (!colr.is_valid ()) return;
|
||||
|
||||
unsigned iteration_count = 0;
|
||||
@ -263,7 +260,6 @@ static void _colr_closure (hb_face_t *face,
|
||||
colr.closure_V0palette_indices (glyphs_colred, &palette_indices);
|
||||
_remap_indexes (&layer_indices, layers_map);
|
||||
_remap_palette_indexes (&palette_indices, palettes_map);
|
||||
colr.fini ();
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -294,8 +290,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
|
||||
const hb_set_t *glyphs,
|
||||
hb_subset_plan_t *plan)
|
||||
{
|
||||
OT::cmap::accelerator_t cmap;
|
||||
cmap.init (plan->source);
|
||||
OT::cmap::accelerator_t cmap (plan->source);
|
||||
|
||||
constexpr static const int size_threshold = 4096;
|
||||
|
||||
@ -343,8 +338,6 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
|
||||
|
||||
+ plan->codepoint_to_glyph->keys () | hb_sink (plan->unicodes);
|
||||
+ plan->codepoint_to_glyph->values () | hb_sink (plan->_glyphset_gsub);
|
||||
|
||||
cmap.fini ();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -353,13 +346,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
||||
bool close_over_gpos,
|
||||
bool close_over_gdef)
|
||||
{
|
||||
OT::glyf::accelerator_t glyf;
|
||||
OT::glyf::accelerator_t glyf (plan->source);
|
||||
#ifndef HB_NO_SUBSET_CFF
|
||||
OT::cff1::accelerator_t cff;
|
||||
#endif
|
||||
glyf.init (plan->source);
|
||||
#ifndef HB_NO_SUBSET_CFF
|
||||
cff.init (plan->source);
|
||||
OT::cff1::accelerator_t cff (plan->source);
|
||||
#endif
|
||||
|
||||
plan->_glyphset_gsub->add (0); // Not-def
|
||||
@ -419,11 +408,6 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
||||
plan->layout_variation_indices,
|
||||
plan->layout_variation_idx_map);
|
||||
#endif
|
||||
|
||||
#ifndef HB_NO_SUBSET_CFF
|
||||
cff.fini ();
|
||||
#endif
|
||||
glyf.fini ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
3
thirdparty/harfbuzz/src/hb-uniscribe.cc
vendored
3
thirdparty/harfbuzz/src/hb-uniscribe.cc
vendored
@ -878,7 +878,8 @@ retry:
|
||||
if (backward)
|
||||
hb_buffer_reverse (buffer);
|
||||
|
||||
buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
|
||||
buffer->clear_glyph_flags ();
|
||||
buffer->unsafe_to_break ();
|
||||
|
||||
/* Wow, done! */
|
||||
return true;
|
||||
|
200
thirdparty/harfbuzz/src/hb-vector.hh
vendored
200
thirdparty/harfbuzz/src/hb-vector.hh
vendored
@ -32,11 +32,14 @@
|
||||
#include "hb-null.hh"
|
||||
|
||||
|
||||
template <typename Type>
|
||||
struct hb_vector_t
|
||||
template <typename Type,
|
||||
bool sorted=false>
|
||||
struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty_t>::type
|
||||
{
|
||||
typedef Type item_t;
|
||||
static constexpr unsigned item_size = hb_static_size (Type);
|
||||
using array_t = typename std::conditional<sorted, hb_sorted_array_t<Type>, hb_array_t<Type>>::type;
|
||||
using c_array_t = typename std::conditional<sorted, hb_sorted_array_t<const Type>, hb_array_t<const Type>>::type;
|
||||
|
||||
hb_vector_t () = default;
|
||||
hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t ()
|
||||
@ -82,16 +85,10 @@ struct hb_vector_t
|
||||
|
||||
void fini ()
|
||||
{
|
||||
shrink_vector (0);
|
||||
hb_free (arrayZ);
|
||||
init ();
|
||||
}
|
||||
void fini_deep ()
|
||||
{
|
||||
unsigned int count = length;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
arrayZ[i].fini ();
|
||||
fini ();
|
||||
}
|
||||
|
||||
void reset ()
|
||||
{
|
||||
@ -152,24 +149,24 @@ struct hb_vector_t
|
||||
template <typename T>
|
||||
hb_vector_t& operator << (T&& v) { push (std::forward<T> (v)); return *this; }
|
||||
|
||||
hb_array_t< Type> as_array () { return hb_array (arrayZ, length); }
|
||||
hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); }
|
||||
array_t as_array () { return hb_array (arrayZ, length); }
|
||||
c_array_t as_array () const { return hb_array (arrayZ, length); }
|
||||
|
||||
/* Iterator. */
|
||||
typedef hb_array_t<const Type> iter_t;
|
||||
typedef hb_array_t< Type> writer_t;
|
||||
typedef c_array_t iter_t;
|
||||
typedef array_t writer_t;
|
||||
iter_t iter () const { return as_array (); }
|
||||
writer_t writer () { return as_array (); }
|
||||
operator iter_t () const { return iter (); }
|
||||
operator writer_t () { return writer (); }
|
||||
|
||||
hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
|
||||
c_array_t sub_array (unsigned int start_offset, unsigned int count) const
|
||||
{ return as_array ().sub_array (start_offset, count); }
|
||||
hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
|
||||
c_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
|
||||
{ return as_array ().sub_array (start_offset, count); }
|
||||
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
|
||||
array_t sub_array (unsigned int start_offset, unsigned int count)
|
||||
{ return as_array ().sub_array (start_offset, count); }
|
||||
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
|
||||
array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
|
||||
{ return as_array ().sub_array (start_offset, count); }
|
||||
|
||||
hb_sorted_array_t<Type> as_sorted_array ()
|
||||
@ -192,6 +189,7 @@ struct hb_vector_t
|
||||
template <typename T>
|
||||
Type *push (T&& v)
|
||||
{
|
||||
/* TODO Emplace? */
|
||||
Type *p = push ();
|
||||
if (p == &Crap (Type))
|
||||
// If push failed to allocate then don't copy v, since this may cause
|
||||
@ -204,6 +202,92 @@ struct hb_vector_t
|
||||
|
||||
bool in_error () const { return allocated < 0; }
|
||||
|
||||
template <typename T = Type,
|
||||
hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
|
||||
Type *
|
||||
realloc_vector (unsigned new_allocated)
|
||||
{
|
||||
return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
|
||||
}
|
||||
template <typename T = Type,
|
||||
hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
|
||||
Type *
|
||||
realloc_vector (unsigned new_allocated)
|
||||
{
|
||||
Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type));
|
||||
if (likely (new_array))
|
||||
{
|
||||
for (unsigned i = 0; i < length; i++)
|
||||
new (std::addressof (new_array[i])) Type ();
|
||||
for (unsigned i = 0; i < (unsigned) length; i++)
|
||||
new_array[i] = std::move (arrayZ[i]);
|
||||
unsigned old_length = length;
|
||||
shrink_vector (0);
|
||||
length = old_length;
|
||||
hb_free (arrayZ);
|
||||
}
|
||||
return new_array;
|
||||
}
|
||||
|
||||
template <typename T = Type,
|
||||
hb_enable_if (std::is_trivially_constructible<T>::value ||
|
||||
!std::is_default_constructible<T>::value)>
|
||||
void
|
||||
grow_vector (unsigned size)
|
||||
{
|
||||
memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
|
||||
length = size;
|
||||
}
|
||||
template <typename T = Type,
|
||||
hb_enable_if (!std::is_trivially_constructible<T>::value &&
|
||||
std::is_default_constructible<T>::value)>
|
||||
void
|
||||
grow_vector (unsigned size)
|
||||
{
|
||||
while (length < size)
|
||||
{
|
||||
length++;
|
||||
new (std::addressof (arrayZ[length - 1])) Type ();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T = Type,
|
||||
hb_enable_if (std::is_trivially_destructible<T>::value)>
|
||||
void
|
||||
shrink_vector (unsigned size)
|
||||
{
|
||||
length = size;
|
||||
}
|
||||
template <typename T = Type,
|
||||
hb_enable_if (!std::is_trivially_destructible<T>::value)>
|
||||
void
|
||||
shrink_vector (unsigned size)
|
||||
{
|
||||
while ((unsigned) length > size)
|
||||
{
|
||||
arrayZ[(unsigned) length - 1].~Type ();
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T = Type,
|
||||
hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
|
||||
void
|
||||
shift_down_vector (unsigned i)
|
||||
{
|
||||
memmove (static_cast<void *> (&arrayZ[i - 1]),
|
||||
static_cast<void *> (&arrayZ[i]),
|
||||
(length - i) * sizeof (Type));
|
||||
}
|
||||
template <typename T = Type,
|
||||
hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
|
||||
void
|
||||
shift_down_vector (unsigned i)
|
||||
{
|
||||
for (; i < length; i++)
|
||||
arrayZ[i - 1] = std::move (arrayZ[i]);
|
||||
}
|
||||
|
||||
/* Allocate for size but don't adjust length. */
|
||||
bool alloc (unsigned int size)
|
||||
{
|
||||
@ -225,7 +309,7 @@ struct hb_vector_t
|
||||
(new_allocated < (unsigned) allocated) ||
|
||||
hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
|
||||
if (likely (!overflows))
|
||||
new_array = (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
|
||||
new_array = realloc_vector (new_allocated);
|
||||
|
||||
if (unlikely (!new_array))
|
||||
{
|
||||
@ -246,7 +330,9 @@ struct hb_vector_t
|
||||
return false;
|
||||
|
||||
if (size > length)
|
||||
memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
|
||||
grow_vector (size);
|
||||
else if (size < length)
|
||||
shrink_vector (size);
|
||||
|
||||
length = size;
|
||||
return true;
|
||||
@ -255,48 +341,38 @@ struct hb_vector_t
|
||||
Type pop ()
|
||||
{
|
||||
if (!length) return Null (Type);
|
||||
return std::move (arrayZ[--length]); /* Does this move actually work? */
|
||||
Type v = std::move (arrayZ[length - 1]);
|
||||
arrayZ[length - 1].~Type ();
|
||||
length--;
|
||||
return v;
|
||||
}
|
||||
|
||||
void remove (unsigned int i)
|
||||
{
|
||||
if (unlikely (i >= length))
|
||||
return;
|
||||
memmove (static_cast<void *> (&arrayZ[i]),
|
||||
static_cast<void *> (&arrayZ[i + 1]),
|
||||
(length - i - 1) * sizeof (Type));
|
||||
arrayZ[i].~Type ();
|
||||
shift_down_vector (i + 1);
|
||||
length--;
|
||||
}
|
||||
|
||||
void shrink (int size_)
|
||||
{
|
||||
unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
|
||||
if (size < length)
|
||||
length = size;
|
||||
if (size >= length)
|
||||
return;
|
||||
|
||||
shrink_vector (size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Type *find (T v)
|
||||
{
|
||||
for (unsigned int i = 0; i < length; i++)
|
||||
if (arrayZ[i] == v)
|
||||
return &arrayZ[i];
|
||||
return nullptr;
|
||||
}
|
||||
template <typename T>
|
||||
const Type *find (T v) const
|
||||
{
|
||||
for (unsigned int i = 0; i < length; i++)
|
||||
if (arrayZ[i] == v)
|
||||
return &arrayZ[i];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Sorting API. */
|
||||
void qsort (int (*cmp)(const void*, const void*))
|
||||
{ as_array ().qsort (cmp); }
|
||||
void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
|
||||
{ as_array ().qsort (start, end); }
|
||||
|
||||
/* Unsorted search API. */
|
||||
template <typename T>
|
||||
Type *lsearch (const T &x, Type *not_found = nullptr)
|
||||
{ return as_array ().lsearch (x, not_found); }
|
||||
@ -306,47 +382,25 @@ struct hb_vector_t
|
||||
template <typename T>
|
||||
bool lfind (const T &x, unsigned *pos = nullptr) const
|
||||
{ return as_array ().lfind (x, pos); }
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct hb_sorted_vector_t : hb_vector_t<Type>
|
||||
{
|
||||
hb_sorted_vector_t () = default;
|
||||
~hb_sorted_vector_t () = default;
|
||||
hb_sorted_vector_t (hb_sorted_vector_t& o) = default;
|
||||
hb_sorted_vector_t (hb_sorted_vector_t &&o) = default;
|
||||
hb_sorted_vector_t (std::initializer_list<Type> lst) : hb_vector_t<Type> (lst) {}
|
||||
template <typename Iterable,
|
||||
hb_requires (hb_is_iterable (Iterable))>
|
||||
hb_sorted_vector_t (const Iterable &o) : hb_vector_t<Type> (o) {}
|
||||
hb_sorted_vector_t& operator = (const hb_sorted_vector_t &o) = default;
|
||||
hb_sorted_vector_t& operator = (hb_sorted_vector_t &&o) = default;
|
||||
friend void swap (hb_sorted_vector_t& a, hb_sorted_vector_t& b)
|
||||
{ hb_swap ((hb_vector_t<Type>&) (a), (hb_vector_t<Type>&) (b)); }
|
||||
|
||||
hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->length); }
|
||||
hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); }
|
||||
|
||||
/* Iterator. */
|
||||
typedef hb_sorted_array_t<const Type> const_iter_t;
|
||||
typedef hb_sorted_array_t< Type> iter_t;
|
||||
const_iter_t iter () const { return as_array (); }
|
||||
const_iter_t citer () const { return as_array (); }
|
||||
iter_t iter () { return as_array (); }
|
||||
operator iter_t () { return iter (); }
|
||||
operator const_iter_t () const { return iter (); }
|
||||
|
||||
template <typename T>
|
||||
/* Sorted search API. */
|
||||
template <typename T,
|
||||
bool Sorted=sorted, hb_enable_if (Sorted)>
|
||||
Type *bsearch (const T &x, Type *not_found = nullptr)
|
||||
{ return as_array ().bsearch (x, not_found); }
|
||||
template <typename T>
|
||||
template <typename T,
|
||||
bool Sorted=sorted, hb_enable_if (Sorted)>
|
||||
const Type *bsearch (const T &x, const Type *not_found = nullptr) const
|
||||
{ return as_array ().bsearch (x, not_found); }
|
||||
template <typename T>
|
||||
template <typename T,
|
||||
bool Sorted=sorted, hb_enable_if (Sorted)>
|
||||
bool bfind (const T &x, unsigned int *i = nullptr,
|
||||
hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
|
||||
unsigned int to_store = (unsigned int) -1) const
|
||||
{ return as_array ().bfind (x, i, not_found, to_store); }
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
using hb_sorted_vector_t = hb_vector_t<Type, true>;
|
||||
|
||||
#endif /* HB_VECTOR_HH */
|
||||
|
6
thirdparty/harfbuzz/src/hb-version.h
vendored
6
thirdparty/harfbuzz/src/hb-version.h
vendored
@ -47,20 +47,20 @@ HB_BEGIN_DECLS
|
||||
*
|
||||
* The minor component of the library version available at compile-time.
|
||||
*/
|
||||
#define HB_VERSION_MINOR 2
|
||||
#define HB_VERSION_MINOR 3
|
||||
/**
|
||||
* HB_VERSION_MICRO:
|
||||
*
|
||||
* The micro component of the library version available at compile-time.
|
||||
*/
|
||||
#define HB_VERSION_MICRO 0
|
||||
#define HB_VERSION_MICRO 1
|
||||
|
||||
/**
|
||||
* HB_VERSION_STRING:
|
||||
*
|
||||
* A string literal containing the library version available at compile-time.
|
||||
*/
|
||||
#define HB_VERSION_STRING "3.2.0"
|
||||
#define HB_VERSION_STRING "3.3.1"
|
||||
|
||||
/**
|
||||
* HB_VERSION_ATLEAST:
|
||||
|
Loading…
Reference in New Issue
Block a user