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 "svtools/optionsdrawinglayer.hxx"
28 #include <svx/rotmodit.hxx>
29 #include <editeng/shaditem.hxx>
30 #include <editeng/svxfont.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <tools/poly.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/pdfextoutdevdata.hxx>
35 #include <svtools/accessibilityoptions.hxx>
36 #include <svx/framelinkarray.hxx>
37 #include <drawinglayer/geometry/viewinformation2d.hxx>
38 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
39 #include <basegfx/matrix/b2dhommatrix.hxx>
40 #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
41 #include <vcl/lineinfo.hxx>
42 #include <vcl/gradient.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"
73 using namespace com::sun::star
;
75 // STATIC DATA -----------------------------------------------------------
77 // Farben fuer ChangeTracking "nach Autor" wie im Writer (swmodul1.cxx)
79 #define SC_AUTHORCOLORCOUNT 9
81 static const ColorData nAuthorColor
[ SC_AUTHORCOLORCOUNT
] = {
82 COL_LIGHTRED
, COL_LIGHTBLUE
, COL_LIGHTMAGENTA
,
83 COL_GREEN
, COL_RED
, COL_BLUE
,
84 COL_BROWN
, COL_MAGENTA
, COL_CYAN
};
87 // Hilfsklasse, fuer die Farbzuordnung,
88 // um nicht mehrfach hintereinander denselben User aus der Liste zu suchen
90 class ScActionColorChanger
93 const ScAppOptions
& rOpt
;
94 const std::set
<OUString
>& rUsers
;
95 OUString aLastUserName
;
96 size_t nLastUserIndex
;
100 ScActionColorChanger( const ScChangeTrack
& rTrack
);
101 ~ScActionColorChanger() {}
103 void Update( const ScChangeAction
& rAction
);
104 ColorData
GetColor() const { return nColor
; }
107 //------------------------------------------------------------------
109 ScActionColorChanger::ScActionColorChanger( const ScChangeTrack
& rTrack
) :
110 rOpt( SC_MOD()->GetAppOptions() ),
111 rUsers( rTrack
.GetUserCollection() ),
117 void ScActionColorChanger::Update( const ScChangeAction
& rAction
)
120 switch (rAction
.GetType())
122 case SC_CAT_INSERT_COLS
:
123 case SC_CAT_INSERT_ROWS
:
124 case SC_CAT_INSERT_TABS
:
125 nSetColor
= rOpt
.GetTrackInsertColor();
127 case SC_CAT_DELETE_COLS
:
128 case SC_CAT_DELETE_ROWS
:
129 case SC_CAT_DELETE_TABS
:
130 nSetColor
= rOpt
.GetTrackDeleteColor();
133 nSetColor
= rOpt
.GetTrackMoveColor();
136 nSetColor
= rOpt
.GetTrackContentColor();
139 if ( nSetColor
!= COL_TRANSPARENT
) // Farbe eingestellt
143 if (!aLastUserName
.equals(rAction
.GetUser()))
145 aLastUserName
= rAction
.GetUser();
146 std::set
<OUString
>::const_iterator it
= rUsers
.find(aLastUserName
);
147 if (it
== rUsers
.end())
149 // empty string is possible if a name wasn't found while saving a 5.0 file
150 SAL_INFO_IF( aLastUserName
.isEmpty(), "sc.ui", "Author not found" );
155 size_t nPos
= std::distance(rUsers
.begin(), it
);
156 nLastUserIndex
= nPos
% SC_AUTHORCOLORCOUNT
;
159 nColor
= nAuthorColor
[nLastUserIndex
];
163 //==================================================================
165 ScOutputData::ScOutputData( OutputDevice
* pNewDev
, ScOutputType eNewType
,
166 ScTableInfo
& rTabInfo
, ScDocument
* pNewDoc
,
167 SCTAB nNewTab
, long nNewScrX
, long nNewScrY
,
168 SCCOL nNewX1
, SCROW nNewY1
, SCCOL nNewX2
, SCROW nNewY2
,
169 double nPixelPerTwipsX
, double nPixelPerTwipsY
,
170 const Fraction
* pZoomX
, const Fraction
* pZoomY
) :
172 mpRefDevice( pNewDev
), // default is output device
173 pFmtDevice( pNewDev
), // default is output device
174 mrTabInfo( rTabInfo
),
175 pRowInfo( rTabInfo
.mpRowInfo
),
176 nArrCount( rTabInfo
.mnArrCount
),
186 mnPPTX( nPixelPerTwipsX
),
187 mnPPTY( nPixelPerTwipsY
),
190 pDrawView( NULL
), // #114135#
193 bSingleGrid( false ),
194 bPagebreakMode( false ),
195 bSolidBackground( false ),
196 mbUseStyleColor( false ),
197 mbForceAutoColor( SC_MOD()->GetAccessOptions().GetIsAutomaticFontColor() ),
198 mbSyntaxMode( false ),
201 pFormulaColor( NULL
),
202 aGridColor( COL_BLACK
),
203 mbShowNullValues( sal_True
),
204 mbShowFormulas( false ),
205 bShowSpellErrors( false ),
206 bMarkClipped( false ), // sal_False fuer Drucker/Metafile etc.
208 bAnyRotated( false ),
209 bAnyClipped( false ),
210 mpTargetPaintWindow(NULL
), // #i74769# use SdrPaintWindow direct
211 mpSpellCheckCxt(NULL
)
216 aZoomX
= Fraction(1,1);
220 aZoomY
= Fraction(1,1);
226 mpDoc
->StripHidden( nVisX1
, nVisY1
, nVisX2
, nVisY2
, nTab
);
229 for (SCCOL nX
=nVisX1
; nX
<=nVisX2
; nX
++)
230 nScrW
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
235 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
236 nScrH
+= pRowInfo
[nArrY
].nHeight
;
238 bTabProtected
= mpDoc
->IsTabProtected( nTab
);
239 nTabTextDirection
= mpDoc
->GetEditTextDirection( nTab
);
240 bLayoutRTL
= mpDoc
->IsLayoutRTL( nTab
);
243 ScOutputData::~ScOutputData()
247 delete pFormulaColor
;
250 void ScOutputData::SetSpellCheckContext( const sc::SpellCheckContext
* pCxt
)
252 mpSpellCheckCxt
= pCxt
;
255 void ScOutputData::SetContentDevice( OutputDevice
* pContentDev
)
257 // use pContentDev instead of pDev where used
259 if ( mpRefDevice
== mpDev
)
260 mpRefDevice
= pContentDev
;
261 if ( pFmtDevice
== mpDev
)
262 pFmtDevice
= pContentDev
;
266 void ScOutputData::SetMirrorWidth( long nNew
)
271 void ScOutputData::SetGridColor( const Color
& rColor
)
276 void ScOutputData::SetMarkClipped( sal_Bool bSet
)
281 void ScOutputData::SetShowNullValues( sal_Bool bSet
)
283 mbShowNullValues
= bSet
;
286 void ScOutputData::SetShowFormulas( sal_Bool bSet
)
288 mbShowFormulas
= bSet
;
291 void ScOutputData::SetShowSpellErrors( sal_Bool bSet
)
293 bShowSpellErrors
= bSet
;
296 void ScOutputData::SetSnapPixel( sal_Bool bSet
)
301 void ScOutputData::SetEditCell( SCCOL nCol
, SCROW nRow
)
305 bEditMode
= sal_True
;
308 void ScOutputData::SetMetaFileMode( sal_Bool bNewMode
)
310 bMetaFile
= bNewMode
;
313 void ScOutputData::SetSingleGrid( sal_Bool bNewMode
)
315 bSingleGrid
= bNewMode
;
318 void ScOutputData::SetSyntaxMode( sal_Bool bNewMode
)
320 mbSyntaxMode
= bNewMode
;
324 pValueColor
= new Color( COL_LIGHTBLUE
);
325 pTextColor
= new Color( COL_BLACK
);
326 pFormulaColor
= new Color( COL_GREEN
);
330 void ScOutputData::DrawGrid( sal_Bool bGrid
, sal_Bool bPage
)
337 ScBreakType nBreak
= BREAK_NONE
;
338 ScBreakType nBreakOld
= BREAK_NONE
;
345 bPage
= false; // keine "normalen" Umbrueche ueber volle Breite/Hoehe
347 //! um den einen Pixel sieht das Metafile (oder die Druck-Ausgabe) anders aus
348 //! als die Bildschirmdarstellung, aber wenigstens passen Druck und Metafile zusammen
350 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
351 long nOneX
= aOnePixel
.Width();
352 long nOneY
= aOnePixel
.Height();
356 long nLayoutSign
= bLayoutRTL
? -1 : 1;
357 long nSignedOneX
= nOneX
* nLayoutSign
;
359 if ( eType
== OUTTYPE_WINDOW
)
361 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
362 aPageColor
.SetColor( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
);
363 aManualColor
.SetColor( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
367 aPageColor
= aGridColor
;
368 aManualColor
= aGridColor
;
371 mpDev
->SetLineColor( aGridColor
);
372 ScGridMerger
aGrid( mpDev
, nOneX
, nOneY
);
380 nPosX
+= nMirrorW
- nOneX
;
382 for (nX
=nX1
; nX
<=nX2
; nX
++)
384 SCCOL nXplus1
= nX
+1;
385 SCCOL nXplus2
= nX
+2;
386 sal_uInt16 nWidth
= pRowInfo
[0].pCellInfo
[nXplus1
].nWidth
;
389 nPosX
+= nWidth
* nLayoutSign
;
393 // Seitenumbrueche auch in ausgeblendeten suchen
394 SCCOL nCol
= nXplus1
;
395 while (nCol
<= MAXCOL
)
397 nBreak
= mpDoc
->HasColBreak(nCol
, nTab
);
398 bool bHidden
= mpDoc
->ColHidden(nCol
, nTab
);
400 if ( nBreak
|| !bHidden
)
405 if (nBreak
!= nBreakOld
)
408 mpDev
->SetLineColor( (nBreak
& BREAK_MANUAL
) ? aManualColor
:
409 nBreak
? aPageColor
: aGridColor
);
414 sal_Bool bDraw
= bGrid
|| nBreakOld
; // einfaches Gitter nur wenn eingestellt
416 sal_uInt16 nWidthXplus2
= pRowInfo
[0].pCellInfo
[nXplus2
].nWidth
;
417 bSingle
= bSingleGrid
; //! in Fillinfo holen !!!!!
418 if ( nX
<MAXCOL
&& !bSingle
)
420 bSingle
= ( nWidthXplus2
== 0 );
421 for (nArrY
=1; nArrY
+1<nArrCount
&& !bSingle
; nArrY
++)
423 if (pRowInfo
[nArrY
].pCellInfo
[nXplus2
].bHOverlapped
)
425 if (pRowInfo
[nArrY
].pCellInfo
[nXplus1
].bHideGrid
)
432 if ( nX
<MAXCOL
&& bSingle
)
434 SCCOL nVisX
= nXplus1
;
435 while ( nVisX
< MAXCOL
&& !mpDoc
->GetColWidth(nVisX
,nTab
) )
440 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
442 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
443 nNextY
= nPosY
+ pThisRowInfo
->nHeight
;
445 sal_Bool bHOver
= pThisRowInfo
->pCellInfo
[nXplus1
].bHideGrid
;
449 bHOver
= pThisRowInfo
->pCellInfo
[nXplus2
].bHOverlapped
;
453 bHOver
= pThisRowInfo
->pCellInfo
[nVisX
+1].bHOverlapped
;
455 bHOver
= ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
456 nVisX
,pThisRowInfo
->nRowNo
,nTab
,ATTR_MERGE_FLAG
))
459 bHOver
= ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
460 nXplus1
,pThisRowInfo
->nRowNo
,nTab
,ATTR_MERGE_FLAG
))
465 if (pThisRowInfo
->bChanged
&& !bHOver
)
467 aGrid
.AddVerLine( nPosX
-nSignedOneX
, nPosY
, nNextY
-nOneY
);
474 aGrid
.AddVerLine( nPosX
-nSignedOneX
, nScrY
, nScrY
+nScrH
-nOneY
);
481 // Horizontale Linien
484 bool bHiddenRow
= true;
485 SCROW nHiddenEndRow
= -1;
487 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
489 SCSIZE nArrYplus1
= nArrY
+1;
490 nY
= pRowInfo
[nArrY
].nRowNo
;
491 SCROW nYplus1
= nY
+1;
492 nPosY
+= pRowInfo
[nArrY
].nHeight
;
494 if (pRowInfo
[nArrY
].bChanged
)
498 for (SCROW i
= nYplus1
; i
<= MAXROW
; ++i
)
500 if (i
> nHiddenEndRow
)
501 bHiddenRow
= mpDoc
->RowHidden(i
, nTab
, NULL
, &nHiddenEndRow
);
502 /* TODO: optimize the row break thing for large hidden
503 * segments where HasRowBreak() has to be called
504 * nevertheless for each row, as a row break is drawn also
505 * for hidden rows, above them. This needed to be done only
506 * once per hidden segment, maybe giving manual breaks
507 * priority. Something like GetNextRowBreak() and
508 * GetNextManualRowBreak(). */
509 nBreak
= mpDoc
->HasRowBreak(i
, nTab
);
510 if (!bHiddenRow
|| nBreak
)
514 if (nBreakOld
!= nBreak
)
517 mpDev
->SetLineColor( (nBreak
& BREAK_MANUAL
) ? aManualColor
:
518 (nBreak
) ? aPageColor
: aGridColor
);
523 bool bDraw
= bGrid
|| nBreakOld
; // einfaches Gitter nur wenn eingestellt
525 sal_Bool bNextYisNextRow
= (pRowInfo
[nArrYplus1
].nRowNo
== nYplus1
);
526 bSingle
= !bNextYisNextRow
; // Hidden
527 for (SCCOL i
=nX1
; i
<=nX2
&& !bSingle
; i
++)
529 if (pRowInfo
[nArrYplus1
].pCellInfo
[i
+1].bVOverlapped
)
535 if ( bSingle
&& nY
<MAXROW
)
537 SCROW nVisY
= pRowInfo
[nArrYplus1
].nRowNo
;
541 nPosX
+= nMirrorW
- nOneX
;
544 for (SCCOL i
=nX1
; i
<=nX2
; i
++)
546 nNextX
= nPosX
+ pRowInfo
[0].pCellInfo
[i
+1].nWidth
* nLayoutSign
;
547 if (nNextX
!= nPosX
) // sichtbar
550 if ( bNextYisNextRow
)
551 bVOver
= pRowInfo
[nArrYplus1
].pCellInfo
[i
+1].bVOverlapped
;
554 bVOver
= ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
555 i
,nYplus1
,nTab
,ATTR_MERGE_FLAG
))
557 && ((ScMergeFlagAttr
*)mpDoc
->GetAttr(
558 i
,nVisY
,nTab
,ATTR_MERGE_FLAG
))
560 //! nVisY aus Array ??
564 aGrid
.AddHorLine( nPosX
, nNextX
-nSignedOneX
, nPosY
-nOneY
);
572 aGrid
.AddHorLine( nScrX
, nScrX
+nScrW
-nOneX
, nPosY
-nOneY
);
579 // ----------------------------------------------------------------------------
581 void ScOutputData::SetPagebreakMode( ScPageBreakData
* pPageData
)
583 bPagebreakMode
= true;
585 return; // noch nicht initialisiert -> alles "nicht gedruckt"
587 // gedruckten Bereich markieren
588 // (in FillInfo ist schon alles auf sal_False initialisiert)
590 sal_uInt16 nRangeCount
= sal::static_int_cast
<sal_uInt16
>(pPageData
->GetCount());
591 for (sal_uInt16 nPos
=0; nPos
<nRangeCount
; nPos
++)
593 ScRange aRange
= pPageData
->GetData( nPos
).GetPrintRange();
595 SCCOL nStartX
= std::max( aRange
.aStart
.Col(), nX1
);
596 SCCOL nEndX
= std::min( aRange
.aEnd
.Col(), nX2
);
597 SCROW nStartY
= std::max( aRange
.aStart
.Row(), nY1
);
598 SCROW nEndY
= std::min( aRange
.aEnd
.Row(), nY2
);
600 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
602 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
603 if ( pThisRowInfo
->bChanged
&& pThisRowInfo
->nRowNo
>= nStartY
&&
604 pThisRowInfo
->nRowNo
<= nEndY
)
606 for (SCCOL nX
=nStartX
; nX
<=nEndX
; nX
++)
607 pThisRowInfo
->pCellInfo
[nX
+1].bPrinted
= sal_True
;
613 void ScOutputData::FindRotated()
615 //! nRotMax speichern
617 for (SCSIZE nRotY
=0; nRotY
<nArrCount
; nRotY
++)
618 if (pRowInfo
[nRotY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nRotY
].nRotMaxCol
> nRotMax
)
619 nRotMax
= pRowInfo
[nRotY
].nRotMaxCol
;
621 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++)
623 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
624 if ( pThisRowInfo
->nRotMaxCol
!= SC_ROTMAX_NONE
&&
625 ( pThisRowInfo
->bChanged
|| pRowInfo
[nArrY
-1].bChanged
||
626 ( nArrY
+1<nArrCount
&& pRowInfo
[nArrY
+1].bChanged
) ) )
628 SCROW nY
= pThisRowInfo
->nRowNo
;
630 for (SCCOL nX
=0; nX
<=nRotMax
; nX
++)
632 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
633 const ScPatternAttr
* pPattern
= pInfo
->pPatternAttr
;
634 const SfxItemSet
* pCondSet
= pInfo
->pConditionSet
;
636 if ( !pPattern
&& !mpDoc
->ColHidden(nX
, nTab
) )
638 pPattern
= mpDoc
->GetPattern( nX
, nY
, nTab
);
639 pCondSet
= mpDoc
->GetCondResult( nX
, nY
, nTab
);
642 if ( pPattern
) // Spalte nicht ausgeblendet
644 sal_uInt8 nDir
= pPattern
->GetRotateDir( pCondSet
);
645 if (nDir
!= SC_ROTDIR_NONE
)
647 pInfo
->nRotateDir
= nDir
;
648 bAnyRotated
= sal_True
;
656 // ----------------------------------------------------------------------------
658 static sal_uInt16
lcl_GetRotateDir( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
660 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
661 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
663 sal_uInt16 nRet
= SC_ROTDIR_NONE
;
665 long nAttrRotate
= pPattern
->GetRotateVal( pCondSet
);
668 SvxRotateMode eRotMode
= (SvxRotateMode
)((const SvxRotateModeItem
&)
669 pPattern
->GetItem(ATTR_ROTATE_MODE
, pCondSet
)).GetValue();
671 if ( eRotMode
== SVX_ROTATE_MODE_STANDARD
)
672 nRet
= SC_ROTDIR_STANDARD
;
673 else if ( eRotMode
== SVX_ROTATE_MODE_CENTER
)
674 nRet
= SC_ROTDIR_CENTER
;
675 else if ( eRotMode
== SVX_ROTATE_MODE_TOP
|| eRotMode
== SVX_ROTATE_MODE_BOTTOM
)
677 long nRot180
= nAttrRotate
% 18000; // 1/100 Grad
678 if ( nRot180
== 9000 )
679 nRet
= SC_ROTDIR_CENTER
;
680 else if ( ( eRotMode
== SVX_ROTATE_MODE_TOP
&& nRot180
< 9000 ) ||
681 ( eRotMode
== SVX_ROTATE_MODE_BOTTOM
&& nRot180
> 9000 ) )
682 nRet
= SC_ROTDIR_LEFT
;
684 nRet
= SC_ROTDIR_RIGHT
;
691 static const SvxBrushItem
* lcl_FindBackground( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
693 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
694 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
695 const SvxBrushItem
* pBackground
= (const SvxBrushItem
*)
696 &pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
698 sal_uInt16 nDir
= lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
);
700 // CENTER wird wie RIGHT behandelt...
701 if ( nDir
== SC_ROTDIR_RIGHT
|| nDir
== SC_ROTDIR_CENTER
)
703 // Text geht nach rechts -> Hintergrund von links nehmen
704 while ( nCol
> 0 && lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
) == nDir
&&
705 pBackground
->GetColor().GetTransparency() != 255 )
708 pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
709 pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
710 pBackground
= (const SvxBrushItem
*)&pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
713 else if ( nDir
== SC_ROTDIR_LEFT
)
715 // Text geht nach links -> Hintergrund von rechts nehmen
716 while ( nCol
< MAXCOL
&& lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
) == nDir
&&
717 pBackground
->GetColor().GetTransparency() != 255 )
720 pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
721 pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
722 pBackground
= (const SvxBrushItem
*)&pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
729 // ----------------------------------------------------------------------------
731 static bool lcl_EqualBack( const RowInfo
& rFirst
, const RowInfo
& rOther
,
732 SCCOL nX1
, SCCOL nX2
, bool bShowProt
, bool bPagebreakMode
)
734 if ( rFirst
.bChanged
!= rOther
.bChanged
||
735 rFirst
.bEmptyBack
!= rOther
.bEmptyBack
)
741 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
743 const ScPatternAttr
* pPat1
= rFirst
.pCellInfo
[nX
+1].pPatternAttr
;
744 const ScPatternAttr
* pPat2
= rOther
.pCellInfo
[nX
+1].pPatternAttr
;
745 if ( !pPat1
|| !pPat2
||
746 &pPat1
->GetItem(ATTR_PROTECTION
) != &pPat2
->GetItem(ATTR_PROTECTION
) )
752 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
753 if ( rFirst
.pCellInfo
[nX
+1].pBackground
!= rOther
.pCellInfo
[nX
+1].pBackground
)
757 if ( rFirst
.nRotMaxCol
!= SC_ROTMAX_NONE
|| rOther
.nRotMaxCol
!= SC_ROTMAX_NONE
)
758 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
759 if ( rFirst
.pCellInfo
[nX
+1].nRotateDir
!= rOther
.pCellInfo
[nX
+1].nRotateDir
)
762 if ( bPagebreakMode
)
763 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
764 if ( rFirst
.pCellInfo
[nX
+1].bPrinted
!= rOther
.pCellInfo
[nX
+1].bPrinted
)
767 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
769 const Color
* pCol1
= rFirst
.pCellInfo
[nX
+1].pColorScale
;
770 const Color
* pCol2
= rOther
.pCellInfo
[nX
+1].pColorScale
;
771 if( (pCol1
&& !pCol2
) || (!pCol1
&& pCol2
) )
774 if (pCol1
&& (*pCol1
!= *pCol2
))
777 const ScDataBarInfo
* pInfo1
= rFirst
.pCellInfo
[nX
+1].pDataBar
;
778 const ScDataBarInfo
* pInfo2
= rOther
.pCellInfo
[nX
+1].pDataBar
;
780 if( (pInfo1
&& !pInfo2
) || (!pInfo1
&& pInfo2
) )
783 if (pInfo1
&& (*pInfo1
!= *pInfo2
))
786 // each cell with an icon set should be painted the same way
787 const ScIconSetInfo
* pIconSet1
= rFirst
.pCellInfo
[nX
+1].pIconSet
;
788 const ScIconSetInfo
* pIconSet2
= rOther
.pCellInfo
[nX
+1].pIconSet
;
790 if(pIconSet1
|| pIconSet2
)
797 void ScOutputData::DrawDocumentBackground()
799 if ( !bSolidBackground
)
802 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
803 long nOneX
= aOnePixel
.Width();
804 long nOneY
= aOnePixel
.Height();
805 Rectangle
aRect(nScrX
- nOneX
, nScrY
- nOneY
, nScrX
+ nScrW
, nScrY
+ nScrH
);
806 Color
aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
);
807 mpDev
->SetFillColor(aBgColor
);
808 mpDev
->DrawRect(aRect
);
813 static const double lclCornerRectTransparency
= 40.0;
815 void drawDataBars( const ScDataBarInfo
* pOldDataBarInfo
, OutputDevice
* pDev
, const Rectangle
& rRect
)
818 Rectangle aPaintRect
= rRect
;
819 aPaintRect
.Top() += 2;
820 aPaintRect
.Bottom() -= 2;
821 aPaintRect
.Left() += 2;
822 aPaintRect
.Right() -= 2;
823 if(pOldDataBarInfo
->mnZero
)
825 //need to calculate null point in cell
826 long nLength
= aPaintRect
.Right() - aPaintRect
.Left();
827 nPosZero
= static_cast<long>(aPaintRect
.Left() + nLength
*pOldDataBarInfo
->mnZero
/100.0);
831 nPosZero
= aPaintRect
.Left();
834 if(pOldDataBarInfo
->mnLength
< 0)
836 aPaintRect
.Right() = nPosZero
;
837 long nLength
= nPosZero
- aPaintRect
.Left();
838 aPaintRect
.Left() = nPosZero
+ static_cast<long>(nLength
* pOldDataBarInfo
->mnLength
/100.0);
840 else if(pOldDataBarInfo
->mnLength
> 0)
842 aPaintRect
.Left() = nPosZero
;
843 long nLength
= aPaintRect
.Right() - nPosZero
;
844 aPaintRect
.Right() = nPosZero
+ static_cast<long>(nLength
* pOldDataBarInfo
->mnLength
/100.0);
849 if(pOldDataBarInfo
->mbGradient
)
851 pDev
->SetLineColor(pOldDataBarInfo
->maColor
);
852 Gradient
aGradient(GradientStyle_LINEAR
, pOldDataBarInfo
->maColor
, COL_TRANSPARENT
);
854 if(pOldDataBarInfo
->mnLength
< 0)
855 aGradient
.SetAngle(2700);
857 aGradient
.SetAngle(900);
859 pDev
->DrawGradient(aPaintRect
, aGradient
);
861 pDev
->SetLineColor();
865 pDev
->SetFillColor(pOldDataBarInfo
->maColor
);
866 pDev
->DrawRect(aPaintRect
);
870 if(pOldDataBarInfo
->mnZero
&& pOldDataBarInfo
->mnZero
!= 100)
872 Point
aPoint1(nPosZero
, rRect
.Top());
873 Point
aPoint2(nPosZero
, rRect
.Bottom());
874 LineInfo
aLineInfo(LINE_DASH
, 1);
875 aLineInfo
.SetDashCount( 4 );
876 aLineInfo
.SetDistance( 3 );
877 aLineInfo
.SetDashLen( 3 );
878 pDev
->SetFillColor(pOldDataBarInfo
->maAxisColor
);
879 pDev
->SetLineColor(pOldDataBarInfo
->maAxisColor
);
880 pDev
->DrawLine(aPoint1
, aPoint2
, aLineInfo
);
881 pDev
->SetLineColor();
882 pDev
->SetFillColor();
886 BitmapEx
& getIcon( ScIconSetType eType
, sal_Int32 nIndex
)
888 return ScIconSetFormat::getBitmap( eType
, nIndex
);
891 void drawIconSets( const ScIconSetInfo
* pOldIconSetInfo
, OutputDevice
* pDev
, const Rectangle
& rRect
)
894 ScIconSetType eType
= pOldIconSetInfo
->eIconSetType
;
895 sal_Int32 nIndex
= pOldIconSetInfo
->nIconIndex
;
896 BitmapEx
& rIcon
= getIcon( eType
, nIndex
);
897 long aOrigSize
= std::max
<long>(0,std::min(rRect
.GetSize().getWidth() - 4, rRect
.GetSize().getHeight() -4));
898 pDev
->DrawBitmapEx( Point( rRect
.Left() +2, rRect
.Top() + 2 ), Size(aOrigSize
, aOrigSize
), rIcon
);
901 void drawCells(const Color
* pColor
, const SvxBrushItem
* pBackground
, const Color
*& pOldColor
, const SvxBrushItem
*& pOldBackground
,
902 Rectangle
& rRect
, long nPosX
, long nSignedOneX
, OutputDevice
* pDev
, const ScDataBarInfo
* pDataBarInfo
, const ScDataBarInfo
*& pOldDataBarInfo
,
903 const ScIconSetInfo
* pIconSetInfo
, const ScIconSetInfo
*& pOldIconSetInfo
)
906 // need to paint if old color scale has been used and now
907 // we have a different color or a style based background
908 // we can here fall back to pointer comparison
909 if (pOldColor
&& (pBackground
|| pOldColor
!= pColor
|| pOldDataBarInfo
|| pDataBarInfo
|| pIconSetInfo
|| pOldIconSetInfo
))
911 rRect
.Right() = nPosX
-nSignedOneX
;
912 if( !pOldColor
->GetTransparency() )
914 pDev
->SetFillColor( *pOldColor
);
915 pDev
->DrawRect( rRect
);
917 if( pOldDataBarInfo
)
918 drawDataBars( pOldDataBarInfo
, pDev
, rRect
);
919 if( pOldIconSetInfo
)
920 drawIconSets( pOldIconSetInfo
, pDev
, rRect
);
922 rRect
.Left() = nPosX
- nSignedOneX
;
925 if ( pOldBackground
&& (pColor
||pBackground
!= pOldBackground
|| pOldDataBarInfo
|| pDataBarInfo
|| pIconSetInfo
|| pOldIconSetInfo
) )
927 rRect
.Right() = nPosX
-nSignedOneX
;
928 if (pOldBackground
) // ==0 if hidden
930 Color aBackCol
= pOldBackground
->GetColor();
931 if ( !aBackCol
.GetTransparency() ) //! partial transparency?
933 pDev
->SetFillColor( aBackCol
);
934 pDev
->DrawRect( rRect
);
937 if( pOldDataBarInfo
)
938 drawDataBars( pOldDataBarInfo
, pDev
, rRect
);
939 if( pOldIconSetInfo
)
940 drawIconSets( pOldIconSetInfo
, pDev
, rRect
);
942 rRect
.Left() = nPosX
- nSignedOneX
;
945 if (!pOldBackground
&& !pOldColor
&& (pDataBarInfo
|| pIconSetInfo
))
947 rRect
.Right() = nPosX
-nSignedOneX
;
948 rRect
.Left() = nPosX
- nSignedOneX
;
953 // only update pOldColor if the colors changed
954 if (!pOldColor
|| *pOldColor
!= *pColor
)
957 pOldBackground
= NULL
;
961 pOldBackground
= pBackground
;
966 pOldDataBarInfo
= pDataBarInfo
;
968 pOldDataBarInfo
= NULL
;
971 pOldIconSetInfo
= pIconSetInfo
;
973 pOldIconSetInfo
= NULL
;
978 void ScOutputData::DrawBackground()
980 FindRotated(); //! von aussen ?
983 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
984 long nOneX
= aOnePixel
.Width();
985 long nOneY
= aOnePixel
.Height();
990 long nLayoutSign
= bLayoutRTL
? -1 : 1;
991 long nSignedOneX
= nOneX
* nLayoutSign
;
993 mpDev
->SetLineColor();
995 bool bShowProt
= mbSyntaxMode
&& mpDoc
->IsTabProtected(nTab
);
996 bool bDoAll
= bShowProt
|| bPagebreakMode
|| bSolidBackground
;
998 bool bCellContrast
= mbUseStyleColor
&&
999 Application::GetSettings().GetStyleSettings().GetHighContrastMode();
1002 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1004 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1005 long nRowHeight
= pThisRowInfo
->nHeight
;
1007 if ( pThisRowInfo
->bChanged
)
1009 if ( ( ( pThisRowInfo
->bEmptyBack
) || mbSyntaxMode
) && !bDoAll
)
1015 // scan for rows with the same background:
1017 while ( nArrY
+nSkip
+2<nArrCount
&&
1018 lcl_EqualBack( *pThisRowInfo
, pRowInfo
[nArrY
+nSkip
+1],
1019 nX1
, nX2
, bShowProt
, bPagebreakMode
) )
1022 nRowHeight
+= pRowInfo
[nArrY
+nSkip
].nHeight
; // after incrementing
1027 nPosX
+= nMirrorW
- nOneX
;
1028 aRect
= Rectangle( nPosX
, nPosY
-nOneY
, nPosX
, nPosY
+nRowHeight
-nOneY
);
1030 const SvxBrushItem
* pOldBackground
= NULL
;
1031 const SvxBrushItem
* pBackground
;
1032 const Color
* pOldColor
= NULL
;
1033 const Color
* pColor
= NULL
;
1034 const ScDataBarInfo
* pOldDataBarInfo
= NULL
;
1035 const ScIconSetInfo
* pOldIconSetInfo
= NULL
;
1036 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
1038 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
1042 // high contrast for cell borders and backgrounds -> empty background
1043 pBackground
= ScGlobal::GetEmptyBrushItem();
1045 else if (bShowProt
) // show cell protection in syntax mode
1047 const ScPatternAttr
* pP
= pInfo
->pPatternAttr
;
1050 const ScProtectionAttr
& rProt
= (const ScProtectionAttr
&)
1051 pP
->GetItem(ATTR_PROTECTION
);
1052 if (rProt
.GetProtection() || rProt
.GetHideCell())
1053 pBackground
= ScGlobal::GetProtectedBrushItem();
1055 pBackground
= ScGlobal::GetEmptyBrushItem();
1061 pBackground
= pInfo
->pBackground
;
1063 if ( bPagebreakMode
&& !pInfo
->bPrinted
)
1064 pBackground
= ScGlobal::GetProtectedBrushItem();
1066 if ( pInfo
->nRotateDir
> SC_ROTDIR_STANDARD
&&
1067 pBackground
->GetColor().GetTransparency() != 255 &&
1070 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
1071 pBackground
= lcl_FindBackground( mpDoc
, nX
, nY
, nTab
);
1074 pColor
= pInfo
->pColorScale
;
1075 const ScDataBarInfo
* pDataBarInfo
= pInfo
->pDataBar
;
1076 const ScIconSetInfo
* pIconSetInfo
= pInfo
->pIconSet
;
1077 drawCells( pColor
, pBackground
, pOldColor
, pOldBackground
, aRect
, nPosX
, nSignedOneX
, mpDev
, pDataBarInfo
, pOldDataBarInfo
, pIconSetInfo
, pOldIconSetInfo
);
1079 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
1081 drawCells( NULL
, NULL
, pOldColor
, pOldBackground
, aRect
, nPosX
, nSignedOneX
, mpDev
, NULL
, pOldDataBarInfo
, NULL
, pOldIconSetInfo
);
1086 nPosY
+= nRowHeight
;
1090 void ScOutputData::DrawShadow()
1092 DrawExtraShadow( false, false, false, false );
1095 void ScOutputData::DrawExtraShadow(sal_Bool bLeft
, sal_Bool bTop
, sal_Bool bRight
, sal_Bool bBottom
)
1097 mpDev
->SetLineColor();
1099 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1100 bool bCellContrast
= mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1101 Color aAutoTextColor
;
1102 if ( bCellContrast
)
1103 aAutoTextColor
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
1105 long nInitPosX
= nScrX
;
1108 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1109 long nOneX
= aOnePixel
.Width();
1110 nInitPosX
+= nMirrorW
- nOneX
;
1112 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1114 long nPosY
= nScrY
- pRowInfo
[0].nHeight
;
1115 for (SCSIZE nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1117 bool bCornerY
= ( nArrY
== 0 ) || ( nArrY
+1 == nArrCount
);
1118 bool bSkipY
= ( nArrY
==0 && !bTop
) || ( nArrY
+1 == nArrCount
&& !bBottom
);
1120 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1121 long nRowHeight
= pThisRowInfo
->nHeight
;
1123 if ( pThisRowInfo
->bChanged
&& !bSkipY
)
1125 long nPosX
= nInitPosX
- pRowInfo
[0].pCellInfo
[nX1
].nWidth
* nLayoutSign
;
1126 for (SCCOL nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++)
1128 bool bCornerX
= ( nArrX
==nX1
|| nArrX
==nX2
+2 );
1129 bool bSkipX
= ( nArrX
==nX1
&& !bLeft
) || ( nArrX
==nX2
+2 && !bRight
);
1131 for (sal_uInt16 nPass
=0; nPass
<2; nPass
++) // horizontal / vertikal
1133 const SvxShadowItem
* pAttr
= nPass
?
1134 pThisRowInfo
->pCellInfo
[nArrX
].pVShadowOrigin
:
1135 pThisRowInfo
->pCellInfo
[nArrX
].pHShadowOrigin
;
1136 if ( pAttr
&& !bSkipX
)
1138 ScShadowPart ePart
= nPass
?
1139 pThisRowInfo
->pCellInfo
[nArrX
].eVShadowPart
:
1140 pThisRowInfo
->pCellInfo
[nArrX
].eHShadowPart
;
1143 if ( (nPass
==0 && bCornerX
) || (nPass
==1 && bCornerY
) )
1144 if ( ePart
!= SC_SHADOW_CORNER
)
1149 long nThisWidth
= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
;
1150 long nMaxWidth
= nThisWidth
;
1153 //! direction must depend on shadow location
1154 SCCOL nWx
= nArrX
; // nX+1
1155 while (nWx
<nX2
&& !pRowInfo
[0].pCellInfo
[nWx
+1].nWidth
)
1157 nMaxWidth
= pRowInfo
[0].pCellInfo
[nWx
+1].nWidth
;
1160 // rectangle is in logical orientation
1161 Rectangle
aRect( nPosX
, nPosY
,
1162 nPosX
+ ( nThisWidth
- 1 ) * nLayoutSign
,
1163 nPosY
+ pRowInfo
[nArrY
].nHeight
- 1 );
1165 long nSize
= pAttr
->GetWidth();
1166 long nSizeX
= (long)(nSize
*mnPPTX
);
1167 if (nSizeX
>= nMaxWidth
) nSizeX
= nMaxWidth
-1;
1168 long nSizeY
= (long)(nSize
*mnPPTY
);
1169 if (nSizeY
>= nRowHeight
) nSizeY
= nRowHeight
-1;
1171 nSizeX
*= nLayoutSign
; // used only to add to rectangle values
1173 SvxShadowLocation eLoc
= pAttr
->GetLocation();
1176 // Shadow location is specified as "visual" (right is always right),
1177 // so the attribute's location value is mirrored here and in FillInfo.
1180 case SVX_SHADOW_BOTTOMRIGHT
: eLoc
= SVX_SHADOW_BOTTOMLEFT
; break;
1181 case SVX_SHADOW_BOTTOMLEFT
: eLoc
= SVX_SHADOW_BOTTOMRIGHT
; break;
1182 case SVX_SHADOW_TOPRIGHT
: eLoc
= SVX_SHADOW_TOPLEFT
; break;
1183 case SVX_SHADOW_TOPLEFT
: eLoc
= SVX_SHADOW_TOPRIGHT
; break;
1186 // added to avoid warnings
1191 if (ePart
== SC_SHADOW_HORIZ
|| ePart
== SC_SHADOW_HSTART
||
1192 ePart
== SC_SHADOW_CORNER
)
1194 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_TOPRIGHT
)
1195 aRect
.Top() = aRect
.Bottom() - nSizeY
;
1197 aRect
.Bottom() = aRect
.Top() + nSizeY
;
1199 if (ePart
== SC_SHADOW_VERT
|| ePart
== SC_SHADOW_VSTART
||
1200 ePart
== SC_SHADOW_CORNER
)
1202 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_BOTTOMLEFT
)
1203 aRect
.Left() = aRect
.Right() - nSizeX
;
1205 aRect
.Right() = aRect
.Left() + nSizeX
;
1207 if (ePart
== SC_SHADOW_HSTART
)
1209 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_BOTTOMLEFT
)
1210 aRect
.Right() -= nSizeX
;
1212 aRect
.Left() += nSizeX
;
1214 if (ePart
== SC_SHADOW_VSTART
)
1216 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_TOPRIGHT
)
1217 aRect
.Bottom() -= nSizeY
;
1219 aRect
.Top() += nSizeY
;
1222 //! merge rectangles?
1223 mpDev
->SetFillColor( bCellContrast
? aAutoTextColor
: pAttr
->GetColor() );
1224 mpDev
->DrawRect( aRect
);
1229 nPosX
+= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
* nLayoutSign
;
1232 nPosY
+= nRowHeight
;
1240 void ScOutputData::DrawClear()
1243 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1244 long nOneX
= aOnePixel
.Width();
1245 long nOneY
= aOnePixel
.Height();
1247 // (called only for ScGridWindow)
1248 Color
aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
);
1253 mpDev
->SetLineColor();
1255 mpDev
->SetFillColor( aBgColor
);
1258 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1260 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1261 long nRowHeight
= pThisRowInfo
->nHeight
;
1263 if ( pThisRowInfo
->bChanged
)
1265 // scan for more rows which must be painted:
1267 while ( nArrY
+nSkip
+2<nArrCount
&& pRowInfo
[nArrY
+nSkip
+1].bChanged
)
1270 nRowHeight
+= pRowInfo
[nArrY
+nSkip
].nHeight
; // after incrementing
1273 aRect
= Rectangle( Point( nScrX
, nPosY
),
1274 Size( nScrW
+1-nOneX
, nRowHeight
+1-nOneY
) );
1275 mpDev
->DrawRect( aRect
);
1279 nPosY
+= nRowHeight
;
1285 long lclGetSnappedX( OutputDevice
& rDev
, long nPosX
, bool bSnapPixel
)
1287 return (bSnapPixel
&& nPosX
) ? rDev
.PixelToLogic( rDev
.LogicToPixel( Size( nPosX
, 0 ) ) ).Width() : nPosX
;
1290 long lclGetSnappedY( OutputDevice
& rDev
, long nPosY
, bool bSnapPixel
)
1292 return (bSnapPixel
&& nPosY
) ? rDev
.PixelToLogic( rDev
.LogicToPixel( Size( 0, nPosY
) ) ).Height() : nPosY
;
1295 size_t lclGetArrayColFromCellInfoX( sal_uInt16 nCellInfoX
, sal_uInt16 nCellInfoFirstX
, sal_uInt16 nCellInfoLastX
, bool bRTL
)
1297 return static_cast< size_t >( bRTL
? (nCellInfoLastX
+ 2 - nCellInfoX
) : (nCellInfoX
- nCellInfoFirstX
) );
1301 * Temporarily turn off antialiasing.
1303 class AntiAliasingSwitch
1305 SvtOptionsDrawinglayer maDrawOpt
;
1308 AntiAliasingSwitch(bool bOn
) : mbOldSetting(maDrawOpt
.IsAntiAliasing())
1310 maDrawOpt
.SetAntiAliasing(bOn
);
1313 ~AntiAliasingSwitch()
1315 maDrawOpt
.SetAntiAliasing(mbOldSetting
);
1321 void ScOutputData::DrawFrame()
1323 // No anti-aliasing for drawing cell borders.
1324 AntiAliasingSwitch
aAASwitch(false);
1326 sal_uLong nOldDrawMode
= mpDev
->GetDrawMode();
1329 bool bUseSingleColor
= false;
1330 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1331 bool bCellContrast
= mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1333 // if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
1334 // for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
1335 // that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
1336 // must be reset and the border colors handled here.
1338 if ( ( nOldDrawMode
& DRAWMODE_WHITEFILL
) && ( nOldDrawMode
& DRAWMODE_BLACKLINE
) )
1340 mpDev
->SetDrawMode( nOldDrawMode
& (~DRAWMODE_WHITEFILL
) );
1341 aSingleColor
.SetColor( COL_BLACK
);
1342 bUseSingleColor
= true;
1344 else if ( ( nOldDrawMode
& DRAWMODE_SETTINGSFILL
) && ( nOldDrawMode
& DRAWMODE_SETTINGSLINE
) )
1346 mpDev
->SetDrawMode( nOldDrawMode
& (~DRAWMODE_SETTINGSFILL
) );
1347 aSingleColor
= rStyleSettings
.GetWindowTextColor(); // same as used in VCL for DRAWMODE_SETTINGSLINE
1348 bUseSingleColor
= true;
1350 else if ( bCellContrast
)
1352 aSingleColor
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
1353 bUseSingleColor
= true;
1356 const Color
* pForceColor
= bUseSingleColor
? &aSingleColor
: 0;
1359 DrawRotatedFrame( pForceColor
); // removes the lines that must not be painted here
1361 long nInitPosX
= nScrX
;
1364 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1365 long nOneX
= aOnePixel
.Width();
1366 nInitPosX
+= nMirrorW
- nOneX
;
1368 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1371 // *** set column and row sizes of the frame border array ***
1373 svx::frame::Array
& rArray
= mrTabInfo
.maArray
;
1374 size_t nColCount
= rArray
.GetColCount();
1375 size_t nRowCount
= rArray
.GetRowCount();
1379 // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
1380 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
1381 long nOldPosY
= nScrY
- 1 - pRowInfo
[ 0 ].nHeight
;
1382 long nOldSnapY
= lclGetSnappedY( *mpDev
, nOldPosY
, bSnapPixel
);
1383 rArray
.SetYOffset( nOldSnapY
);
1384 for( size_t nRow
= 0; nRow
< nRowCount
; ++nRow
)
1386 long nNewPosY
= nOldPosY
+ pRowInfo
[ nRow
].nHeight
;
1387 long nNewSnapY
= lclGetSnappedY( *mpDev
, nNewPosY
, bSnapPixel
);
1388 rArray
.SetRowHeight( nRow
, nNewSnapY
- nOldSnapY
);
1389 nOldPosY
= nNewPosY
;
1390 nOldSnapY
= nNewSnapY
;
1395 // column nX1 is not visible (dummy for borders from left) - subtract its width from initial position
1396 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
1397 long nOldPosX
= nInitPosX
- nLayoutSign
* (1 + pRowInfo
[ 0 ].pCellInfo
[ nX1
].nWidth
);
1398 long nOldSnapX
= lclGetSnappedX( *mpDev
, nOldPosX
, bSnapPixel
);
1399 // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
1401 rArray
.SetXOffset( nOldSnapX
);
1402 for( sal_uInt16 nInfoIdx
= nX1
; nInfoIdx
<= nX2
+ 2; ++nInfoIdx
)
1404 size_t nCol
= lclGetArrayColFromCellInfoX( nInfoIdx
, nX1
, nX2
, bLayoutRTL
);
1405 long nNewPosX
= nOldPosX
+ pRowInfo
[ 0 ].pCellInfo
[ nInfoIdx
].nWidth
* nLayoutSign
;
1406 long nNewSnapX
= lclGetSnappedX( *mpDev
, nNewPosX
, bSnapPixel
);
1407 rArray
.SetColWidth( nCol
, std::abs( nNewSnapX
- nOldSnapX
) );
1408 nOldPosX
= nNewPosX
;
1409 nOldSnapX
= nNewSnapX
;
1412 rArray
.SetXOffset( nOldSnapX
);
1414 // *** draw the array ***
1416 size_t nFirstCol
= 1;
1417 size_t nFirstRow
= 1;
1418 size_t nLastCol
= nColCount
- 2;
1419 size_t nLastRow
= nRowCount
- 2;
1421 if( mrTabInfo
.mbPageMode
)
1422 rArray
.SetClipRange( nFirstCol
, nFirstRow
, nLastCol
, nLastRow
);
1424 // draw only rows with set RowInfo::bChanged flag
1425 size_t nRow1
= nFirstRow
;
1426 drawinglayer::processor2d::BaseProcessor2D
* pProcessor
= CreateProcessor2D();
1430 while( nRow1
<= nLastRow
)
1432 while( (nRow1
<= nLastRow
) && !pRowInfo
[ nRow1
].bChanged
) ++nRow1
;
1433 if( nRow1
<= nLastRow
)
1435 size_t nRow2
= nRow1
;
1436 while( (nRow2
+ 1 <= nLastRow
) && pRowInfo
[ nRow2
+ 1 ].bChanged
) ++nRow2
;
1437 rArray
.DrawRange( pProcessor
, nFirstCol
, nRow1
, nLastCol
, nRow2
, pForceColor
);
1444 mpDev
->SetDrawMode(nOldDrawMode
);
1447 // -------------------------------------------------------------------------
1449 // Linie unter der Zelle
1451 static const ::editeng::SvxBorderLine
* lcl_FindHorLine( ScDocument
* pDoc
,
1452 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, sal_uInt16 nRotDir
,
1455 if ( nRotDir
!= SC_ROTDIR_LEFT
&& nRotDir
!= SC_ROTDIR_RIGHT
)
1458 bool bFound
= false;
1461 if ( nRotDir
== SC_ROTDIR_LEFT
)
1463 // Text nach links -> Linie von rechts
1464 if ( nCol
< MAXCOL
)
1467 return NULL
; // war nix
1471 // Text nach rechts -> Linie von links
1475 return NULL
; // war nix
1477 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
1478 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
1479 if ( !pPattern
->GetRotateVal( pCondSet
) ||
1480 ((const SvxRotateModeItem
&)pPattern
->GetItem(
1481 ATTR_ROTATE_MODE
, pCondSet
)).GetValue() == SVX_ROTATE_MODE_STANDARD
)
1487 const ::editeng::SvxBorderLine
* pThisBottom
;
1488 if ( ValidRow(nRow
) )
1489 pThisBottom
= ((const SvxBoxItem
*)pDoc
->GetAttr( nCol
, nRow
, nTab
, ATTR_BORDER
))->GetBottom();
1492 const ::editeng::SvxBorderLine
* pNextTop
;
1493 if ( nRow
< MAXROW
)
1494 pNextTop
= ((const SvxBoxItem
*)pDoc
->GetAttr( nCol
, nRow
+1, nTab
, ATTR_BORDER
))->GetTop();
1498 if ( ScHasPriority( pThisBottom
, pNextTop
) )
1505 static long lcl_getRotate( ScDocument
* pDoc
, SCTAB nTab
, SCCOL nX
, SCROW nY
)
1509 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1510 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nX
, nY
, nTab
);
1512 nRotate
= pPattern
->GetRotateVal( pCondSet
);
1517 void ScOutputData::DrawRotatedFrame( const Color
* pForceColor
)
1519 //! nRotMax speichern
1520 SCCOL nRotMax
= nX2
;
1521 for (SCSIZE nRotY
=0; nRotY
<nArrCount
; nRotY
++)
1522 if (pRowInfo
[nRotY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nRotY
].nRotMaxCol
> nRotMax
)
1523 nRotMax
= pRowInfo
[nRotY
].nRotMaxCol
;
1525 const ScPatternAttr
* pPattern
;
1526 const SfxItemSet
* pCondSet
;
1528 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1529 bool bCellContrast
= mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1531 // color (pForceColor) is determined externally, including DrawMode changes
1533 long nInitPosX
= nScrX
;
1536 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
1537 long nOneX
= aOnePixel
.Width();
1538 nInitPosX
+= nMirrorW
- nOneX
;
1540 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1542 Rectangle
aClipRect( Point(nScrX
, nScrY
), Size(nScrW
, nScrH
) );
1546 mpDev
->IntersectClipRegion( aClipRect
);
1549 mpDev
->SetClipRegion( Region( aClipRect
) );
1551 svx::frame::Array
& rArray
= mrTabInfo
.maArray
;
1552 drawinglayer::processor2d::BaseProcessor2D
* pProcessor
= CreateProcessor2D( );
1555 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++)
1557 // Rotated wird auch 1 Zeile ueber/unter Changed gezeichnet, falls Teile
1558 // in die Zeile hineinragen...
1560 RowInfo
& rPrevRowInfo
= pRowInfo
[nArrY
-1];
1561 RowInfo
& rThisRowInfo
= pRowInfo
[nArrY
];
1562 RowInfo
& rNextRowInfo
= pRowInfo
[nArrY
+1];
1564 size_t nRow
= static_cast< size_t >( nArrY
);
1566 long nRowHeight
= rThisRowInfo
.nHeight
;
1567 if ( rThisRowInfo
.nRotMaxCol
!= SC_ROTMAX_NONE
&&
1568 ( rThisRowInfo
.bChanged
|| rPrevRowInfo
.bChanged
||
1569 ( nArrY
+1<nArrCount
&& rNextRowInfo
.bChanged
) ) )
1571 SCROW nY
= rThisRowInfo
.nRowNo
;
1574 for (nX
=0; nX
<=nRotMax
; nX
++)
1576 if (nX
==nX1
) nPosX
= nInitPosX
; // calculated individually for preceding positions
1578 sal_uInt16 nArrX
= nX
+ 1;
1580 CellInfo
* pInfo
= &rThisRowInfo
.pCellInfo
[nArrX
];
1581 long nColWidth
= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
;
1582 if ( pInfo
->nRotateDir
> SC_ROTDIR_STANDARD
&&
1583 !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
1585 pPattern
= pInfo
->pPatternAttr
;
1586 pCondSet
= pInfo
->pConditionSet
;
1589 pPattern
= mpDoc
->GetPattern( nX
, nY
, nTab
);
1590 pInfo
->pPatternAttr
= pPattern
;
1591 pCondSet
= mpDoc
->GetCondResult( nX
, nY
, nTab
);
1592 pInfo
->pConditionSet
= pCondSet
;
1595 //! LastPattern etc.
1597 long nAttrRotate
= pPattern
->GetRotateVal( pCondSet
);
1598 SvxRotateMode eRotMode
= (SvxRotateMode
)((const SvxRotateModeItem
&)
1599 pPattern
->GetItem(ATTR_ROTATE_MODE
, pCondSet
)).GetValue();
1603 if (nX
<nX1
) // negative Position berechnen
1610 nPosX
-= nLayoutSign
* (long) pRowInfo
[0].pCellInfo
[nCol
+1].nWidth
;
1614 // Startposition minus 1, damit auch schraege Hintergruende
1615 // zur Umrandung passen (Umrandung ist auf dem Gitter)
1617 long nTop
= nPosY
- 1;
1618 long nBottom
= nPosY
+ nRowHeight
- 1;
1619 long nTopLeft
= nPosX
- nLayoutSign
;
1620 long nTopRight
= nPosX
+ ( nColWidth
- 1 ) * nLayoutSign
;
1621 long nBotLeft
= nTopLeft
;
1622 long nBotRight
= nTopRight
;
1624 // inclusion of the sign here hasn't been decided yet
1625 // (if not, the extension of the non-rotated background must also be changed)
1626 double nRealOrient
= nLayoutSign
* nAttrRotate
* F_PI18000
; // 1/100th degrees
1627 double nCos
= cos( nRealOrient
);
1628 double nSin
= sin( nRealOrient
);
1630 long nSkew
= (long) ( nRowHeight
* nCos
/ nSin
);
1634 case SVX_ROTATE_MODE_BOTTOM
:
1638 case SVX_ROTATE_MODE_CENTER
:
1645 case SVX_ROTATE_MODE_TOP
:
1651 // added to avoid warnings
1656 aPoints
[0] = Point( nTopLeft
, nTop
);
1657 aPoints
[1] = Point( nTopRight
, nTop
);
1658 aPoints
[2] = Point( nBotRight
, nBottom
);
1659 aPoints
[3] = Point( nBotLeft
, nBottom
);
1661 const SvxBrushItem
* pBackground
= pInfo
->pBackground
;
1663 pBackground
= (const SvxBrushItem
*) &pPattern
->GetItem(
1664 ATTR_BACKGROUND
, pCondSet
);
1667 // high contrast for cell borders and backgrounds -> empty background
1668 pBackground
= ScGlobal::GetEmptyBrushItem();
1670 if(!pInfo
->pColorScale
)
1672 const Color
& rColor
= pBackground
->GetColor();
1673 if ( rColor
.GetTransparency() != 255 )
1675 // draw background only for the changed row itself
1676 // (background doesn't extend into other cells).
1677 // For the borders (rotated and normal), clipping should be
1678 // set if the row isn't changed, but at least the borders
1679 // don't cover the cell contents.
1680 if ( rThisRowInfo
.bChanged
)
1682 Polygon
aPoly( 4, aPoints
);
1684 // ohne Pen wird bei DrawPolygon rechts und unten
1685 // ein Pixel weggelassen...
1686 if ( rColor
.GetTransparency() == 0 )
1687 mpDev
->SetLineColor(rColor
);
1689 mpDev
->SetLineColor();
1690 mpDev
->SetFillColor(rColor
);
1691 mpDev
->DrawPolygon( aPoly
);
1697 Polygon
aPoly( 4, aPoints
);
1698 const Color
* pColor
= pInfo
->pColorScale
;
1700 // ohne Pen wird bei DrawPolygon rechts und unten
1701 // ein Pixel weggelassen...
1702 if ( pColor
->GetTransparency() == 0 )
1703 mpDev
->SetLineColor(*pColor
);
1705 mpDev
->SetLineColor();
1706 mpDev
->SetFillColor(*pColor
);
1707 mpDev
->DrawPolygon( aPoly
);
1711 svx::frame::Style aTopLine
, aBottomLine
, aLeftLine
, aRightLine
;
1713 if ( nX
< nX1
|| nX
> nX2
) // Attribute in FillInfo nicht gesetzt
1715 //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
1716 const ::editeng::SvxBorderLine
* pLeftLine
;
1717 const ::editeng::SvxBorderLine
* pTopLine
;
1718 const ::editeng::SvxBorderLine
* pRightLine
;
1719 const ::editeng::SvxBorderLine
* pBottomLine
;
1720 mpDoc
->GetBorderLines( nX
, nY
, nTab
,
1721 &pLeftLine
, &pTopLine
, &pRightLine
, &pBottomLine
);
1722 aTopLine
.Set( pTopLine
, mnPPTY
);
1723 aBottomLine
.Set( pBottomLine
, mnPPTY
);
1724 aLeftLine
.Set( pLeftLine
, mnPPTX
);
1725 aRightLine
.Set( pRightLine
, mnPPTX
);
1729 size_t nCol
= lclGetArrayColFromCellInfoX( nArrX
, nX1
, nX2
, bLayoutRTL
);
1730 aTopLine
= rArray
.GetCellStyleTop( nCol
, nRow
);
1731 aBottomLine
= rArray
.GetCellStyleBottom( nCol
, nRow
);
1732 aLeftLine
= rArray
.GetCellStyleLeft( nCol
, nRow
);
1733 aRightLine
= rArray
.GetCellStyleRight( nCol
, nRow
);
1734 // in RTL mode the array is already mirrored -> swap back left/right borders
1736 std::swap( aLeftLine
, aRightLine
);
1739 const svx::frame::Style noStyle
;
1741 long nUpperRotate
= lcl_getRotate( mpDoc
, nTab
, nX
, nY
- 1 );
1742 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1743 aPoints
[bLayoutRTL
?1:0], aPoints
[bLayoutRTL
?0:1], aTopLine
,
1744 svx::frame::Style(),
1745 svx::frame::Style(),
1747 svx::frame::Style(),
1748 svx::frame::Style(),
1750 pForceColor
, nUpperRotate
, nAttrRotate
) );
1752 long nLowerRotate
= lcl_getRotate( mpDoc
, nTab
, nX
, nY
+ 1 );
1753 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1754 aPoints
[bLayoutRTL
?2:3], aPoints
[bLayoutRTL
?3:2], aBottomLine
,
1756 svx::frame::Style(),
1757 svx::frame::Style(),
1759 svx::frame::Style(),
1760 svx::frame::Style(),
1761 pForceColor
, 18000 - nAttrRotate
, 18000 - nLowerRotate
) );
1763 // Vertical slanted lines
1764 long nLeftRotate
= lcl_getRotate( mpDoc
, nTab
, nX
- 1, nY
);
1765 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1766 aPoints
[0], aPoints
[3], aLeftLine
,
1768 svx::frame::Style(),
1769 svx::frame::Style(),
1771 svx::frame::Style(),
1772 svx::frame::Style(),
1773 pForceColor
, nAttrRotate
, nLeftRotate
) );
1775 long nRightRotate
= lcl_getRotate( mpDoc
, nTab
, nX
+ 1, nY
);
1776 pProcessor
->process( svx::frame::CreateBorderPrimitives(
1777 aPoints
[1], aPoints
[2], aRightLine
,
1778 svx::frame::Style(),
1779 svx::frame::Style(),
1781 svx::frame::Style(),
1782 svx::frame::Style(),
1784 pForceColor
, 18000 - nRightRotate
, 18000 - nAttrRotate
) );
1787 nPosX
+= nColWidth
* nLayoutSign
;
1790 // erst hinterher im zweiten Schritt die Linien fuer normale Ausgabe loeschen
1792 nX
= nX1
> 0 ? (nX1
-1) : static_cast<SCCOL
>(0);
1793 for (; nX
<=nX2
+1; nX
++) // sichtbarer Teil +- 1
1795 sal_uInt16 nArrX
= nX
+ 1;
1796 CellInfo
& rInfo
= rThisRowInfo
.pCellInfo
[nArrX
];
1797 if ( rInfo
.nRotateDir
> SC_ROTDIR_STANDARD
&&
1798 !rInfo
.bHOverlapped
&& !rInfo
.bVOverlapped
)
1800 pPattern
= rInfo
.pPatternAttr
;
1801 pCondSet
= rInfo
.pConditionSet
;
1803 size_t nCol
= lclGetArrayColFromCellInfoX( nArrX
, nX1
, nX2
, bLayoutRTL
);
1805 // horizontal: angrenzende Linie verlaengern
1806 // (nur, wenn die gedrehte Zelle eine Umrandung hat)
1807 sal_uInt16 nDir
= rInfo
.nRotateDir
;
1808 if ( rArray
.GetCellStyleTop( nCol
, nRow
).Prim() )
1810 svx::frame::Style
aStyle( lcl_FindHorLine( mpDoc
, nX
, nY
, nTab
, nDir
, true ), mnPPTY
);
1811 rArray
.SetCellStyleTop( nCol
, nRow
, aStyle
);
1813 rArray
.SetCellStyleBottom( nCol
, nRow
- 1, aStyle
);
1815 if ( rArray
.GetCellStyleBottom( nCol
, nRow
).Prim() )
1817 svx::frame::Style
aStyle( lcl_FindHorLine( mpDoc
, nX
, nY
, nTab
, nDir
, false ), mnPPTY
);
1818 rArray
.SetCellStyleBottom( nCol
, nRow
, aStyle
);
1819 if( nRow
+ 1 < rArray
.GetRowCount() )
1820 rArray
.SetCellStyleTop( nCol
, nRow
+ 1, aStyle
);
1823 // always remove vertical borders
1824 if( !rArray
.IsMergedOverlappedLeft( nCol
, nRow
) )
1826 rArray
.SetCellStyleLeft( nCol
, nRow
, svx::frame::Style() );
1828 rArray
.SetCellStyleRight( nCol
- 1, nRow
, svx::frame::Style() );
1830 if( !rArray
.IsMergedOverlappedRight( nCol
, nRow
) )
1832 rArray
.SetCellStyleRight( nCol
, nRow
, svx::frame::Style() );
1833 if( nCol
+ 1 < rArray
.GetColCount() )
1834 rArray
.SetCellStyleLeft( nCol
+ 1, nRow
, svx::frame::Style() );
1837 // remove diagonal borders
1838 rArray
.SetCellStyleTLBR( nCol
, nRow
, svx::frame::Style() );
1839 rArray
.SetCellStyleBLTR( nCol
, nRow
, svx::frame::Style() );
1843 nPosY
+= nRowHeight
;
1846 if ( pProcessor
) delete pProcessor
;
1851 mpDev
->SetClipRegion();
1854 drawinglayer::processor2d::BaseProcessor2D
* ScOutputData::CreateProcessor2D( )
1856 mpDoc
->InitDrawLayer(mpDoc
->GetDocumentShell());
1857 ScDrawLayer
* pDrawLayer
= mpDoc
->GetDrawLayer();
1861 basegfx::B2DRange aViewRange
;
1862 SdrPage
*pDrawPage
= pDrawLayer
->GetPage( static_cast< sal_uInt16
>( nTab
) );
1863 const drawinglayer::geometry::ViewInformation2D
aNewViewInfos(
1864 basegfx::B2DHomMatrix( ),
1865 mpDev
->GetViewTransformation(),
1867 GetXDrawPageForSdrPage( pDrawPage
),
1869 uno::Sequence
< beans::PropertyValue
>() );
1871 return drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
1872 *mpDev
, aNewViewInfos
);
1877 Region
ScOutputData::GetChangedAreaRegion()
1880 Rectangle aDrawingRect
;
1885 aDrawingRect
.Left() = nScrX
;
1886 aDrawingRect
.Right() = nScrX
+nScrW
-1;
1888 for(nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1890 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1892 if(pThisRowInfo
->bChanged
)
1896 aDrawingRect
.Top() = nPosY
;
1900 aDrawingRect
.Bottom() = nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
1904 aRegion
.Union(mpDev
->PixelToLogic(aDrawingRect
));
1908 nPosY
+= pRowInfo
[nArrY
].nHeight
;
1913 aRegion
.Union(mpDev
->PixelToLogic(aDrawingRect
));
1919 sal_Bool
ScOutputData::SetChangedClip()
1923 Rectangle aDrawingRect
;
1924 aDrawingRect
.Left() = nScrX
;
1925 aDrawingRect
.Right() = nScrX
+nScrW
-1;
1930 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1932 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1934 if ( pThisRowInfo
->bChanged
)
1938 aDrawingRect
.Top() = nPosY
;
1941 aDrawingRect
.Bottom() = nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
1945 aPoly
.Insert( Polygon( mpDev
->PixelToLogic(aDrawingRect
) ) );
1948 nPosY
+= pRowInfo
[nArrY
].nHeight
;
1952 aPoly
.Insert( Polygon( mpDev
->PixelToLogic(aDrawingRect
) ) );
1954 sal_Bool bRet
= (aPoly
.Count() != 0);
1956 mpDev
->SetClipRegion(Region(aPoly
));
1960 void ScOutputData::FindChanged()
1965 bool bWasIdleEnabled
= mpDoc
->IsIdleEnabled();
1966 mpDoc
->EnableIdle(false);
1967 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1968 pRowInfo
[nArrY
].bChanged
= false;
1970 bool bProgress
= false;
1971 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1973 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1974 for (nX
=nX1
; nX
<=nX2
; nX
++)
1976 const ScRefCellValue
& rCell
= pThisRowInfo
->pCellInfo
[nX
+1].maCell
;
1978 if (rCell
.meType
!= CELLTYPE_FORMULA
)
1981 ScFormulaCell
* pFCell
= rCell
.mpFormula
;
1982 if ( !bProgress
&& pFCell
->GetDirty() )
1984 ScProgress::CreateInterpretProgress(mpDoc
, true);
1987 if (pFCell
->IsRunning())
1988 // still being interpreted. Skip it.
1991 (void)pFCell
->GetValue();
1992 if (!pFCell
->IsChanged())
1993 // the result hasn't changed. Skip it.
1996 pThisRowInfo
->bChanged
= true;
1997 if ( pThisRowInfo
->pCellInfo
[nX
+1].bMerged
)
1999 SCSIZE nOverY
= nArrY
+ 1;
2000 while ( nOverY
<nArrCount
&&
2001 pRowInfo
[nOverY
].pCellInfo
[nX
+1].bVOverlapped
)
2003 pRowInfo
[nOverY
].bChanged
= true;
2010 ScProgress::DeleteInterpretProgress();
2011 mpDoc
->EnableIdle(bWasIdleEnabled
);
2014 void ScOutputData::DrawRefMark( SCCOL nRefStartX
, SCROW nRefStartY
,
2015 SCCOL nRefEndX
, SCROW nRefEndY
,
2016 const Color
& rColor
, sal_Bool bHandle
)
2018 PutInOrder( nRefStartX
, nRefEndX
);
2019 PutInOrder( nRefStartY
, nRefEndY
);
2021 if ( nRefStartX
== nRefEndX
&& nRefStartY
== nRefEndY
)
2022 mpDoc
->ExtendMerge( nRefStartX
, nRefStartY
, nRefEndX
, nRefEndY
, nTab
);
2024 if ( nRefStartX
<= nVisX2
&& nRefEndX
>= nVisX1
&&
2025 nRefStartY
<= nVisY2
&& nRefEndY
>= nVisY1
)
2029 long nMaxX
= nScrX
+ nScrW
- 1;
2030 long nMaxY
= nScrY
+ nScrH
- 1;
2037 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2039 sal_Bool bTop
= false;
2040 sal_Bool bBottom
= false;
2041 sal_Bool bLeft
= false;
2042 sal_Bool bRight
= false;
2045 bool bNoStartY
= ( nY1
< nRefStartY
);
2046 bool bNoEndY
= false;
2047 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++) // loop to end for bNoEndY check
2049 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2051 if ( nY
==nRefStartY
|| (nY
>nRefStartY
&& bNoStartY
) )
2058 nMaxY
= nPosY
+ pRowInfo
[nArrY
].nHeight
- 2;
2061 if ( nY
>nRefEndY
&& bNoEndY
)
2066 bNoStartY
= ( nY
< nRefStartY
);
2067 bNoEndY
= ( nY
< nRefEndY
);
2068 nPosY
+= pRowInfo
[nArrY
].nHeight
;
2073 nPosX
+= nMirrorW
- 1; // always in pixels
2075 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2077 if ( nX
==nRefStartX
)
2084 nMaxX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 2 ) * nLayoutSign
;
2087 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2090 if ( nMaxX
* nLayoutSign
>= nMinX
* nLayoutSign
&&
2093 mpDev
->SetLineColor( rColor
);
2094 if (bTop
&& bBottom
&& bLeft
&& bRight
)
2096 mpDev
->SetFillColor();
2097 mpDev
->DrawRect( Rectangle( nMinX
, nMinY
, nMaxX
, nMaxY
) );
2102 mpDev
->DrawLine( Point( nMinX
, nMinY
), Point( nMaxX
, nMinY
) );
2104 mpDev
->DrawLine( Point( nMinX
, nMaxY
), Point( nMaxX
, nMaxY
) );
2106 mpDev
->DrawLine( Point( nMinX
, nMinY
), Point( nMinX
, nMaxY
) );
2108 mpDev
->DrawLine( Point( nMaxX
, nMinY
), Point( nMaxX
, nMaxY
) );
2110 if ( bHandle
&& bRight
&& bBottom
)
2112 mpDev
->SetLineColor( rColor
);
2113 mpDev
->SetFillColor( rColor
);
2115 const sal_Int32 aRadius
= 4;
2117 sal_Int32 aRectMaxX1
= nMaxX
- nLayoutSign
* aRadius
;
2118 sal_Int32 aRectMaxX2
= nMaxX
+ nLayoutSign
;
2119 sal_Int32 aRectMinX1
= nMinX
- nLayoutSign
;
2120 sal_Int32 aRectMinX2
= nMinX
+ nLayoutSign
* aRadius
;
2122 sal_Int32 aRectMaxY1
= nMaxY
- aRadius
;
2123 sal_Int32 aRectMaxY2
= nMaxY
+ 1;
2124 sal_Int32 aRectMinY1
= nMinY
- 1;
2125 sal_Int32 aRectMinY2
= nMinY
+ aRadius
;
2127 // Draw corner rectangles
2128 Rectangle
aLowerRight( aRectMaxX1
, aRectMaxY1
, aRectMaxX2
, aRectMaxY2
);
2129 Rectangle
aUpperLeft ( aRectMinX1
, aRectMinY1
, aRectMinX2
, aRectMinY2
);
2130 Rectangle
aLowerLeft ( aRectMinX1
, aRectMaxY1
, aRectMinX2
, aRectMaxY2
);
2131 Rectangle
aUpperRight( aRectMaxX1
, aRectMinY1
, aRectMaxX2
, aRectMinY2
);
2133 mpDev
->DrawTransparent( PolyPolygon( Polygon( aLowerRight
) ), lclCornerRectTransparency
);
2134 mpDev
->DrawTransparent( PolyPolygon( Polygon( aUpperLeft
) ), lclCornerRectTransparency
);
2135 mpDev
->DrawTransparent( PolyPolygon( Polygon( aLowerLeft
) ), lclCornerRectTransparency
);
2136 mpDev
->DrawTransparent( PolyPolygon( Polygon( aUpperRight
) ), lclCornerRectTransparency
);
2142 void ScOutputData::DrawOneChange( SCCOL nRefStartX
, SCROW nRefStartY
,
2143 SCCOL nRefEndX
, SCROW nRefEndY
,
2144 const Color
& rColor
, sal_uInt16 nType
)
2146 PutInOrder( nRefStartX
, nRefEndX
);
2147 PutInOrder( nRefStartY
, nRefEndY
);
2149 if ( nRefStartX
== nRefEndX
&& nRefStartY
== nRefEndY
)
2150 mpDoc
->ExtendMerge( nRefStartX
, nRefStartY
, nRefEndX
, nRefEndY
, nTab
);
2152 if ( nRefStartX
<= nVisX2
+ 1 && nRefEndX
>= nVisX1
&&
2153 nRefStartY
<= nVisY2
+ 1 && nRefEndY
>= nVisY1
) // +1 because it touches next cells left/top
2157 long nMaxX
= nScrX
+nScrW
-1;
2158 long nMaxY
= nScrY
+nScrH
-1;
2165 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2167 sal_Bool bTop
= false;
2168 sal_Bool bBottom
= false;
2169 sal_Bool bLeft
= false;
2170 sal_Bool bRight
= false;
2173 bool bNoStartY
= ( nY1
< nRefStartY
);
2174 bool bNoEndY
= false;
2175 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++) // loop to end for bNoEndY check
2177 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2179 if ( nY
==nRefStartY
|| (nY
>nRefStartY
&& bNoStartY
) )
2186 nMaxY
= nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
2189 if ( nY
>nRefEndY
&& bNoEndY
)
2194 bNoStartY
= ( nY
< nRefStartY
);
2195 bNoEndY
= ( nY
< nRefEndY
);
2196 nPosY
+= pRowInfo
[nArrY
].nHeight
;
2201 nPosX
+= nMirrorW
- 1; // always in pixels
2203 for (SCCOL nX
=nX1
; nX
<=nX2
+1; nX
++)
2205 if ( nX
==nRefStartX
)
2207 nMinX
= nPosX
- nLayoutSign
;
2212 nMaxX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 1 ) * nLayoutSign
;
2215 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2218 if ( nMaxX
* nLayoutSign
>= nMinX
* nLayoutSign
&&
2221 if ( nType
== SC_CAT_DELETE_ROWS
)
2222 bLeft
= bRight
= bBottom
= false; //! dicke Linie ???
2223 else if ( nType
== SC_CAT_DELETE_COLS
)
2224 bTop
= bBottom
= bRight
= false; //! dicke Linie ???
2226 mpDev
->SetLineColor( rColor
);
2227 if (bTop
&& bBottom
&& bLeft
&& bRight
)
2229 mpDev
->SetFillColor();
2230 mpDev
->DrawRect( Rectangle( nMinX
, nMinY
, nMaxX
, nMaxY
) );
2236 mpDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMaxX
,nMinY
) );
2237 if ( nType
== SC_CAT_DELETE_ROWS
)
2238 mpDev
->DrawLine( Point( nMinX
,nMinY
+1 ), Point( nMaxX
,nMinY
+1 ) );
2241 mpDev
->DrawLine( Point( nMinX
,nMaxY
), Point( nMaxX
,nMaxY
) );
2244 mpDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMinX
,nMaxY
) );
2245 if ( nType
== SC_CAT_DELETE_COLS
)
2246 mpDev
->DrawLine( Point( nMinX
+nLayoutSign
,nMinY
), Point( nMinX
+nLayoutSign
,nMaxY
) );
2249 mpDev
->DrawLine( Point( nMaxX
,nMinY
), Point( nMaxX
,nMaxY
) );
2251 if ( bLeft
&& bTop
)
2253 mpDev
->SetLineColor();
2254 mpDev
->SetFillColor( rColor
);
2255 mpDev
->DrawRect( Rectangle( nMinX
+nLayoutSign
, nMinY
+1, nMinX
+3*nLayoutSign
, nMinY
+3 ) );
2261 void ScOutputData::DrawChangeTrack()
2263 ScChangeTrack
* pTrack
= mpDoc
->GetChangeTrack();
2264 ScChangeViewSettings
* pSettings
= mpDoc
->GetChangeViewSettings();
2265 if ( !pTrack
|| !pTrack
->GetFirst() || !pSettings
|| !pSettings
->ShowChanges() )
2266 return; // nix da oder abgeschaltet
2268 ScActionColorChanger
aColorChanger(*pTrack
);
2270 // Clipping passiert von aussen
2271 //! ohne Clipping, nur betroffene Zeilen painten ??!??!?
2275 if ( nEndX
< MAXCOL
) ++nEndX
; // auch noch von der naechsten Zelle, weil die Markierung
2276 if ( nEndY
< MAXROW
) ++nEndY
; // in die jeweils vorhergehende Zelle hineinragt
2277 ScRange
aViewRange( nX1
, nY1
, nTab
, nEndX
, nEndY
, nTab
);
2278 const ScChangeAction
* pAction
= pTrack
->GetFirst();
2281 ScChangeActionType eActionType
;
2282 if ( pAction
->IsVisible() )
2284 eActionType
= pAction
->GetType();
2285 const ScBigRange
& rBig
= pAction
->GetBigRange();
2286 if ( rBig
.aStart
.Tab() == nTab
)
2288 ScRange aRange
= rBig
.MakeRange();
2290 if ( eActionType
== SC_CAT_DELETE_ROWS
)
2291 aRange
.aEnd
.SetRow( aRange
.aStart
.Row() );
2292 else if ( eActionType
== SC_CAT_DELETE_COLS
)
2293 aRange
.aEnd
.SetCol( aRange
.aStart
.Col() );
2295 if ( aRange
.Intersects( aViewRange
) &&
2296 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *mpDoc
) )
2298 aColorChanger
.Update( *pAction
);
2299 Color
aColor( aColorChanger
.GetColor() );
2300 DrawOneChange( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2301 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aColor
, sal::static_int_cast
<sal_uInt16
>(eActionType
) );
2305 if ( eActionType
== SC_CAT_MOVE
&&
2306 ((const ScChangeActionMove
*)pAction
)->
2307 GetFromRange().aStart
.Tab() == nTab
)
2309 ScRange aRange
= ((const ScChangeActionMove
*)pAction
)->
2310 GetFromRange().MakeRange();
2311 if ( aRange
.Intersects( aViewRange
) &&
2312 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *mpDoc
) )
2314 aColorChanger
.Update( *pAction
);
2315 Color
aColor( aColorChanger
.GetColor() );
2316 DrawOneChange( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2317 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aColor
, sal::static_int_cast
<sal_uInt16
>(eActionType
) );
2322 pAction
= pAction
->GetNext();
2326 //TODO: moggi Need to check if this can't be written simpler
2327 void ScOutputData::DrawNoteMarks()
2332 long nInitPosX
= nScrX
;
2334 nInitPosX
+= nMirrorW
- 1; // always in pixels
2335 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2338 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2340 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2341 if ( pThisRowInfo
->bChanged
)
2343 long nPosX
= nInitPosX
;
2344 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2346 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2347 bool bIsMerged
= false;
2349 if ( nX
==nX1
&& pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
2351 // find start of merged cell
2353 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2356 mpDoc
->ExtendOverlapped( nMergeX
, nMergeY
, nX
, nY
, nTab
);
2357 // use origin's pCell for NotePtr test below
2360 if ( mpDoc
->GetNote(nX
, pRowInfo
[nArrY
].nRowNo
, nTab
) && ( bIsMerged
||
2361 ( !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
) ) )
2365 mpDev
->SetLineColor();
2367 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2368 if ( mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode() )
2369 mpDev
->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
2371 mpDev
->SetFillColor(COL_LIGHTRED
);
2376 long nMarkX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 4 ) * nLayoutSign
;
2377 if ( bIsMerged
|| pInfo
->bMerged
)
2379 // if merged, add widths of all cells
2380 SCCOL nNextX
= nX
+ 1;
2381 while ( nNextX
<= nX2
+ 1 && pThisRowInfo
->pCellInfo
[nNextX
+1].bHOverlapped
)
2383 nMarkX
+= pRowInfo
[0].pCellInfo
[nNextX
+1].nWidth
* nLayoutSign
;
2387 if ( bLayoutRTL
? ( nMarkX
>= 0 ) : ( nMarkX
< nScrX
+nScrW
) )
2388 mpDev
->DrawRect( Rectangle( nMarkX
,nPosY
,nMarkX
+2*nLayoutSign
,nPosY
+2 ) );
2391 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2394 nPosY
+= pThisRowInfo
->nHeight
;
2398 void ScOutputData::AddPDFNotes()
2400 vcl::PDFExtOutDevData
* pPDFData
= PTR_CAST( vcl::PDFExtOutDevData
, mpDev
->GetExtOutDevData() );
2401 if ( !pPDFData
|| !pPDFData
->GetIsExportNotes() )
2404 long nInitPosX
= nScrX
;
2407 Size aOnePixel
= mpDev
->PixelToLogic(Size(1,1));
2408 long nOneX
= aOnePixel
.Width();
2409 nInitPosX
+= nMirrorW
- nOneX
;
2411 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2414 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2416 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2417 if ( pThisRowInfo
->bChanged
)
2419 long nPosX
= nInitPosX
;
2420 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2422 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2423 bool bIsMerged
= false;
2424 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2428 if ( nX
==nX1
&& pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
2430 // find start of merged cell
2432 mpDoc
->ExtendOverlapped( nMergeX
, nMergeY
, nX
, nY
, nTab
);
2433 // use origin's pCell for NotePtr test below
2436 if ( mpDoc
->GetNote(nMergeX
, nMergeY
, nTab
) && ( bIsMerged
||
2437 ( !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
) ) )
2439 long nNoteWidth
= (long)( SC_CLIPMARK_SIZE
* mnPPTX
);
2440 long nNoteHeight
= (long)( SC_CLIPMARK_SIZE
* mnPPTY
);
2442 long nMarkX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- nNoteWidth
) * nLayoutSign
;
2443 if ( bIsMerged
|| pInfo
->bMerged
)
2445 // if merged, add widths of all cells
2446 SCCOL nNextX
= nX
+ 1;
2447 while ( nNextX
<= nX2
+ 1 && pThisRowInfo
->pCellInfo
[nNextX
+1].bHOverlapped
)
2449 nMarkX
+= pRowInfo
[0].pCellInfo
[nNextX
+1].nWidth
* nLayoutSign
;
2453 if ( bLayoutRTL
? ( nMarkX
>= 0 ) : ( nMarkX
< nScrX
+nScrW
) )
2455 Rectangle
aNoteRect( nMarkX
, nPosY
, nMarkX
+nNoteWidth
*nLayoutSign
, nPosY
+nNoteHeight
);
2456 const ScPostIt
* pNote
= mpDoc
->GetNote(nMergeX
, nMergeY
, nTab
);
2458 // Note title is the cell address (as on printed note pages)
2459 ScAddress
aAddress( nMergeX
, nMergeY
, nTab
);
2460 OUString
aTitle(aAddress
.Format(SCA_VALID
, mpDoc
, mpDoc
->GetAddressConvention()));
2462 // Content has to be a simple string without line breaks
2463 OUString aContent
= pNote
->GetText();
2464 aContent
= aContent
.replaceAll("\n", " ");
2467 aNote
.Title
= aTitle
;
2468 aNote
.Contents
= aContent
;
2469 pPDFData
->CreateNote( aNoteRect
, aNote
);
2473 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2476 nPosY
+= pThisRowInfo
->nHeight
;
2480 void ScOutputData::DrawClipMarks()
2485 Color
aArrowFillCol( COL_LIGHTRED
);
2487 sal_uLong nOldDrawMode
= mpDev
->GetDrawMode();
2488 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2489 if ( mbUseStyleColor
&& rStyleSettings
.GetHighContrastMode() )
2491 // use DrawMode to change the arrow's outline color
2492 mpDev
->SetDrawMode( nOldDrawMode
| DRAWMODE_SETTINGSLINE
);
2493 // use text color also for the fill color
2494 aArrowFillCol
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
2497 long nInitPosX
= nScrX
;
2499 nInitPosX
+= nMirrorW
- 1; // always in pixels
2500 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2502 Rectangle aCellRect
;
2504 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2506 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2507 if ( pThisRowInfo
->bChanged
)
2509 SCROW nY
= pThisRowInfo
->nRowNo
;
2510 long nPosX
= nInitPosX
;
2511 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2513 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2514 if (pInfo
->nClipMark
)
2516 if (pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
2518 // merge origin may be outside of visible area - use document functions
2522 long nStartPosX
= nPosX
;
2523 long nStartPosY
= nPosY
;
2525 while ( nOverX
> 0 && ( ((const ScMergeFlagAttr
*)mpDoc
->GetAttr(
2526 nOverX
, nOverY
, nTab
, ATTR_MERGE_FLAG
))->GetValue() & SC_MF_HOR
) )
2529 nStartPosX
-= nLayoutSign
* (long) ( mpDoc
->GetColWidth(nOverX
,nTab
) * mnPPTX
);
2532 while ( nOverY
> 0 && ( ((const ScMergeFlagAttr
*)mpDoc
->GetAttr(
2533 nOverX
, nOverY
, nTab
, ATTR_MERGE_FLAG
))->GetValue() & SC_MF_VER
) )
2536 nStartPosY
-= nLayoutSign
* (long) ( mpDoc
->GetRowHeight(nOverY
,nTab
) * mnPPTY
);
2539 long nOutWidth
= (long) ( mpDoc
->GetColWidth(nOverX
,nTab
) * mnPPTX
);
2540 long nOutHeight
= (long) ( mpDoc
->GetRowHeight(nOverY
,nTab
) * mnPPTY
);
2542 const ScMergeAttr
* pMerge
= (const ScMergeAttr
*)
2543 mpDoc
->GetAttr( nOverX
, nOverY
, nTab
, ATTR_MERGE
);
2544 SCCOL nCountX
= pMerge
->GetColMerge();
2545 for (SCCOL i
=1; i
<nCountX
; i
++)
2546 nOutWidth
+= (long) ( mpDoc
->GetColWidth(nOverX
+i
,nTab
) * mnPPTX
);
2547 SCROW nCountY
= pMerge
->GetRowMerge();
2548 nOutHeight
+= (long) mpDoc
->GetScaledRowHeight( nOverY
+1, nOverY
+nCountY
-1, nTab
, mnPPTY
);
2551 nStartPosX
-= nOutWidth
- 1;
2552 aCellRect
= Rectangle( Point( nStartPosX
, nStartPosY
), Size( nOutWidth
, nOutHeight
) );
2556 long nOutWidth
= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
2557 long nOutHeight
= pThisRowInfo
->nHeight
;
2559 if ( pInfo
->bMerged
&& pInfo
->pPatternAttr
)
2563 const ScMergeAttr
* pMerge
=
2564 (ScMergeAttr
*)&pInfo
->pPatternAttr
->GetItem(ATTR_MERGE
);
2565 SCCOL nCountX
= pMerge
->GetColMerge();
2566 for (SCCOL i
=1; i
<nCountX
; i
++)
2567 nOutWidth
+= (long) ( mpDoc
->GetColWidth(nOverX
+i
,nTab
) * mnPPTX
);
2568 SCROW nCountY
= pMerge
->GetRowMerge();
2569 nOutHeight
+= (long) mpDoc
->GetScaledRowHeight( nOverY
+1, nOverY
+nCountY
-1, nTab
, mnPPTY
);
2572 long nStartPosX
= nPosX
;
2574 nStartPosX
-= nOutWidth
- 1;
2575 // #i80447# create aCellRect from two points in case nOutWidth is 0
2576 aCellRect
= Rectangle( Point( nStartPosX
, nPosY
),
2577 Point( nStartPosX
+nOutWidth
-1, nPosY
+nOutHeight
-1 ) );
2580 aCellRect
.Bottom() -= 1; // don't paint over the cell grid
2582 aCellRect
.Left() += 1;
2584 aCellRect
.Right() -= 1;
2586 long nMarkPixel
= (long)( SC_CLIPMARK_SIZE
* mnPPTX
);
2587 Size
aMarkSize( nMarkPixel
, (nMarkPixel
-1)*2 );
2589 if ( pInfo
->nClipMark
& ( bLayoutRTL
? SC_CLIPMARK_RIGHT
: SC_CLIPMARK_LEFT
) )
2592 Rectangle aMarkRect
= aCellRect
;
2593 aMarkRect
.Right() = aCellRect
.Left()+nMarkPixel
-1;
2594 SvxFont::DrawArrow( *mpDev
, aMarkRect
, aMarkSize
, aArrowFillCol
, true );
2596 if ( pInfo
->nClipMark
& ( bLayoutRTL
? SC_CLIPMARK_LEFT
: SC_CLIPMARK_RIGHT
) )
2599 Rectangle aMarkRect
= aCellRect
;
2600 aMarkRect
.Left() = aCellRect
.Right()-nMarkPixel
+1;
2601 SvxFont::DrawArrow( *mpDev
, aMarkRect
, aMarkSize
, aArrowFillCol
, false );
2604 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2607 nPosY
+= pThisRowInfo
->nHeight
;
2610 mpDev
->SetDrawMode(nOldDrawMode
);
2615 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */