summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Röttsches <drott@chromium.org>2021-06-29 20:51:32 +0300
committerWerner Lemberg <wl@gnu.org>2021-07-01 06:15:22 +0200
commit0348c627b19864203c0eb3752f49850851a65200 (patch)
treed21ddf20bf9be4e456d39cf80927dfdb8b89dedc
parentf27b4834b7dcf9d667fd5173106be0cddb0ec1c2 (diff)
downloadfreetype2-0348c627b19864203c0eb3752f49850851a65200.tar.gz
[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.
-rw-r--r--ChangeLog15
-rw-r--r--src/sfnt/ttcolr.c37
2 files changed, 39 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index a1de34602..eccf4a1c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2021-06-30 Dominik Röttsches <drott@chromium.org>
+
+ [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 <apodtele@gmail.com>
* 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 );