xref: /trunk/main/sc/source/ui/view/drawutil.cxx (revision 61dff127b6698e0bae836c8aedd6ec62111483d1)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 
33 // INCLUDE ---------------------------------------------------------------
34 
35 #include <vcl/outdev.hxx>
36 
37 #include "drawutil.hxx"
38 #include "document.hxx"
39 #include "global.hxx"
40 #include "viewdata.hxx"
41 
42 // STATIC DATA -----------------------------------------------------------
43 
44 // -----------------------------------------------------------------------
45 
46 
47 inline Fraction MakeFraction( long nA, long nB )
48 {
49     return ( nA && nB ) ? Fraction(nA,nB) : Fraction(1,1);
50 }
51 
52 void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab,
53                             SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
54                             OutputDevice* pDev,
55                             const Fraction& rZoomX, const Fraction& rZoomY,
56                             double nPPTX, double nPPTY,
57                             Fraction& rScaleX, Fraction& rScaleY )
58 {
59     long nPixelX = 0;
60     long nTwipsX = 0;
61     long nPixelY = 0;
62     long nTwipsY = 0;
63     for (SCCOL i=nStartCol; i<nEndCol; i++)
64     {
65         sal_uInt16 nWidth = pDoc->GetColWidth(i,nTab);
66         nTwipsX += (long) nWidth;
67         nPixelX += ScViewData::ToPixel( nWidth, nPPTX );
68     }
69 
70     for (SCROW nRow = nStartRow; nRow <= nEndRow-1; ++nRow)
71     {
72         SCROW nLastRow = nRow;
73         if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow))
74         {
75             nRow = nLastRow;
76             continue;
77         }
78 
79         sal_uInt16 nHeight = pDoc->GetRowHeight(nRow, nTab);
80         nTwipsY += static_cast<long>(nHeight);
81         nPixelY += ScViewData::ToPixel(nHeight, nPPTY);
82     }
83 
84     // #i116848# To get a large-enough number for PixelToLogic, multiply the integer values
85     // instead of using a larger number of rows
86     if ( nTwipsY )
87     {
88         long nMultiply = 2000000 / nTwipsY;
89         if ( nMultiply > 1 )
90         {
91             nTwipsY *= nMultiply;
92             nPixelY *= nMultiply;
93         }
94     }
95 
96     MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY );
97     Point aPixelLog = pDev->PixelToLogic( Point( nPixelX,nPixelY ), aHMMMode );
98 
99     //  Fraction(double) ctor can be used here (and avoid overflows of PixelLog * Zoom)
100     //  because ReduceInaccurate is called later anyway.
101 
102     if ( aPixelLog.X() && nTwipsX )
103         rScaleX = Fraction( ((double)aPixelLog.X()) *
104                             ((double)rZoomX.GetNumerator()) /
105                             ((double)nTwipsX) /
106                             ((double)HMM_PER_TWIPS) /
107                             ((double)rZoomX.GetDenominator()) );
108     else
109         rScaleX = Fraction( 1, 1 );
110 
111     if ( aPixelLog.Y() && nTwipsY )
112         rScaleY = Fraction( ((double)aPixelLog.Y()) *
113                             ((double)rZoomY.GetNumerator()) /
114                             ((double)nTwipsY) /
115                             ((double)HMM_PER_TWIPS) /
116                             ((double)rZoomY.GetDenominator()) );
117     else
118         rScaleY = Fraction( 1, 1 );
119 
120     //  25 bits of accuracy are needed to always hit the right part of
121     //  cells in the last rows (was 17 before 1M rows).
122     rScaleX.ReduceInaccurate( 25 );
123     rScaleY.ReduceInaccurate( 25 );
124 }
125 
126 
127 
128 
129