Subversion Repositories tpanel

Rev

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

Rev 403 Rev 404
Line 61... Line 61...
61
#include "tlock.h"
61
#include "tlock.h"
62
#if TESTMODE == 1
62
#if TESTMODE == 1
63
#include "testmode.h"
63
#include "testmode.h"
64
#endif
64
#endif
65
 
65
 
-
 
66
#if __cplusplus < 201402L
-
 
67
#   error "This module requires at least C++14 standard!"
-
 
68
#else
-
 
69
#   if __cplusplus < 201703L
-
 
70
#       include <experimental/filesystem>
-
 
71
namespace fs = std::experimental::filesystem;
-
 
72
#       warning "Support for C++14 and experimental filesystem will be removed in a future version!"
-
 
73
#   else
-
 
74
#       include <filesystem>
-
 
75
#       ifdef __ANDROID__
-
 
76
namespace fs = std::__fs::filesystem;
-
 
77
#       else
-
 
78
namespace fs = std::filesystem;
-
 
79
#       endif
-
 
80
#   endif
-
 
81
#endif
-
 
82
 
66
using std::exception;
83
using std::exception;
67
using std::string;
84
using std::string;
68
using std::vector;
85
using std::vector;
69
using std::unique_ptr;
86
using std::unique_ptr;
70
using std::map;
87
using std::map;
Line 5407... Line 5424...
5407
        return true;
5424
        return true;
5408
 
5425
 
5409
    // The border was not found or defined to be not drawn. Therefor we look
5426
    // The border was not found or defined to be not drawn. Therefor we look
5410
    // into the system directory (__system/graphics/borders). If the wanted
5427
    // into the system directory (__system/graphics/borders). If the wanted
5411
    // border exists there, we're drawing it.
5428
    // border exists there, we're drawing it.
5412
    BORDER_t bd, bda;
5429
    BORDER_t bd;
5413
    int numBorders = 0;
5430
    int numBorders = 0;
5414
 
5431
 
5415
    if (sr.size() == 2)
5432
    if (sr.size() == 2)
5416
    {
5433
    {
5417
        if (gPageManager->getSystemDraw()->getBorder(bname, TSystemDraw::LT_OFF, &bd))
5434
        if (gPageManager->getSystemDraw()->getBorder(bname, TSystemDraw::LT_OFF, &bd))
5418
            numBorders++;
5435
            numBorders++;
5419
 
-
 
5420
        if (gPageManager->getSystemDraw()->getBorder(bname, TSystemDraw::LT_ON, &bda))
-
 
5421
            numBorders++;
-
 
5422
    }
5436
    }
5423
    else if (gPageManager->getSystemDraw()->getBorder(bname, TSystemDraw::LT_ON, &bd))
5437
    else if (gPageManager->getSystemDraw()->getBorder(bname, TSystemDraw::LT_ON, &bd))
5424
        numBorders++;
5438
        numBorders++;
5425
 
5439
 
5426
    if (numBorders > 0)
5440
    if (numBorders > 0)
Line 5428... Line 5442...
5428
        SkColor color = TColor::getSkiaColor(sr[instance].cb);      // border color
5442
        SkColor color = TColor::getSkiaColor(sr[instance].cb);      // border color
5429
        MSG_DEBUG("Button color: #" << std::setw(6) << std::setfill('0') << std::hex << color);
5443
        MSG_DEBUG("Button color: #" << std::setw(6) << std::setfill('0') << std::hex << color);
5430
        // Load images
5444
        // Load images
5431
        SkBitmap imgB, imgBR, imgR, imgTR, imgT, imgTL, imgL, imgBL;
5445
        SkBitmap imgB, imgBR, imgR, imgTR, imgT, imgTL, imgL, imgBL;
5432
 
5446
 
5433
        if (!retrieveImage(bd.b, bda.b, &imgB, color) || imgB.empty())
5447
        if (!getBorderFragment(bd.b, bd.b_alpha, &imgB, color) || imgB.empty())
5434
            return false;
5448
            return false;
5435
 
5449
 
5436
        MSG_DEBUG("Got images " << bd.b << " and " << bda.b << " with size " << imgB.info().width() << " x " << imgB.info().height());
5450
        MSG_DEBUG("Got images " << bd.b << " and " << bd.b_alpha << " with size " << imgB.info().width() << " x " << imgB.info().height());
5437
        if (!retrieveImage(bd.br, bda.br, &imgBR, color) || imgBR.empty())
5451
        if (!getBorderFragment(bd.br, bd.br_alpha, &imgBR, color) || imgBR.empty())
5438
            return false;
5452
            return false;
5439
 
5453
 
5440
        MSG_DEBUG("Got images " << bd.br << " and " << bda.br << " with size " << imgBR.info().width() << " x " << imgBR.info().height());
5454
        MSG_DEBUG("Got images " << bd.br << " and " << bd.br_alpha << " with size " << imgBR.info().width() << " x " << imgBR.info().height());
5441
        if (!retrieveImage(bd.r, bda.r, &imgR, color) || imgR.empty())
5455
        if (!getBorderFragment(bd.r, bd.r_alpha, &imgR, color) || imgR.empty())
5442
            return false;
5456
            return false;
5443
 
5457
 
5444
        MSG_DEBUG("Got images " << bd.r << " and " << bda.r << " with size " << imgR.info().width() << " x " << imgR.info().height());
5458
        MSG_DEBUG("Got images " << bd.r << " and " << bd.r_alpha << " with size " << imgR.info().width() << " x " << imgR.info().height());
5445
        if (!retrieveImage(bd.tr, bda.tr, &imgTR, color) || imgTR.empty())
5459
        if (!getBorderFragment(bd.tr, bd.tr_alpha, &imgTR, color) || imgTR.empty())
5446
            return false;
5460
            return false;
5447
 
5461
 
5448
        MSG_DEBUG("Got images " << bd.tr << " and " << bda.tr << " with size " << imgTR.info().width() << " x " << imgTR.info().height());
5462
        MSG_DEBUG("Got images " << bd.tr << " and " << bd.tr_alpha << " with size " << imgTR.info().width() << " x " << imgTR.info().height());
5449
        if (!retrieveImage(bd.t, bda.t, &imgT, color) || imgT.empty())
5463
        if (!getBorderFragment(bd.t, bd.t_alpha, &imgT, color) || imgT.empty())
5450
            return false;
5464
            return false;
5451
 
5465
 
5452
        MSG_DEBUG("Got images " << bd.t << " and " << bda.t << " with size " << imgT.info().width() << " x " << imgT.info().height());
5466
        MSG_DEBUG("Got images " << bd.t << " and " << bd.t_alpha << " with size " << imgT.info().width() << " x " << imgT.info().height());
5453
        if (!retrieveImage(bd.tl, bda.tl, &imgTL, color) || imgTL.empty())
5467
        if (!getBorderFragment(bd.tl, bd.tl_alpha, &imgTL, color) || imgTL.empty())
5454
            return false;
5468
            return false;
5455
 
5469
 
5456
        MSG_DEBUG("Got images " << bd.tl << " and " << bda.tl << " with size " << imgTL.info().width() << " x " << imgTL.info().height());
5470
        MSG_DEBUG("Got images " << bd.tl << " and " << bd.tl_alpha << " with size " << imgTL.info().width() << " x " << imgTL.info().height());
5457
        if (!retrieveImage(bd.l, bda.l, &imgL, color) || imgL.empty())
5471
        if (!getBorderFragment(bd.l, bd.l_alpha, &imgL, color) || imgL.empty())
5458
            return false;
5472
            return false;
5459
 
5473
 
5460
        mBorderWidth = imgL.info().width();
5474
        mBorderWidth = imgL.info().width();
5461
        MSG_DEBUG("Got images " << bd.l << " and " << bda.l << " with size " << imgL.info().width() << " x " << imgL.info().height());
5475
        MSG_DEBUG("Got images " << bd.l << " and " << bd.l_alpha << " with size " << imgL.info().width() << " x " << imgL.info().height());
5462
 
5476
 
5463
        if (!retrieveImage(bd.bl, bda.bl, &imgBL, color) || imgBL.empty())
5477
        if (!getBorderFragment(bd.bl, bd.bl_alpha, &imgBL, color) || imgBL.empty())
5464
            return false;
5478
            return false;
5465
 
5479
 
5466
        MSG_DEBUG("Got images " << bd.bl << " and " << bda.bl << " with size " << imgBL.info().width() << " x " << imgBL.info().height());
5480
        MSG_DEBUG("Got images " << bd.bl << " and " << bd.bl_alpha << " with size " << imgBL.info().width() << " x " << imgBL.info().height());
5467
        MSG_DEBUG("Button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
5481
        MSG_DEBUG("Button image size: " << (imgTL.info().width() + imgT.info().width() + imgTR.info().width()) << " x " << (imgTL.info().height() + imgL.info().height() + imgBL.info().height()));
5468
        MSG_DEBUG("Total size: " << wt << " x " << ht);
5482
        MSG_DEBUG("Total size: " << wt << " x " << ht);
5469
        stretchImageWidth(&imgB, wt - imgBL.info().width() - imgBR.info().width());
5483
        stretchImageWidth(&imgB, wt - imgBL.info().width() - imgBR.info().width());
5470
        stretchImageWidth(&imgT, wt - imgTL.info().width() - imgTR.info().width());
5484
        stretchImageWidth(&imgT, wt - imgTL.info().width() - imgTR.info().width());
5471
        stretchImageHeight(&imgL, ht - imgTL.info().height() - imgBL.info().height());
5485
        stretchImageHeight(&imgL, ht - imgTL.info().height() - imgBL.info().height());
Line 5478... Line 5492...
5478
        SkCanvas target(*bm, SkSurfaceProps());
5492
        SkCanvas target(*bm, SkSurfaceProps());
5479
        SkCanvas canvas(frame, SkSurfaceProps());
5493
        SkCanvas canvas(frame, SkSurfaceProps());
5480
        SkPaint paint;
5494
        SkPaint paint;
5481
 
5495
 
5482
        paint.setBlendMode(SkBlendMode::kSrcOver);
5496
        paint.setBlendMode(SkBlendMode::kSrcOver);
-
 
5497
        paint.setAntiAlias(true);
5483
        sk_sp<SkImage> _image = SkImages::RasterFromBitmap(imgB);   // bottom
5498
        sk_sp<SkImage> _image = SkImages::RasterFromBitmap(imgB);   // bottom
5484
        canvas.drawImage(_image, imgBL.info().width(), ht - imgB.info().height(), SkSamplingOptions(), &paint);
5499
        canvas.drawImage(_image, imgBL.info().width(), ht - imgB.info().height(), SkSamplingOptions(), &paint);
5485
        _image = SkImages::RasterFromBitmap(imgT);                  // top
5500
        _image = SkImages::RasterFromBitmap(imgT);                  // top
5486
        canvas.drawImage(_image, imgTL.info().width(), 0, SkSamplingOptions(), &paint);
5501
        canvas.drawImage(_image, imgTL.info().width(), 0, SkSamplingOptions(), &paint);
5487
        _image = SkImages::RasterFromBitmap(imgBR);                 // bottom right
5502
        _image = SkImages::RasterFromBitmap(imgBR);                 // bottom right
Line 5496... Line 5511...
5496
        canvas.drawImage(_image, 0, imgTL.info().height(), SkSamplingOptions(), &paint);
5511
        canvas.drawImage(_image, 0, imgTL.info().height(), SkSamplingOptions(), &paint);
5497
        _image = SkImages::RasterFromBitmap(imgR);                  // right
5512
        _image = SkImages::RasterFromBitmap(imgR);                  // right
5498
        canvas.drawImage(_image, wt - imgR.info().width(), imgTR.info().height(), SkSamplingOptions(), &paint);
5513
        canvas.drawImage(_image, wt - imgR.info().width(), imgTR.info().height(), SkSamplingOptions(), &paint);
5499
 
5514
 
5500
        erasePart(bm, frame, Border::ERASE_OUTSIDE, imgL.info().width());
5515
        erasePart(bm, frame, Border::ERASE_OUTSIDE, imgL.info().width());
5501
//        backgroundFrame(bm, frame, color);
-
 
5502
        _image = SkImages::RasterFromBitmap(frame);
5516
        _image = SkImages::RasterFromBitmap(frame);
5503
        paint.setBlendMode(SkBlendMode::kSrcATop);
5517
        paint.setBlendMode(SkBlendMode::kSrcATop);
5504
        target.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
5518
        target.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
5505
    }
5519
    }
5506
    else    // We try to draw a frame by forcing it to draw even the not to draw marked frames.
5520
    else    // We try to draw a frame by forcing it to draw even the not to draw marked frames.
Line 7255... Line 7269...
7255
    }
7269
    }
7256
 
7270
 
7257
    return maskBm;
7271
    return maskBm;
7258
}
7272
}
7259
 
7273
 
7260
SkBitmap TButton::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)
-
 
7261
{
-
 
7262
    DECL_TRACER("TButton::retrieveBorderImage(const string& pa, const string& pb, SkColor color, SkColor bgColor)");
-
 
7263
 
-
 
7264
    SkBitmap bm, bma;
-
 
7265
 
-
 
7266
    if (!pa.empty() && !retrieveImage(pa, &bm))
-
 
7267
        return SkBitmap();
-
 
7268
 
-
 
7269
    if (!pb.empty() && !retrieveImage(pb, &bma))
-
 
7270
        return bm;
-
 
7271
//        return SkBitmap();
-
 
7272
 
-
 
7273
    return colorImage(bm, bma, color, bgColor, false);
-
 
7274
}
-
 
7275
 
-
 
7276
bool TButton::retrieveImage(const string& path, SkBitmap* image)
7274
bool TButton::retrieveImage(const string& path, SkBitmap* image)
7277
{
7275
{
7278
    DECL_TRACER("TButton::retrieveImage(const string& path, SkBitmap* image)");
7276
    DECL_TRACER("TButton::retrieveImage(const string& path, SkBitmap* image)");
7279
 
7277
 
-
 
7278
    if (!fs::exists(path) || !fs::is_regular_file(path))
-
 
7279
    {
-
 
7280
        MSG_WARNING("File " << path << " does not exist or is not a regular file!");
-
 
7281
        return false;
-
 
7282
    }
-
 
7283
 
7280
    sk_sp<SkData> im;
7284
    sk_sp<SkData> im;
7281
 
7285
 
7282
    if (!(im = readImage(path)))
7286
    if (!(im = readImage(path)))
7283
        return false;
7287
        return false;
7284
 
7288
 
Line 7292... Line 7296...
7292
 
7296
 
7293
    return true;
7297
    return true;
7294
}
7298
}
7295
 
7299
 
7296
/**
7300
/**
7297
 * @brief retrieveImage - get border
7301
 * @brief getBorderFragment - get part of border
7298
 * The method reads a particular border image from the disk and converts it to
7302
 * The method reads a border image fragment from the disk and converts it to
7299
 * the border color. If there is a base image and a alpha mask image, the pixels
7303
 * the border color. If there is a base image and an alpha mask image, the
7300
 * of the alpha mask are converted to the border color and then the base image
7304
 * pixels of the alpha mask are converted to the border color and then the base
7301
 * is layed over the mask image.
7305
 * image is layed over the mask image.
7302
 * In case there is no base image, an image with the same size as the mask image
7306
 * In case there is no base image, an image with the same size as the mask image
7303
 * is created and filled transparaent.
7307
 * is created and filled transparaent.
7304
 *
7308
 *
7305
 * @param path      The path and file name of the base image.
7309
 * @param path      The path and file name of the base image.
7306
 * @param pathAlpha The path and file name of the alpha mask image.
7310
 * @param pathAlpha The path and file name of the alpha mask image.
Line 7308... Line 7312...
7308
 * @param color     The border color
7312
 * @param color     The border color
7309
 *
7313
 *
7310
 * @return In case the images exists and were loaded successfully, TRUE is
7314
 * @return In case the images exists and were loaded successfully, TRUE is
7311
 * returned.
7315
 * returned.
7312
 */
7316
 */
7313
bool TButton::retrieveImage(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)
7317
bool TButton::getBorderFragment(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)
7314
{
7318
{
7315
    DECL_TRACER("TButton::retrieveImage(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)");
7319
    DECL_TRACER("TButton::getBorderFragment(const string& path, const string& pathAlpha, SkBitmap* image, SkColor color)");
-
 
7320
 
-
 
7321
    if (!image)
-
 
7322
    {
-
 
7323
        MSG_ERROR("Invalid pointer to image!");
-
 
7324
        return false;
-
 
7325
    }
7316
 
7326
 
7317
    sk_sp<SkData> im;
7327
    sk_sp<SkData> im;
7318
    SkBitmap bm;
7328
    SkBitmap bm;
7319
    bool haveBaseImage = false;
7329
    bool haveBaseImage = false;
7320
 
7330
 
-
 
7331
    // If the path ends with "alpha.png" then it is a mask image. This not what
-
 
7332
    // we want first unless this is the only image available.
7321
    if (!endsWith(path, "alpha.png") || pathAlpha.empty())
7333
    if (!endsWith(path, "alpha.png") || pathAlpha.empty())
7322
    {
7334
    {
7323
        if (!(im = readImage(path)))
7335
        if (retrieveImage(path, image))
-
 
7336
        {
-
 
7337
            haveBaseImage = true;
-
 
7338
            // Underly the pixels with the border color
-
 
7339
            MSG_DEBUG("Path: " << path << ", pathAlpha: " << pathAlpha);
-
 
7340
            if (pathAlpha.empty() || !fs::exists(pathAlpha) || path == pathAlpha)
-
 
7341
            {
-
 
7342
                SkImageInfo info = image->info();
7324
            return false;
7343
                SkBitmap b;
-
 
7344
                allocPixels(info.width(), info.height(), &b);
-
 
7345
                b.eraseColor(SK_ColorTRANSPARENT);
7325
 
7346
 
7326
        DecodeDataToBitmap(im, image);
7347
                for (int x = 0; x < info.width(); ++x)
-
 
7348
                {
-
 
7349
                    for (int y = 0; y < info.height(); ++y)
-
 
7350
                    {
-
 
7351
                        SkColor alpha = SkColorGetA(image->getColor(x, y));
-
 
7352
                        uint32_t *pix = b.getAddr32(x, y);
7327
 
7353
 
7328
        if (image->empty())
7354
                        if (alpha > 0)
7329
        {
-
 
7330
            MSG_WARNING("Could not create the image " << path);
7355
                            *pix = color;
7331
            return false;
7356
                    }
7332
        }
7357
                }
7333
 
7358
 
7334
        haveBaseImage = true;
7359
                SkPaint paint;
-
 
7360
                paint.setAntiAlias(true);
-
 
7361
                paint.setBlendMode(SkBlendMode::kDstATop);
-
 
7362
                SkCanvas can(*image);
-
 
7363
                sk_sp<SkImage> _image = SkImages::RasterFromBitmap(b);
-
 
7364
                can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
-
 
7365
            }
-
 
7366
        }
7335
    }
7367
    }
7336
 
7368
 
-
 
7369
    // If there is no valid path return.
7337
    if (pathAlpha.empty())
7370
    if (pathAlpha.empty())
7338
        return true;
-
 
7339
 
-
 
7340
    if (!(im = readImage(pathAlpha)))
-
 
7341
        return true;
7371
        return haveBaseImage;
7342
 
7372
 
7343
    DecodeDataToBitmap(im, &bm);
7373
    // On error retrieving the image, return.
7344
 
-
 
7345
    if (bm.empty())
7374
    if (!retrieveImage(pathAlpha, &bm))
7346
    {
-
 
7347
        MSG_WARNING("Could not create alpha mask image " << pathAlpha);
-
 
7348
        return true;
7375
        return haveBaseImage;
7349
    }
-
 
7350
 
7376
 
-
 
7377
    // If there was no base image loaded, allocate the space for an image
-
 
7378
    // filled transparent. Make it the same size as the mask image.
7351
    if (!haveBaseImage)
7379
    if (!haveBaseImage)
7352
    {
7380
    {
7353
        allocPixels(bm.info().width(), bm.info().height(), image);
7381
        allocPixels(bm.info().width(), bm.info().height(), image);
7354
        image->eraseColor(SK_ColorTRANSPARENT);
7382
        image->eraseColor(SK_ColorTRANSPARENT);
7355
    }
7383
    }
7356
 
7384
 
-
 
7385
    // Only if the base image and the mask image have the same size, which
-
 
7386
    // should be the case, then the visible pixels of the mask image are
-
 
7387
    // colored by the border color.
7357
    if (image->info().dimensions() == bm.info().dimensions())
7388
    if (image->info().dimensions() == bm.info().dimensions())
7358
    {
7389
    {
7359
        for (int y = 0; y < image->info().height(); ++y)
7390
        for (int y = 0; y < image->info().height(); ++y)
7360
        {
7391
        {
7361
            for (int x = 0; x < image->info().width(); ++x)
7392
            for (int x = 0; x < image->info().width(); ++x)
Line 7370... Line 7401...
7370
                    *pix = SkColorSetA(color, alpha);
7401
                    *pix = SkColorSetA(color, alpha);
7371
            }
7402
            }
7372
        }
7403
        }
7373
    }
7404
    }
7374
 
7405
 
-
 
7406
    // Here we draw the border fragment over the base image.
7375
    SkPaint paint;
7407
    SkPaint paint;
-
 
7408
    paint.setAntiAlias(true);
7376
    paint.setBlendMode(SkBlendMode::kDstATop);
7409
    paint.setBlendMode(SkBlendMode::kDstATop);
7377
    SkCanvas can(*image);
7410
    SkCanvas can(*image);
7378
    sk_sp<SkImage> _image = SkImages::RasterFromBitmap(bm);
7411
    sk_sp<SkImage> _image = SkImages::RasterFromBitmap(bm);
7379
    can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
7412
    can.drawImage(_image, 0, 0, SkSamplingOptions(), &paint);
7380
 
7413