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