summaryrefslogtreecommitdiff
path: root/vcl/unx/generic
diff options
context:
space:
mode:
authorEike Rathke <erack@erack.de>2011-09-09 18:19:43 +0200
committerEike Rathke <erack@erack.de>2011-09-09 18:28:20 +0200
commit052f181dad89ad34d90513bc9dcd3e3239727933 (patch)
tree1157c86ef42326e155da194abbd996bb7fa41fc5 /vcl/unx/generic
parentd3794d2d8ab2ee3f8118d61538bb753335b37f23 (diff)
Use new line heights only if SAL_USE_NEW_LINEHEIGHT=1
Commit 3364fefe1e2dec522211040f2f9ea37bf5cd7466 introduced a new (and font technically correct) handling of interline spacing that affects line heights in all applications. Activate that only if SAL_USE_NEW_LINEHEIGHT=1 is set in the environment, else use the old handling until all quirks are sorted out.
Diffstat (limited to 'vcl/unx/generic')
-rw-r--r--vcl/unx/generic/glyphs/gcach_ftyp.cxx88
1 files changed, 81 insertions, 7 deletions
diff --git a/vcl/unx/generic/glyphs/gcach_ftyp.cxx b/vcl/unx/generic/glyphs/gcach_ftyp.cxx
index 5610b014af84..ffa4aa33b642 100644
--- a/vcl/unx/generic/glyphs/gcach_ftyp.cxx
+++ b/vcl/unx/generic/glyphs/gcach_ftyp.cxx
@@ -951,6 +951,18 @@ int ServerFont::GetEmUnits() const
void ServerFont::FetchFontMetric( ImplFontMetricData& rTo, long& rFactor ) const
{
+ const int UNDETERMINED = 0xFEED;
+ static int nUseNewLineHeight = UNDETERMINED;
+ if (nUseNewLineHeight == UNDETERMINED)
+ {
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex());
+ if (nUseNewLineHeight == UNDETERMINED)
+ {
+ const char* pEnv = getenv( "SAL_USE_NEW_LINEHEIGHT");
+ nUseNewLineHeight = (pEnv ? atoi(pEnv) : 0);
+ }
+ }
+
static_cast<ImplFontAttributes&>(rTo) = mpFontInfo->GetFontAttributes();
rTo.mbScalableFont = true;
@@ -977,8 +989,15 @@ void ServerFont::FetchFontMetric( ImplFontMetricData& rTo, long& rFactor ) const
const FT_Size_Metrics& rMetrics = maFaceFT->size->metrics;
rTo.mnAscent = (+rMetrics.ascender + 32) >> 6;
rTo.mnDescent = (-rMetrics.descender + 32) >> 6;
- rTo.mnExtLeading = ((rMetrics.height + 32) >> 6) - (rTo.mnAscent + rTo.mnDescent);
- rTo.mnIntLeading = (rTo.mnAscent + rTo.mnDescent) - ((maFaceFT->units_per_EM + 32) >> 6);
+ if (nUseNewLineHeight)
+ {
+ rTo.mnExtLeading = ((rMetrics.height + 32) >> 6) - (rTo.mnAscent + rTo.mnDescent);
+ rTo.mnIntLeading = (rTo.mnAscent + rTo.mnDescent) - ((maFaceFT->units_per_EM + 32) >> 6);
+ }
+ else
+ {
+ rTo.mnIntLeading = ((rMetrics.height + 32) >> 6) - (rTo.mnAscent + rTo.mnDescent);
+ }
rTo.mnSlant = 0;
const TT_OS2* pOS2 = (const TT_OS2*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_os2 );
@@ -1014,12 +1033,67 @@ void ServerFont::FetchFontMetric( ImplFontMetricData& rTo, long& rFactor ) const
}
const double fScale = (double)GetFontSelData().mnHeight / maFaceFT->units_per_EM;
- if( pOS2->sTypoAscender || pOS2->sTypoDescender )
+ if (nUseNewLineHeight)
+ {
+ if( pOS2->sTypoAscender || pOS2->sTypoDescender )
+ {
+ rTo.mnAscent = (long)( pOS2->sTypoAscender * fScale + 0.5 );
+ rTo.mnDescent = (long)( -pOS2->sTypoDescender * fScale + 0.5 );
+ rTo.mnExtLeading = (long)( pOS2->sTypoLineGap * fScale + 0.5 );
+ rTo.mnIntLeading = (long)( (pOS2->sTypoAscender - pOS2->sTypoDescender - maFaceFT->units_per_EM) * fScale + 0.5 );
+ }
+ }
+ else
{
- rTo.mnAscent = (long)( pOS2->sTypoAscender * fScale + 0.5 );
- rTo.mnDescent = (long)( -pOS2->sTypoDescender * fScale + 0.5 );
- rTo.mnExtLeading = (long)( pOS2->sTypoLineGap * fScale + 0.5 );
- rTo.mnIntLeading = (long)( (pOS2->sTypoAscender - pOS2->sTypoDescender - maFaceFT->units_per_EM) * fScale + 0.5 );
+ // #108862# sanity check, some fonts treat descent as signed !!!
+ int nDescent = pOS2->usWinDescent;
+ if( nDescent > 5*maFaceFT->units_per_EM )
+ nDescent = (short)pOS2->usWinDescent; // interpret it as signed!
+
+ if( pOS2->usWinAscent || pOS2->usWinDescent ) // #i30551#
+ {
+ rTo.mnAscent = (long)( +pOS2->usWinAscent * fScale + 0.5 );
+ rTo.mnDescent = (long)( +nDescent * fScale + 0.5 );
+ rTo.mnIntLeading = (long)( (+pOS2->usWinAscent + pOS2->usWinDescent - maFaceFT->units_per_EM) * fScale + 0.5 );
+ }
+ rTo.mnExtLeading = 0;
+ const TT_HoriHeader* pHHEA = (const TT_HoriHeader*)FT_Get_Sfnt_Table( maFaceFT, ft_sfnt_hhea );
+ if( (pHHEA != NULL) && (pOS2->usWinAscent || pOS2->usWinDescent) )
+ {
+ int nExtLeading = pHHEA->Line_Gap;
+ nExtLeading -= (pOS2->usWinAscent + pOS2->usWinDescent);
+ nExtLeading += (pHHEA->Ascender - pHHEA->Descender);
+ if( nExtLeading > 0 )
+ rTo.mnExtLeading = (long)(nExtLeading * fScale + 0.5);
+ }
+
+ // Check for CJK capabilities of the current font
+ // #107888# workaround for Asian...
+ // TODO: remove when ExtLeading fully implemented
+ sal_Bool bCJKCapable = ((pOS2->ulUnicodeRange2 & 0x2DF00000) != 0);
+
+ if ( bCJKCapable && (pOS2->usWinAscent || pOS2->usWinDescent) )
+ {
+ rTo.mnIntLeading += rTo.mnExtLeading;
+
+ // #109280# The line height for Asian fonts is too small.
+ // Therefore we add half of the external leading to the
+ // ascent, the other half is added to the descent.
+ const long nHalfTmpExtLeading = rTo.mnExtLeading / 2;
+ const long nOtherHalfTmpExtLeading = rTo.mnExtLeading - nHalfTmpExtLeading;
+
+ // #110641# external leading for Asian fonts.
+ // The factor 0.3 has been verified during experiments.
+ const long nCJKExtLeading = (long)(0.30 * (rTo.mnAscent + rTo.mnDescent));
+
+ if ( nCJKExtLeading > rTo.mnExtLeading )
+ rTo.mnExtLeading = nCJKExtLeading - rTo.mnExtLeading;
+ else
+ rTo.mnExtLeading = 0;
+
+ rTo.mnAscent += nHalfTmpExtLeading;
+ rTo.mnDescent += nOtherHalfTmpExtLeading;
+ }
}
}