Subversion Repositories tpanel

Rev

Rev 384 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 384 Rev 404
Line 32... Line 32...
32
#include "tresources.h"
32
#include "tresources.h"
33
#include "tpagemanager.h"
33
#include "tpagemanager.h"
34
#include "tintborder.h"
34
#include "tintborder.h"
35
#include "terror.h"
35
#include "terror.h"
36
 
36
 
-
 
37
#if __cplusplus < 201402L
-
 
38
#   error "This module requires at least C++14 standard!"
-
 
39
#else
-
 
40
#   if __cplusplus < 201703L
-
 
41
#       include <experimental/filesystem>
-
 
42
namespace fs = std::experimental::filesystem;
-
 
43
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
-
 
44
#   else
-
 
45
#       include <filesystem>
-
 
46
#       ifdef __ANDROID__
-
 
47
namespace fs = std::__fs::filesystem;
-
 
48
#       else
-
 
49
namespace fs = std::filesystem;
-
 
50
#       endif
-
 
51
#   endif
-
 
52
#endif
-
 
53
 
37
using std::string;
54
using std::string;
38
using std::vector;
55
using std::vector;
39
 
56
 
40
bool TPageInterface::drawText(PAGE_T& pinfo, SkBitmap *img)
57
bool TPageInterface::drawText(PAGE_T& pinfo, SkBitmap *img)
41
{
58
{
Line 186... Line 203...
186
        delete intBorder;
203
        delete intBorder;
187
        intBorder = nullptr;
204
        intBorder = nullptr;
188
    }
205
    }
189
 
206
 
190
    // Try to find the border in the system table
207
    // Try to find the border in the system table
191
    BORDER_t bd, bda;
208
    BORDER_t bd;
192
    bool classExist = (gPageManager && gPageManager->getSystemDraw());
209
    bool classExist = (gPageManager && gPageManager->getSystemDraw());
193
 
210
 
194
    if (!classExist)
211
    if (!classExist)
195
        return false;
212
        return false;
196
 
213
 
Line 199... Line 216...
199
    if (!gPageManager->getSystemDraw()->getBorder(borderName, TSystemDraw::LT_OFF, &bd, borderName))
216
    if (!gPageManager->getSystemDraw()->getBorder(borderName, TSystemDraw::LT_OFF, &bd, borderName))
200
        return false;
217
        return false;
201
 
218
 
202
    MSG_DEBUG("System border \"" << borderName << "\" found.");
219
    MSG_DEBUG("System border \"" << borderName << "\" found.");
203
    SkColor color = TColor::getSkiaColor(pinfo.sr[instance].cb);      // border color
220
    SkColor color = TColor::getSkiaColor(pinfo.sr[instance].cb);      // border color
204
    SkColor bgColor = TColor::getSkiaColor(pinfo.sr[instance].cf);    // fill color
-
 
205
    MSG_DEBUG("Button color: #" << std::setw(6) << std::setfill('0') << std::hex << color << std::dec);
221
    MSG_DEBUG("Button color: #" << std::setw(6) << std::setfill('0') << std::hex << color << std::dec);
206
    // Load images
222
    // Load images
207
    SkBitmap imgB, imgBR, imgR, imgTR, imgT, imgTL, imgL, imgBL;
223
    SkBitmap imgB, imgBR, imgR, imgTR, imgT, imgTL, imgL, imgBL;
208
 
224
 
209
    imgB = retrieveBorderImage(bd.b, bda.b, color, bgColor);
225
    if (!getBorderFragment(bd.b, bd.b_alpha, &imgB, color))
210
 
-
 
211
    if (imgB.empty())
-
 
212
        return false;
226
        return false;
213
 
227
 
214
    MSG_DEBUG("Got images " << bd.b << " and " << bda.b << " with size " << imgB.info().width() << " x " << imgB.info().height());
228
    MSG_DEBUG("Got images " << bd.b << " and " << bd.b_alpha << " with size " << imgB.info().width() << " x " << imgB.info().height());
215
    imgBR = retrieveBorderImage(bd.br, bda.br, color, bgColor);
229
    if (!getBorderFragment(bd.br, bd.br_alpha, &imgBR, color))
216
 
-
 
217
    if (imgBR.empty())
-
 
218
        return false;
230
        return false;
219
 
231
 
220
    MSG_DEBUG("Got images " << bd.br << " and " << bda.br << " with size " << imgBR.info().width() << " x " << imgBR.info().height());
232
    MSG_DEBUG("Got images " << bd.br << " and " << bd.br_alpha << " with size " << imgBR.info().width() << " x " << imgBR.info().height());
221
    imgR = retrieveBorderImage(bd.r, bda.r, color, bgColor);
233
    if (!getBorderFragment(bd.r, bd.r_alpha, &imgR, color))
222
 
-
 
223
    if (imgR.empty())
-
 
224
        return false;
234
        return false;
225
 
235
 
226
    MSG_DEBUG("Got images " << bd.r << " and " << bda.r << " with size " << imgR.info().width() << " x " << imgR.info().height());
236
    MSG_DEBUG("Got images " << bd.r << " and " << bd.r_alpha << " with size " << imgR.info().width() << " x " << imgR.info().height());
227
    imgTR = retrieveBorderImage(bd.tr, bda.tr, color, bgColor);
237
    if (!getBorderFragment(bd.tr, bd.tr_alpha, &imgTR, color))
228
 
-
 
229
    if (imgTR.empty())
-
 
230
        return false;
238
        return false;
231
 
239
 
232
    MSG_DEBUG("Got images " << bd.tr << " and " << bda.tr << " with size " << imgTR.info().width() << " x " << imgTR.info().height());
240
    MSG_DEBUG("Got images " << bd.tr << " and " << bd.tr_alpha << " with size " << imgTR.info().width() << " x " << imgTR.info().height());
233
    imgT = retrieveBorderImage(bd.t, bda.t, color, bgColor);
241
    if (getBorderFragment(bd.t, bd.t_alpha, &imgT, color))
234
 
-
 
235
    if (imgT.empty())
-
 
236
        return false;
242
        return false;
237
 
243
 
238
    MSG_DEBUG("Got images " << bd.t << " and " << bda.t << " with size " << imgT.info().width() << " x " << imgT.info().height());
244
    MSG_DEBUG("Got images " << bd.t << " and " << bd.t_alpha << " with size " << imgT.info().width() << " x " << imgT.info().height());
239
    imgTL = retrieveBorderImage(bd.tl, bda.tl, color, bgColor);
245
    if (!getBorderFragment(bd.tl, bd.tl_alpha, &imgTL, color))
240
 
-
 
241
    if (imgTL.empty())
-
 
242
        return false;
246
        return false;
243
 
247
 
244
    MSG_DEBUG("Got images " << bd.tl << " and " << bda.tl << " with size " << imgTL.info().width() << " x " << imgTL.info().height());
248
    MSG_DEBUG("Got images " << bd.tl << " and " << bd.tl_alpha << " with size " << imgTL.info().width() << " x " << imgTL.info().height());
245
    imgL = retrieveBorderImage(bd.l, bda.l, color, bgColor);
249
    if (!getBorderFragment(bd.l, bd.l_alpha, &imgL, color))
246
 
-
 
247
    if (imgL.empty())
-
 
248
        return false;
250
        return false;
249
 
251
 
250
    MSG_DEBUG("Got images " << bd.l << " and " << bda.l << " with size " << imgL.info().width() << " x " << imgL.info().height());
252
    MSG_DEBUG("Got images " << bd.l << " and " << bd.l_alpha << " with size " << imgL.info().width() << " x " << imgL.info().height());
251
    imgBL = retrieveBorderImage(bd.bl, bda.bl, color, bgColor);
253
    if (!getBorderFragment(bd.bl, bd.bl_alpha, &imgBL, color))
252
 
-
 
253
    if (imgBL.empty())
-
 
254
        return false;
254
        return false;
255
 
255
 
256
    MSG_DEBUG("Got images " << bd.bl << " and " << bda.bl << " with size " << imgBL.info().width() << " x " << imgBL.info().height());
256
    MSG_DEBUG("Got images " << bd.bl << " and " << bd.bl_alpha << " with size " << imgBL.info().width() << " x " << imgBL.info().height());
257
    MSG_DEBUG("Button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
257
    MSG_DEBUG("Button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
258
    MSG_DEBUG("Total size: " << pinfo.width << " x " << pinfo.height);
258
    MSG_DEBUG("Total size: " << pinfo.width << " x " << pinfo.height);
259
    stretchImageWidth(&imgB, pinfo.width - imgBL.info().width() - imgBR.info().width());
259
    stretchImageWidth(&imgB, pinfo.width - imgBL.info().width() - imgBR.info().width());
260
    stretchImageWidth(&imgT, pinfo.width - imgTL.info().width() - imgTR.info().width());
260
    stretchImageWidth(&imgT, pinfo.width - imgTL.info().width() - imgTR.info().width());
261
    stretchImageHeight(&imgL, pinfo.height - imgTL.info().height() - imgBL.info().height());
261
    stretchImageHeight(&imgL, pinfo.height - imgTL.info().height() - imgBL.info().height());
262
    stretchImageHeight(&imgR, pinfo.height - imgTR.info().height() - imgBR.info().height());
262
    stretchImageHeight(&imgR, pinfo.height - imgTR.info().height() - imgBR.info().height());
263
    MSG_DEBUG("Stretched button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
263
    MSG_DEBUG("Stretched button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
264
    // Draw the frame
264
    // Draw the frame
-
 
265
    SkBitmap frame;
-
 
266
    allocPixels(bm->info().width(), bm->info().height(), &frame);
-
 
267
    frame.eraseColor(SK_ColorTRANSPARENT);
-
 
268
    SkCanvas target(*bm, SkSurfaceProps());
-
 
269
    SkCanvas canvas(frame, SkSurfaceProps());
265
    SkPaint paint;
270
    SkPaint paint;
266
    SkCanvas canvas(*bm, SkSurfaceProps());
-
 
267
 
271
 
268
    paint.setBlendMode(SkBlendMode::kSrc);
272
    paint.setBlendMode(SkBlendMode::kSrcOver);
269
    paint.setColor(color);
273
    paint.setAntiAlias(true);
270
    sk_sp<SkImage> _image = SkImages::RasterFromBitmap(imgB);                                                                              // Bottom
274
    sk_sp<SkImage> _image = SkImages::RasterFromBitmap(imgB);   // bottom
271
    canvas.drawImage(_image, imgBL.info().width(), pinfo.height - imgB.info().height(), SkSamplingOptions(), &paint);
275
    canvas.drawImage(_image, imgBL.info().width(), pinfo.height - imgB.info().height(), SkSamplingOptions(), &paint);
-
 
276
    _image = SkImages::RasterFromBitmap(imgT);                  // top
-
 
277
    canvas.drawImage(_image, imgTL.info().width(), 0, SkSamplingOptions(), &paint);
272
    _image = SkImages::RasterFromBitmap(imgBR);                                                                                            // Corner bottom right
278
    _image = SkImages::RasterFromBitmap(imgBR);                 // bottom right
273
    canvas.drawImage(_image, pinfo.width - imgBR.info().width(), pinfo.height - imgBR.info().height(), SkSamplingOptions(), &paint);
279
    canvas.drawImage(_image, pinfo.width - imgBR.info().width(), pinfo.height - imgBR.info().height(), SkSamplingOptions(), &paint);
274
    _image = SkImages::RasterFromBitmap(imgR);                                                                                             // Right
-
 
275
    canvas.drawImage(_image, pinfo.width - imgR.info().width(), imgTR.info().height(), SkSamplingOptions(), &paint);
-
 
276
    _image = SkImages::RasterFromBitmap(imgTR);                                                                                            // Corner top right
280
    _image = SkImages::RasterFromBitmap(imgTR);                 // top right
277
    canvas.drawImage(_image, pinfo.width - imgTR.info().width(), 0, SkSamplingOptions(), &paint);
281
    canvas.drawImage(_image, pinfo.width - imgTR.info().width(), 0, SkSamplingOptions(), &paint);
278
    _image = SkImages::RasterFromBitmap(imgT);                                                                                             // Top
-
 
279
    canvas.drawImage(_image, imgTL.info().width(), 0, SkSamplingOptions(), &paint);
-
 
280
    _image = SkImages::RasterFromBitmap(imgTL);                                                                                            // Corner top left
282
    _image = SkImages::RasterFromBitmap(imgTL);                 // top left
281
    canvas.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
283
    canvas.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
282
    _image = SkImages::RasterFromBitmap(imgL);                                                                                             // Left
-
 
283
    canvas.drawImage(_image, 0, imgTL.info().height(), SkSamplingOptions(), &paint);
-
 
284
    _image = SkImages::RasterFromBitmap(imgBL);                                                                                            // Corner bottom left
284
    _image = SkImages::RasterFromBitmap(imgBL);                 // bottom left
285
    canvas.drawImage(_image, 0, pinfo.height - imgBL.info().height(), SkSamplingOptions(), &paint);
285
    canvas.drawImage(_image, 0, pinfo.height - imgBL.info().height(), SkSamplingOptions(), &paint);
-
 
286
    _image = SkImages::RasterFromBitmap(imgL);                  // left
-
 
287
    canvas.drawImage(_image, 0, imgTL.info().height(), SkSamplingOptions(), &paint);
-
 
288
    _image = SkImages::RasterFromBitmap(imgR);                  // right
-
 
289
    canvas.drawImage(_image, pinfo.width - imgR.info().width(), imgTR.info().height(), SkSamplingOptions(), &paint);
-
 
290
 
-
 
291
    Border::TIntBorder iborder;
-
 
292
    iborder.erasePart(bm, frame, Border::ERASE_OUTSIDE, imgL.info().width());
-
 
293
    _image = SkImages::RasterFromBitmap(frame);
-
 
294
    paint.setBlendMode(SkBlendMode::kSrcATop);
-
 
295
    target.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
286
    return true;
296
    return true;
287
}
297
}
288
 
298
 
289
Button::POSITION_t TPageInterface::calcImagePosition(PAGE_T *page, int width, int height, Button::CENTER_CODE cc, int line)
299
Button::POSITION_t TPageInterface::calcImagePosition(PAGE_T *page, int width, int height, Button::CENTER_CODE cc, int line)
290
{
300
{
Line 1124... Line 1134...
1124
    }
1134
    }
1125
 
1135
 
1126
    return string();
1136
    return string();
1127
}
1137
}
1128
 
1138
 
-
 
1139
/**
-
 
1140
 * @brief getBorderFragment - get part of border
-
 
1141
 * The method reads a border image fragment from the disk and converts it to
-
 
1142
 * the border color. If there is a base image and an alpha mask image, the
-
 
1143
 * pixels of the alpha mask are converted to the border color and then the base
-
 
1144
 * image is layed over the mask image.
-
 
1145
 * In case there is no base image, an image with the same size as the mask image
-
 
1146
 * is created and filled transparaent.
-
 
1147
 *
-
 
1148
 * @param path      The path and file name of the base image.
-
 
1149
 * @param pathAlpha The path and file name of the alpha mask image.
-
 
1150
 * @param image     A pointer to an empty bitmap.
-
 
1151
 * @param color     The border color
-
 
1152
 *
-
 
1153
 * @return In case the images exists and were loaded successfully, TRUE is
-
 
1154
 * returned.
-
 
1155
 */
-
 
1156
bool TPageInterface::getBorderFragment(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)
-
 
1157
{
-
 
1158
    DECL_TRACER("TPageInterface::getBorderFragment(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)");
-
 
1159
 
-
 
1160
    if (!image)
-
 
1161
    {
-
 
1162
        MSG_ERROR("Invalid pointer to image!");
-
 
1163
        return false;
-
 
1164
    }
-
 
1165
 
-
 
1166
    sk_sp<SkData> im;
-
 
1167
    SkBitmap bm;
-
 
1168
    bool haveBaseImage = false;
-
 
1169
 
-
 
1170
    // If the path ends with "alpha.png" then it is a mask image. This not what
-
 
1171
    // we want first unless this is the only image available.
-
 
1172
    if (!endsWith(path, "alpha.png") || pathAlpha.empty())
-
 
1173
    {
-
 
1174
        if (retrieveImage(path, image))
-
 
1175
        {
-
 
1176
            haveBaseImage = true;
-
 
1177
            // Underly the pixels with the border color
-
 
1178
            MSG_DEBUG("Path: " << path << ", pathAlpha: " << pathAlpha);
-
 
1179
            if (pathAlpha.empty() || !fs::exists(pathAlpha) || path == pathAlpha)
-
 
1180
            {
-
 
1181
                SkImageInfo info = image->info();
-
 
1182
                SkBitmap b;
-
 
1183
                allocPixels(info.width(), info.height(), &b);
-
 
1184
                b.eraseColor(SK_ColorTRANSPARENT);
-
 
1185
 
-
 
1186
                for (int x = 0; x < info.width(); ++x)
-
 
1187
                {
-
 
1188
                    for (int y = 0; y < info.height(); ++y)
-
 
1189
                    {
-
 
1190
                        SkColor alpha = SkColorGetA(image->getColor(x, y));
-
 
1191
                        uint32_t *pix = b.getAddr32(x, y);
-
 
1192
 
-
 
1193
                        if (alpha > 0)
-
 
1194
                            *pix = color;
-
 
1195
                    }
-
 
1196
                }
-
 
1197
 
-
 
1198
                SkPaint paint;
-
 
1199
                paint.setAntiAlias(true);
-
 
1200
                paint.setBlendMode(SkBlendMode::kDstATop);
-
 
1201
                SkCanvas can(*image);
-
 
1202
                sk_sp<SkImage> _image = SkImages::RasterFromBitmap(b);
-
 
1203
                can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
-
 
1204
            }
-
 
1205
        }
-
 
1206
    }
-
 
1207
 
-
 
1208
    // If there is no valid path return.
-
 
1209
    if (pathAlpha.empty())
-
 
1210
        return haveBaseImage;
-
 
1211
 
-
 
1212
    // On error retrieving the image, return.
-
 
1213
    if (!retrieveImage(pathAlpha, &bm))
-
 
1214
        return haveBaseImage;
-
 
1215
 
-
 
1216
    // If there was no base image loaded, allocate the space for an image
-
 
1217
    // filled transparent. Make it the same size as the mask image.
-
 
1218
    if (!haveBaseImage)
-
 
1219
    {
-
 
1220
        allocPixels(bm.info().width(), bm.info().height(), image);
-
 
1221
        image->eraseColor(SK_ColorTRANSPARENT);
-
 
1222
    }
-
 
1223
 
-
 
1224
    // Only if the base image and the mask image have the same size, which
-
 
1225
    // should be the case, then the visible pixels of the mask image are
-
 
1226
    // colored by the border color.
-
 
1227
    if (image->info().dimensions() == bm.info().dimensions())
-
 
1228
    {
-
 
1229
        for (int y = 0; y < image->info().height(); ++y)
-
 
1230
        {
-
 
1231
            for (int x = 0; x < image->info().width(); ++x)
-
 
1232
            {
-
 
1233
                SkColor col = bm.getColor(x, y);
-
 
1234
                SkColor alpha = SkColorGetA(col);
-
 
1235
                uint32_t *pix = bm.getAddr32(x, y);
-
 
1236
 
-
 
1237
                if (alpha == 0)
-
 
1238
                    *pix = SK_ColorTRANSPARENT;
-
 
1239
                else
-
 
1240
                    *pix = SkColorSetA(color, alpha);
-
 
1241
            }
-
 
1242
        }
-
 
1243
    }
-
 
1244
 
-
 
1245
    // Here we draw the border fragment over the base image.
-
 
1246
    SkPaint paint;
-
 
1247
    paint.setAntiAlias(true);
-
 
1248
    paint.setBlendMode(SkBlendMode::kDstATop);
-
 
1249
    SkCanvas can(*image);
-
 
1250
    sk_sp<SkImage> _image = SkImages::RasterFromBitmap(bm);
-
 
1251
    can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
-
 
1252
 
-
 
1253
    return true;
-
 
1254
}
-
 
1255
 
1129
SkBitmap TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)
1256
SkBitmap TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)
1130
{
1257
{
1131
    DECL_TRACER("TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)");
1258
    DECL_TRACER("TPageInterface::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)");
1132
 
1259
 
1133
    SkBitmap bm, bma;
1260
    SkBitmap bm, bma;