Allow the DX rendering engine to run on Windows 7 (#1274)
Certain DirectX features are unavailable on windows 7. The important ones as they are used in the DX renderer are color font rendering and fallback font support. Color fonts did not exist at all on windows 7 so running basic glyphrun rendering should work just fine. Fallback font support was not exposed to the user in windows 7, making dealing with them difficult. Rather than try to get some workarounds to properly enable it I have opted to just conditionally disable the support on windows 7.
This commit is contained in:
parent
b9cc819afe
commit
0219781753
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <wrl.h>
|
||||
#include <wrl/client.h>
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
using namespace Microsoft::Console::Render;
|
||||
|
||||
|
@ -19,10 +20,10 @@ using namespace Microsoft::Console::Render;
|
|||
// - font - The DirectWrite font face to use while calculating layout (by default, will fallback if necessary)
|
||||
// - clusters - From the backing buffer, the text to be displayed clustered by the columns it should consume.
|
||||
// - width - The count of pixels available per column (the expected pixel width of every column)
|
||||
CustomTextLayout::CustomTextLayout(IDWriteFactory2* const factory,
|
||||
CustomTextLayout::CustomTextLayout(IDWriteFactory1* const factory,
|
||||
IDWriteTextAnalyzer1* const analyzer,
|
||||
IDWriteTextFormat2* const format,
|
||||
IDWriteFontFace5* const font,
|
||||
IDWriteTextFormat* const format,
|
||||
IDWriteFontFace1* const font,
|
||||
std::basic_string_view<Cluster> const clusters,
|
||||
size_t const width) :
|
||||
_factory{ factory },
|
||||
|
@ -134,7 +135,11 @@ CustomTextLayout::CustomTextLayout(IDWriteFactory2* const factory,
|
|||
RETURN_IF_FAILED(_analyzer->AnalyzeNumberSubstitution(this, 0, textLength, this));
|
||||
|
||||
// Perform our custom font fallback analyzer that mimics the pattern of the real analyzers.
|
||||
RETURN_IF_FAILED(_AnalyzeFontFallback(this, 0, textLength));
|
||||
// Fallback routines are not available below Windows 8.1, so just skip them and let a replacement character happen.
|
||||
if (IsWindows8Point1OrGreater())
|
||||
{
|
||||
RETURN_IF_FAILED(_AnalyzeFontFallback(this, 0, textLength));
|
||||
}
|
||||
|
||||
// Ensure that a font face is attached to every run
|
||||
for (auto& run : _runs)
|
||||
|
|
|
@ -19,10 +19,10 @@ namespace Microsoft::Console::Render
|
|||
public:
|
||||
// Based on the Windows 7 SDK sample at https://github.com/pauldotknopf/WindowsSDK7-Samples/tree/master/multimedia/DirectWrite/CustomLayout
|
||||
|
||||
CustomTextLayout(IDWriteFactory2* const factory,
|
||||
CustomTextLayout(IDWriteFactory1* const factory,
|
||||
IDWriteTextAnalyzer1* const analyzer,
|
||||
IDWriteTextFormat2* const format,
|
||||
IDWriteFontFace5* const font,
|
||||
IDWriteTextFormat* const format,
|
||||
IDWriteFontFace1* const font,
|
||||
const std::basic_string_view<::Microsoft::Console::Render::Cluster> clusters,
|
||||
size_t const width);
|
||||
|
||||
|
@ -90,7 +90,7 @@ namespace Microsoft::Console::Render
|
|||
UINT8 bidiLevel;
|
||||
bool isNumberSubstituted;
|
||||
bool isSideways;
|
||||
::Microsoft::WRL::ComPtr<IDWriteFontFace5> fontFace;
|
||||
::Microsoft::WRL::ComPtr<IDWriteFontFace1> fontFace;
|
||||
FLOAT fontScale;
|
||||
|
||||
inline bool ContainsTextPosition(UINT32 desiredTextPosition) const
|
||||
|
@ -135,16 +135,16 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] static UINT32 _EstimateGlyphCount(const UINT32 textLength) noexcept;
|
||||
|
||||
private:
|
||||
const ::Microsoft::WRL::ComPtr<IDWriteFactory2> _factory;
|
||||
const ::Microsoft::WRL::ComPtr<IDWriteFactory1> _factory;
|
||||
|
||||
// DirectWrite analyzer
|
||||
const ::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> _analyzer;
|
||||
|
||||
// DirectWrite text format
|
||||
const ::Microsoft::WRL::ComPtr<IDWriteTextFormat2> _format;
|
||||
const ::Microsoft::WRL::ComPtr<IDWriteTextFormat> _format;
|
||||
|
||||
// DirectWrite font face
|
||||
const ::Microsoft::WRL::ComPtr<IDWriteFontFace5> _font;
|
||||
const ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _font;
|
||||
|
||||
// The text we're analyzing and processing into a layout
|
||||
std::wstring _text;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <wrl.h>
|
||||
#include <wrl/client.h>
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
using namespace Microsoft::Console::Render;
|
||||
|
||||
|
@ -239,8 +240,8 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
|
|||
D2D1_POINT_2F baselineOrigin = origin;
|
||||
baselineOrigin.y += drawingContext->spacing.baseline;
|
||||
|
||||
::Microsoft::WRL::ComPtr<ID2D1DeviceContext4> d2dContext4;
|
||||
RETURN_IF_FAILED(drawingContext->renderTarget->QueryInterface(d2dContext4.GetAddressOf()));
|
||||
::Microsoft::WRL::ComPtr<ID2D1DeviceContext> d2dContext;
|
||||
RETURN_IF_FAILED(drawingContext->renderTarget->QueryInterface(d2dContext.GetAddressOf()));
|
||||
|
||||
// Draw the background
|
||||
D2D1_RECT_F rect;
|
||||
|
@ -254,13 +255,17 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
|
|||
rect.right += glyphRun->glyphAdvances[i];
|
||||
}
|
||||
|
||||
d2dContext4->FillRectangle(rect, drawingContext->backgroundBrush);
|
||||
d2dContext->FillRectangle(rect, drawingContext->backgroundBrush);
|
||||
|
||||
// Now go onto drawing the text.
|
||||
|
||||
// First check if we want a color font and try to extract color emoji first.
|
||||
if (WI_IsFlagSet(drawingContext->options, D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT))
|
||||
// Color emoji are only available on Windows 10+
|
||||
if (WI_IsFlagSet(drawingContext->options, D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT) && IsWindows10OrGreater())
|
||||
{
|
||||
::Microsoft::WRL::ComPtr<ID2D1DeviceContext4> d2dContext4;
|
||||
RETURN_IF_FAILED(d2dContext.As(&d2dContext4));
|
||||
|
||||
::Microsoft::WRL::ComPtr<IDWriteFactory4> dwriteFactory4;
|
||||
RETURN_IF_FAILED(drawingContext->dwriteFactory->QueryInterface(dwriteFactory4.GetAddressOf()));
|
||||
|
||||
|
@ -409,11 +414,11 @@ void CustomTextRenderer::_FillRectangle(void* clientDrawingContext,
|
|||
_In_ const DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription,
|
||||
ID2D1Brush* brush)
|
||||
{
|
||||
::Microsoft::WRL::ComPtr<ID2D1DeviceContext4> d2dContext4;
|
||||
RETURN_IF_FAILED(clientDrawingContext->renderTarget->QueryInterface(d2dContext4.GetAddressOf()));
|
||||
::Microsoft::WRL::ComPtr<ID2D1DeviceContext> d2dContext;
|
||||
RETURN_IF_FAILED(clientDrawingContext->renderTarget->QueryInterface(d2dContext.GetAddressOf()));
|
||||
|
||||
// Using the context is the easiest/default way of drawing.
|
||||
d2dContext4->DrawGlyphRun(baselineOrigin, glyphRun, glyphRunDescription, brush, measuringMode);
|
||||
d2dContext->DrawGlyphRun(baselineOrigin, glyphRun, glyphRunDescription, brush, measuringMode);
|
||||
|
||||
// However, we could probably add options here and switch out to one of these other drawing methods (making it
|
||||
// conditional based on the IUnknown* clientDrawingEffect or on some other switches and try these out instead:
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../../types/inc/Viewport.hpp"
|
||||
#include "../../inc/unicode.hpp"
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
|
@ -191,7 +192,16 @@ DxEngine::~DxEngine()
|
|||
SwapChainDesc.BufferCount = 2;
|
||||
SwapChainDesc.SampleDesc.Count = 1;
|
||||
SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
SwapChainDesc.Scaling = DXGI_SCALING_NONE;
|
||||
|
||||
// DXGI_SCALING_NONE is only valid on Windows 8+
|
||||
if (IsWindows8OrGreater())
|
||||
{
|
||||
SwapChainDesc.Scaling = DXGI_SCALING_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
}
|
||||
|
||||
switch (_chainMode)
|
||||
{
|
||||
|
@ -886,7 +896,7 @@ void DxEngine::_InvalidOr(RECT rc) noexcept
|
|||
|
||||
// Get the baseline for this font as that's where we draw from
|
||||
DWRITE_LINE_SPACING spacing;
|
||||
RETURN_IF_FAILED(_dwriteTextFormat->GetLineSpacing(&spacing));
|
||||
RETURN_IF_FAILED(_dwriteTextFormat->GetLineSpacing(&spacing.method, &spacing.height, &spacing.baseline));
|
||||
|
||||
// Assemble the drawing context information
|
||||
DrawingContext context(_d2dRenderTarget.Get(),
|
||||
|
@ -1248,9 +1258,9 @@ float DxEngine::GetScaling() const noexcept
|
|||
FontInfo& pfiFontInfo,
|
||||
int const iDpi) noexcept
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IDWriteTextFormat2> format;
|
||||
Microsoft::WRL::ComPtr<IDWriteTextFormat> format;
|
||||
Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> analyzer;
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace5> face;
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace1> face;
|
||||
|
||||
return _GetProposedFont(pfiFontInfoDesired,
|
||||
pfiFontInfo,
|
||||
|
@ -1352,12 +1362,12 @@ float DxEngine::GetScaling() const noexcept
|
|||
// - style - Normal, italic, etc.
|
||||
// Return Value:
|
||||
// - Smart pointer holding interface reference for queryable font data.
|
||||
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFace5> DxEngine::_FindFontFace(const std::wstring& familyName,
|
||||
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFace1> DxEngine::_FindFontFace(const std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT weight,
|
||||
DWRITE_FONT_STRETCH stretch,
|
||||
DWRITE_FONT_STYLE style) const
|
||||
{
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace5> fontFace;
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace1> fontFace;
|
||||
|
||||
Microsoft::WRL::ComPtr<IDWriteFontCollection> fontCollection;
|
||||
THROW_IF_FAILED(_dwriteFactory->GetSystemFontCollection(&fontCollection, false));
|
||||
|
@ -1394,9 +1404,9 @@ float DxEngine::GetScaling() const noexcept
|
|||
[[nodiscard]] HRESULT DxEngine::_GetProposedFont(const FontInfoDesired& desired,
|
||||
FontInfo& actual,
|
||||
const int dpi,
|
||||
Microsoft::WRL::ComPtr<IDWriteTextFormat2>& textFormat,
|
||||
Microsoft::WRL::ComPtr<IDWriteTextFormat>& textFormat,
|
||||
Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1>& textAnalyzer,
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace5>& fontFace) const noexcept
|
||||
Microsoft::WRL::ComPtr<IDWriteFontFace1>& fontFace) const noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -1508,7 +1518,7 @@ float DxEngine::GetScaling() const noexcept
|
|||
|
||||
fontFace = face;
|
||||
|
||||
THROW_IF_FAILED(textFormat->SetLineSpacing(&lineSpacing));
|
||||
THROW_IF_FAILED(textFormat->SetLineSpacing(lineSpacing.method, lineSpacing.height, lineSpacing.baseline));
|
||||
THROW_IF_FAILED(textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR));
|
||||
THROW_IF_FAILED(textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP));
|
||||
|
||||
|
|
|
@ -146,9 +146,9 @@ namespace Microsoft::Console::Render
|
|||
|
||||
// Device-Independent Resources
|
||||
::Microsoft::WRL::ComPtr<ID2D1Factory> _d2dFactory;
|
||||
::Microsoft::WRL::ComPtr<IDWriteFactory2> _dwriteFactory;
|
||||
::Microsoft::WRL::ComPtr<IDWriteTextFormat2> _dwriteTextFormat;
|
||||
::Microsoft::WRL::ComPtr<IDWriteFontFace5> _dwriteFontFace;
|
||||
::Microsoft::WRL::ComPtr<IDWriteFactory1> _dwriteFactory;
|
||||
::Microsoft::WRL::ComPtr<IDWriteTextFormat> _dwriteTextFormat;
|
||||
::Microsoft::WRL::ComPtr<IDWriteFontFace1> _dwriteFontFace;
|
||||
::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> _dwriteTextAnalyzer;
|
||||
::Microsoft::WRL::ComPtr<CustomTextRenderer> _customRenderer;
|
||||
|
||||
|
@ -178,7 +178,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT _EnableDisplayAccess(const bool outputEnabled) noexcept;
|
||||
|
||||
[[nodiscard]] ::Microsoft::WRL::ComPtr<IDWriteFontFace5> _FindFontFace(const std::wstring& familyName,
|
||||
[[nodiscard]] ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _FindFontFace(const std::wstring& familyName,
|
||||
DWRITE_FONT_WEIGHT weight,
|
||||
DWRITE_FONT_STRETCH stretch,
|
||||
DWRITE_FONT_STYLE style) const;
|
||||
|
@ -186,9 +186,9 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] HRESULT _GetProposedFont(const FontInfoDesired& desired,
|
||||
FontInfo& actual,
|
||||
const int dpi,
|
||||
::Microsoft::WRL::ComPtr<IDWriteTextFormat2>& textFormat,
|
||||
::Microsoft::WRL::ComPtr<IDWriteTextFormat>& textFormat,
|
||||
::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1>& textAnalyzer,
|
||||
::Microsoft::WRL::ComPtr<IDWriteFontFace5>& fontFace) const noexcept;
|
||||
::Microsoft::WRL::ComPtr<IDWriteFontFace1>& fontFace) const noexcept;
|
||||
|
||||
[[nodiscard]] COORD _GetFontSize() const noexcept;
|
||||
|
||||
|
|
Loading…
Reference in New Issue