annotate data/model/PowerOfTwoZoomConstraint.cpp @ 1719:6af7bd6aaf79 3.3-stable

Branch
author Chris Cannam
date Tue, 21 May 2019 17:14:23 +0100
parents bf32b26d1dad
children 1ae6a19464a7
rev   line source
Chris@147 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@147 2
Chris@147 3 /*
Chris@147 4 Sonic Visualiser
Chris@147 5 An audio file viewer and annotation editor.
Chris@147 6 Centre for Digital Music, Queen Mary, University of London.
Chris@147 7 This file copyright 2006 Chris Cannam.
Chris@147 8
Chris@147 9 This program is free software; you can redistribute it and/or
Chris@147 10 modify it under the terms of the GNU General Public License as
Chris@147 11 published by the Free Software Foundation; either version 2 of the
Chris@147 12 License, or (at your option) any later version. See the file
Chris@147 13 COPYING included with this distribution for more information.
Chris@147 14 */
Chris@147 15
Chris@147 16 #include "PowerOfTwoZoomConstraint.h"
Chris@147 17
Chris@1324 18 ZoomLevel
Chris@1324 19 PowerOfTwoZoomConstraint::getNearestZoomLevel(ZoomLevel requested,
Chris@1324 20 RoundingDirection dir) const
Chris@1324 21 {
Chris@1324 22 int blockSize;
Chris@1324 23
Chris@1324 24 if (requested.zone == ZoomLevel::FramesPerPixel) {
Chris@1324 25 blockSize = getNearestBlockSize(requested.level, dir);
Chris@1324 26 if (blockSize > getMaxZoomLevel().level) {
Chris@1324 27 blockSize = getMaxZoomLevel().level;
Chris@1324 28 }
Chris@1324 29 return { requested.zone, blockSize };
Chris@1324 30 } else {
Chris@1324 31 RoundingDirection opposite = dir;
Chris@1324 32 if (dir == RoundUp) opposite = RoundDown;
Chris@1324 33 else if (dir == RoundDown) opposite = RoundUp;
Chris@1324 34 blockSize = getNearestBlockSize(requested.level, opposite);
Chris@1324 35 if (blockSize > getMinZoomLevel().level) {
Chris@1324 36 blockSize = getMinZoomLevel().level;
Chris@1324 37 }
Chris@1324 38 if (blockSize == 1) {
Chris@1324 39 return { ZoomLevel::FramesPerPixel, 1 };
Chris@1324 40 } else {
Chris@1324 41 return { requested.zone, blockSize };
Chris@1324 42 }
Chris@1324 43 }
Chris@1324 44 }
Chris@1324 45
Chris@929 46 int
Chris@929 47 PowerOfTwoZoomConstraint::getNearestBlockSize(int req,
Chris@1429 48 RoundingDirection dir) const
Chris@147 49 {
Chris@1530 50 int max = getMaxZoomLevel().level;
Chris@147 51
Chris@1528 52 if (req > max) {
Chris@1528 53 return max;
Chris@1528 54 }
Chris@1528 55
Chris@1528 56 for (int bs = 1; bs <= max; bs *= 2) {
Chris@1528 57 if (bs < req) {
Chris@1528 58 continue;
Chris@1528 59 } else if (bs == req) {
Chris@1528 60 return bs;
Chris@1528 61 } else { // bs > req
Chris@1429 62 if (dir == RoundNearest) {
Chris@1429 63 if (bs - req < req - bs/2) {
Chris@1528 64 return bs;
Chris@1429 65 } else {
Chris@1528 66 return bs/2;
Chris@1429 67 }
Chris@1429 68 } else if (dir == RoundDown) {
Chris@1528 69 return bs/2;
Chris@1429 70 } else {
Chris@1528 71 return bs;
Chris@1429 72 }
Chris@1429 73 }
Chris@147 74 }
Chris@147 75
Chris@1528 76 return max;
Chris@147 77 }
Chris@147 78