diff --git a/ChangeLog b/ChangeLog index b69f74045..604d3e576 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2018-06-12 Werner Lemberg + + Finish CPAL/COLR support (2/4). + + * src/sfnt/ttcolr.c (tt_face_palette_set): New function. + (tt_face_load_colr): Allocate `face->palette' and call + `tt_face_palette_set'. + Adjust return error code in case of error. + + * src/sfnt/ttcolr.h: Updated. + + * include/freetype/internal/sfnt.h (TT_Set_Palette_Func): New + function type. + (SFNT_Interface, FT_DEFINE_SFNT_INTERFACE): Add it. + + * src/sfnt/sfdriver.c (sfnt_interface), src/sfnt/sfobjs.c + (sfnt_done_face): Updated. + 2018-06-12 Werner Lemberg Finish CPAL/COLR support (1/4). diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h index 00b7ae5e5..7270d1208 100644 --- a/include/freetype/internal/sfnt.h +++ b/include/freetype/internal/sfnt.h @@ -469,6 +469,29 @@ FT_BEGIN_HEADER FT_UShort* aadvance ); + /************************************************************************** + * + * @FuncType: + * TT_Set_Palette_Func + * + * @Description: + * Load the colors into `face->palette' for a given palette index. + * + * @Input: + * face :: + * The target face object. + * + * idx :: + * The palette index. + * + * @Return: + * FreeType error code. 0 means success. + */ + typedef FT_Error + (*TT_Set_Palette_Func)( TT_Face face, + FT_UInt idx ); + + /************************************************************************** * * @FuncType: @@ -739,6 +762,7 @@ FT_BEGIN_HEADER TT_Load_Table_Func load_colr; TT_Free_Table_Func free_colr; + TT_Set_Palette_Func set_palette; TT_Load_Colr_Layer_Func load_colr_layer; TT_Blend_Colr_Func colr_blend; @@ -786,6 +810,7 @@ FT_BEGIN_HEADER load_strike_metrics_, \ load_colr_, \ free_colr_, \ + set_palette_, \ load_colr_layer_, \ colr_blend_, \ get_metrics_, \ @@ -823,6 +848,7 @@ FT_BEGIN_HEADER load_strike_metrics_, \ load_colr_, \ free_colr_, \ + set_palette_, \ load_colr_layer_, \ colr_blend_, \ get_metrics_, \ diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c index 600577145..dd3f80101 100644 --- a/src/sfnt/sfdriver.c +++ b/src/sfnt/sfdriver.c @@ -1261,6 +1261,8 @@ /* TT_Load_Table_Func load_colr */ PUT_COLOR_LAYERS( tt_face_free_colr ), /* 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_colr_blend_layer ), diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index 67b5ff4a7..6a431ed2b 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -1812,6 +1812,7 @@ FT_FREE( face->palette_data.palette_name_ids ); FT_FREE( face->palette_data.palette_types ); FT_FREE( face->palette_data.palette_entry_name_ids ); + FT_FREE( face->palette ); face->sfnt = NULL; } diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 8e232c3fb..9783b7072 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -289,16 +289,26 @@ face->colr_and_cpal = cc; + /* set up default palette */ + if ( FT_NEW_ARRAY( face->palette, + face->palette_data.num_palette_entries ) ) + goto NoColor; + + tt_face_palette_set( face, 0 ); + return FT_Err_Ok; InvalidTable: - error = FT_THROW( Invalid_File_Format ); + error = FT_THROW( Invalid_Table ); NoColor: FT_FRAME_RELEASE( colr_table ); FT_FRAME_RELEASE( cpal_table ); - /* arrays in `face->palette_data' are freed in `sfnt_face_done' */ + FT_FREE( cc ); + + /* arrays in `face->palette_data' and `face->palette' */ + /* are freed in `sfnt_done_face' */ return error; } @@ -462,6 +472,43 @@ } + FT_LOCAL_DEF( FT_Error ) + tt_face_palette_set( TT_Face face, + FT_UInt palette_index ) + { + ColrCpal* colr_and_cpal = (ColrCpal *)face->colr_and_cpal; + Cpal* cpal = &colr_and_cpal->cpal; + + FT_Byte* offset; + FT_Byte* p; + + FT_Color* q; + FT_Color* limit; + + + if ( palette_index >= face->palette_data.num_palettes ) + return FT_THROW( Invalid_Argument ); + + offset = cpal->color_indices + 2 * palette_index; + p = cpal->colors + COLOR_SIZE * FT_PEEK_USHORT( offset ); + + q = face->palette; + limit = q + face->palette_data.num_palette_entries * sizeof ( FT_Color ); + + while ( q < limit ) + { + q->blue = FT_NEXT_BYTE( p ); + q->green = FT_NEXT_BYTE( p ); + q->red = FT_NEXT_BYTE( p ); + q->alpha = FT_NEXT_BYTE( p ); + + q++; + } + + return FT_Err_Ok; + } + + FT_LOCAL_DEF( FT_Error ) tt_face_colr_blend_layer( TT_Face face, FT_UInt color_index, diff --git a/src/sfnt/ttcolr.h b/src/sfnt/ttcolr.h index 1e1b4a2e0..bb9b40738 100644 --- a/src/sfnt/ttcolr.h +++ b/src/sfnt/ttcolr.h @@ -42,6 +42,10 @@ FT_BEGIN_HEADER FT_Glyph_Layer *ret_layers, FT_UShort* ret_num_layers ); + FT_LOCAL( FT_Error ) + tt_face_palette_set( TT_Face face, + FT_UInt palette_index ); + FT_LOCAL( FT_Error ) tt_face_colr_blend_layer( TT_Face face, FT_UInt color_index,