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