[glyf] Flesh out VarCompositeGlyph
This commit is contained in:
parent
21f671bc45
commit
575d99406a
|
@ -14,42 +14,37 @@ struct VarCompositeGlyphRecord
|
||||||
protected:
|
protected:
|
||||||
enum var_composite_glyph_flag_t
|
enum var_composite_glyph_flag_t
|
||||||
{
|
{
|
||||||
ARG_1_AND_2_ARE_WORDS = 0x0001,
|
USE_MY_METRICS = 0x0001,
|
||||||
ARGS_ARE_XY_VALUES = 0x0002,
|
AXIS_INDICES_ARE_SHORT = 0x0002,
|
||||||
ROUND_XY_TO_GRID = 0x0004,
|
UNIFORM_SCALE = 0x0004,
|
||||||
WE_HAVE_A_SCALE = 0x0008,
|
HAVE_TRANSLATE_X = 0x0008,
|
||||||
MORE_COMPONENTS = 0x0020,
|
HAVE_TRANSLATE_Y = 0x0010,
|
||||||
WE_HAVE_AN_X_AND_Y_SCALE = 0x0040,
|
HAVE_ROTATION = 0x0020,
|
||||||
WE_HAVE_A_TWO_BY_TWO = 0x0080,
|
HAVE_SCALE_X = 0x0040,
|
||||||
WE_HAVE_INSTRUCTIONS = 0x0100,
|
HAVE_SCALE_Y = 0x0080,
|
||||||
USE_MY_METRICS = 0x0200,
|
HAVE_SKEW_X = 0x0100,
|
||||||
OVERLAP_COMPOUND = 0x0400,
|
HAVE_SKEW_Y = 0x0200,
|
||||||
SCALED_COMPONENT_OFFSET = 0x0800,
|
HAVE_TCENTER_X = 0x0400,
|
||||||
UNSCALED_COMPONENT_OFFSET = 0x1000,
|
HAVE_TCENTER_Y = 0x0800,
|
||||||
#ifndef HB_NO_BEYOND_64K
|
|
||||||
GID_IS_24BIT = 0x2000
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{
|
{
|
||||||
unsigned int size = min_size;
|
unsigned int size = min_size;
|
||||||
/* glyphIndex is 24bit instead of 16bit */
|
|
||||||
#ifndef HB_NO_BEYOND_64K
|
|
||||||
if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size;
|
|
||||||
#endif
|
|
||||||
/* arg1 and 2 are int16 */
|
|
||||||
if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
|
|
||||||
/* arg1 and 2 are int8 */
|
|
||||||
else size += 2;
|
|
||||||
|
|
||||||
/* One x 16 bit (scale) */
|
unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
|
||||||
if (flags & WE_HAVE_A_SCALE) size += 2;
|
size += num_axes * axis_width;
|
||||||
/* Two x 16 bit (xscale, yscale) */
|
|
||||||
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
|
if (flags & HAVE_TRANSLATE_X) size += 2;
|
||||||
/* Four x 16 bit (xscale, scale01, scale10, yscale) */
|
if (flags & HAVE_TRANSLATE_Y) size += 2;
|
||||||
else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
|
if (flags & HAVE_ROTATION) size += 2;
|
||||||
|
if (flags & HAVE_SCALE_X) size += 2;
|
||||||
|
if (flags & HAVE_SCALE_Y) size += 2;
|
||||||
|
if (flags & HAVE_SKEW_X) size += 2;
|
||||||
|
if (flags & HAVE_SKEW_Y) size += 2;
|
||||||
|
if (flags & HAVE_TCENTER_X) size += 2;
|
||||||
|
if (flags & HAVE_TCENTER_Y) size += 2;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -58,81 +53,126 @@ struct VarCompositeGlyphRecord
|
||||||
{
|
{
|
||||||
float matrix[4];
|
float matrix[4];
|
||||||
contour_point_t trans;
|
contour_point_t trans;
|
||||||
if (get_transformation (matrix, trans))
|
|
||||||
{
|
|
||||||
points.transform (matrix);
|
points.transform (matrix);
|
||||||
points.translate (trans);
|
points.translate (trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void transform (float (&matrix)[4], contour_point_t &trans,
|
||||||
|
float (other)[6])
|
||||||
|
{
|
||||||
|
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L268
|
||||||
|
float xx1 = other[0];
|
||||||
|
float xy1 = other[1];
|
||||||
|
float yx1 = other[2];
|
||||||
|
float yy1 = other[3];
|
||||||
|
float dx1 = other[4];
|
||||||
|
float dy1 = other[5];
|
||||||
|
float xx2 = matrix[0];
|
||||||
|
float xy2 = matrix[1];
|
||||||
|
float yx2 = matrix[2];
|
||||||
|
float yy2 = matrix[3];
|
||||||
|
float dx2 = trans.x;
|
||||||
|
float dy2 = trans.y;
|
||||||
|
|
||||||
|
matrix[0] = xx1*xx2 + xy1*yx2;
|
||||||
|
matrix[1] = xx1*xy2 + xy1*yy2;
|
||||||
|
matrix[2] = yx1*xx2 + yy1*yx2;
|
||||||
|
matrix[3] = yx1*xy2 + yy1*yy2;
|
||||||
|
trans.x = xx2*dx1 + yx2*dy1 + dx2;
|
||||||
|
trans.y = xy2*dx1 + yy2*dy1 + dy2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
|
static void translate (float (&matrix)[4], contour_point_t &trans,
|
||||||
|
float translateX, float translateY)
|
||||||
{
|
{
|
||||||
|
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213
|
||||||
|
float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY};
|
||||||
|
transform (matrix, trans, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scale (float (&matrix)[4], contour_point_t &trans,
|
||||||
|
float scaleX, float scaleY)
|
||||||
|
{
|
||||||
|
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224
|
||||||
|
float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f};
|
||||||
|
transform (matrix, trans, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rotate (float (&matrix)[4], contour_point_t &trans,
|
||||||
|
float rotation)
|
||||||
|
{
|
||||||
|
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
|
||||||
|
rotation = rotation * float (M_PI);
|
||||||
|
float c = cosf (rotation);
|
||||||
|
float s = sinf (rotation);
|
||||||
|
float other[6] = {c, s, -s, c, 0.f, 0.f};
|
||||||
|
transform (matrix, trans, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skew (float (&matrix)[4], contour_point_t &trans,
|
||||||
|
float skewX, float skewY)
|
||||||
|
{
|
||||||
|
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
|
||||||
|
skewX = skewX * float (M_PI);
|
||||||
|
skewY = skewY * float (M_PI);
|
||||||
|
float other[6] = {1.f, tanf (skewY), tanf (skewX), 0.f, 0.f};
|
||||||
|
transform (matrix, trans, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_transformation (float (&matrix)[4], contour_point_t &trans) const
|
||||||
|
{
|
||||||
|
float translateX = 0.f;
|
||||||
|
float translateY = 0.f;
|
||||||
|
float rotation = 0.f;
|
||||||
|
float scaleX = 1.f;
|
||||||
|
float scaleY = 1.f;
|
||||||
|
float skewX = 0.f;
|
||||||
|
float skewY = 0.f;
|
||||||
|
float tCenterX = 0.f;
|
||||||
|
float tCenterY = 0.f;
|
||||||
|
|
||||||
|
unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
|
||||||
|
unsigned axes_size = num_axes * axis_width;
|
||||||
|
const HBUINT16 *p = (const HBUINT16 *) (axes_size +
|
||||||
|
&StructAfter<const HBUINT8> (num_axes));
|
||||||
|
|
||||||
|
if (flags & HAVE_TRANSLATE_X) translateX = * (const FWORD *) p++;
|
||||||
|
if (flags & HAVE_TRANSLATE_Y) translateY = * (const FWORD *) p++;
|
||||||
|
if (flags & HAVE_ROTATION) rotation = (* (const F2DOT14 *) p++).to_float ();
|
||||||
|
if (flags & HAVE_SCALE_X) scaleX = * (const F4DOT12 *) p++;
|
||||||
|
if (flags & HAVE_SCALE_Y) scaleY = * (const F4DOT12 *) p++;
|
||||||
|
if (flags & HAVE_SKEW_X) skewX = (* (const F2DOT14 *) p++).to_float ();
|
||||||
|
if (flags & HAVE_SKEW_Y) skewY = (* (const F2DOT14 *) p++).to_float ();
|
||||||
|
if (flags & HAVE_TCENTER_X) tCenterX = * (const FWORD *) p++;
|
||||||
|
if (flags & HAVE_TCENTER_Y) tCenterY = * (const FWORD *) p++;
|
||||||
|
|
||||||
|
if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y))
|
||||||
|
scaleY = scaleX;
|
||||||
|
|
||||||
matrix[0] = matrix[3] = 1.f;
|
matrix[0] = matrix[3] = 1.f;
|
||||||
matrix[1] = matrix[2] = 0.f;
|
matrix[1] = matrix[2] = 0.f;
|
||||||
|
trans.init (0.f, 0.f);
|
||||||
|
|
||||||
const auto *p = &StructAfter<const HBINT8> (flags);
|
translate (matrix, trans, translateX + tCenterX, translateY + tCenterY);
|
||||||
#ifndef HB_NO_BEYOND_64K
|
rotate (matrix, trans, rotation);
|
||||||
if (flags & GID_IS_24BIT)
|
scale (matrix, trans, scaleX, scaleY);
|
||||||
p += HBGlyphID24::static_size;
|
skew (matrix, trans, -skewX, skewY);
|
||||||
else
|
translate (matrix, trans, -tCenterX, -tCenterY);
|
||||||
#endif
|
|
||||||
p += HBGlyphID16::static_size;
|
|
||||||
int tx, ty;
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
trans.init ((float) tx, (float) ty);
|
|
||||||
|
|
||||||
{
|
|
||||||
const F2DOT14 *points = (const F2DOT14 *) p;
|
|
||||||
if (flags & WE_HAVE_A_SCALE)
|
|
||||||
{
|
|
||||||
matrix[0] = matrix[3] = points[0].to_float ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
|
|
||||||
{
|
|
||||||
matrix[0] = points[0].to_float ();
|
|
||||||
matrix[3] = points[1].to_float ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (flags & WE_HAVE_A_TWO_BY_TWO)
|
|
||||||
{
|
|
||||||
matrix[0] = points[0].to_float ();
|
|
||||||
matrix[1] = points[1].to_float ();
|
|
||||||
matrix[2] = points[2].to_float ();
|
|
||||||
matrix[3] = points[3].to_float ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tx || ty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
hb_codepoint_t get_gid () const
|
hb_codepoint_t get_gid () const
|
||||||
{
|
{
|
||||||
#ifndef HB_NO_BEYOND_64K
|
return gid;
|
||||||
if (flags & GID_IS_24BIT)
|
|
||||||
return StructAfter<const HBGlyphID24> (flags);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return StructAfter<const HBGlyphID16> (flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 flags;
|
HBUINT16 flags;
|
||||||
HBUINT24 pad;
|
HBGlyphID16 gid;
|
||||||
|
HBUINT8 num_axes;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_MIN (4);
|
DEFINE_SIZE_MIN (5);
|
||||||
};
|
};
|
||||||
|
|
||||||
using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>;
|
using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>;
|
||||||
|
|
|
@ -157,6 +157,9 @@ struct HBFixed : Type
|
||||||
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
|
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
|
||||||
using F2DOT14 = HBFixed<HBINT16, 14>;
|
using F2DOT14 = HBFixed<HBINT16, 14>;
|
||||||
|
|
||||||
|
/* 16-bit signed fixed number with the low 12 bits of fraction (4.12). */
|
||||||
|
using F4DOT12 = HBFixed<HBINT16, 12>;
|
||||||
|
|
||||||
/* 32-bit signed fixed-point number (16.16). */
|
/* 32-bit signed fixed-point number (16.16). */
|
||||||
using F16DOT16 = HBFixed<HBINT32, 16>;
|
using F16DOT16 = HBFixed<HBINT32, 16>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue