summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/sfnt/sfwoff2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/sfnt/sfwoff2.c')
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfwoff2.c144
1 files changed, 99 insertions, 45 deletions
diff --git a/src/3rdparty/freetype/src/sfnt/sfwoff2.c b/src/3rdparty/freetype/src/sfnt/sfwoff2.c
index 5c8202f823..b2855b8e72 100644
--- a/src/3rdparty/freetype/src/sfnt/sfwoff2.c
+++ b/src/3rdparty/freetype/src/sfnt/sfwoff2.c
@@ -4,7 +4,7 @@
*
* WOFF2 format management (base).
*
- * Copyright (C) 2019-2020 by
+ * Copyright (C) 2019-2022 by
* Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -26,8 +26,6 @@
#include <brotli/decode.h>
-#endif
-
/**************************************************************************
*
@@ -86,6 +84,8 @@
#define BBOX_STREAM 5
#define INSTRUCTION_STREAM 6
+#define HAVE_OVERLAP_SIMPLE_BITMAP 0x1
+
static void
stream_close( FT_Stream stream )
@@ -96,20 +96,19 @@
FT_FREE( stream->base );
stream->size = 0;
- stream->base = NULL;
stream->close = NULL;
}
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
compare_tags( const void* a,
const void* b )
{
WOFF2_Table table1 = *(WOFF2_Table*)a;
WOFF2_Table table2 = *(WOFF2_Table*)b;
- FT_ULong tag1 = table1->Tag;
- FT_ULong tag2 = table2->Tag;
+ FT_Tag tag1 = table1->Tag;
+ FT_Tag tag2 = table2->Tag;
if ( tag1 > tag2 )
@@ -316,8 +315,6 @@
const FT_Byte* src,
FT_ULong src_size )
{
-#ifdef FT_CONFIG_OPTION_USE_BROTLI
-
/* this cast is only of importance on 32bit systems; */
/* we don't validate it */
FT_Offset uncompressed_size = (FT_Offset)dst_size;
@@ -338,20 +335,13 @@
FT_TRACE2(( "woff2_decompress: Brotli stream decompressed.\n" ));
return FT_Err_Ok;
-
-#else /* !FT_CONFIG_OPTION_USE_BROTLI */
-
- FT_ERROR(( "woff2_decompress: Brotli support not available.\n" ));
- return FT_THROW( Unimplemented_Feature );
-
-#endif /* !FT_CONFIG_OPTION_USE_BROTLI */
}
static WOFF2_Table
find_table( WOFF2_Table* tables,
FT_UShort num_tables,
- FT_ULong tag )
+ FT_Tag tag )
{
FT_Int i;
@@ -534,6 +524,7 @@
const WOFF2_Point points,
FT_UShort n_contours,
FT_UShort instruction_len,
+ FT_Bool have_overlap,
FT_Byte* dst,
FT_ULong dst_size,
FT_ULong* glyph_size )
@@ -561,6 +552,9 @@
FT_Int dy = point.y - last_y;
+ if ( i == 0 && have_overlap )
+ flag |= GLYF_OVERLAP_SIMPLE;
+
if ( dx == 0 )
flag |= GLYF_THIS_X_IS_SAME;
else if ( dx > -256 && dx < 256 )
@@ -790,7 +784,7 @@
goto Fail;
loca_buf_size = loca_values_size * offset_size;
- if ( FT_NEW_ARRAY( loca_buf, loca_buf_size ) )
+ if ( FT_QNEW_ARRAY( loca_buf, loca_buf_size ) )
goto Fail;
dst = loca_buf;
@@ -845,15 +839,18 @@
FT_UInt num_substreams = 7;
+ FT_UShort option_flags;
FT_UShort num_glyphs;
FT_UShort index_format;
FT_ULong expected_loca_length;
FT_UInt offset;
FT_UInt i;
FT_ULong points_size;
- FT_ULong bitmap_length;
FT_ULong glyph_buf_size;
FT_ULong bbox_bitmap_offset;
+ FT_ULong bbox_bitmap_length;
+ FT_ULong overlap_bitmap_offset = 0;
+ FT_ULong overlap_bitmap_length = 0;
const FT_ULong glyf_start = *out_offset;
FT_ULong dest_offset = *out_offset;
@@ -869,15 +866,17 @@
if ( FT_NEW_ARRAY( substreams, num_substreams ) )
goto Fail;
- if ( FT_STREAM_SKIP( 4 ) )
+ if ( FT_STREAM_SKIP( 2 ) )
+ goto Fail;
+ if ( FT_READ_USHORT( option_flags ) )
goto Fail;
if ( FT_READ_USHORT( num_glyphs ) )
goto Fail;
if ( FT_READ_USHORT( index_format ) )
goto Fail;
- FT_TRACE4(( "num_glyphs = %u; index_format = %u\n",
- num_glyphs, index_format ));
+ FT_TRACE4(( "option_flags = %u; num_glyphs = %u; index_format = %u\n",
+ option_flags, num_glyphs, index_format ));
info->num_glyphs = num_glyphs;
@@ -890,7 +889,7 @@
if ( info->loca_table->dst_length != expected_loca_length )
goto Fail;
- offset = ( 2 + num_substreams ) * 4;
+ offset = 2 + 2 + 2 + 2 + ( num_substreams * 4 );
if ( offset > info->glyf_table->TransformLength )
goto Fail;
@@ -913,6 +912,20 @@
offset += substream_size;
}
+ if ( option_flags & HAVE_OVERLAP_SIMPLE_BITMAP )
+ {
+ /* Size of overlapBitmap = floor((numGlyphs + 7) / 8) */
+ overlap_bitmap_length = ( num_glyphs + 7U ) >> 3;
+ if ( overlap_bitmap_length > info->glyf_table->TransformLength - offset )
+ goto Fail;
+
+ overlap_bitmap_offset = pos + offset;
+
+ FT_TRACE5(( " Overlap bitmap: offset = %lu; size = %lu;\n",
+ overlap_bitmap_offset, overlap_bitmap_length ));
+ offset += overlap_bitmap_length;
+ }
+
if ( FT_NEW_ARRAY( loca_values, num_glyphs + 1 ) )
goto Fail;
@@ -920,8 +933,9 @@
bbox_bitmap_offset = substreams[BBOX_STREAM].offset;
/* Size of bboxBitmap = 4 * floor((numGlyphs + 31) / 32) */
- bitmap_length = ( ( num_glyphs + 31U ) >> 5 ) << 2;
- substreams[BBOX_STREAM].offset += bitmap_length;
+ bbox_bitmap_length = ( ( num_glyphs + 31U ) >> 5 ) << 2;
+ /* bboxStreamSize is the combined size of bboxBitmap and bboxStream. */
+ substreams[BBOX_STREAM].offset += bbox_bitmap_length;
glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF;
if ( FT_NEW_ARRAY( glyph_buf, glyph_buf_size ) )
@@ -959,7 +973,7 @@
/* composite glyph */
FT_Bool have_instructions = FALSE;
FT_UShort instruction_size = 0;
- FT_ULong composite_size;
+ FT_ULong composite_size = 0;
FT_ULong size_needed;
FT_Byte* pointer = NULL;
@@ -1037,8 +1051,11 @@
FT_ULong flag_size;
FT_ULong triplet_size;
FT_ULong triplet_bytes_used;
- FT_Byte* flags_buf = NULL;
- FT_Byte* triplet_buf = NULL;
+ FT_Bool have_overlap = FALSE;
+ FT_Byte overlap_bitmap;
+ FT_ULong overlap_offset;
+ FT_Byte* flags_buf = NULL;
+ FT_Byte* triplet_buf = NULL;
FT_UShort instruction_size;
FT_ULong size_needed;
FT_Int end_point;
@@ -1047,6 +1064,17 @@
FT_Byte* pointer = NULL;
+ /* Set `have_overlap`. */
+ if ( overlap_bitmap_offset )
+ {
+ overlap_offset = overlap_bitmap_offset + ( i >> 3 );
+ if ( FT_STREAM_SEEK( overlap_offset ) ||
+ FT_READ_BYTE( overlap_bitmap ) )
+ goto Fail;
+ if ( overlap_bitmap & ( 0x80 >> ( i & 7 ) ) )
+ have_overlap = TRUE;
+ }
+
if ( FT_NEW_ARRAY( n_points_arr, n_contours ) )
goto Fail;
@@ -1167,6 +1195,7 @@
points,
n_contours,
instruction_size,
+ have_overlap,
glyph_buf,
glyph_buf_size,
&glyph_size ) )
@@ -1852,11 +1881,10 @@
FT_NEW_ARRAY( indices, woff2.num_tables ) )
goto Exit;
- FT_TRACE2((
- "\n"
- " tag flags transform origLen transformLen offset\n"
- " -----------------------------------------------------------\n" ));
- /* " XXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX" */
+ FT_TRACE2(( "\n" ));
+ FT_TRACE2(( " tag flags transform origLen transformLen offset\n" ));
+ FT_TRACE2(( " -----------------------------------------------------------\n" ));
+ /* " XXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX" */
for ( nn = 0; nn < woff2.num_tables; nn++ )
{
@@ -2076,7 +2104,7 @@
error = FT_THROW( Invalid_Table );
goto Exit;
}
- file_offset = ROUND4(woff2.metaOffset + woff2.metaLength);
+ file_offset = ROUND4( woff2.metaOffset + woff2.metaLength );
}
if ( woff2.privOffset )
@@ -2086,7 +2114,7 @@
error = FT_THROW( Invalid_Table );
goto Exit;
}
- file_offset = ROUND4(woff2.privOffset + woff2.privLength);
+ file_offset = ROUND4( woff2.privOffset + woff2.privLength );
}
if ( file_offset != ( ROUND4( woff2.length ) ) )
@@ -2098,7 +2126,7 @@
/* Validate requested face index. */
*num_faces = woff2.num_fonts;
/* value -(N+1) requests information on index N */
- if ( *face_instance_index < 0 )
+ if ( *face_instance_index < 0 && face_index > 0 )
face_index--;
if ( face_index >= woff2.num_fonts )
@@ -2119,8 +2147,8 @@
/* Create a temporary array. */
- if ( FT_NEW_ARRAY( temp_indices,
- ttc_font->num_tables ) )
+ if ( FT_QNEW_ARRAY( temp_indices,
+ ttc_font->num_tables ) )
goto Exit;
FT_TRACE4(( "Storing tables for TTC face index %d.\n", face_index ));
@@ -2128,9 +2156,9 @@
temp_indices[nn] = indices[ttc_font->table_indices[nn]];
/* Resize array to required size. */
- if ( FT_RENEW_ARRAY( indices,
- woff2.num_tables,
- ttc_font->num_tables ) )
+ if ( FT_QRENEW_ARRAY( indices,
+ woff2.num_tables,
+ ttc_font->num_tables ) )
goto Exit;
for ( nn = 0; nn < ttc_font->num_tables; nn++ )
@@ -2170,8 +2198,8 @@
}
/* Write sfnt header. */
- if ( FT_ALLOC( sfnt, sfnt_size ) ||
- FT_NEW( sfnt_stream ) )
+ if ( FT_QALLOC( sfnt, sfnt_size ) ||
+ FT_NEW( sfnt_stream ) )
goto Exit;
sfnt_header = sfnt;
@@ -2209,6 +2237,25 @@
sizeof ( WOFF2_Table ),
compare_tags );
+ /* reject fonts that have multiple tables with the same tag */
+ for ( nn = 1; nn < woff2.num_tables; nn++ )
+ {
+ FT_Tag tag = indices[nn]->Tag;
+
+
+ if ( tag == indices[nn - 1]->Tag )
+ {
+ FT_ERROR(( "woff2_open_font:"
+ " multiple tables with tag `%c%c%c%c'.\n",
+ (FT_Char)( tag >> 24 ),
+ (FT_Char)( tag >> 16 ),
+ (FT_Char)( tag >> 8 ),
+ (FT_Char)( tag ) ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ }
+
if ( woff2.uncompressed_size < 1 )
{
error = FT_THROW( Invalid_Table );
@@ -2223,8 +2270,8 @@
}
/* Allocate memory for uncompressed table data. */
- if ( FT_ALLOC( uncompressed_buf, woff2.uncompressed_size ) ||
- FT_FRAME_ENTER( woff2.totalCompressedSize ) )
+ if ( FT_QALLOC( uncompressed_buf, woff2.uncompressed_size ) ||
+ FT_FRAME_ENTER( woff2.totalCompressedSize ) )
goto Exit;
/* Uncompress the stream. */
@@ -2333,5 +2380,12 @@
#undef BBOX_STREAM
#undef INSTRUCTION_STREAM
+#else /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+ /* ANSI C doesn't like empty source files */
+ typedef int _sfwoff2_dummy;
+
+#endif /* !FT_CONFIG_OPTION_USE_BROTLI */
+
/* END */