Merge pull request #47072 from bruvzg/hb_2_8_0

HarfBuzz: Update to version 2.8.0
This commit is contained in:
Rémi Verschelde 2021-03-16 21:28:00 +01:00 committed by GitHub
commit a6066c5e42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
121 changed files with 3844 additions and 3151 deletions

View file

@ -83,8 +83,8 @@ if env["builtin_harfbuzz"]:
"src/hb-ot-shape-complex-indic.cc",
"src/hb-ot-shape-complex-khmer.cc",
"src/hb-ot-shape-complex-myanmar.cc",
"src/hb-ot-shape-complex-syllabic.cc",
"src/hb-ot-shape-complex-thai.cc",
"src/hb-ot-shape-complex-use-table.cc",
"src/hb-ot-shape-complex-use.cc",
"src/hb-ot-shape-complex-vowel-constraints.cc",
"src/hb-ot-shape-fallback.cc",

View file

@ -174,7 +174,7 @@ Files extracted from upstream source:
## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
- Version: 2.7.4 (7236c7e29cef1c2d76c7a284c5081ff4d3aa1127, 2020)
- Version: 2.8.0 (03538e872a0610a65fad692b33d3646f387cf578, 2021)
- License: MIT
Files extracted from upstream source:

View file

@ -1,3 +1,18 @@
Overview of changes leading to 2.8.0
Tuesday, March 16, 2021
====================================
- Shape joining scripts other than Arabic/Syriac using the Universal Shaping Engine.
Previously these were shaped using the generalized Arabic shaper. (David Corbett)
- Fix regression in shaping of U+0B55 ORIYA SIGN OVERLINE. (David Corbett)
- Update language tags. (David Corbett)
- Variations: reduce error: do not round each interpolated delta. (Just van Rossum)
- Documentation improvements. (Khaled Hosny, Nathan Willis)
- Subsetter improvements: subsets most, if not all, lookup types now. (Garret Rieger, Qunxin Liu)
- Fuzzer-found fixes and other improvements when memory failures happen. (Behdad)
- Removed most atomic implementations now that we have C++11 atomic impl. (Behdad)
- General codebase upkeep; using more C++11 features: constexpr constructors, etc. (Behdad)
Overview of changes leading to 2.7.4
Sunday, December 27, 2020
====================================

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

@ -227,7 +227,7 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
*
* <note>Note: does not examine the `GSUB` table.</note>
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 2.3.0
*/
@ -294,7 +294,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
*
* <note>Note: does not examine the `GPOS` table.</note>
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 2.3.0
*/
@ -325,7 +325,7 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
* Tests whether the specified face includes any tracking information
* in the `trak` table.
*
* Return value: true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 2.3.0
*/
@ -350,7 +350,7 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
* hb_aat_layout_get_feature_types:
* @face: #hb_face_t to work upon
* @start_offset: offset of the first feature type to retrieve
* @feature_count: (inout) (allow-none): Input = the maximum number of feature types to return;
* @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
*
@ -374,9 +374,9 @@ hb_aat_layout_get_feature_types (hb_face_t *face,
* @face: #hb_face_t to work upon
* @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type
*
* Fetches the name ID of the specified feature type in the face's `name` table.
* Fetches the name identifier of the specified feature type in the face's `name` table.
*
* Return value: Name ID of the requested feature type
* Return value: Name identifier of the requested feature type
*
* Since: 2.2.0
*/
@ -388,15 +388,15 @@ hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
}
/**
* hb_aat_layout_feature_type_get_selectors:
* 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) (allow-none): Input = the maximum number of selectors to return;
* @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): A buffer pointer.
* The selectors available for the feature type queries.
* @default_index: (out) (allow-none): The index of the feature's default selector, if any
* @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.
*

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
@ -38,47 +38,47 @@ 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:
* @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION:
* @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION:
* @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT:
* @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING:
* @HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION:
* @HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS:
* @HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS:
* @HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS:
* @HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES:
* @HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING:
* @HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION:
* @HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT:
* @HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA:
* @HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES:
* @HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE:
* @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_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.
* 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
*/
@ -732,6 +732,14 @@ 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);
/**
* 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;

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
@ -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_memory
#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: (optional): 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.
@ -237,7 +234,7 @@ hb_blob_destroy (hb_blob_t *blob)
* @blob: An #hb_blob_t
* @key: The user-data key to set
* @data: A pointer to the user data to set
* @destroy: (optional): A callback to call when @data is not needed anymore
* @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 blob.
@ -299,7 +296,7 @@ hb_blob_make_immutable (hb_blob_t *blob)
*
* Tests whether a blob is immutable.
*
* Return value: %true if @blob is immutable, false otherwise
* Return value: %true if @blob is immutable, %false otherwise
*
* Since: 0.9.2
**/
@ -365,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);
}
@ -440,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;

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
@ -38,10 +38,12 @@ HB_BEGIN_DECLS
/**
* hb_memory_mode_t:
* @HB_MEMORY_MODE_DUPLICATE
* @HB_MEMORY_MODE_READONLY
* @HB_MEMORY_MODE_WRITABLE
* @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
* @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.

View file

@ -400,8 +400,8 @@ _hb_buffer_serialize_unicode_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
@ -514,8 +514,10 @@ hb_buffer_serialize_glyphs (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.
* @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
@ -635,8 +637,8 @@ _hb_buffer_serialize_invalid (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
@ -724,15 +726,17 @@ parse_hex (const char *pp, const char *end, uint32_t *pv)
/**
* 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
**/
@ -795,14 +799,16 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
/**
* hb_buffer_deserialize_unicode:
* @buffer: an #hb_buffer_t buffer.
* @buf: (array length=buf_len):
* @buf_len:
* @end_ptr: (out):
* @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.
* @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:
* Return value: %true if @buf is not fully consumed, %false otherwise.
*
* Since: 2.7.3
**/

View file

@ -218,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;
@ -233,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;
@ -290,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;
@ -303,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;
@ -316,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;
@ -333,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;
}
@ -353,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)
{
@ -768,7 +732,7 @@ hb_buffer_destroy (hb_buffer_t *buffer)
* @buffer: An #hb_buffer_t
* @key: The user-data key
* @data: A pointer to the user data
* @destroy: (optional): A callback to call when @data is not needed anymore
* @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.
@ -795,7 +759,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
* Fetches the user data associated with the specified key,
* attached to the specified buffer.
*
* Return value: (transfer-none): A pointer to the user data
* Return value: (transfer none): A pointer to the user data
*
* Since: 0.9.2
**/
@ -1137,7 +1101,7 @@ hb_buffer_get_cluster_level (hb_buffer_t *buffer)
* 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
**/
@ -1222,6 +1186,9 @@ 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 ();
}
@ -1237,6 +1204,9 @@ 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 ();
}
@ -1321,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 */
@ -1501,20 +1471,20 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
*
* 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.
@ -1551,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
@ -1768,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;
@ -1784,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]));
@ -1902,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
@ -1994,11 +1967,11 @@ hb_buffer_diff (hb_buffer_t *buffer,
/**
* hb_buffer_set_message_func:
* @buffer: An #hb_buffer_t
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
* @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
@ -90,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 >*/
@ -150,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, \
@ -203,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,
@ -288,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 >*/
@ -579,6 +590,35 @@ hb_buffer_deserialize_unicode (hb_buffer_t *buffer,
* 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,
@ -618,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

@ -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,14 +332,14 @@ 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); }
void assert_glyphs ()
@ -349,7 +352,7 @@ struct hb_buffer_t
assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
}
bool ensure_glyphs ()
HB_NODISCARD bool ensure_glyphs ()
{
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
{
@ -360,7 +363,7 @@ struct hb_buffer_t
}
return true;
}
bool ensure_unicode ()
HB_NODISCARD bool ensure_unicode ()
{
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
{
@ -372,8 +375,8 @@ struct hb_buffer_t
return true;
}
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
HB_INTERNAL bool shift_forward (unsigned int count);
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

@ -675,8 +675,8 @@ hb_version_string ()
* Tests the library version against a minimum value,
* as three integer components.
*
* Return value: True if the library is equal to or greater than
* the test value, false otherwise
* Return value: %true if the library is equal to or greater than
* the test value, %false otherwise
*
* Since: 0.9.30
**/
@ -1003,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
*/
@ -1029,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
*/
@ -1055,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
*/
@ -1069,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
*/
@ -1083,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
*/
@ -1097,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
@ -135,7 +135,7 @@ typedef union _hb_var_int_t {
/**
* hb_tag_t:
*
*
* Data type for tag identifiers. Tags are four
* byte integers, each byte representing a character.
*
@ -148,22 +148,48 @@ 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 characters.
* 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 the characters from 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. */
@ -263,6 +289,13 @@ hb_direction_to_string (hb_direction_t direction);
/* 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
@ -271,6 +304,13 @@ 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
@ -279,160 +319,164 @@ hb_language_get_default (void);
/**
* hb_script_t:
* @HB_SCRIPT_COMMON: HB_TAG ('Z','y','y','y')
* @HB_SCRIPT_INHERITED: HB_TAG ('Z','i','n','h')
* @HB_SCRIPT_UNKNOWN: HB_TAG ('Z','z','z','z')
* @HB_SCRIPT_ARABIC
* @HB_SCRIPT_ARMENIAN
* @HB_SCRIPT_BENGALI
* @HB_SCRIPT_CYRILLIC
* @HB_SCRIPT_DEVANAGARI
* @HB_SCRIPT_GEORGIAN
* @HB_SCRIPT_GREEK
* @HB_SCRIPT_GUJARATI
* @HB_SCRIPT_GURMUKHI
* @HB_SCRIPT_HANGUL
* @HB_SCRIPT_HAN
* @HB_SCRIPT_HEBREW
* @HB_SCRIPT_HIRAGANA
* @HB_SCRIPT_KANNADA
* @HB_SCRIPT_KATAKANA
* @HB_SCRIPT_LAO
* @HB_SCRIPT_LATIN
* @HB_SCRIPT_MALAYALAM
* @HB_SCRIPT_ORIYA
* @HB_SCRIPT_TAMIL
* @HB_SCRIPT_TELUGU
* @HB_SCRIPT_THAI
* @HB_SCRIPT_TIBETAN
* @HB_SCRIPT_BOPOMOFO
* @HB_SCRIPT_BRAILLE
* @HB_SCRIPT_CANADIAN_SYLLABICS
* @HB_SCRIPT_CHEROKEE
* @HB_SCRIPT_ETHIOPIC
* @HB_SCRIPT_KHMER
* @HB_SCRIPT_MONGOLIAN
* @HB_SCRIPT_MYANMAR
* @HB_SCRIPT_OGHAM
* @HB_SCRIPT_RUNIC
* @HB_SCRIPT_SINHALA
* @HB_SCRIPT_SYRIAC
* @HB_SCRIPT_THAANA
* @HB_SCRIPT_YI
* @HB_SCRIPT_DESERET
* @HB_SCRIPT_GOTHIC
* @HB_SCRIPT_OLD_ITALIC
* @HB_SCRIPT_BUHID
* @HB_SCRIPT_HANUNOO
* @HB_SCRIPT_TAGALOG
* @HB_SCRIPT_TAGBANWA
* @HB_SCRIPT_CYPRIOT
* @HB_SCRIPT_LIMBU
* @HB_SCRIPT_LINEAR_B
* @HB_SCRIPT_OSMANYA
* @HB_SCRIPT_SHAVIAN
* @HB_SCRIPT_TAI_LE
* @HB_SCRIPT_UGARITIC
* @HB_SCRIPT_BUGINESE
* @HB_SCRIPT_COPTIC
* @HB_SCRIPT_GLAGOLITIC
* @HB_SCRIPT_KHAROSHTHI
* @HB_SCRIPT_NEW_TAI_LUE
* @HB_SCRIPT_OLD_PERSIAN
* @HB_SCRIPT_SYLOTI_NAGRI
* @HB_SCRIPT_TIFINAGH
* @HB_SCRIPT_BALINESE
* @HB_SCRIPT_CUNEIFORM
* @HB_SCRIPT_NKO
* @HB_SCRIPT_PHAGS_PA
* @HB_SCRIPT_PHOENICIAN
* @HB_SCRIPT_CARIAN
* @HB_SCRIPT_CHAM
* @HB_SCRIPT_KAYAH_LI
* @HB_SCRIPT_LEPCHA
* @HB_SCRIPT_LYCIAN
* @HB_SCRIPT_LYDIAN
* @HB_SCRIPT_OL_CHIKI
* @HB_SCRIPT_REJANG
* @HB_SCRIPT_SAURASHTRA
* @HB_SCRIPT_SUNDANESE
* @HB_SCRIPT_VAI
* @HB_SCRIPT_AVESTAN
* @HB_SCRIPT_BAMUM
* @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS
* @HB_SCRIPT_IMPERIAL_ARAMAIC
* @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI
* @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN
* @HB_SCRIPT_JAVANESE
* @HB_SCRIPT_KAITHI
* @HB_SCRIPT_LISU
* @HB_SCRIPT_MEETEI_MAYEK
* @HB_SCRIPT_OLD_SOUTH_ARABIAN
* @HB_SCRIPT_OLD_TURKIC
* @HB_SCRIPT_SAMARITAN
* @HB_SCRIPT_TAI_THAM
* @HB_SCRIPT_TAI_VIET
* @HB_SCRIPT_BATAK
* @HB_SCRIPT_BRAHMI
* @HB_SCRIPT_MANDAIC
* @HB_SCRIPT_CHAKMA
* @HB_SCRIPT_MEROITIC_CURSIVE
* @HB_SCRIPT_MEROITIC_HIEROGLYPHS
* @HB_SCRIPT_MIAO
* @HB_SCRIPT_SHARADA
* @HB_SCRIPT_SORA_SOMPENG
* @HB_SCRIPT_TAKRI
* @HB_SCRIPT_BASSA_VAH
* @HB_SCRIPT_CAUCASIAN_ALBANIAN
* @HB_SCRIPT_DUPLOYAN
* @HB_SCRIPT_ELBASAN
* @HB_SCRIPT_GRANTHA
* @HB_SCRIPT_KHOJKI
* @HB_SCRIPT_KHUDAWADI
* @HB_SCRIPT_LINEAR_A
* @HB_SCRIPT_MAHAJANI
* @HB_SCRIPT_MANICHAEAN
* @HB_SCRIPT_MENDE_KIKAKUI
* @HB_SCRIPT_MODI
* @HB_SCRIPT_MRO
* @HB_SCRIPT_NABATAEAN
* @HB_SCRIPT_OLD_NORTH_ARABIAN
* @HB_SCRIPT_OLD_PERMIC
* @HB_SCRIPT_PAHAWH_HMONG
* @HB_SCRIPT_PALMYRENE
* @HB_SCRIPT_PAU_CIN_HAU
* @HB_SCRIPT_PSALTER_PAHLAVI
* @HB_SCRIPT_SIDDHAM
* @HB_SCRIPT_TIRHUTA
* @HB_SCRIPT_WARANG_CITI
* @HB_SCRIPT_AHOM
* @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS
* @HB_SCRIPT_HATRAN
* @HB_SCRIPT_MULTANI
* @HB_SCRIPT_OLD_HUNGARIAN
* @HB_SCRIPT_SIGNWRITING
* @HB_SCRIPT_ADLAM
* @HB_SCRIPT_BHAIKSUKI
* @HB_SCRIPT_MARCHEN
* @HB_SCRIPT_OSAGE
* @HB_SCRIPT_TANGUT
* @HB_SCRIPT_NEWA
* @HB_SCRIPT_MASARAM_GONDI
* @HB_SCRIPT_NUSHU
* @HB_SCRIPT_SOYOMBO
* @HB_SCRIPT_ZANABAZAR_SQUARE
* @HB_SCRIPT_DOGRA
* @HB_SCRIPT_GUNJALA_GONDI
* @HB_SCRIPT_HANIFI_ROHINGYA
* @HB_SCRIPT_MAKASAR
* @HB_SCRIPT_MEDEFAIDRIN
* @HB_SCRIPT_OLD_SOGDIAN
* @HB_SCRIPT_SOGDIAN
* @HB_SCRIPT_ELYMAIC
* @HB_SCRIPT_NANDINAGARI
* @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG
* @HB_SCRIPT_WANCHO
* @HB_SCRIPT_INVALID: #HB_TAG_NONE
* @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/).
@ -441,208 +485,208 @@ hb_language_get_default (void);
*
**/
/* 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.
@ -687,19 +731,33 @@ typedef struct hb_user_data_key_t {
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
*/
@ -717,7 +775,7 @@ typedef void (*hb_destroy_func_t) (void *user_data);
* 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 {
@ -741,8 +799,8 @@ hb_feature_to_string (hb_feature_t *feature,
* @value: The value of the variation axis
*
* Data type for holding variation data. Registered OpenType
* variation-axis tags are listed at
* https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg
* variation-axis tags are listed in
* [OpenType Axis Tag Registry](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg).
*
* Since: 1.4.2
*/
@ -769,6 +827,17 @@ hb_variation_to_string (hb_variation_t *variation,
*/
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_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_func_t) (hb_unicode_
/**
* 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

@ -957,6 +957,8 @@ _hb_directwrite_font_release (void *data)
* hb_directwrite_face_create:
* @font_face: a DirectWrite IDWriteFontFace object.
*
* Constructs a new face object from the specified DirectWrite IDWriteFontFace.
*
* Return value: #hb_face_t object corresponding to the given input
*
* Since: 2.4.0
@ -974,6 +976,8 @@ hb_directwrite_face_create (IDWriteFontFace *font_face)
* hb_directwrite_face_get_font_face:
* @face: a #hb_face_t object
*
* Gets the DirectWrite IDWriteFontFace associated with @face.
*
* Return value: DirectWrite IDWriteFontFace object corresponding to the given input
*
* Since: 2.5.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

@ -89,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. */
};
@ -100,7 +100,7 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
* hb_face_create_for_tables:
* @reference_table_func: (closure user_data) (destroy destroy) (scope notified): Table-referencing function
* @user_data: A pointer to the user data
* @destroy: (optional): A callback to call when @data is not needed anymore
* @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
@ -235,7 +235,7 @@ hb_face_create (hb_blob_t *blob,
*
* Fetches the singleton empty face object.
*
* Return value: (transfer full) The empty face object
* Return value: (transfer full): The empty face object
*
* Since: 0.9.2
**/
@ -299,7 +299,7 @@ hb_face_destroy (hb_face_t *face)
* @face: A face object
* @key: The user-data key to set
* @data: A pointer to the user data
* @destroy: (optional): A callback to call when @data is not needed anymore
* @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.
@ -360,7 +360,7 @@ hb_face_make_immutable (hb_face_t *face)
*
* Tests whether the given face object is immutable.
*
* Return value: True is @face is immutable, false otherwise
* Return value: %true is @face is immutable, %false otherwise
*
* Since: 0.9.2
**/
@ -756,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
@ -58,6 +58,19 @@ 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))

View file

@ -628,7 +628,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
* @ffuncs: The font-functions structure
* @key: The user-data key to set
* @data: A pointer to the user data set
* @destroy: (optional): A callback to call when @data is not needed anymore
* @destroy: (nullable): A callback to call when @data is not needed anymore
* @replace: Whether to replace an existing data with the same key
*
* Attaches a user-data key/data pair to the specified font-functions structure.
@ -690,7 +690,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
*
* Tests whether a font-functions structure is immutable.
*
* Return value: %true if @ffuncs is immutable, false otherwise
* Return value: %true if @ffuncs is immutable, %false otherwise
*
* Since: 0.9.2
**/
@ -753,10 +753,10 @@ hb_font_t::has_func (unsigned int i)
* @font: #hb_font_t to work upon
* @extents: (out): The font extents retrieved
*
* Fetches the extents for a specified font, in horizontal
* Fetches the extents for a specified font, for horizontal
* text segments.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 1.1.3
**/
@ -772,10 +772,10 @@ hb_font_get_h_extents (hb_font_t *font,
* @font: #hb_font_t to work upon
* @extents: (out): The font extents retrieved
*
* Fetches the extents for a specified font, in vertical
* Fetches the extents for a specified font, for vertical
* text segments.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 1.1.3
**/
@ -790,7 +790,7 @@ hb_font_get_v_extents (hb_font_t *font,
* hb_font_get_glyph:
* @font: #hb_font_t to work upon
* @unicode: The Unicode code point to query
* @variation_selector: (optional): A variation-selector code point
* @variation_selector: A variation-selector code point
* @glyph: (out): The glyph ID retrieved
*
* Fetches the glyph ID for a Unicode code point in the specified
@ -799,7 +799,7 @@ hb_font_get_v_extents (hb_font_t *font,
* If @variation_selector is 0, calls hb_font_get_nominal_glyph();
* otherwise calls hb_font_get_variation_glyph().
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -827,7 +827,7 @@ hb_font_get_glyph (hb_font_t *font,
* for code points modified by variation selectors. For variation-selector
* support, user hb_font_get_variation_glyph() or use hb_font_get_glyph().
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 1.2.3
**/
@ -841,11 +841,17 @@ hb_font_get_nominal_glyph (hb_font_t *font,
/**
* hb_font_get_nominal_glyphs:
* @font: a font.
* @font: #hb_font_t to work upon
* @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
*
* Fetches 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:
* Return value: the number of code points processed
*
* Since: 2.6.3
**/
@ -873,7 +879,7 @@ hb_font_get_nominal_glyphs (hb_font_t *font,
* by the specified variation-selector code point, in the specified
* font.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 1.2.3
**/
@ -931,7 +937,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
* @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: (out): The stride between successive advances
* @advance_stride: The stride between successive advances
*
* Fetches the advances for a sequence of glyph IDs in the specified
* font, for horizontal text segments.
@ -983,7 +989,7 @@ hb_font_get_glyph_v_advances (hb_font_t* font,
* Fetches the (X,Y) coordinates of the origin for a glyph ID
* in the specified font, for horizontal text segments.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1006,7 +1012,7 @@ hb_font_get_glyph_h_origin (hb_font_t *font,
* Fetches the (X,Y) coordinates of the origin for a glyph ID
* in the specified font, for vertical text segments.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1026,7 +1032,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
* @right_glyph: The glyph ID of the right glyph in the glyph pair
*
* Fetches the kerning-adjustment value for a glyph-pair in
* the specified font, in horizontal text segments.
* the specified font, for horizontal text segments.
*
* <note>It handles legacy kerning only (as returned by the corresponding
* #hb_font_funcs_t function).</note>
@ -1051,7 +1057,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
* @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair
*
* Fetches the kerning-adjustment value for a glyph-pair in
* the specified font, in vertical text segments.
* the specified font, for vertical text segments.
*
* <note>It handles legacy kerning only (as returned by the corresponding
* #hb_font_funcs_t function).</note>
@ -1079,7 +1085,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font,
* Fetches the #hb_glyph_extents_t data for a glyph ID
* in the specified font.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1102,7 +1108,7 @@ hb_font_get_glyph_extents (hb_font_t *font,
* Fetches the (x,y) coordinates of a specified contour-point index
* in the specified glyph, within the specified font.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1125,7 +1131,7 @@ hb_font_get_glyph_contour_point (hb_font_t *font,
*
* Fetches the glyph-name string for a glyph ID in the specified @font.
*
* Return value: %true if data found, zero otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1149,7 +1155,7 @@ hb_font_get_glyph_name (hb_font_t *font,
*
* <note>Note: @len == -1 means the name string is null-terminated.</note>
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1169,7 +1175,7 @@ hb_font_get_glyph_from_name (hb_font_t *font,
* hb_font_get_extents_for_direction:
* @font: #hb_font_t to work upon
* @direction: The direction of the text segment
* @extents: (out): The #hb_glyph_extents_t retrieved
* @extents: (out): The #hb_font_extents_t retrieved
*
* Fetches the extents for a font in a text segment of the
* specified direction.
@ -1364,7 +1370,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
* Calls the appropriate direction-specific variant (horizontal
* or vertical) depending on the value of @direction.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1393,7 +1399,7 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font,
* Calls the appropriate direction-specific variant (horizontal
* or vertical) depending on the value of @direction.
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1444,7 +1450,7 @@ hb_font_glyph_to_string (hb_font_t *font,
*
* <note>Note: @len == -1 means the string is null-terminated.</note>
*
* Return value: %true if data found, false otherwise
* Return value: %true if data found, %false otherwise
*
* Since: 0.9.2
**/
@ -1664,12 +1670,12 @@ hb_font_destroy (hb_font_t *font)
* @font: #hb_font_t to work upon
* @key: The user-data key
* @data: A pointer to the user data
* @destroy: (optional): A callback to call when @data is not needed anymore
* @destroy: (nullable): A callback to call when @data is not needed anymore
* @replace: Whether to replace an existing data with the same key
*
* Attaches a user-data key/data pair to the specified font object.
*
* Return value:
* Return value: %true if success, %false otherwise
*
* Since: 0.9.2
**/
@ -1728,7 +1734,7 @@ hb_font_make_immutable (hb_font_t *font)
*
* Tests whether a font object is immutable.
*
* Return value: %true if @font is immutable, false otherwise
* Return value: %true if @font is immutable, %false otherwise
*
* Since: 0.9.2
**/
@ -1828,9 +1834,9 @@ hb_font_get_face (hb_font_t *font)
/**
* hb_font_set_funcs:
* @font: #hb_font_t to work upon
* @klass: (closure font_data) (destroy destroy) (scope notified):
* @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure.
* @font_data: Data to attach to @font
* @destroy: (optional): The function to call when @font_data is not needed anymore
* @destroy: (nullable): The function to call when @font_data is not needed anymore
*
* Replaces the font-functions structure attached to a font, updating
* the font's user-data with @font-data and the @destroy callback.
@ -1867,7 +1873,7 @@ hb_font_set_funcs (hb_font_t *font,
* hb_font_set_funcs_data:
* @font: #hb_font_t to work upon
* @font_data: (destroy destroy) (scope notified): Data to attach to @font
* @destroy: (optional): The function to call when @font_data is not needed anymore
* @destroy: (nullable): The function to call when @font_data is not needed anymore
*
* Replaces the user data attached to a font, updating the font's
* @destroy callback.
@ -2212,10 +2218,14 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
#ifdef HB_EXPERIMENTAL_API
/**
* hb_font_get_var_coords_design:
* @font: #hb_font_t to work upon
* @length: (out): number of coordinates
*
* Return value is valid as long as variation coordinates of the font
* are not modified.
*
* Return value: coordinates array
*
* Since: EXPERIMENTAL
*/
const float *
@ -2319,7 +2329,7 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font,
* @ffuncs: The font-functions structure
* @func: (closure user_data) (destroy destroy) (scope notified): callback function
* @user_data: data to pass to @func
* @destroy: (optional): function to call when @user_data is not needed anymore
* @destroy: (nullable): function to call when @user_data is not needed anymore
*
* Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and
* hb_font_funcs_set_variation_glyph_func() instead.

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;
@ -141,6 +146,16 @@ typedef struct 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);
@ -150,7 +165,7 @@ typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *fon
*
* A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
*
* This method should retrieve the extents for a font, in horizontal-direction
* 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.
*
@ -162,7 +177,7 @@ typedef hb_font_get_font_extents_func_t 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, in vertical-direction
* 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.
*
@ -172,12 +187,19 @@ 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,
@ -186,6 +208,12 @@ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *fo
/**
* 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.
*
@ -193,6 +221,8 @@ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *fo
* 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,
@ -202,12 +232,22 @@ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *
/**
* 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,
@ -220,12 +260,18 @@ typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void
/**
* 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,
@ -257,6 +303,14 @@ 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.
*
@ -295,12 +349,20 @@ 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,
@ -314,7 +376,7 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon
* 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, in horizontal-direction text segments. Each
* origin for a glyph, for horizontal-direction text segments. Each
* coordinate must be returned in an #hb_position_t output parameter.
*
**/
@ -326,25 +388,53 @@ typedef hb_font_get_glyph_origin_func_t 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, in vertical-direction text segments. Each coordinate
* 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,
@ -354,6 +444,13 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo
/**
* 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.
*
@ -361,6 +458,8 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo
* 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,
@ -370,12 +469,20 @@ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, vo
/**
* 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,
@ -384,12 +491,20 @@ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_
/**
* 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 */
@ -404,7 +519,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -420,7 +535,7 @@ hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -436,7 +551,7 @@ hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -452,7 +567,7 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -468,7 +583,7 @@ hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -484,7 +599,7 @@ hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -500,7 +615,7 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -516,7 +631,7 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -532,7 +647,7 @@ hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -548,7 +663,7 @@ hb_font_funcs_set_glyph_v_advances_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -564,7 +679,7 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -577,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
**/
@ -596,7 +711,7 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -612,7 +727,7 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -628,7 +743,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*
@ -644,7 +759,7 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
* @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: (optional): The function to call when @user_data is not needed anymore
* @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.
*

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: (optional): 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

@ -70,6 +70,8 @@ fail:
* hb_gdi_face_create:
* @hfont: a HFONT object.
*
* Constructs a new face object from the specified GDI HFONT.
*
* Return value: #hb_face_t object corresponding to the given input
*
* Since: 2.6.0

View file

@ -24,7 +24,7 @@
* Google Author(s): Behdad Esfahbod
*/
#ifndef HB_GOBJECT_H_IN
#if !defined(HB_GOBJECT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR)
#error "Include <hb-gobject.h> instead."
#endif
@ -40,47 +40,22 @@ HB_BEGIN_DECLS
/* Object types */
/**
* hb_gobject_blob_get_type:
*
* Since: 0.9.2
**/
HB_EXTERN GType
hb_gobject_blob_get_type (void);
#define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ())
/**
* hb_gobject_buffer_get_type:
*
* Since: 0.9.2
**/
HB_EXTERN GType
hb_gobject_buffer_get_type (void);
#define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ())
/**
* hb_gobject_face_get_type:
*
* Since: 0.9.2
**/
HB_EXTERN GType
hb_gobject_face_get_type (void);
#define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
/**
* hb_gobject_font_get_type:
*
* Since: 0.9.2
**/
HB_EXTERN GType
hb_gobject_font_get_type (void);
#define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ())
/**
* hb_gobject_font_funcs_get_type:
*
* Since: 0.9.2
**/
HB_EXTERN GType
hb_gobject_font_funcs_get_type (void);
#define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ())
@ -97,11 +72,6 @@ HB_EXTERN GType
hb_gobject_shape_plan_get_type (void);
#define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ())
/**
* hb_gobject_unicode_funcs_get_type:
*
* Since: 0.9.2
**/
HB_EXTERN GType
hb_gobject_unicode_funcs_get_type (void);
#define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ())

View file

@ -195,6 +195,11 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_graphite2_font_get_gr_font:
* @font: An #hb_font_t
*
* Always returns %NULL. Use hb_graphite2_face_get_gr_face() instead.
*
* Return value: (nullable): Graphite2 font associated with @font.
*
* Since: 0.9.10
* Deprecated: 1.4.2
@ -284,7 +289,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
return true;
}
buffer->ensure (glyph_count);
(void) buffer->ensure (glyph_count);
scratch = buffer->get_scratch_buffer (&scratch_size);
while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) +
DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size)

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

@ -117,7 +117,7 @@ hb_map_destroy (hb_map_t *map)
* @map: A map
* @key: The user-data key to set
* @data: A pointer to the user data to set
* @destroy: (optional): A callback to call when @data is not needed anymore
* @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 map.
@ -162,7 +162,7 @@ hb_map_get_user_data (hb_map_t *map,
*
* Tests whether memory allocation for a set was successful.
*
* Return value: %true if allocation succeeded, false otherwise
* Return value: %true if allocation succeeded, %false otherwise
*
* Since: 1.7.7
**/
@ -230,7 +230,7 @@ hb_map_del (hb_map_t *map,
*
* Tests whether @key is an element of @map.
*
* Return value: %true if @key is found in @map, false otherwise
* Return value: %true if @key is found in @map, %false otherwise
*
* Since: 1.7.7
**/
@ -253,6 +253,9 @@ hb_map_has (const hb_map_t *map,
void
hb_map_clear (hb_map_t *map)
{
if (unlikely (hb_object_is_immutable (map)))
return;
return map->clear ();
}

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,7 +36,11 @@
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)

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<unsigne
#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

@ -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);
};

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,6 +97,8 @@ 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.
*

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,6 +87,13 @@ 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

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

@ -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;
}

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 {}
@ -1860,8 +1882,8 @@ 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;
int non_zero_index = 0, index = 0;
for (const hb_pair_t<unsigned, const OffsetTo<RuleSet>&> _ : + hb_enumerate (ruleSet)
| hb_filter (klass_map, hb_first))
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

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,7 +1202,7 @@ 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
@ -1243,7 +1254,7 @@ 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 coordinates
* @variations_index: (out): The array of feature variations found for the query
@ -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;
}
@ -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

@ -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

@ -119,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
@ -193,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
**/
@ -208,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
**/
@ -223,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

View file

@ -177,15 +177,14 @@ struct OS2
if (!c->plan->glyphs_requested->is_empty ())
{
hb_map_t unicode_glyphid_map;
OT::cmap::accelerator_t cmap;
cmap.init (c->plan->source);
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)
| hb_map (hb_first)

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,69 +948,6 @@ 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,
@ -1008,11 +955,16 @@ initial_reordering_indic (const hb_ot_shape_plan_t *plan,
{
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");
}

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[] = {
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
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 char _khmer_syllable_machine_trans_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
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, 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_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
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, 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_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
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
};
static const unsigned 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
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
};
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, 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,156 +183,271 @@ 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;
#line 242 "hb-ot-shape-complex-khmer-machine.hh"
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
#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"
p = 0;
pe = eof = buffer->len;
unsigned int syllable_serial = 1;
#line 258 "hb-ot-shape-complex-khmer-machine.hh"
#line 106 "hb-ot-shape-complex-khmer-machine.rl"
p = 0;
pe = eof = buffer->len;
unsigned int syllable_serial = 1;
#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"
}
_keys = _khmer_syllable_machine_trans_keys + (cs<<1);
_inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs];
_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];
if ( _khmer_syllable_machine_trans_actions[_trans] == 0 )
goto _again;
switch ( _khmer_syllable_machine_trans_actions[_trans] ) {
case 2:
{ts = p;}}
#line 241 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
}
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]));
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"
}
_again:
switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
case 6:
{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;}
break;
#line 351 "hb-ot-shape-complex-khmer-machine.hh"
{ts = 0;}}
#line 437 "hb-ot-shape-complex-khmer-machine.hh"
break;
}
}
p += 1;
goto _resume;
}
_out: {}
}
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"
}
#undef found_syllable

View file

@ -1,113 +0,0 @@
/*
* 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"
%%{
machine khmer_syllable_machine;
alphtype unsigned char;
write data;
}%%
%%{
# Same order as enum khmer_category_t. Not sure how to avoid duplication.
C = 1;
V = 2;
ZWNJ = 5;
ZWJ = 6;
PLACEHOLDER = 11;
DOTTEDCIRCLE = 12;
Coeng= 14;
Ra = 16;
Robatic = 20;
Xgroup = 21;
Ygroup = 22;
VAbv = 26;
VBlw = 27;
VPre = 28;
VPst = 29;
c = (C | Ra | V);
cn = c.((ZWJ|ZWNJ)?.Robatic)?;
joiner = (ZWJ | ZWNJ);
xgroup = (joiner*.Xgroup)*;
ygroup = Ygroup*;
# This grammar was experimentally extracted from what Uniscribe allows.
matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?;
syllable_tail = xgroup matra_group xgroup (Coeng.c)? ygroup;
broken_cluster = (Coeng.cn)* (Coeng | syllable_tail);
consonant_syllable = (cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster;
other = any;
main := |*
consonant_syllable => { found_syllable (consonant_syllable); };
broken_cluster => { found_syllable (broken_cluster); };
other => { found_syllable (non_khmer_cluster); };
*|;
}%%
#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
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;
%%{
write init;
getkey info[p].khmer_category();
}%%
p = 0;
pe = eof = buffer->len;
unsigned int syllable_serial = 1;
%%{
write exec;
}%%
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

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,76 +290,17 @@ 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)
{
if (buffer->message (font, "start reordering khmer")) {
insert_dotted_circles_khmer (plan, font, buffer);
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);

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

@ -1,69 +0,0 @@
/*
* Copyright © 2019,2020 David Corbett
*
* 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_MACHINE_INDEX_HH
#define HB_OT_SHAPE_COMPLEX_MACHINE_INDEX_HH
#include "hb.hh"
template <typename Iter>
struct machine_index_t :
hb_iter_with_fallback_t<machine_index_t<Iter>,
typename Iter::item_t>
{
machine_index_t (const Iter& it) : it (it) {}
machine_index_t (const machine_index_t& o) : it (o.it) {}
static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
typename Iter::item_t __item__ () const { return *it; }
typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; }
unsigned __len__ () const { return it.len (); }
void __next__ () { ++it; }
void __forward__ (unsigned n) { it += n; }
void __prev__ () { --it; }
void __rewind__ (unsigned n) { it -= n; }
void operator = (unsigned n)
{ unsigned index = (*it).first; if (index < n) it += n - index; else if (index > n) it -= index - n; }
void operator = (const machine_index_t& o) { *this = (*o.it).first; }
bool operator == (const machine_index_t& o) const { return (*it).first == (*o.it).first; }
bool operator != (const machine_index_t& o) const { return !(*this == o); }
private:
Iter it;
};
struct
{
template <typename Iter,
hb_requires (hb_is_iterable (Iter))>
machine_index_t<hb_iter_type<Iter>>
operator () (Iter&& it) const
{ return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); }
}
HB_FUNCOBJ (machine_index);
#endif /* HB_OT_SHAPE_COMPLEX_MACHINE_INDEX_HH */

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,17 +98,6 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
}
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,
@ -265,70 +255,16 @@ 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)
{
if (buffer->message (font, "start reordering myanmar")) {
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);

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;

File diff suppressed because it is too large Load diff

View file

@ -31,56 +31,57 @@
* 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 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
#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
@ -767,7 +768,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11710 */ B, B, B, B, B, B, B, B, B, B, B, O, O, MBlw, MPre, MAbv,
/* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VMAbv, O, O, O, O,
/* 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 5848
@ -1066,7 +1067,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
}; /* Table items: 8824; occupancy: 79% */
USE_TABLE_ELEMENT_TYPE
static inline uint8_t
hb_use_get_category (hb_codepoint_t u)
{
switch (u >> 12)
@ -1154,7 +1155,7 @@ hb_use_get_category (hb_codepoint_t u)
default:
break;
}
return USE_O;
return USE(O);
}
#undef B
@ -1198,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,22 +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_hieroglyph_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,
@ -239,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;
}
@ -253,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++)
{
@ -267,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)
{
@ -279,7 +261,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
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:
@ -289,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];
@ -336,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;
}
}
@ -359,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;
}
}
@ -368,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);
}
@ -387,24 +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_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. */
@ -441,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)
@ -454,76 +436,22 @@ 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)
{
if (buffer->message (font, "start reordering USE")) {
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");
(void) buffer->message (font, "end reordering USE");
}
HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);

View file

@ -1,96 +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_N = 4, /* BASE_NUM */
USE_GB = 5, /* BASE_OTHER */
USE_SUB = 11, /* CONS_SUB */
USE_H = 12, /* HALANT */
USE_HN = 13, /* HALANT_NUM */
USE_ZWNJ = 14, /* Zero width non-joiner */
USE_R = 18, /* REPHA */
USE_S = 19, /* SYM */
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_G = 49, /* HIEROGLYPH */
USE_J = 50, /* HIEROGLYPH_JOINER */
USE_SB = 51, /* HIEROGLYPH_SEGMENT_BEGIN */
USE_SE = 52, /* HIEROGLYPH_SEGMENT_END */
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:
@ -326,10 +316,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_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,7 +319,7 @@ 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:
@ -351,10 +333,10 @@ 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:
@ -363,7 +345,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
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:
@ -376,11 +358,11 @@ 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_MEDEFAIDRIN:
case HB_SCRIPT_OLD_SOGDIAN:
//case HB_SCRIPT_SOGDIAN:
case HB_SCRIPT_SOGDIAN:
/* Unicode-12.0 additions */
case HB_SCRIPT_ELYMAIC:

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);
@ -419,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))
{
@ -428,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.
@ -451,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. */
@ -466,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 ();
}

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

View file

@ -6,8 +6,8 @@
*
* on files with these headers:
*
* <meta name="updated_at" content="2020-11-17 08:21 AM" />
* File-Date: 2020-09-29
* <meta name="updated_at" content="2021-02-12 04:08 PM" />
* File-Date: 2021-03-05
*/
#ifndef HB_OT_TAG_TABLE_HH
@ -169,6 +169,7 @@ static const LangTag ot_languages[] = {
{"bko", HB_TAG('B','M','L',' ')}, /* Kwa' -> Bamileke */
{"bla", HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */
{"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */
{"blg", HB_TAG('I','B','A',' ')}, /* Balau (retired code) -> Iban */
{"bli", HB_TAG_NONE }, /* Bolia != Baluchi */
{"blk", HB_TAG('B','L','K',' ')}, /* Pao Karen */
{"blk", HB_TAG('K','R','N',' ')}, /* Pa'o Karen -> Karen */
@ -358,6 +359,7 @@ static const LangTag ot_languages[] = {
{"czo", HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese, Simplified */
{"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin -> Chin */
{"da", HB_TAG('D','A','N',' ')}, /* Danish */
/*{"dag", HB_TAG('D','A','G',' ')},*/ /* Dagbani */
{"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */
/*{"dar", HB_TAG('D','A','R',' ')},*/ /* Dargwa */
@ -834,6 +836,7 @@ static const LangTag ot_languages[] = {
{"lri", HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */
{"lrm", HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */
{"lrt", HB_TAG('C','P','P',' ')}, /* Larantuka Malay -> Creoles */
{"lsb", HB_TAG_NONE }, /* Burundian Sign Language != Lower Sorbian */
{"lsm", HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */
{"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
{"ltg", HB_TAG('L','V','I',' ')}, /* Latgalian -> Latvian */
@ -990,7 +993,7 @@ static const LangTag ot_languages[] = {
/*{"nga", HB_TAG('N','G','A',' ')},*/ /* Ngbaka */
{"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
{"ngm", HB_TAG('C','P','P',' ')}, /* Ngatik Men's Creole -> Creoles */
{"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni -> Sutu */
{"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni (retired code) -> Sutu */
{"ngr", HB_TAG_NONE }, /* Engdewu != Nagari */
{"ngu", HB_TAG('N','A','H',' ')}, /* Guerrero Nahuatl -> Nahuatl */
{"nhc", HB_TAG('N','A','H',' ')}, /* Tabasco Nahuatl -> Nahuatl */
@ -1520,6 +1523,8 @@ static const LangTag ot_languages[] = {
{"xmm", HB_TAG('C','P','P',' ')}, /* Manado Malay -> Creoles */
{"xmv", HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */
{"xmw", HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */
{"xnj", HB_TAG('S','X','T',' ')}, /* Ngoni (Tanzania) -> Sutu */
{"xnq", HB_TAG('S','X','T',' ')}, /* Ngoni (Mozambique) -> Sutu */
{"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri (macrolanguage) */
/*{"xog", HB_TAG('X','O','G',' ')},*/ /* Soga */
{"xpe", HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */
@ -2808,6 +2813,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
return hb_language_from_string ("hnd", -1); /* Southern Hindko */
case HB_TAG('H','Y','E',' '): /* Armenian */
return hb_language_from_string ("hyw", -1); /* Western Armenian */
case HB_TAG('I','B','A',' '): /* Iban */
return hb_language_from_string ("iba", -1); /* Iban */
case HB_TAG('I','J','O',' '): /* Ijo */
return hb_language_from_string ("ijo", -1); /* Ijo [family] */
case HB_TAG('I','N','U',' '): /* Inuktitut */
@ -2892,6 +2899,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */
case HB_TAG('S','R','B',' '): /* Serbian */
return hb_language_from_string ("sr", -1); /* Serbian */
case HB_TAG('S','X','T',' '): /* Sutu */
return hb_language_from_string ("xnj", -1); /* Ngoni (Tanzania) */
case HB_TAG('S','Y','R',' '): /* Syriac */
return hb_language_from_string ("syr", -1); /* Syriac [macrolanguage] */
case HB_TAG('S','Y','R','E'): /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */

View file

@ -164,6 +164,15 @@ hb_ot_all_tags_from_script (hb_script_t script,
*count = i;
}
/**
* hb_ot_tag_to_script:
* @tag: a script tag
*
* Converts a script tag to an #hb_script_t.
*
* Return value: The #hb_script_t corresponding to @tag.
*
**/
hb_script_t
hb_ot_tag_to_script (hb_tag_t tag)
{
@ -351,13 +360,13 @@ parse_private_use_subtag (const char *private_use_subtag,
* hb_ot_tags_from_script_and_language:
* @script: an #hb_script_t to convert.
* @language: an #hb_language_t to convert.
* @script_count: (allow-none): maximum number of script tags to retrieve (IN)
* @script_count: (inout) (optional): maximum number of script tags to retrieve (IN)
* and actual number of script tags retrieved (OUT)
* @script_tags: (out) (allow-none): array of size at least @script_count to store the
* @script_tags: (out) (optional): array of size at least @script_count to store the
* script tag results
* @language_count: (allow-none): maximum number of language tags to retrieve
* @language_count: (inout) (optional): maximum number of language tags to retrieve
* (IN) and actual number of language tags retrieved (OUT)
* @language_tags: (out) (allow-none): array of size at least @language_count to store
* @language_tags: (out) (optional): array of size at least @language_count to store
* the language tag results
*
* Converts an #hb_script_t and an #hb_language_t to script and language tags.
@ -424,10 +433,12 @@ hb_ot_tags_from_script_and_language (hb_script_t script,
/**
* hb_ot_tag_to_language:
* @tag: an language tag
*
* Converts a language tag to an #hb_language_t.
*
*
* Return value: (transfer none):
* Return value: (transfer none) (nullable):
* The #hb_language_t corresponding to @tag.
*
* Since: 0.9.2
**/
@ -478,9 +489,9 @@ hb_ot_tag_to_language (hb_tag_t tag)
* hb_ot_tags_to_script_and_language:
* @script_tag: a script tag
* @language_tag: a language tag
* @script: (allow-none): the #hb_script_t corresponding to @script_tag (OUT).
* @language: (allow-none): the #hb_language_t corresponding to @script_tag and
* @language_tag (OUT).
* @script: (out) (optional): the #hb_script_t corresponding to @script_tag.
* @language: (out) (optional): the #hb_language_t corresponding to @script_tag and
* @language_tag.
*
* Converts a script tag and a language tag to an #hb_script_t and an
* #hb_language_t.

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