-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
direct_write.h
160 lines (128 loc) · 6.1 KB
/
direct_write.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#pragma once
namespace uih::direct_write {
class TextLayout {
public:
TextLayout(wil::com_ptr_t<IDWriteFactory> factory, wil::com_ptr_t<IDWriteGdiInterop> gdi_interop,
wil::com_ptr_t<IDWriteTextLayout> text_layout, DWRITE_RENDERING_MODE rendering_mode,
bool force_greyscale_antialiasing)
: m_factory(std::move(factory))
, m_gdi_interop(std::move(gdi_interop))
, m_text_layout(std::move(text_layout))
, m_rendering_mode(rendering_mode)
, m_force_greyscale_antialiasing(force_greyscale_antialiasing)
{
}
float get_max_height() const noexcept;
float get_max_width() const noexcept;
DWRITE_TEXT_METRICS get_metrics() const;
DWRITE_OVERHANG_METRICS get_overhang_metrics() const;
void render_with_transparent_background(
HDC dc, RECT output_rect, COLORREF default_colour, float x_origin_offset = 0.0f) const;
void render_with_solid_background(HDC dc, float x_origin, float y_origin, RECT clip_rect,
COLORREF background_colour, COLORREF default_text_colour) const;
void set_colour(COLORREF colour, DWRITE_TEXT_RANGE text_range) const;
void set_max_height(float value) const;
void set_max_width(float value) const;
void set_underline(bool is_underlined, DWRITE_TEXT_RANGE text_range) const;
void set_font(const wchar_t* font_family, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STRETCH stretch,
DWRITE_FONT_STYLE style, float size, DWRITE_TEXT_RANGE text_range) const;
private:
wil::com_ptr_t<IDWriteRenderingParams> create_rendering_params() const;
wil::com_ptr_t<IDWriteFactory> m_factory;
wil::com_ptr_t<IDWriteGdiInterop> m_gdi_interop;
wil::com_ptr_t<IDWriteTextLayout> m_text_layout;
DWRITE_RENDERING_MODE m_rendering_mode{};
bool m_force_greyscale_antialiasing{};
};
struct TextPosition {
int left{};
float left_remainder_dip{};
int top{};
int width{};
int height{};
};
class TextFormat {
public:
TextFormat(std::shared_ptr<class Context> context, wil::com_ptr_t<IDWriteFactory> factory,
wil::com_ptr_t<IDWriteGdiInterop> gdi_interop, wil::com_ptr_t<IDWriteTextFormat> text_format,
DWRITE_RENDERING_MODE rendering_mode, bool force_greyscale_antialiasing)
: m_context(std::move(context))
, m_factory(std::move(factory))
, m_gdi_interop(std::move(gdi_interop))
, m_text_format(std::move(text_format))
, m_rendering_mode(rendering_mode)
, m_force_greyscale_antialiasing(force_greyscale_antialiasing)
{
}
void set_text_alignment(DWRITE_TEXT_ALIGNMENT value = DWRITE_TEXT_ALIGNMENT_LEADING) const;
void set_paragraph_alignment(DWRITE_PARAGRAPH_ALIGNMENT value) const;
void set_word_wrapping(DWRITE_WORD_WRAPPING value) const;
void enable_trimming_sign();
void disable_trimming_sign() const;
[[nodiscard]] int get_minimum_height(std::wstring_view text = std::wstring_view(L"", 0)) const;
[[nodiscard]] TextPosition measure_text_position(
std::wstring_view text, int height, float max_width = 65536.0f) const;
[[nodiscard]] int measure_text_width(std::wstring_view text) const;
[[nodiscard]] TextLayout create_text_layout(std::wstring_view text, float max_width, float max_height) const;
private:
std::shared_ptr<Context> m_context;
wil::com_ptr_t<IDWriteFactory> m_factory;
wil::com_ptr_t<IDWriteGdiInterop> m_gdi_interop;
wil::com_ptr_t<IDWriteTextFormat> m_text_format;
wil::com_ptr_t<IDWriteInlineObject> m_trimming_sign;
DWRITE_RENDERING_MODE m_rendering_mode{};
bool m_force_greyscale_antialiasing{};
};
struct Font {
wil::com_ptr_t<IDWriteFont> font;
std::wstring localised_name;
};
struct FontFamily {
wil::com_ptr_t<IDWriteFontFamily> family;
std::wstring localised_name;
bool is_symbol_font{};
std::vector<Font> fonts() const;
};
class Context : public std::enable_shared_from_this<Context> {
public:
using Ptr = std::shared_ptr<Context>;
static Ptr s_create()
{
auto ptr = s_ptr.lock();
if (!ptr) {
ptr = std::make_shared<Context>();
s_ptr = ptr;
}
return ptr;
}
Context();
const wil::com_ptr_t<IDWriteFactory1>& factory() { return m_factory; }
LOGFONT create_log_font(const wil::com_ptr_t<IDWriteFont>& font) const;
wil::com_ptr_t<IDWriteFont> create_font(const LOGFONT& log_font) const;
TextFormat create_text_format(const wil::com_ptr_t<IDWriteFont>& font, float font_size);
TextFormat create_text_format(const wil::com_ptr_t<IDWriteFontFamily>& font_family, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, float font_size);
TextFormat create_text_format(const wchar_t* family_name, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STRETCH stretch,
DWRITE_FONT_STYLE style, float font_size);
TextFormat create_text_format(const LOGFONT& log_font, float font_size);
std::optional<TextFormat> create_text_format_with_fallback(
const LOGFONT& log_font, std::optional<float> font_size = {}) noexcept;
TextFormat wrap_text_format(wil::com_ptr_t<IDWriteTextFormat> text_format,
DWRITE_RENDERING_MODE rendering_mode = DWRITE_RENDERING_MODE_DEFAULT, bool force_greyscale_antialiasing = false,
bool set_defaults = true);
wil::com_ptr_t<IDWriteTypography> get_default_typography();
std::optional<std::wstring> get_face_name(const wchar_t* family_name, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style) const;
std::vector<FontFamily> get_font_families() const;
private:
inline static std::weak_ptr<Context> s_ptr;
wil::com_ptr_t<IDWriteFactory1> m_factory;
wil::com_ptr_t<IDWriteGdiInterop> m_gdi_interop;
wil::com_ptr_t<IDWriteTypography> m_default_typography;
};
std::wstring get_localised_string(const wil::com_ptr_t<IDWriteLocalizedStrings>& localised_strings);
float get_default_scaling_factor();
float dip_to_px(float dip, float scaling_factor = get_default_scaling_factor());
float px_to_dip(float px, float scaling_factor = get_default_scaling_factor());
float pt_to_dip(float point_size);
} // namespace uih::direct_write