Merge pull request #3991 from harfbuzz/paint-optimize-transform

Paint optimize transform
This commit is contained in:
Behdad Esfahbod 2022-12-31 14:38:06 -07:00 committed by GitHub
commit 1a0dd49f1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 164 additions and 120 deletions

View File

@ -334,78 +334,59 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
break;
case FT_COLR_PAINTFORMAT_TRANSLATE:
{
c->funcs->push_transform (c->data,
0.f, 0.f, 0.f, 0.f,
paint.u.translate.dx / 65536.f,
paint.u.translate.dy / 65536.f);
float dx = paint.u.translate.dx / 65536.f;
float dy = paint.u.translate.dy / 65536.f;
c->funcs->push_translate (c->data, dx, dy);
c->recurse (paint.u.translate.paint);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, dx, dy);
}
break;
case FT_COLR_PAINTFORMAT_SCALE:
{
bool has_translate = paint.u.scale.center_x != 0 || paint.u.scale.center_y != 0;
if (has_translate)
c->funcs->push_transform (c->data,
1.f, 0.f, 0.f, 1.f,
+paint.u.scale.center_x / 65536.f,
+paint.u.scale.center_y / 65536.f);
c->funcs->push_transform (c->data,
paint.u.scale.scale_x / 65536.f,
0.f, 0.f,
paint.u.scale.scale_y / 65536.f,
0.f, 0.f);
if (has_translate)
c->funcs->push_transform (c->data,
1.f, 0.f, 0.f, 1.f,
-paint.u.scale.center_x / 65536.f,
-paint.u.scale.center_y / 65536.f);
float dx = paint.u.scale.center_x / 65536.f;
float dy = paint.u.scale.center_y / 65536.f;
float sx = paint.u.scale.scale_x / 65536.f;
float sy = paint.u.scale.scale_y / 65536.f;
c->funcs->push_translate (c->data, +dx, +dy);
c->funcs->push_scale (c->data, sx, sy);
c->funcs->push_translate (c->data, -dx, -dy);
c->recurse (paint.u.scale.paint);
c->funcs->pop_transform (c->data);
if (has_translate)
{
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
}
c->funcs->pop_translate (c->data, -dx, -dy);
c->funcs->pop_scale (c->data, sx, sy);
c->funcs->pop_translate (c->data, +dx, +dy);
}
break;
case FT_COLR_PAINTFORMAT_ROTATE:
{
float dx = paint.u.rotate.center_x / 65536.f;
float dy = paint.u.rotate.center_y / 65536.f;
float a = paint.u.rotate.angle / 65536.f;
float cc = cosf (a * (float) M_PI);
float ss = sinf (a * (float) M_PI);
c->funcs->push_transform (c->data,
1.f, 0.f, 0.f, 1.f,
+paint.u.rotate.center_x / 65536.f,
+paint.u.rotate.center_y / 65536.f);
c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.);
c->funcs->push_transform (c->data,
1.f, 0.f, 0.f, 1.f,
-paint.u.rotate.center_x / 65536.f,
-paint.u.rotate.center_y / 65536.f);
c->funcs->push_translate (c->data, +dx, +dy);
c->funcs->push_rotate (c->data, a);
c->funcs->push_translate (c->data, -dx, -dy);
c->recurse (paint.u.rotate.paint);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, -dx, -dy);
c->funcs->pop_rotate (c->data, a);
c->funcs->pop_translate (c->data, +dx, +dy);
}
break;
case FT_COLR_PAINTFORMAT_SKEW:
{
float x = +tanf (paint.u.skew.x_skew_angle / 65536.f * (float) M_PI);
float y = -tanf (paint.u.skew.y_skew_angle / 65536.f * (float) M_PI);
c->funcs->push_transform (c->data,
1.f, 0.f, 0.f, 1.f,
+paint.u.skew.center_x / 65536.f,
+paint.u.skew.center_y / 65536.f);
c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.);
c->funcs->push_transform (c->data,
1.f, 0.f, 0.f, 1.f,
-paint.u.skew.center_x / 65536.f,
-paint.u.skew.center_y / 65536.f);
float dx = paint.u.skew.center_x / 65536.f;
float dy = paint.u.skew.center_y / 65536.f;
float sx = paint.u.skew.x_skew_angle / 65536.f;
float sy = paint.u.skew.y_skew_angle / 65536.f;
c->funcs->push_translate (c->data, +dx, +dy);
c->funcs->push_skew (c->data, sx, sy);
c->funcs->push_translate (c->data, -dx, -dy);
c->recurse (paint.u.skew.paint);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, -dx, -dy);
c->funcs->pop_skew (c->data, sx, sy);
c->funcs->pop_translate (c->data, +dx, +dy);
}
break;
case FT_COLR_PAINTFORMAT_COMPOSITE:

View File

@ -885,12 +885,12 @@ struct PaintTranslate
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
c->funcs->push_transform (c->data,
1., 0., 0., 1.,
dx + c->instancer (varIdxBase, 0),
dy + c->instancer (varIdxBase, 0));
float ddx = dx + c->instancer (varIdxBase, 0);
float ddy = dy + c->instancer (varIdxBase, 1);
c->funcs->push_translate (c->data, ddx, ddy);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, ddx, ddy);
}
HBUINT8 format; /* format = 14(noVar) or 15 (Var) */
@ -922,13 +922,12 @@ struct PaintScale
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
c->funcs->push_transform (c->data,
scaleX.to_float (c->instancer (varIdxBase, 0)),
0., 0.,
scaleY.to_float (c->instancer (varIdxBase, 1)),
0., 0.);
float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
c->funcs->push_scale (c->data, sx, sy);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_scale (c->data, sx, sy);
}
HBUINT8 format; /* format = 16 (noVar) or 17(Var) */
@ -960,19 +959,18 @@ struct PaintScaleAroundCenter
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
float tCenterX = centerX + c->instancer (varIdxBase, 2);
float tCenterY = centerY + c->instancer (varIdxBase, 3);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY);
c->funcs->push_transform (c->data,
scaleX.to_float (c->instancer (varIdxBase, 0)),
0., 0.,
scaleY.to_float (c->instancer (varIdxBase, 1)),
0., 0.);
c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY);
c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_scale (c->data, sx, sy);
c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, -tCenterX, -tCenterY);
c->funcs->pop_scale (c->data, sx, sy);
c->funcs->pop_translate (c->data, +tCenterX, +tCenterY);
}
HBUINT8 format; /* format = 18 (noVar) or 19(Var) */
@ -1007,9 +1005,10 @@ struct PaintScaleUniform
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
float s = scale + c->instancer (varIdxBase, 0);
c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.);
c->funcs->push_scale (c->data, s, s);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_scale (c->data, s, s);
}
HBUINT8 format; /* format = 20 (noVar) or 21(Var) */
@ -1043,13 +1042,14 @@ struct PaintScaleUniformAroundCenter
float s = scale + c->instancer (varIdxBase, 0);
float tCenterX = centerX + c->instancer (varIdxBase, 1);
float tCenterY = centerY + c->instancer (varIdxBase, 2);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY);
c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.);
c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY);
c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_scale (c->data, s, s);
c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, -tCenterX, -tCenterY);
c->funcs->pop_scale (c->data, s, s);
c->funcs->pop_translate (c->data, +tCenterX, +tCenterY);
}
HBUINT8 format; /* format = 22 (noVar) or 23(Var) */
@ -1083,11 +1083,10 @@ struct PaintRotate
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
float a = angle.to_float (c->instancer (varIdxBase, 0));
float cc = cosf (a * (float) M_PI);
float ss = sinf (a * (float) M_PI);
c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.);
c->funcs->push_rotate (c->data, a);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_rotate (c->data, a);
}
HBUINT8 format; /* format = 24 (noVar) or 25(Var) */
@ -1119,17 +1118,16 @@ struct PaintRotateAroundCenter
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
float a = angle.to_float (c->instancer (varIdxBase, 0));
float cc = cosf (a * (float) M_PI);
float ss = sinf (a * (float) M_PI);
float tCenterX = centerX + c->instancer (varIdxBase, 1);
float tCenterY = centerY + c->instancer (varIdxBase, 2);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY);
c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.);
c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY);
c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_rotate (c->data, a);
c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, -tCenterX, -tCenterY);
c->funcs->pop_rotate (c->data, a);
c->funcs->pop_translate (c->data, +tCenterX, +tCenterY);
}
HBUINT8 format; /* format = 26 (noVar) or 27(Var) */
@ -1162,11 +1160,12 @@ struct PaintSkew
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI);
float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI);
c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.);
float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
c->funcs->push_skew (c->data, sx, sy);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_skew (c->data, sx, sy);
}
HBUINT8 format; /* format = 28(noVar) or 29 (Var) */
@ -1198,17 +1197,18 @@ struct PaintSkewAroundCenter
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{
float x = +tanf (xSkewAngle.to_float(c->instancer (varIdxBase, 0)) * (float) M_PI);
float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI);
float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
float tCenterX = centerX + c->instancer (varIdxBase, 2);
float tCenterY = centerY + c->instancer (varIdxBase, 3);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY);
c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.);
c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY);
c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_skew (c->data, sx, sy);
c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
c->recurse (this+src);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data);
c->funcs->pop_translate (c->data, -tCenterX, -tCenterY);
c->funcs->pop_skew (c->data, sx, sy);
c->funcs->pop_translate (c->data, +tCenterX, +tCenterY);
}
HBUINT8 format; /* format = 30(noVar) or 31 (Var) */

View File

@ -138,6 +138,9 @@ struct hb_paint_funcs_t
mode,
!user_data ? nullptr : user_data->pop_group); }
/* Internal specializations. */
void push_root_transform (void *paint_data,
const hb_font_t *font)
{
@ -145,9 +148,8 @@ struct hb_paint_funcs_t
int xscale = font->x_scale, yscale = font->y_scale;
float slant = font->slant_xy;
func.push_transform (this, paint_data,
xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0,
!user_data ? nullptr : user_data->push_transform);
push_transform (paint_data,
xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0);
}
void pop_root_transform (void *paint_data)
{
@ -163,15 +165,76 @@ struct hb_paint_funcs_t
int yscale = font->y_scale ? font->y_scale : upem;
float slant = font->slant_xy;
func.push_transform (this, paint_data,
upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0,
!user_data ? nullptr : user_data->push_transform);
push_transform (paint_data,
upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0);
}
void pop_inverse_root_transform (void *paint_data)
{
func.pop_transform (this, paint_data,
!user_data ? nullptr : user_data->pop_transform);
}
void push_translate (void *paint_data,
float dx, float dy)
{
if (dx || dy)
push_transform (paint_data,
1.f, 0.f, 0.f, 1.f, dx, dy);
}
void pop_translate (void *paint_data,
float dx, float dy)
{
if (dx || dy)
pop_transform (paint_data);
}
void push_scale (void *paint_data,
float sx, float sy)
{
if (sx != 1.f || sy != 1.f)
push_transform (paint_data,
sx, 0.f, 0.f, sy, 0.f, 0.f);
}
void pop_scale (void *paint_data,
float sx, float sy)
{
if (sx != 1.f || sy != 1.f)
pop_transform (paint_data);
}
void push_rotate (void *paint_data,
float a)
{
if (a)
{
float cc = cosf (a * (float) M_PI);
float ss = sinf (a * (float) M_PI);
push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f);
}
}
void pop_rotate (void *paint_data,
float a)
{
if (a)
pop_transform (paint_data);
}
void push_skew (void *paint_data,
float sx, float sy)
{
if (sx || sy)
{
float x = +tanf (sx * (float) M_PI);
float y = -tanf (sy * (float) M_PI);
push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f);
}
}
void pop_skew (void *paint_data,
float sx, float sy)
{
if (sx || sy)
pop_transform (paint_data);
}
};
DECLARE_NULL_INSTANCE (hb_paint_funcs_t);

View File

@ -9,9 +9,9 @@ start clip rectangle 5.000000 5.000000 15.000000 15.000000
end clip
end transform
push group
start transform 0.000000 0.000000 0.000000 0.000000 1000.000000 1000.000000
start transform 1.000000 0.000000 0.000000 1.000000 1000.000000 1000.000000
start transform 1.000000 -0.363874 -0.176283 1.000000 0.000000 0.000000
start transform 0.000000 0.000000 0.000000 0.000000 -1000.000000 -1000.000000
start transform 1.000000 0.000000 0.000000 1.000000 -1000.000000 -1000.000000
start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000
start clip glyph 3
start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000

View File

@ -11,9 +11,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000
pop group mode 3
push group
push group
start transform 0.000000 0.000000 0.000000 0.000000 333.000000 667.000000
start transform 1.000000 0.000000 0.000000 1.000000 333.000000 667.000000
start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000
start transform 0.000000 0.000000 0.000000 0.000000 -333.000000 -667.000000
start transform 1.000000 0.000000 0.000000 1.000000 -333.000000 -667.000000
start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000
start clip glyph 2
start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000
@ -25,9 +25,9 @@ start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000
end transform
end transform
push group
start transform 0.000000 0.000000 0.000000 0.000000 667.000000 333.000000
start transform 1.000000 0.000000 0.000000 1.000000 667.000000 333.000000
start transform 8192.000000 0.000000 0.000000 8192.000000 0.000000 0.000000
start transform 0.000000 0.000000 0.000000 0.000000 -667.000000 -333.000000
start transform 1.000000 0.000000 0.000000 1.000000 -667.000000 -333.000000
start transform 50.000000 0.000000 -0.000000 50.000000 0.000000 0.000000
start clip glyph 2
start transform 0.020000 0.000000 0.000000 0.020000 0.000000 0.000000