1 /* This file is part of the KDE project
2    Copyright (C) 2008 Marijn Kruisselbrink <mkruisselbrink@kde.org>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8 
9    This library 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 GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18 */
19 
20 #include "KPrBoxSnakesWipeStrategy.h"
21 #include "KPrBoxSnakesWipeEffectFactory.h"
22 
getSubType(int horRepeat,int verRepeat,bool clockwise,bool reverse)23 static int getSubType(int horRepeat, int verRepeat, bool clockwise, bool reverse)
24 {
25     if (!reverse) {
26         if (horRepeat == 2 && verRepeat == 1) return clockwise ? KPrBoxSnakesWipeEffectFactory::TwoBoxBottomIn : KPrBoxSnakesWipeEffectFactory::TwoBoxTopIn;
27         if (horRepeat == 1 && verRepeat == 2) return clockwise ? KPrBoxSnakesWipeEffectFactory::TwoBoxLeftIn : KPrBoxSnakesWipeEffectFactory::TwoBoxRightIn;
28         return clockwise ? KPrBoxSnakesWipeEffectFactory::FourBoxHorizontalIn : KPrBoxSnakesWipeEffectFactory::FourBoxVerticalIn;
29     } else {
30         if (horRepeat == 2 && verRepeat == 1) return clockwise ? KPrBoxSnakesWipeEffectFactory::TwoBoxBottomOut : KPrBoxSnakesWipeEffectFactory::TwoBoxTopOut;
31         if (horRepeat == 1 && verRepeat == 2) return clockwise ? KPrBoxSnakesWipeEffectFactory::TwoBoxLeftOut : KPrBoxSnakesWipeEffectFactory::TwoBoxRightOut;
32         return clockwise ? KPrBoxSnakesWipeEffectFactory::FourBoxHorizontalOut : KPrBoxSnakesWipeEffectFactory::FourBoxVerticalOut;
33     }
34 }
35 
getSmilSubType(int horRepeat,int verRepeat,bool clockwise)36 static const char * getSmilSubType(int horRepeat, int verRepeat, bool clockwise)
37 {
38     if (horRepeat == 2 && verRepeat == 1) return clockwise ? "twoBoxBottom" : "twoBoxTop";
39     if (horRepeat == 1 && verRepeat == 2) return clockwise ? "twoBoxLeft" : "twoBoxRight";
40     return clockwise ? "fourBoxHorizontal" : "fourBoxVertical";
41 }
42 
KPrBoxSnakesWipeStrategy(int horRepeat,int verRepeat,bool clockwise,bool reverse)43 KPrBoxSnakesWipeStrategy::KPrBoxSnakesWipeStrategy(int horRepeat, int verRepeat, bool clockwise, bool reverse)
44     : KPrMatrixWipeStrategy( getSubType(horRepeat, verRepeat, clockwise, reverse), "spiralWipe", getSmilSubType(horRepeat, verRepeat, clockwise), reverse ),
45     m_horRepeat(horRepeat), m_verRepeat(verRepeat), m_clockwise(clockwise)
46 {
47     setNeedEvenSquares();
48 }
49 
~KPrBoxSnakesWipeStrategy()50 KPrBoxSnakesWipeStrategy::~KPrBoxSnakesWipeStrategy()
51 {
52 }
53 
getFirstLeg(bool clockwise,int verrepeat,int horrepeat)54 static int getFirstLeg(bool clockwise, int verrepeat, int horrepeat) {
55     if (verrepeat == 1 && horrepeat == 2) return clockwise ? 3 : 0;
56     if (verrepeat == 2 && horrepeat == 1) return clockwise ? 0 : 3;
57     if (verrepeat == 2 && horrepeat == 2) return clockwise ? 0 : 0;
58     return 0;
59 }
60 
squareIndex(int x,int y,int columns,int rows)61 int KPrBoxSnakesWipeStrategy::squareIndex(int x, int y, int columns, int rows)
62 {
63     if (m_horRepeat == 2) {
64         if (x >= columns / 2) {
65             x = columns - x - 1;
66         }
67         columns /= 2;
68     }
69     if (m_verRepeat == 2) {
70         if (y >= rows / 2) {
71             y = rows - y - 1;
72         }
73         rows /= 2;
74     }
75     int m_firstLeg = getFirstLeg(m_clockwise, m_verRepeat, m_horRepeat);
76 
77     int curRing = qMin(qMin(x, y), qMin(columns - x - 1, rows - y - 1));
78     int maxRingSize = (columns + rows - 2) * 2;
79     int passed = 0;
80     if (curRing > 0) passed = curRing * (maxRingSize + maxRingSize - (curRing-1) * 8) / 2;
81     int leg = 0;
82     if (m_clockwise) {
83         if (y == curRing) {
84             leg = 0;
85         }
86         if (x == columns - curRing - 1) {
87             leg = 1;
88         }
89         if (y == rows - curRing - 1) {
90             leg = 2;
91         }
92         if (x == curRing && y != curRing) {
93             leg = 3;
94         }
95         if (curRing * 2 + 1 == rows) {
96             if (m_firstLeg == 0 || m_firstLeg == 3) {
97                 leg = 0;
98             }
99         }
100         if (leg < m_firstLeg) leg += 4;
101         if (leg > m_firstLeg && leg < m_firstLeg+4) passed += (m_firstLeg&1 ? rows : columns) - 2*curRing - 1;
102         if (leg > m_firstLeg+1 && leg < m_firstLeg+4) passed += (m_firstLeg&1 ? columns : rows) - 2*curRing - 1;
103         if (leg > m_firstLeg+2 && leg < m_firstLeg+4) passed += (m_firstLeg&1 ? rows : columns) - 2*curRing - 1;
104         if (leg > 3) leg -= 4;
105 
106         if (leg == 0) {
107             passed += x - curRing;
108         } else if (leg == 1) {
109             passed += y - curRing;
110         } else if (leg == 2) {
111             passed += columns - x - curRing - 1;
112         } else if (leg == 3) {
113             passed += rows - y - curRing - 1;
114         }
115     } else {
116         if (x == curRing) {
117             leg = 0;
118         }
119         if (y == rows - curRing - 1) {
120             leg = 1;
121         }
122         if (x == columns - curRing - 1) {
123             leg = 2;
124         }
125         if (y == curRing && x != curRing) {
126             leg = 3;
127         }
128         if (curRing * 2 + 1 == rows) {
129             if (m_firstLeg == 0 || m_firstLeg == 1) {
130                 leg = 1;
131             }
132         }
133         if (leg < m_firstLeg) leg += 4;
134         if (leg > m_firstLeg && leg < m_firstLeg+4) passed += (m_firstLeg&1 ? columns : rows) - 2*curRing - 1;
135         if (leg > m_firstLeg+1 && leg < m_firstLeg+4) passed += (m_firstLeg&1 ? rows : columns) - 2*curRing - 1;
136         if (leg > m_firstLeg+2 && leg < m_firstLeg+4) passed += (m_firstLeg&1 ? columns : rows) - 2*curRing - 1;
137         if (leg > 3) leg -= 4;
138 
139         if (leg == 0) {
140             passed += y - curRing;
141         } else if (leg == 1) {
142             passed += x - curRing;
143         } else if (leg == 2) {
144             passed += rows - y - curRing - 1;
145         } else if (leg == 3) {
146             passed += columns - x - curRing - 1;
147         }
148     }
149     return reverse() ? columns * rows - passed - 1 : passed;
150 }
151 
maxIndex(int columns,int rows)152 int KPrBoxSnakesWipeStrategy::maxIndex(int columns, int rows)
153 {
154     return columns * rows / m_horRepeat / m_verRepeat;
155 }
156 
157