diff --git a/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp b/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp index ea95665adc..f947abfcf0 100644 --- a/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp +++ b/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp @@ -181,6 +181,19 @@ public: return {}; } + ComSmartPtr findFontForFace (IDWriteFontFace* face) + { + for (const auto& collection : collections) + { + ComSmartPtr result; + + if (SUCCEEDED (collection->GetFontFromFontFace (face, result.resetAndGetPointerAddress()))) + return result; + } + + return {}; + } + void addCollection (ComSmartPtr collection) { const std::scoped_lock lock { mutex }; @@ -552,7 +565,7 @@ public: const auto family = factories->getFonts().getFamilyByName (name.toWideCharPointer()); if (family == nullptr) - return {}; + return getLastResortTypeface (f); const auto weight = f.isBold() ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL; const auto italic = f.isItalic() ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; @@ -831,6 +844,52 @@ private: collection); } + // This attempts to replicate the behaviour of the non-directwrite typeface lookup in JUCE 7 and older + static Typeface::Ptr getLastResortTypeface (const Font& font) + { + auto* dc = CreateCompatibleDC (nullptr); + const ScopeGuard deleteDC { [&] { DeleteDC (dc); } }; + + SetMapperFlags (dc, 0); + SetMapMode (dc, MM_TEXT); + + const auto style = font.getTypefaceStyle(); + + LOGFONTW lf{}; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfOutPrecision = OUT_OUTLINE_PRECIS; + lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; + lf.lfQuality = PROOF_QUALITY; + lf.lfItalic = (BYTE) (style.contains ("Italic") ? TRUE : FALSE); + lf.lfWeight = style.contains ("Bold") ? FW_BOLD : FW_NORMAL; + lf.lfHeight = -256; + font.getTypefaceName().copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName)); + + auto* hfont = CreateFontIndirectW (&lf); + const ScopeGuard deleteFont { [&] { DeleteObject (hfont); } }; + + auto* prevFont = hfont != nullptr ? SelectObject (dc, hfont) : nullptr; + const ScopeGuard reinstateFont { [&] { if (prevFont != nullptr) SelectObject (dc, prevFont); } }; + + SharedResourcePointer factories; + + ComSmartPtr interop; + if (FAILED (factories->getDWriteFactory()->GetGdiInterop (interop.resetAndGetPointerAddress())) || interop == nullptr) + return {}; + + ComSmartPtr dwFontFace; + if (FAILED (interop->CreateFontFaceFromHdc (dc, dwFontFace.resetAndGetPointerAddress())) || dwFontFace == nullptr) + return {}; + + const auto dwFont = factories->getFonts().findFontForFace (dwFontFace); + + if (dwFont == nullptr) + return {}; + + return fromFont (dwFont, nullptr, nullptr, MetricsMechanism::gdiWithDwriteFallback); + } + SharedResourcePointer factories; ComSmartPtr collection; ComSmartPtr dwFont;