xref: /trunk/main/sc/source/ui/view/drawutil.cxx (revision d70dcc85)
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