diff --git a/ChangeLog b/ChangeLog index d310facff..62400f4c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2021-02-10 Dominik Röttsches + + [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 [sfnt] Provide optional root transform for 'COLR' v1 glyph graph. diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 5d8e8dcb9..c157796dc 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; @@ -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; diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 6ba3a6350..b90e35b61 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;