xref: /trunk/main/sc/source/ui/view/invmerge.cxx (revision b3f79822)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 #include <vcl/window.hxx>
30 #include <tools/debug.hxx>
31 
32 #include "invmerge.hxx"
33 
34 //------------------------------------------------------------------
35 
ScInvertMerger(Window * pWindow)36 ScInvertMerger::ScInvertMerger( Window* pWindow ) :
37     pWin( pWindow ),
38     pRects( NULL )
39 {
40 	//	both rectangles empty
41 }
42 
ScInvertMerger(::std::vector<Rectangle> * pRectangles)43 ScInvertMerger::ScInvertMerger( ::std::vector< Rectangle >* pRectangles ) :
44     pWin( NULL ),
45     pRects( pRectangles )
46 {
47     //  collect rectangles instead of inverting
48 }
49 
~ScInvertMerger()50 ScInvertMerger::~ScInvertMerger()
51 {
52 	Flush();
53 }
54 
Flush()55 void ScInvertMerger::Flush()
56 {
57 	FlushLine();
58 	FlushTotal();
59 
60 	DBG_ASSERT( aLineRect.IsEmpty() && aTotalRect.IsEmpty(), "Flush: not empty" );
61 
62     if ( pRects )
63     {
64         //
65         // also join vertically if there are non-adjacent columns involved
66         //
67 
68         size_t nComparePos = 0;
69         while ( nComparePos < pRects->size() )
70         {
71             Rectangle aCompRect = (*pRects)[nComparePos];
72             sal_Int32 nBottom = aCompRect.Bottom();
73             size_t nOtherPos = nComparePos + 1;
74 
75             while ( nOtherPos < pRects->size() )
76             {
77                 Rectangle aOtherRect = (*pRects)[nOtherPos];
78                 if ( aOtherRect.Top() > nBottom + 1 )
79                 {
80                     // rectangles are sorted, so we can stop searching
81                     break;
82                 }
83                 if ( aOtherRect.Top() == nBottom + 1 &&
84                      aOtherRect.Left() == aCompRect.Left() &&
85                      aOtherRect.Right() == aCompRect.Right() )
86                 {
87                     // extend first rectangle
88                     nBottom = aOtherRect.Bottom();
89                     aCompRect.Bottom() = nBottom;
90                     (*pRects)[nComparePos].Bottom() = nBottom;
91 
92                     // remove second rectangle
93                     pRects->erase( pRects->begin() + nOtherPos );
94 
95                     // continue at unmodified nOtherPos
96                 }
97                 else
98                     ++nOtherPos;
99             }
100 
101             ++nComparePos;
102         }
103     }
104 }
105 
FlushTotal()106 void ScInvertMerger::FlushTotal()
107 {
108 	if( aTotalRect.IsEmpty() )
109 		return;							// nothing to do
110 
111     if ( pWin )
112         pWin->Invert( aTotalRect, INVERT_HIGHLIGHT );
113     else if ( pRects )
114         pRects->push_back( aTotalRect );
115 
116 	aTotalRect.SetEmpty();
117 }
118 
FlushLine()119 void ScInvertMerger::FlushLine()
120 {
121 	if( aLineRect.IsEmpty() )
122 		return;							// nothing to do
123 
124 	if ( aTotalRect.IsEmpty() )
125 	{
126 		aTotalRect = aLineRect;			// start new total rect
127 	}
128 	else
129 	{
130 		if ( aLineRect.Left()  == aTotalRect.Left()  &&
131 			 aLineRect.Right() == aTotalRect.Right() &&
132 			 aLineRect.Top()   == aTotalRect.Bottom() + 1 )
133 		{
134 			// extend total rect
135 			aTotalRect.Bottom() = aLineRect.Bottom();
136 		}
137 		else
138 		{
139 			FlushTotal();					// draw old total rect
140 			aTotalRect = aLineRect;			// and start new one
141 		}
142 	}
143 
144 	aLineRect.SetEmpty();
145 }
146 
AddRect(const Rectangle & rRect)147 void ScInvertMerger::AddRect( const Rectangle& rRect )
148 {
149     Rectangle aJustified = rRect;
150     if ( rRect.Left() > rRect.Right() )     // switch for RTL layout
151     {
152         aJustified.Left() = rRect.Right();
153         aJustified.Right() = rRect.Left();
154     }
155 
156 	if ( aLineRect.IsEmpty() )
157 	{
158 		aLineRect = aJustified;             // start new line rect
159 	}
160 	else
161 	{
162 		sal_Bool bDone = sal_False;
163 		if ( aJustified.Top()    == aLineRect.Top()    &&
164 			 aJustified.Bottom() == aLineRect.Bottom() )
165 		{
166 			// try to extend line rect
167 			if ( aJustified.Left() == aLineRect.Right() + 1 )
168 			{
169 				aLineRect.Right() = aJustified.Right();
170 				bDone = sal_True;
171 			}
172 			else if ( aJustified.Right() + 1 == aLineRect.Left() )	// for RTL layout
173 			{
174 				aLineRect.Left() = aJustified.Left();
175 				bDone = sal_True;
176 			}
177 		}
178 		if (!bDone)
179 		{
180 			FlushLine();				// use old line rect for total rect
181 			aLineRect = aJustified;		// and start new one
182 		}
183 	}
184 }
185 
186 
187 
188 
189