Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <vcl/window.hxx>
30 : :
31 : : #include "invmerge.hxx"
32 : :
33 : : //------------------------------------------------------------------
34 : :
35 : 39 : ScInvertMerger::ScInvertMerger( ::std::vector< Rectangle >* pRectangles ) :
36 : 39 : pRects( pRectangles )
37 : : {
38 : : // collect rectangles instead of inverting
39 : 39 : }
40 : :
41 : 39 : ScInvertMerger::~ScInvertMerger()
42 : : {
43 : 39 : Flush();
44 : 39 : }
45 : :
46 : 39 : void ScInvertMerger::Flush()
47 : : {
48 : 39 : FlushLine();
49 : 39 : FlushTotal();
50 : :
51 : : OSL_ENSURE( aLineRect.IsEmpty() && aTotalRect.IsEmpty(), "Flush: not empty" );
52 : :
53 [ + - ]: 39 : if ( pRects )
54 : : {
55 : : //
56 : : // also join vertically if there are non-adjacent columns involved
57 : : //
58 : :
59 : 39 : size_t nComparePos = 0;
60 [ + + ]: 78 : while ( nComparePos < pRects->size() )
61 : : {
62 [ + - ]: 39 : Rectangle aCompRect = (*pRects)[nComparePos];
63 : 39 : sal_Int32 nBottom = aCompRect.Bottom();
64 : 39 : size_t nOtherPos = nComparePos + 1;
65 : :
66 [ - + ]: 39 : while ( nOtherPos < pRects->size() )
67 : : {
68 [ # # ]: 0 : Rectangle aOtherRect = (*pRects)[nOtherPos];
69 [ # # ]: 0 : if ( aOtherRect.Top() > nBottom + 1 )
70 : : {
71 : : // rectangles are sorted, so we can stop searching
72 : : break;
73 : : }
74 [ # # # # : 0 : if ( aOtherRect.Top() == nBottom + 1 &&
# # ][ # # ]
75 : 0 : aOtherRect.Left() == aCompRect.Left() &&
76 : 0 : aOtherRect.Right() == aCompRect.Right() )
77 : : {
78 : : // extend first rectangle
79 : 0 : nBottom = aOtherRect.Bottom();
80 : 0 : aCompRect.Bottom() = nBottom;
81 [ # # ]: 0 : (*pRects)[nComparePos].Bottom() = nBottom;
82 : :
83 : : // remove second rectangle
84 [ # # ][ # # ]: 0 : pRects->erase( pRects->begin() + nOtherPos );
85 : :
86 : : // continue at unmodified nOtherPos
87 : : }
88 : : else
89 : 0 : ++nOtherPos;
90 : : }
91 : :
92 : 39 : ++nComparePos;
93 : : }
94 : : }
95 : 39 : }
96 : :
97 : 39 : void ScInvertMerger::FlushTotal()
98 : : {
99 [ - + ]: 39 : if( aTotalRect.IsEmpty() )
100 : 39 : return; // nothing to do
101 : :
102 [ + - ]: 39 : if ( pRects )
103 : 39 : pRects->push_back( aTotalRect );
104 : :
105 : 39 : aTotalRect.SetEmpty();
106 : : }
107 : :
108 : 89 : void ScInvertMerger::FlushLine()
109 : : {
110 [ - + ]: 89 : if( aLineRect.IsEmpty() )
111 : 89 : return; // nothing to do
112 : :
113 [ + + ]: 89 : if ( aTotalRect.IsEmpty() )
114 : : {
115 : 39 : aTotalRect = aLineRect; // start new total rect
116 : : }
117 : : else
118 : : {
119 [ + - + - : 150 : if ( aLineRect.Left() == aTotalRect.Left() &&
+ - ][ + - ]
120 : 50 : aLineRect.Right() == aTotalRect.Right() &&
121 : 50 : aLineRect.Top() == aTotalRect.Bottom() + 1 )
122 : : {
123 : : // extend total rect
124 : 50 : aTotalRect.Bottom() = aLineRect.Bottom();
125 : : }
126 : : else
127 : : {
128 : 0 : FlushTotal(); // draw old total rect
129 : 0 : aTotalRect = aLineRect; // and start new one
130 : : }
131 : : }
132 : :
133 : 89 : aLineRect.SetEmpty();
134 : : }
135 : :
136 : 447 : void ScInvertMerger::AddRect( const Rectangle& rRect )
137 : : {
138 : 447 : Rectangle aJustified = rRect;
139 [ - + ]: 447 : if ( rRect.Left() > rRect.Right() ) // switch for RTL layout
140 : : {
141 : 0 : aJustified.Left() = rRect.Right();
142 : 0 : aJustified.Right() = rRect.Left();
143 : : }
144 : :
145 [ + - ][ + + ]: 447 : if ( aLineRect.IsEmpty() )
146 : : {
147 : 39 : aLineRect = aJustified; // start new line rect
148 : : }
149 : : else
150 : : {
151 : 408 : sal_Bool bDone = false;
152 [ + + + - ]: 766 : if ( aJustified.Top() == aLineRect.Top() &&
[ + + ]
153 : 358 : aJustified.Bottom() == aLineRect.Bottom() )
154 : : {
155 : : // try to extend line rect
156 [ + - ]: 358 : if ( aJustified.Left() == aLineRect.Right() + 1 )
157 : : {
158 : 358 : aLineRect.Right() = aJustified.Right();
159 : 358 : bDone = sal_True;
160 : : }
161 [ # # ]: 0 : else if ( aJustified.Right() + 1 == aLineRect.Left() ) // for RTL layout
162 : : {
163 : 0 : aLineRect.Left() = aJustified.Left();
164 : 0 : bDone = sal_True;
165 : : }
166 : : }
167 [ + + ]: 408 : if (!bDone)
168 : : {
169 [ + - ]: 50 : FlushLine(); // use old line rect for total rect
170 : 50 : aLineRect = aJustified; // and start new one
171 : : }
172 : : }
173 : 447 : }
174 : :
175 : :
176 : :
177 : :
178 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|