summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2016-12-15 17:17:17 +0200
committerKhaled Hosny <khaledhosny@eglug.org>2016-12-16 01:29:20 +0000
commit641b3461dd57b73807f7f55fa2d9b08fb777ed20 (patch)
tree1507eff413d98a5b9c8351d6f4a818024c8ab931 /vcl
parentfcbbd6089da7e60bf616041517a2aee3017ae448 (diff)
tdf#104533: Fix font metrics for non-SFNT fonts
They can still be used with the old layout engine, so fallback to old code when we encounter one of them. Not needed on master as the old layout engine is gone there. Change-Id: Ibe3e4772cb519843eeb44cfc7efd912ae9737b69 Reviewed-on: https://gerrit.libreoffice.org/32049 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Khaled Hosny <khaledhosny@eglug.org>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/win/gdi/salfont.cxx48
1 files changed, 42 insertions, 6 deletions
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 10ec674c9f07..fd207a5db7bf 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1252,14 +1252,17 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFa
// get the font metric
OUTLINETEXTMETRICW aOutlineMetric;
- const bool bOK = GetOutlineTextMetricsW(getHDC(), sizeof(OUTLINETEXTMETRICW), &aOutlineMetric);
+ TEXTMETRICW aWinMetric;
+ bool bOK = GetOutlineTextMetricsW(getHDC(), sizeof(OUTLINETEXTMETRICW), &aOutlineMetric);
+ if (bOK)
+ aWinMetric = aOutlineMetric.otmTextMetrics;
+ else
+ bOK = GetTextMetricsW(getHDC(), &aWinMetric);
// restore the HDC to the font in the base level
SelectFont( getHDC(), hOldFont );
if( !bOK )
return;
- TEXTMETRICW aWinMetric = aOutlineMetric.otmTextMetrics;
-
// device independent font attributes
rxFontMetric->SetFamilyType(ImplFamilyToSal( aWinMetric.tmPitchAndFamily ));
rxFontMetric->SetSymbolFlag(aWinMetric.tmCharSet == SYMBOL_CHARSET);
@@ -1290,9 +1293,42 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFa
// transformation dependent font metrics
rxFontMetric->SetWidth( static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmAveCharWidth ) );
- const std::vector<uint8_t> rHhea(aHheaRawData.get(), aHheaRawData.get() + aHheaRawData.size());
- const std::vector<uint8_t> rOS2(aOS2RawData.get(), aOS2RawData.get() + aOS2RawData.size());
- rxFontMetric->ImplCalcLineSpacing(rHhea, rOS2, aOutlineMetric.otmEMSquare);
+ if (aHheaRawData.size() > 0 || aOS2RawData.size() > 0)
+ {
+ const std::vector<uint8_t> rHhea(aHheaRawData.get(), aHheaRawData.get() + aHheaRawData.size());
+ const std::vector<uint8_t> rOS2(aOS2RawData.get(), aOS2RawData.get() + aOS2RawData.size());
+ rxFontMetric->ImplCalcLineSpacing(rHhea, rOS2, aOutlineMetric.otmEMSquare);
+ }
+ else
+ {
+ // Falback to GDI code, can only happen with non-SFNT fonts
+ rxFontMetric->SetInternalLeading( static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmInternalLeading ) );
+ rxFontMetric->SetExternalLeading( static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmExternalLeading ) );
+ rxFontMetric->SetAscent( static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmAscent ) );
+ rxFontMetric->SetDescent( static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmDescent ) );
+ // #107888# improved metric compatibility for Asian fonts...
+ // TODO: assess workaround below for CWS >= extleading
+ // TODO: evaluate use of aWinMetric.sTypo* members for CJK
+ if( mpWinFontData[nFallbackLevel] && mpWinFontData[nFallbackLevel]->SupportsCJK() )
+ {
+ rxFontMetric->SetInternalLeading( rxFontMetric->GetInternalLeading() + rxFontMetric->GetExternalLeading() );
+
+ // #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 = rxFontMetric->GetExternalLeading() / 2;
+ const long nOtherHalfTmpExtLeading = rxFontMetric->GetExternalLeading() - nHalfTmpExtLeading;
+
+ // #110641# external leading for Asian fonts.
+ // The factor 0.3 has been confirmed with experiments.
+ long nCJKExtLeading = static_cast<long>(0.30 * (rxFontMetric->GetAscent() + rxFontMetric->GetDescent()));
+ nCJKExtLeading -= rxFontMetric->GetExternalLeading();
+ rxFontMetric->SetExternalLeading( (nCJKExtLeading > 0) ? nCJKExtLeading : 0 );
+
+ rxFontMetric->SetAscent( rxFontMetric->GetAscent() + nHalfTmpExtLeading );
+ rxFontMetric->SetDescent( rxFontMetric->GetDescent() + nOtherHalfTmpExtLeading );
+ }
+ }
rxFontMetric->SetMinKashida( GetMinKashidaWidth() );
}