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 <svx/framelinkarray.hxx>
30 : :
31 : : #include <math.h>
32 : : #include <vector>
33 : : #include <algorithm>
34 : : #include <vcl/outdev.hxx>
35 : :
36 : : namespace svx {
37 : : namespace frame {
38 : :
39 : : // ============================================================================
40 : :
41 : :
42 : 1443152 : Cell::Cell() :
43 : : mnAddLeft( 0 ),
44 : : mnAddRight( 0 ),
45 : : mnAddTop( 0 ),
46 : : mnAddBottom( 0 ),
47 : : mbMergeOrig( false ),
48 : : mbOverlapX( false ),
49 : 1443152 : mbOverlapY( false )
50 : : {
51 : 1443152 : }
52 : :
53 : 1392 : void Cell::MirrorSelfX( bool bMirrorStyles, bool bSwapDiag )
54 : : {
55 : 1392 : std::swap( maLeft, maRight );
56 : 1392 : std::swap( mnAddLeft, mnAddRight );
57 [ + - ]: 1392 : if( bMirrorStyles )
58 : : {
59 : 1392 : maLeft.MirrorSelf();
60 : 1392 : maRight.MirrorSelf();
61 : : }
62 [ - + ]: 1392 : if( bSwapDiag )
63 : : {
64 : 0 : std::swap( maTLBR, maBLTR );
65 [ # # ]: 0 : if( bMirrorStyles )
66 : : {
67 : 0 : maTLBR.MirrorSelf();
68 : 0 : maBLTR.MirrorSelf();
69 : : }
70 : : }
71 : 1392 : }
72 : :
73 : : // ----------------------------------------------------------------------------
74 : :
75 : :
76 : 2690 : void lclRecalcCoordVec( LongVec& rCoords, const LongVec& rSizes )
77 : : {
78 : : DBG_ASSERT( rCoords.size() == rSizes.size() + 1, "lclRecalcCoordVec - inconsistent vectors" );
79 : 2690 : LongVec::iterator aCIt = rCoords.begin();
80 : 2690 : LongVec::const_iterator aSIt = rSizes.begin(), aSEnd = rSizes.end();
81 [ + - ][ + - ]: 35734 : for( ; aSIt != aSEnd; ++aCIt, ++aSIt )
[ + - ][ + + ]
82 [ + - ][ + - ]: 33044 : *(aCIt + 1) = *aCIt + *aSIt;
[ + - ][ + - ]
83 : 2690 : }
84 : :
85 : 5 : void lclSetMergedRange( CellVec& rCells, size_t nWidth, size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow )
86 : : {
87 [ + + ]: 23 : for( size_t nCol = nFirstCol; nCol <= nLastCol; ++nCol )
88 : : {
89 [ + + ]: 94 : for( size_t nRow = nFirstRow; nRow <= nLastRow; ++nRow )
90 : : {
91 : 76 : Cell& rCell = rCells[ nRow * nWidth + nCol ];
92 : 76 : rCell.mbMergeOrig = false;
93 : 76 : rCell.mbOverlapX = nCol > nFirstCol;
94 : 76 : rCell.mbOverlapY = nRow > nFirstRow;
95 : : }
96 : : }
97 : 5 : rCells[ nFirstRow * nWidth + nFirstCol ].mbMergeOrig = true;
98 : 5 : }
99 : :
100 : : // ----------------------------------------------------------------------------
101 : :
102 : 139 : static const Style OBJ_STYLE_NONE;
103 : 139 : static const Cell OBJ_CELL_NONE;
104 : :
105 : : const bool DIAG_DBL_CLIP_DEFAULT = false;
106 : :
107 : : // ============================================================================
108 : :
109 : 10340 : ArrayImpl::ArrayImpl( size_t nWidth, size_t nHeight, bool bDiagDblClip ) :
110 : : mnWidth( nWidth ),
111 : : mnHeight( nHeight ),
112 : : mnFirstClipCol( 0 ),
113 : : mnFirstClipRow( 0 ),
114 : : mnLastClipCol( nWidth - 1 ),
115 : : mnLastClipRow( nHeight - 1 ),
116 : : mbXCoordsDirty( false ),
117 : : mbYCoordsDirty( false ),
118 [ + - ][ + - ]: 10340 : mbDiagDblClip( bDiagDblClip )
[ + - ][ + - ]
119 : : {
120 : : // default-construct all vectors
121 [ + - ]: 10340 : maCells.resize( mnWidth * mnHeight );
122 [ + - ]: 10340 : maWidths.resize( mnWidth, 0L );
123 [ + - ]: 10340 : maHeights.resize( mnHeight, 0L );
124 [ + - ]: 10340 : maXCoords.resize( mnWidth + 1, 0L );
125 [ + - ]: 10340 : maYCoords.resize( mnHeight + 1, 0L );
126 : 10340 : }
127 : :
128 : 17353171 : const Cell& ArrayImpl::GetCell( size_t nCol, size_t nRow ) const
129 : : {
130 [ + - ]: 17353171 : return IsValidPos( nCol, nRow ) ? maCells[ GetIndex( nCol, nRow ) ] : OBJ_CELL_NONE;
131 : : }
132 : :
133 : 7624962 : Cell& ArrayImpl::GetCellAcc( size_t nCol, size_t nRow )
134 : : {
135 [ + + ][ + - ]: 7624962 : static Cell aDummy;
[ + - ][ # # ]
136 [ + - ]: 7624962 : return IsValidPos( nCol, nRow ) ? maCells[ GetIndex( nCol, nRow ) ] : aDummy;
137 : : }
138 : :
139 : 3990715 : size_t ArrayImpl::GetMergedFirstCol( size_t nCol, size_t nRow ) const
140 : : {
141 : 3990715 : size_t nFirstCol = nCol;
142 [ + + ][ + + ]: 3991324 : while( (nFirstCol > 0) && GetCell( nFirstCol, nRow ).mbOverlapX ) --nFirstCol;
[ + + ]
143 : 3990715 : return nFirstCol;
144 : : }
145 : :
146 : 3990715 : size_t ArrayImpl::GetMergedFirstRow( size_t nCol, size_t nRow ) const
147 : : {
148 : 3990715 : size_t nFirstRow = nRow;
149 [ + + ][ + + ]: 3991435 : while( (nFirstRow > 0) && GetCell( nCol, nFirstRow ).mbOverlapY ) --nFirstRow;
[ + + ]
150 : 3990715 : return nFirstRow;
151 : : }
152 : :
153 : 810639 : size_t ArrayImpl::GetMergedLastCol( size_t nCol, size_t nRow ) const
154 : : {
155 : 810639 : size_t nLastCol = nCol + 1;
156 [ + - ][ + + ]: 811077 : while( (nLastCol < mnWidth) && GetCell( nLastCol, nRow ).mbOverlapX ) ++nLastCol;
[ + + ]
157 : 810639 : return nLastCol - 1;
158 : : }
159 : :
160 : 810639 : size_t ArrayImpl::GetMergedLastRow( size_t nCol, size_t nRow ) const
161 : : {
162 : 810639 : size_t nLastRow = nRow + 1;
163 [ + - ][ + + ]: 811158 : while( (nLastRow < mnHeight) && GetCell( nCol, nLastRow ).mbOverlapY ) ++nLastRow;
[ + + ]
164 : 810639 : return nLastRow - 1;
165 : : }
166 : :
167 : 2218654 : const Cell& ArrayImpl::GetMergedOriginCell( size_t nCol, size_t nRow ) const
168 : : {
169 : 2218654 : return GetCell( GetMergedFirstCol( nCol, nRow ), GetMergedFirstRow( nCol, nRow ) );
170 : : }
171 : :
172 : 227262 : bool ArrayImpl::IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const
173 : : {
174 : 227262 : const Cell& rCell = GetCell( nCol, nRow );
175 [ - + ][ + + ]: 227262 : return rCell.mbOverlapX || (rCell.mnAddLeft > 0);
176 : : }
177 : :
178 : 325630 : bool ArrayImpl::IsMergedOverlappedRight( size_t nCol, size_t nRow ) const
179 : : {
180 [ + + ][ - + ]: 325630 : return GetCell( nCol + 1, nRow ).mbOverlapX || (GetCell( nCol, nRow ).mnAddRight > 0);
181 : : }
182 : :
183 : 223224 : bool ArrayImpl::IsMergedOverlappedTop( size_t nCol, size_t nRow ) const
184 : : {
185 : 223224 : const Cell& rCell = GetCell( nCol, nRow );
186 [ - + ][ + + ]: 223224 : return rCell.mbOverlapY || (rCell.mnAddTop > 0);
187 : : }
188 : :
189 : 333802 : bool ArrayImpl::IsMergedOverlappedBottom( size_t nCol, size_t nRow ) const
190 : : {
191 [ + + ][ - + ]: 333802 : return GetCell( nCol, nRow + 1 ).mbOverlapY || (GetCell( nCol, nRow ).mnAddBottom > 0);
192 : : }
193 : :
194 : 2429395 : bool ArrayImpl::IsColInClipRange( size_t nCol ) const
195 : : {
196 [ + + ][ + + ]: 2429395 : return (mnFirstClipCol <= nCol) && (nCol <= mnLastClipCol);
197 : : }
198 : :
199 : 2429108 : bool ArrayImpl::IsRowInClipRange( size_t nRow ) const
200 : : {
201 [ + + ][ + + ]: 2429108 : return (mnFirstClipRow <= nRow) && (nRow <= mnLastClipRow);
202 : : }
203 : :
204 : 1319432 : bool ArrayImpl::IsInClipRange( size_t nCol, size_t nRow ) const
205 : : {
206 [ + + ][ + + ]: 1319432 : return IsColInClipRange( nCol ) && IsRowInClipRange( nRow );
207 : : }
208 : :
209 : 501323 : long ArrayImpl::GetColPosition( size_t nCol ) const
210 : : {
211 [ + + ]: 501323 : if( mbXCoordsDirty )
212 : : {
213 : 1345 : lclRecalcCoordVec( maXCoords, maWidths );
214 : 1345 : mbXCoordsDirty = false;
215 : : }
216 : 501323 : return maXCoords[ nCol ];
217 : : }
218 : :
219 : 497335 : long ArrayImpl::GetRowPosition( size_t nRow ) const
220 : : {
221 [ + + ]: 497335 : if( mbYCoordsDirty )
222 : : {
223 : 1345 : lclRecalcCoordVec( maYCoords, maHeights );
224 : 1345 : mbYCoordsDirty = false;
225 : : }
226 : 497335 : return maYCoords[ nRow ];
227 : : }
228 : :
229 : 144 : long ArrayImpl::GetColWidth( size_t nFirstCol, size_t nLastCol ) const
230 : : {
231 : 144 : return GetColPosition( nLastCol + 1 ) - GetColPosition( nFirstCol );
232 : : }
233 : :
234 : 144 : long ArrayImpl::GetRowHeight( size_t nFirstRow, size_t nLastRow ) const
235 : : {
236 : 144 : return GetRowPosition( nLastRow + 1 ) - GetRowPosition( nFirstRow );
237 : : }
238 : :
239 : 659716 : double ArrayImpl::GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
240 : : {
241 : 659716 : double fAngle = 0.0;
242 [ + - ]: 659716 : if( IsValidPos( nCol, nRow ) )
243 : : {
244 [ + - ][ + + ]: 659716 : if( bSimple || !GetCell( nCol, nRow ).IsMerged() )
[ + + ]
245 : : {
246 : 659572 : fAngle = frame::GetHorDiagAngle( maWidths[ nCol ] + 1, maHeights[ nRow ] + 1 );
247 : : }
248 : : else
249 : : {
250 : : // return correct angle for each cell in the merged range
251 : 144 : size_t nFirstCol = GetMergedFirstCol( nCol, nRow );
252 : 144 : size_t nFirstRow = GetMergedFirstRow( nCol, nRow );
253 : 144 : const Cell& rCell = GetCell( nFirstCol, nFirstRow );
254 : 144 : long nWidth = GetColWidth( nFirstCol, GetMergedLastCol( nCol, nRow ) ) + rCell.mnAddLeft + rCell.mnAddRight;
255 : 144 : long nHeight = GetRowHeight( nFirstRow, GetMergedLastRow( nCol, nRow ) ) + rCell.mnAddTop + rCell.mnAddBottom;
256 : 144 : fAngle = frame::GetHorDiagAngle( nWidth + 1, nHeight + 1 );
257 : : }
258 : : }
259 : 659716 : return fAngle;
260 : : }
261 : :
262 : 333928 : double ArrayImpl::GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
263 : : {
264 : 333928 : double fAngle = GetHorDiagAngle( nCol, nRow, bSimple );
265 [ + - ]: 333928 : return (fAngle > 0.0) ? (F_PI2 - fAngle) : 0.0;
266 : : }
267 : :
268 : : // ============================================================================
269 : :
270 : : class MergedCellIterator
271 : : {
272 : : public:
273 : : explicit MergedCellIterator( const Array& rArray, size_t nCol, size_t nRow );
274 : :
275 [ # # ][ # # ]: 0 : inline bool Is() const { return (mnCol <= mnLastCol) && (mnRow <= mnLastRow); }
276 : 0 : inline size_t Col() const { return mnCol; }
277 : 0 : inline size_t Row() const { return mnRow; }
278 : :
279 : : MergedCellIterator& operator++();
280 : :
281 : : private:
282 : : size_t mnFirstCol;
283 : : size_t mnFirstRow;
284 : : size_t mnLastCol;
285 : : size_t mnLastRow;
286 : : size_t mnCol;
287 : : size_t mnRow;
288 : : };
289 : :
290 : : // ----------------------------------------------------------------------------
291 : :
292 : 0 : MergedCellIterator::MergedCellIterator( const Array& rArray, size_t nCol, size_t nRow )
293 : : {
294 : : DBG_ASSERT( rArray.IsMerged( nCol, nRow ), "svx::frame::MergedCellIterator::MergedCellIterator - not in merged range" );
295 : 0 : rArray.GetMergedRange( mnFirstCol, mnFirstRow, mnLastCol, mnLastRow, nCol, nRow );
296 : 0 : mnCol = mnFirstCol;
297 : 0 : mnRow = mnFirstRow;
298 : 0 : }
299 : :
300 : 0 : MergedCellIterator& MergedCellIterator::operator++()
301 : : {
302 : : DBG_ASSERT( Is(), "svx::frame::MergedCellIterator::operator++() - already invalid" );
303 [ # # ]: 0 : if( ++mnCol > mnLastCol )
304 : : {
305 : 0 : mnCol = mnFirstCol;
306 : 0 : ++mnRow;
307 : : }
308 : 0 : return *this;
309 : : }
310 : :
311 : : // ============================================================================
312 : :
313 : : #define DBG_FRAME_CHECK( cond, funcname, error ) DBG_ASSERT( cond, "svx::frame::Array::" funcname " - " error )
314 : : #define DBG_FRAME_CHECK_COL( col, funcname ) DBG_FRAME_CHECK( (col) < GetColCount(), funcname, "invalid column index" )
315 : : #define DBG_FRAME_CHECK_ROW( row, funcname ) DBG_FRAME_CHECK( (row) < GetRowCount(), funcname, "invalid row index" )
316 : : #define DBG_FRAME_CHECK_COLROW( col, row, funcname ) DBG_FRAME_CHECK( ((col) < GetColCount()) && ((row) < GetRowCount()), funcname, "invalid cell index" )
317 : : #define DBG_FRAME_CHECK_INDEX( index, funcname ) DBG_FRAME_CHECK( (index) < GetCellCount(), funcname, "invalid cell index" )
318 : : #define DBG_FRAME_CHECK_COL_1( col, funcname ) DBG_FRAME_CHECK( (col) <= GetColCount(), funcname, "invalid column index" )
319 : : #define DBG_FRAME_CHECK_ROW_1( row, funcname ) DBG_FRAME_CHECK( (row) <= GetRowCount(), funcname, "invalid row index" )
320 : :
321 : : // ----------------------------------------------------------------------------
322 : :
323 : : #define CELL( col, row ) mxImpl->GetCell( col, row )
324 : : #define CELLACC( col, row ) mxImpl->GetCellAcc( col, row )
325 : : #define ORIGCELL( col, row ) mxImpl->GetMergedOriginCell( col, row )
326 : :
327 : : // ----------------------------------------------------------------------------
328 : :
329 : 5170 : Array::Array()
330 : : {
331 [ + - ]: 5170 : Initialize( 0, 0 );
332 : 5170 : }
333 : :
334 : 5170 : Array::~Array()
335 : : {
336 : 5170 : }
337 : :
338 : : // array size and column/row indexes ------------------------------------------
339 : :
340 : 10340 : void Array::Initialize( size_t nWidth, size_t nHeight )
341 : : {
342 [ + + ]: 10340 : bool bDiagDblClip = mxImpl.get() ? mxImpl->mbDiagDblClip : DIAG_DBL_CLIP_DEFAULT;
343 [ + - ]: 10340 : mxImpl.reset( new ArrayImpl( nWidth, nHeight, bDiagDblClip ) );
344 : 10340 : }
345 : :
346 : 1345 : size_t Array::GetColCount() const
347 : : {
348 : 1345 : return mxImpl->mnWidth;
349 : : }
350 : :
351 : 1345 : size_t Array::GetRowCount() const
352 : : {
353 : 1345 : return mxImpl->mnHeight;
354 : : }
355 : :
356 : 4 : size_t Array::GetCellCount() const
357 : : {
358 : 4 : return mxImpl->maCells.size();
359 : : }
360 : :
361 : 0 : size_t Array::GetCellIndex( size_t nCol, size_t nRow, bool bRTL ) const
362 : : {
363 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetCellIndex" );
364 [ # # ]: 0 : if (bRTL)
365 : 0 : nCol = mxImpl->GetMirrorCol(nCol);
366 : 0 : return mxImpl->GetIndex( nCol, nRow );
367 : : }
368 : :
369 : : // cell border styles ---------------------------------------------------------
370 : :
371 : 1270827 : void Array::SetCellStyleLeft( size_t nCol, size_t nRow, const Style& rStyle )
372 : : {
373 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleLeft" );
374 : 1270827 : CELLACC( nCol, nRow ).maLeft = rStyle;
375 : 1270827 : }
376 : :
377 : 1270827 : void Array::SetCellStyleRight( size_t nCol, size_t nRow, const Style& rStyle )
378 : : {
379 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleRight" );
380 : 1270827 : CELLACC( nCol, nRow ).maRight = rStyle;
381 : 1270827 : }
382 : :
383 : 1270827 : void Array::SetCellStyleTop( size_t nCol, size_t nRow, const Style& rStyle )
384 : : {
385 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleTop" );
386 : 1270827 : CELLACC( nCol, nRow ).maTop = rStyle;
387 : 1270827 : }
388 : :
389 : 1270827 : void Array::SetCellStyleBottom( size_t nCol, size_t nRow, const Style& rStyle )
390 : : {
391 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleBottom" );
392 : 1270827 : CELLACC( nCol, nRow ).maBottom = rStyle;
393 : 1270827 : }
394 : :
395 : 1270827 : void Array::SetCellStyleTLBR( size_t nCol, size_t nRow, const Style& rStyle )
396 : : {
397 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleTLBR" );
398 : 1270827 : CELLACC( nCol, nRow ).maTLBR = rStyle;
399 : 1270827 : }
400 : :
401 : 1270827 : void Array::SetCellStyleBLTR( size_t nCol, size_t nRow, const Style& rStyle )
402 : : {
403 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleBLTR" );
404 : 1270827 : CELLACC( nCol, nRow ).maBLTR = rStyle;
405 : 1270827 : }
406 : :
407 : 0 : void Array::SetCellStyleDiag( size_t nCol, size_t nRow, const Style& rTLBR, const Style& rBLTR )
408 : : {
409 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleDiag" );
410 : 0 : Cell& rCell = CELLACC( nCol, nRow );
411 : 0 : rCell.maTLBR = rTLBR;
412 : 0 : rCell.maBLTR = rBLTR;
413 : 0 : }
414 : :
415 : 0 : void Array::SetColumnStyleLeft( size_t nCol, const Style& rStyle )
416 : : {
417 : : DBG_FRAME_CHECK_COL( nCol, "SetColumnStyleLeft" );
418 [ # # ]: 0 : for( size_t nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
419 : 0 : SetCellStyleLeft( nCol, nRow, rStyle );
420 : 0 : }
421 : :
422 : 0 : void Array::SetColumnStyleRight( size_t nCol, const Style& rStyle )
423 : : {
424 : : DBG_FRAME_CHECK_COL( nCol, "SetColumnStyleRight" );
425 [ # # ]: 0 : for( size_t nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
426 : 0 : SetCellStyleRight( nCol, nRow, rStyle );
427 : 0 : }
428 : :
429 : 0 : void Array::SetRowStyleTop( size_t nRow, const Style& rStyle )
430 : : {
431 : : DBG_FRAME_CHECK_ROW( nRow, "SetRowStyleTop" );
432 [ # # ]: 0 : for( size_t nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
433 : 0 : SetCellStyleTop( nCol, nRow, rStyle );
434 : 0 : }
435 : :
436 : 0 : void Array::SetRowStyleBottom( size_t nRow, const Style& rStyle )
437 : : {
438 : : DBG_FRAME_CHECK_ROW( nRow, "SetRowStyleBottom" );
439 [ # # ]: 0 : for( size_t nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
440 : 0 : SetCellStyleBottom( nCol, nRow, rStyle );
441 : 0 : }
442 : :
443 : 227672 : const Style& Array::GetCellStyleLeft( size_t nCol, size_t nRow, bool bSimple ) const
444 : : {
445 : : // simple: always return own left style
446 [ - + ]: 227672 : if( bSimple )
447 : 0 : return CELL( nCol, nRow ).maLeft;
448 : : // outside clipping rows or overlapped in merged cells: invisible
449 [ + + ][ + + ]: 227672 : if( !mxImpl->IsRowInClipRange( nRow ) || mxImpl->IsMergedOverlappedLeft( nCol, nRow ) )
[ + + ]
450 : 437 : return OBJ_STYLE_NONE;
451 : : // left clipping border: always own left style
452 [ + + ]: 227235 : if( nCol == mxImpl->mnFirstClipCol )
453 : 189 : return ORIGCELL( nCol, nRow ).maLeft;
454 : : // right clipping border: always right style of left neighbor cell
455 [ + + ]: 227046 : if( nCol == mxImpl->mnLastClipCol + 1 )
456 : 63 : return ORIGCELL( nCol - 1, nRow ).maRight;
457 : : // outside clipping columns: invisible
458 [ - + ]: 226983 : if( !mxImpl->IsColInClipRange( nCol ) )
459 : 0 : return OBJ_STYLE_NONE;
460 : : // inside clipping range: maximum of own left style and right style of left neighbor cell
461 : 227672 : return std::max( ORIGCELL( nCol, nRow ).maLeft, ORIGCELL( nCol - 1, nRow ).maRight );
462 : : }
463 : :
464 : 325788 : const Style& Array::GetCellStyleRight( size_t nCol, size_t nRow, bool bSimple ) const
465 : : {
466 : : // simple: always return own right style
467 [ - + ]: 325788 : if( bSimple )
468 : 0 : return CELL( nCol, nRow ).maRight;
469 : : // outside clipping rows or overlapped in merged cells: invisible
470 [ + + ][ + + ]: 325788 : if( !mxImpl->IsRowInClipRange( nRow ) || mxImpl->IsMergedOverlappedRight( nCol, nRow ) )
[ + + ]
471 : 212 : return OBJ_STYLE_NONE;
472 : : // left clipping border: always left style of right neighbor cell
473 [ - + ]: 325576 : if( nCol + 1 == mxImpl->mnFirstClipCol )
474 : 0 : return ORIGCELL( nCol + 1, nRow ).maLeft;
475 : : // right clipping border: always own right style
476 [ + + ]: 325576 : if( nCol == mxImpl->mnLastClipCol )
477 : 126 : return ORIGCELL( nCol, nRow ).maRight;
478 : : // outside clipping columns: invisible
479 [ - + ]: 325450 : if( !mxImpl->IsColInClipRange( nCol ) )
480 : 0 : return OBJ_STYLE_NONE;
481 : : // inside clipping range: maximum of own right style and left style of right neighbor cell
482 : 325788 : return std::max( ORIGCELL( nCol, nRow ).maRight, ORIGCELL( nCol + 1, nRow ).maLeft );
483 : : }
484 : :
485 : 223602 : const Style& Array::GetCellStyleTop( size_t nCol, size_t nRow, bool bSimple ) const
486 : : {
487 : : // simple: always return own top style
488 [ - + ]: 223602 : if( bSimple )
489 : 0 : return CELL( nCol, nRow ).maTop;
490 : : // outside clipping columns or overlapped in merged cells: invisible
491 [ + + ][ + + ]: 223602 : if( !mxImpl->IsColInClipRange( nCol ) || mxImpl->IsMergedOverlappedTop( nCol, nRow ) )
[ + + ]
492 : 406 : return OBJ_STYLE_NONE;
493 : : // top clipping border: always own top style
494 [ + + ]: 223196 : if( nRow == mxImpl->mnFirstClipRow )
495 : 237 : return ORIGCELL( nCol, nRow ).maTop;
496 : : // bottom clipping border: always bottom style of top neighbor cell
497 [ + + ]: 222959 : if( nRow == mxImpl->mnLastClipRow + 1 )
498 : 79 : return ORIGCELL( nCol, nRow - 1 ).maBottom;
499 : : // outside clipping rows: invisible
500 [ - + ]: 222880 : if( !mxImpl->IsRowInClipRange( nRow ) )
501 : 0 : return OBJ_STYLE_NONE;
502 : : // inside clipping range: maximum of own top style and bottom style of top neighbor cell
503 : 223602 : return std::max( ORIGCELL( nCol, nRow ).maTop, ORIGCELL( nCol, nRow - 1 ).maBottom );
504 : : }
505 : :
506 : 333928 : const Style& Array::GetCellStyleBottom( size_t nCol, size_t nRow, bool bSimple ) const
507 : : {
508 : : // simple: always return own bottom style
509 [ - + ]: 333928 : if( bSimple )
510 : 0 : return CELL( nCol, nRow ).maBottom;
511 : : // outside clipping columns or overlapped in merged cells: invisible
512 [ + + ][ + + ]: 333928 : if( !mxImpl->IsColInClipRange( nCol ) || mxImpl->IsMergedOverlappedBottom( nCol, nRow ) )
[ + + ]
513 : 182 : return OBJ_STYLE_NONE;
514 : : // top clipping border: always top style of bottom neighbor cell
515 [ - + ]: 333746 : if( nRow + 1 == mxImpl->mnFirstClipRow )
516 : 0 : return ORIGCELL( nCol, nRow + 1 ).maTop;
517 : : // bottom clipping border: always own bottom style
518 [ + + ]: 333746 : if( nRow == mxImpl->mnLastClipRow )
519 : 158 : return ORIGCELL( nCol, nRow ).maBottom;
520 : : // outside clipping rows: invisible
521 [ - + ]: 333588 : if( !mxImpl->IsRowInClipRange( nRow ) )
522 : 0 : return OBJ_STYLE_NONE;
523 : : // inside clipping range: maximum of own bottom style and top style of bottom neighbor cell
524 : 333928 : return std::max( ORIGCELL( nCol, nRow ).maBottom, ORIGCELL( nCol, nRow + 1 ).maTop );
525 : : }
526 : :
527 : 151063 : const Style& Array::GetCellStyleTLBR( size_t nCol, size_t nRow, bool bSimple ) const
528 : : {
529 : 151063 : return bSimple ? CELL( nCol, nRow ).maTLBR :
530 [ + - ][ # # ]: 302126 : (mxImpl->IsInClipRange( nCol, nRow ) ? ORIGCELL( nCol, nRow ).maTLBR : OBJ_STYLE_NONE);
531 : : }
532 : :
533 : 151063 : const Style& Array::GetCellStyleBLTR( size_t nCol, size_t nRow, bool bSimple ) const
534 : : {
535 : 151063 : return bSimple ? CELL( nCol, nRow ).maBLTR :
536 [ + - ][ # # ]: 302126 : (mxImpl->IsInClipRange( nCol, nRow ) ? ORIGCELL( nCol, nRow ).maBLTR : OBJ_STYLE_NONE);
537 : : }
538 : :
539 : 329858 : const Style& Array::GetCellStyleTL( size_t nCol, size_t nRow ) const
540 : : {
541 : : // not in clipping range: always invisible
542 [ + + ]: 329858 : if( !mxImpl->IsInClipRange( nCol, nRow ) )
543 : 142 : return OBJ_STYLE_NONE;
544 : : // return style only for top-left cell
545 : 329716 : size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
546 : 329716 : size_t nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
547 : : return ((nCol == nFirstCol) && (nRow == nFirstRow)) ?
548 [ + + ][ + + ]: 329858 : CELL( nFirstCol, nFirstRow ).maTLBR : OBJ_STYLE_NONE;
549 : : }
550 : :
551 : 329858 : const Style& Array::GetCellStyleBR( size_t nCol, size_t nRow ) const
552 : : {
553 : : // not in clipping range: always invisible
554 [ + + ]: 329858 : if( !mxImpl->IsInClipRange( nCol, nRow ) )
555 : 142 : return OBJ_STYLE_NONE;
556 : : // return style only for bottom-right cell
557 : 329716 : size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
558 : 329716 : size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
559 : : return ((nCol == nLastCol) && (nRow == nLastRow)) ?
560 [ + + ][ + + ]: 329858 : CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), mxImpl->GetMergedFirstRow( nCol, nRow ) ).maTLBR : OBJ_STYLE_NONE;
561 : : }
562 : :
563 : 329858 : const Style& Array::GetCellStyleBL( size_t nCol, size_t nRow ) const
564 : : {
565 : : // not in clipping range: always invisible
566 [ + + ]: 329858 : if( !mxImpl->IsInClipRange( nCol, nRow ) )
567 : 142 : return OBJ_STYLE_NONE;
568 : : // return style only for bottom-left cell
569 : 329716 : size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
570 : 329716 : size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
571 : : return ((nCol == nFirstCol) && (nRow == nLastRow)) ?
572 [ + + ][ + + ]: 329858 : CELL( nFirstCol, mxImpl->GetMergedFirstRow( nCol, nRow ) ).maBLTR : OBJ_STYLE_NONE;
573 : : }
574 : :
575 : 329858 : const Style& Array::GetCellStyleTR( size_t nCol, size_t nRow ) const
576 : : {
577 : : // not in clipping range: always invisible
578 [ + + ]: 329858 : if( !mxImpl->IsInClipRange( nCol, nRow ) )
579 : 142 : return OBJ_STYLE_NONE;
580 : : // return style only for top-right cell
581 : 329716 : size_t nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
582 : 329716 : size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
583 : : return ((nCol == nLastCol) && (nRow == nFirstRow)) ?
584 [ + + ][ + + ]: 329858 : CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), nFirstRow ).maBLTR : OBJ_STYLE_NONE;
585 : : }
586 : :
587 : : // cell merging ---------------------------------------------------------------
588 : :
589 : 5 : void Array::SetMergedRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow )
590 : : {
591 : : DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "SetMergedRange" );
592 : : DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "SetMergedRange" );
593 : : #if OSL_DEBUG_LEVEL >= 2
594 : : {
595 : : bool bFound = false;
596 : : for( size_t nCurrCol = nFirstCol; !bFound && (nCurrCol <= nLastCol); ++nCurrCol )
597 : : for( size_t nCurrRow = nFirstRow; !bFound && (nCurrRow <= nLastRow); ++nCurrRow )
598 : : bFound = CELL( nCurrCol, nCurrRow ).IsMerged();
599 : : DBG_FRAME_CHECK( !bFound, "SetMergedRange", "overlapping merged ranges" );
600 : : }
601 : : #endif
602 [ + - ][ + - ]: 5 : if( mxImpl->IsValidPos( nFirstCol, nFirstRow ) && mxImpl->IsValidPos( nLastCol, nLastRow ) )
[ + - ]
603 : 5 : lclSetMergedRange( mxImpl->maCells, mxImpl->mnWidth, nFirstCol, nFirstRow, nLastCol, nLastRow );
604 : 5 : }
605 : :
606 : 0 : void Array::SetAddMergedLeftSize( size_t nCol, size_t nRow, long nAddSize )
607 : : {
608 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedLeftSize" );
609 : : DBG_FRAME_CHECK( mxImpl->GetMergedFirstCol( nCol, nRow ) == 0, "SetAddMergedLeftSize", "additional border inside array" );
610 [ # # ][ # # ]: 0 : for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
611 [ # # ]: 0 : CELLACC( aIt.Col(), aIt.Row() ).mnAddLeft = nAddSize;
612 : 0 : }
613 : :
614 : 0 : void Array::SetAddMergedRightSize( size_t nCol, size_t nRow, long nAddSize )
615 : : {
616 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedRightSize" );
617 : : DBG_FRAME_CHECK( mxImpl->GetMergedLastCol( nCol, nRow ) + 1 == mxImpl->mnWidth, "SetAddMergedRightSize", "additional border inside array" );
618 [ # # ][ # # ]: 0 : for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
619 [ # # ]: 0 : CELLACC( aIt.Col(), aIt.Row() ).mnAddRight = nAddSize;
620 : 0 : }
621 : :
622 : 0 : void Array::SetAddMergedTopSize( size_t nCol, size_t nRow, long nAddSize )
623 : : {
624 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedTopSize" );
625 : : DBG_FRAME_CHECK( mxImpl->GetMergedFirstRow( nCol, nRow ) == 0, "SetAddMergedTopSize", "additional border inside array" );
626 [ # # ][ # # ]: 0 : for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
627 [ # # ]: 0 : CELLACC( aIt.Col(), aIt.Row() ).mnAddTop = nAddSize;
628 : 0 : }
629 : :
630 : 0 : void Array::SetAddMergedBottomSize( size_t nCol, size_t nRow, long nAddSize )
631 : : {
632 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedBottomSize" );
633 : : DBG_FRAME_CHECK( mxImpl->GetMergedLastRow( nCol, nRow ) + 1 == mxImpl->mnHeight, "SetAddMergedBottomSize", "additional border inside array" );
634 [ # # ][ # # ]: 0 : for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
635 [ # # ]: 0 : CELLACC( aIt.Col(), aIt.Row() ).mnAddBottom = nAddSize;
636 : 0 : }
637 : :
638 : 1442971 : bool Array::IsMerged( size_t nCol, size_t nRow ) const
639 : : {
640 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMerged" );
641 : 1442971 : return CELL( nCol, nRow ).IsMerged();
642 : : }
643 : :
644 : 0 : bool Array::IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const
645 : : {
646 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOverlappedLeft" );
647 : 0 : return mxImpl->IsMergedOverlappedLeft( nCol, nRow );
648 : : }
649 : :
650 : 0 : bool Array::IsMergedOverlappedRight( size_t nCol, size_t nRow ) const
651 : : {
652 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOverlappedRight" );
653 : 0 : return mxImpl->IsMergedOverlappedRight( nCol, nRow );
654 : : }
655 : :
656 : 0 : void Array::GetMergedOrigin( size_t& rnFirstCol, size_t& rnFirstRow, size_t nCol, size_t nRow ) const
657 : : {
658 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetMergedOrigin" );
659 : 0 : rnFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
660 : 0 : rnFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
661 : 0 : }
662 : :
663 : 0 : void Array::GetMergedRange( size_t& rnFirstCol, size_t& rnFirstRow,
664 : : size_t& rnLastCol, size_t& rnLastRow, size_t nCol, size_t nRow ) const
665 : : {
666 : 0 : GetMergedOrigin( rnFirstCol, rnFirstRow, nCol, nRow );
667 : 0 : rnLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
668 : 0 : rnLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
669 : 0 : }
670 : :
671 : : // clipping -------------------------------------------------------------------
672 : :
673 : 63 : void Array::SetClipRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow )
674 : : {
675 : : DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "SetClipRange" );
676 : : DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "SetClipRange" );
677 : 63 : mxImpl->mnFirstClipCol = nFirstCol;
678 : 63 : mxImpl->mnFirstClipRow = nFirstRow;
679 : 63 : mxImpl->mnLastClipCol = nLastCol;
680 : 63 : mxImpl->mnLastClipRow = nLastRow;
681 : 63 : }
682 : :
683 : 0 : Rectangle Array::GetClipRangeRectangle() const
684 : : {
685 : : return Rectangle(
686 : 0 : mxImpl->GetColPosition( mxImpl->mnFirstClipCol ),
687 : 0 : mxImpl->GetRowPosition( mxImpl->mnFirstClipRow ),
688 : 0 : mxImpl->GetColPosition( mxImpl->mnLastClipCol + 1 ),
689 : 0 : mxImpl->GetRowPosition( mxImpl->mnLastClipRow + 1 ) );
690 : : }
691 : :
692 : : // cell coordinates -----------------------------------------------------------
693 : :
694 : 1345 : void Array::SetXOffset( long nXOffset )
695 : : {
696 : 1345 : mxImpl->maXCoords[ 0 ] = nXOffset;
697 : 1345 : mxImpl->mbXCoordsDirty = true;
698 : 1345 : }
699 : :
700 : 1345 : void Array::SetYOffset( long nYOffset )
701 : : {
702 : 1345 : mxImpl->maYCoords[ 0 ] = nYOffset;
703 : 1345 : mxImpl->mbYCoordsDirty = true;
704 : 1345 : }
705 : :
706 : 14487 : void Array::SetColWidth( size_t nCol, long nWidth )
707 : : {
708 : : DBG_FRAME_CHECK_COL( nCol, "SetColWidth" );
709 : 14487 : mxImpl->maWidths[ nCol ] = nWidth;
710 : 14487 : mxImpl->mbXCoordsDirty = true;
711 : 14487 : }
712 : :
713 : 18557 : void Array::SetRowHeight( size_t nRow, long nHeight )
714 : : {
715 : : DBG_FRAME_CHECK_ROW( nRow, "SetRowHeight" );
716 : 18557 : mxImpl->maHeights[ nRow ] = nHeight;
717 : 18557 : mxImpl->mbYCoordsDirty = true;
718 : 18557 : }
719 : :
720 : 0 : void Array::SetAllColWidths( long nWidth )
721 : : {
722 : 0 : std::fill( mxImpl->maWidths.begin(), mxImpl->maWidths.end(), nWidth );
723 : 0 : mxImpl->mbXCoordsDirty = true;
724 : 0 : }
725 : :
726 : 0 : void Array::SetAllRowHeights( long nHeight )
727 : : {
728 : 0 : std::fill( mxImpl->maHeights.begin(), mxImpl->maHeights.end(), nHeight );
729 : 0 : mxImpl->mbYCoordsDirty = true;
730 : 0 : }
731 : :
732 : 453189 : long Array::GetColPosition( size_t nCol ) const
733 : : {
734 : : DBG_FRAME_CHECK_COL_1( nCol, "GetColPosition" );
735 : 453189 : return mxImpl->GetColPosition( nCol );
736 : : }
737 : :
738 : 453189 : long Array::GetRowPosition( size_t nRow ) const
739 : : {
740 : : DBG_FRAME_CHECK_ROW_1( nRow, "GetRowPosition" );
741 : 453189 : return mxImpl->GetRowPosition( nRow );
742 : : }
743 : :
744 : 151063 : long Array::GetColWidth( size_t nFirstCol, size_t nLastCol ) const
745 : : {
746 : : DBG_FRAME_CHECK_COL( nFirstCol, "GetColWidth" );
747 : : DBG_FRAME_CHECK_COL( nLastCol, "GetColWidth" );
748 : 151063 : return GetColPosition( nLastCol + 1 ) - GetColPosition( nFirstCol );
749 : : }
750 : :
751 : 151063 : long Array::GetRowHeight( size_t nFirstRow, size_t nLastRow ) const
752 : : {
753 : : DBG_FRAME_CHECK_ROW( nFirstRow, "GetRowHeight" );
754 : : DBG_FRAME_CHECK_ROW( nLastRow, "GetRowHeight" );
755 : 151063 : return GetRowPosition( nLastRow + 1 ) - GetRowPosition( nFirstRow );
756 : : }
757 : :
758 : 0 : long Array::GetWidth() const
759 : : {
760 : 0 : return GetColPosition( mxImpl->mnWidth ) - GetColPosition( 0 );
761 : : }
762 : :
763 : 0 : long Array::GetHeight() const
764 : : {
765 : 0 : return GetRowPosition( mxImpl->mnHeight ) - GetRowPosition( 0 );
766 : : }
767 : :
768 : 151063 : Point Array::GetCellPosition( size_t nCol, size_t nRow, bool bSimple ) const
769 : : {
770 [ - + ]: 151063 : size_t nFirstCol = bSimple ? nCol : mxImpl->GetMergedFirstCol( nCol, nRow );
771 [ - + ]: 151063 : size_t nFirstRow = bSimple ? nRow : mxImpl->GetMergedFirstRow( nCol, nRow );
772 : 151063 : return Point( GetColPosition( nFirstCol ), GetRowPosition( nFirstRow ) );
773 : : }
774 : :
775 : 151063 : Size Array::GetCellSize( size_t nCol, size_t nRow, bool bSimple ) const
776 : : {
777 [ - + ]: 151063 : size_t nFirstCol = bSimple ? nCol : mxImpl->GetMergedFirstCol( nCol, nRow );
778 [ - + ]: 151063 : size_t nFirstRow = bSimple ? nRow : mxImpl->GetMergedFirstRow( nCol, nRow );
779 [ - + ]: 151063 : size_t nLastCol = bSimple ? nCol : mxImpl->GetMergedLastCol( nCol, nRow );
780 [ - + ]: 151063 : size_t nLastRow = bSimple ? nRow : mxImpl->GetMergedLastRow( nCol, nRow );
781 : 151063 : return Size( GetColWidth( nFirstCol, nLastCol ) + 1, GetRowHeight( nFirstRow, nLastRow ) + 1 );
782 : : }
783 : :
784 : 151063 : Rectangle Array::GetCellRect( size_t nCol, size_t nRow, bool bSimple ) const
785 : : {
786 [ + - ][ + - ]: 151063 : Rectangle aRect( GetCellPosition( nCol, nRow, bSimple ), GetCellSize( nCol, nRow, bSimple ) );
787 : :
788 : : // adjust rectangle for partly visible merged cells
789 : 151063 : const Cell& rCell = CELL( nCol, nRow );
790 [ + + ][ + + ]: 151063 : if( !bSimple && rCell.IsMerged() )
[ + - ]
791 : : {
792 : 2 : aRect.Left() -= rCell.mnAddLeft;
793 : 2 : aRect.Right() += rCell.mnAddRight;
794 : 2 : aRect.Top() -= rCell.mnAddTop;
795 : 2 : aRect.Bottom() += rCell.mnAddBottom;
796 : : }
797 : 151063 : return aRect;
798 : : }
799 : :
800 : : // diagonal frame borders -----------------------------------------------------
801 : :
802 : 0 : double Array::GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
803 : : {
804 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetHorDiagAngle" );
805 : 0 : return mxImpl->GetHorDiagAngle( nCol, nRow, bSimple );
806 : : }
807 : :
808 : 0 : double Array::GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
809 : : {
810 : : DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetVerDiagAngle" );
811 : 0 : return mxImpl->GetVerDiagAngle( nCol, nRow, bSimple );
812 : : }
813 : :
814 : 5170 : void Array::SetUseDiagDoubleClipping( bool bSet )
815 : : {
816 : 5170 : mxImpl->mbDiagDblClip = bSet;
817 : 5170 : }
818 : :
819 : : // mirroring ------------------------------------------------------------------
820 : :
821 : 4 : void Array::MirrorSelfX( bool bMirrorStyles, bool bSwapDiag )
822 : : {
823 [ + - ]: 4 : CellVec aNewCells;
824 [ + - ][ + - ]: 4 : aNewCells.reserve( GetCellCount() );
825 : :
826 : : size_t nCol, nRow;
827 [ + + ]: 120 : for( nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
828 : : {
829 [ + + ]: 1508 : for( nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
830 : : {
831 [ + - ][ + - ]: 1392 : aNewCells.push_back( CELL( mxImpl->GetMirrorCol( nCol ), nRow ) );
832 [ + - ][ + - ]: 1392 : aNewCells.back().MirrorSelfX( bMirrorStyles, bSwapDiag );
833 : : }
834 : : }
835 [ + + ]: 120 : for( nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
836 : : {
837 [ + + ]: 1508 : for( nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
838 : : {
839 [ + - ][ - + ]: 1392 : if( CELL( nCol, nRow ).mbMergeOrig )
840 : : {
841 [ # # ]: 0 : size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
842 [ # # ]: 0 : size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
843 : 0 : lclSetMergedRange( aNewCells, mxImpl->mnWidth,
844 : : mxImpl->GetMirrorCol( nLastCol ), nRow,
845 [ # # ]: 0 : mxImpl->GetMirrorCol( nCol ), nLastRow );
846 : : }
847 : : }
848 : : }
849 : 4 : mxImpl->maCells.swap( aNewCells );
850 : :
851 [ + - ]: 4 : std::reverse( mxImpl->maWidths.begin(), mxImpl->maWidths.end() );
852 : 4 : mxImpl->mbXCoordsDirty = true;
853 : 4 : }
854 : :
855 : : // drawing --------------------------------------------------------------------
856 : :
857 : 1345 : void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
858 : : size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
859 : : const Color* pForceColor ) const
860 : : {
861 : : DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "DrawRange" );
862 : : DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "DrawRange" );
863 : :
864 : : size_t nCol, nRow;
865 : :
866 : : // *** diagonal frame borders ***
867 [ + + ]: 17212 : for( nRow = nFirstRow; nRow <= nLastRow; ++nRow )
868 : : {
869 [ + + ]: 166964 : for( nCol = nFirstCol; nCol <= nLastCol; ++nCol )
870 : : {
871 : 151097 : const Cell& rCell = CELL( nCol, nRow );
872 : 151097 : bool bOverlapX = rCell.mbOverlapX;
873 : 151097 : bool bOverlapY = rCell.mbOverlapY;
874 : 151097 : bool bFirstCol = nCol == nFirstCol;
875 : 151097 : bool bFirstRow = nRow == nFirstRow;
876 [ + + ][ + + ]: 151097 : if( (!bOverlapX && !bOverlapY) || (bFirstCol && bFirstRow) ||
[ + - ][ + + ]
[ + - ][ + + ]
[ - + ][ + + ]
877 : 68 : (!bOverlapY && bFirstCol) || (!bOverlapX && bFirstRow) )
878 : : {
879 [ + - ]: 151063 : Rectangle aRect( GetCellRect( nCol, nRow ) );
880 [ + - ][ + - ]: 151063 : if( (aRect.GetWidth() > 1) && (aRect.GetHeight() > 1) )
[ + - ][ + - ]
[ + - ]
881 : : {
882 [ + - ]: 151063 : size_t _nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
883 [ + - ]: 151063 : size_t _nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
884 : :
885 [ + - ]: 151063 : const Style aTlbrStyle = GetCellStyleTLBR( _nFirstCol, _nFirstRow, true );
886 [ - + ]: 151063 : if ( aTlbrStyle.GetWidth( ) )
887 : : pProcessor->process( CreateClippedBorderPrimitives(
888 : : aRect.TopLeft(), aRect.BottomRight(),
889 [ # # ][ # # ]: 0 : aTlbrStyle, aRect ) );
[ # # ][ # # ]
890 : :
891 [ + - ]: 151063 : const Style aBltrStyle = GetCellStyleBLTR( _nFirstCol, _nFirstRow, true );
892 [ - + ]: 151063 : if ( aBltrStyle.GetWidth( ) )
893 : : pProcessor->process( CreateClippedBorderPrimitives(
894 : : aRect.BottomLeft(), aRect.TopRight(),
895 [ # # ][ # # ]: 151063 : aBltrStyle, aRect ) );
[ # # ][ # # ]
[ # # ]
896 : : }
897 : : }
898 : : }
899 : : }
900 : :
901 : : // *** horizontal frame borders ***
902 : :
903 [ + + ]: 18557 : for( nRow = nFirstRow; nRow <= nLastRow + 1; ++nRow )
904 : : {
905 [ + - ]: 17212 : double fAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow );
906 [ + - ]: 17212 : double fTAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow - 1 );
907 : :
908 : : // *Start*** variables store the data of the left end of the cached frame border
909 [ + - ][ + - ]: 17212 : Point aStartPos( mxImpl->GetColPosition( nFirstCol ), mxImpl->GetRowPosition( nRow ) );
910 [ + - ]: 17212 : const Style* pStart = &GetCellStyleTop( nFirstCol, nRow );
911 [ + - ]: 17212 : DiagStyle aStartLFromTR( GetCellStyleBL( nFirstCol, nRow - 1 ), fTAngle );
912 [ + - ]: 17212 : const Style* pStartLFromT = &GetCellStyleLeft( nFirstCol, nRow - 1 );
913 [ + - ]: 17212 : const Style* pStartLFromL = &GetCellStyleTop( nFirstCol - 1, nRow );
914 [ + - ]: 17212 : const Style* pStartLFromB = &GetCellStyleLeft( nFirstCol, nRow );
915 [ + - ]: 17212 : DiagStyle aStartLFromBR( GetCellStyleTL( nFirstCol, nRow ), fAngle );
916 : :
917 : : // *End*** variables store the data of the right end of the cached frame border
918 [ + - ]: 17212 : DiagStyle aEndRFromTL( GetCellStyleBR( nFirstCol, nRow - 1 ), fTAngle );
919 [ + - ]: 17212 : const Style* pEndRFromT = &GetCellStyleRight( nFirstCol, nRow - 1 );
920 [ + - ]: 17212 : const Style* pEndRFromR = &GetCellStyleTop( nFirstCol + 1, nRow );
921 [ + - ]: 17212 : const Style* pEndRFromB = &GetCellStyleRight( nFirstCol, nRow );
922 [ + - ]: 17212 : DiagStyle aEndRFromBL( GetCellStyleTR( nFirstCol, nRow ), fAngle );
923 : :
924 [ + + ]: 162894 : for( nCol = nFirstCol + 1; nCol <= nLastCol; ++nCol )
925 : : {
926 [ + - ]: 145682 : fAngle = mxImpl->GetHorDiagAngle( nCol, nRow );
927 [ + - ]: 145682 : fTAngle = mxImpl->GetHorDiagAngle( nCol, nRow - 1 );
928 : :
929 : 145682 : const Style& rCurr = *pEndRFromR;
930 : :
931 [ + - ]: 145682 : DiagStyle aLFromTR( GetCellStyleBL( nCol, nRow - 1 ), fTAngle );
932 : 145682 : const Style& rLFromT = *pEndRFromT;
933 : 145682 : const Style& rLFromL = *pStart;
934 : 145682 : const Style& rLFromB = *pEndRFromB;
935 [ + - ]: 145682 : DiagStyle aLFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
936 : :
937 [ + - ]: 145682 : DiagStyle aRFromTL( GetCellStyleBR( nCol, nRow - 1 ), fTAngle );
938 [ + - ]: 145682 : const Style& rRFromT = GetCellStyleRight( nCol, nRow - 1 );
939 [ + - ]: 145682 : const Style& rRFromR = GetCellStyleTop( nCol + 1, nRow );
940 [ + - ]: 145682 : const Style& rRFromB = GetCellStyleRight( nCol, nRow );
941 [ + - ]: 145682 : DiagStyle aRFromBL( GetCellStyleTR( nCol, nRow ), fAngle );
942 : :
943 : : // check if current frame border can be connected to cached frame border
944 [ + + ]: 145682 : if( !CheckFrameBorderConnectable( *pStart, rCurr,
945 [ + - ]: 145682 : aEndRFromTL, rLFromT, aLFromTR, aEndRFromBL, rLFromB, aLFromBR ) )
946 : : {
947 : : // draw previous frame border
948 [ + - ]: 280 : Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
949 [ + - ][ + + ]: 280 : if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
[ + + ]
950 : : pProcessor->process( CreateBorderPrimitives( aStartPos, aEndPos, *pStart,
951 : : aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
952 [ + - ][ + - ]: 197 : aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor ) );
[ + - ]
953 : :
954 : : // re-init "*Start***" variables
955 : 280 : aStartPos = aEndPos;
956 : 280 : pStart = &rCurr;
957 : 280 : aStartLFromTR = aLFromTR;
958 : 280 : pStartLFromT = &rLFromT;
959 : 280 : pStartLFromL = &rLFromL;
960 : 280 : pStartLFromB = &rLFromB;
961 : 280 : aStartLFromBR = aLFromBR;
962 : : }
963 : :
964 : : // store current styles in "*End***" variables
965 : 145682 : aEndRFromTL = aRFromTL;
966 : 145682 : pEndRFromT = &rRFromT;
967 : 145682 : pEndRFromR = &rRFromR;
968 : 145682 : pEndRFromB = &rRFromB;
969 : 145682 : aEndRFromBL = aRFromBL;
970 : : }
971 : :
972 : : // draw last frame border
973 [ + - ]: 17212 : Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
974 [ + - ][ + + ]: 17212 : if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
[ + + ]
975 : : pProcessor->process( CreateBorderPrimitives( aStartPos, aEndPos, *pStart,
976 : : aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
977 [ + - ][ + - ]: 3 : aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor ) );
[ + - ]
978 : : }
979 : :
980 : : // *** vertical frame borders ***
981 [ + + ]: 14487 : for( nCol = nFirstCol; nCol <= nLastCol + 1; ++nCol )
982 : : {
983 [ + - ]: 13142 : double fAngle = mxImpl->GetVerDiagAngle( nCol, nFirstRow );
984 [ + - ]: 13142 : double fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nFirstRow );
985 : :
986 : : // *Start*** variables store the data of the top end of the cached frame border
987 [ + - ][ + - ]: 13142 : Point aStartPos( mxImpl->GetColPosition( nCol ), mxImpl->GetRowPosition( nFirstRow ) );
988 [ + - ]: 13142 : const Style* pStart = &GetCellStyleLeft( nCol, nFirstRow );
989 [ + - ]: 13142 : DiagStyle aStartTFromBL( GetCellStyleTR( nCol - 1, nFirstRow ), fLAngle );
990 [ + - ]: 13142 : const Style* pStartTFromL = &GetCellStyleTop( nCol - 1, nFirstRow );
991 [ + - ]: 13142 : const Style* pStartTFromT = &GetCellStyleLeft( nCol, nFirstRow - 1 );
992 [ + - ]: 13142 : const Style* pStartTFromR = &GetCellStyleTop( nCol, nFirstRow );
993 [ + - ]: 13142 : DiagStyle aStartTFromBR( GetCellStyleTL( nCol, nFirstRow ), fAngle );
994 : :
995 : : // *End*** variables store the data of the bottom end of the cached frame border
996 [ + - ]: 13142 : DiagStyle aEndBFromTL( GetCellStyleBR( nCol - 1, nFirstRow ), fLAngle );
997 [ + - ]: 13142 : const Style* pEndBFromL = &GetCellStyleBottom( nCol - 1, nFirstRow );
998 [ + - ]: 13142 : const Style* pEndBFromB = &GetCellStyleLeft( nCol, nFirstRow + 1 );
999 [ + - ]: 13142 : const Style* pEndBFromR = &GetCellStyleBottom( nCol, nFirstRow );
1000 [ + - ]: 13142 : DiagStyle aEndBFromTR( GetCellStyleBL( nCol, nFirstRow ), fAngle );
1001 : :
1002 [ + + ]: 166964 : for( nRow = nFirstRow + 1; nRow <= nLastRow; ++nRow )
1003 : : {
1004 [ + - ]: 153822 : fAngle = mxImpl->GetVerDiagAngle( nCol, nRow );
1005 [ + - ]: 153822 : fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nRow );
1006 : :
1007 : 153822 : const Style& rCurr = *pEndBFromB;
1008 : :
1009 [ + - ]: 153822 : DiagStyle aTFromBL( GetCellStyleTR( nCol - 1, nRow ), fLAngle );
1010 : 153822 : const Style& rTFromL = *pEndBFromL;
1011 : 153822 : const Style& rTFromT = *pStart;
1012 : 153822 : const Style& rTFromR = *pEndBFromR;
1013 [ + - ]: 153822 : DiagStyle aTFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
1014 : :
1015 [ + - ]: 153822 : DiagStyle aBFromTL( GetCellStyleBR( nCol - 1, nRow ), fLAngle );
1016 [ + - ]: 153822 : const Style& rBFromL = GetCellStyleBottom( nCol - 1, nRow );
1017 [ + - ]: 153822 : const Style& rBFromB = GetCellStyleLeft( nCol, nRow + 1 );
1018 [ + - ]: 153822 : const Style& rBFromR = GetCellStyleBottom( nCol, nRow );
1019 [ + - ]: 153822 : DiagStyle aBFromTR( GetCellStyleBL( nCol, nRow ), fAngle );
1020 : :
1021 : : // check if current frame border can be connected to cached frame border
1022 [ + + ]: 153822 : if( !CheckFrameBorderConnectable( *pStart, rCurr,
1023 [ + - ]: 153822 : aEndBFromTL, rTFromL, aTFromBL, aEndBFromTR, rTFromR, aTFromBR ) )
1024 : : {
1025 : : // draw previous frame border
1026 [ + - ]: 362 : Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
1027 [ + - ][ + + ]: 362 : if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
[ + + ]
1028 : : pProcessor->process( CreateBorderPrimitives( aEndPos, aStartPos, *pStart,
1029 : : aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
1030 [ + - ][ + - ]: 181 : aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor ) );
[ + - ]
1031 : :
1032 : : // re-init "*Start***" variables
1033 : 362 : aStartPos = aEndPos;
1034 : 362 : pStart = &rCurr;
1035 : 362 : aStartTFromBL = aTFromBL;
1036 : 362 : pStartTFromL = &rTFromL;
1037 : 362 : pStartTFromT = &rTFromT;
1038 : 362 : pStartTFromR = &rTFromR;
1039 : 362 : aStartTFromBR = aTFromBR;
1040 : : }
1041 : :
1042 : : // store current styles in "*End***" variables
1043 : 153822 : aEndBFromTL = aBFromTL;
1044 : 153822 : pEndBFromL = &rBFromL;
1045 : 153822 : pEndBFromB = &rBFromB;
1046 : 153822 : pEndBFromR = &rBFromR;
1047 : 153822 : aEndBFromTR = aBFromTR;
1048 : : }
1049 : :
1050 : : // draw last frame border
1051 [ + - ]: 13142 : Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
1052 [ # # ][ - + ]: 13142 : if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
[ - + ]
1053 : : pProcessor->process( CreateBorderPrimitives( aEndPos, aStartPos, *pStart,
1054 : : aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
1055 [ # # ][ # # ]: 0 : aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor ) );
[ # # ]
1056 : : }
1057 : 1345 : }
1058 : :
1059 : 0 : void Array::DrawRange( OutputDevice& rDev,
1060 : : size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
1061 : : const Color* pForceColor ) const
1062 : : {
1063 : : DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "DrawRange" );
1064 : : DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "DrawRange" );
1065 : :
1066 : : size_t nCol, nRow;
1067 : :
1068 : : // *** diagonal frame borders ***
1069 : :
1070 : : // set clipping region to clip partly visible merged cells
1071 : 0 : rDev.Push( PUSH_CLIPREGION );
1072 [ # # ]: 0 : rDev.IntersectClipRegion( GetClipRangeRectangle() );
1073 [ # # ]: 0 : for( nRow = nFirstRow; nRow <= nLastRow; ++nRow )
1074 : : {
1075 [ # # ]: 0 : for( nCol = nFirstCol; nCol <= nLastCol; ++nCol )
1076 : : {
1077 : 0 : const Cell& rCell = CELL( nCol, nRow );
1078 : 0 : bool bOverlapX = rCell.mbOverlapX;
1079 : 0 : bool bOverlapY = rCell.mbOverlapY;
1080 : 0 : bool bFirstCol = nCol == nFirstCol;
1081 : 0 : bool bFirstRow = nRow == nFirstRow;
1082 [ # # ][ # # ]: 0 : if( (!bOverlapX && !bOverlapY) || (bFirstCol && bFirstRow) ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1083 : 0 : (!bOverlapY && bFirstCol) || (!bOverlapX && bFirstRow) )
1084 : : {
1085 [ # # ]: 0 : Rectangle aRect( GetCellRect( nCol, nRow ) );
1086 [ # # ][ # # ]: 0 : if( (aRect.GetWidth() > 1) && (aRect.GetHeight() > 1) )
[ # # ][ # # ]
[ # # ]
1087 : : {
1088 [ # # ]: 0 : size_t _nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
1089 [ # # ]: 0 : size_t _nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
1090 [ # # ]: 0 : size_t _nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
1091 [ # # ]: 0 : size_t _nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
1092 : :
1093 : : DrawDiagFrameBorders( rDev, aRect,
1094 [ # # ][ # # ]: 0 : GetCellStyleTLBR( _nFirstCol, _nFirstRow, true ), GetCellStyleBLTR( _nFirstCol, _nFirstRow, true ),
1095 [ # # ][ # # ]: 0 : GetCellStyleLeft( _nFirstCol, _nFirstRow ), GetCellStyleTop( _nFirstCol, _nFirstRow ),
1096 [ # # ][ # # ]: 0 : GetCellStyleRight( _nLastCol, _nLastRow ), GetCellStyleBottom( _nLastCol, _nLastRow ),
1097 [ # # ][ # # ]: 0 : GetCellStyleLeft( _nFirstCol, _nLastRow ), GetCellStyleBottom( _nFirstCol, _nLastRow ),
1098 [ # # ][ # # ]: 0 : GetCellStyleRight( _nLastCol, _nFirstRow ), GetCellStyleTop( _nLastCol, _nFirstRow ),
1099 [ # # ]: 0 : pForceColor, mxImpl->mbDiagDblClip );
1100 : : }
1101 : : }
1102 : : }
1103 : : }
1104 : 0 : rDev.Pop(); // clip region
1105 : :
1106 : : // *** horizontal frame borders ***
1107 : :
1108 [ # # ]: 0 : for( nRow = nFirstRow; nRow <= nLastRow + 1; ++nRow )
1109 : : {
1110 [ # # ]: 0 : double fAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow );
1111 [ # # ]: 0 : double fTAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow - 1 );
1112 : :
1113 : : // *Start*** variables store the data of the left end of the cached frame border
1114 [ # # ][ # # ]: 0 : Point aStartPos( mxImpl->GetColPosition( nFirstCol ), mxImpl->GetRowPosition( nRow ) );
1115 [ # # ]: 0 : const Style* pStart = &GetCellStyleTop( nFirstCol, nRow );
1116 [ # # ]: 0 : DiagStyle aStartLFromTR( GetCellStyleBL( nFirstCol, nRow - 1 ), fTAngle );
1117 [ # # ]: 0 : const Style* pStartLFromT = &GetCellStyleLeft( nFirstCol, nRow - 1 );
1118 [ # # ]: 0 : const Style* pStartLFromL = &GetCellStyleTop( nFirstCol - 1, nRow );
1119 [ # # ]: 0 : const Style* pStartLFromB = &GetCellStyleLeft( nFirstCol, nRow );
1120 [ # # ]: 0 : DiagStyle aStartLFromBR( GetCellStyleTL( nFirstCol, nRow ), fAngle );
1121 : :
1122 : : // *End*** variables store the data of the right end of the cached frame border
1123 [ # # ]: 0 : DiagStyle aEndRFromTL( GetCellStyleBR( nFirstCol, nRow - 1 ), fTAngle );
1124 [ # # ]: 0 : const Style* pEndRFromT = &GetCellStyleRight( nFirstCol, nRow - 1 );
1125 [ # # ]: 0 : const Style* pEndRFromR = &GetCellStyleTop( nFirstCol + 1, nRow );
1126 [ # # ]: 0 : const Style* pEndRFromB = &GetCellStyleRight( nFirstCol, nRow );
1127 [ # # ]: 0 : DiagStyle aEndRFromBL( GetCellStyleTR( nFirstCol, nRow ), fAngle );
1128 : :
1129 [ # # ]: 0 : for( nCol = nFirstCol + 1; nCol <= nLastCol; ++nCol )
1130 : : {
1131 [ # # ]: 0 : fAngle = mxImpl->GetHorDiagAngle( nCol, nRow );
1132 [ # # ]: 0 : fTAngle = mxImpl->GetHorDiagAngle( nCol, nRow - 1 );
1133 : :
1134 : 0 : const Style& rCurr = *pEndRFromR;
1135 : :
1136 [ # # ]: 0 : DiagStyle aLFromTR( GetCellStyleBL( nCol, nRow - 1 ), fTAngle );
1137 : 0 : const Style& rLFromT = *pEndRFromT;
1138 : 0 : const Style& rLFromL = *pStart;
1139 : 0 : const Style& rLFromB = *pEndRFromB;
1140 [ # # ]: 0 : DiagStyle aLFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
1141 : :
1142 [ # # ]: 0 : DiagStyle aRFromTL( GetCellStyleBR( nCol, nRow - 1 ), fTAngle );
1143 [ # # ]: 0 : const Style& rRFromT = GetCellStyleRight( nCol, nRow - 1 );
1144 [ # # ]: 0 : const Style& rRFromR = GetCellStyleTop( nCol + 1, nRow );
1145 [ # # ]: 0 : const Style& rRFromB = GetCellStyleRight( nCol, nRow );
1146 [ # # ]: 0 : DiagStyle aRFromBL( GetCellStyleTR( nCol, nRow ), fAngle );
1147 : :
1148 : : // check if current frame border can be connected to cached frame border
1149 [ # # ]: 0 : if( !CheckFrameBorderConnectable( *pStart, rCurr,
1150 [ # # ]: 0 : aEndRFromTL, rLFromT, aLFromTR, aEndRFromBL, rLFromB, aLFromBR ) )
1151 : : {
1152 : : // draw previous frame border
1153 [ # # ]: 0 : Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
1154 [ # # ][ # # ]: 0 : if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
[ # # ]
1155 : : DrawHorFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1156 : : aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
1157 [ # # ]: 0 : aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor );
1158 : :
1159 : : // re-init "*Start***" variables
1160 : 0 : aStartPos = aEndPos;
1161 : 0 : pStart = &rCurr;
1162 : 0 : aStartLFromTR = aLFromTR;
1163 : 0 : pStartLFromT = &rLFromT;
1164 : 0 : pStartLFromL = &rLFromL;
1165 : 0 : pStartLFromB = &rLFromB;
1166 : 0 : aStartLFromBR = aLFromBR;
1167 : : }
1168 : :
1169 : : // store current styles in "*End***" variables
1170 : 0 : aEndRFromTL = aRFromTL;
1171 : 0 : pEndRFromT = &rRFromT;
1172 : 0 : pEndRFromR = &rRFromR;
1173 : 0 : pEndRFromB = &rRFromB;
1174 : 0 : aEndRFromBL = aRFromBL;
1175 : : }
1176 : :
1177 : : // draw last frame border
1178 [ # # ]: 0 : Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
1179 [ # # ][ # # ]: 0 : if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
[ # # ]
1180 : : DrawHorFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1181 : : aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
1182 [ # # ]: 0 : aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor );
1183 : : }
1184 : :
1185 : : // *** vertical frame borders ***
1186 : :
1187 [ # # ]: 0 : for( nCol = nFirstCol; nCol <= nLastCol + 1; ++nCol )
1188 : : {
1189 [ # # ]: 0 : double fAngle = mxImpl->GetVerDiagAngle( nCol, nFirstRow );
1190 [ # # ]: 0 : double fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nFirstRow );
1191 : :
1192 : : // *Start*** variables store the data of the top end of the cached frame border
1193 [ # # ][ # # ]: 0 : Point aStartPos( mxImpl->GetColPosition( nCol ), mxImpl->GetRowPosition( nFirstRow ) );
1194 [ # # ]: 0 : const Style* pStart = &GetCellStyleLeft( nCol, nFirstRow );
1195 [ # # ]: 0 : DiagStyle aStartTFromBL( GetCellStyleTR( nCol - 1, nFirstRow ), fLAngle );
1196 [ # # ]: 0 : const Style* pStartTFromL = &GetCellStyleTop( nCol - 1, nFirstRow );
1197 [ # # ]: 0 : const Style* pStartTFromT = &GetCellStyleLeft( nCol, nFirstRow - 1 );
1198 [ # # ]: 0 : const Style* pStartTFromR = &GetCellStyleTop( nCol, nFirstRow );
1199 [ # # ]: 0 : DiagStyle aStartTFromBR( GetCellStyleTL( nCol, nFirstRow ), fAngle );
1200 : :
1201 : : // *End*** variables store the data of the bottom end of the cached frame border
1202 [ # # ]: 0 : DiagStyle aEndBFromTL( GetCellStyleBR( nCol - 1, nFirstRow ), fLAngle );
1203 [ # # ]: 0 : const Style* pEndBFromL = &GetCellStyleBottom( nCol - 1, nFirstRow );
1204 [ # # ]: 0 : const Style* pEndBFromB = &GetCellStyleLeft( nCol, nFirstRow + 1 );
1205 [ # # ]: 0 : const Style* pEndBFromR = &GetCellStyleBottom( nCol, nFirstRow );
1206 [ # # ]: 0 : DiagStyle aEndBFromTR( GetCellStyleBL( nCol, nFirstRow ), fAngle );
1207 : :
1208 [ # # ]: 0 : for( nRow = nFirstRow + 1; nRow <= nLastRow; ++nRow )
1209 : : {
1210 [ # # ]: 0 : fAngle = mxImpl->GetVerDiagAngle( nCol, nRow );
1211 [ # # ]: 0 : fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nRow );
1212 : :
1213 : 0 : const Style& rCurr = *pEndBFromB;
1214 : :
1215 [ # # ]: 0 : DiagStyle aTFromBL( GetCellStyleTR( nCol - 1, nRow ), fLAngle );
1216 : 0 : const Style& rTFromL = *pEndBFromL;
1217 : 0 : const Style& rTFromT = *pStart;
1218 : 0 : const Style& rTFromR = *pEndBFromR;
1219 [ # # ]: 0 : DiagStyle aTFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
1220 : :
1221 [ # # ]: 0 : DiagStyle aBFromTL( GetCellStyleBR( nCol - 1, nRow ), fLAngle );
1222 [ # # ]: 0 : const Style& rBFromL = GetCellStyleBottom( nCol - 1, nRow );
1223 [ # # ]: 0 : const Style& rBFromB = GetCellStyleLeft( nCol, nRow + 1 );
1224 [ # # ]: 0 : const Style& rBFromR = GetCellStyleBottom( nCol, nRow );
1225 [ # # ]: 0 : DiagStyle aBFromTR( GetCellStyleBL( nCol, nRow ), fAngle );
1226 : :
1227 : : // check if current frame border can be connected to cached frame border
1228 [ # # ]: 0 : if( !CheckFrameBorderConnectable( *pStart, rCurr,
1229 [ # # ]: 0 : aEndBFromTL, rTFromL, aTFromBL, aEndBFromTR, rTFromR, aTFromBR ) )
1230 : : {
1231 : : // draw previous frame border
1232 [ # # ]: 0 : Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
1233 [ # # ][ # # ]: 0 : if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
[ # # ]
1234 : : DrawVerFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1235 : : aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR,
1236 [ # # ]: 0 : aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR, pForceColor );
1237 : :
1238 : : // re-init "*Start***" variables
1239 : 0 : aStartPos = aEndPos;
1240 : 0 : pStart = &rCurr;
1241 : 0 : aStartTFromBL = aTFromBL;
1242 : 0 : pStartTFromL = &rTFromL;
1243 : 0 : pStartTFromT = &rTFromT;
1244 : 0 : pStartTFromR = &rTFromR;
1245 : 0 : aStartTFromBR = aTFromBR;
1246 : : }
1247 : :
1248 : : // store current styles in "*End***" variables
1249 : 0 : aEndBFromTL = aBFromTL;
1250 : 0 : pEndBFromL = &rBFromL;
1251 : 0 : pEndBFromB = &rBFromB;
1252 : 0 : pEndBFromR = &rBFromR;
1253 : 0 : aEndBFromTR = aBFromTR;
1254 : : }
1255 : :
1256 : : // draw last frame border
1257 [ # # ]: 0 : Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
1258 [ # # ][ # # ]: 0 : if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
[ # # ]
1259 : : DrawVerFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1260 : : aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR,
1261 [ # # ]: 0 : aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR, pForceColor );
1262 : : }
1263 : 0 : }
1264 : :
1265 : 0 : void Array::DrawArray( OutputDevice& rDev, const Color* pForceColor ) const
1266 : : {
1267 [ # # ][ # # ]: 0 : if( mxImpl->mnWidth && mxImpl->mnHeight )
[ # # ]
1268 : 0 : DrawRange( rDev, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1, pForceColor );
1269 : 0 : }
1270 : :
1271 : : // ----------------------------------------------------------------------------
1272 : :
1273 : : #undef ORIGCELL
1274 : : #undef CELLACC
1275 : : #undef CELL
1276 : :
1277 : : // ----------------------------------------------------------------------------
1278 : :
1279 : : #undef DBG_FRAME_CHECK_ROW_1
1280 : : #undef DBG_FRAME_CHECK_COL_1
1281 : : #undef DBG_FRAME_CHECK_INDEX
1282 : : #undef DBG_FRAME_CHECK_COLROW
1283 : : #undef DBG_FRAME_CHECK_ROW
1284 : : #undef DBG_FRAME_CHECK_COL
1285 : : #undef DBG_FRAME_CHECK
1286 : :
1287 : : // ============================================================================
1288 : :
1289 : : } // namespace frame
1290 [ + - ][ + - ]: 417 : } // namespace svx
1291 : :
1292 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|