Skip to content

Commit eb34993

Browse files
authored
Introduce DxFontRenderData (#9096)
This is my attempt to isolate all the dwrite font related thing by introducing a new layer - `DxFontRenderData`. This will free `DxRenderer` & `CustomTextLayout` from the burden of handling fonts & box effects. The logic is more simplified & streamlined. In short I just moved everything fonts-related into `DxFontRenderData` and started from there. There's no modification to code logic. Just pure structural stuff. SGR support tracking issue: #6879 Initial Italic support PR: #8580
1 parent 4c53c59 commit eb34993

10 files changed

+928
-875
lines changed

src/renderer/base/lib/base.vcxproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<RootNamespace>base</RootNamespace>
77
<ProjectName>RendererBase</ProjectName>
88
<TargetName>ConRenderBase</TargetName>
9-
<ConfigurationType>StaticLibrary</ConfigurationType>
9+
<ConfigurationType>StaticLibrary</ConfigurationType>
1010
</PropertyGroup>
1111
<Import Project="$(SolutionDir)src\common.build.pre.props" />
1212
<ItemGroup>

src/renderer/dx/CustomTextLayout.cpp

+23-288
Large diffs are not rendered by default.

src/renderer/dx/CustomTextLayout.h

+4-21
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <wrl/implements.h>
1212

1313
#include "BoxDrawingEffect.h"
14+
#include "DxFontRenderData.h"
1415
#include "../inc/Cluster.hpp"
1516

1617
namespace Microsoft::Console::Render
@@ -20,14 +21,7 @@ namespace Microsoft::Console::Render
2021
public:
2122
// Based on the Windows 7 SDK sample at https://github.com/pauldotknopf/WindowsSDK7-Samples/tree/master/multimedia/DirectWrite/CustomLayout
2223

23-
CustomTextLayout(gsl::not_null<IDWriteFactory1*> const factory,
24-
gsl::not_null<IDWriteTextAnalyzer1*> const analyzer,
25-
gsl::not_null<IDWriteTextFormat*> const normalFormat,
26-
gsl::not_null<IDWriteTextFormat*> const italicFormat,
27-
gsl::not_null<IDWriteFontFace1*> const normalFont,
28-
gsl::not_null<IDWriteFontFace1*> const italicFont,
29-
size_t const width,
30-
IBoxDrawingEffect* const boxEffect);
24+
CustomTextLayout(gsl::not_null<DxFontRenderData*> const fontRenderData);
3125

3226
[[nodiscard]] HRESULT STDMETHODCALLTYPE AppendClusters(const gsl::span<const ::Microsoft::Console::Render::Cluster> clusters);
3327

@@ -71,8 +65,6 @@ namespace Microsoft::Console::Render
7165
UINT32 textLength,
7266
_In_ IDWriteNumberSubstitution* numberSubstitution) override;
7367

74-
[[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept;
75-
7668
protected:
7769
// A single contiguous run of characters containing the same analysis results.
7870
struct Run
@@ -157,24 +149,15 @@ namespace Microsoft::Console::Render
157149
[[nodiscard]] static constexpr UINT32 _EstimateGlyphCount(const UINT32 textLength) noexcept;
158150

159151
private:
160-
const ::Microsoft::WRL::ComPtr<IDWriteFactory1> _factory;
161-
162-
// DirectWrite analyzer
163-
const ::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> _analyzer;
152+
// DirectWrite font render data
153+
DxFontRenderData* _fontRenderData;
164154

165155
// DirectWrite text formats
166-
const ::Microsoft::WRL::ComPtr<IDWriteTextFormat> _format;
167-
const ::Microsoft::WRL::ComPtr<IDWriteTextFormat> _formatItalic;
168156
IDWriteTextFormat* _formatInUse;
169157

170158
// DirectWrite font faces
171-
const ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _font;
172-
const ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _fontItalic;
173159
IDWriteFontFace1* _fontInUse;
174160

175-
// Box drawing effect
176-
const ::Microsoft::WRL::ComPtr<IBoxDrawingEffect> _boxDrawingEffect;
177-
178161
// The text we're analyzing and processing into a layout
179162
std::wstring _text;
180163
std::vector<UINT16> _textClusterColumns;

src/renderer/dx/DxFontRenderData.cpp

+755
Large diffs are not rendered by default.

src/renderer/dx/DxFontRenderData.h

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
#pragma once
5+
6+
#include "../../renderer/inc/FontInfoDesired.hpp"
7+
#include "BoxDrawingEffect.h"
8+
9+
#include <dwrite.h>
10+
#include <dwrite_1.h>
11+
#include <dwrite_2.h>
12+
#include <dwrite_3.h>
13+
14+
#include <wrl.h>
15+
16+
namespace Microsoft::Console::Render
17+
{
18+
class DxFontRenderData
19+
{
20+
public:
21+
struct LineMetrics
22+
{
23+
float gridlineWidth;
24+
float underlineOffset;
25+
float underlineOffset2;
26+
float underlineWidth;
27+
float strikethroughOffset;
28+
float strikethroughWidth;
29+
};
30+
31+
DxFontRenderData(::Microsoft::WRL::ComPtr<IDWriteFactory1> dwriteFactory) noexcept;
32+
33+
// DirectWrite text analyzer from the factory
34+
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> Analyzer() noexcept;
35+
36+
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFallback> SystemFontFallback();
37+
38+
[[nodiscard]] til::size GlyphCell() noexcept;
39+
[[nodiscard]] LineMetrics GetLineMetrics() noexcept;
40+
41+
// The DirectWrite format object representing the size and other text properties to be applied (by default)
42+
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteTextFormat> DefaultTextFormat() noexcept;
43+
44+
// The DirectWrite font face to use while calculating layout (by default)
45+
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFace1> DefaultFontFace() noexcept;
46+
47+
// Box drawing scaling effects that are cached for the base font across layouts
48+
[[nodiscard]] Microsoft::WRL::ComPtr<IBoxDrawingEffect> DefaultBoxDrawingEffect() noexcept;
49+
50+
// The italic variant of the format object representing the size and other text properties for italic text
51+
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteTextFormat> ItalicTextFormat() noexcept;
52+
53+
// The italic variant of the font face to use while calculating layout for italic text
54+
[[nodiscard]] Microsoft::WRL::ComPtr<IDWriteFontFace1> ItalicFontFace() noexcept;
55+
56+
[[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& desired, FontInfo& fiFontInfo, const int dpi) noexcept;
57+
58+
[[nodiscard]] static HRESULT STDMETHODCALLTYPE s_CalculateBoxEffect(IDWriteTextFormat* format, size_t widthPixels, IDWriteFontFace1* face, float fontScale, IBoxDrawingEffect** effect) noexcept;
59+
60+
private:
61+
[[nodiscard]] ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _ResolveFontFaceWithFallback(std::wstring& familyName,
62+
DWRITE_FONT_WEIGHT& weight,
63+
DWRITE_FONT_STRETCH& stretch,
64+
DWRITE_FONT_STYLE& style,
65+
std::wstring& localeName) const;
66+
67+
[[nodiscard]] ::Microsoft::WRL::ComPtr<IDWriteFontFace1> _FindFontFace(std::wstring& familyName,
68+
DWRITE_FONT_WEIGHT& weight,
69+
DWRITE_FONT_STRETCH& stretch,
70+
DWRITE_FONT_STYLE& style,
71+
std::wstring& localeName) const;
72+
73+
[[nodiscard]] std::wstring _GetFontFamilyName(gsl::not_null<IDWriteFontFamily*> const fontFamily,
74+
std::wstring& localeName) const;
75+
76+
// A locale that can be used on construction of assorted DX objects that want to know one.
77+
[[nodiscard]] std::wstring _GetUserLocaleName();
78+
79+
::Microsoft::WRL::ComPtr<IDWriteFactory1> _dwriteFactory;
80+
81+
::Microsoft::WRL::ComPtr<IDWriteTextAnalyzer1> _dwriteTextAnalyzer;
82+
::Microsoft::WRL::ComPtr<IDWriteTextFormat> _dwriteTextFormat;
83+
::Microsoft::WRL::ComPtr<IDWriteTextFormat> _dwriteTextFormatItalic;
84+
::Microsoft::WRL::ComPtr<IDWriteFontFace1> _dwriteFontFace;
85+
::Microsoft::WRL::ComPtr<IDWriteFontFace1> _dwriteFontFaceItalic;
86+
87+
::Microsoft::WRL::ComPtr<IBoxDrawingEffect> _boxDrawingEffect;
88+
89+
::Microsoft::WRL::ComPtr<IDWriteFontFallback> _systemFontFallback;
90+
std::wstring _userLocaleName;
91+
92+
til::size _glyphCell;
93+
94+
LineMetrics _lineMetrics;
95+
};
96+
}

0 commit comments

Comments
 (0)