void addAttributedRange (const AttributedString::Attribute& attr, IDWriteTextLayout* textLayout, const int textLen, ID2D1RenderTarget* const renderTarget, IDWriteFontCollection* const fontCollection) { DWRITE_TEXT_RANGE range; range.startPosition = attr.range.getStart(); range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart()); const Font* const font = attr.getFont(); if (font != nullptr) { BOOL fontFound = false; uint32 fontIndex; fontCollection->FindFamilyName (FontStyleHelpers::getConcreteFamilyName (*font).toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; ComSmartPtr<IDWriteFontFamily> fontFamily; HRESULT hr = fontCollection->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress()); ComSmartPtr<IDWriteFont> dwFont; uint32 fontFacesCount = 0; fontFacesCount = fontFamily->GetFontCount(); for (int i = fontFacesCount; --i >= 0;) { hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); if (font->getTypefaceStyle() == getFontFaceName (dwFont)) break; } textLayout->SetFontFamilyName (attr.getFont()->getTypefaceName().toWideCharPointer(), range); textLayout->SetFontWeight (dwFont->GetWeight(), range); textLayout->SetFontStretch (dwFont->GetStretch(), range); textLayout->SetFontStyle (dwFont->GetStyle(), range); const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (dwFont); textLayout->SetFontSize (font->getHeight() * fontHeightToEmSizeFactor, range); } if (attr.getColour() != nullptr) { ComSmartPtr<ID2D1SolidColorBrush> d2dBrush; renderTarget->CreateSolidColorBrush (D2D1::ColorF (D2D1::ColorF (attr.getColour()->getFloatRed(), attr.getColour()->getFloatGreen(), attr.getColour()->getFloatBlue(), attr.getColour()->getFloatAlpha())), d2dBrush.resetAndGetPointerAddress()); // We need to call SetDrawingEffect with a legimate brush to get DirectWrite to break text based on colours textLayout->SetDrawingEffect (d2dBrush, range); } }
StringArray Font::findAllTypefaceStyles (const String& family) { if (FontStyleHelpers::isPlaceholderFamilyName (family)) return findAllTypefaceStyles (FontStyleHelpers::getConcreteFamilyNameFromPlaceholder (family)); StringArray results; #if JUCE_USE_DIRECTWRITE const Direct2DFactories& factories = Direct2DFactories::getInstance(); if (factories.systemFonts != nullptr) { BOOL fontFound = false; uint32 fontIndex = 0; HRESULT hr = factories.systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; // Get the font family using the search results // Fonts like: Times New Roman, Times New Roman Bold, Times New Roman Italic are all in the same font family ComSmartPtr<IDWriteFontFamily> fontFamily; hr = factories.systemFonts->GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress()); // Get the font faces ComSmartPtr<IDWriteFont> dwFont; uint32 fontFacesCount = 0; fontFacesCount = fontFamily->GetFontCount(); for (uint32 i = 0; i < fontFacesCount; ++i) { hr = fontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); // Ignore any algorithmically generated bold and oblique styles.. if (dwFont->GetSimulations() == DWRITE_FONT_SIMULATIONS_NONE) results.addIfNotAlreadyThere (getFontFaceName (dwFont)); } } else #endif { results.add ("Regular"); results.add ("Italic"); results.add ("Bold"); results.add ("Bold Italic"); } return results; }
StringArray Font::findAllTypefaceStyles(const String& family) { StringArray results; #if JUCE_USE_DIRECTWRITE const Direct2DFactories& factories = Direct2DFactories::getInstance(); if (factories.systemFonts != nullptr) { BOOL fontFound = false; uint32 fontIndex = 0; HRESULT hr = factories.systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound); if (! fontFound) fontIndex = 0; // Get the font family using the search results // Fonts like: Times New Roman, Times New Roman Bold, Times New Roman Italic are all in the same font family ComSmartPtr<IDWriteFontFamily> dwFontFamily; hr = factories.systemFonts->GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress()); // Get the font faces ComSmartPtr<IDWriteFont> dwFont; uint32 fontFacesCount = 0; fontFacesCount = dwFontFamily->GetFontCount(); for (uint32 i = 0; i < fontFacesCount; ++i) { hr = dwFontFamily->GetFont (i, dwFont.resetAndGetPointerAddress()); ComSmartPtr<IDWriteLocalizedStrings> dwFaceNames; hr = dwFont->GetFaceNames (dwFaceNames.resetAndGetPointerAddress()); jassert (dwFaceNames != nullptr); uint32 index = 0; BOOL exists = false; hr = dwFaceNames->FindLocaleName (L"en-us", &index, &exists); if (! exists) index = 0; uint32 length = 0; hr = dwFaceNames->GetStringLength (index, &length); HeapBlock <wchar_t> styleName (length + 1); hr = dwFaceNames->GetString (index, styleName, length + 1); String style (styleName); // For unknown reasons, DirectWrite does not enumerate the Arial Narrow fonts properly. // It uses the same style name "Narrow" for all four fonts. Since only one of these fonts // is accessible, we will ignore the duplicates. if (style == "Narrow" && results.contains("Narrow")) continue; // DirectWrite automatically adds extra bold and oblique font styles which are algorithmic // style simulations. These styles don't show up in any other software. We will ignore them. if (dwFont->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) continue; results.add(style); } } else #endif { results.add ("Regular"); results.add ("Italic"); results.add ("Bold"); results.add ("Bold Italic"); } return results; }