Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : : *
5 : : * The contents of this file are subject to the Mozilla Public License Version
6 : : * 1.1 (the "License"); you may not use this file except in compliance with
7 : : * the License or as specified alternatively below. You may obtain a copy of
8 : : * the License at http://www.mozilla.org/MPL/
9 : : *
10 : : * Software distributed under the License is distributed on an "AS IS" basis,
11 : : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : : * for the specific language governing rights and limitations under the
13 : : * License.
14 : : *
15 : : * Major Contributor(s):
16 : : * Copyright (C) 2012 Tim Hardeck <thardeck@suse.com>
17 : : *
18 : : * All Rights Reserved.
19 : : *
20 : : * For minor contributions see the git repository.
21 : : *
22 : : * Alternatively, the contents of this file may be used under the terms of
23 : : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : : * instead of those above.
27 : : */
28 : :
29 : : #include <basegfx/tools/zoomtools.hxx>
30 : :
31 : : namespace basegfx
32 : : {
33 : : namespace zoomtools
34 : : {
35 : :
36 : : /** 2^(1/6) as the default step
37 : :
38 : : This ensures (unless the rounding is used) that 6 steps lead
39 : : to double / half zoom level.
40 : : */
41 : : const double ZOOM_FACTOR = 1.12246205;
42 : :
43 : : /**
44 : : * Round a value against a specified multiple. Values below half
45 : : * of the multiple are rounded down and all others are rounded up.
46 : : *
47 : : * @param nCurrent current value
48 : : * @param nMultiple multiple against which the current value is rounded
49 : : */
50 : 0 : static long roundMultiple(long nCurrent, int nMultiple)
51 : : {
52 : : // round zoom to a multiple of nMultiple
53 : 0 : return (( nCurrent + nMultiple / 2 ) - ( nCurrent + nMultiple / 2 ) % nMultiple);
54 : : }
55 : :
56 : : /**
57 : : * Convert geometric progression results into more common values by
58 : : * rounding them against certain multiples depending on the size.
59 : : * Beginning with 50 the multiple is 5, with 100, 10, and so on.
60 : : *
61 : : * @param nCurrent current zoom factor
62 : : */
63 : 0 : static long roundZoom(double nCurrent)
64 : : {
65 : : // convert nCurrent properly to int
66 : 0 : long nNew = nCurrent + 0.5;
67 : :
68 : : // round to more common numbers above 50
69 [ # # ]: 0 : if (nNew > 1000) {
70 : 0 : nNew = roundMultiple(nNew, 100);
71 [ # # ]: 0 : } else if ( nNew > 500 ) {
72 : 0 : nNew = roundMultiple(nNew, 50);
73 [ # # ]: 0 : } else if ( nNew > 100 ) {
74 : 0 : nNew = roundMultiple(nNew, 10);
75 [ # # ]: 0 : } else if ( nNew > 50 ) {
76 : 0 : nNew = roundMultiple(nNew, 5);
77 : : }
78 : :
79 : 0 : return nNew;
80 : : }
81 : :
82 : : /**
83 : : * Make sure that a certain step isn't skipped during the zooming
84 : : * progress.
85 : : *
86 : : * @param nCurrent current zoom factor
87 : : * @param nPrevious previous zoom factor
88 : : * @param nStep step which shouldn't be skipped
89 : : */
90 : 0 : static long enforceStep(long nCurrent, long nPrevious, int nStep)
91 : : {
92 [ # # ][ # # ]: 0 : if ((( nCurrent > nStep ) && ( nPrevious < nStep ))
[ # # ][ # # ]
93 : : || (( nCurrent < nStep ) && ( nPrevious > nStep )))
94 : 0 : return nStep;
95 : : else
96 : 0 : return nCurrent;
97 : : }
98 : :
99 : : /**
100 : : * Increasing the zoom level.
101 : : *
102 : : * @param nCurrent current zoom factor
103 : : */
104 : 0 : long zoomIn(long nCurrent)
105 : : {
106 : 0 : long nNew = roundZoom( nCurrent * ZOOM_FACTOR );
107 : : // make sure some values are not skipped
108 : 0 : nNew = enforceStep(nNew, nCurrent, 200);
109 : 0 : nNew = enforceStep(nNew, nCurrent, 100);
110 : 0 : nNew = enforceStep(nNew, nCurrent, 75);
111 : 0 : nNew = enforceStep(nNew, nCurrent, 50);
112 : 0 : nNew = enforceStep(nNew, nCurrent, 25);
113 : 0 : return nNew;
114 : : }
115 : :
116 : : /**
117 : : * Decreasing the zoom level.
118 : : *
119 : : * @param nCurrent current zoom factor
120 : : */
121 : 0 : long zoomOut(long nCurrent)
122 : : {
123 : 0 : long nNew = roundZoom( nCurrent / ZOOM_FACTOR );
124 : : // make sure some values are not skipped
125 : 0 : nNew = enforceStep(nNew, nCurrent, 200);
126 : 0 : nNew = enforceStep(nNew, nCurrent, 100);
127 : 0 : nNew = enforceStep(nNew, nCurrent, 75);
128 : 0 : nNew = enforceStep(nNew, nCurrent, 50);
129 : 0 : nNew = enforceStep(nNew, nCurrent, 25);
130 : 0 : return nNew;
131 : : }
132 : : } // namespace zoomtools
133 : : } // namespace basegfx
134 : :
135 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|