File indexing completed on 2025-01-05 03:57:25

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2017-05-24
0007  * Description : images transition manager.
0008  *
0009  * SPDX-FileCopyrightText: 2017-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "transitionmngr_p.h"
0016 
0017 namespace Digikam
0018 {
0019 
0020 int TransitionMngr::Private::transitionSweep(bool aInit)
0021 {
0022     if (aInit)
0023     {
0024         // subtype: 0=sweep right to left, 1=sweep left to right
0025         //          2=sweep bottom to top, 3=sweep top to bottom
0026         eff_subType = randomGenerator->bounded(4);
0027         eff_w       = eff_outSize.width();
0028         eff_h       = eff_outSize.height();
0029         eff_dx      = (eff_subType == 1 ? 16 : -16);
0030         eff_dy      = (eff_subType == 3 ? 16 : -16);
0031         eff_x       = (eff_subType == 1 ? 0  : eff_w);
0032         eff_y       = (eff_subType == 3 ? 0  : eff_h);
0033     }
0034 
0035     if ((eff_subType == 0) || (eff_subType == 1))
0036     {
0037         // horizontal sweep
0038         if (((eff_subType == 0) && (eff_x < -64)) ||
0039             ((eff_subType == 1) && (eff_x > eff_w + 64)))
0040         {
0041             eff_curFrame = eff_outImage;
0042             return -1;
0043         }
0044 
0045         int w;
0046         int x;
0047         int i;
0048 
0049         for (w = 2, i = 4, x = eff_x ; i > 0 ; --i, w <<= 1, x -= eff_dx)
0050         {
0051             eff_px  = x;
0052             eff_py  = 0;
0053             eff_psx = w;
0054             eff_psy = eff_h;
0055 
0056             QPainter bufferPainter(&eff_curFrame);
0057             bufferPainter.fillRect(eff_px, eff_py, eff_psx, eff_psy, QBrush(eff_outImage));
0058             bufferPainter.end();
0059         }
0060 
0061         eff_x += eff_dx;
0062     }
0063     else
0064     {
0065         // vertical sweep
0066         if (((eff_subType == 2) && (eff_y < -64)) ||
0067             ((eff_subType == 3) && (eff_y > eff_h + 64)))
0068         {
0069             eff_curFrame = eff_outImage;
0070             return -1;
0071         }
0072 
0073         int h;
0074         int y;
0075         int i;
0076 
0077         for (h = 2, i = 4, y = eff_y ; i > 0 ; --i, h <<= 1, y -= eff_dy)
0078         {
0079             eff_px  = 0;
0080             eff_py  = y;
0081             eff_psx = eff_w;
0082             eff_psy = h;
0083 
0084             QPainter bufferPainter(&eff_curFrame);
0085             bufferPainter.fillRect(eff_px, eff_py, eff_psx, eff_psy, QBrush(eff_outImage));
0086             bufferPainter.end();
0087         }
0088 
0089         eff_y += eff_dy;
0090     }
0091 
0092     return 20;
0093 }
0094 
0095 int TransitionMngr::Private::transitionHorizLines(bool aInit)
0096 {
0097     static int iyPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
0098 
0099     if (aInit)
0100     {
0101         eff_w = eff_outSize.width();
0102         eff_h = eff_outSize.height();
0103         eff_i = 0;
0104     }
0105 
0106     if (iyPos[eff_i] < 0)
0107     {
0108         return -1;
0109     }
0110 
0111     int until    = eff_h;
0112 
0113     QPainter bufferPainter(&eff_curFrame);
0114     QBrush brush = QBrush(eff_outImage);
0115 
0116     for (int iPos = iyPos[eff_i] ; iPos < until ; iPos += 8)
0117     {
0118         bufferPainter.fillRect(0, iPos, eff_w, 1, brush);
0119     }
0120 
0121     bufferPainter.end();
0122 
0123     eff_i++;
0124 
0125     if (iyPos[eff_i] >= 0)
0126     {
0127         return 160;
0128     }
0129 
0130     eff_curFrame = eff_outImage;
0131 
0132     return -1;
0133 }
0134 
0135 int TransitionMngr::Private::transitionVertLines(bool aInit)
0136 {
0137     static int ixPos[] = { 0, 4, 2, 6, 1, 5, 3, 7, -1 };
0138 
0139     if (aInit)
0140     {
0141         eff_w = eff_outSize.width();
0142         eff_h = eff_outSize.height();
0143         eff_i = 0;
0144     }
0145 
0146     if (ixPos[eff_i] < 0)
0147     {
0148         return -1;
0149     }
0150 
0151     int iPos;
0152     int until    = eff_w;
0153 
0154     QPainter bufferPainter(&eff_curFrame);
0155     QBrush brush = QBrush(eff_outImage);
0156 
0157     for (iPos = ixPos[eff_i] ; iPos < until ; iPos += 8)
0158     {
0159         bufferPainter.fillRect(iPos, 0, 1, eff_h, brush);
0160     }
0161 
0162     bufferPainter.end();
0163 
0164     eff_i++;
0165 
0166     if (ixPos[eff_i] >= 0)
0167     {
0168         return 160;
0169     }
0170 
0171     eff_curFrame = eff_outImage;
0172 
0173     return -1;
0174 }
0175 
0176 int TransitionMngr::Private::transitionMultiCircleOut(bool aInit)
0177 {
0178     int x, y, i;
0179     double alpha;
0180 
0181     if (aInit)
0182     {
0183         eff_w     = eff_outSize.width();
0184         eff_h     = eff_outSize.height();
0185         eff_x     = eff_w;
0186         eff_y     = eff_h >> 1;
0187         eff_pa.setPoint(0, eff_w >> 1, eff_h >> 1);
0188         eff_pa.setPoint(3, eff_w >> 1, eff_h >> 1);
0189         eff_fy    = sqrt((double)eff_w * eff_w + eff_h * eff_h) / 2;
0190         eff_i     = randomGenerator->bounded(2, 17);
0191         eff_fd    = M_PI * 2 / eff_i;
0192         eff_alpha = eff_fd;
0193         eff_wait  = 10 * eff_i;
0194         eff_fx    = M_PI / 32;  // divisor must be powers of 8
0195     }
0196 
0197     if (eff_alpha < 0)
0198     {
0199         eff_curFrame = eff_outImage;
0200         return -1;
0201     }
0202 
0203     for (alpha = eff_alpha, i = eff_i ; i >= 0 ; --i, alpha += eff_fd)
0204     {
0205         x     = (eff_w >> 1) + (int)(eff_fy * cos(-alpha));
0206         y     = (eff_h >> 1) + (int)(eff_fy * sin(-alpha));
0207         eff_x = (eff_w >> 1) + (int)(eff_fy * cos(-alpha + eff_fx));
0208         eff_y = (eff_h >> 1) + (int)(eff_fy * sin(-alpha + eff_fx));
0209 
0210         eff_pa.setPoint(1, x, y);
0211         eff_pa.setPoint(2, eff_x, eff_y);
0212 
0213         QPainterPath painterPath;
0214         painterPath.addPolygon(QPolygon(eff_pa));
0215 
0216         QPainter bufferPainter(&eff_curFrame);
0217         bufferPainter.fillPath(painterPath, QBrush(eff_outImage));
0218         bufferPainter.end();
0219     }
0220 
0221     eff_alpha -= eff_fx;
0222 
0223     return eff_wait;
0224 }
0225 
0226 int TransitionMngr::Private::transitionCircleOut(bool aInit)
0227 {
0228     int x, y;
0229 
0230     if (aInit)
0231     {
0232         eff_w     = eff_outSize.width();
0233         eff_h     = eff_outSize.height();
0234         eff_x     = eff_w;
0235         eff_y     = eff_h >> 1;
0236         eff_alpha = 2 * M_PI;
0237         eff_pa.setPoint(0, eff_w >> 1, eff_h >> 1);
0238         eff_pa.setPoint(3, eff_w >> 1, eff_h >> 1);
0239         eff_fx    = M_PI / 16;                       // divisor must be powers of 8
0240         eff_fy    = sqrt((double)eff_w * eff_w + eff_h * eff_h) / 2;
0241     }
0242 
0243     if (eff_alpha < 0)
0244     {
0245         eff_curFrame = eff_outImage;
0246         return -1;
0247     }
0248 
0249     x          = eff_x;
0250     y          = eff_y;
0251     eff_x      = (eff_w >> 1) + (int)(eff_fy * cos(eff_alpha));
0252     eff_y      = (eff_h >> 1) + (int)(eff_fy * sin(eff_alpha));
0253     eff_alpha -= eff_fx;
0254 
0255     eff_pa.setPoint(1, x, y);
0256     eff_pa.setPoint(2, eff_x, eff_y);
0257 
0258     QPainterPath painterPath;
0259     painterPath.addPolygon(QPolygon(eff_pa));
0260     QPainter bufferPainter(&eff_curFrame);
0261     bufferPainter.fillPath(painterPath, QBrush(eff_outImage));
0262     bufferPainter.end();
0263 
0264     return 20;
0265 }
0266 
0267 } // namespace Digikam