ref: 540b954574569bc56e4ea61eec67159e88ca4dff
parent: d156cabcaed41beeed2fb92cff2a72302b726435
author: Suzuki, Toshiya (鈴木俊哉) <[email protected]>
date: Fri Dec 21 01:03:59 EST 2007
Improvement of POSIX resource-fork accessor to load Mac OS X HelveLTMM
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2007-12-21 suzuki toshiya <[email protected]>
+
+ Improvement of POSIX resource-fork accessor to load unsorted
+ references in a resource. In HelveLTMM (resource-fork
+ PostScript Type1 font bundled to Mac OS X since 10.3.x),
+ the appearance order of PFB chunks is not sorted.
+ Sorting the chunks by reference IDs is required.
+
+ * include/freetype/internal/ftrfork.h (FT_RFork_Ref):
+ New structure type to store a pair of reference ID and offset
+ to the chunk.
+
+ * src/base/ftrfork.c (ft_raccess_sort_ref_by_id):
+ New function to sort FT_RFork_Ref by their reference ID.
+
+ (FT_Raccess_Get_DataOffsets): Returns an array of offsets
+ that is sorted by reference ID.
+
2007-12-14 Werner Lemberg <[email protected]>
* src/cff/cffparse.c (cff_parse_real): Don't apply `power_ten'
--- a/include/freetype/internal/ftrfork.h
+++ b/include/freetype/internal/ftrfork.h
@@ -36,6 +36,13 @@
/* Don't forget to increment the number if you add a new guessing rule. */
#define FT_RACCESS_N_RULES 9
+ /* Structure to describe a reference in resource, by its resource id */
+ /* and internal offset. `POST' resource expects to be concatenated by */
+ /* the order of resource id, instead of its appearance in the file. */
+ typedef struct FT_RFork_Ref_ {
+ FT_UShort res_id;
+ FT_ULong offset;
+ } FT_RFork_Ref;
/*************************************************************************/
/* */
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -132,6 +132,19 @@
}
+ static int
+ ft_raccess_sort_ref_by_id( FT_RFork_Ref* a,
+ FT_RFork_Ref* b )
+ {
+ if ( a->res_id < b->res_id )
+ return ( -1 );
+ else if ( a->res_id > b->res_id )
+ return ( 1 );
+ else
+ return ( 0 );
+ }
+
+
FT_BASE_DEF( FT_Error )
FT_Raccess_Get_DataOffsets( FT_Library library,
FT_Stream stream,
@@ -147,6 +160,7 @@
FT_Memory memory = library->memory;
FT_Long temp;
FT_Long *offsets_internal;
+ FT_RFork_Ref *ref;
error = FT_Stream_Seek( stream, map_offset );
@@ -179,28 +193,42 @@
if ( error )
return error;
- if ( FT_NEW_ARRAY( offsets_internal, *count ) )
+ if ( FT_NEW_ARRAY( ref, *count ) )
return error;
for ( j = 0; j < *count; ++j )
{
- (void)FT_STREAM_SKIP( 2 ); /* resource id */
- (void)FT_STREAM_SKIP( 2 ); /* rsource name */
-
+ if ( FT_READ_USHORT( ref[j].res_id ) )
+ goto Exit;
+ if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
+ goto Exit;
if ( FT_READ_LONG( temp ) )
- {
- FT_FREE( offsets_internal );
- return error;
- }
+ goto Exit;
+ if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
+ goto Exit;
- offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL );
-
- (void)FT_STREAM_SKIP( 4 ); /* mbz */
+ ref[j].offset = temp & 0xFFFFFFL;
}
- *offsets = offsets_internal;
+ ft_qsort( ref, *count, sizeof( FT_RFork_Ref ),
+ ( int(*)(const void*, const void*) )
+ ft_raccess_sort_ref_by_id );
- return FT_Err_Ok;
+ if ( FT_NEW_ARRAY( offsets_internal, *count ) )
+ goto Exit;
+
+ /* XXX: duplicated reference ID,
+ * gap between reference IDs are acceptable?
+ * further investigation on Apple implementation is needed.
+ */
+ for ( j = 0; j < *count; ++j )
+ offsets_internal[j] = rdata_pos + ref[j].offset;
+
+ *offsets = offsets_internal;
+ error = FT_Err_Ok;
+Exit:
+ FT_FREE( ref );
+ return error;
}
}