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