add components transformation
This commit is contained in:
parent
139e87b56c
commit
bd040a4354
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue