wxMaxima
FontAttribs.h
1 // -*- mode: c++; c-file-style: "linux"; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 //
3 // Copyright (C) 2020 Kuba Ober <kuba@mareimbrium.org>
4 //
5 // Everyone is permitted to copy and distribute verbatim copies
6 // of this licence document, but changing it is not allowed.
7 //
8 // WXWINDOWS LIBRARY LICENCE
9 // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
10 //
11 // This library is free software; you can redistribute it and/or modify it
12 // under the terms of the GNU Library General Public Licence as published by
13 // the Free Software Foundation; either version 2 of the Licence, or (at your
14 // option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful, but WITHOUT
17 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
19 // Licence for more details.
20 //
21 // You should have received a copy of the GNU Library General Public Licence
22 // along with this software, usually in a file named COPYING.LIB. If not,
23 // write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
24 // Floor, Boston, MA 02110-1301 USA.
25 //
26 // EXCEPTION NOTICE
27 //
28 // 1. As a special exception, the copyright holders of this library give
29 // permission for additional uses of the text contained in this release of the
30 // library as licenced under the wxWindows Library Licence, applying either
31 // version 3.1 of the Licence, or (at your option) any later version of the
32 // Licence as published by the copyright holders of version 3.1 of the Licence
33 // document.
34 //
35 // 2. The exception is that you may use, copy, link, modify and distribute
36 // under your own terms, binary object code versions of works based on the
37 // Library.
38 //
39 // 3. If you copy code from files distributed under the terms of the GNU
40 // General Public Licence or the GNU Library General Public Licence into a
41 // copy of this library, as this licence permits, the exception does not apply
42 // to the code that you add in this way. To avoid misleading anyone as to the
43 // status of such modified files, you must delete this exception notice from
44 // such code and/or adjust the licensing conditions notice accordingly.
45 //
46 // 4. If you write modifications of your own for this library, it is your
47 // choice whether to permit this exception to apply to your modifications. If
48 // you do not wish that, you must delete the exception notice from such code
49 // and/or adjust the licensing conditions notice accordingly.
50 //
51 // SPDX-License-Identifier: wxWindows
52 
53 #ifndef WXMAXIMA_FONTATTRIBS_H
54 #define WXMAXIMA_FONTATTRIBS_H
55 
56 #include "EnumWrapper.h"
57 #include "stx/clamp.hpp"
58 #include <wx/font.h>
59 #include <wx/version.h>
60 #include <algorithm>
61 #include <cstdint>
62 #include <functional>
63 #include <limits>
64 
69 
97 class AFontSize final
98 {
99  constexpr static float Size_Unit = 0.05f;
100 
101 public:
102  using value_type = int16_t;
103 
104  constexpr static float Minimum_Size = 4.0f;
105  constexpr static float Maximum_Size = std::numeric_limits<value_type>::max() * Size_Unit;
106 
107  constexpr AFontSize() = default;
108  constexpr explicit AFontSize(float size) : m_uSize(ToUSize(size)) {}
109  constexpr AFontSize(AFontSize minimum, double size) : m_uSize(std::max(minimum.m_uSize, ToUSize(float(size)))) {}
110  constexpr AFontSize(AFontSize minimum, AFontSize size) : m_uSize(std::max(minimum.m_uSize, size.m_uSize)) {}
111  constexpr AFontSize(const AFontSize &o) = default;
112 
113  constexpr void Set(float size) { m_uSize = ToUSize(size); }
114  constexpr void Clear() { m_uSize = {}; }
115  // Old cppcheck bugs:
116  // cppcheck-suppress operatorEq
117  constexpr AFontSize &operator=(const AFontSize &o) = default;
118 
119  constexpr bool operator==(AFontSize o) const { return m_uSize == o.m_uSize; }
120  constexpr bool operator!=(AFontSize o) const { return m_uSize != o.m_uSize; }
121  constexpr bool operator<(AFontSize o) const { return m_uSize < o.m_uSize; }
122  constexpr bool operator>(AFontSize o) const { return m_uSize > o.m_uSize; }
123  constexpr float Get() const { return IsValid() ? m_uSize * Size_Unit : Minimum_Size; }
124  constexpr long GetAsLong() const { return long(Get() + 0.5f); }
125  constexpr auto GetForWX() const;
126  constexpr bool IsNull() const { return !IsValid(); }
127  constexpr bool IsValid() const { return m_uSize > 0; }
128  constexpr bool IsMinimal() const { return m_uSize == ToUSize(Minimum_Size); }
129 
130  struct Equals {
131  bool operator()(AFontSize l, AFontSize r) const { return l == r; }
132  };
133 
134 private:
135  friend struct std::hash<AFontSize>;
136  friend bool EqualToWithin(AFontSize, AFontSize, float);
137  value_type m_uSize = {};
138  constexpr static value_type ToUSize(float size);
139 };
140 
141 // The "namespace std" ships around a g++ bug, as described in
142 // https://stackoverflow.com/questions/25594644/warning-specialization-of-template-in-different-namespace/25594681#25594681
143 namespace std
144 {
145  template <> struct hash<AFontSize> final
146  {
147  size_t operator()(AFontSize name) const { return std::hash<int16_t>()(name.m_uSize); }
148  };
149 }
150 
151 constexpr double operator*(double factor, AFontSize size) { return factor * size.Get(); }
152 constexpr double operator*(AFontSize size, double factor) { return size.Get() * factor; }
153 constexpr double operator/(double dividend, AFontSize size) { return dividend / size.Get(); }
154 constexpr double operator/(AFontSize size, double divisor) { return size.Get() / divisor; }
155 constexpr double operator+(double offset, AFontSize size) { return offset + size.Get(); }
156 constexpr double operator+(AFontSize size, double offset) { return size.Get() + offset; }
157 constexpr double operator-(double offset, AFontSize size) { return offset - size.Get(); }
158 constexpr double operator-(AFontSize size, double offset) { return size.Get() - offset; }
159 constexpr AFontSize operator-=(AFontSize &size, double factor) { return size.Set(float(size - factor)), size; }
160 
161 constexpr AFontSize::value_type AFontSize::ToUSize(float size)
162 {
163  return AFontSize::value_type(stx::clamp(size, Minimum_Size, Maximum_Size) / Size_Unit + 0.5f);
164 }
165 
167 constexpr auto AFontSize::GetForWX() const
168 {
169 #if wxCHECK_VERSION(3,1,2)
170  return Get();
171 #else
172  return GetAsLong();
173 #endif
174 }
175 
177 bool EqualToWithin(AFontSize left, AFontSize right, float limit);
178 
179 #endif
EnumWrapper< wxFontEncoding, int16_t, wxFONTENCODING_DEFAULT >
AFontSize::GetForWX
constexpr auto GetForWX() const
Get the numerical value suitable for passing to wxFont/wxFontInfo.
Definition: FontAttribs.h:167
AFontSize::Equals
Definition: FontAttribs.h:130
AFontSize
Definition: FontAttribs.h:97
AFontSize::EqualToWithin
friend bool EqualToWithin(AFontSize, AFontSize, float)
Whether the difference between to font sizes is below a provided limit value.
Definition: FontAttribs.cpp:63