Skip to content

Commit

Permalink
Add support for italics in the GDI renderer.
Browse files Browse the repository at this point in the history
  • Loading branch information
j4james committed Dec 13, 2020
1 parent d02812d commit 660b32f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
5 changes: 4 additions & 1 deletion src/renderer/gdi/gdirenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace Microsoft::Console::Render
bool _isTrueTypeFont;
UINT _fontCodepage;
HFONT _hfont;
HFONT _hfontItalic;
TEXTMETRICW _tmFontMetrics;

static const size_t s_cPolyTextCache = 80;
Expand Down Expand Up @@ -122,6 +123,7 @@ namespace Microsoft::Console::Render

COLORREF _lastFg;
COLORREF _lastBg;
bool _lastFontItalic;

[[nodiscard]] HRESULT _InvalidCombine(const RECT* const prc) noexcept;
[[nodiscard]] HRESULT _InvalidOffset(const POINT* const ppt) noexcept;
Expand Down Expand Up @@ -152,7 +154,8 @@ namespace Microsoft::Console::Render
[[nodiscard]] HRESULT _GetProposedFont(const FontInfoDesired& FontDesired,
_Out_ FontInfo& Font,
const int iDpi,
_Inout_ wil::unique_hfont& hFont) noexcept;
_Inout_ wil::unique_hfont& hFont,
_Inout_ wil::unique_hfont& hFontItalic) noexcept;

COORD _GetFontSize() const;
bool _IsMinimized() const;
Expand Down
52 changes: 46 additions & 6 deletions src/renderer/gdi/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ GdiEngine::GdiEngine() :
_fInvalidRectUsed(false),
_lastFg(INVALID_COLOR),
_lastBg(INVALID_COLOR),
_lastFontItalic(false),
_fPaintStarted(false),
_hfont((HFONT)INVALID_HANDLE_VALUE)
_hfont(nullptr),
_hfontItalic(nullptr)
{
ZeroMemory(_pPolyText, sizeof(POLYTEXTW) * s_cPolyTextCache);
_rcInvalid = { 0 };
Expand Down Expand Up @@ -88,6 +90,12 @@ GdiEngine::~GdiEngine()
_hfont = nullptr;
}

if (_hfontItalic != nullptr)
{
LOG_HR_IF(E_FAIL, !(DeleteObject(_hfontItalic)));
_hfontItalic = nullptr;
}

if (_hdcMemoryContext != nullptr)
{
LOG_HR_IF(E_FAIL, !(DeleteObject(_hdcMemoryContext)));
Expand Down Expand Up @@ -128,6 +136,9 @@ GdiEngine::~GdiEngine()
LOG_HR_IF_NULL(E_FAIL, SelectFont(_hdcMemoryContext, _hfont));
}

// Record the fact that the selected font is not italic.
_lastFontItalic = false;

if (nullptr != hdcRealWindow)
{
LOG_HR_IF(E_FAIL, !(ReleaseDC(_hwndTargetWindow, hdcRealWindow)));
Expand Down Expand Up @@ -210,6 +221,14 @@ GdiEngine::~GdiEngine()
RETURN_IF_FAILED(s_SetWindowLongWHelper(_hwndTargetWindow, GWL_CONSOLE_BKCOLOR, colorBackground));
}

// If the italic attribute has changed, select an appropriate font variant.
const auto fontItalic = textAttributes.IsItalic();
if (fontItalic != _lastFontItalic)
{
SelectFont(_hdcMemoryContext, fontItalic ? _hfontItalic : _hfont);
_lastFontItalic = fontItalic;
}

return S_OK;
}

Expand All @@ -223,12 +242,15 @@ GdiEngine::~GdiEngine()
// - S_OK if set successfully or relevant GDI error via HRESULT.
[[nodiscard]] HRESULT GdiEngine::UpdateFont(const FontInfoDesired& FontDesired, _Out_ FontInfo& Font) noexcept
{
wil::unique_hfont hFont;
RETURN_IF_FAILED(_GetProposedFont(FontDesired, Font, _iCurrentDpi, hFont));
wil::unique_hfont hFont, hFontItalic;
RETURN_IF_FAILED(_GetProposedFont(FontDesired, Font, _iCurrentDpi, hFont, hFontItalic));

// Select into DC
RETURN_HR_IF_NULL(E_FAIL, SelectFont(_hdcMemoryContext, hFont.get()));

// Record the fact that the selected font is not italic.
_lastFontItalic = false;

// Save off the font metrics for various other calculations
RETURN_HR_IF(E_FAIL, !(GetTextMetricsW(_hdcMemoryContext, &_tmFontMetrics)));

Expand Down Expand Up @@ -300,6 +322,16 @@ GdiEngine::~GdiEngine()
// Save the font.
_hfont = hFont.release();

// Persist italic font for cleanup (and free existing if necessary)
if (_hfontItalic != nullptr)
{
LOG_HR_IF(E_FAIL, !(DeleteObject(_hfontItalic)));
_hfontItalic = nullptr;
}

// Save the italic font.
_hfontItalic = hFontItalic.release();

// Save raster vs. TrueType and codepage data in case we need to convert.
_isTrueTypeFont = Font.IsTrueTypeFont();
_fontCodepage = Font.GetCodePage();
Expand Down Expand Up @@ -346,8 +378,8 @@ GdiEngine::~GdiEngine()
// - S_OK if set successfully or relevant GDI error via HRESULT.
[[nodiscard]] HRESULT GdiEngine::GetProposedFont(const FontInfoDesired& FontDesired, _Out_ FontInfo& Font, const int iDpi) noexcept
{
wil::unique_hfont hFont;
return _GetProposedFont(FontDesired, Font, iDpi, hFont);
wil::unique_hfont hFont, hFontItalic;
return _GetProposedFont(FontDesired, Font, iDpi, hFont, hFontItalic);
}

// Method Description:
Expand All @@ -373,12 +405,14 @@ GdiEngine::~GdiEngine()
// - Font - the actual font
// - iDpi - The DPI we will have when rendering
// - hFont - A smart pointer to receive a handle to a ready-to-use GDI font.
// - hFontItalic - A smart pointer to receive a handle to an italic variant of the font.
// Return Value:
// - S_OK if set successfully or relevant GDI error via HRESULT.
[[nodiscard]] HRESULT GdiEngine::_GetProposedFont(const FontInfoDesired& FontDesired,
_Out_ FontInfo& Font,
const int iDpi,
_Inout_ wil::unique_hfont& hFont) noexcept
_Inout_ wil::unique_hfont& hFont,
_Inout_ wil::unique_hfont& hFontItalic) noexcept
{
wil::unique_hdc hdcTemp(CreateCompatibleDC(_hdcMemoryContext));
RETURN_HR_IF_NULL(E_FAIL, hdcTemp.get());
Expand All @@ -395,6 +429,7 @@ GdiEngine::~GdiEngine()
// it may very well decide to choose Courier New instead of the Terminal raster.
#pragma prefast(suppress : 38037, "raster fonts get special handling, we need to get it this way")
hFont.reset((HFONT)GetStockObject(OEM_FIXED_FONT));
hFontItalic.reset((HFONT)GetStockObject(OEM_FIXED_FONT));
}
else
{
Expand Down Expand Up @@ -454,6 +489,11 @@ GdiEngine::~GdiEngine()
// Create font.
hFont.reset(CreateFontIndirectW(&lf));
RETURN_HR_IF_NULL(E_FAIL, hFont.get());

// Create italic variant of the font.
lf.lfItalic = TRUE;
hFontItalic.reset(CreateFontIndirectW(&lf));
RETURN_HR_IF_NULL(E_FAIL, hFontItalic.get());
}

// Select into DC
Expand Down

0 comments on commit 660b32f

Please sign in to comment.