[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.
This commit is contained in:
suzuki toshiya 2013-12-27 16:44:24 +09:00
parent 5f577462bd
commit e2d2b1544f
4 changed files with 52 additions and 5 deletions

View File

@ -1,3 +1,24 @@
2013-12-27 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
[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 <wl@gnu.org>
Fix Savannah bug #40997.

View File

@ -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. */
/* */
/* <Output> */
/* 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 );

View File

@ -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 )
{

View File

@ -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;