ref: e2d2b1544f24413fa62e0c845184b429eb227e9d
parent: 5f577462bd7cc8e2ca6fe4a1efecee6d8a95e7be
author: suzuki toshiya <[email protected]>
date: Fri Dec 27 11:44:24 EST 2013
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2013-12-27 suzuki toshiya <[email protected]>
+
+ [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 <[email protected]>
Fix Savannah bug #40997.
--- a/include/internal/ftrfork.h
+++ b/include/internal/ftrfork.h
@@ -224,6 +224,13 @@
/* 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. */
+ /* */
/* <Output> */
/* offsets :: */
/* The stream offsets for the resource data specified by `tag'. */
@@ -246,6 +253,7 @@
FT_Long map_offset,
FT_Long rdata_pos,
FT_Long tag,
+ FT_Bool sort_by_res_id,
FT_Long **offsets,
FT_Long *count );
--- 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 )
{
--- 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;