1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/embed/EmbedMisc.hpp>
22 #include "scitems.hxx"
23 #include <editeng/boxitem.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <editeng/editdata.hxx>
26 #include <svtools/colorcfg.hxx>
27 #include <svx/rotmodit.hxx>
28 #include <editeng/shaditem.hxx>
29 #include <editeng/svxfont.hxx>
30 #include <svx/svdoole2.hxx>
31 #include <tools/poly.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/pdfextoutdevdata.hxx>
34 #include <svtools/accessibilityoptions.hxx>
35 #include <svx/framelinkarray.hxx>
36 #include <drawinglayer/geometry/viewinformation2d.hxx>
37 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
38 #include <basegfx/matrix/b2dhommatrix.hxx>
39 #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
40 #include <vcl/lineinfo.hxx>
41 #include <vcl/gradient.hxx>
42 #include <vcl/settings.hxx>
43 #include <svx/unoapi.hxx>
46 #include "document.hxx"
47 #include "drwlayer.hxx"
48 #include "formulacell.hxx"
50 #include "patattr.hxx"
51 #include "docpool.hxx"
52 #include "tabvwsh.hxx"
53 #include "progress.hxx"
54 #include "pagedata.hxx"
55 #include "chgtrack.hxx"
56 #include "chgviset.hxx"
57 #include "viewutil.hxx"
58 #include "gridmerg.hxx"
59 #include "invmerge.hxx"
60 #include "fillinfo.hxx"
62 #include "appoptio.hxx"
65 #include "scresid.hxx"
66 #include "colorscale.hxx"
72 #include <boost/scoped_ptr.hpp>
74 using namespace com::sun::star
;
78 // color for ChangeTracking "by author" as in the writer (swmodul1.cxx)
80 #define SC_AUTHORCOLORCOUNT 9
82 static const ColorData nAuthorColor
[ SC_AUTHORCOLORCOUNT
] = {
83 COL_LIGHTRED
, COL_LIGHTBLUE
, COL_LIGHTMAGENTA
,
84 COL_GREEN
, COL_RED
, COL_BLUE
,
85 COL_BROWN
, COL_MAGENTA
, COL_CYAN
};
88 // Helper class for color assignment to avoid repeated lookups for the same user
90 ScActionColorChanger::ScActionColorChanger( const ScChangeTrack
& rTrack
) :
91 rOpt( SC_MOD()->GetAppOptions() ),
92 rUsers( rTrack
.GetUserCollection() ),
98 void ScActionColorChanger::Update( const ScChangeAction
& rAction
)
101 switch (rAction
.GetType())
103 case SC_CAT_INSERT_COLS
:
104 case SC_CAT_INSERT_ROWS
:
105 case SC_CAT_INSERT_TABS
:
106 nSetColor
= rOpt
.GetTrackInsertColor();
108 case SC_CAT_DELETE_COLS
:
109 case SC_CAT_DELETE_ROWS
:
110 case SC_CAT_DELETE_TABS
:
111 nSetColor
= rOpt
.GetTrackDeleteColor();
114 nSetColor
= rOpt
.GetTrackMoveColor();
117 nSetColor
= rOpt
.GetTrackContentColor();
120 if ( nSetColor
!= COL_TRANSPARENT
) // color assigned
124 if (!aLastUserName
.equals(rAction
.GetUser()))
126 aLastUserName
= rAction
.GetUser();
127 std::set
<OUString
>::const_iterator it
= rUsers
.find(aLastUserName
);
128 if (it
== rUsers
.end())
130 // empty string is possible if a name wasn't found while saving a 5.0 file
131 SAL_INFO_IF( aLastUserName
.isEmpty(), "sc.ui", "Author not found" );
136 size_t nPos
= std::distance(rUsers
.begin(), it
);
137 nLastUserIndex
= nPos
% SC_AUTHORCOLORCOUNT
;
140 nColor
= nAuthorColor
[nLastUserIndex
];
145 ScOutputData::ScOutputData( OutputDevice
* pNewDev
, ScOutputType eNewType
,
146 ScTableInfo
& rTabInfo
, ScDocument
* pNewDoc
,
147 SCTAB nNewTab
, long nNewScrX
, long nNewScrY
,
148 SCCOL nNewX1
, SCROW nNewY1
, SCCOL nNewX2
, SCROW nNewY2
,
149 double nPixelPerTwipsX
, double nPixelPerTwipsY
,
150 const Fraction
* pZoomX
, const Fraction
* pZoomY
) :
152 mpRefDevice( pNewDev
), // default is output device
153 pFmtDevice( pNewDev
), // default is output device
154 mrTabInfo( rTabInfo
),
155 pRowInfo( rTabInfo
.mpRowInfo
),
156 nArrCount( rTabInfo
.mnArrCount
),
166 mnPPTX( nPixelPerTwipsX
),
167 mnPPTY( nPixelPerTwipsY
),
170 pDrawView( NULL
), // #114135#
175 bSingleGrid( false ),
176 bPagebreakMode( false ),
177 bSolidBackground( false ),
178 mbUseStyleColor( false ),
179 mbForceAutoColor( SC_MOD()->GetAccessOptions().GetIsAutomaticFontColor() ),
180 mbSyntaxMode( false ),
183 pFormulaColor( NULL
),
184 aGridColor( COL_BLACK
),
185 mbShowNullValues( true ),
186 mbShowFormulas( false ),
187 bShowSpellErrors( false ),
188 bMarkClipped( false ), // sal_False for printer/metafile etc.
190 bAnyRotated( false ),
191 bAnyClipped( false ),
192 mpTargetPaintWindow(NULL
), // #i74769# use SdrPaintWindow direct
193 mpSpellCheckCxt(NULL
)
198 aZoomX
= Fraction(1,1);
202 aZoomY
= Fraction(1,1);
208 mpDoc
->StripHidden( nVisX1
, nVisY1
, nVisX2
, nVisY2
, nTab
);
211 for (SCCOL nX
=nVisX1
; nX
<=nVisX2
; nX
++)
212 nScrW
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
217 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
218 nScrH
+= pRowInfo
[nArrY
].nHeight
;
220 bTabProtected
= mpDoc
->IsTabProtected( nTab
);
221 nTabTextDirection
= mpDoc
->GetEditTextDirection( nTab
);
222 bLayoutRTL
= mpDoc
->IsLayoutRTL( nTab
);
225 ScOutputData::~ScOutputData()
229 delete pFormulaColor
;
232 void ScOutputData::SetSpellCheckContext( const sc::SpellCheckContext
* pCxt
)
234 mpSpellCheckCxt
= pCxt
;
237 void ScOutputData::SetContentDevice( OutputDevice
* pContentDev
)
239 // use pContentDev instead of pDev where used
241 if ( mpRefDevice
== mpDev
)
242 mpRefDevice
= pContentDev
;
243 if ( pFmtDevice
== mpDev
)
244 pFmtDevice
= pContentDev
;
248 void ScOutputData::SetMirrorWidth( long nNew
)
253 void ScOutputData::SetGridColor( const Color
& rColor
)
258 void ScOutputData::SetMarkClipped( bool bSet
)
263 void ScOutputData::SetShowNullValues( bool bSet
)
265 mbShowNullValues
= bSet
;
268 void ScOutputData::SetShowFormulas( bool bSet
)
270 mbShowFormulas
= bSet
;
273 void ScOutputData::SetShowSpellErrors( bool bSet
)
275 bShowSpellErrors
= bSet
;
278 void ScOutputData::SetSnapPixel( bool bSet
)
283 void ScOutputData::SetEditCell( SCCOL nCol
, SCROW nRow
)
290 void ScOutputData::SetMetaFileMode( bool bNewMode
)
292 bMetaFile
= bNewMode
;
295 void ScOutputData::SetSingleGrid( bool bNewMode
)
297 bSingleGrid
= bNewMode
;
300 void ScOutputData::SetSyntaxMode( bool bNewMode
)
302 mbSyntaxMode
= bNewMode
;
306 pValueColor
= new Color( COL_LIGHTBLUE
);
307 pTextColor
= new Color( COL_BLACK
);
308 pFormulaColor
= new Color( COL_GREEN
);
312 void ScOutputData::DrawGrid( bool bGrid
, bool bPage
)
319 ScBreakType nBreak
= BREAK_NONE
;
320 ScBreakType nBreakOld
= BREAK_NONE
;
327 bPage
= false; // no "normal" breaks over the whole width/height
329 //! um den einen Pixel sieht das Metafile (oder die Druck-Ausgabe) anders aus
330 //! als die Bildschirmdarstellung, aber wenigstens passen Druck und Metafile zusammen
332 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
333 long nOneX
= aOnePixel
.Width();
334 long nOneY
= aOnePixel
.Height();
338 long nLayoutSign
= bLayoutRTL
? -1 : 1;
339 long nSignedOneX
= nOneX
* nLayoutSign
;
341 if ( eType
== OUTTYPE_WINDOW
)
343 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
344 aPageColor
.SetColor( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
);
345 aManualColor
.SetColor( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
349 aPageColor
= aGridColor
;
350 aManualColor
= aGridColor
;
353 mpDev
->SetLineColor( aGridColor
);
354 ScGridMerger
aGrid( mpDev
, nOneX
, nOneY
);
360 nPosX
+= nMirrorW
- nOneX
;
362 for (nX
=nX1
; nX
<=nX2
; nX
++)
364 SCCOL nXplus1
= nX
+1;
365 SCCOL nXplus2
= nX
+2;
366 sal_uInt16 nWidth
= pRowInfo
[0].pCellInfo
[nXplus1
].nWidth
;
369 nPosX
+= nWidth
* nLayoutSign
;
373 // Seitenumbrueche auch in ausgeblendeten suchen
374 SCCOL nCol
= nXplus1
;
375 while (nCol
<= MAXCOL
)
377 nBreak
= mpDoc
->HasColBreak(nCol
, nTab
);
378 bool bHidden
= mpDoc
->ColHidden(nCol
, nTab
);
380 if ( nBreak
|| !bHidden
)
385 if (nBreak
!= nBreakOld
)
388 mpDev
->SetLineColor( (nBreak
& BREAK_MANUAL
) ? aManualColor
:
389 nBreak
? aPageColor
: aGridColor
);
394 bool bDraw
= bGrid
|| nBreakOld
; // simple grid only if set that way
396 sal_uInt16 nWidthXplus2
= pRowInfo
[0].pCellInfo
[nXplus2
].nWidth
;
397 bSingle
= bSingleGrid
; //! get into Fillinfo !!!!!
398 if ( nX
<MAXCOL
&& !bSingle
)
400 bSingle
= ( nWidthXplus2
== 0 );
401 for (nArrY
=1; nArrY
+1<nArrCount
&& !bSingle
; nArrY
++)
403 if (pRowInfo
[nArrY
].pCellInfo
[nXplus2
].bHOverlapped
)
405 if (pRowInfo
[nArrY
].pCellInfo
[nXplus1
].bHideGrid
)
412 if ( nX
<MAXCOL
&& bSingle
)
414 SCCOL nVisX
= nXplus1
;
415 while ( nVisX
< MAXCOL
&& !mpDoc
->GetColWidth(nVisX
,nTab
) )
420 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
422 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
423 nNextY
= nPosY
+ pThisRowInfo
->nHeight
;
425 bool bHOver
= pThisRowInfo
->pCellInfo
[nXplus1
].bHideGrid
;
429 bHOver
= pThisRowInfo
->pCellInfo
[nXplus2
].bHOverlapped
;
433 bHOver
= pThisRowInfo
->pCellInfo
[nVisX
+1].bHOverlapped
;
435 bHOver
= ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
436 nVisX
,pThisRowInfo
->nRowNo
,nTab
,ATTR_MERGE_FLAG
))
439 bHOver
= ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
440 nXplus1
,pThisRowInfo
->nRowNo
,nTab
,ATTR_MERGE_FLAG
))
445 if (pThisRowInfo
->bChanged
&& !bHOver
)
447 aGrid
.AddVerLine( nPosX
-nSignedOneX
, nPosY
, nNextY
-nOneY
);
454 aGrid
.AddVerLine( nPosX
-nSignedOneX
, nScrY
, nScrY
+nScrH
-nOneY
);
462 bool bHiddenRow
= true;
463 SCROW nHiddenEndRow
= -1;
465 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
467 SCSIZE nArrYplus1
= nArrY
+1;
468 nY
= pRowInfo
[nArrY
].nRowNo
;
469 SCROW nYplus1
= nY
+1;
470 nPosY
+= pRowInfo
[nArrY
].nHeight
;
472 if (pRowInfo
[nArrY
].bChanged
)
476 for (SCROW i
= nYplus1
; i
<= MAXROW
; ++i
)
478 if (i
> nHiddenEndRow
)
479 bHiddenRow
= mpDoc
->RowHidden(i
, nTab
, NULL
, &nHiddenEndRow
);
480 /* TODO: optimize the row break thing for large hidden
481 * segments where HasRowBreak() has to be called
482 * nevertheless for each row, as a row break is drawn also
483 * for hidden rows, above them. This needed to be done only
484 * once per hidden segment, maybe giving manual breaks
485 * priority. Something like GetNextRowBreak() and
486 * GetNextManualRowBreak(). */
487 nBreak
= mpDoc
->HasRowBreak(i
, nTab
);
488 if (!bHiddenRow
|| nBreak
)
492 if (nBreakOld
!= nBreak
)
495 mpDev
->SetLineColor( (nBreak
& BREAK_MANUAL
) ? aManualColor
:
496 (nBreak
) ? aPageColor
: aGridColor
);
501 bool bDraw
= bGrid
|| nBreakOld
; // simple grid only if set so
503 bool bNextYisNextRow
= (pRowInfo
[nArrYplus1
].nRowNo
== nYplus1
);
504 bSingle
= !bNextYisNextRow
; // Hidden
505 for (SCCOL i
=nX1
; i
<=nX2
&& !bSingle
; i
++)
507 if (pRowInfo
[nArrYplus1
].pCellInfo
[i
+1].bVOverlapped
)
513 if ( bSingle
&& nY
<MAXROW
)
515 SCROW nVisY
= pRowInfo
[nArrYplus1
].nRowNo
;
519 nPosX
+= nMirrorW
- nOneX
;
522 for (SCCOL i
=nX1
; i
<=nX2
; i
++)
524 nNextX
= nPosX
+ pRowInfo
[0].pCellInfo
[i
+1].nWidth
* nLayoutSign
;
525 if (nNextX
!= nPosX
) // visible
528 if ( bNextYisNextRow
)
529 bVOver
= pRowInfo
[nArrYplus1
].pCellInfo
[i
+1].bVOverlapped
;
532 bVOver
= ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
533 i
,nYplus1
,nTab
,ATTR_MERGE_FLAG
))
535 && ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
536 i
,nVisY
,nTab
,ATTR_MERGE_FLAG
))
538 //! nVisY from Array ??
542 aGrid
.AddHorLine( nPosX
, nNextX
-nSignedOneX
, nPosY
-nOneY
);
550 aGrid
.AddHorLine( nScrX
, nScrX
+nScrW
-nOneX
, nPosY
-nOneY
);
557 void ScOutputData::SetPagebreakMode( ScPageBreakData
* pPageData
)
559 bPagebreakMode
= true;
561 return; // not yet initialized -> everything "not printed"
563 // mark printed range
564 // (everything in FillInfo is already initialized to sal_False)
566 sal_uInt16 nRangeCount
= sal::static_int_cast
<sal_uInt16
>(pPageData
->GetCount());
567 for (sal_uInt16 nPos
=0; nPos
<nRangeCount
; nPos
++)
569 ScRange aRange
= pPageData
->GetData( nPos
).GetPrintRange();
571 SCCOL nStartX
= std::max( aRange
.aStart
.Col(), nX1
);
572 SCCOL nEndX
= std::min( aRange
.aEnd
.Col(), nX2
);
573 SCROW nStartY
= std::max( aRange
.aStart
.Row(), nY1
);
574 SCROW nEndY
= std::min( aRange
.aEnd
.Row(), nY2
);
576 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
578 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
579 if ( pThisRowInfo
->bChanged
&& pThisRowInfo
->nRowNo
>= nStartY
&&
580 pThisRowInfo
->nRowNo
<= nEndY
)
582 for (SCCOL nX
=nStartX
; nX
<=nEndX
; nX
++)
583 pThisRowInfo
->pCellInfo
[nX
+1].bPrinted
= true;
589 void ScOutputData::FindRotated()
593 for (SCSIZE nRotY
=0; nRotY
<nArrCount
; nRotY
++)
594 if (pRowInfo
[nRotY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nRotY
].nRotMaxCol
> nRotMax
)
595 nRotMax
= pRowInfo
[nRotY
].nRotMaxCol
;
597 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++)
599 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
600 if ( pThisRowInfo
->nRotMaxCol
!= SC_ROTMAX_NONE
&&
601 ( pThisRowInfo
->bChanged
|| pRowInfo
[nArrY
-1].bChanged
||
602 ( nArrY
+1<nArrCount
&& pRowInfo
[nArrY
+1].bChanged
) ) )
604 SCROW nY
= pThisRowInfo
->nRowNo
;
606 for (SCCOL nX
=0; nX
<=nRotMax
; nX
++)
608 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
609 const ScPatternAttr
* pPattern
= pInfo
->pPatternAttr
;
610 const SfxItemSet
* pCondSet
= pInfo
->pConditionSet
;
612 if ( !pPattern
&& !mpDoc
->ColHidden(nX
, nTab
) )
614 pPattern
= mpDoc
->GetPattern( nX
, nY
, nTab
);
615 pCondSet
= mpDoc
->GetCondResult( nX
, nY
, nTab
);
618 if ( pPattern
) // column isn't hidden
620 sal_uInt8 nDir
= pPattern
->GetRotateDir( pCondSet
);
621 if (nDir
!= SC_ROTDIR_NONE
)
623 pInfo
->nRotateDir
= nDir
;
632 static sal_uInt16
lcl_GetRotateDir( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
634 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
635 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
637 sal_uInt16 nRet
= SC_ROTDIR_NONE
;
639 long nAttrRotate
= pPattern
->GetRotateVal( pCondSet
);
642 SvxRotateMode eRotMode
= (SvxRotateMode
)((const SvxRotateModeItem
&)
643 pPattern
->GetItem(ATTR_ROTATE_MODE
, pCondSet
)).GetValue();
645 if ( eRotMode
== SVX_ROTATE_MODE_STANDARD
)
646 nRet
= SC_ROTDIR_STANDARD
;
647 else if ( eRotMode
== SVX_ROTATE_MODE_CENTER
)
648 nRet
= SC_ROTDIR_CENTER
;
649 else if ( eRotMode
== SVX_ROTATE_MODE_TOP
|| eRotMode
== SVX_ROTATE_MODE_BOTTOM
)
651 long nRot180
= nAttrRotate
% 18000; // 1/100 degree
652 if ( nRot180
== 9000 )
653 nRet
= SC_ROTDIR_CENTER
;
654 else if ( ( eRotMode
== SVX_ROTATE_MODE_TOP
&& nRot180
< 9000 ) ||
655 ( eRotMode
== SVX_ROTATE_MODE_BOTTOM
&& nRot180
> 9000 ) )
656 nRet
= SC_ROTDIR_LEFT
;
658 nRet
= SC_ROTDIR_RIGHT
;
665 static const SvxBrushItem
* lcl_FindBackground( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
667 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
668 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
669 const SvxBrushItem
* pBackground
= (const SvxBrushItem
*)
670 &pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
672 sal_uInt16 nDir
= lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
);
674 // treat CENTER like RIGHT
675 if ( nDir
== SC_ROTDIR_RIGHT
|| nDir
== SC_ROTDIR_CENTER
)
677 // text goes to the right -> take background from the left
678 while ( nCol
> 0 && lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
) == nDir
&&
679 pBackground
->GetColor().GetTransparency() != 255 )
682 pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
683 pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
684 pBackground
= (const SvxBrushItem
*)&pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
687 else if ( nDir
== SC_ROTDIR_LEFT
)
689 // text goes to the left -> take background from the right
690 while ( nCol
< MAXCOL
&& lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
) == nDir
&&
691 pBackground
->GetColor().GetTransparency() != 255 )
694 pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
695 pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
696 pBackground
= (const SvxBrushItem
*)&pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
704 static bool lcl_EqualBack( const RowInfo
& rFirst
, const RowInfo
& rOther
,
705 SCCOL nX1
, SCCOL nX2
, bool bShowProt
, bool bPagebreakMode
)
707 if ( rFirst
.bChanged
!= rOther
.bChanged
||
708 rFirst
.bEmptyBack
!= rOther
.bEmptyBack
)
714 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
716 const ScPatternAttr
* pPat1
= rFirst
.pCellInfo
[nX
+1].pPatternAttr
;
717 const ScPatternAttr
* pPat2
= rOther
.pCellInfo
[nX
+1].pPatternAttr
;
718 if ( !pPat1
|| !pPat2
||
719 &pPat1
->GetItem(ATTR_PROTECTION
) != &pPat2
->GetItem(ATTR_PROTECTION
) )
725 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
726 if ( rFirst
.pCellInfo
[nX
+1].pBackground
!= rOther
.pCellInfo
[nX
+1].pBackground
)
730 if ( rFirst
.nRotMaxCol
!= SC_ROTMAX_NONE
|| rOther
.nRotMaxCol
!= SC_ROTMAX_NONE
)
731 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
732 if ( rFirst
.pCellInfo
[nX
+1].nRotateDir
!= rOther
.pCellInfo
[nX
+1].nRotateDir
)
735 if ( bPagebreakMode
)
736 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
737 if ( rFirst
.pCellInfo
[nX
+1].bPrinted
!= rOther
.pCellInfo
[nX
+1].bPrinted
)
740 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
742 const Color
* pCol1
= rFirst
.pCellInfo
[nX
+1].pColorScale
;
743 const Color
* pCol2
= rOther
.pCellInfo
[nX
+1].pColorScale
;
744 if( (pCol1
&& !pCol2
) || (!pCol1
&& pCol2
) )
747 if (pCol1
&& (*pCol1
!= *pCol2
))
750 const ScDataBarInfo
* pInfo1
= rFirst
.pCellInfo
[nX
+1].pDataBar
;
751 const ScDataBarInfo
* pInfo2
= rOther
.pCellInfo
[nX
+1].pDataBar
;
753 if( (pInfo1
&& !pInfo2
) || (!pInfo1
&& pInfo2
) )
756 if (pInfo1
&& (*pInfo1
!= *pInfo2
))
759 // each cell with an icon set should be painted the same way
760 const ScIconSetInfo
* pIconSet1
= rFirst
.pCellInfo
[nX
+1].pIconSet
;
761 const ScIconSetInfo
* pIconSet2
= rOther
.pCellInfo
[nX
+1].pIconSet
;
763 if(pIconSet1
|| pIconSet2
)
770 void ScOutputData::DrawDocumentBackground()
772 if ( !bSolidBackground
)
775 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
776 long nOneX
= aOnePixel
.Width();
777 long nOneY
= aOnePixel
.Height();
778 Rectangle
aRect(nScrX
- nOneX
, nScrY
- nOneY
, nScrX
+ nScrW
, nScrY
+ nScrH
);
779 Color
aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
);
780 mpDev
->SetFillColor(aBgColor
);
781 mpDev
->DrawRect(aRect
);
786 static const double lclCornerRectTransparency
= 40.0;
788 void drawDataBars( const ScDataBarInfo
* pOldDataBarInfo
, OutputDevice
* pDev
, const Rectangle
& rRect
)
791 Rectangle aPaintRect
= rRect
;
792 aPaintRect
.Top() += 2;
793 aPaintRect
.Bottom() -= 2;
794 aPaintRect
.Left() += 2;
795 aPaintRect
.Right() -= 2;
796 if(pOldDataBarInfo
->mnZero
)
798 // need to calculate null point in cell
799 long nLength
= aPaintRect
.Right() - aPaintRect
.Left();
800 nPosZero
= static_cast<long>(aPaintRect
.Left() + nLength
*pOldDataBarInfo
->mnZero
/100.0);
804 nPosZero
= aPaintRect
.Left();
807 if(pOldDataBarInfo
->mnLength
< 0)
809 aPaintRect
.Right() = nPosZero
;
810 long nLength
= nPosZero
- aPaintRect
.Left();
811 aPaintRect
.Left() = nPosZero
+ static_cast<long>(nLength
* pOldDataBarInfo
->mnLength
/100.0);
813 else if(pOldDataBarInfo
->mnLength
> 0)
815 aPaintRect
.Left() = nPosZero
;
816 long nLength
= aPaintRect
.Right() - nPosZero
;
817 aPaintRect
.Right() = nPosZero
+ static_cast<long>(nLength
* pOldDataBarInfo
->mnLength
/100.0);
822 if(pOldDataBarInfo
->mbGradient
)
824 pDev
->SetLineColor(pOldDataBarInfo
->maColor
);
825 Gradient
aGradient(GradientStyle_LINEAR
, pOldDataBarInfo
->maColor
, COL_TRANSPARENT
);
827 if(pOldDataBarInfo
->mnLength
< 0)
828 aGradient
.SetAngle(2700);
830 aGradient
.SetAngle(900);
832 pDev
->DrawGradient(aPaintRect
, aGradient
);
834 pDev
->SetLineColor();
838 pDev
->SetFillColor(pOldDataBarInfo
->maColor
);
839 pDev
->DrawRect(aPaintRect
);
843 if(pOldDataBarInfo
->mnZero
&& pOldDataBarInfo
->mnZero
!= 100)
845 Point
aPoint1(nPosZero
, rRect
.Top());
846 Point
aPoint2(nPosZero
, rRect
.Bottom());
847 LineInfo
aLineInfo(LINE_DASH
, 1);
848 aLineInfo
.SetDashCount( 4 );
849 aLineInfo
.SetDistance( 3 );
850 aLineInfo
.SetDashLen( 3 );
851 pDev
->SetFillColor(pOldDataBarInfo
->maAxisColor
);
852 pDev
->SetLineColor(pOldDataBarInfo
->maAxisColor
);
853 pDev
->DrawLine(aPoint1
, aPoint2
, aLineInfo
);
854 pDev
->SetLineColor();
855 pDev
->SetFillColor();
859 BitmapEx
& getIcon( ScIconSetType eType
, sal_Int32 nIndex
)
861 return ScIconSetFormat::getBitmap( eType
, nIndex
);
864 void drawIconSets( const ScIconSetInfo
* pOldIconSetInfo
, OutputDevice
* pDev
, const Rectangle
& rRect
)
867 ScIconSetType eType
= pOldIconSetInfo
->eIconSetType
;
868 sal_Int32 nIndex
= pOldIconSetInfo
->nIconIndex
;
869 BitmapEx
& rIcon
= getIcon( eType
, nIndex
);
870 long aOrigSize
= std::max
<long>(0,std::min(rRect
.GetSize().getWidth() - 4, rRect
.GetSize().getHeight() -4));
871 pDev
->DrawBitmapEx( Point( rRect
.Left() +2, rRect
.Top() + 2 ), Size(aOrigSize
, aOrigSize
), rIcon
);
874 void drawCells(const Color
* pColor
, const SvxBrushItem
* pBackground
, const Color
*& pOldColor
, const SvxBrushItem
*& pOldBackground
,
875 Rectangle
& rRect
, long nPosX
, long nSignedOneX
, OutputDevice
* pDev
, const ScDataBarInfo
* pDataBarInfo
, const ScDataBarInfo
*& pOldDataBarInfo
,
876 const ScIconSetInfo
* pIconSetInfo
, const ScIconSetInfo
*& pOldIconSetInfo
)
879 // need to paint if old color scale has been used and now
880 // we have a different color or a style based background
881 // we can here fall back to pointer comparison
882 if (pOldColor
&& (pBackground
|| pOldColor
!= pColor
|| pOldDataBarInfo
|| pDataBarInfo
|| pIconSetInfo
|| pOldIconSetInfo
))
884 rRect
.Right() = nPosX
-nSignedOneX
;
885 if( !pOldColor
->GetTransparency() )
887 pDev
->SetFillColor( *pOldColor
);
888 pDev
->DrawRect( rRect
);
890 if( pOldDataBarInfo
)
891 drawDataBars( pOldDataBarInfo
, pDev
, rRect
);
892 if( pOldIconSetInfo
)
893 drawIconSets( pOldIconSetInfo
, pDev
, rRect
);
895 rRect
.Left() = nPosX
- nSignedOneX
;
898 if ( pOldBackground
&& (pColor
||pBackground
!= pOldBackground
|| pOldDataBarInfo
|| pDataBarInfo
|| pIconSetInfo
|| pOldIconSetInfo
) )
900 rRect
.Right() = nPosX
-nSignedOneX
;
901 if (pOldBackground
) // ==0 if hidden
903 Color aBackCol
= pOldBackground
->GetColor();
904 if ( !aBackCol
.GetTransparency() ) //! partial transparency?
906 pDev
->SetFillColor( aBackCol
);
907 pDev
->DrawRect( rRect
);
910 if( pOldDataBarInfo
)
911 drawDataBars( pOldDataBarInfo
, pDev
, rRect
);
912 if( pOldIconSetInfo
)
913 drawIconSets( pOldIconSetInfo
, pDev
, rRect
);
915 rRect
.Left() = nPosX
- nSignedOneX
;
918 if (!pOldBackground
&& !pOldColor
&& (pDataBarInfo
|| pIconSetInfo
))
920 rRect
.Right() = nPosX
-nSignedOneX
;
921 rRect
.Left() = nPosX
- nSignedOneX
;
926 // only update pOldColor if the colors changed
927 if (!pOldColor
|| *pOldColor
!= *pColor
)
930 pOldBackground
= NULL
;
934 pOldBackground
= pBackground
;
939 pOldDataBarInfo
= pDataBarInfo
;
941 pOldDataBarInfo
= NULL
;
944 pOldIconSetInfo
= pIconSetInfo
;
946 pOldIconSetInfo
= NULL
;
951 void ScOutputData::DrawBackground()
953 FindRotated(); //! from the outside?
956 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
957 long nOneX
= aOnePixel
.Width();
958 long nOneY
= aOnePixel
.Height();
963 long nLayoutSign
= bLayoutRTL
? -1 : 1;
964 long nSignedOneX
= nOneX
* nLayoutSign
;
966 mpDev
->SetLineColor();
968 bool bShowProt
= mbSyntaxMode
&& mpDoc
->IsTabProtected(nTab
);
969 bool bDoAll
= bShowProt
|| bPagebreakMode
|| bSolidBackground
;
971 bool bCellContrast
= mbUseStyleColor
&&
972 Application::GetSettings().GetStyleSettings().GetHighContrastMode();
975 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
977 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
978 long nRowHeight
= pThisRowInfo
->nHeight
;
980 if ( pThisRowInfo
->bChanged
)
982 if ( ( ( pThisRowInfo
->bEmptyBack
) || mbSyntaxMode
) && !bDoAll
)
988 // scan for rows with the same background:
990 while ( nArrY
+nSkip
+2<nArrCount
&&
991 lcl_EqualBack( *pThisRowInfo
, pRowInfo
[nArrY
+nSkip
+1],
992 nX1
, nX2
, bShowProt
, bPagebreakMode
) )
995 nRowHeight
+= pRowInfo
[nArrY
+nSkip
].nHeight
; // after incrementing
1000 nPosX
+= nMirrorW
- nOneX
;
1001 aRect
= Rectangle( nPosX
, nPosY
-nOneY
, nPosX
, nPosY
+nRowHeight
-nOneY
);
1003 const SvxBrushItem
* pOldBackground
= NULL
;
1004 const SvxBrushItem
* pBackground
;
1005 const Color
* pOldColor
= NULL
;
1006 const Color
* pColor
= NULL
;
1007 const ScDataBarInfo
* pOldDataBarInfo
= NULL
;
1008 const ScIconSetInfo
* pOldIconSetInfo
= NULL
;
1009 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
1011 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
1015 // high contrast for cell borders and backgrounds -> empty background
1016 pBackground
= ScGlobal::GetEmptyBrushItem();
1018 else if (bShowProt
) // show cell protection in syntax mode
1020 const ScPatternAttr
* pP
= pInfo
->pPatternAttr
;
1023 const ScProtectionAttr
& rProt
= (const ScProtectionAttr
&)
1024 pP
->GetItem(ATTR_PROTECTION
);
1025 if (rProt
.GetProtection() || rProt
.GetHideCell())
1026 pBackground
= ScGlobal::GetProtectedBrushItem();
1028 pBackground
= ScGlobal::GetEmptyBrushItem();
1034 pBackground
= pInfo
->pBackground
;
1036 if ( bPagebreakMode
&& !pInfo
->bPrinted
)
1037 pBackground
= ScGlobal::GetProtectedBrushItem();
1039 if ( pInfo
->nRotateDir
> SC_ROTDIR_STANDARD
&&
1040 pBackground
->GetColor().GetTransparency() != 255 &&
1043 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
1044 pBackground
= lcl_FindBackground( mpDoc
, nX
, nY
, nTab
);
1047 pColor
= pInfo
->pColorScale
;
1048 const ScDataBarInfo
* pDataBarInfo
= pInfo
->pDataBar
;
1049 const ScIconSetInfo
* pIconSetInfo
= pInfo
->pIconSet
;
1050 drawCells( pColor
, pBackground
, pOldColor
, pOldBackground
, aRect
, nPosX
, nSignedOneX
, mpDev
, pDataBarInfo
, pOldDataBarInfo
, pIconSetInfo
, pOldIconSetInfo
);
1052 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
1054 drawCells( NULL
, NULL
, pOldColor
, pOldBackground
, aRect
, nPosX
, nSignedOneX
, mpDev
, NULL
, pOldDataBarInfo
, NULL
, pOldIconSetInfo
);
1059 nPosY
+= nRowHeight
;
1063 void ScOutputData::DrawShadow()
1065 DrawExtraShadow( false, false, false, false );
1068 void ScOutputData::DrawExtraShadow(bool bLeft
, bool bTop
, bool bRight
, bool bBottom
)
1070 mpDev
->SetLineColor();
1072 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1073 bool bCellContrast
= mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1074 Color aAutoTextColor
;
1075 if ( bCellContrast
)
1076 aAutoTextColor
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
1078 long nInitPosX
= nScrX
;
1081 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1082 long nOneX
= aOnePixel
.Width();
1083 nInitPosX
+= nMirrorW
- nOneX
;
1085 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1087 long nPosY
= nScrY
- pRowInfo
[0].nHeight
;
1088 for (SCSIZE nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1090 bool bCornerY
= ( nArrY
== 0 ) || ( nArrY
+1 == nArrCount
);
1091 bool bSkipY
= ( nArrY
==0 && !bTop
) || ( nArrY
+1 == nArrCount
&& !bBottom
);
1093 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1094 long nRowHeight
= pThisRowInfo
->nHeight
;
1096 if ( pThisRowInfo
->bChanged
&& !bSkipY
)
1098 long nPosX
= nInitPosX
- pRowInfo
[0].pCellInfo
[nX1
].nWidth
* nLayoutSign
;
1099 for (SCCOL nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++)
1101 bool bCornerX
= ( nArrX
==nX1
|| nArrX
==nX2
+2 );
1102 bool bSkipX
= ( nArrX
==nX1
&& !bLeft
) || ( nArrX
==nX2
+2 && !bRight
);
1104 for (sal_uInt16 nPass
=0; nPass
<2; nPass
++) // horizontal / vertical
1106 const SvxShadowItem
* pAttr
= nPass
?
1107 pThisRowInfo
->pCellInfo
[nArrX
].pVShadowOrigin
:
1108 pThisRowInfo
->pCellInfo
[nArrX
].pHShadowOrigin
;
1109 if ( pAttr
&& !bSkipX
)
1111 ScShadowPart ePart
= nPass
?
1112 pThisRowInfo
->pCellInfo
[nArrX
].eVShadowPart
:
1113 pThisRowInfo
->pCellInfo
[nArrX
].eHShadowPart
;
1116 if ( (nPass
==0 && bCornerX
) || (nPass
==1 && bCornerY
) )
1117 if ( ePart
!= SC_SHADOW_CORNER
)
1122 long nThisWidth
= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
;
1123 long nMaxWidth
= nThisWidth
;
1126 //! direction must depend on shadow location
1127 SCCOL nWx
= nArrX
; // nX+1
1128 while (nWx
<nX2
&& !pRowInfo
[0].pCellInfo
[nWx
+1].nWidth
)
1130 nMaxWidth
= pRowInfo
[0].pCellInfo
[nWx
+1].nWidth
;
1133 // rectangle is in logical orientation
1134 Rectangle
aRect( nPosX
, nPosY
,
1135 nPosX
+ ( nThisWidth
- 1 ) * nLayoutSign
,
1136 nPosY
+ pRowInfo
[nArrY
].nHeight
- 1 );
1138 long nSize
= pAttr
->GetWidth();
1139 long nSizeX
= (long)(nSize
*mnPPTX
);
1140 if (nSizeX
>= nMaxWidth
) nSizeX
= nMaxWidth
-1;
1141 long nSizeY
= (long)(nSize
*mnPPTY
);
1142 if (nSizeY
>= nRowHeight
) nSizeY
= nRowHeight
-1;
1144 nSizeX
*= nLayoutSign
; // used only to add to rectangle values
1146 SvxShadowLocation eLoc
= pAttr
->GetLocation();
1149 // Shadow location is specified as "visual" (right is always right),
1150 // so the attribute's location value is mirrored here and in FillInfo.
1153 case SVX_SHADOW_BOTTOMRIGHT
: eLoc
= SVX_SHADOW_BOTTOMLEFT
; break;
1154 case SVX_SHADOW_BOTTOMLEFT
: eLoc
= SVX_SHADOW_BOTTOMRIGHT
; break;
1155 case SVX_SHADOW_TOPRIGHT
: eLoc
= SVX_SHADOW_TOPLEFT
; break;
1156 case SVX_SHADOW_TOPLEFT
: eLoc
= SVX_SHADOW_TOPRIGHT
; break;
1159 // added to avoid warnings
1164 if (ePart
== SC_SHADOW_HORIZ
|| ePart
== SC_SHADOW_HSTART
||
1165 ePart
== SC_SHADOW_CORNER
)
1167 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_TOPRIGHT
)
1168 aRect
.Top() = aRect
.Bottom() - nSizeY
;
1170 aRect
.Bottom() = aRect
.Top() + nSizeY
;
1172 if (ePart
== SC_SHADOW_VERT
|| ePart
== SC_SHADOW_VSTART
||
1173 ePart
== SC_SHADOW_CORNER
)
1175 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_BOTTOMLEFT
)
1176 aRect
.Left() = aRect
.Right() - nSizeX
;
1178 aRect
.Right() = aRect
.Left() + nSizeX
;
1180 if (ePart
== SC_SHADOW_HSTART
)
1182 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_BOTTOMLEFT
)
1183 aRect
.Right() -= nSizeX
;
1185 aRect
.Left() += nSizeX
;
1187 if (ePart
== SC_SHADOW_VSTART
)
1189 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_TOPRIGHT
)
1190 aRect
.Bottom() -= nSizeY
;
1192 aRect
.Top() += nSizeY
;
1195 //! merge rectangles?
1196 mpDev
->SetFillColor( bCellContrast
? aAutoTextColor
: pAttr
->GetColor() );
1197 mpDev
->DrawRect( aRect
);
1202 nPosX
+= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
* nLayoutSign
;
1205 nPosY
+= nRowHeight
;
1209 void ScOutputData::DrawClear()
1212 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1213 long nOneX
= aOnePixel
.Width();
1214 long nOneY
= aOnePixel
.Height();
1216 // (called only for ScGridWindow)
1217 Color
aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
);
1222 mpDev
->SetLineColor();
1224 mpDev
->SetFillColor( aBgColor
);
1227 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1229 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1230 long nRowHeight
= pThisRowInfo
->nHeight
;
1232 if ( pThisRowInfo
->bChanged
)
1234 // scan for more rows which must be painted:
1236 while ( nArrY
+nSkip
+2<nArrCount
&& pRowInfo
[nArrY
+nSkip
+1].bChanged
)
1239 nRowHeight
+= pRowInfo
[nArrY
+nSkip
].nHeight
; // after incrementing
1242 aRect
= Rectangle( Point( nScrX
, nPosY
),
1243 Size( nScrW
+1-nOneX
, nRowHeight
+1-nOneY
) );
1244 mpDev
->DrawRect( aRect
);
1248 nPosY
+= nRowHeight
;
1255 long lclGetSnappedX( OutputDevice
& rDev
, long nPosX
, bool bSnapPixel
)
1257 return (bSnapPixel
&& nPosX
) ? rDev
.PixelToLogic( rDev
.LogicToPixel( Size( nPosX
, 0 ) ) ).Width() : nPosX
;
1260 long lclGetSnappedY( OutputDevice
& rDev
, long nPosY
, bool bSnapPixel
)
1262 return (bSnapPixel
&& nPosY
) ? rDev
.PixelToLogic( rDev
.LogicToPixel( Size( 0, nPosY
) ) ).Height() : nPosY
;
1265 size_t lclGetArrayColFromCellInfoX( sal_uInt16 nCellInfoX
, sal_uInt16 nCellInfoFirstX
, sal_uInt16 nCellInfoLastX
, bool bRTL
)
1267 return static_cast< size_t >( bRTL
? (nCellInfoLastX
+ 2 - nCellInfoX
) : (nCellInfoX
- nCellInfoFirstX
) );
1270 void ScOutputData::DrawFrame()
1272 sal_uLong nOldDrawMode
= mpDev
->GetDrawMode();
1275 bool bUseSingleColor
= false;
1276 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1277 bool bCellContrast
= mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1279 // if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
1280 // for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
1281 // that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
1282 // must be reset and the border colors handled here.
1284 if ( ( nOldDrawMode
& DRAWMODE_WHITEFILL
) && ( nOldDrawMode
& DRAWMODE_BLACKLINE
) )
1286 mpDev
->SetDrawMode( nOldDrawMode
& (~DRAWMODE_WHITEFILL
) );
1287 aSingleColor
.SetColor( COL_BLACK
);
1288 bUseSingleColor
= true;
1290 else if ( ( nOldDrawMode
& DRAWMODE_SETTINGSFILL
) && ( nOldDrawMode
& DRAWMODE_SETTINGSLINE
) )
1292 mpDev
->SetDrawMode( nOldDrawMode
& (~DRAWMODE_SETTINGSFILL
) );
1293 aSingleColor
= rStyleSettings
.GetWindowTextColor(); // same as used in VCL for DRAWMODE_SETTINGSLINE
1294 bUseSingleColor
= true;
1296 else if ( bCellContrast
)
1298 aSingleColor
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
1299 bUseSingleColor
= true;
1302 const Color
* pForceColor
= bUseSingleColor
? &aSingleColor
: 0;
1305 DrawRotatedFrame( pForceColor
); // removes the lines that must not be painted here
1307 long nInitPosX
= nScrX
;
1310 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1311 long nOneX
= aOnePixel
.Width();
1312 nInitPosX
+= nMirrorW
- nOneX
;
1314 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1317 // *** set column and row sizes of the frame border array ***
1319 svx::frame::Array
& rArray
= mrTabInfo
.maArray
;
1320 size_t nColCount
= rArray
.GetColCount();
1321 size_t nRowCount
= rArray
.GetRowCount();
1325 // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
1326 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
1327 long nOldPosY
= nScrY
- 1 - pRowInfo
[ 0 ].nHeight
;
1328 long nOldSnapY
= lclGetSnappedY( *mpDev
, nOldPosY
, bSnapPixel
);
1329 rArray
.SetYOffset( nOldSnapY
);
1330 for( size_t nRow
= 0; nRow
< nRowCount
; ++nRow
)
1332 long nNewPosY
= nOldPosY
+ pRowInfo
[ nRow
].nHeight
;
1333 long nNewSnapY
= lclGetSnappedY( *mpDev
, nNewPosY
, bSnapPixel
);
1334 rArray
.SetRowHeight( nRow
, nNewSnapY
- nOldSnapY
);
1335 nOldPosY
= nNewPosY
;
1336 nOldSnapY
= nNewSnapY
;
1341 // column nX1 is not visible (dummy for borders from left) - subtract its width from initial position
1342 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
1343 long nOldPosX
= nInitPosX
- nLayoutSign
* (1 + pRowInfo
[ 0 ].pCellInfo
[ nX1
].nWidth
);
1344 long nOldSnapX
= lclGetSnappedX( *mpDev
, nOldPosX
, bSnapPixel
);
1345 // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
1347 rArray
.SetXOffset( nOldSnapX
);
1348 for( sal_uInt16 nInfoIdx
= nX1
; nInfoIdx
<= nX2
+ 2; ++nInfoIdx
)
1350 size_t nCol
= lclGetArrayColFromCellInfoX( nInfoIdx
, nX1
, nX2
, bLayoutRTL
);
1351 long nNewPosX
= nOldPosX
+ pRowInfo
[ 0 ].pCellInfo
[ nInfoIdx
].nWidth
* nLayoutSign
;
1352 long nNewSnapX
= lclGetSnappedX( *mpDev
, nNewPosX
, bSnapPixel
);
1353 rArray
.SetColWidth( nCol
, std::abs( nNewSnapX
- nOldSnapX
) );
1354 nOldPosX
= nNewPosX
;
1355 nOldSnapX
= nNewSnapX
;
1358 rArray
.SetXOffset( nOldSnapX
);
1360 // *** draw the array ***
1362 size_t nFirstCol
= 1;
1363 size_t nFirstRow
= 1;
1364 size_t nLastCol
= nColCount
- 2;
1365 size_t nLastRow
= nRowCount
- 2;
1367 if( mrTabInfo
.mbPageMode
)
1368 rArray
.SetClipRange( nFirstCol
, nFirstRow
, nLastCol
, nLastRow
);
1370 // draw only rows with set RowInfo::bChanged flag
1371 size_t nRow1
= nFirstRow
;
1372 boost::scoped_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor(CreateProcessor2D());
1376 while( nRow1
<= nLastRow
)
1378 while( (nRow1
<= nLastRow
) && !pRowInfo
[ nRow1
].bChanged
) ++nRow1
;
1379 if( nRow1
<= nLastRow
)
1381 size_t nRow2
= nRow1
;
1382 while( (nRow2
+ 1 <= nLastRow
) && pRowInfo
[ nRow2
+ 1 ].bChanged
) ++nRow2
;
1383 rArray
.DrawRange( pProcessor
.get(), nFirstCol
, nRow1
, nLastCol
, nRow2
, pForceColor
);
1389 mpDev
->SetDrawMode(nOldDrawMode
);
1393 // Line below the cell
1395 static const ::editeng::SvxBorderLine
* lcl_FindHorLine( ScDocument
* pDoc
,
1396 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_uInt16 nRotDir
,
1399 if ( nRotDir
!= SC_ROTDIR_LEFT
&& nRotDir
!= SC_ROTDIR_RIGHT
)
1402 bool bFound
= false;
1405 if ( nRotDir
== SC_ROTDIR_LEFT
)
1407 // text to the left -> line from the right
1408 if ( nCol
< MAXCOL
)
1411 return NULL
; // couldn't find it
1415 // text to the right -> line from the left
1419 return NULL
; // couldn't find it
1421 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
1422 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
1423 if ( !pPattern
->GetRotateVal( pCondSet
) ||
1424 ((const SvxRotateModeItem
&)pPattern
->GetItem(
1425 ATTR_ROTATE_MODE
, pCondSet
)).GetValue() == SVX_ROTATE_MODE_STANDARD
)
1431 const ::editeng::SvxBorderLine
* pThisBottom
;
1432 if ( ValidRow(nRow
) )
1433 pThisBottom
= ((const SvxBoxItem
*)pDoc
->GetAttr( nCol
, nRow
, nTab
, ATTR_BORDER
))->GetBottom();
1436 const ::editeng::SvxBorderLine
* pNextTop
;
1437 if ( nRow
< MAXROW
)
1438 pNextTop
= ((const SvxBoxItem
*)pDoc
->GetAttr( nCol
, nRow
+1, nTab
, ATTR_BORDER
))->GetTop();
1442 if ( ScHasPriority( pThisBottom
, pNextTop
) )
1449 static long lcl_getRotate( ScDocument
* pDoc
, SCTAB nTab
, SCCOL nX
, SCROW nY
)
1453 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1454 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nX
, nY
, nTab
);
1456 nRotate
= pPattern
->GetRotateVal( pCondSet
);
1461 void ScOutputData::DrawRotatedFrame( const Color
* pForceColor
)
1464 SCCOL nRotMax
= nX2
;
1465 for (SCSIZE nRotY
=0; nRotY
<nArrCount
; nRotY
++)
1466 if (pRowInfo
[nRotY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nRotY
].nRotMaxCol
> nRotMax
)
1467 nRotMax
= pRowInfo
[nRotY
].nRotMaxCol
;
1469 const ScPatternAttr
* pPattern
;
1470 const SfxItemSet
* pCondSet
;
1472 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1473 bool bCellContrast
= mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1475 // color (pForceColor) is determined externally, including DrawMode changes
1477 long nInitPosX
= nScrX
;
1480 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1481 long nOneX
= aOnePixel
.Width();
1482 nInitPosX
+= nMirrorW
- nOneX
;
1484 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1486 Rectangle
aClipRect( Point(nScrX
, nScrY
), Size(nScrW
, nScrH
) );
1490 mpDev
->IntersectClipRegion( aClipRect
);
1493 mpDev
->SetClipRegion( Region( aClipRect
) );
1495 svx::frame::Array
& rArray
= mrTabInfo
.maArray
;
1496 boost::scoped_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor(CreateProcessor2D( ));
1499 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++)
1501 // Rotated is also drawn one line above/below Changed if parts extend into the cell
1503 RowInfo
& rPrevRowInfo
= pRowInfo
[nArrY
-1];
1504 RowInfo
& rThisRowInfo
= pRowInfo
[nArrY
];
1505 RowInfo
& rNextRowInfo
= pRowInfo
[nArrY
+1];
1507 size_t nRow
= static_cast< size_t >( nArrY
);
1509 long nRowHeight
= rThisRowInfo
.nHeight
;
1510 if ( rThisRowInfo
.nRotMaxCol
!= SC_ROTMAX_NONE
&&
1511 ( rThisRowInfo
.bChanged
|| rPrevRowInfo
.bChanged
||
1512 ( nArrY
+1<nArrCount
&& rNextRowInfo
.bChanged
) ) )
1514 SCROW nY
= rThisRowInfo
.nRowNo
;
1517 for (nX
=0; nX
<=nRotMax
; nX
++)
1519 if (nX
==nX1
) nPosX
= nInitPosX
; // calculated individually for preceding positions
1521 sal_uInt16 nArrX
= nX
+ 1;
1523 CellInfo
* pInfo
= &rThisRowInfo
.pCellInfo
[nArrX
];
1524 long nColWidth
= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
;
1525 if ( pInfo
->nRotateDir
> SC_ROTDIR_STANDARD
&&
1526 !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
1528 pPattern
= pInfo
->pPatternAttr
;
1529 pCondSet
= pInfo
->pConditionSet
;
1532 pPattern
= mpDoc
->GetPattern( nX
, nY
, nTab
);
1533 pInfo
->pPatternAttr
= pPattern
;
1534 pCondSet
= mpDoc
->GetCondResult( nX
, nY
, nTab
);
1535 pInfo
->pConditionSet
= pCondSet
;
1538 //! LastPattern etc.
1540 long nAttrRotate
= pPattern
->GetRotateVal( pCondSet
);
1541 SvxRotateMode eRotMode
= (SvxRotateMode
)((const SvxRotateModeItem
&)
1542 pPattern
->GetItem(ATTR_ROTATE_MODE
, pCondSet
)).GetValue();
1546 if (nX
<nX1
) // compute negative position
1553 nPosX
-= nLayoutSign
* (long) pRowInfo
[0].pCellInfo
[nCol
+1].nWidth
;
1557 // start position minus 1 so rotated backgrounds suit the border
1558 // (border is on the grid)
1560 long nTop
= nPosY
- 1;
1561 long nBottom
= nPosY
+ nRowHeight
- 1;
1562 long nTopLeft
= nPosX
- nLayoutSign
;
1563 long nTopRight
= nPosX
+ ( nColWidth
- 1 ) * nLayoutSign
;
1564 long nBotLeft
= nTopLeft
;
1565 long nBotRight
= nTopRight
;
1567 // inclusion of the sign here hasn't been decided yet
1568 // (if not, the extension of the non-rotated background must also be changed)
1569 double nRealOrient
= nLayoutSign
* nAttrRotate
* F_PI18000
; // 1/100th degrees
1570 double nCos
= cos( nRealOrient
);
1571 double nSin
= sin( nRealOrient
);
1573 long nSkew
= (long) ( nRowHeight
* nCos
/ nSin
);
1577 case SVX_ROTATE_MODE_BOTTOM
:
1581 case SVX_ROTATE_MODE_CENTER
:
1588 case SVX_ROTATE_MODE_TOP
:
1594 // added to avoid warnings
1599 aPoints
[0] = Point( nTopLeft
, nTop
);
1600 aPoints
[1] = Point( nTopRight
, nTop
);
1601 aPoints
[2] = Point( nBotRight
, nBottom
);
1602 aPoints
[3] = Point( nBotLeft
, nBottom
);
1604 const SvxBrushItem
* pBackground
= pInfo
->pBackground
;
1606 pBackground
= (const SvxBrushItem
*) &pPattern
->GetItem(
1607 ATTR_BACKGROUND
, pCondSet
);
1610 // high contrast for cell borders and backgrounds -> empty background
1611 pBackground
= ScGlobal::GetEmptyBrushItem();
1613 if(!pInfo
->pColorScale
)
1615 const Color
& rColor
= pBackground
->GetColor();
1616 if ( rColor
.GetTransparency() != 255 )
1618 // draw background only for the changed row itself
1619 // (background doesn't extend into other cells).
1620 // For the borders (rotated and normal), clipping should be
1621 // set if the row isn't changed, but at least the borders
1622 // don't cover the cell contents.
1623 if ( rThisRowInfo
.bChanged
)
1625 Polygon
aPoly( 4, aPoints
);
1627 // ohne Pen wird bei DrawPolygon rechts und unten
1628 // ein Pixel weggelassen...
1629 if ( rColor
.GetTransparency() == 0 )
1630 mpDev
->SetLineColor(rColor
);
1632 mpDev
->SetLineColor();
1633 mpDev
->SetFillColor(rColor
);
1634 mpDev
->DrawPolygon( aPoly
);
1640 Polygon
aPoly( 4, aPoints
);
1641 const Color
* pColor
= pInfo
->pColorScale
;
1643 // ohne Pen wird bei DrawPolygon rechts und unten
1644 // ein Pixel weggelassen...
1645 if ( pColor
->GetTransparency() == 0 )
1646 mpDev
->SetLineColor(*pColor
);
1648 mpDev
->SetLineColor();
1649 mpDev
->SetFillColor(*pColor
);
1650 mpDev
->DrawPolygon( aPoly
);
1654 svx::frame::Style aTopLine
, aBottomLine
, aLeftLine
, aRightLine
;
1656 if ( nX
< nX1
|| nX
> nX2
) // Attribute in FillInfo nicht gesetzt
1658 //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
1659 const ::editeng::SvxBorderLine
* pLeftLine
;
1660 const ::editeng::SvxBorderLine
* pTopLine
;
1661 const ::editeng::SvxBorderLine
* pRightLine
;
1662 const ::editeng::SvxBorderLine
* pBottomLine
;
1663 mpDoc
->GetBorderLines( nX
, nY
, nTab
,
1664 &pLeftLine
, &pTopLine
, &pRightLine
, &pBottomLine
);
1665 aTopLine
.Set( pTopLine
, mnPPTY
);
1666 aBottomLine
.Set( pBottomLine
, mnPPTY
);
1667 aLeftLine
.Set( pLeftLine
, mnPPTX
);
1668 aRightLine
.Set( pRightLine
, mnPPTX
);
1672 size_t nCol
= lclGetArrayColFromCellInfoX( nArrX
, nX1
, nX2
, bLayoutRTL
);
1673 aTopLine
= rArray
.GetCellStyleTop( nCol
, nRow
);
1674 aBottomLine
= rArray
.GetCellStyleBottom( nCol
, nRow
);
1675 aLeftLine
= rArray
.GetCellStyleLeft( nCol
, nRow
);
1676 aRightLine
= rArray
.GetCellStyleRight( nCol
, nRow
);
1677 // in RTL mode the array is already mirrored -> swap back left/right borders
1679 std::swap( aLeftLine
, aRightLine
);
1682 const svx::frame::Style noStyle
;
1684 if (aTopLine
.Prim() || aTopLine
.Secn())
1686 long nUpperRotate
= lcl_getRotate( mpDoc
, nTab
, nX
, nY
- 1 );
1687 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1688 aPoints
[bLayoutRTL
?1:0], aPoints
[bLayoutRTL
?0:1], aTopLine
,
1689 svx::frame::Style(),
1690 svx::frame::Style(),
1692 svx::frame::Style(),
1693 svx::frame::Style(),
1695 pForceColor
, nUpperRotate
, nAttrRotate
) );
1698 if (aBottomLine
.Prim() || aBottomLine
.Secn())
1700 long nLowerRotate
= lcl_getRotate( mpDoc
, nTab
, nX
, nY
+ 1 );
1701 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1702 aPoints
[bLayoutRTL
?2:3], aPoints
[bLayoutRTL
?3:2], aBottomLine
,
1704 svx::frame::Style(),
1705 svx::frame::Style(),
1707 svx::frame::Style(),
1708 svx::frame::Style(),
1709 pForceColor
, 18000 - nAttrRotate
, 18000 - nLowerRotate
) );
1712 // Vertical slanted lines
1713 if (aLeftLine
.Prim() || aLeftLine
.Secn())
1715 long nLeftRotate
= lcl_getRotate( mpDoc
, nTab
, nX
- 1, nY
);
1716 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1717 aPoints
[0], aPoints
[3], aLeftLine
,
1719 svx::frame::Style(),
1720 svx::frame::Style(),
1722 svx::frame::Style(),
1723 svx::frame::Style(),
1724 pForceColor
, nAttrRotate
, nLeftRotate
) );
1727 if (aRightLine
.Prim() || aRightLine
.Secn())
1729 long nRightRotate
= lcl_getRotate( mpDoc
, nTab
, nX
+ 1, nY
);
1730 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1731 aPoints
[1], aPoints
[2], aRightLine
,
1732 svx::frame::Style(),
1733 svx::frame::Style(),
1735 svx::frame::Style(),
1736 svx::frame::Style(),
1738 pForceColor
, 18000 - nRightRotate
, 18000 - nAttrRotate
) );
1742 nPosX
+= nColWidth
* nLayoutSign
;
1745 // erst hinterher im zweiten Schritt die Linien fuer normale Ausgabe loeschen
1747 nX
= nX1
> 0 ? (nX1
-1) : static_cast<SCCOL
>(0);
1748 for (; nX
<=nX2
+1; nX
++) // sichtbarer Teil +- 1
1750 sal_uInt16 nArrX
= nX
+ 1;
1751 CellInfo
& rInfo
= rThisRowInfo
.pCellInfo
[nArrX
];
1752 if ( rInfo
.nRotateDir
> SC_ROTDIR_STANDARD
&&
1753 !rInfo
.bHOverlapped
&& !rInfo
.bVOverlapped
)
1755 pPattern
= rInfo
.pPatternAttr
;
1756 pCondSet
= rInfo
.pConditionSet
;
1758 size_t nCol
= lclGetArrayColFromCellInfoX( nArrX
, nX1
, nX2
, bLayoutRTL
);
1760 // horizontal: angrenzende Linie verlaengern
1761 // (nur, wenn die gedrehte Zelle eine Umrandung hat)
1762 sal_uInt16 nDir
= rInfo
.nRotateDir
;
1763 if ( rArray
.GetCellStyleTop( nCol
, nRow
).Prim() )
1765 svx::frame::Style
aStyle( lcl_FindHorLine( mpDoc
, nX
, nY
, nTab
, nDir
, true ), mnPPTY
);
1766 rArray
.SetCellStyleTop( nCol
, nRow
, aStyle
);
1768 rArray
.SetCellStyleBottom( nCol
, nRow
- 1, aStyle
);
1770 if ( rArray
.GetCellStyleBottom( nCol
, nRow
).Prim() )
1772 svx::frame::Style
aStyle( lcl_FindHorLine( mpDoc
, nX
, nY
, nTab
, nDir
, false ), mnPPTY
);
1773 rArray
.SetCellStyleBottom( nCol
, nRow
, aStyle
);
1774 if( nRow
+ 1 < rArray
.GetRowCount() )
1775 rArray
.SetCellStyleTop( nCol
, nRow
+ 1, aStyle
);
1778 // always remove vertical borders
1779 if( !rArray
.IsMergedOverlappedLeft( nCol
, nRow
) )
1781 rArray
.SetCellStyleLeft( nCol
, nRow
, svx::frame::Style() );
1783 rArray
.SetCellStyleRight( nCol
- 1, nRow
, svx::frame::Style() );
1785 if( !rArray
.IsMergedOverlappedRight( nCol
, nRow
) )
1787 rArray
.SetCellStyleRight( nCol
, nRow
, svx::frame::Style() );
1788 if( nCol
+ 1 < rArray
.GetColCount() )
1789 rArray
.SetCellStyleLeft( nCol
+ 1, nRow
, svx::frame::Style() );
1792 // remove diagonal borders
1793 rArray
.SetCellStyleTLBR( nCol
, nRow
, svx::frame::Style() );
1794 rArray
.SetCellStyleBLTR( nCol
, nRow
, svx::frame::Style() );
1798 nPosY
+= nRowHeight
;
1806 mpDev
->SetClipRegion();
1809 drawinglayer::processor2d::BaseProcessor2D
* ScOutputData::CreateProcessor2D( )
1811 mpDoc
->InitDrawLayer(mpDoc
->GetDocumentShell());
1812 ScDrawLayer
* pDrawLayer
= mpDoc
->GetDrawLayer();
1816 basegfx::B2DRange aViewRange
;
1817 SdrPage
*pDrawPage
= pDrawLayer
->GetPage( static_cast< sal_uInt16
>( nTab
) );
1818 const drawinglayer::geometry::ViewInformation2D
aNewViewInfos(
1819 basegfx::B2DHomMatrix( ),
1820 mpDev
->GetViewTransformation(),
1822 GetXDrawPageForSdrPage( pDrawPage
),
1824 uno::Sequence
< beans::PropertyValue
>() );
1826 return drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
1827 *mpDev
, aNewViewInfos
);
1832 Region
ScOutputData::GetChangedAreaRegion()
1835 Rectangle aDrawingRect
;
1840 aDrawingRect
.Left() = nScrX
;
1841 aDrawingRect
.Right() = nScrX
+nScrW
-1;
1843 for(nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1845 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1847 if(pThisRowInfo
->bChanged
)
1851 aDrawingRect
.Top() = nPosY
;
1855 aDrawingRect
.Bottom() = nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
1859 aRegion
.Union(mpDev
->PixelToLogic(aDrawingRect
));
1863 nPosY
+= pRowInfo
[nArrY
].nHeight
;
1868 aRegion
.Union(mpDev
->PixelToLogic(aDrawingRect
));
1874 bool ScOutputData::SetChangedClip()
1878 Rectangle aDrawingRect
;
1879 aDrawingRect
.Left() = nScrX
;
1880 aDrawingRect
.Right() = nScrX
+nScrW
-1;
1885 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1887 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1889 if ( pThisRowInfo
->bChanged
)
1893 aDrawingRect
.Top() = nPosY
;
1896 aDrawingRect
.Bottom() = nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
1900 aPoly
.Insert( Polygon( mpDev
->PixelToLogic(aDrawingRect
) ) );
1903 nPosY
+= pRowInfo
[nArrY
].nHeight
;
1907 aPoly
.Insert( Polygon( mpDev
->PixelToLogic(aDrawingRect
) ) );
1909 bool bRet
= (aPoly
.Count() != 0);
1911 mpDev
->SetClipRegion(Region(aPoly
));
1915 void ScOutputData::FindChanged()
1920 bool bWasIdleEnabled
= mpDoc
->IsIdleEnabled();
1921 mpDoc
->EnableIdle(false);
1922 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1923 pRowInfo
[nArrY
].bChanged
= false;
1925 bool bProgress
= false;
1926 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1928 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1929 for (nX
=nX1
; nX
<=nX2
; nX
++)
1931 const ScRefCellValue
& rCell
= pThisRowInfo
->pCellInfo
[nX
+1].maCell
;
1933 if (rCell
.meType
!= CELLTYPE_FORMULA
)
1936 ScFormulaCell
* pFCell
= rCell
.mpFormula
;
1937 if ( !bProgress
&& pFCell
->GetDirty() )
1939 ScProgress::CreateInterpretProgress(mpDoc
, true);
1942 if (pFCell
->IsRunning())
1943 // still being interpreted. Skip it.
1946 (void)pFCell
->GetValue();
1947 if (!pFCell
->IsChanged())
1948 // the result hasn't changed. Skip it.
1951 pThisRowInfo
->bChanged
= true;
1952 if ( pThisRowInfo
->pCellInfo
[nX
+1].bMerged
)
1954 SCSIZE nOverY
= nArrY
+ 1;
1955 while ( nOverY
<nArrCount
&&
1956 pRowInfo
[nOverY
].pCellInfo
[nX
+1].bVOverlapped
)
1958 pRowInfo
[nOverY
].bChanged
= true;
1965 ScProgress::DeleteInterpretProgress();
1966 mpDoc
->EnableIdle(bWasIdleEnabled
);
1969 void ScOutputData::DrawRefMark( SCCOL nRefStartX
, SCROW nRefStartY
,
1970 SCCOL nRefEndX
, SCROW nRefEndY
,
1971 const Color
& rColor
, bool bHandle
)
1973 PutInOrder( nRefStartX
, nRefEndX
);
1974 PutInOrder( nRefStartY
, nRefEndY
);
1976 if ( nRefStartX
== nRefEndX
&& nRefStartY
== nRefEndY
)
1977 mpDoc
->ExtendMerge( nRefStartX
, nRefStartY
, nRefEndX
, nRefEndY
, nTab
);
1979 if ( nRefStartX
<= nVisX2
&& nRefEndX
>= nVisX1
&&
1980 nRefStartY
<= nVisY2
&& nRefEndY
>= nVisY1
)
1984 long nMaxX
= nScrX
+ nScrW
- 1;
1985 long nMaxY
= nScrY
+ nScrH
- 1;
1992 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1995 bool bBottom
= false;
1997 bool bRight
= false;
2000 bool bNoStartY
= ( nY1
< nRefStartY
);
2001 bool bNoEndY
= false;
2002 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++) // loop to end for bNoEndY check
2004 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2006 if ( nY
==nRefStartY
|| (nY
>nRefStartY
&& bNoStartY
) )
2013 nMaxY
= nPosY
+ pRowInfo
[nArrY
].nHeight
- 2;
2016 if ( nY
>nRefEndY
&& bNoEndY
)
2021 bNoStartY
= ( nY
< nRefStartY
);
2022 bNoEndY
= ( nY
< nRefEndY
);
2023 nPosY
+= pRowInfo
[nArrY
].nHeight
;
2028 nPosX
+= nMirrorW
- 1; // always in pixels
2030 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2032 if ( nX
==nRefStartX
)
2039 nMaxX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 2 ) * nLayoutSign
;
2042 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2045 if ( nMaxX
* nLayoutSign
>= nMinX
* nLayoutSign
&&
2048 mpDev
->SetLineColor( rColor
);
2049 if (bTop
&& bBottom
&& bLeft
&& bRight
)
2051 mpDev
->SetFillColor();
2052 mpDev
->DrawRect( Rectangle( nMinX
, nMinY
, nMaxX
, nMaxY
) );
2057 mpDev
->DrawLine( Point( nMinX
, nMinY
), Point( nMaxX
, nMinY
) );
2059 mpDev
->DrawLine( Point( nMinX
, nMaxY
), Point( nMaxX
, nMaxY
) );
2061 mpDev
->DrawLine( Point( nMinX
, nMinY
), Point( nMinX
, nMaxY
) );
2063 mpDev
->DrawLine( Point( nMaxX
, nMinY
), Point( nMaxX
, nMaxY
) );
2065 if ( bHandle
&& bRight
&& bBottom
)
2067 mpDev
->SetLineColor( rColor
);
2068 mpDev
->SetFillColor( rColor
);
2070 const sal_Int32 aRadius
= 4;
2072 sal_Int32 aRectMaxX1
= nMaxX
- nLayoutSign
* aRadius
;
2073 sal_Int32 aRectMaxX2
= nMaxX
+ nLayoutSign
;
2074 sal_Int32 aRectMinX1
= nMinX
- nLayoutSign
;
2075 sal_Int32 aRectMinX2
= nMinX
+ nLayoutSign
* aRadius
;
2077 sal_Int32 aRectMaxY1
= nMaxY
- aRadius
;
2078 sal_Int32 aRectMaxY2
= nMaxY
+ 1;
2079 sal_Int32 aRectMinY1
= nMinY
- 1;
2080 sal_Int32 aRectMinY2
= nMinY
+ aRadius
;
2082 // Draw corner rectangles
2083 Rectangle
aLowerRight( aRectMaxX1
, aRectMaxY1
, aRectMaxX2
, aRectMaxY2
);
2084 Rectangle
aUpperLeft ( aRectMinX1
, aRectMinY1
, aRectMinX2
, aRectMinY2
);
2085 Rectangle
aLowerLeft ( aRectMinX1
, aRectMaxY1
, aRectMinX2
, aRectMaxY2
);
2086 Rectangle
aUpperRight( aRectMaxX1
, aRectMinY1
, aRectMaxX2
, aRectMinY2
);
2088 mpDev
->DrawTransparent( PolyPolygon( Polygon( aLowerRight
) ), lclCornerRectTransparency
);
2089 mpDev
->DrawTransparent( PolyPolygon( Polygon( aUpperLeft
) ), lclCornerRectTransparency
);
2090 mpDev
->DrawTransparent( PolyPolygon( Polygon( aLowerLeft
) ), lclCornerRectTransparency
);
2091 mpDev
->DrawTransparent( PolyPolygon( Polygon( aUpperRight
) ), lclCornerRectTransparency
);
2097 void ScOutputData::DrawOneChange( SCCOL nRefStartX
, SCROW nRefStartY
,
2098 SCCOL nRefEndX
, SCROW nRefEndY
,
2099 const Color
& rColor
, sal_uInt16 nType
)
2101 PutInOrder( nRefStartX
, nRefEndX
);
2102 PutInOrder( nRefStartY
, nRefEndY
);
2104 if ( nRefStartX
== nRefEndX
&& nRefStartY
== nRefEndY
)
2105 mpDoc
->ExtendMerge( nRefStartX
, nRefStartY
, nRefEndX
, nRefEndY
, nTab
);
2107 if ( nRefStartX
<= nVisX2
+ 1 && nRefEndX
>= nVisX1
&&
2108 nRefStartY
<= nVisY2
+ 1 && nRefEndY
>= nVisY1
) // +1 because it touches next cells left/top
2112 long nMaxX
= nScrX
+nScrW
-1;
2113 long nMaxY
= nScrY
+nScrH
-1;
2120 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2123 bool bBottom
= false;
2125 bool bRight
= false;
2128 bool bNoStartY
= ( nY1
< nRefStartY
);
2129 bool bNoEndY
= false;
2130 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++) // loop to end for bNoEndY check
2132 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2134 if ( nY
==nRefStartY
|| (nY
>nRefStartY
&& bNoStartY
) )
2141 nMaxY
= nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
2144 if ( nY
>nRefEndY
&& bNoEndY
)
2149 bNoStartY
= ( nY
< nRefStartY
);
2150 bNoEndY
= ( nY
< nRefEndY
);
2151 nPosY
+= pRowInfo
[nArrY
].nHeight
;
2156 nPosX
+= nMirrorW
- 1; // always in pixels
2158 for (SCCOL nX
=nX1
; nX
<=nX2
+1; nX
++)
2160 if ( nX
==nRefStartX
)
2162 nMinX
= nPosX
- nLayoutSign
;
2167 nMaxX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 1 ) * nLayoutSign
;
2170 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2173 if ( nMaxX
* nLayoutSign
>= nMinX
* nLayoutSign
&&
2176 if ( nType
== SC_CAT_DELETE_ROWS
)
2177 bLeft
= bRight
= bBottom
= false; //! thick lines???
2178 else if ( nType
== SC_CAT_DELETE_COLS
)
2179 bTop
= bBottom
= bRight
= false; //! thick lines???
2181 mpDev
->SetLineColor( rColor
);
2182 if (bTop
&& bBottom
&& bLeft
&& bRight
)
2184 mpDev
->SetFillColor();
2185 mpDev
->DrawRect( Rectangle( nMinX
, nMinY
, nMaxX
, nMaxY
) );
2191 mpDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMaxX
,nMinY
) );
2192 if ( nType
== SC_CAT_DELETE_ROWS
)
2193 mpDev
->DrawLine( Point( nMinX
,nMinY
+1 ), Point( nMaxX
,nMinY
+1 ) );
2196 mpDev
->DrawLine( Point( nMinX
,nMaxY
), Point( nMaxX
,nMaxY
) );
2199 mpDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMinX
,nMaxY
) );
2200 if ( nType
== SC_CAT_DELETE_COLS
)
2201 mpDev
->DrawLine( Point( nMinX
+nLayoutSign
,nMinY
), Point( nMinX
+nLayoutSign
,nMaxY
) );
2204 mpDev
->DrawLine( Point( nMaxX
,nMinY
), Point( nMaxX
,nMaxY
) );
2206 if ( bLeft
&& bTop
)
2208 mpDev
->SetLineColor();
2209 mpDev
->SetFillColor( rColor
);
2210 mpDev
->DrawRect( Rectangle( nMinX
+nLayoutSign
, nMinY
+1, nMinX
+3*nLayoutSign
, nMinY
+3 ) );
2216 void ScOutputData::DrawChangeTrack()
2218 ScChangeTrack
* pTrack
= mpDoc
->GetChangeTrack();
2219 ScChangeViewSettings
* pSettings
= mpDoc
->GetChangeViewSettings();
2220 if ( !pTrack
|| !pTrack
->GetFirst() || !pSettings
|| !pSettings
->ShowChanges() )
2221 return; // nix da oder abgeschaltet
2223 ScActionColorChanger
aColorChanger(*pTrack
);
2225 // Clipping passiert von aussen
2226 //! ohne Clipping, nur betroffene Zeilen painten ??!??!?
2230 if ( nEndX
< MAXCOL
) ++nEndX
; // auch noch von der naechsten Zelle, weil die Markierung
2231 if ( nEndY
< MAXROW
) ++nEndY
; // in die jeweils vorhergehende Zelle hineinragt
2232 ScRange
aViewRange( nX1
, nY1
, nTab
, nEndX
, nEndY
, nTab
);
2233 const ScChangeAction
* pAction
= pTrack
->GetFirst();
2236 ScChangeActionType eActionType
;
2237 if ( pAction
->IsVisible() )
2239 eActionType
= pAction
->GetType();
2240 const ScBigRange
& rBig
= pAction
->GetBigRange();
2241 if ( rBig
.aStart
.Tab() == nTab
)
2243 ScRange aRange
= rBig
.MakeRange();
2245 if ( eActionType
== SC_CAT_DELETE_ROWS
)
2246 aRange
.aEnd
.SetRow( aRange
.aStart
.Row() );
2247 else if ( eActionType
== SC_CAT_DELETE_COLS
)
2248 aRange
.aEnd
.SetCol( aRange
.aStart
.Col() );
2250 if ( aRange
.Intersects( aViewRange
) &&
2251 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *mpDoc
) )
2253 aColorChanger
.Update( *pAction
);
2254 Color
aColor( aColorChanger
.GetColor() );
2255 DrawOneChange( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2256 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aColor
, sal::static_int_cast
<sal_uInt16
>(eActionType
) );
2260 if ( eActionType
== SC_CAT_MOVE
&&
2261 ((const ScChangeActionMove
*)pAction
)->
2262 GetFromRange().aStart
.Tab() == nTab
)
2264 ScRange aRange
= ((const ScChangeActionMove
*)pAction
)->
2265 GetFromRange().MakeRange();
2266 if ( aRange
.Intersects( aViewRange
) &&
2267 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *mpDoc
) )
2269 aColorChanger
.Update( *pAction
);
2270 Color
aColor( aColorChanger
.GetColor() );
2271 DrawOneChange( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2272 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aColor
, sal::static_int_cast
<sal_uInt16
>(eActionType
) );
2277 pAction
= pAction
->GetNext();
2281 //TODO: moggi Need to check if this can't be written simpler
2282 void ScOutputData::DrawNoteMarks()
2287 long nInitPosX
= nScrX
;
2289 nInitPosX
+= nMirrorW
- 1; // always in pixels
2290 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2293 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2295 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2296 if ( pThisRowInfo
->bChanged
)
2298 long nPosX
= nInitPosX
;
2299 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2301 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2302 bool bIsMerged
= false;
2304 if ( nX
==nX1
&& pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
2306 // find start of merged cell
2308 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2311 mpDoc
->ExtendOverlapped( nMergeX
, nMergeY
, nX
, nY
, nTab
);
2312 // use origin's pCell for NotePtr test below
2315 if ( mpDoc
->GetNote(nX
, pRowInfo
[nArrY
].nRowNo
, nTab
) && ( bIsMerged
||
2316 ( !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
) ) )
2320 mpDev
->SetLineColor();
2322 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2323 if ( mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode() )
2324 mpDev
->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
2326 mpDev
->SetFillColor(COL_LIGHTRED
);
2331 long nMarkX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 4 ) * nLayoutSign
;
2332 if ( bIsMerged
|| pInfo
->bMerged
)
2334 // if merged, add widths of all cells
2335 SCCOL nNextX
= nX
+ 1;
2336 while ( nNextX
<= nX2
+ 1 && pThisRowInfo
->pCellInfo
[nNextX
+1].bHOverlapped
)
2338 nMarkX
+= pRowInfo
[0].pCellInfo
[nNextX
+1].nWidth
* nLayoutSign
;
2342 if ( bLayoutRTL
? ( nMarkX
>= 0 ) : ( nMarkX
< nScrX
+nScrW
) )
2343 mpDev
->DrawRect( Rectangle( nMarkX
,nPosY
,nMarkX
+2*nLayoutSign
,nPosY
+2 ) );
2346 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2349 nPosY
+= pThisRowInfo
->nHeight
;
2353 void ScOutputData::AddPDFNotes()
2355 vcl::PDFExtOutDevData
* pPDFData
= PTR_CAST( vcl::PDFExtOutDevData
, mpDev
->GetExtOutDevData() );
2356 if ( !pPDFData
|| !pPDFData
->GetIsExportNotes() )
2359 long nInitPosX
= nScrX
;
2362 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
2363 long nOneX
= aOnePixel
.Width();
2364 nInitPosX
+= nMirrorW
- nOneX
;
2366 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2369 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2371 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2372 if ( pThisRowInfo
->bChanged
)
2374 long nPosX
= nInitPosX
;
2375 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2377 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2378 bool bIsMerged
= false;
2379 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2383 if ( nX
==nX1
&& pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
2385 // find start of merged cell
2387 mpDoc
->ExtendOverlapped( nMergeX
, nMergeY
, nX
, nY
, nTab
);
2388 // use origin's pCell for NotePtr test below
2391 if ( mpDoc
->GetNote(nMergeX
, nMergeY
, nTab
) && ( bIsMerged
||
2392 ( !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
) ) )
2394 long nNoteWidth
= (long)( SC_CLIPMARK_SIZE
* mnPPTX
);
2395 long nNoteHeight
= (long)( SC_CLIPMARK_SIZE
* mnPPTY
);
2397 long nMarkX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- nNoteWidth
) * nLayoutSign
;
2398 if ( bIsMerged
|| pInfo
->bMerged
)
2400 // if merged, add widths of all cells
2401 SCCOL nNextX
= nX
+ 1;
2402 while ( nNextX
<= nX2
+ 1 && pThisRowInfo
->pCellInfo
[nNextX
+1].bHOverlapped
)
2404 nMarkX
+= pRowInfo
[0].pCellInfo
[nNextX
+1].nWidth
* nLayoutSign
;
2408 if ( bLayoutRTL
? ( nMarkX
>= 0 ) : ( nMarkX
< nScrX
+nScrW
) )
2410 Rectangle
aNoteRect( nMarkX
, nPosY
, nMarkX
+nNoteWidth
*nLayoutSign
, nPosY
+nNoteHeight
);
2411 const ScPostIt
* pNote
= mpDoc
->GetNote(nMergeX
, nMergeY
, nTab
);
2413 // Note title is the cell address (as on printed note pages)
2414 ScAddress
aAddress( nMergeX
, nMergeY
, nTab
);
2415 OUString
aTitle(aAddress
.Format(SCA_VALID
, mpDoc
, mpDoc
->GetAddressConvention()));
2417 // Content has to be a simple string without line breaks
2418 OUString aContent
= pNote
->GetText();
2419 aContent
= aContent
.replaceAll("\n", " ");
2422 aNote
.Title
= aTitle
;
2423 aNote
.Contents
= aContent
;
2424 pPDFData
->CreateNote( aNoteRect
, aNote
);
2428 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2431 nPosY
+= pThisRowInfo
->nHeight
;
2435 void ScOutputData::DrawClipMarks()
2440 Color
aArrowFillCol( COL_LIGHTRED
);
2442 sal_uLong nOldDrawMode
= mpDev
->GetDrawMode();
2443 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2444 if ( mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode() )
2446 // use DrawMode to change the arrow's outline color
2447 mpDev
->SetDrawMode( nOldDrawMode
| DRAWMODE_SETTINGSLINE
);
2448 // use text color also for the fill color
2449 aArrowFillCol
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
2452 long nInitPosX
= nScrX
;
2454 nInitPosX
+= nMirrorW
- 1; // always in pixels
2455 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2457 Rectangle aCellRect
;
2459 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2461 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2462 if ( pThisRowInfo
->bChanged
)
2464 SCROW nY
= pThisRowInfo
->nRowNo
;
2465 long nPosX
= nInitPosX
;
2466 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2468 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2469 if (pInfo
->nClipMark
)
2471 if (pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
2473 // merge origin may be outside of visible area - use document functions
2477 long nStartPosX
= nPosX
;
2478 long nStartPosY
= nPosY
;
2480 while ( nOverX
> 0 && ( ((const ScMergeFlagAttr
*)mpDoc
->GetAttr(
2481 nOverX
, nOverY
, nTab
, ATTR_MERGE_FLAG
))->GetValue() & SC_MF_HOR
) )
2484 nStartPosX
-= nLayoutSign
* (long) ( mpDoc
->GetColWidth(nOverX
,nTab
) * mnPPTX
);
2487 while ( nOverY
> 0 && ( ((const ScMergeFlagAttr
*)mpDoc
->GetAttr(
2488 nOverX
, nOverY
, nTab
, ATTR_MERGE_FLAG
))->GetValue() & SC_MF_VER
) )
2491 nStartPosY
-= nLayoutSign
* (long) ( mpDoc
->GetRowHeight(nOverY
,nTab
) * mnPPTY
);
2494 long nOutWidth
= (long) ( mpDoc
->GetColWidth(nOverX
,nTab
) * mnPPTX
);
2495 long nOutHeight
= (long) ( mpDoc
->GetRowHeight(nOverY
,nTab
) * mnPPTY
);
2497 const ScMergeAttr
* pMerge
= (const ScMergeAttr
*)
2498 mpDoc
->GetAttr( nOverX
, nOverY
, nTab
, ATTR_MERGE
);
2499 SCCOL nCountX
= pMerge
->GetColMerge();
2500 for (SCCOL i
=1; i
<nCountX
; i
++)
2501 nOutWidth
+= (long) ( mpDoc
->GetColWidth(nOverX
+i
,nTab
) * mnPPTX
);
2502 SCROW nCountY
= pMerge
->GetRowMerge();
2503 nOutHeight
+= (long) mpDoc
->GetScaledRowHeight( nOverY
+1, nOverY
+nCountY
-1, nTab
, mnPPTY
);
2506 nStartPosX
-= nOutWidth
- 1;
2507 aCellRect
= Rectangle( Point( nStartPosX
, nStartPosY
), Size( nOutWidth
, nOutHeight
) );
2511 long nOutWidth
= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
2512 long nOutHeight
= pThisRowInfo
->nHeight
;
2514 if ( pInfo
->bMerged
&& pInfo
->pPatternAttr
)
2518 const ScMergeAttr
* pMerge
=
2519 (ScMergeAttr
*)&pInfo
->pPatternAttr
->GetItem(ATTR_MERGE
);
2520 SCCOL nCountX
= pMerge
->GetColMerge();
2521 for (SCCOL i
=1; i
<nCountX
; i
++)
2522 nOutWidth
+= (long) ( mpDoc
->GetColWidth(nOverX
+i
,nTab
) * mnPPTX
);
2523 SCROW nCountY
= pMerge
->GetRowMerge();
2524 nOutHeight
+= (long) mpDoc
->GetScaledRowHeight( nOverY
+1, nOverY
+nCountY
-1, nTab
, mnPPTY
);
2527 long nStartPosX
= nPosX
;
2529 nStartPosX
-= nOutWidth
- 1;
2530 // #i80447# create aCellRect from two points in case nOutWidth is 0
2531 aCellRect
= Rectangle( Point( nStartPosX
, nPosY
),
2532 Point( nStartPosX
+nOutWidth
-1, nPosY
+nOutHeight
-1 ) );
2535 aCellRect
.Bottom() -= 1; // don't paint over the cell grid
2537 aCellRect
.Left() += 1;
2539 aCellRect
.Right() -= 1;
2541 long nMarkPixel
= (long)( SC_CLIPMARK_SIZE
* mnPPTX
);
2542 Size
aMarkSize( nMarkPixel
, (nMarkPixel
-1)*2 );
2544 if ( pInfo
->nClipMark
& ( bLayoutRTL
? SC_CLIPMARK_RIGHT
: SC_CLIPMARK_LEFT
) )
2547 Rectangle aMarkRect
= aCellRect
;
2548 aMarkRect
.Right() = aCellRect
.Left()+nMarkPixel
-1;
2549 SvxFont::DrawArrow( *mpDev
, aMarkRect
, aMarkSize
, aArrowFillCol
, true );
2551 if ( pInfo
->nClipMark
& ( bLayoutRTL
? SC_CLIPMARK_LEFT
: SC_CLIPMARK_RIGHT
) )
2554 Rectangle aMarkRect
= aCellRect
;
2555 aMarkRect
.Left() = aCellRect
.Right()-nMarkPixel
+1;
2556 SvxFont::DrawArrow( *mpDev
, aMarkRect
, aMarkSize
, aArrowFillCol
, false );
2559 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2562 nPosY
+= pThisRowInfo
->nHeight
;
2565 mpDev
->SetDrawMode(nOldDrawMode
);
2568 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */