Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <basegfx/tools/zoomtools.hxx>
11 :
12 : namespace basegfx
13 : {
14 : namespace zoomtools
15 : {
16 :
17 : /** 2^(1/6) as the default step
18 :
19 : This ensures (unless the rounding is used) that 6 steps lead
20 : to double / half zoom level.
21 : */
22 : const double ZOOM_FACTOR = 1.12246205;
23 :
24 : /**
25 : * Round a value against a specified multiple. Values below half
26 : * of the multiple are rounded down and all others are rounded up.
27 : *
28 : * @param nCurrent current value
29 : * @param nMultiple multiple against which the current value is rounded
30 : */
31 0 : static long roundMultiple(long nCurrent, int nMultiple)
32 : {
33 : // round zoom to a multiple of nMultiple
34 0 : return (( nCurrent + nMultiple / 2 ) - ( nCurrent + nMultiple / 2 ) % nMultiple);
35 : }
36 :
37 : /**
38 : * Convert geometric progression results into more common values by
39 : * rounding them against certain multiples depending on the size.
40 : * Beginning with 50 the multiple is 5, with 100, 10, and so on.
41 : *
42 : * @param nCurrent current zoom factor
43 : */
44 0 : static long roundZoom(double nCurrent)
45 : {
46 : // convert nCurrent properly to int
47 0 : long nNew = nCurrent + 0.5;
48 :
49 : // round to more common numbers above 50
50 0 : if (nNew > 1000) {
51 0 : nNew = roundMultiple(nNew, 100);
52 0 : } else if ( nNew > 500 ) {
53 0 : nNew = roundMultiple(nNew, 50);
54 0 : } else if ( nNew > 100 ) {
55 0 : nNew = roundMultiple(nNew, 10);
56 0 : } else if ( nNew > 50 ) {
57 0 : nNew = roundMultiple(nNew, 5);
58 : }
59 :
60 0 : return nNew;
61 : }
62 :
63 : /**
64 : * Make sure that a certain step isn't skipped during the zooming
65 : * progress.
66 : *
67 : * @param nCurrent current zoom factor
68 : * @param nPrevious previous zoom factor
69 : * @param nStep step which shouldn't be skipped
70 : */
71 0 : static long enforceStep(long nCurrent, long nPrevious, int nStep)
72 : {
73 0 : if ((( nCurrent > nStep ) && ( nPrevious < nStep ))
74 0 : || (( nCurrent < nStep ) && ( nPrevious > nStep )))
75 0 : return nStep;
76 : else
77 0 : return nCurrent;
78 : }
79 :
80 : /**
81 : * Increasing the zoom level.
82 : *
83 : * @param nCurrent current zoom factor
84 : */
85 0 : long zoomIn(long nCurrent)
86 : {
87 0 : long nNew = roundZoom( nCurrent * ZOOM_FACTOR );
88 : // make sure some values are not skipped
89 0 : nNew = enforceStep(nNew, nCurrent, 200);
90 0 : nNew = enforceStep(nNew, nCurrent, 100);
91 0 : nNew = enforceStep(nNew, nCurrent, 75);
92 0 : nNew = enforceStep(nNew, nCurrent, 50);
93 0 : nNew = enforceStep(nNew, nCurrent, 25);
94 0 : return nNew;
95 : }
96 :
97 : /**
98 : * Decreasing the zoom level.
99 : *
100 : * @param nCurrent current zoom factor
101 : */
102 0 : long zoomOut(long nCurrent)
103 : {
104 0 : long nNew = roundZoom( nCurrent / ZOOM_FACTOR );
105 : // make sure some values are not skipped
106 0 : nNew = enforceStep(nNew, nCurrent, 200);
107 0 : nNew = enforceStep(nNew, nCurrent, 100);
108 0 : nNew = enforceStep(nNew, nCurrent, 75);
109 0 : nNew = enforceStep(nNew, nCurrent, 50);
110 0 : nNew = enforceStep(nNew, nCurrent, 25);
111 0 : return nNew;
112 : }
113 : } // namespace zoomtools
114 : } // namespace basegfx
115 :
116 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|