[GX] Hook up GPOS to Variation Store stored in GDEF

Untested.
pull/279/head
Behdad Esfahbod 8 years ago
parent dcfd309533
commit 151d93de8a
  1. 22
      src/hb-ot-layout-common-private.hh
  2. 27
      src/hb-ot-layout-gdef-table.hh
  3. 40
      src/hb-ot-layout-gpos-table.hh
  4. 2
      src/hb-ot-layout-gsubgpos-private.hh

@ -1418,11 +1418,11 @@ struct VariationDevice
private: private:
inline hb_position_t get_x_delta (hb_font_t *font) const inline hb_position_t get_x_delta (hb_font_t *font, const VarStore &store) const
{ return font->em_scalef_x (get_delta (font->x_coords, font->num_coords)); } { return font->em_scalef_x (get_delta (store, font->x_coords, font->num_coords)); }
inline hb_position_t get_y_delta (hb_font_t *font) const inline hb_position_t get_y_delta (hb_font_t *font, const VarStore &store) const
{ return font->em_scalef_y (get_delta (font->y_coords, font->num_coords)); } { return font->em_scalef_y (get_delta (store, font->y_coords, font->num_coords)); }
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
@ -1432,11 +1432,10 @@ struct VariationDevice
private: private:
inline float get_delta (int *coords, unsigned int coord_count) const inline float get_delta (const VarStore &store,
int *coords, unsigned int coord_count) const
{ {
float v = 0; return store.get_delta (outerIndex, innerIndex, coords, coord_count);
/* XXXXXXXXXXXXXXX call into GDEF. */
return v;
} }
protected: protected:
@ -1449,25 +1448,26 @@ struct VariationDevice
struct Device struct Device
{ {
inline hb_position_t get_x_delta (hb_font_t *font) const inline hb_position_t get_x_delta (hb_font_t *font, const VarStore &store) const
{ {
switch (u.b.format) switch (u.b.format)
{ {
case 1: case 2: case 3: case 1: case 2: case 3:
return u.hinting.get_x_delta (font); return u.hinting.get_x_delta (font);
case 0x8000: case 0x8000:
return u.variation.get_x_delta (font); return u.variation.get_x_delta (font, store);
default: default:
return 0; return 0;
} }
} }
inline hb_position_t get_y_delta (hb_font_t *font) const inline hb_position_t get_y_delta (hb_font_t *font, const VarStore &store) const
{ {
switch (u.b.format) switch (u.b.format)
{ {
case 1: case 2: case 3: case 1: case 2: case 3:
return u.hinting.get_x_delta (font); return u.hinting.get_x_delta (font);
case 0x8000: case 0x8000:
return u.variation.get_y_delta (font, store);
default: default:
return 0; return 0;
} }

@ -97,7 +97,7 @@ struct CaretValueFormat1
friend struct CaretValue; friend struct CaretValue;
private: private:
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
{ {
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate); return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
} }
@ -146,11 +146,11 @@ struct CaretValueFormat3
{ {
friend struct CaretValue; friend struct CaretValue;
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, const VarStore &var_store) const
{ {
return HB_DIRECTION_IS_HORIZONTAL (direction) ? return HB_DIRECTION_IS_HORIZONTAL (direction) ?
font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font) : font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font); font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
} }
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
@ -172,12 +172,15 @@ struct CaretValueFormat3
struct CaretValue struct CaretValue
{ {
inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const inline hb_position_t get_caret_value (hb_font_t *font,
hb_direction_t direction,
hb_codepoint_t glyph_id,
const VarStore &var_store) const
{ {
switch (u.format) { switch (u.format) {
case 1: return u.format1.get_caret_value (font, direction, glyph_id); case 1: return u.format1.get_caret_value (font, direction);
case 2: return u.format2.get_caret_value (font, direction, glyph_id); case 2: return u.format2.get_caret_value (font, direction, glyph_id);
case 3: return u.format3.get_caret_value (font, direction, glyph_id); case 3: return u.format3.get_caret_value (font, direction, var_store);
default:return 0; default:return 0;
} }
} }
@ -210,6 +213,7 @@ struct LigGlyph
inline unsigned int get_lig_carets (hb_font_t *font, inline unsigned int get_lig_carets (hb_font_t *font,
hb_direction_t direction, hb_direction_t direction,
hb_codepoint_t glyph_id, hb_codepoint_t glyph_id,
const VarStore &var_store,
unsigned int start_offset, unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */, unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const hb_position_t *caret_array /* OUT */) const
@ -218,7 +222,7 @@ struct LigGlyph
const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count); const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
unsigned int count = *caret_count; unsigned int count = *caret_count;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id); caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store);
} }
return carets.len; return carets.len;
@ -244,6 +248,7 @@ struct LigCaretList
inline unsigned int get_lig_carets (hb_font_t *font, inline unsigned int get_lig_carets (hb_font_t *font,
hb_direction_t direction, hb_direction_t direction,
hb_codepoint_t glyph_id, hb_codepoint_t glyph_id,
const VarStore &var_store,
unsigned int start_offset, unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */, unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const hb_position_t *caret_array /* OUT */) const
@ -256,7 +261,7 @@ struct LigCaretList
return 0; return 0;
} }
const LigGlyph &lig_glyph = this+ligGlyph[index]; const LigGlyph &lig_glyph = this+ligGlyph[index];
return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
} }
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
@ -367,7 +372,9 @@ struct GDEF
unsigned int start_offset, unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */, unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const hb_position_t *caret_array /* OUT */) const
{ return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); } { return (this+ligCaretList).get_lig_carets (font,
direction, glyph_id, get_var_store(),
start_offset, caret_count, caret_array); }
inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; } inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; }
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const

@ -103,17 +103,17 @@ struct ValueFormat : USHORT
inline unsigned int get_size (void) const inline unsigned int get_size (void) const
{ return get_len () * Value::static_size; } { return get_len () * Value::static_size; }
void apply_value (hb_font_t *font, void apply_value (hb_apply_context_t *c,
hb_direction_t direction,
const void *base, const void *base,
const Value *values, const Value *values,
hb_glyph_position_t &glyph_pos) const hb_glyph_position_t &glyph_pos) const
{ {
unsigned int format = *this; unsigned int format = *this;
hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction);
if (!format) return; if (!format) return;
hb_font_t *font = c->font;
hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction);
if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++)); if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++));
if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++)); if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++));
if (format & xAdvance) { if (format & xAdvance) {
@ -131,25 +131,26 @@ struct ValueFormat : USHORT
bool use_x_device = font->x_ppem || font->num_coords; bool use_x_device = font->x_ppem || font->num_coords;
bool use_y_device = font->y_ppem || font->num_coords; bool use_y_device = font->y_ppem || font->num_coords;
if (!use_x_device && !use_y_device) return; if (!use_x_device && !use_y_device) return;
const VarStore &store = c->var_store;
/* pixel -> fractional pixel */ /* pixel -> fractional pixel */
if (format & xPlaDevice) { if (format & xPlaDevice) {
if (use_x_device) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font); if (use_x_device) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font, store);
values++; values++;
} }
if (format & yPlaDevice) { if (format & yPlaDevice) {
if (use_y_device) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font); if (use_y_device) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font, store);
values++; values++;
} }
if (format & xAdvDevice) { if (format & xAdvDevice) {
if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font); if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font, store);
values++; values++;
} }
if (format & yAdvDevice) { if (format & yAdvDevice) {
/* y_advance values grow downward but font-space grows upward, hence negation */ /* y_advance values grow downward but font-space grows upward, hence negation */
if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font); if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font, store);
values++; values++;
} }
} }
@ -295,9 +296,9 @@ struct AnchorFormat3
*y = font->em_scale_y (yCoordinate); *y = font->em_scale_y (yCoordinate);
if (font->x_ppem || font->num_coords) if (font->x_ppem || font->num_coords)
*x += (this+xDeviceTable).get_x_delta (font); *x += (this+xDeviceTable).get_x_delta (font, c->var_store);
if (font->y_ppem || font->num_coords) if (font->y_ppem || font->num_coords)
*y += (this+yDeviceTable).get_x_delta (font); *y += (this+yDeviceTable).get_x_delta (font, c->var_store);
} }
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
@ -475,8 +476,7 @@ struct SinglePosFormat1
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false); if (likely (index == NOT_COVERED)) return_trace (false);
valueFormat.apply_value (c->font, c->direction, this, valueFormat.apply_value (c, this, values, buffer->cur_pos());
values, buffer->cur_pos());
buffer->idx++; buffer->idx++;
return_trace (true); return_trace (true);
@ -526,7 +526,7 @@ struct SinglePosFormat2
if (likely (index >= valueCount)) return_trace (false); if (likely (index >= valueCount)) return_trace (false);
valueFormat.apply_value (c->font, c->direction, this, valueFormat.apply_value (c, this,
&values[index * valueFormat.get_len ()], &values[index * valueFormat.get_len ()],
buffer->cur_pos()); buffer->cur_pos());
@ -643,10 +643,8 @@ struct PairSet
min = mid + 1; min = mid + 1;
else else
{ {
valueFormats[0].apply_value (c->font, c->direction, this, valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
&record->values[0], buffer->cur_pos()); valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
valueFormats[1].apply_value (c->font, c->direction, this,
&record->values[len1], buffer->pos[pos]);
if (len2) if (len2)
pos++; pos++;
buffer->idx = pos; buffer->idx = pos;
@ -793,10 +791,8 @@ struct PairPosFormat2
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
valueFormat1.apply_value (c->font, c->direction, this, valueFormat1.apply_value (c, this, v, buffer->cur_pos());
v, buffer->cur_pos()); valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
valueFormat2.apply_value (c->font, c->direction, this,
v + len1, buffer->pos[skippy_iter.idx]);
buffer->idx = skippy_iter.idx; buffer->idx = skippy_iter.idx;
if (len2) if (len2)

@ -469,6 +469,7 @@ struct hb_apply_context_t :
unsigned int lookup_props; unsigned int lookup_props;
const GDEF &gdef; const GDEF &gdef;
bool has_glyph_classes; bool has_glyph_classes;
const VarStore &var_store;
skipping_iterator_t iter_input, iter_context; skipping_iterator_t iter_input, iter_context;
unsigned int lookup_index; unsigned int lookup_index;
unsigned int debug_depth; unsigned int debug_depth;
@ -487,6 +488,7 @@ struct hb_apply_context_t :
lookup_props (0), lookup_props (0),
gdef (*hb_ot_layout_from_face (face)->gdef), gdef (*hb_ot_layout_from_face (face)->gdef),
has_glyph_classes (gdef.has_glyph_classes ()), has_glyph_classes (gdef.has_glyph_classes ()),
var_store (gdef.get_var_store ()),
iter_input (), iter_input (),
iter_context (), iter_context (),
lookup_index ((unsigned int) -1), lookup_index ((unsigned int) -1),

Loading…
Cancel
Save