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: */
|