Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 andreas 1
/*
21 andreas 2
 * Copyright (C) 2020, 2021 by Andreas Theofilu <andreas@theosys.at>
7 andreas 3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include "tfont.h"
20
#include "treadxml.h"
21
#include "tconfig.h"
22
#include "terror.h"
23
 
24
#include <include/core/SkFontStyle.h>
25
 
26
using std::string;
27
using std::map;
28
using std::pair;
29
 
30
TFont::TFont()
31
{
32
    DECL_TRACER("TFont::TFont()");
33
    initialize();
34
}
35
 
36
TFont::~TFont()
37
{
38
    DECL_TRACER("TFont::~TFont()");
39
}
40
 
41
void TFont::initialize()
42
{
43
    DECL_TRACER("TFont::initialize()");
44
 
11 andreas 45
    if (mFonts.size() > 0)
46
        mFonts.clear();
47
 
7 andreas 48
    // System fonts first
49
    FONT_T font;
50
 
51
    font.number = 1;
52
    font.faceIndex = 1;
53
    font.fullName = "Courier New";
54
    font.name = "Courier New";
55
    font.size = 9;
56
    font.subfamilyName = "normal";
57
    font.fileSize = 0;
58
    font.usageCount = 0;
59
    mFonts.insert(pair<int, FONT_T>(font.number, font));
60
 
61
    font.number = 2;
62
    font.faceIndex = 2;
63
    font.size = 12;
64
    mFonts.insert(pair<int, FONT_T>(font.number, font));
65
 
66
    font.number = 3;
67
    font.faceIndex = 3;
68
    font.size = 18;
69
    mFonts.insert(pair<int, FONT_T>(font.number, font));
70
 
71
    font.number = 4;
72
    font.faceIndex = 4;
73
    font.size = 26;
74
    mFonts.insert(pair<int, FONT_T>(font.number, font));
75
 
76
    font.number = 5;
77
    font.faceIndex = 5;
78
    font.size = 32;
79
    mFonts.insert(pair<int, FONT_T>(font.number, font));
80
 
81
    font.number = 6;
82
    font.faceIndex = 6;
83
    font.size = 18;
84
    mFonts.insert(pair<int, FONT_T>(font.number, font));
85
 
86
    font.number = 7;
87
    font.faceIndex = 7;
88
    font.size = 26;
89
    mFonts.insert(pair<int, FONT_T>(font.number, font));
90
 
91
    font.number = 8;
92
    font.faceIndex = 8;
93
    font.size = 34;
94
    mFonts.insert(pair<int, FONT_T>(font.number, font));
95
 
96
    font.number = 9;
97
    font.faceIndex = 9;
98
    font.fullName = "AMX Bold";
99
    font.name = "AMX Bold";
100
    font.size = 14;
101
    font.subfamilyName = "bold";
102
    mFonts.insert(pair<int, FONT_T>(font.number, font));
103
 
104
    font.number = 10;
105
    font.faceIndex = 10;
106
    font.size = 20;
107
    mFonts.insert(pair<int, FONT_T>(font.number, font));
108
 
109
    font.number = 11;
110
    font.faceIndex = 11;
111
    font.size = 36;
112
    mFonts.insert(pair<int, FONT_T>(font.number, font));
113
 
114
    font.number = 19;
115
    font.faceIndex = 19;
116
    font.fullName = "Arial";
117
    font.name = "Arial";
118
    font.size = 9;
119
    font.subfamilyName = "normal";
120
    mFonts.insert(pair<int, FONT_T>(font.number, font));
121
 
122
    font.number = 20;
123
    font.faceIndex = 20;
124
    font.size = 10;
125
    mFonts.insert(pair<int, FONT_T>(font.number, font));
126
 
127
    font.number = 21;
128
    font.faceIndex = 21;
129
    font.size = 12;
130
    mFonts.insert(pair<int, FONT_T>(font.number, font));
131
 
132
    font.number = 22;
133
    font.faceIndex = 22;
134
    font.size = 14;
135
    mFonts.insert(pair<int, FONT_T>(font.number, font));
136
 
137
    font.number = 23;
138
    font.faceIndex = 23;
139
    font.size = 16;
140
    mFonts.insert(pair<int, FONT_T>(font.number, font));
141
 
142
    font.number = 24;
143
    font.faceIndex = 24;
144
    font.size = 18;
145
    mFonts.insert(pair<int, FONT_T>(font.number, font));
146
 
147
    font.number = 25;
148
    font.faceIndex = 25;
149
    font.size = 20;
150
    mFonts.insert(pair<int, FONT_T>(font.number, font));
151
 
152
    font.number = 26;
153
    font.faceIndex = 26;
154
    font.size = 24;
155
    mFonts.insert(pair<int, FONT_T>(font.number, font));
156
 
157
    font.number = 27;
158
    font.faceIndex = 27;
159
    font.size = 36;
160
    mFonts.insert(pair<int, FONT_T>(font.number, font));
161
 
162
    font.number = 28;
163
    font.faceIndex = 28;
164
    font.fullName = "Arial Bold";
165
    font.name = "Arial Bold";
166
    font.size = 10;
167
    font.subfamilyName = "bold";
168
    mFonts.insert(pair<int, FONT_T>(font.number, font));
169
 
170
    font.number = 29;
171
    font.faceIndex = 29;
172
    font.size = 8;
173
    mFonts.insert(pair<int, FONT_T>(font.number, font));
174
 
175
    // read the individual fonts from file
176
    TError::clear();
177
    string path = makeFileName(TConfig::getProjectPath(), "fnt.xma");
178
 
179
    if (!isValidFile())
180
    {
181
        MSG_ERROR("File " << path << " doesn't exist or is not readable!");
182
        TError::setError();
183
        return;
184
    }
185
 
186
    TReadXML reader(path);
187
 
188
    if (TError::isError())
189
    {
190
        MSG_ERROR("Stopped scanning file " << path << " because of previous errors!");
191
        return;
192
    }
193
 
194
    reader.findElement("fontList");
195
 
196
    if (!reader.success())
197
    {
198
        MSG_DEBUG("File does not contain the element \"fontList\"!");
199
        TError::setError();
200
        return;
201
    }
202
 
203
    mxml_node_t *node = reader.getFirstChild();
204
 
205
    while (node)
206
    {
207
        string ename = reader.getElementName(node);
208
 
209
        if (ename.compare("font") == 0)
210
        {
211
            mxml_node_t *n = reader.getFirstChild(node);
212
            string snum;
213
            FONT_T ft;
214
 
215
            if (n)
216
            {
217
                snum = reader.getAttributeFromNode(node, "number");
218
 
219
                if (!snum.empty())
220
                    ft.number = atoi(snum.c_str());
221
                else
222
                {
223
                    MSG_ERROR("Element " << ename << " contains no or invalid attribute!");
224
                    TError::setError();
225
                    return;
226
                }
227
 
228
                while (n)
229
                {
230
                    string e = reader.getElementName(n);
231
 
232
                    if (e.compare("file") == 0)
233
                        ft.file = reader.getTextFromNode(n);
234
                    else if (e.compare("fileSize") == 0)
235
                        ft.fileSize = reader.getIntFromNode(n);
236
                    else if (e.compare("faceIndex") == 0)
237
                        ft.faceIndex = reader.getIntFromNode(n);
238
                    else if (e.compare("name") == 0)
239
                        ft.name = reader.getTextFromNode(n);
240
                    else if (e.compare("subfamilyName") == 0)
241
                        ft.subfamilyName = reader.getTextFromNode(n);
242
                    else if (e.compare("fullName") == 0)
243
                        ft.fullName = reader.getTextFromNode(n);
244
                    else if (e.compare("size") == 0)
245
                        ft.size = reader.getIntFromNode(n);
246
                    else if (e.compare("usageCount") == 0)
247
                        ft.usageCount = reader.getIntFromNode(n);
248
 
249
                    n = reader.getNextChild(n);
250
                }
251
 
252
                mFonts.insert(pair<int, FONT_T>(ft.number, ft));
253
            }
254
        }
255
 
256
        node = reader.getNextChild();
257
    }
258
}
259
 
260
FONT_T TFont::getFont(int number)
261
{
262
    DECL_TRACER("TFont::getFont(int number)");
263
 
264
    if (mFonts.size() == 0)
265
    {
266
        MSG_WARNING("No fonts found!");
267
        return FONT_T();
268
    }
269
 
270
    map<int, FONT_T>::iterator iter = mFonts.find(number);
271
 
272
    if (iter == mFonts.end())
273
        return FONT_T();
274
 
275
    return iter->second;
276
}
277
 
278
FONT_STYLE TFont::getStyle(int number)
279
{
280
    DECL_TRACER("TFont::getStyle(int number)");
281
 
282
    map<int, FONT_T>::iterator iter = mFonts.find(number);
283
 
284
    if (iter == mFonts.end())
285
        return FONT_NONE;
286
 
287
    if (iter->second.subfamilyName.compare("Regular") == 0)
288
        return FONT_NORMAL;
289
    else if (iter->second.subfamilyName.compare("Italic") == 0)
290
        return FONT_ITALIC;
291
    else if (iter->second.subfamilyName.compare("Bold") == 0)
292
        return FONT_BOLD;
293
    else if (iter->second.subfamilyName.compare("Bold Italic") == 0)
294
        return FONT_BOLD_ITALIC;
295
 
296
    return FONT_NORMAL;
297
}
298
 
299
FONT_STYLE TFont::getStyle(FONT_T& font)
300
{
301
    DECL_TRACER("TFont::getStyle(int number)");
302
 
303
    if (font.subfamilyName.compare("Regular") == 0)
304
        return FONT_NORMAL;
305
    else if (font.subfamilyName.compare("Italic") == 0)
306
        return FONT_ITALIC;
307
    else if (font.subfamilyName.compare("Bold") == 0)
308
        return FONT_BOLD;
309
    else if (font.subfamilyName.compare("Bold Italic") == 0)
310
        return FONT_BOLD_ITALIC;
311
 
312
    return FONT_NORMAL;
313
}
314
 
315
 
316
#define MAX_FACES   10
317
 
318
sk_sp<SkTypeface> TFont::getTypeFace(int number)
319
{
320
    DECL_TRACER("TFont::getTypeFace(int number)");
321
 
322
    map<int, FONT_T>::iterator iter = mFonts.find(number);
323
 
324
    if (iter == mFonts.end())
325
    {
326
        MSG_ERROR("No font with index " << number << " found!");
327
        TError::setError();
328
        return sk_sp<SkTypeface>();
329
    }
330
 
331
    string path = TConfig::getProjectPath() + "/fonts/" + iter->second.file;
332
    sk_sp<SkTypeface> tf;
333
    MSG_TRACE("Loading font \"" << path << "\" ...");
334
    tf = SkTypeface::MakeFromFile(path.c_str(), iter->second.faceIndex);
335
 
336
    if (!tf)
337
    {
338
        MSG_ERROR("Error loading font \"" << path << "\"");
339
        TError::setError();
340
        return tf;
341
    }
342
    else
343
    {
344
        MSG_TRACE("Font \"" << path << "\" was loaded successfull.");
345
    }
346
 
347
    SkString sname;
348
    tf->getFamilyName(&sname);
349
    MSG_DEBUG("Found font name \"" << sname.c_str() << "\" with attributes: bold=" << ((tf->isBold())?"TRUE":"FALSE") << ", italic=" << ((tf->isItalic())?"TRUE":"FALSE") << ", fixed=" << ((tf->isFixedPitch())?"TRUE":"FALSE"));
350
 
351
    if (iter->second.name.compare(sname.c_str()) != 0)
352
    {
353
        MSG_WARNING("The loaded font \"" << sname.c_str() << "\" is not the wanted font \"" << iter->second.name << "\"!");
354
    }
355
 
356
    FONT_STYLE style = getStyle(iter->second);
357
 
358
    if (style == FONT_BOLD && tf->isBold())
359
        return tf;
360
    else if (style == FONT_ITALIC && tf->isItalic())
361
        return tf;
362
    else if (style == FONT_BOLD_ITALIC && tf->isBold() && tf->isItalic())
363
        return tf;
364
    else if (style == FONT_NORMAL && !tf->isBold() && !tf->isItalic())
365
        return tf;
366
 
367
    MSG_WARNING("The wanted font style " << iter->second.subfamilyName << " was not found!");
368
    return tf;
369
}