From d3d3ff76d11acf8956108d4f66ea1068c14c3f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= Date: Mon, 1 Nov 2021 17:32:27 +0200 Subject: [PATCH] [sfnt] Clarify `COLR` v1 FT_Paint* format representations * include/freetype/ftcolor.h (FT_PaintLinearGradient, FT_PaintRadialGradient, FT_PaintSweepGradient, FT_PaintTransform, FT_PaintTranslate, FT_PaintScale, FT_PaintRotate, FT_PaintSkew): Clarify 16.16 fixed point representation of struct fields. * src/sfnt/ttcolr.c (read_paint): Shift coordinates for FT_PaintLinearGradient, FT_PaintRadialGradient, FT_PaintSweepGradient accordingly. Fixes: https://gitlab.freedesktop.org/freetype/freetype/-/issues/1110 --- include/freetype/ftcolor.h | 80 +++++++++++++++++++++++--------------- src/sfnt/ttcolr.c | 36 ++++++++++------- 2 files changed, 70 insertions(+), 46 deletions(-) diff --git a/include/freetype/ftcolor.h b/include/freetype/ftcolor.h index cbd2d85bb..08dbac0cc 100644 --- a/include/freetype/ftcolor.h +++ b/include/freetype/ftcolor.h @@ -870,13 +870,16 @@ FT_BEGIN_HEADER * color stops along the gradient. * * p0 :: - * The starting point of the gradient definition (in font units). + * The starting point of the gradient definition in font units + * represented as a 16.16 fixed-point `FT_Vector`. * * p1 :: - * The end point of the gradient definition (in font units). + * The end point of the gradient definition in font units + * represented as a 16.16 fixed-point `FT_Vector`. * * p2 :: - * Optional point~p2 to rotate the gradient (in font units). + * Optional point~p2 to rotate the gradient in font units + * represented as a 16.16 fixed-point `FT_Vector`. * Otherwise equal to~p0. * * @since: @@ -914,19 +917,20 @@ FT_BEGIN_HEADER * color stops along the gradient. * * c0 :: - * The center of the starting point of the radial gradient (in font - * units). + * The center of the starting point of the radial gradient in font + * units represented as a 16.16 fixed-point `FT_Vector`. * * r0 :: - * The radius of the starting circle of the radial gradient (in font - * units). + * The radius of the starting circle of the radial gradient in font + * units represented as a 16.16 fixed-point value. * * c1 :: - * The center of the end point of the radial gradient (in font units). + * The center of the end point of the radial gradient in font units + * represented as a 16.16 fixed-point `FT_Vector`. * * r1 :: - * The radius of the end circle of the radial gradient (in font - * units). + * The radius of the end circle of the radial gradient in font + * units represented as a 16.16 fixed-point value. * * @since: * 2.11 -- **currently experimental only!** There might be changes @@ -938,9 +942,9 @@ FT_BEGIN_HEADER FT_ColorLine colorline; FT_Vector c0; - FT_UShort r0; + FT_Pos r0; FT_Vector c1; - FT_UShort r1; + FT_Pos r1; } FT_PaintRadialGradient; @@ -963,16 +967,17 @@ FT_BEGIN_HEADER * color stops along the gradient. * * center :: - * The center of the sweep gradient (in font units). + * The center of the sweep gradient in font units represented as a + * vector of 16.16 fixed-point values. * * start_angle :: - * The start angle of the sweep gradient, in 16.16 fixed point + * The start angle of the sweep gradient in 16.16 fixed-point * format specifying degrees divided by 180.0 (as in the * spec). Multiply by 180.0f to receive degrees value. Values are * given counter-clockwise, starting from the (positive) y~axis. * * end_angle :: - * The end angle of the sweep gradient, in 16.16 fixed point + * The end angle of the sweep gradient in 16.16 fixed-point * format specifying degrees divided by 180.0 (as in the * spec). Multiply by 180.0f to receive degrees value. Values are * given counter-clockwise, starting from the (positive) y~axis. @@ -1061,7 +1066,8 @@ FT_BEGIN_HEADER * An opaque paint that is subject to being transformed. * * affine :: - * A 2x3 transformation matrix in @FT_Affine23 format. + * A 2x3 transformation matrix in @FT_Affine23 format containing + * 16.16 fixed-point values. * * @since: * 2.11 -- **currently experimental only!** There might be changes @@ -1091,10 +1097,12 @@ FT_BEGIN_HEADER * rotated. * * dx :: - * Translation in x~direction (in font units). + * Translation in x~direction in font units represented as a + * 16.16 fixed-point value. * * dy :: - * Translation in y~direction (in font units). + * Translation in y~direction in font units represented as a + * 16.16 fixed-point value. * * @since: * 2.11 -- **currently experimental only!** There might be changes @@ -1132,16 +1140,20 @@ FT_BEGIN_HEADER * scaled. * * scale_x :: - * Scale factor in x~direction. + * Scale factor in x~direction represented as a + * 16.16 fixed-point value. * * scale_y :: - * Scale factor in y~direction. + * Scale factor in y~direction represented as a + * 16.16 fixed-point value. * * center_x :: - * x~coordinate of center point to scale from. + * x~coordinate of center point to scale from represented as a + * 16.16 fixed-point value. * * center_y :: - * y~coordinate of center point to scale from. + * y~coordinate of center point to scale from represented as a + * 16.16 fixed-point value. * * @since: * 2.11 -- **currently experimental only!** There might be changes @@ -1177,16 +1189,16 @@ FT_BEGIN_HEADER * * angle :: * The rotation angle that is to be applied in degrees divided by - * 180.0 (as in the spec). Multiply by 180.0f to receive degrees - * value. + * 180.0 (as in the spec) represented as a 16.16 fixed-point + * value. Multiply by 180.0f to receive degrees value. * * center_x :: - * The x~coordinate of the pivot point of the rotation (in font - * units). + * The x~coordinate of the pivot point of the rotation in font + * units) represented as a 16.16 fixed-point value. * * center_y :: - * The y~coordinate of the pivot point of the rotation (in font - * units). + * The y~coordinate of the pivot point of the rotation in font + * units represented as a 16.16 fixed-point value. * * @since: * 2.11 -- **currently experimental only!** There might be changes @@ -1223,17 +1235,21 @@ FT_BEGIN_HEADER * * x_skew_angle :: * The skewing angle in x~direction in degrees divided by 180.0 - * (as in the spec). Multiply by 180.0f to receive degrees. + * (as in the spec) represented as a 16.16 fixed-point + * value. Multiply by 180.0f to receive degrees. * * y_skew_angle :: * The skewing angle in y~direction in degrees divided by 180.0 - * (as in the spec). Multiply by 180.0f to receive degrees. + * (as in the spec) represented as a 16.16 fixed-point + * value. Multiply by 180.0f to receive degrees. * * center_x :: - * The x~coordinate of the pivot point of the skew (in font units). + * The x~coordinate of the pivot point of the skew in font units + * represented as a 16.16 fixed-point value. * * center_y :: - * The y~coordinate of the pivot point of the skew (in font units). + * The y~coordinate of the pivot point of the skew in font units + * represented as a 16.16 fixed-point value. * * @since: * 2.11 -- **currently experimental only!** There might be changes diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 8b31b20cf..deec80b9b 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -505,12 +505,16 @@ &apaint->u.linear_gradient.colorline ) ) return 0; - apaint->u.linear_gradient.p0.x = FT_NEXT_SHORT( p ); - apaint->u.linear_gradient.p0.y = FT_NEXT_SHORT( p ); - apaint->u.linear_gradient.p1.x = FT_NEXT_SHORT( p ); - apaint->u.linear_gradient.p1.y = FT_NEXT_SHORT( p ); - apaint->u.linear_gradient.p2.x = FT_NEXT_SHORT( p ); - apaint->u.linear_gradient.p2.y = FT_NEXT_SHORT( p ); + /* + * In order to support variations expose these as FT_Fixed 16.16 values so + * that we can support fractional values after interpolation. + */ + apaint->u.linear_gradient.p0.x = FT_NEXT_SHORT( p ) << 16; + apaint->u.linear_gradient.p0.y = FT_NEXT_SHORT( p ) << 16; + apaint->u.linear_gradient.p1.x = FT_NEXT_SHORT( p ) << 16; + apaint->u.linear_gradient.p1.y = FT_NEXT_SHORT( p ) << 16; + apaint->u.linear_gradient.p2.x = FT_NEXT_SHORT( p ) << 16; + apaint->u.linear_gradient.p2.y = FT_NEXT_SHORT( p ) << 16; return 1; } @@ -521,15 +525,15 @@ &apaint->u.radial_gradient.colorline ) ) return 0; - apaint->u.radial_gradient.c0.x = FT_NEXT_SHORT( p ); - apaint->u.radial_gradient.c0.y = FT_NEXT_SHORT( p ); + apaint->u.radial_gradient.c0.x = FT_NEXT_SHORT( p ) << 16; + apaint->u.radial_gradient.c0.y = FT_NEXT_SHORT( p ) << 16; - apaint->u.radial_gradient.r0 = FT_NEXT_USHORT( p ); + apaint->u.radial_gradient.r0 = FT_NEXT_USHORT( p ) << 16; - apaint->u.radial_gradient.c1.x = FT_NEXT_SHORT( p ); - apaint->u.radial_gradient.c1.y = FT_NEXT_SHORT( p ); + apaint->u.radial_gradient.c1.x = FT_NEXT_SHORT( p ) << 16; + apaint->u.radial_gradient.c1.y = FT_NEXT_SHORT( p ) << 16; - apaint->u.radial_gradient.r1 = FT_NEXT_USHORT( p ); + apaint->u.radial_gradient.r1 = FT_NEXT_USHORT( p ) << 16; return 1; } @@ -540,8 +544,8 @@ &apaint->u.sweep_gradient.colorline ) ) return 0; - apaint->u.sweep_gradient.center.x = FT_NEXT_SHORT( p ); - apaint->u.sweep_gradient.center.y = FT_NEXT_SHORT( p ); + apaint->u.sweep_gradient.center.x = FT_NEXT_SHORT( p ) << 16; + apaint->u.sweep_gradient.center.y = FT_NEXT_SHORT( p ) << 16; apaint->u.sweep_gradient.start_angle = FT_NEXT_SHORT( p ) << 2; apaint->u.sweep_gradient.end_angle = FT_NEXT_SHORT( p ) << 2; @@ -568,6 +572,10 @@ p = child_table_p; + /* + * The following matrix coefficients are encoded as + * OpenType 16.16 fixed-point values. + */ apaint->u.transform.affine.xx = FT_NEXT_LONG( p ); apaint->u.transform.affine.yx = FT_NEXT_LONG( p ); apaint->u.transform.affine.xy = FT_NEXT_LONG( p );