xref: /AOO41X/main/sc/source/ui/view/output.cxx (revision d8ed516ea0fc6892f985be7d5d4e6d1de071d97b)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <com/sun/star/embed/EmbedMisc.hpp>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "scitems.hxx"
32cdf0e10cSrcweir #include <editeng/boxitem.hxx>
33cdf0e10cSrcweir #include <editeng/brshitem.hxx>
34cdf0e10cSrcweir #include <editeng/editdata.hxx>
35cdf0e10cSrcweir #include <svtools/colorcfg.hxx>
36cdf0e10cSrcweir #include <svx/rotmodit.hxx>
37cdf0e10cSrcweir #include <editeng/shaditem.hxx>
38cdf0e10cSrcweir #include <editeng/svxfont.hxx>
39cdf0e10cSrcweir #include <svx/svdoole2.hxx>
40cdf0e10cSrcweir #include <tools/poly.hxx>
41cdf0e10cSrcweir #include <vcl/svapp.hxx>
42cdf0e10cSrcweir #include <vcl/pdfextoutdevdata.hxx>
43cdf0e10cSrcweir #include <svtools/accessibilityoptions.hxx>
44cdf0e10cSrcweir #include <svx/framelinkarray.hxx>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include "output.hxx"
47cdf0e10cSrcweir #include "document.hxx"
48cdf0e10cSrcweir #include "cell.hxx"
49cdf0e10cSrcweir #include "attrib.hxx"
50cdf0e10cSrcweir #include "patattr.hxx"
51cdf0e10cSrcweir #include "docpool.hxx"
52cdf0e10cSrcweir #include "tabvwsh.hxx"
53cdf0e10cSrcweir #include "progress.hxx"
54cdf0e10cSrcweir #include "pagedata.hxx"
55cdf0e10cSrcweir #include "chgtrack.hxx"
56cdf0e10cSrcweir #include "chgviset.hxx"
57cdf0e10cSrcweir #include "viewutil.hxx"
58cdf0e10cSrcweir #include "gridmerg.hxx"
59cdf0e10cSrcweir #include "invmerge.hxx"
60cdf0e10cSrcweir #include "fillinfo.hxx"
61cdf0e10cSrcweir #include "scmod.hxx"
62cdf0e10cSrcweir #include "appoptio.hxx"
63cdf0e10cSrcweir #include "postit.hxx"
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #include <math.h>
66cdf0e10cSrcweir 
67cdf0e10cSrcweir using namespace com::sun::star;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
70cdf0e10cSrcweir 
71cdf0e10cSrcweir //	Farben fuer ChangeTracking "nach Autor" wie im Writer (swmodul1.cxx)
72cdf0e10cSrcweir 
73cdf0e10cSrcweir #define SC_AUTHORCOLORCOUNT		9
74cdf0e10cSrcweir 
75cdf0e10cSrcweir static ColorData nAuthorColor[ SC_AUTHORCOLORCOUNT ] = {
76cdf0e10cSrcweir 					COL_LIGHTRED, 		COL_LIGHTBLUE,		COL_LIGHTMAGENTA,
77cdf0e10cSrcweir 					COL_GREEN,			COL_RED,			COL_BLUE,
78cdf0e10cSrcweir 					COL_BROWN,			COL_MAGENTA,		COL_CYAN };
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //	Hilfsklasse, fuer die Farbzuordnung,
81cdf0e10cSrcweir //	um nicht mehrfach hintereinander denselben User aus der Liste zu suchen
82cdf0e10cSrcweir 
83cdf0e10cSrcweir class ScActionColorChanger
84cdf0e10cSrcweir {
85cdf0e10cSrcweir private:
86cdf0e10cSrcweir 	const ScAppOptions&		rOpt;
87cdf0e10cSrcweir 	const ScStrCollection&	rUsers;
88cdf0e10cSrcweir 	String					aLastUserName;
89cdf0e10cSrcweir 	sal_uInt16					nLastUserIndex;
90cdf0e10cSrcweir 	ColorData				nColor;
91cdf0e10cSrcweir 
92cdf0e10cSrcweir public:
93cdf0e10cSrcweir 				ScActionColorChanger( const ScChangeTrack& rTrack );
94cdf0e10cSrcweir 				~ScActionColorChanger() {}
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 	void		Update( const ScChangeAction& rAction );
97cdf0e10cSrcweir 	ColorData	GetColor() const	{ return nColor; }
98cdf0e10cSrcweir };
99cdf0e10cSrcweir 
100cdf0e10cSrcweir //------------------------------------------------------------------
101cdf0e10cSrcweir 
102cdf0e10cSrcweir ScActionColorChanger::ScActionColorChanger( const ScChangeTrack& rTrack ) :
103cdf0e10cSrcweir 	rOpt( SC_MOD()->GetAppOptions() ),
104cdf0e10cSrcweir 	rUsers( rTrack.GetUserCollection() ),
105cdf0e10cSrcweir 	nLastUserIndex( 0 ),
106cdf0e10cSrcweir 	nColor( COL_BLACK )
107cdf0e10cSrcweir {
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
110cdf0e10cSrcweir void ScActionColorChanger::Update( const ScChangeAction& rAction )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir 	ColorData nSetColor;
113cdf0e10cSrcweir 	switch (rAction.GetType())
114cdf0e10cSrcweir 	{
115cdf0e10cSrcweir 		case SC_CAT_INSERT_COLS:
116cdf0e10cSrcweir 		case SC_CAT_INSERT_ROWS:
117cdf0e10cSrcweir 		case SC_CAT_INSERT_TABS:
118cdf0e10cSrcweir 			nSetColor = rOpt.GetTrackInsertColor();
119cdf0e10cSrcweir 			break;
120cdf0e10cSrcweir 		case SC_CAT_DELETE_COLS:
121cdf0e10cSrcweir 		case SC_CAT_DELETE_ROWS:
122cdf0e10cSrcweir 		case SC_CAT_DELETE_TABS:
123cdf0e10cSrcweir 			nSetColor = rOpt.GetTrackDeleteColor();
124cdf0e10cSrcweir 			break;
125cdf0e10cSrcweir 		case SC_CAT_MOVE:
126cdf0e10cSrcweir 			nSetColor = rOpt.GetTrackMoveColor();
127cdf0e10cSrcweir 			break;
128cdf0e10cSrcweir 		default:
129cdf0e10cSrcweir 			nSetColor = rOpt.GetTrackContentColor();
130cdf0e10cSrcweir 			break;
131cdf0e10cSrcweir 	}
132cdf0e10cSrcweir 	if ( nSetColor != COL_TRANSPARENT )		// Farbe eingestellt
133cdf0e10cSrcweir 		nColor = nSetColor;
134cdf0e10cSrcweir 	else									// nach Autor
135cdf0e10cSrcweir 	{
136cdf0e10cSrcweir 		if ( rAction.GetUser() != aLastUserName )
137cdf0e10cSrcweir 		{
138cdf0e10cSrcweir 			aLastUserName = rAction.GetUser();
139cdf0e10cSrcweir 			StrData aData(aLastUserName);
140cdf0e10cSrcweir 			sal_uInt16 nIndex;
141cdf0e10cSrcweir 			if (!rUsers.Search(&aData, nIndex))
142cdf0e10cSrcweir 			{
143cdf0e10cSrcweir 				// empty string is possible if a name wasn't found while saving a 5.0 file
144cdf0e10cSrcweir 				DBG_ASSERT( aLastUserName.Len() == 0, "Author not found" );
145cdf0e10cSrcweir 				nIndex = 0;
146cdf0e10cSrcweir 			}
147cdf0e10cSrcweir 			nLastUserIndex = nIndex % SC_AUTHORCOLORCOUNT;
148cdf0e10cSrcweir 		}
149cdf0e10cSrcweir 		nColor = nAuthorColor[nLastUserIndex];
150cdf0e10cSrcweir 	}
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir //==================================================================
154cdf0e10cSrcweir 
155cdf0e10cSrcweir ScOutputData::ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
156cdf0e10cSrcweir                             ScTableInfo& rTabInfo, ScDocument* pNewDoc,
157cdf0e10cSrcweir 							SCTAB nNewTab, long nNewScrX, long nNewScrY,
158cdf0e10cSrcweir 							SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2,
159cdf0e10cSrcweir 							double nPixelPerTwipsX, double nPixelPerTwipsY,
160cdf0e10cSrcweir 							const Fraction* pZoomX, const Fraction* pZoomY ) :
161cdf0e10cSrcweir 	pDev( pNewDev ),
162cdf0e10cSrcweir 	pRefDevice( pNewDev ),		// default is output device
163cdf0e10cSrcweir 	pFmtDevice( pNewDev ),		// default is output device
164cdf0e10cSrcweir     mrTabInfo( rTabInfo ),
165cdf0e10cSrcweir     pRowInfo( rTabInfo.mpRowInfo ),
166cdf0e10cSrcweir     nArrCount( rTabInfo.mnArrCount ),
167cdf0e10cSrcweir 	pDoc( pNewDoc ),
168cdf0e10cSrcweir 	nTab( nNewTab ),
169cdf0e10cSrcweir 	nScrX( nNewScrX ),
170cdf0e10cSrcweir 	nScrY( nNewScrY ),
171cdf0e10cSrcweir 	nX1( nNewX1 ),
172cdf0e10cSrcweir 	nY1( nNewY1 ),
173cdf0e10cSrcweir 	nX2( nNewX2 ),
174cdf0e10cSrcweir 	nY2( nNewY2 ),
175cdf0e10cSrcweir 	eType( eNewType ),
176cdf0e10cSrcweir 	nPPTX( nPixelPerTwipsX ),
177cdf0e10cSrcweir 	nPPTY( nPixelPerTwipsY ),
178cdf0e10cSrcweir 	pEditObj( NULL ),
179cdf0e10cSrcweir 	pViewShell( NULL ),
180cdf0e10cSrcweir 	pDrawView( NULL ), // #114135#
181cdf0e10cSrcweir 	bEditMode( sal_False ),
182cdf0e10cSrcweir 	bMetaFile( sal_False ),
183cdf0e10cSrcweir 	bSingleGrid( sal_False ),
184cdf0e10cSrcweir 	bPagebreakMode( sal_False ),
185cdf0e10cSrcweir 	bSolidBackground( sal_False ),
186cdf0e10cSrcweir 	bUseStyleColor( sal_False ),
187cdf0e10cSrcweir 	bForceAutoColor( SC_MOD()->GetAccessOptions().GetIsAutomaticFontColor() ),
188cdf0e10cSrcweir 	bSyntaxMode( sal_False ),
189cdf0e10cSrcweir 	pValueColor( NULL ),
190cdf0e10cSrcweir 	pTextColor( NULL ),
191cdf0e10cSrcweir 	pFormulaColor( NULL ),
192cdf0e10cSrcweir 	aGridColor( COL_BLACK ),
193cdf0e10cSrcweir 	bShowNullValues( sal_True ),
194cdf0e10cSrcweir 	bShowFormulas( sal_False ),
195cdf0e10cSrcweir 	bShowSpellErrors( sal_False ),
196cdf0e10cSrcweir 	bMarkClipped( sal_False ),			// sal_False fuer Drucker/Metafile etc.
197cdf0e10cSrcweir 	bSnapPixel( sal_False ),
198cdf0e10cSrcweir 	bAnyRotated( sal_False ),
199cdf0e10cSrcweir 	bAnyClipped( sal_False ),
200cdf0e10cSrcweir 	mpTargetPaintWindow(0) // #i74769# use SdrPaintWindow direct
201cdf0e10cSrcweir {
202cdf0e10cSrcweir 	if (pZoomX)
203cdf0e10cSrcweir 		aZoomX = *pZoomX;
204cdf0e10cSrcweir 	else
205cdf0e10cSrcweir 		aZoomX = Fraction(1,1);
206cdf0e10cSrcweir 	if (pZoomY)
207cdf0e10cSrcweir 		aZoomY = *pZoomY;
208cdf0e10cSrcweir 	else
209cdf0e10cSrcweir 		aZoomY = Fraction(1,1);
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 	nVisX1 = nX1;
212cdf0e10cSrcweir 	nVisY1 = nY1;
213cdf0e10cSrcweir 	nVisX2 = nX2;
214cdf0e10cSrcweir 	nVisY2 = nY2;
215cdf0e10cSrcweir 	pDoc->StripHidden( nVisX1, nVisY1, nVisX2, nVisY2, nTab );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 	nScrW = 0;
218cdf0e10cSrcweir 	for (SCCOL nX=nVisX1; nX<=nVisX2; nX++)
219cdf0e10cSrcweir 		nScrW += pRowInfo[0].pCellInfo[nX+1].nWidth;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir 	nMirrorW = nScrW;
222cdf0e10cSrcweir 
223cdf0e10cSrcweir 	nScrH = 0;
224cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
225cdf0e10cSrcweir 		nScrH += pRowInfo[nArrY].nHeight;
226cdf0e10cSrcweir 
227cdf0e10cSrcweir 	bTabProtected = pDoc->IsTabProtected( nTab );
228cdf0e10cSrcweir 	nTabTextDirection = pDoc->GetEditTextDirection( nTab );
229cdf0e10cSrcweir 	bLayoutRTL = pDoc->IsLayoutRTL( nTab );
230cdf0e10cSrcweir }
231cdf0e10cSrcweir 
232cdf0e10cSrcweir ScOutputData::~ScOutputData()
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	delete pValueColor;
235cdf0e10cSrcweir 	delete pTextColor;
236cdf0e10cSrcweir 	delete pFormulaColor;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir void ScOutputData::SetContentDevice( OutputDevice* pContentDev )
240cdf0e10cSrcweir {
241cdf0e10cSrcweir     // use pContentDev instead of pDev where used
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     if ( pRefDevice == pDev )
244cdf0e10cSrcweir         pRefDevice = pContentDev;
245cdf0e10cSrcweir     if ( pFmtDevice == pDev )
246cdf0e10cSrcweir         pFmtDevice = pContentDev;
247cdf0e10cSrcweir     pDev = pContentDev;
248cdf0e10cSrcweir }
249cdf0e10cSrcweir 
250cdf0e10cSrcweir void ScOutputData::SetMirrorWidth( long nNew )
251cdf0e10cSrcweir {
252cdf0e10cSrcweir 	nMirrorW = nNew;
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir void ScOutputData::SetGridColor( const Color& rColor )
256cdf0e10cSrcweir {
257cdf0e10cSrcweir 	aGridColor = rColor;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir void ScOutputData::SetMarkClipped( sal_Bool bSet )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir 	bMarkClipped = bSet;
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir void ScOutputData::SetShowNullValues( sal_Bool bSet )
266cdf0e10cSrcweir {
267cdf0e10cSrcweir 	bShowNullValues = bSet;
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
270cdf0e10cSrcweir void ScOutputData::SetShowFormulas( sal_Bool bSet )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir 	bShowFormulas = bSet;
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir void ScOutputData::SetShowSpellErrors( sal_Bool bSet )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir 	bShowSpellErrors = bSet;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir void ScOutputData::SetSnapPixel( sal_Bool bSet )
281cdf0e10cSrcweir {
282cdf0e10cSrcweir 	bSnapPixel = bSet;
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir void ScOutputData::SetEditCell( SCCOL nCol, SCROW nRow )
286cdf0e10cSrcweir {
287cdf0e10cSrcweir 	nEditCol = nCol;
288cdf0e10cSrcweir 	nEditRow = nRow;
289cdf0e10cSrcweir 	bEditMode = sal_True;
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir void ScOutputData::SetMetaFileMode( sal_Bool bNewMode )
293cdf0e10cSrcweir {
294cdf0e10cSrcweir 	bMetaFile = bNewMode;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir 
297cdf0e10cSrcweir void ScOutputData::SetSingleGrid( sal_Bool bNewMode )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir 	bSingleGrid = bNewMode;
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir void ScOutputData::SetSyntaxMode( sal_Bool bNewMode )
303cdf0e10cSrcweir {
304cdf0e10cSrcweir 	bSyntaxMode = bNewMode;
305cdf0e10cSrcweir 	if (bNewMode)
306cdf0e10cSrcweir 		if (!pValueColor)
307cdf0e10cSrcweir 		{
308cdf0e10cSrcweir 			pValueColor = new Color( COL_LIGHTBLUE );
309cdf0e10cSrcweir 			pTextColor = new Color( COL_BLACK );
310cdf0e10cSrcweir 			pFormulaColor = new Color( COL_GREEN );
311cdf0e10cSrcweir 		}
312cdf0e10cSrcweir }
313cdf0e10cSrcweir 
314cdf0e10cSrcweir void ScOutputData::DrawGrid( sal_Bool bGrid, sal_Bool bPage )
315cdf0e10cSrcweir {
316cdf0e10cSrcweir 	SCCOL nX;
317cdf0e10cSrcweir 	SCROW nY;
318cdf0e10cSrcweir 	long nPosX;
319cdf0e10cSrcweir 	long nPosY;
320cdf0e10cSrcweir 	SCSIZE nArrY;
321cdf0e10cSrcweir     ScBreakType nBreak    = BREAK_NONE;
322cdf0e10cSrcweir     ScBreakType nBreakOld = BREAK_NONE;
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 	sal_Bool bSingle;
325cdf0e10cSrcweir 	Color aPageColor;
326cdf0e10cSrcweir 	Color aManualColor;
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 	if (bPagebreakMode)
329cdf0e10cSrcweir 		bPage = sal_False;			// keine "normalen" Umbrueche ueber volle Breite/Hoehe
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 	//!	um den einen Pixel sieht das Metafile (oder die Druck-Ausgabe) anders aus
332cdf0e10cSrcweir 	//!	als die Bildschirmdarstellung, aber wenigstens passen Druck und Metafile zusammen
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
335cdf0e10cSrcweir 	long nOneX = aOnePixel.Width();
336cdf0e10cSrcweir 	long nOneY = aOnePixel.Height();
337cdf0e10cSrcweir 	if (bMetaFile)
338cdf0e10cSrcweir 		nOneX = nOneY = 1;
339cdf0e10cSrcweir 
340cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
341cdf0e10cSrcweir 	long nSignedOneX = nOneX * nLayoutSign;
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 	if ( eType == OUTTYPE_WINDOW )
344cdf0e10cSrcweir 	{
345cdf0e10cSrcweir         const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
346cdf0e10cSrcweir         aPageColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor );
347cdf0e10cSrcweir         aManualColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
348cdf0e10cSrcweir 	}
349cdf0e10cSrcweir 	else
350cdf0e10cSrcweir 	{
351cdf0e10cSrcweir 		aPageColor = aGridColor;
352cdf0e10cSrcweir 		aManualColor = aGridColor;
353cdf0e10cSrcweir 	}
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 	pDev->SetLineColor( aGridColor );
356cdf0e10cSrcweir 	ScGridMerger aGrid( pDev, nOneX, nOneY );
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 										//
359cdf0e10cSrcweir 										//	Vertikale Linien
360cdf0e10cSrcweir 										//
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 	nPosX = nScrX;
363cdf0e10cSrcweir 	if ( bLayoutRTL )
364cdf0e10cSrcweir 		nPosX += nMirrorW - nOneX;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir 	for (nX=nX1; nX<=nX2; nX++)
367cdf0e10cSrcweir 	{
368cdf0e10cSrcweir 		SCCOL nXplus1 = nX+1;
369cdf0e10cSrcweir 		SCCOL nXplus2 = nX+2;
370cdf0e10cSrcweir 		sal_uInt16 nWidth = pRowInfo[0].pCellInfo[nXplus1].nWidth;
371cdf0e10cSrcweir 		if (nWidth)
372cdf0e10cSrcweir 		{
373cdf0e10cSrcweir 			nPosX += nWidth * nLayoutSign;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 			if ( bPage )
376cdf0e10cSrcweir 			{
377cdf0e10cSrcweir 				//	Seitenumbrueche auch in ausgeblendeten suchen
378cdf0e10cSrcweir 				SCCOL nCol = nXplus1;
379cdf0e10cSrcweir 				while (nCol <= MAXCOL)
380cdf0e10cSrcweir 				{
381cdf0e10cSrcweir                     nBreak = pDoc->HasColBreak(nCol, nTab);
382cdf0e10cSrcweir                     bool bHidden = pDoc->ColHidden(nCol, nTab);
383cdf0e10cSrcweir 
384cdf0e10cSrcweir                     if ( nBreak || !bHidden )
385cdf0e10cSrcweir 						break;
386cdf0e10cSrcweir 					++nCol;
387cdf0e10cSrcweir 				}
388cdf0e10cSrcweir 
389cdf0e10cSrcweir                 if (nBreak != nBreakOld)
390cdf0e10cSrcweir 				{
391cdf0e10cSrcweir 					aGrid.Flush();
392cdf0e10cSrcweir                     pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
393cdf0e10cSrcweir                                         nBreak ? aPageColor : aGridColor );
394cdf0e10cSrcweir                     nBreakOld = nBreak;
395cdf0e10cSrcweir 				}
396cdf0e10cSrcweir 			}
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 			sal_Bool bDraw = bGrid || nBreakOld;	// einfaches Gitter nur wenn eingestellt
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 			//!	Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
401cdf0e10cSrcweir 			//!	Umbruch mitten in den Wiederholungsspalten liegt.
402cdf0e10cSrcweir 			//!	Dann lieber den aeusseren Rahmen zweimal ausgeben...
403cdf0e10cSrcweir #if 0
404cdf0e10cSrcweir 			//	auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
405cdf0e10cSrcweir 			if ( eType == OUTTYPE_PRINTER && !bMetaFile )
406cdf0e10cSrcweir 			{
407cdf0e10cSrcweir 				if ( nX == MAXCOL )
408cdf0e10cSrcweir 					bDraw = sal_False;
409cdf0e10cSrcweir                 else if (pDoc->HasColBreak(nXplus1, nTab))
410cdf0e10cSrcweir 					bDraw = sal_False;
411cdf0e10cSrcweir 			}
412cdf0e10cSrcweir #endif
413cdf0e10cSrcweir 
414cdf0e10cSrcweir 			sal_uInt16 nWidthXplus2 = pRowInfo[0].pCellInfo[nXplus2].nWidth;
415cdf0e10cSrcweir 			bSingle = bSingleGrid;									//! in Fillinfo holen !!!!!
416cdf0e10cSrcweir 			if ( nX<MAXCOL && !bSingle )
417cdf0e10cSrcweir 			{
418cdf0e10cSrcweir 				bSingle = ( nWidthXplus2 == 0 );
419cdf0e10cSrcweir 				for (nArrY=1; nArrY+1<nArrCount && !bSingle; nArrY++)
420cdf0e10cSrcweir 				{
421cdf0e10cSrcweir 					if (pRowInfo[nArrY].pCellInfo[nXplus2].bHOverlapped)
422cdf0e10cSrcweir 						bSingle = sal_True;
423cdf0e10cSrcweir 					if (pRowInfo[nArrY].pCellInfo[nXplus1].bHideGrid)
424cdf0e10cSrcweir 						bSingle = sal_True;
425cdf0e10cSrcweir 				}
426cdf0e10cSrcweir 			}
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 			if (bDraw)
429cdf0e10cSrcweir 			{
430cdf0e10cSrcweir 				if ( nX<MAXCOL && bSingle )
431cdf0e10cSrcweir 				{
432cdf0e10cSrcweir 					SCCOL nVisX = nXplus1;
433cdf0e10cSrcweir 					while ( nVisX < MAXCOL && !pDoc->GetColWidth(nVisX,nTab) )
434cdf0e10cSrcweir 						++nVisX;
435cdf0e10cSrcweir 
436cdf0e10cSrcweir 					nPosY = nScrY;
437cdf0e10cSrcweir 					long nNextY;
438cdf0e10cSrcweir 					for (nArrY=1; nArrY+1<nArrCount; nArrY++)
439cdf0e10cSrcweir 					{
440cdf0e10cSrcweir 						RowInfo* pThisRowInfo = &pRowInfo[nArrY];
441cdf0e10cSrcweir 						nNextY = nPosY + pThisRowInfo->nHeight;
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 						sal_Bool bHOver = pThisRowInfo->pCellInfo[nXplus1].bHideGrid;
444cdf0e10cSrcweir 						if (!bHOver)
445cdf0e10cSrcweir 						{
446cdf0e10cSrcweir 							if (nWidthXplus2)
447cdf0e10cSrcweir 								bHOver = pThisRowInfo->pCellInfo[nXplus2].bHOverlapped;
448cdf0e10cSrcweir 							else
449cdf0e10cSrcweir 							{
450cdf0e10cSrcweir 								if (nVisX <= nX2)
451cdf0e10cSrcweir 									bHOver = pThisRowInfo->pCellInfo[nVisX+1].bHOverlapped;
452cdf0e10cSrcweir 								else
453cdf0e10cSrcweir 									bHOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
454cdf0e10cSrcweir 												nVisX,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
455cdf0e10cSrcweir 												->IsHorOverlapped();
456cdf0e10cSrcweir 								if (bHOver)
457cdf0e10cSrcweir 									bHOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
458cdf0e10cSrcweir 												nXplus1,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
459cdf0e10cSrcweir 												->IsHorOverlapped();
460cdf0e10cSrcweir 							}
461cdf0e10cSrcweir 						}
462cdf0e10cSrcweir 
463cdf0e10cSrcweir 						if (pThisRowInfo->bChanged && !bHOver)
464cdf0e10cSrcweir 						{
465cdf0e10cSrcweir 							//Point aStart( nPosX-nSignedOneX, nPosY );
466cdf0e10cSrcweir 							//Point aEnd( nPosX-nSignedOneX, nNextY-nOneY );
467cdf0e10cSrcweir 							//pDev->DrawLine( aStart, aEnd );
468cdf0e10cSrcweir 							aGrid.AddVerLine( nPosX-nSignedOneX, nPosY, nNextY-nOneY );
469cdf0e10cSrcweir 						}
470cdf0e10cSrcweir 						nPosY = nNextY;
471cdf0e10cSrcweir 					}
472cdf0e10cSrcweir 				}
473cdf0e10cSrcweir 				else
474cdf0e10cSrcweir 				{
475cdf0e10cSrcweir 					//Point aStart( nPosX-nSignedOneX, nScrY );
476cdf0e10cSrcweir 					//Point aEnd( nPosX-nSignedOneX, nScrY+nScrH-nOneY );
477cdf0e10cSrcweir 					//pDev->DrawLine( aStart, aEnd );
478cdf0e10cSrcweir 					aGrid.AddVerLine( nPosX-nSignedOneX, nScrY, nScrY+nScrH-nOneY );
479cdf0e10cSrcweir 				}
480cdf0e10cSrcweir 			}
481cdf0e10cSrcweir 		}
482cdf0e10cSrcweir 	}
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 										//
485cdf0e10cSrcweir 										//	Horizontale Linien
486cdf0e10cSrcweir 										//
487cdf0e10cSrcweir 
488cdf0e10cSrcweir     bool bHiddenRow = true;
489cdf0e10cSrcweir     SCROW nHiddenEndRow = -1;
490cdf0e10cSrcweir 	nPosY = nScrY;
491cdf0e10cSrcweir 	for (nArrY=1; nArrY+1<nArrCount; nArrY++)
492cdf0e10cSrcweir 	{
493cdf0e10cSrcweir 		SCSIZE nArrYplus1 = nArrY+1;
494cdf0e10cSrcweir 		nY = pRowInfo[nArrY].nRowNo;
495cdf0e10cSrcweir 		SCROW nYplus1 = nY+1;
496cdf0e10cSrcweir 		nPosY += pRowInfo[nArrY].nHeight;
497cdf0e10cSrcweir 
498cdf0e10cSrcweir 		if (pRowInfo[nArrY].bChanged)
499cdf0e10cSrcweir 		{
500cdf0e10cSrcweir 			if ( bPage )
501cdf0e10cSrcweir 			{
502cdf0e10cSrcweir                 for (SCROW i = nYplus1; i <= MAXROW; ++i)
503cdf0e10cSrcweir                 {
504cdf0e10cSrcweir                     if (i > nHiddenEndRow)
505cdf0e10cSrcweir                         bHiddenRow = pDoc->RowHidden(i, nTab, nHiddenEndRow);
506cdf0e10cSrcweir                     /* TODO: optimize the row break thing for large hidden
507cdf0e10cSrcweir                      * segments where HasRowBreak() has to be called
508cdf0e10cSrcweir                      * nevertheless for each row, as a row break is drawn also
509cdf0e10cSrcweir                      * for hidden rows, above them. This needed to be done only
510cdf0e10cSrcweir                      * once per hidden segment, maybe giving manual breaks
511cdf0e10cSrcweir                      * priority. Something like GetNextRowBreak() and
512cdf0e10cSrcweir                      * GetNextManualRowBreak(). */
513cdf0e10cSrcweir                     nBreak = pDoc->HasRowBreak(i, nTab);
514cdf0e10cSrcweir                     if (!bHiddenRow || nBreak)
515cdf0e10cSrcweir                         break;
516cdf0e10cSrcweir                 }
517cdf0e10cSrcweir 
518cdf0e10cSrcweir                 if (nBreakOld != nBreak)
519cdf0e10cSrcweir 				{
520cdf0e10cSrcweir 					aGrid.Flush();
521cdf0e10cSrcweir 					pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
522cdf0e10cSrcweir                                         (nBreak) ? aPageColor : aGridColor );
523cdf0e10cSrcweir                     nBreakOld = nBreak;
524cdf0e10cSrcweir 				}
525cdf0e10cSrcweir 			}
526cdf0e10cSrcweir 
527cdf0e10cSrcweir 			sal_Bool bDraw = bGrid || nBreakOld;	// einfaches Gitter nur wenn eingestellt
528cdf0e10cSrcweir 
529cdf0e10cSrcweir 			//!	Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
530cdf0e10cSrcweir 			//!	Umbruch mitten in den Wiederholungszeilen liegt.
531cdf0e10cSrcweir 			//!	Dann lieber den aeusseren Rahmen zweimal ausgeben...
532cdf0e10cSrcweir #if 0
533cdf0e10cSrcweir 			//	auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
534cdf0e10cSrcweir 			if ( eType == OUTTYPE_PRINTER && !bMetaFile )
535cdf0e10cSrcweir 			{
536cdf0e10cSrcweir 				if ( nY == MAXROW )
537cdf0e10cSrcweir 					bDraw = sal_False;
538cdf0e10cSrcweir                 else if (pDoc->HasRowBreak(nYplus1, nTab))
539cdf0e10cSrcweir 					bDraw = sal_False;
540cdf0e10cSrcweir 			}
541cdf0e10cSrcweir #endif
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 			sal_Bool bNextYisNextRow = (pRowInfo[nArrYplus1].nRowNo == nYplus1);
544cdf0e10cSrcweir 			bSingle = !bNextYisNextRow;				// Hidden
545cdf0e10cSrcweir 			for (SCCOL i=nX1; i<=nX2 && !bSingle; i++)
546cdf0e10cSrcweir 			{
547cdf0e10cSrcweir 				if (pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped)
548cdf0e10cSrcweir 					bSingle = sal_True;
549cdf0e10cSrcweir 			}
550cdf0e10cSrcweir 
551cdf0e10cSrcweir 			if (bDraw)
552cdf0e10cSrcweir 			{
553cdf0e10cSrcweir 				if ( bSingle && nY<MAXROW )
554cdf0e10cSrcweir 				{
555cdf0e10cSrcweir 					SCROW nVisY = pRowInfo[nArrYplus1].nRowNo;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 					nPosX = nScrX;
558cdf0e10cSrcweir 					if ( bLayoutRTL )
559cdf0e10cSrcweir 						nPosX += nMirrorW - nOneX;
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 					long nNextX;
562cdf0e10cSrcweir 					for (SCCOL i=nX1; i<=nX2; i++)
563cdf0e10cSrcweir 					{
564cdf0e10cSrcweir 						nNextX = nPosX + pRowInfo[0].pCellInfo[i+1].nWidth * nLayoutSign;
565cdf0e10cSrcweir 						if (nNextX != nPosX)								// sichtbar
566cdf0e10cSrcweir 						{
567cdf0e10cSrcweir 							sal_Bool bVOver;
568cdf0e10cSrcweir 							if ( bNextYisNextRow )
569cdf0e10cSrcweir 								bVOver = pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped;
570cdf0e10cSrcweir 							else
571cdf0e10cSrcweir 							{
572cdf0e10cSrcweir 								bVOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
573cdf0e10cSrcweir 											i,nYplus1,nTab,ATTR_MERGE_FLAG))
574cdf0e10cSrcweir 											->IsVerOverlapped()
575cdf0e10cSrcweir 									&& 	 ((ScMergeFlagAttr*)pDoc->GetAttr(
576cdf0e10cSrcweir 											i,nVisY,nTab,ATTR_MERGE_FLAG))
577cdf0e10cSrcweir 											->IsVerOverlapped();
578cdf0e10cSrcweir 									//! nVisY aus Array ??
579cdf0e10cSrcweir 							}
580cdf0e10cSrcweir 							if (!bVOver)
581cdf0e10cSrcweir 							{
582cdf0e10cSrcweir 								//Point aStart( nPosX, nPosY-nOneY );
583cdf0e10cSrcweir 								//Point aEnd( nNextX-nSignedOneX, nPosY-nOneY );
584cdf0e10cSrcweir 								//pDev->DrawLine( aStart, aEnd );
585cdf0e10cSrcweir 								aGrid.AddHorLine( nPosX, nNextX-nSignedOneX, nPosY-nOneY );
586cdf0e10cSrcweir 							}
587cdf0e10cSrcweir 						}
588cdf0e10cSrcweir 						nPosX = nNextX;
589cdf0e10cSrcweir 					}
590cdf0e10cSrcweir 				}
591cdf0e10cSrcweir 				else
592cdf0e10cSrcweir 				{
593cdf0e10cSrcweir 					//Point aStart( nScrX, nPosY-nOneY );
594cdf0e10cSrcweir 					//Point aEnd( nScrX+nScrW-nOneX, nPosY-nOneY );
595cdf0e10cSrcweir 					//pDev->DrawLine( aStart, aEnd );
596cdf0e10cSrcweir 					aGrid.AddHorLine( nScrX, nScrX+nScrW-nOneX, nPosY-nOneY );
597cdf0e10cSrcweir 				}
598cdf0e10cSrcweir 			}
599cdf0e10cSrcweir 		}
600cdf0e10cSrcweir 	}
601cdf0e10cSrcweir }
602cdf0e10cSrcweir 
603cdf0e10cSrcweir //	----------------------------------------------------------------------------
604cdf0e10cSrcweir 
605cdf0e10cSrcweir void ScOutputData::SetPagebreakMode( ScPageBreakData* pPageData )
606cdf0e10cSrcweir {
607cdf0e10cSrcweir 	bPagebreakMode = sal_True;
608cdf0e10cSrcweir 	if (!pPageData)
609cdf0e10cSrcweir 		return;						// noch nicht initialisiert -> alles "nicht gedruckt"
610cdf0e10cSrcweir 
611cdf0e10cSrcweir 	//	gedruckten Bereich markieren
612cdf0e10cSrcweir 	//	(in FillInfo ist schon alles auf sal_False initialisiert)
613cdf0e10cSrcweir 
614cdf0e10cSrcweir     sal_uInt16 nRangeCount = sal::static_int_cast<sal_uInt16>(pPageData->GetCount());
615cdf0e10cSrcweir 	for (sal_uInt16 nPos=0; nPos<nRangeCount; nPos++)
616cdf0e10cSrcweir 	{
617cdf0e10cSrcweir 		ScRange aRange = pPageData->GetData( nPos ).GetPrintRange();
618cdf0e10cSrcweir 
619cdf0e10cSrcweir 		SCCOL nStartX = Max( aRange.aStart.Col(), nX1 );
620cdf0e10cSrcweir 		SCCOL nEndX   = Min( aRange.aEnd.Col(),   nX2 );
621cdf0e10cSrcweir 		SCROW nStartY = Max( aRange.aStart.Row(), nY1 );
622cdf0e10cSrcweir 		SCROW nEndY   = Min( aRange.aEnd.Row(),   nY2 );
623cdf0e10cSrcweir 
624cdf0e10cSrcweir 		for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
625cdf0e10cSrcweir 		{
626cdf0e10cSrcweir 			RowInfo* pThisRowInfo = &pRowInfo[nArrY];
627cdf0e10cSrcweir 			if ( pThisRowInfo->bChanged && pThisRowInfo->nRowNo >= nStartY &&
628cdf0e10cSrcweir 										   pThisRowInfo->nRowNo <= nEndY )
629cdf0e10cSrcweir 			{
630cdf0e10cSrcweir 				for (SCCOL nX=nStartX; nX<=nEndX; nX++)
631cdf0e10cSrcweir 					pThisRowInfo->pCellInfo[nX+1].bPrinted = sal_True;
632cdf0e10cSrcweir 			}
633cdf0e10cSrcweir 		}
634cdf0e10cSrcweir 	}
635cdf0e10cSrcweir }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir void ScOutputData::FindRotated()
638cdf0e10cSrcweir {
639cdf0e10cSrcweir 	//!	nRotMax speichern
640cdf0e10cSrcweir 	SCCOL nRotMax = nX2;
641cdf0e10cSrcweir 	for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
642cdf0e10cSrcweir 		if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
643cdf0e10cSrcweir 			nRotMax = pRowInfo[nRotY].nRotMaxCol;
644cdf0e10cSrcweir 
645cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
646cdf0e10cSrcweir 	{
647cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
648cdf0e10cSrcweir 		if ( pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE &&
649cdf0e10cSrcweir 			 ( pThisRowInfo->bChanged || pRowInfo[nArrY-1].bChanged ||
650cdf0e10cSrcweir 			   ( nArrY+1<nArrCount && pRowInfo[nArrY+1].bChanged ) ) )
651cdf0e10cSrcweir 		{
652cdf0e10cSrcweir 			SCROW nY = pThisRowInfo->nRowNo;
653cdf0e10cSrcweir 
654cdf0e10cSrcweir 			for (SCCOL nX=0; nX<=nRotMax; nX++)
655cdf0e10cSrcweir 			{
656cdf0e10cSrcweir 				CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
657cdf0e10cSrcweir 				const ScPatternAttr* pPattern = pInfo->pPatternAttr;
658cdf0e10cSrcweir 				const SfxItemSet* pCondSet = pInfo->pConditionSet;
659cdf0e10cSrcweir 
660cdf0e10cSrcweir                 if ( !pPattern && !pDoc->ColHidden(nX, nTab) )
661cdf0e10cSrcweir 				{
662cdf0e10cSrcweir 					pPattern = pDoc->GetPattern( nX, nY, nTab );
663cdf0e10cSrcweir 					pCondSet = pDoc->GetCondResult( nX, nY, nTab );
664cdf0e10cSrcweir 				}
665cdf0e10cSrcweir 
666cdf0e10cSrcweir 				if ( pPattern )		// Spalte nicht ausgeblendet
667cdf0e10cSrcweir 				{
668cdf0e10cSrcweir 					sal_uInt8 nDir = pPattern->GetRotateDir( pCondSet );
669cdf0e10cSrcweir 					if (nDir != SC_ROTDIR_NONE)
670cdf0e10cSrcweir 					{
671cdf0e10cSrcweir 						pInfo->nRotateDir = nDir;
672cdf0e10cSrcweir 						bAnyRotated = sal_True;
673cdf0e10cSrcweir 					}
674cdf0e10cSrcweir 				}
675cdf0e10cSrcweir 			}
676cdf0e10cSrcweir 		}
677cdf0e10cSrcweir 	}
678cdf0e10cSrcweir }
679cdf0e10cSrcweir 
680cdf0e10cSrcweir //	----------------------------------------------------------------------------
681cdf0e10cSrcweir 
682cdf0e10cSrcweir sal_uInt16 lcl_GetRotateDir( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
683cdf0e10cSrcweir {
684cdf0e10cSrcweir 	const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
685cdf0e10cSrcweir 	const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
686cdf0e10cSrcweir 
687cdf0e10cSrcweir 	sal_uInt16 nRet = SC_ROTDIR_NONE;
688cdf0e10cSrcweir 
689cdf0e10cSrcweir 	long nAttrRotate = pPattern->GetRotateVal( pCondSet );
690cdf0e10cSrcweir 	if ( nAttrRotate )
691cdf0e10cSrcweir 	{
692cdf0e10cSrcweir 		SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
693cdf0e10cSrcweir 					pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 		if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
696cdf0e10cSrcweir 			nRet = SC_ROTDIR_STANDARD;
697cdf0e10cSrcweir 		else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
698cdf0e10cSrcweir 			nRet = SC_ROTDIR_CENTER;
699cdf0e10cSrcweir 		else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
700cdf0e10cSrcweir 		{
701cdf0e10cSrcweir 			long nRot180 = nAttrRotate % 18000;		// 1/100 Grad
702cdf0e10cSrcweir 			if ( nRot180 == 9000 )
703cdf0e10cSrcweir 				nRet = SC_ROTDIR_CENTER;
704cdf0e10cSrcweir 			else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000 ) ||
705cdf0e10cSrcweir 					  ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000 ) )
706cdf0e10cSrcweir 				nRet = SC_ROTDIR_LEFT;
707cdf0e10cSrcweir 			else
708cdf0e10cSrcweir 				nRet = SC_ROTDIR_RIGHT;
709cdf0e10cSrcweir 		}
710cdf0e10cSrcweir 	}
711cdf0e10cSrcweir 
712cdf0e10cSrcweir 	return nRet;
713cdf0e10cSrcweir }
714cdf0e10cSrcweir 
715cdf0e10cSrcweir const SvxBrushItem* lcl_FindBackground( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
716cdf0e10cSrcweir {
717cdf0e10cSrcweir 	const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
718cdf0e10cSrcweir 	const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
719cdf0e10cSrcweir 	const SvxBrushItem* pBackground = (const SvxBrushItem*)
720cdf0e10cSrcweir 							&pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
721cdf0e10cSrcweir 
722cdf0e10cSrcweir 	sal_uInt16 nDir = lcl_GetRotateDir( pDoc, nCol, nRow, nTab );
723cdf0e10cSrcweir 
724cdf0e10cSrcweir 	//	CENTER wird wie RIGHT behandelt...
725cdf0e10cSrcweir 	if ( nDir == SC_ROTDIR_RIGHT || nDir == SC_ROTDIR_CENTER )
726cdf0e10cSrcweir 	{
727cdf0e10cSrcweir 		//	Text geht nach rechts -> Hintergrund von links nehmen
728cdf0e10cSrcweir 		while ( nCol > 0 && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
729cdf0e10cSrcweir 							pBackground->GetColor().GetTransparency() != 255 )
730cdf0e10cSrcweir 		{
731cdf0e10cSrcweir 			--nCol;
732cdf0e10cSrcweir 			pPattern = pDoc->GetPattern( nCol, nRow, nTab );
733cdf0e10cSrcweir 			pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
734cdf0e10cSrcweir 			pBackground = (const SvxBrushItem*)&pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
735cdf0e10cSrcweir 		}
736cdf0e10cSrcweir 	}
737cdf0e10cSrcweir 	else if ( nDir == SC_ROTDIR_LEFT )
738cdf0e10cSrcweir 	{
739cdf0e10cSrcweir 		//	Text geht nach links -> Hintergrund von rechts nehmen
740cdf0e10cSrcweir 		while ( nCol < MAXCOL && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
741cdf0e10cSrcweir 							pBackground->GetColor().GetTransparency() != 255 )
742cdf0e10cSrcweir 		{
743cdf0e10cSrcweir 			++nCol;
744cdf0e10cSrcweir 			pPattern = pDoc->GetPattern( nCol, nRow, nTab );
745cdf0e10cSrcweir 			pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
746cdf0e10cSrcweir 			pBackground = (const SvxBrushItem*)&pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
747cdf0e10cSrcweir 		}
748cdf0e10cSrcweir 	}
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 	return pBackground;
751cdf0e10cSrcweir }
752cdf0e10cSrcweir 
753cdf0e10cSrcweir //	----------------------------------------------------------------------------
754cdf0e10cSrcweir 
755cdf0e10cSrcweir sal_Bool lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther,
756cdf0e10cSrcweir 					SCCOL nX1, SCCOL nX2, sal_Bool bShowProt, sal_Bool bPagebreakMode )
757cdf0e10cSrcweir {
758cdf0e10cSrcweir 	if ( rFirst.bChanged   != rOther.bChanged ||
759cdf0e10cSrcweir 		 rFirst.bEmptyBack != rOther.bEmptyBack )
760cdf0e10cSrcweir 		return sal_False;
761cdf0e10cSrcweir 
762cdf0e10cSrcweir 	SCCOL nX;
763cdf0e10cSrcweir 	if ( bShowProt )
764cdf0e10cSrcweir 	{
765cdf0e10cSrcweir 		for ( nX=nX1; nX<=nX2; nX++ )
766cdf0e10cSrcweir 		{
767cdf0e10cSrcweir 			const ScPatternAttr* pPat1 = rFirst.pCellInfo[nX+1].pPatternAttr;
768cdf0e10cSrcweir 			const ScPatternAttr* pPat2 = rOther.pCellInfo[nX+1].pPatternAttr;
769cdf0e10cSrcweir 			if ( !pPat1 || !pPat2 ||
770cdf0e10cSrcweir 					&pPat1->GetItem(ATTR_PROTECTION) != &pPat2->GetItem(ATTR_PROTECTION) )
771cdf0e10cSrcweir 				return sal_False;
772cdf0e10cSrcweir 		}
773cdf0e10cSrcweir 	}
774cdf0e10cSrcweir 	else
775cdf0e10cSrcweir 	{
776cdf0e10cSrcweir 		for ( nX=nX1; nX<=nX2; nX++ )
777cdf0e10cSrcweir 			if ( rFirst.pCellInfo[nX+1].pBackground != rOther.pCellInfo[nX+1].pBackground )
778cdf0e10cSrcweir 				return sal_False;
779cdf0e10cSrcweir 	}
780cdf0e10cSrcweir 
781cdf0e10cSrcweir 	if ( rFirst.nRotMaxCol != SC_ROTMAX_NONE || rOther.nRotMaxCol != SC_ROTMAX_NONE )
782cdf0e10cSrcweir 		for ( nX=nX1; nX<=nX2; nX++ )
783cdf0e10cSrcweir 			if ( rFirst.pCellInfo[nX+1].nRotateDir != rOther.pCellInfo[nX+1].nRotateDir )
784cdf0e10cSrcweir 				return sal_False;
785cdf0e10cSrcweir 
786cdf0e10cSrcweir 	if ( bPagebreakMode )
787cdf0e10cSrcweir 		for ( nX=nX1; nX<=nX2; nX++ )
788cdf0e10cSrcweir 			if ( rFirst.pCellInfo[nX+1].bPrinted != rOther.pCellInfo[nX+1].bPrinted )
789cdf0e10cSrcweir 				return sal_False;
790cdf0e10cSrcweir 
791cdf0e10cSrcweir 	return sal_True;
792cdf0e10cSrcweir }
793cdf0e10cSrcweir 
794cdf0e10cSrcweir void ScOutputData::DrawBackground()
795cdf0e10cSrcweir {
796cdf0e10cSrcweir 	FindRotated();				//! von aussen ?
797cdf0e10cSrcweir 
798cdf0e10cSrcweir 	ScModule* pScMod = SC_MOD();
799cdf0e10cSrcweir 
800cdf0e10cSrcweir 	// used only if bSolidBackground is set (only for ScGridWindow):
801cdf0e10cSrcweir     Color aBgColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
802cdf0e10cSrcweir 
803cdf0e10cSrcweir 	Rectangle aRect;
804cdf0e10cSrcweir 	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
805cdf0e10cSrcweir 	long nOneX = aOnePixel.Width();
806cdf0e10cSrcweir 	long nOneY = aOnePixel.Height();
807cdf0e10cSrcweir 
808cdf0e10cSrcweir 	if (bMetaFile)
809cdf0e10cSrcweir 		nOneX = nOneY = 0;
810cdf0e10cSrcweir 
811cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
812cdf0e10cSrcweir 	long nSignedOneX = nOneX * nLayoutSign;
813cdf0e10cSrcweir 
814cdf0e10cSrcweir 	pDev->SetLineColor();
815cdf0e10cSrcweir 
816cdf0e10cSrcweir 	sal_Bool bShowProt = bSyntaxMode && pDoc->IsTabProtected(nTab);
817cdf0e10cSrcweir 	sal_Bool bDoAll = bShowProt || bPagebreakMode || bSolidBackground;
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
820cdf0e10cSrcweir 	sal_Bool bCellContrast = bUseStyleColor &&
821cdf0e10cSrcweir 			Application::GetSettings().GetStyleSettings().GetHighContrastMode();
822cdf0e10cSrcweir 
823cdf0e10cSrcweir 	long nPosY = nScrY;
824cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
825cdf0e10cSrcweir 	{
826cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
827cdf0e10cSrcweir 		long nRowHeight = pThisRowInfo->nHeight;
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged )
830cdf0e10cSrcweir 		{
831cdf0e10cSrcweir 			if ( ( ( pThisRowInfo->bEmptyBack ) || bSyntaxMode ) && !bDoAll )
832cdf0e10cSrcweir 			{
833cdf0e10cSrcweir 				//	nichts
834cdf0e10cSrcweir 			}
835cdf0e10cSrcweir 			else
836cdf0e10cSrcweir 			{
837cdf0e10cSrcweir 				// scan for rows with the same background:
838cdf0e10cSrcweir 				SCSIZE nSkip = 0;
839cdf0e10cSrcweir 				while ( nArrY+nSkip+2<nArrCount &&
840cdf0e10cSrcweir 						lcl_EqualBack( *pThisRowInfo, pRowInfo[nArrY+nSkip+1],
841cdf0e10cSrcweir 										nX1, nX2, bShowProt, bPagebreakMode ) )
842cdf0e10cSrcweir 				{
843cdf0e10cSrcweir 					++nSkip;
844cdf0e10cSrcweir 					nRowHeight += pRowInfo[nArrY+nSkip].nHeight;	// after incrementing
845cdf0e10cSrcweir 				}
846cdf0e10cSrcweir 
847cdf0e10cSrcweir 				long nPosX = nScrX;
848cdf0e10cSrcweir 				if ( bLayoutRTL )
849cdf0e10cSrcweir 					nPosX += nMirrorW - nOneX;
850cdf0e10cSrcweir 				aRect = Rectangle( nPosX,nPosY, nPosX,nPosY+nRowHeight-nOneY );
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 				const SvxBrushItem* pOldBackground = NULL;
853cdf0e10cSrcweir 				const SvxBrushItem* pBackground;
854cdf0e10cSrcweir 				for (SCCOL nX=nX1; nX<=nX2; nX++)
855cdf0e10cSrcweir 				{
856cdf0e10cSrcweir 					CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
857cdf0e10cSrcweir 
858cdf0e10cSrcweir 					if (bCellContrast)
859cdf0e10cSrcweir 					{
860cdf0e10cSrcweir 						//	high contrast for cell borders and backgrounds -> empty background
861cdf0e10cSrcweir 						pBackground = ScGlobal::GetEmptyBrushItem();
862cdf0e10cSrcweir 					}
863cdf0e10cSrcweir 					else if (bShowProt)			// show cell protection in syntax mode
864cdf0e10cSrcweir 					{
865cdf0e10cSrcweir 						const ScPatternAttr* pP = pInfo->pPatternAttr;
866cdf0e10cSrcweir 						if (pP)
867cdf0e10cSrcweir 						{
868cdf0e10cSrcweir 							const ScProtectionAttr& rProt = (const ScProtectionAttr&)
869cdf0e10cSrcweir 																pP->GetItem(ATTR_PROTECTION);
870cdf0e10cSrcweir 							if (rProt.GetProtection() || rProt.GetHideCell())
871cdf0e10cSrcweir 								pBackground = ScGlobal::GetProtectedBrushItem();
872cdf0e10cSrcweir 							else
873cdf0e10cSrcweir 								pBackground = ScGlobal::GetEmptyBrushItem();
874cdf0e10cSrcweir 						}
875cdf0e10cSrcweir 						else
876cdf0e10cSrcweir 							pBackground = NULL;
877cdf0e10cSrcweir 					}
878cdf0e10cSrcweir 					else
879cdf0e10cSrcweir 						pBackground = pInfo->pBackground;
880cdf0e10cSrcweir 
881cdf0e10cSrcweir 					if ( bPagebreakMode && !pInfo->bPrinted )
882cdf0e10cSrcweir 						pBackground = ScGlobal::GetProtectedBrushItem();
883cdf0e10cSrcweir 
884cdf0e10cSrcweir 					if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
885cdf0e10cSrcweir 							pBackground->GetColor().GetTransparency() != 255 &&
886cdf0e10cSrcweir 							!bCellContrast )
887cdf0e10cSrcweir 					{
888cdf0e10cSrcweir 						SCROW nY = pRowInfo[nArrY].nRowNo;
889cdf0e10cSrcweir 						pBackground = lcl_FindBackground( pDoc, nX, nY, nTab );
890cdf0e10cSrcweir 					}
891cdf0e10cSrcweir 
892cdf0e10cSrcweir 					if ( pBackground != pOldBackground )
893cdf0e10cSrcweir 					{
894cdf0e10cSrcweir 						aRect.Right() = nPosX-nSignedOneX;
895cdf0e10cSrcweir 						if (pOldBackground)				// ==0 if hidden
896cdf0e10cSrcweir 						{
897cdf0e10cSrcweir 							Color aBackCol = pOldBackground->GetColor();
898cdf0e10cSrcweir 							if ( bSolidBackground && aBackCol.GetTransparency() )
899cdf0e10cSrcweir 								aBackCol = aBgColor;
900cdf0e10cSrcweir 							if ( !aBackCol.GetTransparency() )		//! partial transparency?
901cdf0e10cSrcweir 							{
902cdf0e10cSrcweir 								pDev->SetFillColor( aBackCol );
903cdf0e10cSrcweir 								pDev->DrawRect( aRect );
904cdf0e10cSrcweir 							}
905cdf0e10cSrcweir 						}
906cdf0e10cSrcweir 						aRect.Left() = nPosX;
907cdf0e10cSrcweir 						pOldBackground = pBackground;
908cdf0e10cSrcweir 					}
909cdf0e10cSrcweir 					nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
910cdf0e10cSrcweir 				}
911cdf0e10cSrcweir 				aRect.Right() = nPosX-nSignedOneX;
912cdf0e10cSrcweir 				if (pOldBackground)
913cdf0e10cSrcweir 				{
914cdf0e10cSrcweir 					Color aBackCol = pOldBackground->GetColor();
915cdf0e10cSrcweir 					if ( bSolidBackground && aBackCol.GetTransparency() )
916cdf0e10cSrcweir 						aBackCol = aBgColor;
917cdf0e10cSrcweir 					if ( !aBackCol.GetTransparency() )		//! partial transparency?
918cdf0e10cSrcweir 					{
919cdf0e10cSrcweir 						pDev->SetFillColor( aBackCol );
920cdf0e10cSrcweir 						pDev->DrawRect( aRect );
921cdf0e10cSrcweir 					}
922cdf0e10cSrcweir 				}
923cdf0e10cSrcweir 
924cdf0e10cSrcweir 				nArrY += nSkip;
925cdf0e10cSrcweir 			}
926cdf0e10cSrcweir 		}
927cdf0e10cSrcweir 		nPosY += nRowHeight;
928cdf0e10cSrcweir 	}
929cdf0e10cSrcweir }
930cdf0e10cSrcweir 
931cdf0e10cSrcweir void ScOutputData::DrawShadow()
932cdf0e10cSrcweir {
933cdf0e10cSrcweir 	DrawExtraShadow( sal_False, sal_False, sal_False, sal_False );
934cdf0e10cSrcweir }
935cdf0e10cSrcweir 
936cdf0e10cSrcweir void ScOutputData::DrawExtraShadow(sal_Bool bLeft, sal_Bool bTop, sal_Bool bRight, sal_Bool bBottom)
937cdf0e10cSrcweir {
938cdf0e10cSrcweir 	pDev->SetLineColor();
939cdf0e10cSrcweir 
940cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
941cdf0e10cSrcweir 	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
942cdf0e10cSrcweir 	sal_Bool bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
943cdf0e10cSrcweir 	Color aAutoTextColor;
944cdf0e10cSrcweir 	if ( bCellContrast )
945cdf0e10cSrcweir         aAutoTextColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
946cdf0e10cSrcweir 
947cdf0e10cSrcweir 	long nInitPosX = nScrX;
948cdf0e10cSrcweir 	if ( bLayoutRTL )
949cdf0e10cSrcweir 	{
950cdf0e10cSrcweir 		Size aOnePixel = pDev->PixelToLogic(Size(1,1));
951cdf0e10cSrcweir 		long nOneX = aOnePixel.Width();
952cdf0e10cSrcweir 		nInitPosX += nMirrorW - nOneX;
953cdf0e10cSrcweir 	}
954cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
955cdf0e10cSrcweir 
956cdf0e10cSrcweir 	long nPosY = nScrY - pRowInfo[0].nHeight;
957cdf0e10cSrcweir 	for (SCSIZE nArrY=0; nArrY<nArrCount; nArrY++)
958cdf0e10cSrcweir 	{
959cdf0e10cSrcweir 		sal_Bool bCornerY = ( nArrY == 0 ) || ( nArrY+1 == nArrCount );
960cdf0e10cSrcweir 		sal_Bool bSkipY = ( nArrY==0 && !bTop ) || ( nArrY+1 == nArrCount && !bBottom );
961cdf0e10cSrcweir 
962cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
963cdf0e10cSrcweir 		long nRowHeight = pThisRowInfo->nHeight;
964cdf0e10cSrcweir 
965cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged && !bSkipY )
966cdf0e10cSrcweir 		{
967cdf0e10cSrcweir 			long nPosX = nInitPosX - pRowInfo[0].pCellInfo[nX1].nWidth * nLayoutSign;
968cdf0e10cSrcweir 			for (SCCOL nArrX=nX1; nArrX<=nX2+2; nArrX++)
969cdf0e10cSrcweir 			{
970cdf0e10cSrcweir 				sal_Bool bCornerX = ( nArrX==nX1 || nArrX==nX2+2 );
971cdf0e10cSrcweir 				sal_Bool bSkipX = ( nArrX==nX1 && !bLeft ) || ( nArrX==nX2+2 && !bRight );
972cdf0e10cSrcweir 
973cdf0e10cSrcweir 				for (sal_uInt16 nPass=0; nPass<2; nPass++)			// horizontal / vertikal
974cdf0e10cSrcweir 				{
975cdf0e10cSrcweir 					const SvxShadowItem* pAttr = nPass ?
976cdf0e10cSrcweir 							pThisRowInfo->pCellInfo[nArrX].pVShadowOrigin :
977cdf0e10cSrcweir 							pThisRowInfo->pCellInfo[nArrX].pHShadowOrigin;
978cdf0e10cSrcweir 					if ( pAttr && !bSkipX )
979cdf0e10cSrcweir 					{
980cdf0e10cSrcweir 						ScShadowPart ePart = nPass ?
981cdf0e10cSrcweir 								pThisRowInfo->pCellInfo[nArrX].eVShadowPart :
982cdf0e10cSrcweir 								pThisRowInfo->pCellInfo[nArrX].eHShadowPart;
983cdf0e10cSrcweir 
984cdf0e10cSrcweir 						sal_Bool bDo = sal_True;
985cdf0e10cSrcweir 						if ( (nPass==0 && bCornerX) || (nPass==1 && bCornerY) )
986cdf0e10cSrcweir 							if ( ePart != SC_SHADOW_CORNER )
987cdf0e10cSrcweir 								bDo = sal_False;
988cdf0e10cSrcweir 
989cdf0e10cSrcweir 						if (bDo)
990cdf0e10cSrcweir 						{
991cdf0e10cSrcweir 							long nThisWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
992cdf0e10cSrcweir 							long nMaxWidth = nThisWidth;
993cdf0e10cSrcweir 							if (!nMaxWidth)
994cdf0e10cSrcweir 							{
995cdf0e10cSrcweir 								//!	direction must depend on shadow location
996cdf0e10cSrcweir 								SCCOL nWx = nArrX;		// nX+1
997cdf0e10cSrcweir 								while (nWx<nX2 && !pRowInfo[0].pCellInfo[nWx+1].nWidth)
998cdf0e10cSrcweir 									++nWx;
999cdf0e10cSrcweir 								nMaxWidth = pRowInfo[0].pCellInfo[nWx+1].nWidth;
1000cdf0e10cSrcweir 							}
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir //							Rectangle aRect( Point(nPosX,nPosY),
1003cdf0e10cSrcweir //											 Size( pRowInfo[0].pCellInfo[nArrX].nWidth,
1004cdf0e10cSrcweir //													pRowInfo[nArrY].nHeight ) );
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir 							// rectangle is in logical orientation
1007cdf0e10cSrcweir 							Rectangle aRect( nPosX, nPosY,
1008cdf0e10cSrcweir 											 nPosX + ( nThisWidth - 1 ) * nLayoutSign,
1009cdf0e10cSrcweir 											 nPosY + pRowInfo[nArrY].nHeight - 1 );
1010cdf0e10cSrcweir 
1011cdf0e10cSrcweir 							long nSize = pAttr->GetWidth();
1012cdf0e10cSrcweir 							long nSizeX = (long)(nSize*nPPTX);
1013cdf0e10cSrcweir 							if (nSizeX >= nMaxWidth) nSizeX = nMaxWidth-1;
1014cdf0e10cSrcweir 							long nSizeY = (long)(nSize*nPPTY);
1015cdf0e10cSrcweir 							if (nSizeY >= nRowHeight) nSizeY = nRowHeight-1;
1016cdf0e10cSrcweir 
1017cdf0e10cSrcweir 							nSizeX *= nLayoutSign;		// used only to add to rectangle values
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir 							SvxShadowLocation eLoc = pAttr->GetLocation();
1020cdf0e10cSrcweir 							if ( bLayoutRTL )
1021cdf0e10cSrcweir 							{
1022cdf0e10cSrcweir 								//	Shadow location is specified as "visual" (right is always right),
1023cdf0e10cSrcweir 								//	so the attribute's location value is mirrored here and in FillInfo.
1024cdf0e10cSrcweir 								switch (eLoc)
1025cdf0e10cSrcweir 								{
1026cdf0e10cSrcweir 									case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT;	break;
1027cdf0e10cSrcweir 									case SVX_SHADOW_BOTTOMLEFT:	 eLoc = SVX_SHADOW_BOTTOMRIGHT;	break;
1028cdf0e10cSrcweir 									case SVX_SHADOW_TOPRIGHT:	 eLoc = SVX_SHADOW_TOPLEFT;		break;
1029cdf0e10cSrcweir 									case SVX_SHADOW_TOPLEFT:	 eLoc = SVX_SHADOW_TOPRIGHT;	break;
1030cdf0e10cSrcweir                                     default:
1031cdf0e10cSrcweir                                     {
1032cdf0e10cSrcweir                                         // added to avoid warnings
1033cdf0e10cSrcweir                                     }
1034cdf0e10cSrcweir 								}
1035cdf0e10cSrcweir 							}
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir 							if (ePart == SC_SHADOW_HORIZ || ePart == SC_SHADOW_HSTART ||
1038cdf0e10cSrcweir 								ePart == SC_SHADOW_CORNER)
1039cdf0e10cSrcweir 							{
1040cdf0e10cSrcweir 								if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
1041cdf0e10cSrcweir 									aRect.Top() = aRect.Bottom() - nSizeY;
1042cdf0e10cSrcweir 								else
1043cdf0e10cSrcweir 									aRect.Bottom() = aRect.Top() + nSizeY;
1044cdf0e10cSrcweir 							}
1045cdf0e10cSrcweir 							if (ePart == SC_SHADOW_VERT || ePart == SC_SHADOW_VSTART ||
1046cdf0e10cSrcweir 								ePart == SC_SHADOW_CORNER)
1047cdf0e10cSrcweir 							{
1048cdf0e10cSrcweir 								if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
1049cdf0e10cSrcweir 									aRect.Left() = aRect.Right() - nSizeX;
1050cdf0e10cSrcweir 								else
1051cdf0e10cSrcweir 									aRect.Right() = aRect.Left() + nSizeX;
1052cdf0e10cSrcweir 							}
1053cdf0e10cSrcweir 							if (ePart == SC_SHADOW_HSTART)
1054cdf0e10cSrcweir 							{
1055cdf0e10cSrcweir 								if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
1056cdf0e10cSrcweir 									aRect.Right() -= nSizeX;
1057cdf0e10cSrcweir 								else
1058cdf0e10cSrcweir 									aRect.Left() += nSizeX;
1059cdf0e10cSrcweir 							}
1060cdf0e10cSrcweir 							if (ePart == SC_SHADOW_VSTART)
1061cdf0e10cSrcweir 							{
1062cdf0e10cSrcweir 								if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
1063cdf0e10cSrcweir 									aRect.Bottom() -= nSizeY;
1064cdf0e10cSrcweir 								else
1065cdf0e10cSrcweir 									aRect.Top() += nSizeY;
1066cdf0e10cSrcweir 							}
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir 							//! merge rectangles?
1069cdf0e10cSrcweir 							pDev->SetFillColor( bCellContrast ? aAutoTextColor : pAttr->GetColor() );
1070cdf0e10cSrcweir 							pDev->DrawRect( aRect );
1071cdf0e10cSrcweir 						}
1072cdf0e10cSrcweir 					}
1073cdf0e10cSrcweir 				}
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir 				nPosX += pRowInfo[0].pCellInfo[nArrX].nWidth * nLayoutSign;
1076cdf0e10cSrcweir 			}
1077cdf0e10cSrcweir 		}
1078cdf0e10cSrcweir 		nPosY += nRowHeight;
1079cdf0e10cSrcweir 	}
1080cdf0e10cSrcweir }
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir //
1083cdf0e10cSrcweir //	Loeschen
1084cdf0e10cSrcweir //
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir void ScOutputData::DrawClear()
1087cdf0e10cSrcweir {
1088cdf0e10cSrcweir 	Rectangle aRect;
1089cdf0e10cSrcweir 	Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1090cdf0e10cSrcweir 	long nOneX = aOnePixel.Width();
1091cdf0e10cSrcweir 	long nOneY = aOnePixel.Height();
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir 	// (called only for ScGridWindow)
1094cdf0e10cSrcweir     Color aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir 	if (bMetaFile)
1097cdf0e10cSrcweir 		nOneX = nOneY = 0;
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir 	pDev->SetLineColor();
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir 	pDev->SetFillColor( aBgColor );
1102cdf0e10cSrcweir 
1103cdf0e10cSrcweir 	long nPosY = nScrY;
1104cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
1105cdf0e10cSrcweir 	{
1106cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1107cdf0e10cSrcweir 		long nRowHeight = pThisRowInfo->nHeight;
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged )
1110cdf0e10cSrcweir 		{
1111cdf0e10cSrcweir 			// scan for more rows which must be painted:
1112cdf0e10cSrcweir 			SCSIZE nSkip = 0;
1113cdf0e10cSrcweir 			while ( nArrY+nSkip+2<nArrCount && pRowInfo[nArrY+nSkip+1].bChanged )
1114cdf0e10cSrcweir 			{
1115cdf0e10cSrcweir 				++nSkip;
1116cdf0e10cSrcweir 				nRowHeight += pRowInfo[nArrY+nSkip].nHeight;	// after incrementing
1117cdf0e10cSrcweir 			}
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir 			aRect = Rectangle( Point( nScrX, nPosY ),
1120cdf0e10cSrcweir 					Size( nScrW+1-nOneX, nRowHeight+1-nOneY) );
1121cdf0e10cSrcweir 			pDev->DrawRect( aRect );
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir 			nArrY += nSkip;
1124cdf0e10cSrcweir 		}
1125cdf0e10cSrcweir 		nPosY += nRowHeight;
1126cdf0e10cSrcweir 	}
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir //
1131cdf0e10cSrcweir //	Linien
1132cdf0e10cSrcweir //
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir long lclGetSnappedX( OutputDevice& rDev, long nPosX, bool bSnapPixel )
1135cdf0e10cSrcweir {
1136cdf0e10cSrcweir     return (bSnapPixel && nPosX) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( nPosX, 0 ) ) ).Width() : nPosX;
1137cdf0e10cSrcweir }
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir long lclGetSnappedY( OutputDevice& rDev, long nPosY, bool bSnapPixel )
1140cdf0e10cSrcweir {
1141cdf0e10cSrcweir     return (bSnapPixel && nPosY) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( 0, nPosY ) ) ).Height() : nPosY;
1142cdf0e10cSrcweir }
1143cdf0e10cSrcweir 
1144cdf0e10cSrcweir size_t lclGetArrayColFromCellInfoX( sal_uInt16 nCellInfoX, sal_uInt16 nCellInfoFirstX, sal_uInt16 nCellInfoLastX, bool bRTL )
1145cdf0e10cSrcweir {
1146cdf0e10cSrcweir     return static_cast< size_t >( bRTL ? (nCellInfoLastX + 2 - nCellInfoX) : (nCellInfoX - nCellInfoFirstX) );
1147cdf0e10cSrcweir }
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir void ScOutputData::DrawFrame()
1150cdf0e10cSrcweir {
1151cdf0e10cSrcweir 	sal_uLong nOldDrawMode = pDev->GetDrawMode();
1152cdf0e10cSrcweir 
1153cdf0e10cSrcweir 	Color aSingleColor;
1154cdf0e10cSrcweir 	sal_Bool bUseSingleColor = sal_False;
1155cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1156cdf0e10cSrcweir 	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
1157cdf0e10cSrcweir 	sal_Bool bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir 	//	#107519# if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
1160cdf0e10cSrcweir 	//	for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
1161cdf0e10cSrcweir 	//	that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
1162cdf0e10cSrcweir 	//	must be reset and the border colors handled here.
1163cdf0e10cSrcweir 
1164cdf0e10cSrcweir 	if ( ( nOldDrawMode & DRAWMODE_WHITEFILL ) && ( nOldDrawMode & DRAWMODE_BLACKLINE ) )
1165cdf0e10cSrcweir 	{
1166cdf0e10cSrcweir 		pDev->SetDrawMode( nOldDrawMode & (~DRAWMODE_WHITEFILL) );
1167cdf0e10cSrcweir 		aSingleColor.SetColor( COL_BLACK );
1168cdf0e10cSrcweir 		bUseSingleColor = sal_True;
1169cdf0e10cSrcweir 	}
1170cdf0e10cSrcweir 	else if ( ( nOldDrawMode & DRAWMODE_SETTINGSFILL ) && ( nOldDrawMode & DRAWMODE_SETTINGSLINE ) )
1171cdf0e10cSrcweir 	{
1172cdf0e10cSrcweir 		pDev->SetDrawMode( nOldDrawMode & (~DRAWMODE_SETTINGSFILL) );
1173cdf0e10cSrcweir 		aSingleColor = rStyleSettings.GetWindowTextColor();		// same as used in VCL for DRAWMODE_SETTINGSLINE
1174cdf0e10cSrcweir 		bUseSingleColor = sal_True;
1175cdf0e10cSrcweir 	}
1176cdf0e10cSrcweir 	else if ( bCellContrast )
1177cdf0e10cSrcweir 	{
1178cdf0e10cSrcweir 		aSingleColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
1179cdf0e10cSrcweir 		bUseSingleColor = sal_True;
1180cdf0e10cSrcweir 	}
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir     const Color* pForceColor = bUseSingleColor ? &aSingleColor : 0;
1183cdf0e10cSrcweir 
1184cdf0e10cSrcweir 	if (bAnyRotated)
1185cdf0e10cSrcweir 		DrawRotatedFrame( pForceColor );		// removes the lines that must not be painted here
1186cdf0e10cSrcweir 
1187cdf0e10cSrcweir 	long nInitPosX = nScrX;
1188cdf0e10cSrcweir 	if ( bLayoutRTL )
1189cdf0e10cSrcweir 	{
1190cdf0e10cSrcweir 		Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1191cdf0e10cSrcweir 		long nOneX = aOnePixel.Width();
1192cdf0e10cSrcweir 		nInitPosX += nMirrorW - nOneX;
1193cdf0e10cSrcweir 	}
1194cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir 
1197cdf0e10cSrcweir     // *** set column and row sizes of the frame border array ***
1198cdf0e10cSrcweir 
1199cdf0e10cSrcweir     svx::frame::Array& rArray = mrTabInfo.maArray;
1200cdf0e10cSrcweir     size_t nColCount = rArray.GetColCount();
1201cdf0e10cSrcweir     size_t nRowCount = rArray.GetRowCount();
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir     // row heights
1204cdf0e10cSrcweir 
1205cdf0e10cSrcweir     // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
1206cdf0e10cSrcweir     // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
1207cdf0e10cSrcweir     long nOldPosY = nScrY - 1 - pRowInfo[ 0 ].nHeight;
1208cdf0e10cSrcweir     long nOldSnapY = lclGetSnappedY( *pDev, nOldPosY, bSnapPixel );
1209cdf0e10cSrcweir     rArray.SetYOffset( nOldSnapY );
1210cdf0e10cSrcweir     for( size_t nRow = 0; nRow < nRowCount; ++nRow )
1211cdf0e10cSrcweir     {
1212cdf0e10cSrcweir         long nNewPosY = nOldPosY + pRowInfo[ nRow ].nHeight;
1213cdf0e10cSrcweir         long nNewSnapY = lclGetSnappedY( *pDev, nNewPosY, bSnapPixel );
1214cdf0e10cSrcweir         rArray.SetRowHeight( nRow, nNewSnapY - nOldSnapY );
1215cdf0e10cSrcweir         nOldPosY = nNewPosY;
1216cdf0e10cSrcweir         nOldSnapY = nNewSnapY;
1217cdf0e10cSrcweir     }
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir     // column widths
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir     // column nX1 is not visible (dummy for borders from left) - subtract its width from initial position
1222cdf0e10cSrcweir     // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
1223cdf0e10cSrcweir     long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 ].pCellInfo[ nX1 ].nWidth);
1224cdf0e10cSrcweir     long nOldSnapX = lclGetSnappedX( *pDev, nOldPosX, bSnapPixel );
1225cdf0e10cSrcweir     // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
1226cdf0e10cSrcweir     if( !bLayoutRTL )
1227cdf0e10cSrcweir         rArray.SetXOffset( nOldSnapX );
1228cdf0e10cSrcweir     for( sal_uInt16 nInfoIdx = nX1; nInfoIdx <= nX2 + 2; ++nInfoIdx )
1229cdf0e10cSrcweir     {
1230cdf0e10cSrcweir         size_t nCol = lclGetArrayColFromCellInfoX( nInfoIdx, nX1, nX2, bLayoutRTL );
1231cdf0e10cSrcweir         long nNewPosX = nOldPosX + pRowInfo[ 0 ].pCellInfo[ nInfoIdx ].nWidth * nLayoutSign;
1232cdf0e10cSrcweir         long nNewSnapX = lclGetSnappedX( *pDev, nNewPosX, bSnapPixel );
1233cdf0e10cSrcweir         rArray.SetColWidth( nCol, Abs( nNewSnapX - nOldSnapX ) );
1234cdf0e10cSrcweir         nOldPosX = nNewPosX;
1235cdf0e10cSrcweir         nOldSnapX = nNewSnapX;
1236cdf0e10cSrcweir     }
1237cdf0e10cSrcweir     if( bLayoutRTL )
1238cdf0e10cSrcweir         rArray.SetXOffset( nOldSnapX );
1239cdf0e10cSrcweir 
1240cdf0e10cSrcweir     // *** draw the array ***
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir     size_t nFirstCol = 1;
1243cdf0e10cSrcweir     size_t nFirstRow = 1;
1244cdf0e10cSrcweir     size_t nLastCol = nColCount - 2;
1245cdf0e10cSrcweir     size_t nLastRow = nRowCount - 2;
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir     if( mrTabInfo.mbPageMode )
1248cdf0e10cSrcweir         rArray.SetClipRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir     // draw only rows with set RowInfo::bChanged flag
1251cdf0e10cSrcweir     size_t nRow1 = nFirstRow;
1252cdf0e10cSrcweir     while( nRow1 <= nLastRow )
1253cdf0e10cSrcweir     {
1254cdf0e10cSrcweir         while( (nRow1 <= nLastRow) && !pRowInfo[ nRow1 ].bChanged ) ++nRow1;
1255cdf0e10cSrcweir         if( nRow1 <= nLastRow )
1256cdf0e10cSrcweir         {
1257cdf0e10cSrcweir             size_t nRow2 = nRow1;
1258cdf0e10cSrcweir             while( (nRow2 + 1 <= nLastRow) && pRowInfo[ nRow2 + 1 ].bChanged ) ++nRow2;
1259cdf0e10cSrcweir             rArray.DrawRange( *pDev, nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
1260cdf0e10cSrcweir             nRow1 = nRow2 + 1;
1261cdf0e10cSrcweir         }
1262cdf0e10cSrcweir     }
1263cdf0e10cSrcweir 
1264cdf0e10cSrcweir 	pDev->SetDrawMode(nOldDrawMode);
1265cdf0e10cSrcweir }
1266cdf0e10cSrcweir 
1267cdf0e10cSrcweir //	-------------------------------------------------------------------------
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir //	Linie unter der Zelle
1270cdf0e10cSrcweir 
1271cdf0e10cSrcweir const SvxBorderLine* lcl_FindHorLine( ScDocument* pDoc,
1272cdf0e10cSrcweir 						SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nRotDir,
1273cdf0e10cSrcweir 						sal_Bool bTopLine )
1274cdf0e10cSrcweir {
1275cdf0e10cSrcweir 	if ( nRotDir != SC_ROTDIR_LEFT && nRotDir != SC_ROTDIR_RIGHT )
1276cdf0e10cSrcweir 		return NULL;
1277cdf0e10cSrcweir 
1278cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
1279cdf0e10cSrcweir 	while (!bFound)
1280cdf0e10cSrcweir 	{
1281cdf0e10cSrcweir 		if ( nRotDir == SC_ROTDIR_LEFT )
1282cdf0e10cSrcweir 		{
1283cdf0e10cSrcweir 			//	Text nach links -> Linie von rechts
1284cdf0e10cSrcweir 			if ( nCol < MAXCOL )
1285cdf0e10cSrcweir 				++nCol;
1286cdf0e10cSrcweir 			else
1287cdf0e10cSrcweir 				return NULL;				// war nix
1288cdf0e10cSrcweir 		}
1289cdf0e10cSrcweir 		else
1290cdf0e10cSrcweir 		{
1291cdf0e10cSrcweir 			//	Text nach rechts -> Linie von links
1292cdf0e10cSrcweir 			if ( nCol > 0 )
1293cdf0e10cSrcweir 				--nCol;
1294cdf0e10cSrcweir 			else
1295cdf0e10cSrcweir 				return NULL;				// war nix
1296cdf0e10cSrcweir 		}
1297cdf0e10cSrcweir 		const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
1298cdf0e10cSrcweir 		const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
1299cdf0e10cSrcweir 		if ( !pPattern->GetRotateVal( pCondSet ) ||
1300cdf0e10cSrcweir 				((const SvxRotateModeItem&)pPattern->GetItem(
1301cdf0e10cSrcweir 					ATTR_ROTATE_MODE, pCondSet)).GetValue() == SVX_ROTATE_MODE_STANDARD )
1302cdf0e10cSrcweir 			bFound = sal_True;
1303cdf0e10cSrcweir 	}
1304cdf0e10cSrcweir 
1305cdf0e10cSrcweir 	if (bTopLine)
1306cdf0e10cSrcweir 		--nRow;
1307cdf0e10cSrcweir 	const SvxBorderLine* pThisBottom;
1308cdf0e10cSrcweir 	if ( ValidRow(nRow) )
1309cdf0e10cSrcweir 		pThisBottom = ((const SvxBoxItem*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER ))->GetBottom();
1310cdf0e10cSrcweir 	else
1311cdf0e10cSrcweir 		pThisBottom = NULL;
1312cdf0e10cSrcweir 	const SvxBorderLine* pNextTop;
1313cdf0e10cSrcweir 	if ( nRow < MAXROW )
1314cdf0e10cSrcweir 		pNextTop = ((const SvxBoxItem*)pDoc->GetAttr( nCol, nRow+1, nTab, ATTR_BORDER ))->GetTop();
1315cdf0e10cSrcweir 	else
1316cdf0e10cSrcweir 		pNextTop = NULL;
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir 	if ( ScHasPriority( pThisBottom, pNextTop ) )
1319cdf0e10cSrcweir 		return pThisBottom;
1320cdf0e10cSrcweir 	else
1321cdf0e10cSrcweir 		return pNextTop;
1322cdf0e10cSrcweir }
1323cdf0e10cSrcweir 
1324cdf0e10cSrcweir // lcl_HorizLine muss genau zu normal ausgegebenen Linien passen!
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir void lcl_HorizLine( OutputDevice& rDev, const Point& rLeft, const Point& rRight,
1327cdf0e10cSrcweir                     const svx::frame::Style& rLine, const Color* pForceColor )
1328cdf0e10cSrcweir {
1329cdf0e10cSrcweir     svx::frame::DrawHorFrameBorder( rDev, rLeft, rRight, rLine, pForceColor );
1330cdf0e10cSrcweir }
1331cdf0e10cSrcweir 
1332cdf0e10cSrcweir void lcl_VertLineEnds( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
1333cdf0e10cSrcweir         const Color& rColor, long nXOffs, long nWidth,
1334cdf0e10cSrcweir         const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine )
1335cdf0e10cSrcweir {
1336cdf0e10cSrcweir     rDev.SetLineColor(rColor);              // PEN_NULL ???
1337cdf0e10cSrcweir     rDev.SetFillColor(rColor);
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir 	//	Position oben/unten muss unabhaengig von der Liniendicke sein,
1340cdf0e10cSrcweir 	//	damit der Winkel stimmt (oder X-Position auch anpassen)
1341cdf0e10cSrcweir 	long nTopPos = rTop.Y();
1342cdf0e10cSrcweir 	long nBotPos = rBottom.Y();
1343cdf0e10cSrcweir 
1344cdf0e10cSrcweir     long nTopLeft = rTop.X() + nXOffs;
1345cdf0e10cSrcweir     long nTopRight = nTopLeft + nWidth - 1;
1346cdf0e10cSrcweir 
1347cdf0e10cSrcweir     long nBotLeft = rBottom.X() + nXOffs;
1348cdf0e10cSrcweir     long nBotRight = nBotLeft + nWidth - 1;
1349cdf0e10cSrcweir 
1350cdf0e10cSrcweir 	//	oben abschliessen
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir     if ( rTopLine.Prim() )
1353cdf0e10cSrcweir 	{
1354cdf0e10cSrcweir         long nLineW = rTopLine.GetWidth();
1355cdf0e10cSrcweir         if (nLineW >= 2)
1356cdf0e10cSrcweir 		{
1357cdf0e10cSrcweir 			Point aTriangle[3];
1358cdf0e10cSrcweir 			aTriangle[0] = Point( nTopLeft, nTopPos );		// wie aPoints[0]
1359cdf0e10cSrcweir 			aTriangle[1] = Point( nTopRight, nTopPos );		// wie aPoints[1]
1360cdf0e10cSrcweir             aTriangle[2] = Point( rTop.X(), nTopPos - (nLineW - 1) / 2 );
1361cdf0e10cSrcweir 			Polygon aTriPoly( 3, aTriangle );
1362cdf0e10cSrcweir             rDev.DrawPolygon( aTriPoly );
1363cdf0e10cSrcweir 		}
1364cdf0e10cSrcweir 	}
1365cdf0e10cSrcweir 
1366cdf0e10cSrcweir 	//	unten abschliessen
1367cdf0e10cSrcweir 
1368cdf0e10cSrcweir     if ( rBottomLine.Prim() )
1369cdf0e10cSrcweir 	{
1370cdf0e10cSrcweir         long nLineW = rBottomLine.GetWidth();
1371cdf0e10cSrcweir         if (nLineW >= 2)
1372cdf0e10cSrcweir 		{
1373cdf0e10cSrcweir 			Point aTriangle[3];
1374cdf0e10cSrcweir 			aTriangle[0] = Point( nBotLeft, nBotPos );		// wie aPoints[3]
1375cdf0e10cSrcweir 			aTriangle[1] = Point( nBotRight, nBotPos );		// wie aPoints[2]
1376cdf0e10cSrcweir             aTriangle[2] = Point( rBottom.X(), nBotPos - (nLineW - 1) / 2 + nLineW - 1 );
1377cdf0e10cSrcweir 			Polygon aTriPoly( 3, aTriangle );
1378cdf0e10cSrcweir             rDev.DrawPolygon( aTriPoly );
1379cdf0e10cSrcweir 		}
1380cdf0e10cSrcweir 	}
1381cdf0e10cSrcweir }
1382cdf0e10cSrcweir 
1383cdf0e10cSrcweir void lcl_VertLine( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
1384cdf0e10cSrcweir                     const svx::frame::Style& rLine,
1385cdf0e10cSrcweir                     const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine,
1386cdf0e10cSrcweir                     const Color* pForceColor )
1387cdf0e10cSrcweir {
1388cdf0e10cSrcweir     if( rLine.Prim() )
1389cdf0e10cSrcweir     {
1390cdf0e10cSrcweir         svx::frame::DrawVerFrameBorderSlanted( rDev, rTop, rBottom, rLine, pForceColor );
1391cdf0e10cSrcweir 
1392cdf0e10cSrcweir         svx::frame::Style aScaled( rLine );
1393cdf0e10cSrcweir         aScaled.ScaleSelf( 1.0 / cos( svx::frame::GetVerDiagAngle( rTop, rBottom ) ) );
1394cdf0e10cSrcweir         if( pForceColor )
1395cdf0e10cSrcweir             aScaled.SetColor( *pForceColor );
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir         long nXOffs = (aScaled.GetWidth() - 1) / -2L;
1398cdf0e10cSrcweir 
1399cdf0e10cSrcweir         lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
1400cdf0e10cSrcweir             nXOffs, aScaled.Prim(), rTopLine, rBottomLine );
1401cdf0e10cSrcweir 
1402cdf0e10cSrcweir         if( aScaled.Secn() )
1403cdf0e10cSrcweir             lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
1404cdf0e10cSrcweir                 nXOffs + aScaled.Prim() + aScaled.Dist(), aScaled.Secn(), rTopLine, rBottomLine );
1405cdf0e10cSrcweir     }
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir 
1408cdf0e10cSrcweir void ScOutputData::DrawRotatedFrame( const Color* pForceColor )
1409cdf0e10cSrcweir {
1410cdf0e10cSrcweir 	//!	nRotMax speichern
1411cdf0e10cSrcweir 	SCCOL nRotMax = nX2;
1412cdf0e10cSrcweir 	for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
1413cdf0e10cSrcweir 		if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
1414cdf0e10cSrcweir 			nRotMax = pRowInfo[nRotY].nRotMaxCol;
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir 	const ScPatternAttr* pPattern;
1417cdf0e10cSrcweir 	const SfxItemSet*	 pCondSet;
1418cdf0e10cSrcweir 
1419cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1420cdf0e10cSrcweir 	//	#105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
1421cdf0e10cSrcweir 	sal_Bool bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
1422cdf0e10cSrcweir 
1423cdf0e10cSrcweir 	//	color (pForceColor) is determined externally, including DrawMode changes
1424cdf0e10cSrcweir 
1425cdf0e10cSrcweir 	long nInitPosX = nScrX;
1426cdf0e10cSrcweir 	if ( bLayoutRTL )
1427cdf0e10cSrcweir 	{
1428cdf0e10cSrcweir 		Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1429cdf0e10cSrcweir 		long nOneX = aOnePixel.Width();
1430cdf0e10cSrcweir 		nInitPosX += nMirrorW - nOneX;
1431cdf0e10cSrcweir 	}
1432cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
1433cdf0e10cSrcweir 
1434cdf0e10cSrcweir 	Rectangle aClipRect( Point(nScrX, nScrY), Size(nScrW, nScrH) );
1435cdf0e10cSrcweir 	if (bMetaFile)
1436cdf0e10cSrcweir 	{
1437cdf0e10cSrcweir 		pDev->Push();
1438cdf0e10cSrcweir 		pDev->IntersectClipRegion( aClipRect );
1439cdf0e10cSrcweir 	}
1440cdf0e10cSrcweir 	else
1441cdf0e10cSrcweir 		pDev->SetClipRegion( Region( aClipRect ) );
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir     svx::frame::Array& rArray = mrTabInfo.maArray;
1444cdf0e10cSrcweir 
1445cdf0e10cSrcweir 	long nPosY = nScrY;
1446cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
1447cdf0e10cSrcweir 	{
1448cdf0e10cSrcweir 		//	Rotated wird auch 1 Zeile ueber/unter Changed gezeichnet, falls Teile
1449cdf0e10cSrcweir 		//	in die Zeile hineinragen...
1450cdf0e10cSrcweir 
1451cdf0e10cSrcweir         RowInfo& rPrevRowInfo = pRowInfo[nArrY-1];
1452cdf0e10cSrcweir         RowInfo& rThisRowInfo = pRowInfo[nArrY];
1453cdf0e10cSrcweir         RowInfo& rNextRowInfo = pRowInfo[nArrY+1];
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir         size_t nRow = static_cast< size_t >( nArrY );
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir         long nRowHeight = rThisRowInfo.nHeight;
1458cdf0e10cSrcweir         if ( rThisRowInfo.nRotMaxCol != SC_ROTMAX_NONE &&
1459cdf0e10cSrcweir              ( rThisRowInfo.bChanged || rPrevRowInfo.bChanged ||
1460cdf0e10cSrcweir                ( nArrY+1<nArrCount && rNextRowInfo.bChanged ) ) )
1461cdf0e10cSrcweir 		{
1462cdf0e10cSrcweir             SCROW nY = rThisRowInfo.nRowNo;
1463cdf0e10cSrcweir 			long nPosX = 0;
1464cdf0e10cSrcweir 			SCCOL nX;
1465cdf0e10cSrcweir 			for (nX=0; nX<=nRotMax; nX++)
1466cdf0e10cSrcweir 			{
1467cdf0e10cSrcweir 				if (nX==nX1) nPosX = nInitPosX;		// calculated individually for preceding positions
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir                 sal_uInt16 nArrX = nX + 1;
1470cdf0e10cSrcweir 
1471cdf0e10cSrcweir                 CellInfo* pInfo = &rThisRowInfo.pCellInfo[nArrX];
1472cdf0e10cSrcweir                 long nColWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
1473cdf0e10cSrcweir 				if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
1474cdf0e10cSrcweir 						!pInfo->bHOverlapped && !pInfo->bVOverlapped )
1475cdf0e10cSrcweir 				{
1476cdf0e10cSrcweir 					pPattern = pInfo->pPatternAttr;
1477cdf0e10cSrcweir 					pCondSet = pInfo->pConditionSet;
1478cdf0e10cSrcweir 					if (!pPattern)
1479cdf0e10cSrcweir 					{
1480cdf0e10cSrcweir 						pPattern = pDoc->GetPattern( nX, nY, nTab );
1481cdf0e10cSrcweir 						pInfo->pPatternAttr = pPattern;
1482cdf0e10cSrcweir 						pCondSet = pDoc->GetCondResult( nX, nY, nTab );
1483cdf0e10cSrcweir 						pInfo->pConditionSet = pCondSet;
1484cdf0e10cSrcweir 					}
1485cdf0e10cSrcweir 
1486cdf0e10cSrcweir 					//!	LastPattern etc.
1487cdf0e10cSrcweir 
1488cdf0e10cSrcweir 					long nAttrRotate = pPattern->GetRotateVal( pCondSet );
1489cdf0e10cSrcweir 					SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
1490cdf0e10cSrcweir 									pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
1491cdf0e10cSrcweir 
1492cdf0e10cSrcweir 					if ( nAttrRotate )
1493cdf0e10cSrcweir 					{
1494cdf0e10cSrcweir 						if (nX<nX1)			// negative Position berechnen
1495cdf0e10cSrcweir 						{
1496cdf0e10cSrcweir 							nPosX = nInitPosX;
1497cdf0e10cSrcweir 							SCCOL nCol = nX1;
1498cdf0e10cSrcweir 							while (nCol > nX)
1499cdf0e10cSrcweir 							{
1500cdf0e10cSrcweir 								--nCol;
1501cdf0e10cSrcweir 								nPosX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
1502cdf0e10cSrcweir 							}
1503cdf0e10cSrcweir 						}
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir 						//	Startposition minus 1, damit auch schraege Hintergruende
1506cdf0e10cSrcweir 						//	zur Umrandung passen (Umrandung ist auf dem Gitter)
1507cdf0e10cSrcweir 
1508cdf0e10cSrcweir 						long nTop = nPosY - 1;
1509cdf0e10cSrcweir 						long nBottom = nPosY + nRowHeight - 1;
1510cdf0e10cSrcweir 						long nTopLeft = nPosX - nLayoutSign;
1511cdf0e10cSrcweir 						long nTopRight = nPosX + ( nColWidth - 1 ) * nLayoutSign;
1512cdf0e10cSrcweir 						long nBotLeft = nTopLeft;
1513cdf0e10cSrcweir 						long nBotRight = nTopRight;
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir 						//	inclusion of the sign here hasn't been decided yet
1516cdf0e10cSrcweir 						//	(if not, the extension of the non-rotated background must also be changed)
1517cdf0e10cSrcweir 						double nRealOrient = nLayoutSign * nAttrRotate * F_PI18000;		// 1/100th degrees
1518cdf0e10cSrcweir 						double nCos = cos( nRealOrient );
1519cdf0e10cSrcweir 						double nSin = sin( nRealOrient );
1520cdf0e10cSrcweir 						//!	begrenzen !!!
1521cdf0e10cSrcweir 						long nSkew = (long) ( nRowHeight * nCos / nSin );
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir 						switch (eRotMode)
1524cdf0e10cSrcweir 						{
1525cdf0e10cSrcweir 							case SVX_ROTATE_MODE_BOTTOM:
1526cdf0e10cSrcweir 								nTopLeft += nSkew;
1527cdf0e10cSrcweir 								nTopRight += nSkew;
1528cdf0e10cSrcweir 								break;
1529cdf0e10cSrcweir 							case SVX_ROTATE_MODE_CENTER:
1530cdf0e10cSrcweir 								nSkew /= 2;
1531cdf0e10cSrcweir 								nTopLeft += nSkew;
1532cdf0e10cSrcweir 								nTopRight += nSkew;
1533cdf0e10cSrcweir 								nBotLeft -= nSkew;
1534cdf0e10cSrcweir 								nBotRight -= nSkew;
1535cdf0e10cSrcweir 								break;
1536cdf0e10cSrcweir 							case SVX_ROTATE_MODE_TOP:
1537cdf0e10cSrcweir 								nBotLeft -= nSkew;
1538cdf0e10cSrcweir 								nBotRight -= nSkew;
1539cdf0e10cSrcweir 								break;
1540cdf0e10cSrcweir                             default:
1541cdf0e10cSrcweir                             {
1542cdf0e10cSrcweir                                 // added to avoid warnings
1543cdf0e10cSrcweir                             }
1544cdf0e10cSrcweir 						}
1545cdf0e10cSrcweir 
1546cdf0e10cSrcweir 						Point aPoints[4];
1547cdf0e10cSrcweir 						aPoints[0] = Point( nTopLeft, nTop );
1548cdf0e10cSrcweir 						aPoints[1] = Point( nTopRight, nTop );
1549cdf0e10cSrcweir 						aPoints[2] = Point( nBotRight, nBottom );
1550cdf0e10cSrcweir 						aPoints[3] = Point( nBotLeft, nBottom );
1551cdf0e10cSrcweir 
1552cdf0e10cSrcweir 						const SvxBrushItem* pBackground = pInfo->pBackground;
1553cdf0e10cSrcweir 						if (!pBackground)
1554cdf0e10cSrcweir 							pBackground = (const SvxBrushItem*) &pPattern->GetItem(
1555cdf0e10cSrcweir 												ATTR_BACKGROUND, pCondSet );
1556cdf0e10cSrcweir 						if (bCellContrast)
1557cdf0e10cSrcweir 						{
1558cdf0e10cSrcweir 							//	high contrast for cell borders and backgrounds -> empty background
1559cdf0e10cSrcweir 							pBackground = ScGlobal::GetEmptyBrushItem();
1560cdf0e10cSrcweir 						}
1561cdf0e10cSrcweir 						const Color& rColor = pBackground->GetColor();
1562cdf0e10cSrcweir 						if ( rColor.GetTransparency() != 255 )
1563cdf0e10cSrcweir 						{
1564cdf0e10cSrcweir 							//	#95879# draw background only for the changed row itself
1565cdf0e10cSrcweir 							//	(background doesn't extend into other cells).
1566cdf0e10cSrcweir 							//	For the borders (rotated and normal), clipping should be
1567cdf0e10cSrcweir 							//	set if the row isn't changed, but at least the borders
1568cdf0e10cSrcweir 							//	don't cover the cell contents.
1569cdf0e10cSrcweir                             if ( rThisRowInfo.bChanged )
1570cdf0e10cSrcweir 							{
1571cdf0e10cSrcweir 								Polygon aPoly( 4, aPoints );
1572cdf0e10cSrcweir 
1573cdf0e10cSrcweir 								//	ohne Pen wird bei DrawPolygon rechts und unten
1574cdf0e10cSrcweir 								//	ein Pixel weggelassen...
1575cdf0e10cSrcweir 								if ( rColor.GetTransparency() == 0 )
1576cdf0e10cSrcweir 									pDev->SetLineColor(rColor);
1577cdf0e10cSrcweir 								else
1578cdf0e10cSrcweir 									pDev->SetLineColor();
1579cdf0e10cSrcweir 								pDev->SetFillColor(rColor);
1580cdf0e10cSrcweir 								pDev->DrawPolygon( aPoly );
1581cdf0e10cSrcweir 							}
1582cdf0e10cSrcweir 						}
1583cdf0e10cSrcweir 
1584cdf0e10cSrcweir                         svx::frame::Style aTopLine, aBottomLine, aLeftLine, aRightLine;
1585cdf0e10cSrcweir 
1586cdf0e10cSrcweir 						if ( nX < nX1 || nX > nX2 )		// Attribute in FillInfo nicht gesetzt
1587cdf0e10cSrcweir 						{
1588cdf0e10cSrcweir 							//!	Seitengrenzen fuer Druck beruecksichtigen !!!!!
1589cdf0e10cSrcweir                             const SvxBorderLine* pLeftLine;
1590cdf0e10cSrcweir                             const SvxBorderLine* pTopLine;
1591cdf0e10cSrcweir                             const SvxBorderLine* pRightLine;
1592cdf0e10cSrcweir                             const SvxBorderLine* pBottomLine;
1593cdf0e10cSrcweir 							pDoc->GetBorderLines( nX, nY, nTab,
1594cdf0e10cSrcweir 									&pLeftLine, &pTopLine, &pRightLine, &pBottomLine );
1595cdf0e10cSrcweir                             aTopLine.Set( pTopLine, nPPTY );
1596cdf0e10cSrcweir                             aBottomLine.Set( pBottomLine, nPPTY );
1597cdf0e10cSrcweir                             aLeftLine.Set( pLeftLine, nPPTX );
1598cdf0e10cSrcweir                             aRightLine.Set( pRightLine, nPPTX );
1599cdf0e10cSrcweir 						}
1600cdf0e10cSrcweir                         else
1601cdf0e10cSrcweir                         {
1602cdf0e10cSrcweir                             size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
1603cdf0e10cSrcweir                             aTopLine = rArray.GetCellStyleTop( nCol, nRow );
1604cdf0e10cSrcweir                             aBottomLine = rArray.GetCellStyleBottom( nCol, nRow );
1605cdf0e10cSrcweir                             aLeftLine = rArray.GetCellStyleLeft( nCol, nRow );
1606cdf0e10cSrcweir                             aRightLine = rArray.GetCellStyleRight( nCol, nRow );
1607cdf0e10cSrcweir                             // in RTL mode the array is already mirrored -> swap back left/right borders
1608cdf0e10cSrcweir                             if( bLayoutRTL )
1609cdf0e10cSrcweir                                 std::swap( aLeftLine, aRightLine );
1610cdf0e10cSrcweir                         }
1611cdf0e10cSrcweir 
1612cdf0e10cSrcweir                         lcl_HorizLine( *pDev, aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine, pForceColor );
1613cdf0e10cSrcweir                         lcl_HorizLine( *pDev, aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine, pForceColor );
1614cdf0e10cSrcweir 
1615cdf0e10cSrcweir                         lcl_VertLine( *pDev, aPoints[0], aPoints[3], aLeftLine, aTopLine, aBottomLine, pForceColor );
1616cdf0e10cSrcweir                         lcl_VertLine( *pDev, aPoints[1], aPoints[2], aRightLine, aTopLine, aBottomLine, pForceColor );
1617cdf0e10cSrcweir 					}
1618cdf0e10cSrcweir 				}
1619cdf0e10cSrcweir 				nPosX += nColWidth * nLayoutSign;
1620cdf0e10cSrcweir 			}
1621cdf0e10cSrcweir 
1622cdf0e10cSrcweir 			//	erst hinterher im zweiten Schritt die Linien fuer normale Ausgabe loeschen
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir 			nX = nX1 > 0 ? (nX1-1) : static_cast<SCCOL>(0);
1625cdf0e10cSrcweir 			for (; nX<=nX2+1; nX++)			// sichtbarer Teil +- 1
1626cdf0e10cSrcweir 			{
1627cdf0e10cSrcweir                 sal_uInt16 nArrX = nX + 1;
1628cdf0e10cSrcweir                 CellInfo& rInfo = rThisRowInfo.pCellInfo[nArrX];
1629cdf0e10cSrcweir                 if ( rInfo.nRotateDir > SC_ROTDIR_STANDARD &&
1630cdf0e10cSrcweir                         !rInfo.bHOverlapped && !rInfo.bVOverlapped )
1631cdf0e10cSrcweir 				{
1632cdf0e10cSrcweir                     pPattern = rInfo.pPatternAttr;
1633cdf0e10cSrcweir                     pCondSet = rInfo.pConditionSet;
1634cdf0e10cSrcweir 					SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
1635cdf0e10cSrcweir 									pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
1636cdf0e10cSrcweir 
1637cdf0e10cSrcweir                     size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
1638cdf0e10cSrcweir 
1639cdf0e10cSrcweir 					//	horizontal: angrenzende Linie verlaengern
1640cdf0e10cSrcweir 					//	(nur, wenn die gedrehte Zelle eine Umrandung hat)
1641cdf0e10cSrcweir                     sal_uInt16 nDir = rInfo.nRotateDir;
1642cdf0e10cSrcweir                     if ( rArray.GetCellStyleTop( nCol, nRow ).Prim() && eRotMode != SVX_ROTATE_MODE_TOP )
1643cdf0e10cSrcweir                     {
1644cdf0e10cSrcweir                         svx::frame::Style aStyle( lcl_FindHorLine( pDoc, nX, nY, nTab, nDir, sal_True ), nPPTY );
1645cdf0e10cSrcweir                         rArray.SetCellStyleTop( nCol, nRow, aStyle );
1646cdf0e10cSrcweir                         if( nRow > 0 )
1647cdf0e10cSrcweir                             rArray.SetCellStyleBottom( nCol, nRow - 1, aStyle );
1648cdf0e10cSrcweir                     }
1649cdf0e10cSrcweir                     if ( rArray.GetCellStyleBottom( nCol, nRow ).Prim() && eRotMode != SVX_ROTATE_MODE_BOTTOM )
1650cdf0e10cSrcweir                     {
1651cdf0e10cSrcweir                         svx::frame::Style aStyle( lcl_FindHorLine( pDoc, nX, nY, nTab, nDir, sal_False ), nPPTY );
1652cdf0e10cSrcweir                         rArray.SetCellStyleBottom( nCol, nRow, aStyle );
1653cdf0e10cSrcweir                         if( nRow + 1 < rArray.GetRowCount() )
1654cdf0e10cSrcweir                             rArray.SetCellStyleTop( nCol, nRow + 1, aStyle );
1655cdf0e10cSrcweir                     }
1656cdf0e10cSrcweir 
1657cdf0e10cSrcweir                     // always remove vertical borders
1658cdf0e10cSrcweir                     if( !rArray.IsMergedOverlappedLeft( nCol, nRow ) )
1659cdf0e10cSrcweir                     {
1660cdf0e10cSrcweir                         rArray.SetCellStyleLeft( nCol, nRow, svx::frame::Style() );
1661cdf0e10cSrcweir                         if( nCol > 0 )
1662cdf0e10cSrcweir                             rArray.SetCellStyleRight( nCol - 1, nRow, svx::frame::Style() );
1663cdf0e10cSrcweir                     }
1664cdf0e10cSrcweir                     if( !rArray.IsMergedOverlappedRight( nCol, nRow ) )
1665cdf0e10cSrcweir                     {
1666cdf0e10cSrcweir                         rArray.SetCellStyleRight( nCol, nRow, svx::frame::Style() );
1667cdf0e10cSrcweir                         if( nCol + 1 < rArray.GetColCount() )
1668cdf0e10cSrcweir                             rArray.SetCellStyleLeft( nCol + 1, nRow, svx::frame::Style() );
1669cdf0e10cSrcweir                     }
1670cdf0e10cSrcweir 
1671cdf0e10cSrcweir                     // remove diagonal borders
1672cdf0e10cSrcweir                     rArray.SetCellStyleTLBR( nCol, nRow, svx::frame::Style() );
1673cdf0e10cSrcweir                     rArray.SetCellStyleBLTR( nCol, nRow, svx::frame::Style() );
1674cdf0e10cSrcweir 				}
1675cdf0e10cSrcweir 			}
1676cdf0e10cSrcweir 		}
1677cdf0e10cSrcweir 		nPosY += nRowHeight;
1678cdf0e10cSrcweir 	}
1679cdf0e10cSrcweir 
1680cdf0e10cSrcweir 	if (bMetaFile)
1681cdf0e10cSrcweir 		pDev->Pop();
1682cdf0e10cSrcweir 	else
1683cdf0e10cSrcweir 		pDev->SetClipRegion();
1684cdf0e10cSrcweir }
1685cdf0e10cSrcweir 
1686cdf0e10cSrcweir //	Drucker
1687cdf0e10cSrcweir 
1688*d8ed516eSArmin Le Grand Region ScOutputData::GetChangedAreaRegion()
1689cdf0e10cSrcweir {
1690*d8ed516eSArmin Le Grand     Region aRegion;
1691cdf0e10cSrcweir     Rectangle aDrawingRect;
1692*d8ed516eSArmin Le Grand     bool bHad(false);
1693*d8ed516eSArmin Le Grand     long nPosY = nScrY;
1694*d8ed516eSArmin Le Grand     SCSIZE nArrY;
1695*d8ed516eSArmin Le Grand 
1696cdf0e10cSrcweir     aDrawingRect.Left() = nScrX;
1697cdf0e10cSrcweir     aDrawingRect.Right() = nScrX+nScrW-1;
1698cdf0e10cSrcweir 
1699cdf0e10cSrcweir     for(nArrY=1; nArrY+1<nArrCount; nArrY++)
1700cdf0e10cSrcweir     {
1701cdf0e10cSrcweir         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1702cdf0e10cSrcweir 
1703cdf0e10cSrcweir         if(pThisRowInfo->bChanged)
1704cdf0e10cSrcweir         {
1705cdf0e10cSrcweir             if(!bHad)
1706cdf0e10cSrcweir             {
1707cdf0e10cSrcweir                 aDrawingRect.Top() = nPosY;
1708*d8ed516eSArmin Le Grand                 bHad = true;
1709cdf0e10cSrcweir             }
1710*d8ed516eSArmin Le Grand 
1711cdf0e10cSrcweir             aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
1712cdf0e10cSrcweir         }
1713cdf0e10cSrcweir         else if(bHad)
1714cdf0e10cSrcweir         {
1715*d8ed516eSArmin Le Grand             aRegion.Union(pDev->PixelToLogic(aDrawingRect));
1716*d8ed516eSArmin Le Grand             bHad = false;
1717cdf0e10cSrcweir         }
1718*d8ed516eSArmin Le Grand 
1719cdf0e10cSrcweir         nPosY += pRowInfo[nArrY].nHeight;
1720cdf0e10cSrcweir     }
1721cdf0e10cSrcweir 
1722cdf0e10cSrcweir     if(bHad)
1723*d8ed516eSArmin Le Grand     {
1724*d8ed516eSArmin Le Grand         aRegion.Union(pDev->PixelToLogic(aDrawingRect));
1725*d8ed516eSArmin Le Grand     }
1726cdf0e10cSrcweir 
1727*d8ed516eSArmin Le Grand     return aRegion;
1728cdf0e10cSrcweir }
1729cdf0e10cSrcweir 
1730cdf0e10cSrcweir sal_Bool ScOutputData::SetChangedClip()
1731cdf0e10cSrcweir {
1732cdf0e10cSrcweir 	PolyPolygon aPoly;
1733cdf0e10cSrcweir 
1734cdf0e10cSrcweir 	Rectangle aDrawingRect;
1735cdf0e10cSrcweir 	aDrawingRect.Left() = nScrX;
1736cdf0e10cSrcweir 	aDrawingRect.Right() = nScrX+nScrW-1;
1737cdf0e10cSrcweir 
1738cdf0e10cSrcweir 	sal_Bool	bHad	= sal_False;
1739cdf0e10cSrcweir 	long	nPosY	= nScrY;
1740cdf0e10cSrcweir 	SCSIZE	nArrY;
1741cdf0e10cSrcweir 	for (nArrY=1; nArrY+1<nArrCount; nArrY++)
1742cdf0e10cSrcweir 	{
1743cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1744cdf0e10cSrcweir 
1745cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged )
1746cdf0e10cSrcweir 		{
1747cdf0e10cSrcweir 			if (!bHad)
1748cdf0e10cSrcweir 			{
1749cdf0e10cSrcweir 				aDrawingRect.Top() = nPosY;
1750cdf0e10cSrcweir 				bHad = sal_True;
1751cdf0e10cSrcweir 			}
1752cdf0e10cSrcweir 			aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
1753cdf0e10cSrcweir 		}
1754cdf0e10cSrcweir 		else if (bHad)
1755cdf0e10cSrcweir 		{
1756cdf0e10cSrcweir 			aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
1757cdf0e10cSrcweir 			bHad = sal_False;
1758cdf0e10cSrcweir 		}
1759cdf0e10cSrcweir 		nPosY += pRowInfo[nArrY].nHeight;
1760cdf0e10cSrcweir 	}
1761cdf0e10cSrcweir 
1762cdf0e10cSrcweir 	if (bHad)
1763cdf0e10cSrcweir 		aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
1764cdf0e10cSrcweir 
1765cdf0e10cSrcweir 	sal_Bool bRet = (aPoly.Count() != 0);
1766cdf0e10cSrcweir 	if (bRet)
1767cdf0e10cSrcweir 		pDev->SetClipRegion(Region(aPoly));
1768cdf0e10cSrcweir 	return bRet;
1769cdf0e10cSrcweir }
1770cdf0e10cSrcweir 
1771cdf0e10cSrcweir void ScOutputData::FindChanged()
1772cdf0e10cSrcweir {
1773cdf0e10cSrcweir 	SCCOL	nX;
1774cdf0e10cSrcweir 	SCSIZE	nArrY;
1775cdf0e10cSrcweir 
1776cdf0e10cSrcweir 	sal_Bool bWasIdleDisabled = pDoc->IsIdleDisabled();
1777cdf0e10cSrcweir 	pDoc->DisableIdle( sal_True );
1778cdf0e10cSrcweir 	for (nArrY=0; nArrY<nArrCount; nArrY++)
1779cdf0e10cSrcweir 		pRowInfo[nArrY].bChanged = sal_False;
1780cdf0e10cSrcweir 
1781cdf0e10cSrcweir 	sal_Bool bProgress = sal_False;
1782cdf0e10cSrcweir 	for (nArrY=0; nArrY<nArrCount; nArrY++)
1783cdf0e10cSrcweir 	{
1784cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1785cdf0e10cSrcweir 		for (nX=nX1; nX<=nX2; nX++)
1786cdf0e10cSrcweir 		{
1787cdf0e10cSrcweir 			ScBaseCell* pCell = pThisRowInfo->pCellInfo[nX+1].pCell;
1788cdf0e10cSrcweir 			if (pCell)
1789cdf0e10cSrcweir 				if (pCell->GetCellType() == CELLTYPE_FORMULA)
1790cdf0e10cSrcweir 				{
1791cdf0e10cSrcweir 					ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
1792cdf0e10cSrcweir 					if ( !bProgress && pFCell->GetDirty() )
1793cdf0e10cSrcweir 					{
1794cdf0e10cSrcweir 						ScProgress::CreateInterpretProgress( pDoc, sal_True );
1795cdf0e10cSrcweir 						bProgress = sal_True;
1796cdf0e10cSrcweir 					}
1797cdf0e10cSrcweir 					if (!pFCell->IsRunning())
1798cdf0e10cSrcweir 					{
1799cdf0e10cSrcweir                         (void)pFCell->GetValue();
1800cdf0e10cSrcweir 						if (pFCell->IsChanged())
1801cdf0e10cSrcweir 						{
1802cdf0e10cSrcweir 							pThisRowInfo->bChanged = sal_True;
1803cdf0e10cSrcweir 							if ( pThisRowInfo->pCellInfo[nX+1].bMerged )
1804cdf0e10cSrcweir 							{
1805cdf0e10cSrcweir 								SCSIZE nOverY = nArrY + 1;
1806cdf0e10cSrcweir 								while ( nOverY<nArrCount &&
1807cdf0e10cSrcweir 										pRowInfo[nOverY].pCellInfo[nX+1].bVOverlapped )
1808cdf0e10cSrcweir 								{
1809cdf0e10cSrcweir 									pRowInfo[nOverY].bChanged = sal_True;
1810cdf0e10cSrcweir 									++nOverY;
1811cdf0e10cSrcweir 								}
1812cdf0e10cSrcweir 							}
1813cdf0e10cSrcweir 						}
1814cdf0e10cSrcweir 					}
1815cdf0e10cSrcweir 				}
1816cdf0e10cSrcweir 		}
1817cdf0e10cSrcweir 	}
1818cdf0e10cSrcweir 	if ( bProgress )
1819cdf0e10cSrcweir 		ScProgress::DeleteInterpretProgress();
1820cdf0e10cSrcweir 	pDoc->DisableIdle( bWasIdleDisabled );
1821cdf0e10cSrcweir }
1822cdf0e10cSrcweir 
1823cdf0e10cSrcweir #ifdef OLD_SELECTION_PAINT
1824cdf0e10cSrcweir void ScOutputData::DrawMark( Window* pWin )
1825cdf0e10cSrcweir {
1826cdf0e10cSrcweir     Rectangle aRect;
1827cdf0e10cSrcweir     ScInvertMerger aInvert( pWin );
1828cdf0e10cSrcweir     //!	additional method AddLineRect for ScInvertMerger?
1829cdf0e10cSrcweir 
1830cdf0e10cSrcweir     long nPosY = nScrY;
1831cdf0e10cSrcweir     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
1832cdf0e10cSrcweir     {
1833cdf0e10cSrcweir         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1834cdf0e10cSrcweir         if (pThisRowInfo->bChanged)
1835cdf0e10cSrcweir         {
1836cdf0e10cSrcweir             long nPosX = nScrX;
1837cdf0e10cSrcweir             if (bLayoutRTL)
1838cdf0e10cSrcweir                 nPosX += nMirrorW - 1;      // always in pixels
1839cdf0e10cSrcweir 
1840cdf0e10cSrcweir             aRect = Rectangle( Point( nPosX,nPosY ), Size(1, pThisRowInfo->nHeight) );
1841cdf0e10cSrcweir             if (bLayoutRTL)
1842cdf0e10cSrcweir                 aRect.Left() = aRect.Right() + 1;
1843cdf0e10cSrcweir             else
1844cdf0e10cSrcweir                 aRect.Right() = aRect.Left() - 1;
1845cdf0e10cSrcweir 
1846cdf0e10cSrcweir             sal_Bool bOldMarked = sal_False;
1847cdf0e10cSrcweir             for (SCCOL nX=nX1; nX<=nX2; nX++)
1848cdf0e10cSrcweir             {
1849cdf0e10cSrcweir                 if (pThisRowInfo->pCellInfo[nX+1].bMarked != bOldMarked)
1850cdf0e10cSrcweir                 {
1851cdf0e10cSrcweir                     if (bOldMarked && aRect.Right() >= aRect.Left())
1852cdf0e10cSrcweir                         aInvert.AddRect( aRect );
1853cdf0e10cSrcweir 
1854cdf0e10cSrcweir                     if (bLayoutRTL)
1855cdf0e10cSrcweir                         aRect.Right() = nPosX;
1856cdf0e10cSrcweir                     else
1857cdf0e10cSrcweir                         aRect.Left() = nPosX;
1858cdf0e10cSrcweir 
1859cdf0e10cSrcweir                     bOldMarked = pThisRowInfo->pCellInfo[nX+1].bMarked;
1860cdf0e10cSrcweir                 }
1861cdf0e10cSrcweir 
1862cdf0e10cSrcweir                 if (bLayoutRTL)
1863cdf0e10cSrcweir                 {
1864cdf0e10cSrcweir                     nPosX -= pRowInfo[0].pCellInfo[nX+1].nWidth;
1865cdf0e10cSrcweir                     aRect.Left() = nPosX+1;
1866cdf0e10cSrcweir                 }
1867cdf0e10cSrcweir                 else
1868cdf0e10cSrcweir                 {
1869cdf0e10cSrcweir                     nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth;
1870cdf0e10cSrcweir                     aRect.Right() = nPosX-1;
1871cdf0e10cSrcweir                 }
1872cdf0e10cSrcweir             }
1873cdf0e10cSrcweir             if (bOldMarked && aRect.Right() >= aRect.Left())
1874cdf0e10cSrcweir                 aInvert.AddRect( aRect );
1875cdf0e10cSrcweir         }
1876cdf0e10cSrcweir         nPosY += pThisRowInfo->nHeight;
1877cdf0e10cSrcweir     }
1878cdf0e10cSrcweir }
1879cdf0e10cSrcweir #endif
1880cdf0e10cSrcweir 
1881cdf0e10cSrcweir void ScOutputData::DrawRefMark( SCCOL nRefStartX, SCROW nRefStartY,
1882cdf0e10cSrcweir 								SCCOL nRefEndX, SCROW nRefEndY,
1883cdf0e10cSrcweir 								const Color& rColor, sal_Bool bHandle )
1884cdf0e10cSrcweir {
1885cdf0e10cSrcweir 	PutInOrder( nRefStartX, nRefEndX );
1886cdf0e10cSrcweir 	PutInOrder( nRefStartY, nRefEndY );
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir 	if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
1889cdf0e10cSrcweir 		pDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
1890cdf0e10cSrcweir 
1891cdf0e10cSrcweir 	if ( nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
1892cdf0e10cSrcweir 		 nRefStartY <= nVisY2 && nRefEndY >= nVisY1 )
1893cdf0e10cSrcweir 	{
1894cdf0e10cSrcweir 		long nMinX = nScrX;
1895cdf0e10cSrcweir 		long nMinY = nScrY;
1896cdf0e10cSrcweir 		long nMaxX = nScrX+nScrW-1;
1897cdf0e10cSrcweir 		long nMaxY = nScrY+nScrH-1;
1898cdf0e10cSrcweir 		if ( bLayoutRTL )
1899cdf0e10cSrcweir 		{
1900cdf0e10cSrcweir 			long nTemp = nMinX;
1901cdf0e10cSrcweir 			nMinX = nMaxX;
1902cdf0e10cSrcweir 			nMaxX = nTemp;
1903cdf0e10cSrcweir 		}
1904cdf0e10cSrcweir 		long nLayoutSign = bLayoutRTL ? -1 : 1;
1905cdf0e10cSrcweir 
1906cdf0e10cSrcweir 		sal_Bool bTop    = sal_False;
1907cdf0e10cSrcweir 		sal_Bool bBottom = sal_False;
1908cdf0e10cSrcweir 		sal_Bool bLeft   = sal_False;
1909cdf0e10cSrcweir 		sal_Bool bRight	 = sal_False;
1910cdf0e10cSrcweir 
1911cdf0e10cSrcweir 		long nPosY = nScrY;
1912cdf0e10cSrcweir 		sal_Bool bNoStartY = ( nY1 < nRefStartY );
1913cdf0e10cSrcweir 		sal_Bool bNoEndY   = sal_False;
1914cdf0e10cSrcweir 		for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)		// loop to end for bNoEndY check
1915cdf0e10cSrcweir 		{
1916cdf0e10cSrcweir 			SCROW nY = pRowInfo[nArrY].nRowNo;
1917cdf0e10cSrcweir 
1918cdf0e10cSrcweir 			if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
1919cdf0e10cSrcweir 			{
1920cdf0e10cSrcweir 				nMinY = nPosY;
1921cdf0e10cSrcweir 				bTop = sal_True;
1922cdf0e10cSrcweir 			}
1923cdf0e10cSrcweir 			if ( nY==nRefEndY )
1924cdf0e10cSrcweir 			{
1925cdf0e10cSrcweir 				nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
1926cdf0e10cSrcweir 				bBottom = sal_True;
1927cdf0e10cSrcweir 			}
1928cdf0e10cSrcweir 			if ( nY>nRefEndY && bNoEndY )
1929cdf0e10cSrcweir 			{
1930cdf0e10cSrcweir 				nMaxY = nPosY-2;
1931cdf0e10cSrcweir 				bBottom = sal_True;
1932cdf0e10cSrcweir 			}
1933cdf0e10cSrcweir 			bNoStartY = ( nY < nRefStartY );
1934cdf0e10cSrcweir 			bNoEndY   = ( nY < nRefEndY );
1935cdf0e10cSrcweir 			nPosY += pRowInfo[nArrY].nHeight;
1936cdf0e10cSrcweir 		}
1937cdf0e10cSrcweir 
1938cdf0e10cSrcweir 		long nPosX = nScrX;
1939cdf0e10cSrcweir 		if ( bLayoutRTL )
1940cdf0e10cSrcweir 			nPosX += nMirrorW - 1;		// always in pixels
1941cdf0e10cSrcweir 
1942cdf0e10cSrcweir 		for (SCCOL nX=nX1; nX<=nX2; nX++)
1943cdf0e10cSrcweir 		{
1944cdf0e10cSrcweir 			if ( nX==nRefStartX )
1945cdf0e10cSrcweir 			{
1946cdf0e10cSrcweir 				nMinX = nPosX;
1947cdf0e10cSrcweir 				bLeft = sal_True;
1948cdf0e10cSrcweir 			}
1949cdf0e10cSrcweir 			if ( nX==nRefEndX )
1950cdf0e10cSrcweir 			{
1951cdf0e10cSrcweir 				nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * nLayoutSign;
1952cdf0e10cSrcweir 				bRight = sal_True;
1953cdf0e10cSrcweir 			}
1954cdf0e10cSrcweir 			nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
1955cdf0e10cSrcweir 		}
1956cdf0e10cSrcweir 
1957cdf0e10cSrcweir 		if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
1958cdf0e10cSrcweir 			 nMaxY >= nMinY )
1959cdf0e10cSrcweir 		{
1960cdf0e10cSrcweir 			pDev->SetLineColor( rColor );
1961cdf0e10cSrcweir 			if (bTop && bBottom && bLeft && bRight)
1962cdf0e10cSrcweir 			{
1963cdf0e10cSrcweir 				pDev->SetFillColor();
1964cdf0e10cSrcweir 				pDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
1965cdf0e10cSrcweir 			}
1966cdf0e10cSrcweir 			else
1967cdf0e10cSrcweir 			{
1968cdf0e10cSrcweir 				if (bTop)
1969cdf0e10cSrcweir 					pDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
1970cdf0e10cSrcweir 				if (bBottom)
1971cdf0e10cSrcweir 					pDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
1972cdf0e10cSrcweir 				if (bLeft)
1973cdf0e10cSrcweir 					pDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
1974cdf0e10cSrcweir 				if (bRight)
1975cdf0e10cSrcweir 					pDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
1976cdf0e10cSrcweir 			}
1977cdf0e10cSrcweir 			if ( bHandle && bRight && bBottom )
1978cdf0e10cSrcweir 			{
1979cdf0e10cSrcweir 				pDev->SetLineColor();
1980cdf0e10cSrcweir 				pDev->SetFillColor( rColor );
1981cdf0e10cSrcweir 				pDev->DrawRect( Rectangle( nMaxX-3*nLayoutSign, nMaxY-3, nMaxX+nLayoutSign, nMaxY+1 ) );
1982cdf0e10cSrcweir 			}
1983cdf0e10cSrcweir 		}
1984cdf0e10cSrcweir 	}
1985cdf0e10cSrcweir }
1986cdf0e10cSrcweir 
1987cdf0e10cSrcweir void ScOutputData::DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
1988cdf0e10cSrcweir 								SCCOL nRefEndX, SCROW nRefEndY,
1989cdf0e10cSrcweir 								const Color& rColor, sal_uInt16 nType )
1990cdf0e10cSrcweir {
1991cdf0e10cSrcweir 	PutInOrder( nRefStartX, nRefEndX );
1992cdf0e10cSrcweir 	PutInOrder( nRefStartY, nRefEndY );
1993cdf0e10cSrcweir 
1994cdf0e10cSrcweir 	if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
1995cdf0e10cSrcweir 		pDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
1996cdf0e10cSrcweir 
1997cdf0e10cSrcweir 	if ( nRefStartX <= nVisX2 + 1 && nRefEndX >= nVisX1 &&
1998cdf0e10cSrcweir 		 nRefStartY <= nVisY2 + 1 && nRefEndY >= nVisY1 )		// +1 because it touches next cells left/top
1999cdf0e10cSrcweir 	{
2000cdf0e10cSrcweir 		long nMinX = nScrX;
2001cdf0e10cSrcweir 		long nMinY = nScrY;
2002cdf0e10cSrcweir 		long nMaxX = nScrX+nScrW-1;
2003cdf0e10cSrcweir 		long nMaxY = nScrY+nScrH-1;
2004cdf0e10cSrcweir 		if ( bLayoutRTL )
2005cdf0e10cSrcweir 		{
2006cdf0e10cSrcweir 			long nTemp = nMinX;
2007cdf0e10cSrcweir 			nMinX = nMaxX;
2008cdf0e10cSrcweir 			nMaxX = nTemp;
2009cdf0e10cSrcweir 		}
2010cdf0e10cSrcweir 		long nLayoutSign = bLayoutRTL ? -1 : 1;
2011cdf0e10cSrcweir 
2012cdf0e10cSrcweir 		sal_Bool bTop    = sal_False;
2013cdf0e10cSrcweir 		sal_Bool bBottom = sal_False;
2014cdf0e10cSrcweir 		sal_Bool bLeft   = sal_False;
2015cdf0e10cSrcweir 		sal_Bool bRight	 = sal_False;
2016cdf0e10cSrcweir 
2017cdf0e10cSrcweir 		long nPosY = nScrY;
2018cdf0e10cSrcweir 		sal_Bool bNoStartY = ( nY1 < nRefStartY );
2019cdf0e10cSrcweir 		sal_Bool bNoEndY   = sal_False;
2020cdf0e10cSrcweir 		for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)		// loop to end for bNoEndY check
2021cdf0e10cSrcweir 		{
2022cdf0e10cSrcweir 			SCROW nY = pRowInfo[nArrY].nRowNo;
2023cdf0e10cSrcweir 
2024cdf0e10cSrcweir 			if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
2025cdf0e10cSrcweir 			{
2026cdf0e10cSrcweir 				nMinY = nPosY - 1;
2027cdf0e10cSrcweir 				bTop = sal_True;
2028cdf0e10cSrcweir 			}
2029cdf0e10cSrcweir 			if ( nY==nRefEndY )
2030cdf0e10cSrcweir 			{
2031cdf0e10cSrcweir 				nMaxY = nPosY + pRowInfo[nArrY].nHeight - 1;
2032cdf0e10cSrcweir 				bBottom = sal_True;
2033cdf0e10cSrcweir 			}
2034cdf0e10cSrcweir 			if ( nY>nRefEndY && bNoEndY )
2035cdf0e10cSrcweir 			{
2036cdf0e10cSrcweir 				nMaxY = nPosY - 1;
2037cdf0e10cSrcweir 				bBottom = sal_True;
2038cdf0e10cSrcweir 			}
2039cdf0e10cSrcweir 			bNoStartY = ( nY < nRefStartY );
2040cdf0e10cSrcweir 			bNoEndY   = ( nY < nRefEndY );
2041cdf0e10cSrcweir 			nPosY += pRowInfo[nArrY].nHeight;
2042cdf0e10cSrcweir 		}
2043cdf0e10cSrcweir 
2044cdf0e10cSrcweir 		long nPosX = nScrX;
2045cdf0e10cSrcweir 		if ( bLayoutRTL )
2046cdf0e10cSrcweir 			nPosX += nMirrorW - 1;		// always in pixels
2047cdf0e10cSrcweir 
2048cdf0e10cSrcweir 		for (SCCOL nX=nX1; nX<=nX2+1; nX++)
2049cdf0e10cSrcweir 		{
2050cdf0e10cSrcweir 			if ( nX==nRefStartX )
2051cdf0e10cSrcweir 			{
2052cdf0e10cSrcweir 				nMinX = nPosX - nLayoutSign;
2053cdf0e10cSrcweir 				bLeft = sal_True;
2054cdf0e10cSrcweir 			}
2055cdf0e10cSrcweir 			if ( nX==nRefEndX )
2056cdf0e10cSrcweir 			{
2057cdf0e10cSrcweir 				nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 1 ) * nLayoutSign;
2058cdf0e10cSrcweir 				bRight = sal_True;
2059cdf0e10cSrcweir 			}
2060cdf0e10cSrcweir 			nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2061cdf0e10cSrcweir 		}
2062cdf0e10cSrcweir 
2063cdf0e10cSrcweir 		if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
2064cdf0e10cSrcweir 			 nMaxY >= nMinY )
2065cdf0e10cSrcweir 		{
2066cdf0e10cSrcweir 			if ( nType == SC_CAT_DELETE_ROWS )
2067cdf0e10cSrcweir 				bLeft = bRight = bBottom = sal_False;		//! dicke Linie ???
2068cdf0e10cSrcweir 			else if ( nType == SC_CAT_DELETE_COLS )
2069cdf0e10cSrcweir 				bTop = bBottom = bRight = sal_False;		//! dicke Linie ???
2070cdf0e10cSrcweir 
2071cdf0e10cSrcweir 			pDev->SetLineColor( rColor );
2072cdf0e10cSrcweir 			if (bTop && bBottom && bLeft && bRight)
2073cdf0e10cSrcweir 			{
2074cdf0e10cSrcweir 				pDev->SetFillColor();
2075cdf0e10cSrcweir 				pDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
2076cdf0e10cSrcweir 			}
2077cdf0e10cSrcweir 			else
2078cdf0e10cSrcweir 			{
2079cdf0e10cSrcweir 				if (bTop)
2080cdf0e10cSrcweir 				{
2081cdf0e10cSrcweir 					pDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
2082cdf0e10cSrcweir 					if ( nType == SC_CAT_DELETE_ROWS )
2083cdf0e10cSrcweir 						pDev->DrawLine( Point( nMinX,nMinY+1 ), Point( nMaxX,nMinY+1 ) );
2084cdf0e10cSrcweir 				}
2085cdf0e10cSrcweir 				if (bBottom)
2086cdf0e10cSrcweir 					pDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
2087cdf0e10cSrcweir 				if (bLeft)
2088cdf0e10cSrcweir 				{
2089cdf0e10cSrcweir 					pDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
2090cdf0e10cSrcweir 					if ( nType == SC_CAT_DELETE_COLS )
2091cdf0e10cSrcweir 						pDev->DrawLine( Point( nMinX+nLayoutSign,nMinY ), Point( nMinX+nLayoutSign,nMaxY ) );
2092cdf0e10cSrcweir 				}
2093cdf0e10cSrcweir 				if (bRight)
2094cdf0e10cSrcweir 					pDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
2095cdf0e10cSrcweir 			}
2096cdf0e10cSrcweir 			if ( bLeft && bTop )
2097cdf0e10cSrcweir 			{
2098cdf0e10cSrcweir 				pDev->SetLineColor();
2099cdf0e10cSrcweir 				pDev->SetFillColor( rColor );
2100cdf0e10cSrcweir 				pDev->DrawRect( Rectangle( nMinX+nLayoutSign, nMinY+1, nMinX+3*nLayoutSign, nMinY+3 ) );
2101cdf0e10cSrcweir 			}
2102cdf0e10cSrcweir 		}
2103cdf0e10cSrcweir 	}
2104cdf0e10cSrcweir }
2105cdf0e10cSrcweir 
2106cdf0e10cSrcweir void ScOutputData::DrawChangeTrack()
2107cdf0e10cSrcweir {
2108cdf0e10cSrcweir 	ScChangeTrack* pTrack = pDoc->GetChangeTrack();
2109cdf0e10cSrcweir 	ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
2110cdf0e10cSrcweir 	if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
2111cdf0e10cSrcweir 		return;			// nix da oder abgeschaltet
2112cdf0e10cSrcweir 
2113cdf0e10cSrcweir 	ScActionColorChanger aColorChanger(*pTrack);
2114cdf0e10cSrcweir 
2115cdf0e10cSrcweir 	//	Clipping passiert von aussen
2116cdf0e10cSrcweir 	//!	ohne Clipping, nur betroffene Zeilen painten ??!??!?
2117cdf0e10cSrcweir 
2118cdf0e10cSrcweir 	SCCOL nEndX = nX2;
2119cdf0e10cSrcweir 	SCROW nEndY = nY2;
2120cdf0e10cSrcweir 	if ( nEndX < MAXCOL ) ++nEndX;		// auch noch von der naechsten Zelle, weil die Markierung
2121cdf0e10cSrcweir 	if ( nEndY < MAXROW ) ++nEndY;		// in die jeweils vorhergehende Zelle hineinragt
2122cdf0e10cSrcweir 	ScRange aViewRange( nX1, nY1, nTab, nEndX, nEndY, nTab );
2123cdf0e10cSrcweir 	const ScChangeAction* pAction = pTrack->GetFirst();
2124cdf0e10cSrcweir 	while (pAction)
2125cdf0e10cSrcweir 	{
2126cdf0e10cSrcweir 		ScChangeActionType eActionType;
2127cdf0e10cSrcweir 		if ( pAction->IsVisible() )
2128cdf0e10cSrcweir 		{
2129cdf0e10cSrcweir 			eActionType = pAction->GetType();
2130cdf0e10cSrcweir 			const ScBigRange& rBig = pAction->GetBigRange();
2131cdf0e10cSrcweir 			if ( rBig.aStart.Tab() == nTab )
2132cdf0e10cSrcweir 			{
2133cdf0e10cSrcweir 				ScRange aRange = rBig.MakeRange();
2134cdf0e10cSrcweir 
2135cdf0e10cSrcweir 				if ( eActionType == SC_CAT_DELETE_ROWS )
2136cdf0e10cSrcweir 					aRange.aEnd.SetRow( aRange.aStart.Row() );
2137cdf0e10cSrcweir 				else if ( eActionType == SC_CAT_DELETE_COLS )
2138cdf0e10cSrcweir 					aRange.aEnd.SetCol( aRange.aStart.Col() );
2139cdf0e10cSrcweir 
2140cdf0e10cSrcweir 				if ( aRange.Intersects( aViewRange ) &&
2141cdf0e10cSrcweir 					 ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
2142cdf0e10cSrcweir 				{
2143cdf0e10cSrcweir 					aColorChanger.Update( *pAction );
2144cdf0e10cSrcweir 					Color aColor( aColorChanger.GetColor() );
2145cdf0e10cSrcweir 					DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2146cdf0e10cSrcweir                                     aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2147cdf0e10cSrcweir 
2148cdf0e10cSrcweir 				}
2149cdf0e10cSrcweir 			}
2150cdf0e10cSrcweir 			if ( eActionType == SC_CAT_MOVE &&
2151cdf0e10cSrcweir 					((const ScChangeActionMove*)pAction)->
2152cdf0e10cSrcweir 						GetFromRange().aStart.Tab() == nTab )
2153cdf0e10cSrcweir 			{
2154cdf0e10cSrcweir 				ScRange aRange = ((const ScChangeActionMove*)pAction)->
2155cdf0e10cSrcweir 						GetFromRange().MakeRange();
2156cdf0e10cSrcweir 				if ( aRange.Intersects( aViewRange ) &&
2157cdf0e10cSrcweir 					 ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
2158cdf0e10cSrcweir 				{
2159cdf0e10cSrcweir 					aColorChanger.Update( *pAction );
2160cdf0e10cSrcweir 					Color aColor( aColorChanger.GetColor() );
2161cdf0e10cSrcweir 					DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
2162cdf0e10cSrcweir                                     aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
2163cdf0e10cSrcweir 				}
2164cdf0e10cSrcweir 			}
2165cdf0e10cSrcweir 		}
2166cdf0e10cSrcweir 
2167cdf0e10cSrcweir 		pAction = pAction->GetNext();
2168cdf0e10cSrcweir 	}
2169cdf0e10cSrcweir }
2170cdf0e10cSrcweir 
2171cdf0e10cSrcweir void ScOutputData::DrawNoteMarks()
2172cdf0e10cSrcweir {
2173cdf0e10cSrcweir 	sal_Bool bFirst = sal_True;
2174cdf0e10cSrcweir 
2175cdf0e10cSrcweir 	long nInitPosX = nScrX;
2176cdf0e10cSrcweir 	if ( bLayoutRTL )
2177cdf0e10cSrcweir 		nInitPosX += nMirrorW - 1;				// always in pixels
2178cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
2179cdf0e10cSrcweir 
2180cdf0e10cSrcweir 	long nPosY = nScrY;
2181cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2182cdf0e10cSrcweir 	{
2183cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2184cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged )
2185cdf0e10cSrcweir 		{
2186cdf0e10cSrcweir 			long nPosX = nInitPosX;
2187cdf0e10cSrcweir 			for (SCCOL nX=nX1; nX<=nX2; nX++)
2188cdf0e10cSrcweir 			{
2189cdf0e10cSrcweir 				CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2190cdf0e10cSrcweir 				ScBaseCell* pCell = pInfo->pCell;
2191cdf0e10cSrcweir 				sal_Bool bIsMerged = sal_False;
2192cdf0e10cSrcweir 
2193cdf0e10cSrcweir 				if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2194cdf0e10cSrcweir 				{
2195cdf0e10cSrcweir 					// find start of merged cell
2196cdf0e10cSrcweir 					bIsMerged = sal_True;
2197cdf0e10cSrcweir 					SCROW nY = pRowInfo[nArrY].nRowNo;
2198cdf0e10cSrcweir 					SCCOL nMergeX = nX;
2199cdf0e10cSrcweir 					SCROW nMergeY = nY;
2200cdf0e10cSrcweir 					pDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2201cdf0e10cSrcweir 					pCell = pDoc->GetCell( ScAddress(nMergeX,nMergeY,nTab) );
2202cdf0e10cSrcweir 					// use origin's pCell for NotePtr test below
2203cdf0e10cSrcweir 				}
2204cdf0e10cSrcweir 
2205cdf0e10cSrcweir                 if ( pCell && pCell->HasNote() && ( bIsMerged ||
2206cdf0e10cSrcweir 						( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
2207cdf0e10cSrcweir 				{
2208cdf0e10cSrcweir 					if (bFirst)
2209cdf0e10cSrcweir 					{
2210cdf0e10cSrcweir 						pDev->SetLineColor();
2211cdf0e10cSrcweir 
2212cdf0e10cSrcweir 						const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2213cdf0e10cSrcweir 						if ( bUseStyleColor && rStyleSettings.GetHighContrastMode() )
2214cdf0e10cSrcweir                             pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2215cdf0e10cSrcweir 						else
2216cdf0e10cSrcweir 							pDev->SetFillColor(COL_LIGHTRED);
2217cdf0e10cSrcweir 
2218cdf0e10cSrcweir 						bFirst = sal_False;
2219cdf0e10cSrcweir 					}
2220cdf0e10cSrcweir 
2221cdf0e10cSrcweir 					long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 4 ) * nLayoutSign;
2222cdf0e10cSrcweir 					if ( bIsMerged || pInfo->bMerged )
2223cdf0e10cSrcweir 					{
2224cdf0e10cSrcweir 						//	if merged, add widths of all cells
2225cdf0e10cSrcweir 						SCCOL nNextX = nX + 1;
2226cdf0e10cSrcweir 						while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
2227cdf0e10cSrcweir 						{
2228cdf0e10cSrcweir 							nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
2229cdf0e10cSrcweir 							++nNextX;
2230cdf0e10cSrcweir 						}
2231cdf0e10cSrcweir 					}
2232cdf0e10cSrcweir 					if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2233cdf0e10cSrcweir 						pDev->DrawRect( Rectangle( nMarkX,nPosY,nMarkX+2*nLayoutSign,nPosY+2 ) );
2234cdf0e10cSrcweir 				}
2235cdf0e10cSrcweir 
2236cdf0e10cSrcweir 				nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2237cdf0e10cSrcweir 			}
2238cdf0e10cSrcweir 		}
2239cdf0e10cSrcweir 		nPosY += pThisRowInfo->nHeight;
2240cdf0e10cSrcweir 	}
2241cdf0e10cSrcweir }
2242cdf0e10cSrcweir 
2243cdf0e10cSrcweir void ScOutputData::AddPDFNotes()
2244cdf0e10cSrcweir {
2245cdf0e10cSrcweir     vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
2246cdf0e10cSrcweir     if ( !pPDFData || !pPDFData->GetIsExportNotes() )
2247cdf0e10cSrcweir         return;
2248cdf0e10cSrcweir 
2249cdf0e10cSrcweir     long nInitPosX = nScrX;
2250cdf0e10cSrcweir     if ( bLayoutRTL )
2251cdf0e10cSrcweir     {
2252cdf0e10cSrcweir         Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2253cdf0e10cSrcweir         long nOneX = aOnePixel.Width();
2254cdf0e10cSrcweir         nInitPosX += nMirrorW - nOneX;
2255cdf0e10cSrcweir     }
2256cdf0e10cSrcweir     long nLayoutSign = bLayoutRTL ? -1 : 1;
2257cdf0e10cSrcweir 
2258cdf0e10cSrcweir     long nPosY = nScrY;
2259cdf0e10cSrcweir     for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2260cdf0e10cSrcweir     {
2261cdf0e10cSrcweir         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2262cdf0e10cSrcweir         if ( pThisRowInfo->bChanged )
2263cdf0e10cSrcweir         {
2264cdf0e10cSrcweir             long nPosX = nInitPosX;
2265cdf0e10cSrcweir             for (SCCOL nX=nX1; nX<=nX2; nX++)
2266cdf0e10cSrcweir             {
2267cdf0e10cSrcweir                 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2268cdf0e10cSrcweir                 ScBaseCell* pCell = pInfo->pCell;
2269cdf0e10cSrcweir                 sal_Bool bIsMerged = sal_False;
2270cdf0e10cSrcweir                 SCROW nY = pRowInfo[nArrY].nRowNo;
2271cdf0e10cSrcweir                 SCCOL nMergeX = nX;
2272cdf0e10cSrcweir                 SCROW nMergeY = nY;
2273cdf0e10cSrcweir 
2274cdf0e10cSrcweir                 if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
2275cdf0e10cSrcweir                 {
2276cdf0e10cSrcweir                     // find start of merged cell
2277cdf0e10cSrcweir                     bIsMerged = sal_True;
2278cdf0e10cSrcweir                     pDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
2279cdf0e10cSrcweir                     pCell = pDoc->GetCell( ScAddress(nMergeX,nMergeY,nTab) );
2280cdf0e10cSrcweir                     // use origin's pCell for NotePtr test below
2281cdf0e10cSrcweir                 }
2282cdf0e10cSrcweir 
2283cdf0e10cSrcweir                 if ( pCell && pCell->HasNote() && ( bIsMerged ||
2284cdf0e10cSrcweir                         ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
2285cdf0e10cSrcweir                 {
2286cdf0e10cSrcweir                     long nNoteWidth = (long)( SC_CLIPMARK_SIZE * nPPTX );
2287cdf0e10cSrcweir                     long nNoteHeight = (long)( SC_CLIPMARK_SIZE * nPPTY );
2288cdf0e10cSrcweir 
2289cdf0e10cSrcweir                     long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - nNoteWidth ) * nLayoutSign;
2290cdf0e10cSrcweir                     if ( bIsMerged || pInfo->bMerged )
2291cdf0e10cSrcweir                     {
2292cdf0e10cSrcweir                         //  if merged, add widths of all cells
2293cdf0e10cSrcweir                         SCCOL nNextX = nX + 1;
2294cdf0e10cSrcweir                         while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
2295cdf0e10cSrcweir                         {
2296cdf0e10cSrcweir                             nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
2297cdf0e10cSrcweir                             ++nNextX;
2298cdf0e10cSrcweir                         }
2299cdf0e10cSrcweir                     }
2300cdf0e10cSrcweir                     if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
2301cdf0e10cSrcweir                     {
2302cdf0e10cSrcweir                         Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight );
2303cdf0e10cSrcweir                         const ScPostIt* pNote = pCell->GetNote();
2304cdf0e10cSrcweir 
2305cdf0e10cSrcweir                         // Note title is the cell address (as on printed note pages)
2306cdf0e10cSrcweir                         String aTitle;
2307cdf0e10cSrcweir                         ScAddress aAddress( nMergeX, nMergeY, nTab );
2308cdf0e10cSrcweir                         aAddress.Format( aTitle, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
2309cdf0e10cSrcweir 
2310cdf0e10cSrcweir                         // Content has to be a simple string without line breaks
2311cdf0e10cSrcweir                         String aContent = pNote->GetText();
2312cdf0e10cSrcweir                         xub_StrLen nPos;
2313cdf0e10cSrcweir                         while ( (nPos=aContent.Search('\n')) != STRING_NOTFOUND )
2314cdf0e10cSrcweir                             aContent.SetChar( nPos, ' ' );
2315cdf0e10cSrcweir 
2316cdf0e10cSrcweir                         vcl::PDFNote aNote;
2317cdf0e10cSrcweir                         aNote.Title = aTitle;
2318cdf0e10cSrcweir                         aNote.Contents = aContent;
2319cdf0e10cSrcweir                         pPDFData->CreateNote( aNoteRect, aNote );
2320cdf0e10cSrcweir                     }
2321cdf0e10cSrcweir                 }
2322cdf0e10cSrcweir 
2323cdf0e10cSrcweir                 nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2324cdf0e10cSrcweir             }
2325cdf0e10cSrcweir         }
2326cdf0e10cSrcweir         nPosY += pThisRowInfo->nHeight;
2327cdf0e10cSrcweir     }
2328cdf0e10cSrcweir }
2329cdf0e10cSrcweir 
2330cdf0e10cSrcweir void ScOutputData::DrawClipMarks()
2331cdf0e10cSrcweir {
2332cdf0e10cSrcweir 	if (!bAnyClipped)
2333cdf0e10cSrcweir 		return;
2334cdf0e10cSrcweir 
2335cdf0e10cSrcweir 	Color aArrowFillCol( COL_LIGHTRED );
2336cdf0e10cSrcweir 
2337cdf0e10cSrcweir 	sal_uLong nOldDrawMode = pDev->GetDrawMode();
2338cdf0e10cSrcweir 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2339cdf0e10cSrcweir 	if ( bUseStyleColor && rStyleSettings.GetHighContrastMode() )
2340cdf0e10cSrcweir 	{
2341cdf0e10cSrcweir 		//	use DrawMode to change the arrow's outline color
2342cdf0e10cSrcweir 		pDev->SetDrawMode( nOldDrawMode | DRAWMODE_SETTINGSLINE );
2343cdf0e10cSrcweir 		//	use text color also for the fill color
2344cdf0e10cSrcweir         aArrowFillCol.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2345cdf0e10cSrcweir 	}
2346cdf0e10cSrcweir 
2347cdf0e10cSrcweir 	long nInitPosX = nScrX;
2348cdf0e10cSrcweir 	if ( bLayoutRTL )
2349cdf0e10cSrcweir 		nInitPosX += nMirrorW - 1;				// always in pixels
2350cdf0e10cSrcweir 	long nLayoutSign = bLayoutRTL ? -1 : 1;
2351cdf0e10cSrcweir 
2352cdf0e10cSrcweir 	Rectangle aCellRect;
2353cdf0e10cSrcweir 	long nPosY = nScrY;
2354cdf0e10cSrcweir 	for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
2355cdf0e10cSrcweir 	{
2356cdf0e10cSrcweir 		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
2357cdf0e10cSrcweir 		if ( pThisRowInfo->bChanged )
2358cdf0e10cSrcweir 		{
2359cdf0e10cSrcweir 			SCROW nY = pThisRowInfo->nRowNo;
2360cdf0e10cSrcweir 			long nPosX = nInitPosX;
2361cdf0e10cSrcweir 			for (SCCOL nX=nX1; nX<=nX2; nX++)
2362cdf0e10cSrcweir 			{
2363cdf0e10cSrcweir 				CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
2364cdf0e10cSrcweir 				if (pInfo->nClipMark)
2365cdf0e10cSrcweir 				{
2366cdf0e10cSrcweir 					if (pInfo->bHOverlapped || pInfo->bVOverlapped)
2367cdf0e10cSrcweir 					{
2368cdf0e10cSrcweir 						//	merge origin may be outside of visible area - use document functions
2369cdf0e10cSrcweir 
2370cdf0e10cSrcweir 						SCCOL nOverX = nX;
2371cdf0e10cSrcweir 						SCROW nOverY = nY;
2372cdf0e10cSrcweir 						long nStartPosX = nPosX;
2373cdf0e10cSrcweir 						long nStartPosY = nPosY;
2374cdf0e10cSrcweir 
2375cdf0e10cSrcweir 						while ( nOverX > 0 && ( ((const ScMergeFlagAttr*)pDoc->GetAttr(
2376cdf0e10cSrcweir 								nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_HOR ) )
2377cdf0e10cSrcweir 						{
2378cdf0e10cSrcweir 							--nOverX;
2379cdf0e10cSrcweir 							nStartPosX -= nLayoutSign * (long) ( pDoc->GetColWidth(nOverX,nTab) * nPPTX );
2380cdf0e10cSrcweir 						}
2381cdf0e10cSrcweir 
2382cdf0e10cSrcweir 						while ( nOverY > 0 && ( ((const ScMergeFlagAttr*)pDoc->GetAttr(
2383cdf0e10cSrcweir 								nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_VER ) )
2384cdf0e10cSrcweir 						{
2385cdf0e10cSrcweir 							--nOverY;
2386cdf0e10cSrcweir 							nStartPosY -= nLayoutSign * (long) ( pDoc->GetRowHeight(nOverY,nTab) * nPPTY );
2387cdf0e10cSrcweir 						}
2388cdf0e10cSrcweir 
2389cdf0e10cSrcweir 						long nOutWidth = (long) ( pDoc->GetColWidth(nOverX,nTab) * nPPTX );
2390cdf0e10cSrcweir 						long nOutHeight = (long) ( pDoc->GetRowHeight(nOverY,nTab) * nPPTY );
2391cdf0e10cSrcweir 
2392cdf0e10cSrcweir 						const ScMergeAttr* pMerge = (const ScMergeAttr*)
2393cdf0e10cSrcweir 									pDoc->GetAttr( nOverX, nOverY, nTab, ATTR_MERGE );
2394cdf0e10cSrcweir 						SCCOL nCountX = pMerge->GetColMerge();
2395cdf0e10cSrcweir 						for (SCCOL i=1; i<nCountX; i++)
2396cdf0e10cSrcweir 							nOutWidth += (long) ( pDoc->GetColWidth(nOverX+i,nTab) * nPPTX );
2397cdf0e10cSrcweir 						SCROW nCountY = pMerge->GetRowMerge();
2398cdf0e10cSrcweir                         nOutHeight += (long) pDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, nPPTY);
2399cdf0e10cSrcweir 
2400cdf0e10cSrcweir 						if ( bLayoutRTL )
2401cdf0e10cSrcweir 							nStartPosX -= nOutWidth - 1;
2402cdf0e10cSrcweir 						aCellRect = Rectangle( Point( nStartPosX, nStartPosY ), Size( nOutWidth, nOutHeight ) );
2403cdf0e10cSrcweir 					}
2404cdf0e10cSrcweir 					else
2405cdf0e10cSrcweir 					{
2406cdf0e10cSrcweir 						long nOutWidth = pRowInfo[0].pCellInfo[nX+1].nWidth;
2407cdf0e10cSrcweir 						long nOutHeight = pThisRowInfo->nHeight;
2408cdf0e10cSrcweir 
2409cdf0e10cSrcweir 						if ( pInfo->bMerged && pInfo->pPatternAttr )
2410cdf0e10cSrcweir 						{
2411cdf0e10cSrcweir 							SCCOL nOverX = nX;
2412cdf0e10cSrcweir 							SCROW nOverY = nY;
2413cdf0e10cSrcweir 							const ScMergeAttr* pMerge =
2414cdf0e10cSrcweir 									(ScMergeAttr*)&pInfo->pPatternAttr->GetItem(ATTR_MERGE);
2415cdf0e10cSrcweir 							SCCOL nCountX = pMerge->GetColMerge();
2416cdf0e10cSrcweir 							for (SCCOL i=1; i<nCountX; i++)
2417cdf0e10cSrcweir 								nOutWidth += (long) ( pDoc->GetColWidth(nOverX+i,nTab) * nPPTX );
2418cdf0e10cSrcweir 							SCROW nCountY = pMerge->GetRowMerge();
2419cdf0e10cSrcweir                             nOutHeight += (long) pDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, nPPTY);
2420cdf0e10cSrcweir 						}
2421cdf0e10cSrcweir 
2422cdf0e10cSrcweir 						long nStartPosX = nPosX;
2423cdf0e10cSrcweir 						if ( bLayoutRTL )
2424cdf0e10cSrcweir 							nStartPosX -= nOutWidth - 1;
2425cdf0e10cSrcweir                         // #i80447# create aCellRect from two points in case nOutWidth is 0
2426cdf0e10cSrcweir                         aCellRect = Rectangle( Point( nStartPosX, nPosY ),
2427cdf0e10cSrcweir                                                Point( nStartPosX+nOutWidth-1, nPosY+nOutHeight-1 ) );
2428cdf0e10cSrcweir 					}
2429cdf0e10cSrcweir 
2430cdf0e10cSrcweir 					aCellRect.Bottom() -= 1;	// don't paint over the cell grid
2431cdf0e10cSrcweir 					if ( bLayoutRTL )
2432cdf0e10cSrcweir 						aCellRect.Left() += 1;
2433cdf0e10cSrcweir 					else
2434cdf0e10cSrcweir 						aCellRect.Right() -= 1;
2435cdf0e10cSrcweir 
2436cdf0e10cSrcweir 					long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
2437cdf0e10cSrcweir 					Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
2438cdf0e10cSrcweir 
2439cdf0e10cSrcweir 					if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_RIGHT : SC_CLIPMARK_LEFT ) )
2440cdf0e10cSrcweir 					{
2441cdf0e10cSrcweir 						//	visually left
2442cdf0e10cSrcweir 						Rectangle aMarkRect = aCellRect;
2443cdf0e10cSrcweir 						aMarkRect.Right() = aCellRect.Left()+nMarkPixel-1;
2444cdf0e10cSrcweir #if 0
2445cdf0e10cSrcweir 						//!	Test
2446cdf0e10cSrcweir 						pDev->SetLineColor(); pDev->SetFillColor(COL_YELLOW);
2447cdf0e10cSrcweir 						pDev->DrawRect(aMarkRect);
2448cdf0e10cSrcweir 						//!	Test
2449cdf0e10cSrcweir #endif
2450cdf0e10cSrcweir 						SvxFont::DrawArrow( *pDev, aMarkRect, aMarkSize, aArrowFillCol, sal_True );
2451cdf0e10cSrcweir 					}
2452cdf0e10cSrcweir 					if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_LEFT : SC_CLIPMARK_RIGHT ) )
2453cdf0e10cSrcweir 					{
2454cdf0e10cSrcweir 						//	visually right
2455cdf0e10cSrcweir 						Rectangle aMarkRect = aCellRect;
2456cdf0e10cSrcweir 						aMarkRect.Left() = aCellRect.Right()-nMarkPixel+1;
2457cdf0e10cSrcweir #if 0
2458cdf0e10cSrcweir 						//!	Test
2459cdf0e10cSrcweir 						pDev->SetLineColor(); pDev->SetFillColor(COL_LIGHTGREEN);
2460cdf0e10cSrcweir 						pDev->DrawRect(aMarkRect);
2461cdf0e10cSrcweir 						//!	Test
2462cdf0e10cSrcweir #endif
2463cdf0e10cSrcweir 						SvxFont::DrawArrow( *pDev, aMarkRect, aMarkSize, aArrowFillCol, sal_False );
2464cdf0e10cSrcweir 					}
2465cdf0e10cSrcweir 				}
2466cdf0e10cSrcweir 				nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
2467cdf0e10cSrcweir 			}
2468cdf0e10cSrcweir 		}
2469cdf0e10cSrcweir 		nPosY += pThisRowInfo->nHeight;
2470cdf0e10cSrcweir 	}
2471cdf0e10cSrcweir 
2472cdf0e10cSrcweir 	pDev->SetDrawMode(nOldDrawMode);
2473cdf0e10cSrcweir }
2474cdf0e10cSrcweir 
2475cdf0e10cSrcweir 
2476cdf0e10cSrcweir 
2477