diff --git a/ChangeLog b/ChangeLog index a1de34602..eccf4a1c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2021-06-30 Dominik Röttsches + + [sfnt] Handle fonts without layer list in 'COLR' v1. + + 'COLR' v1 fonts do not necessarily need to have a layer list; for + this reason, 'fontTools' recently started generating fonts in a way + that drops the layer list if there are no layers in it. This + results in the layer list offset becoming zero, which FreeType + treated as an invalid table. Fix that and handle the case for layer + list offset being 0. This slightly changes how we need to calculate + the starting offset for paints. + + * src/sfnt/ttcolr.c (tt_face_load_colr): Handle case of layer list + offset being zero without outright rejecting table. + 2021-06-30 Alexei Podtelezhnikov * src/raster/ftraster.c (Render_Single_Pass): Simplify `band_stack'. diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 1e297ac8c..34accddb3 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -186,24 +186,35 @@ layer_offset_v1 = FT_NEXT_ULONG( p ); - if ( !layer_offset_v1 || layer_offset_v1 >= table_size ) + if ( layer_offset_v1 >= table_size ) goto InvalidTable; - p1 = (FT_Byte*)( table + layer_offset_v1 ); - num_layers_v1 = FT_PEEK_ULONG( p1 ); + 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; + 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->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 ); + 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 );