From 9b31c44620b30d3b2e6f6c0aa1cf54409cbd1087 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Thu, 14 Jun 2018 21:30:43 +0200 Subject: [PATCH] Replace `FT_Get_GlyphLayers' with `FT_Get_Color_Glyph_Layer'. This avoids any additional allocation of COLR related structures in a glyph slot. * include/freetype/freetype.h (FT_Glyph_Layer, FT_Glyph_LayerRec, FT_Get_GlyphLayers): Removed. * include/freetype/internal/ftobjs.h (FT_Colr_InternalRec): Removed. (FT_Slot_InternalRec): Remove `color_layers'. * include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func): Removed. (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Remove `load_colr_layer'. * src/base/ftobjs.c (ft_glyph_slot_done): Updated. (FT_Render_Glyph_Internal): Use `FT_Get_Color_Glyph_Layer'. (FT_Get_GlyphLayers): Removed. * src/sfnt/sfdriver.c (sfnt_interface): Updated. * src/sfnt/ttcolr.c (tt_face_load_colr_layers): Removed. * src/sfnt/ttcolr.h: Updated. * src/truetype/ttgload.c (TT_Load_Glyph): Updated. --- ChangeLog | 29 +++++++ include/freetype/freetype.h | 95 --------------------- include/freetype/internal/ftobjs.h | 14 --- include/freetype/internal/sfnt.h | 37 -------- src/base/ftobjs.c | 131 ++++++++++++----------------- src/sfnt/sfdriver.c | 2 - src/sfnt/ttcolr.c | 68 --------------- src/sfnt/ttcolr.h | 6 -- src/truetype/ttgload.c | 33 -------- 9 files changed, 85 insertions(+), 330 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5df7fa590..d1559ac2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2018-06-14 Werner Lemberg + + Replace `FT_Get_GlyphLayers' with `FT_Get_Color_Glyph_Layer'. + + This avoids any additional allocation of COLR related structures in + a glyph slot. + + * include/freetype/freetype.h (FT_Glyph_Layer, FT_Glyph_LayerRec, + FT_Get_GlyphLayers): Removed. + + * include/freetype/internal/ftobjs.h (FT_Colr_InternalRec): Removed. + (FT_Slot_InternalRec): Remove `color_layers'. + + * include/freetype/internal/sfnt.h (TT_Load_Colr_Layer_Func): + Removed. + (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Remove + `load_colr_layer'. + + * src/base/ftobjs.c (ft_glyph_slot_done): Updated. + (FT_Render_Glyph_Internal): Use `FT_Get_Color_Glyph_Layer'. + (FT_Get_GlyphLayers): Removed. + + * src/sfnt/sfdriver.c (sfnt_interface): Updated. + + * src/sfnt/ttcolr.c (tt_face_load_colr_layers): Removed. + * src/sfnt/ttcolr.h: Updated. + + * src/truetype/ttgload.c (TT_Load_Glyph): Updated. + 2018-06-14 Werner Lemberg Provide iterative API to access `COLR' data. diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 02abd8a59..546e5d87e 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -4169,101 +4169,6 @@ FT_BEGIN_HEADER FT_Matrix *p_transform ); - /********************************************************************** - * - * @type: - * FT_Glyph_Layer - * - * @description: - * A handle to an @FT_Glyph_LayerRec structure to model a given - * colored glyph layer. - */ - typedef struct FT_Glyph_LayerRec_* FT_Glyph_Layer; - - - /********************************************************************** - * - * @struct: - * FT_Glyph_LayerRec - * - * @description: - * This structure models a given colored glyph layer as defined in the - * OpenType `COLR' table. It is used by @FT_Get_GlyphLayers. - * - * @fields: - * glyph_index :: - * The glyph index of the current glyph layer. - * - * color_index :: - * The color index into the font face's color palette, which can be - * retrieved with @FT_Palette_Select. The value 0xFFFF is special; it - * doesn't reference a palette entry but indicates that the text - * foreground color should be used instead (to be set up by the - * application outside of FreeType). - */ - typedef struct FT_Glyph_LayerRec_ - { - FT_UShort glyph_index; - FT_UShort color_index; - - } FT_Glyph_LayerRec; - - - /************************************************************************* - * - * @func: - * FT_Get_GlyphLayers - * - * @description: - * This is an interface to the `COLR' table in OpenType fonts to - * retrieve the colored glyph layers array associated with the current - * glyph slot. - * - * https://docs.microsoft.com/en-us/typography/opentype/spec/colr - * - * The glyph layer data for a given glyph slot, if present, provides an - * alternative, multi-colour glyph representation: Instead of rendering - * the outline or bitmap in the glyph slot, glyphs with the indices and - * colors returned in the @FT_Glyph_Layer array are rendered layer by - * layer. - * - * @input: - * glyph :: - * The source glyph slot. - * - * @output: - * anum_layers :: - * The number of colored glyph layers for `glyph'. - * - * alayers :: - * An @FT_Glyph_Layer array with `anum_layers' elements. NULL if there - * aren't glyph layers. - * - * The elements are ordered in the z~direction from bottom to top; an - * element `n' should be rendered with the associated palette color - * and blended on top of the already rendered layers (elements 0, 1, - * ..., n-1). - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * The data in `alayers' is owned and managed by the glyph slot. - * - * This function is necessary if you want to handle glyph layers by - * yourself. In particular, functions that operate with @FT_GlyphRec - * objects (like @FT_Get_Glyph or @FT_Glyph_To_Bitmap) don't have access - * to this information. - * - * @FT_Render_Glyph, however, handles colored glyph layers - * automatically if the @FT_LOAD_COLOR flag is passed to it. - */ - FT_EXPORT( FT_Error ) - FT_Get_GlyphLayers( FT_GlyphSlot glyph, - FT_UShort *anum_layers, - FT_Glyph_Layer *alayers ); - - /********************************************************************** * * @struct: diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 9e92a31da..54f973a60 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -384,15 +384,6 @@ FT_BEGIN_HEADER } FT_Face_InternalRec; - typedef struct FT_Colr_InternalRec_ - { - FT_Glyph_Layer layers; - FT_UShort num_layers; - FT_Int32 load_flags; - - } FT_Colr_InternalRec, *FT_Colr_Internal; - - /************************************************************************** * * @Struct: @@ -432,9 +423,6 @@ FT_BEGIN_HEADER * glyph_hints :: * Format-specific glyph hints management. * - * color_layers :: - * Data from (SFNT) COLR/CPAL tables. - * * load_flags :: * The load flags passed as an argument to @FT_Load_Glyph while * initializing the glyph slot. @@ -451,8 +439,6 @@ FT_BEGIN_HEADER FT_Vector glyph_delta; void* glyph_hints; - FT_Colr_Internal color_layers; - FT_Int32 load_flags; } FT_GlyphSlot_InternalRec; diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h index 2093c28e7..bcc266563 100644 --- a/include/freetype/internal/sfnt.h +++ b/include/freetype/internal/sfnt.h @@ -492,40 +492,6 @@ FT_BEGIN_HEADER FT_UInt idx ); - /************************************************************************** - * - * @FuncType: - * TT_Load_Colr_Layer_Func - * - * @Description: - * Load the color layer data given a glyph index. - * - * @Input: - * face :: - * The target face object. - * - * idx :: - * The glyph index. - * - * @Output: - * layers :: - * The layer info with color index and glyph index. - * Deallocate with `FT_FREE'. - * - * num_layers :: - * Number of layers. - * - * @Return: - * FreeType error code. 0 means success. Returns an error if no - * color layer information exists for `idx'. - */ - typedef FT_Error - (*TT_Load_Colr_Layer_Func)( TT_Face face, - FT_UInt idx, - FT_Glyph_Layer *layers, - FT_UShort* num_layers ); - - /************************************************************************** * * @FuncType: @@ -808,7 +774,6 @@ FT_BEGIN_HEADER TT_Free_Table_Func free_cpal; TT_Free_Table_Func free_colr; TT_Set_Palette_Func set_palette; - TT_Load_Colr_Layer_Func load_colr_layer; TT_Get_Colr_Layer_Func get_colr_layer; TT_Blend_Colr_Func colr_blend; @@ -859,7 +824,6 @@ FT_BEGIN_HEADER free_cpal_, \ free_colr_, \ set_palette_, \ - load_colr_layer_, \ get_colr_layer_, \ colr_blend_, \ get_metrics_, \ @@ -900,7 +864,6 @@ FT_BEGIN_HEADER free_cpal_, \ free_colr_, \ set_palette_, \ - load_colr_layer_, \ get_colr_layer_, \ colr_blend_, \ get_metrics_, \ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 29a1c114c..e733f955e 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -532,16 +532,6 @@ /* free bitmap buffer if needed */ ft_glyphslot_free_bitmap( slot ); - /* free glyph color layers if needed */ - if ( slot->internal->color_layers ) - { - FT_Colr_InternalRec* color_layers = slot->internal->color_layers; - - - FT_FREE( color_layers->layers ); - FT_FREE( slot->internal->color_layers ); - } - /* slot->internal might be NULL in out-of-memory situations */ if ( slot->internal ) { @@ -4513,69 +4503,85 @@ FT_Render_Mode render_mode ) { FT_Error error = FT_Err_Ok; + FT_Face face = slot->face; FT_Renderer renderer; - /* if it is already a bitmap, no need to do anything */ switch ( slot->format ) { case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ break; default: - if ( slot->internal->color_layers ) + if ( slot->internal->load_flags & FT_LOAD_COLOR ) { - FT_Face face = slot->face; + FT_LayerIterator iterator; + + FT_UInt base_glyph = slot->glyph_index; + + FT_UInt glyph_index; + FT_UInt color_index; - error = FT_New_GlyphSlot( face, NULL ); - if ( !error ) + /* check whether we have colored glyph layers */ + iterator.p = NULL; + glyph_index = FT_Get_Color_Glyph_Layer( face, + base_glyph, + &color_index, + &iterator ); + if ( glyph_index ) { - TT_Face ttface = (TT_Face)face; - SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; - - FT_Glyph_Layer glyph_layers = - slot->internal->color_layers->layers; - - FT_Int idx; - - - for ( idx = 0; - idx < slot->internal->color_layers->num_layers; - idx++ ) + error = FT_New_GlyphSlot( face, NULL ); + if ( !error ) { - FT_Int32 load_flags; + TT_Face ttface = (TT_Face)face; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; - load_flags = slot->internal->color_layers->load_flags - & ~FT_LOAD_COLOR; - load_flags |= FT_LOAD_RENDER; + do + { + FT_Int32 load_flags = slot->internal->load_flags; - error = FT_Load_Glyph( face, - glyph_layers[idx].glyph_index, - load_flags ); - if ( error ) - break; - error = sfnt->colr_blend( ttface, - glyph_layers[idx].color_index, - slot, - face->glyph ); - if ( error ) - break; + /* disable the `FT_LOAD_COLOR' flag to avoid recursion */ + /* right here in this function */ + load_flags &= ~FT_LOAD_COLOR; + + /* render into the new `face->glyph' glyph slot */ + load_flags |= FT_LOAD_RENDER; + + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + break; + + /* blend new `face->glyph' into old `slot'; */ + /* at the first call, `slot' is still empty */ + error = sfnt->colr_blend( ttface, + color_index, + slot, + face->glyph ); + if ( error ) + break; + + } while ( ( glyph_index = + FT_Get_Color_Glyph_Layer( face, + base_glyph, + &color_index, + &iterator ) ) != 0 ); + + if ( !error ) + slot->format = FT_GLYPH_FORMAT_BITMAP; + + /* this call also restores `slot' as the glyph slot */ + FT_Done_GlyphSlot( face->glyph ); } if ( !error ) - slot->format = FT_GLYPH_FORMAT_BITMAP; + return error; - FT_Done_GlyphSlot( face->glyph ); + /* Failed to do the colored layer. Draw outline instead. */ + slot->format = FT_GLYPH_FORMAT_OUTLINE; } - - if ( !error ) - return error; - - /* Failed to do the colored layer. Draw outline instead. */ - slot->format = FT_GLYPH_FORMAT_OUTLINE; } { @@ -5465,31 +5471,6 @@ } - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_GlyphLayers( FT_GlyphSlot glyph, - FT_UShort *anum_layers, - FT_Glyph_Layer *alayers ) - { - if ( !glyph ) - return FT_THROW( Invalid_Argument ); - - if ( glyph->internal->color_layers ) - { - *anum_layers = glyph->internal->color_layers->num_layers; - *alayers = glyph->internal->color_layers->layers; - } - else - { - *anum_layers = 0; - *alayers = NULL; - } - - return FT_Err_Ok; - } - - /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_UInt ) diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c index e1f481802..cd2d8091b 100644 --- a/src/sfnt/sfdriver.c +++ b/src/sfnt/sfdriver.c @@ -1268,8 +1268,6 @@ /* TT_Free_Table_Func free_colr */ PUT_COLOR_LAYERS( tt_face_palette_set ), /* TT_Set_Palette_Func set_palette */ - PUT_COLOR_LAYERS( tt_face_load_colr_layers ), - /* TT_Load_Colr_Layer_Func load_colr_layer */ PUT_COLOR_LAYERS( tt_face_get_colr_layer ), /* TT_Get_Colr_Layer_Func get_colr_layer */ PUT_COLOR_LAYERS( tt_face_colr_blend_layer ), diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 323f0ca51..7e44d42ad 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -207,74 +207,6 @@ } - FT_LOCAL_DEF( FT_Error ) - tt_face_load_colr_layers( TT_Face face, - FT_UInt glyph_id, - FT_Glyph_Layer *ret_layers, - FT_UShort* ret_num_layers ) - { - FT_Error error; - FT_Memory memory = face->root.memory; - - Colr* colr = (Colr*)face->colr; - - BaseGlyphRecord glyph_record; - FT_Glyph_Layer layers = NULL; - int layer_idx; - FT_Byte* layer_record_ptr; - - - if ( !ret_layers || !ret_num_layers ) - return FT_THROW( Invalid_Argument ); - - if ( !find_base_glyph_record( colr->base_glyphs, - colr->num_base_glyphs, - glyph_id, - &glyph_record ) ) - { - *ret_layers = NULL; - *ret_num_layers = 0; - - return FT_Err_Ok; - } - - /* Load all colors for the glyphs; this would be stored in the slot. */ - layer_record_ptr = colr->layers + - glyph_record.first_layer_index * LAYER_SIZE; - - if ( FT_NEW_ARRAY( layers, glyph_record.num_layers ) ) - goto Error; - - for ( layer_idx = 0; layer_idx < glyph_record.num_layers; layer_idx++ ) - { - FT_UShort gid = FT_NEXT_USHORT( layer_record_ptr ); - FT_UShort palette_entry_index = FT_NEXT_USHORT( layer_record_ptr ); - - - if ( palette_entry_index != 0xFFFF && - palette_entry_index >= face->palette_data.num_palette_entries ) - { - error = FT_THROW( Invalid_Table ); - goto Error; - } - - layers[layer_idx].color_index = palette_entry_index; - layers[layer_idx].glyph_index = gid; - } - - *ret_layers = layers; - *ret_num_layers = glyph_record.num_layers; - - return FT_Err_Ok; - - Error: - if ( layers ) - FT_FREE( layers ); - - return error; - } - - FT_LOCAL_DEF( FT_UInt ) tt_face_get_colr_layer( TT_Face face, FT_UInt base_glyph, diff --git a/src/sfnt/ttcolr.h b/src/sfnt/ttcolr.h index 480fd6770..983ab831e 100644 --- a/src/sfnt/ttcolr.h +++ b/src/sfnt/ttcolr.h @@ -36,12 +36,6 @@ FT_BEGIN_HEADER FT_LOCAL( void ) tt_face_free_colr( TT_Face face ); - FT_LOCAL( FT_Error ) - tt_face_load_colr_layers( TT_Face face, - FT_UInt glyph_id, - FT_Glyph_Layer *ret_layers, - FT_UShort* ret_num_layers ); - FT_LOCAL( FT_UInt ) tt_face_get_colr_layer( TT_Face face, FT_UInt base_glyph, diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index c5e96e687..f0f6a0602 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -2904,39 +2904,6 @@ size->metrics->y_ppem < 24 ) glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; - /* The outline based algorithm took care of metrics. */ - /* Read additional color info if requested. */ - if ( ( load_flags & FT_LOAD_COLOR ) && - ( (TT_Face)glyph->face )->colr ) - { - TT_Face face = (TT_Face)glyph->face; - FT_Memory memory = face->root.memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; - - FT_Glyph_Layer glyph_layers; - FT_UShort num_glyph_layers; - - - error = sfnt->load_colr_layer( face, - glyph_index, - &glyph_layers, - &num_glyph_layers ); - if ( error ) - return error; - - if ( !glyph->internal->color_layers ) - { - if ( FT_NEW( glyph->internal->color_layers ) ) - return error; - } - - FT_FREE( glyph->internal->color_layers->layers ); - - glyph->internal->color_layers->layers = glyph_layers; - glyph->internal->color_layers->num_layers = num_glyph_layers; - glyph->internal->color_layers->load_flags = load_flags; - } - Exit: #ifdef FT_DEBUG_LEVEL_TRACE if ( error )