wxMaxima
TextStyle.h
Go to the documentation of this file.
1 // -*- mode: c++; c-file-style: "linux"; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 //
3 // Copyright (C) 2004-2015 Andrej Vodopivec <andrej.vodopivec@gmail.com>
4 // Copyright (C) 2020 Kuba Ober <kuba@mareimbrium.org>
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 2 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 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // SPDX-License-Identifier: GPL-2.0+
22 
23 #ifndef TEXTSTYLE_H
24 #define TEXTSTYLE_H
25 
26 #include "precomp.h"
27 
33 #include <wx/colour.h>
34 #include <wx/config.h>
35 #include <wx/font.h>
36 #include <wx/settings.h>
37 #include <cstdint>
38 #include <functional>
39 #include "FontAttribs.h"
40 
54 class AFontName final
55 {
56  using AFN = AFontName;
57 public:
58  AFontName() = default;
64  explicit AFontName(const wxString &fontName) : m_fontName(Intern(fontName)) {}
65  AFontName(const AFontName &o) : m_fontName(o.m_fontName) {}
66  operator const wxString &() const { return GetAsString(); }
67  bool operator==(const AFontName &o) const { return m_fontName == o.m_fontName; }
68  bool operator<(const AFontName &o) const { return m_fontName < o.m_fontName; }
69  bool empty() const { return !m_fontName || m_fontName->empty(); }
70  AFontName &operator=(const AFontName &o)
71  {
72  m_fontName = o.m_fontName;
73  return *this;
74  }
75  AFontName &Set(const wxString &str)
76  {
77  m_fontName = Intern(str);
78  return *this;
79  }
80  const wxString& GetAsString() const { return m_fontName ? *m_fontName : *GetInternedEmpty(); }
81 
82  // All constant font names should be collected here, to avoid needless duplication and
83  // lookups.
84  static AFontName Linux_Libertine_O() { static auto n = AFN(wxT("Linux Libertine O")); return n; }
85  static AFontName Linux_Libertine_G() { static auto n = AFN(wxT("Linux Libertine G")); return n; }
86  static AFontName Linux_Libertine() { static auto n = AFN(wxT("Linux Libertine")); return n; }
87  static AFontName Times_New_Roman() { static auto n = AFN(wxT("Times New Roman")); return n; }
88  static AFontName Monaco() { static auto n = AFN(wxT("Monaco")); return n; }
89  static AFontName Arial() { static auto n = AFN(wxT("Arial")); return n; }
90  static AFontName Symbol() { static auto n = AFN(wxT("Symbol")); return n; }
91  static AFontName CMEX10() { static auto n = AFN(wxT("jsMath-cmex10")); return n; }
92  static AFontName CMSY10() { static auto n = AFN(wxT("jsMath-cmsy10")); return n; }
93  static AFontName CMR10() { static auto n = AFN(wxT("jsMath-cmr10")); return n; }
94  static AFontName CMMI10() { static auto n = AFN(wxT("jsMath-cmmi10")); return n; }
95  static AFontName CMTI10() { static auto n = AFN(wxT("jsMath-cmti10")); return n; }
96 
97 private:
98  friend class FontCache;
99  friend struct std::hash<AFontName>;
100  const wxString *m_fontName = {};
101 
102  static const wxString *Intern(const wxString &str);
103  static const wxString *GetInternedEmpty();
104 };
105 
106 namespace std {
107 template <> struct hash<AFontName> final
108 {
109  size_t operator()(AFontName name) const
110  {
111  return hash<const void*>()(name.m_fontName);
112  }
113 };
114 }
115 
117 static constexpr uint32_t MAKE_RGB(uint32_t r, uint32_t g, uint32_t b)
118 { return (0xFF & r) | ((0xFF & g) << 8) | ((0xFF & b) << 16); }
119 
130 class Style final
131 {
132 public:
133  Style() = default;
134  Style(const Style &);
135  explicit Style(AFontSize fontSize) { m.fontSize = fontSize; }
136 
137  Style &operator=(const Style &);
138  bool operator==(const Style &o) const = delete;
139 
144  Style &Read(wxConfigBase *config, const wxString &where);
146  void Write(wxConfigBase *config, const wxString &where) const;
147 
149  static const Style &FromFont(const wxFont &font);
151  static const Style &FromStockFont(wxStockGDI::Item font);
152 
153  constexpr static wxFontFamily Default_Family{wxFONTFAMILY_DEFAULT};
154  constexpr static wxFontEncoding Default_Encoding{wxFONTENCODING_DEFAULT};
155  constexpr static wxFontWeight Default_Weight{wxFONTWEIGHT_NORMAL};
156  constexpr static wxFontStyle Default_FontStyle{wxFONTSTYLE_NORMAL};
157  constexpr static bool Default_Underlined{false};
158  constexpr static bool Default_Strikethrough{false};
159  constexpr static AFontSize Default_FontSize{10.0f};
160  constexpr static uint32_t Default_ColorRGB{MAKE_RGB(0, 0, 0)};
161  static AFontName Default_FontName();
162  static const wxColor &Default_Color();
163 
164  wxFontFamily GetFamily() const;
165  wxFontEncoding GetEncoding() const;
166  wxFontWeight GetWeight() const;
167  bool IsBold() const { return GetWeight() == wxFONTWEIGHT_BOLD; }
168  bool IsLight() const { return GetWeight() == wxFONTWEIGHT_LIGHT; }
169  wxFontStyle GetFontStyle() const;
170  bool IsItalic() const { return GetFontStyle() == wxFONTSTYLE_ITALIC; }
171  bool IsSlant() const { return GetFontStyle() == wxFONTSTYLE_SLANT; }
172  bool IsUnderlined() const;
173  bool IsStrikethrough() const;
174  AFontName GetFontName() const;
175  const wxString &GetNameStr() const;
176  AFontSize GetFontSize() const;
177  uint32_t GetRGBColor() const;
178  wxColor GetColor() const { return wxColor(GetRGBColor()); }
179 
180  using did_change = bool;
181  did_change SetFamily(wxFontFamily family);
182  did_change SetEncoding(wxFontEncoding encoding);
183  did_change SetWeight(wxFontWeight weight);
184  did_change SetBold(bool bold = true);
185  did_change SetLight(bool light = true);
186  did_change SetFontStyle(wxFontStyle style);
187  did_change SetItalic(bool italic = true);
188  did_change SetSlant(bool slant = true);
189  did_change SetUnderlined(bool underlined = true);
190  did_change SetStrikethrough(bool strikethrough = true);
191  did_change SetFontName(AFontName fontName);
192  did_change SetFontSize(AFontSize fontSize);
193  did_change SetRGBColor(uint32_t rgb);
194  did_change SetColor(const wxColor &color);
195  did_change SetColor(wxSystemColour sysColour);
196 
198  did_change ResolveToFont();
199 
200  Style& Family(wxFontFamily family) { return SetFamily(family), *this; }
201  Style& Encoding(wxFontEncoding encoding) { return SetEncoding(encoding), *this; }
202  Style& Weight(wxFontWeight weight) { return SetWeight(weight), *this; }
203  Style& FontStyle(wxFontStyle style) { return SetFontStyle(style), *this; }
204  Style& Bold(bool bold = true) { return SetBold(bold), *this; }
205  Style& Light(bool light = true) { return SetLight(light), *this; }
206  Style& Italic(bool italic = true) { return SetItalic(italic), *this; }
207  Style& Slant(bool slant = true) { return SetSlant(slant), *this; }
208  Style& Underlined(bool underlined = true) { return SetUnderlined(underlined), *this; }
209  Style& Strikethrough(bool strikethrough = true) { return SetStrikethrough(strikethrough), *this; }
210  Style& FontName(class AFontName fontName) { return SetFontName(fontName), *this; }
211  Style& FontSize(float size) { return SetFontSize(AFontSize(size)), *this; }
212  Style& FontSize(AFontSize fontSize) { return SetFontSize(fontSize), *this; }
213  Style& RGBColor(uint32_t rgb) { return SetRGBColor(rgb), *this; }
214  Style& Color(const wxColor &color) { return SetColor(color), *this; }
215  Style& Color(uint8_t r, uint8_t g, uint8_t b) { return SetColor({r, g, b}), *this; }
216  Style& Color(wxSystemColour sysColour) { return SetColor(sysColour), *this; }
217  Style& ChangeLightness(int alpha) { return SetColor(GetColor().ChangeLightness(alpha)), *this; }
218 
219  wxFontInfo GetAsFontInfo() const;
220 
221  bool IsFontLessThan(const Style &o) const { return GetFontHash() < o.GetFontHash(); }
222  bool IsFontEqualTo(const Style &) const;
223  bool IsStyleEqualTo(const Style &o) const;
224 
225  bool IsFontOk() const;
226  bool HasFontCached() const { return m.fontHash && m.font; }
227  const wxFont& GetFont() const { return HasFontCached() ? *m.font : LookupFont(); }
228 
230  did_change SetFromFont(const wxFont&);
232  did_change SetFontFrom(const Style&);
234  did_change SetFontFaceFrom(const Style&);
236  did_change SetFontFaceAndSizeFrom(const Style&);
237 
238  constexpr static bool IsFractionalFontSizeSupported() { return wxCHECK_VERSION(3,1,2); } //-V686 //-V501
239  static AFontSize GetFontSize(const wxFont &);
240  static void SetFontSize(wxFont &, AFontSize fontSize);
241 
242  wxString GetDump() const;
243 
244 private:
245  friend struct StyleFontHasher;
246  friend class FontCache;
247  Style &FromFontNoCache(const wxFont &);
248  void SetFromFontNoCache(const wxFont &);
249 
250  struct Data // POD, 40 bytes on 64-bit platforms
251  {
252  // 8/4-byte members
253  AFontName fontName = Default_FontName();
254  mutable const wxFont *font = nullptr;
255  mutable size_t fontHash = 0;
256  // 4-byte members
257  uint32_t rgbColor = Default_ColorRGB;
258  // 2-byte members
259  AFontSize fontSize = Default_FontSize;
260  AFontFamily family = Default_Family;
261  AFontEncoding encoding = Default_Encoding;
262  AFontWeight weight = Default_Weight;
263  AFontStyle fontStyle = Default_FontStyle;
264  // 1-byte members
265  bool underlined : 1;
266  bool strikethrough : 1;
267  bool isNotOK : 1;
268 
269  Data() : underlined(false), strikethrough(false), isNotOK(false) {}
270  static constexpr enum class NotOK_t {} NotOK = {};
271  // cppcheck-suppress noExplicitConstructor
272  Data(NotOK_t) : underlined(false), strikethrough(false), isNotOK(true) {}
273  } m;
274  static_assert(sizeof(Data) <= 40,
275  "Style::Data is misaligned and grew too big.");
276 
277  size_t GetFontHash() const;
278 
279  const wxFont& LookupFont() const;
280  // cppcheck-suppress noExplicitConstructor
281  Style(Data::NotOK_t) : m(Data::NotOK) {}
282 };
283 
285 struct StyleFontHasher final
286 {
287  size_t operator()(const Style &style) const { return style.GetFontHash(); }
288 };
289 
291 struct StyleFontLess final
292 {
293  bool operator()(const Style &l, const Style &r) const { return l.IsFontLessThan(r); }
294 };
295 
297 struct StyleFontEquals final
298 {
299  bool operator()(const Style &l, const Style &r) const { return l.IsFontEqualTo(r); }
300 };
301 
307 enum TextStyle : int8_t
308 {
309  TS_DEFAULT = 0,
310  TS_VARIABLE = 1,
311  TS_NUMBER = 2,
312  TS_FUNCTION = 3,
313  TS_SPECIAL_CONSTANT = 4,
314  TS_GREEK_CONSTANT = 5,
315  TS_STRING = 6,
316  TS_INPUT = 7,
317  TS_MAIN_PROMPT = 8,
318  TS_OTHER_PROMPT = 9,
319  TS_LABEL = 10,
320  TS_USERLABEL = 11,
321  TS_HIGHLIGHT = 12,
322  TS_WARNING = 13,
323  TS_ERROR = 14,
324  TS_ASCIIMATHS = 15,
325  TS_TEXT = 16,
326  TS_HEADING6 = 17,
327  TS_HEADING5 = 18,
328  TS_SUBSUBSECTION = 19,
329  TS_SUBSECTION = 20,
330  TS_SECTION = 21,
331  TS_TITLE = 22,
332  TS_TEXT_BACKGROUND = 23,
333  TS_DOCUMENT_BACKGROUND = 24,
334  TS_CELL_BRACKET = 25,
335  TS_ACTIVE_CELL_BRACKET = 26,
336  TS_CURSOR = 27,
337  TS_SELECTION = 28,
338  TS_EQUALSSELECTION = 29,
339  TS_OUTDATED = 30,
340  TS_CODE_VARIABLE = 31,
341  TS_CODE_FUNCTION = 32,
342  TS_CODE_COMMENT = 33,
343  TS_CODE_NUMBER = 34,
344  TS_CODE_STRING = 35,
345  TS_CODE_OPERATOR = 36,
346  TS_CODE_LISP = 37,
347  TS_CODE_ENDOFLINE = 38,
348  TS_MATH = 39, // custom font = math font
350 };
351 
352 #endif // TEXTSTYLE_H
Style::SetFontFaceAndSizeFrom
did_change SetFontFaceAndSizeFrom(const Style &)
Sets font-face and size only properties based on another style (not attributes like bold,...
Definition: TextStyle.cpp:353
NUMBEROFSTYLES
@ NUMBEROFSTYLES
This is not a style, but its value tells us how many styles are defined.
Definition: TextStyle.h:349
TextStyle
TextStyle
Definition: TextStyle.h:307
Style::SetFontFrom
did_change SetFontFrom(const Style &)
Sets all font-related properties based on another style, including size, font style and weight.
Definition: TextStyle.cpp:332
Style::SetFontFaceFrom
did_change SetFontFaceFrom(const Style &)
Sets font-face-only properties based on another style.
Definition: TextStyle.cpp:345
Style::Read
Style & Read(wxConfigBase *config, const wxString &where)
Definition: TextStyle.cpp:514
EnumWrapper< wxFontFamily, int16_t, wxFONTFAMILY_DEFAULT >
Style::SetFromFont
did_change SetFromFont(const wxFont &)
Sets all font-related properties based on another font.
Definition: TextStyle.cpp:329
AFontName
Definition: TextStyle.h:54
StyleFontHasher
Hash functor of the font size and attributes of the style.
Definition: TextStyle.h:285
Style::GetFontSize
AFontSize GetFontSize() const
The size of this style's font, asserted to be valid.
Definition: TextStyle.cpp:209
Style::FromStockFont
static const Style & FromStockFont(wxStockGDI::Item font)
Gets a style that represents a stock font. The font is pre-cached.
Definition: TextStyle.cpp:580
Style
Definition: TextStyle.h:130
Style::FromFont
static const Style & FromFont(const wxFont &font)
Gets a style that represents a given font. The font gets cached.
Definition: TextStyle.cpp:569
AFontSize
Definition: FontAttribs.h:97
FontCache
Definition: FontCache.h:36
Style::ResolveToFont
did_change ResolveToFont()
Resolves the style to the parameters of the font it represents.
Definition: TextStyle.cpp:321
Style::Write
void Write(wxConfigBase *config, const wxString &where) const
Write this style to a config source.
Definition: TextStyle.cpp:543
StyleFontEquals
Equals-comparator of the font size and attributes of the style.
Definition: TextStyle.h:297
StyleFontLess
Less-than-comparator of the font size and attributes of the style.
Definition: TextStyle.h:291
AFontName::AFontName
AFontName(const wxString &fontName)
Definition: TextStyle.h:64