[paint] Add internal push_translate/pop_translate

This commit is contained in:
Behdad Esfahbod 2022-12-31 11:24:42 -07:00
parent df91677997
commit 7363eb373a
3 changed files with 56 additions and 62 deletions

View File

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

View File

@ -885,12 +885,11 @@ struct PaintTranslate
void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
{ {
c->funcs->push_transform (c->data, float ddx = dx + c->instancer (varIdxBase, 0);
1., 0., 0., 1., float ddy = dy + c->instancer (varIdxBase, 1);
dx + c->instancer (varIdxBase, 0), c->funcs->push_translate (c->data, ddx, ddy);
dy + c->instancer (varIdxBase, 0));
c->recurse (this+src); 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) */ HBUINT8 format; /* format = 14(noVar) or 15 (Var) */
@ -962,17 +961,17 @@ struct PaintScaleAroundCenter
{ {
float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterX = centerX + c->instancer (varIdxBase, 2);
float tCenterY = centerY + c->instancer (varIdxBase, 3); float tCenterY = centerY + c->instancer (varIdxBase, 3);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_transform (c->data, c->funcs->push_transform (c->data,
scaleX.to_float (c->instancer (varIdxBase, 0)), scaleX.to_float (c->instancer (varIdxBase, 0)),
0., 0., 0., 0.,
scaleY.to_float (c->instancer (varIdxBase, 1)), scaleY.to_float (c->instancer (varIdxBase, 1)),
0., 0.); 0., 0.);
c->funcs->push_transform (c->data, 0., 0., 0., 0., -tCenterX, -tCenterY); c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
c->recurse (this+src); c->recurse (this+src);
c->funcs->pop_translate (c->data, -tCenterX, -tCenterY);
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_transform (c->data);
} }
HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ HBUINT8 format; /* format = 18 (noVar) or 19(Var) */
@ -1043,13 +1042,13 @@ struct PaintScaleUniformAroundCenter
float s = scale + c->instancer (varIdxBase, 0); float s = scale + c->instancer (varIdxBase, 0);
float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterX = centerX + c->instancer (varIdxBase, 1);
float tCenterY = centerY + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 2);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_transform (c->data, s, 0., 0., s, 0., 0.); 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->recurse (this+src); c->recurse (this+src);
c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
c->funcs->pop_transform (c->data); c->funcs->pop_transform (c->data);
c->funcs->pop_transform (c->data); c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->pop_transform (c->data);
} }
HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ HBUINT8 format; /* format = 22 (noVar) or 23(Var) */
@ -1123,13 +1122,13 @@ struct PaintRotateAroundCenter
float ss = sinf (a * (float) M_PI); float ss = sinf (a * (float) M_PI);
float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterX = centerX + c->instancer (varIdxBase, 1);
float tCenterY = centerY + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 2);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_transform (c->data, cc, ss, -ss, cc, 0., 0.); 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->recurse (this+src); c->recurse (this+src);
c->funcs->pop_translate (c->data, -tCenterX, -tCenterY);
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_transform (c->data);
} }
HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ HBUINT8 format; /* format = 26 (noVar) or 27(Var) */
@ -1202,13 +1201,13 @@ struct PaintSkewAroundCenter
float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI); float y = -tanf (ySkewAngle.to_float(c->instancer (varIdxBase, 1)) * (float) M_PI);
float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterX = centerX + c->instancer (varIdxBase, 2);
float tCenterY = centerY + c->instancer (varIdxBase, 3); float tCenterY = centerY + c->instancer (varIdxBase, 3);
c->funcs->push_transform (c->data, 0., 0., 0., 0., +tCenterX, +tCenterY); c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
c->funcs->push_transform (c->data, 1., y, x, 1., 0., 0.); 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->recurse (this+src); c->recurse (this+src);
c->funcs->pop_translate (c->data, -tCenterX, -tCenterY);
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_transform (c->data);
} }
HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ HBUINT8 format; /* format = 30(noVar) or 31 (Var) */

View File

@ -173,6 +173,20 @@ struct hb_paint_funcs_t
func.pop_transform (this, paint_data, func.pop_transform (this, paint_data,
!user_data ? nullptr : user_data->pop_transform); !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);
}
}; };
DECLARE_NULL_INSTANCE (hb_paint_funcs_t); DECLARE_NULL_INSTANCE (hb_paint_funcs_t);