Looks like there were bugs in the code I originally wrote.
Jules you need to add:
if ((attr.getFont()->getStyleFlags() & Font::bold) == Font::bold) textLayout->SetFontWeight(DWRITE_FONT_WEIGHT_BOLD, range);
if ((attr.getFont()->getStyleFlags() & Font::italic) == Font::italic) textLayout->SetFontStyle(DWRITE_FONT_STYLE_ITALIC, range);
to addAttributedRange() in DirectWriteTypeLayout.cpp.
Full code for new addAttributedRange():
void addAttributedRange (const AttributedString::Attribute& attr, IDWriteTextLayout* textLayout,
const int textLen, ID2D1DCRenderTarget* const renderTarget, IDWriteFontCollection* const fontCollection)
{
DWRITE_TEXT_RANGE range;
range.startPosition = attr.range.getStart();
range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart());
if (attr.getFont() != nullptr)
{
textLayout->SetFontFamilyName (attr.getFont()->getTypefaceName().toWideCharPointer(), range);
if ((attr.getFont()->getStyleFlags() & Font::bold) == Font::bold) textLayout->SetFontWeight(DWRITE_FONT_WEIGHT_BOLD, range);
if ((attr.getFont()->getStyleFlags() & Font::italic) == Font::italic) textLayout->SetFontStyle(DWRITE_FONT_STYLE_ITALIC, range);
const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*attr.getFont(), *fontCollection);
textLayout->SetFontSize (attr.getFont()->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);
}
}
You also need to change two lines in getFontName() in DirectWriteTypeLayout.cpp.
Old lines:
if (dwFont->GetWeight() == DWRITE_FONT_WEIGHT_BOLD) styleFlags &= Font::bold;
if (dwFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC) styleFlags &= Font::italic;
New lines:
if (dwFont->GetWeight() == DWRITE_FONT_WEIGHT_BOLD) styleFlags |= Font::bold;
if (dwFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC) styleFlags |= Font::italic;
Full code for new getFontName():
String getFontName (DWRITE_GLYPH_RUN const* glyphRun, int& styleFlags) const
{
ComSmartPtr<IDWriteFont> dwFont;
HRESULT hr = fontCollection->GetFontFromFontFace (glyphRun->fontFace, dwFont.resetAndGetPointerAddress());
jassert (dwFont != nullptr);
if (dwFont->GetWeight() == DWRITE_FONT_WEIGHT_BOLD) styleFlags |= Font::bold;
if (dwFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC) styleFlags |= Font::italic;
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
hr = dwFont->GetFontFamily (dwFontFamily.resetAndGetPointerAddress());
jassert (dwFontFamily != nullptr);
// Get the Font Family Names
ComSmartPtr<IDWriteLocalizedStrings> dwFamilyNames;
hr = dwFontFamily->GetFamilyNames (dwFamilyNames.resetAndGetPointerAddress());
jassert (dwFamilyNames != nullptr);
UINT32 index = 0;
BOOL exists = false;
hr = dwFamilyNames->FindLocaleName (L"en-us", &index, &exists);
if (! exists)
index = 0;
UINT32 length = 0;
hr = dwFamilyNames->GetStringLength (index, &length);
HeapBlock <wchar_t> name (length + 1);
hr = dwFamilyNames->GetString (index, name, length + 1);
return String (name);
}