From f420f4c2e84deb182e4f675c1a0d45bede110ff2 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sun, 1 Jan 2017 19:44:25 +0000 Subject: Revert "tdf#103514: Always ignore bitmap fonts on Windows" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit e80621fb04093d5ab950485357f6058dcbaf8aaf. Lots of crashes related to this change, lets revert and see if we can fix it in 5.3: http://crashreport.libreoffice.org/stats/signature/ImplReleaseTempFonts(SalData%20&) Change-Id: I86b7d85fe1bfb7be28fbed7dc8957f71d1bedc55 Reviewed-on: https://gerrit.libreoffice.org/32591 Tested-by: Jenkins Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- vcl/win/gdi/salfont.cxx | 110 +++++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 49 deletions(-) diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 803817da3ef3..df406d4c4f88 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -69,6 +69,10 @@ inline int IntTimes256FromFixed(FIXED f) return nFixedTimes256; } +// these variables can be static because they store system wide settings +static bool bImplSalCourierScalable = false; +static bool bImplSalCourierNew = false; + // TODO: also support temporary TTC font files typedef std::map< OUString, FontAttributes > FontAttrMap; @@ -419,13 +423,6 @@ LanguageType MapCharToLanguage( sal_UCS4 uChar ) return LANGUAGE_DONTKNOW; } -class WinPreMatchFontSubstititution -: public ImplPreMatchFontSubstitution -{ -public: - bool FindFontSubstitute(FontSelectPattern&) const override; -}; - class WinGlyphFallbackSubstititution : public ImplGlyphFallbackFontSubstitution { @@ -509,39 +506,6 @@ namespace } } -// These are Win 3.1 bitmap fonts using "FON" font format -// which is not supported with "Direct Write" so let's substitute them -// with a font that is supported and always available. -// Based on: -// https://dxr.mozilla.org/mozilla-esr10/source/gfx/thebes/gfxDWriteFontList.cpp#1057 -static const std::map aBitmapFontSubs = -{ - { "MS Sans Serif", "Microsoft Sans Serif" }, - { "MS Serif", "Times New Roman" }, - { "Small Fonts", "Arial" }, - { "Courier", "Courier New" }, - { "Roman", "Times New Roman" }, - { "Script", "Mistral" } -}; - -// TODO: See if Windows have API that we can use here to improve font fallback. -bool WinPreMatchFontSubstititution::FindFontSubstitute(FontSelectPattern& rFontSelData) const -{ - if (rFontSelData.IsSymbolFont() || IsStarSymbol(rFontSelData.maSearchName)) - return false; - - for (const auto& aSub : aBitmapFontSubs) - { - if (rFontSelData.maSearchName == GetEnglishSearchFontName(aSub.first)) - { - rFontSelData.maSearchName = aSub.second; - return true; - } - } - - return false; -} - // find a fallback font for missing characters // TODO: should stylistic matches be searched and preferred? bool WinGlyphFallbackSubstititution::FindFontSubstitute( FontSelectPattern& rFontSelData, OUString& rMissingChars ) const @@ -628,6 +592,9 @@ struct ImplEnumInfo LOGFONTA* mpLogFontA; LOGFONTW* mpLogFontW; UINT mnPreferredCharSet; + bool mbCourier; + bool mbImplSalCourierScalable; + bool mbImplSalCourierNew; bool mbPrinter; int mnFontCount; }; @@ -1394,6 +1361,26 @@ HFONT WinSalGraphics::ImplDoSetFont( FontSelectPattern* i_pFont, float& o_rFontS LOGFONTW aLogFont; ImplGetLogFontFromFontSelect( getHDC(), i_pFont, aLogFont, true ); + // on the display we prefer Courier New when Courier is a + // bitmap only font and we need to stretch or rotate it + if( mbScreen + && (i_pFont->mnWidth != 0 + || i_pFont->mnOrientation != 0 + || i_pFont->mpFontData == NULL + || (i_pFont->mpFontData->GetHeight() != i_pFont->mnHeight)) + && !bImplSalCourierScalable + && bImplSalCourierNew + && (ImplSalWICompareAscii( aLogFont.lfFaceName, "Courier" ) == 0) ) + lstrcpynW( aLogFont.lfFaceName, L"Courier New", 12 ); + + // Script and Roman are Win 3.1 bitmap fonts using "FON" font format + // which is not supported with "Direct Write" so let's substitute them + // with a font that is supported and always available. + if (ImplSalWICompareAscii(aLogFont.lfFaceName, "Script") == 0) + wcscpy(aLogFont.lfFaceName, L"Times New Roman"); + if (ImplSalWICompareAscii(aLogFont.lfFaceName, "Roman") == 0) + wcscpy(aLogFont.lfFaceName, L"Times New Roman"); + // #i47675# limit font requests to MAXFONTHEIGHT // TODO: share MAXFONTHEIGHT font instance if( (-aLogFont.lfHeight <= MAXFONTHEIGHT) @@ -1657,6 +1644,12 @@ int CALLBACK SalEnumFontsProcExW( const ENUMLOGFONTEXW* pLogFont, // Ignore vertical fonts if ( pLogFont->elfLogFont.lfFaceName[0] != '@' ) { + if ( !pInfo->mbImplSalCourierNew ) + pInfo->mbImplSalCourierNew = ImplSalWICompareAscii( pLogFont->elfLogFont.lfFaceName, "Courier New" ) == 0; + if ( !pInfo->mbImplSalCourierScalable ) + pInfo->mbCourier = ImplSalWICompareAscii( pLogFont->elfLogFont.lfFaceName, "Courier" ) == 0; + else + pInfo->mbCourier = FALSE; OUString aName = OUString(reinterpret_cast(pLogFont->elfLogFont.lfFaceName)); pInfo->mpName = &aName; memcpy( pInfo->mpLogFontW->lfFaceName, pLogFont->elfLogFont.lfFaceName, (aName.getLength()+1)*sizeof( wchar_t ) ); @@ -1666,21 +1659,23 @@ int CALLBACK SalEnumFontsProcExW( const ENUMLOGFONTEXW* pLogFont, pInfo->mpLogFontW->lfFaceName[0] = '\0'; pInfo->mpLogFontW->lfCharSet = DEFAULT_CHARSET; pInfo->mpName = NULL; + pInfo->mbCourier = FALSE; } } else { - // Ignore non-device font on printer. - if (pInfo->mbPrinter && !(nFontType & DEVICE_FONTTYPE)) - return 1; - - // Ignore non-scalable fonts. - if (nFontType & RASTER_FONTTYPE) - return 1; + // ignore non-scalable non-device font on printer + if( pInfo->mbPrinter ) + if( (nFontType & RASTER_FONTTYPE) && !(nFontType & DEVICE_FONTTYPE) ) + return 1; WinFontFace* pData = ImplLogMetricToDevFontDataW( pLogFont, &(pMetric->ntmTm), nFontType ); pData->SetFontId( sal_IntPtr( pInfo->mnFontCount++ ) ); + // knowing Courier to be scalable is nice + if( pInfo->mbCourier ) + pInfo->mbImplSalCourierScalable |= pData->IsScalable(); + pInfo->mpList->Add( pData ); } @@ -1962,8 +1957,19 @@ void WinSalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection ) aInfo.mpName = NULL; aInfo.mpLogFontA = NULL; aInfo.mpLogFontW = NULL; + aInfo.mbCourier = false; aInfo.mbPrinter = mbPrinter; aInfo.mnFontCount = 0; + if ( !mbPrinter ) + { + aInfo.mbImplSalCourierScalable = false; + aInfo.mbImplSalCourierNew = false; + } + else + { + aInfo.mbImplSalCourierScalable = true; + aInfo.mbImplSalCourierNew = true; + } aInfo.mnPreferredCharSet = DEFAULT_CHARSET; DWORD nCP = GetACP(); @@ -1978,11 +1984,17 @@ void WinSalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection ) EnumFontFamiliesExW( getHDC(), &aLogFont, (FONTENUMPROCW)SalEnumFontsProcExW, (LPARAM)(void*)&aInfo, 0 ); + // check what Courier fonts are used on the screen, so to perhaps + // map Courier to CourierNew in SetFont() + if ( !mbPrinter ) + { + bImplSalCourierScalable = aInfo.mbImplSalCourierScalable; + bImplSalCourierNew = aInfo.mbImplSalCourierNew; + } + // set glyph fallback hook static WinGlyphFallbackSubstititution aSubstFallback( getHDC() ); - static WinPreMatchFontSubstititution aPreMatchFont; pFontCollection->SetFallbackHook( &aSubstFallback ); - pFontCollection->SetPreMatchHook(&aPreMatchFont); } void WinSalGraphics::ClearDevFontCache() -- cgit v1.2.3