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