summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/sfnt
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/sfnt')
-rw-r--r--src/3rdparty/freetype/src/sfnt/module.mk2
-rw-r--r--src/3rdparty/freetype/src/sfnt/pngshim.c26
-rw-r--r--src/3rdparty/freetype/src/sfnt/pngshim.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/rules.mk3
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfdriver.c247
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfdriver.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/sferrors.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfnt.c3
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfobjs.c158
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfobjs.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfwoff.c43
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfwoff.h5
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfwoff2.c225
-rw-r--r--src/3rdparty/freetype/src/sfnt/sfwoff2.h5
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttbdf.c15
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttbdf.h4
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttcmap.c564
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttcmap.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttcmapc.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttcolr.c1513
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttcolr.h28
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttcpal.c4
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttcpal.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttkern.c21
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttkern.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttload.c123
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttload.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttmtx.c6
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttmtx.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttpost.c325
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttpost.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttsbit.c90
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttsbit.h2
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttsvg.c413
-rw-r--r--src/3rdparty/freetype/src/sfnt/ttsvg.h43
-rw-r--r--src/3rdparty/freetype/src/sfnt/woff2tags.c16
-rw-r--r--src/3rdparty/freetype/src/sfnt/woff2tags.h8
37 files changed, 3008 insertions, 906 deletions
diff --git a/src/3rdparty/freetype/src/sfnt/module.mk b/src/3rdparty/freetype/src/sfnt/module.mk
index 0f459d8421..4491a1b22f 100644
--- a/src/3rdparty/freetype/src/sfnt/module.mk
+++ b/src/3rdparty/freetype/src/sfnt/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2020 by
+# Copyright (C) 1996-2023 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/src/3rdparty/freetype/src/sfnt/pngshim.c b/src/3rdparty/freetype/src/sfnt/pngshim.c
index 1bd3a7eeb5..33712162e0 100644
--- a/src/3rdparty/freetype/src/sfnt/pngshim.c
+++ b/src/3rdparty/freetype/src/sfnt/pngshim.c
@@ -4,7 +4,7 @@
*
* PNG Bitmap glyph support.
*
- * Copyright (C) 2013-2020 by
+ * Copyright (C) 2013-2023 by
* Google, Inc.
* Written by Stuart Gill and Behdad Esfahbod.
*
@@ -72,7 +72,6 @@
( ( __clang_major__ >= 4 ) || \
( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \
defined( __OPTIMIZE__ ) && \
- !defined( __EMSCRIPTEN__ ) && \
defined( __SSE__ ) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
@@ -240,7 +239,7 @@
*e = FT_THROW( Invalid_Stream_Read );
png_error( png, NULL );
- return;
+ /* return; (never reached) */
}
ft_memcpy( data, stream->cursor, length );
@@ -271,7 +270,10 @@
int bitdepth, color_type, interlace;
FT_Int i;
- png_byte* *rows = NULL; /* pacify compiler */
+
+ /* `rows` gets modified within a 'setjmp' scope; */
+ /* we thus need the `volatile` keyword. */
+ png_byte* *volatile rows = NULL;
if ( x_offset < 0 ||
@@ -365,7 +367,7 @@
}
/* transform transparency to alpha */
- if ( png_get_valid(png, info, PNG_INFO_tRNS ) )
+ if ( png_get_valid( png, info, PNG_INFO_tRNS ) )
png_set_tRNS_to_alpha( png );
if ( bitdepth == 16 )
@@ -385,7 +387,7 @@
png_set_filler( png, 0xFF, PNG_FILLER_AFTER );
/* recheck header after setting EXPAND options */
- png_read_update_info(png, info );
+ png_read_update_info( png, info );
png_get_IHDR( png, info,
&imgWidth, &imgHeight,
&bitdepth, &color_type, &interlace,
@@ -404,9 +406,7 @@
switch ( color_type )
{
- default:
- /* Shouldn't happen, but fall through. */
-
+ default: /* Shouldn't happen, but ... */
case PNG_COLOR_TYPE_RGB_ALPHA:
png_set_read_user_transform_fn( png, premultiply_data );
break;
@@ -428,7 +428,7 @@
goto DestroyExit;
}
- if ( FT_NEW_ARRAY( rows, imgHeight ) )
+ if ( FT_QNEW_ARRAY( rows, imgHeight ) )
{
error = FT_THROW( Out_Of_Memory );
goto DestroyExit;
@@ -439,11 +439,11 @@
png_read_image( png, rows );
- FT_FREE( rows );
-
png_read_end( png, info );
DestroyExit:
+ /* even if reading fails with longjmp, rows must be freed */
+ FT_FREE( rows );
png_destroy_read_struct( &png, &info, NULL );
FT_Stream_Close( &stream );
@@ -454,7 +454,7 @@
#else /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */
/* ANSI C doesn't like empty source files */
- typedef int _pngshim_dummy;
+ typedef int pngshim_dummy_;
#endif /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */
diff --git a/src/3rdparty/freetype/src/sfnt/pngshim.h b/src/3rdparty/freetype/src/sfnt/pngshim.h
index 2d6e83d69b..903bd2bc34 100644
--- a/src/3rdparty/freetype/src/sfnt/pngshim.h
+++ b/src/3rdparty/freetype/src/sfnt/pngshim.h
@@ -4,7 +4,7 @@
*
* PNG Bitmap glyph support.
*
- * Copyright (C) 2013-2020 by
+ * Copyright (C) 2013-2023 by
* Google, Inc.
* Written by Stuart Gill and Behdad Esfahbod.
*
diff --git a/src/3rdparty/freetype/src/sfnt/rules.mk b/src/3rdparty/freetype/src/sfnt/rules.mk
index f56ef060ed..4d2d7e8d84 100644
--- a/src/3rdparty/freetype/src/sfnt/rules.mk
+++ b/src/3rdparty/freetype/src/sfnt/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2020 by
+# Copyright (C) 1996-2023 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@@ -36,6 +36,7 @@ SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
$(SFNT_DIR)/ttbdf.c \
$(SFNT_DIR)/ttcmap.c \
$(SFNT_DIR)/ttcolr.c \
+ $(SFNT_DIR)/ttsvg.c \
$(SFNT_DIR)/ttcpal.c \
$(SFNT_DIR)/ttkern.c \
$(SFNT_DIR)/ttload.c \
diff --git a/src/3rdparty/freetype/src/sfnt/sfdriver.c b/src/3rdparty/freetype/src/sfnt/sfdriver.c
index 0460339a74..0925940b03 100644
--- a/src/3rdparty/freetype/src/sfnt/sfdriver.c
+++ b/src/3rdparty/freetype/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
*
* High-level SFNT driver interface (body).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -36,6 +36,10 @@
#include "ttcpal.h"
#endif
+#ifdef FT_CONFIG_OPTION_SVG
+#include "ttsvg.h"
+#endif
+
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
#include "ttpost.h"
#endif
@@ -75,41 +79,57 @@
*
*/
- static void*
- get_sfnt_table( TT_Face face,
+ FT_CALLBACK_DEF( FT_Error )
+ sfnt_load_table( FT_Face face, /* TT_Face */
+ FT_ULong tag,
+ FT_Long offset,
+ FT_Byte* buffer,
+ FT_ULong* length )
+ {
+ TT_Face ttface = (TT_Face)face;
+
+
+ return tt_face_load_any( ttface, tag, offset, buffer, length );
+ }
+
+
+ FT_CALLBACK_DEF( void* )
+ get_sfnt_table( FT_Face face, /* TT_Face */
FT_Sfnt_Tag tag )
{
+ TT_Face ttface = (TT_Face)face;
+
void* table;
switch ( tag )
{
case FT_SFNT_HEAD:
- table = &face->header;
+ table = &ttface->header;
break;
case FT_SFNT_HHEA:
- table = &face->horizontal;
+ table = &ttface->horizontal;
break;
case FT_SFNT_VHEA:
- table = face->vertical_info ? &face->vertical : NULL;
+ table = ttface->vertical_info ? &ttface->vertical : NULL;
break;
case FT_SFNT_OS2:
- table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2;
+ table = ( ttface->os2.version == 0xFFFFU ) ? NULL : &ttface->os2;
break;
case FT_SFNT_POST:
- table = &face->postscript;
+ table = &ttface->postscript;
break;
case FT_SFNT_MAXP:
- table = &face->max_profile;
+ table = &ttface->max_profile;
break;
case FT_SFNT_PCLT:
- table = face->pclt.Version ? &face->pclt : NULL;
+ table = ttface->pclt.Version ? &ttface->pclt : NULL;
break;
default:
@@ -120,26 +140,29 @@
}
- static FT_Error
- sfnt_table_info( TT_Face face,
+ FT_CALLBACK_DEF( FT_Error )
+ sfnt_table_info( FT_Face face, /* TT_Face */
FT_UInt idx,
FT_ULong *tag,
FT_ULong *offset,
FT_ULong *length )
{
+ TT_Face ttface = (TT_Face)face;
+
+
if ( !offset || !length )
return FT_THROW( Invalid_Argument );
if ( !tag )
- *length = face->num_tables;
+ *length = ttface->num_tables;
else
{
- if ( idx >= face->num_tables )
+ if ( idx >= ttface->num_tables )
return FT_THROW( Table_Missing );
- *tag = face->dir_tables[idx].Tag;
- *offset = face->dir_tables[idx].Offset;
- *length = face->dir_tables[idx].Length;
+ *tag = ttface->dir_tables[idx].Tag;
+ *offset = ttface->dir_tables[idx].Offset;
+ *length = ttface->dir_tables[idx].Length;
}
return FT_Err_Ok;
@@ -149,9 +172,9 @@
FT_DEFINE_SERVICE_SFNT_TABLEREC(
sfnt_service_sfnt_table,
- (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */
- (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */
- (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */
+ sfnt_load_table, /* FT_SFNT_TableLoadFunc load_table */
+ get_sfnt_table, /* FT_SFNT_TableGetFunc get_table */
+ sfnt_table_info /* FT_SFNT_TableInfoFunc table_info */
)
@@ -162,7 +185,7 @@
*
*/
- static FT_Error
+ FT_CALLBACK_DEF( FT_Error )
sfnt_get_glyph_name( FT_Face face,
FT_UInt glyph_index,
FT_Pointer buffer,
@@ -180,7 +203,7 @@
}
- static FT_UInt
+ FT_CALLBACK_DEF( FT_UInt )
sfnt_get_name_index( FT_Face face,
const FT_String* glyph_name )
{
@@ -217,8 +240,8 @@
FT_DEFINE_SERVICE_GLYPHDICTREC(
sfnt_service_glyph_dict,
- (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */
- (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index /* name_index */
+ sfnt_get_glyph_name, /* FT_GlyphDict_GetNameFunc get_name */
+ sfnt_get_name_index /* FT_GlyphDict_NameIndexFunc name_index */
)
#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
@@ -374,61 +397,61 @@
{
case 15:
k4 ^= (FT_UInt32)tail[14] << 16;
- /* fall through */
+ FALL_THROUGH;
case 14:
k4 ^= (FT_UInt32)tail[13] << 8;
- /* fall through */
+ FALL_THROUGH;
case 13:
k4 ^= (FT_UInt32)tail[12];
k4 *= c4;
k4 = ROTL32( k4, 18 );
k4 *= c1;
h4 ^= k4;
- /* fall through */
+ FALL_THROUGH;
case 12:
k3 ^= (FT_UInt32)tail[11] << 24;
- /* fall through */
+ FALL_THROUGH;
case 11:
k3 ^= (FT_UInt32)tail[10] << 16;
- /* fall through */
+ FALL_THROUGH;
case 10:
k3 ^= (FT_UInt32)tail[9] << 8;
- /* fall through */
+ FALL_THROUGH;
case 9:
k3 ^= (FT_UInt32)tail[8];
k3 *= c3;
k3 = ROTL32( k3, 17 );
k3 *= c4;
h3 ^= k3;
- /* fall through */
+ FALL_THROUGH;
case 8:
k2 ^= (FT_UInt32)tail[7] << 24;
- /* fall through */
+ FALL_THROUGH;
case 7:
k2 ^= (FT_UInt32)tail[6] << 16;
- /* fall through */
+ FALL_THROUGH;
case 6:
k2 ^= (FT_UInt32)tail[5] << 8;
- /* fall through */
+ FALL_THROUGH;
case 5:
k2 ^= (FT_UInt32)tail[4];
k2 *= c2;
k2 = ROTL32( k2, 16 );
k2 *= c3;
h2 ^= k2;
- /* fall through */
+ FALL_THROUGH;
case 4:
k1 ^= (FT_UInt32)tail[3] << 24;
- /* fall through */
+ FALL_THROUGH;
case 3:
k1 ^= (FT_UInt32)tail[2] << 16;
- /* fall through */
+ FALL_THROUGH;
case 2:
k1 ^= (FT_UInt32)tail[1] << 8;
- /* fall through */
+ FALL_THROUGH;
case 1:
k1 ^= (FT_UInt32)tail[0];
k1 *= c1;
@@ -491,17 +514,15 @@
char_type_func char_type,
FT_Bool report_invalid_characters )
{
- FT_Error error = FT_Err_Ok;
+ FT_Error error;
char* result = NULL;
FT_String* r;
FT_Char* p;
FT_UInt len;
- FT_UNUSED( error );
-
- if ( FT_ALLOC( result, entry->stringLength / 2 + 1 ) )
+ if ( FT_QALLOC( result, entry->stringLength / 2 + 1 ) )
return NULL;
if ( FT_STREAM_SEEK( entry->stringOffset ) ||
@@ -521,15 +542,14 @@
FT_TRACE0(( "get_win_string:"
" Character 0x%X invalid in PS name string\n",
((unsigned)p[0])*256 + (unsigned)p[1] ));
- break;
+ continue;
}
}
- if ( !len )
- *r = '\0';
+ *r = '\0';
FT_FRAME_EXIT();
- if ( !len )
+ if ( r != result )
return result;
get_win_string_error:
@@ -550,17 +570,15 @@
char_type_func char_type,
FT_Bool report_invalid_characters )
{
- FT_Error error = FT_Err_Ok;
+ FT_Error error;
char* result = NULL;
FT_String* r;
FT_Char* p;
FT_UInt len;
- FT_UNUSED( error );
-
- if ( FT_ALLOC( result, entry->stringLength + 1 ) )
+ if ( FT_QALLOC( result, entry->stringLength + 1 ) )
return NULL;
if ( FT_STREAM_SEEK( entry->stringOffset ) ||
@@ -580,15 +598,14 @@
FT_TRACE0(( "get_apple_string:"
" Character `%c' (0x%X) invalid in PS name string\n",
*p, *p ));
- break;
+ continue;
}
}
- if ( !len )
- *r = '\0';
+ *r = '\0';
FT_FRAME_EXIT();
- if ( !len )
+ if ( r != result )
return result;
get_apple_string_error:
@@ -602,7 +619,7 @@
}
- static FT_Bool
+ FT_CALLBACK_DEF( FT_Bool )
sfnt_get_name_id( TT_Face face,
FT_UShort id,
FT_Int *win,
@@ -657,7 +674,7 @@
/*
- * Find the shortest decimal representation of a 16.16 fixed point
+ * Find the shortest decimal representation of a 16.16 fixed-point
* number. The function fills `buf' with the result, returning a pointer
* to the position after the representation's last byte.
*/
@@ -733,7 +750,7 @@
an equivalent representation of `fixed'.
The above FOR loop always finds the larger of the two values; I
- verified this by iterating over all possible fixed point numbers.
+ verified this by iterating over all possible fixed-point numbers.
If the remainder is 17232*10, both values are equally good, and we
take the next even number (following IEEE 754's `round to nearest,
@@ -741,7 +758,7 @@
If the remainder is smaller than 17232*10, the lower of the two
numbers is nearer to the exact result (values 17232 and 34480 were
- also found by testing all possible fixed point values).
+ also found by testing all possible fixed-point values).
We use this to find a shorter decimal representation. If not ending
with digit zero, we take the representation with less error.
@@ -819,9 +836,9 @@
if ( !found )
{
- /* as a last resort we try the family name; note that this is */
- /* not in the Adobe TechNote, but GX fonts (which predate the */
- /* TechNote) benefit from this behaviour */
+ /* according to the 'name' documentation in the OpenType */
+ /* specification the font family name is to be used if the */
+ /* typographic family name is missing, so let's do that */
found = sfnt_get_name_id( face,
TT_NAME_ID_FONT_FAMILY,
&win,
@@ -853,6 +870,10 @@
{
FT_TRACE0(( "sfnt_get_var_ps_name:"
" No valid PS name prefix for font instances found\n" ));
+ /* XXX It probably makes sense to never let this fail */
+ /* since an arbitrary prefix should work, too. */
+ /* On the other hand, it is very unlikely that */
+ /* we ever reach this code at all. */
return NULL;
}
@@ -868,8 +889,8 @@
result[len] = '\0';
FT_TRACE0(( "sfnt_get_var_ps_name:"
- " Shortening variation PS name prefix\n"
- " "
+ " Shortening variation PS name prefix\n" ));
+ FT_TRACE0(( " "
" to %d characters\n", len ));
}
@@ -920,16 +941,16 @@
if ( !subfamily_name )
{
FT_TRACE1(( "sfnt_get_var_ps_name:"
- " can't construct named instance PS name;\n"
- " "
+ " can't construct named instance PS name;\n" ));
+ FT_TRACE1(( " "
" trying to construct normal instance PS name\n" ));
goto construct_instance_name;
}
/* after the prefix we have character `-' followed by the */
/* subfamily name (using only characters a-z, A-Z, and 0-9) */
- if ( FT_ALLOC( result, face->var_postscript_prefix_len +
- 1 + ft_strlen( subfamily_name ) + 1 ) )
+ if ( FT_QALLOC( result, face->var_postscript_prefix_len +
+ 1 + ft_strlen( subfamily_name ) + 1 ) )
return NULL;
ft_strcpy( result, face->var_postscript_prefix );
@@ -957,9 +978,9 @@
construct_instance_name:
axis = mm_var->axis;
- if ( FT_ALLOC( result,
- face->var_postscript_prefix_len +
- num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) )
+ if ( FT_QALLOC( result,
+ face->var_postscript_prefix_len +
+ num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) )
return NULL;
p = result;
@@ -993,6 +1014,7 @@
if ( t != ' ' && ft_isalnum( t ) )
*p++ = t;
}
+ *p++ = '\0';
}
check_length:
@@ -1040,47 +1062,49 @@
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
- static const char*
- sfnt_get_ps_name( TT_Face face )
+ FT_CALLBACK_DEF( const char* )
+ sfnt_get_ps_name( FT_Face face ) /* TT_Face */
{
+ TT_Face ttface = (TT_Face)face;
+
FT_Int found, win, apple;
const char* result = NULL;
- if ( face->postscript_name )
- return face->postscript_name;
+ if ( ttface->postscript_name )
+ return ttface->postscript_name;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- if ( face->blend &&
- ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
- FT_IS_VARIATION( FT_FACE( face ) ) ) )
+ if ( ttface->blend &&
+ ( FT_IS_NAMED_INSTANCE( face ) ||
+ FT_IS_VARIATION( face ) ) )
{
- face->postscript_name = sfnt_get_var_ps_name( face );
- return face->postscript_name;
+ ttface->postscript_name = sfnt_get_var_ps_name( ttface );
+ return ttface->postscript_name;
}
#endif
/* scan the name table to see whether we have a Postscript name here, */
/* either in Macintosh or Windows platform encodings */
- found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple );
+ found = sfnt_get_name_id( ttface, TT_NAME_ID_PS_NAME, &win, &apple );
if ( !found )
return NULL;
/* prefer Windows entries over Apple */
if ( win != -1 )
- result = get_win_string( face->root.memory,
- face->name_table.stream,
- face->name_table.names + win,
+ result = get_win_string( FT_FACE_MEMORY( face ),
+ ttface->name_table.stream,
+ ttface->name_table.names + win,
sfnt_is_postscript,
1 );
if ( !result && apple != -1 )
- result = get_apple_string( face->root.memory,
- face->name_table.stream,
- face->name_table.names + apple,
+ result = get_apple_string( FT_FACE_MEMORY( face ),
+ ttface->name_table.stream,
+ ttface->name_table.names + apple,
sfnt_is_postscript,
1 );
- face->postscript_name = result;
+ ttface->postscript_name = result;
return result;
}
@@ -1089,7 +1113,7 @@
FT_DEFINE_SERVICE_PSFONTNAMEREC(
sfnt_service_ps_name,
- (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */
+ sfnt_get_ps_name /* FT_PsName_GetFunc get_ps_font_name */
)
@@ -1099,14 +1123,14 @@
FT_DEFINE_SERVICE_TTCMAPSREC(
tt_service_get_cmap_info,
- (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */
+ tt_get_cmap_info /* TT_CMap_Info_GetFunc get_cmap_info */
)
#ifdef TT_CONFIG_OPTION_BDF
static FT_Error
- sfnt_get_charset_id( TT_Face face,
+ sfnt_get_charset_id( FT_Face face,
const char* *acharset_encoding,
const char* *acharset_registry )
{
@@ -1144,8 +1168,8 @@
FT_DEFINE_SERVICE_BDFRec(
sfnt_service_bdf,
- (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */
- (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */
+ sfnt_get_charset_id, /* FT_BDF_GetCharsetIdFunc get_charset_id */
+ tt_face_find_bdf_prop /* FT_BDF_GetPropertyFunc get_property */
)
@@ -1213,6 +1237,14 @@
#define PUT_COLOR_LAYERS( a ) NULL
#endif
+#ifdef FT_CONFIG_OPTION_SVG
+#define PUT_SVG_SUPPORT( a ) a
+#else
+#define PUT_SVG_SUPPORT( a ) NULL
+#endif
+
+#define PUT_COLOR_LAYERS_V1( a ) PUT_COLOR_LAYERS( a )
+
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
#define PUT_PS_NAMES( a ) a
#else
@@ -1271,9 +1303,9 @@
/* TT_Free_Table_Func free_eblc */
PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ),
- /* TT_Set_SBit_Strike_Func set_sbit_strike */
+ /* TT_Set_SBit_Strike_Func set_sbit_strike */
PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
- /* TT_Load_Strike_Metrics_Func load_strike_metrics */
+ /* TT_Load_Strike_Metrics_Func load_strike_metrics */
PUT_COLOR_LAYERS( tt_face_load_cpal ),
/* TT_Load_Table_Func load_cpal */
@@ -1287,13 +1319,32 @@
/* TT_Set_Palette_Func set_palette */
PUT_COLOR_LAYERS( tt_face_get_colr_layer ),
/* TT_Get_Colr_Layer_Func get_colr_layer */
+
+ PUT_COLOR_LAYERS_V1( tt_face_get_colr_glyph_paint ),
+ /* TT_Get_Color_Glyph_Paint_Func get_colr_glyph_paint */
+ PUT_COLOR_LAYERS_V1( tt_face_get_color_glyph_clipbox ),
+ /* TT_Get_Color_Glyph_ClipBox_Func get_clipbox */
+ PUT_COLOR_LAYERS_V1( tt_face_get_paint_layers ),
+ /* TT_Get_Paint_Layers_Func get_paint_layers */
+ PUT_COLOR_LAYERS_V1( tt_face_get_colorline_stops ),
+ /* TT_Get_Paint get_paint */
+ PUT_COLOR_LAYERS_V1( tt_face_get_paint ),
+ /* TT_Get_Colorline_Stops_Func get_colorline_stops */
+
PUT_COLOR_LAYERS( tt_face_colr_blend_layer ),
/* TT_Blend_Colr_Func colr_blend */
tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */
tt_face_get_name, /* TT_Get_Name_Func get_name */
- sfnt_get_name_id /* TT_Get_Name_ID_Func get_name_id */
+ sfnt_get_name_id, /* TT_Get_Name_ID_Func get_name_id */
+
+ PUT_SVG_SUPPORT( tt_face_load_svg ),
+ /* TT_Load_Table_Func load_svg */
+ PUT_SVG_SUPPORT( tt_face_free_svg ),
+ /* TT_Free_Table_Func free_svg */
+ PUT_SVG_SUPPORT( tt_face_load_svg_doc )
+ /* TT_Load_Svg_Doc_Func load_svg_doc */
)
@@ -1309,9 +1360,9 @@
(const void*)&sfnt_interface, /* module specific interface */
- (FT_Module_Constructor)NULL, /* module_init */
- (FT_Module_Destructor) NULL, /* module_done */
- (FT_Module_Requester) sfnt_get_interface /* get_interface */
+ NULL, /* FT_Module_Constructor module_init */
+ NULL, /* FT_Module_Destructor module_done */
+ sfnt_get_interface /* FT_Module_Requester get_interface */
)
diff --git a/src/3rdparty/freetype/src/sfnt/sfdriver.h b/src/3rdparty/freetype/src/sfnt/sfdriver.h
index 1ac2706325..2445958b69 100644
--- a/src/3rdparty/freetype/src/sfnt/sfdriver.h
+++ b/src/3rdparty/freetype/src/sfnt/sfdriver.h
@@ -4,7 +4,7 @@
*
* High-level SFNT driver interface (specification).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/sferrors.h b/src/3rdparty/freetype/src/sfnt/sferrors.h
index 55c3e76b66..e7a8eb04bb 100644
--- a/src/3rdparty/freetype/src/sfnt/sferrors.h
+++ b/src/3rdparty/freetype/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
*
* SFNT error codes (specification only).
*
- * Copyright (C) 2001-2020 by
+ * Copyright (C) 2001-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/sfnt.c b/src/3rdparty/freetype/src/sfnt/sfnt.c
index 471239ff0b..8e4f08a90c 100644
--- a/src/3rdparty/freetype/src/sfnt/sfnt.c
+++ b/src/3rdparty/freetype/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
*
* Single object library component.
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -27,6 +27,7 @@
#include "ttcmap.c"
#include "ttcolr.c"
#include "ttcpal.c"
+#include "ttsvg.c"
#include "ttkern.c"
#include "ttload.c"
diff --git a/src/3rdparty/freetype/src/sfnt/sfobjs.c b/src/3rdparty/freetype/src/sfnt/sfobjs.c
index 39460be2e6..f5d66ef840 100644
--- a/src/3rdparty/freetype/src/sfnt/sfobjs.c
+++ b/src/3rdparty/freetype/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
*
* SFNT object management (base).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -65,7 +65,7 @@
len = (FT_UInt)entry->stringLength / 2;
- if ( FT_NEW_ARRAY( string, len + 1 ) )
+ if ( FT_QNEW_ARRAY( string, len + 1 ) )
return NULL;
for ( n = 0; n < len; n++ )
@@ -100,7 +100,7 @@
len = (FT_UInt)entry->stringLength;
- if ( FT_NEW_ARRAY( string, len + 1 ) )
+ if ( FT_QNEW_ARRAY( string, len + 1 ) )
return NULL;
for ( n = 0; n < len; n++ )
@@ -360,17 +360,27 @@
FT_FRAME_END
};
+#ifndef FT_CONFIG_OPTION_USE_BROTLI
+ FT_UNUSED( face_instance_index );
+ FT_UNUSED( woff2_num_faces );
+#endif
+
face->ttc_header.tag = 0;
face->ttc_header.version = 0;
face->ttc_header.count = 0;
+#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \
+ defined( FT_CONFIG_OPTION_USE_BROTLI )
retry:
+#endif
+
offset = FT_STREAM_POS();
if ( FT_READ_ULONG( tag ) )
return error;
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
if ( tag == TTAG_wOFF )
{
FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" ));
@@ -386,7 +396,9 @@
stream = face->root.stream;
goto retry;
}
+#endif
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
if ( tag == TTAG_wOF2 )
{
FT_TRACE2(( "sfnt_open_font: file is a WOFF2; synthesizing SFNT\n" ));
@@ -405,6 +417,7 @@
stream = face->root.stream;
goto retry;
}
+#endif
if ( tag != 0x00010000UL &&
tag != TTAG_ttcf &&
@@ -446,7 +459,7 @@
return FT_THROW( Array_Too_Large );
/* now read the offsets of each font in the file */
- if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
+ if ( FT_QNEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
return error;
if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
@@ -464,7 +477,7 @@
face->ttc_header.version = 1 << 16;
face->ttc_header.count = 1;
- if ( FT_NEW( face->ttc_header.offsets ) )
+ if ( FT_QNEW( face->ttc_header.offsets ) )
return error;
face->ttc_header.offsets[0] = offset;
@@ -521,17 +534,23 @@
0 );
}
- if ( !face->var )
+ if ( !face->tt_var )
{
/* we want the metrics variations interface */
/* from the `truetype' module only */
FT_Module tt_module = FT_Get_Module( library, "truetype" );
- face->var = ft_module_get_service( tt_module,
- FT_SERVICE_ID_METRICS_VARIATIONS,
- 0 );
+ face->tt_var = ft_module_get_service( tt_module,
+ FT_SERVICE_ID_METRICS_VARIATIONS,
+ 0 );
}
+
+ if ( !face->face_var )
+ face->face_var = ft_module_get_service(
+ &face->root.driver->root,
+ FT_SERVICE_ID_METRICS_VARIATIONS,
+ 0 );
#endif
FT_TRACE2(( "SFNT driver\n" ));
@@ -553,7 +572,7 @@
face_index = FT_ABS( face_instance_index ) & 0xFFFF;
/* 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 >= face->ttc_header.count )
@@ -643,8 +662,8 @@
*/
if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) &&
- !( FT_ALLOC( default_values, num_axes * 4 ) ||
- FT_ALLOC( instance_values, num_axes * 4 ) ) )
+ !( FT_QALLOC( default_values, num_axes * 4 ) ||
+ FT_QALLOC( instance_values, num_axes * 4 ) ) )
{
/* the current stream position is 16 bytes after the table start */
FT_ULong array_start = FT_STREAM_POS() - 16 + offset;
@@ -679,6 +698,9 @@
instance_offset += instance_size;
}
+ /* named instance indices start with value 1 */
+ face->var_default_named_instance = i + 1;
+
if ( i == num_instances )
{
/* no default instance in named instance table; */
@@ -771,17 +793,23 @@
FT_Int num_params,
FT_Parameter* params )
{
- FT_Error error;
+ FT_Error error;
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
- FT_Error psnames_error;
+ FT_Error psnames_error;
#endif
- FT_Bool has_outline;
- FT_Bool is_apple_sbit;
- FT_Bool is_apple_sbix;
- FT_Bool has_CBLC;
- FT_Bool has_CBDT;
- FT_Bool ignore_typographic_family = FALSE;
- FT_Bool ignore_typographic_subfamily = FALSE;
+
+ FT_Bool has_outline;
+ FT_Bool is_apple_sbit;
+
+ FT_Bool has_CBLC;
+ FT_Bool has_CBDT;
+ FT_Bool has_EBLC;
+ FT_Bool has_bloc;
+ FT_Bool has_sbix;
+
+ FT_Bool ignore_typographic_family = FALSE;
+ FT_Bool ignore_typographic_subfamily = FALSE;
+ FT_Bool ignore_sbix = FALSE;
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
@@ -800,6 +828,8 @@
ignore_typographic_family = TRUE;
else if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY )
ignore_typographic_subfamily = TRUE;
+ else if ( params[i].tag == FT_PARAM_TAG_IGNORE_SBIX )
+ ignore_sbix = TRUE;
}
}
@@ -820,7 +850,8 @@
/* it doesn't contain outlines. */
/* */
- FT_TRACE2(( "sfnt_load_face: %p\n\n", (void *)face ));
+ FT_TRACE2(( "sfnt_load_face: %p\n", (void *)face ));
+ FT_TRACE2(( "\n" ));
/* do we have outlines in there? */
#ifdef FT_CONFIG_OPTION_INCREMENTAL
@@ -834,14 +865,17 @@
tt_face_lookup_table( face, TTAG_CFF2 ) );
#endif
- is_apple_sbit = 0;
- is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
+ /* check which sbit formats are present */
+ has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 );
+ has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 );
+ has_EBLC = !face->goto_table( face, TTAG_EBLC, stream, 0 );
+ has_bloc = !face->goto_table( face, TTAG_bloc, stream, 0 );
+ has_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
- /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
- * outline rendered on top. We don't support that yet, so just ignore
- * the 'glyf' outline and advertise it as a bitmap-only font. */
- if ( is_apple_sbix )
- has_outline = FALSE;
+ is_apple_sbit = FALSE;
+
+ if ( ignore_sbix )
+ has_sbix = FALSE;
/* if this font doesn't contain outlines, we try to load */
/* a `bhed' table */
@@ -853,16 +887,13 @@
/* load the font header (`head' table) if this isn't an Apple */
/* sbit font file */
- if ( !is_apple_sbit || is_apple_sbix )
+ if ( !is_apple_sbit || has_sbix )
{
LOAD_( head );
if ( error )
goto Exit;
}
- has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 );
- has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 );
-
/* Ignore outlines for CBLC/CBDT fonts. */
if ( has_CBLC || has_CBDT )
has_outline = FALSE;
@@ -972,7 +1003,11 @@
/* the optional tables */
/* embedded bitmap support */
- if ( sfnt->load_eblc )
+ /* TODO: Replace this clumsy check for all possible sbit tables */
+ /* with something better (for example, by passing a parameter */
+ /* to suppress 'sbix' loading). */
+ if ( sfnt->load_eblc &&
+ ( has_CBLC || has_EBLC || has_bloc || has_sbix ) )
LOAD_( eblc );
/* colored glyph support */
@@ -982,6 +1017,10 @@
LOAD_( colr );
}
+ /* OpenType-SVG glyph support */
+ if ( sfnt->load_svg )
+ LOAD_( svg );
+
/* consider the pclt, kerning, and gasp tables as optional */
LOAD_( pclt );
LOAD_( gasp );
@@ -1024,6 +1063,16 @@
GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
}
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ {
+ FT_Memory memory = face->root.memory;
+
+
+ if ( FT_STRDUP( face->non_var_style_name, face->root.style_name ) )
+ goto Exit;
+ }
+#endif
+
/* now set up root fields */
{
FT_Face root = &face->root;
@@ -1036,11 +1085,19 @@
*/
if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC ||
face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ||
- face->colr )
+ face->colr ||
+ face->svg )
flags |= FT_FACE_FLAG_COLOR; /* color glyphs */
if ( has_outline == TRUE )
- flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
+ {
+ /* by default (and for backward compatibility) we handle */
+ /* fonts with an 'sbix' table as bitmap-only */
+ if ( has_sbix )
+ flags |= FT_FACE_FLAG_SBIX; /* with 'sbix' bitmaps */
+ else
+ flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
+ }
/* The sfnt driver only supports bitmap fonts natively, thus we */
/* don't set FT_FACE_FLAG_HINTER. */
@@ -1069,13 +1126,7 @@
/* Don't bother to load the tables unless somebody asks for them. */
/* No need to do work which will (probably) not be used. */
if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
- {
- if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
- tt_face_lookup_table( face, TTAG_gvar ) != 0 )
- flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
- if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 )
- flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
- }
+ flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
#endif
root->face_flags = flags;
@@ -1149,9 +1200,10 @@
}
/* synthesize Unicode charmap if one is missing */
- if ( !has_unicode )
+ if ( !has_unicode &&
+ root->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
{
- FT_CharMapRec cmaprec;
+ FT_CharMapRec cmaprec;
cmaprec.face = root;
@@ -1188,7 +1240,7 @@
if ( count > 0 )
{
- FT_Memory memory = face->root.stream->memory;
+ FT_Memory memory = face->root.memory;
FT_UShort em_size = face->header.Units_Per_EM;
FT_Short avgwidth = face->os2.xAvgCharWidth;
FT_Size_Metrics metrics;
@@ -1207,7 +1259,7 @@
/* of `FT_Face', we map `available_sizes' indices to strike */
/* indices */
if ( FT_NEW_ARRAY( root->available_sizes, count ) ||
- FT_NEW_ARRAY( sbit_strike_map, count ) )
+ FT_QNEW_ARRAY( sbit_strike_map, count ) )
goto Exit;
bsize_idx = 0;
@@ -1236,7 +1288,7 @@
}
/* reduce array size to the actually used elements */
- (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx );
+ FT_MEM_QRENEW_ARRAY( sbit_strike_map, count, bsize_idx );
/* from now on, all strike indices are mapped */
/* using `sbit_strike_map' */
@@ -1262,7 +1314,8 @@
*
* Set up metrics.
*/
- if ( FT_IS_SCALABLE( root ) )
+ if ( FT_IS_SCALABLE( root ) ||
+ FT_HAS_SBIX( root ) )
{
/* XXX What about if outline header is missing */
/* (e.g. sfnt wrapped bitmap)? */
@@ -1401,6 +1454,12 @@
sfnt->free_cpal( face );
sfnt->free_colr( face );
}
+
+#ifdef FT_CONFIG_OPTION_SVG
+ /* free SVG data */
+ if ( sfnt->free_svg )
+ sfnt->free_svg( face );
+#endif
}
#ifdef TT_CONFIG_OPTION_BDF
@@ -1460,6 +1519,7 @@
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_FREE( face->var_postscript_prefix );
+ FT_FREE( face->non_var_style_name );
#endif
/* freeing glyph color palette data */
diff --git a/src/3rdparty/freetype/src/sfnt/sfobjs.h b/src/3rdparty/freetype/src/sfnt/sfobjs.h
index e8e3042083..906aebbf90 100644
--- a/src/3rdparty/freetype/src/sfnt/sfobjs.h
+++ b/src/3rdparty/freetype/src/sfnt/sfobjs.h
@@ -4,7 +4,7 @@
*
* SFNT object management (specification).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/sfwoff.c b/src/3rdparty/freetype/src/sfnt/sfwoff.c
index f0a32e1e06..7c0ce2205e 100644
--- a/src/3rdparty/freetype/src/sfnt/sfwoff.c
+++ b/src/3rdparty/freetype/src/sfnt/sfwoff.c
@@ -4,7 +4,7 @@
*
* WOFF format management (base).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -23,6 +23,9 @@
#include <freetype/ftgzip.h>
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
+
+
/**************************************************************************
*
* The macro FT_COMPONENT is used in trace mode. It is an implicit
@@ -61,12 +64,11 @@
FT_FREE( stream->base );
stream->size = 0;
- stream->base = NULL;
stream->close = NULL;
}
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
compare_offsets( const void* a,
const void* b )
{
@@ -109,7 +111,7 @@
FT_ULong sfnt_offset;
FT_Int nn;
- FT_ULong old_tag = 0;
+ FT_Tag old_tag = 0;
static const FT_Frame_Field woff_header_fields[] =
{
@@ -160,8 +162,7 @@
}
/* Don't trust `totalSfntSize' before thorough checks. */
- if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
- FT_NEW( sfnt_stream ) )
+ if ( FT_QALLOC( sfnt, 12 ) || FT_NEW( sfnt_stream ) )
goto Exit;
sfnt_header = sfnt;
@@ -194,13 +195,13 @@
/* tag value, the tables themselves are not. We thus have to */
/* sort them by offset and check that they don't overlap. */
- if ( FT_NEW_ARRAY( tables, woff.num_tables ) ||
- FT_NEW_ARRAY( indices, woff.num_tables ) )
+ if ( FT_QNEW_ARRAY( tables, woff.num_tables ) ||
+ FT_QNEW_ARRAY( indices, woff.num_tables ) )
goto Exit;
- FT_TRACE2(( "\n"
- " tag offset compLen origLen checksum\n"
- " -------------------------------------------\n" ));
+ FT_TRACE2(( "\n" ));
+ FT_TRACE2(( " tag offset compLen origLen checksum\n" ));
+ FT_TRACE2(( " -------------------------------------------\n" ));
if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
goto Exit;
@@ -326,9 +327,7 @@
}
/* Now use `totalSfntSize'. */
- if ( FT_REALLOC( sfnt,
- 12 + woff.num_tables * 16UL,
- woff.totalSfntSize ) )
+ if ( FT_QREALLOC( sfnt, 12, woff.totalSfntSize ) )
goto Exit;
sfnt_header = sfnt + 12;
@@ -360,8 +359,6 @@
}
else
{
-#ifdef FT_CONFIG_OPTION_USE_ZLIB
-
/* Uncompress with zlib. */
FT_ULong output_len = table->OrigLength;
@@ -377,13 +374,6 @@
error = FT_THROW( Invalid_Table );
goto Exit1;
}
-
-#else /* !FT_CONFIG_OPTION_USE_ZLIB */
-
- error = FT_THROW( Unimplemented_Feature );
- goto Exit1;
-
-#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
}
FT_FRAME_EXIT();
@@ -433,5 +423,12 @@
#undef WRITE_USHORT
#undef WRITE_ULONG
+#else /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+ /* ANSI C doesn't like empty source files */
+ typedef int sfwoff_dummy_;
+
+#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
+
/* END */
diff --git a/src/3rdparty/freetype/src/sfnt/sfwoff.h b/src/3rdparty/freetype/src/sfnt/sfwoff.h
index d177ab1160..d438422737 100644
--- a/src/3rdparty/freetype/src/sfnt/sfwoff.h
+++ b/src/3rdparty/freetype/src/sfnt/sfwoff.h
@@ -4,7 +4,7 @@
*
* WOFFF format management (specification).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -26,12 +26,15 @@
FT_BEGIN_HEADER
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
FT_LOCAL( FT_Error )
woff_open_font( FT_Stream stream,
TT_Face face );
+#endif
+
FT_END_HEADER
#endif /* SFWOFF_H_ */
diff --git a/src/3rdparty/freetype/src/sfnt/sfwoff2.c b/src/3rdparty/freetype/src/sfnt/sfwoff2.c
index 5c8202f823..2be44a347a 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-2023 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
-
/**************************************************************************
*
@@ -38,6 +36,8 @@
#undef FT_COMPONENT
#define FT_COMPONENT sfwoff2
+ /* An arbitrary, heuristic size limit (67MByte) for expanded WOFF2 data. */
+#define MAX_SFNT_SIZE ( 1 << 26 )
#define READ_255USHORT( var ) FT_SET_ERROR( Read255UShort( stream, &var ) )
@@ -86,6 +86,8 @@
#define BBOX_STREAM 5
#define INSTRUCTION_STREAM 6
+#define HAVE_OVERLAP_SIMPLE_BITMAP 0x1
+
static void
stream_close( FT_Stream stream )
@@ -96,20 +98,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 )
@@ -230,9 +231,9 @@
{
FT_TRACE6(( "Reallocating %lu to %lu.\n",
*dst_size, (*offset + size) ));
- if ( FT_REALLOC( dst,
- (FT_ULong)( *dst_size ),
- (FT_ULong)( *offset + size ) ) )
+ if ( FT_QREALLOC( dst,
+ (FT_ULong)( *dst_size ),
+ (FT_ULong)( *offset + size ) ) )
goto Exit;
*dst_size = *offset + size;
@@ -316,8 +317,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 +337,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 +526,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 +554,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 +786,7 @@
goto Fail;
loca_buf_size = loca_values_size * offset_size;
- if ( FT_NEW_ARRAY( loca_buf, loca_buf_size ) )
+ if ( FT_QALLOC( loca_buf, loca_buf_size ) )
goto Fail;
dst = loca_buf;
@@ -845,15 +841,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;
@@ -866,18 +865,20 @@
WOFF2_Point points = NULL;
- if ( FT_NEW_ARRAY( substreams, num_substreams ) )
+ if ( FT_QNEW_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 +891,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,21 +914,36 @@
offset += substream_size;
}
- if ( FT_NEW_ARRAY( loca_values, num_glyphs + 1 ) )
+ 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_QNEW_ARRAY( loca_values, num_glyphs + 1 ) )
goto Fail;
points_size = 0;
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 ) )
+ if ( FT_QALLOC( glyph_buf, glyph_buf_size ) )
goto Fail;
- if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
+ if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
goto Fail;
for ( i = 0; i < num_glyphs; ++i )
@@ -959,7 +975,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;
@@ -985,7 +1001,7 @@
size_needed = 12 + composite_size + instruction_size;
if ( glyph_buf_size < size_needed )
{
- if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
+ if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
goto Fail;
glyph_buf_size = size_needed;
}
@@ -1037,8 +1053,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,7 +1066,18 @@
FT_Byte* pointer = NULL;
- if ( FT_NEW_ARRAY( n_points_arr, n_contours ) )
+ /* 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_QNEW_ARRAY( n_points_arr, n_contours ) )
goto Fail;
if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) )
@@ -1084,7 +1114,7 @@
/* Create array to store point information. */
points_size = total_n_points;
- if ( FT_NEW_ARRAY( points, points_size ) )
+ if ( FT_QNEW_ARRAY( points, points_size ) )
goto Fail;
if ( triplet_decode( flags_buf,
@@ -1113,7 +1143,7 @@
instruction_size;
if ( glyph_buf_size < size_needed )
{
- if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
+ if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
goto Fail;
glyph_buf_size = size_needed;
}
@@ -1167,6 +1197,7 @@
points,
n_contours,
instruction_size,
+ have_overlap,
glyph_buf,
glyph_buf_size,
&glyph_size ) )
@@ -1197,8 +1228,7 @@
*glyf_checksum += compute_ULong_sum( glyph_buf, glyph_size );
/* Store x_mins, may be required to reconstruct `hmtx'. */
- if ( n_contours > 0 )
- info->x_mins[i] = (FT_Short)x_min;
+ info->x_mins[i] = (FT_Short)x_min;
}
info->glyf_table->dst_length = dest_offset - info->glyf_table->dst_offset;
@@ -1315,7 +1345,7 @@
offset_size = index_format ? 4 : 2;
/* Create `x_mins' array. */
- if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
+ if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
return error;
loca_offset = info->loca_table->src_offset;
@@ -1403,8 +1433,8 @@
if ( num_hmetrics < 1 )
goto Fail;
- if ( FT_NEW_ARRAY( advance_widths, num_hmetrics ) ||
- FT_NEW_ARRAY( lsbs, num_glyphs ) )
+ if ( FT_QNEW_ARRAY( advance_widths, num_hmetrics ) ||
+ FT_QNEW_ARRAY( lsbs, num_glyphs ) )
goto Fail;
/* Read `advanceWidth' stream. Always present. */
@@ -1455,7 +1485,7 @@
/* Build the hmtx table. */
hmtx_table_size = 2 * num_hmetrics + 2 * num_glyphs;
- if ( FT_NEW_ARRAY( hmtx_table, hmtx_table_size ) )
+ if ( FT_QALLOC( hmtx_table, hmtx_table_size ) )
goto Fail;
dst = hmtx_table;
@@ -1512,10 +1542,10 @@
{
/* Memory management of `transformed_buf' is handled by the caller. */
- FT_Error error = FT_Err_Ok;
- FT_Stream stream = NULL;
- FT_Byte* buf_cursor = NULL;
- FT_Byte* table_entry = NULL;
+ FT_Error error = FT_Err_Ok;
+ FT_Stream stream = NULL;
+ FT_Byte* buf_cursor = NULL;
+ FT_Byte table_entry[16];
/* We are reallocating memory for `sfnt', so its pointer may change. */
FT_Byte* sfnt = *sfnt_bytes;
@@ -1556,10 +1586,6 @@
}
}
- /* Create buffer for table entries. */
- if ( FT_NEW_ARRAY( table_entry, 16 ) )
- goto Fail;
-
/* Create a stream for the uncompressed buffer. */
if ( FT_NEW( stream ) )
goto Fail;
@@ -1722,7 +1748,6 @@
/* Set pointer of sfnt stream to its correct value. */
*sfnt_bytes = sfnt;
- FT_FREE( table_entry );
FT_Stream_Close( stream );
FT_FREE( stream );
@@ -1735,7 +1760,6 @@
/* Set pointer of sfnt stream to its correct value. */
*sfnt_bytes = sfnt;
- FT_FREE( table_entry );
FT_Stream_Close( stream );
FT_FREE( stream );
@@ -1848,15 +1872,14 @@
woff2.ttc_fonts = NULL;
/* Read table directory. */
- if ( FT_NEW_ARRAY( tables, woff2.num_tables ) ||
- FT_NEW_ARRAY( indices, woff2.num_tables ) )
+ if ( FT_QNEW_ARRAY( tables, woff2.num_tables ) ||
+ FT_QNEW_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++ )
{
@@ -1921,10 +1944,11 @@
goto Exit;
}
+ table->flags = flags;
table->src_offset = src_offset;
table->src_length = table->TransformLength;
src_offset += table->TransformLength;
- table->flags = flags;
+ table->dst_offset = 0;
FT_TRACE2(( " %c%c%c%c %08d %08d %08ld %08ld %08ld\n",
(FT_Char)( table->Tag >> 24 ),
@@ -1982,6 +2006,7 @@
FT_TRACE4(( "Number of fonts in TTC: %d\n", woff2.num_fonts ));
+ /* pre-zero pointers within in case of failure */
if ( FT_NEW_ARRAY( woff2.ttc_fonts, woff2.num_fonts ) )
goto Exit;
@@ -1995,7 +2020,7 @@
if ( FT_READ_ULONG( ttc_font->flavor ) )
goto Exit;
- if ( FT_NEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
+ if ( FT_QNEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
goto Exit;
FT_TRACE5(( "Number of tables in font %d: %d\n",
@@ -2076,7 +2101,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 +2111,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 +2123,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 +2144,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 +2153,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++ )
@@ -2157,9 +2182,8 @@
else
sfnt_size = woff2.totalSfntSize;
- /* Value 1<<26 = 67108864 is heuristic. */
- if (sfnt_size >= (1 << 26))
- sfnt_size = 1 << 26;
+ if ( sfnt_size >= MAX_SFNT_SIZE )
+ sfnt_size = MAX_SFNT_SIZE;
#ifdef FT_DEBUG_LEVEL_TRACE
if ( sfnt_size != woff2.totalSfntSize )
@@ -2170,8 +2194,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,22 +2233,46 @@
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 );
goto Exit;
}
- if ( woff2.uncompressed_size > sfnt_size )
+ /* We must not blindly trust `uncompressed_size` since its */
+ /* value might be corrupted. If it is too large, reject the */
+ /* font. In other words, we don't accept a WOFF2 font that */
+ /* expands to something larger than MAX_SFNT_SIZE. If ever */
+ /* necessary, this limit can be easily adjusted. */
+ if ( woff2.uncompressed_size > MAX_SFNT_SIZE )
{
- FT_ERROR(( "woff2_open_font: SFNT table lengths are too large.\n" ));
- error = FT_THROW( Invalid_Table );
+ FT_ERROR(( "Uncompressed font too large.\n" ));
+ error = FT_THROW( Array_Too_Large );
goto Exit;
}
/* 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. */
@@ -2255,9 +2303,9 @@
{
FT_TRACE5(( "Trimming sfnt stream from %lu to %lu.\n",
sfnt_size, woff2.actual_sfnt_size ));
- if ( FT_REALLOC( sfnt,
- (FT_ULong)( sfnt_size ),
- (FT_ULong)( woff2.actual_sfnt_size ) ) )
+ if ( FT_QREALLOC( sfnt,
+ (FT_ULong)( sfnt_size ),
+ (FT_ULong)( woff2.actual_sfnt_size ) ) )
goto Exit;
}
@@ -2333,5 +2381,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 */
diff --git a/src/3rdparty/freetype/src/sfnt/sfwoff2.h b/src/3rdparty/freetype/src/sfnt/sfwoff2.h
index 798f66bd0a..4901286ee0 100644
--- a/src/3rdparty/freetype/src/sfnt/sfwoff2.h
+++ b/src/3rdparty/freetype/src/sfnt/sfwoff2.h
@@ -4,7 +4,7 @@
*
* WOFFF2 format management (specification).
*
- * Copyright (C) 2019-2020 by
+ * Copyright (C) 2019-2023 by
* Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -26,6 +26,7 @@
FT_BEGIN_HEADER
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
/* Leave the first byte open to store `flag_byte'. */
#define WOFF2_FLAGS_TRANSFORM 1 << 8
@@ -55,6 +56,7 @@ FT_BEGIN_HEADER
#define GLYF_REPEAT 1 << 3
#define GLYF_THIS_X_IS_SAME 1 << 4
#define GLYF_THIS_Y_IS_SAME 1 << 5
+#define GLYF_OVERLAP_SIMPLE 1 << 6
/* Other constants */
#define CONTOUR_OFFSET_END_POINT 10
@@ -66,6 +68,7 @@ FT_BEGIN_HEADER
FT_Int* face_index,
FT_Long* num_faces );
+#endif /* FT_CONFIG_OPTION_USE_BROTLI */
FT_END_HEADER
diff --git a/src/3rdparty/freetype/src/sfnt/ttbdf.c b/src/3rdparty/freetype/src/sfnt/ttbdf.c
index a287d3afc4..536fa7467e 100644
--- a/src/3rdparty/freetype/src/sfnt/ttbdf.c
+++ b/src/3rdparty/freetype/src/sfnt/ttbdf.c
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded BDF properties (body).
*
- * Copyright (C) 2005-2020 by
+ * Copyright (C) 2005-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -136,13 +136,14 @@
FT_LOCAL_DEF( FT_Error )
- tt_face_find_bdf_prop( TT_Face face,
+ tt_face_find_bdf_prop( FT_Face face, /* TT_Face */
const char* property_name,
BDF_PropertyRec *aprop )
{
- TT_BDF bdf = &face->bdf;
- FT_Size size = FT_FACE( face )->size;
- FT_Error error = FT_Err_Ok;
+ TT_Face ttface = (TT_Face)face;
+ TT_BDF bdf = &ttface->bdf;
+ FT_Size size = FT_FACE_SIZE( face );
+ FT_Error error = FT_Err_Ok;
FT_Byte* p;
FT_UInt count;
FT_Byte* strike;
@@ -153,7 +154,7 @@
if ( bdf->loaded == 0 )
{
- error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
+ error = tt_face_load_bdf_props( ttface, FT_FACE_STREAM( face ) );
if ( error )
goto Exit;
}
@@ -248,7 +249,7 @@
#else /* !TT_CONFIG_OPTION_BDF */
/* ANSI C doesn't like empty source files */
- typedef int _tt_bdf_dummy;
+ typedef int tt_bdf_dummy_;
#endif /* !TT_CONFIG_OPTION_BDF */
diff --git a/src/3rdparty/freetype/src/sfnt/ttbdf.h b/src/3rdparty/freetype/src/sfnt/ttbdf.h
index e60c01cb8b..0d7a0acecc 100644
--- a/src/3rdparty/freetype/src/sfnt/ttbdf.h
+++ b/src/3rdparty/freetype/src/sfnt/ttbdf.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded BDF properties (specification).
*
- * Copyright (C) 2005-2020 by
+ * Copyright (C) 2005-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -34,7 +34,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
- tt_face_find_bdf_prop( TT_Face face,
+ tt_face_find_bdf_prop( FT_Face face,
const char* property_name,
BDF_PropertyRec *aprop );
diff --git a/src/3rdparty/freetype/src/sfnt/ttcmap.c b/src/3rdparty/freetype/src/sfnt/ttcmap.c
index 556a712199..9ba25dcbc1 100644
--- a/src/3rdparty/freetype/src/sfnt/ttcmap.c
+++ b/src/3rdparty/freetype/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
*
* TrueType character mapping table (cmap) support (body).
*
- * Copyright (C) 2002-2020 by
+ * Copyright (C) 2002-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -59,10 +59,14 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap_init( TT_CMap cmap,
- FT_Byte* table )
+ tt_cmap_init( FT_CMap cmap, /* TT_CMap */
+ void* table_ )
{
- cmap->data = table;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = (FT_Byte*)table_;
+
+
+ ttcmap->data = table;
return FT_Err_Ok;
}
@@ -128,21 +132,23 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap0_char_index( TT_CMap cmap,
+ tt_cmap0_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
return char_code < 256 ? table[6 + char_code] : 0;
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap0_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap0_char_next( FT_CMap cmap, /* TT_CMap */
FT_UInt32 *pchar_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt32 charcode = *pchar_code;
FT_UInt32 result = 0;
FT_UInt gindex = 0;
@@ -165,10 +171,11 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap0_get_info( TT_CMap cmap,
+ tt_cmap0_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 4;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 4;
cmap_info->format = 0;
@@ -453,10 +460,11 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap2_char_index( TT_CMap cmap,
+ tt_cmap2_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt result = 0;
FT_Byte* subheader;
@@ -465,7 +473,7 @@
if ( subheader )
{
FT_Byte* p = subheader;
- FT_UInt idx = (FT_UInt)(char_code & 0xFF);
+ FT_UInt idx = (FT_UInt)( char_code & 0xFF );
FT_UInt start, count;
FT_Int delta;
FT_UInt offset;
@@ -491,11 +499,12 @@
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap2_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap2_char_next( FT_CMap cmap, /* TT_CMap */
FT_UInt32 *pcharcode )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt gindex = 0;
FT_UInt32 result = 0;
FT_UInt32 charcode = *pcharcode + 1;
@@ -579,10 +588,11 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap2_get_info( TT_CMap cmap,
+ tt_cmap2_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 4;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 4;
cmap_info->format = 2;
@@ -706,18 +716,20 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap4_init( TT_CMap4 cmap,
- FT_Byte* table )
+ tt_cmap4_init( FT_CMap cmap, /* TT_CMap4 */
+ void* table_ )
{
+ TT_CMap4 ttcmap = (TT_CMap4)cmap;
+ FT_Byte* table = (FT_Byte*)table_;
FT_Byte* p;
- cmap->cmap.data = table;
+ ttcmap->cmap.data = table;
- p = table + 6;
- cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1;
- cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
- cmap->cur_gindex = 0;
+ p = table + 6;
+ ttcmap->num_ranges = FT_PEEK_USHORT( p ) >> 1;
+ ttcmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
+ ttcmap->cur_gindex = 0;
return FT_Err_Ok;
}
@@ -755,7 +767,7 @@
cmap->cur_start == 0xFFFFU &&
cmap->cur_end == 0xFFFFU )
{
- TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face;
+ TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
FT_Byte* limit = face->cmap_table + face->cmap_size;
@@ -788,15 +800,12 @@
static void
tt_cmap4_next( TT_CMap4 cmap )
{
- TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face;
+ TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
FT_Byte* limit = face->cmap_table + face->cmap_size;
FT_UInt charcode;
- if ( cmap->cur_charcode >= 0xFFFFUL )
- goto Fail;
-
charcode = (FT_UInt)cmap->cur_charcode + 1;
if ( charcode < cmap->cur_start )
@@ -882,7 +891,6 @@
charcode = cmap->cur_start;
}
- Fail:
cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
cmap->cur_gindex = 0;
}
@@ -916,6 +924,16 @@
length = (FT_UInt)( valid->limit - table );
}
+ /* it also happens that the `length' field is too small; */
+ /* this is easy to correct */
+ if ( length < (FT_UInt)( valid->limit - table ) )
+ {
+ if ( valid->level >= FT_VALIDATE_PARANOID )
+ FT_INVALID_DATA;
+
+ length = (FT_UInt)( valid->limit - table );
+ }
+
if ( length < 16 )
FT_INVALID_TOO_SHORT;
@@ -1087,32 +1105,26 @@
FT_UInt32* pcharcode,
FT_Bool next )
{
- TT_Face face = (TT_Face)cmap->cmap.charmap.face;
+ TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
FT_Byte* limit = face->cmap_table + face->cmap_size;
FT_UInt num_segs2, start, end, offset;
FT_Int delta;
FT_UInt i, num_segs;
- FT_UInt32 charcode = *pcharcode;
+ FT_UInt32 charcode = *pcharcode + next;
FT_UInt gindex = 0;
FT_Byte* p;
FT_Byte* q;
p = cmap->data + 6;
- num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
-
- num_segs = num_segs2 >> 1;
+ num_segs = TT_PEEK_USHORT( p ) >> 1;
if ( !num_segs )
return 0;
- if ( next )
- charcode++;
-
- if ( charcode > 0xFFFFU )
- return 0;
+ num_segs2 = num_segs << 1;
/* linear search */
p = cmap->data + 14; /* ends table */
@@ -1222,37 +1234,30 @@
FT_UInt32* pcharcode,
FT_Bool next )
{
- TT_Face face = (TT_Face)cmap->cmap.charmap.face;
+ TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
FT_Byte* limit = face->cmap_table + face->cmap_size;
FT_UInt num_segs2, start, end, offset;
FT_Int delta;
FT_UInt max, min, mid, num_segs;
- FT_UInt charcode = (FT_UInt)*pcharcode;
+ FT_UInt charcode = (FT_UInt)*pcharcode + next;
FT_UInt gindex = 0;
FT_Byte* p;
p = cmap->data + 6;
- num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
+ num_segs = TT_PEEK_USHORT( p ) >> 1;
- if ( !num_segs2 )
+ if ( !num_segs )
return 0;
- num_segs = num_segs2 >> 1;
-
- /* make compiler happy */
- mid = num_segs;
- end = 0xFFFFU;
-
- if ( next )
- charcode++;
+ num_segs2 = num_segs << 1;
min = 0;
max = num_segs;
/* binary search */
- while ( min < max )
+ do
{
mid = ( min + max ) >> 1;
p = cmap->data + 14 + mid * 2;
@@ -1435,6 +1440,7 @@
break;
}
}
+ while ( min < max );
if ( next )
{
@@ -1444,12 +1450,8 @@
/* if `charcode' is not in any segment, then `mid' is */
/* the segment nearest to `charcode' */
- if ( charcode > end )
- {
- mid++;
- if ( mid == num_segs )
- return 0;
- }
+ if ( charcode > end && ++mid == num_segs )
+ return 0;
if ( tt_cmap4_set_range( cmap4, mid ) )
{
@@ -1464,7 +1466,6 @@
cmap4->cur_gindex = gindex;
else
{
- cmap4->cur_charcode = charcode;
tt_cmap4_next( cmap4 );
gindex = cmap4->cur_gindex;
}
@@ -1479,31 +1480,35 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap4_char_index( TT_CMap cmap,
+ tt_cmap4_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
+ TT_CMap ttcmap = (TT_CMap)cmap;
+
+
if ( char_code >= 0x10000UL )
return 0;
- if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
- return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
+ if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
+ return tt_cmap4_char_map_linear( ttcmap, &char_code, 0 );
else
- return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
+ return tt_cmap4_char_map_binary( ttcmap, &char_code, 0 );
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap4_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap4_char_next( FT_CMap cmap, /* TT_CMap */
FT_UInt32 *pchar_code )
{
+ TT_CMap ttcmap = (TT_CMap)cmap;
FT_UInt gindex;
if ( *pchar_code >= 0xFFFFU )
return 0;
- if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
- gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
+ if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
+ gindex = tt_cmap4_char_map_linear( ttcmap, pchar_code, 1 );
else
{
TT_CMap4 cmap4 = (TT_CMap4)cmap;
@@ -1518,7 +1523,7 @@
*pchar_code = cmap4->cur_charcode;
}
else
- gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
+ gindex = tt_cmap4_char_map_binary( ttcmap, pchar_code, 1 );
}
return gindex;
@@ -1526,10 +1531,11 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap4_get_info( TT_CMap cmap,
+ tt_cmap4_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 4;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 4;
cmap_info->format = 4;
@@ -1630,10 +1636,11 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap6_char_index( TT_CMap cmap,
+ tt_cmap6_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt result = 0;
FT_Byte* p = table + 6;
FT_UInt start = TT_NEXT_USHORT( p );
@@ -1651,11 +1658,12 @@
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap6_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap6_char_next( FT_CMap cmap, /* TT_CMap */
FT_UInt32 *pchar_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt32 result = 0;
FT_UInt32 char_code = *pchar_code + 1;
FT_UInt gindex = 0;
@@ -1696,10 +1704,11 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap6_get_info( TT_CMap cmap,
+ tt_cmap6_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 4;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 4;
cmap_info->format = 6;
@@ -1890,10 +1899,11 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap8_char_index( TT_CMap cmap,
+ tt_cmap8_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt result = 0;
FT_Byte* p = table + 8204;
FT_UInt32 num_groups = TT_NEXT_ULONG( p );
@@ -1922,15 +1932,16 @@
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap8_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap8_char_next( FT_CMap cmap, /* TT_CMap */
FT_UInt32 *pchar_code )
{
- FT_Face face = cmap->cmap.charmap.face;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Face face = FT_CMAP_FACE( cmap );
FT_UInt32 result = 0;
FT_UInt32 char_code;
FT_UInt gindex = 0;
- FT_Byte* table = cmap->data;
+ FT_Byte* table = ttcmap->data;
FT_Byte* p = table + 8204;
FT_UInt32 num_groups = TT_NEXT_ULONG( p );
FT_UInt32 start, end, start_id;
@@ -1990,10 +2001,11 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap8_get_info( TT_CMap cmap,
+ tt_cmap8_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 8;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 8;
cmap_info->format = 8;
@@ -2094,10 +2106,11 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap10_char_index( TT_CMap cmap,
+ tt_cmap10_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt result = 0;
FT_Byte* p = table + 12;
FT_UInt32 start = TT_NEXT_ULONG( p );
@@ -2120,11 +2133,12 @@
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap10_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap10_char_next( FT_CMap cmap, /* TT_CMap */
FT_UInt32 *pchar_code )
{
- FT_Byte* table = cmap->data;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* table = ttcmap->data;
FT_UInt32 char_code;
FT_UInt gindex = 0;
FT_Byte* p = table + 12;
@@ -2162,10 +2176,11 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap10_get_info( TT_CMap cmap,
+ tt_cmap10_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 8;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 8;
cmap_info->format = 10;
@@ -2243,15 +2258,19 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap12_init( TT_CMap12 cmap,
- FT_Byte* table )
+ tt_cmap12_init( FT_CMap cmap, /* TT_CMap12 */
+ void* table_ )
{
- cmap->cmap.data = table;
+ TT_CMap12 ttcmap = (TT_CMap12)cmap;
+ FT_Byte* table = (FT_Byte*)table_;
+
+
+ ttcmap->cmap.data = table;
- table += 12;
- cmap->num_groups = FT_PEEK_ULONG( table );
+ table += 12;
+ ttcmap->num_groups = FT_PEEK_ULONG( table );
- cmap->valid = 0;
+ ttcmap->valid = 0;
return FT_Err_Ok;
}
@@ -2321,23 +2340,21 @@
/* cmap->cur_group should be set up properly by caller */
/* */
static void
- tt_cmap12_next( TT_CMap12 cmap )
+ tt_cmap12_next( FT_CMap cmap ) /* TT_CMap12 */
{
- FT_Face face = cmap->cmap.cmap.charmap.face;
- FT_Byte* p;
- FT_ULong start, end, start_id, char_code;
- FT_ULong n;
- FT_UInt gindex;
-
+ TT_CMap12 ttcmap = (TT_CMap12)cmap;
+ FT_Face face = FT_CMAP_FACE( cmap );
+ FT_Byte* p;
+ FT_ULong start, end, start_id, char_code;
+ FT_ULong n;
+ FT_UInt gindex;
- if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
- goto Fail;
- char_code = cmap->cur_charcode + 1;
+ char_code = ttcmap->cur_charcode + 1;
- for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
+ for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
{
- p = cmap->cmap.data + 16 + 12 * n;
+ p = ttcmap->cmap.data + 16 + 12 * n;
start = TT_NEXT_ULONG( p );
end = TT_NEXT_ULONG( p );
start_id = TT_PEEK_ULONG( p );
@@ -2369,16 +2386,16 @@
if ( gindex >= (FT_UInt)face->num_glyphs )
continue;
- cmap->cur_charcode = char_code;
- cmap->cur_gindex = gindex;
- cmap->cur_group = n;
+ ttcmap->cur_charcode = char_code;
+ ttcmap->cur_gindex = gindex;
+ ttcmap->cur_group = n;
return;
}
}
Fail:
- cmap->valid = 0;
+ ttcmap->valid = 0;
}
@@ -2390,7 +2407,7 @@
FT_UInt gindex = 0;
FT_Byte* p = cmap->data + 12;
FT_UInt32 num_groups = TT_PEEK_ULONG( p );
- FT_UInt32 char_code = *pchar_code;
+ FT_UInt32 char_code = *pchar_code + next;
FT_UInt32 start, end, start_id;
FT_UInt32 max, min, mid;
@@ -2398,23 +2415,11 @@
if ( !num_groups )
return 0;
- /* make compiler happy */
- mid = num_groups;
- end = 0xFFFFFFFFUL;
-
- if ( next )
- {
- if ( char_code >= 0xFFFFFFFFUL )
- return 0;
-
- char_code++;
- }
-
min = 0;
max = num_groups;
/* binary search */
- while ( min < max )
+ do
{
mid = ( min + max ) >> 1;
p = cmap->data + 16 + 12 * mid;
@@ -2438,22 +2443,19 @@
break;
}
}
+ while ( min < max );
if ( next )
{
- FT_Face face = cmap->cmap.charmap.face;
+ FT_Face face = FT_CMAP_FACE( cmap );
TT_CMap12 cmap12 = (TT_CMap12)cmap;
/* if `char_code' is not in any group, then `mid' is */
/* the group nearest to `char_code' */
- if ( char_code > end )
- {
- mid++;
- if ( mid == num_groups )
- return 0;
- }
+ if ( char_code > end && ++mid == num_groups )
+ return 0;
cmap12->valid = 1;
cmap12->cur_charcode = char_code;
@@ -2464,7 +2466,7 @@
if ( !gindex )
{
- tt_cmap12_next( cmap12 );
+ tt_cmap12_next( FT_CMAP( cmap12 ) );
if ( cmap12->valid )
gindex = cmap12->cur_gindex;
@@ -2480,25 +2482,28 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap12_char_index( TT_CMap cmap,
+ tt_cmap12_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
- return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
+ return tt_cmap12_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap12_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap12_char_next( FT_CMap cmap, /* TT_CMap12 */
FT_UInt32 *pchar_code )
{
TT_CMap12 cmap12 = (TT_CMap12)cmap;
FT_UInt gindex;
+ if ( *pchar_code >= 0xFFFFFFFFUL )
+ return 0;
+
/* no need to search */
if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
{
- tt_cmap12_next( cmap12 );
+ tt_cmap12_next( FT_CMAP( cmap12 ) );
if ( cmap12->valid )
{
gindex = cmap12->cur_gindex;
@@ -2508,17 +2513,18 @@
gindex = 0;
}
else
- gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
+ gindex = tt_cmap12_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
return gindex;
}
FT_CALLBACK_DEF( FT_Error )
- tt_cmap12_get_info( TT_CMap cmap,
+ tt_cmap12_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 8;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 8;
cmap_info->format = 12;
@@ -2596,15 +2602,19 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap13_init( TT_CMap13 cmap,
- FT_Byte* table )
+ tt_cmap13_init( FT_CMap cmap, /* TT_CMap13 */
+ void* table_ )
{
- cmap->cmap.data = table;
+ TT_CMap13 ttcmap = (TT_CMap13)cmap;
+ FT_Byte* table = (FT_Byte*)table_;
- table += 12;
- cmap->num_groups = FT_PEEK_ULONG( table );
- cmap->valid = 0;
+ ttcmap->cmap.data = table;
+
+ table += 12;
+ ttcmap->num_groups = FT_PEEK_ULONG( table );
+
+ ttcmap->valid = 0;
return FT_Err_Ok;
}
@@ -2669,23 +2679,21 @@
/* cmap->cur_group should be set up properly by caller */
/* */
static void
- tt_cmap13_next( TT_CMap13 cmap )
+ tt_cmap13_next( FT_CMap cmap ) /* TT_CMap13 */
{
- FT_Face face = cmap->cmap.cmap.charmap.face;
- FT_Byte* p;
- FT_ULong start, end, glyph_id, char_code;
- FT_ULong n;
- FT_UInt gindex;
-
+ TT_CMap13 ttcmap = (TT_CMap13)cmap;
+ FT_Face face = FT_CMAP_FACE( cmap );
+ FT_Byte* p;
+ FT_ULong start, end, glyph_id, char_code;
+ FT_ULong n;
+ FT_UInt gindex;
- if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
- goto Fail;
- char_code = cmap->cur_charcode + 1;
+ char_code = ttcmap->cur_charcode + 1;
- for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
+ for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
{
- p = cmap->cmap.data + 16 + 12 * n;
+ p = ttcmap->cmap.data + 16 + 12 * n;
start = TT_NEXT_ULONG( p );
end = TT_NEXT_ULONG( p );
glyph_id = TT_PEEK_ULONG( p );
@@ -2699,17 +2707,16 @@
if ( gindex && gindex < (FT_UInt)face->num_glyphs )
{
- cmap->cur_charcode = char_code;
- cmap->cur_gindex = gindex;
- cmap->cur_group = n;
+ ttcmap->cur_charcode = char_code;
+ ttcmap->cur_gindex = gindex;
+ ttcmap->cur_group = n;
return;
}
}
}
- Fail:
- cmap->valid = 0;
+ ttcmap->valid = 0;
}
@@ -2721,7 +2728,7 @@
FT_UInt gindex = 0;
FT_Byte* p = cmap->data + 12;
FT_UInt32 num_groups = TT_PEEK_ULONG( p );
- FT_UInt32 char_code = *pchar_code;
+ FT_UInt32 char_code = *pchar_code + next;
FT_UInt32 start, end;
FT_UInt32 max, min, mid;
@@ -2729,23 +2736,11 @@
if ( !num_groups )
return 0;
- /* make compiler happy */
- mid = num_groups;
- end = 0xFFFFFFFFUL;
-
- if ( next )
- {
- if ( char_code >= 0xFFFFFFFFUL )
- return 0;
-
- char_code++;
- }
-
min = 0;
max = num_groups;
/* binary search */
- while ( min < max )
+ do
{
mid = ( min + max ) >> 1;
p = cmap->data + 16 + 12 * mid;
@@ -2764,6 +2759,7 @@
break;
}
}
+ while ( min < max );
if ( next )
{
@@ -2774,12 +2770,8 @@
/* if `char_code' is not in any group, then `mid' is */
/* the group nearest to `char_code' */
- if ( char_code > end )
- {
- mid++;
- if ( mid == num_groups )
- return 0;
- }
+ if ( char_code > end && ++mid == num_groups )
+ return 0;
cmap13->valid = 1;
cmap13->cur_charcode = char_code;
@@ -2790,7 +2782,7 @@
if ( !gindex )
{
- tt_cmap13_next( cmap13 );
+ tt_cmap13_next( FT_CMAP( cmap13 ) );
if ( cmap13->valid )
gindex = cmap13->cur_gindex;
@@ -2806,25 +2798,28 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap13_char_index( TT_CMap cmap,
+ tt_cmap13_char_index( FT_CMap cmap, /* TT_CMap */
FT_UInt32 char_code )
{
- return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
+ return tt_cmap13_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap13_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap13_char_next( FT_CMap cmap, /* TT_CMap13 */
FT_UInt32 *pchar_code )
{
TT_CMap13 cmap13 = (TT_CMap13)cmap;
FT_UInt gindex;
+ if ( *pchar_code >= 0xFFFFFFFFUL )
+ return 0;
+
/* no need to search */
if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
{
- tt_cmap13_next( cmap13 );
+ tt_cmap13_next( FT_CMAP( cmap13 ) );
if ( cmap13->valid )
{
gindex = cmap13->cur_gindex;
@@ -2834,17 +2829,18 @@
gindex = 0;
}
else
- gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
+ gindex = tt_cmap13_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
return gindex;
}
FT_CALLBACK_DEF( FT_Error )
- tt_cmap13_get_info( TT_CMap cmap,
+ tt_cmap13_get_info( FT_CharMap cmap, /* TT_CMap */
TT_CMapInfo *cmap_info )
{
- FT_Byte* p = cmap->data + 8;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = ttcmap->data + 8;
cmap_info->format = 13;
@@ -2959,14 +2955,15 @@
FT_CALLBACK_DEF( void )
- tt_cmap14_done( TT_CMap14 cmap )
+ tt_cmap14_done( FT_CMap cmap ) /* TT_CMap14 */
{
- FT_Memory memory = cmap->memory;
+ TT_CMap14 ttcmap = (TT_CMap14)cmap;
+ FT_Memory memory = ttcmap->memory;
- cmap->max_results = 0;
- if ( memory && cmap->results )
- FT_FREE( cmap->results );
+ ttcmap->max_results = 0;
+ if ( memory && ttcmap->results )
+ FT_FREE( ttcmap->results );
}
@@ -2994,15 +2991,19 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap14_init( TT_CMap14 cmap,
- FT_Byte* table )
+ tt_cmap14_init( FT_CMap cmap, /* TT_CMap14 */
+ void* table_ )
{
- cmap->cmap.data = table;
+ TT_CMap14 ttcmap = (TT_CMap14)cmap;
+ FT_Byte* table = (FT_Byte*)table_;
+
+
+ ttcmap->cmap.data = table;
- table += 6;
- cmap->num_selectors = FT_PEEK_ULONG( table );
- cmap->max_results = 0;
- cmap->results = NULL;
+ table += 6;
+ ttcmap->num_selectors = FT_PEEK_ULONG( table );
+ ttcmap->max_results = 0;
+ ttcmap->results = NULL;
return FT_Err_Ok;
}
@@ -3132,7 +3133,7 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap14_char_index( TT_CMap cmap,
+ tt_cmap14_char_index( FT_CMap cmap,
FT_UInt32 char_code )
{
FT_UNUSED( cmap );
@@ -3143,8 +3144,8 @@
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap14_char_next( TT_CMap cmap,
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap14_char_next( FT_CMap cmap,
FT_UInt32 *pchar_code )
{
FT_UNUSED( cmap );
@@ -3156,7 +3157,7 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap14_get_info( TT_CMap cmap,
+ tt_cmap14_get_info( FT_CharMap cmap,
TT_CMapInfo *cmap_info )
{
FT_UNUSED( cmap );
@@ -3270,12 +3271,16 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap14_char_var_index( TT_CMap cmap,
- TT_CMap ucmap,
+ tt_cmap14_char_var_index( FT_CMap cmap, /* TT_CMap */
+ FT_CMap ucmap, /* TT_CMap */
FT_UInt32 charcode,
FT_UInt32 variantSelector )
{
- FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ TT_CMap ttucmap = (TT_CMap)ucmap;
+
+ FT_Byte* p = tt_cmap14_find_variant( ttcmap->data + 6,
+ variantSelector );
FT_ULong defOff;
FT_ULong nondefOff;
@@ -3286,16 +3291,16 @@
defOff = TT_NEXT_ULONG( p );
nondefOff = TT_PEEK_ULONG( p );
- if ( defOff != 0 &&
- tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+ if ( defOff != 0 &&
+ tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
{
/* This is the default variant of this charcode. GID not stored */
/* here; stored in the normal Unicode charmap instead. */
- return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
+ return ttucmap->cmap.clazz->char_index( &ttucmap->cmap, charcode );
}
if ( nondefOff != 0 )
- return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
+ return tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
charcode );
return 0;
@@ -3303,11 +3308,13 @@
FT_CALLBACK_DEF( FT_Int )
- tt_cmap14_char_var_isdefault( TT_CMap cmap,
+ tt_cmap14_char_var_isdefault( FT_CMap cmap, /* TT_CMap */
FT_UInt32 charcode,
FT_UInt32 variantSelector )
{
- FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte* p = tt_cmap14_find_variant( ttcmap->data + 6,
+ variantSelector );
FT_ULong defOff;
FT_ULong nondefOff;
@@ -3318,13 +3325,13 @@
defOff = TT_NEXT_ULONG( p );
nondefOff = TT_NEXT_ULONG( p );
- if ( defOff != 0 &&
- tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+ if ( defOff != 0 &&
+ tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
return 1;
- if ( nondefOff != 0 &&
- tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
- charcode ) != 0 )
+ if ( nondefOff != 0 &&
+ tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
+ charcode ) != 0 )
return 0;
return -1;
@@ -3332,12 +3339,13 @@
FT_CALLBACK_DEF( FT_UInt32* )
- tt_cmap14_variants( TT_CMap cmap,
+ tt_cmap14_variants( FT_CMap cmap, /* TT_CMap14 */
FT_Memory memory )
{
+ TT_CMap ttcmap = (TT_CMap)cmap;
TT_CMap14 cmap14 = (TT_CMap14)cmap;
FT_UInt32 count = cmap14->num_selectors;
- FT_Byte* p = cmap->data + 10;
+ FT_Byte* p = ttcmap->data + 10;
FT_UInt32* result;
FT_UInt32 i;
@@ -3358,13 +3366,14 @@
FT_CALLBACK_DEF( FT_UInt32 * )
- tt_cmap14_char_variants( TT_CMap cmap,
+ tt_cmap14_char_variants( FT_CMap cmap, /* TT_CMap14 */
FT_Memory memory,
FT_UInt32 charCode )
{
- TT_CMap14 cmap14 = (TT_CMap14) cmap;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ TT_CMap14 cmap14 = (TT_CMap14)cmap;
FT_UInt32 count = cmap14->num_selectors;
- FT_Byte* p = cmap->data + 10;
+ FT_Byte* p = ttcmap->data + 10;
FT_UInt32* q;
@@ -3378,12 +3387,12 @@
FT_ULong nondefOff = TT_NEXT_ULONG( p );
- if ( ( defOff != 0 &&
- tt_cmap14_char_map_def_binary( cmap->data + defOff,
- charCode ) ) ||
- ( nondefOff != 0 &&
- tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
- charCode ) != 0 ) )
+ if ( ( defOff != 0 &&
+ tt_cmap14_char_map_def_binary( ttcmap->data + defOff,
+ charCode ) ) ||
+ ( nondefOff != 0 &&
+ tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
+ charCode ) != 0 ) )
{
q[0] = varSel;
q++;
@@ -3479,15 +3488,16 @@
FT_CALLBACK_DEF( FT_UInt32 * )
- tt_cmap14_variant_chars( TT_CMap cmap,
+ tt_cmap14_variant_chars( FT_CMap cmap, /* TT_CMap */
FT_Memory memory,
FT_UInt32 variantSelector )
{
- FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6,
- variantSelector );
- FT_Int i;
- FT_ULong defOff;
- FT_ULong nondefOff;
+ TT_CMap ttcmap = (TT_CMap)cmap;
+ FT_Byte *p = tt_cmap14_find_variant( ttcmap->data + 6,
+ variantSelector );
+ FT_Int i;
+ FT_ULong defOff;
+ FT_ULong nondefOff;
if ( !p )
@@ -3500,16 +3510,16 @@
return NULL;
if ( defOff == 0 )
- return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
+ return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
memory );
else if ( nondefOff == 0 )
- return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
+ return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
memory );
else
{
/* Both a default and a non-default glyph set? That's probably not */
/* good font design, but the spec allows for it... */
- TT_CMap14 cmap14 = (TT_CMap14) cmap;
+ TT_CMap14 cmap14 = (TT_CMap14)cmap;
FT_UInt32 numRanges;
FT_UInt32 numMappings;
FT_UInt32 duni;
@@ -3521,18 +3531,18 @@
FT_UInt32 *ret;
- p = cmap->data + nondefOff;
- dp = cmap->data + defOff;
+ p = ttcmap->data + nondefOff;
+ dp = ttcmap->data + defOff;
numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
dcnt = tt_cmap14_def_char_count( dp );
numRanges = (FT_UInt32)TT_NEXT_ULONG( dp );
if ( numMappings == 0 )
- return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
+ return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
memory );
if ( dcnt == 0 )
- return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
+ return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
memory );
if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
@@ -3654,9 +3664,10 @@
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
FT_CALLBACK_DEF( const char * )
- tt_get_glyph_name( TT_Face face,
+ tt_get_glyph_name( void* face_, /* TT_Face */
FT_UInt idx )
{
+ TT_Face face = (TT_Face)face_;
FT_String* PSname = NULL;
@@ -3667,12 +3678,13 @@
FT_CALLBACK_DEF( FT_Error )
- tt_cmap_unicode_init( PS_Unicodes unicodes,
- FT_Pointer pointer )
+ tt_cmap_unicode_init( FT_CMap cmap, /* PS_Unicodes */
+ FT_Pointer pointer )
{
- TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
- FT_Memory memory = FT_FACE_MEMORY( face );
- FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
+ PS_Unicodes unicodes = (PS_Unicodes)cmap;
+ TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
+ FT_Memory memory = FT_FACE_MEMORY( face );
+ FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
FT_UNUSED( pointer );
@@ -3683,17 +3695,18 @@
return psnames->unicodes_init( memory,
unicodes,
face->root.num_glyphs,
- (PS_GetGlyphNameFunc)&tt_get_glyph_name,
+ &tt_get_glyph_name,
(PS_FreeGlyphNameFunc)NULL,
(FT_Pointer)face );
}
FT_CALLBACK_DEF( void )
- tt_cmap_unicode_done( PS_Unicodes unicodes )
+ tt_cmap_unicode_done( FT_CMap cmap ) /* PS_Unicodes */
{
- FT_Face face = FT_CMAP_FACE( unicodes );
- FT_Memory memory = FT_FACE_MEMORY( face );
+ PS_Unicodes unicodes = (PS_Unicodes)cmap;
+ FT_Face face = FT_CMAP_FACE( cmap );
+ FT_Memory memory = FT_FACE_MEMORY( face );
FT_FREE( unicodes->maps );
@@ -3702,23 +3715,25 @@
FT_CALLBACK_DEF( FT_UInt )
- tt_cmap_unicode_char_index( PS_Unicodes unicodes,
- FT_UInt32 char_code )
+ tt_cmap_unicode_char_index( FT_CMap cmap, /* PS_Unicodes */
+ FT_UInt32 char_code )
{
- TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
- FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
+ PS_Unicodes unicodes = (PS_Unicodes)cmap;
+ TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
+ FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
return psnames->unicodes_char_index( unicodes, char_code );
}
- FT_CALLBACK_DEF( FT_UInt32 )
- tt_cmap_unicode_char_next( PS_Unicodes unicodes,
- FT_UInt32 *pchar_code )
+ FT_CALLBACK_DEF( FT_UInt )
+ tt_cmap_unicode_char_next( FT_CMap cmap, /* PS_Unicodes */
+ FT_UInt32 *pchar_code )
{
- TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
- FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
+ PS_Unicodes unicodes = (PS_Unicodes)cmap;
+ TT_Face face = (TT_Face)FT_CMAP_FACE( cmap );
+ FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
return psnames->unicodes_char_next( unicodes, pchar_code );
@@ -3869,13 +3884,14 @@
}
- FT_LOCAL( FT_Error )
+ FT_LOCAL_DEF( FT_Error )
tt_get_cmap_info( FT_CharMap charmap,
TT_CMapInfo *cmap_info )
{
- FT_CMap cmap = (FT_CMap)charmap;
+ FT_CMap cmap = FT_CMAP( charmap );
TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
+
if ( clazz->get_cmap_info )
return clazz->get_cmap_info( charmap, cmap_info );
else
diff --git a/src/3rdparty/freetype/src/sfnt/ttcmap.h b/src/3rdparty/freetype/src/sfnt/ttcmap.h
index c7d7c21d2c..ff52917ed5 100644
--- a/src/3rdparty/freetype/src/sfnt/ttcmap.h
+++ b/src/3rdparty/freetype/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
*
* TrueType character mapping table (cmap) support (specification).
*
- * Copyright (C) 2002-2020 by
+ * Copyright (C) 2002-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/ttcmapc.h b/src/3rdparty/freetype/src/sfnt/ttcmapc.h
index 2e4ce5075b..0af48c2478 100644
--- a/src/3rdparty/freetype/src/sfnt/ttcmapc.h
+++ b/src/3rdparty/freetype/src/sfnt/ttcmapc.h
@@ -4,7 +4,7 @@
*
* TT CMAP classes definitions (specification only).
*
- * Copyright (C) 2009-2020 by
+ * Copyright (C) 2009-2023 by
* Oran Agra and Mickey Gabel.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/ttcolr.c b/src/3rdparty/freetype/src/sfnt/ttcolr.c
index 9025e356ce..281e7135ee 100644
--- a/src/3rdparty/freetype/src/sfnt/ttcolr.c
+++ b/src/3rdparty/freetype/src/sfnt/ttcolr.c
@@ -4,8 +4,8 @@
*
* TrueType and OpenType colored glyph layer support (body).
*
- * Copyright (C) 2018-2020 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
+ * Copyright (C) 2018-2023 by
+ * David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
*
@@ -27,11 +27,16 @@
*/
+#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include <freetype/tttags.h>
#include <freetype/ftcolor.h>
+#include <freetype/config/integer-types.h>
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include <freetype/internal/services/svmm.h>
+#endif
#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
@@ -39,12 +44,52 @@
/* NOTE: These are the table sizes calculated through the specs. */
-#define BASE_GLYPH_SIZE 6U
-#define LAYER_SIZE 4U
-#define COLR_HEADER_SIZE 14U
-
-
- typedef struct BaseGlyphRecord_
+#define BASE_GLYPH_SIZE 6U
+#define BASE_GLYPH_PAINT_RECORD_SIZE 6U
+#define LAYER_V1_LIST_PAINT_OFFSET_SIZE 4U
+#define LAYER_V1_LIST_NUM_LAYERS_SIZE 4U
+#define COLOR_STOP_SIZE 6U
+#define VAR_IDX_BASE_SIZE 4U
+#define LAYER_SIZE 4U
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#colr-header */
+/* 3 * uint16 + 2 * Offset32 */
+#define COLRV0_HEADER_SIZE 14U
+/* COLRV0_HEADER_SIZE + 5 * Offset32 */
+#define COLRV1_HEADER_SIZE 34U
+
+
+#define ENSURE_READ_BYTES( byte_size ) \
+ if ( p < colr->paints_start_v1 || \
+ p > (FT_Byte*)colr->table + colr->table_size - byte_size ) \
+ return 0
+
+
+ typedef enum FT_PaintFormat_Internal_
+ {
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID = 3,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT = 5,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT = 7,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT = 9,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM = 13,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE = 15,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE = 17,
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER = 19,
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM = 21,
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER = 23,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE = 25,
+ FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER = 26,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER = 27,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW = 29,
+ FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER = 30,
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER = 31,
+
+ } FT_PaintFormat_Internal;
+
+
+ typedef struct BaseGlyphRecord_
{
FT_UShort gid;
FT_UShort first_layer_index;
@@ -53,7 +98,16 @@
} BaseGlyphRecord;
- typedef struct Colr_
+ typedef struct BaseGlyphV1Record_
+ {
+ FT_UShort gid;
+ /* Offset from start of BaseGlyphV1List, i.e., from base_glyphs_v1. */
+ FT_ULong paint_offset;
+
+ } BaseGlyphV1Record;
+
+
+ typedef struct Colr_
{
FT_UShort version;
FT_UShort num_base_glyphs;
@@ -62,7 +116,29 @@
FT_Byte* base_glyphs;
FT_Byte* layers;
- /* The memory which backs up the `COLR' table. */
+ FT_ULong num_base_glyphs_v1;
+ /* Points at beginning of BaseGlyphV1List. */
+ FT_Byte* base_glyphs_v1;
+
+ FT_ULong num_layers_v1;
+ FT_Byte* layers_v1;
+
+ FT_Byte* clip_list;
+
+ /*
+ * Paint tables start at the minimum of the end of the LayerList and the
+ * end of the BaseGlyphList. Record this location in a field here for
+ * safety checks when accessing paint tables.
+ */
+ FT_Byte* paints_start_v1;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ /* Item Variation Store for variable 'COLR' v1. */
+ GX_ItemVarStoreRec var_store;
+ GX_DeltaSetIdxMapRec delta_set_idx_map;
+#endif
+
+ /* The memory that backs up the `COLR' table. */
void* table;
FT_ULong table_size;
@@ -88,11 +164,18 @@
FT_Byte* table = NULL;
FT_Byte* p = NULL;
+ /* Needed for reading array lengths in referenced tables. */
+ FT_Byte* p1 = NULL;
Colr* colr = NULL;
FT_ULong base_glyph_offset, layer_offset;
+ FT_ULong base_glyphs_offset_v1, num_base_glyphs_v1;
+ FT_ULong layer_offset_v1, num_layers_v1, clip_list_offset;
FT_ULong table_size;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ FT_ULong colr_offset_in_stream;
+#endif
/* `COLR' always needs `CPAL' */
@@ -103,8 +186,12 @@
if ( error )
goto NoColr;
- if ( table_size < COLR_HEADER_SIZE )
- goto InvalidTable;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ colr_offset_in_stream = FT_STREAM_POS();
+#endif
+
+ if ( table_size < COLRV0_HEADER_SIZE )
+ goto NoColr;
if ( FT_FRAME_EXTRACT( table_size, table ) )
goto NoColr;
@@ -115,7 +202,7 @@
goto NoColr;
colr->version = FT_NEXT_USHORT( p );
- if ( colr->version != 0 )
+ if ( colr->version != 0 && colr->version != 1 )
goto InvalidTable;
colr->num_base_glyphs = FT_NEXT_USHORT( p );
@@ -135,6 +222,131 @@
if ( colr->num_layers * LAYER_SIZE > table_size - layer_offset )
goto InvalidTable;
+ if ( colr->version == 1 )
+ {
+ if ( table_size < COLRV1_HEADER_SIZE )
+ goto InvalidTable;
+
+ base_glyphs_offset_v1 = FT_NEXT_ULONG( p );
+
+ if ( base_glyphs_offset_v1 >= table_size - 4 )
+ goto InvalidTable;
+
+ p1 = (FT_Byte*)( table + base_glyphs_offset_v1 );
+ num_base_glyphs_v1 = FT_PEEK_ULONG( p1 );
+
+ if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE >
+ table_size - base_glyphs_offset_v1 )
+ goto InvalidTable;
+
+ colr->num_base_glyphs_v1 = num_base_glyphs_v1;
+ colr->base_glyphs_v1 = p1;
+
+ layer_offset_v1 = FT_NEXT_ULONG( p );
+
+ if ( layer_offset_v1 >= table_size )
+ goto InvalidTable;
+
+ if ( layer_offset_v1 )
+ {
+ if ( layer_offset_v1 >= table_size - 4 )
+ goto InvalidTable;
+
+ 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;
+
+ 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 );
+ }
+ 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;
+ }
+
+ clip_list_offset = FT_NEXT_ULONG( p );
+
+ if ( clip_list_offset >= table_size )
+ goto InvalidTable;
+
+ if ( clip_list_offset )
+ colr->clip_list = (FT_Byte*)( table + clip_list_offset );
+ else
+ colr->clip_list = 0;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ colr->var_store.dataCount = 0;
+ colr->var_store.varData = NULL;
+ colr->var_store.axisCount = 0;
+ colr->var_store.regionCount = 0;
+ colr->var_store.varRegionList = 0;
+
+ colr->delta_set_idx_map.mapCount = 0;
+ colr->delta_set_idx_map.outerIndex = NULL;
+ colr->delta_set_idx_map.innerIndex = NULL;
+
+ if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
+ {
+ FT_ULong var_idx_map_offset, var_store_offset;
+
+ FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
+
+
+ var_idx_map_offset = FT_NEXT_ULONG( p );
+
+ if ( var_idx_map_offset >= table_size )
+ goto InvalidTable;
+
+ var_store_offset = FT_NEXT_ULONG( p );
+ if ( var_store_offset >= table_size )
+ goto InvalidTable;
+
+ if ( var_store_offset )
+ {
+ /* If variation info has not been initialized yet, try doing so, */
+ /* otherwise loading the variation store will fail as it */
+ /* requires access to `blend` for checking the number of axes. */
+ if ( !face->blend )
+ if ( mm->get_mm_var( FT_FACE( face ), NULL ) )
+ goto InvalidTable;
+
+ /* Try loading `VarIdxMap` and `VarStore`. */
+ error = mm->load_item_var_store(
+ FT_FACE( face ),
+ colr_offset_in_stream + var_store_offset,
+ &colr->var_store );
+ if ( error != FT_Err_Ok )
+ goto InvalidTable;
+ }
+
+ if ( colr->var_store.axisCount && var_idx_map_offset )
+ {
+ error = mm->load_delta_set_idx_map(
+ FT_FACE( face ),
+ colr_offset_in_stream + var_idx_map_offset,
+ &colr->delta_set_idx_map,
+ &colr->var_store,
+ table_size );
+ if ( error != FT_Err_Ok )
+ goto InvalidTable;
+ }
+ }
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+ }
+
colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset );
colr->layers = (FT_Byte*)( table + layer_offset );
colr->table = table;
@@ -145,6 +357,18 @@
return FT_Err_Ok;
InvalidTable:
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ {
+ FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
+
+
+ mm->done_delta_set_idx_map( FT_FACE( face ),
+ &colr->delta_set_idx_map );
+ mm->done_item_var_store( FT_FACE( face ),
+ &colr->var_store );
+ }
+#endif
+
error = FT_THROW( Invalid_Table );
NoColr:
@@ -166,6 +390,17 @@
if ( colr )
{
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ {
+ FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
+
+
+ mm->done_delta_set_idx_map( FT_FACE( face ),
+ &colr->delta_set_idx_map );
+ mm->done_item_var_store( FT_FACE( face ),
+ &colr->var_store );
+ }
+#endif
FT_FRAME_RELEASE( colr->table );
FT_FREE( colr );
}
@@ -174,17 +409,17 @@
static FT_Bool
find_base_glyph_record( FT_Byte* base_glyph_begin,
- FT_Int num_base_glyph,
+ FT_UInt num_base_glyph,
FT_UInt glyph_id,
BaseGlyphRecord* record )
{
- FT_Int min = 0;
- FT_Int max = num_base_glyph - 1;
+ FT_UInt min = 0;
+ FT_UInt max = num_base_glyph;
- while ( min <= max )
+ while ( min < max )
{
- FT_Int mid = min + ( max - min ) / 2;
+ FT_UInt mid = min + ( max - min ) / 2;
FT_Byte* p = base_glyph_begin + mid * BASE_GLYPH_SIZE;
FT_UShort gid = FT_NEXT_USHORT( p );
@@ -193,7 +428,7 @@
if ( gid < glyph_id )
min = mid + 1;
else if (gid > glyph_id )
- max = mid - 1;
+ max = mid;
else
{
record->gid = gid;
@@ -248,7 +483,9 @@
iterator->p = colr->layers + offset;
}
- if ( iterator->layer >= iterator->num_layers )
+ if ( iterator->layer >= iterator->num_layers ||
+ iterator->p < colr->layers ||
+ iterator->p >= ( (FT_Byte*)colr->table + colr->table_size ) )
return 0;
*aglyph_index = FT_NEXT_USHORT( iterator->p );
@@ -265,6 +502,1240 @@
}
+ static FT_Bool
+ read_color_line( Colr* colr,
+ FT_Byte* color_line_p,
+ FT_ColorLine* colorline,
+ FT_Bool read_variable )
+ {
+ FT_Byte* p = color_line_p;
+ FT_PaintExtend paint_extend;
+
+
+ ENSURE_READ_BYTES( 3 );
+
+ paint_extend = (FT_PaintExtend)FT_NEXT_BYTE( p );
+ if ( paint_extend > FT_COLR_PAINT_EXTEND_REFLECT )
+ return 0;
+
+ colorline->extend = paint_extend;
+
+ colorline->color_stop_iterator.num_color_stops = FT_NEXT_USHORT( p );
+ colorline->color_stop_iterator.p = p;
+ colorline->color_stop_iterator.current_color_stop = 0;
+ colorline->color_stop_iterator.read_variable = read_variable;
+
+ return 1;
+ }
+
+
+ /*
+ * Read a paint offset for `FT_Paint*` objects that have them and check
+ * whether it is within reasonable limits within the font and the COLR
+ * table.
+ *
+ * Return 1 on success, 0 on failure.
+ */
+ static FT_Bool
+ get_child_table_pointer ( Colr* colr,
+ FT_Byte* paint_base,
+ FT_Byte** p,
+ FT_Byte** child_table_pointer )
+ {
+ FT_UInt32 paint_offset;
+ FT_Byte* child_table_p;
+
+
+ if ( !child_table_pointer )
+ return 0;
+
+ if ( *p < colr->paints_start_v1 ||
+ *p > (FT_Byte*)colr->table + colr->table_size - 1 - 3 )
+ return 0;
+
+ paint_offset = FT_NEXT_UOFF3( *p );
+ if ( !paint_offset )
+ return 0;
+
+ child_table_p = (FT_Byte*)( paint_base + paint_offset );
+
+ if ( child_table_p < colr->paints_start_v1 ||
+ child_table_p >= ( (FT_Byte*)colr->table + colr->table_size ) )
+ return 0;
+
+ *child_table_pointer = child_table_p;
+ return 1;
+ }
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+ static FT_Bool
+ get_deltas_for_var_index_base ( TT_Face face,
+ Colr* colr,
+ FT_ULong var_index_base,
+ FT_UInt num_deltas,
+ FT_ItemVarDelta* deltas )
+ {
+ FT_UInt outer_index = 0;
+ FT_UInt inner_index = 0;
+ FT_ULong loop_var_index = var_index_base;
+
+ FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
+
+ FT_UInt i = 0;
+
+
+ if ( var_index_base == 0xFFFFFFFF )
+ {
+ for ( i = 0; i < num_deltas; ++i )
+ deltas[i] = 0;
+ return 1;
+ }
+
+ for ( i = 0; i < num_deltas; ++i )
+ {
+ loop_var_index = var_index_base + i;
+
+ if ( colr->delta_set_idx_map.innerIndex )
+ {
+ if ( loop_var_index >= colr->delta_set_idx_map.mapCount )
+ loop_var_index = colr->delta_set_idx_map.mapCount - 1;
+
+ outer_index = colr->delta_set_idx_map.outerIndex[loop_var_index];
+ inner_index = colr->delta_set_idx_map.innerIndex[loop_var_index];
+ }
+ else
+ {
+ outer_index = 0;
+ inner_index = loop_var_index;
+ }
+
+ deltas[i] = mm->get_item_delta( FT_FACE( face ), &colr->var_store,
+ outer_index, inner_index );
+ }
+
+ return 1;
+ }
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+
+
+ static FT_Bool
+ read_paint( TT_Face face,
+ Colr* colr,
+ FT_Byte* p,
+ FT_COLR_Paint* apaint )
+ {
+ FT_Byte* paint_base = p;
+ FT_Byte* child_table_p = NULL;
+ FT_Bool do_read_var = FALSE;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ FT_ULong var_index_base = 0;
+ /* Longest varIndexBase offset is 5 in the spec. */
+ FT_ItemVarDelta item_deltas[6] = { 0, 0, 0, 0, 0, 0 };
+#else
+ FT_UNUSED( face );
+#endif
+
+
+ if ( !p || !colr || !colr->table )
+ return 0;
+
+ /* The last byte of the 'COLR' table is at 'size-1'; subtract 1 of */
+ /* that to account for the expected format byte we are going to read. */
+ if ( p < colr->paints_start_v1 ||
+ p > (FT_Byte*)colr->table + colr->table_size - 2 )
+ return 0;
+
+ apaint->format = (FT_PaintFormat)FT_NEXT_BYTE( p );
+
+ if ( apaint->format >= FT_COLR_PAINT_FORMAT_MAX )
+ return 0;
+
+ if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_LAYERS )
+ {
+ /* Initialize layer iterator/ */
+ FT_Byte num_layers;
+ FT_UInt32 first_layer_index;
+
+
+ num_layers = FT_NEXT_BYTE( p );
+ if ( num_layers > colr->num_layers_v1 )
+ return 0;
+
+ first_layer_index = FT_NEXT_ULONG( p );
+ if ( first_layer_index + num_layers > colr->num_layers_v1 )
+ return 0;
+
+ apaint->u.colr_layers.layer_iterator.num_layers = num_layers;
+ apaint->u.colr_layers.layer_iterator.layer = 0;
+ /* TODO: Check whether pointer is outside colr? */
+ apaint->u.colr_layers.layer_iterator.p =
+ colr->layers_v1 +
+ LAYER_V1_LIST_NUM_LAYERS_SIZE +
+ LAYER_V1_LIST_PAINT_OFFSET_SIZE * first_layer_index;
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID )
+ {
+ ENSURE_READ_BYTES( 4 );
+ apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p );
+ apaint->u.solid.color.alpha = FT_NEXT_SHORT( p );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG( p );
+
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.solid.color.alpha += (FT_F2Dot14)item_deltas[0];
+ }
+#endif
+
+ apaint->format = FT_COLR_PAINTFORMAT_SOLID;
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH )
+ {
+ ENSURE_READ_BYTES(2);
+ apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p );
+
+ return 1;
+ }
+
+ /*
+ * Grouped below here are all paint formats that have an offset to a
+ * child paint table as the first entry (for example, a color line or a
+ * child paint table). Retrieve that and determine whether that paint
+ * offset is valid first.
+ */
+
+ if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
+ return 0;
+
+ if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ||
+ ( do_read_var =
+ ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT ) ) )
+ {
+ if ( !read_color_line( colr,
+ child_table_p,
+ &apaint->u.linear_gradient.colorline,
+ do_read_var ) )
+ return 0;
+
+ /*
+ * In order to support variations expose these as FT_Fixed 16.16
+ * values so that we can support fractional values after
+ * interpolation.
+ */
+ ENSURE_READ_BYTES( 12 );
+ apaint->u.linear_gradient.p0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( do_read_var )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG ( p );
+
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.linear_gradient.p0.x += INT_TO_FIXED( item_deltas[0] );
+ apaint->u.linear_gradient.p0.y += INT_TO_FIXED( item_deltas[1] );
+ apaint->u.linear_gradient.p1.x += INT_TO_FIXED( item_deltas[2] );
+ apaint->u.linear_gradient.p1.y += INT_TO_FIXED( item_deltas[3] );
+ apaint->u.linear_gradient.p2.x += INT_TO_FIXED( item_deltas[4] );
+ apaint->u.linear_gradient.p2.y += INT_TO_FIXED( item_deltas[5] );
+ }
+#endif
+
+ apaint->format = FT_COLR_PAINTFORMAT_LINEAR_GRADIENT;
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ||
+ ( do_read_var =
+ ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT ) ) )
+ {
+ FT_Pos tmp;
+
+
+ if ( !read_color_line( colr,
+ child_table_p,
+ &apaint->u.radial_gradient.colorline,
+ do_read_var ) )
+ return 0;
+
+
+ /* In the OpenType specification, `r0` and `r1` are defined as */
+ /* `UFWORD`. Since FreeType doesn't have a corresponding 16.16 */
+ /* format we convert to `FWORD` and replace negative values with */
+ /* (32bit) `FT_INT_MAX`. */
+
+ ENSURE_READ_BYTES( 12 );
+
+ apaint->u.radial_gradient.c0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.radial_gradient.c0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+ tmp = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.radial_gradient.r0 = tmp < 0 ? FT_INT_MAX : tmp;
+
+ apaint->u.radial_gradient.c1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.radial_gradient.c1.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+ tmp = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.radial_gradient.r1 = tmp < 0 ? FT_INT_MAX : tmp;
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( do_read_var )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG ( p );
+
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.radial_gradient.c0.x += INT_TO_FIXED( item_deltas[0] );
+ apaint->u.radial_gradient.c0.y += INT_TO_FIXED( item_deltas[1] );
+
+ // TODO: Anything to be done about UFWORD deltas here?
+ apaint->u.radial_gradient.r0 += INT_TO_FIXED( item_deltas[2] );
+
+ apaint->u.radial_gradient.c1.x += INT_TO_FIXED( item_deltas[3] );
+ apaint->u.radial_gradient.c1.y += INT_TO_FIXED( item_deltas[4] );
+
+ apaint->u.radial_gradient.r1 += INT_TO_FIXED( item_deltas[5] );
+ }
+#endif
+
+ apaint->format = FT_COLR_PAINTFORMAT_RADIAL_GRADIENT;
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT ||
+ ( do_read_var =
+ ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT ) ) )
+ {
+ if ( !read_color_line( colr,
+ child_table_p,
+ &apaint->u.sweep_gradient.colorline,
+ do_read_var) )
+ return 0;
+
+ ENSURE_READ_BYTES( 8 );
+
+ apaint->u.sweep_gradient.center.x =
+ INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.sweep_gradient.center.y =
+ INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+ apaint->u.sweep_gradient.start_angle =
+ F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.sweep_gradient.end_angle =
+ F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( do_read_var )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG ( p );
+
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+ item_deltas ) )
+ return 0;
+
+ // TODO: Handle overflow?
+ apaint->u.sweep_gradient.center.x += INT_TO_FIXED( item_deltas[0] );
+ apaint->u.sweep_gradient.center.y += INT_TO_FIXED( item_deltas[1] );
+
+ apaint->u.sweep_gradient.start_angle +=
+ F2DOT14_TO_FIXED( item_deltas[2] );
+ apaint->u.sweep_gradient.end_angle +=
+ F2DOT14_TO_FIXED( item_deltas[3] );
+ }
+#endif
+ apaint->format = FT_COLR_PAINTFORMAT_SWEEP_GRADIENT;
+
+ return 1;
+ }
+
+ if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH )
+ {
+ ENSURE_READ_BYTES( 2 );
+ apaint->u.glyph.paint.p = child_table_p;
+ apaint->u.glyph.paint.insert_root_transform = 0;
+ apaint->u.glyph.glyphID = FT_NEXT_USHORT( p );
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM )
+ {
+ apaint->u.transform.paint.p = child_table_p;
+ apaint->u.transform.paint.insert_root_transform = 0;
+
+ if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
+ return 0;
+
+ p = child_table_p;
+
+ /*
+ * The following matrix coefficients are encoded as
+ * OpenType 16.16 fixed-point values.
+ */
+ ENSURE_READ_BYTES( 24 );
+ apaint->u.transform.affine.xx = FT_NEXT_LONG( p );
+ apaint->u.transform.affine.yx = FT_NEXT_LONG( p );
+ apaint->u.transform.affine.xy = FT_NEXT_LONG( p );
+ apaint->u.transform.affine.yy = FT_NEXT_LONG( p );
+ apaint->u.transform.affine.dx = FT_NEXT_LONG( p );
+ apaint->u.transform.affine.dy = FT_NEXT_LONG( p );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG( p );
+
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.transform.affine.xx += (FT_Fixed)item_deltas[0];
+ apaint->u.transform.affine.yx += (FT_Fixed)item_deltas[1];
+ apaint->u.transform.affine.xy += (FT_Fixed)item_deltas[2];
+ apaint->u.transform.affine.yy += (FT_Fixed)item_deltas[3];
+ apaint->u.transform.affine.dx += (FT_Fixed)item_deltas[4];
+ apaint->u.transform.affine.dy += (FT_Fixed)item_deltas[5];
+ }
+#endif
+
+ apaint->format = FT_COLR_PAINTFORMAT_TRANSFORM;
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE )
+ {
+ apaint->u.translate.paint.p = child_table_p;
+ apaint->u.translate.paint.insert_root_transform = 0;
+
+ ENSURE_READ_BYTES( 4 );
+ apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG( p );
+
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.translate.dx += INT_TO_FIXED( item_deltas[0] );
+ apaint->u.translate.dy += INT_TO_FIXED( item_deltas[1] );
+ }
+#endif
+
+ apaint->format = FT_COLR_PAINTFORMAT_TRANSLATE;
+
+ return 1;
+ }
+
+ else if ( apaint->format >= FT_COLR_PAINTFORMAT_SCALE &&
+ (FT_PaintFormat_Internal)apaint->format <=
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+ {
+ apaint->u.scale.paint.p = child_table_p;
+ apaint->u.scale.paint.insert_root_transform = 0;
+
+ /* All scale paints get at least one scale value. */
+ ENSURE_READ_BYTES( 2 );
+ apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+ /* Non-uniform ones read an extra y value. */
+ if ( apaint->format == FT_COLR_PAINTFORMAT_SCALE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
+ {
+ ENSURE_READ_BYTES( 2 );
+ apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+ }
+ else
+ apaint->u.scale.scale_y = apaint->u.scale.scale_x;
+
+ /* Scale paints that have a center read center coordinates, */
+ /* otherwise the center is (0,0). */
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+ {
+ ENSURE_READ_BYTES( 4 );
+ apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
+ apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
+ }
+ else
+ {
+ apaint->u.scale.center_x = 0;
+ apaint->u.scale.center_y = 0;
+ }
+
+ /* Base values set, now handle variations. */
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG( p );
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE )
+ {
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
+ apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[1] );
+ }
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
+ {
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
+ apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[1] );
+ apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[2] );
+ apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[3] );
+ }
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM )
+ {
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
+ apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[0] );
+ }
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
+ {
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 3,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
+ apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[0] );
+ apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[1] );
+ apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[2] );
+ }
+ }
+#endif
+
+ /* FT 'COLR' v1 API output format always returns fully defined */
+ /* structs; we thus set the format to the public API value. */
+ apaint->format = FT_COLR_PAINTFORMAT_SCALE;
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+ {
+ apaint->u.rotate.paint.p = child_table_p;
+ apaint->u.rotate.paint.insert_root_transform = 0;
+
+ ENSURE_READ_BYTES( 2 );
+ apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+ {
+ ENSURE_READ_BYTES( 4 );
+ apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ }
+ else
+ {
+ apaint->u.rotate.center_x = 0;
+ apaint->u.rotate.center_y = 0;
+ }
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+ {
+ FT_UInt num_deltas = 0;
+
+
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG( p );
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
+ num_deltas = 3;
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE )
+ num_deltas = 1;
+
+ if ( num_deltas > 0 )
+ {
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base,
+ num_deltas, item_deltas ) )
+ return 0;
+
+ apaint->u.rotate.angle += F2DOT14_TO_FIXED( item_deltas[0] );
+
+ if ( num_deltas == 3 )
+ {
+ apaint->u.rotate.center_x += INT_TO_FIXED( item_deltas[1] );
+ apaint->u.rotate.center_y += INT_TO_FIXED( item_deltas[2] );
+ }
+ }
+ }
+#endif
+
+ apaint->format = FT_COLR_PAINTFORMAT_ROTATE;
+
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+ {
+ apaint->u.skew.paint.p = child_table_p;
+ apaint->u.skew.paint.insert_root_transform = 0;
+
+ ENSURE_READ_BYTES( 4 );
+ apaint->u.skew.x_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+ {
+ ENSURE_READ_BYTES( 4 );
+ apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
+ }
+ else
+ {
+ apaint->u.skew.center_x = 0;
+ apaint->u.skew.center_y = 0;
+ }
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+ {
+ ENSURE_READ_BYTES( 4 );
+ var_index_base = FT_NEXT_ULONG( p );
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW )
+ {
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
+ apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
+ }
+
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
+ {
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+ item_deltas ) )
+ return 0;
+
+ apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
+ apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
+ apaint->u.skew.center_x += INT_TO_FIXED( item_deltas[2] );
+ apaint->u.skew.center_y += INT_TO_FIXED( item_deltas[3] );
+ }
+ }
+#endif
+
+ apaint->format = FT_COLR_PAINTFORMAT_SKEW;
+
+ return 1;
+ }
+
+ else if ( apaint->format == FT_COLR_PAINTFORMAT_COMPOSITE )
+ {
+ FT_UInt composite_mode;
+
+
+ apaint->u.composite.source_paint.p = child_table_p;
+ apaint->u.composite.source_paint.insert_root_transform = 0;
+
+ ENSURE_READ_BYTES( 1 );
+ composite_mode = FT_NEXT_BYTE( p );
+ if ( composite_mode >= FT_COLR_COMPOSITE_MAX )
+ return 0;
+
+ apaint->u.composite.composite_mode = (FT_Composite_Mode)composite_mode;
+
+ if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
+ return 0;
+
+ apaint->u.composite.backdrop_paint.p =
+ child_table_p;
+ apaint->u.composite.backdrop_paint.insert_root_transform =
+ 0;
+
+ return 1;
+ }
+
+ return 0;
+ }
+
+
+ static FT_Bool
+ find_base_glyph_v1_record( FT_Byte * base_glyph_begin,
+ FT_UInt num_base_glyph,
+ FT_UInt glyph_id,
+ BaseGlyphV1Record *record )
+ {
+ FT_UInt min = 0;
+ FT_UInt max = num_base_glyph;
+
+
+ while ( min < max )
+ {
+ FT_UInt mid = min + ( max - min ) / 2;
+
+ /*
+ * `base_glyph_begin` is the beginning of `BaseGlyphV1List`;
+ * skip `numBaseGlyphV1Records` by adding 4 to start binary search
+ * in the array of `BaseGlyphV1Record`.
+ */
+ FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE;
+
+ FT_UShort gid = FT_NEXT_USHORT( p );
+
+
+ if ( gid < glyph_id )
+ min = mid + 1;
+ else if (gid > glyph_id )
+ max = mid;
+ else
+ {
+ record->gid = gid;
+ record->paint_offset = FT_NEXT_ULONG ( p );
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ tt_face_get_colr_glyph_paint( TT_Face face,
+ FT_UInt base_glyph,
+ FT_Color_Root_Transform root_transform,
+ FT_OpaquePaint* opaque_paint )
+ {
+ Colr* colr = (Colr*)face->colr;
+ BaseGlyphV1Record base_glyph_v1_record;
+ FT_Byte* p;
+
+ if ( !colr || !colr->table )
+ return 0;
+
+ if ( colr->version < 1 || !colr->num_base_glyphs_v1 ||
+ !colr->base_glyphs_v1 )
+ return 0;
+
+ if ( opaque_paint->p )
+ return 0;
+
+ if ( !find_base_glyph_v1_record( colr->base_glyphs_v1,
+ colr->num_base_glyphs_v1,
+ base_glyph,
+ &base_glyph_v1_record ) )
+ return 0;
+
+ if ( !base_glyph_v1_record.paint_offset ||
+ base_glyph_v1_record.paint_offset > colr->table_size )
+ return 0;
+
+ p = (FT_Byte*)( colr->base_glyphs_v1 +
+ base_glyph_v1_record.paint_offset );
+ if ( p >= ( (FT_Byte*)colr->table + colr->table_size ) )
+ return 0;
+
+ opaque_paint->p = p;
+
+ if ( root_transform == FT_COLOR_INCLUDE_ROOT_TRANSFORM )
+ opaque_paint->insert_root_transform = 1;
+ else
+ opaque_paint->insert_root_transform = 0;
+
+ return 1;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ tt_face_get_color_glyph_clipbox( TT_Face face,
+ FT_UInt base_glyph,
+ FT_ClipBox* clip_box )
+ {
+ Colr* colr;
+
+ FT_Byte *p, *p1, *clip_base, *limit;
+
+ FT_Byte clip_list_format;
+ FT_ULong num_clip_boxes, i;
+ FT_UShort gid_start, gid_end;
+ FT_UInt32 clip_box_offset;
+ FT_Byte format;
+
+ const FT_Byte num_corners = 4;
+ FT_Vector corners[4];
+ FT_Byte j;
+ FT_BBox font_clip_box;
+
+
+ colr = (Colr*)face->colr;
+ if ( !colr )
+ return 0;
+
+ if ( !colr->clip_list )
+ return 0;
+
+ p = colr->clip_list;
+
+ /* Limit points to the first byte after the end of the color table. */
+ /* Thus, in subsequent limit checks below we need to check whether the */
+ /* read pointer is strictly greater than a position offset by certain */
+ /* field sizes to the left of that position. */
+ limit = (FT_Byte*)colr->table + colr->table_size;
+
+ /* Check whether we can extract one `uint8` and one `uint32`. */
+ if ( p > limit - ( 1 + 4 ) )
+ return 0;
+
+ clip_base = p;
+ clip_list_format = FT_NEXT_BYTE ( p );
+
+ /* Format byte used here to be able to upgrade ClipList for >16bit */
+ /* glyph ids; for now we can expect it to be 1. */
+ if ( !( clip_list_format == 1 ) )
+ return 0;
+
+ num_clip_boxes = FT_NEXT_ULONG( p );
+
+ /* Check whether we can extract two `uint16` and one `Offset24`, */
+ /* `num_clip_boxes` times. */
+ if ( colr->table_size / ( 2 + 2 + 3 ) < num_clip_boxes ||
+ p > limit - ( 2 + 2 + 3 ) * num_clip_boxes )
+ return 0;
+
+ for ( i = 0; i < num_clip_boxes; ++i )
+ {
+ gid_start = FT_NEXT_USHORT( p );
+ gid_end = FT_NEXT_USHORT( p );
+ clip_box_offset = FT_NEXT_UOFF3( p );
+
+ if ( base_glyph >= gid_start && base_glyph <= gid_end )
+ {
+ p1 = (FT_Byte*)( clip_base + clip_box_offset );
+
+ /* Check whether we can extract one `uint8`. */
+ if ( p1 > limit - 1 )
+ return 0;
+
+ format = FT_NEXT_BYTE( p1 );
+
+ if ( format > 2 )
+ return 0;
+
+ /* Check whether we can extract four `FWORD`. */
+ if ( p1 > limit - ( 2 + 2 + 2 + 2 ) )
+ return 0;
+
+ /* `face->root.size->metrics.x_scale` and `y_scale` are factors */
+ /* that scale a font unit value in integers to a 26.6 fixed value */
+ /* according to the requested size, see for example */
+ /* `ft_recompute_scaled_metrics`. */
+ font_clip_box.xMin = FT_MulFix( FT_NEXT_SHORT( p1 ),
+ face->root.size->metrics.x_scale );
+ font_clip_box.yMin = FT_MulFix( FT_NEXT_SHORT( p1 ),
+ face->root.size->metrics.y_scale );
+ font_clip_box.xMax = FT_MulFix( FT_NEXT_SHORT( p1 ),
+ face->root.size->metrics.x_scale );
+ font_clip_box.yMax = FT_MulFix( FT_NEXT_SHORT( p1 ),
+ face->root.size->metrics.y_scale );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ if ( format == 2 )
+ {
+ FT_ULong var_index_base = 0;
+ /* varIndexBase offset for clipbox is 3 at most. */
+ FT_ItemVarDelta item_deltas[4] = { 0, 0, 0, 0 };
+
+
+ /* Check whether we can extract a 32-bit varIndexBase now. */
+ if ( p1 > limit - 4 )
+ return 0;
+
+ var_index_base = FT_NEXT_ULONG( p1 );
+
+ if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
+ item_deltas ) )
+ return 0;
+
+ font_clip_box.xMin +=
+ FT_MulFix( item_deltas[0], face->root.size->metrics.x_scale );
+ font_clip_box.yMin +=
+ FT_MulFix( item_deltas[1], face->root.size->metrics.y_scale );
+ font_clip_box.xMax +=
+ FT_MulFix( item_deltas[2], face->root.size->metrics.x_scale );
+ font_clip_box.yMax +=
+ FT_MulFix( item_deltas[3], face->root.size->metrics.y_scale );
+ }
+#endif
+
+ /* Make 4 corner points (xMin, yMin), (xMax, yMax) and transform */
+ /* them. If we we would only transform two corner points and */
+ /* span a rectangle based on those, the rectangle may become too */
+ /* small to cover the glyph. */
+ corners[0].x = font_clip_box.xMin;
+ corners[1].x = font_clip_box.xMin;
+ corners[2].x = font_clip_box.xMax;
+ corners[3].x = font_clip_box.xMax;
+
+ corners[0].y = font_clip_box.yMin;
+ corners[1].y = font_clip_box.yMax;
+ corners[2].y = font_clip_box.yMax;
+ corners[3].y = font_clip_box.yMin;
+
+ for ( j = 0; j < num_corners; ++j )
+ {
+ if ( face->root.internal->transform_flags & 1 )
+ FT_Vector_Transform( &corners[j],
+ &face->root.internal->transform_matrix );
+
+ if ( face->root.internal->transform_flags & 2 )
+ {
+ corners[j].x += face->root.internal->transform_delta.x;
+ corners[j].y += face->root.internal->transform_delta.y;
+ }
+ }
+
+ clip_box->bottom_left = corners[0];
+ clip_box->top_left = corners[1];
+ clip_box->top_right = corners[2];
+ clip_box->bottom_right = corners[3];
+
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ tt_face_get_paint_layers( TT_Face face,
+ FT_LayerIterator* iterator,
+ FT_OpaquePaint* opaque_paint )
+ {
+ FT_Byte* p = NULL;
+ FT_Byte* p_first_layer = NULL;
+ FT_Byte* p_paint = NULL;
+ FT_UInt32 paint_offset;
+
+ Colr* colr;
+
+
+ if ( iterator->layer == iterator->num_layers )
+ return 0;
+
+ colr = (Colr*)face->colr;
+ if ( !colr )
+ return 0;
+
+ /*
+ * We have an iterator pointing at a paint offset as part of the
+ * `paintOffset` array in `LayerV1List`.
+ */
+ p = iterator->p;
+
+ /*
+ * Do a cursor sanity check of the iterator. Counting backwards from
+ * where it stands, we need to end up at a position after the beginning
+ * of the `LayerV1List` table and not after the end of the
+ * `LayerV1List`.
+ */
+ p_first_layer = p -
+ iterator->layer * LAYER_V1_LIST_PAINT_OFFSET_SIZE -
+ LAYER_V1_LIST_NUM_LAYERS_SIZE;
+ if ( p_first_layer < (FT_Byte*)colr->layers_v1 )
+ return 0;
+ if ( p_first_layer >= (FT_Byte*)(
+ colr->layers_v1 + LAYER_V1_LIST_NUM_LAYERS_SIZE +
+ colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ) )
+ return 0;
+
+ /*
+ * Before reading, ensure that `p` is within 'COLR' v1 and we can read a
+ * 4-byte ULONG.
+ */
+ if ( p < colr->layers_v1 ||
+ p > (FT_Byte*)colr->table + colr->table_size - 4 )
+ return 0;
+
+ paint_offset =
+ FT_NEXT_ULONG( p );
+ opaque_paint->insert_root_transform =
+ 0;
+
+ p_paint = (FT_Byte*)( colr->layers_v1 + paint_offset );
+
+ if ( p_paint < colr->paints_start_v1 ||
+ p_paint >= ( (FT_Byte*)colr->table + colr->table_size ) )
+ return 0;
+
+ opaque_paint->p = p_paint;
+
+ iterator->p = p;
+
+ iterator->layer++;
+
+ return 1;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ tt_face_get_colorline_stops( TT_Face face,
+ FT_ColorStop* color_stop,
+ FT_ColorStopIterator *iterator )
+ {
+ Colr* colr = (Colr*)face->colr;
+
+ FT_Byte* p;
+ FT_ULong var_index_base;
+ FT_Byte* last_entry_p = NULL;
+ FT_UInt entry_size = COLOR_STOP_SIZE;
+
+
+ if ( !colr || !colr->table || !iterator )
+ return 0;
+
+ if ( iterator->current_color_stop >= iterator->num_color_stops )
+ return 0;
+
+ if ( iterator->read_variable )
+ entry_size += VAR_IDX_BASE_SIZE;
+
+ /* Calculate the start pointer for the last to-be-read (Var)ColorStop */
+ /* and check whether we can read a full (Var)ColorStop at that */
+ /* position by comparing it to the position that is the size of one */
+ /* (Var)ColorStop before the end of the 'COLR' table. */
+ last_entry_p =
+ iterator->p + ( iterator->num_color_stops - 1 -
+ iterator->current_color_stop ) * entry_size;
+ if ( iterator->p < colr->paints_start_v1 ||
+ last_entry_p > (FT_Byte*)colr->table +
+ colr->table_size - entry_size )
+ return 0;
+
+ /* Iterator points at first `ColorStop` of `ColorLine`. */
+ p = iterator->p;
+
+ color_stop->stop_offset = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
+
+ color_stop->color.palette_index = FT_NEXT_USHORT( p );
+
+ color_stop->color.alpha = FT_NEXT_SHORT( p );
+
+ if ( iterator->read_variable )
+ {
+ /* Pointer p needs to be advanced independently of whether we intend */
+ /* to take variable deltas into account or not. Otherwise iteration */
+ /* would fail due to wrong offsets. */
+ var_index_base = FT_NEXT_ULONG( p );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ {
+ FT_Int item_deltas[2];
+
+
+ if ( !get_deltas_for_var_index_base( face, colr,
+ var_index_base,
+ 2,
+ item_deltas ) )
+ return 0;
+
+ color_stop->stop_offset += F2DOT14_TO_FIXED( item_deltas[0] );
+ color_stop->color.alpha += (FT_F2Dot14)item_deltas[1];
+ }
+#else
+ FT_UNUSED( var_index_base );
+#endif
+ }
+
+ iterator->p = p;
+ iterator->current_color_stop++;
+
+ return 1;
+ }
+
+
+ FT_LOCAL_DEF( FT_Bool )
+ tt_face_get_paint( TT_Face face,
+ FT_OpaquePaint opaque_paint,
+ FT_COLR_Paint* paint )
+ {
+ Colr* colr = (Colr*)face->colr;
+ FT_OpaquePaint next_paint;
+ FT_Matrix ft_root_scale;
+
+ if ( !colr || !colr->base_glyphs_v1 || !colr->table )
+ return 0;
+
+ if ( opaque_paint.insert_root_transform )
+ {
+ /* 'COLR' v1 glyph information is returned in unscaled coordinates,
+ * i.e., `FT_Size` is not applied or multiplied into the values. When
+ * client applications draw color glyphs, they can request to include
+ * a top-level transform, which includes the active `x_scale` and
+ * `y_scale` information for scaling the glyph, as well the additional
+ * transform and translate configured through `FT_Set_Transform`.
+ * This allows client applications to apply this top-level transform
+ * to the graphics context first and only once, then have gradient and
+ * contour scaling applied correctly when performing the additional
+ * drawing operations for subsequenct paints. Prepare this initial
+ * transform here.
+ */
+ paint->format = FT_COLR_PAINTFORMAT_TRANSFORM;
+
+ next_paint.p = opaque_paint.p;
+ next_paint.insert_root_transform = 0;
+ paint->u.transform.paint = next_paint;
+
+ /* `x_scale` and `y_scale` are in 26.6 format, representing the scale
+ * factor to get from font units to requested size. However, expected
+ * return values are in 16.16, so we shift accordingly with rounding.
+ */
+ ft_root_scale.xx = ( face->root.size->metrics.x_scale + 32 ) >> 6;
+ ft_root_scale.xy = 0;
+ ft_root_scale.yx = 0;
+ ft_root_scale.yy = ( face->root.size->metrics.y_scale + 32 ) >> 6;
+
+ if ( face->root.internal->transform_flags & 1 )
+ FT_Matrix_Multiply( &face->root.internal->transform_matrix,
+ &ft_root_scale );
+
+ paint->u.transform.affine.xx = ft_root_scale.xx;
+ paint->u.transform.affine.xy = ft_root_scale.xy;
+ paint->u.transform.affine.yx = ft_root_scale.yx;
+ paint->u.transform.affine.yy = ft_root_scale.yy;
+
+ /* The translation is specified in 26.6 format and, according to the
+ * documentation of `FT_Set_Translate`, is performed on the character
+ * size given in the last call to `FT_Set_Char_Size`. The
+ * 'PaintTransform' paint table's `FT_Affine23` format expects
+ * values in 16.16 format, thus we need to shift by 10 bits.
+ */
+ if ( face->root.internal->transform_flags & 2 )
+ {
+ paint->u.transform.affine.dx =
+ face->root.internal->transform_delta.x * ( 1 << 10 );
+ paint->u.transform.affine.dy =
+ face->root.internal->transform_delta.y * ( 1 << 10 );
+ }
+ else
+ {
+ paint->u.transform.affine.dx = 0;
+ paint->u.transform.affine.dy = 0;
+ }
+
+ return 1;
+ }
+
+ return read_paint( face, colr, opaque_paint.p, paint );
+ }
+
+
FT_LOCAL_DEF( FT_Error )
tt_face_colr_blend_layer( TT_Face face,
FT_UInt color_index,
@@ -443,7 +1914,7 @@
#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
/* ANSI C doesn't like empty source files */
- typedef int _tt_colr_dummy;
+ typedef int tt_colr_dummy_;
#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
diff --git a/src/3rdparty/freetype/src/sfnt/ttcolr.h b/src/3rdparty/freetype/src/sfnt/ttcolr.h
index 6412162669..20c85f0359 100644
--- a/src/3rdparty/freetype/src/sfnt/ttcolr.h
+++ b/src/3rdparty/freetype/src/sfnt/ttcolr.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType colored glyph layer support (specification).
*
- * Copyright (C) 2018-2020 by
+ * Copyright (C) 2018-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
@@ -42,6 +42,32 @@ FT_BEGIN_HEADER
FT_UInt *acolor_index,
FT_LayerIterator* iterator );
+ FT_LOCAL( FT_Bool )
+ tt_face_get_colr_glyph_paint( TT_Face face,
+ FT_UInt base_glyph,
+ FT_Color_Root_Transform root_transform,
+ FT_OpaquePaint* paint );
+
+ FT_LOCAL( FT_Bool )
+ tt_face_get_color_glyph_clipbox( TT_Face face,
+ FT_UInt base_glyph,
+ FT_ClipBox* clip_box );
+
+ FT_LOCAL( FT_Bool )
+ tt_face_get_paint_layers( TT_Face face,
+ FT_LayerIterator* iterator,
+ FT_OpaquePaint* paint );
+
+ FT_LOCAL( FT_Bool )
+ tt_face_get_colorline_stops( TT_Face face,
+ FT_ColorStop* color_stop,
+ FT_ColorStopIterator* iterator );
+
+ FT_LOCAL( FT_Bool )
+ tt_face_get_paint( TT_Face face,
+ FT_OpaquePaint opaque_paint,
+ FT_COLR_Paint* paint );
+
FT_LOCAL( FT_Error )
tt_face_colr_blend_layer( TT_Face face,
FT_UInt color_index,
diff --git a/src/3rdparty/freetype/src/sfnt/ttcpal.c b/src/3rdparty/freetype/src/sfnt/ttcpal.c
index 9c514bafe5..46ae08596f 100644
--- a/src/3rdparty/freetype/src/sfnt/ttcpal.c
+++ b/src/3rdparty/freetype/src/sfnt/ttcpal.c
@@ -4,7 +4,7 @@
*
* TrueType and OpenType color palette support (body).
*
- * Copyright (C) 2018-2020 by
+ * Copyright (C) 2018-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
@@ -303,7 +303,7 @@
#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
/* ANSI C doesn't like empty source files */
- typedef int _tt_cpal_dummy;
+ typedef int tt_cpal_dummy_;
#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
diff --git a/src/3rdparty/freetype/src/sfnt/ttcpal.h b/src/3rdparty/freetype/src/sfnt/ttcpal.h
index b544be696a..8e9913f0cc 100644
--- a/src/3rdparty/freetype/src/sfnt/ttcpal.h
+++ b/src/3rdparty/freetype/src/sfnt/ttcpal.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType color palette support (specification).
*
- * Copyright (C) 2018-2020 by
+ * Copyright (C) 2018-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
diff --git a/src/3rdparty/freetype/src/sfnt/ttkern.c b/src/3rdparty/freetype/src/sfnt/ttkern.c
index d4a70c7855..a47d08bd6d 100644
--- a/src/3rdparty/freetype/src/sfnt/ttkern.c
+++ b/src/3rdparty/freetype/src/sfnt/ttkern.c
@@ -5,7 +5,7 @@
* Load the basic TrueType kerning table. This doesn't handle
* kerning data within the GPOS table at the moment.
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -94,7 +94,7 @@
p_next = p;
- p += 2; /* skip version */
+ p += 2; /* skip version */
length = FT_NEXT_USHORT( p );
coverage = FT_NEXT_USHORT( p );
@@ -144,7 +144,7 @@
cur_pair = FT_NEXT_ULONG( p );
- if ( cur_pair <= old_pair )
+ if ( cur_pair < old_pair )
break;
p += 2;
@@ -187,11 +187,18 @@
FT_UInt left_glyph,
FT_UInt right_glyph )
{
- FT_Int result = 0;
- FT_UInt count, mask;
- FT_Byte* p = face->kern_table;
- FT_Byte* p_limit = p + face->kern_table_size;
+ FT_Int result = 0;
+ FT_UInt count, mask;
+ FT_Byte* p;
+ FT_Byte* p_limit;
+
+
+ if ( !face->kern_table )
+ return result;
+
+ p = face->kern_table;
+ p_limit = p + face->kern_table_size;
p += 4;
mask = 0x0001;
diff --git a/src/3rdparty/freetype/src/sfnt/ttkern.h b/src/3rdparty/freetype/src/sfnt/ttkern.h
index f44b5bdeb0..960c7da494 100644
--- a/src/3rdparty/freetype/src/sfnt/ttkern.h
+++ b/src/3rdparty/freetype/src/sfnt/ttkern.h
@@ -5,7 +5,7 @@
* Load the basic TrueType kerning table. This doesn't handle
* kerning data within the GPOS table at the moment.
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/ttload.c b/src/3rdparty/freetype/src/sfnt/ttload.c
index 4b46f41357..7b44e9cd2e 100644
--- a/src/3rdparty/freetype/src/sfnt/ttload.c
+++ b/src/3rdparty/freetype/src/sfnt/ttload.c
@@ -5,7 +5,7 @@
* Load the basic TrueType tables, i.e., tables that can be either in
* TTF or OTF fonts (body).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -205,9 +205,8 @@
if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
{
- nn--;
FT_TRACE2(( "check_table_dir:"
- " can read only %d table%s in font (instead of %d)\n",
+ " can read only %hu table%s in font (instead of %hu)\n",
nn, nn == 1 ? "" : "s", sfnt->num_tables ));
sfnt->num_tables = nn;
break;
@@ -217,7 +216,7 @@
if ( table.Offset > stream->size )
{
- FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
+ FT_TRACE2(( "check_table_dir: table entry %hu invalid\n", nn ));
continue;
}
else if ( table.Length > stream->size - table.Offset )
@@ -232,7 +231,7 @@
valid_entries++;
else
{
- FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
+ FT_TRACE2(( "check_table_dir: table entry %hu invalid\n", nn ));
continue;
}
}
@@ -381,7 +380,7 @@
/* load the table directory */
- FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables ));
+ FT_TRACE2(( "-- Number of tables: %10hu\n", sfnt.num_tables ));
FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag ));
if ( sfnt.format_tag != TTAG_OTTO )
@@ -416,9 +415,9 @@
FT_FRAME_ENTER( sfnt.num_tables * 16L ) )
goto Exit;
- FT_TRACE2(( "\n"
- " tag offset length checksum\n"
- " ----------------------------------\n" ));
+ FT_TRACE2(( "\n" ));
+ FT_TRACE2(( " tag offset length checksum\n" ));
+ FT_TRACE2(( " ----------------------------------\n" ));
valid_entries = 0;
for ( nn = 0; nn < sfnt.num_tables; nn++ )
@@ -505,7 +504,15 @@
FT_FRAME_EXIT();
- FT_TRACE2(( "table directory loaded\n\n" ));
+ if ( !valid_entries )
+ {
+ FT_TRACE2(( "tt_face_load_font_dir: no valid tables found\n" ));
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
+ }
+
+ FT_TRACE2(( "table directory loaded\n" ));
+ FT_TRACE2(( "\n" ));
Exit:
return error;
@@ -671,8 +678,8 @@
if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
goto Exit;
- FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
- FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format ));
+ FT_TRACE3(( "Units per EM: %4hu\n", header->Units_Per_EM ));
+ FT_TRACE3(( "IndexToLoc: %4hd\n", header->Index_To_Loc_Format ));
Exit:
return error;
@@ -794,15 +801,15 @@
if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
{
FT_TRACE0(( "tt_face_load_maxp:"
- " too much twilight points in `maxp' table;\n"
- " "
+ " too much twilight points in `maxp' table;\n" ));
+ FT_TRACE0(( " "
" some glyphs might be rendered incorrectly\n" ));
maxProfile->maxTwilightPoints = 0xFFFFU - 4;
}
}
- FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
+ FT_TRACE3(( "numGlyphs: %hu\n", maxProfile->numGlyphs ));
Exit:
return error;
@@ -836,6 +843,8 @@
FT_ULong table_pos, table_len;
FT_ULong storage_start, storage_limit;
TT_NameTable table;
+ TT_Name names = NULL;
+ TT_LangTag langTags = NULL;
static const FT_Frame_Field name_table_fields[] =
{
@@ -916,13 +925,13 @@
storage_start += 2 + 4 * table->numLangTagRecords;
/* allocate language tag records array */
- if ( FT_NEW_ARRAY( table->langTags, table->numLangTagRecords ) ||
- FT_FRAME_ENTER( table->numLangTagRecords * 4 ) )
+ if ( FT_QNEW_ARRAY( langTags, table->numLangTagRecords ) ||
+ FT_FRAME_ENTER( table->numLangTagRecords * 4 ) )
goto Exit;
/* load language tags */
{
- TT_LangTag entry = table->langTags;
+ TT_LangTag entry = langTags;
TT_LangTag limit = FT_OFFSET( entry, table->numLangTagRecords );
@@ -938,7 +947,13 @@
/* invalid entry; ignore it */
entry->stringLength = 0;
}
+
+ /* mark the string as not yet loaded */
+ entry->string = NULL;
}
+
+ table->langTags = langTags;
+ langTags = NULL;
}
FT_FRAME_EXIT();
@@ -947,14 +962,15 @@
}
/* allocate name records array */
- if ( FT_NEW_ARRAY( table->names, table->numNameRecords ) ||
- FT_FRAME_ENTER( table->numNameRecords * 12 ) )
+ if ( FT_QNEW_ARRAY( names, table->numNameRecords ) ||
+ FT_FRAME_ENTER( table->numNameRecords * 12 ) )
goto Exit;
/* load name records */
{
- TT_Name entry = table->names;
+ TT_Name entry = names;
FT_UInt count = table->numNameRecords;
+ FT_UInt valid = 0;
for ( ; count > 0; count-- )
@@ -987,15 +1003,20 @@
}
}
+ /* mark the string as not yet converted */
+ entry->string = NULL;
+
+ valid++;
entry++;
}
/* reduce array size to the actually used elements */
- count = (FT_UInt)( entry - table->names );
- (void)FT_RENEW_ARRAY( table->names,
- table->numNameRecords,
- count );
- table->numNameRecords = count;
+ FT_MEM_QRENEW_ARRAY( names,
+ table->numNameRecords,
+ valid );
+ table->names = names;
+ names = NULL;
+ table->numNameRecords = valid;
}
FT_FRAME_EXIT();
@@ -1004,6 +1025,8 @@
face->num_names = (FT_UShort)table->numNameRecords;
Exit:
+ FT_FREE( names );
+ FT_FREE( langTags );
return error;
}
@@ -1249,11 +1272,11 @@
}
}
- FT_TRACE3(( "sTypoAscender: %4d\n", os2->sTypoAscender ));
- FT_TRACE3(( "sTypoDescender: %4d\n", os2->sTypoDescender ));
- FT_TRACE3(( "usWinAscent: %4u\n", os2->usWinAscent ));
- FT_TRACE3(( "usWinDescent: %4u\n", os2->usWinDescent ));
- FT_TRACE3(( "fsSelection: 0x%2x\n", os2->fsSelection ));
+ FT_TRACE3(( "sTypoAscender: %4hd\n", os2->sTypoAscender ));
+ FT_TRACE3(( "sTypoDescender: %4hd\n", os2->sTypoDescender ));
+ FT_TRACE3(( "usWinAscent: %4hu\n", os2->usWinAscent ));
+ FT_TRACE3(( "usWinDescent: %4hu\n", os2->usWinDescent ));
+ FT_TRACE3(( "fsSelection: 0x%2hx\n", os2->fsSelection ));
Exit:
return error;
@@ -1311,6 +1334,12 @@
if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
return error;
+ if ( post->FormatType != 0x00030000L &&
+ post->FormatType != 0x00025000L &&
+ post->FormatType != 0x00020000L &&
+ post->FormatType != 0x00010000L )
+ return FT_THROW( Invalid_Post_Table_Format );
+
/* we don't load the glyph names, we do that in another */
/* module (ttpost). */
@@ -1410,8 +1439,8 @@
FT_Error error;
FT_Memory memory = stream->memory;
- FT_UInt j,num_ranges;
- TT_GaspRange gaspranges = NULL;
+ FT_UShort j, num_ranges;
+ TT_GaspRange gasp_ranges = NULL;
/* the gasp table is optional */
@@ -1422,8 +1451,8 @@
if ( FT_FRAME_ENTER( 4L ) )
goto Exit;
- face->gasp.version = FT_GET_USHORT();
- face->gasp.numRanges = FT_GET_USHORT();
+ face->gasp.version = FT_GET_USHORT();
+ num_ranges = FT_GET_USHORT();
FT_FRAME_EXIT();
@@ -1435,29 +1464,31 @@
goto Exit;
}
- num_ranges = face->gasp.numRanges;
- FT_TRACE3(( "numRanges: %u\n", num_ranges ));
+ FT_TRACE3(( "numRanges: %hu\n", num_ranges ));
- if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) ||
- FT_FRAME_ENTER( num_ranges * 4L ) )
+ if ( FT_QNEW_ARRAY( gasp_ranges, num_ranges ) ||
+ FT_FRAME_ENTER( num_ranges * 4L ) )
goto Exit;
- gaspranges = face->gasp.gaspRanges;
-
for ( j = 0; j < num_ranges; j++ )
{
- gaspranges[j].maxPPEM = FT_GET_USHORT();
- gaspranges[j].gaspFlag = FT_GET_USHORT();
+ gasp_ranges[j].maxPPEM = FT_GET_USHORT();
+ gasp_ranges[j].gaspFlag = FT_GET_USHORT();
- FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
+ FT_TRACE3(( "gaspRange %hu: rangeMaxPPEM %5hu, rangeGaspBehavior 0x%hx\n",
j,
- gaspranges[j].maxPPEM,
- gaspranges[j].gaspFlag ));
+ gasp_ranges[j].maxPPEM,
+ gasp_ranges[j].gaspFlag ));
}
+ face->gasp.gaspRanges = gasp_ranges;
+ gasp_ranges = NULL;
+ face->gasp.numRanges = num_ranges;
+
FT_FRAME_EXIT();
Exit:
+ FT_FREE( gasp_ranges );
return error;
}
diff --git a/src/3rdparty/freetype/src/sfnt/ttload.h b/src/3rdparty/freetype/src/sfnt/ttload.h
index 4e53d8b782..1499dd5735 100644
--- a/src/3rdparty/freetype/src/sfnt/ttload.h
+++ b/src/3rdparty/freetype/src/sfnt/ttload.h
@@ -5,7 +5,7 @@
* Load the basic TrueType tables, i.e., tables that can be either in
* TTF or OTF fonts (specification).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/ttmtx.c b/src/3rdparty/freetype/src/sfnt/ttmtx.c
index 021123336e..38ee9ae728 100644
--- a/src/3rdparty/freetype/src/sfnt/ttmtx.c
+++ b/src/3rdparty/freetype/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
*
* Load the metrics tables common to TTF and OTF fonts (body).
*
- * Copyright (C) 2006-2020 by
+ * Copyright (C) 2006-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -239,7 +239,7 @@
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
FT_Service_MetricsVariations var =
- (FT_Service_MetricsVariations)face->var;
+ (FT_Service_MetricsVariations)face->tt_var;
#endif
@@ -306,7 +306,7 @@
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- if ( var )
+ if ( var && face->blend )
{
FT_Face f = FT_FACE( face );
FT_Int a = (FT_Int)*aadvance;
diff --git a/src/3rdparty/freetype/src/sfnt/ttmtx.h b/src/3rdparty/freetype/src/sfnt/ttmtx.h
index dba65ca9ba..56d2b62766 100644
--- a/src/3rdparty/freetype/src/sfnt/ttmtx.h
+++ b/src/3rdparty/freetype/src/sfnt/ttmtx.h
@@ -4,7 +4,7 @@
*
* Load the metrics tables common to TTF and OTF fonts (specification).
*
- * Copyright (C) 2006-2020 by
+ * Copyright (C) 2006-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/ttpost.c b/src/3rdparty/freetype/src/sfnt/ttpost.c
index e93a4bf1b1..1dfad4298b 100644
--- a/src/3rdparty/freetype/src/sfnt/ttpost.c
+++ b/src/3rdparty/freetype/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
* PostScript name table processing for TrueType and OpenType fonts
* (body).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -58,7 +58,7 @@
#define MAC_NAME( x ) (FT_String*)psnames->macintosh_name( (FT_UInt)(x) )
-#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
+#else /* !FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
/* Otherwise, we ignore the `psnames' module, and provide our own */
@@ -152,155 +152,109 @@
};
-#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
+#endif /* !FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
static FT_Error
- load_format_20( TT_Face face,
- FT_Stream stream,
- FT_ULong post_limit )
+ load_format_20( TT_Post_Names names,
+ FT_Stream stream,
+ FT_UShort num_glyphs,
+ FT_ULong post_len )
{
FT_Memory memory = stream->memory;
FT_Error error;
- FT_Int num_glyphs;
- FT_UShort num_names;
+ FT_UShort n;
+ FT_UShort num_names = 0;
FT_UShort* glyph_indices = NULL;
- FT_Char** name_strings = NULL;
+ FT_Byte** name_strings = NULL;
+ FT_Byte* q;
- if ( FT_READ_USHORT( num_glyphs ) )
- goto Exit;
-
- /* UNDOCUMENTED! The number of glyphs in this table can be smaller */
- /* than the value in the maxp table (cf. cyberbit.ttf). */
-
- /* There already exist fonts which have more than 32768 glyph names */
- /* in this table, so the test for this threshold has been dropped. */
-
- if ( num_glyphs > face->max_profile.numGlyphs )
+ if ( (FT_ULong)num_glyphs * 2 > post_len )
{
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
- /* load the indices */
- {
- FT_Int n;
-
-
- if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) ||
- FT_FRAME_ENTER( num_glyphs * 2L ) )
- goto Fail;
-
- for ( n = 0; n < num_glyphs; n++ )
- glyph_indices[n] = FT_GET_USHORT();
+ /* load the indices and note their maximum */
+ if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
+ FT_FRAME_ENTER( num_glyphs * 2 ) )
+ goto Fail;
- FT_FRAME_EXIT();
- }
+ q = (FT_Byte*)stream->cursor;
- /* compute number of names stored in table */
+ for ( n = 0; n < num_glyphs; n++ )
{
- FT_Int n;
+ FT_UShort idx = FT_NEXT_USHORT( q );
- num_names = 0;
+ if ( idx > num_names )
+ num_names = idx;
- for ( n = 0; n < num_glyphs; n++ )
- {
- FT_Int idx;
+ glyph_indices[n] = idx;
+ }
+ FT_FRAME_EXIT();
- idx = glyph_indices[n];
- if ( idx >= 258 )
- {
- idx -= 257;
- if ( idx > num_names )
- num_names = (FT_UShort)idx;
- }
- }
- }
+ /* compute number of names stored in the table */
+ num_names = num_names > 257 ? num_names - 257 : 0;
/* now load the name strings */
+ if ( num_names )
{
- FT_UShort n;
+ FT_ULong p;
+ FT_Byte* strings;
- if ( FT_NEW_ARRAY( name_strings, num_names ) )
- goto Fail;
+ post_len -= (FT_ULong)num_glyphs * 2;
- for ( n = 0; n < num_names; n++ )
- {
- FT_UInt len;
+ if ( FT_QALLOC( name_strings, num_names * sizeof ( FT_Byte* ) +
+ post_len + 1 ) )
+ goto Fail;
+ strings = (FT_Byte*)( name_strings + num_names );
+ if ( FT_STREAM_READ( strings, post_len ) )
+ goto Fail;
- if ( FT_STREAM_POS() >= post_limit )
- break;
- else
- {
- FT_TRACE6(( "load_format_20: %ld byte left in post table\n",
- post_limit - FT_STREAM_POS() ));
+ /* convert from Pascal- to C-strings and set pointers */
+ for ( p = 0, n = 0; p < post_len && n < num_names; n++ )
+ {
+ FT_UInt len = strings[p];
- if ( FT_READ_BYTE( len ) )
- goto Fail1;
- }
- if ( len > post_limit ||
- FT_STREAM_POS() > post_limit - len )
+ if ( len > 63U )
{
- FT_Int d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS();
-
-
- FT_ERROR(( "load_format_20:"
- " exceeding string length (%d),"
- " truncating at end of post table (%d byte left)\n",
- len, d ));
- len = (FT_UInt)FT_MAX( 0, d );
+ error = FT_THROW( Invalid_File_Format );
+ goto Fail;
}
- if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) ||
- FT_STREAM_READ( name_strings[n], len ) )
- goto Fail1;
-
- name_strings[n][len] = '\0';
+ strings[p] = 0;
+ name_strings[n] = strings + p + 1;
+ p += len + 1;
}
+ strings[post_len] = 0;
+ /* deal with missing or insufficient string data */
if ( n < num_names )
{
- FT_ERROR(( "load_format_20:"
- " all entries in post table are already parsed,"
- " using NULL names for gid %d - %d\n",
- n, num_names - 1 ));
+ FT_TRACE4(( "load_format_20: %hu PostScript names are truncated\n",
+ num_names - n ));
+
for ( ; n < num_names; n++ )
- if ( FT_NEW_ARRAY( name_strings[n], 1 ) )
- goto Fail1;
- else
- name_strings[n][0] = '\0';
+ name_strings[n] = strings + post_len;
}
}
/* all right, set table fields and exit successfully */
- {
- TT_Post_20 table = &face->postscript_names.names.format_20;
+ names->num_glyphs = num_glyphs;
+ names->num_names = num_names;
+ names->glyph_indices = glyph_indices;
+ names->glyph_names = name_strings;
-
- table->num_glyphs = (FT_UShort)num_glyphs;
- table->num_names = (FT_UShort)num_names;
- table->glyph_indices = glyph_indices;
- table->glyph_names = name_strings;
- }
return FT_Err_Ok;
- Fail1:
- {
- FT_UShort n;
-
-
- for ( n = 0; n < num_names; n++ )
- FT_FREE( name_strings[n] );
- }
-
Fail:
FT_FREE( name_strings );
FT_FREE( glyph_indices );
@@ -311,66 +265,55 @@
static FT_Error
- load_format_25( TT_Face face,
- FT_Stream stream,
- FT_ULong post_limit )
+ load_format_25( TT_Post_Names names,
+ FT_Stream stream,
+ FT_UShort num_glyphs,
+ FT_ULong post_len )
{
FT_Memory memory = stream->memory;
FT_Error error;
- FT_Int num_glyphs;
- FT_Char* offset_table = NULL;
-
- FT_UNUSED( post_limit );
-
+ FT_UShort n;
+ FT_UShort* glyph_indices = NULL;
+ FT_Byte* q;
- if ( FT_READ_USHORT( num_glyphs ) )
- goto Exit;
- /* check the number of glyphs */
- if ( num_glyphs > face->max_profile.numGlyphs ||
- num_glyphs > 258 ||
- num_glyphs < 1 )
+ /* check the number of glyphs, including the theoretical limit */
+ if ( num_glyphs > post_len ||
+ num_glyphs > 258 + 128 )
{
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
- if ( FT_NEW_ARRAY( offset_table, num_glyphs ) ||
- FT_STREAM_READ( offset_table, num_glyphs ) )
+ /* load the indices and check their Mac range */
+ if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
+ FT_FRAME_ENTER( num_glyphs ) )
goto Fail;
- /* now check the offset table */
- {
- FT_Int n;
+ q = (FT_Byte*)stream->cursor;
+ for ( n = 0; n < num_glyphs; n++ )
+ {
+ FT_Int idx = n + FT_NEXT_CHAR( q );
- for ( n = 0; n < num_glyphs; n++ )
- {
- FT_Long idx = (FT_Long)n + offset_table[n];
+ if ( idx < 0 || idx > 257 )
+ idx = 0;
- if ( idx < 0 || idx > num_glyphs )
- {
- error = FT_THROW( Invalid_File_Format );
- goto Fail;
- }
- }
+ glyph_indices[n] = (FT_UShort)idx;
}
- /* OK, set table fields and exit successfully */
- {
- TT_Post_25 table = &face->postscript_names.names.format_25;
-
+ FT_FRAME_EXIT();
- table->num_glyphs = (FT_UShort)num_glyphs;
- table->offsets = offset_table;
- }
+ /* OK, set table fields and exit successfully */
+ names->num_glyphs = num_glyphs;
+ names->glyph_indices = glyph_indices;
return FT_Err_Ok;
Fail:
- FT_FREE( offset_table );
+ FT_FREE( glyph_indices );
Exit:
return error;
@@ -380,40 +323,37 @@
static FT_Error
load_post_names( TT_Face face )
{
- FT_Stream stream;
- FT_Error error;
- FT_Fixed format;
+ FT_Error error = FT_Err_Ok;
+ FT_Stream stream = face->root.stream;
+ FT_Fixed format = face->postscript.FormatType;
FT_ULong post_len;
- FT_ULong post_limit;
+ FT_UShort num_glyphs;
- /* get a stream for the face's resource */
- stream = face->root.stream;
-
/* seek to the beginning of the PS names table */
error = face->goto_table( face, TTAG_post, stream, &post_len );
if ( error )
goto Exit;
- post_limit = FT_STREAM_POS() + post_len;
-
- format = face->postscript.FormatType;
-
- /* go to beginning of subtable */
- if ( FT_STREAM_SKIP( 32 ) )
+ /* UNDOCUMENTED! The number of glyphs in this table can be smaller */
+ /* than the value in the maxp table (cf. cyberbit.ttf). */
+ if ( post_len < 34 ||
+ FT_STREAM_SKIP( 32 ) ||
+ FT_READ_USHORT( num_glyphs ) ||
+ num_glyphs > face->max_profile.numGlyphs ||
+ num_glyphs == 0 )
goto Exit;
- /* now read postscript table */
+ /* now read postscript names data */
if ( format == 0x00020000L )
- error = load_format_20( face, stream, post_limit );
+ error = load_format_20( &face->postscript_names, stream,
+ num_glyphs, post_len - 34 );
else if ( format == 0x00025000L )
- error = load_format_25( face, stream, post_limit );
- else
- error = FT_THROW( Invalid_File_Format );
-
- face->postscript_names.loaded = 1;
+ error = load_format_25( &face->postscript_names, stream,
+ num_glyphs, post_len - 34 );
Exit:
+ face->postscript_names.loaded = 1; /* even if failed */
return error;
}
@@ -423,37 +363,20 @@
{
FT_Memory memory = face->root.memory;
TT_Post_Names names = &face->postscript_names;
- FT_Fixed format;
- if ( names->loaded )
+ if ( names->num_glyphs )
{
- format = face->postscript.FormatType;
-
- if ( format == 0x00020000L )
- {
- TT_Post_20 table = &names->names.format_20;
- FT_UShort n;
-
-
- FT_FREE( table->glyph_indices );
- table->num_glyphs = 0;
-
- for ( n = 0; n < table->num_names; n++ )
- FT_FREE( table->glyph_names[n] );
-
- FT_FREE( table->glyph_names );
- table->num_names = 0;
- }
- else if ( format == 0x00025000L )
- {
- TT_Post_25 table = &names->names.format_25;
-
+ FT_FREE( names->glyph_indices );
+ names->num_glyphs = 0;
+ }
- FT_FREE( table->offsets );
- table->num_glyphs = 0;
- }
+ if ( names->num_names )
+ {
+ FT_FREE( names->glyph_names );
+ names->num_names = 0;
}
+
names->loaded = 0;
}
@@ -489,7 +412,6 @@
FT_String** PSname )
{
FT_Error error;
- TT_Post_Names names;
FT_Fixed format;
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
@@ -509,8 +431,6 @@
return FT_THROW( Unimplemented_Feature );
#endif
- names = &face->postscript_names;
-
/* `.notdef' by default */
*PSname = MAC_NAME( 0 );
@@ -521,9 +441,10 @@
if ( idx < 258 ) /* paranoid checking */
*PSname = MAC_NAME( idx );
}
- else if ( format == 0x00020000L )
+ else if ( format == 0x00020000L ||
+ format == 0x00025000L )
{
- TT_Post_20 table = &names->names.format_20;
+ TT_Post_Names names = &face->postscript_names;
if ( !names->loaded )
@@ -533,43 +454,29 @@
goto End;
}
- if ( idx < (FT_UInt)table->num_glyphs )
+ if ( idx < (FT_UInt)names->num_glyphs )
{
- FT_UShort name_index = table->glyph_indices[idx];
+ FT_UShort name_index = names->glyph_indices[idx];
if ( name_index < 258 )
*PSname = MAC_NAME( name_index );
- else
- *PSname = (FT_String*)table->glyph_names[name_index - 258];
+ else /* only for version 2.0 */
+ *PSname = (FT_String*)names->glyph_names[name_index - 258];
}
}
- else if ( format == 0x00025000L )
- {
- TT_Post_25 table = &names->names.format_25;
-
-
- if ( !names->loaded )
- {
- error = load_post_names( face );
- if ( error )
- goto End;
- }
-
- if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */
- *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] );
- }
/* nothing to do for format == 0x00030000L */
End:
+ /* post format errors ignored */
return FT_Err_Ok;
}
#else /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
/* ANSI C doesn't like empty source files */
- typedef int _tt_post_dummy;
+ typedef int tt_post_dummy_;
#endif /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
diff --git a/src/3rdparty/freetype/src/sfnt/ttpost.h b/src/3rdparty/freetype/src/sfnt/ttpost.h
index 94c7d16800..528f1c5f2f 100644
--- a/src/3rdparty/freetype/src/sfnt/ttpost.h
+++ b/src/3rdparty/freetype/src/sfnt/ttpost.h
@@ -5,7 +5,7 @@
* PostScript name table processing for TrueType and OpenType fonts
* (specification).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/ttsbit.c b/src/3rdparty/freetype/src/sfnt/ttsbit.c
index 9dd4419710..03f90a628d 100644
--- a/src/3rdparty/freetype/src/sfnt/ttsbit.c
+++ b/src/3rdparty/freetype/src/sfnt/ttsbit.c
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded bitmap support (body).
*
- * Copyright (C) 2005-2020 by
+ * Copyright (C) 2005-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Copyright 2013 by Google, Inc.
@@ -172,13 +172,8 @@
goto Exit;
}
- /* we currently don't support bit 1; however, it is better to */
- /* draw at least something... */
if ( flags == 3 )
- FT_TRACE1(( "tt_face_load_sbit_strikes:"
- " sbix overlay not supported yet\n"
- " "
- " expect bad rendering results\n" ));
+ face->root.face_flags |= FT_FACE_FLAG_SBIX_OVERLAY;
/*
* Count the number of strikes available in the table. We are a bit
@@ -240,8 +235,8 @@
if ( !face->ebdt_size )
{
FT_TRACE2(( "tt_face_load_sbit_strikes:"
- " no embedded bitmap data table found;\n"
- " "
+ " no embedded bitmap data table found;\n" ));
+ FT_TRACE2(( " "
" resetting number of strikes to zero\n" ));
face->sbit_num_strikes = 0;
}
@@ -345,8 +340,8 @@
if ( metrics->ascender == 0 )
{
FT_TRACE2(( "tt_face_load_strike_metrics:"
- " sanitizing invalid ascender and descender\n"
- " "
+ " sanitizing invalid ascender and descender\n" ));
+ FT_TRACE2(( " "
" values for strike %ld (%dppem, %dppem)\n",
strike_index,
metrics->x_ppem, metrics->y_ppem ));
@@ -374,8 +369,8 @@
if ( metrics->height == 0 )
{
FT_TRACE2(( "tt_face_load_strike_metrics:"
- " sanitizing invalid height value\n"
- " "
+ " sanitizing invalid height value\n" ));
+ FT_TRACE2(( " "
" for strike (%d, %d)\n",
metrics->x_ppem, metrics->y_ppem ));
metrics->height = metrics->y_ppem * 64;
@@ -390,11 +385,9 @@
/* set the scale values (in 16.16 units) so advances */
/* from the hmtx and vmtx table are scaled correctly */
- metrics->x_scale = FT_MulDiv( metrics->x_ppem,
- 64 * 0x10000,
+ metrics->x_scale = FT_DivFix( metrics->x_ppem * 64,
face->header.Units_Per_EM );
- metrics->y_scale = FT_MulDiv( metrics->y_ppem,
- 64 * 0x10000,
+ metrics->y_scale = FT_DivFix( metrics->y_ppem * 64,
face->header.Units_Per_EM );
return FT_Err_Ok;
@@ -404,9 +397,9 @@
{
FT_Stream stream = face->root.stream;
FT_UInt offset;
- FT_UShort upem, ppem, resolution;
+ FT_UShort ppem, resolution;
TT_HoriHeader *hori;
- FT_Pos ppem_; /* to reduce casts */
+ FT_Fixed scale;
FT_Error error;
FT_Byte* p;
@@ -429,32 +422,23 @@
FT_FRAME_EXIT();
- upem = face->header.Units_Per_EM;
- hori = &face->horizontal;
-
metrics->x_ppem = ppem;
metrics->y_ppem = ppem;
- ppem_ = (FT_Pos)ppem;
+ scale = FT_DivFix( ppem * 64, face->header.Units_Per_EM );
+ hori = &face->horizontal;
- metrics->ascender =
- FT_MulDiv( hori->Ascender, ppem_ * 64, upem );
- metrics->descender =
- FT_MulDiv( hori->Descender, ppem_ * 64, upem );
- metrics->height =
- FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap,
- ppem_ * 64, upem );
- metrics->max_advance =
- FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem );
+ metrics->ascender = FT_MulFix( hori->Ascender, scale );
+ metrics->descender = FT_MulFix( hori->Descender, scale );
+ metrics->height =
+ FT_MulFix( hori->Ascender - hori->Descender + hori->Line_Gap,
+ scale );
+ metrics->max_advance = FT_MulFix( hori->advance_Width_Max, scale );
/* set the scale values (in 16.16 units) so advances */
/* from the hmtx and vmtx table are scaled correctly */
- metrics->x_scale = FT_MulDiv( metrics->x_ppem,
- 64 * 0x10000,
- face->header.Units_Per_EM );
- metrics->y_scale = FT_MulDiv( metrics->y_ppem,
- 64 * 0x10000,
- face->header.Units_Per_EM );
+ metrics->x_scale = scale;
+ metrics->y_scale = scale;
return error;
}
@@ -726,6 +710,9 @@
pitch = bitmap->pitch;
line = bitmap->buffer;
+ if ( !line )
+ goto Exit;
+
width = decoder->metrics->width;
height = decoder->metrics->height;
@@ -1206,7 +1193,7 @@
goto Fail;
p += 1; /* skip padding */
- /* fall-through */
+ FALL_THROUGH;
case 9:
loader = tt_sbit_decoder_load_compound;
@@ -1573,23 +1560,40 @@
if ( !error )
{
- FT_Short abearing;
+ FT_Short abearing; /* not used here */
FT_UShort aadvance;
tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
metrics->horiBearingX = (FT_Short)originOffsetX;
- metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
+ metrics->vertBearingX = (FT_Short)originOffsetX;
+
+ metrics->horiBearingY = (FT_Short)( originOffsetY + metrics->height );
+ metrics->vertBearingY = (FT_Short)originOffsetY;
+
metrics->horiAdvance = (FT_UShort)( aadvance *
face->root.size->metrics.x_ppem /
face->header.Units_Per_EM );
+
+ if ( face->vertical_info )
+ tt_face_get_metrics( face, TRUE, glyph_index, &abearing, &aadvance );
+ else if ( face->os2.version != 0xFFFFU )
+ aadvance = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
+ face->os2.sTypoDescender );
+ else
+ aadvance = (FT_UShort)FT_ABS( face->horizontal.Ascender -
+ face->horizontal.Descender );
+
+ metrics->vertAdvance = (FT_UShort)( aadvance *
+ face->root.size->metrics.x_ppem /
+ face->header.Units_Per_EM );
}
return error;
}
- FT_LOCAL( FT_Error )
+ FT_LOCAL_DEF( FT_Error )
tt_face_load_sbit_image( TT_Face face,
FT_ULong strike_index,
FT_UInt glyph_index,
@@ -1673,7 +1677,7 @@
#else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
/* ANSI C doesn't like empty source files */
- typedef int _tt_sbit_dummy;
+ typedef int tt_sbit_dummy_;
#endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
diff --git a/src/3rdparty/freetype/src/sfnt/ttsbit.h b/src/3rdparty/freetype/src/sfnt/ttsbit.h
index b867e43a61..07e2db461a 100644
--- a/src/3rdparty/freetype/src/sfnt/ttsbit.h
+++ b/src/3rdparty/freetype/src/sfnt/ttsbit.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded bitmap support (specification).
*
- * Copyright (C) 1996-2020 by
+ * Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/src/3rdparty/freetype/src/sfnt/ttsvg.c b/src/3rdparty/freetype/src/sfnt/ttsvg.c
new file mode 100644
index 0000000000..4461d483b0
--- /dev/null
+++ b/src/3rdparty/freetype/src/sfnt/ttsvg.c
@@ -0,0 +1,413 @@
+/****************************************************************************
+ *
+ * ttsvg.c
+ *
+ * OpenType SVG Color (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * 'SVG' table specification:
+ *
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/svg
+ *
+ */
+
+#include <ft2build.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/tttags.h>
+#include <freetype/ftgzip.h>
+#include <freetype/otsvg.h>
+
+
+#ifdef FT_CONFIG_OPTION_SVG
+
+#include "ttsvg.h"
+
+
+ /* NOTE: These table sizes are given by the specification. */
+#define SVG_TABLE_HEADER_SIZE (10U)
+#define SVG_DOCUMENT_RECORD_SIZE (12U)
+#define SVG_DOCUMENT_LIST_MINIMUM_SIZE (2U + SVG_DOCUMENT_RECORD_SIZE)
+#define SVG_MINIMUM_SIZE (SVG_TABLE_HEADER_SIZE + \
+ SVG_DOCUMENT_LIST_MINIMUM_SIZE)
+
+
+ typedef struct Svg_
+ {
+ FT_UShort version; /* table version (starting at 0) */
+ FT_UShort num_entries; /* number of SVG document records */
+
+ FT_Byte* svg_doc_list; /* pointer to the start of SVG Document List */
+
+ void* table; /* memory that backs up SVG */
+ FT_ULong table_size;
+
+ } Svg;
+
+
+ /**************************************************************************
+ *
+ * The macro FT_COMPONENT is used in trace mode. It is an implicit
+ * parameter of the FT_TRACE() and FT_ERROR() macros, usued to print/log
+ * messages during execution.
+ */
+#undef FT_COMPONENT
+#define FT_COMPONENT ttsvg
+
+
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_load_svg( TT_Face face,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = face->root.memory;
+
+ FT_ULong table_size;
+ FT_Byte* table = NULL;
+ FT_Byte* p = NULL;
+ Svg* svg = NULL;
+ FT_ULong offsetToSVGDocumentList;
+
+
+ error = face->goto_table( face, TTAG_SVG, stream, &table_size );
+ if ( error )
+ goto NoSVG;
+
+ if ( table_size < SVG_MINIMUM_SIZE )
+ goto InvalidTable;
+
+ if ( FT_FRAME_EXTRACT( table_size, table ) )
+ goto NoSVG;
+
+ /* Allocate memory for the SVG object */
+ if ( FT_NEW( svg ) )
+ goto NoSVG;
+
+ p = table;
+ svg->version = FT_NEXT_USHORT( p );
+ offsetToSVGDocumentList = FT_NEXT_ULONG( p );
+
+ if ( offsetToSVGDocumentList < SVG_TABLE_HEADER_SIZE ||
+ offsetToSVGDocumentList > table_size -
+ SVG_DOCUMENT_LIST_MINIMUM_SIZE )
+ goto InvalidTable;
+
+ svg->svg_doc_list = (FT_Byte*)( table + offsetToSVGDocumentList );
+
+ p = svg->svg_doc_list;
+ svg->num_entries = FT_NEXT_USHORT( p );
+
+ FT_TRACE3(( "version: %d\n", svg->version ));
+ FT_TRACE3(( "number of entries: %d\n", svg->num_entries ));
+
+ if ( offsetToSVGDocumentList + 2U +
+ svg->num_entries * SVG_DOCUMENT_RECORD_SIZE > table_size )
+ goto InvalidTable;
+
+ svg->table = table;
+ svg->table_size = table_size;
+
+ face->svg = svg;
+ face->root.face_flags |= FT_FACE_FLAG_SVG;
+
+ return FT_Err_Ok;
+
+ InvalidTable:
+ error = FT_THROW( Invalid_Table );
+
+ NoSVG:
+ FT_FRAME_RELEASE( table );
+ FT_FREE( svg );
+ face->svg = NULL;
+
+ return error;
+ }
+
+
+ FT_LOCAL_DEF( void )
+ tt_face_free_svg( TT_Face face )
+ {
+ FT_Memory memory = face->root.memory;
+ FT_Stream stream = face->root.stream;
+
+ Svg* svg = (Svg*)face->svg;
+
+
+ if ( svg )
+ {
+ FT_FRAME_RELEASE( svg->table );
+ FT_FREE( svg );
+ }
+ }
+
+
+ typedef struct Svg_doc_
+ {
+ FT_UShort start_glyph_id;
+ FT_UShort end_glyph_id;
+
+ FT_ULong offset;
+ FT_ULong length;
+
+ } Svg_doc;
+
+
+ static Svg_doc
+ extract_svg_doc( FT_Byte* stream )
+ {
+ Svg_doc doc;
+
+
+ doc.start_glyph_id = FT_NEXT_USHORT( stream );
+ doc.end_glyph_id = FT_NEXT_USHORT( stream );
+
+ doc.offset = FT_NEXT_ULONG( stream );
+ doc.length = FT_NEXT_ULONG( stream );
+
+ return doc;
+ }
+
+
+ static FT_Int
+ compare_svg_doc( Svg_doc doc,
+ FT_UInt glyph_index )
+ {
+ if ( glyph_index < doc.start_glyph_id )
+ return -1;
+ else if ( glyph_index > doc.end_glyph_id )
+ return 1;
+ else
+ return 0;
+ }
+
+
+ static FT_Error
+ find_doc( FT_Byte* document_records,
+ FT_UShort num_entries,
+ FT_UInt glyph_index,
+ FT_ULong *doc_offset,
+ FT_ULong *doc_length,
+ FT_UShort *start_glyph,
+ FT_UShort *end_glyph )
+ {
+ FT_Error error;
+
+ Svg_doc start_doc;
+ Svg_doc mid_doc = { 0, 0, 0, 0 }; /* pacify compiler */
+ Svg_doc end_doc;
+
+ FT_Bool found = FALSE;
+ FT_UInt i = 0;
+
+ FT_UInt start_index = 0;
+ FT_UInt end_index = num_entries - 1;
+ FT_Int comp_res;
+
+
+ /* search algorithm */
+ if ( num_entries == 0 )
+ {
+ error = FT_THROW( Invalid_Table );
+ return error;
+ }
+
+ start_doc = extract_svg_doc( document_records + start_index * 12 );
+ end_doc = extract_svg_doc( document_records + end_index * 12 );
+
+ if ( ( compare_svg_doc( start_doc, glyph_index ) == -1 ) ||
+ ( compare_svg_doc( end_doc, glyph_index ) == 1 ) )
+ {
+ error = FT_THROW( Invalid_Glyph_Index );
+ return error;
+ }
+
+ while ( start_index <= end_index )
+ {
+ i = ( start_index + end_index ) / 2;
+ mid_doc = extract_svg_doc( document_records + i * 12 );
+ comp_res = compare_svg_doc( mid_doc, glyph_index );
+
+ if ( comp_res == 1 )
+ {
+ start_index = i + 1;
+ start_doc = extract_svg_doc( document_records + start_index * 4 );
+ }
+ else if ( comp_res == -1 )
+ {
+ end_index = i - 1;
+ end_doc = extract_svg_doc( document_records + end_index * 4 );
+ }
+ else
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ /* search algorithm end */
+
+ if ( found != TRUE )
+ {
+ FT_TRACE5(( "SVG glyph not found\n" ));
+ error = FT_THROW( Invalid_Glyph_Index );
+ }
+ else
+ {
+ *doc_offset = mid_doc.offset;
+ *doc_length = mid_doc.length;
+
+ *start_glyph = mid_doc.start_glyph_id;
+ *end_glyph = mid_doc.end_glyph_id;
+
+ error = FT_Err_Ok;
+ }
+
+ return error;
+ }
+
+
+ FT_LOCAL_DEF( FT_Error )
+ tt_face_load_svg_doc( FT_GlyphSlot glyph,
+ FT_UInt glyph_index )
+ {
+ FT_Error error = FT_Err_Ok;
+ TT_Face face = (TT_Face)glyph->face;
+ FT_Memory memory = face->root.memory;
+ Svg* svg = (Svg*)face->svg;
+
+ FT_Byte* doc_list;
+ FT_ULong doc_limit;
+
+ FT_Byte* doc;
+ FT_ULong doc_offset;
+ FT_ULong doc_length;
+ FT_UShort doc_start_glyph_id;
+ FT_UShort doc_end_glyph_id;
+
+ FT_SVG_Document svg_document = (FT_SVG_Document)glyph->other;
+
+
+ FT_ASSERT( !( svg == NULL ) );
+
+ doc_list = svg->svg_doc_list;
+
+ error = find_doc( doc_list + 2, svg->num_entries, glyph_index,
+ &doc_offset, &doc_length,
+ &doc_start_glyph_id, &doc_end_glyph_id );
+ if ( error != FT_Err_Ok )
+ goto Exit;
+
+ doc_limit = svg->table_size -
+ (FT_ULong)( doc_list - (FT_Byte*)svg->table );
+ if ( doc_offset > doc_limit ||
+ doc_length > doc_limit - doc_offset )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ doc = doc_list + doc_offset;
+
+ if ( doc_length > 6 &&
+ doc[0] == 0x1F &&
+ doc[1] == 0x8B &&
+ doc[2] == 0x08 )
+ {
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
+
+ FT_ULong uncomp_size;
+ FT_Byte* uncomp_buffer = NULL;
+
+
+ /*
+ * Get the size of the original document. This helps in allotting the
+ * buffer to accommodate the uncompressed version. The last 4 bytes
+ * of the compressed document are equal to the original size modulo
+ * 2^32. Since the size of SVG documents is less than 2^32 bytes we
+ * can use this accurately. The four bytes are stored in
+ * little-endian format.
+ */
+ FT_TRACE4(( "SVG document is GZIP compressed\n" ));
+ uncomp_size = (FT_ULong)doc[doc_length - 1] << 24 |
+ (FT_ULong)doc[doc_length - 2] << 16 |
+ (FT_ULong)doc[doc_length - 3] << 8 |
+ (FT_ULong)doc[doc_length - 4];
+
+ if ( FT_QALLOC( uncomp_buffer, uncomp_size ) )
+ goto Exit;
+
+ error = FT_Gzip_Uncompress( memory,
+ uncomp_buffer,
+ &uncomp_size,
+ doc,
+ doc_length );
+ if ( error )
+ {
+ FT_FREE( uncomp_buffer );
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ glyph->internal->flags |= FT_GLYPH_OWN_GZIP_SVG;
+
+ doc = uncomp_buffer;
+ doc_length = uncomp_size;
+
+#else /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+ error = FT_THROW( Unimplemented_Feature );
+ goto Exit;
+
+#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
+ }
+
+ svg_document->svg_document = doc;
+ svg_document->svg_document_length = doc_length;
+
+ svg_document->metrics = glyph->face->size->metrics;
+ svg_document->units_per_EM = glyph->face->units_per_EM;
+
+ svg_document->start_glyph_id = doc_start_glyph_id;
+ svg_document->end_glyph_id = doc_end_glyph_id;
+
+ svg_document->transform.xx = 0x10000;
+ svg_document->transform.xy = 0;
+ svg_document->transform.yx = 0;
+ svg_document->transform.yy = 0x10000;
+
+ svg_document->delta.x = 0;
+ svg_document->delta.y = 0;
+
+ FT_TRACE5(( "start_glyph_id: %d\n", doc_start_glyph_id ));
+ FT_TRACE5(( "end_glyph_id: %d\n", doc_end_glyph_id ));
+ FT_TRACE5(( "svg_document:\n" ));
+ FT_TRACE5(( " %.*s\n", (FT_UInt)doc_length, doc ));
+
+ glyph->other = svg_document;
+
+ Exit:
+ return error;
+ }
+
+#else /* !FT_CONFIG_OPTION_SVG */
+
+ /* ANSI C doesn't like empty source files */
+ typedef int tt_svg_dummy_;
+
+#endif /* !FT_CONFIG_OPTION_SVG */
+
+
+/* END */
diff --git a/src/3rdparty/freetype/src/sfnt/ttsvg.h b/src/3rdparty/freetype/src/sfnt/ttsvg.h
new file mode 100644
index 0000000000..3f32321ded
--- /dev/null
+++ b/src/3rdparty/freetype/src/sfnt/ttsvg.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ *
+ * ttsvg.h
+ *
+ * OpenType SVG Color (specification).
+ *
+ * Copyright (C) 2022-2023 by
+ * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+#ifndef TTSVG_H_
+#define TTSVG_H_
+
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/tttypes.h>
+
+
+FT_BEGIN_HEADER
+
+ FT_LOCAL( FT_Error )
+ tt_face_load_svg( TT_Face face,
+ FT_Stream stream );
+
+ FT_LOCAL( void )
+ tt_face_free_svg( TT_Face face );
+
+ FT_LOCAL( FT_Error )
+ tt_face_load_svg_doc( FT_GlyphSlot glyph,
+ FT_UInt glyph_index );
+
+FT_END_HEADER
+
+#endif /* TTSVG_H_ */
+
+
+/* END */
diff --git a/src/3rdparty/freetype/src/sfnt/woff2tags.c b/src/3rdparty/freetype/src/sfnt/woff2tags.c
index fd9f2e6c5d..eeedd9906b 100644
--- a/src/3rdparty/freetype/src/sfnt/woff2tags.c
+++ b/src/3rdparty/freetype/src/sfnt/woff2tags.c
@@ -4,7 +4,7 @@
*
* WOFF2 Font table tags (base).
*
- * Copyright (C) 2019-2020 by
+ * Copyright (C) 2019-2023 by
* Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -17,6 +17,9 @@
#include <freetype/tttags.h>
+
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
#include "woff2tags.h"
/*
@@ -28,10 +31,10 @@
*
* for details.
*/
- FT_LOCAL_DEF( FT_ULong )
+ FT_LOCAL_DEF( FT_Tag )
woff2_known_tags( FT_Byte index )
{
- const FT_ULong known_tags[63] =
+ static const FT_Tag known_tags[63] =
{
FT_MAKE_TAG('c', 'm', 'a', 'p'), /* 0 */
FT_MAKE_TAG('h', 'e', 'a', 'd'), /* 1 */
@@ -105,5 +108,12 @@
return known_tags[index];
}
+#else /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+ /* ANSI C doesn't like empty source files */
+ typedef int woff2tags_dummy_;
+
+#endif /* !FT_CONFIG_OPTION_USE_BROTLI */
+
/* END */
diff --git a/src/3rdparty/freetype/src/sfnt/woff2tags.h b/src/3rdparty/freetype/src/sfnt/woff2tags.h
index c437c77aa1..1201848e5e 100644
--- a/src/3rdparty/freetype/src/sfnt/woff2tags.h
+++ b/src/3rdparty/freetype/src/sfnt/woff2tags.h
@@ -2,9 +2,9 @@
*
* woff2tags.h
*
- * WOFFF2 Font table tags (specification).
+ * WOFF2 Font table tags (specification).
*
- * Copyright (C) 2019-2020 by
+ * Copyright (C) 2019-2023 by
* Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -26,10 +26,12 @@
FT_BEGIN_HEADER
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
- FT_LOCAL( FT_ULong )
+ FT_LOCAL( FT_Tag )
woff2_known_tags( FT_Byte index );
+#endif
FT_END_HEADER