[sfnt] Implement 'COLR' v1 sweep gradients. * freetype.h (FT_PaintSweepGradient): Add `FT_PaintSweepGradient` to represent a 'COLR' v1 sweep gradient. Update format. (FT_PaintFormat): Update shifted paint formats. Sync with spec. * sfnt/ttcolr.c (read_paint): Logic to parse sweep gradients. Fix struct access in radial gradient implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
diff --git a/ChangeLog b/ChangeLog
index d310fac..62400f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2021-02-10 Dominik Röttsches <drott@chromium.org>
+
+ [sfnt] Implement 'COLR' v1 sweep gradients.
+
+ * freetype.h (FT_PaintSweepGradient): Add `FT_PaintSweepGradient` to
+ represent a 'COLR' v1 sweep gradient.
+ Update format.
+ (FT_PaintFormat): Update shifted paint formats.
+ Sync with spec.
+ * sfnt/ttcolr.c (read_paint): Logic to parse sweep gradients.
+ Fix struct access in radial gradient implementation.
+
2021-02-09 Dominik Röttsches <drott@chromium.org>
[sfnt] Provide optional root transform for 'COLR' v1 glyph graph.
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 5d8e8dc..c157796 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -4235,14 +4235,15 @@ FT_BEGIN_HEADER
FT_COLR_PAINTFORMAT_SOLID = 2,
FT_COLR_PAINTFORMAT_LINEAR_GRADIENT = 3,
FT_COLR_PAINTFORMAT_RADIAL_GRADIENT = 4,
- FT_COLR_PAINTFORMAT_GLYPH = 5,
- FT_COLR_PAINTFORMAT_COLR_GLYPH = 6,
- FT_COLR_PAINTFORMAT_TRANSFORMED = 7,
- FT_COLR_PAINTFORMAT_TRANSLATE = 8,
- FT_COLR_PAINTFORMAT_ROTATE = 9,
- FT_COLR_PAINTFORMAT_SKEW = 10,
- FT_COLR_PAINTFORMAT_COMPOSITE = 11,
- FT_COLR_PAINT_FORMAT_MAX = 12,
+ FT_COLR_PAINTFORMAT_SWEEP_GRADIENT = 5,
+ FT_COLR_PAINTFORMAT_GLYPH = 6,
+ FT_COLR_PAINTFORMAT_COLR_GLYPH = 7,
+ FT_COLR_PAINTFORMAT_TRANSFORMED = 8,
+ FT_COLR_PAINTFORMAT_TRANSLATE = 9,
+ FT_COLR_PAINTFORMAT_ROTATE = 10,
+ FT_COLR_PAINTFORMAT_SKEW = 11,
+ FT_COLR_PAINTFORMAT_COMPOSITE = 12,
+ FT_COLR_PAINT_FORMAT_MAX = 13,
FT_COLR_PAINTFORMAT_UNSUPPORTED = 255
} FT_PaintFormat;
@@ -4611,7 +4612,6 @@ FT_BEGIN_HEADER
{
FT_ColorLine colorline;
- /* TODO: Potentially expose those as x0, y0 etc. */
FT_Vector c0;
FT_UShort r0;
FT_Vector c1;
@@ -4623,6 +4623,48 @@ FT_BEGIN_HEADER
/**************************************************************************
*
* @struct:
+ * FT_PaintSweepGradient
+ *
+ * @description:
+ * A structure representing a `PaintSweepGradient` value of the 'COLR'
+ * v1 extensions, see
+ * 'https://github.com/googlefonts/colr-gradients-spec'. The glyph
+ * layer filled with this paint is drawn filled with a sweep gradient
+ * from `start_angle` to `end_angle`.
+ *
+ * @fields:
+ * colorline ::
+ * The @FT_ColorLine information for this paint, i.e., the list of
+ * color stops along the gradient.
+ *
+ * center ::
+ * The center of the sweep gradient (in font units).
+ *
+ * start_angle ::
+ * The start angle of the sweep gradient, in 16.16 fixed point format
+ * specifying degrees. 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 format
+ * specifying degrees. Values are given counter-clockwise, starting
+ * from the (positive) y~axis.
+ *
+ */
+ typedef struct FT_PaintSweepGradient_
+ {
+ FT_ColorLine colorline;
+
+ FT_Vector center;
+ FT_Fixed start_angle;
+ FT_Fixed end_angle;
+
+ } FT_PaintSweepGradient;
+
+
+ /**************************************************************************
+ *
+ * @struct:
* FT_PaintGlyph
*
* @description:
@@ -4853,6 +4895,7 @@ FT_BEGIN_HEADER
* * @FT_PaintSolid
* * @FT_PaintLinearGradient
* * @FT_PaintRadialGradient
+ * * @FT_PaintSweepGradient
* * @FT_PaintTransformed
* * @FT_PaintTranslate
* * @FT_PaintRotate
@@ -4871,6 +4914,7 @@ FT_BEGIN_HEADER
FT_PaintSolid solid;
FT_PaintLinearGradient linear_gradient;
FT_PaintRadialGradient radial_gradient;
+ FT_PaintSweepGradient sweep_gradient;
FT_PaintTransformed transformed;
FT_PaintTranslate translate;
FT_PaintRotate rotate;
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index 6ba3a63..b90e35b 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -441,7 +441,7 @@
if ( !read_color_line( paint_base,
color_line_offset,
- &apaint->u.linear_gradient.colorline ) )
+ &apaint->u.radial_gradient.colorline ) )
return 0;
/* skip VarIdx entries */
@@ -462,6 +462,28 @@
FT_NEXT_ULONG ( p );
}
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT )
+ {
+ FT_ULong color_line_offset = color_line_offset = FT_NEXT_OFF3( p );
+
+
+ if ( !read_color_line( paint_base,
+ color_line_offset,
+ &apaint->u.sweep_gradient.colorline ) )
+ return 0;
+
+ /* skip VarIdx entries */
+ apaint->u.sweep_gradient.center.x = FT_NEXT_SHORT ( p );
+ FT_NEXT_ULONG ( p );
+ apaint->u.sweep_gradient.center.y = FT_NEXT_SHORT ( p );
+ FT_NEXT_ULONG ( p );
+
+ apaint->u.sweep_gradient.start_angle = FT_NEXT_LONG( p );
+ FT_NEXT_ULONG ( p );
+ apaint->u.sweep_gradient.end_angle = FT_NEXT_LONG( p );
+ FT_NEXT_ULONG ( p );
+ }
+
else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORMED )
{
FT_UInt32 paint_offset;
@@ -842,7 +864,7 @@
/* `x_scale` and `y_scale` are in 26.6 format, representing the scale
* factor to get from font units to requested size. However, expected
- * return values are in 16.16, so we shift accordingly with rounding.
+ * return values are in 16.16, so we shift accordingly with rounding.
*/
ft_root_scale.xx = ( face->root.size->metrics.x_scale + 32 ) >> 6;
ft_root_scale.xy = 0;