[GX] Add data types for encoding numerical variations
This commit is contained in:
parent
b843c6d8b6
commit
6d9d3c55bb
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue