Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 andreas 1
/*
21 andreas 2
 * Copyright (C) 2020, 2021 by Andreas Theofilu <andreas@theosys.at>
4 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 <include/core/SkBitmap.h>
20
#include <include/core/SkData.h>
21
#include <include/core/SkImage.h>
22
#include <include/core/SkImageGenerator.h>
23
#include <include/core/SkStream.h>
24
#include <include/core/SkTypeface.h>
25
 
11 andreas 26
#include <iconv.h>
27
 
4 andreas 28
#include "tresources.h"
29
#include "terror.h"
30
#include "tconfig.h"
31
 
32
sk_sp<SkData> (*gResourceFactory)(const char*) = nullptr;
33
 
34
using std::string;
35
using std::endl;
11 andreas 36
using std::vector;
4 andreas 37
 
11 andreas 38
typedef struct
39
{
40
    unsigned char ch;
41
    short byte;
42
}CHTABLE;
43
 
44
static CHTABLE __cht[] = {
45
    {0x80,	0x20AC},
46
    {0x81,	0x0081},
47
    {0x82,	0x201A},
48
    {0x83,	0x0192},
49
    {0x84,	0x201E},
50
    {0x85,	0x2026},
51
    {0x86,	0x2020},
52
    {0x87,	0x2021},
53
    {0x88,	0x02C6},
54
    {0x89,	0x2030},
55
    {0x8A,	0x0160},
56
    {0x8B,	0x2039},
57
    {0x8C,	0x0152},
58
    {0x8D,	0x008d},
59
    {0x8E,	0x017D},
60
    {0x8F,	0x008f},
61
    {0x90,	0x0090},
62
    {0x91,	0x2018},
63
    {0x92,	0x2019},
64
    {0x93,	0x201C},
65
    {0x94,	0x201D},
66
    {0x95,	0x2022},
67
    {0x96,	0x2013},
68
    {0x97,	0x2014},
69
    {0x98,	0x02DC},
70
    {0x99,	0x2122},
71
    {0x9A,	0x0161},
72
    {0x9B,	0x203A},
73
    {0x9C,	0x0153},
74
    {0x9D,	0x009d},
75
    {0x9E,	0x017E},
76
    {0x9F,	0x0178},
77
    {0xA0,	0x00A0},
78
    {0xA1,	0x00A1},
79
    {0xA2,	0x00A2},
80
    {0xA3,	0x00A3},
81
    {0xA4,	0x00A4},
82
    {0xA5,	0x00A5},
83
    {0xA6,	0x00A6},
84
    {0xA7,	0x00A7},
85
    {0xA8,	0x00A8},
86
    {0xA9,	0x00A9},
87
    {0xAA,	0x00AA},
88
    {0xAB,	0x00AB},
89
    {0xAC,	0x00AC},
90
    {0xAD,	0x00AD},
91
    {0xAE,	0x00AE},
92
    {0xAF,	0x00AF},
93
    {0xB0,	0x00B0},
94
    {0xB1,	0x00B1},
95
    {0xB2,	0x00B2},
96
    {0xB3,	0x00B3},
97
    {0xB4,	0x00B4},
98
    {0xB5,	0x00B5},
99
    {0xB6,	0x00B6},
100
    {0xB7,	0x00B7},
101
    {0xB8,	0x00B8},
102
    {0xB9,	0x00B9},
103
    {0xBA,	0x00BA},
104
    {0xBB,	0x00BB},
105
    {0xBC,	0x00BC},
106
    {0xBD,	0x00BD},
107
    {0xBE,	0x00BE},
108
    {0xBF,	0x00BF},
109
    {0xC0,	0x00C0},
110
    {0xC1,	0x00C1},
111
    {0xC2,	0x00C2},
112
    {0xC3,	0x00C3},
113
    {0xC4,	0x00C4},
114
    {0xC5,	0x00C5},
115
    {0xC6,	0x00C6},
116
    {0xC7,	0x00C7},
117
    {0xC8,	0x00C8},
118
    {0xC9,	0x00C9},
119
    {0xCA,	0x00CA},
120
    {0xCB,	0x00CB},
121
    {0xCC,	0x00CC},
122
    {0xCD,	0x00CD},
123
    {0xCE,	0x00CE},
124
    {0xCF,	0x00CF},
125
    {0xD0,	0x00D0},
126
    {0xD1,	0x00D1},
127
    {0xD2,	0x00D2},
128
    {0xD3,	0x00D3},
129
    {0xD4,	0x00D4},
130
    {0xD5,	0x00D5},
131
    {0xD6,	0x00D6},
132
    {0xD7,	0x00D7},
133
    {0xD8,	0x00D8},
134
    {0xD9,	0x00D9},
135
    {0xDA,	0x00DA},
136
    {0xDB,	0x00DB},
137
    {0xDC,	0x00DC},
138
    {0xDD,	0x00DD},
139
    {0xDE,	0x00DE},
140
    {0xDF,	0x00DF},
141
    {0xE0,	0x00E0},
142
    {0xE1,	0x00E1},
143
    {0xE2,	0x00E2},
144
    {0xE3,	0x00E3},
145
    {0xE4,	0x00E4},
146
    {0xE5,	0x00E5},
147
    {0xE6,	0x00E6},
148
    {0xE7,	0x00E7},
149
    {0xE8,	0x00E8},
150
    {0xE9,	0x00E9},
151
    {0xEA,	0x00EA},
152
    {0xEB,	0x00EB},
153
    {0xEC,	0x00EC},
154
    {0xED,	0x00ED},
155
    {0xEE,	0x00EE},
156
    {0xEF,	0x00EF},
157
    {0xF0,	0x00F0},
158
    {0xF1,	0x00F1},
159
    {0xF2,	0x00F2},
160
    {0xF3,	0x00F3},
161
    {0xF4,	0x00F4},
162
    {0xF5,	0x00F5},
163
    {0xF6,	0x00F6},
164
    {0xF7,	0x00F7},
165
    {0xF8,	0x00F8},
166
    {0xF9,	0x00F9},
167
    {0xFA,	0x00FA},
168
    {0xFB,	0x00FB},
169
    {0xFC,	0x00FC},
170
    {0xFD,	0x00FD},
171
    {0xFE,	0x00FE},
172
    {0xFF,	0x00FF}
173
};
174
 
4 andreas 175
SkString GetResourcePath(const char* resource)
176
{
177
    string path = TConfig::getProjectPath() + "/images/" + resource;
178
    return SkString(path);
179
}
180
 
181
bool DecodeDataToBitmap(sk_sp<SkData> data, SkBitmap* dst)
182
{
183
    std::unique_ptr<SkImageGenerator> gen(SkImageGenerator::MakeFromEncoded(std::move(data)));
184
    return gen && dst->tryAllocPixels(gen->getInfo()) &&
23 andreas 185
#ifdef __ANDROID__
186
    gen->getPixels(gen->getInfo().makeColorType(kBGRA_8888_SkColorType).makeAlphaType(kPremul_SkAlphaType), dst->getPixels(), dst->rowBytes());
187
#else
4 andreas 188
    gen->getPixels(gen->getInfo().makeColorSpace(nullptr), dst->getPixels(), dst->rowBytes());
23 andreas 189
#endif
4 andreas 190
}
191
 
192
std::unique_ptr<SkStreamAsset> GetResourceAsStream(const char* resource)
193
{
194
    sk_sp<SkData> data = GetResourceAsData(resource);
195
    return data ? std::unique_ptr<SkStreamAsset>(new SkMemoryStream(std::move(data)))
196
    : nullptr;
197
}
198
 
199
sk_sp<SkData> GetResourceAsData(const char* resource)
200
{
201
    if (sk_sp<SkData> data = gResourceFactory ? gResourceFactory(resource) : SkData::MakeFromFileName(GetResourcePath(resource).c_str()))
202
    {
203
        return data;
204
    }
205
 
6 andreas 206
    MSG_ERROR("GetResourceAsData: Resource \"" << GetResourcePath(resource).c_str() << "\" not found." << endl);
4 andreas 207
    TError::setError();
208
#ifdef SK_TOOLS_REQUIRE_RESOURCES
6 andreas 209
    SK_ABORT("GetResourceAsData: missing resource");
4 andreas 210
#endif
211
    return nullptr;
212
}
213
 
214
sk_sp<SkTypeface> MakeResourceAsTypeface(const char* resource, int ttcIndex)
215
{
216
    return SkTypeface::MakeFromStream(GetResourceAsStream(resource), ttcIndex);
217
}
6 andreas 218
 
219
/*
220
 * Read the image from a file and save it into a data buffer. This is the base
221
 * to convert the image.
222
 */
223
sk_sp<SkData> readImage(const string& fname)
224
{
225
    sk_sp<SkData> data = GetResourceAsData(fname.c_str());
226
 
227
    if (!data)
228
    {
229
        MSG_ERROR("readImage: Error loading the image " << fname);
230
        TError::setError();
231
    }
232
 
233
    return data;
234
}
11 andreas 235
 
236
vector<string> StrSplit(const string& str, const string& seps, const bool trimEmpty)
237
{
238
    size_t pos = 0, mark = 0;
239
    vector<string> parts;
240
    string::const_iterator it, sepIt;
241
 
242
    for (it = str.begin(); it != str.end(); ++it)
243
    {
244
        for (sepIt = seps.begin(); sepIt != seps.end(); ++sepIt)
245
        {
21 andreas 246
            if (pos > 0 && *it == *sepIt)
11 andreas 247
            {
248
                size_t len = pos - mark;
21 andreas 249
 
250
                if (len > 0)
251
                    parts.push_back(str.substr(mark, len));
252
                else
253
                    parts.push_back(string());
254
 
11 andreas 255
                mark = pos + 1;
256
                break;
257
            }
21 andreas 258
            else if (*it == *sepIt)
259
                mark = pos + 1;
11 andreas 260
        }
261
 
262
        pos++;
263
    }
264
 
265
    parts.push_back(str.substr(mark));
266
 
267
    if (trimEmpty)
268
    {
269
        vector<string> nparts;
270
 
271
        for (auto it = parts.begin(); it != parts.end(); ++it)
272
        {
273
            if (it->empty())
274
                continue;
275
 
276
            nparts.push_back(*it);
277
        }
278
 
279
        return nparts;
280
    }
281
 
282
    return parts;
283
}
284
 
285
string latin1ToUTF8(const string& str)
286
{
287
    DECL_TRACER("NameFormat::latin1ToUTF8(const string& str)");
288
    string out;
289
 
290
    for (size_t i = 0; i < str.length(); i++)
291
    {
292
        uint8_t ch = str.at(i);
293
 
294
        if (ch < 0x80)
295
        {
296
            out.push_back(ch);
297
        }
298
        else
299
        {
300
            out.push_back(0xc0 | ch >> 6);
301
            out.push_back(0x80 | (ch & 0x3f));
302
        }
303
    }
304
 
305
    return out;
306
}
307
 
308
string cp1250ToUTF8(const string& str)
309
{
310
    DECL_TRACER("cp1250ToUTF8(const string& str)");
311
 
312
    string out;
313
 
314
    for (size_t j = 0; j < str.length(); j++)
315
    {
316
        int i = -1;
317
        unsigned char ch = str.at(j);
318
        short utf = -1;
319
 
320
        if (ch < 0x80)
321
        {
322
            do
323
            {
324
                i++;
325
 
326
                if (__cht[i].ch == ch)
327
                {
328
                    utf = __cht[i].byte;
329
                    break;
330
                }
331
            }
332
            while (__cht[i].ch != 0xff);
333
 
334
            if (utf < 0)
335
                utf = ch;
336
        }
337
        else
338
            utf = ch;
339
 
340
        if (utf > 0x00ff)
341
        {
342
            out.push_back((utf >> 8) & 0x00ff);
343
            out.push_back(utf & 0x00ff);
344
        }
345
        else if (ch > 0x7f)
346
        {
347
            out.push_back(0xc0 | ch >> 6);
348
            out.push_back(0x80 | (ch & 0x3f));
349
        }
350
        else
351
            out.push_back(ch);
352
    }
353
 
354
    return out;
355
}
356
 
357
string UTF8ToCp1250(const string& str)
358
{
359
    DECL_TRACER("UTF8ToCp1250(const string& str)");
360
 
361
    char dst[1024];
362
    size_t srclen = 0;
363
    char* pIn, *pInSave;
364
 
365
    srclen = str.length();
366
    memset(&dst[0], 0, sizeof(dst));
367
 
368
    try
369
    {
370
        pIn = new char[srclen + 1];
371
        memcpy(pIn, str.c_str(), srclen);
372
        *(pIn+srclen) = 0;
373
        pInSave = pIn;
374
    }
375
    catch(std::exception& e)
376
    {
377
        MSG_ERROR("Error: " << e.what());
378
        return "";
379
    }
380
 
381
    size_t dstlen = sizeof(dst) - 1;
382
    char* pOut = (char *)dst;
383
 
384
    iconv_t conv = iconv_open("CP1250", "UTF-8");
385
 
386
    if (conv == (iconv_t)-1)
387
    {
388
        MSG_ERROR("Error opening iconv!");
389
        delete[] pInSave;
390
        return str;
391
    }
392
 
393
    size_t ret = iconv(conv, &pIn, &srclen, &pOut, &dstlen);
394
    iconv_close(conv);
395
    delete[] pInSave;
396
 
397
    if (ret == (size_t)-1)
398
    {
399
        MSG_ERROR("Error converting a string!");
400
        return str;
401
    }
402
 
403
    return string(dst);
404
}
21 andreas 405
 
406
void *renew(void *mem, size_t old_size, size_t new_size)
407
{
408
    if (old_size == new_size)
409
        return mem;
410
 
411
    try
412
    {
413
        void *memory = new char[new_size];
414
        size_t len = (new_size < old_size) ? new_size : old_size;
415
        memcpy(memory, mem, len);
416
        delete[] (char *)mem;
417
        mem = memory;
418
        return memory;
419
    }
420
    catch(std::exception& e)
421
    {
422
        MSG_ERROR(e.what());
423
        throw e;
424
    }
425
 
426
    return nullptr;
427
}
428
 
429
string toUpper(string& str)
430
{
431
    string::iterator iter;
432
 
433
    for (iter = str.begin(); iter != str.end(); iter++)
434
        *iter = std::toupper(*iter);
435
 
436
    return str;
437
}
438
 
439
string toLower(string& str)
440
{
441
    string::iterator iter;
442
 
443
    for (iter = str.begin(); iter != str.end(); iter++)
444
        *iter = std::tolower(*iter);
445
 
446
    return str;
447
}