Skip to content

Commit

Permalink
Add support for italics in the DX renderer.
Browse files Browse the repository at this point in the history
  • Loading branch information
j4james committed Dec 14, 2020
1 parent 660b32f commit 966f748
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
47 changes: 43 additions & 4 deletions src/renderer/dx/DxRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ DxEngine::DxEngine() :
_foregroundColor{ 0 },
_backgroundColor{ 0 },
_selectionBackground{},
_fontIsItalic{ false },
_glyphCell{},
_boxDrawingEffect{},
_haveDeviceResources{ false },
Expand All @@ -99,6 +100,7 @@ DxEngine::DxEngine() :
_prevScale{ 1.0f },
_chainMode{ SwapChainMode::ForComposition },
_customLayout{},
_customLayoutItalic{},
_customRenderer{ ::Microsoft::WRL::Make<CustomTextRenderer>() },
_drawingContext{}
{
Expand Down Expand Up @@ -1468,12 +1470,15 @@ try
// Calculate positioning of our origin.
const D2D1_POINT_2F origin = til::point{ coord } * _glyphCell;

// Pick the appropriate layout for the current font style.
const auto& layout = _fontIsItalic ? _customLayoutItalic : _customLayout;

// Create the text layout
RETURN_IF_FAILED(_customLayout->Reset());
RETURN_IF_FAILED(_customLayout->AppendClusters(clusters));
RETURN_IF_FAILED(layout->Reset());
RETURN_IF_FAILED(layout->AppendClusters(clusters));

// Layout then render the text
RETURN_IF_FAILED(_customLayout->Draw(_drawingContext.get(), _customRenderer.Get(), origin.x, origin.y));
RETURN_IF_FAILED(layout->Draw(_drawingContext.get(), _customRenderer.Get(), origin.x, origin.y));

return S_OK;
}
Expand Down Expand Up @@ -1733,6 +1738,9 @@ CATCH_RETURN()
}*/
}

// Record the fact that we need to render the text with an italic font.
_fontIsItalic = textAttributes.IsItalic();

// If we have a drawing context, it may be choosing its antialiasing based
// on the colors. Update it if it exists.
// We only need to do this here because this is called all the time on painting frames
Expand Down Expand Up @@ -1766,17 +1774,20 @@ try
fiFontInfo,
_dpi,
_dwriteTextFormat,
_dwriteTextFormatItalic,
_dwriteTextAnalyzer,
_dwriteFontFace,
_dwriteFontFaceItalic,
_lineMetrics));

_glyphCell = fiFontInfo.GetSize();

// Calculate and cache the box effect for the base font. Scale is 1.0f because the base font is exactly the scale we want already.
RETURN_IF_FAILED(CustomTextLayout::s_CalculateBoxEffect(_dwriteTextFormat.Get(), _glyphCell.width(), _dwriteFontFace.Get(), 1.0f, &_boxDrawingEffect));

// Prepare the text layout
// Prepare the text layouts - one for regular text and one for italics.
_customLayout = WRL::Make<CustomTextLayout>(_dwriteFactory.Get(), _dwriteTextAnalyzer.Get(), _dwriteTextFormat.Get(), _dwriteFontFace.Get(), _glyphCell.width(), _boxDrawingEffect.Get());
_customLayoutItalic = WRL::Make<CustomTextLayout>(_dwriteFactory.Get(), _dwriteTextAnalyzer.Get(), _dwriteTextFormatItalic.Get(), _dwriteFontFaceItalic.Get(), _glyphCell.width(), _boxDrawingEffect.Get());

return S_OK;
}
Expand Down Expand Up @@ -1863,16 +1874,20 @@ float DxEngine::GetScaling() const noexcept
int const iDpi) noexcept
{
Microsoft::WRL::ComPtr<IDWriteTextFormat> format;
Microsoft::WRL::ComPtr<IDWriteTextFormat> formatItalic;
Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> analyzer;
Microsoft::WRL::ComPtr<IDWriteFontFace1> face;
Microsoft::WRL::ComPtr<IDWriteFontFace1> faceItalic;
LineMetrics lineMetrics;

return _GetProposedFont(pfiFontInfoDesired,
pfiFontInfo,
iDpi,
format,
formatItalic,
analyzer,
face,
faceItalic,
lineMetrics);
}

Expand Down Expand Up @@ -2141,8 +2156,10 @@ CATCH_RETURN();
FontInfo& actual,
const int dpi,
Microsoft::WRL::ComPtr<IDWriteTextFormat>& textFormat,
Microsoft::WRL::ComPtr<IDWriteTextFormat>& textFormatItalic,
Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1>& textAnalyzer,
Microsoft::WRL::ComPtr<IDWriteFontFace1>& fontFace,
Microsoft::WRL::ComPtr<IDWriteFontFace1>& fontFaceItalic,
LineMetrics& lineMetrics) const noexcept
{
try
Expand Down Expand Up @@ -2277,11 +2294,33 @@ CATCH_RETURN();

THROW_IF_FAILED(format.As(&textFormat));

// We also need to create an italic variant of the font face and text
// format, based on the same parameters, but using an italic style.
std::wstring fontNameItalic = fontName;
DWRITE_FONT_WEIGHT weightItalic = weight;
DWRITE_FONT_STYLE styleItalic = DWRITE_FONT_STYLE_ITALIC;
DWRITE_FONT_STRETCH stretchItalic = stretch;

const auto faceItalic = _ResolveFontFaceWithFallback(fontNameItalic, weightItalic, stretchItalic, styleItalic, fontLocaleName);

Microsoft::WRL::ComPtr<IDWriteTextFormat> formatItalic;
THROW_IF_FAILED(_dwriteFactory->CreateTextFormat(fontNameItalic.data(),
nullptr,
weightItalic,
styleItalic,
stretchItalic,
fontSize,
localeName.data(),
&formatItalic));

THROW_IF_FAILED(formatItalic.As(&textFormatItalic));

Microsoft::WRL::ComPtr<IDWriteTextAnalyzer> analyzer;
THROW_IF_FAILED(_dwriteFactory->CreateTextAnalyzer(&analyzer));
THROW_IF_FAILED(analyzer.As(&textAnalyzer));

fontFace = face;
fontFaceItalic = faceItalic;

THROW_IF_FAILED(textFormat->SetLineSpacing(lineSpacing.method, lineSpacing.height, lineSpacing.baseline));
THROW_IF_FAILED(textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR));
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/dx/DxRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ namespace Microsoft::Console::Render
D2D1_COLOR_F _foregroundColor;
D2D1_COLOR_F _backgroundColor;
D2D1_COLOR_F _selectionBackground;
boolean _fontIsItalic;

uint16_t _hyperlinkHoveredId;

Expand All @@ -188,9 +189,12 @@ namespace Microsoft::Console::Render

::Microsoft::WRL::ComPtr<IDWriteFactory1> _dwriteFactory;
::Microsoft::WRL::ComPtr<IDWriteTextFormat> _dwriteTextFormat;
::Microsoft::WRL::ComPtr<IDWriteTextFormat> _dwriteTextFormatItalic;
::Microsoft::WRL::ComPtr<IDWriteFontFace1> _dwriteFontFace;
::Microsoft::WRL::ComPtr<IDWriteFontFace1> _dwriteFontFaceItalic;
::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> _dwriteTextAnalyzer;
::Microsoft::WRL::ComPtr<CustomTextLayout> _customLayout;
::Microsoft::WRL::ComPtr<CustomTextLayout> _customLayoutItalic;
::Microsoft::WRL::ComPtr<CustomTextRenderer> _customRenderer;
::Microsoft::WRL::ComPtr<ID2D1StrokeStyle> _strokeStyle;
::Microsoft::WRL::ComPtr<ID2D1StrokeStyle> _dashStrokeStyle;
Expand Down Expand Up @@ -287,8 +291,10 @@ namespace Microsoft::Console::Render
FontInfo& actual,
const int dpi,
::Microsoft::WRL::ComPtr<IDWriteTextFormat>& textFormat,
::Microsoft::WRL::ComPtr<IDWriteTextFormat>& textFormatItalic,
::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1>& textAnalyzer,
::Microsoft::WRL::ComPtr<IDWriteFontFace1>& fontFace,
::Microsoft::WRL::ComPtr<IDWriteFontFace1>& fontFaceItalic,
LineMetrics& lineMetrics) const noexcept;

[[nodiscard]] til::size _GetClientSize() const;
Expand Down

0 comments on commit 966f748

Please sign in to comment.