summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/win/gdi/salfont.cxx116
1 files changed, 50 insertions, 66 deletions
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 7f11d658a40a..d3e4e5ec39df 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()