1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21// LOVE
22#include "GlyphData.h"
23
24// UTF-8
25#include "libraries/utf8/utf8.h"
26
27// stdlib
28#include <iostream>
29#include <cstddef>
30
31namespace love
32{
33namespace font
34{
35
36love::Type GlyphData::type("GlyphData", &Data::type);
37
38GlyphData::GlyphData(uint32 glyph, GlyphMetrics glyphMetrics, PixelFormat f)
39 : glyph(glyph)
40 , metrics(glyphMetrics)
41 , data(nullptr)
42 , format(f)
43{
44 if (f != PIXELFORMAT_LA8 && f != PIXELFORMAT_RGBA8)
45 throw love::Exception("Invalid GlyphData pixel format.");
46
47 if (metrics.width > 0 && metrics.height > 0)
48 data = new uint8[metrics.width * metrics.height * getPixelSize()];
49}
50
51GlyphData::GlyphData(const GlyphData &c)
52 : glyph(c.glyph)
53 , metrics(c.metrics)
54 , data(nullptr)
55 , format(c.format)
56{
57 if (metrics.width > 0 && metrics.height > 0)
58 {
59 data = new uint8[metrics.width * metrics.height * getPixelSize()];
60 memcpy(data, c.data, c.getSize());
61 }
62}
63
64GlyphData::~GlyphData()
65{
66 delete[] data;
67}
68
69GlyphData *GlyphData::clone() const
70{
71 return new GlyphData(*this);
72}
73
74void *GlyphData::getData() const
75{
76 return data;
77}
78
79size_t GlyphData::getPixelSize() const
80{
81 return getPixelFormatSize(format);
82}
83
84void *GlyphData::getData(int x, int y) const
85{
86 size_t offset = (y * getWidth() + x) * getPixelSize();
87 return data + offset;
88}
89
90size_t GlyphData::getSize() const
91{
92 return size_t(getWidth() * getHeight()) * getPixelSize();
93}
94
95int GlyphData::getHeight() const
96{
97 return metrics.height;
98}
99
100int GlyphData::getWidth() const
101{
102 return metrics.width;
103}
104
105uint32 GlyphData::getGlyph() const
106{
107 return glyph;
108}
109
110std::string GlyphData::getGlyphString() const
111{
112 char u[5] = {0, 0, 0, 0, 0};
113 ptrdiff_t length = 0;
114
115 try
116 {
117 char *end = utf8::append(glyph, u);
118 length = end - u;
119 }
120 catch (utf8::exception &e)
121 {
122 throw love::Exception("UTF-8 decoding error: %s", e.what());
123 }
124
125 // Just in case...
126 if (length < 0)
127 return "";
128
129 return std::string(u, length);
130}
131
132int GlyphData::getAdvance() const
133{
134 return metrics.advance;
135}
136
137int GlyphData::getBearingX() const
138{
139 return metrics.bearingX;
140}
141
142int GlyphData::getBearingY() const
143{
144 return metrics.bearingY;
145}
146
147int GlyphData::getMinX() const
148{
149 return getBearingX();
150}
151
152int GlyphData::getMinY() const
153{
154 return getHeight() - getBearingY();
155}
156
157int GlyphData::getMaxX() const
158{
159 return getBearingX() + getWidth();
160}
161
162int GlyphData::getMaxY() const
163{
164 return getBearingY();
165}
166
167PixelFormat GlyphData::getFormat() const
168{
169 return format;
170}
171
172} // font
173} // love
174