|
|
|
@ -55,7 +55,7 @@ struct ValueFormat : USHORT |
|
|
|
|
inline unsigned int get_len () const |
|
|
|
|
{ return _hb_popcount32 ((unsigned int) *this); } |
|
|
|
|
|
|
|
|
|
const void apply_value (hb_ot_layout_context_t *context, |
|
|
|
|
const void apply_value (hb_ot_layout_t *layout, |
|
|
|
|
const char *base, |
|
|
|
|
const Value *values, |
|
|
|
|
hb_glyph_position_t *glyph_pos) const |
|
|
|
@ -97,8 +97,8 @@ struct ValueRecord { |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
x_scale = context->font->x_scale; |
|
|
|
|
y_scale = context->font->y_scale; |
|
|
|
|
x_scale = layout->gpos_info.x_scale; |
|
|
|
|
y_scale = layout->gpos_info.y_scale; |
|
|
|
|
/* design units -> fractional pixel */ |
|
|
|
|
if (format & xPlacement) |
|
|
|
|
glyph_pos->x_pos += x_scale * *(SHORT*)values++ / 0x10000; |
|
|
|
@ -109,10 +109,10 @@ struct ValueRecord { |
|
|
|
|
if (format & yAdvance) |
|
|
|
|
glyph_pos->y_advance += y_scale * *(SHORT*)values++ / 0x10000; |
|
|
|
|
|
|
|
|
|
if (HB_LIKELY (!context->font->dvi)) |
|
|
|
|
if (HB_LIKELY (!layout->gpos_info.dvi)) |
|
|
|
|
{ |
|
|
|
|
x_ppem = context->font->x_ppem; |
|
|
|
|
y_ppem = context->font->y_ppem; |
|
|
|
|
x_ppem = layout->gpos_info.x_ppem; |
|
|
|
|
y_ppem = layout->gpos_info.y_ppem; |
|
|
|
|
/* pixel -> fractional pixel */ |
|
|
|
|
if (format & xPlaDevice) |
|
|
|
|
glyph_pos->x_pos += (base+*(OffsetTo<Device>*)values++).get_delta (x_ppem) << 6; |
|
|
|
@ -133,11 +133,11 @@ struct AnchorFormat1 |
|
|
|
|
friend struct Anchor; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
inline void get_anchor (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id, |
|
|
|
|
inline void get_anchor (hb_ot_layout_t *layout, hb_codepoint_t glyph_id, |
|
|
|
|
hb_position_t *x, hb_position_t *y) const |
|
|
|
|
{ |
|
|
|
|
*x = context->font->x_scale * xCoordinate / 0x10000; |
|
|
|
|
*y = context->font->y_scale * yCoordinate / 0x10000; |
|
|
|
|
*x = layout->gpos_info.x_scale * xCoordinate / 0x10000; |
|
|
|
|
*y = layout->gpos_info.y_scale * yCoordinate / 0x10000; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
@ -152,12 +152,12 @@ struct AnchorFormat2 |
|
|
|
|
friend struct Anchor; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
inline void get_anchor (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id, |
|
|
|
|
inline void get_anchor (hb_ot_layout_t *layout, hb_codepoint_t glyph_id, |
|
|
|
|
hb_position_t *x, hb_position_t *y) const |
|
|
|
|
{ |
|
|
|
|
/* TODO Contour */ |
|
|
|
|
*x = context->font->x_scale * xCoordinate / 0x10000; |
|
|
|
|
*y = context->font->y_scale * yCoordinate / 0x10000; |
|
|
|
|
*x = layout->gpos_info.x_scale * xCoordinate / 0x10000; |
|
|
|
|
*y = layout->gpos_info.y_scale * yCoordinate / 0x10000; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
@ -173,16 +173,16 @@ struct AnchorFormat3 |
|
|
|
|
friend struct Anchor; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
inline void get_anchor (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id, |
|
|
|
|
inline void get_anchor (hb_ot_layout_t *layout, hb_codepoint_t glyph_id, |
|
|
|
|
hb_position_t *x, hb_position_t *y) const |
|
|
|
|
{ |
|
|
|
|
*x = context->font->x_scale * xCoordinate / 0x10000; |
|
|
|
|
*y = context->font->y_scale * yCoordinate / 0x10000; |
|
|
|
|
*x = layout->gpos_info.x_scale * xCoordinate / 0x10000; |
|
|
|
|
*y = layout->gpos_info.y_scale * yCoordinate / 0x10000; |
|
|
|
|
|
|
|
|
|
if (!context->font->dvi) |
|
|
|
|
if (!layout->gpos_info.dvi) |
|
|
|
|
{ |
|
|
|
|
*x += (this+xDeviceTable).get_delta (context->font->x_ppem) << 6; |
|
|
|
|
*y += (this+yDeviceTable).get_delta (context->font->y_ppem) << 6; |
|
|
|
|
*x += (this+xDeviceTable).get_delta (layout->gpos_info.x_ppem) << 6; |
|
|
|
|
*y += (this+yDeviceTable).get_delta (layout->gpos_info.y_ppem) << 6; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -203,15 +203,15 @@ ASSERT_SIZE (AnchorFormat3, 10); |
|
|
|
|
|
|
|
|
|
struct Anchor |
|
|
|
|
{ |
|
|
|
|
inline void get_anchor (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id, |
|
|
|
|
inline void get_anchor (hb_ot_layout_t *layout, hb_codepoint_t glyph_id, |
|
|
|
|
hb_position_t *x, hb_position_t *y) const |
|
|
|
|
{ |
|
|
|
|
*x = *y = 0; |
|
|
|
|
switch (u.format) { |
|
|
|
|
case 1: u.format1->get_anchor (context, glyph_id, x, y); return; |
|
|
|
|
case 2: u.format2->get_anchor (context, glyph_id, x, y); return; |
|
|
|
|
case 3: u.format3->get_anchor (context, glyph_id, x, y); return; |
|
|
|
|
default: return; |
|
|
|
|
case 1: u.format1->get_anchor (layout, glyph_id, x, y); return; |
|
|
|
|
case 2: u.format2->get_anchor (layout, glyph_id, x, y); return; |
|
|
|
|
case 3: u.format3->get_anchor (layout, glyph_id, x, y); return; |
|
|
|
|
default: return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -263,7 +263,7 @@ struct SinglePosFormat1 |
|
|
|
|
if (HB_LIKELY (index == NOT_COVERED)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
valueFormat.apply_value (context, (const char *) this, values, CURPOSITION ()); |
|
|
|
|
valueFormat.apply_value (layout, (const char *) this, values, CURPOSITION ()); |
|
|
|
|
|
|
|
|
|
buffer->in_pos++; |
|
|
|
|
return true; |
|
|
|
@ -296,7 +296,7 @@ struct SinglePosFormat2 |
|
|
|
|
if (HB_LIKELY (index >= valueCount)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
valueFormat.apply_value (context, (const char *) this, |
|
|
|
|
valueFormat.apply_value (layout, (const char *) this, |
|
|
|
|
values + index * valueFormat.get_len (), |
|
|
|
|
CURPOSITION ()); |
|
|
|
|
|
|
|
|
@ -382,7 +382,7 @@ struct PairPosFormat1 |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
unsigned int j = buffer->in_pos + 1; |
|
|
|
|
while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, NULL)) |
|
|
|
|
while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), lookup_flag, NULL)) |
|
|
|
|
{ |
|
|
|
|
if (HB_UNLIKELY (j == end)) |
|
|
|
|
return false; |
|
|
|
@ -401,8 +401,8 @@ struct PairPosFormat1 |
|
|
|
|
{ |
|
|
|
|
if (IN_GLYPH (j) == record->secondGlyph) |
|
|
|
|
{ |
|
|
|
|
valueFormat1.apply_value (context, (const char *) this, record->values, CURPOSITION ()); |
|
|
|
|
valueFormat2.apply_value (context, (const char *) this, record->values + len1, POSITION (j)); |
|
|
|
|
valueFormat1.apply_value (layout, (const char *) this, record->values, CURPOSITION ()); |
|
|
|
|
valueFormat2.apply_value (layout, (const char *) this, record->values + len1, POSITION (j)); |
|
|
|
|
if (len2) |
|
|
|
|
j++; |
|
|
|
|
buffer->in_pos = j; |
|
|
|
@ -447,7 +447,7 @@ struct PairPosFormat2 |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
unsigned int j = buffer->in_pos + 1; |
|
|
|
|
while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, NULL)) |
|
|
|
|
while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), lookup_flag, NULL)) |
|
|
|
|
{ |
|
|
|
|
if (HB_UNLIKELY (j == end)) |
|
|
|
|
return false; |
|
|
|
@ -464,8 +464,8 @@ struct PairPosFormat2 |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
const Value *v = values + record_len * (klass1 * class2Count + klass2); |
|
|
|
|
valueFormat1.apply_value (context, (const char *) this, v, CURPOSITION ()); |
|
|
|
|
valueFormat2.apply_value (context, (const char *) this, v + len1, POSITION (j)); |
|
|
|
|
valueFormat1.apply_value (layout, (const char *) this, v, CURPOSITION ()); |
|
|
|
|
valueFormat2.apply_value (layout, (const char *) this, v + len1, POSITION (j)); |
|
|
|
|
|
|
|
|
|
if (len2) |
|
|
|
|
j++; |
|
|
|
@ -665,7 +665,7 @@ struct CursivePosFormat1 |
|
|
|
|
Since horizontal advance widths or vertical advance heights |
|
|
|
|
can be used alone but not together, no ambiguity occurs. */ |
|
|
|
|
|
|
|
|
|
struct hb_ot_layout_context_t::info_t::gpos_t *gpi = &context->info.gpos; |
|
|
|
|
struct hb_ot_layout_t::gpos_info_t *gpi = &layout->gpos_info; |
|
|
|
|
hb_codepoint_t last_pos = gpi->last; |
|
|
|
|
gpi->last = HB_OT_LAYOUT_GPOS_NO_LAST; |
|
|
|
|
|
|
|
|
@ -683,11 +683,11 @@ struct CursivePosFormat1 |
|
|
|
|
goto end; |
|
|
|
|
|
|
|
|
|
hb_position_t entry_x, entry_y; |
|
|
|
|
(this+record.entryAnchor).get_anchor (context, IN_CURGLYPH (), &entry_x, &entry_y); |
|
|
|
|
(this+record.entryAnchor).get_anchor (layout, IN_CURGLYPH (), &entry_x, &entry_y); |
|
|
|
|
|
|
|
|
|
/* TODO vertical */ |
|
|
|
|
|
|
|
|
|
if (buffer->direction == HB_DIRECTION_RTL) |
|
|
|
|
if (gpi->r2l) |
|
|
|
|
{ |
|
|
|
|
POSITION (buffer->in_pos)->x_advance = entry_x - gpi->anchor_x; |
|
|
|
|
POSITION (buffer->in_pos)->new_advance = TRUE; |
|
|
|
@ -713,7 +713,7 @@ struct CursivePosFormat1 |
|
|
|
|
if (record.exitAnchor) |
|
|
|
|
{ |
|
|
|
|
gpi->last = buffer->in_pos; |
|
|
|
|
(this+record.exitAnchor).get_anchor (context, IN_CURGLYPH (), &gpi->anchor_x, &gpi->anchor_y); |
|
|
|
|
(this+record.exitAnchor).get_anchor (layout, IN_CURGLYPH (), &gpi->anchor_x, &gpi->anchor_y); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer->in_pos++; |
|
|
|
@ -782,7 +782,7 @@ struct MarkBasePosFormat1 |
|
|
|
|
/* now we search backwards for a non-mark glyph */ |
|
|
|
|
unsigned int count = buffer->in_pos; |
|
|
|
|
unsigned int i = 1, j = count - 1; |
|
|
|
|
while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), LookupFlag::IgnoreMarks, &property)) |
|
|
|
|
while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), LookupFlag::IgnoreMarks, &property)) |
|
|
|
|
{ |
|
|
|
|
if (HB_UNLIKELY (i == count)) |
|
|
|
|
return false; |
|
|
|
@ -809,9 +809,9 @@ struct MarkBasePosFormat1 |
|
|
|
|
|
|
|
|
|
hb_position_t mark_x, mark_y, base_x, base_y; |
|
|
|
|
|
|
|
|
|
mark_anchor.get_anchor (context, IN_CURGLYPH (), &mark_x, &mark_y); |
|
|
|
|
mark_anchor.get_anchor (layout, IN_CURGLYPH (), &mark_x, &mark_y); |
|
|
|
|
unsigned int index = base_index * classCount + mark_class; |
|
|
|
|
(&base_array+base_array.matrix[index]).get_anchor (context, IN_GLYPH (j), &base_x, &base_y); |
|
|
|
|
(&base_array+base_array.matrix[index]).get_anchor (layout, IN_GLYPH (j), &base_x, &base_y); |
|
|
|
|
|
|
|
|
|
hb_glyph_position_t *o = POSITION (buffer->in_pos); |
|
|
|
|
o->x_pos = base_x - mark_x; |
|
|
|
@ -900,7 +900,7 @@ struct MarkLigPosFormat1 |
|
|
|
|
/* now we search backwards for a non-mark glyph */ |
|
|
|
|
unsigned int count = buffer->in_pos; |
|
|
|
|
unsigned int i = 1, j = count - 1; |
|
|
|
|
while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), LookupFlag::IgnoreMarks, &property)) |
|
|
|
|
while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), LookupFlag::IgnoreMarks, &property)) |
|
|
|
|
{ |
|
|
|
|
if (HB_UNLIKELY (i == count)) |
|
|
|
|
return false; |
|
|
|
@ -946,9 +946,9 @@ struct MarkLigPosFormat1 |
|
|
|
|
|
|
|
|
|
hb_position_t mark_x, mark_y, lig_x, lig_y; |
|
|
|
|
|
|
|
|
|
mark_anchor.get_anchor (context, IN_CURGLYPH (), &mark_x, &mark_y); |
|
|
|
|
mark_anchor.get_anchor (layout, IN_CURGLYPH (), &mark_x, &mark_y); |
|
|
|
|
unsigned int index = comp_index * classCount + mark_class; |
|
|
|
|
(&lig_attach+lig_attach.matrix[index]).get_anchor (context, IN_GLYPH (j), &lig_x, &lig_y); |
|
|
|
|
(&lig_attach+lig_attach.matrix[index]).get_anchor (layout, IN_GLYPH (j), &lig_x, &lig_y); |
|
|
|
|
|
|
|
|
|
hb_glyph_position_t *o = POSITION (buffer->in_pos); |
|
|
|
|
o->x_pos = lig_x - mark_x; |
|
|
|
@ -1031,7 +1031,7 @@ struct MarkMarkPosFormat1 |
|
|
|
|
/* now we search backwards for a suitable mark glyph until a non-mark glyph */ |
|
|
|
|
unsigned int count = buffer->in_pos; |
|
|
|
|
unsigned int i = 1, j = count - 1; |
|
|
|
|
while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, &property)) |
|
|
|
|
while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), lookup_flag, &property)) |
|
|
|
|
{ |
|
|
|
|
if (HB_UNLIKELY (i == count)) |
|
|
|
|
return false; |
|
|
|
@ -1061,9 +1061,9 @@ struct MarkMarkPosFormat1 |
|
|
|
|
|
|
|
|
|
hb_position_t mark1_x, mark1_y, mark2_x, mark2_y; |
|
|
|
|
|
|
|
|
|
mark1_anchor.get_anchor (context, IN_CURGLYPH (), &mark1_x, &mark1_y); |
|
|
|
|
mark1_anchor.get_anchor (layout, IN_CURGLYPH (), &mark1_x, &mark1_y); |
|
|
|
|
unsigned int index = mark2_index * classCount + mark1_class; |
|
|
|
|
(&mark2_array+mark2_array.matrix[index]).get_anchor (context, IN_GLYPH (j), &mark2_x, &mark2_y); |
|
|
|
|
(&mark2_array+mark2_array.matrix[index]).get_anchor (layout, IN_GLYPH (j), &mark2_x, &mark2_y); |
|
|
|
|
|
|
|
|
|
hb_glyph_position_t *o = POSITION (buffer->in_pos); |
|
|
|
|
o->x_pos = mark2_x - mark1_x; |
|
|
|
@ -1231,7 +1231,7 @@ struct PosLookup : Lookup |
|
|
|
|
return type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool apply_once (hb_ot_layout_context_t *context, |
|
|
|
|
inline bool apply_once (hb_ot_layout_t *layout, |
|
|
|
|
hb_buffer_t *buffer, |
|
|
|
|
unsigned int context_length, |
|
|
|
|
unsigned int nesting_level_left) const |
|
|
|
@ -1240,7 +1240,7 @@ struct PosLookup : Lookup |
|
|
|
|
unsigned int lookup_flag = get_flag (); |
|
|
|
|
unsigned int property; |
|
|
|
|
|
|
|
|
|
if (!_hb_ot_layout_check_glyph_property (context->layout, IN_CURINFO (), lookup_flag, &property)) |
|
|
|
|
if (!_hb_ot_layout_check_glyph_property (layout, IN_CURINFO (), lookup_flag, &property)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < get_subtable_count (); i++) |
|
|
|
@ -1250,7 +1250,7 @@ struct PosLookup : Lookup |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool apply_string (hb_ot_layout_context_t *context, |
|
|
|
|
bool apply_string (hb_ot_layout_t *layout, |
|
|
|
|
hb_buffer_t *buffer, |
|
|
|
|
hb_ot_layout_feature_mask_t mask) const |
|
|
|
|
{ |
|
|
|
@ -1259,7 +1259,7 @@ struct PosLookup : Lookup |
|
|
|
|
if (HB_UNLIKELY (!buffer->in_length)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
context->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST; /* no last valid glyph for cursive pos. */ |
|
|
|
|
layout->gpos_info.last = HB_OT_LAYOUT_GPOS_NO_LAST; /* no last valid glyph for cursive pos. */ |
|
|
|
|
|
|
|
|
|
buffer->in_pos = 0; |
|
|
|
|
while (buffer->in_pos < buffer->in_length) |
|
|
|
@ -1267,7 +1267,7 @@ struct PosLookup : Lookup |
|
|
|
|
bool done; |
|
|
|
|
if (~IN_PROPERTIES (buffer->in_pos) & mask) |
|
|
|
|
{ |
|
|
|
|
done = apply_once (context, buffer, NO_CONTEXT, MAX_NESTING_LEVEL); |
|
|
|
|
done = apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL); |
|
|
|
|
ret |= done; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
@ -1275,7 +1275,7 @@ struct PosLookup : Lookup |
|
|
|
|
done = false; |
|
|
|
|
/* Contrary to properties defined in GDEF, user-defined properties
|
|
|
|
|
will always stop a possible cursive positioning. */ |
|
|
|
|
context->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST; |
|
|
|
|
layout->gpos_info.last = HB_OT_LAYOUT_GPOS_NO_LAST; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!done) |
|
|
|
@ -1302,11 +1302,11 @@ struct GPOS : GSUBGPOS |
|
|
|
|
inline const PosLookup& get_lookup (unsigned int i) const |
|
|
|
|
{ return (const PosLookup&) GSUBGPOS::get_lookup (i); } |
|
|
|
|
|
|
|
|
|
inline bool position_lookup (hb_ot_layout_context_t *context, |
|
|
|
|
inline bool position_lookup (hb_ot_layout_t *layout, |
|
|
|
|
hb_buffer_t *buffer, |
|
|
|
|
unsigned int lookup_index, |
|
|
|
|
hb_ot_layout_feature_mask_t mask) const |
|
|
|
|
{ return get_lookup (lookup_index).apply_string (context, buffer, mask); } |
|
|
|
|
{ return get_lookup (lookup_index).apply_string (layout, buffer, mask); } |
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
ASSERT_SIZE (GPOS, 10); |
|
|
|
@ -1326,7 +1326,7 @@ inline bool ExtensionPos::apply (APPLY_ARG_DEF) const |
|
|
|
|
|
|
|
|
|
static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index) |
|
|
|
|
{ |
|
|
|
|
const GPOS &gpos = *(context->layout->gpos); |
|
|
|
|
const GPOS &gpos = *(layout->gpos); |
|
|
|
|
const PosLookup &l = gpos.get_lookup (lookup_index); |
|
|
|
|
|
|
|
|
|
if (HB_UNLIKELY (nesting_level_left == 0)) |
|
|
|
@ -1336,7 +1336,7 @@ static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index) |
|
|
|
|
if (HB_UNLIKELY (context_length < 1)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
return l.apply_once (context, buffer, context_length, nesting_level_left); |
|
|
|
|
return l.apply_once (layout, buffer, context_length, nesting_level_left); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|