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