[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> 2021-02-09 Dominik Röttsches <drott@chromium.org>
[sfnt] Provide optional root transform for 'COLR' v1 glyph graph. [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_SOLID = 2,
FT_COLR_PAINTFORMAT_LINEAR_GRADIENT = 3, FT_COLR_PAINTFORMAT_LINEAR_GRADIENT = 3,
FT_COLR_PAINTFORMAT_RADIAL_GRADIENT = 4, FT_COLR_PAINTFORMAT_RADIAL_GRADIENT = 4,
FT_COLR_PAINTFORMAT_GLYPH = 5, FT_COLR_PAINTFORMAT_SWEEP_GRADIENT = 5,
FT_COLR_PAINTFORMAT_COLR_GLYPH = 6, FT_COLR_PAINTFORMAT_GLYPH = 6,
FT_COLR_PAINTFORMAT_TRANSFORMED = 7, FT_COLR_PAINTFORMAT_COLR_GLYPH = 7,
FT_COLR_PAINTFORMAT_TRANSLATE = 8, FT_COLR_PAINTFORMAT_TRANSFORMED = 8,
FT_COLR_PAINTFORMAT_ROTATE = 9, FT_COLR_PAINTFORMAT_TRANSLATE = 9,
FT_COLR_PAINTFORMAT_SKEW = 10, FT_COLR_PAINTFORMAT_ROTATE = 10,
FT_COLR_PAINTFORMAT_COMPOSITE = 11, FT_COLR_PAINTFORMAT_SKEW = 11,
FT_COLR_PAINT_FORMAT_MAX = 12, FT_COLR_PAINTFORMAT_COMPOSITE = 12,
FT_COLR_PAINT_FORMAT_MAX = 13,
FT_COLR_PAINTFORMAT_UNSUPPORTED = 255 FT_COLR_PAINTFORMAT_UNSUPPORTED = 255
} FT_PaintFormat; } FT_PaintFormat;
@ -4611,7 +4612,6 @@ FT_BEGIN_HEADER
{ {
FT_ColorLine colorline; FT_ColorLine colorline;
/* TODO: Potentially expose those as x0, y0 etc. */
FT_Vector c0; FT_Vector c0;
FT_UShort r0; FT_UShort r0;
FT_Vector c1; FT_Vector c1;
@ -4620,6 +4620,48 @@ FT_BEGIN_HEADER
} FT_PaintRadialGradient; } 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: * @struct:
@ -4853,6 +4895,7 @@ FT_BEGIN_HEADER
* * @FT_PaintSolid * * @FT_PaintSolid
* * @FT_PaintLinearGradient * * @FT_PaintLinearGradient
* * @FT_PaintRadialGradient * * @FT_PaintRadialGradient
* * @FT_PaintSweepGradient
* * @FT_PaintTransformed * * @FT_PaintTransformed
* * @FT_PaintTranslate * * @FT_PaintTranslate
* * @FT_PaintRotate * * @FT_PaintRotate
@ -4871,6 +4914,7 @@ FT_BEGIN_HEADER
FT_PaintSolid solid; FT_PaintSolid solid;
FT_PaintLinearGradient linear_gradient; FT_PaintLinearGradient linear_gradient;
FT_PaintRadialGradient radial_gradient; FT_PaintRadialGradient radial_gradient;
FT_PaintSweepGradient sweep_gradient;
FT_PaintTransformed transformed; FT_PaintTransformed transformed;
FT_PaintTranslate translate; FT_PaintTranslate translate;
FT_PaintRotate rotate; FT_PaintRotate rotate;

View File

@ -441,7 +441,7 @@
if ( !read_color_line( paint_base, if ( !read_color_line( paint_base,
color_line_offset, color_line_offset,
&apaint->u.linear_gradient.colorline ) ) &apaint->u.radial_gradient.colorline ) )
return 0; return 0;
/* skip VarIdx entries */ /* skip VarIdx entries */
@ -462,6 +462,28 @@
FT_NEXT_ULONG ( p ); 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 ) else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORMED )
{ {
FT_UInt32 paint_offset; FT_UInt32 paint_offset;
@ -842,7 +864,7 @@
/* `x_scale` and `y_scale` are in 26.6 format, representing the scale /* `x_scale` and `y_scale` are in 26.6 format, representing the scale
* factor to get from font units to requested size. However, expected * 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.xx = ( face->root.size->metrics.x_scale + 32 ) >> 6;
ft_root_scale.xy = 0; ft_root_scale.xy = 0;