xref: /trunk/main/sc/source/ui/view/output.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <com/sun/star/embed/EmbedMisc.hpp>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "scitems.hxx"
32cdf0e10cSrcweir #include <editeng/boxitem.hxx>
33cdf0e10cSrcweir #include <editeng/brshitem.hxx>
34cdf0e10cSrcweir #include <editeng/editdata.hxx>
35cdf0e10cSrcweir #include <svtools/colorcfg.hxx>
36cdf0e10cSrcweir #include <svx/rotmodit.hxx>
37cdf0e10cSrcweir #include <editeng/shaditem.hxx>
38cdf0e10cSrcweir #include <editeng/svxfont.hxx>
39cdf0e10cSrcweir #include <svx/svdoole2.hxx>
40cdf0e10cSrcweir #include <tools/poly.hxx>
41cdf0e10cSrcweir #include <vcl/svapp.hxx>
42cdf0e10cSrcweir #include <vcl/pdfextoutdevdata.hxx>
43cdf0e10cSrcweir #include <svtools/accessibilityoptions.hxx>
44cdf0e10cSrcweir #include <svx/framelinkarray.hxx>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include "output.hxx"
47cdf0e10cSrcweir #include "document.hxx"
48cdf0e10cSrcweir #include "cell.hxx"
49cdf0e10cSrcweir #include "attrib.hxx"
50cdf0e10cSrcweir #include "patattr.hxx"
51cdf0e10cSrcweir #include "docpool.hxx"
52cdf0e10cSrcweir #include "tabvwsh.hxx"
53cdf0e10cSrcweir #include "progress.hxx"
54cdf0e10cSrcweir #include "pagedata.hxx"
55cdf0e10cSrcweir #include "chgtrack.hxx"
56cdf0e10cSrcweir #include "chgviset.hxx"
57cdf0e10cSrcweir #include "viewutil.hxx"
58cdf0e10cSrcweir #include "gridmerg.hxx"
59cdf0e10cSrcweir #include "invmerge.hxx"
60cdf0e10cSrcweir #include "fillinfo.hxx"
61cdf0e10cSrcweir #include "scmod.hxx"
62cdf0e10cSrcweir #include "appoptio.hxx"
63cdf0e10cSrcweir #include "postit.hxx"
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #include <math.h>
66cdf0e10cSrcweir 
67cdf0e10cSrcweir using namespace com::sun::star;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
70cdf0e10cSrcweir 
71cdf0e10cSrcweir //  Farben fuer ChangeTracking "nach Autor" wie im Writer (swmodul1.cxx)
72cdf0e10cSrcweir 
73cdf0e10cSrcweir #define SC_AUTHORCOLORCOUNT     9
74cdf0e10cSrcweir 
75cdf0e10cSrcweir static ColorData nAuthorColor[ SC_AUTHORCOLORCOUNT ] = {
76cdf0e10cSrcweir                     COL_LIGHTRED,       COL_LIGHTBLUE,      COL_LIGHTMAGENTA,
77cdf0e10cSrcweir                     COL_GREEN,          COL_RED,            COL_BLUE,
78cdf0e10cSrcweir                     COL_BROWN,          COL_MAGENTA,        COL_CYAN };
79cdf0e10cSrcweir 
80cdf0e10cSrcweir //------------------------------------------------------------------
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;
1671cdf0e10cSrcweir     Rectangle aDrawingRect;
1672*d8ed516eSArmin Le Grand     bool bHad(false);
1673*d8ed516eSArmin Le Grand     long nPosY = nScrY;
1674*d8ed516eSArmin Le Grand     SCSIZE nArrY;
1675*d8ed516eSArmin Le Grand 
1676cdf0e10cSrcweir     aDrawingRect.Left() = nScrX;
1677cdf0e10cSrcweir     aDrawingRect.Right() = nScrX+nScrW-1;
1678cdf0e10cSrcweir 
1679cdf0e10cSrcweir     for(nArrY=1; nArrY+1<nArrCount; nArrY++)
1680cdf0e10cSrcweir     {
1681cdf0e10cSrcweir         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
1682cdf0e10cSrcweir 
1683cdf0e10cSrcweir         if(pThisRowInfo->bChanged)
1684cdf0e10cSrcweir         {
1685cdf0e10cSrcweir             if(!bHad)
1686cdf0e10cSrcweir             {
1687cdf0e10cSrcweir                 aDrawingRect.Top() = nPosY;
1688*d8ed516eSArmin Le Grand                 bHad = true;
1689cdf0e10cSrcweir             }
1690*d8ed516eSArmin Le Grand 
1691cdf0e10cSrcweir             aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
1692cdf0e10cSrcweir         }
1693cdf0e10cSrcweir         else if(bHad)
1694cdf0e10cSrcweir         {
1695*d8ed516eSArmin Le Grand             aRegion.Union(pDev->PixelToLogic(aDrawingRect));
1696*d8ed516eSArmin Le Grand             bHad = false;
1697cdf0e10cSrcweir         }
1698*d8ed516eSArmin Le Grand 
1699cdf0e10cSrcweir         nPosY += pRowInfo[nArrY].nHeight;
1700cdf0e10cSrcweir     }
1701cdf0e10cSrcweir 
1702cdf0e10cSrcweir     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 }
2454