From e2d2b1544f24413fa62e0c845184b429eb227e9d Mon Sep 17 00:00:00 2001 From: suzuki toshiya Date: Fri, 27 Dec 2013 16:44:24 +0900 Subject: [PATCH] [ftrfork] Fix the face order difference between POSIX and Carbon. The fragmented resources in Suitcase and .dfont should be reordered when post resource for Type1 is being restored, but reordering of sfnt resources induces the different face order. Now the ordering is restricted to post resource only, to prevent the different order issue (e.g. the face index in the fontconfig cache generated with Carbon framework is incompatible with that by FreeType2 without Carbon framework.) Found by Khaled Hosny and Hin-Tak Leung. http://lists.gnu.org/archive/html/freetype-devel/2013-02/msg00035.html http://lists.gnu.org/archive/html/freetype-devel/2013-12/msg00027.html * src/base/ftrfork.c (FT_Raccess_Get_DataOffsets): Add a switch `sort_by_res_id' to control the fragmented resource ordering. * include/internal/ftrfork.h: Daclare new switch. * src/base/ftobjs.c (IsMacResource): Enable the soring for post resource, and disable the sorting for sfnt resource. --- ChangeLog | 21 +++++++++++++++++++++ include/internal/ftrfork.h | 8 ++++++++ src/base/ftobjs.c | 7 +++++-- src/base/ftrfork.c | 21 ++++++++++++++++++--- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 028870112..6cbca83fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2013-12-27 suzuki toshiya + + [ftrfork] Fix the face order difference between POSIX and Carbon. + + The fragmented resources in Suitcase and .dfont should be reordered + when post resource for Type1 is being restored, but reordering of + sfnt resources induces the different face order. Now the ordering + is restricted to post resource only, to prevent the different order + issue (e.g. the face index in the fontconfig cache generated with + Carbon framework is incompatible with that by FreeType2 without + Carbon framework.) Found by Khaled Hosny and Hin-Tak Leung. + + http://lists.gnu.org/archive/html/freetype-devel/2013-02/msg00035.html + http://lists.gnu.org/archive/html/freetype-devel/2013-12/msg00027.html + + * src/base/ftrfork.c (FT_Raccess_Get_DataOffsets): Add a switch + `sort_by_res_id' to control the fragmented resource ordering. + * include/internal/ftrfork.h: Daclare new switch. + * src/base/ftobjs.c (IsMacResource): Enable the soring for post + resource, and disable the sorting for sfnt resource. + 2013-12-25 Werner Lemberg Fix Savannah bug #40997. diff --git a/include/internal/ftrfork.h b/include/internal/ftrfork.h index fbc32832b..a0e583b9c 100644 --- a/include/internal/ftrfork.h +++ b/include/internal/ftrfork.h @@ -224,6 +224,13 @@ FT_BEGIN_HEADER /* tag :: */ /* The resource tag. */ /* */ + /* sort_by_res_id :: */ + /* A Boolean to order the fragmented resource by their ids. */ + /* The fragmented resources for POST resource should be sorted */ + /* to restore Type1 font properly. For snft resource, sorting */ + /* may induce the different order of the faces in comparison with */ + /* that by QuickDraw API. */ + /* */ /* */ /* offsets :: */ /* The stream offsets for the resource data specified by `tag'. */ @@ -246,6 +253,7 @@ FT_BEGIN_HEADER FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, + FT_Bool sort_by_res_id, FT_Long **offsets, FT_Long *count ); diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index bd0c66e4a..bed0389ab 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -1801,9 +1801,10 @@ if ( error ) return error; + /* POST resources must be sorted to concatenate properly */ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - TTAG_POST, + TTAG_POST, TRUE, &data_offsets, &count ); if ( !error ) { @@ -1816,9 +1817,11 @@ return error; } + /* sfnt resources should not be sorted to preserve the face order by + QuickDraw API */ error = FT_Raccess_Get_DataOffsets( library, stream, map_offset, rdara_pos, - TTAG_sfnt, + TTAG_sfnt, FALSE, &data_offsets, &count ); if ( !error ) { diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c index 804911721..87ac6fbda 100644 --- a/src/base/ftrfork.c +++ b/src/base/ftrfork.c @@ -151,6 +151,7 @@ FT_Long map_offset, FT_Long rdata_pos, FT_Long tag, + FT_Bool sort_by_res_id, FT_Long **offsets, FT_Long *count ) { @@ -163,6 +164,7 @@ FT_RFork_Ref *ref = NULL; + FT_TRACE3(( "\n" )); error = FT_Stream_Seek( stream, map_offset ); if ( error ) return error; @@ -183,6 +185,8 @@ (char)( 0xff & ( tag_internal >> 16 ) ), (char)( 0xff & ( tag_internal >> 8 ) ), (char)( 0xff & ( tag_internal >> 0 ) ) )); + FT_TRACE3(( " : subcount=%d, suboffset=0x%04x\n", + subcnt, rpos )); if ( tag_internal == tag ) { @@ -208,11 +212,22 @@ goto Exit; ref[j].offset = temp & 0xFFFFFFL; + FT_TRACE3(( " [%d]: resouce_id=0x%04x, offset=0x%08x\n", + j, ref[j].res_id, ref[j].offset )); } - ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); + if (sort_by_res_id) + { + ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, const void*) ) + ft_raccess_sort_ref_by_id ); + + FT_TRACE3(( " -- sort resources by their ids --\n" )); + for ( j = 0; j < *count; ++ j ) { + FT_TRACE3(( " [%d]: resouce_id=0x%04x, offset=0x%08x\n", + j, ref[j].res_id, ref[j].offset )); + } + } if ( FT_NEW_ARRAY( offsets_internal, *count ) ) goto Exit;