27 #ifndef HB_AAT_LAYOUT_MORX_TABLE_HH
28 #define HB_AAT_LAYOUT_MORX_TABLE_HH
41 #define HB_AAT_TAG_morx HB_TAG('m','o','r','x')
42 #define HB_AAT_TAG_mort HB_TAG('m','o','r','t')
49 template <
typename Types>
52 typedef typename Types::HBUINT
HBUINT;
58 static constexpr
bool in_place =
true;
88 if (
flags & MarkFirst)
100 const unsigned char map[16] =
121 unsigned int l = hb_min (2u,
m >> 4);
122 unsigned int r = hb_min (2u,
m & 0x0F);
123 bool reverse_l = 3 == (
m >> 4);
124 bool reverse_r = 3 == (
m & 0x0F);
189 template <
typename Types>
206 static constexpr
bool in_place =
true;
210 DontAdvance = 0x4000,
219 gdef (*
c->gdef_table),
221 has_glyph_classes (gdef.has_glyph_classes ()),
234 return entry.data.markIndex != 0xFFFF ||
entry.data.currentIndex != 0xFFFF;
248 replacement =
nullptr;
251 if (
entry.data.markIndex != 0xFFFF)
261 replacement = &subs_old[Types::wordOffsetToIndex (
offset,
table, subs_old.
arrayZ)];
262 if (!replacement->
sanitize (&
c->sanitizer) || !*replacement)
263 replacement =
nullptr;
268 buffer->info[mark].codepoint = *replacement;
269 if (has_glyph_classes)
270 _hb_glyph_info_set_glyph_props (&
buffer->info[mark],
271 gdef.get_glyph_props (*replacement));
275 replacement =
nullptr;
279 if (
entry.data.currentIndex != 0xFFFF)
289 replacement = &subs_old[Types::wordOffsetToIndex (
offset,
table, subs_old.
arrayZ)];
290 if (!replacement->
sanitize (&
c->sanitizer) || !*replacement)
291 replacement =
nullptr;
295 buffer->info[
idx].codepoint = *replacement;
296 if (has_glyph_classes)
297 _hb_glyph_info_set_glyph_props (&
buffer->info[
idx],
298 gdef.get_glyph_props (*replacement));
302 if (
entry.flags & SetMark)
315 bool has_glyph_classes;
337 unsigned int num_entries = 0;
340 if (!Types::extended)
343 unsigned int num_lookups = 0;
346 for (
unsigned int i = 0;
i < num_entries;
i++)
350 if (
data.markIndex != 0xFFFF)
351 num_lookups = hb_max (num_lookups, 1u +
data.markIndex);
352 if (
data.currentIndex != 0xFFFF)
353 num_lookups = hb_max (num_lookups, 1u +
data.currentIndex);
356 return_trace (substitutionTables.sanitize (
c,
this, num_lookups));
369 template <
bool extended>
377 SetComponent = 0x8000,
379 DontAdvance = 0x4000,
381 PerformAction = 0x2000,
396 {
return entry.flags & PerformAction; }
399 {
return entry.data.ligActionIndex; }
406 SetComponent = 0x8000,
408 DontAdvance = 0x4000,
425 template <
typename Types>
435 static constexpr
bool in_place =
false;
438 DontAdvance = LigatureEntryT::DontAdvance,
442 LigActionLast = 0x80000000,
444 LigActionStore = 0x40000000,
447 LigActionOffset = 0x3FFFFFFF,
465 return LigatureEntryT::performAction (
entry);
473 if (
entry.flags & LigatureEntryT::SetComponent)
476 if (match_length && match_positions[(match_length - 1u) %
ARRAY_LENGTH (match_positions)] ==
buffer->out_len)
483 if (LigatureEntryT::performAction (
entry))
485 DEBUG_MSG (APPLY,
nullptr,
"Perform action with %u", match_length);
494 unsigned int cursor = match_length;
496 unsigned int action_idx = LigatureEntryT::ligActionIndex (
entry);
497 action_idx = Types::offsetToIndex (action_idx,
table, ligAction.arrayZ);
498 const HBUINT32 *actionData = &ligAction[action_idx];
500 unsigned int ligature_idx = 0;
507 DEBUG_MSG (APPLY,
nullptr,
"Stack underflow");
518 uint32_t uoffset =
action & LigActionOffset;
519 if (uoffset & 0x20000000)
520 uoffset |= 0xC0000000;
521 int32_t
offset = (int32_t) uoffset;
522 unsigned int component_idx =
buffer->cur().codepoint +
offset;
523 component_idx = Types::wordOffsetToIndex (component_idx,
table, component.arrayZ);
524 const HBUINT16 &componentData = component[component_idx];
526 ligature_idx += componentData;
528 DEBUG_MSG (APPLY,
nullptr,
"Action store %u last %u",
529 bool (
action & LigActionStore),
530 bool (
action & LigActionLast));
531 if (
action & (LigActionStore | LigActionLast))
533 ligature_idx = Types::offsetToIndex (ligature_idx,
table, ligature.arrayZ);
534 const HBGlyphID16 &ligatureData = ligature[ligature_idx];
538 DEBUG_MSG (APPLY,
nullptr,
"Produced ligature %u", lig);
541 unsigned int lig_end = match_positions[(match_length - 1u) %
ARRAY_LENGTH (match_positions)] + 1u;
543 while (match_length - 1u >
cursor)
545 DEBUG_MSG (APPLY,
nullptr,
"Skipping ligature component");
556 while (!(
action & LigActionLast));
569 unsigned int match_length;
590 ligAction && component && ligature);
606 template <
typename Types>
617 unsigned int num_glyphs =
c->face->get_num_glyphs ();
620 unsigned int count =
c->buffer->len;
621 for (
unsigned int i = 0;
i <
count;
i++)
623 const HBGlyphID16 *replacement = substitute.get_value (
info[
i].codepoint, num_glyphs);
626 info[
i].codepoint = *replacement;
627 if (has_glyph_classes)
628 _hb_glyph_info_set_glyph_props (&
info[
i],
649 template <
typename Types>
672 static constexpr
bool in_place =
false;
676 DontAdvance = 0x4000,
683 CurrentIsKashidaLike= 0x2000,
693 MarkedIsKashidaLike= 0x1000,
703 CurrentInsertBefore= 0x0800,
706 MarkedInsertBefore= 0x0400,
709 CurrentInsertCount= 0x3E0,
714 MarkedInsertCount= 0x001F,
726 insertionAction (
table+
table->insertionAction) {}
731 return (
entry.flags & (CurrentInsertCount | MarkedInsertCount)) &&
732 (
entry.data.currentInsertIndex != 0xFFFF ||
entry.data.markedInsertIndex != 0xFFFF);
740 unsigned mark_loc =
buffer->out_len;
742 if (
entry.data.markedInsertIndex != 0xFFFF)
744 unsigned int count = (
flags & MarkedInsertCount);
746 unsigned int start =
entry.data.markedInsertIndex;
750 bool before =
flags & MarkedInsertBefore;
770 if (
entry.data.currentInsertIndex != 0xFFFF)
772 unsigned int count = (
flags & CurrentInsertCount) >> 5;
774 unsigned int start =
entry.data.currentInsertIndex;
778 bool before =
flags & CurrentInsertBefore;
867 template <
typename Types>
872 template <
typename T>
876 unsigned int get_type ()
const {
return coverage & 0xFF; }
887 AllDirections = 0x20,
903 template <
typename context_t,
typename ...Ts>
904 typename context_t::return_t
dispatch (context_t *
c, Ts&&... ds)
const
906 unsigned int subtable_type = get_type ();
908 switch (subtable_type) {
909 case Rearrangement:
return_trace (
c->dispatch (
u.rearrangement, std::forward<Ts> (ds)...));
910 case Contextual:
return_trace (
c->dispatch (
u.contextual, std::forward<Ts> (ds)...));
912 case Noncontextual:
return_trace (
c->dispatch (
u.noncontextual, std::forward<Ts> (ds)...));
913 case Insertion:
return_trace (
c->dispatch (
u.insertion, std::forward<Ts> (ds)...));
930 !
c->check_range (
this,
length))
952 template <
typename Types>
961 unsigned int count = featureCount;
962 for (
unsigned i = 0;
i <
count;
i++)
964 const Feature &feature = featureZ[
i];
971 if (
map->features.bsearch (
info))
991 const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
992 unsigned int count = subtableCount;
993 for (
unsigned int i = 0;
i <
count;
i++)
1037 if (!
c->buffer->message (
c->font,
"start chainsubtable %d",
c->lookup_index))
1041 c->buffer->reverse ();
1046 c->buffer->reverse ();
1048 (
void)
c->buffer->message (
c->font,
"end chainsubtable %d",
c->lookup_index);
1050 if (
unlikely (!
c->buffer->successful))
return;
1053 subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
1054 c->set_lookup_index (
c->lookup_index + 1);
1065 !
c->check_range (
this,
length))
1068 if (!
c->check_array (featureZ.arrayZ, featureCount))
1071 const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
1072 unsigned int count = subtableCount;
1073 for (
unsigned int i = 0;
i <
count;
i++)
1077 subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
1102 template <
typename Types, hb_tag_t TAG>
1113 unsigned int count = chainCount;
1114 for (
unsigned int i = 0;
i <
count;
i++)
1117 chain = &StructAfter<Chain<Types>> (*chain);
1123 if (
unlikely (!
c->buffer->successful))
return;
1124 c->set_lookup_index (0);
1126 unsigned int count = chainCount;
1127 for (
unsigned int i = 0;
i <
count;
i++)
1129 chain->
apply (
c,
c->plan->aat_map.chain_flags[
i]);
1130 if (
unlikely (!
c->buffer->successful))
return;
1131 chain = &StructAfter<Chain<Types>> (*chain);
1142 unsigned int count = chainCount;
1143 for (
unsigned int i = 0;
i <
count;
i++)
1147 chain = &StructAfter<Chain<Types>> (*chain);
small capitals from c petite p scientific f u
small capitals from c petite p scientific i
[1]
QMap< QString, QString > map
[6]
hb_aat_layout_feature_selector_t
@ HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS
@ HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS
hb_aat_layout_feature_type_t
@ HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE
@ HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE
#define TRACE_SANITIZE(this)
#define DEBUG_MSG(WHAT, OBJ,...)
#define TRACE_DISPATCH(this, format)
#define TRACE_APPLY(this)
#define return_trace(RET)
void const void *obj HB_UNUSED
#define HB_MAX_CONTEXT_LENGTH
backing_store_ptr info
[4]
void *PRIV() memmove(void *d, const void *s, size_t n)
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLenum GLenum GLsizei void * table
#define HB_DIRECTION_IS_VERTICAL(dir)
#define HB_DIRECTION_IS_BACKWARD(dir)
void apply(hb_aat_apply_context_t *c, hb_mask_t flags) const
hb_mask_t compile_flags(const hb_aat_map_builder_t *map) const
DEFINE_SIZE_MIN(8+2 *sizeof(HBUINT))
unsigned int get_size() const
bool sanitize(hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const
UnsizedArrayOf< Feature > featureZ
ContextualSubtable< Types > contextual
RearrangementSubtable< Types > rearrangement
NoncontextualSubtable< Types > noncontextual
unsigned int get_coverage() const
unsigned int get_type() const
InsertionSubtable< Types > insertion
unsigned int get_size() const
bool sanitize(hb_sanitize_context_t *c) const
DEFINE_SIZE_MIN(2 *sizeof(HBUINT)+4)
context_t::return_t dispatch(context_t *c, Ts &&... ds) const
bool apply(hb_aat_apply_context_t *c) const
LigatureSubtable< Types > ligature
bool is_actionable(StateTableDriver< Types, EntryData > *driver, const Entry< EntryData > &entry)
void transition(StateTableDriver< Types, EntryData > *driver, const Entry< EntryData > &entry)
driver_context_t(const ContextualSubtable *table_, hb_aat_apply_context_t *c_)
bool sanitize(hb_sanitize_context_t *c) const
NNOffsetTo< UnsizedListOfOffset16To< Lookup< HBGlyphID16 >, HBUINT, false >, HBUINT > substitutionTables
StateTable< Types, EntryData > machine
bool apply(hb_aat_apply_context_t *c) const
bool sanitize(hb_sanitize_context_t *c) const
HBUINT16 currentInsertIndex
HBUINT16 markedInsertIndex
void transition(StateTableDriver< Types, EntryData > *driver, const Entry< EntryData > &entry)
driver_context_t(const InsertionSubtable *table, hb_aat_apply_context_t *c_)
bool is_actionable(StateTableDriver< Types, EntryData > *driver HB_UNUSED, const Entry< EntryData > &entry)
NNOffsetTo< UnsizedArrayOf< HBGlyphID16 >, HBUINT > insertionAction
StateTable< Types, EntryData > machine
bool apply(hb_aat_apply_context_t *c) const
bool sanitize(hb_sanitize_context_t *c) const
static bool performAction(const Entry< EntryData > &entry)
static unsigned int ligActionIndex(const Entry< EntryData > &entry)
static bool performAction(const Entry< EntryData > &entry)
static unsigned int ligActionIndex(const Entry< EntryData > &entry)
bool is_actionable(StateTableDriver< Types, EntryData > *driver HB_UNUSED, const Entry< EntryData > &entry)
driver_context_t(const LigatureSubtable *table_, hb_aat_apply_context_t *c_)
void transition(StateTableDriver< Types, EntryData > *driver, const Entry< EntryData > &entry)
NNOffsetTo< UnsizedArrayOf< HBUINT32 >, HBUINT > ligAction
NNOffsetTo< UnsizedArrayOf< HBGlyphID16 >, HBUINT > ligature
bool apply(hb_aat_apply_context_t *c) const
NNOffsetTo< UnsizedArrayOf< HBUINT16 >, HBUINT > component
LigatureEntryT::EntryData EntryData
bool sanitize(hb_sanitize_context_t *c) const
StateTable< Types, EntryData > machine
LigatureEntry< Types::extended > LigatureEntryT
const T * get_value(hb_codepoint_t glyph_id, unsigned int num_glyphs) const
bool sanitize(hb_sanitize_context_t *c) const
bool apply(hb_aat_apply_context_t *c) const
Lookup< HBGlyphID16 > substitute
driver_context_t(const RearrangementSubtable *table HB_UNUSED)
bool is_actionable(StateTableDriver< Types, EntryData > *driver HB_UNUSED, const Entry< EntryData > &entry)
void transition(StateTableDriver< Types, EntryData > *driver, const Entry< EntryData > &entry)
bool apply(hb_aat_apply_context_t *c) const
bool sanitize(hb_sanitize_context_t *c) const
StateTable< Types, EntryData > machine
bool sanitize(hb_sanitize_context_t *c) const
void apply(hb_aat_apply_context_t *c) const
Chain< Types > firstChain
void compile_flags(const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) const
bool has_glyph_classes() const
unsigned int get_glyph_props(hb_codepoint_t glyph) const
bool sanitize(hb_sanitize_context_t *c) const
Type arrayZ[HB_VAR_ARRAY]