xref: /AOO41X/main/sc/source/ui/view/invmerge.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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