Tue 05 Nov 2013 01:01:44 PM UTC, original submission:
Hello,
We've faced several problems with freetype compiled on Linux 64bit(Ubuntu 10.04).
1) FT_Load_Sfnt_Table works incorrectly for at least tables TT_Header and TT_HoriHeader. The reason is wrong offsets of struct members.
typedef struct TT_Header_
{
FT_Fixed Table_Version;
FT_Fixed Font_Revision;
FT_Long CheckSum_Adjust;
FT_Long Magic_Number;
FT_UShort Flags;
FT_UShort Units_Per_EM;
FT_Long Created [2];
FT_Long Modified[2];
...
It seems to be FT_Fixed and FT_Long types should be of size 4. But in fttypes.h they are defined as:
typedef signed long FT_Long;
typedef signed long FT_Fixed;
sizeof(long) for 64bit Linux is 8.
The most obvious way to fix it is to redefine FT_Fixed and FT_Long(and maybe FT_ULong just in case) like
typedef signed int FT_Long; // etc
Also there is a good idea about compile time checking offsets in tables.
c++0x has static_assert expr for this, but in earlier versions this can be easily done like this:
char some_unique_name[ ( <some constant expression> ) ? 1 : -1 ];
For example this check will preserve shifting offsets in struct on any platform:
extern int offsetin_TT_Header_[ ( offsetof(TT_Header,Glyph_Data_Format) == 52 ) ? 1 : -1 ];
and for HoriHeader:
extern int sizeof_TT_HoriHeader[ ( offsetof(TT_HoriHeader, number_Of_HMetrics) == 34 ) ? 1 : -1 ];
2) The same problem is for TT_OS2 table. Size of and offsets in this struct are critical. Here are some static_asserts to force offsets in TT_OS2 to be correct:
extern int offsetin_TT_OS2[ ( offsetof(TT_OS2, ulUnicodeRange1) == 42 ) ? 1 : -1 ];
extern int offsetin_TT_OS2_2[ ( offsetof(TT_OS2, fsSelection) == 62 ) ? 1 : -1 ];
extern int offsetin_TT_OS2_3[ ( offsetof(TT_OS2, usMaxContext) == 94 ) ? 1 : -1 ];
To fix sizeof(FT_Long) is not always enough, this struct should be packed to match requirements above. For gcc this may be fixed like this:
typedef struct _attribute_ ((_packed_)) TT_OS2_
{
...
Hope you'll fix this in the next version, thanks!
Eugene
|