Line data Source code
1 : /**
2 : Copyright (c) 2024 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef CORE_FONT_SPFONT_H_
24 : #define CORE_FONT_SPFONT_H_
25 :
26 : #include "SPMemory.h"
27 : #include "SPGeometry.h"
28 : #include "SPVec2.h"
29 : #include "SPColor.h"
30 :
31 : namespace STAPPLER_VERSIONIZED stappler::font {
32 :
33 :
34 : namespace config {
35 :
36 : constexpr bool FontPreloadGroups = false;
37 : constexpr size_t UnicodePlanes = 16;
38 :
39 : }
40 :
41 :
42 : struct CharVector final {
43 : void addChar(char32_t);
44 : void addString(const StringView &);
45 : void addString(const WideStringView &);
46 : void addString(const CharVector &);
47 :
48 : bool empty() const {
49 : return !chars.empty();
50 : }
51 :
52 : mem_std::Vector<char32_t> chars;
53 : };
54 :
55 : using FontLayoutId = ValueWrapper<uint16_t, class FontLayoutIdTag>;
56 :
57 : enum CharAnchor : uint32_t {
58 : BottomLeft,
59 : TopLeft,
60 : TopRight,
61 : BottomRight
62 : };
63 :
64 : struct Metrics final {
65 : uint16_t size = 0; // font size in pixels
66 : uint16_t height = 0; // default font line height
67 : int16_t ascender = 0; // The distance from the baseline to the highest coordinate used to place an outline point
68 : int16_t descender = 0; // The distance from the baseline to the lowest grid coordinate used to place an outline point
69 : int16_t underlinePosition = 0;
70 : int16_t underlineThickness = 0;
71 : };
72 :
73 : struct CharId {
74 : static constexpr uint32_t CharMask = 0x0000FFFFU;
75 : static constexpr uint32_t AnchorMask = 0x00030000U;
76 : static constexpr uint32_t SourceMask = 0xFFFC0000U;
77 : static constexpr uint32_t SourceMax = (SourceMask >> 18);
78 :
79 : static uint32_t getCharId(uint16_t sourceId, char16_t, CharAnchor);
80 : static uint32_t rebindCharId(uint32_t, CharAnchor);
81 : static CharAnchor getAnchorForChar(uint32_t);
82 :
83 : uint32_t layout : 14;
84 : uint32_t anchor : 2;
85 : uint32_t value : 16;
86 :
87 : CharId(uint32_t v) {
88 : memcpy(this, &v, sizeof(uint32_t));
89 : }
90 :
91 : CharId(uint16_t l, char16_t ch, CharAnchor a)
92 : : layout(l), anchor(toInt(a)), value(ch) { }
93 :
94 : operator uint32_t () const {
95 : uint32_t ret;
96 : memcpy(&ret, this, sizeof(uint32_t));
97 : return ret;
98 : }
99 : };
100 :
101 : struct CharShape final {
102 : char16_t charID = 0;
103 : uint16_t xAdvance = 0;
104 :
105 1569144 : operator char16_t() const { return charID; }
106 : };
107 :
108 : struct CharTexture final {
109 : char32_t charID = 0;
110 :
111 : int16_t x = 0;
112 : int16_t y = 0;
113 :
114 : uint16_t width = 0;
115 : uint16_t height = 0;
116 : uint16_t bitmapWidth = 0;
117 : uint16_t bitmapRows = 0;
118 : int16_t pitch = 0;
119 :
120 : uint16_t fontID = 0;
121 :
122 : uint8_t *bitmap;
123 : };
124 :
125 : struct FontAtlasValue {
126 : geom::Vec2 pos;
127 : geom::Vec2 tex;
128 : };
129 :
130 : template <typename Value>
131 : struct FontCharStorage {
132 : using CellType = std::array<Value, 256>;
133 :
134 6716 : FontCharStorage() {
135 6716 : cells.fill(nullptr);
136 6716 : }
137 :
138 6716 : ~FontCharStorage() {
139 1726012 : for (auto &it : cells) {
140 1719296 : if (it) {
141 3134 : delete it;
142 3134 : it = nullptr;
143 : }
144 : }
145 6716 : }
146 :
147 78131 : void emplace(char16_t ch, Value &&value) {
148 78131 : auto cellId = ch / 256;
149 78131 : if (!cells[cellId]) {
150 3134 : cells[cellId] = new CellType;
151 3134 : memset(cells[cellId]->data(), 0, cells[cellId]->size() * sizeof(Value));
152 : }
153 :
154 78131 : (*cells[cellId])[ch % 256] = move(value);
155 78131 : }
156 :
157 2157856 : const Value *get(char16_t ch) const {
158 2157856 : auto cellId = ch / 256;
159 2157856 : auto cell = cells[cellId];
160 2157852 : if (!cell) {
161 6268 : return nullptr;
162 : }
163 2151584 : return &(cell->at(ch % 256));
164 : }
165 :
166 : template <typename Callback>
167 0 : void foreach(const Callback &cb) {
168 0 : for (auto &it : cells) {
169 0 : if (it) {
170 0 : for (auto &iit : *it) {
171 0 : cb(iit);
172 : }
173 : }
174 : }
175 0 : }
176 :
177 : std::array<CellType *, 256> cells;
178 : };
179 :
180 : inline bool operator< (const CharShape &l, const CharShape &c) { return l.charID < c.charID; }
181 : inline bool operator> (const CharShape &l, const CharShape &c) { return l.charID > c.charID; }
182 : inline bool operator<= (const CharShape &l, const CharShape &c) { return l.charID <= c.charID; }
183 : inline bool operator>= (const CharShape &l, const CharShape &c) { return l.charID >= c.charID; }
184 :
185 : inline bool operator< (const CharShape &l, const char16_t &c) { return l.charID < c; }
186 : inline bool operator> (const CharShape &l, const char16_t &c) { return l.charID > c; }
187 : inline bool operator<= (const CharShape &l, const char16_t &c) { return l.charID <= c; }
188 : inline bool operator>= (const CharShape &l, const char16_t &c) { return l.charID >= c; }
189 :
190 : }
191 :
192 : #endif /* CORE_FONT_SPFONT_H_ */
|