[GX] Add data types for encoding numerical variations

This commit is contained in:
Behdad Esfahbod 2016-03-01 19:12:08 +09:00
parent b843c6d8b6
commit 6d9d3c55bb
3 changed files with 126 additions and 0 deletions

View File

@ -108,6 +108,10 @@ struct hb_font_t {
unsigned int x_ppem;
unsigned int y_ppem;
/* Font variation coordinates. */
int *coords;
unsigned int coord_count;
hb_font_funcs_t *klass;
void *user_data;
hb_destroy_func_t destroy;
@ -120,6 +124,8 @@ struct hb_font_t {
{ return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
{ return em_scale (v, dir_scale (direction)); }
@ -531,6 +537,10 @@ struct hb_font_t {
scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
return (hb_position_t) (scaled / upem);
}
inline hb_position_t em_scalef (float v, int scale)
{
return (hb_position_t) (v * scale / face->get_upem ());
}
};
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS

View File

@ -1194,6 +1194,9 @@ hb_font_get_empty (void)
0, /* x_ppem */
0, /* y_ppem */
NULL, /* coords */
0, /* coord_count */
const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
NULL, /* user_data */
NULL, /* destroy */

View File

@ -1236,6 +1236,119 @@ struct Device
};
struct VariationAxis
{
inline float evaluate (int *coords, unsigned int coord_len) const
{
unsigned int i = axisIndex;
int coord = i < coord_len ? coords[i] : 0;
int start = startCoord, peak = peakCoord, end = endCoord;
if (coord < start || coord > end) return 0.;
if (coord == peak) return 1.;
/* Interpolate */
if (coord < peak)
return float (coord - start) / (peak - start);
else
return float (end - coord) / (end - peak);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
public:
Index axisIndex;
F2DOT14 startCoord;
F2DOT14 peakCoord;
F2DOT14 endCoord;
public:
DEFINE_SIZE_STATIC (8);
};
struct VariationTuple
{
inline float evaluate (int *coords, unsigned int coord_len) const
{
float v = 1.;
unsigned int count = axes.len;
for (unsigned int i = 0; i < count; i++)
v *= (this+axes[i]).evaluate (coords, coord_len);
return v;
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (axes.sanitize (c, this));
}
OffsetArrayOf<VariationAxis>
axes;
public:
DEFINE_SIZE_ARRAY (2, axes);
};
struct VariationMap
{
inline const VariationTuple& operator [] (unsigned int i) const
{ return this+tuples[i]; }
inline unsigned int get_len (void) const
{ return tuples.len; }
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (tuples.sanitize (c, this));
}
OffsetArrayOf<VariationTuple>
tuples;
public:
DEFINE_SIZE_ARRAY (2, tuples);
};
struct VariationDevice
{
inline hb_position_t get_x_delta (hb_font_t *font) const
{ return font->em_scalef_x (get_delta (font->coords, font->coord_count)); }
inline hb_position_t get_y_delta (hb_font_t *font) const
{ return font->em_scalef_y (get_delta (font->coords, font->coord_count)); }
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && c->check_range (&deltaValue, numDeltas * SHORT::static_size));
}
private:
inline float get_delta (int *coords, unsigned int coord_count) const
{
float v = 0;
const VariationMap &map = this+variationMap;
unsigned int count = MIN ((unsigned int) numDeltas, map.get_len ());
for (unsigned int i = 0; i < count; i++)
v += deltaValue[i] * map[i].evaluate (coords, coord_count);
return v;
}
protected:
OffsetTo<VariationMap>
variationMap; /* Offset to variation mapping for this table. */
USHORT numDeltas; /* Number of deltas for in this table. */
USHORT deltaFormat; /* Format identifier for this table: 0x10 */
SHORT deltaValue[VAR]; /* Deltas as signed values in design space. */
public:
DEFINE_SIZE_ARRAY (6, deltaValue);
};
} /* namespace OT */