[Libreoffice-commits] core.git: vcl/win

Khaled Hosny khaledhosny at eglug.org
Fri Oct 28 08:40:49 UTC 2016


 vcl/win/gdi/salfont.cxx |  116 ++++++++++++++++++++----------------------------
 1 file changed, 50 insertions(+), 66 deletions(-)

New commits:
commit 8f0f5e0c709d01555a4069f8665889924ed181c7
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Thu Oct 27 22:58:37 2016 +0200

    tdf#103514: Always ignore bitmap fonts on Windows
    
    We should never see any bitmap fonts now, so all the Courier stuff can
    go away.
    
    Since we never list the bitmap fonts in the first place, the old code
    for replacing some of them with scalable equivalents never kicks in. We
    instead implement PreMatchFontSubstitution hook for the same effect.
    
    Change-Id: I54f3c068bcd64554ed3498f4ba5b0f76bbd38589
    Reviewed-on: https://gerrit.libreoffice.org/30345
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 7f11d65..d3e4e5e 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -69,10 +69,6 @@ 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;
-
 // raw font data with a scoped lifetime
 class RawFontData
 {
@@ -283,6 +279,13 @@ LanguageType MapCharToLanguage( sal_UCS4 uChar )
     return LANGUAGE_DONTKNOW;
 }
 
+class WinPreMatchFontSubstititution
+:    public ImplPreMatchFontSubstitution
+{
+public:
+    bool FindFontSubstitute(FontSelectPattern&) const override;
+};
+
 class WinGlyphFallbackSubstititution
 :    public ImplGlyphFallbackFontSubstitution
 {
@@ -363,6 +366,39 @@ 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<OUString, OUString> 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
@@ -449,9 +485,6 @@ struct ImplEnumInfo
     LOGFONTA*           mpLogFontA;
     LOGFONTW*           mpLogFontW;
     UINT                mnPreferredCharSet;
-    bool                mbCourier;
-    bool                mbImplSalCourierScalable;
-    bool                mbImplSalCourierNew;
     bool                mbPrinter;
     int                 mnFontCount;
 };
@@ -1220,26 +1253,6 @@ 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 == nullptr
-      || (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)
@@ -1507,12 +1520,6 @@ int CALLBACK SalEnumFontsProcExW( const LOGFONTW* lpelfe,
         // 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<const sal_Unicode*>(pLogFont->elfLogFont.lfFaceName));
             pInfo->mpName = &aName;
             memcpy( pInfo->mpLogFontW->lfFaceName, pLogFont->elfLogFont.lfFaceName, (aName.getLength()+1)*sizeof( wchar_t ) );
@@ -1522,32 +1529,26 @@ int CALLBACK SalEnumFontsProcExW( const LOGFONTW* lpelfe,
             pInfo->mpLogFontW->lfFaceName[0] = '\0';
             pInfo->mpLogFontW->lfCharSet = DEFAULT_CHARSET;
             pInfo->mpName = nullptr;
-            pInfo->mbCourier = FALSE;
         }
     }
     else
     {
-        // ignore non-scalable non-device font on printer
-        if( pInfo->mbPrinter )
-            if( (nFontType & RASTER_FONTTYPE) && !(nFontType & DEVICE_FONTTYPE) )
-                return 1;
+        // 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 font formats not supported by CommonSalLayout.
         if (SalLayout::UseCommonLayout())
-            if ((nFontType & RASTER_FONTTYPE))
-            {
-                SAL_INFO("vcl.fonts", "Ignoring font with unsupported format: "
-                         << OUString(reinterpret_cast<const sal_Unicode*>(pLogFont->elfLogFont.lfFaceName)));
+            if ((pMetric->ntmTm.ntmFlags & NTM_TYPE1) || (pMetric->ntmTm.ntmFlags & NTM_MULTIPLEMASTER))
                 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 );
     }
 
@@ -1810,19 +1811,8 @@ void WinSalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection )
     aInfo.mpName        = nullptr;
     aInfo.mpLogFontA    = nullptr;
     aInfo.mpLogFontW    = nullptr;
-    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();
@@ -1837,17 +1827,11 @@ void WinSalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection )
     EnumFontFamiliesExW( getHDC(), &aLogFont,
         SalEnumFontsProcExW, reinterpret_cast<LPARAM>(&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()


More information about the Libreoffice-commits mailing list