diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index eb08badbd..2d7e6792a 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -34,9 +34,7 @@ static inline const OT::MATH& _get_math (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH); - hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - return *(layout->math.get ()); } diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh index a041934bf..743d5870e 100644 --- a/src/hb-ot-var-avar-table.hh +++ b/src/hb-ot-var-avar-table.hh @@ -50,7 +50,39 @@ struct AxisValueMap DEFINE_SIZE_STATIC (4); }; -typedef ArrayOf SegmentMaps; +struct SegmentMaps : ArrayOf +{ + inline int map (int value) const + { + /* The following special-cases are not part of OpenType, which requires + * that at least -1, 0, and +1 must be mapped. But we include these as + * part of a better error recovery scheme. */ + + if (!len) + return value; + + if (value <= array[0].fromCoord) + return value - array[0].fromCoord + array[0].toCoord; + + unsigned int i; + unsigned int count = len; + for (i = 1; i < count && value > array[i].fromCoord; i++) + ; + + if (value >= array[i].fromCoord) + return value - array[i].fromCoord + array[i].toCoord; + + if (unlikely (array[i-1].fromCoord == array[i].fromCoord)) + return array[i-1].toCoord; + + int denom = array[i].fromCoord - array[i-1].fromCoord; + return array[i-1].toCoord + + (array[i].toCoord - array[i-1].toCoord) * + (value - array[i-1].fromCoord + denom/2) / denom; + } + + DEFINE_SIZE_ARRAY (2, array); +}; /* * avar — Axis Variations Table @@ -80,6 +112,18 @@ struct avar return_trace (true); } + inline void map_coords (int *coords, unsigned int coords_length) const + { + unsigned int count = MIN (coords_length, axisCount); + + const SegmentMaps *map = &axisSegmentMapsZ; + for (unsigned int i = 0; i < count; i++) + { + coords[i] = map->map (coords[i]); + map = &StructAfter (*map); + } + } + protected: FixedVersion<>version; /* Version of the avar table * initially set to 0x00010000u */ diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 76016e634..d4d16dfff 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -33,19 +33,24 @@ HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) +/* + * fvar/avar + */ + static inline const OT::fvar& _get_fvar (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar); - hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - return *(layout->fvar.get ()); } - -/* - * fvar/avar - */ +static inline const OT::avar& +_get_avar (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::avar); + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + return *(layout->avar.get ()); +} /** * hb_ot_var_has_data: @@ -131,7 +136,8 @@ hb_ot_var_normalize_variations (hb_face_t *face, coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value); } - /* TODO avar */ + const OT::avar &avar = _get_avar (face); + avar.map_coords (coords, coords_length); } /** @@ -149,5 +155,6 @@ hb_ot_var_normalize_coords (hb_face_t *face, for (unsigned int i = 0; i < coords_length; i++) normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); - /* TODO avar */ + const OT::avar &avar = _get_avar (face); + avar.map_coords (normalized_coords, coords_length); }