xref: /trunk/main/sc/source/ui/view/gridmerg.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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 <vcl/outdev.hxx>
34 
35 #include "gridmerg.hxx"
36 
37 //------------------------------------------------------------------
38 
39 ScGridMerger::ScGridMerger( OutputDevice* pOutDev, long nOnePixelX, long nOnePixelY ) :
40     pDev( pOutDev ),
41     nOneX( nOnePixelX ),
42     nOneY( nOnePixelY ),
43     nCount( 0 ),
44     bVertical( sal_False )
45 {
46     //  optimize (DrawGrid) only for pixel MapMode,
47     //  to avoid rounding errors
48 
49     bOptimize = ( pDev->GetMapMode().GetMapUnit() == MAP_PIXEL );
50 }
51 
52 ScGridMerger::~ScGridMerger()
53 {
54     Flush();
55 }
56 
57 void ScGridMerger::AddLine( long nStart, long nEnd, long nPos )
58 {
59     if ( nCount )
60     {
61         //  not first line - test fix position
62         //  more than one previous line - test distance
63 
64         if ( nStart != nFixStart || nEnd != nFixEnd )
65         {
66             if ( nCount == 1 && nPos == nVarStart &&
67                     ( nStart == nFixEnd ||
68                         nStart == nFixEnd + ( bVertical ? nOneY : nOneX ) ) )
69             {
70                 //  additional optimization: extend connected lines
71                 //  keep nCount at 1
72                 nFixEnd = nEnd;
73             }
74             else
75                 Flush();
76         }
77         else if ( nCount == 1 )
78         {
79             nVarDiff = nPos - nVarStart;
80             ++nCount;
81         }
82         else if ( nPos != nVarStart + nCount * nVarDiff )       //! keep VarEnd?
83             Flush();
84         else
85             ++nCount;
86     }
87 
88     if ( !nCount )
89     {
90         //  first line (or flushed above) - just store
91 
92         nFixStart = nStart;
93         nFixEnd   = nEnd;
94         nVarStart = nPos;
95         nVarDiff  = 0;
96         nCount    = 1;
97     }
98 }
99 
100 void ScGridMerger::AddHorLine( long nX1, long nX2, long nY )
101 {
102     if ( bOptimize )
103     {
104         if ( bVertical )
105         {
106             Flush();
107             bVertical = sal_False;
108         }
109         AddLine( nX1, nX2, nY );
110     }
111     else
112         pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
113 }
114 
115 void ScGridMerger::AddVerLine( long nX, long nY1, long nY2 )
116 {
117     if ( bOptimize )
118     {
119         if ( !bVertical )
120         {
121             Flush();
122             bVertical = sal_True;
123         }
124         AddLine( nY1, nY2, nX );
125     }
126     else
127         pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ) );
128 }
129 
130 void ScGridMerger::Flush()
131 {
132     if (nCount)
133     {
134         if (bVertical)
135         {
136             if ( nCount == 1 )
137                 pDev->DrawLine( Point( nVarStart, nFixStart ), Point( nVarStart, nFixEnd ) );
138             else
139             {
140                 long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
141                 if ( nVarDiff < 0 )
142                 {
143                     //  nVarDiff is negative in RTL layout mode
144                     //  Change the positions so DrawGrid is called with a positive distance
145                     //  (nVarStart / nVarDiff can be modified, aren't used after Flush)
146 
147                     nVarDiff = -nVarDiff;
148                     long nTemp = nVarStart;
149                     nVarStart = nVarEnd;
150                     nVarEnd = nTemp;
151                 }
152                 pDev->DrawGrid( Rectangle( nVarStart, nFixStart, nVarEnd, nFixEnd ),
153                                 Size( nVarDiff, nFixEnd - nFixStart ),
154                                 GRID_VERTLINES );
155             }
156         }
157         else
158         {
159             if ( nCount == 1 )
160                 pDev->DrawLine( Point( nFixStart, nVarStart ), Point( nFixEnd, nVarStart ) );
161             else
162             {
163                 long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
164                 pDev->DrawGrid( Rectangle( nFixStart, nVarStart, nFixEnd, nVarEnd ),
165                                 Size( nFixEnd - nFixStart, nVarDiff ),
166                                 GRID_HORZLINES );
167             }
168         }
169         nCount = 0;
170     }
171 }
172 
173 
174 
175