[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.
This commit is contained in:
Dominik Röttsches 2021-02-10 19:24:13 +02:00 committed by Werner Lemberg
parent c8dede7b1c
commit 54c5ad5c92
3 changed files with 89 additions and 11 deletions

View File

@ -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.

View File

@ -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;
@ -4620,6 +4620,48 @@ FT_BEGIN_HEADER
} FT_PaintRadialGradient;
/**************************************************************************
*
* @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:
@ -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;

View File

@ -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;