neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
font.hpp
Go to the documentation of this file.
1// font.hpp
2/*
3 neogfx C++ App/Game Engine
4 Copyright (c) 2015, 2020 Leigh Johnston. All Rights Reserved.
5
6 This program is free software: you can redistribute it and / or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#pragma once
21
22#include <neogfx/neogfx.hpp>
23#include <neolib/core/jar.hpp>
27
28namespace neogfx
29{
30 class i_native_font_face;
31 struct glyph_char;
32 class i_glyph;
33
34 enum class font_style : uint32_t
35 {
36 Invalid = 0x00000000,
37 Normal = 0x00000001,
38 Italic = 0x00000002,
39 Bold = 0x00000004,
40 Underline = 0x00000008,
41 Superscript = 0x00000010,
42 Subscript = 0x00000020,
43 BelowAscenderLine = 0x00000040,
44 AboveBaseline = 0x00000040,
45 Strike = 0x00000100,
46 Emulated = 0x80000000,
54 };
55
56 inline constexpr font_style operator~(font_style aLhs)
57 {
58 return static_cast<font_style>(~static_cast<uint32_t>(aLhs));
59 }
60
61 inline constexpr font_style operator|(font_style aLhs, font_style aRhs)
62 {
63 return static_cast<font_style>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
64 }
65
66 inline constexpr font_style operator&(font_style aLhs, font_style aRhs)
67 {
68 return static_cast<font_style>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
69 }
70
71 inline constexpr font_style operator^(font_style aLhs, font_style aRhs)
72 {
73 return static_cast<font_style>(static_cast<uint32_t>(aLhs) ^ static_cast<uint32_t>(aRhs));
74 }
75
76 inline constexpr font_style& operator|=(font_style& aLhs, font_style aRhs)
77 {
78 return aLhs = static_cast<font_style>(static_cast<uint32_t>(aLhs) | static_cast<uint32_t>(aRhs));
79 }
80
81 inline constexpr font_style& operator&=(font_style& aLhs, font_style aRhs)
82 {
83 return aLhs = static_cast<font_style>(static_cast<uint32_t>(aLhs) & static_cast<uint32_t>(aRhs));
84 }
85
86 inline constexpr font_style& operator^=(font_style& aLhs, font_style aRhs)
87 {
88 return aLhs = static_cast<font_style>(static_cast<uint32_t>(aLhs) ^ static_cast<uint32_t>(aRhs));
89 }
90}
91
100declare_enum_string(neogfx::font_style, BelowAscenderLine)
104declare_enum_string(neogfx::font_style, BoldItalicUnderline)
109declare_enum_string(neogfx::font_style, EmulatedBoldItalic)
111
112namespace neogfx
113{
114 enum class font_weight : uint32_t
115 {
116 Unknown = 0,
117 Thin = 100,
118 Extralight = 200,
119 Ultralight = 200,
120 Light = 300,
121 Normal = 400,
122 Regular = 400,
123 Medium = 500,
124 Semibold = 600,
125 Demibold = 600,
126 Bold = 700,
127 Extrabold = 800,
128 Ultrabold = 800,
129 Heavy = 900,
130 Black = 900
131 };
132
133 class font_info
134 {
135 // exceptions
136 public:
137 struct unknown_style : std::logic_error { unknown_style() : std::logic_error("neogfx::font_info::unknown_style") {} };
138 struct unknown_style_name : std::logic_error { unknown_style_name() : std::logic_error("neogfx::font_info::unknown_style_name") {} };
139 // types
140 public:
141 typedef font_info abstract_type; // todo
142 typedef double point_size;
143 private:
144 typedef std::optional<font_style> optional_style;
145 typedef std::optional<string> optional_style_name;
146 private:
147 class instance;
148 public:
149 font_info();
150 font_info(std::string const& aFamilyName, font_style aStyle, point_size aSize);
151 font_info(std::string const& aFamilyName, std::string const& aStyleName, point_size aSize);
152 font_info(std::string const& aFamilyName, font_style aStyle, std::string const& aStyleName, point_size aSize);
153 font_info(const font_info& aOther);
154 virtual ~font_info();
155 font_info& operator=(const font_info& aOther);
156 private:
157 font_info(std::string const& aFamilyName, const optional_style& aStyle, const optional_style_name& aStyleName, point_size aSize);
158 public:
159 virtual i_string const& family_name() const;
160 virtual bool style_available() const;
161 virtual font_style style() const;
162 virtual bool style_name_available() const;
163 virtual i_string const& style_name() const;
164 virtual bool underline() const;
165 virtual void set_underline(bool aUnderline);
166 virtual font_weight weight() const;
167 virtual point_size size() const;
168 virtual bool kerning() const;
169 virtual void enable_kerning();
170 virtual void disable_kerning();
171 public:
172 font_info with_style(font_style aStyle) const;
173 font_info with_style_xor(font_style aStyle) const;
174 font_info with_underline(bool aUnderline) const;
175 font_info with_size(point_size aSize) const;
176 public:
177 bool operator==(const font_info& aRhs) const;
178 bool operator<(const font_info& aRhs) const;
179 std::strong_ordering operator<=>(const font_info& aRhs) const;
180 public:
181 static font_weight weight_from_style(font_style aStyle);
182 static font_weight weight_from_style_name(std::string aStyleName, bool aUnknownAsRegular = true);
183 private:
184 mutable std::shared_ptr<instance> iInstance;
185 };
186
187 typedef optional<font_info> optional_font_info;
188
189 typedef neolib::small_cookie font_id;
190
191 // todo: abstract font
192 class font : public font_info
193 {
194 friend class font_manager;
195 friend class graphics_context;
196 // exceptions
197 public:
198 struct no_fallback_font : std::logic_error { no_fallback_font() : std::logic_error("neogfx::font::no_fallback_font") {} };
199 // types
200 public:
201 typedef font abstract_type; // todo
202 private:
203 class instance;
204 // construction
205 public:
206 font();
207 font(std::string const& aFamilyName, font_style aStyle, point_size aSize);
208 font(std::string const& aFamilyName, std::string const& aStyleName, point_size aSize);
209 font(const font_info& aFontInfo);
210 font(const font& aOther);
211 font(const font& aOther, font_style aStyle, point_size aSize);
212 font(const font& aOther, std::string const& aStyleName, point_size aSize);
213 static font load_from_file(std::string const& aFileName);
214 static font load_from_file(std::string const& aFileName, font_style aStyle, point_size aSize);
215 static font load_from_file(std::string const& aFileName, std::string const& aStyleName, point_size aSize);
216 static font load_from_memory(const void* aData, std::size_t aSizeInBytes);
217 static font load_from_memory(const void* aData, std::size_t aSizeInBytes, font_style aStyle, point_size aSize);
218 static font load_from_memory(const void* aData, std::size_t aSizeInBytes, std::string const& aStyleName, point_size aSize);
219 ~font();
220 font& operator=(const font& aOther);
221 private:
222 font(i_native_font_face& aNativeFontFace);
223 font(i_native_font_face& aNativeFontFace, font_style aStyle);
224 public:
225 font_id id() const;
226 public:
227 bool has_fallback() const;
228 font fallback() const;
229 // operations
230 public:
231 i_string const& family_name() const override;
232 font_style style() const override;
233 i_string const& style_name() const override;
234 point_size size() const override;
235 neogfx::size em_size() const;
236 dimension height() const;
237 dimension max_advance() const;
238 dimension ascender() const;
239 dimension descender() const;
240 dimension line_spacing() const;
241 using font_info::kerning;
242 dimension kerning(uint32_t aLeftGlyphIndex, uint32_t aRightGlyphIndex) const;
243 bool is_bitmap_font() const;
244 uint32_t num_fixed_sizes() const;
245 point_size fixed_size(uint32_t aFixedSizeIndex) const;
246 public:
247 const i_glyph& glyph(const glyph_char& aGlyphChar) const;
248 public:
249 bool operator==(const font& aRhs) const;
250 bool operator<(const font& aRhs) const;
251 std::strong_ordering operator<=>(const font& aRhs) const;
252 public:
253 i_native_font_face& native_font_face() const;
254 // attributes
255 private:
256 mutable std::shared_ptr<instance> iInstance;
257 };
258
259 typedef optional<font> optional_font;
260
261 template <typename Elem, typename Traits>
262 inline std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& aStream, const font_info& aFont)
263 {
264 aStream << "[";
265 aStream << aFont.family_name();
266 aStream << ",";
267 if (aFont.style_available())
268 aStream << aFont.style();
269 else
270 aStream << aFont.style_name();
271 aStream << ", ";
272 aStream << aFont.size();
273 aStream << ", ";
274 aStream << aFont.underline();
275 aStream << ", ";
276 aStream << aFont.kerning();
277 aStream << "]";
278 return aStream;
279 }
280
281 template <typename Elem, typename Traits>
282 inline std::basic_istream<Elem, Traits>& operator>>(std::basic_istream<Elem, Traits>& aStream, font_info& aFont)
283 {
284 std::string familyName;
285 std::variant<font_style, std::string> style;
286 font_info::point_size size;
287 bool underline;
288 bool kerning;
289
290 auto previousImbued = aStream.getloc();
291 if (typeid(std::use_facet<std::ctype<char>>(previousImbued)) != typeid(neolib::comma_only_whitespace))
292 aStream.imbue(std::locale{ previousImbued, new neolib::comma_only_whitespace{} });
293 char ignore;
294 aStream >> ignore;
295 aStream >> familyName;
296 std::string string;
297 aStream >> string;
298 try
299 {
301 }
302 catch (...)
303 {
304 style = string;
305 }
306 aStream.imbue(std::locale{ previousImbued, new neolib::comma_as_whitespace{} });
307 aStream >> size;
308 aStream >> underline;
309 aStream >> kerning;
310 aStream >> ignore;
311 aStream.imbue(previousImbued);
312
313 if (std::holds_alternative<font_style>(style))
314 aFont = font_info{ familyName, std::get<font_style>(style), size };
315 else
316 aFont = font_info{ familyName, std::get<std::string>(style), size };
317 aFont.set_underline(underline);
318 if (kerning)
319 aFont.enable_kerning();
320 else
321 aFont.disable_kerning();
322
323 return aStream;
324 }
325}
326
327define_setting_type_as(neogfx::font_info, neogfx::font)
#define end_declare_enum(enumName)
Definition i_enum.hpp:62
#define declare_enum_string(enumName, enumEnumerator)
Definition i_enum.hpp:59
#define begin_declare_enum(enumName)
Definition i_enum.hpp:52
#define define_setting_type_as(T, Name)
std::basic_ostream< Elem, Traits > & operator<<(std::basic_ostream< Elem, Traits > &aStream, const basic_point< T > &aPoint)
uint32_t id
constexpr font_style & operator&=(font_style &aLhs, font_style aRhs)
Definition font.hpp:81
constexpr style_aspect operator&(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:60
bool underline(glyph_char const &g)
audio_channel operator^(audio_channel lhs, audio_channel rhs)
audio_channel operator~(audio_channel lhs)
default_geometry_value_type dimension
std::basic_istream< Elem, Traits > & operator>>(std::basic_istream< Elem, Traits > &aStream, basic_point< T > &aPoint)
bool operator<(const basic_rect< CoordinateType, CoordinateSystem > &left, const basic_rect< CoordinateType, CoordinateSystem > &right)
bool operator==(const basic_rect< CoordinateType, CoordinateSystem > &left, const basic_rect< CoordinateType, CoordinateSystem > &right)
constexpr font_style & operator|=(font_style &aLhs, font_style aRhs)
Definition font.hpp:76
constexpr style_aspect operator|(style_aspect aLhs, style_aspect aRhs)
Definition i_style.hpp:55
void set_underline(glyph_char &g, bool aUnderline)
constexpr font_style & operator^=(font_style &aLhs, font_style aRhs)
Definition font.hpp:86
std::partial_ordering operator<=>(const gradient &aLhs, const gradient &aRhs)
Definition gradient.hpp:189
basic_size< coordinate > size
font_style
Definition font.hpp:35
ref_ptr< ConcreteType > make_ref(Args &&... args)
uint16_t small_cookie
Definition i_jar.hpp:45
Definition plf_hive.h:79