diff options
Diffstat (limited to 'Build/source/libs/freetype2/freetype-src/src/sfnt/ttcolr.c')
-rw-r--r-- | Build/source/libs/freetype2/freetype-src/src/sfnt/ttcolr.c | 710 |
1 files changed, 15 insertions, 695 deletions
diff --git a/Build/source/libs/freetype2/freetype-src/src/sfnt/ttcolr.c b/Build/source/libs/freetype2/freetype-src/src/sfnt/ttcolr.c index bd478ab9b5b..9025e356ce3 100644 --- a/Build/source/libs/freetype2/freetype-src/src/sfnt/ttcolr.c +++ b/Build/source/libs/freetype2/freetype-src/src/sfnt/ttcolr.c @@ -4,8 +4,8 @@ * * TrueType and OpenType colored glyph layer support (body). * - * Copyright (C) 2018-2021 by - * David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. + * Copyright (C) 2018-2020 by + * David Turner, Robert Wilhelm, and Werner Lemberg. * * Originally written by Shao Yu Zhang <shaozhang@fb.com>. * @@ -31,7 +31,6 @@ #include <freetype/internal/ftstream.h> #include <freetype/tttags.h> #include <freetype/ftcolor.h> -#include <freetype/config/integer-types.h> #ifdef TT_CONFIG_OPTION_COLOR_LAYERS @@ -40,27 +39,12 @@ /* NOTE: These are the table sizes calculated through the specs. */ -#define BASE_GLYPH_SIZE 6U -#define BASE_GLYPH_PAINT_RECORD_SIZE 6U -#define LAYER_V1_LIST_PAINT_OFFSET_SIZE 4U -#define LAYER_V1_LIST_NUM_LAYERS_SIZE 4U -#define COLOR_STOP_SIZE 6U -#define LAYER_SIZE 4U -#define COLR_HEADER_SIZE 14U +#define BASE_GLYPH_SIZE 6U +#define LAYER_SIZE 4U +#define COLR_HEADER_SIZE 14U - typedef enum FT_PaintFormat_Internal_ - { - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18, - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20, - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22, - FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER = 26, - FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER = 30 - - } FT_PaintFormat_Internal; - - - typedef struct BaseGlyphRecord_ + typedef struct BaseGlyphRecord_ { FT_UShort gid; FT_UShort first_layer_index; @@ -69,16 +53,7 @@ } BaseGlyphRecord; - typedef struct BaseGlyphV1Record_ - { - FT_UShort gid; - /* Offset from start of BaseGlyphV1List, i.e., from base_glyphs_v1. */ - FT_ULong paint_offset; - - } BaseGlyphV1Record; - - - typedef struct Colr_ + typedef struct Colr_ { FT_UShort version; FT_UShort num_base_glyphs; @@ -87,21 +62,7 @@ FT_Byte* base_glyphs; FT_Byte* layers; - FT_ULong num_base_glyphs_v1; - /* Points at beginning of BaseGlyphV1List. */ - FT_Byte* base_glyphs_v1; - - FT_ULong num_layers_v1; - FT_Byte* layers_v1; - - /* - * Paint tables start at the minimum of the end of the LayerList and the - * end of the BaseGlyphList. Record this location in a field here for - * safety checks when accessing paint tables. - */ - FT_Byte* paints_start_v1; - - /* The memory that backs up the `COLR' table. */ + /* The memory which backs up the `COLR' table. */ void* table; FT_ULong table_size; @@ -127,14 +88,10 @@ FT_Byte* table = NULL; FT_Byte* p = NULL; - /* Needed for reading array lengths in referenced tables. */ - FT_Byte* p1 = NULL; Colr* colr = NULL; FT_ULong base_glyph_offset, layer_offset; - FT_ULong base_glyphs_offset_v1, num_base_glyphs_v1; - FT_ULong layer_offset_v1, num_layers_v1; FT_ULong table_size; @@ -158,7 +115,7 @@ goto NoColr; colr->version = FT_NEXT_USHORT( p ); - if ( colr->version != 0 && colr->version != 1 ) + if ( colr->version != 0 ) goto InvalidTable; colr->num_base_glyphs = FT_NEXT_USHORT( p ); @@ -178,56 +135,6 @@ if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset ) goto InvalidTable; - if ( colr->version == 1 ) - { - base_glyphs_offset_v1 = FT_NEXT_ULONG( p ); - - if ( base_glyphs_offset_v1 >= table_size ) - goto InvalidTable; - - p1 = (FT_Byte*)( table + base_glyphs_offset_v1 ); - num_base_glyphs_v1 = FT_PEEK_ULONG( p1 ); - - if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE > - table_size - base_glyphs_offset_v1 ) - goto InvalidTable; - - colr->num_base_glyphs_v1 = num_base_glyphs_v1; - colr->base_glyphs_v1 = p1; - - layer_offset_v1 = FT_NEXT_ULONG( p ); - - if ( layer_offset_v1 >= table_size ) - goto InvalidTable; - - if ( layer_offset_v1 ) - { - p1 = (FT_Byte*)( table + layer_offset_v1 ); - num_layers_v1 = FT_PEEK_ULONG( p1 ); - - if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE > - table_size - layer_offset_v1 ) - goto InvalidTable; - - colr->num_layers_v1 = num_layers_v1; - colr->layers_v1 = p1; - - colr->paints_start_v1 = - FT_MIN( colr->base_glyphs_v1 + - colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE, - colr->layers_v1 + - colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ); - } - else - { - colr->num_layers_v1 = 0; - colr->layers_v1 = 0; - colr->paints_start_v1 = - colr->base_glyphs_v1 + - colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE; - } - } - colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset ); colr->layers = (FT_Byte*)( table + layer_offset ); colr->table = table; @@ -267,17 +174,17 @@ static FT_Bool find_base_glyph_record( FT_Byte* base_glyph_begin, - FT_UInt num_base_glyph, + FT_Int num_base_glyph, FT_UInt glyph_id, BaseGlyphRecord* record ) { - FT_UInt min = 0; - FT_UInt max = num_base_glyph; + FT_Int min = 0; + FT_Int max = num_base_glyph - 1; - while ( min < max ) + while ( min <= max ) { - FT_UInt mid = min + ( max - min ) / 2; + FT_Int mid = min + ( max - min ) / 2; FT_Byte* p = base_glyph_begin + mid * BASE_GLYPH_SIZE; FT_UShort gid = FT_NEXT_USHORT( p ); @@ -286,7 +193,7 @@ if ( gid < glyph_id ) min = mid + 1; else if (gid > glyph_id ) - max = mid; + max = mid - 1; else { record->gid = gid; @@ -358,593 +265,6 @@ } - static FT_Bool - read_color_line( FT_Byte* color_line_p, - FT_ColorLine *colorline ) - { - FT_Byte* p = color_line_p; - FT_PaintExtend paint_extend; - - - paint_extend = (FT_PaintExtend)FT_NEXT_BYTE( p ); - if ( paint_extend > FT_COLR_PAINT_EXTEND_REFLECT ) - return 0; - - colorline->extend = paint_extend; - - colorline->color_stop_iterator.num_color_stops = FT_NEXT_USHORT( p ); - colorline->color_stop_iterator.p = p; - colorline->color_stop_iterator.current_color_stop = 0; - - return 1; - } - - - /* - * Read a paint offset for `FT_Paint*` objects that have them and check - * whether it is within reasonable limits within the font and the COLR - * table. - * - * Return 1 on success, 0 on failure. - */ - static FT_Bool - get_child_table_pointer ( Colr* colr, - FT_Byte* paint_base, - FT_Byte** p, - FT_Byte** child_table_pointer ) - { - FT_UInt32 paint_offset; - FT_Byte* child_table_p; - - - if ( !child_table_pointer ) - return 0; - - paint_offset = FT_NEXT_UOFF3( *p ); - if ( !paint_offset ) - return 0; - - child_table_p = (FT_Byte*)( paint_base + paint_offset ); - - if ( child_table_p < colr->paints_start_v1 || - child_table_p >= ( (FT_Byte*)colr->table + colr->table_size ) ) - return 0; - - *child_table_pointer = child_table_p; - return 1; - } - - - static FT_Bool - read_paint( Colr* colr, - FT_Byte* p, - FT_COLR_Paint* apaint ) - { - FT_Byte* paint_base = p; - FT_Byte* child_table_p = NULL; - - - if ( !p || !colr || !colr->table ) - return 0; - - if ( p < colr->paints_start_v1 || - p >= ( (FT_Byte*)colr->table + colr->table_size ) ) - return 0; - - apaint->format = (FT_PaintFormat)FT_NEXT_BYTE( p ); - - if ( apaint->format >= FT_COLR_PAINT_FORMAT_MAX ) - return 0; - - if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_LAYERS ) - { - /* Initialize layer iterator/ */ - FT_Byte num_layers; - FT_UInt32 first_layer_index; - - - num_layers = FT_NEXT_BYTE( p ); - if ( num_layers > colr->num_layers_v1 ) - return 0; - - first_layer_index = FT_NEXT_ULONG( p ); - if ( first_layer_index + num_layers > colr->num_layers_v1 ) - return 0; - - apaint->u.colr_layers.layer_iterator.num_layers = num_layers; - apaint->u.colr_layers.layer_iterator.layer = 0; - /* TODO: Check whether pointer is outside colr? */ - apaint->u.colr_layers.layer_iterator.p = - colr->layers_v1 + - LAYER_V1_LIST_NUM_LAYERS_SIZE + - LAYER_V1_LIST_PAINT_OFFSET_SIZE * first_layer_index; - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ) - { - apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p ); - apaint->u.solid.color.alpha = FT_NEXT_SHORT( p ); - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH ) - { - apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p ); - - return 1; - } - - /* - * Grouped below here are all paint formats that have an offset to a - * child paint table as the first entry (for example, a color line or a - * child paint table). Retrieve that and determine whether that paint - * offset is valid first. - */ - - if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) - return 0; - - if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ) - { - if ( !read_color_line( child_table_p, - &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 ); - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ) - { - if ( !read_color_line( child_table_p, - &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.r0 = FT_NEXT_USHORT( p ); - - apaint->u.radial_gradient.c1.x = FT_NEXT_SHORT( p ); - apaint->u.radial_gradient.c1.y = FT_NEXT_SHORT( p ); - - apaint->u.radial_gradient.r1 = FT_NEXT_USHORT( p ); - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT ) - { - if ( !read_color_line( child_table_p, - &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.start_angle = FT_NEXT_LONG( p ); - apaint->u.sweep_gradient.end_angle = FT_NEXT_LONG( p ); - - return 1; - } - - if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH ) - { - apaint->u.glyph.paint.p = child_table_p; - apaint->u.glyph.paint.insert_root_transform = 0; - apaint->u.glyph.glyphID = FT_NEXT_USHORT( p ); - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM ) - { - apaint->u.transform.paint.p = child_table_p; - apaint->u.transform.paint.insert_root_transform = 0; - - 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 ); - apaint->u.transform.affine.yy = FT_NEXT_LONG( p ); - apaint->u.transform.affine.dx = FT_NEXT_LONG( p ); - apaint->u.transform.affine.dy = FT_NEXT_LONG( p ); - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE ) - { - apaint->u.translate.paint.p = child_table_p; - apaint->u.translate.paint.insert_root_transform = 0; - - apaint->u.translate.dx = FT_NEXT_LONG( p ); - apaint->u.translate.dy = FT_NEXT_LONG( p ); - - return 1; - } - - else if ( apaint->format == - FT_COLR_PAINTFORMAT_SCALE || - (FT_PaintFormat_Internal)apaint->format == - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER || - (FT_PaintFormat_Internal)apaint->format == - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM || - (FT_PaintFormat_Internal)apaint->format == - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ) - { - apaint->u.scale.paint.p = child_table_p; - apaint->u.scale.paint.insert_root_transform = 0; - - /* All scale paints get at least one scale value. */ - apaint->u.scale.scale_x = FT_NEXT_LONG( p ); - - /* Non-uniform ones read an extra y value. */ - if ( apaint->format == - FT_COLR_PAINTFORMAT_SCALE || - (FT_PaintFormat_Internal)apaint->format == - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ) - apaint->u.scale.scale_y = FT_NEXT_LONG( p ); - else - apaint->u.scale.scale_y = apaint->u.scale.scale_x; - - /* Scale paints that have a center read center coordinates, */ - /* otherwise the center is (0,0). */ - if ( (FT_PaintFormat_Internal)apaint->format == - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER || - (FT_PaintFormat_Internal)apaint->format == - FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ) - { - apaint->u.scale.center_x = FT_NEXT_LONG ( p ); - apaint->u.scale.center_y = FT_NEXT_LONG ( p ); - } - else - { - apaint->u.scale.center_x = 0; - apaint->u.scale.center_y = 0; - } - - /* FT 'COLR' v1 API output format always returns fully defined */ - /* structs; we thus set the format to the public API value. */ - apaint->format = FT_COLR_PAINTFORMAT_SCALE; - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE ) - { - apaint->u.rotate.paint.p = child_table_p; - apaint->u.rotate.paint.insert_root_transform = 0; - - apaint->u.rotate.angle = FT_NEXT_LONG( p ); - - apaint->u.rotate.center_x = FT_NEXT_LONG( p ); - apaint->u.rotate.center_y = FT_NEXT_LONG( p ); - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW ) - { - apaint->u.skew.paint.p = child_table_p; - apaint->u.skew.paint.insert_root_transform = 0; - - apaint->u.skew.x_skew_angle = FT_NEXT_LONG( p ); - apaint->u.skew.y_skew_angle = FT_NEXT_LONG( p ); - - apaint->u.skew.center_x = FT_NEXT_LONG( p ); - apaint->u.skew.center_y = FT_NEXT_LONG( p ); - - return 1; - } - - else if ( apaint->format == FT_COLR_PAINTFORMAT_COMPOSITE ) - { - FT_UInt composite_mode; - - - apaint->u.composite.source_paint.p = child_table_p; - apaint->u.composite.source_paint.insert_root_transform = 0; - - composite_mode = FT_NEXT_BYTE( p ); - if ( composite_mode >= FT_COLR_COMPOSITE_MAX ) - return 0; - - apaint->u.composite.composite_mode = (FT_Composite_Mode)composite_mode; - - if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) ) - return 0; - - apaint->u.composite.backdrop_paint.p = - child_table_p; - apaint->u.composite.backdrop_paint.insert_root_transform = - 0; - - return 1; - } - - return 0; - } - - - static FT_Bool - find_base_glyph_v1_record( FT_Byte * base_glyph_begin, - FT_UInt num_base_glyph, - FT_UInt glyph_id, - BaseGlyphV1Record *record ) - { - FT_UInt min = 0; - FT_UInt max = num_base_glyph; - - - while ( min < max ) - { - FT_UInt mid = min + ( max - min ) / 2; - - /* - * `base_glyph_begin` is the beginning of `BaseGlyphV1List`; - * skip `numBaseGlyphV1Records` by adding 4 to start binary search - * in the array of `BaseGlyphV1Record`. - */ - FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE; - - FT_UShort gid = FT_NEXT_USHORT( p ); - - - if ( gid < glyph_id ) - min = mid + 1; - else if (gid > glyph_id ) - max = mid; - else - { - record->gid = gid; - record->paint_offset = FT_NEXT_ULONG ( p ); - return 1; - } - } - - return 0; - } - - - FT_LOCAL_DEF( FT_Bool ) - tt_face_get_colr_glyph_paint( TT_Face face, - FT_UInt base_glyph, - FT_Color_Root_Transform root_transform, - FT_OpaquePaint* opaque_paint ) - { - Colr* colr = (Colr*)face->colr; - BaseGlyphV1Record base_glyph_v1_record; - FT_Byte* p; - - if ( !colr || !colr->table ) - return 0; - - if ( colr->version < 1 || !colr->num_base_glyphs_v1 || - !colr->base_glyphs_v1 ) - return 0; - - if ( opaque_paint->p ) - return 0; - - if ( !find_base_glyph_v1_record( colr->base_glyphs_v1, - colr->num_base_glyphs_v1, - base_glyph, - &base_glyph_v1_record ) ) - return 0; - - if ( !base_glyph_v1_record.paint_offset || - base_glyph_v1_record.paint_offset > colr->table_size ) - return 0; - - p = (FT_Byte*)( colr->base_glyphs_v1 + - base_glyph_v1_record.paint_offset ); - if ( p >= ( (FT_Byte*)colr->table + colr->table_size ) ) - return 0; - - opaque_paint->p = p; - - if ( root_transform == FT_COLOR_INCLUDE_ROOT_TRANSFORM ) - opaque_paint->insert_root_transform = 1; - else - opaque_paint->insert_root_transform = 0; - - return 1; - } - - - FT_LOCAL_DEF( FT_Bool ) - tt_face_get_paint_layers( TT_Face face, - FT_LayerIterator* iterator, - FT_OpaquePaint* opaque_paint ) - { - FT_Byte* p = NULL; - FT_Byte* p_first_layer = NULL; - FT_Byte* p_paint = NULL; - FT_UInt32 paint_offset; - - Colr* colr; - - - if ( iterator->layer == iterator->num_layers ) - return 0; - - colr = (Colr*)face->colr; - if ( !colr ) - return 0; - - /* - * We have an iterator pointing at a paint offset as part of the - * `paintOffset` array in `LayerV1List`. - */ - p = iterator->p; - - /* - * First ensure that p is within COLRv1. - */ - if ( p < colr->layers_v1 || - p >= ( (FT_Byte*)colr->table + colr->table_size ) ) - return 0; - - /* - * Do a cursor sanity check of the iterator. Counting backwards from - * where it stands, we need to end up at a position after the beginning - * of the `LayerV1List` table and not after the end of the - * `LayerV1List`. - */ - p_first_layer = p - - iterator->layer * LAYER_V1_LIST_PAINT_OFFSET_SIZE - - LAYER_V1_LIST_NUM_LAYERS_SIZE; - if ( p_first_layer < (FT_Byte*)colr->layers_v1 ) - return 0; - if ( p_first_layer >= (FT_Byte*)( - colr->layers_v1 + LAYER_V1_LIST_NUM_LAYERS_SIZE + - colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ) ) - return 0; - - paint_offset = - FT_NEXT_ULONG( p ); - opaque_paint->insert_root_transform = - 0; - - p_paint = (FT_Byte*)( colr->layers_v1 + paint_offset ); - - if ( p_paint < colr->paints_start_v1 || - p_paint >= ( (FT_Byte*)colr->table + colr->table_size ) ) - return 0; - - opaque_paint->p = p_paint; - - iterator->p = p; - - iterator->layer++; - - return 1; - } - - - FT_LOCAL_DEF( FT_Bool ) - tt_face_get_colorline_stops( TT_Face face, - FT_ColorStop* color_stop, - FT_ColorStopIterator *iterator ) - { - Colr* colr = (Colr*)face->colr; - - FT_Byte* p; - - - if ( !colr || !colr->table ) - return 0; - - if ( iterator->current_color_stop >= iterator->num_color_stops ) - return 0; - - if ( iterator->p + - ( ( iterator->num_color_stops - iterator->current_color_stop ) * - COLOR_STOP_SIZE ) > - ( (FT_Byte *)colr->table + colr->table_size ) ) - return 0; - - /* Iterator points at first `ColorStop` of `ColorLine`. */ - p = iterator->p; - - color_stop->stop_offset = FT_NEXT_SHORT( p ); - - color_stop->color.palette_index = FT_NEXT_USHORT( p ); - - color_stop->color.alpha = FT_NEXT_SHORT( p ); - - iterator->p = p; - iterator->current_color_stop++; - - return 1; - } - - - FT_LOCAL_DEF( FT_Bool ) - tt_face_get_paint( TT_Face face, - FT_OpaquePaint opaque_paint, - FT_COLR_Paint* paint ) - { - Colr* colr = (Colr*)face->colr; - FT_OpaquePaint next_paint; - FT_Matrix ft_root_scale; - - if ( !colr || !colr->base_glyphs_v1 || !colr->table ) - return 0; - - if ( opaque_paint.insert_root_transform ) - { - /* 'COLR' v1 glyph information is returned in unscaled coordinates, - * i.e., `FT_Size` is not applied or multiplied into the values. When - * client applications draw color glyphs, they can request to include - * a top-level transform, which includes the active `x_scale` and - * `y_scale` information for scaling the glyph, as well the additional - * transform and translate configured through `FT_Set_Transform`. - * This allows client applications to apply this top-level transform - * to the graphics context first and only once, then have gradient and - * contour scaling applied correctly when performing the additional - * drawing operations for subsequenct paints. Prepare this initial - * transform here. - */ - paint->format = FT_COLR_PAINTFORMAT_TRANSFORM; - - next_paint.p = opaque_paint.p; - next_paint.insert_root_transform = 0; - paint->u.transform.paint = next_paint; - - /* `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. - */ - ft_root_scale.xx = ( face->root.size->metrics.x_scale + 32 ) >> 6; - ft_root_scale.xy = 0; - ft_root_scale.yx = 0; - ft_root_scale.yy = ( face->root.size->metrics.y_scale + 32 ) >> 6; - - if ( face->root.internal->transform_flags & 1 ) - FT_Matrix_Multiply( &face->root.internal->transform_matrix, - &ft_root_scale ); - - paint->u.transform.affine.xx = ft_root_scale.xx; - paint->u.transform.affine.xy = ft_root_scale.xy; - paint->u.transform.affine.yx = ft_root_scale.yx; - paint->u.transform.affine.yy = ft_root_scale.yy; - - /* The translation is specified in 26.6 format and, according to the - * documentation of `FT_Set_Translate`, is performed on the character - * size given in the last call to `FT_Set_Char_Size`. The - * 'PaintTransform' paint table's `FT_Affine23` format expects - * values in 16.16 format, thus we need to shift by 10 bits. - */ - if ( face->root.internal->transform_flags & 2 ) - { - paint->u.transform.affine.dx = - face->root.internal->transform_delta.x << 10; - paint->u.transform.affine.dy = - face->root.internal->transform_delta.y << 10; - } - else - { - paint->u.transform.affine.dx = 0; - paint->u.transform.affine.dy = 0; - } - - return 1; - } - - return read_paint( colr, opaque_paint.p, paint ); - } - - FT_LOCAL_DEF( FT_Error ) tt_face_colr_blend_layer( TT_Face face, FT_UInt color_index, |