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
 
5 andreas 19
#include <iostream>
20
#include <iomanip>
21
 
4 andreas 22
#include "tcolor.h"
23
#include "terror.h"
24
 
25
TPalette *TColor::mPalette = nullptr;
26
 
27
using std::string;
40 andreas 28
using std::vector;
5 andreas 29
using std::setw;
30
using std::setfill;
31
using std::hex;
32
using std::dec;
33
using std::resetiosflags;
4 andreas 34
 
35
TColor::COLOR_T TColor::getAMXColor(const string& color)
36
{
37
    DECL_TRACER("TColor::getAMXColor(const string& color)");
38
 
39
    if (color.empty())
40
        return TColor::COLOR_T();
41
 
42
    size_t pos = color.find('#');
43
 
44
    if (pos == string::npos)
45
    {
46
        if (!mPalette)
47
        {
48
            MSG_ERROR("No palette was set! First set a palette to be able to get any color!");
49
            TError::setError();
50
            return TColor::COLOR_T();
51
        }
52
 
53
        PDATA_T pd = mPalette->findColor(color);
54
 
55
        if (!pd.name.empty())
56
            return splitColors(pd);
57
 
58
        return TColor::COLOR_T();
59
    }
60
 
108 andreas 61
    // Check if we've an index number
62
    if (color.length() <= 2 && isdigit(color[0]))
63
    {
64
        int idx = atoi(color.c_str());
65
 
66
        if (idx < 0 || idx > 88)
67
            return TColor::COLOR_T();
68
 
69
        PDATA_T pd = mPalette->findColor(idx);
70
 
71
        if (!pd.name.empty())
72
            return splitColors(pd);
73
 
74
        return TColor::COLOR_T();
75
    }
76
 
4 andreas 77
    TColor::COLOR_T ct;
78
    ct.red = (int)strtol(color.substr(pos+1, 2).c_str(), NULL, 16);
79
    ct.green = (int)strtol(color.substr(pos+3, 2).c_str(), NULL, 16);
80
    ct.blue = (int)strtol(color.substr(pos+5, 2).c_str(), NULL, 16);
81
 
82
    if (color.length() > 7)
83
        ct.alpha = (int)strtol(color.substr(pos+7).c_str(), NULL, 16);
84
    else
85
        ct.alpha = 0x00ff;
86
 
87
    return ct;
88
}
89
 
90
TColor::COLOR_T TColor::splitColors(PDATA_T& pd)
91
{
92
    DECL_TRACER("TColor::splitColors(PDATA_T& pd)");
93
 
94
    TColor::COLOR_T ct;
95
 
96
    if (pd.color > 0x00ffffff)
97
    {
98
        ct.red = (pd.color & 0xff000000) >> 24;
99
        ct.green = (pd.color & 0x00ff0000) >> 16;
100
        ct.blue = (pd.color & 0x0000ff00) >> 8;
101
        ct.alpha = (pd.color & 0x000000ff);
102
    }
103
    else
104
    {
105
        ct.red = (pd.color & 0xff000000) >> 24;
106
        ct.green = (pd.color & 0x00ff0000) >> 16;
107
        ct.blue = (pd.color & 0x0000ff00) >> 8;
108
        ct.alpha = 0x00ff;
109
    }
110
 
111
    return ct;
112
}
113
 
114
SkColor TColor::getSkiaColor(const std::string& color)
115
{
116
    DECL_TRACER("TColor::getSkiaColor(const std::string& color)");
117
 
118
    COLOR_T col = getAMXColor(color);
59 andreas 119
#ifdef __ANDROID__
120
    return SkColorSetARGB(col.alpha, col.blue, col.green, col.red); // Workaround for a bug in Skia
121
#else
4 andreas 122
    return SkColorSetARGB(col.alpha, col.red, col.green, col.blue);
59 andreas 123
#endif
4 andreas 124
}
5 andreas 125
 
126
ulong TColor::getColor(const std::string& color)
127
{
128
    DECL_TRACER("TColor::getColor(const std::string& color)");
129
 
130
    TColor::COLOR_T ct = getAMXColor(color);
131
    ulong col = ((ct.red << 24) & 0xff000000) | ((ct.green << 16) & 0x00ff0000) | ((ct.blue << 8) & 0x0000ff00) | (ct.alpha & 0x000000ff);
132
    return col;
133
}
7 andreas 134
 
135
std::string TColor::colorToString(ulong color)
136
{
137
    PDATA_T pd;
138
    pd.color = color;
139
    TColor::COLOR_T col = splitColors(pd);
140
    std::stringstream s;
141
    s << std::setw(2) << std::setfill('0') << std::hex << col.red << ":";
142
    s << std::setw(2) << std::setfill('0') << std::hex << col.green << ":";
143
    s << std::setw(2) << std::setfill('0') << std::hex << col.blue << ":";
144
    s << std::setw(2) << std::setfill('0') << std::hex << col.alpha;
145
    std::string ret = s.str();
146
    return ret;
147
}
148
 
149
std::string TColor::colorToString(SkColor color)
150
{
151
    std::stringstream s;
152
    s << std::setw(2) << std::setfill('0') << std::hex << SkColorGetR(color) << ":";
153
    s << std::setw(2) << std::setfill('0') << std::hex << SkColorGetG(color) << ":";
154
    s << std::setw(2) << std::setfill('0') << std::hex << SkColorGetB(color) << ":";
155
    s << std::setw(2) << std::setfill('0') << std::hex << SkColorGetA(color);
156
    std::string ret = s.str();
157
    return ret;
158
}
8 andreas 159
 
40 andreas 160
std::vector<SkColor> TColor::colorRange(SkColor col, int width, int bandwidth, DIRECTION_t dir)
161
{
162
    DECL_TRACER("TColor::colorRange(SkColor col, int width, int bandwidth)");
163
 
164
    int red, green, blue, alpha, colStep;
165
    vector<SkColor> colRange;
166
    SkColor color;
167
 
168
    alpha = SkColorGetA(col);
169
    // Define the start color
170
    if (dir == DIR_LIGHT_DARK || dir == DIR_LIGHT_DARK_LIGHT)
171
    {
172
        red = std::max((int)SkColorGetR(col) - bandwidth, 0);
173
        green = std::max((int)SkColorGetG(col) - bandwidth, 0);
174
        blue = std::max((int)SkColorGetB(col) - bandwidth, 0);
175
 
176
        if (dir == DIR_LIGHT_DARK)
177
            colStep = bandwidth / width;
178
        else
179
            colStep = bandwidth / (width / 2);
180
    }
181
    else
182
    {
183
        red = std::min((int)SkColorGetR(col) + bandwidth, 255);
184
        green = std::min((int)SkColorGetG(col) + bandwidth, 255);
185
        blue = std::min((int)SkColorGetB(col) + bandwidth, 255);
186
 
187
        if (dir == DIR_DARK_LIGHT)
188
            colStep = bandwidth / width;
189
        else
190
            colStep = bandwidth / (width / 2);
191
    }
192
 
193
    if (colStep <= 1)
194
    {
195
        colRange.push_back(col);
196
        return colRange;
197
    }
198
 
199
    switch(dir)
200
    {
201
        case DIR_LIGHT_DARK:
202
            for (int i = 0; i < width; i++)
203
            {
204
                red -= colStep * i;
205
                green -= colStep * i;
206
                blue -= colStep * i;
207
                color = SkColorSetARGB(alpha, red, green, blue);
208
                colRange.push_back(color);
209
            }
210
        break;
211
 
212
        case DIR_DARK_LIGHT:
213
            for (int i = 0; i < width; i++)
214
            {
215
                red += colStep * i;
216
                green += colStep * i;
217
                blue += colStep * i;
218
                color = SkColorSetARGB(alpha, red, green, blue);
219
                colRange.push_back(color);
220
            }
221
        break;
222
 
223
        case DIR_LIGHT_DARK_LIGHT:
224
            for (int i = 0; i < (width / 2); i++)
225
            {
226
                red -= colStep * i;
227
                green -= colStep * i;
228
                blue -= colStep * i;
229
                color = SkColorSetARGB(alpha, red, green, blue);
230
                colRange.push_back(color);
231
            }
232
 
233
            for (int i = 0; i < (width / 2); i++)
234
            {
235
                red += colStep * i;
236
                green += colStep * i;
237
                blue += colStep * i;
238
                color = SkColorSetARGB(alpha, red, green, blue);
239
                colRange.push_back(color);
240
            }
241
        break;
242
 
243
        case DIR_DARK_LIGHT_DARK:
244
            for (int i = 0; i < (width / 2); i++)
245
            {
246
                red += colStep * i;
247
                green += colStep * i;
248
                blue += colStep * i;
249
                color = SkColorSetARGB(alpha, red, green, blue);
250
                colRange.push_back(color);
251
            }
252
 
253
            for (int i = 0; i < (width / 2); i++)
254
            {
255
                red -= colStep * i;
256
                green -= colStep * i;
257
                blue -= colStep * i;
258
                color = SkColorSetARGB(alpha, red, green, blue);
259
                colRange.push_back(color);
260
            }
261
        break;
262
    }
263
 
264
    return colRange;
265
}
266
 
108 andreas 267
bool TColor::isValidAMXcolor(const string& color)
268
{
269
    DECL_TRACER("TColor::isValidAMXcolor(const string& color)");
270
 
271
    if (color.empty())
272
        return false;
273
 
274
    size_t pos = color.find('#');
275
 
276
    if (pos == string::npos)
277
    {
278
        if (!mPalette)
279
        {
280
            MSG_ERROR("No palette was set! First set a palette to be able to get any color!");
281
            return false;
282
        }
283
 
284
        PDATA_T pd = mPalette->findColor(color);
285
 
286
        if (!pd.name.empty())
287
            return true;
288
 
289
        return false;
290
    }
291
 
292
    // Check if we've an index number
293
    if (color.length() <= 2 && isdigit(color[0]))
294
    {
295
        int idx = atoi(color.c_str());
296
 
297
        if (idx < 0 || idx > 88)
298
            return false;
299
 
300
        return true;
301
    }
302
 
303
    if (color.length() >= 7)    // #RRGGBBAA
304
        return true;
305
 
306
    return false;
307
}
308
 
8 andreas 309
int TColor::setAlpha(ulong color, int alpha)
310
{
311
    DECL_TRACER("TColor::setAlpha(ulong color, int alpha)");
312
 
313
    if (alpha > 0x00ff)
314
        alpha = 0x00ff;
315
    else if (alpha < 0)
316
        alpha = 0;
317
 
318
    return ((color & 0xffffff00) | (alpha & 0x00ff));
319
}
320
 
321
SkColor TColor::setAlpha(SkColor color, int alpha)
322
{
323
    DECL_TRACER("TColor::setAlpha(SkColor color, int alpha)");
324
 
325
    if (alpha > 0x00ff)
326
        alpha = 0x00ff;
327
    else if (alpha < 0)
328
        alpha = 0;
329
 
330
    SkColor red = SkColorGetR(color);
331
    SkColor green = SkColorGetG(color);
332
    SkColor blue = SkColorGetB(color);
333
    return SkColorSetARGB(alpha, red, green, blue);
334
}
335
 
336
int TColor::calcAlpha(int alpha1, int alpha2)
337
{
338
    DECL_TRACER("TColor::calcAlpha(int alpha1, int alpha2)");
339
 
340
    return (alpha1 + alpha2) / 2;
341
}
342
 
343
ulong TColor::setAlphaTreshold(ulong color, int alpha)
344
{
345
    DECL_TRACER("TColor::setAlphaTreshold(ulong color, int alpha)");
346
 
347
    uint al = color & 0x000000ff;
348
 
349
    if (al > (uint)alpha)
350
        return (color & 0xffffff00) | (alpha & 0x00ff);
351
 
352
    return color;
353
}
354
 
355
SkColor TColor::setAlphaTreshold(SkColor color, int alpha)
356
{
357
    DECL_TRACER("TColor::setAlphaTreshold(SkColor color, int alpha)");
358
 
359
    int al = SkColorGetA(color);
360
 
361
    if (al > alpha)
362
        return SkColorSetA(color, alpha);
363
 
364
    return color;
365
}