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;