1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: framelinkarray.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/framelinkarray.hxx>
38 #include <vcl/outdev.hxx>
43 // ============================================================================
57 void Cell::MirrorSelfX( bool bMirrorStyles
, bool bSwapDiag
)
59 std::swap( maLeft
, maRight
);
60 std::swap( mnAddLeft
, mnAddRight
);
68 std::swap( maTLBR
, maBLTR
);
77 void Cell::MirrorSelfY( bool bMirrorStyles
, bool bSwapDiag
)
79 std::swap( maTop
, maBottom
);
80 std::swap( mnAddTop
, mnAddBottom
);
84 maBottom
.MirrorSelf();
87 std::swap( maTLBR
, maBLTR
);
88 /* Do not mirror diagonal styles, because they are oriented vertical.
89 Therefore swapping the styles is sufficient for correct behaviour. */
92 // ----------------------------------------------------------------------------
95 void lclRecalcCoordVec( LongVec
& rCoords
, const LongVec
& rSizes
)
97 DBG_ASSERT( rCoords
.size() == rSizes
.size() + 1, "lclRecalcCoordVec - inconsistent vectors" );
98 LongVec::iterator aCIt
= rCoords
.begin();
99 LongVec::const_iterator aSIt
= rSizes
.begin(), aSEnd
= rSizes
.end();
100 for( ; aSIt
!= aSEnd
; ++aCIt
, ++aSIt
)
101 *(aCIt
+ 1) = *aCIt
+ *aSIt
;
104 void lclSetMergedRange( CellVec
& rCells
, size_t nWidth
, size_t nFirstCol
, size_t nFirstRow
, size_t nLastCol
, size_t nLastRow
)
106 for( size_t nCol
= nFirstCol
; nCol
<= nLastCol
; ++nCol
)
108 for( size_t nRow
= nFirstRow
; nRow
<= nLastRow
; ++nRow
)
110 Cell
& rCell
= rCells
[ nRow
* nWidth
+ nCol
];
111 rCell
.mbMergeOrig
= false;
112 rCell
.mbOverlapX
= nCol
> nFirstCol
;
113 rCell
.mbOverlapY
= nRow
> nFirstRow
;
116 rCells
[ nFirstRow
* nWidth
+ nFirstCol
].mbMergeOrig
= true;
119 // ----------------------------------------------------------------------------
121 static const Style OBJ_STYLE_NONE
;
122 static const Cell OBJ_CELL_NONE
;
124 const bool DIAG_DBL_CLIP_DEFAULT
= false;
126 // ============================================================================
128 ArrayImpl::ArrayImpl( size_t nWidth
, size_t nHeight
, bool bDiagDblClip
) :
133 mnLastClipCol( nWidth
- 1 ),
134 mnLastClipRow( nHeight
- 1 ),
135 mbXCoordsDirty( false ),
136 mbYCoordsDirty( false ),
137 mbDiagDblClip( bDiagDblClip
)
139 // default-construct all vectors
140 maCells
.resize( mnWidth
* mnHeight
);
141 maWidths
.resize( mnWidth
, 0L );
142 maHeights
.resize( mnHeight
, 0L );
143 maXCoords
.resize( mnWidth
+ 1, 0L );
144 maYCoords
.resize( mnHeight
+ 1, 0L );
147 const Cell
& ArrayImpl::GetCell( size_t nCol
, size_t nRow
) const
149 return IsValidPos( nCol
, nRow
) ? maCells
[ GetIndex( nCol
, nRow
) ] : OBJ_CELL_NONE
;
152 Cell
& ArrayImpl::GetCellAcc( size_t nCol
, size_t nRow
)
155 return IsValidPos( nCol
, nRow
) ? maCells
[ GetIndex( nCol
, nRow
) ] : aDummy
;
158 size_t ArrayImpl::GetMergedFirstCol( size_t nCol
, size_t nRow
) const
160 size_t nFirstCol
= nCol
;
161 while( (nFirstCol
> 0) && GetCell( nFirstCol
, nRow
).mbOverlapX
) --nFirstCol
;
165 size_t ArrayImpl::GetMergedFirstRow( size_t nCol
, size_t nRow
) const
167 size_t nFirstRow
= nRow
;
168 while( (nFirstRow
> 0) && GetCell( nCol
, nFirstRow
).mbOverlapY
) --nFirstRow
;
172 size_t ArrayImpl::GetMergedLastCol( size_t nCol
, size_t nRow
) const
174 size_t nLastCol
= nCol
+ 1;
175 while( (nLastCol
< mnWidth
) && GetCell( nLastCol
, nRow
).mbOverlapX
) ++nLastCol
;
179 size_t ArrayImpl::GetMergedLastRow( size_t nCol
, size_t nRow
) const
181 size_t nLastRow
= nRow
+ 1;
182 while( (nLastRow
< mnHeight
) && GetCell( nCol
, nLastRow
).mbOverlapY
) ++nLastRow
;
186 const Cell
& ArrayImpl::GetMergedOriginCell( size_t nCol
, size_t nRow
) const
188 return GetCell( GetMergedFirstCol( nCol
, nRow
), GetMergedFirstRow( nCol
, nRow
) );
191 Cell
& ArrayImpl::GetMergedOriginCellAcc( size_t nCol
, size_t nRow
)
193 return GetCellAcc( GetMergedFirstCol( nCol
, nRow
), GetMergedFirstRow( nCol
, nRow
) );
196 bool ArrayImpl::IsMergedOverlappedLeft( size_t nCol
, size_t nRow
) const
198 const Cell
& rCell
= GetCell( nCol
, nRow
);
199 return rCell
.mbOverlapX
|| (rCell
.mnAddLeft
> 0);
202 bool ArrayImpl::IsMergedOverlappedRight( size_t nCol
, size_t nRow
) const
204 return GetCell( nCol
+ 1, nRow
).mbOverlapX
|| (GetCell( nCol
, nRow
).mnAddRight
> 0);
207 bool ArrayImpl::IsMergedOverlappedTop( size_t nCol
, size_t nRow
) const
209 const Cell
& rCell
= GetCell( nCol
, nRow
);
210 return rCell
.mbOverlapY
|| (rCell
.mnAddTop
> 0);
213 bool ArrayImpl::IsMergedOverlappedBottom( size_t nCol
, size_t nRow
) const
215 return GetCell( nCol
, nRow
+ 1 ).mbOverlapY
|| (GetCell( nCol
, nRow
).mnAddBottom
> 0);
218 bool ArrayImpl::IsColInClipRange( size_t nCol
) const
220 return (mnFirstClipCol
<= nCol
) && (nCol
<= mnLastClipCol
);
223 bool ArrayImpl::IsRowInClipRange( size_t nRow
) const
225 return (mnFirstClipRow
<= nRow
) && (nRow
<= mnLastClipRow
);
228 bool ArrayImpl::IsInClipRange( size_t nCol
, size_t nRow
) const
230 return IsColInClipRange( nCol
) && IsRowInClipRange( nRow
);
233 long ArrayImpl::GetColPosition( size_t nCol
) const
237 lclRecalcCoordVec( maXCoords
, maWidths
);
238 mbXCoordsDirty
= false;
240 return maXCoords
[ nCol
];
243 long ArrayImpl::GetRowPosition( size_t nRow
) const
247 lclRecalcCoordVec( maYCoords
, maHeights
);
248 mbYCoordsDirty
= false;
250 return maYCoords
[ nRow
];
253 long ArrayImpl::GetColWidth( size_t nFirstCol
, size_t nLastCol
) const
255 return GetColPosition( nLastCol
+ 1 ) - GetColPosition( nFirstCol
);
258 long ArrayImpl::GetRowHeight( size_t nFirstRow
, size_t nLastRow
) const
260 return GetRowPosition( nLastRow
+ 1 ) - GetRowPosition( nFirstRow
);
263 double ArrayImpl::GetHorDiagAngle( size_t nCol
, size_t nRow
, bool bSimple
) const
266 if( IsValidPos( nCol
, nRow
) )
268 if( bSimple
|| !GetCell( nCol
, nRow
).IsMerged() )
270 fAngle
= frame::GetHorDiagAngle( maWidths
[ nCol
] + 1, maHeights
[ nRow
] + 1 );
274 // return correct angle for each cell in the merged range
275 size_t nFirstCol
= GetMergedFirstCol( nCol
, nRow
);
276 size_t nFirstRow
= GetMergedFirstRow( nCol
, nRow
);
277 const Cell
& rCell
= GetCell( nFirstCol
, nFirstRow
);
278 long nWidth
= GetColWidth( nFirstCol
, GetMergedLastCol( nCol
, nRow
) ) + rCell
.mnAddLeft
+ rCell
.mnAddRight
;
279 long nHeight
= GetRowHeight( nFirstRow
, GetMergedLastRow( nCol
, nRow
) ) + rCell
.mnAddTop
+ rCell
.mnAddBottom
;
280 fAngle
= frame::GetHorDiagAngle( nWidth
+ 1, nHeight
+ 1 );
286 double ArrayImpl::GetVerDiagAngle( size_t nCol
, size_t nRow
, bool bSimple
) const
288 double fAngle
= GetHorDiagAngle( nCol
, nRow
, bSimple
);
289 return (fAngle
> 0.0) ? (F_PI2
- fAngle
) : 0.0;
292 // ============================================================================
294 class MergedCellIterator
297 explicit MergedCellIterator( const Array
& rArray
, size_t nCol
, size_t nRow
);
299 inline bool Is() const { return (mnCol
<= mnLastCol
) && (mnRow
<= mnLastRow
); }
300 inline size_t Col() const { return mnCol
; }
301 inline size_t Row() const { return mnRow
; }
303 MergedCellIterator
& operator++();
314 // ----------------------------------------------------------------------------
316 MergedCellIterator::MergedCellIterator( const Array
& rArray
, size_t nCol
, size_t nRow
)
318 DBG_ASSERT( rArray
.IsMerged( nCol
, nRow
), "svx::frame::MergedCellIterator::MergedCellIterator - not in merged range" );
319 rArray
.GetMergedRange( mnFirstCol
, mnFirstRow
, mnLastCol
, mnLastRow
, nCol
, nRow
);
324 MergedCellIterator
& MergedCellIterator::operator++()
326 DBG_ASSERT( Is(), "svx::frame::MergedCellIterator::operator++() - already invalid" );
327 if( ++mnCol
> mnLastCol
)
335 // ============================================================================
337 #define DBG_FRAME_ERROR( funcname, error ) DBG_ERRORFILE( "svx::frame::Array::" funcname " - " error )
338 #define DBG_FRAME_CHECK( cond, funcname, error ) DBG_ASSERT( cond, "svx::frame::Array::" funcname " - " error )
339 #define DBG_FRAME_CHECK_COL( col, funcname ) DBG_FRAME_CHECK( (col) < GetColCount(), funcname, "invalid column index" )
340 #define DBG_FRAME_CHECK_ROW( row, funcname ) DBG_FRAME_CHECK( (row) < GetRowCount(), funcname, "invalid row index" )
341 #define DBG_FRAME_CHECK_COLROW( col, row, funcname ) DBG_FRAME_CHECK( ((col) < GetColCount()) && ((row) < GetRowCount()), funcname, "invalid cell index" )
342 #define DBG_FRAME_CHECK_INDEX( index, funcname ) DBG_FRAME_CHECK( (index) < GetCellCount(), funcname, "invalid cell index" )
343 #define DBG_FRAME_CHECK_COL_1( col, funcname ) DBG_FRAME_CHECK( (col) <= GetColCount(), funcname, "invalid column index" )
344 #define DBG_FRAME_CHECK_ROW_1( row, funcname ) DBG_FRAME_CHECK( (row) <= GetRowCount(), funcname, "invalid row index" )
346 // ----------------------------------------------------------------------------
348 #define CELL( col, row ) mxImpl->GetCell( col, row )
349 #define CELLACC( col, row ) mxImpl->GetCellAcc( col, row )
350 #define ORIGCELL( col, row ) mxImpl->GetMergedOriginCell( col, row )
351 #define ORIGCELLACC( col, row ) mxImpl->GetMergedOriginCellAcc( col, row )
353 // ----------------------------------------------------------------------------
360 Array::Array( size_t nWidth
, size_t nHeight
)
362 Initialize( nWidth
, nHeight
);
369 // array size and column/row indexes ------------------------------------------
371 void Array::Initialize( size_t nWidth
, size_t nHeight
)
373 bool bDiagDblClip
= mxImpl
.get() ? mxImpl
->mbDiagDblClip
: DIAG_DBL_CLIP_DEFAULT
;
374 mxImpl
.reset( new ArrayImpl( nWidth
, nHeight
, bDiagDblClip
) );
379 Initialize( mxImpl
->mnWidth
, mxImpl
->mnHeight
);
382 size_t Array::GetColCount() const
384 return mxImpl
->mnWidth
;
387 size_t Array::GetRowCount() const
389 return mxImpl
->mnHeight
;
392 size_t Array::GetCellCount() const
394 return mxImpl
->maCells
.size();
397 size_t Array::GetColFromIndex( size_t nCellIndex
) const
399 DBG_FRAME_CHECK_INDEX( nCellIndex
, "GetColFromIndex" );
400 return mxImpl
->mnWidth
? (nCellIndex
% mxImpl
->mnWidth
) : 0;
403 size_t Array::GetRowFromIndex( size_t nCellIndex
) const
405 DBG_FRAME_CHECK_INDEX( nCellIndex
, "GetRowFromIndex" );
406 return mxImpl
->mnWidth
? (nCellIndex
/ mxImpl
->mnWidth
) : 0;
409 size_t Array::GetCellIndex( size_t nCol
, size_t nRow
, bool bRTL
) const
411 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "GetCellIndex" );
413 nCol
= mxImpl
->GetMirrorCol(nCol
);
414 return mxImpl
->GetIndex( nCol
, nRow
);
417 // cell border styles ---------------------------------------------------------
419 void Array::SetCellStyleLeft( size_t nCol
, size_t nRow
, const Style
& rStyle
)
421 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetCellStyleLeft" );
422 CELLACC( nCol
, nRow
).maLeft
= rStyle
;
425 void Array::SetCellStyleRight( size_t nCol
, size_t nRow
, const Style
& rStyle
)
427 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetCellStyleRight" );
428 CELLACC( nCol
, nRow
).maRight
= rStyle
;
431 void Array::SetCellStyleTop( size_t nCol
, size_t nRow
, const Style
& rStyle
)
433 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetCellStyleTop" );
434 CELLACC( nCol
, nRow
).maTop
= rStyle
;
437 void Array::SetCellStyleBottom( size_t nCol
, size_t nRow
, const Style
& rStyle
)
439 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetCellStyleBottom" );
440 CELLACC( nCol
, nRow
).maBottom
= rStyle
;
443 void Array::SetCellStyleTLBR( size_t nCol
, size_t nRow
, const Style
& rStyle
)
445 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetCellStyleTLBR" );
446 CELLACC( nCol
, nRow
).maTLBR
= rStyle
;
449 void Array::SetCellStyleBLTR( size_t nCol
, size_t nRow
, const Style
& rStyle
)
451 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetCellStyleBLTR" );
452 CELLACC( nCol
, nRow
).maBLTR
= rStyle
;
455 void Array::SetCellStyleDiag( size_t nCol
, size_t nRow
, const Style
& rTLBR
, const Style
& rBLTR
)
457 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetCellStyleDiag" );
458 Cell
& rCell
= CELLACC( nCol
, nRow
);
459 rCell
.maTLBR
= rTLBR
;
460 rCell
.maBLTR
= rBLTR
;
463 void Array::SetColumnStyleLeft( size_t nCol
, const Style
& rStyle
)
465 DBG_FRAME_CHECK_COL( nCol
, "SetColumnStyleLeft" );
466 for( size_t nRow
= 0; nRow
< mxImpl
->mnHeight
; ++nRow
)
467 SetCellStyleLeft( nCol
, nRow
, rStyle
);
470 void Array::SetColumnStyleRight( size_t nCol
, const Style
& rStyle
)
472 DBG_FRAME_CHECK_COL( nCol
, "SetColumnStyleRight" );
473 for( size_t nRow
= 0; nRow
< mxImpl
->mnHeight
; ++nRow
)
474 SetCellStyleRight( nCol
, nRow
, rStyle
);
477 void Array::SetRowStyleTop( size_t nRow
, const Style
& rStyle
)
479 DBG_FRAME_CHECK_ROW( nRow
, "SetRowStyleTop" );
480 for( size_t nCol
= 0; nCol
< mxImpl
->mnWidth
; ++nCol
)
481 SetCellStyleTop( nCol
, nRow
, rStyle
);
484 void Array::SetRowStyleBottom( size_t nRow
, const Style
& rStyle
)
486 DBG_FRAME_CHECK_ROW( nRow
, "SetRowStyleBottom" );
487 for( size_t nCol
= 0; nCol
< mxImpl
->mnWidth
; ++nCol
)
488 SetCellStyleBottom( nCol
, nRow
, rStyle
);
491 const Style
& Array::GetCellStyleLeft( size_t nCol
, size_t nRow
, bool bSimple
) const
493 // simple: always return own left style
495 return CELL( nCol
, nRow
).maLeft
;
496 // outside clipping rows or overlapped in merged cells: invisible
497 if( !mxImpl
->IsRowInClipRange( nRow
) || mxImpl
->IsMergedOverlappedLeft( nCol
, nRow
) )
498 return OBJ_STYLE_NONE
;
499 // left clipping border: always own left style
500 if( nCol
== mxImpl
->mnFirstClipCol
)
501 return ORIGCELL( nCol
, nRow
).maLeft
;
502 // right clipping border: always right style of left neighbor cell
503 if( nCol
== mxImpl
->mnLastClipCol
+ 1 )
504 return ORIGCELL( nCol
- 1, nRow
).maRight
;
505 // outside clipping columns: invisible
506 if( !mxImpl
->IsColInClipRange( nCol
) )
507 return OBJ_STYLE_NONE
;
508 // inside clipping range: maximum of own left style and right style of left neighbor cell
509 return std::max( ORIGCELL( nCol
, nRow
).maLeft
, ORIGCELL( nCol
- 1, nRow
).maRight
);
512 const Style
& Array::GetCellStyleRight( size_t nCol
, size_t nRow
, bool bSimple
) const
514 // simple: always return own right style
516 return CELL( nCol
, nRow
).maRight
;
517 // outside clipping rows or overlapped in merged cells: invisible
518 if( !mxImpl
->IsRowInClipRange( nRow
) || mxImpl
->IsMergedOverlappedRight( nCol
, nRow
) )
519 return OBJ_STYLE_NONE
;
520 // left clipping border: always left style of right neighbor cell
521 if( nCol
+ 1 == mxImpl
->mnFirstClipCol
)
522 return ORIGCELL( nCol
+ 1, nRow
).maLeft
;
523 // right clipping border: always own right style
524 if( nCol
== mxImpl
->mnLastClipCol
)
525 return ORIGCELL( nCol
, nRow
).maRight
;
526 // outside clipping columns: invisible
527 if( !mxImpl
->IsColInClipRange( nCol
) )
528 return OBJ_STYLE_NONE
;
529 // inside clipping range: maximum of own right style and left style of right neighbor cell
530 return std::max( ORIGCELL( nCol
, nRow
).maRight
, ORIGCELL( nCol
+ 1, nRow
).maLeft
);
533 const Style
& Array::GetCellStyleTop( size_t nCol
, size_t nRow
, bool bSimple
) const
535 // simple: always return own top style
537 return CELL( nCol
, nRow
).maTop
;
538 // outside clipping columns or overlapped in merged cells: invisible
539 if( !mxImpl
->IsColInClipRange( nCol
) || mxImpl
->IsMergedOverlappedTop( nCol
, nRow
) )
540 return OBJ_STYLE_NONE
;
541 // top clipping border: always own top style
542 if( nRow
== mxImpl
->mnFirstClipRow
)
543 return ORIGCELL( nCol
, nRow
).maTop
;
544 // bottom clipping border: always bottom style of top neighbor cell
545 if( nRow
== mxImpl
->mnLastClipRow
+ 1 )
546 return ORIGCELL( nCol
, nRow
- 1 ).maBottom
;
547 // outside clipping rows: invisible
548 if( !mxImpl
->IsRowInClipRange( nRow
) )
549 return OBJ_STYLE_NONE
;
550 // inside clipping range: maximum of own top style and bottom style of top neighbor cell
551 return std::max( ORIGCELL( nCol
, nRow
).maTop
, ORIGCELL( nCol
, nRow
- 1 ).maBottom
);
554 const Style
& Array::GetCellStyleBottom( size_t nCol
, size_t nRow
, bool bSimple
) const
556 // simple: always return own bottom style
558 return CELL( nCol
, nRow
).maBottom
;
559 // outside clipping columns or overlapped in merged cells: invisible
560 if( !mxImpl
->IsColInClipRange( nCol
) || mxImpl
->IsMergedOverlappedBottom( nCol
, nRow
) )
561 return OBJ_STYLE_NONE
;
562 // top clipping border: always top style of bottom neighbor cell
563 if( nRow
+ 1 == mxImpl
->mnFirstClipRow
)
564 return ORIGCELL( nCol
, nRow
+ 1 ).maTop
;
565 // bottom clipping border: always own bottom style
566 if( nRow
== mxImpl
->mnLastClipRow
)
567 return ORIGCELL( nCol
, nRow
).maBottom
;
568 // outside clipping rows: invisible
569 if( !mxImpl
->IsRowInClipRange( nRow
) )
570 return OBJ_STYLE_NONE
;
571 // inside clipping range: maximum of own bottom style and top style of bottom neighbor cell
572 return std::max( ORIGCELL( nCol
, nRow
).maBottom
, ORIGCELL( nCol
, nRow
+ 1 ).maTop
);
575 const Style
& Array::GetCellStyleTLBR( size_t nCol
, size_t nRow
, bool bSimple
) const
577 return bSimple
? CELL( nCol
, nRow
).maTLBR
:
578 (mxImpl
->IsInClipRange( nCol
, nRow
) ? ORIGCELL( nCol
, nRow
).maTLBR
: OBJ_STYLE_NONE
);
581 const Style
& Array::GetCellStyleBLTR( size_t nCol
, size_t nRow
, bool bSimple
) const
583 return bSimple
? CELL( nCol
, nRow
).maBLTR
:
584 (mxImpl
->IsInClipRange( nCol
, nRow
) ? ORIGCELL( nCol
, nRow
).maBLTR
: OBJ_STYLE_NONE
);
587 const Style
& Array::GetCellStyleTL( size_t nCol
, size_t nRow
) const
589 // not in clipping range: always invisible
590 if( !mxImpl
->IsInClipRange( nCol
, nRow
) )
591 return OBJ_STYLE_NONE
;
592 // return style only for top-left cell
593 size_t nFirstCol
= mxImpl
->GetMergedFirstCol( nCol
, nRow
);
594 size_t nFirstRow
= mxImpl
->GetMergedFirstRow( nCol
, nRow
);
595 return ((nCol
== nFirstCol
) && (nRow
== nFirstRow
)) ?
596 CELL( nFirstCol
, nFirstRow
).maTLBR
: OBJ_STYLE_NONE
;
599 const Style
& Array::GetCellStyleBR( size_t nCol
, size_t nRow
) const
601 // not in clipping range: always invisible
602 if( !mxImpl
->IsInClipRange( nCol
, nRow
) )
603 return OBJ_STYLE_NONE
;
604 // return style only for bottom-right cell
605 size_t nLastCol
= mxImpl
->GetMergedLastCol( nCol
, nRow
);
606 size_t nLastRow
= mxImpl
->GetMergedLastRow( nCol
, nRow
);
607 return ((nCol
== nLastCol
) && (nRow
== nLastRow
)) ?
608 CELL( mxImpl
->GetMergedFirstCol( nCol
, nRow
), mxImpl
->GetMergedFirstRow( nCol
, nRow
) ).maTLBR
: OBJ_STYLE_NONE
;
611 const Style
& Array::GetCellStyleBL( size_t nCol
, size_t nRow
) const
613 // not in clipping range: always invisible
614 if( !mxImpl
->IsInClipRange( nCol
, nRow
) )
615 return OBJ_STYLE_NONE
;
616 // return style only for bottom-left cell
617 size_t nFirstCol
= mxImpl
->GetMergedFirstCol( nCol
, nRow
);
618 size_t nLastRow
= mxImpl
->GetMergedLastRow( nCol
, nRow
);
619 return ((nCol
== nFirstCol
) && (nRow
== nLastRow
)) ?
620 CELL( nFirstCol
, mxImpl
->GetMergedFirstRow( nCol
, nRow
) ).maBLTR
: OBJ_STYLE_NONE
;
623 const Style
& Array::GetCellStyleTR( size_t nCol
, size_t nRow
) const
625 // not in clipping range: always invisible
626 if( !mxImpl
->IsInClipRange( nCol
, nRow
) )
627 return OBJ_STYLE_NONE
;
628 // return style only for top-right cell
629 size_t nFirstRow
= mxImpl
->GetMergedFirstRow( nCol
, nRow
);
630 size_t nLastCol
= mxImpl
->GetMergedLastCol( nCol
, nRow
);
631 return ((nCol
== nLastCol
) && (nRow
== nFirstRow
)) ?
632 CELL( mxImpl
->GetMergedFirstCol( nCol
, nRow
), nFirstRow
).maBLTR
: OBJ_STYLE_NONE
;
635 // cell merging ---------------------------------------------------------------
637 void Array::SetMergedRange( size_t nFirstCol
, size_t nFirstRow
, size_t nLastCol
, size_t nLastRow
)
639 DBG_FRAME_CHECK_COLROW( nFirstCol
, nFirstRow
, "SetMergedRange" );
640 DBG_FRAME_CHECK_COLROW( nLastCol
, nLastRow
, "SetMergedRange" );
641 #if OSL_DEBUG_LEVEL >= 2
644 for( size_t nCurrCol
= nFirstCol
; !bFound
&& (nCurrCol
<= nLastCol
); ++nCurrCol
)
645 for( size_t nCurrRow
= nFirstRow
; !bFound
&& (nCurrRow
<= nLastRow
); ++nCurrRow
)
646 bFound
= CELL( nCurrCol
, nCurrRow
).IsMerged();
647 DBG_FRAME_CHECK( !bFound
, "SetMergedRange", "overlapping merged ranges" );
650 if( mxImpl
->IsValidPos( nFirstCol
, nFirstRow
) && mxImpl
->IsValidPos( nLastCol
, nLastRow
) )
651 lclSetMergedRange( mxImpl
->maCells
, mxImpl
->mnWidth
, nFirstCol
, nFirstRow
, nLastCol
, nLastRow
);
654 void Array::RemoveMergedRange( size_t nCol
, size_t nRow
)
656 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "RemoveMergedRange" );
657 for( MergedCellIterator
aIt( *this, nCol
, nRow
); aIt
.Is(); ++aIt
)
659 Cell
& rCell
= CELLACC( aIt
.Col(), aIt
.Row() );
660 rCell
.mbMergeOrig
= rCell
.mbOverlapX
= rCell
.mbOverlapY
= false;
661 rCell
.mnAddLeft
= rCell
.mnAddRight
= rCell
.mnAddTop
= rCell
.mnAddBottom
= 0;
665 void Array::SetAddMergedLeftSize( size_t nCol
, size_t nRow
, long nAddSize
)
667 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetAddMergedLeftSize" );
668 DBG_FRAME_CHECK( mxImpl
->GetMergedFirstCol( nCol
, nRow
) == 0, "SetAddMergedLeftSize", "additional border inside array" );
669 for( MergedCellIterator
aIt( *this, nCol
, nRow
); aIt
.Is(); ++aIt
)
670 CELLACC( aIt
.Col(), aIt
.Row() ).mnAddLeft
= nAddSize
;
673 void Array::SetAddMergedRightSize( size_t nCol
, size_t nRow
, long nAddSize
)
675 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetAddMergedRightSize" );
676 DBG_FRAME_CHECK( mxImpl
->GetMergedLastCol( nCol
, nRow
) + 1 == mxImpl
->mnWidth
, "SetAddMergedRightSize", "additional border inside array" );
677 for( MergedCellIterator
aIt( *this, nCol
, nRow
); aIt
.Is(); ++aIt
)
678 CELLACC( aIt
.Col(), aIt
.Row() ).mnAddRight
= nAddSize
;
681 void Array::SetAddMergedTopSize( size_t nCol
, size_t nRow
, long nAddSize
)
683 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetAddMergedTopSize" );
684 DBG_FRAME_CHECK( mxImpl
->GetMergedFirstRow( nCol
, nRow
) == 0, "SetAddMergedTopSize", "additional border inside array" );
685 for( MergedCellIterator
aIt( *this, nCol
, nRow
); aIt
.Is(); ++aIt
)
686 CELLACC( aIt
.Col(), aIt
.Row() ).mnAddTop
= nAddSize
;
689 void Array::SetAddMergedBottomSize( size_t nCol
, size_t nRow
, long nAddSize
)
691 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "SetAddMergedBottomSize" );
692 DBG_FRAME_CHECK( mxImpl
->GetMergedLastRow( nCol
, nRow
) + 1 == mxImpl
->mnHeight
, "SetAddMergedBottomSize", "additional border inside array" );
693 for( MergedCellIterator
aIt( *this, nCol
, nRow
); aIt
.Is(); ++aIt
)
694 CELLACC( aIt
.Col(), aIt
.Row() ).mnAddBottom
= nAddSize
;
697 bool Array::IsMerged( size_t nCol
, size_t nRow
) const
699 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsMerged" );
700 return CELL( nCol
, nRow
).IsMerged();
703 bool Array::IsMergedOrigin( size_t nCol
, size_t nRow
) const
705 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsMergedOrigin" );
706 return CELL( nCol
, nRow
).mbMergeOrig
;
709 bool Array::IsMergedOverlapped( size_t nCol
, size_t nRow
) const
711 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsMergedOverlapped" );
712 return CELL( nCol
, nRow
).IsOverlapped();
715 bool Array::IsMergedOverlappedLeft( size_t nCol
, size_t nRow
) const
717 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsMergedOverlappedLeft" );
718 return mxImpl
->IsMergedOverlappedLeft( nCol
, nRow
);
721 bool Array::IsMergedOverlappedRight( size_t nCol
, size_t nRow
) const
723 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsMergedOverlappedRight" );
724 return mxImpl
->IsMergedOverlappedRight( nCol
, nRow
);
727 bool Array::IsMergedOverlappedTop( size_t nCol
, size_t nRow
) const
729 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsMergedOverlappedTop" );
730 return mxImpl
->IsMergedOverlappedTop( nCol
, nRow
);
733 bool Array::IsMergedOverlappedBottom( size_t nCol
, size_t nRow
) const
735 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsMergedOverlappedBottom" );
736 return mxImpl
->IsMergedOverlappedBottom( nCol
, nRow
);
739 void Array::GetMergedOrigin( size_t& rnFirstCol
, size_t& rnFirstRow
, size_t nCol
, size_t nRow
) const
741 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "GetMergedOrigin" );
742 rnFirstCol
= mxImpl
->GetMergedFirstCol( nCol
, nRow
);
743 rnFirstRow
= mxImpl
->GetMergedFirstRow( nCol
, nRow
);
746 void Array::GetMergedSize( size_t& rnWidth
, size_t& rnHeight
, size_t nCol
, size_t nRow
) const
748 size_t nFirstCol
, nFirstRow
, nLastCol
, nLastRow
;
749 GetMergedRange( nFirstCol
, nFirstRow
, nLastCol
, nLastRow
, nCol
, nRow
);
750 rnWidth
= nLastCol
- nFirstCol
+ 1;
751 rnHeight
= nLastRow
- nFirstRow
+ 1;
754 void Array::GetMergedRange( size_t& rnFirstCol
, size_t& rnFirstRow
,
755 size_t& rnLastCol
, size_t& rnLastRow
, size_t nCol
, size_t nRow
) const
757 GetMergedOrigin( rnFirstCol
, rnFirstRow
, nCol
, nRow
);
758 rnLastCol
= mxImpl
->GetMergedLastCol( nCol
, nRow
);
759 rnLastRow
= mxImpl
->GetMergedLastRow( nCol
, nRow
);
762 // clipping -------------------------------------------------------------------
764 void Array::SetClipRange( size_t nFirstCol
, size_t nFirstRow
, size_t nLastCol
, size_t nLastRow
)
766 DBG_FRAME_CHECK_COLROW( nFirstCol
, nFirstRow
, "SetClipRange" );
767 DBG_FRAME_CHECK_COLROW( nLastCol
, nLastRow
, "SetClipRange" );
768 mxImpl
->mnFirstClipCol
= nFirstCol
;
769 mxImpl
->mnFirstClipRow
= nFirstRow
;
770 mxImpl
->mnLastClipCol
= nLastCol
;
771 mxImpl
->mnLastClipRow
= nLastRow
;
774 void Array::RemoveClipRange()
776 if( !mxImpl
->maCells
.empty() )
777 SetClipRange( 0, 0, mxImpl
->mnWidth
- 1, mxImpl
->mnHeight
- 1 );
780 bool Array::IsInClipRange( size_t nCol
, size_t nRow
) const
782 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "IsInClipRange" );
783 return mxImpl
->IsInClipRange( nCol
, nRow
);
786 Rectangle
Array::GetClipRangeRectangle() const
789 mxImpl
->GetColPosition( mxImpl
->mnFirstClipCol
),
790 mxImpl
->GetRowPosition( mxImpl
->mnFirstClipRow
),
791 mxImpl
->GetColPosition( mxImpl
->mnLastClipCol
+ 1 ),
792 mxImpl
->GetRowPosition( mxImpl
->mnLastClipRow
+ 1 ) );
795 // cell coordinates -----------------------------------------------------------
797 void Array::SetXOffset( long nXOffset
)
799 mxImpl
->maXCoords
[ 0 ] = nXOffset
;
800 mxImpl
->mbXCoordsDirty
= true;
803 void Array::SetYOffset( long nYOffset
)
805 mxImpl
->maYCoords
[ 0 ] = nYOffset
;
806 mxImpl
->mbYCoordsDirty
= true;
809 void Array::SetColWidth( size_t nCol
, long nWidth
)
811 DBG_FRAME_CHECK_COL( nCol
, "SetColWidth" );
812 mxImpl
->maWidths
[ nCol
] = nWidth
;
813 mxImpl
->mbXCoordsDirty
= true;
816 void Array::SetRowHeight( size_t nRow
, long nHeight
)
818 DBG_FRAME_CHECK_ROW( nRow
, "SetRowHeight" );
819 mxImpl
->maHeights
[ nRow
] = nHeight
;
820 mxImpl
->mbYCoordsDirty
= true;
823 void Array::SetAllColWidths( long nWidth
)
825 std::fill( mxImpl
->maWidths
.begin(), mxImpl
->maWidths
.end(), nWidth
);
826 mxImpl
->mbXCoordsDirty
= true;
829 void Array::SetAllRowHeights( long nHeight
)
831 std::fill( mxImpl
->maHeights
.begin(), mxImpl
->maHeights
.end(), nHeight
);
832 mxImpl
->mbYCoordsDirty
= true;
835 long Array::GetColPosition( size_t nCol
) const
837 DBG_FRAME_CHECK_COL_1( nCol
, "GetColPosition" );
838 return mxImpl
->GetColPosition( nCol
);
841 long Array::GetRowPosition( size_t nRow
) const
843 DBG_FRAME_CHECK_ROW_1( nRow
, "GetRowPosition" );
844 return mxImpl
->GetRowPosition( nRow
);
847 long Array::GetColWidth( size_t nCol
) const
849 DBG_FRAME_CHECK_COL( nCol
, "GetColWidth" );
850 return mxImpl
->maWidths
[ nCol
];
853 long Array::GetColWidth( size_t nFirstCol
, size_t nLastCol
) const
855 DBG_FRAME_CHECK_COL( nFirstCol
, "GetColWidth" );
856 DBG_FRAME_CHECK_COL( nLastCol
, "GetColWidth" );
857 return GetColPosition( nLastCol
+ 1 ) - GetColPosition( nFirstCol
);
860 long Array::GetRowHeight( size_t nRow
) const
862 DBG_FRAME_CHECK_ROW( nRow
, "GetRowHeight" );
863 return mxImpl
->maHeights
[ nRow
];
866 long Array::GetRowHeight( size_t nFirstRow
, size_t nLastRow
) const
868 DBG_FRAME_CHECK_ROW( nFirstRow
, "GetRowHeight" );
869 DBG_FRAME_CHECK_ROW( nLastRow
, "GetRowHeight" );
870 return GetRowPosition( nLastRow
+ 1 ) - GetRowPosition( nFirstRow
);
873 long Array::GetWidth() const
875 return GetColPosition( mxImpl
->mnWidth
) - GetColPosition( 0 );
878 long Array::GetHeight() const
880 return GetRowPosition( mxImpl
->mnHeight
) - GetRowPosition( 0 );
883 Point
Array::GetCellPosition( size_t nCol
, size_t nRow
, bool bSimple
) const
885 size_t nFirstCol
= bSimple
? nCol
: mxImpl
->GetMergedFirstCol( nCol
, nRow
);
886 size_t nFirstRow
= bSimple
? nRow
: mxImpl
->GetMergedFirstRow( nCol
, nRow
);
887 return Point( GetColPosition( nFirstCol
), GetRowPosition( nFirstRow
) );
890 Size
Array::GetCellSize( size_t nCol
, size_t nRow
, bool bSimple
) const
892 size_t nFirstCol
= bSimple
? nCol
: mxImpl
->GetMergedFirstCol( nCol
, nRow
);
893 size_t nFirstRow
= bSimple
? nRow
: mxImpl
->GetMergedFirstRow( nCol
, nRow
);
894 size_t nLastCol
= bSimple
? nCol
: mxImpl
->GetMergedLastCol( nCol
, nRow
);
895 size_t nLastRow
= bSimple
? nRow
: mxImpl
->GetMergedLastRow( nCol
, nRow
);
896 return Size( GetColWidth( nFirstCol
, nLastCol
) + 1, GetRowHeight( nFirstRow
, nLastRow
) + 1 );
899 Rectangle
Array::GetCellRect( size_t nCol
, size_t nRow
, bool bSimple
) const
901 Rectangle
aRect( GetCellPosition( nCol
, nRow
, bSimple
), GetCellSize( nCol
, nRow
, bSimple
) );
903 // adjust rectangle for partly visible merged cells
904 const Cell
& rCell
= CELL( nCol
, nRow
);
905 if( !bSimple
&& rCell
.IsMerged() )
907 aRect
.Left() -= rCell
.mnAddLeft
;
908 aRect
.Right() += rCell
.mnAddRight
;
909 aRect
.Top() -= rCell
.mnAddTop
;
910 aRect
.Bottom() += rCell
.mnAddBottom
;
915 // diagonal frame borders -----------------------------------------------------
917 double Array::GetHorDiagAngle( size_t nCol
, size_t nRow
, bool bSimple
) const
919 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "GetHorDiagAngle" );
920 return mxImpl
->GetHorDiagAngle( nCol
, nRow
, bSimple
);
923 double Array::GetVerDiagAngle( size_t nCol
, size_t nRow
, bool bSimple
) const
925 DBG_FRAME_CHECK_COLROW( nCol
, nRow
, "GetVerDiagAngle" );
926 return mxImpl
->GetVerDiagAngle( nCol
, nRow
, bSimple
);
929 void Array::SetUseDiagDoubleClipping( bool bSet
)
931 mxImpl
->mbDiagDblClip
= bSet
;
934 bool Array::GetUseDiagDoubleClipping() const
936 return mxImpl
->mbDiagDblClip
;
939 // mirroring ------------------------------------------------------------------
941 void Array::MirrorSelfX( bool bMirrorStyles
, bool bSwapDiag
)
944 aNewCells
.reserve( GetCellCount() );
947 for( nRow
= 0; nRow
< mxImpl
->mnHeight
; ++nRow
)
949 for( nCol
= 0; nCol
< mxImpl
->mnWidth
; ++nCol
)
951 aNewCells
.push_back( CELL( mxImpl
->GetMirrorCol( nCol
), nRow
) );
952 aNewCells
.back().MirrorSelfX( bMirrorStyles
, bSwapDiag
);
955 for( nRow
= 0; nRow
< mxImpl
->mnHeight
; ++nRow
)
957 for( nCol
= 0; nCol
< mxImpl
->mnWidth
; ++nCol
)
959 if( CELL( nCol
, nRow
).mbMergeOrig
)
961 size_t nLastCol
= mxImpl
->GetMergedLastCol( nCol
, nRow
);
962 size_t nLastRow
= mxImpl
->GetMergedLastRow( nCol
, nRow
);
963 lclSetMergedRange( aNewCells
, mxImpl
->mnWidth
,
964 mxImpl
->GetMirrorCol( nLastCol
), nRow
,
965 mxImpl
->GetMirrorCol( nCol
), nLastRow
);
969 mxImpl
->maCells
.swap( aNewCells
);
971 std::reverse( mxImpl
->maWidths
.begin(), mxImpl
->maWidths
.end() );
972 mxImpl
->mbXCoordsDirty
= true;
975 void Array::MirrorSelfY( bool bMirrorStyles
, bool bSwapDiag
)
978 aNewCells
.reserve( GetCellCount() );
981 for( nRow
= 0; nRow
< mxImpl
->mnHeight
; ++nRow
)
983 for( nCol
= 0; nCol
< mxImpl
->mnWidth
; ++nCol
)
985 aNewCells
.push_back( CELL( nCol
, mxImpl
->GetMirrorRow( nRow
) ) );
986 aNewCells
.back().MirrorSelfY( bMirrorStyles
, bSwapDiag
);
989 for( nRow
= 0; nRow
< mxImpl
->mnHeight
; ++nRow
)
991 for( nCol
= 0; nCol
< mxImpl
->mnWidth
; ++nCol
)
993 if( CELL( nCol
, nRow
).mbMergeOrig
)
995 size_t nLastCol
= mxImpl
->GetMergedLastCol( nCol
, nRow
);
996 size_t nLastRow
= mxImpl
->GetMergedLastRow( nCol
, nRow
);
997 lclSetMergedRange( aNewCells
, mxImpl
->mnWidth
,
998 nCol
, mxImpl
->GetMirrorRow( nLastRow
),
999 nLastCol
, mxImpl
->GetMirrorRow( nRow
) );
1003 mxImpl
->maCells
.swap( aNewCells
);
1005 std::reverse( mxImpl
->maHeights
.begin(), mxImpl
->maHeights
.end() );
1006 mxImpl
->mbYCoordsDirty
= true;
1009 // drawing --------------------------------------------------------------------
1011 void Array::DrawCell( OutputDevice
& rDev
, size_t nCol
, size_t nRow
, const Color
* pForceColor
) const
1013 DrawRange( rDev
, nCol
, nRow
, nCol
, nRow
, pForceColor
);
1016 void Array::DrawRange( OutputDevice
& rDev
,
1017 size_t nFirstCol
, size_t nFirstRow
, size_t nLastCol
, size_t nLastRow
,
1018 const Color
* pForceColor
) const
1020 DBG_FRAME_CHECK_COLROW( nFirstCol
, nFirstRow
, "DrawRange" );
1021 DBG_FRAME_CHECK_COLROW( nLastCol
, nLastRow
, "DrawRange" );
1025 // *** diagonal frame borders ***
1027 // set clipping region to clip partly visible merged cells
1028 rDev
.Push( PUSH_CLIPREGION
);
1029 rDev
.IntersectClipRegion( GetClipRangeRectangle() );
1030 for( nRow
= nFirstRow
; nRow
<= nLastRow
; ++nRow
)
1032 for( nCol
= nFirstCol
; nCol
<= nLastCol
; ++nCol
)
1034 const Cell
& rCell
= CELL( nCol
, nRow
);
1035 bool bOverlapX
= rCell
.mbOverlapX
;
1036 bool bOverlapY
= rCell
.mbOverlapY
;
1037 bool bFirstCol
= nCol
== nFirstCol
;
1038 bool bFirstRow
= nRow
== nFirstRow
;
1039 if( (!bOverlapX
&& !bOverlapY
) || (bFirstCol
&& bFirstRow
) ||
1040 (!bOverlapY
&& bFirstCol
) || (!bOverlapX
&& bFirstRow
) )
1042 Rectangle
aRect( GetCellRect( nCol
, nRow
) );
1043 if( (aRect
.GetWidth() > 1) && (aRect
.GetHeight() > 1) )
1045 size_t _nFirstCol
= mxImpl
->GetMergedFirstCol( nCol
, nRow
);
1046 size_t _nFirstRow
= mxImpl
->GetMergedFirstRow( nCol
, nRow
);
1047 size_t _nLastCol
= mxImpl
->GetMergedLastCol( nCol
, nRow
);
1048 size_t _nLastRow
= mxImpl
->GetMergedLastRow( nCol
, nRow
);
1050 DrawDiagFrameBorders( rDev
, aRect
,
1051 GetCellStyleTLBR( _nFirstCol
, _nFirstRow
, true ), GetCellStyleBLTR( _nFirstCol
, _nFirstRow
, true ),
1052 GetCellStyleLeft( _nFirstCol
, _nFirstRow
), GetCellStyleTop( _nFirstCol
, _nFirstRow
),
1053 GetCellStyleRight( _nLastCol
, _nLastRow
), GetCellStyleBottom( _nLastCol
, _nLastRow
),
1054 GetCellStyleLeft( _nFirstCol
, _nLastRow
), GetCellStyleBottom( _nFirstCol
, _nLastRow
),
1055 GetCellStyleRight( _nLastCol
, _nFirstRow
), GetCellStyleTop( _nLastCol
, _nFirstRow
),
1056 pForceColor
, mxImpl
->mbDiagDblClip
);
1061 rDev
.Pop(); // clip region
1063 // *** horizontal frame borders ***
1065 for( nRow
= nFirstRow
; nRow
<= nLastRow
+ 1; ++nRow
)
1067 double fAngle
= mxImpl
->GetHorDiagAngle( nFirstCol
, nRow
);
1068 double fTAngle
= mxImpl
->GetHorDiagAngle( nFirstCol
, nRow
- 1 );
1070 // *Start*** variables store the data of the left end of the cached frame border
1071 Point
aStartPos( mxImpl
->GetColPosition( nFirstCol
), mxImpl
->GetRowPosition( nRow
) );
1072 const Style
* pStart
= &GetCellStyleTop( nFirstCol
, nRow
);
1073 DiagStyle
aStartLFromTR( GetCellStyleBL( nFirstCol
, nRow
- 1 ), fTAngle
);
1074 const Style
* pStartLFromT
= &GetCellStyleLeft( nFirstCol
, nRow
- 1 );
1075 const Style
* pStartLFromL
= &GetCellStyleTop( nFirstCol
- 1, nRow
);
1076 const Style
* pStartLFromB
= &GetCellStyleLeft( nFirstCol
, nRow
);
1077 DiagStyle
aStartLFromBR( GetCellStyleTL( nFirstCol
, nRow
), fAngle
);
1079 // *End*** variables store the data of the right end of the cached frame border
1080 DiagStyle
aEndRFromTL( GetCellStyleBR( nFirstCol
, nRow
- 1 ), fTAngle
);
1081 const Style
* pEndRFromT
= &GetCellStyleRight( nFirstCol
, nRow
- 1 );
1082 const Style
* pEndRFromR
= &GetCellStyleTop( nFirstCol
+ 1, nRow
);
1083 const Style
* pEndRFromB
= &GetCellStyleRight( nFirstCol
, nRow
);
1084 DiagStyle
aEndRFromBL( GetCellStyleTR( nFirstCol
, nRow
), fAngle
);
1086 for( nCol
= nFirstCol
+ 1; nCol
<= nLastCol
; ++nCol
)
1088 fAngle
= mxImpl
->GetHorDiagAngle( nCol
, nRow
);
1089 fTAngle
= mxImpl
->GetHorDiagAngle( nCol
, nRow
- 1 );
1091 const Style
& rCurr
= *pEndRFromR
;
1093 DiagStyle
aLFromTR( GetCellStyleBL( nCol
, nRow
- 1 ), fTAngle
);
1094 const Style
& rLFromT
= *pEndRFromT
;
1095 const Style
& rLFromL
= *pStart
;
1096 const Style
& rLFromB
= *pEndRFromB
;
1097 DiagStyle
aLFromBR( GetCellStyleTL( nCol
, nRow
), fAngle
);
1099 DiagStyle
aRFromTL( GetCellStyleBR( nCol
, nRow
- 1 ), fTAngle
);
1100 const Style
& rRFromT
= GetCellStyleRight( nCol
, nRow
- 1 );
1101 const Style
& rRFromR
= GetCellStyleTop( nCol
+ 1, nRow
);
1102 const Style
& rRFromB
= GetCellStyleRight( nCol
, nRow
);
1103 DiagStyle
aRFromBL( GetCellStyleTR( nCol
, nRow
), fAngle
);
1105 // check if current frame border can be connected to cached frame border
1106 if( !CheckFrameBorderConnectable( *pStart
, rCurr
,
1107 aEndRFromTL
, rLFromT
, aLFromTR
, aEndRFromBL
, rLFromB
, aLFromBR
) )
1109 // draw previous frame border
1110 Point
aEndPos( mxImpl
->GetColPosition( nCol
), aStartPos
.Y() );
1111 if( pStart
->Prim() && (aStartPos
.X() <= aEndPos
.X()) )
1112 DrawHorFrameBorder( rDev
, aStartPos
, aEndPos
, *pStart
,
1113 aStartLFromTR
, *pStartLFromT
, *pStartLFromL
, *pStartLFromB
, aStartLFromBR
,
1114 aEndRFromTL
, *pEndRFromT
, *pEndRFromR
, *pEndRFromB
, aEndRFromBL
, pForceColor
);
1116 // re-init "*Start***" variables
1117 aStartPos
= aEndPos
;
1119 aStartLFromTR
= aLFromTR
;
1120 pStartLFromT
= &rLFromT
;
1121 pStartLFromL
= &rLFromL
;
1122 pStartLFromB
= &rLFromB
;
1123 aStartLFromBR
= aLFromBR
;
1126 // store current styles in "*End***" variables
1127 aEndRFromTL
= aRFromTL
;
1128 pEndRFromT
= &rRFromT
;
1129 pEndRFromR
= &rRFromR
;
1130 pEndRFromB
= &rRFromB
;
1131 aEndRFromBL
= aRFromBL
;
1134 // draw last frame border
1135 Point
aEndPos( mxImpl
->GetColPosition( nCol
), aStartPos
.Y() );
1136 if( pStart
->Prim() && (aStartPos
.X() <= aEndPos
.X()) )
1137 DrawHorFrameBorder( rDev
, aStartPos
, aEndPos
, *pStart
,
1138 aStartLFromTR
, *pStartLFromT
, *pStartLFromL
, *pStartLFromB
, aStartLFromBR
,
1139 aEndRFromTL
, *pEndRFromT
, *pEndRFromR
, *pEndRFromB
, aEndRFromBL
, pForceColor
);
1142 // *** vertical frame borders ***
1144 for( nCol
= nFirstCol
; nCol
<= nLastCol
+ 1; ++nCol
)
1146 double fAngle
= mxImpl
->GetVerDiagAngle( nCol
, nFirstRow
);
1147 double fLAngle
= mxImpl
->GetVerDiagAngle( nCol
- 1, nFirstRow
);
1149 // *Start*** variables store the data of the top end of the cached frame border
1150 Point
aStartPos( mxImpl
->GetColPosition( nCol
), mxImpl
->GetRowPosition( nFirstRow
) );
1151 const Style
* pStart
= &GetCellStyleLeft( nCol
, nFirstRow
);
1152 DiagStyle
aStartTFromBL( GetCellStyleTR( nCol
- 1, nFirstRow
), fLAngle
);
1153 const Style
* pStartTFromL
= &GetCellStyleTop( nCol
- 1, nFirstRow
);
1154 const Style
* pStartTFromT
= &GetCellStyleLeft( nCol
, nFirstRow
- 1 );
1155 const Style
* pStartTFromR
= &GetCellStyleTop( nCol
, nFirstRow
);
1156 DiagStyle
aStartTFromBR( GetCellStyleTL( nCol
, nFirstRow
), fAngle
);
1158 // *End*** variables store the data of the bottom end of the cached frame border
1159 DiagStyle
aEndBFromTL( GetCellStyleBR( nCol
- 1, nFirstRow
), fLAngle
);
1160 const Style
* pEndBFromL
= &GetCellStyleBottom( nCol
- 1, nFirstRow
);
1161 const Style
* pEndBFromB
= &GetCellStyleLeft( nCol
, nFirstRow
+ 1 );
1162 const Style
* pEndBFromR
= &GetCellStyleBottom( nCol
, nFirstRow
);
1163 DiagStyle
aEndBFromTR( GetCellStyleBL( nCol
, nFirstRow
), fAngle
);
1165 for( nRow
= nFirstRow
+ 1; nRow
<= nLastRow
; ++nRow
)
1167 fAngle
= mxImpl
->GetVerDiagAngle( nCol
, nRow
);
1168 fLAngle
= mxImpl
->GetVerDiagAngle( nCol
- 1, nRow
);
1170 const Style
& rCurr
= *pEndBFromB
;
1172 DiagStyle
aTFromBL( GetCellStyleTR( nCol
- 1, nRow
), fLAngle
);
1173 const Style
& rTFromL
= *pEndBFromL
;
1174 const Style
& rTFromT
= *pStart
;
1175 const Style
& rTFromR
= *pEndBFromR
;
1176 DiagStyle
aTFromBR( GetCellStyleTL( nCol
, nRow
), fAngle
);
1178 DiagStyle
aBFromTL( GetCellStyleBR( nCol
- 1, nRow
), fLAngle
);
1179 const Style
& rBFromL
= GetCellStyleBottom( nCol
- 1, nRow
);
1180 const Style
& rBFromB
= GetCellStyleLeft( nCol
, nRow
+ 1 );
1181 const Style
& rBFromR
= GetCellStyleBottom( nCol
, nRow
);
1182 DiagStyle
aBFromTR( GetCellStyleBL( nCol
, nRow
), fAngle
);
1184 // check if current frame border can be connected to cached frame border
1185 if( !CheckFrameBorderConnectable( *pStart
, rCurr
,
1186 aEndBFromTL
, rTFromL
, aTFromBL
, aEndBFromTR
, rTFromR
, aTFromBR
) )
1188 // draw previous frame border
1189 Point
aEndPos( aStartPos
.X(), mxImpl
->GetRowPosition( nRow
) );
1190 if( pStart
->Prim() && (aStartPos
.Y() <= aEndPos
.Y()) )
1191 DrawVerFrameBorder( rDev
, aStartPos
, aEndPos
, *pStart
,
1192 aStartTFromBL
, *pStartTFromL
, *pStartTFromT
, *pStartTFromR
, aStartTFromBR
,
1193 aEndBFromTL
, *pEndBFromL
, *pEndBFromB
, *pEndBFromR
, aEndBFromTR
, pForceColor
);
1195 // re-init "*Start***" variables
1196 aStartPos
= aEndPos
;
1198 aStartTFromBL
= aTFromBL
;
1199 pStartTFromL
= &rTFromL
;
1200 pStartTFromT
= &rTFromT
;
1201 pStartTFromR
= &rTFromR
;
1202 aStartTFromBR
= aTFromBR
;
1205 // store current styles in "*End***" variables
1206 aEndBFromTL
= aBFromTL
;
1207 pEndBFromL
= &rBFromL
;
1208 pEndBFromB
= &rBFromB
;
1209 pEndBFromR
= &rBFromR
;
1210 aEndBFromTR
= aBFromTR
;
1213 // draw last frame border
1214 Point
aEndPos( aStartPos
.X(), mxImpl
->GetRowPosition( nRow
) );
1215 if( pStart
->Prim() && (aStartPos
.Y() <= aEndPos
.Y()) )
1216 DrawVerFrameBorder( rDev
, aStartPos
, aEndPos
, *pStart
,
1217 aStartTFromBL
, *pStartTFromL
, *pStartTFromT
, *pStartTFromR
, aStartTFromBR
,
1218 aEndBFromTL
, *pEndBFromL
, *pEndBFromB
, *pEndBFromR
, aEndBFromTR
, pForceColor
);
1222 void Array::DrawArray( OutputDevice
& rDev
, const Color
* pForceColor
) const
1224 if( mxImpl
->mnWidth
&& mxImpl
->mnHeight
)
1225 DrawRange( rDev
, 0, 0, mxImpl
->mnWidth
- 1, mxImpl
->mnHeight
- 1, pForceColor
);
1228 // ----------------------------------------------------------------------------
1235 // ----------------------------------------------------------------------------
1237 #undef DBG_FRAME_CHECK_ROW_1
1238 #undef DBG_FRAME_CHECK_COL_1
1239 #undef DBG_FRAME_CHECK_INDEX
1240 #undef DBG_FRAME_CHECK_COLROW
1241 #undef DBG_FRAME_CHECK_ROW
1242 #undef DBG_FRAME_CHECK_COL
1243 #undef DBG_FRAME_CHECK
1244 #undef DBG_FRAME_ERROR
1246 // ============================================================================
1248 } // namespace frame