Font: experimental LIME_FREETYPE_SWF_METRICS define that more closely matches SWF behavior for font metrics like ascent/descent

We're currently using freetype 2.9.1's algorithm for choosing font metrics, but it's not exactly the same as SWF (but it is closer than freetype 2.10's new algorithm).

This algorithm should more closely match the font metrics used by AS3 compilers when embedding fonts with [Embed] metadata in AS3.
This commit is contained in:
Josh Tynjala
2024-12-13 14:26:34 -08:00
parent 62ab8eb6fc
commit 0db3c7c095

View File

@@ -537,7 +537,40 @@ namespace lime {
wchar_t* family_name = GetFamilyName ();
#ifdef LIME_FREETYPE_LEGACY_METRICS
#ifdef LIME_FREETYPE_SWF_METRICS
// this should more closely match how [Embed] works in AS3 when
// embedding a font in a SWF
int calculatedAscender = 0;
int calculatedDescender = 0;
int calculatedHeight = 0;
TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_os2);
TT_HoriHeader* hhea = (TT_HoriHeader*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_hhea);
if (os2 && os2->version != 0xFFFFU) {
calculatedAscender = (FT_Short)os2->usWinAscent;
calculatedDescender = -(FT_Short)os2->usWinDescent;
calculatedHeight = calculatedAscender - calculatedDescender;
} else if (hhea) {
calculatedAscender = hhea->Ascender;
calculatedDescender = hhea->Descender;
calculatedHeight = calculatedAscender - calculatedDescender + hhea->Line_Gap;
} else {
// should never happen, but let's have a fallback to be safe
calculatedAscender = ((FT_Face)face)->ascender;
calculatedDescender = ((FT_Face)face)->descender;
calculatedHeight = ((FT_Face)face)->height;
}
#elif defined(LIME_FREETYPE_LEGACY_METRICS)
// this is FreeType's font metrics algorithm from 2.9.1
// it behaves more like SWF than the new algorithm
@@ -773,7 +806,28 @@ namespace lime {
int Font::GetAscender () {
#ifdef LIME_FREETYPE_LEGACY_METRICS
#ifdef LIME_FREETYPE_SWF_METRICS
// this should more closely match how [Embed] works in AS3 when
// embedding a font in a SWF
TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_os2);
TT_HoriHeader* hhea = (TT_HoriHeader*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_hhea);
if (os2 && os2->version != 0xFFFFU) {
return (FT_Short)os2->usWinAscent;
} else if (hhea) {
return hhea->Ascender;
}
// should never happen, but let's have a fallback to be safe
return ((FT_Face)face)->ascender;
#elif defined(LIME_FREETYPE_LEGACY_METRICS)
// this is FreeType's font metrics algorithm from 2.9.1
// it behaves more like SWF than the new algorithm
@@ -829,7 +883,29 @@ namespace lime {
int Font::GetDescender () {
#ifdef LIME_FREETYPE_LEGACY_METRICS
#ifdef LIME_FREETYPE_SWF_METRICS
// this should more closely match how [Embed] works in AS3 when
// embedding a font in a SWF
TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_os2);
TT_HoriHeader* hhea = (TT_HoriHeader*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_hhea);
if (os2 && os2->version != 0xFFFFU) {
return -(FT_Short)os2->usWinDescent;
}
else if (hhea) {
return hhea->Descender;
}
// should never happen, but let's have a fallback to be safe
return ((FT_Face)face)->descender;
#elif defined(LIME_FREETYPE_LEGACY_METRICS)
// this is FreeType's font metrics algorithm from 2.9.1
// it behaves more like SWF than the new algorithm
@@ -1061,7 +1137,32 @@ namespace lime {
int Font::GetHeight () {
#ifdef LIME_FREETYPE_LEGACY_METRICS
#ifdef LIME_FREETYPE_SWF_METRICS
// this should more closely match how [Embed] works in AS3 when
// embedding a font in a SWF
TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_os2);
TT_HoriHeader* hhea = (TT_HoriHeader*)FT_Get_Sfnt_Table(((FT_Face)face), ft_sfnt_hhea);
if (os2 && os2->version != 0xFFFFU) {
int calculatedAscender = (FT_Short)os2->usWinAscent;
int calculatedDescender = -(FT_Short)os2->usWinDescent;
return calculatedAscender - calculatedDescender;
} else if (hhea) {
int calculatedAscender = hhea->Ascender;
int calculatedDescender = hhea->Descender;
return calculatedAscender - calculatedDescender + hhea->Line_Gap;
}
// should never happen, but let's have a fallback to be safe
return ((FT_Face)face)->height;
#elif defined(LIME_FREETYPE_LEGACY_METRICS)
// this is FreeType's font metrics algorithm from 2.9.1
// it behaves more like SWF than the new algorithm