ref: d3d3ff76d11acf8956108d4f66ea1068c14c3f4a
parent: 588a058d9bb0aeffe500686a2d2b4db0e9cddd71
author: Dominik Röttsches <[email protected]>
date: Mon Nov 1 13:32:27 EDT 2021
[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
--- a/include/freetype/ftcolor.h
+++ b/include/freetype/ftcolor.h
@@ -870,13 +870,16 @@
* 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 @@
* 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_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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
*
* 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 @@
*
* 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
--- 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 );