add components transformation

This commit is contained in:
Michiharu Ariza 2019-03-16 16:27:33 -07:00
parent 139e87b56c
commit bd040a4354
2 changed files with 60 additions and 15 deletions

View File

@ -172,6 +172,44 @@ struct glyf
return size;
}
void transform_point (float &x, float &y) const
{
int tx, ty;
const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
if (flags & ARG_1_AND_2_ARE_WORDS)
{
tx = *(const HBINT16 *)p;
p += HBINT16::static_size;
ty = *(const HBINT16 *)p;
p += HBINT16::static_size;
}
else
{
tx = *p++;
ty = *p++;
}
if (!(flags & ARGS_ARE_XY_VALUES)) tx = ty = 0; /* TODO: anchor point unsupported for now */
if (flags & WE_HAVE_A_SCALE)
{
float scale = ((const F2DOT14*)p)->to_float ();
x *= scale;
y *= scale;
}
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
{
x *= ((const F2DOT14*)p)[0].to_float ();
y *= ((const F2DOT14*)p)[1].to_float ();
}
else if (flags & WE_HAVE_A_TWO_BY_TWO)
{
float x_ = x * ((const F2DOT14*)p)[0].to_float () + y * ((const F2DOT14*)p)[1].to_float ();
y = x * ((const F2DOT14*)p)[2].to_float () + y * ((const F2DOT14*)p)[3].to_float ();
x = x_;
}
if (tx | ty) { x += tx; y += ty; }
}
struct Iterator
{
const char *glyph_start;
@ -341,7 +379,8 @@ struct glyf
uint8_t flag = points_[i].flag;
if (coord_setter.is_short (flag))
{
if (unlikely (!checker.in_range (p))) return false;
if (unlikely (!checker.in_range (p)))
return false;
if (coord_setter.is_same (flag))
v += *p++;
else
@ -349,9 +388,10 @@ struct glyf
}
else
{
if (unlikely (!checker.in_range ((const HBUINT16 *)p))) return false;
if (!coord_setter.is_same (flag))
{
if (unlikely (!checker.in_range ((const HBUINT16 *)p)))
return false;
v += *(const HBINT16 *)p;
p += HBINT16::static_size;
}

View File

@ -119,9 +119,9 @@ struct TupleVarHeader
unsigned int get_data_size () const { return varDataSize; }
bool has_peak () const { return (tupleIndex & TuppleIndex::EmbeddedPeakTuple) != 0; }
bool has_intermediate () const { return (tupleIndex & TuppleIndex::IntermediateRegion) != 0; }
bool has_private_points () const { return (tupleIndex & TuppleIndex::PrivatePointNumbers) != 0; }
bool has_peak () const { return (tupleIndex & TuppleIndex::EmbeddedPeakTuple); }
bool has_intermediate () const { return (tupleIndex & TuppleIndex::IntermediateRegion); }
bool has_private_points () const { return (tupleIndex & TuppleIndex::PrivatePointNumbers); }
unsigned int get_index () const { return (tupleIndex & TuppleIndex::TupleIndexMask); }
protected:
@ -144,7 +144,7 @@ struct TupleVarHeader
struct TupleVarCount : HBUINT16
{
bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers) != 0; }
bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
unsigned int get_count () const { return (*this) & CountMask; }
protected:
@ -236,7 +236,7 @@ struct GlyphVarData
if (!check.in_range (p)) return false;
uint16_t count = *p++;
if ((count & POINTS_ARE_WORDS) != 0)
if (count & POINTS_ARE_WORDS)
{
if (!check.in_range (p)) return false;
count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
@ -250,7 +250,7 @@ struct GlyphVarData
uint16_t j;
uint8_t control = *p++;
uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
if ((control & POINTS_ARE_WORDS) != 0)
if (control & POINTS_ARE_WORDS)
{
for (j = 0; j < run_count && i < count; j++, i++)
{
@ -291,12 +291,12 @@ struct GlyphVarData
uint16_t j;
uint8_t control = *p++;
uint16_t run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
if ((control & DELTAS_ARE_ZERO) != 0)
if (control & DELTAS_ARE_ZERO)
{
for (j = 0; j < run_count && i < count; j++, i++)
deltas[i] = 0;
}
else if ((control & DELTAS_ARE_WORDS) != 0)
else if (control & DELTAS_ARE_WORDS)
{
for (j = 0; j < run_count && i < count; j++, i++)
{
@ -505,6 +505,7 @@ struct gvar
if (unlikely (coord_count != gvar_table->axisCount)) return false;
const GlyphVarData *var_data = gvar_table->get_glyph_var_data (glyph);
if (var_data == &Null(GlyphVarData)) return true;
hb_vector_t <unsigned int> shared_indices;
GlyphVarData::tuple_iterator_t iterator;
if (!GlyphVarData::get_tuple_iterator (var_data,
@ -611,10 +612,13 @@ struct gvar
if (!glyf_accel.get_composite (glyph, &composite)) return true; /* simple glyph */
do
{
/* TODO: support component scale/transformation */
if (((composite.current->flags & glyf::CompositeGlyphHeader::USE_MY_METRICS) != 0) &&
!get_var_metrics (composite.current->glyphIndex, coords, coord_count, phantoms))
return false;
if (composite.current->flags & glyf::CompositeGlyphHeader::USE_MY_METRICS)
{
if (!get_var_metrics (composite.current->glyphIndex, coords, coord_count, phantoms))
return false;
for (unsigned int j = 0; j < phantoms.length; j++)
composite.current->transform_point (phantoms[j].x, phantoms[j].y);
}
} while (composite.move_to_next());
return true;
}
@ -664,7 +668,8 @@ struct gvar
if (!get_bounds_var (composite.current->glyphIndex, coords, coord_count, comp_bounds))
return false;
/* TODO: support component scale/transformation */
composite.current->transform_point (comp_bounds.min.x, comp_bounds.min.y);
composite.current->transform_point (comp_bounds.max.x, comp_bounds.max.y);
bounds._union (comp_bounds);
} while (composite.move_to_next());
return true;