ref: 70fd20e67ee79a198237f6a640d57424c2e00bc9
parent: 54c5ad5c9215feca69614565be7ec2030ee46cfb
author: Alexei Podtelezhnikov <apodtele@gmail.com>
date: Fri Feb 12 14:28:05 EST 2021
Decorate qsort callbacks with cdecl. * include/freetype/internal/compiler-macros.h (FT_COMPARE_DEF): Add new macro. * src/base/ftrfork.c, src/bdf/bdflib.c, src/gxvalid/gxvcommn.c, src/psaux/afmparse.c, src/psnames/psmodule.c, src/type1/t1afm.c, src/sfnt/sfwoff.c, src/sfnt/sfwoff2.c: Update qsort callbacks. Fixes #1026 when compiling FreeType with an unusual calling convention while the C library qsort still expects cdecl.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2021-02-12 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ Decorate qsort callbacks with cdecl.
+
+ * include/freetype/internal/compiler-macros.h (FT_COMPARE_DEF):
+ Add new macro.
+ * src/base/ftrfork.c, src/bdf/bdflib.c, src/gxvalid/gxvcommn.c,
+ src/psaux/afmparse.c, src/psnames/psmodule.c, src/type1/t1afm.c,
+ src/sfnt/sfwoff.c, src/sfnt/sfwoff2.c: Update qsort callbacks.
+
+ Fixes #1026 when compiling FreeType with an unusual calling convention
+ while the C library qsort still expects cdecl.
+
2021-02-10 Dominik Röttsches <drott@chromium.org>
[sfnt] Implement 'COLR' v1 sweep gradients.
--- a/include/freetype/internal/compiler-macros.h
+++ b/include/freetype/internal/compiler-macros.h
@@ -267,7 +267,8 @@
/* */
/* FT_CALLBACK_DEF is used to _define_ a callback function, */
/* located in the same source code file as the structure that uses */
- /* it. */
+ /* it. FT_COMPARE_DEF, in addition, ensures the cdecl calling */
+ /* convention on x86, required by the C library qsort. */
/* */
/* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare */
/* and define a callback function, respectively, in a similar way */
@@ -287,6 +288,14 @@
#define FT_CALLBACK_DEF( x ) extern "C" x
#else
#define FT_CALLBACK_DEF( x ) static x
+#endif
+
+#if defined( __i386__ )
+#define FT_COMPARE_DEF( x ) FT_CALLBACK_DEF( x ) __attribute__(( cdecl ))
+#elif defined( _M_IX86 )
+#define FT_COMPARE_DEF( x ) FT_CALLBACK_DEF( x ) __cdecl
+#else
+#define FT_COMPARE_DEF( x ) FT_CALLBACK_DEF( x )
#endif
#define FT_BASE_CALLBACK( x ) FT_FUNCTION_DECLARATION( x )
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -167,16 +167,11 @@
}
- static int
- ft_raccess_sort_ref_by_id( FT_RFork_Ref* a,
- FT_RFork_Ref* b )
+ FT_COMPARE_DEF( int )
+ ft_raccess_sort_ref_by_id( const void* a,
+ const void* b )
{
- if ( a->res_id < b->res_id )
- return -1;
- else if ( a->res_id > b->res_id )
- return 1;
- else
- return 0;
+ return ( (FT_RFork_Ref*)a )->res_id - ( (FT_RFork_Ref*)b )->res_id;
}
@@ -294,8 +289,7 @@
ft_qsort( ref,
(size_t)*count,
sizeof ( FT_RFork_Ref ),
- ( int(*)(const void*,
- const void*) )ft_raccess_sort_ref_by_id );
+ ft_raccess_sort_ref_by_id );
FT_TRACE3(( " -- sort resources by their ids --\n" ));
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -807,7 +807,7 @@
/* Routine to compare two glyphs by encoding so they can be sorted. */
- static int
+ FT_COMPARE_DEF( int )
by_encoding( const void* a,
const void* b )
{
--- a/src/gxvalid/gxvcommn.c
+++ b/src/gxvalid/gxvcommn.c
@@ -46,16 +46,11 @@
/*************************************************************************/
/*************************************************************************/
- static int
- gxv_compare_ushort_offset( FT_UShort* a,
- FT_UShort* b )
+ FT_COMPARE_DEF( int )
+ gxv_compare_ushort_offset( const void* a,
+ const void* b )
{
- if ( *a < *b )
- return -1;
- else if ( *a > *b )
- return 1;
- else
- return 0;
+ return *(FT_UShort*)a - *(FT_UShort*)b;
}
@@ -78,7 +73,7 @@
buff[nmemb] = limit;
ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ),
- ( int(*)(const void*, const void*) )gxv_compare_ushort_offset );
+ gxv_compare_ushort_offset );
if ( buff[nmemb] > limit )
FT_INVALID_OFFSET;
@@ -111,13 +106,17 @@
/*************************************************************************/
/*************************************************************************/
- static int
- gxv_compare_ulong_offset( FT_ULong* a,
- FT_ULong* b )
+ FT_COMPARE_DEF( int )
+ gxv_compare_ulong_offset( const void* a,
+ const void* b )
{
- if ( *a < *b )
+ FT_ULong a_ = *(FT_ULong*)a;
+ FT_ULong b_ = *(FT_ULong*)b;
+
+
+ if ( a_ < b_ )
return -1;
- else if ( *a > *b )
+ else if ( a_ > b_ )
return 1;
else
return 0;
@@ -143,7 +142,7 @@
buff[nmemb] = limit;
ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ),
- ( int(*)(const void*, const void*) )gxv_compare_ulong_offset );
+ gxv_compare_ulong_offset );
if ( buff[nmemb] > limit )
FT_INVALID_OFFSET;
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -667,7 +667,7 @@
/* compare two kerning pairs */
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
afm_compare_kern_pairs( const void* a,
const void* b )
{
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -179,7 +179,7 @@
/* ft_qsort callback to sort the unicode map */
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
compare_uni_maps( const void* a,
const void* b )
{
--- a/src/sfnt/sfwoff.c
+++ b/src/sfnt/sfwoff.c
@@ -66,7 +66,7 @@
}
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
compare_offsets( const void* a,
const void* b )
{
--- a/src/sfnt/sfwoff2.c
+++ b/src/sfnt/sfwoff2.c
@@ -101,7 +101,7 @@
}
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
compare_tags( const void* a,
const void* b )
{
--- a/src/type1/t1afm.c
+++ b/src/type1/t1afm.c
@@ -83,7 +83,7 @@
/* compare two kerning pairs */
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
compare_kern_pairs( const void* a,
const void* b )
{