1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include <svx/framelinkarray.hxx>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <math.h>
29cdf0e10cSrcweir #include <vector>
30cdf0e10cSrcweir #include <algorithm>
31cdf0e10cSrcweir #include <vcl/outdev.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace svx {
34cdf0e10cSrcweir namespace frame {
35cdf0e10cSrcweir 
36cdf0e10cSrcweir // ============================================================================
37cdf0e10cSrcweir 
38cdf0e10cSrcweir 
Cell()39cdf0e10cSrcweir Cell::Cell() :
40cdf0e10cSrcweir     mnAddLeft( 0 ),
41cdf0e10cSrcweir     mnAddRight( 0 ),
42cdf0e10cSrcweir     mnAddTop( 0 ),
43cdf0e10cSrcweir     mnAddBottom( 0 ),
44cdf0e10cSrcweir     mbMergeOrig( false ),
45cdf0e10cSrcweir     mbOverlapX( false ),
46cdf0e10cSrcweir     mbOverlapY( false )
47cdf0e10cSrcweir {
48cdf0e10cSrcweir }
49cdf0e10cSrcweir 
MirrorSelfX(bool bMirrorStyles,bool bSwapDiag)50cdf0e10cSrcweir void Cell::MirrorSelfX( bool bMirrorStyles, bool bSwapDiag )
51cdf0e10cSrcweir {
52cdf0e10cSrcweir     std::swap( maLeft, maRight );
53cdf0e10cSrcweir     std::swap( mnAddLeft, mnAddRight );
54cdf0e10cSrcweir     if( bMirrorStyles )
55cdf0e10cSrcweir     {
56cdf0e10cSrcweir         maLeft.MirrorSelf();
57cdf0e10cSrcweir         maRight.MirrorSelf();
58cdf0e10cSrcweir     }
59cdf0e10cSrcweir     if( bSwapDiag )
60cdf0e10cSrcweir     {
61cdf0e10cSrcweir         std::swap( maTLBR, maBLTR );
62cdf0e10cSrcweir         if( bMirrorStyles )
63cdf0e10cSrcweir         {
64cdf0e10cSrcweir             maTLBR.MirrorSelf();
65cdf0e10cSrcweir             maBLTR.MirrorSelf();
66cdf0e10cSrcweir         }
67cdf0e10cSrcweir     }
68cdf0e10cSrcweir }
69cdf0e10cSrcweir 
MirrorSelfY(bool bMirrorStyles,bool bSwapDiag)70cdf0e10cSrcweir void Cell::MirrorSelfY( bool bMirrorStyles, bool bSwapDiag )
71cdf0e10cSrcweir {
72cdf0e10cSrcweir     std::swap( maTop, maBottom );
73cdf0e10cSrcweir     std::swap( mnAddTop, mnAddBottom );
74cdf0e10cSrcweir     if( bMirrorStyles )
75cdf0e10cSrcweir     {
76cdf0e10cSrcweir         maTop.MirrorSelf();
77cdf0e10cSrcweir         maBottom.MirrorSelf();
78cdf0e10cSrcweir     }
79cdf0e10cSrcweir     if( bSwapDiag )
80cdf0e10cSrcweir         std::swap( maTLBR, maBLTR );
81cdf0e10cSrcweir     /*  Do not mirror diagonal styles, because they are oriented vertical.
82cdf0e10cSrcweir         Therefore swapping the styles is sufficient for correct behaviour. */
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir // ----------------------------------------------------------------------------
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 
lclRecalcCoordVec(LongVec & rCoords,const LongVec & rSizes)88cdf0e10cSrcweir void lclRecalcCoordVec( LongVec& rCoords, const LongVec& rSizes )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir     DBG_ASSERT( rCoords.size() == rSizes.size() + 1, "lclRecalcCoordVec - inconsistent vectors" );
91cdf0e10cSrcweir     LongVec::iterator aCIt = rCoords.begin();
92cdf0e10cSrcweir     LongVec::const_iterator aSIt = rSizes.begin(), aSEnd = rSizes.end();
93cdf0e10cSrcweir     for( ; aSIt != aSEnd; ++aCIt, ++aSIt )
94cdf0e10cSrcweir         *(aCIt + 1) = *aCIt + *aSIt;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
lclSetMergedRange(CellVec & rCells,size_t nWidth,size_t nFirstCol,size_t nFirstRow,size_t nLastCol,size_t nLastRow)97cdf0e10cSrcweir void lclSetMergedRange( CellVec& rCells, size_t nWidth, size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow )
98cdf0e10cSrcweir {
99cdf0e10cSrcweir     for( size_t nCol = nFirstCol; nCol <= nLastCol; ++nCol )
100cdf0e10cSrcweir     {
101cdf0e10cSrcweir         for( size_t nRow = nFirstRow; nRow <= nLastRow; ++nRow )
102cdf0e10cSrcweir         {
103cdf0e10cSrcweir             Cell& rCell = rCells[ nRow * nWidth + nCol ];
104cdf0e10cSrcweir             rCell.mbMergeOrig = false;
105cdf0e10cSrcweir             rCell.mbOverlapX = nCol > nFirstCol;
106cdf0e10cSrcweir             rCell.mbOverlapY = nRow > nFirstRow;
107cdf0e10cSrcweir         }
108cdf0e10cSrcweir     }
109cdf0e10cSrcweir     rCells[ nFirstRow * nWidth + nFirstCol ].mbMergeOrig = true;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir // ----------------------------------------------------------------------------
113cdf0e10cSrcweir 
114cdf0e10cSrcweir static const Style OBJ_STYLE_NONE;
115cdf0e10cSrcweir static const Cell OBJ_CELL_NONE;
116cdf0e10cSrcweir 
117cdf0e10cSrcweir const bool DIAG_DBL_CLIP_DEFAULT = false;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir // ============================================================================
120cdf0e10cSrcweir 
ArrayImpl(size_t nWidth,size_t nHeight,bool bDiagDblClip)121cdf0e10cSrcweir ArrayImpl::ArrayImpl( size_t nWidth, size_t nHeight, bool bDiagDblClip ) :
122cdf0e10cSrcweir     mnWidth( nWidth ),
123cdf0e10cSrcweir     mnHeight( nHeight ),
124cdf0e10cSrcweir     mnFirstClipCol( 0 ),
125cdf0e10cSrcweir     mnFirstClipRow( 0 ),
126cdf0e10cSrcweir     mnLastClipCol( nWidth - 1 ),
127cdf0e10cSrcweir     mnLastClipRow( nHeight - 1 ),
128cdf0e10cSrcweir     mbXCoordsDirty( false ),
129cdf0e10cSrcweir     mbYCoordsDirty( false ),
130cdf0e10cSrcweir     mbDiagDblClip( bDiagDblClip )
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     // default-construct all vectors
133cdf0e10cSrcweir     maCells.resize( mnWidth * mnHeight );
134cdf0e10cSrcweir     maWidths.resize( mnWidth, 0L );
135cdf0e10cSrcweir     maHeights.resize( mnHeight, 0L );
136cdf0e10cSrcweir     maXCoords.resize( mnWidth + 1, 0L );
137cdf0e10cSrcweir     maYCoords.resize( mnHeight + 1, 0L );
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
GetCell(size_t nCol,size_t nRow) const140cdf0e10cSrcweir const Cell& ArrayImpl::GetCell( size_t nCol, size_t nRow ) const
141cdf0e10cSrcweir {
142cdf0e10cSrcweir     return IsValidPos( nCol, nRow ) ? maCells[ GetIndex( nCol, nRow ) ] : OBJ_CELL_NONE;
143cdf0e10cSrcweir }
144cdf0e10cSrcweir 
GetCellAcc(size_t nCol,size_t nRow)145cdf0e10cSrcweir Cell& ArrayImpl::GetCellAcc( size_t nCol, size_t nRow )
146cdf0e10cSrcweir {
147cdf0e10cSrcweir     static Cell aDummy;
148cdf0e10cSrcweir     return IsValidPos( nCol, nRow ) ? maCells[ GetIndex( nCol, nRow ) ] : aDummy;
149cdf0e10cSrcweir }
150cdf0e10cSrcweir 
GetMergedFirstCol(size_t nCol,size_t nRow) const151cdf0e10cSrcweir size_t ArrayImpl::GetMergedFirstCol( size_t nCol, size_t nRow ) const
152cdf0e10cSrcweir {
153cdf0e10cSrcweir     size_t nFirstCol = nCol;
154cdf0e10cSrcweir     while( (nFirstCol > 0) && GetCell( nFirstCol, nRow ).mbOverlapX ) --nFirstCol;
155cdf0e10cSrcweir     return nFirstCol;
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
GetMergedFirstRow(size_t nCol,size_t nRow) const158cdf0e10cSrcweir size_t ArrayImpl::GetMergedFirstRow( size_t nCol, size_t nRow ) const
159cdf0e10cSrcweir {
160cdf0e10cSrcweir     size_t nFirstRow = nRow;
161cdf0e10cSrcweir     while( (nFirstRow > 0) && GetCell( nCol, nFirstRow ).mbOverlapY ) --nFirstRow;
162cdf0e10cSrcweir     return nFirstRow;
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
GetMergedLastCol(size_t nCol,size_t nRow) const165cdf0e10cSrcweir size_t ArrayImpl::GetMergedLastCol( size_t nCol, size_t nRow ) const
166cdf0e10cSrcweir {
167cdf0e10cSrcweir     size_t nLastCol = nCol + 1;
168cdf0e10cSrcweir     while( (nLastCol < mnWidth) && GetCell( nLastCol, nRow ).mbOverlapX ) ++nLastCol;
169cdf0e10cSrcweir     return nLastCol - 1;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
GetMergedLastRow(size_t nCol,size_t nRow) const172cdf0e10cSrcweir size_t ArrayImpl::GetMergedLastRow( size_t nCol, size_t nRow ) const
173cdf0e10cSrcweir {
174cdf0e10cSrcweir     size_t nLastRow = nRow + 1;
175cdf0e10cSrcweir     while( (nLastRow < mnHeight) && GetCell( nCol, nLastRow ).mbOverlapY ) ++nLastRow;
176cdf0e10cSrcweir     return nLastRow - 1;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
GetMergedOriginCell(size_t nCol,size_t nRow) const179cdf0e10cSrcweir const Cell& ArrayImpl::GetMergedOriginCell( size_t nCol, size_t nRow ) const
180cdf0e10cSrcweir {
181cdf0e10cSrcweir     return GetCell( GetMergedFirstCol( nCol, nRow ), GetMergedFirstRow( nCol, nRow ) );
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
GetMergedOriginCellAcc(size_t nCol,size_t nRow)184cdf0e10cSrcweir Cell& ArrayImpl::GetMergedOriginCellAcc( size_t nCol, size_t nRow )
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     return GetCellAcc( GetMergedFirstCol( nCol, nRow ), GetMergedFirstRow( nCol, nRow ) );
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
IsMergedOverlappedLeft(size_t nCol,size_t nRow) const189cdf0e10cSrcweir bool ArrayImpl::IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const
190cdf0e10cSrcweir {
191cdf0e10cSrcweir     const Cell& rCell = GetCell( nCol, nRow );
192cdf0e10cSrcweir     return rCell.mbOverlapX || (rCell.mnAddLeft > 0);
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
IsMergedOverlappedRight(size_t nCol,size_t nRow) const195cdf0e10cSrcweir bool ArrayImpl::IsMergedOverlappedRight( size_t nCol, size_t nRow ) const
196cdf0e10cSrcweir {
197cdf0e10cSrcweir     return GetCell( nCol + 1, nRow ).mbOverlapX || (GetCell( nCol, nRow ).mnAddRight > 0);
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
IsMergedOverlappedTop(size_t nCol,size_t nRow) const200cdf0e10cSrcweir bool ArrayImpl::IsMergedOverlappedTop( size_t nCol, size_t nRow ) const
201cdf0e10cSrcweir {
202cdf0e10cSrcweir     const Cell& rCell = GetCell( nCol, nRow );
203cdf0e10cSrcweir     return rCell.mbOverlapY || (rCell.mnAddTop > 0);
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
IsMergedOverlappedBottom(size_t nCol,size_t nRow) const206cdf0e10cSrcweir bool ArrayImpl::IsMergedOverlappedBottom( size_t nCol, size_t nRow ) const
207cdf0e10cSrcweir {
208cdf0e10cSrcweir     return GetCell( nCol, nRow + 1 ).mbOverlapY || (GetCell( nCol, nRow ).mnAddBottom > 0);
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
IsColInClipRange(size_t nCol) const211cdf0e10cSrcweir bool ArrayImpl::IsColInClipRange( size_t nCol ) const
212cdf0e10cSrcweir {
213cdf0e10cSrcweir     return (mnFirstClipCol <= nCol) && (nCol <= mnLastClipCol);
214cdf0e10cSrcweir }
215cdf0e10cSrcweir 
IsRowInClipRange(size_t nRow) const216cdf0e10cSrcweir bool ArrayImpl::IsRowInClipRange( size_t nRow ) const
217cdf0e10cSrcweir {
218cdf0e10cSrcweir     return (mnFirstClipRow <= nRow) && (nRow <= mnLastClipRow);
219cdf0e10cSrcweir }
220cdf0e10cSrcweir 
IsInClipRange(size_t nCol,size_t nRow) const221cdf0e10cSrcweir bool ArrayImpl::IsInClipRange( size_t nCol, size_t nRow ) const
222cdf0e10cSrcweir {
223cdf0e10cSrcweir     return IsColInClipRange( nCol ) && IsRowInClipRange( nRow );
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
GetColPosition(size_t nCol) const226cdf0e10cSrcweir long ArrayImpl::GetColPosition( size_t nCol ) const
227cdf0e10cSrcweir {
228cdf0e10cSrcweir     if( mbXCoordsDirty )
229cdf0e10cSrcweir     {
230cdf0e10cSrcweir         lclRecalcCoordVec( maXCoords, maWidths );
231cdf0e10cSrcweir         mbXCoordsDirty = false;
232cdf0e10cSrcweir     }
233cdf0e10cSrcweir     return maXCoords[ nCol ];
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
GetRowPosition(size_t nRow) const236cdf0e10cSrcweir long ArrayImpl::GetRowPosition( size_t nRow ) const
237cdf0e10cSrcweir {
238cdf0e10cSrcweir     if( mbYCoordsDirty )
239cdf0e10cSrcweir     {
240cdf0e10cSrcweir         lclRecalcCoordVec( maYCoords, maHeights );
241cdf0e10cSrcweir         mbYCoordsDirty = false;
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir     return maYCoords[ nRow ];
244cdf0e10cSrcweir }
245cdf0e10cSrcweir 
GetColWidth(size_t nFirstCol,size_t nLastCol) const246cdf0e10cSrcweir long ArrayImpl::GetColWidth( size_t nFirstCol, size_t nLastCol ) const
247cdf0e10cSrcweir {
248cdf0e10cSrcweir     return GetColPosition( nLastCol + 1 ) - GetColPosition( nFirstCol );
249cdf0e10cSrcweir }
250cdf0e10cSrcweir 
GetRowHeight(size_t nFirstRow,size_t nLastRow) const251cdf0e10cSrcweir long ArrayImpl::GetRowHeight( size_t nFirstRow, size_t nLastRow ) const
252cdf0e10cSrcweir {
253cdf0e10cSrcweir     return GetRowPosition( nLastRow + 1 ) - GetRowPosition( nFirstRow );
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
GetHorDiagAngle(size_t nCol,size_t nRow,bool bSimple) const256cdf0e10cSrcweir double ArrayImpl::GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
257cdf0e10cSrcweir {
258cdf0e10cSrcweir     double fAngle = 0.0;
259cdf0e10cSrcweir     if( IsValidPos( nCol, nRow ) )
260cdf0e10cSrcweir     {
261cdf0e10cSrcweir         if( bSimple || !GetCell( nCol, nRow ).IsMerged() )
262cdf0e10cSrcweir         {
263cdf0e10cSrcweir             fAngle = frame::GetHorDiagAngle( maWidths[ nCol ] + 1, maHeights[ nRow ] + 1 );
264cdf0e10cSrcweir         }
265cdf0e10cSrcweir         else
266cdf0e10cSrcweir         {
267cdf0e10cSrcweir             // return correct angle for each cell in the merged range
268cdf0e10cSrcweir             size_t nFirstCol = GetMergedFirstCol( nCol, nRow );
269cdf0e10cSrcweir             size_t nFirstRow = GetMergedFirstRow( nCol, nRow );
270cdf0e10cSrcweir             const Cell& rCell = GetCell( nFirstCol, nFirstRow );
271cdf0e10cSrcweir             long nWidth = GetColWidth( nFirstCol, GetMergedLastCol( nCol, nRow ) ) + rCell.mnAddLeft + rCell.mnAddRight;
272cdf0e10cSrcweir             long nHeight = GetRowHeight( nFirstRow, GetMergedLastRow( nCol, nRow ) ) + rCell.mnAddTop + rCell.mnAddBottom;
273cdf0e10cSrcweir             fAngle = frame::GetHorDiagAngle( nWidth + 1, nHeight + 1 );
274cdf0e10cSrcweir         }
275cdf0e10cSrcweir     }
276cdf0e10cSrcweir     return fAngle;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
GetVerDiagAngle(size_t nCol,size_t nRow,bool bSimple) const279cdf0e10cSrcweir double ArrayImpl::GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     double fAngle = GetHorDiagAngle( nCol, nRow, bSimple );
282cdf0e10cSrcweir     return (fAngle > 0.0) ? (F_PI2 - fAngle) : 0.0;
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir // ============================================================================
286cdf0e10cSrcweir 
287cdf0e10cSrcweir class MergedCellIterator
288cdf0e10cSrcweir {
289cdf0e10cSrcweir public:
290cdf0e10cSrcweir     explicit            MergedCellIterator( const Array& rArray, size_t nCol, size_t nRow );
291cdf0e10cSrcweir 
Is() const292cdf0e10cSrcweir     inline bool         Is() const { return (mnCol <= mnLastCol) && (mnRow <= mnLastRow); }
Col() const293cdf0e10cSrcweir     inline size_t       Col() const { return mnCol; }
Row() const294cdf0e10cSrcweir     inline size_t       Row() const { return mnRow; }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     MergedCellIterator& operator++();
297cdf0e10cSrcweir 
298cdf0e10cSrcweir private:
299cdf0e10cSrcweir     size_t              mnFirstCol;
300cdf0e10cSrcweir     size_t              mnFirstRow;
301cdf0e10cSrcweir     size_t              mnLastCol;
302cdf0e10cSrcweir     size_t              mnLastRow;
303cdf0e10cSrcweir     size_t              mnCol;
304cdf0e10cSrcweir     size_t              mnRow;
305cdf0e10cSrcweir };
306cdf0e10cSrcweir 
307cdf0e10cSrcweir // ----------------------------------------------------------------------------
308cdf0e10cSrcweir 
MergedCellIterator(const Array & rArray,size_t nCol,size_t nRow)309cdf0e10cSrcweir MergedCellIterator::MergedCellIterator( const Array& rArray, size_t nCol, size_t nRow )
310cdf0e10cSrcweir {
311cdf0e10cSrcweir     DBG_ASSERT( rArray.IsMerged( nCol, nRow ), "svx::frame::MergedCellIterator::MergedCellIterator - not in merged range" );
312cdf0e10cSrcweir     rArray.GetMergedRange( mnFirstCol, mnFirstRow, mnLastCol, mnLastRow, nCol, nRow );
313cdf0e10cSrcweir     mnCol = mnFirstCol;
314cdf0e10cSrcweir     mnRow = mnFirstRow;
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
operator ++()317cdf0e10cSrcweir MergedCellIterator& MergedCellIterator::operator++()
318cdf0e10cSrcweir {
319cdf0e10cSrcweir     DBG_ASSERT( Is(), "svx::frame::MergedCellIterator::operator++() - already invalid" );
320cdf0e10cSrcweir     if( ++mnCol > mnLastCol )
321cdf0e10cSrcweir     {
322cdf0e10cSrcweir         mnCol = mnFirstCol;
323cdf0e10cSrcweir         ++mnRow;
324cdf0e10cSrcweir     }
325cdf0e10cSrcweir     return *this;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir // ============================================================================
329cdf0e10cSrcweir 
330cdf0e10cSrcweir #define DBG_FRAME_ERROR( funcname, error )              DBG_ERRORFILE( "svx::frame::Array::" funcname " - " error )
331cdf0e10cSrcweir #define DBG_FRAME_CHECK( cond, funcname, error )        DBG_ASSERT( cond, "svx::frame::Array::" funcname " - " error )
332cdf0e10cSrcweir #define DBG_FRAME_CHECK_COL( col, funcname )            DBG_FRAME_CHECK( (col) < GetColCount(), funcname, "invalid column index" )
333cdf0e10cSrcweir #define DBG_FRAME_CHECK_ROW( row, funcname )            DBG_FRAME_CHECK( (row) < GetRowCount(), funcname, "invalid row index" )
334cdf0e10cSrcweir #define DBG_FRAME_CHECK_COLROW( col, row, funcname )    DBG_FRAME_CHECK( ((col) < GetColCount()) && ((row) < GetRowCount()), funcname, "invalid cell index" )
335cdf0e10cSrcweir #define DBG_FRAME_CHECK_INDEX( index, funcname )        DBG_FRAME_CHECK( (index) < GetCellCount(), funcname, "invalid cell index" )
336cdf0e10cSrcweir #define DBG_FRAME_CHECK_COL_1( col, funcname )          DBG_FRAME_CHECK( (col) <= GetColCount(), funcname, "invalid column index" )
337cdf0e10cSrcweir #define DBG_FRAME_CHECK_ROW_1( row, funcname )          DBG_FRAME_CHECK( (row) <= GetRowCount(), funcname, "invalid row index" )
338cdf0e10cSrcweir 
339cdf0e10cSrcweir // ----------------------------------------------------------------------------
340cdf0e10cSrcweir 
341cdf0e10cSrcweir #define CELL( col, row )        mxImpl->GetCell( col, row )
342cdf0e10cSrcweir #define CELLACC( col, row )     mxImpl->GetCellAcc( col, row )
343cdf0e10cSrcweir #define ORIGCELL( col, row )    mxImpl->GetMergedOriginCell( col, row )
344cdf0e10cSrcweir #define ORIGCELLACC( col, row ) mxImpl->GetMergedOriginCellAcc( col, row )
345cdf0e10cSrcweir 
346cdf0e10cSrcweir // ----------------------------------------------------------------------------
347cdf0e10cSrcweir 
Array()348cdf0e10cSrcweir Array::Array()
349cdf0e10cSrcweir {
350cdf0e10cSrcweir     Initialize( 0, 0 );
351cdf0e10cSrcweir }
352cdf0e10cSrcweir 
Array(size_t nWidth,size_t nHeight)353cdf0e10cSrcweir Array::Array( size_t nWidth, size_t nHeight )
354cdf0e10cSrcweir {
355cdf0e10cSrcweir     Initialize( nWidth, nHeight );
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
~Array()358cdf0e10cSrcweir Array::~Array()
359cdf0e10cSrcweir {
360cdf0e10cSrcweir }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir // array size and column/row indexes ------------------------------------------
363cdf0e10cSrcweir 
Initialize(size_t nWidth,size_t nHeight)364cdf0e10cSrcweir void Array::Initialize( size_t nWidth, size_t nHeight )
365cdf0e10cSrcweir {
366cdf0e10cSrcweir     bool bDiagDblClip = mxImpl.get() ? mxImpl->mbDiagDblClip : DIAG_DBL_CLIP_DEFAULT;
367cdf0e10cSrcweir     mxImpl.reset( new ArrayImpl( nWidth, nHeight, bDiagDblClip ) );
368cdf0e10cSrcweir }
369cdf0e10cSrcweir 
Clear()370cdf0e10cSrcweir void Array::Clear()
371cdf0e10cSrcweir {
372cdf0e10cSrcweir     Initialize( mxImpl->mnWidth, mxImpl->mnHeight );
373cdf0e10cSrcweir }
374cdf0e10cSrcweir 
GetColCount() const375cdf0e10cSrcweir size_t Array::GetColCount() const
376cdf0e10cSrcweir {
377cdf0e10cSrcweir     return mxImpl->mnWidth;
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
GetRowCount() const380cdf0e10cSrcweir size_t Array::GetRowCount() const
381cdf0e10cSrcweir {
382cdf0e10cSrcweir     return mxImpl->mnHeight;
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
GetCellCount() const385cdf0e10cSrcweir size_t Array::GetCellCount() const
386cdf0e10cSrcweir {
387cdf0e10cSrcweir     return mxImpl->maCells.size();
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
GetColFromIndex(size_t nCellIndex) const390cdf0e10cSrcweir size_t Array::GetColFromIndex( size_t nCellIndex ) const
391cdf0e10cSrcweir {
392cdf0e10cSrcweir     DBG_FRAME_CHECK_INDEX( nCellIndex, "GetColFromIndex" );
393cdf0e10cSrcweir     return mxImpl->mnWidth ? (nCellIndex % mxImpl->mnWidth) : 0;
394cdf0e10cSrcweir }
395cdf0e10cSrcweir 
GetRowFromIndex(size_t nCellIndex) const396cdf0e10cSrcweir size_t Array::GetRowFromIndex( size_t nCellIndex ) const
397cdf0e10cSrcweir {
398cdf0e10cSrcweir     DBG_FRAME_CHECK_INDEX( nCellIndex, "GetRowFromIndex" );
399cdf0e10cSrcweir     return mxImpl->mnWidth ? (nCellIndex / mxImpl->mnWidth) : 0;
400cdf0e10cSrcweir }
401cdf0e10cSrcweir 
GetCellIndex(size_t nCol,size_t nRow,bool bRTL) const402cdf0e10cSrcweir size_t Array::GetCellIndex( size_t nCol, size_t nRow, bool bRTL ) const
403cdf0e10cSrcweir {
404cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetCellIndex" );
405cdf0e10cSrcweir     if (bRTL)
406cdf0e10cSrcweir         nCol = mxImpl->GetMirrorCol(nCol);
407cdf0e10cSrcweir     return mxImpl->GetIndex( nCol, nRow );
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir // cell border styles ---------------------------------------------------------
411cdf0e10cSrcweir 
SetCellStyleLeft(size_t nCol,size_t nRow,const Style & rStyle)412cdf0e10cSrcweir void Array::SetCellStyleLeft( size_t nCol, size_t nRow, const Style& rStyle )
413cdf0e10cSrcweir {
414cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleLeft" );
415cdf0e10cSrcweir     CELLACC( nCol, nRow ).maLeft = rStyle;
416cdf0e10cSrcweir }
417cdf0e10cSrcweir 
SetCellStyleRight(size_t nCol,size_t nRow,const Style & rStyle)418cdf0e10cSrcweir void Array::SetCellStyleRight( size_t nCol, size_t nRow, const Style& rStyle )
419cdf0e10cSrcweir {
420cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleRight" );
421cdf0e10cSrcweir     CELLACC( nCol, nRow ).maRight = rStyle;
422cdf0e10cSrcweir }
423cdf0e10cSrcweir 
SetCellStyleTop(size_t nCol,size_t nRow,const Style & rStyle)424cdf0e10cSrcweir void Array::SetCellStyleTop( size_t nCol, size_t nRow, const Style& rStyle )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleTop" );
427cdf0e10cSrcweir     CELLACC( nCol, nRow ).maTop = rStyle;
428cdf0e10cSrcweir }
429cdf0e10cSrcweir 
SetCellStyleBottom(size_t nCol,size_t nRow,const Style & rStyle)430cdf0e10cSrcweir void Array::SetCellStyleBottom( size_t nCol, size_t nRow, const Style& rStyle )
431cdf0e10cSrcweir {
432cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleBottom" );
433cdf0e10cSrcweir     CELLACC( nCol, nRow ).maBottom = rStyle;
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
SetCellStyleTLBR(size_t nCol,size_t nRow,const Style & rStyle)436cdf0e10cSrcweir void Array::SetCellStyleTLBR( size_t nCol, size_t nRow, const Style& rStyle )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleTLBR" );
439cdf0e10cSrcweir     CELLACC( nCol, nRow ).maTLBR = rStyle;
440cdf0e10cSrcweir }
441cdf0e10cSrcweir 
SetCellStyleBLTR(size_t nCol,size_t nRow,const Style & rStyle)442cdf0e10cSrcweir void Array::SetCellStyleBLTR( size_t nCol, size_t nRow, const Style& rStyle )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleBLTR" );
445cdf0e10cSrcweir     CELLACC( nCol, nRow ).maBLTR = rStyle;
446cdf0e10cSrcweir }
447cdf0e10cSrcweir 
SetCellStyleDiag(size_t nCol,size_t nRow,const Style & rTLBR,const Style & rBLTR)448cdf0e10cSrcweir void Array::SetCellStyleDiag( size_t nCol, size_t nRow, const Style& rTLBR, const Style& rBLTR )
449cdf0e10cSrcweir {
450cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetCellStyleDiag" );
451cdf0e10cSrcweir     Cell& rCell = CELLACC( nCol, nRow );
452cdf0e10cSrcweir     rCell.maTLBR = rTLBR;
453cdf0e10cSrcweir     rCell.maBLTR = rBLTR;
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
SetColumnStyleLeft(size_t nCol,const Style & rStyle)456cdf0e10cSrcweir void Array::SetColumnStyleLeft( size_t nCol, const Style& rStyle )
457cdf0e10cSrcweir {
458cdf0e10cSrcweir     DBG_FRAME_CHECK_COL( nCol, "SetColumnStyleLeft" );
459cdf0e10cSrcweir     for( size_t nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
460cdf0e10cSrcweir         SetCellStyleLeft( nCol, nRow, rStyle );
461cdf0e10cSrcweir }
462cdf0e10cSrcweir 
SetColumnStyleRight(size_t nCol,const Style & rStyle)463cdf0e10cSrcweir void Array::SetColumnStyleRight( size_t nCol, const Style& rStyle )
464cdf0e10cSrcweir {
465cdf0e10cSrcweir     DBG_FRAME_CHECK_COL( nCol, "SetColumnStyleRight" );
466cdf0e10cSrcweir     for( size_t nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
467cdf0e10cSrcweir         SetCellStyleRight( nCol, nRow, rStyle );
468cdf0e10cSrcweir }
469cdf0e10cSrcweir 
SetRowStyleTop(size_t nRow,const Style & rStyle)470cdf0e10cSrcweir void Array::SetRowStyleTop( size_t nRow, const Style& rStyle )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir     DBG_FRAME_CHECK_ROW( nRow, "SetRowStyleTop" );
473cdf0e10cSrcweir     for( size_t nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
474cdf0e10cSrcweir         SetCellStyleTop( nCol, nRow, rStyle );
475cdf0e10cSrcweir }
476cdf0e10cSrcweir 
SetRowStyleBottom(size_t nRow,const Style & rStyle)477cdf0e10cSrcweir void Array::SetRowStyleBottom( size_t nRow, const Style& rStyle )
478cdf0e10cSrcweir {
479cdf0e10cSrcweir     DBG_FRAME_CHECK_ROW( nRow, "SetRowStyleBottom" );
480cdf0e10cSrcweir     for( size_t nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
481cdf0e10cSrcweir         SetCellStyleBottom( nCol, nRow, rStyle );
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
GetCellStyleLeft(size_t nCol,size_t nRow,bool bSimple) const484cdf0e10cSrcweir const Style& Array::GetCellStyleLeft( size_t nCol, size_t nRow, bool bSimple ) const
485cdf0e10cSrcweir {
486cdf0e10cSrcweir     // simple: always return own left style
487cdf0e10cSrcweir     if( bSimple )
488cdf0e10cSrcweir         return CELL( nCol, nRow ).maLeft;
489cdf0e10cSrcweir     // outside clipping rows or overlapped in merged cells: invisible
490cdf0e10cSrcweir     if( !mxImpl->IsRowInClipRange( nRow ) || mxImpl->IsMergedOverlappedLeft( nCol, nRow ) )
491cdf0e10cSrcweir         return OBJ_STYLE_NONE;
492cdf0e10cSrcweir     // left clipping border: always own left style
493cdf0e10cSrcweir     if( nCol == mxImpl->mnFirstClipCol )
494cdf0e10cSrcweir         return ORIGCELL( nCol, nRow ).maLeft;
495cdf0e10cSrcweir     // right clipping border: always right style of left neighbor cell
496cdf0e10cSrcweir     if( nCol == mxImpl->mnLastClipCol + 1 )
497cdf0e10cSrcweir         return ORIGCELL( nCol - 1, nRow ).maRight;
498cdf0e10cSrcweir     // outside clipping columns: invisible
499cdf0e10cSrcweir     if( !mxImpl->IsColInClipRange( nCol ) )
500cdf0e10cSrcweir         return OBJ_STYLE_NONE;
501cdf0e10cSrcweir     // inside clipping range: maximum of own left style and right style of left neighbor cell
502cdf0e10cSrcweir     return std::max( ORIGCELL( nCol, nRow ).maLeft, ORIGCELL( nCol - 1, nRow ).maRight );
503cdf0e10cSrcweir }
504cdf0e10cSrcweir 
GetCellStyleRight(size_t nCol,size_t nRow,bool bSimple) const505cdf0e10cSrcweir const Style& Array::GetCellStyleRight( size_t nCol, size_t nRow, bool bSimple ) const
506cdf0e10cSrcweir {
507cdf0e10cSrcweir     // simple: always return own right style
508cdf0e10cSrcweir     if( bSimple )
509cdf0e10cSrcweir         return CELL( nCol, nRow ).maRight;
510cdf0e10cSrcweir     // outside clipping rows or overlapped in merged cells: invisible
511cdf0e10cSrcweir     if( !mxImpl->IsRowInClipRange( nRow ) || mxImpl->IsMergedOverlappedRight( nCol, nRow ) )
512cdf0e10cSrcweir         return OBJ_STYLE_NONE;
513cdf0e10cSrcweir     // left clipping border: always left style of right neighbor cell
514cdf0e10cSrcweir     if( nCol + 1 == mxImpl->mnFirstClipCol )
515cdf0e10cSrcweir         return ORIGCELL( nCol + 1, nRow ).maLeft;
516cdf0e10cSrcweir     // right clipping border: always own right style
517cdf0e10cSrcweir     if( nCol == mxImpl->mnLastClipCol )
518cdf0e10cSrcweir         return ORIGCELL( nCol, nRow ).maRight;
519cdf0e10cSrcweir     // outside clipping columns: invisible
520cdf0e10cSrcweir     if( !mxImpl->IsColInClipRange( nCol ) )
521cdf0e10cSrcweir         return OBJ_STYLE_NONE;
522cdf0e10cSrcweir     // inside clipping range: maximum of own right style and left style of right neighbor cell
523cdf0e10cSrcweir     return std::max( ORIGCELL( nCol, nRow ).maRight, ORIGCELL( nCol + 1, nRow ).maLeft );
524cdf0e10cSrcweir }
525cdf0e10cSrcweir 
GetCellStyleTop(size_t nCol,size_t nRow,bool bSimple) const526cdf0e10cSrcweir const Style& Array::GetCellStyleTop( size_t nCol, size_t nRow, bool bSimple ) const
527cdf0e10cSrcweir {
528cdf0e10cSrcweir     // simple: always return own top style
529cdf0e10cSrcweir     if( bSimple )
530cdf0e10cSrcweir         return CELL( nCol, nRow ).maTop;
531cdf0e10cSrcweir     // outside clipping columns or overlapped in merged cells: invisible
532cdf0e10cSrcweir     if( !mxImpl->IsColInClipRange( nCol ) || mxImpl->IsMergedOverlappedTop( nCol, nRow ) )
533cdf0e10cSrcweir         return OBJ_STYLE_NONE;
534cdf0e10cSrcweir     // top clipping border: always own top style
535cdf0e10cSrcweir     if( nRow == mxImpl->mnFirstClipRow )
536cdf0e10cSrcweir         return ORIGCELL( nCol, nRow ).maTop;
537cdf0e10cSrcweir     // bottom clipping border: always bottom style of top neighbor cell
538cdf0e10cSrcweir     if( nRow == mxImpl->mnLastClipRow + 1 )
539cdf0e10cSrcweir         return ORIGCELL( nCol, nRow - 1 ).maBottom;
540cdf0e10cSrcweir     // outside clipping rows: invisible
541cdf0e10cSrcweir     if( !mxImpl->IsRowInClipRange( nRow ) )
542cdf0e10cSrcweir         return OBJ_STYLE_NONE;
543cdf0e10cSrcweir     // inside clipping range: maximum of own top style and bottom style of top neighbor cell
544cdf0e10cSrcweir     return std::max( ORIGCELL( nCol, nRow ).maTop, ORIGCELL( nCol, nRow - 1 ).maBottom );
545cdf0e10cSrcweir }
546cdf0e10cSrcweir 
GetCellStyleBottom(size_t nCol,size_t nRow,bool bSimple) const547cdf0e10cSrcweir const Style& Array::GetCellStyleBottom( size_t nCol, size_t nRow, bool bSimple ) const
548cdf0e10cSrcweir {
549cdf0e10cSrcweir     // simple: always return own bottom style
550cdf0e10cSrcweir     if( bSimple )
551cdf0e10cSrcweir         return CELL( nCol, nRow ).maBottom;
552cdf0e10cSrcweir     // outside clipping columns or overlapped in merged cells: invisible
553cdf0e10cSrcweir     if( !mxImpl->IsColInClipRange( nCol ) || mxImpl->IsMergedOverlappedBottom( nCol, nRow ) )
554cdf0e10cSrcweir         return OBJ_STYLE_NONE;
555cdf0e10cSrcweir     // top clipping border: always top style of bottom neighbor cell
556cdf0e10cSrcweir     if( nRow + 1 == mxImpl->mnFirstClipRow )
557cdf0e10cSrcweir         return ORIGCELL( nCol, nRow + 1 ).maTop;
558cdf0e10cSrcweir     // bottom clipping border: always own bottom style
559cdf0e10cSrcweir     if( nRow == mxImpl->mnLastClipRow )
560cdf0e10cSrcweir         return ORIGCELL( nCol, nRow ).maBottom;
561cdf0e10cSrcweir     // outside clipping rows: invisible
562cdf0e10cSrcweir     if( !mxImpl->IsRowInClipRange( nRow ) )
563cdf0e10cSrcweir         return OBJ_STYLE_NONE;
564cdf0e10cSrcweir     // inside clipping range: maximum of own bottom style and top style of bottom neighbor cell
565cdf0e10cSrcweir     return std::max( ORIGCELL( nCol, nRow ).maBottom, ORIGCELL( nCol, nRow + 1 ).maTop );
566cdf0e10cSrcweir }
567cdf0e10cSrcweir 
GetCellStyleTLBR(size_t nCol,size_t nRow,bool bSimple) const568cdf0e10cSrcweir const Style& Array::GetCellStyleTLBR( size_t nCol, size_t nRow, bool bSimple ) const
569cdf0e10cSrcweir {
570cdf0e10cSrcweir     return bSimple ? CELL( nCol, nRow ).maTLBR :
571cdf0e10cSrcweir         (mxImpl->IsInClipRange( nCol, nRow ) ? ORIGCELL( nCol, nRow ).maTLBR : OBJ_STYLE_NONE);
572cdf0e10cSrcweir }
573cdf0e10cSrcweir 
GetCellStyleBLTR(size_t nCol,size_t nRow,bool bSimple) const574cdf0e10cSrcweir const Style& Array::GetCellStyleBLTR( size_t nCol, size_t nRow, bool bSimple ) const
575cdf0e10cSrcweir {
576cdf0e10cSrcweir     return bSimple ? CELL( nCol, nRow ).maBLTR :
577cdf0e10cSrcweir         (mxImpl->IsInClipRange( nCol, nRow ) ? ORIGCELL( nCol, nRow ).maBLTR : OBJ_STYLE_NONE);
578cdf0e10cSrcweir }
579cdf0e10cSrcweir 
GetCellStyleTL(size_t nCol,size_t nRow) const580cdf0e10cSrcweir const Style& Array::GetCellStyleTL( size_t nCol, size_t nRow ) const
581cdf0e10cSrcweir {
582cdf0e10cSrcweir     // not in clipping range: always invisible
583cdf0e10cSrcweir     if( !mxImpl->IsInClipRange( nCol, nRow ) )
584cdf0e10cSrcweir         return OBJ_STYLE_NONE;
585cdf0e10cSrcweir     // return style only for top-left cell
586cdf0e10cSrcweir     size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
587cdf0e10cSrcweir     size_t nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
588cdf0e10cSrcweir     return ((nCol == nFirstCol) && (nRow == nFirstRow)) ?
589cdf0e10cSrcweir         CELL( nFirstCol, nFirstRow ).maTLBR : OBJ_STYLE_NONE;
590cdf0e10cSrcweir }
591cdf0e10cSrcweir 
GetCellStyleBR(size_t nCol,size_t nRow) const592cdf0e10cSrcweir const Style& Array::GetCellStyleBR( size_t nCol, size_t nRow ) const
593cdf0e10cSrcweir {
594cdf0e10cSrcweir     // not in clipping range: always invisible
595cdf0e10cSrcweir     if( !mxImpl->IsInClipRange( nCol, nRow ) )
596cdf0e10cSrcweir         return OBJ_STYLE_NONE;
597cdf0e10cSrcweir     // return style only for bottom-right cell
598cdf0e10cSrcweir     size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
599cdf0e10cSrcweir     size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
600cdf0e10cSrcweir     return ((nCol == nLastCol) && (nRow == nLastRow)) ?
601cdf0e10cSrcweir         CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), mxImpl->GetMergedFirstRow( nCol, nRow ) ).maTLBR : OBJ_STYLE_NONE;
602cdf0e10cSrcweir }
603cdf0e10cSrcweir 
GetCellStyleBL(size_t nCol,size_t nRow) const604cdf0e10cSrcweir const Style& Array::GetCellStyleBL( size_t nCol, size_t nRow ) const
605cdf0e10cSrcweir {
606cdf0e10cSrcweir     // not in clipping range: always invisible
607cdf0e10cSrcweir     if( !mxImpl->IsInClipRange( nCol, nRow ) )
608cdf0e10cSrcweir         return OBJ_STYLE_NONE;
609cdf0e10cSrcweir     // return style only for bottom-left cell
610cdf0e10cSrcweir     size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
611cdf0e10cSrcweir     size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
612cdf0e10cSrcweir     return ((nCol == nFirstCol) && (nRow == nLastRow)) ?
613cdf0e10cSrcweir         CELL( nFirstCol, mxImpl->GetMergedFirstRow( nCol, nRow ) ).maBLTR : OBJ_STYLE_NONE;
614cdf0e10cSrcweir }
615cdf0e10cSrcweir 
GetCellStyleTR(size_t nCol,size_t nRow) const616cdf0e10cSrcweir const Style& Array::GetCellStyleTR( size_t nCol, size_t nRow ) const
617cdf0e10cSrcweir {
618cdf0e10cSrcweir     // not in clipping range: always invisible
619cdf0e10cSrcweir     if( !mxImpl->IsInClipRange( nCol, nRow ) )
620cdf0e10cSrcweir         return OBJ_STYLE_NONE;
621cdf0e10cSrcweir     // return style only for top-right cell
622cdf0e10cSrcweir     size_t nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
623cdf0e10cSrcweir     size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
624cdf0e10cSrcweir     return ((nCol == nLastCol) && (nRow == nFirstRow)) ?
625cdf0e10cSrcweir         CELL( mxImpl->GetMergedFirstCol( nCol, nRow ), nFirstRow ).maBLTR : OBJ_STYLE_NONE;
626cdf0e10cSrcweir }
627cdf0e10cSrcweir 
628cdf0e10cSrcweir // cell merging ---------------------------------------------------------------
629cdf0e10cSrcweir 
SetMergedRange(size_t nFirstCol,size_t nFirstRow,size_t nLastCol,size_t nLastRow)630cdf0e10cSrcweir void Array::SetMergedRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow )
631cdf0e10cSrcweir {
632cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "SetMergedRange" );
633cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "SetMergedRange" );
634cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2
635cdf0e10cSrcweir     {
636cdf0e10cSrcweir         bool bFound = false;
637cdf0e10cSrcweir         for( size_t nCurrCol = nFirstCol; !bFound && (nCurrCol <= nLastCol); ++nCurrCol )
638cdf0e10cSrcweir             for( size_t nCurrRow = nFirstRow; !bFound && (nCurrRow <= nLastRow); ++nCurrRow )
639cdf0e10cSrcweir                 bFound = CELL( nCurrCol, nCurrRow ).IsMerged();
640cdf0e10cSrcweir         DBG_FRAME_CHECK( !bFound, "SetMergedRange", "overlapping merged ranges" );
641cdf0e10cSrcweir     }
642cdf0e10cSrcweir #endif
643cdf0e10cSrcweir     if( mxImpl->IsValidPos( nFirstCol, nFirstRow ) && mxImpl->IsValidPos( nLastCol, nLastRow ) )
644cdf0e10cSrcweir         lclSetMergedRange( mxImpl->maCells, mxImpl->mnWidth, nFirstCol, nFirstRow, nLastCol, nLastRow );
645cdf0e10cSrcweir }
646cdf0e10cSrcweir 
RemoveMergedRange(size_t nCol,size_t nRow)647cdf0e10cSrcweir void Array::RemoveMergedRange( size_t nCol, size_t nRow )
648cdf0e10cSrcweir {
649cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "RemoveMergedRange" );
650cdf0e10cSrcweir     for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
651cdf0e10cSrcweir     {
652cdf0e10cSrcweir         Cell& rCell = CELLACC( aIt.Col(), aIt.Row() );
653cdf0e10cSrcweir         rCell.mbMergeOrig = rCell.mbOverlapX = rCell.mbOverlapY = false;
654cdf0e10cSrcweir         rCell.mnAddLeft = rCell.mnAddRight = rCell.mnAddTop = rCell.mnAddBottom = 0;
655cdf0e10cSrcweir     }
656cdf0e10cSrcweir }
657cdf0e10cSrcweir 
SetAddMergedLeftSize(size_t nCol,size_t nRow,long nAddSize)658cdf0e10cSrcweir void Array::SetAddMergedLeftSize( size_t nCol, size_t nRow, long nAddSize )
659cdf0e10cSrcweir {
660cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedLeftSize" );
661cdf0e10cSrcweir     DBG_FRAME_CHECK( mxImpl->GetMergedFirstCol( nCol, nRow ) == 0, "SetAddMergedLeftSize", "additional border inside array" );
662cdf0e10cSrcweir     for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
663cdf0e10cSrcweir         CELLACC( aIt.Col(), aIt.Row() ).mnAddLeft = nAddSize;
664cdf0e10cSrcweir }
665cdf0e10cSrcweir 
SetAddMergedRightSize(size_t nCol,size_t nRow,long nAddSize)666cdf0e10cSrcweir void Array::SetAddMergedRightSize( size_t nCol, size_t nRow, long nAddSize )
667cdf0e10cSrcweir {
668cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedRightSize" );
669cdf0e10cSrcweir     DBG_FRAME_CHECK( mxImpl->GetMergedLastCol( nCol, nRow ) + 1 == mxImpl->mnWidth, "SetAddMergedRightSize", "additional border inside array" );
670cdf0e10cSrcweir     for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
671cdf0e10cSrcweir         CELLACC( aIt.Col(), aIt.Row() ).mnAddRight = nAddSize;
672cdf0e10cSrcweir }
673cdf0e10cSrcweir 
SetAddMergedTopSize(size_t nCol,size_t nRow,long nAddSize)674cdf0e10cSrcweir void Array::SetAddMergedTopSize( size_t nCol, size_t nRow, long nAddSize )
675cdf0e10cSrcweir {
676cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedTopSize" );
677cdf0e10cSrcweir     DBG_FRAME_CHECK( mxImpl->GetMergedFirstRow( nCol, nRow ) == 0, "SetAddMergedTopSize", "additional border inside array" );
678cdf0e10cSrcweir     for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
679cdf0e10cSrcweir         CELLACC( aIt.Col(), aIt.Row() ).mnAddTop = nAddSize;
680cdf0e10cSrcweir }
681cdf0e10cSrcweir 
SetAddMergedBottomSize(size_t nCol,size_t nRow,long nAddSize)682cdf0e10cSrcweir void Array::SetAddMergedBottomSize( size_t nCol, size_t nRow, long nAddSize )
683cdf0e10cSrcweir {
684cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "SetAddMergedBottomSize" );
685cdf0e10cSrcweir     DBG_FRAME_CHECK( mxImpl->GetMergedLastRow( nCol, nRow ) + 1 == mxImpl->mnHeight, "SetAddMergedBottomSize", "additional border inside array" );
686cdf0e10cSrcweir     for( MergedCellIterator aIt( *this, nCol, nRow ); aIt.Is(); ++aIt )
687cdf0e10cSrcweir         CELLACC( aIt.Col(), aIt.Row() ).mnAddBottom = nAddSize;
688cdf0e10cSrcweir }
689cdf0e10cSrcweir 
IsMerged(size_t nCol,size_t nRow) const690cdf0e10cSrcweir bool Array::IsMerged( size_t nCol, size_t nRow ) const
691cdf0e10cSrcweir {
692cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMerged" );
693cdf0e10cSrcweir     return CELL( nCol, nRow ).IsMerged();
694cdf0e10cSrcweir }
695cdf0e10cSrcweir 
IsMergedOrigin(size_t nCol,size_t nRow) const696cdf0e10cSrcweir bool Array::IsMergedOrigin( size_t nCol, size_t nRow ) const
697cdf0e10cSrcweir {
698cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOrigin" );
699cdf0e10cSrcweir     return CELL( nCol, nRow ).mbMergeOrig;
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
IsMergedOverlapped(size_t nCol,size_t nRow) const702cdf0e10cSrcweir bool Array::IsMergedOverlapped( size_t nCol, size_t nRow ) const
703cdf0e10cSrcweir {
704cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOverlapped" );
705cdf0e10cSrcweir     return CELL( nCol, nRow ).IsOverlapped();
706cdf0e10cSrcweir }
707cdf0e10cSrcweir 
IsMergedOverlappedLeft(size_t nCol,size_t nRow) const708cdf0e10cSrcweir bool Array::IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const
709cdf0e10cSrcweir {
710cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOverlappedLeft" );
711cdf0e10cSrcweir     return mxImpl->IsMergedOverlappedLeft( nCol, nRow );
712cdf0e10cSrcweir }
713cdf0e10cSrcweir 
IsMergedOverlappedRight(size_t nCol,size_t nRow) const714cdf0e10cSrcweir bool Array::IsMergedOverlappedRight( size_t nCol, size_t nRow ) const
715cdf0e10cSrcweir {
716cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOverlappedRight" );
717cdf0e10cSrcweir     return mxImpl->IsMergedOverlappedRight( nCol, nRow );
718cdf0e10cSrcweir }
719cdf0e10cSrcweir 
IsMergedOverlappedTop(size_t nCol,size_t nRow) const720cdf0e10cSrcweir bool Array::IsMergedOverlappedTop( size_t nCol, size_t nRow ) const
721cdf0e10cSrcweir {
722cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOverlappedTop" );
723cdf0e10cSrcweir     return mxImpl->IsMergedOverlappedTop( nCol, nRow );
724cdf0e10cSrcweir }
725cdf0e10cSrcweir 
IsMergedOverlappedBottom(size_t nCol,size_t nRow) const726cdf0e10cSrcweir bool Array::IsMergedOverlappedBottom( size_t nCol, size_t nRow ) const
727cdf0e10cSrcweir {
728cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsMergedOverlappedBottom" );
729cdf0e10cSrcweir     return mxImpl->IsMergedOverlappedBottom( nCol, nRow );
730cdf0e10cSrcweir }
731cdf0e10cSrcweir 
GetMergedOrigin(size_t & rnFirstCol,size_t & rnFirstRow,size_t nCol,size_t nRow) const732cdf0e10cSrcweir void Array::GetMergedOrigin( size_t& rnFirstCol, size_t& rnFirstRow, size_t nCol, size_t nRow ) const
733cdf0e10cSrcweir {
734cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetMergedOrigin" );
735cdf0e10cSrcweir     rnFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
736cdf0e10cSrcweir     rnFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
737cdf0e10cSrcweir }
738cdf0e10cSrcweir 
GetMergedSize(size_t & rnWidth,size_t & rnHeight,size_t nCol,size_t nRow) const739cdf0e10cSrcweir void Array::GetMergedSize( size_t& rnWidth, size_t& rnHeight, size_t nCol, size_t nRow ) const
740cdf0e10cSrcweir {
741cdf0e10cSrcweir     size_t nFirstCol, nFirstRow, nLastCol, nLastRow;
742cdf0e10cSrcweir     GetMergedRange( nFirstCol, nFirstRow, nLastCol, nLastRow, nCol, nRow );
743cdf0e10cSrcweir     rnWidth = nLastCol - nFirstCol + 1;
744cdf0e10cSrcweir     rnHeight = nLastRow - nFirstRow + 1;
745cdf0e10cSrcweir }
746cdf0e10cSrcweir 
GetMergedRange(size_t & rnFirstCol,size_t & rnFirstRow,size_t & rnLastCol,size_t & rnLastRow,size_t nCol,size_t nRow) const747cdf0e10cSrcweir void Array::GetMergedRange( size_t& rnFirstCol, size_t& rnFirstRow,
748cdf0e10cSrcweir         size_t& rnLastCol, size_t& rnLastRow, size_t nCol, size_t nRow ) const
749cdf0e10cSrcweir {
750cdf0e10cSrcweir     GetMergedOrigin( rnFirstCol, rnFirstRow, nCol, nRow );
751cdf0e10cSrcweir     rnLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
752cdf0e10cSrcweir     rnLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
753cdf0e10cSrcweir }
754cdf0e10cSrcweir 
755cdf0e10cSrcweir // clipping -------------------------------------------------------------------
756cdf0e10cSrcweir 
SetClipRange(size_t nFirstCol,size_t nFirstRow,size_t nLastCol,size_t nLastRow)757cdf0e10cSrcweir void Array::SetClipRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow )
758cdf0e10cSrcweir {
759cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "SetClipRange" );
760cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "SetClipRange" );
761cdf0e10cSrcweir     mxImpl->mnFirstClipCol = nFirstCol;
762cdf0e10cSrcweir     mxImpl->mnFirstClipRow = nFirstRow;
763cdf0e10cSrcweir     mxImpl->mnLastClipCol = nLastCol;
764cdf0e10cSrcweir     mxImpl->mnLastClipRow = nLastRow;
765cdf0e10cSrcweir }
766cdf0e10cSrcweir 
RemoveClipRange()767cdf0e10cSrcweir void Array::RemoveClipRange()
768cdf0e10cSrcweir {
769cdf0e10cSrcweir     if( !mxImpl->maCells.empty() )
770cdf0e10cSrcweir         SetClipRange( 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1 );
771cdf0e10cSrcweir }
772cdf0e10cSrcweir 
IsInClipRange(size_t nCol,size_t nRow) const773cdf0e10cSrcweir bool Array::IsInClipRange( size_t nCol, size_t nRow ) const
774cdf0e10cSrcweir {
775cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "IsInClipRange" );
776cdf0e10cSrcweir     return mxImpl->IsInClipRange( nCol, nRow );
777cdf0e10cSrcweir }
778cdf0e10cSrcweir 
GetClipRangeRectangle() const779cdf0e10cSrcweir Rectangle Array::GetClipRangeRectangle() const
780cdf0e10cSrcweir {
781cdf0e10cSrcweir     return Rectangle(
782cdf0e10cSrcweir         mxImpl->GetColPosition( mxImpl->mnFirstClipCol ),
783cdf0e10cSrcweir         mxImpl->GetRowPosition( mxImpl->mnFirstClipRow ),
784cdf0e10cSrcweir         mxImpl->GetColPosition( mxImpl->mnLastClipCol + 1 ),
785cdf0e10cSrcweir         mxImpl->GetRowPosition( mxImpl->mnLastClipRow + 1 ) );
786cdf0e10cSrcweir }
787cdf0e10cSrcweir 
788cdf0e10cSrcweir // cell coordinates -----------------------------------------------------------
789cdf0e10cSrcweir 
SetXOffset(long nXOffset)790cdf0e10cSrcweir void Array::SetXOffset( long nXOffset )
791cdf0e10cSrcweir {
792cdf0e10cSrcweir     mxImpl->maXCoords[ 0 ] = nXOffset;
793cdf0e10cSrcweir     mxImpl->mbXCoordsDirty = true;
794cdf0e10cSrcweir }
795cdf0e10cSrcweir 
SetYOffset(long nYOffset)796cdf0e10cSrcweir void Array::SetYOffset( long nYOffset )
797cdf0e10cSrcweir {
798cdf0e10cSrcweir     mxImpl->maYCoords[ 0 ] = nYOffset;
799cdf0e10cSrcweir     mxImpl->mbYCoordsDirty = true;
800cdf0e10cSrcweir }
801cdf0e10cSrcweir 
SetColWidth(size_t nCol,long nWidth)802cdf0e10cSrcweir void Array::SetColWidth( size_t nCol, long nWidth )
803cdf0e10cSrcweir {
804cdf0e10cSrcweir     DBG_FRAME_CHECK_COL( nCol, "SetColWidth" );
805cdf0e10cSrcweir     mxImpl->maWidths[ nCol ] = nWidth;
806cdf0e10cSrcweir     mxImpl->mbXCoordsDirty = true;
807cdf0e10cSrcweir }
808cdf0e10cSrcweir 
SetRowHeight(size_t nRow,long nHeight)809cdf0e10cSrcweir void Array::SetRowHeight( size_t nRow, long nHeight )
810cdf0e10cSrcweir {
811cdf0e10cSrcweir     DBG_FRAME_CHECK_ROW( nRow, "SetRowHeight" );
812cdf0e10cSrcweir     mxImpl->maHeights[ nRow ] = nHeight;
813cdf0e10cSrcweir     mxImpl->mbYCoordsDirty = true;
814cdf0e10cSrcweir }
815cdf0e10cSrcweir 
SetAllColWidths(long nWidth)816cdf0e10cSrcweir void Array::SetAllColWidths( long nWidth )
817cdf0e10cSrcweir {
818cdf0e10cSrcweir     std::fill( mxImpl->maWidths.begin(), mxImpl->maWidths.end(), nWidth );
819cdf0e10cSrcweir     mxImpl->mbXCoordsDirty = true;
820cdf0e10cSrcweir }
821cdf0e10cSrcweir 
SetAllRowHeights(long nHeight)822cdf0e10cSrcweir void Array::SetAllRowHeights( long nHeight )
823cdf0e10cSrcweir {
824cdf0e10cSrcweir     std::fill( mxImpl->maHeights.begin(), mxImpl->maHeights.end(), nHeight );
825cdf0e10cSrcweir     mxImpl->mbYCoordsDirty = true;
826cdf0e10cSrcweir }
827cdf0e10cSrcweir 
GetColPosition(size_t nCol) const828cdf0e10cSrcweir long Array::GetColPosition( size_t nCol ) const
829cdf0e10cSrcweir {
830cdf0e10cSrcweir     DBG_FRAME_CHECK_COL_1( nCol, "GetColPosition" );
831cdf0e10cSrcweir     return mxImpl->GetColPosition( nCol );
832cdf0e10cSrcweir }
833cdf0e10cSrcweir 
GetRowPosition(size_t nRow) const834cdf0e10cSrcweir long Array::GetRowPosition( size_t nRow ) const
835cdf0e10cSrcweir {
836cdf0e10cSrcweir     DBG_FRAME_CHECK_ROW_1( nRow, "GetRowPosition" );
837cdf0e10cSrcweir     return mxImpl->GetRowPosition( nRow );
838cdf0e10cSrcweir }
839cdf0e10cSrcweir 
GetColWidth(size_t nCol) const840cdf0e10cSrcweir long Array::GetColWidth( size_t nCol ) const
841cdf0e10cSrcweir {
842cdf0e10cSrcweir     DBG_FRAME_CHECK_COL( nCol, "GetColWidth" );
843cdf0e10cSrcweir     return mxImpl->maWidths[ nCol ];
844cdf0e10cSrcweir }
845cdf0e10cSrcweir 
GetColWidth(size_t nFirstCol,size_t nLastCol) const846cdf0e10cSrcweir long Array::GetColWidth( size_t nFirstCol, size_t nLastCol ) const
847cdf0e10cSrcweir {
848cdf0e10cSrcweir     DBG_FRAME_CHECK_COL( nFirstCol, "GetColWidth" );
849cdf0e10cSrcweir     DBG_FRAME_CHECK_COL( nLastCol, "GetColWidth" );
850cdf0e10cSrcweir     return GetColPosition( nLastCol + 1 ) - GetColPosition( nFirstCol );
851cdf0e10cSrcweir }
852cdf0e10cSrcweir 
GetRowHeight(size_t nRow) const853cdf0e10cSrcweir long Array::GetRowHeight( size_t nRow ) const
854cdf0e10cSrcweir {
855cdf0e10cSrcweir     DBG_FRAME_CHECK_ROW( nRow, "GetRowHeight" );
856cdf0e10cSrcweir     return mxImpl->maHeights[ nRow ];
857cdf0e10cSrcweir }
858cdf0e10cSrcweir 
GetRowHeight(size_t nFirstRow,size_t nLastRow) const859cdf0e10cSrcweir long Array::GetRowHeight( size_t nFirstRow, size_t nLastRow ) const
860cdf0e10cSrcweir {
861cdf0e10cSrcweir     DBG_FRAME_CHECK_ROW( nFirstRow, "GetRowHeight" );
862cdf0e10cSrcweir     DBG_FRAME_CHECK_ROW( nLastRow, "GetRowHeight" );
863cdf0e10cSrcweir     return GetRowPosition( nLastRow + 1 ) - GetRowPosition( nFirstRow );
864cdf0e10cSrcweir }
865cdf0e10cSrcweir 
GetWidth() const866cdf0e10cSrcweir long Array::GetWidth() const
867cdf0e10cSrcweir {
868cdf0e10cSrcweir     return GetColPosition( mxImpl->mnWidth ) - GetColPosition( 0 );
869cdf0e10cSrcweir }
870cdf0e10cSrcweir 
GetHeight() const871cdf0e10cSrcweir long Array::GetHeight() const
872cdf0e10cSrcweir {
873cdf0e10cSrcweir     return GetRowPosition( mxImpl->mnHeight ) - GetRowPosition( 0 );
874cdf0e10cSrcweir }
875cdf0e10cSrcweir 
GetCellPosition(size_t nCol,size_t nRow,bool bSimple) const876cdf0e10cSrcweir Point Array::GetCellPosition( size_t nCol, size_t nRow, bool bSimple ) const
877cdf0e10cSrcweir {
878cdf0e10cSrcweir     size_t nFirstCol = bSimple ? nCol : mxImpl->GetMergedFirstCol( nCol, nRow );
879cdf0e10cSrcweir     size_t nFirstRow = bSimple ? nRow : mxImpl->GetMergedFirstRow( nCol, nRow );
880cdf0e10cSrcweir     return Point( GetColPosition( nFirstCol ), GetRowPosition( nFirstRow ) );
881cdf0e10cSrcweir }
882cdf0e10cSrcweir 
GetCellSize(size_t nCol,size_t nRow,bool bSimple) const883cdf0e10cSrcweir Size Array::GetCellSize( size_t nCol, size_t nRow, bool bSimple ) const
884cdf0e10cSrcweir {
885cdf0e10cSrcweir     size_t nFirstCol = bSimple ? nCol : mxImpl->GetMergedFirstCol( nCol, nRow );
886cdf0e10cSrcweir     size_t nFirstRow = bSimple ? nRow : mxImpl->GetMergedFirstRow( nCol, nRow );
887cdf0e10cSrcweir     size_t nLastCol = bSimple ? nCol : mxImpl->GetMergedLastCol( nCol, nRow );
888cdf0e10cSrcweir     size_t nLastRow = bSimple ? nRow : mxImpl->GetMergedLastRow( nCol, nRow );
889cdf0e10cSrcweir     return Size( GetColWidth( nFirstCol, nLastCol ) + 1, GetRowHeight( nFirstRow, nLastRow ) + 1 );
890cdf0e10cSrcweir }
891cdf0e10cSrcweir 
GetCellRect(size_t nCol,size_t nRow,bool bSimple) const892cdf0e10cSrcweir Rectangle Array::GetCellRect( size_t nCol, size_t nRow, bool bSimple ) const
893cdf0e10cSrcweir {
894cdf0e10cSrcweir     Rectangle aRect( GetCellPosition( nCol, nRow, bSimple ), GetCellSize( nCol, nRow, bSimple ) );
895cdf0e10cSrcweir 
896cdf0e10cSrcweir     // adjust rectangle for partly visible merged cells
897cdf0e10cSrcweir     const Cell& rCell = CELL( nCol, nRow );
898cdf0e10cSrcweir     if( !bSimple && rCell.IsMerged() )
899cdf0e10cSrcweir     {
900cdf0e10cSrcweir         aRect.Left() -= rCell.mnAddLeft;
901cdf0e10cSrcweir         aRect.Right() += rCell.mnAddRight;
902cdf0e10cSrcweir         aRect.Top() -= rCell.mnAddTop;
903cdf0e10cSrcweir         aRect.Bottom() += rCell.mnAddBottom;
904cdf0e10cSrcweir     }
905cdf0e10cSrcweir     return aRect;
906cdf0e10cSrcweir }
907cdf0e10cSrcweir 
908cdf0e10cSrcweir // diagonal frame borders -----------------------------------------------------
909cdf0e10cSrcweir 
GetHorDiagAngle(size_t nCol,size_t nRow,bool bSimple) const910cdf0e10cSrcweir double Array::GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
911cdf0e10cSrcweir {
912cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetHorDiagAngle" );
913cdf0e10cSrcweir     return mxImpl->GetHorDiagAngle( nCol, nRow, bSimple );
914cdf0e10cSrcweir }
915cdf0e10cSrcweir 
GetVerDiagAngle(size_t nCol,size_t nRow,bool bSimple) const916cdf0e10cSrcweir double Array::GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple ) const
917cdf0e10cSrcweir {
918cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nCol, nRow, "GetVerDiagAngle" );
919cdf0e10cSrcweir     return mxImpl->GetVerDiagAngle( nCol, nRow, bSimple );
920cdf0e10cSrcweir }
921cdf0e10cSrcweir 
SetUseDiagDoubleClipping(bool bSet)922cdf0e10cSrcweir void Array::SetUseDiagDoubleClipping( bool bSet )
923cdf0e10cSrcweir {
924cdf0e10cSrcweir     mxImpl->mbDiagDblClip = bSet;
925cdf0e10cSrcweir }
926cdf0e10cSrcweir 
GetUseDiagDoubleClipping() const927cdf0e10cSrcweir bool Array::GetUseDiagDoubleClipping() const
928cdf0e10cSrcweir {
929cdf0e10cSrcweir     return mxImpl->mbDiagDblClip;
930cdf0e10cSrcweir }
931cdf0e10cSrcweir 
932cdf0e10cSrcweir // mirroring ------------------------------------------------------------------
933cdf0e10cSrcweir 
MirrorSelfX(bool bMirrorStyles,bool bSwapDiag)934cdf0e10cSrcweir void Array::MirrorSelfX( bool bMirrorStyles, bool bSwapDiag )
935cdf0e10cSrcweir {
936cdf0e10cSrcweir     CellVec aNewCells;
937cdf0e10cSrcweir     aNewCells.reserve( GetCellCount() );
938cdf0e10cSrcweir 
939cdf0e10cSrcweir     size_t nCol, nRow;
940cdf0e10cSrcweir     for( nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
941cdf0e10cSrcweir     {
942cdf0e10cSrcweir         for( nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
943cdf0e10cSrcweir         {
944cdf0e10cSrcweir             aNewCells.push_back( CELL( mxImpl->GetMirrorCol( nCol ), nRow ) );
945cdf0e10cSrcweir             aNewCells.back().MirrorSelfX( bMirrorStyles, bSwapDiag );
946cdf0e10cSrcweir         }
947cdf0e10cSrcweir     }
948cdf0e10cSrcweir     for( nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
949cdf0e10cSrcweir     {
950cdf0e10cSrcweir         for( nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
951cdf0e10cSrcweir         {
952cdf0e10cSrcweir             if( CELL( nCol, nRow ).mbMergeOrig )
953cdf0e10cSrcweir             {
954cdf0e10cSrcweir                 size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
955cdf0e10cSrcweir                 size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
956cdf0e10cSrcweir                 lclSetMergedRange( aNewCells, mxImpl->mnWidth,
957cdf0e10cSrcweir                     mxImpl->GetMirrorCol( nLastCol ), nRow,
958cdf0e10cSrcweir                     mxImpl->GetMirrorCol( nCol ), nLastRow );
959cdf0e10cSrcweir             }
960cdf0e10cSrcweir         }
961cdf0e10cSrcweir     }
962cdf0e10cSrcweir     mxImpl->maCells.swap( aNewCells );
963cdf0e10cSrcweir 
964cdf0e10cSrcweir     std::reverse( mxImpl->maWidths.begin(), mxImpl->maWidths.end() );
965cdf0e10cSrcweir     mxImpl->mbXCoordsDirty = true;
966cdf0e10cSrcweir }
967cdf0e10cSrcweir 
MirrorSelfY(bool bMirrorStyles,bool bSwapDiag)968cdf0e10cSrcweir void Array::MirrorSelfY( bool bMirrorStyles, bool bSwapDiag )
969cdf0e10cSrcweir {
970cdf0e10cSrcweir     CellVec aNewCells;
971cdf0e10cSrcweir     aNewCells.reserve( GetCellCount() );
972cdf0e10cSrcweir 
973cdf0e10cSrcweir     size_t nCol, nRow;
974cdf0e10cSrcweir     for( nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
975cdf0e10cSrcweir     {
976cdf0e10cSrcweir         for( nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
977cdf0e10cSrcweir         {
978cdf0e10cSrcweir             aNewCells.push_back( CELL( nCol, mxImpl->GetMirrorRow( nRow ) ) );
979cdf0e10cSrcweir             aNewCells.back().MirrorSelfY( bMirrorStyles, bSwapDiag );
980cdf0e10cSrcweir         }
981cdf0e10cSrcweir     }
982cdf0e10cSrcweir     for( nRow = 0; nRow < mxImpl->mnHeight; ++nRow )
983cdf0e10cSrcweir     {
984cdf0e10cSrcweir         for( nCol = 0; nCol < mxImpl->mnWidth; ++nCol )
985cdf0e10cSrcweir         {
986cdf0e10cSrcweir             if( CELL( nCol, nRow ).mbMergeOrig )
987cdf0e10cSrcweir             {
988cdf0e10cSrcweir                 size_t nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
989cdf0e10cSrcweir                 size_t nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
990cdf0e10cSrcweir                 lclSetMergedRange( aNewCells, mxImpl->mnWidth,
991cdf0e10cSrcweir                     nCol, mxImpl->GetMirrorRow( nLastRow ),
992cdf0e10cSrcweir                     nLastCol, mxImpl->GetMirrorRow( nRow ) );
993cdf0e10cSrcweir             }
994cdf0e10cSrcweir         }
995cdf0e10cSrcweir     }
996cdf0e10cSrcweir     mxImpl->maCells.swap( aNewCells );
997cdf0e10cSrcweir 
998cdf0e10cSrcweir     std::reverse( mxImpl->maHeights.begin(), mxImpl->maHeights.end() );
999cdf0e10cSrcweir     mxImpl->mbYCoordsDirty = true;
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir // drawing --------------------------------------------------------------------
1003cdf0e10cSrcweir 
DrawCell(OutputDevice & rDev,size_t nCol,size_t nRow,const Color * pForceColor) const1004cdf0e10cSrcweir void Array::DrawCell( OutputDevice& rDev, size_t nCol, size_t nRow, const Color* pForceColor ) const
1005cdf0e10cSrcweir {
1006cdf0e10cSrcweir     DrawRange( rDev, nCol, nRow, nCol, nRow, pForceColor );
1007cdf0e10cSrcweir }
1008cdf0e10cSrcweir 
DrawRange(OutputDevice & rDev,size_t nFirstCol,size_t nFirstRow,size_t nLastCol,size_t nLastRow,const Color * pForceColor) const1009cdf0e10cSrcweir void Array::DrawRange( OutputDevice& rDev,
1010cdf0e10cSrcweir         size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
1011cdf0e10cSrcweir         const Color* pForceColor ) const
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nFirstCol, nFirstRow, "DrawRange" );
1014cdf0e10cSrcweir     DBG_FRAME_CHECK_COLROW( nLastCol, nLastRow, "DrawRange" );
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir     size_t nCol, nRow;
1017cdf0e10cSrcweir 
1018cdf0e10cSrcweir     // *** diagonal frame borders ***
1019cdf0e10cSrcweir 
1020cdf0e10cSrcweir     // set clipping region to clip partly visible merged cells
1021cdf0e10cSrcweir     rDev.Push( PUSH_CLIPREGION );
1022cdf0e10cSrcweir     rDev.IntersectClipRegion( GetClipRangeRectangle() );
1023cdf0e10cSrcweir     for( nRow = nFirstRow; nRow <= nLastRow; ++nRow )
1024cdf0e10cSrcweir     {
1025cdf0e10cSrcweir         for( nCol = nFirstCol; nCol <= nLastCol; ++nCol )
1026cdf0e10cSrcweir         {
1027cdf0e10cSrcweir             const Cell& rCell = CELL( nCol, nRow );
1028cdf0e10cSrcweir             bool bOverlapX = rCell.mbOverlapX;
1029cdf0e10cSrcweir             bool bOverlapY = rCell.mbOverlapY;
1030cdf0e10cSrcweir             bool bFirstCol = nCol == nFirstCol;
1031cdf0e10cSrcweir             bool bFirstRow = nRow == nFirstRow;
1032cdf0e10cSrcweir             if( (!bOverlapX && !bOverlapY) || (bFirstCol && bFirstRow) ||
1033cdf0e10cSrcweir                 (!bOverlapY && bFirstCol) || (!bOverlapX && bFirstRow) )
1034cdf0e10cSrcweir             {
1035cdf0e10cSrcweir                 Rectangle aRect( GetCellRect( nCol, nRow ) );
1036cdf0e10cSrcweir                 if( (aRect.GetWidth() > 1) && (aRect.GetHeight() > 1) )
1037cdf0e10cSrcweir                 {
1038cdf0e10cSrcweir                     size_t _nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
1039cdf0e10cSrcweir                     size_t _nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
1040cdf0e10cSrcweir                     size_t _nLastCol = mxImpl->GetMergedLastCol( nCol, nRow );
1041cdf0e10cSrcweir                     size_t _nLastRow = mxImpl->GetMergedLastRow( nCol, nRow );
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir                     DrawDiagFrameBorders( rDev, aRect,
1044cdf0e10cSrcweir                         GetCellStyleTLBR( _nFirstCol, _nFirstRow, true ), GetCellStyleBLTR( _nFirstCol, _nFirstRow, true ),
1045cdf0e10cSrcweir                         GetCellStyleLeft( _nFirstCol, _nFirstRow ), GetCellStyleTop( _nFirstCol, _nFirstRow ),
1046cdf0e10cSrcweir                         GetCellStyleRight( _nLastCol, _nLastRow ), GetCellStyleBottom( _nLastCol, _nLastRow ),
1047cdf0e10cSrcweir                         GetCellStyleLeft( _nFirstCol, _nLastRow ), GetCellStyleBottom( _nFirstCol, _nLastRow ),
1048cdf0e10cSrcweir                         GetCellStyleRight( _nLastCol, _nFirstRow ), GetCellStyleTop( _nLastCol, _nFirstRow ),
1049cdf0e10cSrcweir                         pForceColor, mxImpl->mbDiagDblClip );
1050cdf0e10cSrcweir                 }
1051cdf0e10cSrcweir             }
1052cdf0e10cSrcweir         }
1053cdf0e10cSrcweir     }
1054cdf0e10cSrcweir     rDev.Pop(); // clip region
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir     // *** horizontal frame borders ***
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir     for( nRow = nFirstRow; nRow <= nLastRow + 1; ++nRow )
1059cdf0e10cSrcweir     {
1060cdf0e10cSrcweir         double fAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow );
1061cdf0e10cSrcweir         double fTAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow - 1 );
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir         // *Start*** variables store the data of the left end of the cached frame border
1064cdf0e10cSrcweir         Point aStartPos( mxImpl->GetColPosition( nFirstCol ), mxImpl->GetRowPosition( nRow ) );
1065cdf0e10cSrcweir         const Style* pStart = &GetCellStyleTop( nFirstCol, nRow );
1066cdf0e10cSrcweir         DiagStyle aStartLFromTR( GetCellStyleBL( nFirstCol, nRow - 1 ), fTAngle );
1067cdf0e10cSrcweir         const Style* pStartLFromT = &GetCellStyleLeft( nFirstCol, nRow - 1 );
1068cdf0e10cSrcweir         const Style* pStartLFromL = &GetCellStyleTop( nFirstCol - 1, nRow );
1069cdf0e10cSrcweir         const Style* pStartLFromB = &GetCellStyleLeft( nFirstCol, nRow );
1070cdf0e10cSrcweir         DiagStyle aStartLFromBR( GetCellStyleTL( nFirstCol, nRow ), fAngle );
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir         // *End*** variables store the data of the right end of the cached frame border
1073cdf0e10cSrcweir         DiagStyle aEndRFromTL( GetCellStyleBR( nFirstCol, nRow - 1 ), fTAngle );
1074cdf0e10cSrcweir         const Style* pEndRFromT = &GetCellStyleRight( nFirstCol, nRow - 1 );
1075cdf0e10cSrcweir         const Style* pEndRFromR = &GetCellStyleTop( nFirstCol + 1, nRow );
1076cdf0e10cSrcweir         const Style* pEndRFromB = &GetCellStyleRight( nFirstCol, nRow );
1077cdf0e10cSrcweir         DiagStyle aEndRFromBL( GetCellStyleTR( nFirstCol, nRow ), fAngle );
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir         for( nCol = nFirstCol + 1; nCol <= nLastCol; ++nCol )
1080cdf0e10cSrcweir         {
1081cdf0e10cSrcweir             fAngle = mxImpl->GetHorDiagAngle( nCol, nRow );
1082cdf0e10cSrcweir             fTAngle = mxImpl->GetHorDiagAngle( nCol, nRow - 1 );
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir             const Style& rCurr = *pEndRFromR;
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir             DiagStyle aLFromTR( GetCellStyleBL( nCol, nRow - 1 ), fTAngle );
1087cdf0e10cSrcweir             const Style& rLFromT = *pEndRFromT;
1088cdf0e10cSrcweir             const Style& rLFromL = *pStart;
1089cdf0e10cSrcweir             const Style& rLFromB = *pEndRFromB;
1090cdf0e10cSrcweir             DiagStyle aLFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir             DiagStyle aRFromTL( GetCellStyleBR( nCol, nRow - 1 ), fTAngle );
1093cdf0e10cSrcweir             const Style& rRFromT = GetCellStyleRight( nCol, nRow - 1 );
1094cdf0e10cSrcweir             const Style& rRFromR = GetCellStyleTop( nCol + 1, nRow );
1095cdf0e10cSrcweir             const Style& rRFromB = GetCellStyleRight( nCol, nRow );
1096cdf0e10cSrcweir             DiagStyle aRFromBL( GetCellStyleTR( nCol, nRow ), fAngle );
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir             // check if current frame border can be connected to cached frame border
1099cdf0e10cSrcweir             if( !CheckFrameBorderConnectable( *pStart, rCurr,
1100cdf0e10cSrcweir                     aEndRFromTL, rLFromT, aLFromTR, aEndRFromBL, rLFromB, aLFromBR ) )
1101cdf0e10cSrcweir             {
1102cdf0e10cSrcweir                 // draw previous frame border
1103cdf0e10cSrcweir                 Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
1104cdf0e10cSrcweir                 if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
1105cdf0e10cSrcweir                     DrawHorFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1106cdf0e10cSrcweir                         aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
1107cdf0e10cSrcweir                         aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor );
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir                 // re-init "*Start***" variables
1110cdf0e10cSrcweir                 aStartPos = aEndPos;
1111cdf0e10cSrcweir                 pStart = &rCurr;
1112cdf0e10cSrcweir                 aStartLFromTR = aLFromTR;
1113cdf0e10cSrcweir                 pStartLFromT = &rLFromT;
1114cdf0e10cSrcweir                 pStartLFromL = &rLFromL;
1115cdf0e10cSrcweir                 pStartLFromB = &rLFromB;
1116cdf0e10cSrcweir                 aStartLFromBR = aLFromBR;
1117cdf0e10cSrcweir             }
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir             // store current styles in "*End***" variables
1120cdf0e10cSrcweir             aEndRFromTL = aRFromTL;
1121cdf0e10cSrcweir             pEndRFromT = &rRFromT;
1122cdf0e10cSrcweir             pEndRFromR = &rRFromR;
1123cdf0e10cSrcweir             pEndRFromB = &rRFromB;
1124cdf0e10cSrcweir             aEndRFromBL = aRFromBL;
1125cdf0e10cSrcweir         }
1126cdf0e10cSrcweir 
1127cdf0e10cSrcweir         // draw last frame border
1128cdf0e10cSrcweir         Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
1129cdf0e10cSrcweir         if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
1130cdf0e10cSrcweir             DrawHorFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1131cdf0e10cSrcweir                 aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
1132cdf0e10cSrcweir                 aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor );
1133cdf0e10cSrcweir     }
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir     // *** vertical frame borders ***
1136cdf0e10cSrcweir 
1137cdf0e10cSrcweir     for( nCol = nFirstCol; nCol <= nLastCol + 1; ++nCol )
1138cdf0e10cSrcweir     {
1139cdf0e10cSrcweir         double fAngle = mxImpl->GetVerDiagAngle( nCol, nFirstRow );
1140cdf0e10cSrcweir         double fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nFirstRow );
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir         // *Start*** variables store the data of the top end of the cached frame border
1143cdf0e10cSrcweir         Point aStartPos( mxImpl->GetColPosition( nCol ), mxImpl->GetRowPosition( nFirstRow ) );
1144cdf0e10cSrcweir         const Style* pStart = &GetCellStyleLeft( nCol, nFirstRow );
1145cdf0e10cSrcweir         DiagStyle aStartTFromBL( GetCellStyleTR( nCol - 1, nFirstRow ), fLAngle );
1146cdf0e10cSrcweir         const Style* pStartTFromL = &GetCellStyleTop( nCol - 1, nFirstRow );
1147cdf0e10cSrcweir         const Style* pStartTFromT = &GetCellStyleLeft( nCol, nFirstRow - 1 );
1148cdf0e10cSrcweir         const Style* pStartTFromR = &GetCellStyleTop( nCol, nFirstRow );
1149cdf0e10cSrcweir         DiagStyle aStartTFromBR( GetCellStyleTL( nCol, nFirstRow ), fAngle );
1150cdf0e10cSrcweir 
1151cdf0e10cSrcweir         // *End*** variables store the data of the bottom end of the cached frame border
1152cdf0e10cSrcweir         DiagStyle aEndBFromTL( GetCellStyleBR( nCol - 1, nFirstRow ), fLAngle );
1153cdf0e10cSrcweir         const Style* pEndBFromL = &GetCellStyleBottom( nCol - 1, nFirstRow );
1154cdf0e10cSrcweir         const Style* pEndBFromB = &GetCellStyleLeft( nCol, nFirstRow + 1 );
1155cdf0e10cSrcweir         const Style* pEndBFromR = &GetCellStyleBottom( nCol, nFirstRow );
1156cdf0e10cSrcweir         DiagStyle aEndBFromTR( GetCellStyleBL( nCol, nFirstRow ), fAngle );
1157cdf0e10cSrcweir 
1158cdf0e10cSrcweir         for( nRow = nFirstRow + 1; nRow <= nLastRow; ++nRow )
1159cdf0e10cSrcweir         {
1160cdf0e10cSrcweir             fAngle = mxImpl->GetVerDiagAngle( nCol, nRow );
1161cdf0e10cSrcweir             fLAngle = mxImpl->GetVerDiagAngle( nCol - 1, nRow );
1162cdf0e10cSrcweir 
1163cdf0e10cSrcweir             const Style& rCurr = *pEndBFromB;
1164cdf0e10cSrcweir 
1165cdf0e10cSrcweir             DiagStyle aTFromBL( GetCellStyleTR( nCol - 1, nRow ), fLAngle );
1166cdf0e10cSrcweir             const Style& rTFromL = *pEndBFromL;
1167cdf0e10cSrcweir             const Style& rTFromT = *pStart;
1168cdf0e10cSrcweir             const Style& rTFromR = *pEndBFromR;
1169cdf0e10cSrcweir             DiagStyle aTFromBR( GetCellStyleTL( nCol, nRow ), fAngle );
1170cdf0e10cSrcweir 
1171cdf0e10cSrcweir             DiagStyle aBFromTL( GetCellStyleBR( nCol - 1, nRow ), fLAngle );
1172cdf0e10cSrcweir             const Style& rBFromL = GetCellStyleBottom( nCol - 1, nRow );
1173cdf0e10cSrcweir             const Style& rBFromB = GetCellStyleLeft( nCol, nRow + 1 );
1174cdf0e10cSrcweir             const Style& rBFromR = GetCellStyleBottom( nCol, nRow );
1175cdf0e10cSrcweir             DiagStyle aBFromTR( GetCellStyleBL( nCol, nRow ), fAngle );
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir             // check if current frame border can be connected to cached frame border
1178cdf0e10cSrcweir             if( !CheckFrameBorderConnectable( *pStart, rCurr,
1179cdf0e10cSrcweir                     aEndBFromTL, rTFromL, aTFromBL, aEndBFromTR, rTFromR, aTFromBR ) )
1180cdf0e10cSrcweir             {
1181cdf0e10cSrcweir                 // draw previous frame border
1182cdf0e10cSrcweir                 Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
1183cdf0e10cSrcweir                 if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
1184cdf0e10cSrcweir                     DrawVerFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1185cdf0e10cSrcweir                         aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR,
1186cdf0e10cSrcweir                         aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR, pForceColor );
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir                 // re-init "*Start***" variables
1189cdf0e10cSrcweir                 aStartPos = aEndPos;
1190cdf0e10cSrcweir                 pStart = &rCurr;
1191cdf0e10cSrcweir                 aStartTFromBL = aTFromBL;
1192cdf0e10cSrcweir                 pStartTFromL = &rTFromL;
1193cdf0e10cSrcweir                 pStartTFromT = &rTFromT;
1194cdf0e10cSrcweir                 pStartTFromR = &rTFromR;
1195cdf0e10cSrcweir                 aStartTFromBR = aTFromBR;
1196cdf0e10cSrcweir             }
1197cdf0e10cSrcweir 
1198cdf0e10cSrcweir             // store current styles in "*End***" variables
1199cdf0e10cSrcweir             aEndBFromTL = aBFromTL;
1200cdf0e10cSrcweir             pEndBFromL = &rBFromL;
1201cdf0e10cSrcweir             pEndBFromB = &rBFromB;
1202cdf0e10cSrcweir             pEndBFromR = &rBFromR;
1203cdf0e10cSrcweir             aEndBFromTR = aBFromTR;
1204cdf0e10cSrcweir         }
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir         // draw last frame border
1207cdf0e10cSrcweir         Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
1208cdf0e10cSrcweir         if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
1209cdf0e10cSrcweir             DrawVerFrameBorder( rDev, aStartPos, aEndPos, *pStart,
1210cdf0e10cSrcweir                 aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR,
1211cdf0e10cSrcweir                 aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR, pForceColor );
1212cdf0e10cSrcweir     }
1213cdf0e10cSrcweir }
1214cdf0e10cSrcweir 
DrawArray(OutputDevice & rDev,const Color * pForceColor) const1215cdf0e10cSrcweir void Array::DrawArray( OutputDevice& rDev, const Color* pForceColor ) const
1216cdf0e10cSrcweir {
1217cdf0e10cSrcweir     if( mxImpl->mnWidth && mxImpl->mnHeight )
1218cdf0e10cSrcweir         DrawRange( rDev, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1, pForceColor );
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir // ----------------------------------------------------------------------------
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir #undef ORIGCELLACC
1224cdf0e10cSrcweir #undef ORIGCELL
1225cdf0e10cSrcweir #undef CELLACC
1226cdf0e10cSrcweir #undef CELL
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir // ----------------------------------------------------------------------------
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir #undef DBG_FRAME_CHECK_ROW_1
1231cdf0e10cSrcweir #undef DBG_FRAME_CHECK_COL_1
1232cdf0e10cSrcweir #undef DBG_FRAME_CHECK_INDEX
1233cdf0e10cSrcweir #undef DBG_FRAME_CHECK_COLROW
1234cdf0e10cSrcweir #undef DBG_FRAME_CHECK_ROW
1235cdf0e10cSrcweir #undef DBG_FRAME_CHECK_COL
1236cdf0e10cSrcweir #undef DBG_FRAME_CHECK
1237cdf0e10cSrcweir #undef DBG_FRAME_ERROR
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir // ============================================================================
1240cdf0e10cSrcweir 
1241cdf0e10cSrcweir } // namespace frame
1242cdf0e10cSrcweir } // namespace svx
1243cdf0e10cSrcweir 
1244