annotate data/model/test/TestZoomConstraints.h @ 1552:05c3fbaec8ea

Introduce RelativelyFineZoomConstraint, which encodes more-or-less the scheme that was already used for the horizontal thumbwheel in the pane (which overrode the layers' own zoom constraints unless they said they couldn't support any other)
author Chris Cannam
date Wed, 10 Oct 2018 14:32:34 +0100
parents 2f3a77472c8c
children 616d3e8a250b
rev   line source
Chris@1528 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1528 2
Chris@1528 3 /*
Chris@1530 4 Sonic Visualiser
Chris@1530 5 An audio file viewer and annotation editor.
Chris@1530 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1528 7
Chris@1530 8 This program is free software; you can redistribute it and/or
Chris@1530 9 modify it under the terms of the GNU General Public License as
Chris@1530 10 published by the Free Software Foundation; either version 2 of the
Chris@1530 11 License, or (at your option) any later version. See the file
Chris@1530 12 COPYING included with this distribution for more information.
Chris@1528 13 */
Chris@1528 14
Chris@1528 15 #ifndef TEST_ZOOM_CONSTRAINTS_H
Chris@1528 16 #define TEST_ZOOM_CONSTRAINTS_H
Chris@1528 17
Chris@1528 18 #include "../PowerOfTwoZoomConstraint.h"
Chris@1528 19 #include "../PowerOfSqrtTwoZoomConstraint.h"
Chris@1552 20 #include "../RelativelyFineZoomConstraint.h"
Chris@1528 21
Chris@1528 22 #include <QObject>
Chris@1528 23 #include <QtTest>
Chris@1528 24 #include <QDir>
Chris@1528 25
Chris@1528 26 #include <iostream>
Chris@1528 27
Chris@1528 28 using namespace std;
Chris@1528 29
Chris@1528 30 class TestZoomConstraints : public QObject
Chris@1528 31 {
Chris@1528 32 Q_OBJECT
Chris@1528 33
Chris@1552 34 string roundingName(ZoomConstraint::RoundingDirection dir) {
Chris@1552 35 switch (dir) {
Chris@1552 36 case ZoomConstraint::RoundDown: return "RoundDown";
Chris@1552 37 case ZoomConstraint::RoundUp: return "RoundUp";
Chris@1552 38 case ZoomConstraint::RoundNearest: return "RoundNearest";
Chris@1552 39 }
Chris@1552 40 return "<?>";
Chris@1552 41 }
Chris@1552 42
Chris@1552 43 void compare(ZoomLevel zin,
Chris@1552 44 ZoomConstraint::RoundingDirection dir,
Chris@1552 45 ZoomLevel zobt,
Chris@1552 46 ZoomLevel zexp) {
Chris@1552 47 if (zexp.level == 1) {
Chris@1552 48 // A zoom level of "1 pixel per frame" is not considered
Chris@1552 49 // canonical - it should be "1 frame per pixel"
Chris@1552 50 zexp.zone = ZoomLevel::FramesPerPixel;
Chris@1552 51 }
Chris@1552 52 if (zobt == zexp) {
Chris@1552 53 return;
Chris@1552 54 } else {
Chris@1552 55 cerr << "For input " << zin << " and rounding direction "
Chris@1552 56 << roundingName(dir)
Chris@1552 57 << ", expected output " << zexp << " but obtained " << zobt
Chris@1552 58 << endl;
Chris@1552 59 QCOMPARE(zobt, zexp);
Chris@1552 60 }
Chris@1552 61 }
Chris@1552 62
Chris@1531 63 void checkFpp(const ZoomConstraint &c,
Chris@1531 64 ZoomConstraint::RoundingDirection dir,
Chris@1531 65 int n,
Chris@1531 66 int expected) {
Chris@1552 67 ZoomLevel zin(ZoomLevel::FramesPerPixel, n);
Chris@1552 68 ZoomLevel zexp(ZoomLevel::FramesPerPixel, expected);
Chris@1552 69 ZoomLevel zobt(c.getNearestZoomLevel(zin, dir));
Chris@1552 70 compare(zin, dir, zobt, zexp);
Chris@1531 71 }
Chris@1552 72
Chris@1552 73 void checkPpf(const ZoomConstraint &c,
Chris@1552 74 ZoomConstraint::RoundingDirection dir,
Chris@1552 75 int n,
Chris@1552 76 int expected) {
Chris@1552 77 ZoomLevel zin(ZoomLevel::PixelsPerFrame, n);
Chris@1552 78 ZoomLevel zexp(ZoomLevel::PixelsPerFrame, expected);
Chris@1552 79 ZoomLevel zobt(c.getNearestZoomLevel(zin, dir));
Chris@1552 80 compare(zin, dir, zobt, zexp);
Chris@1552 81 }
Chris@1552 82
Chris@1552 83 void checkBoth(const ZoomConstraint &c,
Chris@1552 84 ZoomConstraint::RoundingDirection dir,
Chris@1552 85 int n,
Chris@1552 86 int expected) {
Chris@1552 87 checkFpp(c, dir, n, expected);
Chris@1552 88 checkPpf(c, dir, n, expected);
Chris@1552 89 }
Chris@1552 90
Chris@1552 91 void checkMaxMin(const ZoomConstraint &c,
Chris@1552 92 ZoomConstraint::RoundingDirection dir) {
Chris@1552 93 auto max = c.getMaxZoomLevel();
Chris@1552 94 compare(max, dir,
Chris@1552 95 c.getNearestZoomLevel(max, dir), max);
Chris@1552 96 compare(max.incremented(), dir,
Chris@1552 97 c.getNearestZoomLevel(max.incremented(), dir), max);
Chris@1552 98 auto min = c.getMinZoomLevel();
Chris@1552 99 compare(min, dir,
Chris@1552 100 c.getNearestZoomLevel(min, dir), min);
Chris@1552 101 compare(min.decremented(), dir,
Chris@1552 102 c.getNearestZoomLevel(min.decremented(), dir), min);
Chris@1552 103 }
Chris@1552 104
Chris@1552 105 const static ZoomConstraint::RoundingDirection up = ZoomConstraint::RoundUp;
Chris@1552 106 const static ZoomConstraint::RoundingDirection down = ZoomConstraint::RoundDown;
Chris@1552 107 const static ZoomConstraint::RoundingDirection nearest = ZoomConstraint::RoundNearest;
Chris@1552 108
Chris@1528 109 private slots:
Chris@1528 110 void unconstrainedNearest() {
Chris@1528 111 ZoomConstraint c;
Chris@1552 112 checkBoth(c, nearest, 1, 1);
Chris@1552 113 checkBoth(c, nearest, 2, 2);
Chris@1552 114 checkBoth(c, nearest, 3, 3);
Chris@1552 115 checkBoth(c, nearest, 4, 4);
Chris@1552 116 checkBoth(c, nearest, 20, 20);
Chris@1552 117 checkBoth(c, nearest, 32, 32);
Chris@1530 118 auto max = c.getMaxZoomLevel();
Chris@1530 119 QCOMPARE(c.getNearestZoomLevel(max), max);
Chris@1531 120 QCOMPARE(c.getNearestZoomLevel(max.incremented()), max);
Chris@1528 121 }
Chris@1528 122
Chris@1528 123 void unconstrainedUp() {
Chris@1528 124 ZoomConstraint c;
Chris@1552 125 checkBoth(c, up, 1, 1);
Chris@1552 126 checkBoth(c, up, 2, 2);
Chris@1552 127 checkBoth(c, up, 3, 3);
Chris@1552 128 checkBoth(c, up, 4, 4);
Chris@1552 129 checkBoth(c, up, 20, 20);
Chris@1552 130 checkBoth(c, up, 32, 32);
Chris@1530 131 auto max = c.getMaxZoomLevel();
Chris@1552 132 QCOMPARE(c.getNearestZoomLevel(max, up), max);
Chris@1552 133 QCOMPARE(c.getNearestZoomLevel(max.incremented(), up), max);
Chris@1528 134 }
Chris@1528 135
Chris@1528 136 void unconstrainedDown() {
Chris@1528 137 ZoomConstraint c;
Chris@1552 138 checkBoth(c, down, 1, 1);
Chris@1552 139 checkBoth(c, down, 2, 2);
Chris@1552 140 checkBoth(c, down, 3, 3);
Chris@1552 141 checkBoth(c, down, 4, 4);
Chris@1552 142 checkBoth(c, down, 20, 20);
Chris@1552 143 checkBoth(c, down, 32, 32);
Chris@1530 144 auto max = c.getMaxZoomLevel();
Chris@1552 145 QCOMPARE(c.getNearestZoomLevel(max, down), max);
Chris@1552 146 QCOMPARE(c.getNearestZoomLevel(max.incremented(), down), max);
Chris@1528 147 }
Chris@1528 148
Chris@1528 149 void powerOfTwoNearest() {
Chris@1528 150 PowerOfTwoZoomConstraint c;
Chris@1552 151 checkBoth(c, nearest, 1, 1);
Chris@1552 152 checkBoth(c, nearest, 2, 2);
Chris@1552 153 checkBoth(c, nearest, 3, 2);
Chris@1552 154 checkBoth(c, nearest, 4, 4);
Chris@1552 155 checkBoth(c, nearest, 20, 16);
Chris@1552 156 checkBoth(c, nearest, 23, 16);
Chris@1552 157 checkBoth(c, nearest, 24, 16);
Chris@1552 158 checkBoth(c, nearest, 25, 32);
Chris@1530 159 auto max = c.getMaxZoomLevel();
Chris@1530 160 QCOMPARE(c.getNearestZoomLevel(max), max);
Chris@1531 161 QCOMPARE(c.getNearestZoomLevel(max.incremented()), max);
Chris@1528 162 }
Chris@1528 163
Chris@1528 164 void powerOfTwoUp() {
Chris@1528 165 PowerOfTwoZoomConstraint c;
Chris@1552 166 checkBoth(c, up, 1, 1);
Chris@1552 167 checkBoth(c, up, 2, 2);
Chris@1552 168 checkFpp(c, up, 3, 4);
Chris@1552 169 checkPpf(c, up, 3, 2);
Chris@1552 170 checkBoth(c, up, 4, 4);
Chris@1552 171 checkFpp(c, up, 20, 32);
Chris@1552 172 checkPpf(c, up, 20, 16);
Chris@1552 173 checkBoth(c, up, 32, 32);
Chris@1552 174 checkFpp(c, up, 33, 64);
Chris@1552 175 checkPpf(c, up, 33, 32);
Chris@1552 176 checkMaxMin(c, up);
Chris@1528 177 }
Chris@1528 178
Chris@1528 179 void powerOfTwoDown() {
Chris@1528 180 PowerOfTwoZoomConstraint c;
Chris@1552 181 checkBoth(c, down, 1, 1);
Chris@1552 182 checkBoth(c, down, 2, 2);
Chris@1552 183 checkFpp(c, down, 3, 2);
Chris@1552 184 checkPpf(c, down, 3, 4);
Chris@1552 185 checkBoth(c, down, 4, 4);
Chris@1552 186 checkFpp(c, down, 20, 16);
Chris@1552 187 checkPpf(c, down, 20, 32);
Chris@1552 188 checkBoth(c, down, 32, 32);
Chris@1552 189 checkFpp(c, down, 33, 32);
Chris@1552 190 checkPpf(c, down, 33, 64);
Chris@1552 191 checkMaxMin(c, down);
Chris@1528 192 }
Chris@1528 193
Chris@1528 194 void powerOfSqrtTwoNearest() {
Chris@1528 195 PowerOfSqrtTwoZoomConstraint c;
Chris@1552 196 checkBoth(c, nearest, 1, 1);
Chris@1552 197 checkBoth(c, nearest, 2, 2);
Chris@1552 198 checkBoth(c, nearest, 3, 2);
Chris@1552 199 checkBoth(c, nearest, 4, 4);
Chris@1552 200 checkBoth(c, nearest, 18, 16);
Chris@1552 201 checkBoth(c, nearest, 19, 16);
Chris@1552 202 checkBoth(c, nearest, 20, 22);
Chris@1552 203 checkBoth(c, nearest, 23, 22);
Chris@1552 204 checkBoth(c, nearest, 28, 32);
Chris@1528 205 // PowerOfSqrtTwoZoomConstraint makes an effort to ensure
Chris@1528 206 // bigger numbers get rounded to a multiple of something
Chris@1528 207 // simple (64 or 90 depending on whether they are power-of-two
Chris@1528 208 // or power-of-sqrt-two types)
Chris@1552 209 checkBoth(c, nearest, 350, 360);
Chris@1552 210 // The most extreme level available in ppf mode
Chris@1552 211 // (getMinZoomLevel()) is currently 512, so these bigger
Chris@1552 212 // numbers will only happen in fpp mode
Chris@1552 213 checkFpp(c, nearest, 800, 720);
Chris@1552 214 checkFpp(c, nearest, 1023, 1024);
Chris@1552 215 checkFpp(c, nearest, 1024, 1024);
Chris@1552 216 checkFpp(c, nearest, 1024, 1024);
Chris@1552 217 checkFpp(c, nearest, 1025, 1024);
Chris@1552 218 checkPpf(c, nearest, 800, 512);
Chris@1552 219 checkPpf(c, nearest, 1025, 512);
Chris@1552 220 checkMaxMin(c, nearest);
Chris@1528 221 }
Chris@1528 222
Chris@1528 223 void powerOfSqrtTwoUp() {
Chris@1528 224 PowerOfSqrtTwoZoomConstraint c;
Chris@1552 225 checkBoth(c, up, 1, 1);
Chris@1552 226 checkBoth(c, up, 2, 2);
Chris@1552 227 checkFpp(c, up, 3, 4);
Chris@1552 228 checkPpf(c, up, 3, 2);
Chris@1552 229 checkBoth(c, up, 4, 4);
Chris@1552 230 checkFpp(c, up, 18, 22);
Chris@1552 231 checkPpf(c, up, 18, 16);
Chris@1552 232 checkBoth(c, up, 22, 22);
Chris@1552 233 checkFpp(c, up, 23, 32);
Chris@1552 234 checkPpf(c, up, 23, 22);
Chris@1552 235 // see comments above
Chris@1552 236 checkFpp(c, up, 800, 1024);
Chris@1552 237 checkFpp(c, up, 1023, 1024);
Chris@1552 238 checkFpp(c, up, 1024, 1024);
Chris@1552 239 checkFpp(c, up, 1025, 1440);
Chris@1552 240 checkPpf(c, up, 300, 256);
Chris@1552 241 checkPpf(c, up, 800, 512);
Chris@1552 242 checkPpf(c, up, 1600, 512);
Chris@1552 243 checkMaxMin(c, up);
Chris@1528 244 }
Chris@1528 245
Chris@1528 246 void powerOfSqrtTwoDown() {
Chris@1528 247 PowerOfSqrtTwoZoomConstraint c;
Chris@1552 248 checkBoth(c, down, 1, 1);
Chris@1552 249 checkBoth(c, down, 2, 2);
Chris@1552 250 checkFpp(c, down, 3, 2);
Chris@1552 251 checkPpf(c, down, 3, 4);
Chris@1552 252 checkBoth(c, down, 4, 4);
Chris@1552 253 checkFpp(c, down, 18, 16);
Chris@1552 254 checkPpf(c, down, 18, 22);
Chris@1552 255 checkBoth(c, down, 22, 22);
Chris@1552 256 checkFpp(c, down, 23, 22);
Chris@1552 257 checkPpf(c, down, 23, 32);
Chris@1552 258 // see comments above
Chris@1552 259 checkFpp(c, down, 800, 720);
Chris@1552 260 checkFpp(c, down, 1023, 720);
Chris@1552 261 checkFpp(c, down, 1024, 1024);
Chris@1552 262 checkFpp(c, down, 1025, 1024);
Chris@1552 263 checkPpf(c, down, 300, 360);
Chris@1552 264 checkPpf(c, down, 800, 512);
Chris@1552 265 checkPpf(c, down, 1600, 512);
Chris@1552 266 checkMaxMin(c, down);
Chris@1552 267 }
Chris@1552 268
Chris@1552 269 void relativelyFineNearest() {
Chris@1552 270 RelativelyFineZoomConstraint c;
Chris@1552 271 checkBoth(c, nearest, 1, 1);
Chris@1552 272 checkBoth(c, nearest, 2, 2);
Chris@1552 273 checkBoth(c, nearest, 3, 3);
Chris@1552 274 checkBoth(c, nearest, 4, 4);
Chris@1552 275 checkBoth(c, nearest, 20, 20);
Chris@1552 276 checkBoth(c, nearest, 33, 32);
Chris@1552 277 checkBoth(c, nearest, 59, 56);
Chris@1552 278 checkBoth(c, nearest, 69, 72);
Chris@1552 279 checkBoth(c, nearest, 121, 128);
Chris@1552 280 checkMaxMin(c, nearest);
Chris@1552 281 }
Chris@1552 282
Chris@1552 283 void relativelyFineUp() {
Chris@1552 284 RelativelyFineZoomConstraint c;
Chris@1552 285 checkBoth(c, up, 1, 1);
Chris@1552 286 checkBoth(c, up, 2, 2);
Chris@1552 287 checkBoth(c, up, 3, 3);
Chris@1552 288 checkBoth(c, up, 4, 4);
Chris@1552 289 checkBoth(c, up, 20, 20);
Chris@1552 290 checkFpp(c, up, 33, 36);
Chris@1552 291 checkPpf(c, up, 33, 32);
Chris@1552 292 checkFpp(c, up, 59, 64);
Chris@1552 293 checkPpf(c, up, 59, 56);
Chris@1552 294 checkFpp(c, up, 69, 72);
Chris@1552 295 checkPpf(c, up, 69, 64);
Chris@1552 296 checkFpp(c, up, 121, 128);
Chris@1552 297 checkPpf(c, up, 121, 112);
Chris@1552 298 checkMaxMin(c, up);
Chris@1552 299 }
Chris@1552 300
Chris@1552 301 void relativelyFineDown() {
Chris@1552 302 RelativelyFineZoomConstraint c;
Chris@1552 303 checkBoth(c, down, 1, 1);
Chris@1552 304 checkBoth(c, down, 2, 2);
Chris@1552 305 checkBoth(c, down, 3, 3);
Chris@1552 306 checkBoth(c, down, 4, 4);
Chris@1552 307 checkBoth(c, down, 20, 20);
Chris@1552 308 checkFpp(c, down, 33, 32);
Chris@1552 309 checkPpf(c, down, 33, 36);
Chris@1552 310 checkFpp(c, down, 59, 56);
Chris@1552 311 checkPpf(c, down, 59, 64);
Chris@1552 312 checkFpp(c, down, 69, 64);
Chris@1552 313 checkPpf(c, down, 69, 72);
Chris@1552 314 checkFpp(c, down, 121, 112);
Chris@1552 315 checkPpf(c, down, 121, 128);
Chris@1552 316 checkMaxMin(c, down);
Chris@1528 317 }
Chris@1528 318 };
Chris@1528 319
Chris@1528 320 #endif
Chris@1528 321