8261169: Upgrade HarfBuzz to the latest 2.8.0

Reviewed-by: serb
This commit is contained in:
Phil Race 2021-05-04 18:23:09 +00:00
parent 9c4efddb4a
commit 80323b7f66
122 changed files with 9643 additions and 5379 deletions

View File

@ -465,7 +465,7 @@ else
HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing
HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \
maybe-uninitialized class-memaccess
maybe-uninitialized class-memaccess unused-result
HARFBUZZ_DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \
tautological-constant-out-of-range-compare int-to-pointer-cast \
undef missing-field-initializers range-loop-analysis \

View File

@ -1,4 +1,4 @@
## Harfbuzz v2.7.2
## Harfbuzz v2.8
### Harfbuzz License

View File

@ -510,7 +510,7 @@ struct StateTable
const Entry<Extra> &get_entry (int state, unsigned int klass) const
{
if (unlikely (klass >= nClasses))
klass = StateTable<Types, Entry<Extra>>::CLASS_OUT_OF_BOUNDS;
klass = StateTable::CLASS_OUT_OF_BOUNDS;
const HBUSHORT *states = (this+stateArrayTable).arrayZ;
const Entry<Extra> *entries = (this+entryTable).arrayZ;
@ -576,7 +576,7 @@ struct StateTable
if (unlikely (stop > states))
return_trace (false);
for (const HBUSHORT *p = states; stop < p; p--)
num_entries = hb_max (num_entries, *(p - 1) + 1);
num_entries = hb_max (num_entries, *(p - 1) + 1u);
state_neg = min_state;
}
}
@ -597,7 +597,7 @@ struct StateTable
if (unlikely (stop < states))
return_trace (false);
for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
num_entries = hb_max (num_entries, *p + 1);
num_entries = hb_max (num_entries, *p + 1u);
state_pos = max_state + 1;
}
}
@ -729,7 +729,10 @@ struct ExtendedTypes
template <typename Types, typename EntryData>
struct StateTableDriver
{
StateTableDriver (const StateTable<Types, EntryData> &machine_,
using StateTableT = StateTable<Types, EntryData>;
using EntryT = Entry<EntryData>;
StateTableDriver (const StateTableT &machine_,
hb_buffer_t *buffer_,
hb_face_t *face_) :
machine (machine_),
@ -742,59 +745,101 @@ struct StateTableDriver
if (!c->in_place)
buffer->clear_output ();
int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT;
int state = StateTableT::STATE_START_OF_TEXT;
for (buffer->idx = 0; buffer->successful;)
{
unsigned int klass = buffer->idx < buffer->len ?
machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) :
(unsigned) StateTable<Types, EntryData>::CLASS_END_OF_TEXT;
(unsigned) StateTableT::CLASS_END_OF_TEXT;
DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
const Entry<EntryData> &entry = machine.get_entry (state, klass);
const EntryT &entry = machine.get_entry (state, klass);
const int next_state = machine.new_state (entry.newState);
/* Unsafe-to-break before this if not in state 0, as things might
* go differently if we start from state 0 here.
/* Conditions under which it's guaranteed safe-to-break before current glyph:
*
* Ugh. The indexing here is ugly... */
if (state && buffer->backtrack_len () && buffer->idx < buffer->len)
{
/* If there's no action and we're just epsilon-transitioning to state 0,
* safe to break. */
if (c->is_actionable (this, entry) ||
!(entry.newState == StateTable<Types, EntryData>::STATE_START_OF_TEXT &&
entry.flags == context_t::DontAdvance))
buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
}
* 1. There was no action in this transition; and
*
* 2. If we break before current glyph, the results will be the same. That
* is guaranteed if:
*
* 2a. We were already in start-of-text state; or
*
* 2b. We are epsilon-transitioning to start-of-text state; or
*
* 2c. Starting from start-of-text state seeing current glyph:
*
* 2c'. There won't be any actions; and
*
* 2c". We would end up in the same state that we were going to end up
* in now, including whether epsilon-transitioning.
*
* and
*
* 3. If we break before current glyph, there won't be any end-of-text action
* after previous glyph.
*
* This triples the transitions we need to look up, but is worth returning
* granular unsafe-to-break results. See eg.:
*
* https://github.com/harfbuzz/harfbuzz/issues/2860
*/
const EntryT *wouldbe_entry;
bool safe_to_break =
/* 1. */
!c->is_actionable (this, entry)
&&
/* 2. */
(
/* 2a. */
state == StateTableT::STATE_START_OF_TEXT
||
/* 2b. */
(
(entry.flags & context_t::DontAdvance) &&
next_state == StateTableT::STATE_START_OF_TEXT
)
||
/* 2c. */
(
wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
,
/* 2c'. */
!c->is_actionable (this, *wouldbe_entry)
&&
/* 2c". */
(
next_state == machine.new_state (wouldbe_entry->newState)
&&
(entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
)
)
)
&&
/* 3. */
!c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
;
/* Unsafe-to-break if end-of-text would kick in here. */
if (buffer->idx + 2 <= buffer->len)
{
const Entry<EntryData> &end_entry = machine.get_entry (state, StateTable<Types, EntryData>::CLASS_END_OF_TEXT);
if (c->is_actionable (this, end_entry))
buffer->unsafe_to_break (buffer->idx, buffer->idx + 2);
}
if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
c->transition (this, entry);
state = machine.new_state (entry.newState);
state = next_state;
DEBUG_MSG (APPLY, nullptr, "s%d", state);
if (buffer->idx == buffer->len)
if (buffer->idx == buffer->len || unlikely (!buffer->successful))
break;
if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
if (!c->in_place)
{
for (; buffer->successful && buffer->idx < buffer->len;)
buffer->next_glyph ();
buffer->swap_buffers ();
}
}
public:
const StateTable<Types, EntryData> &machine;
const StateTableT &machine;
hb_buffer_t *buffer;
unsigned int num_glyphs;
};

View File

@ -337,9 +337,9 @@ struct ContextualSubtable
const EntryData &data = entries[i].data;
if (data.markIndex != 0xFFFF)
num_lookups = hb_max (num_lookups, 1 + data.markIndex);
num_lookups = hb_max (num_lookups, 1u + data.markIndex);
if (data.currentIndex != 0xFFFF)
num_lookups = hb_max (num_lookups, 1 + data.currentIndex);
num_lookups = hb_max (num_lookups, 1u + data.currentIndex);
}
return_trace (substitutionTables.sanitize (c, this, num_lookups));
@ -499,7 +499,7 @@ struct LigatureSubtable
}
DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1);
buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]);
if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return;
if (unlikely (!actionData->sanitize (&c->sanitizer))) break;
action = *actionData;
@ -525,25 +525,25 @@ struct LigatureSubtable
hb_codepoint_t lig = ligatureData;
DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
buffer->replace_glyph (lig);
if (unlikely (!buffer->replace_glyph (lig))) return;
unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u;
/* Now go and delete all subsequent components. */
while (match_length - 1u > cursor)
{
DEBUG_MSG (APPLY, nullptr, "Skipping ligature component");
buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]);
buffer->replace_glyph (DELETED_GLYPH);
if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return;
if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return;
}
buffer->move_to (lig_end);
if (unlikely (!buffer->move_to (lig_end))) return;
buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len);
}
actionData++;
}
while (!(action & LigActionLast));
buffer->move_to (end);
if (unlikely (!buffer->move_to (end))) return;
}
}
@ -733,17 +733,16 @@ struct InsertionSubtable
bool before = flags & MarkedInsertBefore;
unsigned int end = buffer->out_len;
buffer->move_to (mark);
if (unlikely (!buffer->move_to (mark))) return;
if (buffer->idx < buffer->len && !before)
buffer->copy_glyph ();
if (unlikely (!buffer->copy_glyph ())) return;
/* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++)
buffer->output_glyph (glyphs[i]);
if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
if (buffer->idx < buffer->len && !before)
buffer->skip_glyph ();
buffer->move_to (end + count);
if (unlikely (!buffer->move_to (end + count))) return;
buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len));
}
@ -764,10 +763,9 @@ struct InsertionSubtable
unsigned int end = buffer->out_len;
if (buffer->idx < buffer->len && !before)
buffer->copy_glyph ();
if (unlikely (!buffer->copy_glyph ())) return;
/* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++)
buffer->output_glyph (glyphs[i]);
if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
if (buffer->idx < buffer->len && !before)
buffer->skip_glyph ();
@ -786,7 +784,7 @@ struct InsertionSubtable
*
* https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417
*/
buffer->move_to ((flags & DontAdvance) ? end : end + count);
if (unlikely (!buffer->move_to ((flags & DontAdvance) ? end : end + count))) return;
}
}

View File

@ -79,13 +79,18 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
* @short_description: Apple Advanced Typography Layout
* @include: hb-aat.h
*
* Functions for querying OpenType Layout features in the font face.
* Functions for querying AAT Layout features in the font face.
*
* HarfBuzz supports all of the AAT tables used to implement shaping. Other
* AAT tables and their associated features are not supported.
**/
#if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT)
/* Table data courtesy of Apple. Converted from mnemonics to integers
/* Mapping from OpenType feature tags to AAT feature names and selectors.
*
* Table data courtesy of Apple. Converted from mnemonics to integers
* when moving to this file. */
static const hb_aat_feature_mapping_t feature_mappings[] =
{
@ -167,6 +172,17 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
{HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF},
};
/**
* hb_aat_layout_find_feature_mapping:
* @tag: The requested #hb_tag_t feature tag
*
* Fetches the AAT feature-and-selector combination that corresponds
* to a given OpenType feature tag.
*
* Return value: the AAT features and selectors corresponding to the
* OpenType feature tag queried
*
**/
const hb_aat_feature_mapping_t *
hb_aat_layout_find_feature_mapping (hb_tag_t tag)
{
@ -202,11 +218,17 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
}
/*
/**
* hb_aat_layout_has_substitution:
* @face:
* @face: #hb_face_t to work upon
*
* Tests whether the specified face includes any substitutions in the
* `morx` or `mort` tables.
*
* <note>Note: does not examine the `GSUB` table.</note>
*
* Return value: %true if data found, %false otherwise
*
* Returns:
* Since: 2.3.0
*/
hb_bool_t
@ -263,11 +285,17 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
}
/*
/**
* hb_aat_layout_has_positioning:
* @face:
* @face: #hb_face_t to work upon
*
* Tests whether the specified face includes any positioning information
* in the `kerx` table.
*
* <note>Note: does not examine the `GPOS` table.</note>
*
* Return value: %true if data found, %false otherwise
*
* Returns:
* Since: 2.3.0
*/
hb_bool_t
@ -290,11 +318,15 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
}
/*
/**
* hb_aat_layout_has_tracking:
* @face:
* @face:: #hb_face_t to work upon
*
* Tests whether the specified face includes any tracking information
* in the `trak` table.
*
* Return value: %true if data found, %false otherwise
*
* Returns:
* Since: 2.3.0
*/
hb_bool_t
@ -316,10 +348,13 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
/**
* hb_aat_layout_get_feature_types:
* @face: a face object
* @start_offset: iteration's start offset
* @feature_count:(inout) (allow-none): buffer size as input, filled size as output
* @features: (out caller-allocates) (array length=feature_count): features buffer
* @face: #hb_face_t to work upon
* @start_offset: offset of the first feature type to retrieve
* @feature_count: (inout) (optional): Input = the maximum number of feature types to return;
* Output = the actual number of feature types returned (may be zero)
* @features: (out caller-allocates) (array length=feature_count): Array of feature types found
*
* Fetches a list of the AAT feature types included in the specified face.
*
* Return value: Number of all available feature types.
*
@ -336,10 +371,12 @@ hb_aat_layout_get_feature_types (hb_face_t *face,
/**
* hb_aat_layout_feature_type_get_name_id:
* @face: a face object
* @feature_type: feature id
* @face: #hb_face_t to work upon
* @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type
*
* Return value: Name ID index
* Fetches the name identifier of the specified feature type in the face's `name` table.
*
* Return value: Name identifier of the requested feature type
*
* Since: 2.2.0
*/
@ -351,19 +388,23 @@ hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
}
/**
* hb_aat_layout_feature_type_get_selectors:
* @face: a face object
* @feature_type: feature id
* @start_offset: iteration's start offset
* @selector_count: (inout) (allow-none): buffer size as input, filled size as output
* @selectors: (out caller-allocates) (array length=selector_count): settings buffer
* @default_index: (out) (allow-none): index of default selector if any
* hb_aat_layout_feature_type_get_selector_infos:
* @face: #hb_face_t to work upon
* @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type
* @start_offset: offset of the first feature type to retrieve
* @selector_count: (inout) (optional): Input = the maximum number of selectors to return;
* Output = the actual number of selectors returned (may be zero)
* @selectors: (out caller-allocates) (array length=selector_count) (optional):
* A buffer pointer. The selectors available for the feature type queries.
* @default_index: (out) (optional): The index of the feature's default selector, if any
*
* Fetches a list of the selectors available for the specified feature in the given face.
*
* If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then
* the feature type is non-exclusive. Otherwise, @default_index is the index of
* the selector that is selected by default.
*
* Return value: Number of all available feature selectors.
* Return value: Number of all available feature selectors
*
* Since: 2.2.0
*/

View File

@ -22,7 +22,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HB_AAT_H_IN
#if !defined(HB_AAT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-aat.h> instead."
#endif
@ -37,7 +37,48 @@ HB_BEGIN_DECLS
/**
* hb_aat_layout_feature_type_t:
* @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type
* @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: [All Typographic Features](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type0)
* @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: [Ligatures](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type1)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2)
* @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: [Letter Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type3)
* @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: [Vertical Substitution](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type4)
* @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: [Linguistic Rearrangement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type5)
* @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING: [Number Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type6)
* @HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE: [Smart Swash](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type8)
* @HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE: [Diacritics](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type9)
* @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION: [Vertical Position](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type10)
* @HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS: [Fractions](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type11)
* @HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE: [Overlapping Characters](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type13)
* @HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS: [Typographic Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type14)
* @HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS: [Mathematical Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type15)
* @HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE: [Ornament Sets](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type16)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES: [Character Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type17)
* @HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE: [Design Complexity](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type18)
* @HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS: [Style Options](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type19)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE: [Character Shape](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type20)
* @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE: [Number Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type21)
* @HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING: [Text Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type22)
* @HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION: [Transliteration](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type23)
* @HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE: [Annotation](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type24)
* @HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE: [Kana Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type25)
* @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE: [Ideographic Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type26)
* @HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE: [Unicode Decomposition](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type27)
* @HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA: [Ruby Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type28)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE: [CJK Symbol Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type29)
* @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE: [Ideographic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type30)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE: [CJK Vertical Roman Placement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type31)
* @HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN: [Italic CJK Roman](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type32)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT: [Case Sensitive Layout](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type33)
* @HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA: [Alternate Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type34)
* @HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES: [Stylistic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type35)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES: [Contextual Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type36)
* @HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE: [Lower Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type37)
* @HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE: [Upper Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type38)
* @HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE: [Language Tag](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type39)
* @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE: [CJK Roman Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type103)
*
* The possible feature types defined for AAT shaping, from Apple [Font Feature Registry](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html).
*
* Since: 2.2.0
*/
@ -85,12 +126,265 @@ typedef enum
HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39,
HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103,
/*< private >*/
_HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_type_t;
/**
* hb_aat_layout_feature_selector_t:
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID: Initial, unset feature selector
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE: Deprecated
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS: Deprecated
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE: Deprecated
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS: Deprecated
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS: Deprecated
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS: Deprecated
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS: for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS: for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS: for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5: for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS: for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT: for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION: for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA: for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE: for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN: Deprecated; use #HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF: for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS: for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
* @HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN: for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE
*
* The selectors defined for specifying AAT feature settings.
*
* Since: 2.2.0
*/
@ -424,6 +718,7 @@ typedef enum
HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2,
HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3,
/*< private >*/
_HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_selector_t;
@ -437,8 +732,15 @@ HB_EXTERN hb_ot_name_id_t
hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
hb_aat_layout_feature_type_t feature_type);
typedef struct hb_aat_layout_feature_selector_info_t
{
/**
* hb_aat_layout_feature_selector_info_t:
* @name_id: The selector's name identifier
* @enable: The value to turn the selector on
* @disable: The value to turn the selector off
*
* Structure representing a setting for an #hb_aat_layout_feature_type_t.
*/
typedef struct hb_aat_layout_feature_selector_info_t {
hb_ot_name_id_t name_id;
hb_aat_layout_feature_selector_t enable;
hb_aat_layout_feature_selector_t disable;
@ -446,6 +748,13 @@ typedef struct hb_aat_layout_feature_selector_info_t
unsigned int reserved;
} hb_aat_layout_feature_selector_info_t;
/**
* HB_AAT_LAYOUT_NO_SELECTOR_INDEX
*
* Used when getting or setting AAT feature selectors. Indicates that
* there is no selector index corresponding to the selector of interest.
*
*/
#define HB_AAT_LAYOUT_NO_SELECTOR_INDEX 0xFFFFu
HB_EXTERN unsigned int

View File

@ -35,6 +35,132 @@
#include "hb-number.hh"
/*
* Flags
*/
/* Enable bitwise ops on enums marked as flags_t */
/* To my surprise, looks like the function resolver is happy to silently cast
* one enum to another... So this doesn't provide the type-checking that I
* originally had in mind... :(.
*
* For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163
*/
#ifdef _MSC_VER
# pragma warning(disable:4200)
# pragma warning(disable:4800)
#endif
#define HB_MARK_AS_FLAG_T(T) \
extern "C++" { \
static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \
static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
} \
static_assert (true, "")
/* Useful for set-operations on small enums.
* For example, for testing "x ∈ {x1, x2, x3}" use:
* (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
*/
#define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x)))
#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0)
#define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x))
#define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x)))
#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0)
/*
* Big-endian integers.
*/
/* Endian swap, used in Windows related backends */
static inline constexpr uint16_t hb_uint16_swap (uint16_t v)
{ return (v >> 8) | (v << 8); }
static inline constexpr uint32_t hb_uint32_swap (uint32_t v)
{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
template <typename Type, int Bytes = sizeof (Type)>
struct BEInt;
template <typename Type>
struct BEInt<Type, 1>
{
public:
BEInt () = default;
constexpr BEInt (Type V) : v {uint8_t (V)} {}
constexpr operator Type () const { return v; }
private: uint8_t v;
};
template <typename Type>
struct BEInt<Type, 2>
{
public:
BEInt () = default;
constexpr BEInt (Type V) : v {uint8_t ((V >> 8) & 0xFF),
uint8_t ((V ) & 0xFF)} {}
struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
constexpr operator Type () const
{
#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
defined(__BYTE_ORDER) && \
(__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
/* Spoon-feed the compiler a big-endian integer with alignment 1.
* https://github.com/harfbuzz/harfbuzz/pull/1398 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
return __builtin_bswap16 (((packed_uint16_t *) this)->v);
#else /* __BYTE_ORDER == __BIG_ENDIAN */
return ((packed_uint16_t *) this)->v;
#endif
#else
return (v[0] << 8)
+ (v[1] );
#endif
}
private: uint8_t v[2];
};
template <typename Type>
struct BEInt<Type, 3>
{
static_assert (!hb_is_signed (Type), "");
public:
BEInt () = default;
constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF),
uint8_t ((V >> 8) & 0xFF),
uint8_t ((V ) & 0xFF)} {}
constexpr operator Type () const { return (v[0] << 16)
+ (v[1] << 8)
+ (v[2] ); }
private: uint8_t v[3];
};
template <typename Type>
struct BEInt<Type, 4>
{
public:
BEInt () = default;
constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF),
uint8_t ((V >> 16) & 0xFF),
uint8_t ((V >> 8) & 0xFF),
uint8_t ((V ) & 0xFF)} {}
constexpr operator Type () const { return (v[0] << 24)
+ (v[1] << 16)
+ (v[2] << 8)
+ (v[3] ); }
private: uint8_t v[4];
};
/* Floats. */
/* We want our rounding towards +infinity. */
static inline float
_hb_roundf (float x) { return floorf (x + .5f); }
#define roundf(x) _hb_roundf(x)
/* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits,
* values will be truncated / overlap, and might not decode exactly. */
#define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z))
@ -48,6 +174,7 @@
#define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300)
#define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu)
struct
{
/* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
@ -215,7 +342,9 @@ struct
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
(hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v)))
(
hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v))
)
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
@ -269,7 +398,9 @@ struct
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
(hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v)))
(
hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v))
)
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
@ -296,6 +427,40 @@ struct
}
HB_FUNCOBJ (hb_get);
struct
{
private:
template <typename T1, typename T2> auto
impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
(
hb_forward<T2> (v2).cmp (hb_forward<T1> (v1)) == 0
)
template <typename T1, typename T2> auto
impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
(
hb_forward<T1> (v1).cmp (hb_forward<T2> (v2)) == 0
)
template <typename T1, typename T2> auto
impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
(
hb_forward<T1> (v1) == hb_forward<T2> (v2)
)
public:
template <typename T1, typename T2> auto
operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN
(
impl (hb_forward<T1> (v1),
hb_forward<T2> (v2),
hb_prioritize)
)
}
HB_FUNCOBJ (hb_equal);
template <typename T1, typename T2>
struct hb_pair_t
@ -350,14 +515,14 @@ struct
{
template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
(a <= b ? hb_forward<T> (a) : hb_forward<T2> (b))
}
HB_FUNCOBJ (hb_min);
struct
{
template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
(a >= b ? hb_forward<T> (a) : hb_forward<T2> (b))
}
HB_FUNCOBJ (hb_max);
struct
@ -375,7 +540,7 @@ HB_FUNCOBJ (hb_clamp);
/* Return the number of 1 bits in v. */
template <typename T>
static inline HB_CONST_FUNC unsigned int
static inline unsigned int
hb_popcount (T v)
{
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
@ -416,7 +581,7 @@ hb_popcount (T v)
/* Returns the number of bits needed to store number */
template <typename T>
static inline HB_CONST_FUNC unsigned int
static inline unsigned int
hb_bit_storage (T v)
{
if (unlikely (!v)) return 0;
@ -490,7 +655,7 @@ hb_bit_storage (T v)
/* Returns the number of zero bits in the least significant side of v */
template <typename T>
static inline HB_CONST_FUNC unsigned int
static inline unsigned int
hb_ctz (T v)
{
if (unlikely (!v)) return 8 * sizeof (T);
@ -988,32 +1153,24 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o
struct hb_bitwise_and
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = false;
static constexpr bool passthru_right = false;
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
}
HB_FUNCOBJ (hb_bitwise_and);
struct hb_bitwise_or
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = true;
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
}
HB_FUNCOBJ (hb_bitwise_or);
struct hb_bitwise_xor
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = true;
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
}
HB_FUNCOBJ (hb_bitwise_xor);
struct hb_bitwise_sub
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = false;
template <typename T> constexpr auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
}

View File

@ -142,7 +142,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
bool lfind (const T &x, unsigned *pos = nullptr) const
{
for (unsigned i = 0; i < length; ++i)
if (!this->arrayZ[i].cmp (x))
if (hb_equal (x, this->arrayZ[i]))
{
if (pos)
*pos = i;

View File

@ -52,7 +52,7 @@
#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
/* C++11-style GCC primitives. */
/* C++11-style GCC primitives. We prefer these as they don't require linking to libstdc++ / libc++. */
#define _hb_memory_barrier() __sync_synchronize ()
@ -73,7 +73,8 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
}
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
#elif !defined(HB_NO_MT) && __cplusplus >= 201103L
#elif !defined(HB_NO_MT)
/* C++11 atomics. */
@ -101,117 +102,6 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
#elif !defined(HB_NO_MT) && defined(_WIN32)
#include <windows.h>
static inline void _hb_memory_barrier ()
{
#if !defined(MemoryBarrier) && !defined(__MINGW32_VERSION)
/* MinGW has a convoluted history of supporting MemoryBarrier. */
LONG dummy = 0;
InterlockedExchange (&dummy, 1);
#else
MemoryBarrier ();
#endif
}
#define _hb_memory_barrier() _hb_memory_barrier ()
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((LONG *) (AI), (V))
static_assert ((sizeof (LONG) == sizeof (int)), "");
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O))
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
#define _hb_memory_barrier() __sync_synchronize ()
#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add ((AI), (V))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
#include <atomic.h>
#include <mbarrier.h>
#define _hb_memory_r_barrier() __machine_r_barrier ()
#define _hb_memory_w_barrier() __machine_w_barrier ()
#define _hb_memory_barrier() __machine_rw_barrier ()
static inline int _hb_fetch_and_add (int *AI, int V)
{
_hb_memory_w_barrier ();
int result = atomic_add_int_nv ((uint_t *) AI, V) - V;
_hb_memory_r_barrier ();
return result;
}
static inline bool _hb_compare_and_swap_ptr (void **P, void *O, void *N)
{
_hb_memory_w_barrier ();
bool result = atomic_cas_ptr (P, O, N) == O;
_hb_memory_r_barrier ();
return result;
}
#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((P), (O), (N))
#elif !defined(HB_NO_MT) && defined(__APPLE__)
#include <libkern/OSAtomic.h>
#ifdef __MAC_OS_X_MIN_REQUIRED
#include <AvailabilityMacros.h>
#elif defined(__IPHONE_OS_MIN_REQUIRED)
#include <Availability.h>
#endif
#define _hb_memory_barrier() OSMemoryBarrier ()
#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), (AI)) - (V))
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((O), (N), (P))
#else
#if __ppc64__ || __x86_64__ || __aarch64__
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
#else
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
#endif
#endif
#elif !defined(HB_NO_MT) && defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__))
#include <builtins.h>
#define _hb_memory_barrier() __lwsync ()
static inline int _hb_fetch_and_add (int *AI, int V)
{
_hb_memory_barrier ();
int result = __fetch_and_add (AI, V);
_hb_memory_barrier ();
return result;
}
static inline bool _hb_compare_and_swaplp (long *P, long O, long N)
{
_hb_memory_barrier ();
bool result = __compare_and_swaplp (P, &O, N);
_hb_memory_barrier ();
return result;
}
#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long *) (P), (long) (O), (long) (N))
static_assert ((sizeof (long) == sizeof (void *)), "");
#elif defined(HB_NO_MT)
#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V))
@ -259,9 +149,11 @@ inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memo
#endif
#define HB_ATOMIC_INT_INIT(V) {V}
struct hb_atomic_int_t
{
hb_atomic_int_t () = default;
constexpr hb_atomic_int_t (int v) : v (v) {}
void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
void set (int v_) { hb_atomic_int_impl_set (&v, v_); }
int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
@ -269,16 +161,17 @@ struct hb_atomic_int_t
int inc () { return hb_atomic_int_impl_add (&v, 1); }
int dec () { return hb_atomic_int_impl_add (&v, -1); }
int v;
int v = 0;
};
#define HB_ATOMIC_PTR_INIT(V) {V}
template <typename P>
struct hb_atomic_ptr_t
{
typedef hb_remove_pointer<P> T;
hb_atomic_ptr_t () = default;
constexpr hb_atomic_ptr_t (T* v) : v (v) {}
void init (T* v_ = nullptr) { set_relaxed (v_); }
void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); }
@ -288,7 +181,7 @@ struct hb_atomic_ptr_t
T * operator -> () const { return get (); }
template <typename C> operator C * () const { return get (); }
T *v;
T *v = nullptr;
};

View File

@ -35,9 +35,6 @@
#include <sys/mman.h>
#endif /* HAVE_SYS_MMAN_H */
#include <stdio.h>
#include <stdlib.h>
/**
* SECTION: hb-blob
@ -58,7 +55,7 @@
* @length: Length of @data in bytes.
* @mode: Memory mode for @data.
* @user_data: Data parameter to pass to @destroy.
* @destroy: Callback to call when @data is not needed anymore.
* @destroy: (nullable): Callback to call when @data is not needed anymore.
*
* Creates a new "blob" object wrapping @data. The @mode parameter is used
* to negotiate ownership and lifecycle of @data.
@ -116,7 +113,7 @@ _hb_blob_destroy (void *data)
* @length: Length of sub-blob.
*
* Returns a blob that represents a range of bytes in @parent. The new
* blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
* blob is always created with #HB_MEMORY_MODE_READONLY, meaning that it
* will never modify data in the parent blob. The parent data is not
* expected to be modified, and will result in undefined behavior if it
* is.
@ -156,7 +153,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
*
* Makes a writable copy of @blob.
*
* Return value: New blob, or nullptr if allocation failed.
* Return value: The new blob, or nullptr if allocation failed
*
* Since: 1.8.0
**/
@ -182,7 +179,7 @@ hb_blob_copy_writable_or_fail (hb_blob_t *blob)
*
* See TODO:link object types for more information.
*
* Return value: (transfer full): the empty blob.
* Return value: (transfer full): The empty blob.
*
* Since: 0.9.2
**/
@ -234,13 +231,15 @@ hb_blob_destroy (hb_blob_t *blob)
/**
* hb_blob_set_user_data: (skip)
* @blob: a blob.
* @key: key for data to set.
* @data: data to set.
* @destroy: callback to call when @data is not needed anymore.
* @replace: whether to replace an existing data with the same key.
* @blob: An #hb_blob_t
* @key: The user-data key to set
* @data: A pointer to the user data to set
* @destroy: (nullable): A callback to call when @data is not needed anymore
* @replace: Whether to replace an existing data with the same key
*
* Return value:
* Attaches a user-data key/data pair to the specified blob.
*
* Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@ -256,12 +255,13 @@ hb_blob_set_user_data (hb_blob_t *blob,
/**
* hb_blob_get_user_data: (skip)
* @blob: a blob.
* @key: key for data to get.
* @blob: a blob
* @key: The user-data key to query
*
* Fetches the user data associated with the specified key,
* attached to the specified font-functions structure.
*
*
* Return value: (transfer none):
* Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@ -275,9 +275,9 @@ hb_blob_get_user_data (hb_blob_t *blob,
/**
* hb_blob_make_immutable:
* @blob: a blob.
*
* @blob: a blob
*
* Makes a blob immutable.
*
* Since: 0.9.2
**/
@ -294,9 +294,9 @@ hb_blob_make_immutable (hb_blob_t *blob)
* hb_blob_is_immutable:
* @blob: a blob.
*
* Tests whether a blob is immutable.
*
*
* Return value: TODO
* Return value: %true if @blob is immutable, %false otherwise
*
* Since: 0.9.2
**/
@ -311,9 +311,9 @@ hb_blob_is_immutable (hb_blob_t *blob)
* hb_blob_get_length:
* @blob: a blob.
*
* Fetches the length of a blob's data.
*
*
* Return value: the length of blob data in bytes.
* Return value: the length of @blob data in bytes.
*
* Since: 0.9.2
**/
@ -326,11 +326,11 @@ hb_blob_get_length (hb_blob_t *blob)
/**
* hb_blob_get_data:
* @blob: a blob.
* @length: (out):
* @length: (out): The length in bytes of the data retrieved
*
* Fetches the data from a blob.
*
*
* Returns: (transfer none) (array length=length):
* Returns: (transfer none) (array length=length): the byte data of @blob.
*
* Since: 0.9.2
**/
@ -362,16 +362,14 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
char *
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
{
if (!blob->try_make_writable ()) {
if (length)
*length = 0;
if (hb_object_is_immutable (blob) ||
!blob->try_make_writable ())
{
if (length) *length = 0;
return nullptr;
}
if (length)
*length = blob->length;
if (length) *length = blob->length;
return const_cast<char *> (blob->data);
}
@ -437,8 +435,8 @@ hb_blob_t::try_make_writable_inplace ()
bool
hb_blob_t::try_make_writable ()
{
if (hb_object_is_immutable (this))
return false;
if (unlikely (!length))
mode = HB_MEMORY_MODE_WRITABLE;
if (this->mode == HB_MEMORY_MODE_WRITABLE)
return true;
@ -558,9 +556,12 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file)
/**
* hb_blob_create_from_file:
* @file_name: font filename.
* @file_name: A font filename
*
* Returns: A hb_blob_t pointer with the content of the file
* Creates a new blob containing the data from the
* specified binary font file.
*
* Returns: An #hb_blob_t pointer with the content of the file
*
* Since: 1.7.7
**/

View File

@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif
@ -36,25 +36,36 @@
HB_BEGIN_DECLS
/*
* Note re various memory-modes:
/**
* hb_memory_mode_t:
* @HB_MEMORY_MODE_DUPLICATE: HarfBuzz immediately makes a copy of the data.
* @HB_MEMORY_MODE_READONLY: HarfBuzz client will never modify the data,
* and HarfBuzz will never modify the data.
* @HB_MEMORY_MODE_WRITABLE: HarfBuzz client made a copy of the data solely
* for HarfBuzz, so HarfBuzz may modify the data.
* @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE: See above
*
* Data type holding the memory modes available to
* client programs.
*
* Regarding these various memory-modes:
*
* - In no case shall the HarfBuzz client modify memory
* that is passed to HarfBuzz in a blob. If there is
* any such possibility, MODE_DUPLICATE should be used
* any such possibility, @HB_MEMORY_MODE_DUPLICATE should be used
* such that HarfBuzz makes a copy immediately,
*
* - Use MODE_READONLY otherwise, unless you really really
* - Use @HB_MEMORY_MODE_READONLY otherwise, unless you really really
* really know what you are doing,
*
* - MODE_WRITABLE is appropriate if you really made a
* - @HB_MEMORY_MODE_WRITABLE is appropriate if you really made a
* copy of data solely for the purpose of passing to
* HarfBuzz and doing that just once (no reuse!),
*
* - If the font is mmap()ed, it's ok to use
* READONLY_MAY_MAKE_WRITABLE, however, using that mode
* correctly is very tricky. Use MODE_READONLY instead.
*/
* - If the font is mmap()ed, it's okay to use
* @HB_MEMORY_READONLY_MAY_MAKE_WRITABLE, however, using that mode
* correctly is very tricky. Use @HB_MEMORY_MODE_READONLY instead.
**/
typedef enum {
HB_MEMORY_MODE_DUPLICATE,
HB_MEMORY_MODE_READONLY,
@ -62,6 +73,14 @@ typedef enum {
HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
} hb_memory_mode_t;
/**
* hb_blob_t:
*
* Data type for blobs. A blob wraps a chunk of binary
* data and facilitates its lifecycle management between
* a client program and HarfBuzz.
*
**/
typedef struct hb_blob_t hb_blob_t;
HB_EXTERN hb_blob_t *

View File

@ -90,6 +90,7 @@ struct hb_blob_ptr_t
unsigned int get_length () const { return b.get ()->length; }
void destroy () { hb_blob_destroy (b.get ()); b = nullptr; }
private:
hb_nonnull_ptr_t<hb_blob_t> b;
};

View File

@ -91,10 +91,10 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
switch ((unsigned) format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
}
@ -125,6 +125,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (i)
*p++ = ',';
else
*p++ = '[';
*p++ = '{';
@ -134,8 +136,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
char g[128];
hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
*p++ = '"';
for (char *q = g; *q; q++) {
if (*q == '"')
for (char *q = g; *q; q++)
{
if (unlikely (*q == '"' || *q == '\\'))
*p++ = '\\';
*p++ = *q;
}
@ -151,10 +154,10 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
x+pos[i].x_offset, y+pos[i].y_offset));
x+pos[i].x_offset, y+pos[i].y_offset));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
pos[i].x_advance, pos[i].y_advance));
pos[i].x_advance, pos[i].y_advance));
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
@ -168,12 +171,14 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
hb_glyph_extents_t extents;
hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
extents.x_bearing, extents.y_bearing));
extents.x_bearing, extents.y_bearing));
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
extents.width, extents.height));
extents.width, extents.height));
}
*p++ = '}';
if (i == end-1)
*p++ = ']';
unsigned int l = p - b;
if (buf_size > l)
@ -196,6 +201,59 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
return end - start;
}
static unsigned int
_hb_buffer_serialize_unicode_json (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
*buf_consumed = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
char *p = b;
if (i)
*p++ = ',';
else
*p++ = '[';
*p++ = '{';
APPEND ("\"u\":");
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
}
*p++ = '}';
if (i == end-1)
*p++ = ']';
unsigned int l = p - b;
if (buf_size > l)
{
memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
*buf = '\0';
} else
return i - start;
}
return end - start;
}
static unsigned int
_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
unsigned int start,
@ -208,7 +266,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
hb_position_t x = 0, y = 0;
@ -221,9 +279,12 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
if (i)
*p++ = '|';
else
*p++ = '[';
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
{
/* TODO Escape delimiters we use. */
hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
p += strlen (p);
}
@ -261,6 +322,10 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
}
if (i == end-1) {
*p++ = ']';
}
unsigned int l = p - b;
if (buf_size > l)
{
@ -282,6 +347,51 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
return end - start;
}
static unsigned int
_hb_buffer_serialize_unicode_text (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_flags_t flags)
{
hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
*buf_consumed = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
char *p = b;
if (i)
*p++ = '|';
else
*p++ = '<';
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "U+%04X", info[i].codepoint));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
}
if (i == end-1)
*p++ = '>';
unsigned int l = p - b;
if (buf_size > l)
{
memcpy (buf, b, l);
buf += l;
buf_size -= l;
*buf_consumed += l;
*buf = '\0';
} else
return i - start;
}
return end - start;
}
/**
* hb_buffer_serialize_glyphs:
* @buffer: an #hb_buffer_t buffer.
@ -290,8 +400,8 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
* @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
* @font: (allow-none): the #hb_font_t used to shape this buffer, needed to
* @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.
* @font: (nullable): the #hb_font_t used to shape this buffer, needed to
* read glyph names and extents. If %NULL, and empty font will be used.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
@ -308,6 +418,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
* ```
* [uni0651=0@518,0+0|uni0628=0+1897]
* ```
*
* - The serialized glyphs are delimited with `[` and `]`.
* - Glyphs are separated with `|`
* - Each glyph starts with glyph name, or glyph index if
@ -316,12 +427,28 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format:
* - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then,
* - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then,
* - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the
* #hb_glyph_extents_t in the format
* `&lt;x_bearing,y_bearing,width,height&gt;`
* - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `<x_bearing,y_bearing,width,height>`
*
* ## json
* TODO.
* A machine-readable, structured format.
* The serialized glyphs will look something like:
*
* ```
* [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0},
* {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}]
* ```
*
* Each glyph is a JSON object, with the following properties:
* - `g`: the glyph name or glyph index if
* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set.
* - `cl`: #hb_glyph_info_t.cluster if
* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
* - `dx`,`dy`,`ax`,`ay`: #hb_glyph_position_t.x_offset, #hb_glyph_position_t.y_offset,
* #hb_glyph_position_t.x_advance and #hb_glyph_position_t.y_advance
* respectively, if #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set.
* - `xb`,`yb`,`w`,`h`: #hb_glyph_extents_t.x_bearing, #hb_glyph_extents_t.y_bearing,
* #hb_glyph_extents_t.width and #hb_glyph_extents_t.height respectively if
* #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set.
*
* Return value:
* The number of serialized items.
@ -339,7 +466,8 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
assert (start <= end && end <= buffer->len);
end = hb_clamp (end, start, buffer->len);
start = hb_min (start, end);
unsigned int sconsumed;
if (!buf_consumed)
@ -348,8 +476,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (buf_size)
*buf = '\0';
assert ((!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)) ||
(buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS));
buffer->assert_glyphs ();
if (!buffer->have_positions)
flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;
@ -364,13 +491,13 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_serialize_glyphs_text (buffer, start, end,
buf, buf_size, buf_consumed,
font, flags);
buf, buf_size, buf_consumed,
font, flags);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_serialize_glyphs_json (buffer, start, end,
buf, buf_size, buf_consumed,
font, flags);
buf, buf_size, buf_consumed,
font, flags);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
@ -379,6 +506,184 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
}
}
/**
* hb_buffer_serialize_unicode:
* @buffer: an #hb_buffer_t buffer.
* @start: the first item in @buffer to serialize.
* @end: the last item in @buffer to serialize.
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
* @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
*
* Serializes @buffer into a textual representation of its content,
* when the buffer contains Unicode codepoints (i.e., before shaping). This is
* useful for showing the contents of the buffer, for example during debugging.
* There are currently two supported serialization formats:
*
* ## text
* A human-readable, plain text format.
* The serialized codepoints will look something like:
*
* ```
*  <U+0651=0|U+0628=1>
* ```
*
* - Glyphs are separated with `|`
* - Unicode codepoints are expressed as zero-padded four (or more)
* digit hexadecimal numbers preceded by `U+`
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, the cluster
* will be indicated with a `=` then #hb_glyph_info_t.cluster.
*
* ## json
* A machine-readable, structured format.
* The serialized codepoints will be a list of objects with the following
* properties:
* - `u`: the Unicode codepoint as a decimal integer
* - `cl`: #hb_glyph_info_t.cluster if
* #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set.
*
* For example:
*
* ```
* [{u:1617,cl:0},{u:1576,cl:1}]
* ```
*
* Return value:
* The number of serialized items.
*
* Since: 2.7.3
**/
unsigned int
hb_buffer_serialize_unicode (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
end = hb_clamp (end, start, buffer->len);
start = hb_min (start, end);
unsigned int sconsumed;
if (!buf_consumed)
buf_consumed = &sconsumed;
*buf_consumed = 0;
if (buf_size)
*buf = '\0';
buffer->assert_unicode ();
if (unlikely (start == end))
return 0;
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_serialize_unicode_text (buffer, start, end,
buf, buf_size, buf_consumed, flags);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_serialize_unicode_json (buffer, start, end,
buf, buf_size, buf_consumed, flags);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
return 0;
}
}
static unsigned int
_hb_buffer_serialize_invalid (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
assert (!buffer->len);
unsigned int sconsumed;
if (!buf_consumed)
buf_consumed = &sconsumed;
if (buf_size < 3)
return 0;
if (format == HB_BUFFER_SERIALIZE_FORMAT_JSON) {
*buf++ = '[';
*buf++ = ']';
*buf = '\0';
} else if (format == HB_BUFFER_SERIALIZE_FORMAT_TEXT) {
*buf++ = '!';
*buf++ = '!';
*buf = '\0';
}
*buf_consumed = 2;
return 0;
}
/**
* hb_buffer_serialize:
* @buffer: an #hb_buffer_t buffer.
* @start: the first item in @buffer to serialize.
* @end: the last item in @buffer to serialize.
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
* @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf.
* @font: (nullable): the #hb_font_t used to shape this buffer, needed to
* read glyph names and extents. If %NULL, and empty font will be used.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
*
* Serializes @buffer into a textual representation of its content, whether
* Unicode codepoints or glyph identifiers and positioning information. This is
* useful for showing the contents of the buffer, for example during debugging.
* See the documentation of hb_buffer_serialize_unicode() and
* hb_buffer_serialize_glyphs() for a description of the output format.
*
* Return value:
* The number of serialized items.
*
* Since: 2.7.3
**/
unsigned int
hb_buffer_serialize (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_font_t *font,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
switch (buffer->content_type)
{
case HB_BUFFER_CONTENT_TYPE_GLYPHS:
return hb_buffer_serialize_glyphs (buffer, start, end, buf, buf_size,
buf_consumed, font, format, flags);
case HB_BUFFER_CONTENT_TYPE_UNICODE:
return hb_buffer_serialize_unicode (buffer, start, end, buf, buf_size,
buf_consumed, format, flags);
case HB_BUFFER_CONTENT_TYPE_INVALID:
default:
return _hb_buffer_serialize_invalid (buffer, start, end, buf, buf_size,
buf_consumed, format, flags);
}
}
static bool
parse_int (const char *pp, const char *end, int32_t *pv)
{
@ -403,21 +708,35 @@ parse_uint (const char *pp, const char *end, uint32_t *pv)
return true;
}
static bool
parse_hex (const char *pp, const char *end, uint32_t *pv)
{
unsigned int v;
const char *p = pp;
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, 16)))
return false;
*pv = v;
return true;
}
#include "hb-buffer-deserialize-json.hh"
#include "hb-buffer-deserialize-text.hh"
/**
* hb_buffer_deserialize_glyphs:
* @buffer: an #hb_buffer_t buffer.
* @buf: (array length=buf_len):
* @buf_len:
* @end_ptr: (out):
* @font:
* @format:
* @buf: (array length=buf_len): string to deserialize
* @buf_len: the size of @buf, or -1 if it is %NULL-terminated
* @end_ptr: (out) (optional): output pointer to the character after last
* consumed one.
* @font: (nullable): font for getting glyph IDs
* @format: the #hb_buffer_serialize_format_t of the input @buf
*
* Deserializes glyphs @buffer from textual representation in the format
* produced by hb_buffer_serialize_glyphs().
*
*
* Return value:
* Return value: %true if @buf is not fully consumed, %false otherwise.
*
* Since: 0.9.7
**/
@ -434,8 +753,14 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
end_ptr = &end;
*end_ptr = buf;
assert ((!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)) ||
(buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS));
buffer->assert_glyphs ();
if (unlikely (hb_object_is_immutable (buffer)))
{
if (end_ptr)
*end_ptr = buf;
return false;
}
if (buf_len == -1)
buf_len = strlen (buf);
@ -454,14 +779,84 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_deserialize_glyphs_text (buffer,
buf, buf_len, end_ptr,
font);
return _hb_buffer_deserialize_text (buffer,
buf, buf_len, end_ptr,
font);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_deserialize_glyphs_json (buffer,
buf, buf_len, end_ptr,
font);
return _hb_buffer_deserialize_json (buffer,
buf, buf_len, end_ptr,
font);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
return false;
}
}
/**
* hb_buffer_deserialize_unicode:
* @buffer: an #hb_buffer_t buffer.
* @buf: (array length=buf_len): string to deserialize
* @buf_len: the size of @buf, or -1 if it is %NULL-terminated
* @end_ptr: (out) (optional): output pointer to the character after last
* consumed one.
* @format: the #hb_buffer_serialize_format_t of the input @buf
*
* Deserializes Unicode @buffer from textual representation in the format
* produced by hb_buffer_serialize_unicode().
*
* Return value: %true if @buf is not fully consumed, %false otherwise.
*
* Since: 2.7.3
**/
hb_bool_t
hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
const char *buf,
int buf_len, /* -1 means nul-terminated */
const char **end_ptr, /* May be NULL */
hb_buffer_serialize_format_t format)
{
const char *end;
if (!end_ptr)
end_ptr = &end;
*end_ptr = buf;
buffer->assert_unicode ();
if (unlikely (hb_object_is_immutable (buffer)))
{
if (end_ptr)
*end_ptr = buf;
return false;
}
if (buf_len == -1)
buf_len = strlen (buf);
if (!buf_len)
{
*end_ptr = buf;
return false;
}
hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
hb_font_t* font = hb_font_get_empty ();
switch (format)
{
case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
return _hb_buffer_deserialize_text (buffer,
buf, buf_len, end_ptr,
font);
case HB_BUFFER_SERIALIZE_FORMAT_JSON:
return _hb_buffer_deserialize_json (buffer,
buf, buf_len, end_ptr,
font);
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID:

View File

@ -37,8 +37,9 @@
* @short_description: Input and output buffers
* @include: hb.h
*
* Buffers serve dual role in HarfBuzz; they hold the input characters that are
* passed to hb_shape(), and after shaping they hold the output glyphs.
* Buffers serve a dual role in HarfBuzz; before shaping, they hold
* the input characters that are passed to hb_shape(), and after
* shaping they hold the output glyphs.
**/
@ -50,7 +51,7 @@
* Checks the equality of two #hb_segment_properties_t's.
*
* Return value:
* %true if all properties of @a equal those of @b, false otherwise.
* %true if all properties of @a equal those of @b, %false otherwise.
*
* Since: 0.9.7
**/
@ -217,9 +218,6 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
void
hb_buffer_t::reset ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
hb_unicode_funcs_destroy (unicode);
unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ());
flags = HB_BUFFER_FLAG_DEFAULT;
@ -232,9 +230,6 @@ hb_buffer_t::reset ()
void
hb_buffer_t::clear ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
props = default_props;
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
@ -289,9 +284,6 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info)
void
hb_buffer_t::remove_output ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
have_output = false;
have_positions = false;
@ -302,9 +294,6 @@ hb_buffer_t::remove_output ()
void
hb_buffer_t::clear_output ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
have_output = true;
have_positions = false;
@ -315,9 +304,6 @@ hb_buffer_t::clear_output ()
void
hb_buffer_t::clear_positions ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
have_output = false;
have_positions = true;
@ -332,15 +318,19 @@ hb_buffer_t::swap_buffers ()
{
if (unlikely (!successful)) return;
assert (idx <= len);
if (unlikely (!next_glyphs (len - idx))) return;
assert (have_output);
have_output = false;
if (out_info != info)
{
hb_glyph_info_t *tmp_string;
tmp_string = info;
hb_glyph_info_t *tmp;
tmp = info;
info = out_info;
out_info = tmp_string;
out_info = tmp;
pos = (hb_glyph_position_t *) out_info;
}
@ -352,31 +342,6 @@ hb_buffer_t::swap_buffers ()
idx = 0;
}
void
hb_buffer_t::replace_glyphs (unsigned int num_in,
unsigned int num_out,
const uint32_t *glyph_data)
{
if (unlikely (!make_room_for (num_in, num_out))) return;
assert (idx + num_in <= len);
merge_clusters (idx, idx + num_in);
hb_glyph_info_t orig_info = info[idx];
hb_glyph_info_t *pinfo = &out_info[out_len];
for (unsigned int i = 0; i < num_out; i++)
{
*pinfo = orig_info;
pinfo->codepoint = glyph_data[i];
pinfo++;
}
idx += num_in;
out_len += num_out;
}
bool
hb_buffer_t::move_to (unsigned int i)
{
@ -617,8 +582,7 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en
void
hb_buffer_t::guess_segment_properties ()
{
assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
assert_unicode ();
/* If script is set to INVALID, guess from buffer contents */
if (props.script == HB_SCRIPT_INVALID) {
@ -706,9 +670,9 @@ hb_buffer_create ()
/**
* hb_buffer_get_empty:
*
* Fetches an empty #hb_buffer_t.
*
*
* Return value: (transfer full):
* Return value: (transfer full): The empty buffer
*
* Since: 0.9.2
**/
@ -720,7 +684,7 @@ hb_buffer_get_empty ()
/**
* hb_buffer_reference: (skip)
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Increases the reference count on @buffer by one. This prevents @buffer from
* being destroyed until a matching call to hb_buffer_destroy() is made.
@ -738,7 +702,7 @@ hb_buffer_reference (hb_buffer_t *buffer)
/**
* hb_buffer_destroy: (skip)
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Deallocate the @buffer.
* Decreases the reference count on @buffer by one. If the result is zero, then
@ -765,15 +729,15 @@ hb_buffer_destroy (hb_buffer_t *buffer)
/**
* hb_buffer_set_user_data: (skip)
* @buffer: an #hb_buffer_t.
* @key:
* @data:
* @destroy:
* @replace:
* @buffer: An #hb_buffer_t
* @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 buffer.
*
*
* Return value:
* Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@ -789,12 +753,13 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_get_user_data: (skip)
* @buffer: an #hb_buffer_t.
* @key:
* @buffer: An #hb_buffer_t
* @key: The user-data key to query
*
* Fetches the user data associated with the specified key,
* attached to the specified buffer.
*
*
* Return value:
* Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@ -808,11 +773,11 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_set_content_type:
* @buffer: an #hb_buffer_t.
* @content_type: the type of buffer contents to set
* @buffer: An #hb_buffer_t
* @content_type: The type of buffer contents to set
*
* Sets the type of @buffer contents, buffers are either empty, contain
* characters (before shaping) or glyphs (the result of shaping).
* Sets the type of @buffer contents. Buffers are either empty, contain
* characters (before shaping), or contain glyphs (the result of shaping).
*
* Since: 0.9.5
**/
@ -825,12 +790,13 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
/**
* hb_buffer_get_content_type:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* see hb_buffer_set_content_type().
* Fetches the type of @buffer contents. Buffers are either empty, contain
* characters (before shaping), or contain glyphs (the result of shaping).
*
* Return value:
* The type of @buffer contents.
* The type of @buffer contents
*
* Since: 0.9.5
**/
@ -843,10 +809,11 @@ hb_buffer_get_content_type (hb_buffer_t *buffer)
/**
* hb_buffer_set_unicode_funcs:
* @buffer: an #hb_buffer_t.
* @unicode_funcs:
*
* @buffer: An #hb_buffer_t
* @unicode_funcs: The Unicode-functions structure
*
* Sets the Unicode-functions structure of a buffer to
* @unicode_funcs.
*
* Since: 0.9.2
**/
@ -867,11 +834,11 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
/**
* hb_buffer_get_unicode_funcs:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Fetches the Unicode-functions structure of a buffer.
*
*
* Return value:
* Return value: The Unicode-functions structure
*
* Since: 0.9.2
**/
@ -883,7 +850,7 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
/**
* hb_buffer_set_direction:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
* @direction: the #hb_direction_t of the @buffer
*
* Set the text flow direction of the buffer. No shaping can happen without
@ -909,7 +876,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
/**
* hb_buffer_get_direction:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* See hb_buffer_set_direction()
*
@ -926,8 +893,8 @@ hb_buffer_get_direction (hb_buffer_t *buffer)
/**
* hb_buffer_set_script:
* @buffer: an #hb_buffer_t.
* @script: an #hb_script_t to set.
* @buffer: An #hb_buffer_t
* @script: An #hb_script_t to set.
*
* Sets the script of @buffer to @script.
*
@ -953,12 +920,12 @@ hb_buffer_set_script (hb_buffer_t *buffer,
/**
* hb_buffer_get_script:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* See hb_buffer_set_script().
* Fetches the script of @buffer.
*
* Return value:
* The #hb_script_t of the @buffer.
* The #hb_script_t of the @buffer
*
* Since: 0.9.2
**/
@ -970,8 +937,8 @@ hb_buffer_get_script (hb_buffer_t *buffer)
/**
* hb_buffer_set_language:
* @buffer: an #hb_buffer_t.
* @language: an hb_language_t to set.
* @buffer: An #hb_buffer_t
* @language: An hb_language_t to set
*
* Sets the language of @buffer to @language.
*
@ -997,7 +964,7 @@ hb_buffer_set_language (hb_buffer_t *buffer,
/**
* hb_buffer_get_language:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* See hb_buffer_set_language().
*
@ -1014,8 +981,8 @@ hb_buffer_get_language (hb_buffer_t *buffer)
/**
* hb_buffer_set_segment_properties:
* @buffer: an #hb_buffer_t.
* @props: an #hb_segment_properties_t to use.
* @buffer: An #hb_buffer_t
* @props: An #hb_segment_properties_t to use
*
* Sets the segment properties of the buffer, a shortcut for calling
* hb_buffer_set_direction(), hb_buffer_set_script() and
@ -1035,8 +1002,8 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_get_segment_properties:
* @buffer: an #hb_buffer_t.
* @props: (out): the output #hb_segment_properties_t.
* @buffer: An #hb_buffer_t
* @props: (out): The output #hb_segment_properties_t
*
* Sets @props to the #hb_segment_properties_t of @buffer.
*
@ -1052,8 +1019,8 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_set_flags:
* @buffer: an #hb_buffer_t.
* @flags: the buffer flags to set.
* @buffer: An #hb_buffer_t
* @flags: The buffer flags to set
*
* Sets @buffer flags to @flags. See #hb_buffer_flags_t.
*
@ -1071,12 +1038,12 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
/**
* hb_buffer_get_flags:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* See hb_buffer_set_flags().
* Fetches the #hb_buffer_flags_t of @buffer.
*
* Return value:
* The @buffer flags.
* The @buffer flags
*
* Since: 0.9.7
**/
@ -1088,10 +1055,12 @@ hb_buffer_get_flags (hb_buffer_t *buffer)
/**
* hb_buffer_set_cluster_level:
* @buffer: an #hb_buffer_t.
* @cluster_level:
*
* @buffer: An #hb_buffer_t
* @cluster_level: The cluster level to set on the buffer
*
* Sets the cluster level of a buffer. The #hb_buffer_cluster_level_t
* dictates one aspect of how HarfBuzz will treat non-base characters
* during shaping.
*
* Since: 0.9.42
**/
@ -1107,11 +1076,13 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer,
/**
* hb_buffer_get_cluster_level:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Fetches the cluster level of a buffer. The #hb_buffer_cluster_level_t
* dictates one aspect of how HarfBuzz will treat non-base characters
* during shaping.
*
*
* Return value:
* Return value: The cluster level of @buffer
*
* Since: 0.9.42
**/
@ -1124,13 +1095,13 @@ hb_buffer_get_cluster_level (hb_buffer_t *buffer)
/**
* hb_buffer_set_replacement_codepoint:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
* @replacement: the replacement #hb_codepoint_t
*
* Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
* when adding text to @buffer.
*
* Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
* Default is #HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
*
* Since: 0.9.31
**/
@ -1146,12 +1117,13 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
/**
* hb_buffer_get_replacement_codepoint:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* See hb_buffer_set_replacement_codepoint().
* Fetches the #hb_codepoint_t that replaces invalid entries for a given encoding
* when adding text to @buffer.
*
* Return value:
* The @buffer replacement #hb_codepoint_t.
* The @buffer replacement #hb_codepoint_t
*
* Since: 0.9.31
**/
@ -1164,7 +1136,7 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
/**
* hb_buffer_set_invisible_glyph:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
* @invisible: the invisible #hb_codepoint_t
*
* Sets the #hb_codepoint_t that replaces invisible characters in
@ -1186,12 +1158,12 @@ hb_buffer_set_invisible_glyph (hb_buffer_t *buffer,
/**
* hb_buffer_get_invisible_glyph:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* See hb_buffer_set_invisible_glyph().
*
* Return value:
* The @buffer invisible #hb_codepoint_t.
* The @buffer invisible #hb_codepoint_t
*
* Since: 2.0.0
**/
@ -1204,7 +1176,7 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer)
/**
* hb_buffer_reset:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Resets the buffer to its initial status, as if it was just newly created
* with hb_buffer_create().
@ -1214,12 +1186,15 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer)
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.
* @buffer: An #hb_buffer_t
*
* Similar to hb_buffer_reset(), but does not clear the Unicode functions and
* the replacement code point.
@ -1229,18 +1204,21 @@ hb_buffer_reset (hb_buffer_t *buffer)
void
hb_buffer_clear_contents (hb_buffer_t *buffer)
{
if (unlikely (hb_object_is_immutable (buffer)))
return;
buffer->clear ();
}
/**
* hb_buffer_pre_allocate:
* @buffer: an #hb_buffer_t.
* @size: number of items to pre allocate.
* @buffer: An #hb_buffer_t
* @size: Number of items to pre allocate.
*
* Pre allocates memory for @buffer to fit at least @size number of items.
*
* Return value:
* %true if @buffer memory allocation succeeded, %false otherwise.
* %true if @buffer memory allocation succeeded, %false otherwise
*
* Since: 0.9.2
**/
@ -1252,7 +1230,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
/**
* hb_buffer_allocation_successful:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Check if allocating memory for the buffer succeeded.
*
@ -1269,9 +1247,9 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer)
/**
* hb_buffer_add:
* @buffer: an #hb_buffer_t.
* @codepoint: a Unicode code point.
* @cluster: the cluster value of @codepoint.
* @buffer: An #hb_buffer_t
* @codepoint: A Unicode code point.
* @cluster: The cluster value of @codepoint.
*
* Appends a character with the Unicode value of @codepoint to @buffer, and
* gives it the initial cluster value of @cluster. Clusters can be any thing
@ -1295,8 +1273,8 @@ hb_buffer_add (hb_buffer_t *buffer,
/**
* hb_buffer_set_length:
* @buffer: an #hb_buffer_t.
* @length: the new length of @buffer.
* @buffer: An #hb_buffer_t
* @length: The new length of @buffer
*
* Similar to hb_buffer_pre_allocate(), but clears any new items added at the
* end.
@ -1313,7 +1291,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
if (unlikely (hb_object_is_immutable (buffer)))
return length == 0;
if (!buffer->ensure (length))
if (unlikely (!buffer->ensure (length)))
return false;
/* Wipe the new space */
@ -1337,7 +1315,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
/**
* hb_buffer_get_length:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Returns the number of items in the buffer.
*
@ -1355,8 +1333,8 @@ hb_buffer_get_length (hb_buffer_t *buffer)
/**
* hb_buffer_get_glyph_infos:
* @buffer: an #hb_buffer_t.
* @length: (out): output array length.
* @buffer: An #hb_buffer_t
* @length: (out): The output-array length.
*
* Returns @buffer glyph information array. Returned pointer
* is valid as long as @buffer contents are not modified.
@ -1379,8 +1357,8 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
/**
* hb_buffer_get_glyph_positions:
* @buffer: an #hb_buffer_t.
* @length: (out): output length.
* @buffer: An #hb_buffer_t
* @length: (out): The output length
*
* Returns @buffer glyph position array. Returned pointer
* is valid as long as @buffer contents are not modified.
@ -1404,14 +1382,33 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
return (hb_glyph_position_t *) buffer->pos;
}
/**
* hb_buffer_has_positions:
* @buffer: an #hb_buffer_t.
*
* Returns whether @buffer has glyph position data.
* A buffer gains position data when hb_buffer_get_glyph_positions() is called on it,
* and cleared of position data when hb_buffer_clear_contents() is called.
*
* Return value:
* %true if the @buffer has position array, %false otherwise.
*
* Since: 2.7.3
**/
HB_EXTERN hb_bool_t
hb_buffer_has_positions (hb_buffer_t *buffer)
{
return buffer->have_positions;
}
/**
* hb_glyph_info_get_glyph_flags:
* @info: a #hb_glyph_info_t.
* @info: a #hb_glyph_info_t
*
* Returns glyph flags encoded within a #hb_glyph_info_t.
*
* Return value:
* The #hb_glyph_flags_t encoded within @info.
* The #hb_glyph_flags_t encoded within @info
*
* Since: 1.5.0
**/
@ -1423,7 +1420,7 @@ hb_glyph_flags_t
/**
* hb_buffer_reverse:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Reverses buffer contents.
*
@ -1437,11 +1434,11 @@ hb_buffer_reverse (hb_buffer_t *buffer)
/**
* hb_buffer_reverse_range:
* @buffer: an #hb_buffer_t.
* @start: start index.
* @end: end index.
* @buffer: An #hb_buffer_t
* @start: start index
* @end: end index
*
* Reverses buffer contents between start to end.
* Reverses buffer contents between @start and @end.
*
* Since: 0.9.41
**/
@ -1454,7 +1451,7 @@ hb_buffer_reverse_range (hb_buffer_t *buffer,
/**
* hb_buffer_reverse_clusters:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Reverses buffer clusters. That is, the buffer contents are
* reversed, then each cluster (consecutive items having the
@ -1470,24 +1467,24 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
/**
* hb_buffer_guess_segment_properties:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Sets unset buffer segment properties based on buffer Unicode
* contents. If buffer is not empty, it must have content type
* %HB_BUFFER_CONTENT_TYPE_UNICODE.
* #HB_BUFFER_CONTENT_TYPE_UNICODE.
*
* If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
* If buffer script is not set (ie. is #HB_SCRIPT_INVALID), it
* will be set to the Unicode script of the first character in
* the buffer that has a script other than %HB_SCRIPT_COMMON,
* %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
* the buffer that has a script other than #HB_SCRIPT_COMMON,
* #HB_SCRIPT_INHERITED, and #HB_SCRIPT_UNKNOWN.
*
* Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
* Next, if buffer direction is not set (ie. is #HB_DIRECTION_INVALID),
* it will be set to the natural horizontal direction of the
* buffer script as returned by hb_script_get_horizontal_direction().
* If hb_script_get_horizontal_direction() returns %HB_DIRECTION_INVALID,
* then %HB_DIRECTION_LTR is used.
* If hb_script_get_horizontal_direction() returns #HB_DIRECTION_INVALID,
* then #HB_DIRECTION_LTR is used.
*
* Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
* Finally, if buffer language is not set (ie. is #HB_LANGUAGE_INVALID),
* it will be set to the process's default language as returned by
* hb_language_get_default(). This may change in the future by
* taking buffer script into consideration when choosing a language.
@ -1513,8 +1510,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
typedef typename utf_t::codepoint_t T;
const hb_codepoint_t replacement = buffer->replacement;
assert ((buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
(!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
buffer->assert_unicode ();
if (unlikely (hb_object_is_immutable (buffer)))
return;
@ -1525,7 +1521,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
if (item_length == -1)
item_length = text_length - item_offset;
buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
if (unlikely (item_length < 0 ||
item_length > INT_MAX / 8 ||
!buffer->ensure (buffer->len + item_length * sizeof (T) / 4)))
return;
/* If buffer is empty and pre-context provided, install it.
* This check is written this way, to make sure people can
@ -1573,12 +1572,12 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf8:
* @buffer: an #hb_buffer_t.
* @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
* @buffer: An #hb_buffer_t
* @text: (array length=text_length) (element-type uint8_t): An array of UTF-8
* characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
* @text_length: The length of the @text, or -1 if it is %NULL terminated.
* @item_offset: The offset of the first character to add to the @buffer.
* @item_length: The number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
*
* See hb_buffer_add_codepoints().
@ -1600,12 +1599,12 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf16:
* @buffer: an #hb_buffer_t.
* @text: (array length=text_length): an array of UTF-16 characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
* @buffer: An #hb_buffer_t
* @text: (array length=text_length): An array of UTF-16 characters to append
* @text_length: The length of the @text, or -1 if it is %NULL terminated
* @item_offset: The offset of the first character to add to the @buffer
* @item_length: The number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated)
*
* See hb_buffer_add_codepoints().
*
@ -1626,12 +1625,12 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf32:
* @buffer: an #hb_buffer_t.
* @text: (array length=text_length): an array of UTF-32 characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
* @buffer: An #hb_buffer_t
* @text: (array length=text_length): An array of UTF-32 characters to append
* @text_length: The length of the @text, or -1 if it is %NULL terminated
* @item_offset: The offset of the first character to add to the @buffer
* @item_length: The number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated)
*
* See hb_buffer_add_codepoints().
*
@ -1652,13 +1651,13 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
/**
* hb_buffer_add_latin1:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
* @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
* characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* characters to append
* @text_length: the length of the @text, or -1 if it is %NULL terminated
* @item_offset: the offset of the first character to add to the @buffer
* @item_length: the number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
* end of @text (assuming it is %NULL terminated)
*
* Similar to hb_buffer_add_codepoints(), but allows only access to first 256
* Unicode code points that can fit in 8-bit strings.
@ -1714,8 +1713,8 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
/**
* hb_buffer_append:
* @buffer: an #hb_buffer_t.
* @source: source #hb_buffer_t.
* @buffer: An #hb_buffer_t
* @source: source #hb_buffer_t
* @start: start index into source buffer to copy. Use 0 to copy from start of buffer.
* @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer.
*
@ -1742,11 +1741,6 @@ hb_buffer_append (hb_buffer_t *buffer,
if (start == end)
return;
if (!buffer->len)
buffer->content_type = source->content_type;
if (!buffer->have_positions && source->have_positions)
buffer->clear_positions ();
if (buffer->len + (end - start) < buffer->len) /* Overflows. */
{
buffer->successful = false;
@ -1758,6 +1752,11 @@ hb_buffer_append (hb_buffer_t *buffer,
if (unlikely (!buffer->successful))
return;
if (!orig_len)
buffer->content_type = source->content_type;
if (!buffer->have_positions && source->have_positions)
buffer->clear_positions ();
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]));
@ -1821,7 +1820,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
/**
* hb_buffer_normalize_glyphs:
* @buffer: an #hb_buffer_t.
* @buffer: An #hb_buffer_t
*
* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
* The resulting clusters should behave identical to pre-reordering clusters.
@ -1834,8 +1833,8 @@ void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
{
assert (buffer->have_positions);
assert ((buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
(!buffer->len && (buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
buffer->assert_glyphs ();
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
@ -1876,8 +1875,8 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g
* @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1.
* @position_fuzz: allowed absolute difference in position values.
*
* If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
* and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most
* If dottedcircle_glyph is (hb_codepoint_t) -1 then #HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
* and #HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most
* callers if just comparing two buffers is needed.
*
* Since: 1.5.0
@ -1967,12 +1966,12 @@ hb_buffer_diff (hb_buffer_t *buffer,
#ifndef HB_NO_BUFFER_MESSAGE
/**
* hb_buffer_set_message_func:
* @buffer: an #hb_buffer_t.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @buffer: An #hb_buffer_t
* @func: (closure user_data) (destroy destroy) (scope notified): Callback function
* @user_data: (nullable): Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_buffer_message_func_t.
*
* Since: 1.1.3
**/

View File

@ -27,7 +27,7 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif
@ -59,8 +59,7 @@ HB_BEGIN_DECLS
* The #hb_glyph_info_t is the structure that holds information about the
* glyphs and their relation to input text.
*/
typedef struct hb_glyph_info_t
{
typedef struct hb_glyph_info_t {
hb_codepoint_t codepoint;
/*< private >*/
hb_mask_t mask;
@ -91,6 +90,8 @@ typedef struct hb_glyph_info_t
* breaking point only.
* @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
*
* Flags for #hb_glyph_info_t.
*
* Since: 1.5.0
*/
typedef enum { /*< flags >*/
@ -151,6 +152,11 @@ typedef struct hb_segment_properties_t {
void *reserved2;
} hb_segment_properties_t;
/**
* HB_SEGMENT_PROPERTIES_DEFAULT:
*
* The default #hb_segment_properties_t of of freshly created #hb_buffer_t.
*/
#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
HB_SCRIPT_INVALID, \
HB_LANGUAGE_INVALID, \
@ -204,6 +210,8 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
* @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer.
* @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping).
* @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping).
*
* The type of #hb_buffer_t contents.
*/
typedef enum {
HB_BUFFER_CONTENT_TYPE_INVALID = 0,
@ -289,6 +297,8 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
* not be inserted in the rendering of incorrect
* character sequences (such at <0905 093E>). Since: 2.4
*
* Flags for #hb_buffer_t.
*
* Since: 0.9.20
*/
typedef enum { /*< flags >*/
@ -316,6 +326,23 @@ hb_buffer_get_flags (hb_buffer_t *buffer);
* @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level,
* equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES.
*
* Data type for holding HarfBuzz's clustering behavior options. The cluster level
* dictates one aspect of how HarfBuzz will treat non-base characters
* during shaping.
*
* In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES, non-base
* characters are merged into the cluster of the base character that precedes them.
*
* In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, non-base characters are initially
* assigned their own cluster values, which are not merged into preceding base
* clusters. This allows HarfBuzz to perform additional operations like reorder
* sequences of adjacent marks.
*
* @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES is the default, because it maintains
* backward compatibility with older versions of HarfBuzz. New client programs that
* do not need to maintain such backward compatibility are recommended to use
* @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS instead of the default.
*
* Since: 0.9.42
*/
typedef enum {
@ -447,6 +474,9 @@ HB_EXTERN hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length);
HB_EXTERN hb_bool_t
hb_buffer_has_positions (hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
@ -518,6 +548,27 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
HB_EXTERN unsigned int
hb_buffer_serialize_unicode (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
HB_EXTERN unsigned int
hb_buffer_serialize (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed,
hb_font_t *font,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
HB_EXTERN hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf,
@ -526,11 +577,48 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
hb_font_t *font,
hb_buffer_serialize_format_t format);
HB_EXTERN hb_bool_t
hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
const char *buf,
int buf_len,
const char **end_ptr,
hb_buffer_serialize_format_t format);
/*
* Compare buffers
*/
/**
* hb_buffer_diff_flags_t:
* @HB_BUFFER_DIFF_FLAG_EQUAL: equal buffers.
* @HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH: buffers with different
* #hb_buffer_content_type_t.
* @HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH: buffers with differing length.
* @HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT: `.notdef` glyph is present in the
* reference buffer.
* @HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT: dotted circle glyph is present
* in the reference buffer.
* @HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH: difference in #hb_glyph_info_t.codepoint
* @HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH: difference in #hb_glyph_info_t.cluster
* @HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH: difference in #hb_glyph_flags_t.
* @HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH: difference in #hb_glyph_position_t.
*
* Flags from comparing two #hb_buffer_t's.
*
* Buffer with different #hb_buffer_content_type_t cannot be meaningfully
* compared in any further detail.
*
* For buffers with differing length, the per-glyph comparison is not
* attempted, though we do still scan reference buffer for dotted circle and
* `.notdef` glyphs.
*
* If the buffers have the same length, we compare them glyph-by-glyph and
* report which aspect(s) of the glyph info/position are different.
*
* Since: 1.5.0
*/
typedef enum { /*< flags >*/
HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000,
@ -570,6 +658,23 @@ hb_buffer_diff (hb_buffer_t *buffer,
* Debugging.
*/
/**
* hb_buffer_message_func_t:
* @buffer: An #hb_buffer_t to work upon
* @font: The #hb_font_t the @buffer is shaped with
* @message: %NULL-terminated message passed to the function
* @user_data: User data pointer passed by the caller
*
* A callback method for #hb_buffer_t. The method gets called with the
* #hb_buffer_t it was set on, the #hb_font_t the buffer is shaped with and a
* message describing what step of the shaping process will be performed.
* Returning %false from this method will skip this shaping step and move to
* the next one.
*
* Return value: %true to perform the shaping step, %false to skip it.
*
* Since: 1.1.3
*/
typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer,
hb_font_t *font,
const char *message,

View File

@ -35,20 +35,20 @@
#ifndef HB_BUFFER_MAX_LEN_FACTOR
#define HB_BUFFER_MAX_LEN_FACTOR 32
#define HB_BUFFER_MAX_LEN_FACTOR 64
#endif
#ifndef HB_BUFFER_MAX_LEN_MIN
#define HB_BUFFER_MAX_LEN_MIN 8192
#define HB_BUFFER_MAX_LEN_MIN 16384
#endif
#ifndef HB_BUFFER_MAX_LEN_DEFAULT
#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
#endif
#ifndef HB_BUFFER_MAX_OPS_FACTOR
#define HB_BUFFER_MAX_OPS_FACTOR 64
#define HB_BUFFER_MAX_OPS_FACTOR 1024
#endif
#ifndef HB_BUFFER_MAX_OPS_MIN
#define HB_BUFFER_MAX_OPS_MIN 1024
#define HB_BUFFER_MAX_OPS_MIN 16384
#endif
#ifndef HB_BUFFER_MAX_OPS_DEFAULT
#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
@ -139,7 +139,7 @@ struct hb_buffer_t
/* Methods */
bool in_error () const { return !successful; }
HB_NODISCARD bool in_error () const { return !successful; }
void allocate_var (unsigned int start, unsigned int count)
{
@ -186,7 +186,7 @@ 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]; }
bool has_separate_output () const { return info != out_info; }
HB_NODISCARD bool has_separate_output () const { return info != out_info; }
HB_INTERNAL void reset ();
@ -210,86 +210,89 @@ struct hb_buffer_t
HB_INTERNAL void clear_output ();
HB_INTERNAL void clear_positions ();
HB_INTERNAL void replace_glyphs (unsigned int num_in,
unsigned int num_out,
const hb_codepoint_t *glyph_data);
void replace_glyph (hb_codepoint_t glyph_index)
template <typename T>
HB_NODISCARD bool replace_glyphs (unsigned int num_in,
unsigned int num_out,
const T *glyph_data)
{
if (unlikely (out_info != info || out_len != idx)) {
if (unlikely (!make_room_for (1, 1))) return;
out_info[out_len] = info[idx];
if (unlikely (!make_room_for (num_in, num_out))) return false;
assert (idx + num_in <= len);
merge_clusters (idx, idx + num_in);
hb_glyph_info_t &orig_info = idx < len ? cur() : prev();
hb_glyph_info_t *pinfo = &out_info[out_len];
for (unsigned int i = 0; i < num_out; i++)
{
*pinfo = orig_info;
pinfo->codepoint = glyph_data[i];
pinfo++;
}
out_info[out_len].codepoint = glyph_index;
idx++;
out_len++;
idx += num_in;
out_len += num_out;
return true;
}
HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph_index)
{ return replace_glyphs (1, 1, &glyph_index); }
/* Makes a copy of the glyph at idx to output and replace glyph_index */
hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index)
HB_NODISCARD bool output_glyph (hb_codepoint_t glyph_index)
{ return replace_glyphs (0, 1, &glyph_index); }
HB_NODISCARD bool output_info (const hb_glyph_info_t &glyph_info)
{
if (unlikely (!make_room_for (0, 1))) return Crap (hb_glyph_info_t);
if (unlikely (idx == len && !out_len))
return Crap (hb_glyph_info_t);
out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1];
out_info[out_len].codepoint = glyph_index;
out_len++;
return out_info[out_len - 1];
}
void output_info (const hb_glyph_info_t &glyph_info)
{
if (unlikely (!make_room_for (0, 1))) return;
if (unlikely (!make_room_for (0, 1))) return false;
out_info[out_len] = glyph_info;
out_len++;
return true;
}
/* Copies glyph at idx to output but doesn't advance idx */
void copy_glyph ()
HB_NODISCARD bool copy_glyph ()
{
if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = info[idx];
out_len++;
/* Extra copy because cur()'s return can be freed within
* output_info() call if buffer reallocates. */
return output_info (hb_glyph_info_t (cur()));
}
/* Copies glyph at idx to output and advance idx.
* If there's no output, just advance idx. */
void
next_glyph ()
HB_NODISCARD bool next_glyph ()
{
if (have_output)
{
if (out_info != info || out_len != idx)
{
if (unlikely (!make_room_for (1, 1))) return;
if (unlikely (!make_room_for (1, 1))) return false;
out_info[out_len] = info[idx];
}
out_len++;
}
idx++;
return true;
}
/* Copies n glyphs at idx to output and advance idx.
* If there's no output, just advance idx. */
void
next_glyphs (unsigned int n)
HB_NODISCARD bool next_glyphs (unsigned int n)
{
if (have_output)
{
if (out_info != info || out_len != idx)
{
if (unlikely (!make_room_for (n, n))) return;
if (unlikely (!make_room_for (n, n))) return false;
memmove (out_info + out_len, info + idx, n * sizeof (out_info[0]));
}
out_len += n;
}
idx += n;
return true;
}
/* Advance idx without copying to output. */
void skip_glyph () { idx++; }
@ -329,18 +332,51 @@ struct hb_buffer_t
/* Internal methods */
HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
HB_INTERNAL bool enlarge (unsigned int size);
HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size);
bool ensure (unsigned int size)
HB_NODISCARD bool ensure (unsigned int size)
{ return likely (!size || size < allocated) ? true : enlarge (size); }
bool ensure_inplace (unsigned int size)
HB_NODISCARD bool ensure_inplace (unsigned int size)
{ return likely (!size || size < allocated); }
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
HB_INTERNAL bool shift_forward (unsigned int count);
void assert_glyphs ()
{
assert ((content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS) ||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
}
void assert_unicode ()
{
assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
}
HB_NODISCARD bool ensure_glyphs ()
{
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
{
if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
return false;
assert (len == 0);
content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
}
return true;
}
HB_NODISCARD bool ensure_unicode ()
{
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
{
if (content_type != HB_BUFFER_CONTENT_TYPE_INVALID)
return false;
assert (len == 0);
content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
}
return true;
}
HB_NODISCARD HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
HB_NODISCARD HB_INTERNAL bool shift_forward (unsigned int count);
typedef long scratch_buffer_t;
HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);

View File

@ -86,12 +86,15 @@ _hb_options_init ()
/**
* hb_tag_from_string:
* @str: (array length=len) (element-type uint8_t):
* @len:
* @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 into an #hb_tag_t. Valid tags
* are four characters. Shorter input strings will be
* padded with spaces. Longer input strings will be
* truncated.
*
*
* Return value:
* Return value: The #hb_tag_t corresponding to @str
*
* Since: 0.9.2
**/
@ -116,10 +119,11 @@ hb_tag_from_string (const char *str, int len)
/**
* hb_tag_to_string:
* @tag:
* @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t):
*
* @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.
* Strings will be four characters long.
*
* Since: 0.9.5
**/
@ -144,12 +148,17 @@ const char direction_strings[][4] = {
/**
* hb_direction_from_string:
* @str: (array length=len) (element-type uint8_t):
* @len:
* @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.
*
* Matching is loose and applies only to the first letter. For
* examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR.
*
* Return value:
* Unmatched strings will return #HB_DIRECTION_INVALID.
*
* Return value: The #hb_direction_t matching @str
*
* Since: 0.9.2
**/
@ -172,11 +181,11 @@ hb_direction_from_string (const char *str, int len)
/**
* hb_direction_to_string:
* @direction:
* @direction: The #hb_direction_t to convert
*
* Converts an #hb_direction_t to a string.
*
*
* Return value: (transfer none):
* Return value: (transfer none): The string corresponding to @direction
*
* Since: 0.9.2
**/
@ -367,9 +376,9 @@ hb_language_from_string (const char *str, int len)
/**
* hb_language_to_string:
* @language: an #hb_language_t to convert.
* @language: The #hb_language_t to convert
*
* See hb_language_from_string().
* Converts an #hb_language_t to a string.
*
* Return value: (transfer none):
* A %NULL-terminated string representing the @language. Must not be freed by
@ -388,16 +397,17 @@ hb_language_to_string (hb_language_t language)
/**
* hb_language_get_default:
*
* Get default language from current locale.
* Fetch the default language from current locale.
*
* Note that the first time this function is called, it calls
* <note>Note that the first time this function is called, it calls
* "setlocale (LC_CTYPE, nullptr)" to fetch current locale. The underlying
* setlocale function is, in many implementations, NOT threadsafe. To avoid
* problems, call this function once before multiple threads can call it.
* This function is only used from hb_buffer_guess_segment_properties() by
* HarfBuzz itself.
* HarfBuzz itself.</note>
*
* Return value: (transfer none):
* Return value: (transfer none): The default language of the locale as
* an #hb_language_t
*
* Since: 0.9.2
**/
@ -448,7 +458,12 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
/* Script variants from https://unicode.org/iso15924/ */
case HB_TAG('A','r','a','n'): return HB_SCRIPT_ARABIC;
case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
case HB_TAG('G','e','o','k'): return HB_SCRIPT_GEORGIAN;
case HB_TAG('H','a','n','s'): return HB_SCRIPT_HAN;
case HB_TAG('H','a','n','t'): return HB_SCRIPT_HAN;
case HB_TAG('J','a','m','o'): return HB_SCRIPT_HANGUL;
case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
@ -489,7 +504,7 @@ hb_script_from_string (const char *str, int len)
* hb_script_to_iso15924_tag:
* @script: an #hb_script_t to convert.
*
* See hb_script_from_iso15924_tag().
* Converts an #hb_script_t to a corresponding ISO 15924 script tag.
*
* Return value:
* An #hb_tag_t representing an ISO 15924 script tag.
@ -504,11 +519,16 @@ hb_script_to_iso15924_tag (hb_script_t script)
/**
* hb_script_get_horizontal_direction:
* @script:
* @script: The #hb_script_t to query
*
* Fetches the #hb_direction_t of a script when it is
* set horizontally. All right-to-left scripts will return
* #HB_DIRECTION_RTL. All left-to-right scripts will return
* #HB_DIRECTION_LTR. Scripts that can be written either
* horizontally or vertically will return #HB_DIRECTION_INVALID.
* Unknown scripts will return #HB_DIRECTION_LTR.
*
*
* Return value:
* Return value: The horizontal #hb_direction_t of @script
*
* Since: 0.9.2
**/
@ -613,9 +633,9 @@ hb_script_get_horizontal_direction (hb_script_t script)
/**
* hb_version:
* @major: (out): Library major version component.
* @minor: (out): Library minor version component.
* @micro: (out): Library micro version component.
* @major: (out): Library major version component
* @minor: (out): Library minor version component
* @micro: (out): Library micro version component
*
* Returns library version as three integer components.
*
@ -636,7 +656,7 @@ hb_version (unsigned int *major,
*
* Returns library version as a string with three components.
*
* Return value: library version string.
* Return value: Library version string
*
* Since: 0.9.2
**/
@ -648,13 +668,15 @@ hb_version_string ()
/**
* hb_version_atleast:
* @major:
* @minor:
* @micro:
* @major: Library major version component
* @minor: Library minor version component
* @micro: Library micro version component
*
* Tests the library version against a minimum value,
* as three integer components.
*
*
* Return value:
* Return value: %true if the library is equal to or greater than
* the test value, %false otherwise
*
* Since: 0.9.30
**/
@ -883,7 +905,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
* </informaltable>
*
* Return value:
* %true if @str is successfully parsed, %false otherwise.
* %true if @str is successfully parsed, %false otherwise
*
* Since: 0.9.5
**/
@ -981,6 +1003,21 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation
/**
* hb_variation_from_string:
* @str: (array length=len) (element-type uint8_t): a string to parse
* @len: length of @str, or -1 if string is %NULL terminated
* @variation: (out): the #hb_variation_t to initialize with the parsed values
*
* Parses a string into a #hb_variation_t.
*
* The format for specifying variation settings follows. All valid CSS
* font-variation-settings values other than 'normal' and 'inherited' are also
* accepted, though, not documented below.
*
* The format is a tag, optionally followed by an equals sign, followed by a
* number. For example `wght=500`, or `slnt=-7.5`.
*
* Return value:
* %true if @str is successfully parsed, %false otherwise
*
* Since: 1.4.2
*/
@ -1007,6 +1044,13 @@ hb_variation_from_string (const char *str, int len,
/**
* hb_variation_to_string:
* @variation: an #hb_variation_t to convert
* @buf: (array length=size) (out): output string
* @size: the allocated size of @buf
*
* Converts an #hb_variation_t into a %NULL-terminated string in the format
* understood by hb_variation_from_string(). The client in responsible for
* allocating big enough size for @buf, 128 bytes is more than enough.
*
* Since: 1.4.2
*/
@ -1033,9 +1077,11 @@ hb_variation_to_string (hb_variation_t *variation,
/**
* hb_color_get_alpha:
* color: a #hb_color_t we are interested in its channels.
* @color: an #hb_color_t we are interested in its channels.
*
* Return value: Alpha channel value of the given color
* Fetches the alpha channel of the given @color.
*
* Return value: Alpha channel value
*
* Since: 2.1.0
*/
@ -1047,9 +1093,11 @@ uint8_t
/**
* hb_color_get_red:
* color: a #hb_color_t we are interested in its channels.
* @color: an #hb_color_t we are interested in its channels.
*
* Return value: Red channel value of the given color
* Fetches the red channel of the given @color.
*
* Return value: Red channel value
*
* Since: 2.1.0
*/
@ -1061,9 +1109,11 @@ uint8_t
/**
* hb_color_get_green:
* color: a #hb_color_t we are interested in its channels.
* @color: an #hb_color_t we are interested in its channels.
*
* Return value: Green channel value of the given color
* Fetches the green channel of the given @color.
*
* Return value: Green channel value
*
* Since: 2.1.0
*/
@ -1075,9 +1125,11 @@ uint8_t
/**
* hb_color_get_blue:
* color: a #hb_color_t we are interested in its channels.
* @color: an #hb_color_t we are interested in its channels.
*
* Return value: Blue channel value of the given color
* Fetches the blue channel of the given @color.
*
* Return value: Blue channel value
*
* Since: 2.1.0
*/

View File

@ -26,7 +26,7 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif
@ -88,11 +88,37 @@ typedef unsigned __int64 uint64_t;
HB_BEGIN_DECLS
/**
* hb_bool_t:
*
* Data type for booleans.
*
**/
typedef int hb_bool_t;
/**
* hb_codepoint_t:
*
* Data type for holding Unicode codepoints. Also
* used to hold glyph IDs.
*
**/
typedef uint32_t hb_codepoint_t;
/**
* hb_position_t:
*
* Data type for holding a single coordinate value.
* Contour points and other multi-dimensional data are
* stored as tuples of #hb_position_t's.
*
**/
typedef int32_t hb_position_t;
/**
* hb_mask_t:
*
* Data type for bitmasks.
*
**/
typedef uint32_t hb_mask_t;
typedef union _hb_var_int_t {
@ -107,13 +133,63 @@ typedef union _hb_var_int_t {
/* hb_tag_t */
/**
* hb_tag_t:
*
* Data type for tag identifiers. Tags are four
* byte integers, each byte representing a character.
*
* Tags are used to identify tables, design-variation axes,
* scripts, languages, font features, and baselines with
* human-readable names.
*
**/
typedef uint32_t hb_tag_t;
/**
* HB_TAG:
* @c1: 1st character of the tag
* @c2: 2nd character of the tag
* @c3: 3rd character of the tag
* @c4: 4th character of the tag
*
* Constructs an #hb_tag_t from four character literals.
*
**/
#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF)))
/**
* HB_UNTAG:
* @tag: an #hb_tag_t
*
* Extracts four character literals from an #hb_tag_t.
*
* Since: 0.6.0
*
**/
#define HB_UNTAG(tag) (uint8_t)(((tag)>>24)&0xFF), (uint8_t)(((tag)>>16)&0xFF), (uint8_t)(((tag)>>8)&0xFF), (uint8_t)((tag)&0xFF)
/**
* HB_TAG_NONE:
*
* Unset #hb_tag_t.
*/
#define HB_TAG_NONE HB_TAG(0,0,0,0)
/**
* HB_TAG_MAX:
*
* Maximum possible unsigned #hb_tag_t.
*
* Since: 0.9.26
*/
#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
/**
* HB_TAG_MAX_SIGNED:
*
* Maximum possible signed #hb_tag_t.
*
* Since: 0.9.33
*/
#define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff)
/* len=-1 means str is NUL-terminated. */
@ -132,6 +208,13 @@ hb_tag_to_string (hb_tag_t tag, char *buf);
* @HB_DIRECTION_RTL: Text is set horizontally from right to left.
* @HB_DIRECTION_TTB: Text is set vertically from top to bottom.
* @HB_DIRECTION_BTT: Text is set vertically from bottom to top.
*
* The direction of a text segment or buffer.
*
* A segment can also be tested for horizontal or vertical
* orientation (irrespective of specific direction) with
* HB_DIRECTION_IS_HORIZONTAL() or HB_DIRECTION_IS_VERTICAL().
*
*/
typedef enum {
HB_DIRECTION_INVALID = 0,
@ -148,17 +231,71 @@ hb_direction_from_string (const char *str, int len);
HB_EXTERN const char *
hb_direction_to_string (hb_direction_t direction);
/**
* HB_DIRECTION_IS_VALID:
* @dir: #hb_direction_t to test
*
* Tests whether a text direction is valid.
*
**/
#define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
/* Direction must be valid for the following */
/**
* HB_DIRECTION_IS_HORIZONTAL:
* @dir: #hb_direction_t to test
*
* Tests whether a text direction is horizontal. Requires
* that the direction be valid.
*
**/
#define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
/**
* HB_DIRECTION_IS_VERTICAL:
* @dir: #hb_direction_t to test
*
* Tests whether a text direction is vertical. Requires
* that the direction be valid.
*
**/
#define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6)
/**
* HB_DIRECTION_IS_FORWARD:
* @dir: #hb_direction_t to test
*
* Tests whether a text direction moves forward (from left to right, or from
* top to bottom). Requires that the direction be valid.
*
**/
#define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4)
/**
* HB_DIRECTION_IS_BACKWARD:
* @dir: #hb_direction_t to test
*
* Tests whether a text direction moves backward (from right to left, or from
* bottom to top). Requires that the direction be valid.
*
**/
#define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5)
/**
* HB_DIRECTION_REVERSE:
* @dir: #hb_direction_t to reverse
*
* Reverses a text direction. Requires that the direction
* be valid.
*
**/
#define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1))
/* hb_language_t */
/**
* hb_language_t:
*
* Data type for languages. Each #hb_language_t corresponds to a BCP 47
* language tag.
*
*/
typedef const struct hb_language_impl_t *hb_language_t;
HB_EXTERN hb_language_t
@ -167,216 +304,389 @@ hb_language_from_string (const char *str, int len);
HB_EXTERN const char *
hb_language_to_string (hb_language_t language);
/**
* HB_LANGUAGE_INVALID:
*
* An unset #hb_language_t.
*
* Since: 0.6.0
*/
#define HB_LANGUAGE_INVALID ((hb_language_t) 0)
HB_EXTERN hb_language_t
hb_language_get_default (void);
/* hb_script_t */
/**
* hb_script_t:
* @HB_SCRIPT_COMMON: `Zyyy`
* @HB_SCRIPT_INHERITED: `Zinh`
* @HB_SCRIPT_UNKNOWN: `Zzzz`
* @HB_SCRIPT_ARABIC: `Arab`
* @HB_SCRIPT_ARMENIAN: `Armn`
* @HB_SCRIPT_BENGALI: `Beng`
* @HB_SCRIPT_CYRILLIC: `Cyrl`
* @HB_SCRIPT_DEVANAGARI: `Deva`
* @HB_SCRIPT_GEORGIAN: `Geor`
* @HB_SCRIPT_GREEK: `Grek`
* @HB_SCRIPT_GUJARATI: `Gujr`
* @HB_SCRIPT_GURMUKHI: `Guru`
* @HB_SCRIPT_HANGUL: `Hang`
* @HB_SCRIPT_HAN: `Hani`
* @HB_SCRIPT_HEBREW: `Hebr`
* @HB_SCRIPT_HIRAGANA: `Hira`
* @HB_SCRIPT_KANNADA: `Knda`
* @HB_SCRIPT_KATAKANA: `Kana`
* @HB_SCRIPT_LAO: `Laoo`
* @HB_SCRIPT_LATIN: `Latn`
* @HB_SCRIPT_MALAYALAM: `Mlym`
* @HB_SCRIPT_ORIYA: `Orya`
* @HB_SCRIPT_TAMIL: `Taml`
* @HB_SCRIPT_TELUGU: `Telu`
* @HB_SCRIPT_THAI: `Thai`
* @HB_SCRIPT_TIBETAN: `Tibt`
* @HB_SCRIPT_BOPOMOFO: `Bopo`
* @HB_SCRIPT_BRAILLE: `Brai`
* @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans`
* @HB_SCRIPT_CHEROKEE: `Cher`
* @HB_SCRIPT_ETHIOPIC: `Ethi`
* @HB_SCRIPT_KHMER: `Khmr`
* @HB_SCRIPT_MONGOLIAN: `Mong`
* @HB_SCRIPT_MYANMAR: `Mymr`
* @HB_SCRIPT_OGHAM: `Ogam`
* @HB_SCRIPT_RUNIC: `Runr`
* @HB_SCRIPT_SINHALA: `Sinh`
* @HB_SCRIPT_SYRIAC: `Syrc`
* @HB_SCRIPT_THAANA: `Thaa`
* @HB_SCRIPT_YI: `Yiii`
* @HB_SCRIPT_DESERET: `Dsrt`
* @HB_SCRIPT_GOTHIC: `Goth`
* @HB_SCRIPT_OLD_ITALIC: `Ital`
* @HB_SCRIPT_BUHID: `Buhd`
* @HB_SCRIPT_HANUNOO: `Hano`
* @HB_SCRIPT_TAGALOG: `Tglg`
* @HB_SCRIPT_TAGBANWA: `Tagb`
* @HB_SCRIPT_CYPRIOT: `Cprt`
* @HB_SCRIPT_LIMBU: `Limb`
* @HB_SCRIPT_LINEAR_B: `Linb`
* @HB_SCRIPT_OSMANYA: `Osma`
* @HB_SCRIPT_SHAVIAN: `Shaw`
* @HB_SCRIPT_TAI_LE: `Tale`
* @HB_SCRIPT_UGARITIC: `Ugar`
* @HB_SCRIPT_BUGINESE: `Bugi`
* @HB_SCRIPT_COPTIC: `Copt`
* @HB_SCRIPT_GLAGOLITIC: `Glag`
* @HB_SCRIPT_KHAROSHTHI: `Khar`
* @HB_SCRIPT_NEW_TAI_LUE: `Talu`
* @HB_SCRIPT_OLD_PERSIAN: `Xpeo`
* @HB_SCRIPT_SYLOTI_NAGRI: `Sylo`
* @HB_SCRIPT_TIFINAGH: `Tfng`
* @HB_SCRIPT_BALINESE: `Bali`
* @HB_SCRIPT_CUNEIFORM: `Xsux`
* @HB_SCRIPT_NKO: `Nkoo`
* @HB_SCRIPT_PHAGS_PA: `Phag`
* @HB_SCRIPT_PHOENICIAN: `Phnx`
* @HB_SCRIPT_CARIAN: `Cari`
* @HB_SCRIPT_CHAM: `Cham`
* @HB_SCRIPT_KAYAH_LI: `Kali`
* @HB_SCRIPT_LEPCHA: `Lepc`
* @HB_SCRIPT_LYCIAN: `Lyci`
* @HB_SCRIPT_LYDIAN: `Lydi`
* @HB_SCRIPT_OL_CHIKI: `Olck`
* @HB_SCRIPT_REJANG: `Rjng`
* @HB_SCRIPT_SAURASHTRA: `Saur`
* @HB_SCRIPT_SUNDANESE: `Sund`
* @HB_SCRIPT_VAI: `Vaii`
* @HB_SCRIPT_AVESTAN: `Avst`
* @HB_SCRIPT_BAMUM: `Bamu`
* @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp`
* @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi`
* @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli`
* @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti`
* @HB_SCRIPT_JAVANESE: `Java`
* @HB_SCRIPT_KAITHI: `Kthi`
* @HB_SCRIPT_LISU: `Lisu`
* @HB_SCRIPT_MEETEI_MAYEK: `Mtei`
* @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb`
* @HB_SCRIPT_OLD_TURKIC: `Orkh`
* @HB_SCRIPT_SAMARITAN: `Samr`
* @HB_SCRIPT_TAI_THAM: `Lana`
* @HB_SCRIPT_TAI_VIET: `Tavt`
* @HB_SCRIPT_BATAK: `Batk`
* @HB_SCRIPT_BRAHMI: `Brah`
* @HB_SCRIPT_MANDAIC: `Mand`
* @HB_SCRIPT_CHAKMA: `Cakm`
* @HB_SCRIPT_MEROITIC_CURSIVE: `Merc`
* @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero`
* @HB_SCRIPT_MIAO: `Plrd`
* @HB_SCRIPT_SHARADA: `Shrd`
* @HB_SCRIPT_SORA_SOMPENG: `Sora`
* @HB_SCRIPT_TAKRI: `Takr`
* @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30
* @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30
* @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30
* @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30
* @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30
* @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30
* @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30
* @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30
* @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30
* @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30
* @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30
* @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30
* @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30
* @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30
* @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30
* @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30
* @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30
* @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30
* @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30
* @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30
* @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30
* @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30
* @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30
* @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30
* @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30
* @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30
* @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30
* @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30
* @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30
* @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0
* @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0
* @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0
* @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0
* @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0
* @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0
* @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0
* @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0
* @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0
* @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0
* @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0
* @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0
* @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0
* @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0
* @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0
* @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0
* @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0
* @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0
* @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0
* @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0
* @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0
* @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7
* @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7
* @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7
* @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7
* @HB_SCRIPT_INVALID: No script set
*
* Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding
* to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/).
*
* See also the Script (sc) property of the Unicode Character Database.
*
**/
/* https://unicode.org/iso15924/ */
/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */
/* Unicode Character Database property: Script (sc) */
typedef enum
{
/*1.1*/ HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'),
/*1.1*/ HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'),
/*5.0*/ HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'),
HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/
HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/
HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/
/*1.1*/ HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'),
/*1.1*/ HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'),
/*1.1*/ HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'),
/*1.1*/ HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'),
/*1.1*/ HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'),
/*1.1*/ HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'),
/*1.1*/ HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'),
/*1.1*/ HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'),
/*1.1*/ HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'),
/*1.1*/ HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'),
/*1.1*/ HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'),
/*1.1*/ HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'),
/*1.1*/ HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'),
/*1.1*/ HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'),
/*1.1*/ HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'),
/*1.1*/ HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'),
/*1.1*/ HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'),
/*1.1*/ HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'),
/*1.1*/ HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'),
/*1.1*/ HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'),
/*1.1*/ HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'),
/*1.1*/ HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'),
HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/
HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/
HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/
HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/
HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/
HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/
HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/
HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/
HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/
HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/
HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/
HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/
HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/
HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/
HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/
HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/
HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/
HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/
HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/
HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/
HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/
HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/
/*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'),
HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/
/*3.0*/ HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'),
/*3.0*/ HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'),
/*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'),
/*3.0*/ HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'),
/*3.0*/ HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'),
/*3.0*/ HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'),
/*3.0*/ HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'),
/*3.0*/ HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'),
/*3.0*/ HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'),
/*3.0*/ HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'),
/*3.0*/ HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'),
/*3.0*/ HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'),
/*3.0*/ HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'),
/*3.0*/ HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'),
HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/
HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/
HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/
HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/
HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/
HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/
HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/
HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/
HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/
HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/
HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/
HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/
HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/
HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/
/*3.1*/ HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'),
/*3.1*/ HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'),
/*3.1*/ HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'),
HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/
HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/
HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/
/*3.2*/ HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'),
/*3.2*/ HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'),
/*3.2*/ HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'),
/*3.2*/ HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'),
HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/
HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/
HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/
HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/
/*4.0*/ HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'),
/*4.0*/ HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'),
/*4.0*/ HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'),
/*4.0*/ HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'),
/*4.0*/ HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'),
/*4.0*/ HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'),
/*4.0*/ HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'),
HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/
HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/
HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/
HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/
HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/
HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/
HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/
/*4.1*/ HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'),
/*4.1*/ HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'),
/*4.1*/ HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'),
/*4.1*/ HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'),
/*4.1*/ HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'),
/*4.1*/ HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'),
/*4.1*/ HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'),
/*4.1*/ HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'),
HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/
HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/
HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/
HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/
HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/
HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/
HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/
HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/
/*5.0*/ HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'),
/*5.0*/ HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'),
/*5.0*/ HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'),
/*5.0*/ HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'),
/*5.0*/ HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'),
HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/
HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/
HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/
HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/
HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/
/*5.1*/ HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'),
/*5.1*/ HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'),
/*5.1*/ HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'),
/*5.1*/ HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'),
/*5.1*/ HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'),
/*5.1*/ HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'),
/*5.1*/ HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'),
/*5.1*/ HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'),
/*5.1*/ HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'),
/*5.1*/ HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'),
/*5.1*/ HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'),
HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/
HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/
HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/
HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/
HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/
HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/
HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/
HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/
HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/
HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/
HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/
/*5.2*/ HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'),
/*5.2*/ HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'),
/*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'),
/*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'),
/*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'),
/*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'),
/*5.2*/ HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'),
/*5.2*/ HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'),
/*5.2*/ HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'),
/*5.2*/ HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'),
/*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'),
/*5.2*/ HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'),
/*5.2*/ HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'),
/*5.2*/ HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'),
/*5.2*/ HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'),
HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/
HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/
HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/
HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/
HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/
HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/
HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/
HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/
HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/
HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/
HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/
HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/
HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/
HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/
HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/
/*6.0*/ HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'),
/*6.0*/ HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'),
/*6.0*/ HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'),
HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/
HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/
HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/
/*6.1*/ HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'),
/*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'),
/*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'),
/*6.1*/ HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'),
/*6.1*/ HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'),
/*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
/*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/
HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/
HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/
HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/
HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/
HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/
HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/
/*
* Since: 0.9.30
*/
/*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
/*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
/*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
/*7.0*/ HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'),
/*7.0*/ HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'),
/*7.0*/ HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'),
/*7.0*/ HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'),
/*7.0*/ HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'),
/*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
/*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
/*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
/*7.0*/ HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'),
/*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
/*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
/*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
/*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
/*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
/*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
/*7.0*/ HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'),
/*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
/*7.0*/ HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'),
/*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
/*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/
HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/
HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/
HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/
HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/
HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/
HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/
HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/
HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/
HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/
HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/
HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/
HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/
HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/
HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/
HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/
HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/
HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/
HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/
HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/
HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/
HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/
HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/
/*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'),
/*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'),
/*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'),
/*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'),
/*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'),
/*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'),
HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/
HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/
HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/
HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/
HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/
HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/
/*
* Since 1.3.0
*/
/*9.0*/ HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'),
/*9.0*/ HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'),
/*9.0*/ HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'),
/*9.0*/ HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'),
/*9.0*/ HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'),
/*9.0*/ HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'),
HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/
HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/
HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/
HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/
HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/
HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/
/*
* Since 1.6.0
*/
/*10.0*/HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'),
/*10.0*/HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'),
/*10.0*/HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'),
/*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'),
HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), /*10.0*/
HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), /*10.0*/
HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/
HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), /*10.0*/
/*
* Since 1.8.0
*/
/*11.0*/HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'),
/*11.0*/HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'),
/*11.0*/HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'),
/*11.0*/HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'),
/*11.0*/HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'),
/*11.0*/HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'),
/*11.0*/HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'),
HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/
HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/
HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/
HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/
HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/
HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/
HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/
/*
* Since 2.4.0
*/
/*12.0*/HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'),
/*12.0*/HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'),
/*12.0*/HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'),
/*12.0*/HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'),
HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/
HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/
HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/
HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/
/*
* Since 2.6.7
*/
/*13.0*/HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'),
/*13.0*/HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'),
/*13.0*/HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'),
/*13.0*/HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'),
HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/
HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/
HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/
HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/
/* No script set. */
HB_SCRIPT_INVALID = HB_TAG_NONE,
HB_SCRIPT_INVALID = HB_TAG_NONE,
/*< private >*/
/* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
* without risking undefined behavior. We have two, for historical reasons.
@ -410,24 +720,44 @@ hb_script_get_horizontal_direction (hb_script_t script);
/* User data */
/**
* hb_user_data_key_t:
*
* Data structure for holding user-data keys.
*
**/
typedef struct hb_user_data_key_t {
/*< private >*/
char unused;
} hb_user_data_key_t;
/**
* hb_destroy_func_t:
* @user_data: the data to be destroyed
*
* A virtual method for destroy user-data callbacks.
*
*/
typedef void (*hb_destroy_func_t) (void *user_data);
/* Font features and variations. */
/**
* HB_FEATURE_GLOBAL_START
* HB_FEATURE_GLOBAL_START:
*
* Special setting for #hb_feature_t.start to apply the feature from the start
* of the buffer.
*
* Since: 2.0.0
*/
#define HB_FEATURE_GLOBAL_START 0
/**
* HB_FEATURE_GLOBAL_END
* HB_FEATURE_GLOBAL_END:
*
* Special setting for #hb_feature_t.end to apply the feature from to the end
* of the buffer.
*
* Since: 2.0.0
*/
@ -435,17 +765,17 @@ typedef void (*hb_destroy_func_t) (void *user_data);
/**
* hb_feature_t:
* @tag: a feature tag
* @value: 0 disables the feature, non-zero (usually 1) enables the feature.
* For features implemented as lookup type 3 (like 'salt') the @value is a one
* based index into the alternates.
* @tag: The #hb_tag_t tag of the feature
* @value: The value of the feature. 0 disables the feature, non-zero (usually
* 1) enables the feature. For features implemented as lookup type 3 (like
* 'salt') the @value is a one based index into the alternates.
* @start: the cluster to start applying this feature setting (inclusive).
* @end: the cluster to end applying this feature setting (exclusive).
*
* The #hb_feature_t is the structure that holds information about requested
* feature application. The feature will be applied with the given value to all
* glyphs which are in clusters between @start (inclusive) and @end (exclusive).
* Setting start to @HB_FEATURE_GLOBAL_START and end to @HB_FEATURE_GLOBAL_END
* Setting start to #HB_FEATURE_GLOBAL_START and end to #HB_FEATURE_GLOBAL_END
* specifies that the feature always applies to the entire buffer.
*/
typedef struct hb_feature_t {
@ -465,6 +795,12 @@ hb_feature_to_string (hb_feature_t *feature,
/**
* hb_variation_t:
* @tag: The #hb_tag_t tag of the variation-axis name
* @value: The value of the variation axis
*
* Data type for holding variation data. Registered OpenType
* variation-axis tags are listed in
* [OpenType Axis Tag Registry](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg).
*
* Since: 1.4.2
*/
@ -484,12 +820,24 @@ hb_variation_to_string (hb_variation_t *variation,
/**
* hb_color_t:
*
* Data type for holding color values.
* Data type for holding color values. Colors are eight bits per
* channel RGB plus alpha transparency.
*
* Since: 2.1.0
*/
typedef uint32_t hb_color_t;
/**
* HB_COLOR:
* @b: blue channel value
* @g: green channel value
* @r: red channel value
* @a: alpha channel value
*
* Constructs an #hb_color_t from four integers.
*
* Since: 2.1.0
*/
#define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a)))
HB_EXTERN uint8_t

View File

@ -34,7 +34,6 @@
#include "hb-coretext.h"
#include "hb-aat-layout.hh"
#include <math.h>
/**
@ -190,7 +189,10 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
* reconfiguring the cascade list causes CoreText crashes. For details, see
* crbug.com/549610 */
// 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) {
#pragma GCC diagnostic pop
CFStringRef fontName = CTFontCopyPostScriptName (ct_font);
bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo;
CFRelease (fontName);
@ -346,7 +348,7 @@ retry:
const hb_coretext_font_data_t *data = font->data.coretext;
if (unlikely (!data)) return nullptr;
if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > .5)
if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > (CGFloat) .5)
{
/* XXX-MT-bug
* Note that evaluating condition above can be dangerous if another thread
@ -402,7 +404,7 @@ hb_coretext_font_create (CTFontRef ct_font)
}
/**
* hb_coretext_face_get_ct_font:
* hb_coretext_font_get_ct_font:
* @font: #hb_font_t to work upon
*
* Fetches the CTFontRef associated with the specified
@ -858,7 +860,7 @@ resize_and_retry:
buffer->len = 0;
uint32_t status_and = ~0, status_or = 0;
double advances_so_far = 0;
CGFloat advances_so_far = 0;
/* For right-to-left runs, CoreText returns the glyphs positioned such that
* any trailing whitespace is to the left of (0,0). Adjust coordinate system
* to fix for that. Test with any RTL string with trailing spaces.
@ -880,10 +882,10 @@ resize_and_retry:
status_or |= run_status;
status_and &= run_status;
DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
double run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
run_advance = -run_advance;
DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
DEBUG_MSG (CORETEXT, run, "Run advance: %g", (double) run_advance);
/* CoreText does automatic font fallback (AKA "cascading") for characters
* not supported by the requested font, and provides no way to turn it off,
@ -1062,7 +1064,7 @@ resize_and_retry:
hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult;
for (unsigned int j = 0; j < num_glyphs; j++)
{
double advance;
CGFloat advance;
if (likely (j + 1 < num_glyphs))
advance = positions[j + 1].x - positions[j].x;
else /* last glyph */
@ -1078,7 +1080,7 @@ resize_and_retry:
hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult;
for (unsigned int j = 0; j < num_glyphs; j++)
{
double advance;
CGFloat advance;
if (likely (j + 1 < num_glyphs))
advance = positions[j + 1].y - positions[j].y;
else /* last glyph */

View File

@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif
@ -53,11 +53,50 @@ HB_BEGIN_DECLS
#ifndef HB_DISABLE_DEPRECATED
/**
* HB_SCRIPT_CANADIAN_ABORIGINAL:
*
* Use #HB_SCRIPT_CANADIAN_SYLLABICS instead:
*
* Deprecated: 0.9.20
*/
#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS
/**
* HB_BUFFER_FLAGS_DEFAULT:
*
* Use #HB_BUFFER_FLAG_DEFAULT instead.
*
* Deprecated: 0.9.20
*/
#define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT
/**
* HB_BUFFER_SERIALIZE_FLAGS_DEFAULT:
*
* Use #HB_BUFFER_SERIALIZE_FLAG_DEFAULT instead.
*
* Deprecated: 0.9.20
*/
#define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT
/**
* hb_font_get_glyph_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @unicode: The Unicode code point to query
* @variation_selector: The variation-selector code point to query
* @glyph: (out): The glyph ID retrieved
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the glyph ID for a specified Unicode code point
* font, with an optional variation selector.
*
* Return value: %true if data found, %false otherwise
* Deprecated: 1.2.3
*
**/
typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
@ -73,6 +112,11 @@ hb_set_invert (hb_set_t *set);
/**
* hb_unicode_eastasian_width_func_t:
* @ufuncs: A Unicode-functions structure
* @unicode: The code point to query
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_unicode_funcs_t structure.
*
* Deprecated: 2.0.0
*/
@ -82,12 +126,12 @@ typedef unsigned int (*hb_unicode_eastasian_width_func_t)
/**
* hb_unicode_funcs_set_eastasian_width_func:
* @ufuncs: a Unicode function structure
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ufuncs: a Unicode-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_unicode_eastasian_width_func_t.
*
* Since: 0.9.2
* Deprecated: 2.0.0
@ -99,6 +143,10 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_eastasian_width:
* @ufuncs: a Unicode-function structure
* @unicode: The code point to query
*
* Don't use. Not used by HarfBuzz.
*
* Since: 0.9.2
* Deprecated: 2.0.0
@ -112,7 +160,7 @@ hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
* hb_unicode_decompose_compatibility_func_t:
* @ufuncs: a Unicode function structure
* @u: codepoint to decompose
* @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
* @decomposed: address of codepoint array (of length #HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
* @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
*
* Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
@ -120,7 +168,7 @@ hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
*
* If @u has no compatibility decomposition, zero should be returned.
*
* The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
* The Unicode standard guarantees that a buffer of length #HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
* compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
* of this function type must ensure that they do not write past the provided array.
*
@ -144,10 +192,12 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_fun
/**
* hb_unicode_funcs_set_decompose_compatibility_func:
* @ufuncs: a Unicode function structure
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
* @ufuncs: A Unicode-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_unicode_decompose_compatibility_func_t.
*
*
*
@ -165,16 +215,25 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *decomposed);
/**
* hb_font_get_glyph_v_kerning_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the kerning-adjustment value for a glyph-pair in
* the specified font, for vertical text segments.
*
**/
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
/**
* hb_font_funcs_set_glyph_v_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_v_kerning_func_t.
*
* Since: 0.9.2
* Deprecated: 2.0.0

View File

@ -38,7 +38,6 @@
template <typename Context, typename Return=hb_empty_t, unsigned int MaxDebugDepth=0>
struct hb_dispatch_context_t
{
hb_dispatch_context_t () : debug_depth (0) {}
private:
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
const Context* thiz () const { return static_cast<const Context *> (this); }
@ -54,7 +53,7 @@ struct hb_dispatch_context_t
{ return obj.dispatch (thiz (), hb_forward<Ts> (ds)...); }
static return_t no_dispatch_return_value () { return Context::default_return_value (); }
static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
unsigned debug_depth;
unsigned debug_depth = 0;
};

View File

@ -22,7 +22,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif

View File

@ -41,8 +41,10 @@
* @short_description: Font face objects
* @include: hb.h
*
* Font face is objects represent a single face in a font family.
* More exactly, a font face represents a single face in a binary font file.
* A font face is an object that represents a single face from within a
* font family.
*
* More precisely, a font face represents a single face in a binary font file.
* Font faces are typically built from a binary blob and a face index.
* Font faces are used to create fonts.
**/
@ -52,7 +54,7 @@
* hb_face_count:
* @blob: a blob.
*
* Get number of faces in a blob.
* Fetches the number of faces in a blob.
*
* Return value: Number of faces in @blob
*
@ -87,8 +89,8 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
nullptr, /* destroy */
0, /* index */
HB_ATOMIC_INT_INIT (1000), /* upem */
HB_ATOMIC_INT_INIT (0), /* num_glyphs */
1000, /* upem */
0, /* num_glyphs */
/* Zero for the rest is fine. */
};
@ -96,13 +98,19 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
/**
* hb_face_create_for_tables:
* @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
* @reference_table_func: (closure user_data) (destroy destroy) (scope notified): Table-referencing function
* @user_data: A pointer to the user data
* @destroy: (nullable): A callback to call when @data is not needed anymore
*
* Variant of hb_face_create(), built for those cases where it is more
* convenient to provide data for individual tables instead of the whole font
* data. With the caveat that hb_face_get_table_tags() does not currently work
* with faces created this way.
*
* Creates a new face object from the specified @user_data and @reference_table_func,
* with the @destroy callback.
*
* Return value: (transfer full)
* Return value: (transfer full): The new face object
*
* Since: 0.9.2
**/
@ -182,12 +190,15 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
/**
* hb_face_create: (Xconstructor)
* @blob:
* @index:
* @blob: #hb_blob_t to work upon
* @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.
*
*
* Return value: (transfer full):
* Return value: (transfer full): The new face object
*
* Since: 0.9.2
**/
@ -222,9 +233,9 @@ hb_face_create (hb_blob_t *blob,
/**
* hb_face_get_empty:
*
* Fetches the singleton empty face object.
*
*
* Return value: (transfer full)
* Return value: (transfer full): The empty face object
*
* Since: 0.9.2
**/
@ -237,11 +248,11 @@ hb_face_get_empty ()
/**
* hb_face_reference: (skip)
* @face: a face.
* @face: A face object
*
* Increases the reference count on a face object.
*
*
* Return value:
* Return value: The @face object
*
* Since: 0.9.2
**/
@ -253,9 +264,11 @@ hb_face_reference (hb_face_t *face)
/**
* hb_face_destroy: (skip)
* @face: a face.
*
* @face: A face object
*
* Decreases the reference count on a face object. When the
* reference count reaches zero, the face is destroyed,
* freeing all memory.
*
* Since: 0.9.2
**/
@ -283,15 +296,15 @@ hb_face_destroy (hb_face_t *face)
/**
* hb_face_set_user_data: (skip)
* @face: a face.
* @key:
* @data:
* @destroy:
* @replace:
* @face: A face object
* @key: The user-data key to set
* @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 given face object.
*
*
* Return value:
* Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@ -307,12 +320,13 @@ hb_face_set_user_data (hb_face_t *face,
/**
* hb_face_get_user_data: (skip)
* @face: a face.
* @key:
* @face: A face object
* @key: The user-data key to query
*
* Fetches the user data associated with the specified key,
* attached to the specified face object.
*
*
* Return value: (transfer none):
* Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@ -325,9 +339,9 @@ hb_face_get_user_data (const hb_face_t *face,
/**
* hb_face_make_immutable:
* @face: a face.
*
* @face: A face object
*
* Makes the given face object immutable.
*
* Since: 0.9.2
**/
@ -342,11 +356,11 @@ hb_face_make_immutable (hb_face_t *face)
/**
* hb_face_is_immutable:
* @face: a face.
* @face: A face object
*
* Tests whether the given face object is immutable.
*
*
* Return value:
* Return value: %true is @face is immutable, %false otherwise
*
* Since: 0.9.2
**/
@ -359,12 +373,13 @@ hb_face_is_immutable (const hb_face_t *face)
/**
* hb_face_reference_table:
* @face: a face.
* @tag:
* @face: A face object
* @tag: The #hb_tag_t of the table to query
*
* Fetches a reference to the specified table within
* the specified face.
*
*
* Return value: (transfer full):
* Return value: (transfer full): A pointer to the @tag table within @face
*
* Since: 0.9.2
**/
@ -380,11 +395,13 @@ hb_face_reference_table (const hb_face_t *face,
/**
* hb_face_reference_blob:
* @face: a face.
* @face: A face object
*
* Fetches a pointer to the binary blob that contains the
* specified face. Returns an empty blob if referencing face data is not
* possible.
*
*
* Return value: (transfer full):
* Return value: (transfer full): A pointer to the blob for @face
*
* Since: 0.9.2
**/
@ -396,10 +413,13 @@ hb_face_reference_blob (hb_face_t *face)
/**
* hb_face_set_index:
* @face: a face.
* @index:
* @face: A face object
* @index: The index to assign
*
* Assigns the specified face-index to @face. Fails if the
* face is immutable.
*
* <note>Note: face indices within a collection are zero-based.</note>
*
* Since: 0.9.2
**/
@ -415,11 +435,13 @@ hb_face_set_index (hb_face_t *face,
/**
* hb_face_get_index:
* @face: a face.
* @face: A face object
*
* Fetches the face-index corresponding to the given face.
*
* <note>Note: face indices within a collection are zero-based.</note>
*
* Return value:
* Return value: The index of @face.
*
* Since: 0.9.2
**/
@ -431,10 +453,10 @@ hb_face_get_index (const hb_face_t *face)
/**
* hb_face_set_upem:
* @face: a face.
* @upem:
*
* @face: A face object
* @upem: The units-per-em value to assign
*
* Sets the units-per-em (upem) for a face object to the specified value.
*
* Since: 0.9.2
**/
@ -450,11 +472,11 @@ hb_face_set_upem (hb_face_t *face,
/**
* hb_face_get_upem:
* @face: a face.
* @face: A face object
*
* Fetches the units-per-em (upem) value of the specified face object.
*
*
* Return value:
* Return value: The upem value of @face
*
* Since: 0.9.2
**/
@ -466,10 +488,10 @@ hb_face_get_upem (const hb_face_t *face)
/**
* hb_face_set_glyph_count:
* @face: a face.
* @glyph_count:
*
* @face: A face object
* @glyph_count: The glyph-count value to assign
*
* Sets the glyph count for a face object to the specified value.
*
* Since: 0.9.7
**/
@ -485,11 +507,11 @@ hb_face_set_glyph_count (hb_face_t *face,
/**
* hb_face_get_glyph_count:
* @face: a face.
* @face: A face object
*
* Fetches the glyph-count value of the specified face object.
*
*
* Return value:
* Return value: The glyph-count value of @face
*
* Since: 0.9.7
**/
@ -501,14 +523,16 @@ hb_face_get_glyph_count (const hb_face_t *face)
/**
* hb_face_get_table_tags:
* @face: a face.
* @start_offset: index of first tag to return.
* @table_count: input length of @table_tags array, output number of items written.
* @table_tags: array to write tags into.
* @face: A face object
* @start_offset: The index of first table tag to retrieve
* @table_count: (inout): Input = the maximum number of table tags to return;
* Output = the actual number of table tags returned (may be zero)
* @table_tags: (out) (array length=table_count): The array of table tags found
*
* Retrieves table tags for a face, if possible.
* Fetches a list of all table tags for a face, if possible. The list returned will
* begin at the offset provided
*
* Return value: total number of tables, or 0 if not possible to list.
* Return value: Total number of tables, or zero if it is not possible to list
*
* Since: 1.6.0
**/
@ -542,8 +566,11 @@ hb_face_get_table_tags (const hb_face_t *face,
#ifndef HB_NO_FACE_COLLECT_UNICODES
/**
* hb_face_collect_unicodes:
* @face: font face.
* @out: set to add Unicode characters covered by @face to.
* @face: A face object
* @out: The set to add Unicode characters to
*
* Collects all of the Unicode characters covered by @face and adds
* them to the #hb_set_t set @out.
*
* Since: 1.9.0
*/
@ -555,10 +582,11 @@ hb_face_collect_unicodes (hb_face_t *face,
}
/**
* hb_face_collect_variation_selectors:
* @face: font face.
* @out: set to add Variation Selector characters covered by @face to.
*
* @face: A face object
* @out: The set to add Variation Selector characters to
*
* Collects all Unicode "Variation Selector" characters covered by @face and adds
* them to the #hb_set_t set @out.
*
* Since: 1.9.0
*/
@ -570,10 +598,12 @@ hb_face_collect_variation_selectors (hb_face_t *face,
}
/**
* hb_face_collect_variation_unicodes:
* @face: font face.
* @out: set to add Unicode characters for @variation_selector covered by @face to.
*
* @face: A face object
* @variation_selector: The Variation Selector to query
* @out: The set to add Unicode characters to
*
* Collects all Unicode characters for @variation_selector covered by @face and adds
* them to the #hb_set_t set @out.
*
* Since: 1.9.0
*/
@ -708,6 +738,9 @@ hb_face_builder_create ()
/**
* hb_face_builder_add_table:
* @face: A face object created with hb_face_builder_create()
* @tag: The #hb_tag_t of the table to add
* @blob: The blob containing the table data to add
*
* Add table for @tag with data provided by @blob to the face. @face must
* be created using hb_face_builder_create().
@ -723,7 +756,7 @@ hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
hb_face_builder_data_t::table_entry_t *entry = data->tables.push ();
if (data->tables.in_error())
if (unlikely (data->tables.in_error()))
return false;
entry->tag = tag;

View File

@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif
@ -46,12 +46,31 @@ hb_face_count (hb_blob_t *blob);
* hb_face_t
*/
/**
* hb_face_t:
*
* Data type for holding font faces.
*
**/
typedef struct hb_face_t hb_face_t;
HB_EXTERN hb_face_t *
hb_face_create (hb_blob_t *blob,
unsigned int index);
/**
* hb_reference_table_func_t:
* @face: an #hb_face_t to reference table for
* @tag: the tag of the table to reference
* @user_data: User data pointer passed by the caller
*
* Callback function for hb_face_create_for_tables().
*
* Return value: (transfer full): A pointer to the @tag table within @face
*
* Since: 0.9.2
*/
typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data);
/* calls destroy() when not needing user_data anymore */

View File

@ -81,7 +81,7 @@ struct hb_face_t
return blob;
}
HB_PURE_FUNC unsigned int get_upem () const
unsigned int get_upem () const
{
unsigned int ret = upem.get_relaxed ();
if (unlikely (!ret))

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif
@ -37,7 +37,12 @@
HB_BEGIN_DECLS
/**
* hb_font_t:
*
* Data type for holding fonts.
*
*/
typedef struct hb_font_t hb_font_t;
@ -45,6 +50,19 @@ typedef struct hb_font_t hb_font_t;
* hb_font_funcs_t
*/
/**
* hb_font_funcs_t:
*
* Data type containing a set of virtual methods used for
* working on #hb_font_t font objects.
*
* HarfBuzz provides a lightweight default function for each of
* the methods in #hb_font_funcs_t. Client programs can implement
* their own replacements for the individual font functions, as
* needed, and replace the default by calling the setter for a
* method.
*
**/
typedef struct hb_font_funcs_t hb_font_funcs_t;
HB_EXTERN hb_font_funcs_t *
@ -81,12 +99,21 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
/* font and glyph extents */
/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */
typedef struct hb_font_extents_t
{
hb_position_t ascender; /* typographic ascender. */
hb_position_t descender; /* typographic descender. */
hb_position_t line_gap; /* suggested line spacing gap. */
/**
* hb_font_extents_t:
* @ascender: The height of typographic ascenders.
* @descender: The depth of typographic descenders.
* @line_gap: The suggested line-spacing gap.
*
* Font-wide extent values, measured in font units.
*
* Note that typically @ascender is positive and @descender
* negative, in coordinate systems that grow up.
**/
typedef struct hb_font_extents_t {
hb_position_t ascender;
hb_position_t descender;
hb_position_t line_gap;
/*< private >*/
hb_position_t reserved9;
hb_position_t reserved8;
@ -99,33 +126,130 @@ typedef struct hb_font_extents_t
hb_position_t reserved1;
} hb_font_extents_t;
/* Note that height is negative in coordinate systems that grow up. */
typedef struct hb_glyph_extents_t
{
hb_position_t x_bearing; /* left side of glyph from origin. */
hb_position_t y_bearing; /* top side of glyph from origin. */
hb_position_t width; /* distance from left to right side. */
hb_position_t height; /* distance from top to bottom side. */
/**
* hb_glyph_extents_t:
* @x_bearing: Distance from the x-origin to the left extremum of the glyph.
* @y_bearing: Distance from the top extremum of the glyph to the y-origin.
* @width: Distance from the left extremum of the glyph to the right extremum.
* @height: Distance from the top extremum of the glyph to the bottom extremum.
*
* Glyph extent values, measured in font units.
*
* Note that @height is negative, in coordinate systems that grow up.
**/
typedef struct hb_glyph_extents_t {
hb_position_t x_bearing;
hb_position_t y_bearing;
hb_position_t width;
hb_position_t height;
} hb_glyph_extents_t;
/* func types */
/**
* hb_font_get_font_extents_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @extents: (out): The font extents retrieved
* @user_data: User data pointer passed by the caller
*
* This method should retrieve the extents for a font.
*
**/
typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data,
hb_font_extents_t *extents,
void *user_data);
/**
* hb_font_get_font_h_extents_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the extents for a font, for horizontal-direction
* text segments. Extents must be returned in an #hb_glyph_extents output
* parameter.
*
**/
typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t;
/**
* hb_font_get_font_v_extents_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the extents for a font, for vertical-direction
* text segments. Extents must be returned in an #hb_glyph_extents output
* parameter.
*
**/
typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t;
/**
* hb_font_get_nominal_glyph_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @unicode: The Unicode code point to query
* @glyph: (out): The glyph ID retrieved
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the nominal glyph ID for a specified Unicode code
* point. Glyph IDs must be returned in a #hb_codepoint_t output parameter.
*
* Return value: %true if data found, %false otherwise
*
**/
typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
void *user_data);
/**
* hb_font_get_variation_glyph_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @unicode: The Unicode code point to query
* @variation_selector: The variation-selector code point to query
* @glyph: (out): The glyph ID retrieved
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the glyph ID for a specified Unicode code point
* followed by a specified Variation Selector code point. Glyph IDs must be
* returned in a #hb_codepoint_t output parameter.
*
* Return value: %true if data found, %false otherwise
*
**/
typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data);
/**
* hb_font_get_nominal_glyphs_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @count: number of code points to query
* @first_unicode: The first Unicode code point to query
* @unicode_stride: The stride between successive code points
* @first_glyph: (out): The first glyph ID retrieved
* @glyph_stride: The stride between successive glyph IDs
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the nominal glyph IDs for a sequence of
* Unicode code points. Glyph IDs must be returned in a #hb_codepoint_t
* output parameter.
*
* Return value: the number of code points processed
*
**/
typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data,
unsigned int count,
const hb_codepoint_t *first_unicode,
@ -134,13 +258,65 @@ typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void
unsigned int glyph_stride,
void *user_data);
/**
* hb_font_get_glyph_advance_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @glyph: The glyph ID to query
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the advance for a specified glyph. The
* method must return an #hb_position_t.
*
* Return value: The advance of @glyph within @font
*
**/
typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
void *user_data);
/**
* hb_font_get_glyph_h_advance_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the advance for a specified glyph, in
* horizontal-direction text segments. Advances must be returned in
* an #hb_position_t output parameter.
*
**/
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
/**
* hb_font_get_glyph_v_advance_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the advance for a specified glyph, in
* vertical-direction text segments. Advances must be returned in
* an #hb_position_t output parameter.
*
**/
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
/**
* hb_font_get_glyph_advances_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @count: The number of glyph IDs in the sequence queried
* @first_glyph: The first glyph ID to query
* @glyph_stride: The stride between successive glyph IDs
* @first_advance: (out): The first advance retrieved
* @advance_stride: The stride between successive advances
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the advances for a sequence of glyphs.
*
**/
typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_data,
unsigned int count,
const hb_codepoint_t *first_glyph,
@ -148,36 +324,188 @@ typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_d
hb_position_t *first_advance,
unsigned advance_stride,
void *user_data);
/**
* hb_font_get_glyph_h_advances_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the advances for a sequence of glyphs, in
* horizontal-direction text segments.
*
**/
typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_h_advances_func_t;
/**
* hb_font_get_glyph_v_advances_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the advances for a sequence of glyphs, in
* vertical-direction text segments.
*
**/
typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t;
/**
* hb_font_get_glyph_origin_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @glyph: The glyph ID to query
* @x: (out): The X coordinate of the origin
* @y: (out): The Y coordinate of the origin
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the (X,Y) coordinates (in font units) of the
* origin for a glyph. Each coordinate must be returned in an #hb_position_t
* output parameter.
*
* Return value: %true if data found, %false otherwise
*
**/
typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y,
void *user_data);
/**
* hb_font_get_glyph_h_origin_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the (X,Y) coordinates (in font units) of the
* origin for a glyph, for horizontal-direction text segments. Each
* coordinate must be returned in an #hb_position_t output parameter.
*
**/
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
/**
* hb_font_get_glyph_v_origin_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the (X,Y) coordinates (in font units) of the
* origin for a glyph, for vertical-direction text segments. Each coordinate
* must be returned in an #hb_position_t output parameter.
*
**/
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
/**
* hb_font_get_glyph_kerning_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @first_glyph: The glyph ID of the first glyph in the glyph pair
* @second_glyph: The glyph ID of the second glyph in the glyph pair
* @user_data: User data pointer passed by the caller
*
* This method should retrieve the kerning-adjustment value for a glyph-pair in
* the specified font, for horizontal text segments.
*
**/
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
/**
* hb_font_get_glyph_h_kerning_func_t:
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the kerning-adjustment value for a glyph-pair in
* the specified font, for horizontal text segments.
*
**/
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
/**
* hb_font_get_glyph_extents_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @glyph: The glyph ID to query
* @extents: (out): The #hb_glyph_extents_t retrieved
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the extents for a specified glyph. Extents must be
* returned in an #hb_glyph_extents output parameter.
*
* Return value: %true if data found, %false otherwise
*
**/
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
void *user_data);
/**
* hb_font_get_glyph_contour_point_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @glyph: The glyph ID to query
* @point_index: The contour-point index to query
* @x: (out): The X value retrieved for the contour point
* @y: (out): The Y value retrieved for the contour point
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the (X,Y) coordinates (in font units) for a
* specified contour point in a glyph. Each coordinate must be returned as
* an #hb_position_t output parameter.
*
* Return value: %true if data found, %false otherwise
*
**/
typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, unsigned int point_index,
hb_position_t *x, hb_position_t *y,
void *user_data);
/**
* hb_font_get_glyph_name_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @glyph: The glyph ID to query
* @name: (out) (array length=size): Name string retrieved for the glyph ID
* @size: Length of the glyph-name string retrieved
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the glyph name that corresponds to a
* glyph ID. The name should be returned in a string output parameter.
*
* Return value: %true if data found, %false otherwise
*
**/
typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
char *name, unsigned int size,
void *user_data);
/**
* hb_font_get_glyph_from_name_func_t:
* @font: #hb_font_t to work upon
* @font_data: @font user data pointer
* @name: (array length=len): The name string to query
* @len: The length of the name queried
* @glyph: (out): The glyph ID retrieved
* @user_data: User data pointer passed by the caller
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the glyph ID that corresponds to a glyph-name
* string.
*
* Return value: %true if data found, %false otherwise
*
**/
typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data,
const char *name, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph,
@ -188,12 +516,12 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
/**
* hb_font_funcs_set_font_h_extents_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_font_h_extents_func_t.
*
* Since: 1.1.2
**/
@ -204,12 +532,12 @@ hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_font_v_extents_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_font_v_extents_func_t.
*
* Since: 1.1.2
**/
@ -220,12 +548,12 @@ hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_nominal_glyph_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_nominal_glyph_func_t.
*
* Since: 1.2.3
**/
@ -236,12 +564,12 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_nominal_glyphs_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_nominal_glyphs_func_t.
*
* Since: 2.0.0
**/
@ -252,12 +580,12 @@ hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_variation_glyph_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_variation_glyph_func_t.
*
* Since: 1.2.3
**/
@ -268,12 +596,12 @@ hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_advance_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_h_advance_func_t.
*
* Since: 0.9.2
**/
@ -284,12 +612,12 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_advance_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_v_advance_func_t.
*
* Since: 0.9.2
**/
@ -300,12 +628,12 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_advances_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_h_advances_func_t.
*
* Since: 1.8.6
**/
@ -316,12 +644,12 @@ hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_advances_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_v_advances_func_t.
*
* Since: 1.8.6
**/
@ -332,12 +660,12 @@ hb_font_funcs_set_glyph_v_advances_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_origin_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_h_origin_func_t.
*
* Since: 0.9.2
**/
@ -348,12 +676,12 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_v_origin_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_v_origin_func_t.
*
* Since: 0.9.2
**/
@ -364,12 +692,12 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_h_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_h_kerning_func_t.
*
* Since: 0.9.2
**/
@ -380,12 +708,12 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_extents_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_extents_func_t.
*
* Since: 0.9.2
**/
@ -396,12 +724,12 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_contour_point_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_contour_point_func_t.
*
* Since: 0.9.2
**/
@ -412,12 +740,12 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_name_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_name_func_t.
*
* Since: 0.9.2
**/
@ -428,12 +756,12 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
/**
* hb_font_funcs_set_glyph_from_name_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @ffuncs: A font-function structure
* @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
* @user_data: Data to pass to @func
* @destroy: (nullable): The function to call when @user_data is not needed anymore
*
* Sets the implementation function for #hb_font_get_glyph_from_name_func_t.
*
* Since: 0.9.2
**/

View File

@ -84,7 +84,7 @@ struct hb_ft_font_t
bool symbol; /* Whether selected cmap is symbol cmap. */
bool unref; /* Whether to destroy ft_face when done. */
mutable hb_atomic_int_t cached_x_scale;
mutable int cached_x_scale;
mutable hb_advance_cache_t advance_cache;
};
@ -101,7 +101,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
ft_font->cached_x_scale.set_relaxed (0);
ft_font->cached_x_scale = 0;
ft_font->advance_cache.init ();
return ft_font;
@ -179,13 +179,13 @@ hb_ft_font_get_load_flags (hb_font_t *font)
}
/**
* hb_ft_get_face:
* hb_ft_font_get_face:
* @font: #hb_font_t to work upon
*
* Fetches the FT_Face associated with the specified #hb_font_t
* font object.
*
* Return value: the FT_Face found
* Return value: (nullable): the FT_Face found or %NULL
*
* Since: 0.9.2
**/
@ -202,11 +202,12 @@ hb_ft_font_get_face (hb_font_t *font)
/**
* hb_ft_font_lock_face:
* @font:
* @font: #hb_font_t to work upon
*
* Gets the FT_Face associated with @font, This face will be kept around until
* you call hb_ft_font_unlock_face().
*
*
* Return value:
* Return value: (nullable): the FT_Face associated with @font or %NULL
* Since: 2.6.5
**/
FT_Face
@ -224,11 +225,10 @@ hb_ft_font_lock_face (hb_font_t *font)
/**
* hb_ft_font_unlock_face:
* @font:
* @font: #hb_font_t to work upon
*
* Releases an FT_Face previously obtained with hb_ft_font_lock_face().
*
*
* Return value:
* Since: 2.6.5
**/
void
@ -335,10 +335,10 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
int load_flags = ft_font->load_flags;
int mult = font->x_scale < 0 ? -1 : +1;
if (font->x_scale != ft_font->cached_x_scale.get ())
if (font->x_scale != ft_font->cached_x_scale)
{
ft_font->advance_cache.clear ();
ft_font->cached_x_scale.set (font->x_scale);
ft_font->cached_x_scale = font->x_scale;
}
for (unsigned int i = 0; i < count; i++)
@ -661,7 +661,7 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data
/**
* hb_ft_face_create:
* @ft_face: (destroy destroy) (scope notified): FT_Face to work upon
* @destroy: A callback to call when the face object is not needed anymore
* @destroy: (nullable): A callback to call when the face object is not needed anymore
*
* Creates an #hb_face_t face object from the specified FT_Face.
*
@ -771,13 +771,13 @@ hb_ft_face_create_cached (FT_Face ft_face)
/**
* hb_ft_font_create:
* @ft_face: (destroy destroy) (scope notified): FT_Face to work upon
* @destroy: (optional): A callback to call when the font object is not needed anymore
* @destroy: (nullable): A callback to call when the font object is not needed anymore
*
* Creates an #hb_font_t font object from the specified FT_Face.
*
* <note>Note: You must set the face size on @ft_face before calling
* hb_ft_font_create() on it. Otherwise, HarfBuzz will not pick up
* the face size.</note>
* hb_ft_font_create() on it. HarfBuzz assumes size is always set and will
* access `size` member of FT_Face unconditionally.</note>
*
* This variant of the function does not provide any life-cycle management.
*
@ -814,7 +814,7 @@ hb_ft_font_create (FT_Face ft_face,
}
/**
* hb_ft_font_has_changed:
* hb_ft_font_changed:
* @font: #hb_font_t to work upon
*
* Refreshes the state of @font when the underlying FT_Face has changed.
@ -884,8 +884,8 @@ hb_ft_font_changed (hb_font_t *font)
* Creates an #hb_font_t font object from the specified FT_Face.
*
* <note>Note: You must set the face size on @ft_face before calling
* hb_ft_font_create_references() on it. Otherwise, HarfBuzz will not pick up
* the face size.</note>
* hb_ft_font_create_referenced() on it. HarfBuzz assumes size is always set
* and will access `size` member of FT_Face unconditionally.</note>
*
* This is the preferred variant of the hb_ft_font_create*
* function family, because it calls FT_Reference_Face() on @ft_face,

View File

@ -922,7 +922,7 @@ HB_FUNCOBJ (hb_none);
template <typename C, typename V,
hb_requires (hb_is_iterable (C))>
inline void
hb_fill (C& c, const V &v)
hb_fill (C&& c, const V &v)
{
for (auto i = hb_iter (c); i; i++)
*i = v;

View File

@ -80,6 +80,11 @@ static inline Type& StructAfter(TObject &X)
* Size checking
*/
/* Size signifying variable-sized array */
#ifndef HB_VAR_ARRAY
#define HB_VAR_ARRAY 1
#endif
/* Check _assertion in a method environment */
#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
void _instance_assertion_on_line_##_line () const \

View File

@ -42,7 +42,9 @@
/**
* hb_map_create: (Xconstructor)
*
* Return value: (transfer full):
* Creates a new, initially empty map.
*
* Return value: (transfer full): The new #hb_map_t
*
* Since: 1.7.7
**/
@ -62,7 +64,9 @@ hb_map_create ()
/**
* hb_map_get_empty:
*
* Return value: (transfer full):
* Fetches the singleton empty #hb_map_t.
*
* Return value: (transfer full): The empty #hb_map_t
*
* Since: 1.7.7
**/
@ -74,9 +78,11 @@ hb_map_get_empty ()
/**
* hb_map_reference: (skip)
* @map: a map.
* @map: A map
*
* Return value: (transfer full):
* Increases the reference count on a map.
*
* Return value: (transfer full): The map
*
* Since: 1.7.7
**/
@ -88,7 +94,11 @@ hb_map_reference (hb_map_t *map)
/**
* hb_map_destroy: (skip)
* @map: a map.
* @map: A map
*
* Decreases the reference count on a map. When
* the reference count reaches zero, the map is
* destroyed, freeing all memory.
*
* Since: 1.7.7
**/
@ -104,13 +114,15 @@ hb_map_destroy (hb_map_t *map)
/**
* hb_map_set_user_data: (skip)
* @map: a map.
* @key:
* @data:
* @destroy:
* @replace:
* @map: A map
* @key: The user-data key to set
* @data: A pointer to the user data to set
* @destroy: (nullable): A callback to call when @data is not needed anymore
* @replace: Whether to replace an existing data with the same key
*
* Return value:
* Attaches a user-data key/data pair to the specified map.
*
* Return value: %true if success, %false otherwise
*
* Since: 1.7.7
**/
@ -126,10 +138,13 @@ hb_map_set_user_data (hb_map_t *map,
/**
* hb_map_get_user_data: (skip)
* @map: a map.
* @key:
* @map: A map
* @key: The user-data key to query
*
* Return value: (transfer none):
* Fetches the user data associated with the specified key,
* attached to the specified map.
*
* Return value: (transfer none): A pointer to the user data
*
* Since: 1.7.7
**/
@ -143,11 +158,11 @@ hb_map_get_user_data (hb_map_t *map,
/**
* hb_map_allocation_successful:
* @map: a map.
* @map: A map
*
* Tests whether memory allocation for a set was successful.
*
*
* Return value:
* Return value: %true if allocation succeeded, %false otherwise
*
* Since: 1.7.7
**/
@ -160,11 +175,11 @@ hb_map_allocation_successful (const hb_map_t *map)
/**
* hb_map_set:
* @map: a map.
* @key:
* @value:
*
* @map: A map
* @key: The key to store in the map
* @value: The value to store for @key
*
* Stores @key:@value in the map.
*
* Since: 1.7.7
**/
@ -178,10 +193,10 @@ hb_map_set (hb_map_t *map,
/**
* hb_map_get:
* @map: a map.
* @key:
*
* @map: A map
* @key: The key to query
*
* Fetches the value stored for @key in @map.
*
* Since: 1.7.7
**/
@ -194,10 +209,10 @@ hb_map_get (const hb_map_t *map,
/**
* hb_map_del:
* @map: a map.
* @key:
*
* @map: A map
* @key: The key to delete
*
* Removes @key and its stored value from @map.
*
* Since: 1.7.7
**/
@ -210,10 +225,12 @@ hb_map_del (hb_map_t *map,
/**
* hb_map_has:
* @map: a map.
* @key:
* @map: A map
* @key: The key to query
*
* Tests whether @key is an element of @map.
*
* Return value: %true if @key is found in @map, %false otherwise
*
* Since: 1.7.7
**/
@ -227,23 +244,28 @@ hb_map_has (const hb_map_t *map,
/**
* hb_map_clear:
* @map: a map.
*
* @map: A map
*
* Clears out the contents of @map.
*
* Since: 1.7.7
**/
void
hb_map_clear (hb_map_t *map)
{
if (unlikely (hb_object_is_immutable (map)))
return;
return map->clear ();
}
/**
* hb_map_is_empty:
* @map: a map.
* @map: A map
*
* Tests whether @map is empty (contains no elements).
*
* Return value: %true if @map is empty
*
* Since: 1.7.7
**/
@ -255,9 +277,11 @@ hb_map_is_empty (const hb_map_t *map)
/**
* hb_map_get_population:
* @map: a map.
* @map: A map
*
* Returns the number of key-value pairs in the map.
*
* Return value: The population of @map
*
* Since: 1.7.7
**/

View File

@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_H_IN
#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb.h> instead."
#endif
@ -36,11 +36,21 @@
HB_BEGIN_DECLS
/*
/**
* HB_MAP_VALUE_INVALID:
*
* Unset #hb_map_t value.
*
* Since: 1.7.7
*/
#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1)
/**
* hb_map_t:
*
* Data type for holding integer-to-integer hash maps.
*
**/
typedef struct hb_map_t hb_map_t;

View File

@ -97,8 +97,6 @@ struct hb_hashmap_t
void reset ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
successful = true;
clear ();
}
@ -171,8 +169,6 @@ struct hb_hashmap_t
void clear ()
{
if (unlikely (hb_object_is_immutable (this)))
return;
if (items)
for (auto &_ : hb_iter (items, mask + 1))
_.clear ();
@ -181,6 +177,7 @@ struct hb_hashmap_t
}
bool is_empty () const { return population == 0; }
explicit operator bool () const { return !is_empty (); }
unsigned int get_population () const { return population; }

View File

@ -49,6 +49,10 @@ template <bool b> using hb_bool_constant = hb_integral_constant<bool, b>;
using hb_true_type = hb_bool_constant<true>;
using hb_false_type = hb_bool_constant<false>;
/* Static-assert as expression. */
template <bool cond> struct static_assert_expr;
template <> struct static_assert_expr<true> : hb_false_type {};
#define static_assert_expr(C) static_assert_expr<C>::value
/* Basic type SFINAE. */
@ -220,6 +224,8 @@ struct hb_reference_wrapper<T&>
};
/* Type traits */
template <typename T>
using hb_is_integral = hb_bool_constant<
hb_is_same (hb_decay<T>, char) ||
@ -292,6 +298,15 @@ template <> struct hb_int_max<unsigned long long> : hb_integral_constant<u
#define hb_int_max(T) hb_int_max<T>::value
/* Class traits. */
#define HB_DELETE_COPY_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \
TypeName() = delete; \
TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
template <typename T, typename>
struct _hb_is_destructible : hb_false_type {};

View File

@ -73,24 +73,6 @@ typedef CRITICAL_SECTION hb_mutex_impl_t;
#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
# include <sched.h>
# define HB_SCHED_YIELD() sched_yield ()
#else
# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
#endif
/* This actually is not a totally awful implementation. */
typedef volatile int hb_mutex_impl_t;
#define HB_MUTEX_IMPL_INIT 0
#define hb_mutex_impl_init(M) *(M) = 0
#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
#define hb_mutex_impl_unlock(M) __sync_lock_release (M)
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
#elif defined(HB_NO_MT)
typedef int hb_mutex_impl_t;

View File

@ -177,6 +177,7 @@ struct hb_nonnull_ptr_t
T * get () const { return v ? v : const_cast<T *> (&Null (T)); }
T * get_raw () const { return v; }
private:
T *v;
};

View File

@ -140,9 +140,7 @@ struct hb_lockable_set_t
* Reference-count.
*/
#define HB_REFERENCE_COUNT_INERT_VALUE 0
#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD
#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (HB_REFERENCE_COUNT_INERT_VALUE)}
#define HB_REFERENCE_COUNT_INIT {0}
struct hb_reference_count_t
{
@ -152,9 +150,9 @@ struct hb_reference_count_t
int get_relaxed () const { return ref_count.get_relaxed (); }
int inc () const { return ref_count.inc (); }
int dec () const { return ref_count.dec (); }
void fini () { ref_count.set_relaxed (HB_REFERENCE_COUNT_POISON_VALUE); }
void fini () { ref_count.set_relaxed (-0x0000DEAD); }
bool is_inert () const { return ref_count.get_relaxed () == HB_REFERENCE_COUNT_INERT_VALUE; }
bool is_inert () const { return !ref_count.get_relaxed (); }
bool is_valid () const { return ref_count.get_relaxed () > 0; }
};
@ -197,15 +195,10 @@ struct hb_user_data_array_t
struct hb_object_header_t
{
hb_reference_count_t ref_count;
mutable hb_atomic_int_t writable;
mutable hb_atomic_int_t writable = 0;
hb_atomic_ptr_t<hb_user_data_array_t> user_data;
};
#define HB_OBJECT_HEADER_STATIC \
{ \
HB_REFERENCE_COUNT_INIT, \
HB_ATOMIC_INT_INIT (false), \
HB_ATOMIC_PTR_INIT (nullptr) \
}
#define HB_OBJECT_HEADER_STATIC {}
/*

View File

@ -48,7 +48,7 @@ namespace OT {
*/
struct OpenTypeFontFile;
struct OffsetTable;
struct OpenTypeOffsetTable;
struct TTCHeader;
@ -78,7 +78,7 @@ typedef struct TableRecord
DEFINE_SIZE_STATIC (16);
} OpenTypeTable;
typedef struct OffsetTable
typedef struct OpenTypeOffsetTable
{
friend struct OpenTypeFontFile;
@ -218,7 +218,7 @@ struct TTCHeaderVersion1
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
FixedVersion<>version; /* Version of the TTC Header (1.0),
* 0x00010000u */
LArrayOf<LOffsetTo<OffsetTable>>
LArrayOf<LOffsetTo<OpenTypeOffsetTable>>
table; /* Array of offsets to the OffsetTable for each font
* from the beginning of the file */
public:

View File

@ -53,14 +53,19 @@ namespace OT {
*/
/* Integer types in big-endian order and no alignment requirement */
template <typename Type, unsigned int Size>
template <typename Type,
unsigned int Size = sizeof (Type)>
struct IntType
{
typedef Type type;
typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type;
IntType& operator = (wide_type i) { v = i; return *this; }
operator wide_type () const { return v; }
IntType () = default;
explicit constexpr IntType (Type V) : v {V} {}
IntType& operator = (Type i) { v = i; return *this; }
/* For reason we define cast out operator for signed/unsigned, instead of Type, see:
* https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */
operator hb_conditional<hb_is_signed (Type), signed, unsigned> () const { return v; }
bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType &o) const { return !(*this == o); }
@ -80,14 +85,21 @@ struct IntType
return pb->cmp (*pa);
}
template <typename Type2>
template <typename Type2,
hb_enable_if (hb_is_integral (Type2) &&
sizeof (Type2) < sizeof (int) &&
sizeof (Type) < sizeof (int))>
int cmp (Type2 a) const
{
Type b = v;
if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int))
return (int) a - (int) b;
else
return a < b ? -1 : a == b ? 0 : +1;
return (int) a - (int) b;
}
template <typename Type2,
hb_enable_if (hb_is_convertible (Type2, Type))>
int cmp (Type2 a) const
{
Type b = v;
return a < b ? -1 : a == b ? 0 : +1;
}
bool sanitize (hb_sanitize_context_t *c) const
{
@ -100,12 +112,12 @@ struct IntType
DEFINE_SIZE_STATIC (Size);
};
typedef IntType<uint8_t, 1> HBUINT8; /* 8-bit unsigned integer. */
typedef IntType<int8_t, 1> HBINT8; /* 8-bit signed integer. */
typedef IntType<uint16_t, 2> HBUINT16; /* 16-bit unsigned integer. */
typedef IntType<int16_t, 2> HBINT16; /* 16-bit signed integer. */
typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */
typedef IntType<int32_t, 4> HBINT32; /* 32-bit signed integer. */
typedef IntType<uint8_t> HBUINT8; /* 8-bit unsigned integer. */
typedef IntType<int8_t> HBINT8; /* 8-bit signed integer. */
typedef IntType<uint16_t> HBUINT16; /* 16-bit unsigned integer. */
typedef IntType<int16_t> HBINT16; /* 16-bit signed integer. */
typedef IntType<uint32_t> HBUINT32; /* 32-bit unsigned integer. */
typedef IntType<int32_t> HBINT32; /* 32-bit signed integer. */
/* Note: we cannot defined a signed HBINT24 because there's no corresponding C type.
* Works for unsigned, but not signed, since we rely on compiler for sign-extension. */
typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */
@ -163,8 +175,8 @@ struct Tag : HBUINT32
{
Tag& operator = (hb_tag_t i) { HBUINT32::operator= (i); return *this; }
/* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
operator const char* () const { return reinterpret_cast<const char *> (&this->v); }
operator char* () { return reinterpret_cast<char *> (&this->v); }
operator const char* () const { return reinterpret_cast<const char *> (this); }
operator char* () { return reinterpret_cast<char *> (this); }
public:
DEFINE_SIZE_STATIC (4);
};
@ -433,8 +445,6 @@ struct UnsizedArrayOf
{ return hb_array (arrayZ, len); }
hb_array_t<const Type> as_array (unsigned int len) const
{ return hb_array (arrayZ, len); }
operator hb_array_t< Type> () { return as_array (); }
operator hb_array_t<const Type> () const { return as_array (); }
template <typename T>
Type &lsearch (unsigned int len, const T &x, Type &not_found = Crap (Type))

View File

@ -183,7 +183,7 @@ struct CFFIndex
else
{
serialize_header(c, + it | hb_map ([] (const byte_str_t &_) { return _.length; }));
for (const byte_str_t &_ : +it)
for (const auto &_ : +it)
_.copy (c);
}
return_trace (true);

View File

@ -426,7 +426,7 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph
else
{
extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ());
extents->width = font->em_scalef_x (bounds.max.x.to_real () - bounds.min.x.to_real ());
extents->width = font->em_scalef_x (bounds.max.x.to_real ()) - extents->x_bearing;
}
if (bounds.min.y >= bounds.max.y)
{
@ -436,7 +436,7 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph
else
{
extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ());
extents->height = font->em_scalef_y (bounds.min.y.to_real () - bounds.max.y.to_real ());
extents->height = font->em_scalef_y (bounds.min.y.to_real ()) - extents->y_bearing;
}
return true;

View File

@ -127,7 +127,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
else
{
extents->x_bearing = font->em_scalef_x (param.min_x.to_real ());
extents->width = font->em_scalef_x (param.max_x.to_real () - param.min_x.to_real ());
extents->width = font->em_scalef_x (param.max_x.to_real ()) - extents->x_bearing;
}
if (param.min_y >= param.max_y)
{
@ -137,7 +137,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
else
{
extents->y_bearing = font->em_scalef_y (param.max_y.to_real ());
extents->height = font->em_scalef_y (param.min_y.to_real () - param.max_y.to_real ());
extents->height = font->em_scalef_y (param.min_y.to_real ()) - extents->y_bearing;
}
return true;

View File

@ -95,7 +95,7 @@ struct CmapSubtableFormat4
HBUINT16 *endCode = c->start_embed<HBUINT16> ();
hb_codepoint_t prev_endcp = 0xFFFF;
for (const hb_item_type<Iterator> _ : +it)
for (const auto& _ : +it)
{
if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first)
{
@ -131,7 +131,7 @@ struct CmapSubtableFormat4
HBUINT16 *startCode = c->start_embed<HBUINT16> ();
hb_codepoint_t prev_cp = 0xFFFF;
for (const hb_item_type<Iterator> _ : +it)
for (const auto& _ : +it)
{
if (prev_cp == 0xFFFF || prev_cp + 1u != _.first)
{
@ -170,7 +170,7 @@ struct CmapSubtableFormat4
if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size)
return nullptr;
for (const hb_item_type<Iterator> _ : +it)
for (const auto& _ : +it)
{
if (_.first == startCode[i])
{
@ -696,7 +696,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
hb_codepoint_t startCharCode = 0xFFFF, endCharCode = 0xFFFF;
hb_codepoint_t glyphID = 0;
for (const hb_item_type<Iterator> _ : +it)
for (const auto& _ : +it)
{
if (startCharCode == 0xFFFF)
{

View File

@ -455,8 +455,8 @@ struct IndexSubtableRecord
unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length;
// Set to invalid state to indicate filling glyphs is not yet started.
if (unlikely (!records->resize (records->length + 1)))
return_trace (c->serializer->check_success (false));
if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
return_trace (false);
(*records)[records->length - 1].firstGlyphIndex = 1;
(*records)[records->length - 1].lastGlyphIndex = 0;
@ -567,8 +567,8 @@ struct IndexSubtableArray
hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup;
build_lookup (c, bitmap_size_context, &lookup);
if (unlikely (lookup.in_error ()))
return c->serializer->check_success (false);
if (unlikely (!c->serializer->propagate_error (lookup)))
return false;
bitmap_size_context->size = 0;
bitmap_size_context->num_tables = 0;

View File

@ -214,7 +214,7 @@ struct COLR
if (unlikely (!old_record))
return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord));
BaseGlyphRecord new_record;
BaseGlyphRecord new_record = {};
new_record.glyphId = new_gid;
new_record.numLayers = old_record->numLayers;
return hb_pair_t<bool, BaseGlyphRecord> (true, new_record);

View File

@ -37,9 +37,6 @@
#include "hb-ot-color-sbix-table.hh"
#include "hb-ot-color-svg-table.hh"
#include <stdlib.h>
#include <string.h>
/**
* SECTION:hb-ot-color
@ -64,7 +61,7 @@
*
* Tests whether a face includes a `CPAL` color-palette table.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 2.1.0
*/
@ -195,7 +192,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face,
*
* Tests whether a face includes any `COLR` color layers.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 2.1.0
*/
@ -242,7 +239,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face,
*
* Tests whether a face includes any `SVG` glyph images.
*
* Return value: true if data found, false otherwise.
* Return value: %true if data found, %false otherwise.
*
* Since: 2.1.0
*/
@ -280,7 +277,7 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
*
* Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables).
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 2.1.0
*/

View File

@ -26,7 +26,7 @@
* Google Author(s): Sascha Brawer, Behdad Esfahbod
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif
@ -66,6 +66,8 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face,
* @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: Flag indicating that the color
* palette is appropriate to use when displaying the font on a dark background such as black.
*
* Flags that describe the properties of color palette.
*
* Since: 2.1.0
*/
typedef enum { /*< flags >*/
@ -95,13 +97,14 @@ hb_ot_color_has_layers (hb_face_t *face);
/**
* hb_ot_color_layer_t:
* @glyph: the glyph ID of the layer
* @color_index: the palette color index of the layer
*
* Pairs of glyph and color index.
*
* Since: 2.1.0
**/
typedef struct hb_ot_color_layer_t
{
typedef struct hb_ot_color_layer_t {
hb_codepoint_t glyph;
unsigned int color_index;
} hb_ot_color_layer_t;

View File

@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif
@ -41,6 +41,13 @@ HB_BEGIN_DECLS
/* https://github.com/harfbuzz/harfbuzz/issues/1734 */
/**
* HB_MATH_GLYPH_PART_FLAG_EXTENDER:
*
* Use #HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER instead.
*
* Deprecated: 2.5.1
*/
#define HB_MATH_GLYPH_PART_FLAG_EXTENDER HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER
@ -71,6 +78,8 @@ hb_ot_tag_from_language (hb_language_t language);
/**
* HB_OT_VAR_NO_AXIS_INDEX:
*
* Do not use.
*
* Since: 1.4.2
* Deprecated: 2.2.0
*/
@ -78,12 +87,18 @@ hb_ot_tag_from_language (hb_language_t language);
/**
* hb_ot_var_axis_t:
* @tag: axis tag
* @name_id: axis name identifier
* @min_value: minimum value of the axis
* @default_value: default value of the axis
* @max_value: maximum value of the axis
*
* Use #hb_ot_var_axis_info_t instead.
*
* Since: 1.4.2
* Deprecated: 2.2.0
*/
typedef struct hb_ot_var_axis_t
{
typedef struct hb_ot_var_axis_t {
hb_tag_t tag;
hb_ot_name_id_t name_id;
float min_value;

View File

@ -306,6 +306,9 @@ _hb_ot_get_font_funcs ()
/**
* hb_ot_font_set_funcs:
* @font: #hb_font_t to work upon
*
* Sets the font functions to use when working with @font.
*
* Since: 0.9.28
**/

View File

@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod, Roozbeh Pournader
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif

View File

@ -186,7 +186,7 @@ struct glyf
| hb_map (&SubsetGlyph::padded_size)
;
if (c->serializer->in_error ()) return_trace (false);
if (unlikely (c->serializer->in_error ())) return_trace (false);
return_trace (c->serializer->check_success (_add_loca_and_head (c->plan,
padded_offsets)));
}
@ -944,9 +944,9 @@ struct glyf
return;
}
extents->x_bearing = font->em_scalef_x (min_x);
extents->width = font->em_scalef_x (max_x - min_x);
extents->width = font->em_scalef_x (max_x) - extents->x_bearing;
extents->y_bearing = font->em_scalef_y (max_y);
extents->height = font->em_scalef_y (min_y - max_y);
extents->height = font->em_scalef_y (min_y) - extents->y_bearing;
}
protected:

View File

@ -43,7 +43,7 @@ namespace OT {
struct head
{
friend struct OffsetTable;
friend struct OpenTypeOffsetTable;
static constexpr hb_tag_t tableTag = HB_OT_TAG_head;

View File

@ -379,12 +379,20 @@ struct Axis
const BaseCoord **coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
if (!base_script.has_data ()) return false;
if (!base_script.has_data ())
{
*coord = nullptr;
return false;
}
if (likely (coord))
{
unsigned int tag_index = 0;
(this+baseTagList).bfind (baseline_tag, &tag_index);
if (!(this+baseTagList).bfind (baseline_tag, &tag_index))
{
*coord = nullptr;
return false;
}
*coord = &base_script.get_base_coord (tag_index);
}
@ -398,7 +406,11 @@ struct Axis
const BaseCoord **max_coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
if (!base_script.has_data ()) return false;
if (!base_script.has_data ())
{
*min_coord = *max_coord = nullptr;
return false;
}
base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);

View File

@ -1128,7 +1128,7 @@ struct Lookup
out->lookupType = lookupType;
out->lookupFlag = lookupFlag;
const hb_set_t *glyphset = c->plan->glyphset ();
const hb_set_t *glyphset = c->plan->glyphset_gsub ();
unsigned int lookup_type = get_type ();
+ hb_iter (get_subtables <TSubTable> ())
| hb_filter ([this, glyphset, lookup_type] (const OffsetTo<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); })
@ -1251,8 +1251,9 @@ struct CoverageFormat1
{
/* TODO Speed up, using hb_set_next() and bsearch()? */
unsigned int count = glyphArray.len;
const HBGlyphID *arr = glyphArray.arrayZ;
for (unsigned int i = 0; i < count; i++)
if (glyphs->has (glyphArray[i]))
if (glyphs->has (arr[i]))
return true;
return false;
}
@ -1356,18 +1357,21 @@ struct CoverageFormat2
bool intersects (const hb_set_t *glyphs) const
{
/* TODO Speed up, using hb_set_next() and bsearch()? */
unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++)
if (rangeRecord[i].intersects (glyphs))
/* TODO(iter) Rewrite as dagger. */
unsigned count = rangeRecord.len;
const RangeRecord *arr = rangeRecord.arrayZ;
for (unsigned i = 0; i < count; i++)
if (arr[i].intersects (glyphs))
return true;
return false;
}
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
{
unsigned int i;
unsigned int count = rangeRecord.len;
for (i = 0; i < count; i++) {
const RangeRecord &range = rangeRecord[i];
/* TODO(iter) Rewrite as dagger. */
unsigned count = rangeRecord.len;
const RangeRecord *arr = rangeRecord.arrayZ;
for (unsigned i = 0; i < count; i++) {
const RangeRecord &range = arr[i];
if (range.value <= index &&
index < (unsigned int) range.value + (range.last - range.first) &&
range.intersects (glyphs))
@ -1502,7 +1506,7 @@ struct Coverage
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
@ -1729,7 +1733,7 @@ struct ClassDefFormat1
hb_map_t *klass_map = nullptr /*OUT*/) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->_glyphset_gsub;
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_sorted_vector_t<HBGlyphID> glyphs;
@ -1784,7 +1788,7 @@ struct ClassDefFormat1
}
template <typename set_t>
bool collect_class (set_t *glyphs, unsigned int klass) const
bool collect_class (set_t *glyphs, unsigned klass) const
{
unsigned int count = classValue.len;
for (unsigned int i = 0; i < count; i++)
@ -1802,7 +1806,7 @@ struct ClassDefFormat1
if (classValue[iter - start]) return true;
return false;
}
bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const
bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
{
unsigned int count = classValue.len;
if (klass == 0)
@ -1815,8 +1819,12 @@ struct ClassDefFormat1
if (hb_set_next (glyphs, &g)) return true;
/* Fall through. */
}
/* TODO Speed up, using set overlap first? */
/* TODO(iter) Rewrite as dagger. */
HBUINT16 k {klass};
const HBUINT16 *arr = classValue.arrayZ;
for (unsigned int i = 0; i < count; i++)
if (classValue[i] == klass && glyphs->has (startGlyph + i))
if (arr[i] == k && glyphs->has (startGlyph + i))
return true;
return false;
}
@ -1898,7 +1906,7 @@ struct ClassDefFormat2
hb_map_t *klass_map = nullptr /*OUT*/) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->_glyphset_gsub;
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_sorted_vector_t<HBGlyphID> glyphs;
@ -1961,11 +1969,14 @@ struct ClassDefFormat2
/* TODO Speed up, using hb_set_next() and bsearch()? */
unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++)
if (rangeRecord[i].intersects (glyphs))
{
const auto& range = rangeRecord[i];
if (range.intersects (glyphs) && range.value)
return true;
}
return false;
}
bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const
bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
{
unsigned int count = rangeRecord.len;
if (klass == 0)
@ -1984,8 +1995,12 @@ struct ClassDefFormat2
return true;
/* Fall through. */
}
/* TODO Speed up, using set overlap first? */
/* TODO(iter) Rewrite as dagger. */
HBUINT16 k {klass};
const RangeRecord *arr = rangeRecord.arrayZ;
for (unsigned int i = 0; i < count; i++)
if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
if (arr[i].value == k && arr[i].intersects (glyphs))
return true;
return false;
}
@ -2537,7 +2552,10 @@ struct VariationStore
for (unsigned i = 0; i < inner_maps.length; i++)
inner_maps[i].fini ();
return_trace (bool (varstore_prime->dataSets));
return_trace (
!c->serializer->in_error()
&& varstore_prime->dataSets);
}
unsigned int get_region_index_count (unsigned int ivs) const

View File

@ -566,6 +566,26 @@ struct AnchorMatrix
return_trace (true);
}
bool subset (hb_subset_context_t *c,
unsigned cols,
const hb_map_t *klass_mapping) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
auto indexes =
+ hb_range (rows * cols)
| hb_filter ([=] (unsigned index) { return klass_mapping->has (index % cols); })
;
out->serialize (c->serializer,
(unsigned) rows,
this,
c->plan->layout_variation_idx_map,
indexes);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
{
TRACE_SANITIZE (this);
@ -755,7 +775,7 @@ struct SinglePosFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
@ -870,7 +890,7 @@ struct SinglePosFormat2
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
unsigned sub_length = valueFormat.get_len ();
@ -1129,7 +1149,7 @@ struct PairSet
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
out->len = 0;
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
unsigned len1 = valueFormats[0].get_len ();
@ -1250,7 +1270,7 @@ struct PairPosFormat1
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
@ -1441,7 +1461,7 @@ struct PairPosFormat2
})
;
const hb_set_t &glyphset = *c->plan->_glyphset_gsub;
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
@ -1728,7 +1748,7 @@ struct CursivePosFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
@ -1904,7 +1924,7 @@ struct MarkBasePosFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
@ -2025,10 +2045,37 @@ typedef AnchorMatrix LigatureAttach; /* component-major--
* mark-minor--
* ordered by class--zero-based. */
typedef OffsetListOf<LigatureAttach> LigatureArray;
/* Array of LigatureAttach
* tables ordered by
* LigatureCoverage Index */
/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
struct LigatureArray : OffsetListOf<LigatureAttach>
{
template <typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
bool subset (hb_subset_context_t *c,
Iterator coverage,
unsigned class_count,
const hb_map_t *klass_mapping) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
auto *out = c->serializer->start_embed (this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
for (const auto _ : + hb_zip (coverage, *this)
| hb_filter (glyphset, hb_first))
{
auto *matrix = out->serialize_append (c->serializer);
if (unlikely (!matrix)) return_trace (false);
matrix->serialize_subset (c,
_.second,
this,
class_count,
klass_mapping);
}
return_trace (this->len);
}
};
struct MarkLigPosFormat1
{
@ -2130,8 +2177,56 @@ struct MarkLigPosFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
// TODO(subset)
return_trace (false);
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
hb_map_t klass_mapping;
Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
if (!klass_mapping.get_population ()) return_trace (false);
out->classCount = klass_mapping.get_population ();
auto mark_iter =
+ hb_zip (this+markCoverage, this+markArray)
| hb_filter (glyphset, hb_first)
;
auto new_mark_coverage =
+ mark_iter
| hb_map_retains_sorting (hb_first)
| hb_map_retains_sorting (glyph_map)
;
if (!out->markCoverage.serialize (c->serializer, out)
.serialize (c->serializer, new_mark_coverage))
return_trace (false);
out->markArray.serialize (c->serializer, out)
.serialize (c->serializer,
&klass_mapping,
c->plan->layout_variation_idx_map,
&(this+markArray),
+ mark_iter
| hb_map (hb_second));
auto new_ligature_coverage =
+ hb_iter (this + ligatureCoverage)
| hb_filter (glyphset)
| hb_map_retains_sorting (glyph_map)
;
if (!out->ligatureCoverage.serialize (c->serializer, out)
.serialize (c->serializer, new_ligature_coverage))
return_trace (false);
out->ligatureArray.serialize_subset (c, ligatureArray, this,
hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const
@ -2164,6 +2259,7 @@ struct MarkLigPosFormat1
DEFINE_SIZE_STATIC (12);
};
struct MarkLigPos
{
template <typename context_t, typename ...Ts>
@ -2288,7 +2384,7 @@ struct MarkMarkPosFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);

View File

@ -356,7 +356,7 @@ struct Sequence
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
if (!intersects (&glyphset)) return_trace (false);
@ -447,7 +447,7 @@ struct MultipleSubstFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
@ -582,7 +582,7 @@ struct AlternateSet
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
@ -682,7 +682,7 @@ struct AlternateSubstFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
@ -840,7 +840,7 @@ struct Ligature
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false);
@ -1058,7 +1058,7 @@ struct LigatureSubstFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);

View File

@ -89,7 +89,7 @@ struct hb_closure_context_t :
bool is_lookup_done (unsigned int lookup_index)
{
if (done_lookups->in_error ())
if (unlikely (done_lookups->in_error ()))
return true;
/* Have we visited this lookup with the current set of glyphs? */
@ -146,7 +146,6 @@ struct hb_closure_lookups_context_t :
if (is_lookup_visited (lookup_index))
return;
set_lookup_visited (lookup_index);
nesting_level_left--;
recurse_func (this, lookup_index);
nesting_level_left++;
@ -163,10 +162,10 @@ struct hb_closure_lookups_context_t :
bool is_lookup_visited (unsigned lookup_index)
{
if (lookup_count++ > HB_MAX_LOOKUP_INDICES)
if (unlikely (lookup_count++ > HB_MAX_LOOKUP_INDICES))
return true;
if (visited_lookups->in_error ())
if (unlikely (visited_lookups->in_error ()))
return true;
return visited_lookups->has (lookup_index);
@ -660,7 +659,7 @@ struct hb_ot_apply_context_t :
void replace_glyph (hb_codepoint_t glyph_index) const
{
_set_glyph_props (glyph_index);
buffer->replace_glyph (glyph_index);
(void) buffer->replace_glyph (glyph_index);
}
void replace_glyph_inplace (hb_codepoint_t glyph_index) const
{
@ -671,13 +670,13 @@ struct hb_ot_apply_context_t :
unsigned int class_guess) const
{
_set_glyph_props (glyph_index, class_guess, true);
buffer->replace_glyph (glyph_index);
(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);
buffer->output_glyph (glyph_index);
(void) buffer->output_glyph (glyph_index);
}
};
@ -1044,7 +1043,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
hb_min (this_comp, last_num_components);
_hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
@ -1188,7 +1187,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
/* Don't recurse to ourself at same position.
* Note that this test is too naive, it doesn't catch longer loops. */
if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index)
if (unlikely (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index))
continue;
if (unlikely (!buffer->move_to (match_positions[idx])))
@ -1226,7 +1225,8 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
* mean that n match positions where removed, as there might
* have been marks and default-ignorables in the sequence. We
* should instead drop match positions between current-position
* and current-position + n instead.
* and current-position + n instead. Though, am not sure which
* one is better. Both cases have valid uses. Sigh.
*
* It should be possible to construct tests for both of these cases.
*/
@ -1272,7 +1272,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
match_positions[next] += delta;
}
buffer->move_to (end);
(void) buffer->move_to (end);
return_trace (true);
}
@ -1389,9 +1389,11 @@ struct Rule
lookup_context);
}
void closure_lookups (hb_closure_lookups_context_t *c) const
void closure_lookups (hb_closure_lookups_context_t *c,
ContextClosureLookupContext &lookup_context) const
{
if (unlikely (c->lookup_limit_exceeded ())) return;
if (!intersects (c->glyphs, lookup_context)) return;
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
(inputZ.as_array (inputCount ? inputCount - 1 : 0));
@ -1521,14 +1523,13 @@ struct RuleSet
;
}
void closure_lookups (hb_closure_lookups_context_t *c) const
void closure_lookups (hb_closure_lookups_context_t *c,
ContextClosureLookupContext &lookup_context) const
{
if (unlikely (c->lookup_limit_exceeded ())) return;
return
+ hb_iter (rule)
| hb_map (hb_add (this))
| hb_apply ([&] (const Rule &_) { _.closure_lookups (c); })
| hb_apply ([&] (const Rule &_) { _.closure_lookups (c, lookup_context); })
;
}
@ -1647,9 +1648,16 @@ struct ContextFormat1
void closure_lookups (hb_closure_lookups_context_t *c) const
{
+ hb_iter (ruleSet)
struct ContextClosureLookupContext lookup_context = {
{intersects_glyph},
nullptr
};
+ hb_zip (this+coverage, ruleSet)
| hb_filter (*c->glyphs, hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
| hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); })
| hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c, lookup_context); })
;
}
@ -1700,7 +1708,7 @@ struct ContextFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
@ -1791,10 +1799,24 @@ struct ContextFormat2
void closure_lookups (hb_closure_lookups_context_t *c) const
{
if (!(this+coverage).intersects (c->glyphs))
return;
const ClassDef &class_def = this+classDef;
struct ContextClosureLookupContext lookup_context = {
{intersects_class},
&class_def
};
+ hb_iter (ruleSet)
| hb_map (hb_add (this))
| hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); })
;
| hb_enumerate
| hb_filter ([&] (const hb_pair_t<unsigned, const RuleSet &> p)
{ return class_def.intersects_class (c->glyphs, p.first); })
| hb_map (hb_second)
| hb_apply ([&] (const RuleSet & _)
{ _.closure_lookups (c, lookup_context); });
}
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
@ -1859,9 +1881,9 @@ struct ContextFormat2
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
bool ret = true;
unsigned non_zero_index = 0, index = 0;
for (const hb_pair_t<unsigned, const OffsetTo<RuleSet>&> _ : + hb_enumerate (ruleSet)
| hb_filter (klass_map, hb_first))
int non_zero_index = 0, index = 0;
for (const auto& _ : + hb_enumerate (ruleSet)
| hb_filter (klass_map, hb_first))
{
auto *o = out->ruleSet.serialize_append (c->serializer);
if (unlikely (!o))
@ -1945,6 +1967,8 @@ struct ContextFormat3
void closure_lookups (hb_closure_lookups_context_t *c) const
{
if (!intersects (c->glyphs))
return;
const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
recurse_lookups (c, lookupCount, lookupRecord);
}
@ -2010,6 +2034,7 @@ struct ContextFormat3
for (const OffsetTo<Coverage>& offset : coverages)
{
/* TODO(subset) This looks like should not be necessary to write this way. */
auto *o = c->serializer->allocate_size<OffsetTo<Coverage>> (OffsetTo<Coverage>::static_size);
if (unlikely (!o)) return_trace (false);
if (!o->serialize_subset (c, offset, this)) return_trace (false);
@ -2238,9 +2263,11 @@ struct ChainRule
lookup_context);
}
void closure_lookups (hb_closure_lookups_context_t *c) const
void closure_lookups (hb_closure_lookups_context_t *c,
ChainContextClosureLookupContext &lookup_context) const
{
if (unlikely (c->lookup_limit_exceeded ())) return;
if (!intersects (c->glyphs, lookup_context)) return;
const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
@ -2296,11 +2323,7 @@ struct ChainRule
{
c->copy (len);
for (const auto g : it)
{
HBUINT16 gid;
gid = g;
c->copy (gid);
}
c->copy ((HBUINT16) g);
}
ChainRule* copy (hb_serialize_context_t *c,
@ -2328,12 +2351,19 @@ struct ChainRule
| hb_map (mapping));
const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead);
HBUINT16 lookupCount;
lookupCount = lookupRecord.len;
if (!c->copy (lookupCount)) return_trace (nullptr);
for (unsigned i = 0; i < (unsigned) lookupCount; i++)
HBUINT16* lookupCount = c->embed (&(lookupRecord.len));
if (!lookupCount) return_trace (nullptr);
for (unsigned i = 0; i < lookupRecord.len; i++)
{
if (!lookup_map->has (lookupRecord[i].lookupListIndex))
{
(*lookupCount)--;
continue;
}
if (!c->copy (lookupRecord[i], lookup_map)) return_trace (nullptr);
}
return_trace (out);
}
@ -2351,7 +2381,7 @@ struct ChainRule
if (!backtrack_map)
{
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
if (!hb_all (backtrack, glyphset) ||
!hb_all (input, glyphset) ||
!hb_all (lookahead, glyphset))
@ -2424,14 +2454,14 @@ struct ChainRuleSet
;
}
void closure_lookups (hb_closure_lookups_context_t *c) const
void closure_lookups (hb_closure_lookups_context_t *c,
ChainContextClosureLookupContext &lookup_context) const
{
if (unlikely (c->lookup_limit_exceeded ())) return;
return
+ hb_iter (rule)
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRule &_) { _.closure_lookups (c); })
| hb_apply ([&] (const ChainRule &_) { _.closure_lookups (c, lookup_context); })
;
}
@ -2552,9 +2582,16 @@ struct ChainContextFormat1
void closure_lookups (hb_closure_lookups_context_t *c) const
{
+ hb_iter (ruleSet)
struct ChainContextClosureLookupContext lookup_context = {
{intersects_glyph},
{nullptr, nullptr, nullptr}
};
+ hb_zip (this+coverage, ruleSet)
| hb_filter (*c->glyphs, hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c); })
| hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c, lookup_context); })
;
}
@ -2604,7 +2641,7 @@ struct ChainContextFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this);
@ -2701,9 +2738,28 @@ struct ChainContextFormat2
void closure_lookups (hb_closure_lookups_context_t *c) const
{
if (!(this+coverage).intersects (c->glyphs))
return;
const ClassDef &backtrack_class_def = this+backtrackClassDef;
const ClassDef &input_class_def = this+inputClassDef;
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
struct ChainContextClosureLookupContext lookup_context = {
{intersects_class},
{&backtrack_class_def,
&input_class_def,
&lookahead_class_def}
};
+ hb_iter (ruleSet)
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c); })
| hb_enumerate
| hb_filter([&] (unsigned klass)
{ return input_class_def.intersects_class (c->glyphs, klass); }, hb_first)
| hb_map (hb_second)
| hb_apply ([&] (const ChainRuleSet &_)
{ _.closure_lookups (c, lookup_context); })
;
}
@ -2779,24 +2835,23 @@ struct ChainContextFormat2
out->coverage.serialize_subset (c, coverage, this);
hb_map_t backtrack_klass_map;
out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, &backtrack_klass_map);
if (unlikely (!c->serializer->check_success (!backtrack_klass_map.in_error ())))
return_trace (false);
// subset inputClassDef based on glyphs survived in Coverage subsetting
hb_map_t input_klass_map;
out->inputClassDef.serialize_subset (c, inputClassDef, this, &input_klass_map);
if (unlikely (!c->serializer->check_success (!input_klass_map.in_error ())))
return_trace (false);
hb_map_t lookahead_klass_map;
out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, &backtrack_klass_map);
// TODO: subset inputClassDef based on glyphs survived in Coverage subsetting
out->inputClassDef.serialize_subset (c, inputClassDef, this, &input_klass_map);
out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, &lookahead_klass_map);
if (unlikely (!c->serializer->check_success (!lookahead_klass_map.in_error ())))
if (unlikely (!c->serializer->propagate_error (backtrack_klass_map,
input_klass_map,
lookahead_klass_map)))
return_trace (false);
unsigned non_zero_index = 0, index = 0;
int non_zero_index = -1, index = 0;
bool ret = true;
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
auto last_non_zero = c->serializer->snapshot ();
for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet)
| hb_filter (input_klass_map, hb_first)
| hb_map (hb_second))
@ -2812,19 +2867,20 @@ struct ChainContextFormat2
&backtrack_klass_map,
&input_klass_map,
&lookahead_klass_map))
{
last_non_zero = c->serializer->snapshot ();
non_zero_index = index;
}
index++;
}
if (!ret) return_trace (ret);
//prune empty trailing ruleSets
--index;
while (index > non_zero_index)
{
out->ruleSet.pop ();
index--;
// prune empty trailing ruleSets
if (index > non_zero_index) {
c->serializer->revert (last_non_zero);
out->ruleSet.len = non_zero_index + 1;
}
return_trace (bool (out->ruleSet));
@ -2908,6 +2964,9 @@ struct ChainContextFormat3
void closure_lookups (hb_closure_lookups_context_t *c) const
{
if (!intersects (c->glyphs))
return;
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
@ -2986,13 +3045,16 @@ struct ChainContextFormat3
TRACE_SERIALIZE (this);
auto *out = c->serializer->start_embed<OffsetArrayOf<Coverage>> ();
if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) return_trace (false);
if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size)))
return_trace (false);
+ it
| hb_apply (subset_offset_array (c, *out, base))
;
for (auto& offset : it) {
auto *o = out->serialize_append (c->serializer);
if (unlikely (!o) || !o->serialize_subset (c, offset, base))
return_trace (false);
}
return_trace (out->len);
return_trace (true);
}
bool subset (hb_subset_context_t *c) const
@ -3113,6 +3175,24 @@ struct ExtensionFormat1
extensionLookupType != T::SubTable::Extension);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
out->format = format;
out->extensionLookupType = extensionLookupType;
const auto& src_offset =
reinterpret_cast<const LOffsetTo<typename T::SubTable> &> (extensionOffset);
auto& dest_offset =
reinterpret_cast<LOffsetTo<typename T::SubTable> &> (out->extensionOffset);
return_trace (dest_offset.serialize_subset (c, src_offset, this, get_type ()));
}
protected:
HBUINT16 format; /* Format identifier. Set to 1. */
HBUINT16 extensionLookupType; /* Lookup type of subtable referenced
@ -3143,6 +3223,18 @@ struct Extension
}
}
// Specialization of dispatch for subset. dispatch() normally just
// dispatches to the sub table this points too, but for subset
// we need to run subset on this subtable too.
template <typename ...Ts>
typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const
{
switch (u.format) {
case 1: return u.format1.subset (c);
default: return c->default_return_value ();
}
}
template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
@ -3320,20 +3412,34 @@ struct GSUBGPOS
return_trace (true);
}
void closure_features (const hb_map_t *lookup_indexes, /* IN */
hb_set_t *feature_indexes /* OUT */) const
void prune_features (const hb_map_t *lookup_indices, /* IN */
hb_set_t *feature_indices /* IN/OUT */) const
{
unsigned int feature_count = hb_min (get_feature_count (), (unsigned) HB_MAX_FEATURES);
for (unsigned i = 0; i < feature_count; i++)
#ifndef HB_NO_VAR
// This is the set of feature indices which have alternate versions defined
// if the FeatureVariation's table and the alternate version(s) intersect the
// set of lookup indices.
hb_set_t alternate_feature_indices;
if (version.to_int () >= 0x00010001u)
(this+featureVars).closure_features (lookup_indices, &alternate_feature_indices);
if (unlikely (alternate_feature_indices.in_error())) {
feature_indices->successful = false;
return;
}
#endif
for (unsigned i : feature_indices->iter())
{
const Feature& f = get_feature (i);
if ((!f.featureParams.is_null ()) || f.intersects_lookup_indexes (lookup_indexes))
feature_indexes->add (i);
}
if (f.featureParams.is_null ()
&& !f.intersects_lookup_indexes (lookup_indices)
#ifndef HB_NO_VAR
if (version.to_int () >= 0x00010001u)
(this+featureVars).closure_features (lookup_indexes, feature_indexes);
&& !alternate_feature_indices.has (i)
#endif
)
feature_indices->del (i);
}
}
unsigned int get_size () const
@ -3378,7 +3484,11 @@ struct GSUBGPOS
this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t));
if (unlikely (!this->accels))
{
this->lookup_count = 0;
this->table.destroy ();
this->table = hb_blob_get_empty ();
}
for (unsigned int i = 0; i < this->lookup_count; i++)
this->accels[i].init (table->get_lookup (i));

View File

@ -76,7 +76,7 @@
* Tests whether a face includes any kerning data in the 'kern' table.
* Does NOT test for kerning lookups in the GPOS table.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
**/
bool
@ -92,7 +92,7 @@ hb_ot_layout_has_kerning (hb_face_t *face)
* Tests whether a face includes any state-machine kerning in the 'kern' table.
* Does NOT examine the GPOS table.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
**/
bool
@ -112,7 +112,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face)
*
* Does NOT examine the GPOS table.
*
* Return value: true is data found, false otherwise
* Return value: %true is data found, %false otherwise
*
**/
bool
@ -268,7 +268,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font,
*
* Tests whether a face has any glyph classes defined in its GDEF table.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
**/
hb_bool_t
@ -322,7 +322,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
* @face: The #hb_face_t to work on
* @glyph: The #hb_codepoint_t code point to query
* @start_offset: offset of the first attachment point to retrieve
* @point_count: (inout) (allow-none): Input = the maximum number of attachment points to return;
* @point_count: (inout) (optional): Input = the maximum number of attachment points to return;
* Output = the actual number of attachment points returned (may be zero)
* @point_array: (out) (array length=point_count): The array of attachment points found for the query
*
@ -350,7 +350,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face,
* @direction: The #hb_direction_t text direction to use
* @glyph: The #hb_codepoint_t code point to query
* @start_offset: offset of the first caret position to retrieve
* @caret_count: (inout) (allow-none): Input = the maximum number of caret positions to return;
* @caret_count: (inout) (optional): Input = the maximum number of caret positions to return;
* Output = the actual number of caret positions returned (may be zero)
* @caret_array: (out) (array length=caret_count): The array of caret positions found for the query
*
@ -410,9 +410,9 @@ get_gsubgpos_table (hb_face_t *face,
/**
* hb_ot_layout_table_get_script_tags:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @start_offset: offset of the first script tag to retrieve
* @script_count: (inout) (allow-none): Input = the maximum number of script tags to return;
* @script_count: (inout) (optional): Input = the maximum number of script tags to return;
* Output = the actual number of script tags returned (may be zero)
* @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query
*
@ -437,14 +437,14 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face,
/**
* hb_ot_layout_table_find_script:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_tag: #hb_tag_t of the script tag requested
* @script_index: (out): The index of the requested script tag
*
* Fetches the index if a given script tag in the specified face's GSUB table
* or GPOS table.
*
* Return value: true if the script is found, false otherwise
* Return value: %true if the script is found, %false otherwise
*
**/
hb_bool_t
@ -481,7 +481,7 @@ hb_ot_layout_table_find_script (hb_face_t *face,
/**
* hb_ot_layout_table_choose_script:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_tags: Array of #hb_tag_t script tags
* @script_index: (out): The index of the requested script tag
* @chosen_script: (out): #hb_tag_t of the script tag requested
@ -504,11 +504,22 @@ hb_ot_layout_table_choose_script (hb_face_t *face,
/**
* hb_ot_layout_table_select_script:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_count: Number of script tags in the array
* @script_tags: Array of #hb_tag_t script tags
* @script_index: (out): The index of the requested script
* @chosen_script: (out): #hb_tag_t of the requested script
* @script_index: (out) (optional): The index of the requested script
* @chosen_script: (out) (optional): #hb_tag_t of the requested script
*
* Selects an OpenType script for @table_tag from the @script_tags array.
*
* If the table does not have any of the requested scripts, then `DFLT`,
* `dflt`, and `latn` tags are tried in that order. If the table still does not
* have any of these scripts, @script_index and @chosen_script are set to
* #HB_OT_LAYOUT_NO_SCRIPT_INDEX.
*
* Return value:
* %true if one of the requested scripts is selected, %false if a fallback
* script is selected or if no scripts are selected.
*
* Since: 2.0.0
**/
@ -566,9 +577,9 @@ hb_ot_layout_table_select_script (hb_face_t *face,
/**
* hb_ot_layout_table_get_feature_tags:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @start_offset: offset of the first feature tag to retrieve
* @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
* @feature_count: (inout) (optional): Input = the maximum number of feature tags to return;
* Output = the actual number of feature tags returned (may be zero)
* @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table
*
@ -591,14 +602,14 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face,
/**
* hb_ot_layout_table_find_feature:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @feature_tag: The #hb_tag_t og the requested feature tag
* @feature_index: (out): The index of the requested feature
*
* Fetches the index for a given feature tag in the specified face's GSUB table
* or GPOS table.
*
* Return value: true if the feature is found, false otherwise
* Return value: %true if the feature is found, %false otherwise
**/
bool
hb_ot_layout_table_find_feature (hb_face_t *face,
@ -626,10 +637,10 @@ hb_ot_layout_table_find_feature (hb_face_t *face,
/**
* hb_ot_layout_script_get_language_tags:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @start_offset: offset of the first language tag to retrieve
* @language_count: (inout) (allow-none): Input = the maximum number of language tags to return;
* @language_count: (inout) (optional): Input = the maximum number of language tags to return;
* Output = the actual number of language tags returned (may be zero)
* @language_tags: (out) (array length=language_count): Array of language tags found in the table
*
@ -655,7 +666,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
/**
* hb_ot_layout_script_find_language:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_tag: The #hb_tag_t of the requested language
* @language_index: The index of the requested language
@ -663,7 +674,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
* Fetches the index of a given language tag in the specified face's GSUB table
* or GPOS table, underneath the specified script tag.
*
* Return value: true if the language tag is found, false otherwise
* Return value: %true if the language tag is found, %false otherwise
*
* Since: ??
* Deprecated: ??
@ -688,7 +699,7 @@ hb_ot_layout_script_find_language (hb_face_t *face,
/**
* hb_ot_layout_script_select_language:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_count: The number of languages in the specified script
* @language_tags: The array of language tags
@ -697,7 +708,7 @@ hb_ot_layout_script_find_language (hb_face_t *face,
* Fetches the index of a given language tag in the specified face's GSUB table
* or GPOS table, underneath the specified script index.
*
* Return value: true if the language tag is found, false otherwise
* Return value: %true if the language tag is found, %false otherwise
*
* Since: 2.0.0
**/
@ -731,7 +742,7 @@ hb_ot_layout_script_select_language (hb_face_t *face,
/**
* hb_ot_layout_language_get_required_feature_index:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_index: The index of the requested language tag
* @feature_index: (out): The index of the requested feature
@ -739,7 +750,7 @@ hb_ot_layout_script_select_language (hb_face_t *face,
* Fetches the index of a requested feature in the given face's GSUB or GPOS table,
* underneath the specified script and language.
*
* Return value: true if the feature is found, false otherwise
* Return value: %true if the feature is found, %false otherwise
*
**/
hb_bool_t
@ -761,7 +772,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
/**
* hb_ot_layout_language_get_required_feature:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_index: The index of the requested language tag
* @feature_index: (out): The index of the requested feature
@ -770,7 +781,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
* Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
* underneath the specified script and language.
*
* Return value: true if the feature is found, false otherwise
* Return value: %true if the feature is found, %false otherwise
*
* Since: 0.9.30
**/
@ -796,11 +807,11 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face,
/**
* hb_ot_layout_language_get_feature_indexes:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_index: The index of the requested language tag
* @start_offset: offset of the first feature tag to retrieve
* @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
* @feature_count: (inout) (optional): Input = the maximum number of feature tags to return;
* Output: the actual number of feature tags returned (may be zero)
* @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query
*
@ -827,11 +838,11 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
/**
* hb_ot_layout_language_get_feature_tags:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_index: The index of the requested language tag
* @start_offset: offset of the first feature tag to retrieve
* @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
* @feature_count: (inout) (optional): Input = the maximum number of feature tags to return;
* Output = the actual number of feature tags returned (may be zero)
* @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query
*
@ -868,7 +879,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
/**
* hb_ot_layout_language_find_feature:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @script_index: The index of the requested script tag
* @language_index: The index of the requested language tag
* @feature_tag: #hb_tag_t of the feature tag requested
@ -877,7 +888,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
* Fetches the index of a given feature tag in the specified face's GSUB table
* or GPOS table, underneath the specified script and language.
*
* Return value: true if the feature is found, false otherwise
* Return value: %true if the feature is found, %false otherwise
*
**/
hb_bool_t
@ -910,10 +921,10 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
/**
* hb_ot_layout_feature_get_lookups:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @feature_index: The index of the requested feature
* @start_offset: offset of the first lookup to retrieve
* @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return;
* @lookup_count: (inout) (optional): Input = the maximum number of lookups to return;
* Output = the actual number of lookups returned (may be zero)
* @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query
*
@ -944,7 +955,7 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
/**
* hb_ot_layout_table_get_lookup_count:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
*
* Fetches the total number of lookups enumerated in the specified
* face's GSUB table or GPOS table.
@ -1101,7 +1112,7 @@ script_collect_features (hb_collect_features_context_t *c,
/**
* hb_ot_layout_collect_features:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @scripts: The array of scripts to collect features for
* @languages: The array of languages to collect features for
* @features: The array of features to collect
@ -1152,7 +1163,7 @@ hb_ot_layout_collect_features (hb_face_t *face,
/**
* hb_ot_layout_collect_lookups:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @scripts: The array of scripts to collect lookups for
* @languages: The array of languages to collect lookups for
* @features: The array of features to collect lookups for
@ -1191,12 +1202,12 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
/**
* hb_ot_layout_lookup_collect_glyphs:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @lookup_index: The index of the feature lookup to query
* @glyphs_before: (out): Array of glyphs preceding the substitution range
* @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup
* @glyphs_after: (out): Array of glyphs following the substitution range
* @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
* @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup
*
* Fetches a list of all glyphs affected by the specified lookup in the
* specified face's GSUB table or GPOS table.
@ -1243,9 +1254,9 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
/**
* hb_ot_layout_table_find_feature_variations:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @coords: The variation coordinates to query
* @num_coords: The number of variation coorinates
* @num_coords: The number of variation coordinates
* @variations_index: (out): The array of feature variations found for the query
*
* Fetches a list of feature variations in the specified face's GSUB table
@ -1268,11 +1279,11 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face,
/**
* hb_ot_layout_feature_with_variations_get_lookups:
* @face: #hb_face_t to work upon
* @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @feature_index: The index of the feature to query
* @variations_index: The index of the feature variation to query
* @start_offset: offset of the first lookup to retrieve
* @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return;
* @lookup_count: (inout) (optional): Input = the maximum number of lookups to return;
* Output = the actual number of lookups returned (may be zero)
* @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query
*
@ -1310,7 +1321,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
*
* Tests whether the specified face includes any GSUB substitutions.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
**/
hb_bool_t
@ -1331,7 +1342,7 @@ hb_ot_layout_has_substitution (hb_face_t *face)
* Tests whether a specified lookup in the specified face would
* trigger a substitution on the given glyph sequence.
*
* Return value: true if a substitution would be triggered, false otherwise
* Return value: %true if a substitution would be triggered, %false otherwise
*
* Since: 0.9.7
**/
@ -1488,7 +1499,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
* hb_ot_layout_has_positioning:
* @face: #hb_face_t to work upon
*
* Return value: true if the face has GPOS data, false otherwise
* Tests whether the specified face includes any GPOS positioning.
*
* Return value: %true if the face has GPOS data, %false otherwise
*
**/
hb_bool_t
@ -1561,7 +1574,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
* For more information on this distinction, see the [`size` feature documentation](
* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size).
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.10
**/
@ -1610,22 +1623,22 @@ hb_ot_layout_get_size_params (hb_face_t *face,
* @face: #hb_face_t to work upon
* @table_tag: table tag to query, "GSUB" or "GPOS".
* @feature_index: index of feature to query.
* @label_id: (out) (allow-none): The name table name ID that specifies a string
* @label_id: (out) (optional): The name table name ID that specifies a string
* for a user-interface label for this feature. (May be NULL.)
* @tooltip_id: (out) (allow-none): The name table name ID that specifies a string
* @tooltip_id: (out) (optional): The name table name ID that specifies a string
* that an application can use for tooltip text for this
* feature. (May be NULL.)
* @sample_id: (out) (allow-none): The name table name ID that specifies sample text
* @sample_id: (out) (optional): The name table name ID that specifies sample text
* that illustrates the effect of this feature. (May be NULL.)
* @num_named_parameters: (out) (allow-none): Number of named parameters. (May be zero.)
* @first_param_id: (out) (allow-none): The first name table name ID used to specify
* @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.)
* @first_param_id: (out) (optional): The first name table name ID used to specify
* strings for user-interface labels for the feature
* parameters. (Must be zero if numParameters is zero.)
*
* Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or
* "Character Variant" ('cvXX') features.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 2.0.0
**/
@ -1685,7 +1698,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face,
* @table_tag: table tag to query, "GSUB" or "GPOS".
* @feature_index: index of feature to query.
* @start_offset: offset of the first character to retrieve
* @char_count: (inout) (allow-none): Input = the maximum number of characters to return;
* @char_count: (inout) (optional): Input = the maximum number of characters to return;
* Output = the actual number of characters returned (may be zero)
* @characters: (out caller-allocates) (array length=char_count): A buffer pointer.
* The Unicode codepoints of the characters for which this feature provides
@ -1769,7 +1782,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
if (applied)
ret = true;
else
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
return ret;
}
@ -1881,7 +1894,7 @@ void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, h
GSUBProxy proxy (font->face);
if (!buffer->message (font, "start table GSUB")) return;
apply (proxy, plan, font, buffer);
(void)buffer->message (font, "end table GSUB");
(void) buffer->message (font, "end table GSUB");
}
void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
@ -1889,7 +1902,7 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_
GPOSProxy proxy (font->face);
if (!buffer->message (font, "start table GPOS")) return;
apply (proxy, plan, font, buffer);
(void)buffer->message (font, "end table GPOS");
(void) buffer->message (font, "end table GPOS");
}
void
@ -1907,7 +1920,7 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
* @baseline_tag: a baseline tag
* @direction: text direction.
* @script_tag: script tag.
* @language_tag: language tag.
* @language_tag: language tag, currently unused.
* @coord: (out): baseline value if found.
*
* Fetches a baseline value from the face.
@ -1964,7 +1977,7 @@ struct hb_get_glyph_alternates_dispatch_t :
* @lookup_index: index of the feature lookup to query.
* @glyph: a glyph id.
* @start_offset: starting offset.
* @alternate_count: (inout) (allow-none): Input = the maximum number of alternate glyphs to return;
* @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return;
* Output = the actual number of alternate glyphs returned (may be zero).
* @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer.
* Alternate glyphs associated with the glyph id.

View File

@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif
@ -38,10 +38,35 @@
HB_BEGIN_DECLS
/**
* HB_OT_TAG_BASE:
*
* OpenType [Baseline Table](https://docs.microsoft.com/en-us/typography/opentype/spec/base).
*/
#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
/**
* HB_OT_TAG_GDEF:
*
* OpenType [Glyph Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef).
*/
#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
/**
* HB_OT_TAG_GSUB:
*
* OpenType [Glyph Substitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub).
*/
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
/**
* HB_OT_TAG_GPOS:
*
* OpenType [Glyph Positioning Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos).
*/
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
/**
* HB_OT_TAG_JSTF:
*
* OpenType [Justification Table](https://docs.microsoft.com/en-us/typography/opentype/spec/jstf).
*/
#define HB_OT_TAG_JSTF HB_TAG('J','S','T','F')
@ -49,18 +74,34 @@ HB_BEGIN_DECLS
* Script & Language tags.
*/
/**
* HB_OT_TAG_DEFAULT_SCRIPT:
*
* OpenType script tag, `DFLT`, for features that are not script-specific.
*
*/
#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T')
/**
* HB_OT_TAG_DEFAULT_LANGUAGE:
*
* OpenType language tag, `dflt`. Not a valid language tag, but some fonts
* mistakenly use it.
*/
#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't')
/**
* HB_OT_MAX_TAGS_PER_SCRIPT:
*
* Maximum number of OpenType tags that can correspond to a give #hb_script_t.
*
* Since: 2.0.0
**/
#define HB_OT_MAX_TAGS_PER_SCRIPT 3u
/**
* HB_OT_MAX_TAGS_PER_LANGUAGE:
*
* Maximum number of OpenType tags that can correspond to a give #hb_language_t.
*
* Since: 2.0.0
**/
#define HB_OT_MAX_TAGS_PER_LANGUAGE 3u
@ -144,9 +185,29 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
* GSUB/GPOS feature query and enumeration interface
*/
/**
* HB_OT_LAYOUT_NO_SCRIPT_INDEX:
*
* Special value for script index indicating unsupported script.
*/
#define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu
/**
* HB_OT_LAYOUT_NO_FEATURE_INDEX:
*
* Special value for feature index indicating unsupported feature.
*/
#define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu
/**
* HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX:
*
* Special value for language index indicating default or unsupported language.
*/
#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu
/**
* HB_OT_LAYOUT_NO_VARIATIONS_INDEX:
*
* Special value for variations index indicating unsupported variation.
*/
#define HB_OT_LAYOUT_NO_VARIATIONS_INDEX 0xFFFFFFFFu
HB_EXTERN unsigned int
@ -433,7 +494,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face,
* @HB_OT_LAYOUT_BASELINE_TAG_MATH: The baseline about which mathematical characters are centered.
* In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered.
*
* Baseline tags from https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags
* Baseline tags from [Baseline Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags) registry.
*
* Since: 2.6.0
*/
@ -446,6 +507,7 @@ typedef enum {
HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT = HB_TAG ('i','d','t','p'),
HB_OT_LAYOUT_BASELINE_TAG_MATH = HB_TAG ('m','a','t','h'),
/*< private >*/
_HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_ot_layout_baseline_tag_t;

View File

@ -315,12 +315,13 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info)
}
static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info);
static inline bool
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
{
return (info->unicode_props() & UPROPS_MASK_IGNORABLE) &&
!_hb_glyph_info_ligated (info);
!_hb_glyph_info_substituted (info);
}
static inline bool
_hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info)

View File

@ -140,12 +140,12 @@ struct hb_ot_map_t
void get_stage_lookups (unsigned int table_index, unsigned int stage,
const struct lookup_map_t **plookups, unsigned int *lookup_count) const
{
if (unlikely (stage == UINT_MAX)) {
if (unlikely (stage > stages[table_index].length))
{
*plookups = nullptr;
*lookup_count = 0;
return;
}
assert (stage <= stages[table_index].length);
unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0;
unsigned int end = stage < stages[table_index].length ? stages[table_index][stage].last_lookup : lookups[table_index].length;
*plookups = end == start ? nullptr : &lookups[table_index][start];

View File

@ -56,7 +56,7 @@
*
* Tests whether a face has a `MATH` table.
*
* Return value: true if the table is found, false otherwise
* Return value: %true if the table is found, %false otherwise
*
* Since: 1.3.3
**/
@ -142,7 +142,7 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
*
* Tests whether the given glyph index is an extended shape in the face.
*
* Return value: true if the glyph is an extended shape, false otherwise
* Return value: %true if the glyph is an extended shape, %false otherwise
*
* Since: 1.3.3
**/

View File

@ -24,7 +24,7 @@
* Igalia Author(s): Frédéric Wang
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif
@ -40,18 +40,89 @@ HB_BEGIN_DECLS
* MATH
*/
/**
* HB_OT_TAG_MATH:
*
* OpenType [Mathematical Typesetting Table](https://docs.microsoft.com/en-us/typography/opentype/spec/math).
*
* Since: 1.3.3
*/
#define HB_OT_TAG_MATH HB_TAG('M','A','T','H')
/* Use with hb_buffer_set_script() for math shaping. */
/**
* HB_OT_MATH_SCRIPT:
*
* OpenType script tag for math shaping, for use with
* Use with hb_buffer_set_script().
*
* Since: 1.3.3
*/
#define HB_OT_MATH_SCRIPT HB_TAG('m','a','t','h')
/* Types */
/**
* hb_ot_math_constant_t:
* @HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN: scriptPercentScaleDown
* @HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN: scriptScriptPercentScaleDown
* @HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT: delimitedSubFormulaMinHeight
* @HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT: displayOperatorMinHeight
* @HB_OT_MATH_CONSTANT_MATH_LEADING: mathLeading
* @HB_OT_MATH_CONSTANT_AXIS_HEIGHT: axisHeight
* @HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT: accentBaseHeight
* @HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT: flattenedAccentBaseHeight
* @HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN: subscriptShiftDown
* @HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX: subscriptTopMax
* @HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN: subscriptBaselineDropMin
* @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP: superscriptShiftUp
* @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED: superscriptShiftUpCramped
* @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN: superscriptBottomMin
* @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX: superscriptBaselineDropMax
* @HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN: subSuperscriptGapMin
* @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT: superscriptBottomMaxWithSubscript
* @HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT: spaceAfterScript
* @HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN: upperLimitGapMin
* @HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN: upperLimitBaselineRiseMin
* @HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN: lowerLimitGapMin
* @HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN: lowerLimitBaselineDropMin
* @HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP: stackTopShiftUp
* @HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP: stackTopDisplayStyleShiftUp
* @HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN: stackBottomShiftDown
* @HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN: stackBottomDisplayStyleShiftDown
* @HB_OT_MATH_CONSTANT_STACK_GAP_MIN: stackGapMin
* @HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN: stackDisplayStyleGapMin
* @HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP: stretchStackTopShiftUp
* @HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN: stretchStackBottomShiftDown
* @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN: stretchStackGapAboveMin
* @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN: stretchStackGapBelowMin
* @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP: fractionNumeratorShiftUp
* @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP: fractionNumeratorDisplayStyleShiftUp
* @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN: fractionDenominatorShiftDown
* @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN: fractionDenominatorDisplayStyleShiftDown
* @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN: fractionNumeratorGapMin
* @HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN: fractionNumDisplayStyleGapMin
* @HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS: fractionRuleThickness
* @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN: fractionDenominatorGapMin
* @HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN: fractionDenomDisplayStyleGapMin
* @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP: skewedFractionHorizontalGap
* @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP: skewedFractionVerticalGap
* @HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP: overbarVerticalGap
* @HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS: overbarRuleThickness
* @HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER: overbarExtraAscender
* @HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP: underbarVerticalGap
* @HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS: underbarRuleThickness
* @HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER: underbarExtraDescender
* @HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP: radicalVerticalGap
* @HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP: radicalDisplayStyleVerticalGap
* @HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS: radicalRuleThickness
* @HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER: radicalExtraAscender
* @HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE: radicalKernBeforeDegree
* @HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE: radicalKernAfterDegree
* @HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT: radicalDegreeBottomRaisePercent
*
* The 'MATH' table constants specified at
* https://docs.microsoft.com/en-us/typography/opentype/spec/math
* The 'MATH' table constants, refer to
* [OpenType documentation](https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table)
* For more explanations.
*
* Since: 1.3.3
*/
@ -116,6 +187,10 @@ typedef enum {
/**
* hb_ot_math_kern_t:
* @HB_OT_MATH_KERN_TOP_RIGHT: The top right corner of the glyph.
* @HB_OT_MATH_KERN_TOP_LEFT: The top left corner of the glyph.
* @HB_OT_MATH_KERN_BOTTOM_RIGHT: The bottom right corner of the glyph.
* @HB_OT_MATH_KERN_BOTTOM_LEFT: The bottom left corner of the glyph.
*
* The math kerning-table types defined for the four corners
* of a glyph.
@ -145,6 +220,8 @@ typedef struct hb_ot_math_glyph_variant_t {
/**
* hb_ot_math_glyph_part_flags_t:
* @HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER: This is an extender glyph part that
* can be repeated to reach the desired length.
*
* Flags for math glyph parts.
*

View File

@ -41,9 +41,11 @@
* hb_ot_meta_get_entry_tags:
* @face: a face object
* @start_offset: iteration's start offset
* @entries_count:(inout) (allow-none): buffer size as input, filled size as output
* @entries_count:(inout) (optional): buffer size as input, filled size as output
* @entries: (out caller-allocates) (array length=entries_count): entries tags buffer
*
* Fetches all available feature types.
*
* Return value: Number of all available feature types.
*
* Since: 2.6.0

View File

@ -22,7 +22,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif
@ -54,6 +54,7 @@ typedef enum {
HB_OT_META_TAG_DESIGN_LANGUAGES = HB_TAG ('d','l','n','g'),
HB_OT_META_TAG_SUPPORTED_LANGUAGES = HB_TAG ('s','l','n','g'),
/*< private >*/
_HB_OT_META_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_ot_meta_tag_t;

View File

@ -33,6 +33,15 @@
#include "hb-ot-face.hh"
/**
* SECTION:hb-ot-metrics
* @title: hb-ot-metrics
* @short_description: OpenType Metrics
* @include: hb-ot.h
*
* Functions for fetching metrics from fonts.
**/
static float
_fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag)
{
@ -110,11 +119,11 @@ _get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_t metrics_tag)
/**
* hb_ot_metrics_get_position:
* @font: a #hb_font_t object.
* @font: an #hb_font_t object.
* @metrics_tag: tag of metrics value you like to fetch.
* @position: (out) (optional): result of metrics value from the font.
*
* It fetches metrics value corresponding to a given tag from a font.
* Fetches metrics value corresponding to @metrics_tag from @font.
*
* Returns: Whether found the requested metrics in the font.
* Since: 2.6.0
@ -184,10 +193,13 @@ hb_ot_metrics_get_position (hb_font_t *font,
#ifndef HB_NO_VAR
/**
* hb_ot_metrics_get_variation:
* @font:
* @metrics_tag:
* @font: an #hb_font_t object.
* @metrics_tag: tag of metrics value you like to fetch.
*
* Returns:
* Fetches metrics value corresponding to @metrics_tag from @font with the
* current font variation settings applied.
*
* Returns: The requested metric value.
*
* Since: 2.6.0
**/
@ -199,10 +211,13 @@ hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
/**
* hb_ot_metrics_get_x_variation:
* @font:
* @metrics_tag:
* @font: an #hb_font_t object.
* @metrics_tag: tag of metrics value you like to fetch.
*
* Returns:
* Fetches horizontal metrics value corresponding to @metrics_tag from @font
* with the current font variation settings applied.
*
* Returns: The requested metric value.
*
* Since: 2.6.0
**/
@ -214,10 +229,13 @@ hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
/**
* hb_ot_metrics_get_y_variation:
* @font:
* @metrics_tag:
* @font: an #hb_font_t object.
* @metrics_tag: tag of metrics value you like to fetch.
*
* Returns:
* Fetches vertical metrics value corresponding to @metrics_tag from @font with
* the current font variation settings applied.
*
* Returns: The requested metric value.
*
* Since: 2.6.0
**/

View File

@ -22,7 +22,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif
@ -66,7 +66,8 @@ HB_BEGIN_DECLS
* @HB_OT_METRICS_TAG_UNDERLINE_SIZE: underline size.
* @HB_OT_METRICS_TAG_UNDERLINE_OFFSET: underline offset.
*
* From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags
* Metric tags corresponding to [MVAR Value
* Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags)
*
* Since: 2.6.0
**/
@ -100,6 +101,7 @@ typedef enum {
HB_OT_METRICS_TAG_UNDERLINE_SIZE = HB_TAG ('u','n','d','s'),
HB_OT_METRICS_TAG_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o'),
/*< private >*/
_HB_OT_METRICS_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_ot_metrics_tag_t;

View File

@ -46,7 +46,7 @@
/**
* hb_ot_name_list_names:
* @face: font face.
* @num_entries: (out) (allow-none): number of returned entries.
* @num_entries: (out) (optional): number of returned entries.
*
* Enumerates all available name IDs and language combinations. Returned
* array is owned by the @face and should not be modified. It can be
@ -150,7 +150,7 @@ hb_ot_name_get_utf (hb_face_t *face,
* @face: font face.
* @name_id: OpenType name identifier to fetch.
* @language: language to fetch the name for.
* @text_size: (inout) (allow-none): input size of @text buffer, and output size of
* @text_size: (inout) (optional): input size of @text buffer, and output size of
* text written to buffer.
* @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into.
*
@ -177,7 +177,7 @@ hb_ot_name_get_utf8 (hb_face_t *face,
* @face: font face.
* @name_id: OpenType name identifier to fetch.
* @language: language to fetch the name for.
* @text_size: (inout) (allow-none): input size of @text buffer, and output size of
* @text_size: (inout) (optional): input size of @text buffer, and output size of
* text written to buffer.
* @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into.
*
@ -203,7 +203,7 @@ hb_ot_name_get_utf16 (hb_face_t *face,
* @face: font face.
* @name_id: OpenType name identifier to fetch.
* @language: language to fetch the name for.
* @text_size: (inout) (allow-none): input size of @text buffer, and output size of
* @text_size: (inout) (optional): input size of @text buffer, and output size of
* text written to buffer.
* @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into.
*

View File

@ -22,7 +22,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif
@ -88,8 +88,7 @@ typedef unsigned int hb_ot_name_id_t;
*
* Since: 2.1.0
**/
typedef struct hb_ot_name_entry_t
{
typedef struct hb_ot_name_entry_t {
hb_ot_name_id_t name_id;
/*< private >*/
hb_var_int_t var;

View File

@ -183,8 +183,7 @@ struct OS2
cmap.collect_mapping (&unicodes, &unicode_glyphid_map);
cmap.fini ();
if (c->plan->unicodes->is_empty ()) unicodes.clear ();
else hb_set_set (&unicodes, c->plan->unicodes);
hb_set_set (&unicodes, c->plan->unicodes);
+ unicode_glyphid_map.iter ()
| hb_filter (c->plan->glyphs_requested, hb_second)

View File

@ -87,7 +87,6 @@ struct post
if (unlikely (!post_prime)) return_trace (false);
serialize (c->serializer);
if (c->serializer->in_error () || c->serializer->ran_out_of_room) return_trace (false);
return_trace (true);
}

View File

@ -142,7 +142,7 @@
OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \
) \
OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \
/* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */
/* static_assert_expr (len(FromGlyphs) == len(ToGlyphs)) */
#define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \
OT_SUBLOOKUP(Name, 1, \
@ -151,7 +151,7 @@
OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \
) \
OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \
/* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */
/* static_assert_expr (len(FirstGlyphs) == len(LigatureSetOffsets)) */
#define OT_LIGATURE_SET(Name, LigatureSetOffsets) \
OT_UARRAY(Name, OT_LIST(LigatureSetOffsets))

View File

@ -33,7 +33,7 @@
/* buffer var allocations */
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
#define arabic_shaping_action() complex_var_u8_auxiliary() /* arabic shaping action */
#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0

View File

@ -119,7 +119,7 @@ data_destroy_hangul (void *data)
#define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu))
/* buffer var allocations */
#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
#define hangul_shaping_feature() complex_var_u8_auxiliary() /* hangul jamo shaping feature */
static bool
is_zero_width_char (hb_font_t *font,
@ -205,7 +205,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
{
/* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
buffer->next_glyph ();
if (unlikely (!buffer->next_glyph ())) break;
if (!is_zero_width_char (font, u))
{
buffer->merge_out_clusters (start, end + 1);
@ -218,23 +218,25 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
else
{
/* No valid syllable as base for tone mark; try to insert dotted circle. */
if (!(buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) &&
font->has_glyph (0x25CCu))
if (!(buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) &&
font->has_glyph (0x25CCu))
{
hb_codepoint_t chars[2];
if (!is_zero_width_char (font, u)) {
if (!is_zero_width_char (font, u))
{
chars[0] = u;
chars[1] = 0x25CCu;
} else {
} else
{
chars[0] = 0x25CCu;
chars[1] = u;
}
buffer->replace_glyphs (1, 2, chars);
(void) buffer->replace_glyphs (1, 2, chars);
}
else
{
/* No dotted circle available in the font; just leave tone mark untouched. */
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
}
start = end = buffer->out_len;
@ -271,9 +273,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex;
if (font->has_glyph (s))
{
buffer->replace_glyphs (t ? 3 : 2, 1, &s);
if (unlikely (!buffer->successful))
return;
(void) buffer->replace_glyphs (t ? 3 : 2, 1, &s);
end = start + 1;
continue;
}
@ -285,17 +285,19 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
* Set jamo features on the individual glyphs, and advance past them.
*/
buffer->cur().hangul_shaping_feature() = LJMO;
buffer->next_glyph ();
(void) buffer->next_glyph ();
buffer->cur().hangul_shaping_feature() = VJMO;
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (t)
{
buffer->cur().hangul_shaping_feature() = TJMO;
buffer->next_glyph ();
(void) buffer->next_glyph ();
end = start + 3;
}
else
end = start + 2;
if (unlikely (!buffer->successful))
break;
if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
buffer->merge_out_clusters (start, end);
continue;
@ -321,9 +323,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_codepoint_t new_s = s + new_tindex;
if (font->has_glyph (new_s))
{
buffer->replace_glyphs (2, 1, &new_s);
if (unlikely (!buffer->successful))
return;
(void) buffer->replace_glyphs (2, 1, &new_s);
end = start + 1;
continue;
}
@ -347,19 +347,18 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
(!tindex || font->has_glyph (decomposed[2])))
{
unsigned int s_len = tindex ? 3 : 2;
buffer->replace_glyphs (1, s_len, decomposed);
(void) buffer->replace_glyphs (1, s_len, decomposed);
/* If we decomposed an LV because of a non-combining T following,
* we want to include this T in the syllable.
*/
if (has_glyph && !tindex)
{
buffer->next_glyph ();
(void) buffer->next_glyph ();
s_len++;
}
if (unlikely (!buffer->successful))
return;
break;
/* We decomposed S: apply jamo features to the individual glyphs
* that are now in buffer->out_info.
@ -383,17 +382,15 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (has_glyph)
{
/* We didn't decompose the S, so just advance past it. */
/* We didn't decompose the S, so just advance past it and fall through. */
end = start + 1;
buffer->next_glyph ();
continue;
}
}
/* Didn't find a recognizable syllable, so we leave end <= start;
* this will prevent tone-mark reordering happening.
*/
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
buffer->swap_buffers ();
}

View File

@ -31,8 +31,37 @@
#include "hb.hh"
enum indic_syllable_type_t {
indic_consonant_syllable,
indic_vowel_syllable,
indic_standalone_cluster,
indic_symbol_cluster,
indic_broken_cluster,
indic_non_indic_cluster,
};
#line 36 "hb-ot-shape-complex-indic-machine.hh"
#line 45 "hb-ot-shape-complex-indic-machine.hh"
#define indic_syllable_machine_ex_A 10u
#define indic_syllable_machine_ex_C 1u
#define indic_syllable_machine_ex_CM 17u
#define indic_syllable_machine_ex_CS 19u
#define indic_syllable_machine_ex_DOTTEDCIRCLE 12u
#define indic_syllable_machine_ex_H 4u
#define indic_syllable_machine_ex_M 7u
#define indic_syllable_machine_ex_N 3u
#define indic_syllable_machine_ex_PLACEHOLDER 11u
#define indic_syllable_machine_ex_RS 13u
#define indic_syllable_machine_ex_Ra 16u
#define indic_syllable_machine_ex_Repha 15u
#define indic_syllable_machine_ex_SM 8u
#define indic_syllable_machine_ex_Symbol 18u
#define indic_syllable_machine_ex_V 2u
#define indic_syllable_machine_ex_ZWJ 6u
#define indic_syllable_machine_ex_ZWNJ 5u
#line 65 "hb-ot-shape-complex-indic-machine.hh"
static const unsigned char _indic_syllable_machine_trans_keys[] = {
8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
4u, 13u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u,
@ -384,18 +413,18 @@ static const int indic_syllable_machine_error = -1;
static const int indic_syllable_machine_en_main = 39;
#line 36 "hb-ot-shape-complex-indic-machine.rl"
#line 46 "hb-ot-shape-complex-indic-machine.rl"
#line 93 "hb-ot-shape-complex-indic-machine.rl"
#line 102 "hb-ot-shape-complex-indic-machine.rl"
#define found_syllable(syllable_type) \
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
@ -407,7 +436,7 @@ find_syllables_indic (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 411 "hb-ot-shape-complex-indic-machine.hh"
#line 440 "hb-ot-shape-complex-indic-machine.hh"
{
cs = indic_syllable_machine_start;
ts = 0;
@ -415,7 +444,7 @@ find_syllables_indic (hb_buffer_t *buffer)
act = 0;
}
#line 113 "hb-ot-shape-complex-indic-machine.rl"
#line 122 "hb-ot-shape-complex-indic-machine.rl"
p = 0;
@ -423,7 +452,7 @@ find_syllables_indic (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
#line 427 "hb-ot-shape-complex-indic-machine.hh"
#line 456 "hb-ot-shape-complex-indic-machine.hh"
{
int _slen;
int _trans;
@ -437,7 +466,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
#line 441 "hb-ot-shape-complex-indic-machine.hh"
#line 470 "hb-ot-shape-complex-indic-machine.hh"
}
_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@ -460,64 +489,64 @@ _eof_trans:
{te = p+1;}
break;
case 11:
#line 89 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (non_indic_cluster); }}
#line 98 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (indic_non_indic_cluster); }}
break;
case 13:
#line 84 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
#line 93 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_consonant_syllable); }}
break;
case 14:
#line 85 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (vowel_syllable); }}
#line 94 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_vowel_syllable); }}
break;
case 17:
#line 86 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (standalone_cluster); }}
#line 95 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_standalone_cluster); }}
break;
case 19:
#line 87 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (symbol_cluster); }}
#line 96 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_symbol_cluster); }}
break;
case 15:
#line 88 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
#line 97 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_broken_cluster); }}
break;
case 16:
#line 89 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (non_indic_cluster); }}
#line 98 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_non_indic_cluster); }}
break;
case 1:
#line 84 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
#line 93 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }}
break;
case 3:
#line 85 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
#line 94 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }}
break;
case 7:
#line 86 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
#line 95 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }}
break;
case 8:
#line 87 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (symbol_cluster); }}
#line 96 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }}
break;
case 4:
#line 88 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
#line 97 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_broken_cluster); }}
break;
case 6:
#line 1 "NONE"
{ switch( act ) {
case 1:
{{p = ((te))-1;} found_syllable (consonant_syllable); }
{{p = ((te))-1;} found_syllable (indic_consonant_syllable); }
break;
case 5:
{{p = ((te))-1;} found_syllable (broken_cluster); }
{{p = ((te))-1;} found_syllable (indic_broken_cluster); }
break;
case 6:
{{p = ((te))-1;} found_syllable (non_indic_cluster); }
{{p = ((te))-1;} found_syllable (indic_non_indic_cluster); }
break;
}
}
@ -525,22 +554,22 @@ _eof_trans:
case 18:
#line 1 "NONE"
{te = p+1;}
#line 84 "hb-ot-shape-complex-indic-machine.rl"
#line 93 "hb-ot-shape-complex-indic-machine.rl"
{act = 1;}
break;
case 5:
#line 1 "NONE"
{te = p+1;}
#line 88 "hb-ot-shape-complex-indic-machine.rl"
#line 97 "hb-ot-shape-complex-indic-machine.rl"
{act = 5;}
break;
case 12:
#line 1 "NONE"
{te = p+1;}
#line 89 "hb-ot-shape-complex-indic-machine.rl"
#line 98 "hb-ot-shape-complex-indic-machine.rl"
{act = 6;}
break;
#line 544 "hb-ot-shape-complex-indic-machine.hh"
#line 573 "hb-ot-shape-complex-indic-machine.hh"
}
_again:
@ -549,7 +578,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
#line 553 "hb-ot-shape-complex-indic-machine.hh"
#line 582 "hb-ot-shape-complex-indic-machine.hh"
}
if ( ++p != pe )
@ -565,7 +594,7 @@ _again:
}
#line 121 "hb-ot-shape-complex-indic-machine.rl"
#line 130 "hb-ot-shape-complex-indic-machine.rl"
}

View File

@ -82,7 +82,7 @@
#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
static const uint16_t indic_table[] = {
#define indic_offset_0x0028u 0
@ -404,7 +404,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
}; /* Table items: 1792; occupancy: 70% */
INDIC_TABLE_ELEMENT_TYPE
uint16_t
hb_indic_get_categories (hb_codepoint_t u)
{
switch (u >> 12)

View File

@ -29,6 +29,7 @@
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-indic.hh"
#include "hb-ot-shape-complex-indic-machine.hh"
#include "hb-ot-shape-complex-vowel-constraints.hh"
#include "hb-ot-layout.hh"
@ -337,19 +338,6 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
return POS_BASE_C;
}
enum indic_syllable_type_t {
indic_consonant_syllable,
indic_vowel_syllable,
indic_standalone_cluster,
indic_symbol_cluster,
indic_broken_cluster,
indic_non_indic_cluster,
};
#include "hb-ot-shape-complex-indic-machine.hh"
static void
setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
@ -764,7 +752,28 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* We could use buffer->sort() for this, if there was no special
* reordering of pre-base stuff happening later...
* We don't want to merge_clusters all of that, which buffer->sort()
* would.
* would. Here's a concrete example:
*
* Assume there's a pre-base consonant and explicit Halant before base,
* followed by a prebase-reordering (left) Matra:
*
* C,H,ZWNJ,B,M
*
* At this point in reordering we would have:
*
* M,C,H,ZWNJ,B
*
* whereas in final reordering we will bring the Matra closer to Base:
*
* C,H,ZWNJ,M,B
*
* That's why we don't want to merge-clusters anything before the Base
* at this point. But if something moved from after Base to before it,
* we should merge clusters from base to them. In final-reordering, we
* only move things around before base, and merge-clusters up to base.
* These two merge-clusters from the two sides of base will interlock
* to merge things correctly. See:
* https://github.com/harfbuzz/harfbuzz/issues/2272
*/
if (indic_plan->is_old_spec || end - start > 127)
buffer->merge_clusters (base, end);
@ -774,17 +783,18 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
for (unsigned int i = base; i < end; i++)
if (info[i].syllable() != 255)
{
unsigned int min = i;
unsigned int max = i;
unsigned int j = start + info[i].syllable();
while (j != i)
{
min = hb_min (min, j);
max = hb_max (max, j);
unsigned int next = start + info[j].syllable();
info[j].syllable() = 255; /* So we don't process j later again. */
j = next;
}
if (i != max)
buffer->merge_clusters (i, max + 1);
buffer->merge_clusters (hb_max (base, min), max + 1);
}
}
@ -938,79 +948,24 @@ initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
}
}
static inline void
insert_dotted_circles_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
/* Note: This loop is extra overhead, but should not be measurable.
* TODO Use a buffer scratch flag to remove the loop. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == indic_broken_cluster)
{
has_broken_syllables = true;
break;
}
if (likely (!has_broken_syllables))
return;
hb_codepoint_t dottedcircle_glyph;
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
return;
hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu;
set_indic_properties (dottedcircle);
dottedcircle.codepoint = dottedcircle_glyph;
buffer->clear_output ();
buffer->idx = 0;
unsigned int last_syllable = 0;
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
indic_syllable_type_t syllable_type = (indic_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == indic_broken_cluster))
{
last_syllable = syllable;
hb_glyph_info_t ginfo = dottedcircle;
ginfo.cluster = buffer->cur().cluster;
ginfo.mask = buffer->cur().mask;
ginfo.syllable() = buffer->cur().syllable();
/* Insert dottedcircle after possible Repha. */
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().indic_category() == OT_Repha)
buffer->next_glyph ();
buffer->output_info (ginfo);
}
else
buffer->next_glyph ();
}
buffer->swap_buffers ();
}
static void
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (!buffer->message (font, "start reordering indic initial"))
return;
update_consonant_positions_indic (plan, font, buffer);
insert_dotted_circles_indic (plan, font, buffer);
hb_syllabic_insert_dotted_circles (font, buffer,
indic_broken_cluster,
OT_DOTTEDCIRCLE,
OT_Repha);
foreach_syllable (buffer, start, end)
initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
(void) buffer->message (font, "end reordering indic initial");
}
static void
@ -1485,8 +1440,11 @@ final_reordering_indic (const hb_ot_shape_plan_t *plan,
unsigned int count = buffer->len;
if (unlikely (!count)) return;
foreach_syllable (buffer, start, end)
final_reordering_syllable_indic (plan, buffer, start, end);
if (buffer->message (font, "start reordering indic final")) {
foreach_syllable (buffer, start, end)
final_reordering_syllable_indic (plan, buffer, start, end);
(void) buffer->message (font, "end reordering indic final");
}
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);

View File

@ -29,16 +29,14 @@
#include "hb.hh"
#include "hb-ot-shape-complex.hh"
#include "hb-ot-shape-complex-syllabic.hh"
/* buffer var allocations */
#define indic_category() complex_var_u8_0() /* indic_category_t */
#define indic_position() complex_var_u8_1() /* indic_position_t */
#define indic_category() complex_var_u8_category() /* indic_category_t */
#define indic_position() complex_var_u8_auxiliary() /* indic_position_t */
#define INDIC_TABLE_ELEMENT_TYPE uint16_t
/* Cateories used in the OpenType spec:
* https://docs.microsoft.com/en-us/typography/script-development/devanagari
*/
@ -177,7 +175,7 @@ enum indic_matra_category_t {
#define INDIC_COMBINE_CATEGORIES(S,M) \
( \
ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
static_assert_expr (S < 255 && M < 255) + \
( S | \
( \
( \
@ -194,7 +192,7 @@ enum indic_matra_category_t {
) \
)
HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE
HB_INTERNAL uint16_t
hb_indic_get_categories (hb_codepoint_t u);
@ -307,17 +305,12 @@ static const hb_codepoint_t ra_chars[] = {
0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */
0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */
0x179Au, /* Khmer */
};
static inline bool
is_ra (hb_codepoint_t u)
{
for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++)
if (u == ra_chars[i])
return true;
return false;
return hb_array (ra_chars).lfind (u);
}
static inline void
@ -325,7 +318,7 @@ set_indic_properties (hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u);
indic_category_t cat = (indic_category_t) (type & 0x7Fu);
indic_category_t cat = (indic_category_t) (type & 0xFFu);
indic_position_t pos = (indic_position_t) (type >> 8);
@ -370,6 +363,7 @@ set_indic_properties (hb_glyph_info_t &info)
else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N;
else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */
else if (unlikely (u == 0x0B55u)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/2849 */
else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */
else if (unlikely (u == 0x09FCu)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/1613 */

View File

@ -1,211 +1,179 @@
#line 1 "hb-ot-shape-complex-khmer-machine.rl"
/*
* Copyright © 2011,2012 Google, Inc.
*
* 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
*/
* Copyright © 2011,2012 Google, Inc.
*
* 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
*/
#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH
#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH
#include "hb.hh"
#line 36 "hb-ot-shape-complex-khmer-machine.hh"
static const unsigned char _khmer_syllable_machine_trans_keys[] = {
5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u,
5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u,
5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 29u, 5u, 29u, 5u, 29u, 5u, 29u,
22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 26u, 5u, 29u,
5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 5u, 29u,
0
enum khmer_syllable_type_t {
khmer_consonant_syllable,
khmer_broken_cluster,
khmer_non_khmer_cluster,
};
static const char _khmer_syllable_machine_key_spans[] = {
22, 17, 22, 17, 16, 17, 22, 17,
22, 17, 17, 22, 17, 16, 17, 22,
17, 22, 17, 22, 29, 25, 25, 25,
1, 18, 25, 25, 25, 16, 22, 25,
25, 1, 18, 25, 25, 16, 25, 25
#line 41 "hb-ot-shape-complex-khmer-machine.hh"
#define khmer_syllable_machine_ex_C 1u
#define khmer_syllable_machine_ex_Coeng 14u
#define khmer_syllable_machine_ex_DOTTEDCIRCLE 12u
#define khmer_syllable_machine_ex_PLACEHOLDER 11u
#define khmer_syllable_machine_ex_Ra 16u
#define khmer_syllable_machine_ex_Robatic 20u
#define khmer_syllable_machine_ex_V 2u
#define khmer_syllable_machine_ex_VAbv 26u
#define khmer_syllable_machine_ex_VBlw 27u
#define khmer_syllable_machine_ex_VPre 28u
#define khmer_syllable_machine_ex_VPst 29u
#define khmer_syllable_machine_ex_Xgroup 21u
#define khmer_syllable_machine_ex_Ygroup 22u
#define khmer_syllable_machine_ex_ZWJ 6u
#define khmer_syllable_machine_ex_ZWNJ 5u
#line 59 "hb-ot-shape-complex-khmer-machine.hh"
static const unsigned char _khmer_syllable_machine_trans_keys[] = {
2u, 8u, 2u, 6u, 2u, 8u, 2u, 6u,
0u, 0u, 2u, 6u, 2u, 8u, 2u, 6u,
2u, 8u, 2u, 6u, 2u, 6u, 2u, 8u,
2u, 6u, 0u, 0u, 2u, 6u, 2u, 8u,
2u, 6u, 2u, 8u, 2u, 6u, 2u, 8u,
0u, 11u, 2u, 11u, 2u, 11u, 2u, 11u,
7u, 7u, 2u, 7u, 2u, 11u, 2u, 11u,
2u, 11u, 0u, 0u, 2u, 8u, 2u, 11u,
2u, 11u, 7u, 7u, 2u, 7u, 2u, 11u,
2u, 11u, 0u, 0u, 2u, 11u, 2u, 11u,
0u
};
static const signed char _khmer_syllable_machine_char_class[] = {
0, 0, 1, 1, 2, 2, 1, 1,
1, 1, 3, 3, 1, 4, 1, 0,
1, 1, 1, 5, 6, 7, 1, 1,
1, 8, 9, 10, 11, 0
};
static const short _khmer_syllable_machine_index_offsets[] = {
0, 23, 41, 64, 82, 99, 117, 140,
158, 181, 199, 217, 240, 258, 275, 293,
316, 334, 357, 375, 398, 428, 454, 480,
506, 508, 527, 553, 579, 605, 622, 645,
671, 697, 699, 718, 744, 770, 787, 813
0, 7, 12, 19, 24, 25, 30, 37,
42, 49, 54, 59, 66, 71, 72, 77,
84, 89, 96, 101, 108, 120, 130, 140,
150, 151, 157, 167, 177, 187, 188, 195,
205, 215, 216, 222, 232, 242, 243, 253,
0
};
static const char _khmer_syllable_machine_indicies[] = {
1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2,
3, 0, 0, 0, 0, 4, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 3,
0, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 0, 0, 0, 4, 0,
5, 5, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 6, 6, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 6, 0, 7, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8, 0, 9, 9, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 10, 0, 0,
0, 0, 4, 0, 9, 9, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 10, 0, 11, 11,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 12, 0,
0, 0, 0, 4, 0, 11, 11, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 12, 0, 14,
14, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 15,
13, 14, 14, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 15, 16, 16, 16, 16, 17, 16,
18, 18, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
17, 16, 19, 19, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 19, 16, 20, 20, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 21, 16, 22, 22, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 23, 16, 16,
16, 16, 17, 16, 22, 22, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 23, 16, 24, 24,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 25, 16,
16, 16, 16, 17, 16, 24, 24, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 25, 16, 14,
14, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 26, 15,
16, 16, 16, 16, 17, 16, 28, 28,
27, 27, 29, 29, 27, 27, 27, 27,
2, 2, 27, 30, 27, 28, 27, 27,
27, 27, 15, 19, 27, 27, 27, 17,
23, 25, 21, 27, 32, 32, 31, 31,
31, 31, 31, 31, 31, 33, 31, 31,
31, 31, 31, 2, 3, 6, 31, 31,
31, 4, 10, 12, 8, 31, 34, 34,
31, 31, 31, 31, 31, 31, 31, 35,
31, 31, 31, 31, 31, 31, 3, 6,
31, 31, 31, 4, 10, 12, 8, 31,
5, 5, 31, 31, 31, 31, 31, 31,
31, 35, 31, 31, 31, 31, 31, 31,
4, 6, 31, 31, 31, 31, 31, 31,
8, 31, 6, 31, 7, 7, 31, 31,
31, 31, 31, 31, 31, 35, 31, 31,
31, 31, 31, 31, 8, 6, 31, 36,
36, 31, 31, 31, 31, 31, 31, 31,
35, 31, 31, 31, 31, 31, 31, 10,
6, 31, 31, 31, 4, 31, 31, 8,
31, 37, 37, 31, 31, 31, 31, 31,
31, 31, 35, 31, 31, 31, 31, 31,
31, 12, 6, 31, 31, 31, 4, 10,
31, 8, 31, 34, 34, 31, 31, 31,
31, 31, 31, 31, 33, 31, 31, 31,
31, 31, 31, 3, 6, 31, 31, 31,
4, 10, 12, 8, 31, 28, 28, 31,
31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 28, 31, 14, 14,
38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 15, 38,
38, 38, 38, 17, 38, 40, 40, 39,
39, 39, 39, 39, 39, 39, 41, 39,
39, 39, 39, 39, 39, 15, 19, 39,
39, 39, 17, 23, 25, 21, 39, 18,
18, 39, 39, 39, 39, 39, 39, 39,
41, 39, 39, 39, 39, 39, 39, 17,
19, 39, 39, 39, 39, 39, 39, 21,
39, 19, 39, 20, 20, 39, 39, 39,
39, 39, 39, 39, 41, 39, 39, 39,
39, 39, 39, 21, 19, 39, 42, 42,
39, 39, 39, 39, 39, 39, 39, 41,
39, 39, 39, 39, 39, 39, 23, 19,
39, 39, 39, 17, 39, 39, 21, 39,
43, 43, 39, 39, 39, 39, 39, 39,
39, 41, 39, 39, 39, 39, 39, 39,
25, 19, 39, 39, 39, 17, 23, 39,
21, 39, 44, 44, 39, 39, 39, 39,
39, 39, 39, 39, 39, 39, 39, 39,
39, 44, 39, 45, 45, 39, 39, 39,
39, 39, 39, 39, 30, 39, 39, 39,
39, 39, 26, 15, 19, 39, 39, 39,
17, 23, 25, 21, 39, 40, 40, 39,
39, 39, 39, 39, 39, 39, 30, 39,
39, 39, 39, 39, 39, 15, 19, 39,
39, 39, 17, 23, 25, 21, 39, 0
static const signed char _khmer_syllable_machine_indicies[] = {
1, 0, 0, 2, 3, 0, 4, 1,
0, 0, 0, 3, 1, 0, 0, 0,
3, 0, 4, 5, 0, 0, 0, 4,
6, 7, 0, 0, 0, 8, 9, 0,
0, 0, 10, 0, 4, 9, 0, 0,
0, 10, 11, 0, 0, 0, 12, 0,
4, 11, 0, 0, 0, 12, 14, 13,
13, 13, 15, 14, 16, 16, 16, 15,
16, 17, 18, 16, 16, 16, 17, 19,
20, 16, 16, 16, 21, 22, 16, 16,
16, 23, 16, 17, 22, 16, 16, 16,
23, 24, 16, 16, 16, 25, 16, 17,
24, 16, 16, 16, 25, 14, 16, 16,
26, 15, 16, 17, 29, 28, 30, 2,
31, 28, 15, 19, 17, 23, 25, 21,
33, 32, 34, 2, 3, 6, 4, 10,
12, 8, 35, 32, 36, 32, 3, 6,
4, 10, 12, 8, 5, 32, 36, 32,
4, 6, 32, 32, 32, 8, 6, 7,
32, 36, 32, 8, 6, 37, 32, 36,
32, 10, 6, 4, 32, 32, 8, 38,
32, 36, 32, 12, 6, 4, 10, 32,
8, 35, 32, 34, 32, 3, 6, 4,
10, 12, 8, 29, 14, 39, 39, 39,
15, 39, 17, 41, 40, 42, 40, 15,
19, 17, 23, 25, 21, 18, 40, 42,
40, 17, 19, 40, 40, 40, 21, 19,
20, 40, 42, 40, 21, 19, 43, 40,
42, 40, 23, 19, 17, 40, 40, 21,
44, 40, 42, 40, 25, 19, 17, 23,
40, 21, 45, 46, 40, 31, 26, 15,
19, 17, 23, 25, 21, 41, 40, 31,
40, 15, 19, 17, 23, 25, 21, 0
};
static const char _khmer_syllable_machine_trans_targs[] = {
static const signed char _khmer_syllable_machine_index_defaults[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 13, 16, 16, 16, 16, 16,
16, 16, 16, 16, 28, 32, 32, 32,
32, 32, 32, 32, 32, 32, 39, 40,
40, 40, 40, 40, 40, 40, 40, 40,
0
};
static const signed char _khmer_syllable_machine_cond_targs[] = {
20, 1, 28, 22, 23, 3, 24, 5,
25, 7, 26, 9, 27, 20, 10, 31,
20, 32, 12, 33, 14, 34, 16, 35,
18, 36, 39, 20, 21, 30, 37, 20,
0, 29, 2, 4, 6, 8, 20, 20,
11, 13, 15, 17, 38, 19
18, 36, 39, 20, 20, 21, 30, 37,
20, 0, 29, 2, 4, 6, 8, 20,
20, 11, 13, 15, 17, 38, 19, 0
};
static const char _khmer_syllable_machine_trans_actions[] = {
static const signed char _khmer_syllable_machine_cond_actions[] = {
1, 0, 2, 2, 2, 0, 0, 0,
2, 0, 2, 0, 2, 3, 0, 4,
5, 2, 0, 0, 0, 2, 0, 2,
0, 2, 4, 8, 2, 9, 0, 10,
0, 0, 0, 0, 0, 0, 11, 12,
0, 0, 0, 0, 4, 0
0, 2, 4, 0, 8, 2, 9, 0,
10, 0, 0, 0, 0, 0, 0, 11,
12, 0, 0, 0, 0, 4, 0, 0
};
static const char _khmer_syllable_machine_to_state_actions[] = {
static const signed char _khmer_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0,
0
};
static const char _khmer_syllable_machine_from_state_actions[] = {
static const signed char _khmer_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0,
0
};
static const unsigned char _khmer_syllable_machine_eof_trans[] = {
static const signed char _khmer_syllable_machine_eof_trans[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 14, 17, 17, 17, 17, 17,
17, 17, 17, 17, 0, 32, 32, 32,
32, 32, 32, 32, 32, 32, 39, 40,
40, 40, 40, 40, 40, 40, 40, 40
17, 17, 17, 17, 28, 33, 33, 33,
33, 33, 33, 33, 33, 33, 40, 41,
41, 41, 41, 41, 41, 41, 41, 41,
0
};
static const int khmer_syllable_machine_start = 20;
@ -215,155 +183,270 @@ static const int khmer_syllable_machine_error = -1;
static const int khmer_syllable_machine_en_main = 20;
#line 36 "hb-ot-shape-complex-khmer-machine.rl"
#line 43 "hb-ot-shape-complex-khmer-machine.rl"
#line 80 "hb-ot-shape-complex-khmer-machine.rl"
#line 86 "hb-ot-shape-complex-khmer-machine.rl"
#define found_syllable(syllable_type) \
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables_khmer (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
#line 242 "hb-ot-shape-complex-khmer-machine.hh"
#line 210 "hb-ot-shape-complex-khmer-machine.hh"
{
cs = khmer_syllable_machine_start;
ts = 0;
te = 0;
act = 0;
cs = (int)khmer_syllable_machine_start;
ts = 0;
te = 0;
act = 0;
}
#line 100 "hb-ot-shape-complex-khmer-machine.rl"
#line 106 "hb-ot-shape-complex-khmer-machine.rl"
p = 0;
pe = eof = buffer->len;
p = 0;
pe = eof = buffer->len;
unsigned int syllable_serial = 1;
unsigned int syllable_serial = 1;
#line 258 "hb-ot-shape-complex-khmer-machine.hh"
#line 226 "hb-ot-shape-complex-khmer-machine.hh"
{
int _slen;
int _trans;
const unsigned char *_keys;
const char *_inds;
if ( p == pe )
goto _test_eof;
_resume:
switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
case 7:
unsigned int _trans = 0;
const unsigned char * _keys;
const signed char * _inds;
int _ic;
_resume: {}
if ( p == pe && p != eof )
goto _out;
switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
case 7: {
{
#line 1 "NONE"
{ts = p;}
break;
#line 272 "hb-ot-shape-complex-khmer-machine.hh"
}
{ts = p;}}
_keys = _khmer_syllable_machine_trans_keys + (cs<<1);
_inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs];
#line 241 "hb-ot-shape-complex-khmer-machine.hh"
_slen = _khmer_syllable_machine_key_spans[cs];
_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) &&
( info[p].khmer_category()) <= _keys[1] ?
( info[p].khmer_category()) - _keys[0] : _slen ];
_eof_trans:
cs = _khmer_syllable_machine_trans_targs[_trans];
break;
}
}
if ( _khmer_syllable_machine_trans_actions[_trans] == 0 )
goto _again;
if ( p == eof ) {
if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) {
_trans = (unsigned int)_khmer_syllable_machine_eof_trans[cs] - 1;
}
}
else {
_keys = ( _khmer_syllable_machine_trans_keys + ((cs<<1)));
_inds = ( _khmer_syllable_machine_indicies + (_khmer_syllable_machine_index_offsets[cs]));
switch ( _khmer_syllable_machine_trans_actions[_trans] ) {
case 2:
if ( (info[p].khmer_category()) <= 29 && (info[p].khmer_category()) >= 1 ) {
_ic = (int)_khmer_syllable_machine_char_class[(int)(info[p].khmer_category()) - 1];
if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) )
_trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) ));
else
_trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs];
}
else {
_trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs];
}
}
cs = (int)_khmer_syllable_machine_cond_targs[_trans];
if ( _khmer_syllable_machine_cond_actions[_trans] != 0 ) {
switch ( _khmer_syllable_machine_cond_actions[_trans] ) {
case 2: {
{
#line 1 "NONE"
{te = p+1;}
break;
case 8:
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{te = p+1;{ found_syllable (non_khmer_cluster); }}
break;
case 10:
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 12:
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 11:
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (non_khmer_cluster); }}
break;
case 1:
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
break;
case 5:
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
case 3:
{te = p+1;}}
#line 279 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 8: {
{
#line 82 "hb-ot-shape-complex-khmer-machine.rl"
{te = p+1;{
#line 82 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_non_khmer_cluster); }
}}
#line 292 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 10: {
{
#line 80 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p = p - 1;{
#line 80 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_consonant_syllable); }
}}
#line 305 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 12: {
{
#line 81 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p = p - 1;{
#line 81 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_broken_cluster); }
}}
#line 318 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 11: {
{
#line 82 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p = p - 1;{
#line 82 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_non_khmer_cluster); }
}}
#line 331 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 1: {
{
#line 80 "hb-ot-shape-complex-khmer-machine.rl"
{p = ((te))-1;
{
#line 80 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_consonant_syllable); }
}}
#line 345 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 5: {
{
#line 81 "hb-ot-shape-complex-khmer-machine.rl"
{p = ((te))-1;
{
#line 81 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_broken_cluster); }
}}
#line 359 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 3: {
{
#line 1 "NONE"
{ switch( act ) {
case 2:
{{p = ((te))-1;} found_syllable (broken_cluster); }
break;
case 3:
{{p = ((te))-1;} found_syllable (non_khmer_cluster); }
break;
}
}
break;
case 4:
{switch( act ) {
case 2: {
p = ((te))-1;
{
#line 81 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_broken_cluster); }
break;
}
case 3: {
p = ((te))-1;
{
#line 82 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (khmer_non_khmer_cluster); }
break;
}
}}
}
#line 385 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 4: {
{
#line 1 "NONE"
{te = p+1;}
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{act = 2;}
break;
case 9:
{te = p+1;}}
#line 395 "hb-ot-shape-complex-khmer-machine.hh"
{
#line 81 "hb-ot-shape-complex-khmer-machine.rl"
{act = 2;}}
#line 401 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
case 9: {
{
#line 1 "NONE"
{te = p+1;}
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{act = 3;}
break;
#line 342 "hb-ot-shape-complex-khmer-machine.hh"
{te = p+1;}}
#line 411 "hb-ot-shape-complex-khmer-machine.hh"
{
#line 82 "hb-ot-shape-complex-khmer-machine.rl"
{act = 3;}}
#line 417 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
}
}
if ( p == eof ) {
if ( cs >= 20 )
goto _out;
}
else {
switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
case 6: {
{
#line 1 "NONE"
{ts = 0;}}
#line 437 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
}
p += 1;
goto _resume;
}
_out: {}
}
_again:
switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
case 6:
#line 1 "NONE"
{ts = 0;}
break;
#line 351 "hb-ot-shape-complex-khmer-machine.hh"
}
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) {
_trans = _khmer_syllable_machine_eof_trans[cs] - 1;
goto _eof_trans;
}
}
}
#line 108 "hb-ot-shape-complex-khmer-machine.rl"
#line 114 "hb-ot-shape-complex-khmer-machine.rl"
}

View File

@ -29,6 +29,7 @@
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-khmer.hh"
#include "hb-ot-shape-complex-khmer-machine.hh"
#include "hb-ot-layout.hh"
@ -140,27 +141,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan)
struct khmer_shape_plan_t
{
bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
{
hb_codepoint_t glyph = virama_glyph;
if (unlikely (virama_glyph == (hb_codepoint_t) -1))
{
if (!font->get_nominal_glyph (0x17D2u, &glyph))
glyph = 0;
/* Technically speaking, the spec says we should apply 'locl' to virama too.
* Maybe one day... */
/* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph
* during shape planning... Instead, overwrite it here. It's safe. Don't worry! */
virama_glyph = glyph;
}
*pglyph = glyph;
return glyph != 0;
}
mutable hb_codepoint_t virama_glyph;
hb_mask_t mask_array[KHMER_NUM_FEATURES];
};
@ -171,8 +151,6 @@ data_create_khmer (const hb_ot_shape_plan_t *plan)
if (unlikely (!khmer_plan))
return nullptr;
khmer_plan->virama_glyph = (hb_codepoint_t) -1;
for (unsigned int i = 0; i < ARRAY_LENGTH (khmer_plan->mask_array); i++)
khmer_plan->mask_array[i] = (khmer_features[i].flags & F_GLOBAL) ?
0 : plan->map.get_1_mask (khmer_features[i].tag);
@ -186,15 +164,6 @@ data_destroy_khmer (void *data)
free (data);
}
enum khmer_syllable_type_t {
khmer_consonant_syllable,
khmer_broken_cluster,
khmer_non_khmer_cluster,
};
#include "hb-ot-shape-complex-khmer-machine.hh"
static void
setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
@ -321,79 +290,22 @@ reorder_syllable_khmer (const hb_ot_shape_plan_t *plan,
}
}
static inline void
insert_dotted_circles_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
/* Note: This loop is extra overhead, but should not be measurable.
* TODO Use a buffer scratch flag to remove the loop. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == khmer_broken_cluster)
{
has_broken_syllables = true;
break;
}
if (likely (!has_broken_syllables))
return;
hb_codepoint_t dottedcircle_glyph;
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
return;
hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu;
set_khmer_properties (dottedcircle);
dottedcircle.codepoint = dottedcircle_glyph;
buffer->clear_output ();
buffer->idx = 0;
unsigned int last_syllable = 0;
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == khmer_broken_cluster))
{
last_syllable = syllable;
hb_glyph_info_t ginfo = dottedcircle;
ginfo.cluster = buffer->cur().cluster;
ginfo.mask = buffer->cur().mask;
ginfo.syllable() = buffer->cur().syllable();
/* Insert dottedcircle after possible Repha. */
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().khmer_category() == OT_Repha)
buffer->next_glyph ();
buffer->output_info (ginfo);
}
else
buffer->next_glyph ();
}
buffer->swap_buffers ();
}
static void
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles_khmer (plan, font, buffer);
foreach_syllable (buffer, start, end)
reorder_syllable_khmer (plan, font->face, buffer, start, end);
if (buffer->message (font, "start reordering khmer"))
{
hb_syllabic_insert_dotted_circles (font, buffer,
khmer_broken_cluster,
OT_DOTTEDCIRCLE,
OT_Repha);
foreach_syllable (buffer, start, end)
reorder_syllable_khmer (plan, font->face, buffer, start, end);
(void) buffer->message (font, "end reordering khmer");
}
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
}

View File

@ -54,7 +54,7 @@ set_khmer_properties (hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u);
khmer_category_t cat = (khmer_category_t) (type & 0x7Fu);
khmer_category_t cat = (khmer_category_t) (type & 0xFFu);
indic_position_t pos = (indic_position_t) (type >> 8);

View File

@ -31,8 +31,43 @@
#include "hb.hh"
enum myanmar_syllable_type_t {
myanmar_consonant_syllable,
myanmar_punctuation_cluster,
myanmar_broken_cluster,
myanmar_non_myanmar_cluster,
};
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
#line 43 "hb-ot-shape-complex-myanmar-machine.hh"
#define myanmar_syllable_machine_ex_A 10u
#define myanmar_syllable_machine_ex_As 18u
#define myanmar_syllable_machine_ex_C 1u
#define myanmar_syllable_machine_ex_CS 19u
#define myanmar_syllable_machine_ex_D 32u
#define myanmar_syllable_machine_ex_D0 20u
#define myanmar_syllable_machine_ex_DB 3u
#define myanmar_syllable_machine_ex_GB 11u
#define myanmar_syllable_machine_ex_H 4u
#define myanmar_syllable_machine_ex_IV 2u
#define myanmar_syllable_machine_ex_MH 21u
#define myanmar_syllable_machine_ex_MR 22u
#define myanmar_syllable_machine_ex_MW 23u
#define myanmar_syllable_machine_ex_MY 24u
#define myanmar_syllable_machine_ex_P 31u
#define myanmar_syllable_machine_ex_PT 25u
#define myanmar_syllable_machine_ex_Ra 16u
#define myanmar_syllable_machine_ex_V 8u
#define myanmar_syllable_machine_ex_VAbv 26u
#define myanmar_syllable_machine_ex_VBlw 27u
#define myanmar_syllable_machine_ex_VPre 28u
#define myanmar_syllable_machine_ex_VPst 29u
#define myanmar_syllable_machine_ex_VS 30u
#define myanmar_syllable_machine_ex_ZWJ 6u
#define myanmar_syllable_machine_ex_ZWNJ 5u
#line 71 "hb-ot-shape-complex-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
@ -293,18 +328,18 @@ static const int myanmar_syllable_machine_error = -1;
static const int myanmar_syllable_machine_en_main = 0;
#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
#line 44 "hb-ot-shape-complex-myanmar-machine.rl"
#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
#line 101 "hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
@ -316,7 +351,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
#line 355 "hb-ot-shape-complex-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@ -324,7 +359,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
act = 0;
}
#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
#line 121 "hb-ot-shape-complex-myanmar-machine.rl"
p = 0;
@ -332,7 +367,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
#line 336 "hb-ot-shape-complex-myanmar-machine.hh"
#line 371 "hb-ot-shape-complex-myanmar-machine.hh"
{
int _slen;
int _trans;
@ -346,7 +381,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
#line 350 "hb-ot-shape-complex-myanmar-machine.hh"
#line 385 "hb-ot-shape-complex-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@ -365,38 +400,38 @@ _eof_trans:
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 6:
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_consonant_syllable); }}
break;
case 4:
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
break;
case 10:
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (punctuation_cluster); }}
#line 95 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_punctuation_cluster); }}
break;
case 8:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
#line 96 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_broken_cluster); }}
break;
case 3:
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
break;
case 5:
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (myanmar_consonant_syllable); }}
break;
case 7:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
#line 96 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (myanmar_broken_cluster); }}
break;
case 9:
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
#line 97 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
break;
#line 400 "hb-ot-shape-complex-myanmar-machine.hh"
#line 435 "hb-ot-shape-complex-myanmar-machine.hh"
}
_again:
@ -405,7 +440,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
#line 409 "hb-ot-shape-complex-myanmar-machine.hh"
#line 444 "hb-ot-shape-complex-myanmar-machine.hh"
}
if ( ++p != pe )
@ -421,7 +456,7 @@ _again:
}
#line 122 "hb-ot-shape-complex-myanmar-machine.rl"
#line 129 "hb-ot-shape-complex-myanmar-machine.rl"
}

View File

@ -29,6 +29,7 @@
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-myanmar.hh"
#include "hb-ot-shape-complex-myanmar-machine.hh"
/*
@ -97,23 +98,6 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
}
static void
override_features_myanmar (hb_ot_shape_planner_t *plan)
{
plan->map.disable_feature (HB_TAG('l','i','g','a'));
}
enum myanmar_syllable_type_t {
myanmar_consonant_syllable,
myanmar_punctuation_cluster,
myanmar_broken_cluster,
myanmar_non_myanmar_cluster,
};
#include "hb-ot-shape-complex-myanmar-machine.hh"
static void
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
@ -271,72 +255,21 @@ reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
}
static inline void
insert_dotted_circles_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
/* Note: This loop is extra overhead, but should not be measurable.
* TODO Use a buffer scratch flag to remove the loop. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == myanmar_broken_cluster)
{
has_broken_syllables = true;
break;
}
if (likely (!has_broken_syllables))
return;
hb_codepoint_t dottedcircle_glyph;
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
return;
hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu;
set_myanmar_properties (dottedcircle);
dottedcircle.codepoint = dottedcircle_glyph;
buffer->clear_output ();
buffer->idx = 0;
unsigned int last_syllable = 0;
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == myanmar_broken_cluster))
{
last_syllable = syllable;
hb_glyph_info_t ginfo = dottedcircle;
ginfo.cluster = buffer->cur().cluster;
ginfo.mask = buffer->cur().mask;
ginfo.syllable() = buffer->cur().syllable();
buffer->output_info (ginfo);
}
else
buffer->next_glyph ();
}
buffer->swap_buffers ();
}
static void
reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles_myanmar (plan, font, buffer);
if (buffer->message (font, "start reordering myanmar"))
{
hb_syllabic_insert_dotted_circles (font, buffer,
myanmar_broken_cluster,
OT_GB);
foreach_syllable (buffer, start, end)
reorder_syllable_myanmar (plan, font->face, buffer, start, end);
foreach_syllable (buffer, start, end)
reorder_syllable_myanmar (plan, font->face, buffer, start, end);
(void) buffer->message (font, "end reordering myanmar");
}
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
@ -346,7 +279,7 @@ reorder_myanmar (const hb_ot_shape_plan_t *plan,
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
{
collect_features_myanmar,
override_features_myanmar,
nullptr, /* override_features */
nullptr, /* data_create */
nullptr, /* data_destroy */
nullptr, /* preprocess_text */

View File

@ -64,7 +64,7 @@ set_myanmar_properties (hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u);
unsigned int cat = type & 0x7Fu;
unsigned int cat = type & 0xFFu;
indic_position_t pos = (indic_position_t) (type >> 8);
/* Myanmar

View File

@ -0,0 +1,100 @@
/*
* Copyright © 2021 Behdad Esfahbod.
*
* 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.
*/
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-syllabic.hh"
void
hb_syllabic_insert_dotted_circles (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int broken_syllable_type,
unsigned int dottedcircle_category,
int repha_category)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
/* Note: This loop is extra overhead, but should not be measurable.
* TODO Use a buffer scratch flag to remove the loop. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_syllable_type)
{
has_broken_syllables = true;
break;
}
if (likely (!has_broken_syllables))
return;
hb_codepoint_t dottedcircle_glyph;
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
return;
hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu;
dottedcircle.complex_var_u8_category() = dottedcircle_category;
dottedcircle.codepoint = dottedcircle_glyph;
buffer->clear_output ();
buffer->idx = 0;
unsigned int last_syllable = 0;
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
if (unlikely (last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type))
{
last_syllable = syllable;
hb_glyph_info_t ginfo = dottedcircle;
ginfo.cluster = buffer->cur().cluster;
ginfo.mask = buffer->cur().mask;
ginfo.syllable() = buffer->cur().syllable();
/* Insert dottedcircle after possible Repha. */
if (repha_category != -1)
{
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().complex_var_u8_category() == (unsigned) repha_category)
(void) buffer->next_glyph ();
}
(void) buffer->output_info (ginfo);
}
else
(void) buffer->next_glyph ();
}
buffer->swap_buffers ();
}
#endif

View File

@ -0,0 +1,41 @@
/*
* Copyright © 2021 Behdad Esfahbod.
*
* 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.
*/
#ifndef HB_OT_SHAPE_COMPLEX_SYLLABIC_HH
#define HB_OT_SHAPE_COMPLEX_SYLLABIC_HH
#include "hb.hh"
#include "hb-ot-shape-complex.hh"
HB_INTERNAL void
hb_syllabic_insert_dotted_circles (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int broken_syllable_type,
unsigned int dottedcircle_category,
int repha_category = -1);
#endif /* HB_OT_SHAPE_COMPLEX_SYLLABIC_HH */

View File

@ -323,20 +323,19 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
buffer->clear_output ();
unsigned int count = buffer->len;
for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
for (buffer->idx = 0; buffer->idx < count /* No need for: && buffer->successful */;)
{
hb_codepoint_t u = buffer->cur().codepoint;
if (likely (!IS_SARA_AM (u))) {
buffer->next_glyph ();
if (likely (!IS_SARA_AM (u)))
{
if (unlikely (!buffer->next_glyph ())) break;
continue;
}
/* Is SARA AM. Decompose and reorder. */
hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
_hb_glyph_info_set_continuation (&nikhahit);
buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u));
if (unlikely (!buffer->successful))
return;
(void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
_hb_glyph_info_set_continuation (&buffer->prev());
if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break;
/* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */
unsigned int end = buffer->out_len;

View File

@ -2,7 +2,7 @@
/*
* The following table is generated by running:
*
* ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
* ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
*
* on files with these headers:
*
@ -10,63 +10,78 @@
* # Date: 2019-07-22, 19:55:00 GMT [KW, RP]
* # IndicPositionalCategory-13.0.0.txt
* # Date: 2019-07-23, 00:01:00 GMT [KW, RP]
* # ArabicShaping-13.0.0.txt
* # Date: 2020-01-31, 23:55:00 GMT [KW, RP]
* # Blocks-13.0.0.txt
* # Date: 2019-07-10, 19:06:00 GMT [KW]
* # Override values For Indic_Syllabic_Category
* # Not derivable
* # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
* # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-24
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
* # Override values For Indic_Positional_Category
* # Not derivable
* # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
* # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
* # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21
* # Updated for L2/19-083 by Andrew Glass 2019-05-06
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-30
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
* UnicodeData.txt does not have a header.
*/
#ifndef HB_OT_SHAPE_COMPLEX_USE_TABLE_HH
#define HB_OT_SHAPE_COMPLEX_USE_TABLE_HH
#include "hb.hh"
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-use.hh"
#include "hb-ot-shape-complex-use-machine.hh"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
#define B USE_B /* BASE */
#define CGJ USE_CGJ /* CGJ */
#define CS USE_CS /* CONS_WITH_STACKER */
#define GB USE_GB /* BASE_OTHER */
#define H USE_H /* HALANT */
#define HN USE_HN /* HALANT_NUM */
#define HVM USE_HVM /* HALANT_OR_VOWEL_MODIFIER */
#define IND USE_IND /* BASE_IND */
#define N USE_N /* BASE_NUM */
#define O USE_O /* OTHER */
#define R USE_R /* REPHA */
#define Rsv USE_Rsv /* Reserved */
#define S USE_S /* SYM */
#define SUB USE_SUB /* CONS_SUB */
#define Sk USE_Sk /* SAKOT */
#define VS USE_VS /* VARIATION_SELECTOR */
#define WJ USE_WJ /* Word_Joiner */
#define ZWJ USE_ZWJ /* ZWJ */
#define ZWNJ USE_ZWNJ /* ZWNJ */
#define CMAbv USE_CMAbv
#define CMBlw USE_CMBlw
#define FAbv USE_FAbv
#define FBlw USE_FBlw
#define FPst USE_FPst
#define FMAbv USE_FMAbv
#define FMBlw USE_FMBlw
#define FMPst USE_FMPst
#define MAbv USE_MAbv
#define MBlw USE_MBlw
#define MPst USE_MPst
#define MPre USE_MPre
#define SMAbv USE_SMAbv
#define SMBlw USE_SMBlw
#define VAbv USE_VAbv
#define VBlw USE_VBlw
#define VPst USE_VPst
#define VPre USE_VPre
#define VMAbv USE_VMAbv
#define VMBlw USE_VMBlw
#define VMPst USE_VMPst
#define VMPre USE_VMPre
#define B USE(B) /* BASE */
#define CS USE(CS) /* CONS_WITH_STACKER */
#define G USE(G) /* HIEROGLYPH */
#define GB USE(GB) /* BASE_OTHER */
#define H USE(H) /* HALANT */
#define HN USE(HN) /* HALANT_NUM */
#define HVM USE(HVM) /* HALANT_OR_VOWEL_MODIFIER */
#define J USE(J) /* HIEROGLYPH_JOINER */
#define N USE(N) /* BASE_NUM */
#define O USE(O) /* OTHER */
#define R USE(R) /* REPHA */
#define S USE(S) /* SYM */
#define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */
#define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */
#define SUB USE(SUB) /* CONS_SUB */
#define Sk USE(Sk) /* SAKOT */
#define ZWNJ USE(ZWNJ) /* ZWNJ */
#define CMAbv USE(CMAbv)
#define CMBlw USE(CMBlw)
#define FAbv USE(FAbv)
#define FBlw USE(FBlw)
#define FPst USE(FPst)
#define FMAbv USE(FMAbv)
#define FMBlw USE(FMBlw)
#define FMPst USE(FMPst)
#define MAbv USE(MAbv)
#define MBlw USE(MBlw)
#define MPst USE(MPst)
#define MPre USE(MPre)
#define SMAbv USE(SMAbv)
#define SMBlw USE(SMBlw)
#define VAbv USE(VAbv)
#define VBlw USE(VBlw)
#define VPst USE(VPst)
#define VPre USE(VPre)
#define VMAbv USE(VMAbv)
#define VMBlw USE(VMBlw)
#define VMPst USE(VMPst)
#define VMPre USE(VMPre)
#pragma GCC diagnostic pop
static const USE_TABLE_ELEMENT_TYPE use_table[] = {
static const uint8_t use_table[] = {
#define use_offset_0x0028u 0
@ -86,13 +101,31 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 00D0 */ O, O, O, O, O, O, O, GB,
#define use_offset_0x0348u 80
#define use_offset_0x0640u 80
/* Combining Diacritical Marks */
O, O, O, O, O, O, O, CGJ,
/* Arabic */
#define use_offset_0x0900u 88
/* 0640 */ B, O, O, O, O, O, O, O,
#define use_offset_0x07c8u 88
/* NKo */
O, O, B, B, B, B, B, B,
/* 07D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
/* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, O, O, VMAbv, O, O,
#define use_offset_0x0840u 144
/* Mandaic */
/* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, O, O, O, O,
#define use_offset_0x0900u 176
/* Devanagari */
@ -112,7 +145,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre,
/* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPst, VPst, H, IND, O,
/* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
/* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B,
/* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FMAbv, O,
@ -145,18 +178,18 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0B10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv,
/* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, O, O, VPst, VPst, H, O, O,
/* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
/* 0B50 */ O, O, O, O, O, VAbv, VAbv, VAbv, O, O, O, O, B, B, O, B,
/* 0B60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Tamil */
/* 0B80 */ O, O, VMAbv, IND, O, B, B, B, B, B, B, O, O, O, B, B,
/* 0B80 */ O, O, VMAbv, O, O, B, B, B, B, B, B, O, O, O, B, B,
/* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B,
/* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B,
/* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst,
/* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, O, O,
/* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O,
/* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O,
/* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
@ -189,10 +222,10 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst,
/* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, R, O,
/* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B,
/* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O,
/* 0D50 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, B,
/* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND,
/* 0D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Sinhala */
@ -201,28 +234,30 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O,
/* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst,
/* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPst, VPre, VPst, VPst, VPst, VPst,
/* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst,
/* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0DF0 */ O, O, VPst, VPst, O, O, O, O,
#define use_offset_0x0f18u 1360
#define use_offset_0x0f00u 1448
/* Tibetan */
VBlw, VBlw, O, O, O, O, O, O,
/* 0F00 */ B, B, O, O, B, B, B, O, O, O, O, O, O, O, O, O,
/* 0F10 */ O, O, O, O, O, O, O, O, VBlw, VBlw, O, O, O, O, O, O,
/* 0F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0F30 */ B, B, B, B, O, FMBlw, O, FMBlw, O, CMAbv, O, O, O, O, VPst, VPre,
/* 0F30 */ B, B, B, B, O, FBlw, O, FBlw, O, CMAbv, O, O, O, O, VPst, VPre,
/* 0F40 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B,
/* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
/* 0F70 */ O, VBlw, VBlw, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, VMPst,
/* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, IND, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB,
/* 0F70 */ O, CMBlw, VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, O,
/* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, O, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB,
/* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O,
/* 0FC0 */ O, O, O, O, O, O, FMBlw, O,
/* 0FC0 */ O, O, O, O, O, O, FBlw, O,
#define use_offset_0x1000u 1536
#define use_offset_0x1000u 1648
/* Myanmar */
@ -238,7 +273,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst,
/* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O,
#define use_offset_0x1700u 1696
#define use_offset_0x1700u 1808
/* Tagalog */
@ -266,12 +301,27 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPst, VPst,
/* 17C0 */ VPst, VPre, VPre, VPre, VPst, VPst, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, FMAbv,
/* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre,
/* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv,
/* 17D0 */ FMAbv, VAbv, H, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, O, O,
/* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 17F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
#define use_offset_0x1900u 1936
/* Mongolian */
/* 1800 */ B, O, O, O, O, O, O, B, O, O, B, O, O, O, O, O,
/* 1810 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1870 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
/* 1880 */ GB, GB, GB, GB, GB, CMAbv, CMAbv, B, B, B, B, B, B, B, B, B,
/* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, O, O, O, O, O,
#define use_offset_0x1900u 2240
/* Limbu */
@ -279,7 +329,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O,
/* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, O, O, O, O,
/* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VAbv, FMBlw, O, O, O, O,
/* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VMAbv, FMBlw, O, O, O, O,
/* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* Tai Le */
@ -302,7 +352,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* Buginese */
/* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A10 */ B, B, B, B, B, B, B, VAbv, VBlw, VPre, VPst, VAbv, O, O, O, O,
/* 1A10 */ B, B, B, B, B, B, B, VAbv, VAbv, VPre, VPst, VAbv, O, O, O, O,
/* Tai Tham */
@ -311,11 +361,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, O,
/* 1A60 */ Sk, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre,
/* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, FMAbv, FMAbv, O, O, FMBlw,
/* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, VMAbv, VMAbv, O, O, VMBlw,
/* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x1b00u 2352
#define use_offset_0x1b00u 2656
/* Balinese */
@ -324,7 +374,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre,
/* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O,
/* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O,
/* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB,
/* 1B60 */ O, S, GB, S, S, S, S, S, GB, S, S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
/* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O,
@ -351,51 +401,61 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O,
/* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,
#define use_offset_0x1cd0u 2688
#define use_offset_0x1cd0u 2992
/* Vedic Extensions */
/* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
/* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O,
/* 1CF0 */ O, O, IND, IND, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O,
/* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O,
#define use_offset_0x1df8u 2736
#define use_offset_0x1df8u 3040
/* Combining Diacritical Marks Supplement */
O, O, O, FMAbv, O, O, O, O,
#define use_offset_0x2008u 2744
#define use_offset_0x2008u 3048
/* General Punctuation */
O, O, O, O, ZWNJ, ZWJ, O, O,
O, O, O, O, ZWNJ, O, O, O,
/* 2010 */ GB, GB, GB, GB, GB, O, O, O,
#define use_offset_0x2060u 2760
#define use_offset_0x2070u 3064
/* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Superscripts and Subscripts */
/* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O,
/* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O,
#define use_offset_0x20f0u 2800
#define use_offset_0x20f0u 3088
/* Combining Diacritical Marks for Symbols */
/* 20F0 */ VMAbv, O, O, O, O, O, O, O,
#define use_offset_0x25c8u 2808
#define use_offset_0x25c8u 3096
/* Geometric Shapes */
O, O, O, O, GB, O, O, O,
O, O, O, O, B, O, O, O,
#define use_offset_0xa800u 2816
#define use_offset_0x2d30u 3104
/* Tifinagh */
/* 2D30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 2D40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 2D50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B,
/* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H,
#define use_offset_0xa800u 3184
/* Syloti Nagri */
@ -445,7 +505,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* A980 */ VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B,
/* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, MBlw, MBlw, MBlw,
/* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, MBlw, MPst, MBlw,
/* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@ -459,7 +519,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AA00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* AA20 */ B, B, B, B, B, B, B, B, B, VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre,
/* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MBlw, MBlw, O, O, O, O, O, O, O, O, O,
/* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MAbv, MBlw, O, O, O, O, O, O, O, O, O,
/* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, O, O,
/* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@ -482,7 +542,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst,
/* AAF0 */ O, O, O, O, O, VMPst, H, O,
#define use_offset_0xabc0u 3576
#define use_offset_0xabc0u 3944
/* Meetei Mayek */
@ -492,27 +552,75 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O,
/* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0xfe00u 3640
/* Variation Selectors */
/* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS,
#define use_offset_0x10a00u 3656
#define use_offset_0x10a00u 4008
/* Kharoshthi */
/* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VBlw, VBlw, VMBlw, VMAbv,
/* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VPst, VMBlw, VMBlw, VMAbv,
/* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B,
/* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H,
/* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
#define use_offset_0x11000u 3736
#define use_offset_0x10ac0u 4088
/* Manichaean */
/* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B,
/* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O,
#define use_offset_0x10b80u 4128
/* Psalter Pahlavi */
/* 10B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O,
#define use_offset_0x10d00u 4176
/* Hanifi Rohingya */
/* 10D00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O,
/* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x10e80u 4240
/* Yezidi */
/* 10E80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10E90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O,
/* 10EB0 */ B, B, O, O, O, O, O, O,
#define use_offset_0x10f30u 4296
/* Sogdian */
/* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,
/* 10F50 */ VMBlw, B, B, B, B, O, O, O,
#define use_offset_0x10fb0u 4336
/* Chorasmian */
/* 10FB0 */ B, O, B, B, B, B, B, O, B, B, B, B, B, B, B, B,
/* 10FC0 */ O, B, B, B, B, O, O, O, O, B, B, B, O, O, O, O,
/* 10FD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 10FE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 10FF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Brahmi */
/* 11000 */ VMPst, VMAbv, VMPst, CS, CS, B, B, B, B, B, B, B, B, B, B, B,
@ -531,7 +639,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O,
#define use_offset_0x11100u 3928
#define use_offset_0x11100u 4608
/* Chakma */
@ -539,7 +647,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11120 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VBlw, VAbv, VAbv,
/* 11130 */ VBlw, VAbv, VAbv, H, CMBlw, O, B, B, B, B, B, B, B, B, B, B,
/* 11130 */ VBlw, VAbv, VAbv, H, CMAbv, O, B, B, B, B, B, B, B, B, B, B,
/* 11140 */ O, O, O, O, B, VPst, VPst, B, O, O, O, O, O, O, O, O,
/* Mahajani */
@ -555,7 +663,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv,
/* 111C0 */ H, B, R, R, O, O, O, O, GB, FMBlw, CMBlw, VAbv, VBlw, O, VPre, VMAbv,
/* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 111D0 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O,
/* Sinhala Archaic Numbers */
@ -569,7 +677,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw,
/* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O,
#define use_offset_0x11280u 4248
#define use_offset_0x11280u 4928
/* Multani */
@ -592,12 +700,12 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 11330 */ B, O, B, B, O, B, B, B, B, B, O, CMBlw, CMBlw, B, VPst, VPst,
/* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPst, VPst, HVM, O, O,
/* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, HVM, O, O,
/* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B,
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
#define use_offset_0x11400u 4496
#define use_offset_0x11400u 5176
/* Newa */
@ -616,11 +724,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPst, VPst, VPst, VPst, VMAbv,
/* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv,
/* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O,
/* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x11580u 4720
#define use_offset_0x11580u 5400
/* Siddham */
@ -628,7 +736,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst,
/* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, VPst, VPst, VMAbv, VMAbv, VMPst, H,
/* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H,
/* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, O, O,
/* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
@ -663,7 +771,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O,
/* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
#define use_offset_0x11800u 5168
#define use_offset_0x11800u 5848
/* Dogra */
@ -673,7 +781,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw,
/* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O,
#define use_offset_0x11900u 5232
#define use_offset_0x11900u 5912
/* Dives Akuru */
@ -681,11 +789,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11900 */ B, B, B, B, B, B, B, O, O, B, O, O, B, B, B, B,
/* 11910 */ B, B, B, B, O, B, B, O, B, B, B, B, B, B, B, B,
/* 11920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11930 */ VPst, VPst, VPst, VPst, VPst, VPre, O, VPre, VPst, O, O, VMAbv, VMAbv, VPst, H, R,
/* 11940 */ MPst, R, MBlw, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
/* 11930 */ VPst, VPst, VPst, VPst, VPst, VPre, O, VPre, VPre, O, O, VMAbv, VMAbv, VPst, H, R,
/* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
/* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x119a0u 5328
#define use_offset_0x119a0u 6008
/* Nandinagari */
@ -713,7 +821,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw,
/* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O,
#define use_offset_0x11c00u 5584
#define use_offset_0x11c00u 6264
/* Bhaiksuki */
@ -734,7 +842,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O,
#define use_offset_0x11d00u 5768
#define use_offset_0x11d00u 6448
/* Masaram Gondi */
@ -754,7 +862,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O,
/* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x11ee0u 5944
#define use_offset_0x11ee0u 6624
/* Makasar */
@ -762,9 +870,204 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O,
}; /* Table items: 5968; occupancy: 74% */
#define use_offset_0x13000u 6648
USE_TABLE_ELEMENT_TYPE
/* Egyptian Hieroglyphs */
/* 13000 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13010 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13020 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13030 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13040 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13050 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13060 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13070 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13080 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13090 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 130A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 130B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 130C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 130D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 130E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 130F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13100 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13110 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13120 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13130 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13140 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13150 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13160 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13170 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13180 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13190 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 131A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 131B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 131C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 131D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 131E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 131F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13200 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13210 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13220 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13230 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13240 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13250 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13260 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13270 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13280 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13290 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 132A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 132B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 132C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 132D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 132E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 132F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13300 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13310 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13320 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13330 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13340 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13350 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13360 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13370 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13380 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13390 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 133A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 133B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 133C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 133D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 133E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 133F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13400 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13410 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G,
/* 13420 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, O,
/* Egyptian Hieroglyph Format Controls */
/* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O,
#define use_offset_0x16b00u 7736
/* Pahawh Hmong */
/* 16B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O,
#define use_offset_0x16f00u 7792
/* Miao */
/* 16F00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16F10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16F40 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, CMBlw,
/* 16F50 */ O, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
/* 16F60 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
/* 16F70 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw,
/* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw,
/* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O,
#define use_offset_0x16fe0u 7944
/* Ideographic Symbols and Punctuation */
/* 16FE0 */ O, O, O, O, B, O, O, O,
#define use_offset_0x18b00u 7952
/* Khitan Small Script */
/* 18B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18BA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18BE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18BF0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18C90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18CA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18CB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18CD0 */ B, B, B, B, B, B, O, O,
#define use_offset_0x1bc00u 8424
/* Duployan */
/* 1BC00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BC10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BC20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BC30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BC40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BC50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BC60 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O,
/* 1BC70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
/* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
/* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O,
#define use_offset_0x1e100u 8584
/* Nyiakeng Puachue Hmong */
/* 1E100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O,
/* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O,
/* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B,
#define use_offset_0x1e2c0u 8664
/* Wancho */
/* 1E2C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E2D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv,
/* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x1e900u 8728
/* Adlam */
/* 1E900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O,
/* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
}; /* Table items: 8824; occupancy: 79% */
static inline uint8_t
hb_use_get_category (hb_codepoint_t u)
{
switch (u >> 12)
@ -772,14 +1075,16 @@ hb_use_get_category (hb_codepoint_t u)
case 0x0u:
if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u];
if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u];
if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u];
if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u];
if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u];
if (hb_in_range<hb_codepoint_t> (u, 0x0F18u, 0x0FC7u)) return use_table[u - 0x0F18u + use_offset_0x0f18u];
if (hb_in_range<hb_codepoint_t> (u, 0x0F00u, 0x0FC7u)) return use_table[u - 0x0F00u + use_offset_0x0f00u];
break;
case 0x1u:
if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u];
if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u];
if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x18AFu)) return use_table[u - 0x1700u + use_offset_0x1700u];
if (hb_in_range<hb_codepoint_t> (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u];
if (hb_in_range<hb_codepoint_t> (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u];
if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u];
@ -788,9 +1093,10 @@ hb_use_get_category (hb_codepoint_t u)
case 0x2u:
if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
if (hb_in_range<hb_codepoint_t> (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u];
if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u];
if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u];
if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u];
if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u];
break;
case 0xAu:
@ -798,16 +1104,18 @@ hb_use_get_category (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u];
break;
case 0xFu:
if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
break;
case 0x10u:
if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AE7u)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u];
if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u];
if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u];
if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u];
if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F57u)) return use_table[u - 0x10F30u + use_offset_0x10f30u];
if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u];
break;
case 0x11u:
if (hb_in_range<hb_codepoint_t> (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u];
if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u];
if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u];
if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
@ -820,30 +1128,52 @@ hb_use_get_category (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0x11EE0u, 0x11EF7u)) return use_table[u - 0x11EE0u + use_offset_0x11ee0u];
break;
case 0x13u:
if (hb_in_range<hb_codepoint_t> (u, 0x13000u, 0x1343Fu)) return use_table[u - 0x13000u + use_offset_0x13000u];
break;
case 0x16u:
if (hb_in_range<hb_codepoint_t> (u, 0x16B00u, 0x16B37u)) return use_table[u - 0x16B00u + use_offset_0x16b00u];
if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u];
if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u];
break;
case 0x18u:
if (hb_in_range<hb_codepoint_t> (u, 0x18B00u, 0x18CD7u)) return use_table[u - 0x18B00u + use_offset_0x18b00u];
break;
case 0x1Bu:
if (hb_in_range<hb_codepoint_t> (u, 0x1BC00u, 0x1BC9Fu)) return use_table[u - 0x1BC00u + use_offset_0x1bc00u];
break;
case 0x1Eu:
if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u];
if (hb_in_range<hb_codepoint_t> (u, 0x1E2C0u, 0x1E2FFu)) return use_table[u - 0x1E2C0u + use_offset_0x1e2c0u];
if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u];
break;
default:
break;
}
return USE_O;
return USE(O);
}
#undef B
#undef CGJ
#undef CS
#undef G
#undef GB
#undef H
#undef HN
#undef HVM
#undef IND
#undef J
#undef N
#undef O
#undef R
#undef Rsv
#undef S
#undef SB
#undef SE
#undef SUB
#undef Sk
#undef VS
#undef WJ
#undef ZWJ
#undef ZWNJ
#undef CMAbv
#undef CMBlw
@ -869,5 +1199,5 @@ hb_use_get_category (hb_codepoint_t u)
#undef VMPre
#endif
#endif /* HB_OT_SHAPE_COMPLEX_USE_TABLE_HH */
/* == End of generated table == */

View File

@ -30,14 +30,12 @@
#ifndef HB_NO_OT_SHAPE
#include "hb-ot-shape-complex-use.hh"
#include "hb-ot-shape-complex-use-machine.hh"
#include "hb-ot-shape-complex-use-table.hh"
#include "hb-ot-shape-complex-arabic.hh"
#include "hb-ot-shape-complex-arabic-joining-list.hh"
#include "hb-ot-shape-complex-vowel-constraints.hh"
/* buffer var allocations */
#define use_category() complex_var_u8_1()
/*
* Universal Shaping Engine.
@ -69,11 +67,11 @@ use_topographical_features[] =
};
/* Same order as use_topographical_features. */
enum joining_form_t {
USE_ISOL,
USE_INIT,
USE_MEDI,
USE_FINA,
_USE_NONE
JOINING_FORM_ISOL,
JOINING_FORM_INIT,
JOINING_FORM_MEDI,
JOINING_FORM_FINA,
_JOINING_FORM_NONE
};
static const hb_tag_t
use_other_features[] =
@ -186,21 +184,6 @@ data_destroy_use (void *data)
free (data);
}
enum use_syllable_type_t {
use_independent_cluster,
use_virama_terminated_cluster,
use_sakot_terminated_cluster,
use_standard_cluster,
use_number_joiner_terminated_cluster,
use_numeral_cluster,
use_symbol_cluster,
use_broken_cluster,
use_non_cluster,
};
#include "hb-ot-shape-complex-use-machine.hh"
static void
setup_masks_use (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
@ -238,7 +221,7 @@ setup_rphf_mask (const hb_ot_shape_plan_t *plan,
foreach_syllable (buffer, start, end)
{
unsigned int limit = info[start].use_category() == USE_R ? 1 : hb_min (3u, end - start);
unsigned int limit = info[start].use_category() == USE(R) ? 1 : hb_min (3u, end - start);
for (unsigned int i = start; i < start + limit; i++)
info[i].mask |= mask;
}
@ -252,7 +235,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
if (use_plan->arabic_plan)
return;
static_assert ((USE_INIT < 4 && USE_ISOL < 4 && USE_MEDI < 4 && USE_FINA < 4), "");
static_assert ((JOINING_FORM_INIT < 4 && JOINING_FORM_ISOL < 4 && JOINING_FORM_MEDI < 4 && JOINING_FORM_FINA < 4), "");
hb_mask_t masks[4], all_masks = 0;
for (unsigned int i = 0; i < 4; i++)
{
@ -266,7 +249,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
hb_mask_t other_masks = ~all_masks;
unsigned int last_start = 0;
joining_form_t last_form = _USE_NONE;
joining_form_t last_form = _JOINING_FORM_NONE;
hb_glyph_info_t *info = buffer->info;
foreach_syllable (buffer, start, end)
{
@ -275,9 +258,10 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
{
case use_independent_cluster:
case use_symbol_cluster:
case use_hieroglyph_cluster:
case use_non_cluster:
/* These don't join. Nothing to do. */
last_form = _USE_NONE;
last_form = _JOINING_FORM_NONE;
break;
case use_virama_terminated_cluster:
@ -287,18 +271,18 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
case use_numeral_cluster:
case use_broken_cluster:
bool join = last_form == USE_FINA || last_form == USE_ISOL;
bool join = last_form == JOINING_FORM_FINA || last_form == JOINING_FORM_ISOL;
if (join)
{
/* Fixup previous syllable's form. */
last_form = last_form == USE_FINA ? USE_MEDI : USE_INIT;
last_form = last_form == JOINING_FORM_FINA ? JOINING_FORM_MEDI : JOINING_FORM_INIT;
for (unsigned int i = last_start; i < start; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
}
/* Form for this syllable. */
last_form = join ? USE_FINA : USE_ISOL;
last_form = join ? JOINING_FORM_FINA : JOINING_FORM_ISOL;
for (unsigned int i = start; i < end; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
@ -334,11 +318,11 @@ record_rphf_use (const hb_ot_shape_plan_t *plan,
foreach_syllable (buffer, start, end)
{
/* Mark a substituted repha as USE_R. */
/* Mark a substituted repha as USE(R). */
for (unsigned int i = start; i < end && (info[i].mask & mask); i++)
if (_hb_glyph_info_substituted (&info[i]))
{
info[i].use_category() = USE_R;
info[i].use_category() = USE(R);
break;
}
}
@ -357,7 +341,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
for (unsigned int i = start; i < end; i++)
if (_hb_glyph_info_substituted (&info[i]))
{
info[i].use_category() = USE_VPre;
info[i].use_category() = USE(VPre);
break;
}
}
@ -366,7 +350,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
static inline bool
is_halant_use (const hb_glyph_info_t &info)
{
return (info.use_category() == USE_H || info.use_category() == USE_HVM) &&
return (info.use_category() == USE(H) || info.use_category() == USE(HVM)) &&
!_hb_glyph_info_ligated (&info);
}
@ -385,25 +369,24 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
hb_glyph_info_t *info = buffer->info;
#define POST_BASE_FLAGS64 (FLAG64 (USE_FM) | \
FLAG64 (USE_FAbv) | \
FLAG64 (USE_FBlw) | \
FLAG64 (USE_FPst) | \
FLAG64 (USE_MAbv) | \
FLAG64 (USE_MBlw) | \
FLAG64 (USE_MPst) | \
FLAG64 (USE_MPre) | \
FLAG64 (USE_VAbv) | \
FLAG64 (USE_VBlw) | \
FLAG64 (USE_VPst) | \
FLAG64 (USE_VPre) | \
FLAG64 (USE_VMAbv) | \
FLAG64 (USE_VMBlw) | \
FLAG64 (USE_VMPst) | \
FLAG64 (USE_VMPre))
#define POST_BASE_FLAGS64 (FLAG64 (USE(FAbv)) | \
FLAG64 (USE(FBlw)) | \
FLAG64 (USE(FPst)) | \
FLAG64 (USE(MAbv)) | \
FLAG64 (USE(MBlw)) | \
FLAG64 (USE(MPst)) | \
FLAG64 (USE(MPre)) | \
FLAG64 (USE(VAbv)) | \
FLAG64 (USE(VBlw)) | \
FLAG64 (USE(VPst)) | \
FLAG64 (USE(VPre)) | \
FLAG64 (USE(VMAbv)) | \
FLAG64 (USE(VMBlw)) | \
FLAG64 (USE(VMPst)) | \
FLAG64 (USE(VMPre)))
/* Move things forward. */
if (info[start].use_category() == USE_R && end - start > 1)
if (info[start].use_category() == USE(R) && end - start > 1)
{
/* Got a repha. Reorder it towards the end, but before the first post-base
* glyph. */
@ -440,7 +423,7 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
* shift things in between forward. */
j = i + 1;
}
else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) &&
else if (((flag) & (FLAG (USE(VPre)) | FLAG (USE(VMPre)))) &&
/* Only move the first component of a MultipleSubst. */
0 == _hb_glyph_info_get_lig_comp (&info[i]) &&
j < i)
@ -453,73 +436,23 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
}
}
static inline void
insert_dotted_circles_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
return;
/* Note: This loop is extra overhead, but should not be measurable.
* TODO Use a buffer scratch flag to remove the loop. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == use_broken_cluster)
{
has_broken_syllables = true;
break;
}
if (likely (!has_broken_syllables))
return;
hb_glyph_info_t dottedcircle = {0};
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint))
return;
dottedcircle.use_category() = hb_use_get_category (0x25CC);
buffer->clear_output ();
buffer->idx = 0;
unsigned int last_syllable = 0;
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
use_syllable_type_t syllable_type = (use_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == use_broken_cluster))
{
last_syllable = syllable;
hb_glyph_info_t ginfo = dottedcircle;
ginfo.cluster = buffer->cur().cluster;
ginfo.mask = buffer->cur().mask;
ginfo.syllable() = buffer->cur().syllable();
/* Insert dottedcircle after possible Repha. */
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().use_category() == USE_R)
buffer->next_glyph ();
buffer->output_info (ginfo);
}
else
buffer->next_glyph ();
}
buffer->swap_buffers ();
}
static void
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles_use (plan, font, buffer);
if (buffer->message (font, "start reordering USE"))
{
hb_syllabic_insert_dotted_circles (font, buffer,
use_broken_cluster,
USE(B),
USE(R));
foreach_syllable (buffer, start, end)
reorder_syllable_use (buffer, start, end);
foreach_syllable (buffer, start, end)
reorder_syllable_use (buffer, start, end);
(void) buffer->message (font, "end reordering USE");
}
HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
}

View File

@ -1,105 +0,0 @@
/*
* Copyright © 2015 Mozilla Foundation.
* Copyright © 2015 Google, Inc.
*
* 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.
*
* Mozilla Author(s): Jonathan Kew
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_SHAPE_COMPLEX_USE_HH
#define HB_OT_SHAPE_COMPLEX_USE_HH
#include "hb.hh"
#include "hb-ot-shape-complex.hh"
#define USE_TABLE_ELEMENT_TYPE uint8_t
/* Cateories used in the Universal Shaping Engine spec:
* https://docs.microsoft.com/en-us/typography/script-development/use
*/
/* Note: This enum is duplicated in the -machine.rl source file.
* Not sure how to avoid duplication. */
enum use_category_t {
USE_O = 0, /* OTHER */
USE_B = 1, /* BASE */
USE_IND = 3, /* BASE_IND */
USE_N = 4, /* BASE_NUM */
USE_GB = 5, /* BASE_OTHER */
USE_CGJ = 6, /* CGJ */
// USE_F = 7, /* CONS_FINAL */
USE_FM = 8, /* CONS_FINAL_MOD */
// USE_M = 9, /* CONS_MED */
// USE_CM = 10, /* CONS_MOD */
USE_SUB = 11, /* CONS_SUB */
USE_H = 12, /* HALANT */
USE_HN = 13, /* HALANT_NUM */
USE_ZWNJ = 14, /* Zero width non-joiner */
USE_ZWJ = 15, /* Zero width joiner */
USE_WJ = 16, /* Word joiner */
USE_Rsv = 17, /* Reserved characters */
USE_R = 18, /* REPHA */
USE_S = 19, /* SYM */
// USE_SM = 20, /* SYM_MOD */
USE_VS = 21, /* VARIATION_SELECTOR */
// USE_V = 36, /* VOWEL */
// USE_VM = 40, /* VOWEL_MOD */
USE_CS = 43, /* CONS_WITH_STACKER */
/* https://github.com/harfbuzz/harfbuzz/issues/1102 */
USE_HVM = 44, /* HALANT_OR_VOWEL_MODIFIER */
USE_Sk = 48, /* SAKOT */
USE_FAbv = 24, /* CONS_FINAL_ABOVE */
USE_FBlw = 25, /* CONS_FINAL_BELOW */
USE_FPst = 26, /* CONS_FINAL_POST */
USE_MAbv = 27, /* CONS_MED_ABOVE */
USE_MBlw = 28, /* CONS_MED_BELOW */
USE_MPst = 29, /* CONS_MED_POST */
USE_MPre = 30, /* CONS_MED_PRE */
USE_CMAbv = 31, /* CONS_MOD_ABOVE */
USE_CMBlw = 32, /* CONS_MOD_BELOW */
USE_VAbv = 33, /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */
USE_VBlw = 34, /* VOWEL_BELOW / VOWEL_BELOW_POST */
USE_VPst = 35, /* VOWEL_POST UIPC = Right */
USE_VPre = 22, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */
USE_VMAbv = 37, /* VOWEL_MOD_ABOVE */
USE_VMBlw = 38, /* VOWEL_MOD_BELOW */
USE_VMPst = 39, /* VOWEL_MOD_POST */
USE_VMPre = 23, /* VOWEL_MOD_PRE */
USE_SMAbv = 41, /* SYM_MOD_ABOVE */
USE_SMBlw = 42, /* SYM_MOD_BELOW */
USE_FMAbv = 45, /* CONS_FINAL_MOD UIPC = Top */
USE_FMBlw = 46, /* CONS_FINAL_MOD UIPC = Bottom */
USE_FMPst = 47, /* CONS_FINAL_MOD UIPC = Not_Applicable */
};
HB_INTERNAL USE_TABLE_ELEMENT_TYPE
hb_use_get_category (hb_codepoint_t u);
#endif /* HB_OT_SHAPE_COMPLEX_USE_HH */

View File

@ -23,15 +23,15 @@
static void
_output_dotted_circle (hb_buffer_t *buffer)
{
hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);
_hb_glyph_info_reset_continuation (&dottedcircle);
(void) buffer->output_glyph (0x25CCu);
_hb_glyph_info_reset_continuation (&buffer->prev());
}
static void
_output_with_dotted_circle (hb_buffer_t *buffer)
{
_output_dotted_circle (buffer);
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
void
@ -51,7 +51,6 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
*
* https://github.com/harfbuzz/harfbuzz/issues/1019
*/
bool processed = false;
buffer->clear_output ();
unsigned int count = buffer->len;
switch ((unsigned) buffer->props.script)
@ -97,15 +96,14 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
buffer->idx + 2 < count &&
0x0907u == buffer->cur (2).codepoint)
{
buffer->next_glyph ();
(void) buffer->next_glyph ();
matched = true;
}
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_BENGALI:
@ -124,10 +122,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x09E2u == buffer->cur (1).codepoint;
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_GURMUKHI:
@ -161,10 +158,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_GUJARATI:
@ -186,10 +182,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0ABEu == buffer->cur (1).codepoint;
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_ORIYA:
@ -205,10 +200,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0B57u == buffer->cur (1).codepoint;
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_TAMIL:
@ -220,10 +214,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
{
matched = true;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_TELUGU:
@ -244,10 +237,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0C55u == buffer->cur (1).codepoint;
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_KANNADA:
@ -263,10 +255,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0CCCu == buffer->cur (1).codepoint;
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_MALAYALAM:
@ -290,10 +281,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_SINHALA:
@ -320,16 +310,15 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
switch (buffer->cur (1).codepoint)
{
case 0x0DCAu: case 0x0DD9u: case 0x0DDAu: case 0x0DDCu:
case 0x0DDDu:
case 0x0DDDu: case 0x0DDEu:
matched = true;
break;
}
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_BRAHMI:
@ -348,10 +337,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x11042u == buffer->cur (1).codepoint;
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_KHUDAWADI:
@ -370,10 +358,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_TIRHUTA:
@ -397,10 +384,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_MODI:
@ -418,10 +404,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
case HB_SCRIPT_TAKRI:
@ -442,21 +427,15 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x116B2u == buffer->cur (1).codepoint;
break;
}
buffer->next_glyph ();
(void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer);
}
processed = true;
break;
default:
break;
}
if (processed)
{
if (buffer->idx < count)
buffer->next_glyph ();
buffer->swap_buffers ();
}
buffer->swap_buffers ();
}

View File

@ -35,8 +35,8 @@
/* buffer var allocations, used by complex shapers */
#define complex_var_u8_0() var2.u8[2]
#define complex_var_u8_1() var2.u8[3]
#define complex_var_u8_category() var2.u8[2]
#define complex_var_u8_auxiliary() var2.u8[3]
#define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32
@ -186,27 +186,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_ARABIC:
/* Unicode-3.0 additions */
case HB_SCRIPT_MONGOLIAN:
case HB_SCRIPT_SYRIAC:
/* Unicode-5.0 additions */
case HB_SCRIPT_NKO:
case HB_SCRIPT_PHAGS_PA:
/* Unicode-6.0 additions */
case HB_SCRIPT_MANDAIC:
/* Unicode-7.0 additions */
case HB_SCRIPT_MANICHAEAN:
case HB_SCRIPT_PSALTER_PAHLAVI:
/* Unicode-9.0 additions */
case HB_SCRIPT_ADLAM:
/* Unicode-11.0 additions */
case HB_SCRIPT_HANIFI_ROHINGYA:
case HB_SCRIPT_SOGDIAN:
/* For Arabic script, use the Arabic shaper even if no OT script tag was found.
* This is because we do fallback shaping for Arabic script (and not others).
* But note that Arabic shaping is applicable only to horizontal layout; for
@ -284,8 +265,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
return &_hb_ot_complex_shaper_myanmar;
/* https://github.com/harfbuzz/harfbuzz/issues/1162 */
#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g'))
case HB_SCRIPT_MYANMAR_ZAWGYI:
/* https://github.com/harfbuzz/harfbuzz/issues/1162 */
return &_hb_ot_complex_shaper_myanmar_zawgyi;
@ -294,7 +276,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_TIBETAN:
/* Unicode-3.0 additions */
//case HB_SCRIPT_MONGOLIAN:
case HB_SCRIPT_MONGOLIAN:
//case HB_SCRIPT_SINHALA:
/* Unicode-3.2 additions */
@ -315,8 +297,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-5.0 additions */
case HB_SCRIPT_BALINESE:
//case HB_SCRIPT_NKO:
//case HB_SCRIPT_PHAGS_PA:
case HB_SCRIPT_NKO:
case HB_SCRIPT_PHAGS_PA:
/* Unicode-5.1 additions */
case HB_SCRIPT_CHAM:
@ -337,10 +319,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-6.0 additions */
case HB_SCRIPT_BATAK:
case HB_SCRIPT_BRAHMI:
//case HB_SCRIPT_MANDAIC:
case HB_SCRIPT_MANDAIC:
/* Unicode-6.1 additions */
case HB_SCRIPT_CHAKMA:
case HB_SCRIPT_MIAO:
case HB_SCRIPT_SHARADA:
case HB_SCRIPT_TAKRI:
@ -350,18 +333,19 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_KHOJKI:
case HB_SCRIPT_KHUDAWADI:
case HB_SCRIPT_MAHAJANI:
//case HB_SCRIPT_MANICHAEAN:
case HB_SCRIPT_MANICHAEAN:
case HB_SCRIPT_MODI:
case HB_SCRIPT_PAHAWH_HMONG:
//case HB_SCRIPT_PSALTER_PAHLAVI:
case HB_SCRIPT_PSALTER_PAHLAVI:
case HB_SCRIPT_SIDDHAM:
case HB_SCRIPT_TIRHUTA:
/* Unicode-8.0 additions */
case HB_SCRIPT_AHOM:
case HB_SCRIPT_MULTANI:
/* Unicode-9.0 additions */
//case HB_SCRIPT_ADLAM:
case HB_SCRIPT_ADLAM:
case HB_SCRIPT_BHAIKSUKI:
case HB_SCRIPT_MARCHEN:
case HB_SCRIPT_NEWA:
@ -374,12 +358,17 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-11.0 additions */
case HB_SCRIPT_DOGRA:
case HB_SCRIPT_GUNJALA_GONDI:
//case HB_SCRIPT_HANIFI_ROHINGYA:
case HB_SCRIPT_HANIFI_ROHINGYA:
case HB_SCRIPT_MAKASAR:
//case HB_SCRIPT_SOGDIAN:
case HB_SCRIPT_MEDEFAIDRIN:
case HB_SCRIPT_OLD_SOGDIAN:
case HB_SCRIPT_SOGDIAN:
/* Unicode-12.0 additions */
case HB_SCRIPT_ELYMAIC:
case HB_SCRIPT_NANDINAGARI:
case HB_SCRIPT_NYIAKENG_PUACHUE_HMONG:
case HB_SCRIPT_WANCHO:
/* Unicode-13.0 additions */
case HB_SCRIPT_CHORASMIAN:

View File

@ -301,7 +301,7 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Don't shift down "above" marks too much. */
if ((y_gap > 0) != (pos.y_offset > 0))
{
unsigned int correction = -pos.y_offset / 2;
int correction = -pos.y_offset / 2;
base_extents.y_bearing += correction;
base_extents.height -= correction;
pos.y_offset += correction;

View File

@ -101,8 +101,9 @@ set_glyph (hb_glyph_info_t &info, hb_font_t *font)
static inline void
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
{
/* This is very confusing indeed. */
buffer->cur().glyph_index() = glyph;
buffer->output_glyph (unichar); /* This is very confusing indeed. */
(void) buffer->output_glyph (unichar);
_hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
}
@ -110,7 +111,7 @@ static inline void
next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
{
buffer->cur().glyph_index() = glyph;
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
static inline void
@ -229,30 +230,35 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
{
hb_codepoint_t unicode = buffer->cur().codepoint;
buffer->replace_glyphs (2, 1, &unicode);
(void) buffer->replace_glyphs (2, 1, &unicode);
}
else
{
/* Just pass on the two characters separately, let GSUB do its magic. */
set_glyph (buffer->cur(), font);
buffer->next_glyph ();
(void) buffer->next_glyph ();
set_glyph (buffer->cur(), font);
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
/* Skip any further variation selectors. */
while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
while (buffer->idx < end &&
buffer->successful &&
unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
{
set_glyph (buffer->cur(), font);
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
} else {
}
else
{
set_glyph (buffer->cur(), font);
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
}
if (likely (buffer->idx < end)) {
if (likely (buffer->idx < end))
{
set_glyph (buffer->cur(), font);
buffer->next_glyph ();
(void) buffer->next_glyph ();
}
}
@ -348,7 +354,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
sizeof (buffer->info[0]),
&buffer->cur().glyph_index(),
sizeof (buffer->info[0]));
buffer->next_glyphs (done);
if (unlikely (!buffer->next_glyphs (done))) break;
}
while (buffer->idx < end && buffer->successful)
decompose_current_character (&c, might_short_circuit);
@ -373,7 +379,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* Second round, reorder (inplace) */
if (!all_simple)
if (!all_simple && buffer->message(font, "start reorder"))
{
count = buffer->len;
for (unsigned int i = 0; i < count; i++)
@ -399,6 +405,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
i = end;
}
(void) buffer->message(font, "end reorder");
}
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
{
@ -408,7 +415,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
*/
for (unsigned int i = 1; i + 1 < buffer->len; i++)
if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1]))
(info_cc(buffer->info[i+1]) == 0 || info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])))
{
_hb_glyph_info_unhide (&buffer->info[i]);
}
@ -418,6 +425,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* Third round, recompose */
if (!all_simple &&
buffer->successful &&
(mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT))
{
@ -427,8 +435,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer->clear_output ();
count = buffer->len;
unsigned int starter = 0;
buffer->next_glyph ();
while (buffer->idx < count && buffer->successful)
(void) buffer->next_glyph ();
while (buffer->idx < count /* No need for: && buffer->successful */)
{
hb_codepoint_t composed, glyph;
if (/* We don't try to compose a non-mark character with it's preceding starter.
@ -450,9 +458,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
font->get_nominal_glyph (composed, &glyph))
{
/* Composes. */
buffer->next_glyph (); /* Copy to out-buffer. */
if (unlikely (!buffer->successful))
return;
if (unlikely (!buffer->next_glyph ())) break; /* Copy to out-buffer. */
buffer->merge_out_clusters (starter, buffer->out_len);
buffer->out_len--; /* Remove the second composable. */
/* Modify starter and carry on. */
@ -465,7 +471,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
}
/* Blocked, or doesn't compose. */
buffer->next_glyph ();
if (unlikely (!buffer->next_glyph ())) break;
if (info_cc (buffer->prev()) == 0)
starter = buffer->out_len - 1;

View File

@ -534,9 +534,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
hb_glyph_info_t info = dottedcircle;
info.cluster = buffer->cur().cluster;
info.mask = buffer->cur().mask;
buffer->output_info (info);
while (buffer->idx < buffer->len && buffer->successful)
buffer->next_glyph ();
(void) buffer->output_info (info);
buffer->swap_buffers ();
}
@ -896,8 +894,11 @@ hb_ot_substitute_post (const hb_ot_shape_context_t *c)
hb_aat_layout_remove_deleted_glyphs (c->buffer);
#endif
if (c->plan->shaper->postprocess_glyphs)
if (c->plan->shaper->postprocess_glyphs &&
c->buffer->message(c->font, "start postprocess-glyphs")) {
c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
(void) c->buffer->message(c->font, "end postprocess-glyphs");
}
}
@ -1120,8 +1121,11 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
hb_ensure_native_direction (c->buffer);
if (c->plan->shaper->preprocess_text)
if (c->plan->shaper->preprocess_text &&
c->buffer->message(c->font, "start preprocess-text")) {
c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
(void) c->buffer->message(c->font, "end preprocess-text");
}
hb_ot_substitute_pre (c);
hb_ot_position (c);
@ -1155,6 +1159,12 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
/**
* hb_ot_shape_plan_collect_lookups:
* @shape_plan: #hb_shape_plan_t to query
* @table_tag: GSUB or GPOS
* @lookup_indexes: (out): The #hb_set_t set of lookups returned
*
* Computes the complete set of GSUB or GPOS lookups that are applicable
* under a given @shape_plan.
*
* Since: 0.9.7
**/
@ -1189,6 +1199,15 @@ add_char (hb_font_t *font,
/**
* hb_ot_shape_glyphs_closure:
* @font: #hb_font_t to work upon
* @buffer: The input buffer to compute from
* @features: (array length=num_features): The features enabled on the buffer
* @num_features: The number of features enabled on the buffer
* @glyphs: (out): The #hb_set_t set of glyphs comprising the transitive closure of the query
*
* Computes the transitive closure of glyphs needed for a specified
* input buffer under the given font and feature list. The closure is
* computed as a set, not as a list.
*
* Since: 0.9.2
**/

View File

@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_H_IN
#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-ot.h> instead."
#endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More