Discussion:
[ft-devel] af_face_globals_is_digit bug?
Tony Smith
2018-09-24 09:44:15 UTC
Permalink
Dear Freetype

We are long term users of Freetype, which we find is an excellent piece of software. We now have a need to use Freetype with Harfbuzz so we have decided to upgrade from FreeType 2.4.8 to 2.9.1. We are very sensitive to the metrics Freetype produces, so we have run tests to compare the differences between the two versions.

We noticed a few very small differences in the font metrics we were getting for digits. We found this was introduced between Freetype 2.6.0 and 2.6.1, when the following define was changed from:

#define AF_STYLE_MASK 0x7F
#define AF_DIGIT 0x80

To:

#define AF_STYLE_MASK 0x3FFF
#define AF_DIGIT 0x8000U
#define AF_NONBASE 0x4000U

This stopped the following function from working.

FT_LOCAL_DEF( FT_Bool )
af_face_globals_is_digit( AF_FaceGlobals globals,
FT_UInt gindex )
{
if ( gindex < (FT_ULong)globals->glyph_count )
return (FT_Bool)(globals->glyph_styles[gindex] & AF_DIGIT );

return (FT_Bool)0;
}

We believe the problem is that FT_Bool is defined to be an unsigned char (at least on a Linux platform). So we are getting

(unsigned char)( globals->glyph_styles[gindex] & 0x8000)

Even if the most significant bit is set in globals->glyph_styles[gindex] (as it will be for the Digits), it will evaluate to something like:

(unsigned char)( 0x8532 & 0x8000)

And then

(unsigned char)( 0x8000)

Which will return 0x00 - i.e. false - not as expected.

If we change our local copy of your code to the following and we are able to produce consistent results between releases 2.6.0 and 2.6.1:

FT_LOCAL_DEF( FT_Bool )
af_face_globals_is_digit( AF_FaceGlobals globals,
FT_UInt gindex )
{
if ( gindex < (FT_ULong)globals->glyph_count )
return (FT_Bool)(( globals->glyph_styles[gindex] & AF_DIGIT ) == AF_DIGIT);

return (FT_Bool)0;
}

Please note that this code change is applicable to the latest 2.9.1 release.

The main platform tested on was Linux Intel.

Kind regards, Tony Smith
--
This e-mail message has been scanned and cleared by Google Message Security
and the UNICOM Global security systems. This message is for the named
person's use only. If you receive this message in error, please delete it
and notify the sender.
Werner LEMBERG
2018-09-25 07:13:38 UTC
Permalink
Post by Tony Smith
We noticed a few very small differences in the font metrics we were
getting for digits. [...]
If we change our local copy of your code to the following and we are
FT_LOCAL_DEF( FT_Bool )
af_face_globals_is_digit( AF_FaceGlobals globals,
FT_UInt gindex )
{
if ( gindex < (FT_ULong)globals->glyph_count )
return (FT_Bool)(( globals->glyph_styles[gindex] & AF_DIGIT ) == AF_DIGIT);
return (FT_Bool)0;
}
Thanks a lot for the report. I've fixed this now. Please test!


Werner

Loading...