Branch data TLA Line data Source code
1 : : // Copyright (c) 2014-2022 Thomas Fussell
2 : : // Copyright (c) 2010-2015 openpyxl
3 : : // Copyright (c) 2024-2025 xlnt-community
4 : : //
5 : : // Permission is hereby granted, free of charge, to any person obtaining a copy
6 : : // of this software and associated documentation files (the "Software"), to deal
7 : : // in the Software without restriction, including without limitation the rights
8 : : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : : // copies of the Software, and to permit persons to whom the Software is
10 : : // furnished to do so, subject to the following conditions:
11 : : //
12 : : // The above copyright notice and this permission notice shall be included in
13 : : // all copies or substantial portions of the Software.
14 : : //
15 : : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : : // THE SOFTWARE
22 : : //
23 : : // @license: http://www.opensource.org/licenses/mit-license.php
24 : : // @author: see AUTHORS file
25 : :
26 : : #pragma once
27 : :
28 : : #include <cstring>
29 : : #include <functional>
30 : :
31 : : #include <xlnt/xlnt_config.hpp>
32 : : #include <xlnt/styles/color.hpp>
33 : : #include <xlnt/utils/optional.hpp>
34 : : #include <xlnt/utils/hash_combine.hpp>
35 : :
36 : : namespace xlnt {
37 : :
38 : : class style;
39 : :
40 : : /// <summary>
41 : : /// Describes the font style of a particular cell.
42 : : /// </summary>
43 : : class XLNT_API font
44 : : {
45 : : public:
46 : : /// <summary>
47 : : /// Text can be underlined in the enumerated ways
48 : : /// </summary>
49 : : enum class underline_style
50 : : {
51 : : none,
52 : : double_,
53 : : double_accounting,
54 : : single,
55 : : single_accounting
56 : : };
57 : :
58 : : /// <summary>
59 : : /// Constructs a default font. Calibri, size 12
60 : : /// </summary>
61 : : font();
62 : :
63 : : /// <summary>
64 : : /// Sets the bold state of the font to bold and returns a reference to the font.
65 : : /// </summary>
66 : : font &bold(bool bold);
67 : :
68 : : /// <summary>
69 : : /// Returns the bold state of the font.
70 : : /// </summary>
71 : : bool bold() const;
72 : :
73 : : /// <summary>
74 : : /// Sets the vertical alignment of the font to subscript and returns a reference to the font.
75 : : /// </summary>
76 : : font &subscript(bool value);
77 : :
78 : : /// <summary>
79 : : /// Returns true if this font has a vertical alignment of subscript.
80 : : /// </summary>
81 : : bool subscript() const;
82 : :
83 : : /// <summary>
84 : : /// Sets the vertical alignment of the font to superscript and returns a reference to the font.
85 : : /// </summary>
86 : : font &superscript(bool value);
87 : :
88 : : /// <summary>
89 : : /// Returns true if this font has a vertical alignment of superscript.
90 : : /// </summary>
91 : : bool superscript() const;
92 : :
93 : : /// <summary>
94 : : /// Sets the bold state of the font to bold and returns a reference to the font.
95 : : /// </summary>
96 : : font &italic(bool italic);
97 : :
98 : : /// <summary>
99 : : /// Returns true if this font has italics applied.
100 : : /// </summary>
101 : : bool italic() const;
102 : :
103 : : /// <summary>
104 : : /// Sets the bold state of the font to bold and returns a reference to the font.
105 : : /// </summary>
106 : : font &strikethrough(bool strikethrough);
107 : :
108 : : /// <summary>
109 : : /// Returns true if this font has a strikethrough applied.
110 : : /// </summary>
111 : : bool strikethrough() const;
112 : :
113 : : /// <summary>
114 : : /// Sets the bold state of the font to bold and returns a reference to the font.
115 : : /// </summary>
116 : : font &outline(bool outline);
117 : :
118 : : /// <summary>
119 : : /// Returns true if this font has an outline applied.
120 : : /// </summary>
121 : : bool outline() const;
122 : :
123 : : /// <summary>
124 : : /// Sets the shadow state of the font to shadow and returns a reference to the font.
125 : : /// </summary>
126 : : font &shadow(bool shadow);
127 : :
128 : : /// <summary>
129 : : /// Returns true if this font has a shadow applied.
130 : : /// </summary>
131 : : bool shadow() const;
132 : :
133 : : /// <summary>
134 : : /// Sets the underline state of the font to new_underline and returns a reference to the font.
135 : : /// </summary>
136 : : font &underline(underline_style new_underline);
137 : :
138 : : /// <summary>
139 : : /// Returns true if this font has any type of underline applied.
140 : : /// </summary>
141 : : bool underlined() const;
142 : :
143 : : /// <summary>
144 : : /// Returns the particular style of underline this font has applied.
145 : : /// </summary>
146 : : underline_style underline() const;
147 : :
148 : : /// <summary>
149 : : /// Returns true if this font has a defined size.
150 : : /// </summary>
151 : : bool has_size() const;
152 : :
153 : : /// <summary>
154 : : /// Sets the size of the font to size and returns a reference to the font.
155 : : /// </summary>
156 : : font &size(double size);
157 : :
158 : : /// <summary>
159 : : /// Returns the size of the font.
160 : : /// </summary>
161 : : double size() const;
162 : :
163 : : /// <summary>
164 : : /// Returns true if this font has a particular face applied (e.g. "Comic Sans").
165 : : /// </summary>
166 : : bool has_name() const;
167 : :
168 : : /// <summary>
169 : : /// Sets the font face to name and returns a reference to the font.
170 : : /// </summary>
171 : : font &name(const std::string &name);
172 : :
173 : : /// <summary>
174 : : /// Returns the name of the font face.
175 : : /// </summary>
176 : : const std::string &name() const;
177 : :
178 : : /// <summary>
179 : : /// Returns true if this font has a color applied.
180 : : /// </summary>
181 : : bool has_color() const;
182 : :
183 : : /// <summary>
184 : : /// Sets the color of the font to c and returns a reference to the font.
185 : : /// </summary>
186 : : font &color(const color &c);
187 : :
188 : : /// <summary>
189 : : /// Returns the color that this font is using.
190 : : /// </summary>
191 : : xlnt::color color() const;
192 : :
193 : : /// <summary>
194 : : /// Returns true if this font has a family defined.
195 : : /// </summary>
196 : : bool has_family() const;
197 : :
198 : : /// <summary>
199 : : /// Sets the family index of the font to family and returns a reference to the font.
200 : : /// </summary>
201 : : font &family(std::size_t family);
202 : :
203 : : /// <summary>
204 : : /// Returns the family index for the font.
205 : : /// </summary>
206 : : std::size_t family() const;
207 : :
208 : : /// <summary>
209 : : /// Returns true if this font has a charset defined.
210 : : /// </summary>
211 : : bool has_charset() const;
212 : :
213 : : // TODO: charset should be an enum, not a number
214 : :
215 : : /// <summary>
216 : : /// Sets the charset of the font to charset and returns a reference to the font.
217 : : /// </summary>
218 : : font &charset(std::size_t charset);
219 : :
220 : : /// <summary>
221 : : /// Returns the charset of the font.
222 : : /// </summary>
223 : : std::size_t charset() const;
224 : :
225 : : /// <summary>
226 : : /// Returns true if this font has a scheme.
227 : : /// </summary>
228 : : bool has_scheme() const;
229 : :
230 : : /// <summary>
231 : : /// Sets the scheme of the font to scheme and returns a reference to the font.
232 : : /// </summary>
233 : : font &scheme(const std::string &scheme);
234 : :
235 : : /// <summary>
236 : : /// Returns the scheme of this font.
237 : : /// </summary>
238 : : const std::string &scheme() const;
239 : :
240 : : /// <summary>
241 : : /// Returns true if left is exactly equal to right.
242 : : /// </summary>
243 : : bool operator==(const font &other) const;
244 : :
245 : : /// <summary>
246 : : /// Returns true if left is not exactly equal to right.
247 : : /// </summary>
248 : : bool operator!=(const font &other) const
249 : : {
250 : : return !operator==(other);
251 : : }
252 : :
253 : : private:
254 : : friend class style;
255 : :
256 : : /// <summary>
257 : : /// The name of the font
258 : : /// </summary>
259 : : optional<std::string> name_;
260 : :
261 : : /// <summary>
262 : : /// size
263 : : /// </summary>
264 : : optional<double> size_;
265 : :
266 : : /// <summary>
267 : : /// bold
268 : : /// </summary>
269 : : bool bold_ = false;
270 : :
271 : : /// <summary>
272 : : /// italic
273 : : /// </summary>
274 : : bool italic_ = false;
275 : :
276 : : /// <summary>
277 : : /// superscript
278 : : /// </summary>
279 : : bool superscript_ = false;
280 : :
281 : : /// <summary>
282 : : /// subscript
283 : : /// </summary>
284 : : bool subscript_ = false;
285 : :
286 : : /// <summary>
287 : : /// strikethrough
288 : : /// </summary>
289 : : bool strikethrough_ = false;
290 : :
291 : : /// <summary>
292 : : /// outline
293 : : /// </summary>
294 : : bool outline_ = false;
295 : :
296 : : /// <summary>
297 : : /// shadow
298 : : /// </summary>
299 : : bool shadow_ = false;
300 : :
301 : : /// <summary>
302 : : /// underline style
303 : : /// </summary>
304 : : underline_style underline_ = underline_style::none;
305 : :
306 : : /// <summary>
307 : : /// color
308 : : /// </summary>
309 : : optional<xlnt::color> color_;
310 : :
311 : : /// <summary>
312 : : /// family
313 : : /// </summary>
314 : : optional<std::size_t> family_;
315 : :
316 : : /// <summary>
317 : : /// charset
318 : : /// </summary>
319 : : optional<std::size_t> charset_;
320 : :
321 : : /// <summary>
322 : : /// scheme
323 : : /// </summary>
324 : : optional<std::string> scheme_;
325 : : };
326 : :
327 : : } // namespace xlnt
328 : :
329 : : namespace std {
330 : :
331 : : template<>
332 : : struct hash<xlnt::font>
333 : : {
334 :CBC 72 : size_t operator()(const xlnt::font& f) const
335 : : {
336 : 72 : size_t seed = 0;
337 : :
338 : : // Hash name
339 [ + + + ]: 72 : if (f.has_name())
340 : : {
341 [ + ]: 41 : xlnt::detail::hash_combine(seed, f.name());
342 : : }
343 : :
344 : : // Hash size
345 [ + + + ]: 72 : if (f.has_size())
346 : : {
347 [ + ]: 41 : xlnt::detail::hash_combine(seed, f.size());
348 : : }
349 : :
350 : : // Hash all boolean properties
351 [ + ]: 72 : xlnt::detail::hash_combine(seed, f.bold());
352 [ + ]: 72 : xlnt::detail::hash_combine(seed, f.italic());
353 [ + ]: 72 : xlnt::detail::hash_combine(seed, f.superscript());
354 [ + ]: 72 : xlnt::detail::hash_combine(seed, f.subscript());
355 [ + ]: 72 : xlnt::detail::hash_combine(seed, f.strikethrough());
356 [ + ]: 72 : xlnt::detail::hash_combine(seed, static_cast<int>(f.underline()));
357 [ + ]: 72 : xlnt::detail::hash_combine(seed, f.outline());
358 [ + ]: 72 : xlnt::detail::hash_combine(seed, f.shadow());
359 : :
360 : : // Hash scheme
361 [ + + + ]: 72 : if (f.has_scheme())
362 : : {
363 [ + ]: 1 : xlnt::detail::hash_combine(seed, f.scheme());
364 : : }
365 : :
366 : : // Hash color (importantly, this re-uses the std::hash<xlnt::color> we just defined)
367 [ + + + ]: 72 : if (f.has_color())
368 : : {
369 [ + + ]: 1 : xlnt::detail::hash_combine(seed, f.color());
370 : : }
371 : :
372 : : // Hash family
373 [ + + + ]: 72 : if (f.has_family())
374 : : {
375 [ + ]: 3 : xlnt::detail::hash_combine(seed, f.family());
376 : : }
377 : :
378 : : // Hash charset
379 [ + + + ]: 72 : if (f.has_charset())
380 : : {
381 [ + ]: 1 : xlnt::detail::hash_combine(seed, f.charset());
382 : : }
383 : :
384 : 72 : return seed;
385 : : }
386 : : };
387 : :
388 : : } // namespace std
|