1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: output.cxx,v $
10 * $Revision: 1.35.100.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include <com/sun/star/embed/EmbedMisc.hpp>
38 #include "scitems.hxx"
39 #include <svx/boxitem.hxx>
40 #include <svx/brshitem.hxx>
41 #include <svx/editdata.hxx>
42 #include <svtools/colorcfg.hxx>
43 #include <svx/rotmodit.hxx>
44 #include <svx/shaditem.hxx>
45 #include <svx/svxfont.hxx>
46 #include <svx/svdoole2.hxx>
47 #include <tools/poly.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/pdfextoutdevdata.hxx>
50 #include <svtools/accessibilityoptions.hxx>
51 #include <svx/framelinkarray.hxx>
54 #include "document.hxx"
57 #include "patattr.hxx"
58 #include "docpool.hxx"
59 #include "tabvwsh.hxx"
60 #include "progress.hxx"
61 #include "pagedata.hxx"
62 #include "chgtrack.hxx"
63 #include "chgviset.hxx"
64 #include "viewutil.hxx"
65 #include "gridmerg.hxx"
66 #include "invmerge.hxx"
67 #include "fillinfo.hxx"
69 #include "appoptio.hxx"
74 using namespace com::sun::star
;
76 // STATIC DATA -----------------------------------------------------------
78 // Farben fuer ChangeTracking "nach Autor" wie im Writer (swmodul1.cxx)
80 #define SC_AUTHORCOLORCOUNT 9
82 static 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
};
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 ScStrCollection
& rUsers
;
96 USHORT 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 ( rAction
.GetUser() != aLastUserName
)
145 aLastUserName
= rAction
.GetUser();
146 StrData
aData(aLastUserName
);
148 if (!rUsers
.Search(&aData
, nIndex
))
150 // empty string is possible if a name wasn't found while saving a 5.0 file
151 DBG_ASSERT( aLastUserName
.Len() == 0, "Author not found" );
154 nLastUserIndex
= nIndex
% SC_AUTHORCOLORCOUNT
;
156 nColor
= nAuthorColor
[nLastUserIndex
];
160 //==================================================================
162 ScOutputData::ScOutputData( OutputDevice
* pNewDev
, ScOutputType eNewType
,
163 ScTableInfo
& rTabInfo
, ScDocument
* pNewDoc
,
164 SCTAB nNewTab
, long nNewScrX
, long nNewScrY
,
165 SCCOL nNewX1
, SCROW nNewY1
, SCCOL nNewX2
, SCROW nNewY2
,
166 double nPixelPerTwipsX
, double nPixelPerTwipsY
,
167 const Fraction
* pZoomX
, const Fraction
* pZoomY
) :
169 pRefDevice( pNewDev
), // default is output device
170 pFmtDevice( pNewDev
), // default is output device
171 mrTabInfo( rTabInfo
),
172 pRowInfo( rTabInfo
.mpRowInfo
),
173 nArrCount( rTabInfo
.mnArrCount
),
183 nPPTX( nPixelPerTwipsX
),
184 nPPTY( nPixelPerTwipsY
),
187 pDrawView( NULL
), // #114135#
190 bSingleGrid( FALSE
),
191 bPagebreakMode( FALSE
),
192 bSolidBackground( FALSE
),
193 bUseStyleColor( FALSE
),
194 bForceAutoColor( SC_MOD()->GetAccessOptions().GetIsAutomaticFontColor() ),
195 bSyntaxMode( FALSE
),
198 pFormulaColor( NULL
),
199 aGridColor( COL_BLACK
),
200 bShowNullValues( TRUE
),
201 bShowFormulas( FALSE
),
202 bShowSpellErrors( FALSE
),
203 bMarkClipped( FALSE
), // FALSE fuer Drucker/Metafile etc.
205 bAnyRotated( FALSE
),
206 bAnyClipped( FALSE
),
207 mpTargetPaintWindow(0) // #i74769# use SdrPaintWindow direct
212 aZoomX
= Fraction(1,1);
216 aZoomY
= Fraction(1,1);
222 pDoc
->StripHidden( nVisX1
, nVisY1
, nVisX2
, nVisY2
, nTab
);
225 for (SCCOL nX
=nVisX1
; nX
<=nVisX2
; nX
++)
226 nScrW
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
231 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
232 nScrH
+= pRowInfo
[nArrY
].nHeight
;
234 bTabProtected
= pDoc
->IsTabProtected( nTab
);
235 nTabTextDirection
= pDoc
->GetEditTextDirection( nTab
);
236 bLayoutRTL
= pDoc
->IsLayoutRTL( nTab
);
239 ScOutputData::~ScOutputData()
243 delete pFormulaColor
;
246 void ScOutputData::SetContentDevice( OutputDevice
* pContentDev
)
248 // use pContentDev instead of pDev where used
250 if ( pRefDevice
== pDev
)
251 pRefDevice
= pContentDev
;
252 if ( pFmtDevice
== pDev
)
253 pFmtDevice
= pContentDev
;
257 void ScOutputData::SetMirrorWidth( long nNew
)
262 void ScOutputData::SetGridColor( const Color
& rColor
)
267 void ScOutputData::SetMarkClipped( BOOL bSet
)
272 void ScOutputData::SetShowNullValues( BOOL bSet
)
274 bShowNullValues
= bSet
;
277 void ScOutputData::SetShowFormulas( BOOL bSet
)
279 bShowFormulas
= bSet
;
282 void ScOutputData::SetShowSpellErrors( BOOL bSet
)
284 bShowSpellErrors
= bSet
;
287 void ScOutputData::SetSnapPixel( BOOL bSet
)
292 void ScOutputData::SetEditCell( SCCOL nCol
, SCROW nRow
)
299 void ScOutputData::SetMetaFileMode( BOOL bNewMode
)
301 bMetaFile
= bNewMode
;
304 void ScOutputData::SetSingleGrid( BOOL bNewMode
)
306 bSingleGrid
= bNewMode
;
309 void ScOutputData::SetSyntaxMode( BOOL bNewMode
)
311 bSyntaxMode
= bNewMode
;
315 pValueColor
= new Color( COL_LIGHTBLUE
);
316 pTextColor
= new Color( COL_BLACK
);
317 pFormulaColor
= new Color( COL_GREEN
);
321 void ScOutputData::DrawGrid( BOOL bGrid
, BOOL bPage
)
328 ScBreakType nBreak
= BREAK_NONE
;
329 ScBreakType nBreakOld
= BREAK_NONE
;
336 bPage
= FALSE
; // keine "normalen" Umbrueche ueber volle Breite/Hoehe
338 //! um den einen Pixel sieht das Metafile (oder die Druck-Ausgabe) anders aus
339 //! als die Bildschirmdarstellung, aber wenigstens passen Druck und Metafile zusammen
341 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
342 long nOneX
= aOnePixel
.Width();
343 long nOneY
= aOnePixel
.Height();
347 long nLayoutSign
= bLayoutRTL
? -1 : 1;
348 long nSignedOneX
= nOneX
* nLayoutSign
;
350 if ( eType
== OUTTYPE_WINDOW
)
352 const svtools::ColorConfig
& rColorCfg
= SC_MOD()->GetColorConfig();
353 aPageColor
.SetColor( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC
).nColor
);
354 aManualColor
.SetColor( rColorCfg
.GetColorValue(svtools::CALCPAGEBREAKMANUAL
).nColor
);
358 aPageColor
= aGridColor
;
359 aManualColor
= aGridColor
;
362 pDev
->SetLineColor( aGridColor
);
363 ScGridMerger
aGrid( pDev
, nOneX
, nOneY
);
371 nPosX
+= nMirrorW
- nOneX
;
373 for (nX
=nX1
; nX
<=nX2
; nX
++)
375 SCCOL nXplus1
= nX
+1;
376 SCCOL nXplus2
= nX
+2;
377 USHORT nWidth
= pRowInfo
[0].pCellInfo
[nXplus1
].nWidth
;
380 nPosX
+= nWidth
* nLayoutSign
;
384 // Seitenumbrueche auch in ausgeblendeten suchen
385 SCCOL nCol
= nXplus1
;
386 while (nCol
<= MAXCOL
)
388 BYTE nDocFl
= pDoc
->GetColFlags( nCol
, nTab
);
389 nBreak
= pDoc
->HasColBreak(nCol
, nTab
);
390 bool bHidden
= pDoc
->ColHidden(nCol
, nTab
);
392 if ( nBreak
|| !bHidden
)
397 if (nBreak
!= nBreakOld
)
400 pDev
->SetLineColor( (nBreak
& BREAK_MANUAL
) ? aManualColor
:
401 nBreak
? aPageColor
: aGridColor
);
406 BOOL bDraw
= bGrid
|| nBreakOld
; // einfaches Gitter nur wenn eingestellt
408 //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
409 //! Umbruch mitten in den Wiederholungsspalten liegt.
410 //! Dann lieber den aeusseren Rahmen zweimal ausgeben...
412 // auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
413 if ( eType
== OUTTYPE_PRINTER
&& !bMetaFile
)
417 else if (pDoc
->HasColBreak(nXplus1
, nTab
))
422 USHORT nWidthXplus2
= pRowInfo
[0].pCellInfo
[nXplus2
].nWidth
;
423 bSingle
= bSingleGrid
; //! in Fillinfo holen !!!!!
424 if ( nX
<MAXCOL
&& !bSingle
)
426 bSingle
= ( nWidthXplus2
== 0 );
427 for (nArrY
=1; nArrY
+1<nArrCount
&& !bSingle
; nArrY
++)
429 if (pRowInfo
[nArrY
].pCellInfo
[nXplus2
].bHOverlapped
)
431 if (pRowInfo
[nArrY
].pCellInfo
[nXplus1
].bHideGrid
)
438 if ( nX
<MAXCOL
&& bSingle
)
440 SCCOL nVisX
= nXplus1
;
441 while ( nVisX
< MAXCOL
&& !pDoc
->GetColWidth(nVisX
,nTab
) )
446 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
448 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
449 nNextY
= nPosY
+ pThisRowInfo
->nHeight
;
451 BOOL bHOver
= pThisRowInfo
->pCellInfo
[nXplus1
].bHideGrid
;
455 bHOver
= pThisRowInfo
->pCellInfo
[nXplus2
].bHOverlapped
;
459 bHOver
= pThisRowInfo
->pCellInfo
[nVisX
+1].bHOverlapped
;
461 bHOver
= ((ScMergeFlagAttr
*)pDoc
->GetAttr(
462 nVisX
,pThisRowInfo
->nRowNo
,nTab
,ATTR_MERGE_FLAG
))
465 bHOver
= ((ScMergeFlagAttr
*)pDoc
->GetAttr(
466 nXplus1
,pThisRowInfo
->nRowNo
,nTab
,ATTR_MERGE_FLAG
))
471 if (pThisRowInfo
->bChanged
&& !bHOver
)
473 //Point aStart( nPosX-nSignedOneX, nPosY );
474 //Point aEnd( nPosX-nSignedOneX, nNextY-nOneY );
475 //pDev->DrawLine( aStart, aEnd );
476 aGrid
.AddVerLine( nPosX
-nSignedOneX
, nPosY
, nNextY
-nOneY
);
483 //Point aStart( nPosX-nSignedOneX, nScrY );
484 //Point aEnd( nPosX-nSignedOneX, nScrY+nScrH-nOneY );
485 //pDev->DrawLine( aStart, aEnd );
486 aGrid
.AddVerLine( nPosX
-nSignedOneX
, nScrY
, nScrY
+nScrH
-nOneY
);
493 // Horizontale Linien
497 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
499 SCSIZE nArrYplus1
= nArrY
+1;
500 nY
= pRowInfo
[nArrY
].nRowNo
;
501 SCROW nYplus1
= nY
+1;
502 nPosY
+= pRowInfo
[nArrY
].nHeight
;
504 if (pRowInfo
[nArrY
].bChanged
)
508 for (SCROW i
= nYplus1
; i
<= MAXROW
; ++i
)
510 nBreak
= pDoc
->HasRowBreak(i
, nTab
);
511 bool bHidden
= pDoc
->RowHidden(i
, nTab
);
512 if (nBreak
|| !bHidden
)
516 if (nBreakOld
!= nBreak
)
519 pDev
->SetLineColor( (nBreak
& BREAK_MANUAL
) ? aManualColor
:
520 (nBreak
) ? aPageColor
: aGridColor
);
525 BOOL bDraw
= bGrid
|| nBreakOld
; // einfaches Gitter nur wenn eingestellt
527 //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
528 //! Umbruch mitten in den Wiederholungszeilen liegt.
529 //! Dann lieber den aeusseren Rahmen zweimal ausgeben...
531 // auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
532 if ( eType
== OUTTYPE_PRINTER
&& !bMetaFile
)
536 else if (pDoc
->HasRowBreak(nYplus1
, nTab
))
541 BOOL bNextYisNextRow
= (pRowInfo
[nArrYplus1
].nRowNo
== nYplus1
);
542 bSingle
= !bNextYisNextRow
; // Hidden
543 for (SCCOL i
=nX1
; i
<=nX2
&& !bSingle
; i
++)
545 if (pRowInfo
[nArrYplus1
].pCellInfo
[i
+1].bVOverlapped
)
551 if ( bSingle
&& nY
<MAXROW
)
553 SCROW nVisY
= pRowInfo
[nArrYplus1
].nRowNo
;
557 nPosX
+= nMirrorW
- nOneX
;
560 for (SCCOL i
=nX1
; i
<=nX2
; i
++)
562 nNextX
= nPosX
+ pRowInfo
[0].pCellInfo
[i
+1].nWidth
* nLayoutSign
;
563 if (nNextX
!= nPosX
) // sichtbar
566 if ( bNextYisNextRow
)
567 bVOver
= pRowInfo
[nArrYplus1
].pCellInfo
[i
+1].bVOverlapped
;
570 bVOver
= ((ScMergeFlagAttr
*)pDoc
->GetAttr(
571 i
,nYplus1
,nTab
,ATTR_MERGE_FLAG
))
573 && ((ScMergeFlagAttr
*)pDoc
->GetAttr(
574 i
,nVisY
,nTab
,ATTR_MERGE_FLAG
))
576 //! nVisY aus Array ??
580 //Point aStart( nPosX, nPosY-nOneY );
581 //Point aEnd( nNextX-nSignedOneX, nPosY-nOneY );
582 //pDev->DrawLine( aStart, aEnd );
583 aGrid
.AddHorLine( nPosX
, nNextX
-nSignedOneX
, nPosY
-nOneY
);
591 //Point aStart( nScrX, nPosY-nOneY );
592 //Point aEnd( nScrX+nScrW-nOneX, nPosY-nOneY );
593 //pDev->DrawLine( aStart, aEnd );
594 aGrid
.AddHorLine( nScrX
, nScrX
+nScrW
-nOneX
, nPosY
-nOneY
);
601 // ----------------------------------------------------------------------------
603 void ScOutputData::SetPagebreakMode( ScPageBreakData
* pPageData
)
605 bPagebreakMode
= TRUE
;
607 return; // noch nicht initialisiert -> alles "nicht gedruckt"
609 // gedruckten Bereich markieren
610 // (in FillInfo ist schon alles auf FALSE initialisiert)
612 USHORT nRangeCount
= sal::static_int_cast
<USHORT
>(pPageData
->GetCount());
613 for (USHORT nPos
=0; nPos
<nRangeCount
; nPos
++)
615 ScRange aRange
= pPageData
->GetData( nPos
).GetPrintRange();
617 SCCOL nStartX
= Max( aRange
.aStart
.Col(), nX1
);
618 SCCOL nEndX
= Min( aRange
.aEnd
.Col(), nX2
);
619 SCROW nStartY
= Max( aRange
.aStart
.Row(), nY1
);
620 SCROW nEndY
= Min( aRange
.aEnd
.Row(), nY2
);
622 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
624 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
625 if ( pThisRowInfo
->bChanged
&& pThisRowInfo
->nRowNo
>= nStartY
&&
626 pThisRowInfo
->nRowNo
<= nEndY
)
628 for (SCCOL nX
=nStartX
; nX
<=nEndX
; nX
++)
629 pThisRowInfo
->pCellInfo
[nX
+1].bPrinted
= TRUE
;
635 void ScOutputData::FindRotated()
637 //! nRotMax speichern
639 for (SCSIZE nRotY
=0; nRotY
<nArrCount
; nRotY
++)
640 if (pRowInfo
[nRotY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nRotY
].nRotMaxCol
> nRotMax
)
641 nRotMax
= pRowInfo
[nRotY
].nRotMaxCol
;
643 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++)
645 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
646 if ( pThisRowInfo
->nRotMaxCol
!= SC_ROTMAX_NONE
&&
647 ( pThisRowInfo
->bChanged
|| pRowInfo
[nArrY
-1].bChanged
||
648 ( nArrY
+1<nArrCount
&& pRowInfo
[nArrY
+1].bChanged
) ) )
650 SCROW nY
= pThisRowInfo
->nRowNo
;
652 for (SCCOL nX
=0; nX
<=nRotMax
; nX
++)
654 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
655 const ScPatternAttr
* pPattern
= pInfo
->pPatternAttr
;
656 const SfxItemSet
* pCondSet
= pInfo
->pConditionSet
;
658 if ( !pPattern
&& !pDoc
->ColHidden(nX
, nTab
) )
660 pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
661 pCondSet
= pDoc
->GetCondResult( nX
, nY
, nTab
);
664 if ( pPattern
) // Spalte nicht ausgeblendet
666 BYTE nDir
= pPattern
->GetRotateDir( pCondSet
);
667 if (nDir
!= SC_ROTDIR_NONE
)
669 pInfo
->nRotateDir
= nDir
;
678 // ----------------------------------------------------------------------------
680 USHORT
lcl_GetRotateDir( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
682 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
683 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
685 USHORT nRet
= SC_ROTDIR_NONE
;
687 long nAttrRotate
= pPattern
->GetRotateVal( pCondSet
);
690 SvxRotateMode eRotMode
= (SvxRotateMode
)((const SvxRotateModeItem
&)
691 pPattern
->GetItem(ATTR_ROTATE_MODE
, pCondSet
)).GetValue();
693 if ( eRotMode
== SVX_ROTATE_MODE_STANDARD
)
694 nRet
= SC_ROTDIR_STANDARD
;
695 else if ( eRotMode
== SVX_ROTATE_MODE_CENTER
)
696 nRet
= SC_ROTDIR_CENTER
;
697 else if ( eRotMode
== SVX_ROTATE_MODE_TOP
|| eRotMode
== SVX_ROTATE_MODE_BOTTOM
)
699 long nRot180
= nAttrRotate
% 18000; // 1/100 Grad
700 if ( nRot180
== 9000 )
701 nRet
= SC_ROTDIR_CENTER
;
702 else if ( ( eRotMode
== SVX_ROTATE_MODE_TOP
&& nRot180
< 9000 ) ||
703 ( eRotMode
== SVX_ROTATE_MODE_BOTTOM
&& nRot180
> 9000 ) )
704 nRet
= SC_ROTDIR_LEFT
;
706 nRet
= SC_ROTDIR_RIGHT
;
713 const SvxBrushItem
* lcl_FindBackground( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
715 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
716 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
717 const SvxBrushItem
* pBackground
= (const SvxBrushItem
*)
718 &pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
720 USHORT nDir
= lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
);
722 // CENTER wird wie RIGHT behandelt...
723 if ( nDir
== SC_ROTDIR_RIGHT
|| nDir
== SC_ROTDIR_CENTER
)
725 // Text geht nach rechts -> Hintergrund von links nehmen
726 while ( nCol
> 0 && lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
) == nDir
&&
727 pBackground
->GetColor().GetTransparency() != 255 )
730 pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
731 pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
732 pBackground
= (const SvxBrushItem
*)&pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
735 else if ( nDir
== SC_ROTDIR_LEFT
)
737 // Text geht nach links -> Hintergrund von rechts nehmen
738 while ( nCol
< MAXCOL
&& lcl_GetRotateDir( pDoc
, nCol
, nRow
, nTab
) == nDir
&&
739 pBackground
->GetColor().GetTransparency() != 255 )
742 pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
743 pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
744 pBackground
= (const SvxBrushItem
*)&pPattern
->GetItem( ATTR_BACKGROUND
, pCondSet
);
751 // ----------------------------------------------------------------------------
753 BOOL
lcl_EqualBack( const RowInfo
& rFirst
, const RowInfo
& rOther
,
754 SCCOL nX1
, SCCOL nX2
, BOOL bShowProt
, BOOL bPagebreakMode
)
756 if ( rFirst
.bChanged
!= rOther
.bChanged
||
757 rFirst
.bEmptyBack
!= rOther
.bEmptyBack
)
763 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
765 const ScPatternAttr
* pPat1
= rFirst
.pCellInfo
[nX
+1].pPatternAttr
;
766 const ScPatternAttr
* pPat2
= rOther
.pCellInfo
[nX
+1].pPatternAttr
;
767 if ( !pPat1
|| !pPat2
||
768 &pPat1
->GetItem(ATTR_PROTECTION
) != &pPat2
->GetItem(ATTR_PROTECTION
) )
774 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
775 if ( rFirst
.pCellInfo
[nX
+1].pBackground
!= rOther
.pCellInfo
[nX
+1].pBackground
)
779 if ( rFirst
.nRotMaxCol
!= SC_ROTMAX_NONE
|| rOther
.nRotMaxCol
!= SC_ROTMAX_NONE
)
780 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
781 if ( rFirst
.pCellInfo
[nX
+1].nRotateDir
!= rOther
.pCellInfo
[nX
+1].nRotateDir
)
784 if ( bPagebreakMode
)
785 for ( nX
=nX1
; nX
<=nX2
; nX
++ )
786 if ( rFirst
.pCellInfo
[nX
+1].bPrinted
!= rOther
.pCellInfo
[nX
+1].bPrinted
)
792 void ScOutputData::DrawDocumentBackground()
794 if ( !bSolidBackground
)
797 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
798 long nOneX
= aOnePixel
.Width();
799 long nOneY
= aOnePixel
.Height();
800 Rectangle
aRect(nScrX
- nOneX
, nScrY
- nOneY
, nScrX
+ nScrW
, nScrY
+ nScrH
);
801 Color
aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
);
802 pDev
->SetFillColor(aBgColor
);
803 pDev
->DrawRect(aRect
);
806 void ScOutputData::DrawBackground()
808 FindRotated(); //! von aussen ?
811 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
812 long nOneX
= aOnePixel
.Width();
813 long nOneY
= aOnePixel
.Height();
818 long nLayoutSign
= bLayoutRTL
? -1 : 1;
819 long nSignedOneX
= nOneX
* nLayoutSign
;
821 pDev
->SetLineColor();
823 BOOL bShowProt
= bSyntaxMode
&& pDoc
->IsTabProtected(nTab
);
824 BOOL bDoAll
= bShowProt
|| bPagebreakMode
|| bSolidBackground
;
826 // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
827 BOOL bCellContrast
= bUseStyleColor
&&
828 Application::GetSettings().GetStyleSettings().GetHighContrastMode();
831 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
833 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
834 long nRowHeight
= pThisRowInfo
->nHeight
;
836 if ( pThisRowInfo
->bChanged
)
838 if ( ( ( pThisRowInfo
->bEmptyBack
) || bSyntaxMode
) && !bDoAll
)
844 // scan for rows with the same background:
846 while ( nArrY
+nSkip
+2<nArrCount
&&
847 lcl_EqualBack( *pThisRowInfo
, pRowInfo
[nArrY
+nSkip
+1],
848 nX1
, nX2
, bShowProt
, bPagebreakMode
) )
851 nRowHeight
+= pRowInfo
[nArrY
+nSkip
].nHeight
; // after incrementing
856 nPosX
+= nMirrorW
- nOneX
;
857 aRect
= Rectangle( nPosX
, nPosY
-nOneY
, nPosX
, nPosY
+nRowHeight
-nOneY
);
859 const SvxBrushItem
* pOldBackground
= NULL
;
860 const SvxBrushItem
* pBackground
;
861 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
863 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
867 // high contrast for cell borders and backgrounds -> empty background
868 pBackground
= ScGlobal::GetEmptyBrushItem();
870 else if (bShowProt
) // show cell protection in syntax mode
872 const ScPatternAttr
* pP
= pInfo
->pPatternAttr
;
875 const ScProtectionAttr
& rProt
= (const ScProtectionAttr
&)
876 pP
->GetItem(ATTR_PROTECTION
);
877 if (rProt
.GetProtection() || rProt
.GetHideCell())
878 pBackground
= ScGlobal::GetProtectedBrushItem();
880 pBackground
= ScGlobal::GetEmptyBrushItem();
886 pBackground
= pInfo
->pBackground
;
888 if ( bPagebreakMode
&& !pInfo
->bPrinted
)
889 pBackground
= ScGlobal::GetProtectedBrushItem();
891 if ( pInfo
->nRotateDir
> SC_ROTDIR_STANDARD
&&
892 pBackground
->GetColor().GetTransparency() != 255 &&
895 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
896 pBackground
= lcl_FindBackground( pDoc
, nX
, nY
, nTab
);
899 if ( pBackground
!= pOldBackground
)
901 aRect
.Right() = nPosX
-nSignedOneX
;
902 if (pOldBackground
) // ==0 if hidden
904 Color aBackCol
= pOldBackground
->GetColor();
905 if ( !aBackCol
.GetTransparency() ) //! partial transparency?
907 pDev
->SetFillColor( aBackCol
);
908 pDev
->DrawRect( aRect
);
911 aRect
.Left() = nPosX
- nSignedOneX
;
912 pOldBackground
= pBackground
;
914 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
916 aRect
.Right() = nPosX
-nSignedOneX
;
919 Color aBackCol
= pOldBackground
->GetColor();
920 if ( !aBackCol
.GetTransparency() ) //! partial transparency?
922 pDev
->SetFillColor( aBackCol
);
923 pDev
->DrawRect( aRect
);
934 void ScOutputData::DrawShadow()
936 DrawExtraShadow( FALSE
, FALSE
, FALSE
, FALSE
);
939 void ScOutputData::DrawExtraShadow(BOOL bLeft
, BOOL bTop
, BOOL bRight
, BOOL bBottom
)
941 pDev
->SetLineColor();
943 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
944 // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
945 BOOL bCellContrast
= bUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
946 Color aAutoTextColor
;
948 aAutoTextColor
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
950 long nInitPosX
= nScrX
;
953 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
954 long nOneX
= aOnePixel
.Width();
955 nInitPosX
+= nMirrorW
- nOneX
;
957 long nLayoutSign
= bLayoutRTL
? -1 : 1;
959 long nPosY
= nScrY
- pRowInfo
[0].nHeight
;
960 for (SCSIZE nArrY
=0; nArrY
<nArrCount
; nArrY
++)
962 BOOL bCornerY
= ( nArrY
== 0 ) || ( nArrY
+1 == nArrCount
);
963 BOOL bSkipY
= ( nArrY
==0 && !bTop
) || ( nArrY
+1 == nArrCount
&& !bBottom
);
965 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
966 long nRowHeight
= pThisRowInfo
->nHeight
;
968 if ( pThisRowInfo
->bChanged
&& !bSkipY
)
970 long nPosX
= nInitPosX
- pRowInfo
[0].pCellInfo
[nX1
].nWidth
* nLayoutSign
;
971 for (SCCOL nArrX
=nX1
; nArrX
<=nX2
+2; nArrX
++)
973 BOOL bCornerX
= ( nArrX
==nX1
|| nArrX
==nX2
+2 );
974 BOOL bSkipX
= ( nArrX
==nX1
&& !bLeft
) || ( nArrX
==nX2
+2 && !bRight
);
976 for (USHORT nPass
=0; nPass
<2; nPass
++) // horizontal / vertikal
978 const SvxShadowItem
* pAttr
= nPass
?
979 pThisRowInfo
->pCellInfo
[nArrX
].pVShadowOrigin
:
980 pThisRowInfo
->pCellInfo
[nArrX
].pHShadowOrigin
;
981 if ( pAttr
&& !bSkipX
)
983 ScShadowPart ePart
= nPass
?
984 pThisRowInfo
->pCellInfo
[nArrX
].eVShadowPart
:
985 pThisRowInfo
->pCellInfo
[nArrX
].eHShadowPart
;
988 if ( (nPass
==0 && bCornerX
) || (nPass
==1 && bCornerY
) )
989 if ( ePart
!= SC_SHADOW_CORNER
)
994 long nThisWidth
= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
;
995 long nMaxWidth
= nThisWidth
;
998 //! direction must depend on shadow location
999 SCCOL nWx
= nArrX
; // nX+1
1000 while (nWx
<nX2
&& !pRowInfo
[0].pCellInfo
[nWx
+1].nWidth
)
1002 nMaxWidth
= pRowInfo
[0].pCellInfo
[nWx
+1].nWidth
;
1005 // Rectangle aRect( Point(nPosX,nPosY),
1006 // Size( pRowInfo[0].pCellInfo[nArrX].nWidth,
1007 // pRowInfo[nArrY].nHeight ) );
1009 // rectangle is in logical orientation
1010 Rectangle
aRect( nPosX
, nPosY
,
1011 nPosX
+ ( nThisWidth
- 1 ) * nLayoutSign
,
1012 nPosY
+ pRowInfo
[nArrY
].nHeight
- 1 );
1014 long nSize
= pAttr
->GetWidth();
1015 long nSizeX
= (long)(nSize
*nPPTX
);
1016 if (nSizeX
>= nMaxWidth
) nSizeX
= nMaxWidth
-1;
1017 long nSizeY
= (long)(nSize
*nPPTY
);
1018 if (nSizeY
>= nRowHeight
) nSizeY
= nRowHeight
-1;
1020 nSizeX
*= nLayoutSign
; // used only to add to rectangle values
1022 SvxShadowLocation eLoc
= pAttr
->GetLocation();
1025 // Shadow location is specified as "visual" (right is always right),
1026 // so the attribute's location value is mirrored here and in FillInfo.
1029 case SVX_SHADOW_BOTTOMRIGHT
: eLoc
= SVX_SHADOW_BOTTOMLEFT
; break;
1030 case SVX_SHADOW_BOTTOMLEFT
: eLoc
= SVX_SHADOW_BOTTOMRIGHT
; break;
1031 case SVX_SHADOW_TOPRIGHT
: eLoc
= SVX_SHADOW_TOPLEFT
; break;
1032 case SVX_SHADOW_TOPLEFT
: eLoc
= SVX_SHADOW_TOPRIGHT
; break;
1035 // added to avoid warnings
1040 if (ePart
== SC_SHADOW_HORIZ
|| ePart
== SC_SHADOW_HSTART
||
1041 ePart
== SC_SHADOW_CORNER
)
1043 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_TOPRIGHT
)
1044 aRect
.Top() = aRect
.Bottom() - nSizeY
;
1046 aRect
.Bottom() = aRect
.Top() + nSizeY
;
1048 if (ePart
== SC_SHADOW_VERT
|| ePart
== SC_SHADOW_VSTART
||
1049 ePart
== SC_SHADOW_CORNER
)
1051 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_BOTTOMLEFT
)
1052 aRect
.Left() = aRect
.Right() - nSizeX
;
1054 aRect
.Right() = aRect
.Left() + nSizeX
;
1056 if (ePart
== SC_SHADOW_HSTART
)
1058 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_BOTTOMLEFT
)
1059 aRect
.Right() -= nSizeX
;
1061 aRect
.Left() += nSizeX
;
1063 if (ePart
== SC_SHADOW_VSTART
)
1065 if (eLoc
== SVX_SHADOW_TOPLEFT
|| eLoc
== SVX_SHADOW_TOPRIGHT
)
1066 aRect
.Bottom() -= nSizeY
;
1068 aRect
.Top() += nSizeY
;
1071 //! merge rectangles?
1072 pDev
->SetFillColor( bCellContrast
? aAutoTextColor
: pAttr
->GetColor() );
1073 pDev
->DrawRect( aRect
);
1078 nPosX
+= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
* nLayoutSign
;
1081 nPosY
+= nRowHeight
;
1089 void ScOutputData::DrawClear()
1092 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
1093 long nOneX
= aOnePixel
.Width();
1094 long nOneY
= aOnePixel
.Height();
1096 // (called only for ScGridWindow)
1097 Color
aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR
).nColor
);
1102 pDev
->SetLineColor();
1104 pDev
->SetFillColor( aBgColor
);
1107 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1109 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1110 long nRowHeight
= pThisRowInfo
->nHeight
;
1112 if ( pThisRowInfo
->bChanged
)
1114 // scan for more rows which must be painted:
1116 while ( nArrY
+nSkip
+2<nArrCount
&& pRowInfo
[nArrY
+nSkip
+1].bChanged
)
1119 nRowHeight
+= pRowInfo
[nArrY
+nSkip
].nHeight
; // after incrementing
1122 aRect
= Rectangle( Point( nScrX
, nPosY
),
1123 Size( nScrW
+1-nOneX
, nRowHeight
+1-nOneY
) );
1124 pDev
->DrawRect( aRect
);
1128 nPosY
+= nRowHeight
;
1137 long lclGetSnappedX( OutputDevice
& rDev
, long nPosX
, bool bSnapPixel
)
1139 return (bSnapPixel
&& nPosX
) ? rDev
.PixelToLogic( rDev
.LogicToPixel( Size( nPosX
, 0 ) ) ).Width() : nPosX
;
1142 long lclGetSnappedY( OutputDevice
& rDev
, long nPosY
, bool bSnapPixel
)
1144 return (bSnapPixel
&& nPosY
) ? rDev
.PixelToLogic( rDev
.LogicToPixel( Size( 0, nPosY
) ) ).Height() : nPosY
;
1147 size_t lclGetArrayColFromCellInfoX( USHORT nCellInfoX
, USHORT nCellInfoFirstX
, USHORT nCellInfoLastX
, bool bRTL
)
1149 return static_cast< size_t >( bRTL
? (nCellInfoLastX
+ 2 - nCellInfoX
) : (nCellInfoX
- nCellInfoFirstX
) );
1152 void ScOutputData::DrawFrame()
1154 ULONG nOldDrawMode
= pDev
->GetDrawMode();
1157 BOOL bUseSingleColor
= FALSE
;
1158 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1159 // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
1160 BOOL bCellContrast
= bUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1162 // #107519# if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
1163 // for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
1164 // that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
1165 // must be reset and the border colors handled here.
1167 if ( ( nOldDrawMode
& DRAWMODE_WHITEFILL
) && ( nOldDrawMode
& DRAWMODE_BLACKLINE
) )
1169 pDev
->SetDrawMode( nOldDrawMode
& (~DRAWMODE_WHITEFILL
) );
1170 aSingleColor
.SetColor( COL_BLACK
);
1171 bUseSingleColor
= TRUE
;
1173 else if ( ( nOldDrawMode
& DRAWMODE_SETTINGSFILL
) && ( nOldDrawMode
& DRAWMODE_SETTINGSLINE
) )
1175 pDev
->SetDrawMode( nOldDrawMode
& (~DRAWMODE_SETTINGSFILL
) );
1176 aSingleColor
= rStyleSettings
.GetWindowTextColor(); // same as used in VCL for DRAWMODE_SETTINGSLINE
1177 bUseSingleColor
= TRUE
;
1179 else if ( bCellContrast
)
1181 aSingleColor
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
1182 bUseSingleColor
= TRUE
;
1185 const Color
* pForceColor
= bUseSingleColor
? &aSingleColor
: 0;
1188 DrawRotatedFrame( pForceColor
); // removes the lines that must not be painted here
1190 long nInitPosX
= nScrX
;
1193 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
1194 long nOneX
= aOnePixel
.Width();
1195 nInitPosX
+= nMirrorW
- nOneX
;
1197 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1200 // *** set column and row sizes of the frame border array ***
1202 svx::frame::Array
& rArray
= mrTabInfo
.maArray
;
1203 size_t nColCount
= rArray
.GetColCount();
1204 size_t nRowCount
= rArray
.GetRowCount();
1208 // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
1209 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
1210 long nOldPosY
= nScrY
- 1 - pRowInfo
[ 0 ].nHeight
;
1211 long nOldSnapY
= lclGetSnappedY( *pDev
, nOldPosY
, bSnapPixel
);
1212 rArray
.SetYOffset( nOldSnapY
);
1213 for( size_t nRow
= 0; nRow
< nRowCount
; ++nRow
)
1215 long nNewPosY
= nOldPosY
+ pRowInfo
[ nRow
].nHeight
;
1216 long nNewSnapY
= lclGetSnappedY( *pDev
, nNewPosY
, bSnapPixel
);
1217 rArray
.SetRowHeight( nRow
, nNewSnapY
- nOldSnapY
);
1218 nOldPosY
= nNewPosY
;
1219 nOldSnapY
= nNewSnapY
;
1224 // column nX1 is not visible (dummy for borders from left) - subtract its width from initial position
1225 // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
1226 long nOldPosX
= nInitPosX
- nLayoutSign
* (1 + pRowInfo
[ 0 ].pCellInfo
[ nX1
].nWidth
);
1227 long nOldSnapX
= lclGetSnappedX( *pDev
, nOldPosX
, bSnapPixel
);
1228 // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
1230 rArray
.SetXOffset( nOldSnapX
);
1231 for( USHORT nInfoIdx
= nX1
; nInfoIdx
<= nX2
+ 2; ++nInfoIdx
)
1233 size_t nCol
= lclGetArrayColFromCellInfoX( nInfoIdx
, nX1
, nX2
, bLayoutRTL
);
1234 long nNewPosX
= nOldPosX
+ pRowInfo
[ 0 ].pCellInfo
[ nInfoIdx
].nWidth
* nLayoutSign
;
1235 long nNewSnapX
= lclGetSnappedX( *pDev
, nNewPosX
, bSnapPixel
);
1236 rArray
.SetColWidth( nCol
, Abs( nNewSnapX
- nOldSnapX
) );
1237 nOldPosX
= nNewPosX
;
1238 nOldSnapX
= nNewSnapX
;
1241 rArray
.SetXOffset( nOldSnapX
);
1243 // *** draw the array ***
1245 size_t nFirstCol
= 1;
1246 size_t nFirstRow
= 1;
1247 size_t nLastCol
= nColCount
- 2;
1248 size_t nLastRow
= nRowCount
- 2;
1250 if( mrTabInfo
.mbPageMode
)
1251 rArray
.SetClipRange( nFirstCol
, nFirstRow
, nLastCol
, nLastRow
);
1253 // draw only rows with set RowInfo::bChanged flag
1254 size_t nRow1
= nFirstRow
;
1255 while( nRow1
<= nLastRow
)
1257 while( (nRow1
<= nLastRow
) && !pRowInfo
[ nRow1
].bChanged
) ++nRow1
;
1258 if( nRow1
<= nLastRow
)
1260 size_t nRow2
= nRow1
;
1261 while( (nRow2
+ 1 <= nLastRow
) && pRowInfo
[ nRow2
+ 1 ].bChanged
) ++nRow2
;
1262 rArray
.DrawRange( *pDev
, nFirstCol
, nRow1
, nLastCol
, nRow2
, pForceColor
);
1267 pDev
->SetDrawMode(nOldDrawMode
);
1270 // -------------------------------------------------------------------------
1272 // Linie unter der Zelle
1274 const SvxBorderLine
* lcl_FindHorLine( ScDocument
* pDoc
,
1275 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, USHORT nRotDir
,
1278 if ( nRotDir
!= SC_ROTDIR_LEFT
&& nRotDir
!= SC_ROTDIR_RIGHT
)
1281 BOOL bFound
= FALSE
;
1284 if ( nRotDir
== SC_ROTDIR_LEFT
)
1286 // Text nach links -> Linie von rechts
1287 if ( nCol
< MAXCOL
)
1290 return NULL
; // war nix
1294 // Text nach rechts -> Linie von links
1298 return NULL
; // war nix
1300 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
1301 const SfxItemSet
* pCondSet
= pDoc
->GetCondResult( nCol
, nRow
, nTab
);
1302 if ( !pPattern
->GetRotateVal( pCondSet
) ||
1303 ((const SvxRotateModeItem
&)pPattern
->GetItem(
1304 ATTR_ROTATE_MODE
, pCondSet
)).GetValue() == SVX_ROTATE_MODE_STANDARD
)
1310 const SvxBorderLine
* pThisBottom
;
1311 if ( ValidRow(nRow
) )
1312 pThisBottom
= ((const SvxBoxItem
*)pDoc
->GetAttr( nCol
, nRow
, nTab
, ATTR_BORDER
))->GetBottom();
1315 const SvxBorderLine
* pNextTop
;
1316 if ( nRow
< MAXROW
)
1317 pNextTop
= ((const SvxBoxItem
*)pDoc
->GetAttr( nCol
, nRow
+1, nTab
, ATTR_BORDER
))->GetTop();
1321 if ( ScHasPriority( pThisBottom
, pNextTop
) )
1327 // lcl_HorizLine muss genau zu normal ausgegebenen Linien passen!
1329 void lcl_HorizLine( OutputDevice
& rDev
, const Point
& rLeft
, const Point
& rRight
,
1330 const svx::frame::Style
& rLine
, const Color
* pForceColor
)
1332 svx::frame::DrawHorFrameBorder( rDev
, rLeft
, rRight
, rLine
, pForceColor
);
1335 void lcl_VertLineEnds( OutputDevice
& rDev
, const Point
& rTop
, const Point
& rBottom
,
1336 const Color
& rColor
, long nXOffs
, long nWidth
,
1337 const svx::frame::Style
& rTopLine
, const svx::frame::Style
& rBottomLine
)
1339 rDev
.SetLineColor(rColor
); // PEN_NULL ???
1340 rDev
.SetFillColor(rColor
);
1342 // Position oben/unten muss unabhaengig von der Liniendicke sein,
1343 // damit der Winkel stimmt (oder X-Position auch anpassen)
1344 long nTopPos
= rTop
.Y();
1345 long nBotPos
= rBottom
.Y();
1347 long nTopLeft
= rTop
.X() + nXOffs
;
1348 long nTopRight
= nTopLeft
+ nWidth
- 1;
1350 long nBotLeft
= rBottom
.X() + nXOffs
;
1351 long nBotRight
= nBotLeft
+ nWidth
- 1;
1353 // oben abschliessen
1355 if ( rTopLine
.Prim() )
1357 long nLineW
= rTopLine
.GetWidth();
1361 aTriangle
[0] = Point( nTopLeft
, nTopPos
); // wie aPoints[0]
1362 aTriangle
[1] = Point( nTopRight
, nTopPos
); // wie aPoints[1]
1363 aTriangle
[2] = Point( rTop
.X(), nTopPos
- (nLineW
- 1) / 2 );
1364 Polygon
aTriPoly( 3, aTriangle
);
1365 rDev
.DrawPolygon( aTriPoly
);
1369 // unten abschliessen
1371 if ( rBottomLine
.Prim() )
1373 long nLineW
= rBottomLine
.GetWidth();
1377 aTriangle
[0] = Point( nBotLeft
, nBotPos
); // wie aPoints[3]
1378 aTriangle
[1] = Point( nBotRight
, nBotPos
); // wie aPoints[2]
1379 aTriangle
[2] = Point( rBottom
.X(), nBotPos
- (nLineW
- 1) / 2 + nLineW
- 1 );
1380 Polygon
aTriPoly( 3, aTriangle
);
1381 rDev
.DrawPolygon( aTriPoly
);
1386 void lcl_VertLine( OutputDevice
& rDev
, const Point
& rTop
, const Point
& rBottom
,
1387 const svx::frame::Style
& rLine
,
1388 const svx::frame::Style
& rTopLine
, const svx::frame::Style
& rBottomLine
,
1389 const Color
* pForceColor
)
1393 svx::frame::DrawVerFrameBorderSlanted( rDev
, rTop
, rBottom
, rLine
, pForceColor
);
1395 svx::frame::Style
aScaled( rLine
);
1396 aScaled
.ScaleSelf( 1.0 / cos( svx::frame::GetVerDiagAngle( rTop
, rBottom
) ) );
1398 aScaled
.SetColor( *pForceColor
);
1400 long nXOffs
= (aScaled
.GetWidth() - 1) / -2L;
1402 lcl_VertLineEnds( rDev
, rTop
, rBottom
, aScaled
.GetColor(),
1403 nXOffs
, aScaled
.Prim(), rTopLine
, rBottomLine
);
1405 if( aScaled
.Secn() )
1406 lcl_VertLineEnds( rDev
, rTop
, rBottom
, aScaled
.GetColor(),
1407 nXOffs
+ aScaled
.Prim() + aScaled
.Dist(), aScaled
.Secn(), rTopLine
, rBottomLine
);
1411 void ScOutputData::DrawRotatedFrame( const Color
* pForceColor
)
1413 //! nRotMax speichern
1414 SCCOL nRotMax
= nX2
;
1415 for (SCSIZE nRotY
=0; nRotY
<nArrCount
; nRotY
++)
1416 if (pRowInfo
[nRotY
].nRotMaxCol
!= SC_ROTMAX_NONE
&& pRowInfo
[nRotY
].nRotMaxCol
> nRotMax
)
1417 nRotMax
= pRowInfo
[nRotY
].nRotMaxCol
;
1419 const ScPatternAttr
* pPattern
;
1420 const SfxItemSet
* pCondSet
;
1422 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
1423 // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE)
1424 BOOL bCellContrast
= bUseStyleColor
&& rStyleSettings
.GetHighContrastMode();
1426 // color (pForceColor) is determined externally, including DrawMode changes
1428 long nInitPosX
= nScrX
;
1431 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
1432 long nOneX
= aOnePixel
.Width();
1433 nInitPosX
+= nMirrorW
- nOneX
;
1435 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1437 Rectangle
aClipRect( Point(nScrX
, nScrY
), Size(nScrW
, nScrH
) );
1441 pDev
->IntersectClipRegion( aClipRect
);
1444 pDev
->SetClipRegion( Region( aClipRect
) );
1446 svx::frame::Array
& rArray
= mrTabInfo
.maArray
;
1449 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++)
1451 // Rotated wird auch 1 Zeile ueber/unter Changed gezeichnet, falls Teile
1452 // in die Zeile hineinragen...
1454 RowInfo
& rPrevRowInfo
= pRowInfo
[nArrY
-1];
1455 RowInfo
& rThisRowInfo
= pRowInfo
[nArrY
];
1456 RowInfo
& rNextRowInfo
= pRowInfo
[nArrY
+1];
1458 size_t nRow
= static_cast< size_t >( nArrY
);
1460 long nRowHeight
= rThisRowInfo
.nHeight
;
1461 if ( rThisRowInfo
.nRotMaxCol
!= SC_ROTMAX_NONE
&&
1462 ( rThisRowInfo
.bChanged
|| rPrevRowInfo
.bChanged
||
1463 ( nArrY
+1<nArrCount
&& rNextRowInfo
.bChanged
) ) )
1465 SCROW nY
= rThisRowInfo
.nRowNo
;
1468 for (nX
=0; nX
<=nRotMax
; nX
++)
1470 if (nX
==nX1
) nPosX
= nInitPosX
; // calculated individually for preceding positions
1472 USHORT nArrX
= nX
+ 1;
1474 CellInfo
* pInfo
= &rThisRowInfo
.pCellInfo
[nArrX
];
1475 long nColWidth
= pRowInfo
[0].pCellInfo
[nArrX
].nWidth
;
1476 if ( pInfo
->nRotateDir
> SC_ROTDIR_STANDARD
&&
1477 !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
1479 pPattern
= pInfo
->pPatternAttr
;
1480 pCondSet
= pInfo
->pConditionSet
;
1483 pPattern
= pDoc
->GetPattern( nX
, nY
, nTab
);
1484 pInfo
->pPatternAttr
= pPattern
;
1485 pCondSet
= pDoc
->GetCondResult( nX
, nY
, nTab
);
1486 pInfo
->pConditionSet
= pCondSet
;
1489 //! LastPattern etc.
1491 long nAttrRotate
= pPattern
->GetRotateVal( pCondSet
);
1492 SvxRotateMode eRotMode
= (SvxRotateMode
)((const SvxRotateModeItem
&)
1493 pPattern
->GetItem(ATTR_ROTATE_MODE
, pCondSet
)).GetValue();
1497 if (nX
<nX1
) // negative Position berechnen
1504 nPosX
-= nLayoutSign
* (long) pRowInfo
[0].pCellInfo
[nCol
+1].nWidth
;
1508 // Startposition minus 1, damit auch schraege Hintergruende
1509 // zur Umrandung passen (Umrandung ist auf dem Gitter)
1511 long nTop
= nPosY
- 1;
1512 long nBottom
= nPosY
+ nRowHeight
- 1;
1513 long nTopLeft
= nPosX
- nLayoutSign
;
1514 long nTopRight
= nPosX
+ ( nColWidth
- 1 ) * nLayoutSign
;
1515 long nBotLeft
= nTopLeft
;
1516 long nBotRight
= nTopRight
;
1518 // inclusion of the sign here hasn't been decided yet
1519 // (if not, the extension of the non-rotated background must also be changed)
1520 double nRealOrient
= nLayoutSign
* nAttrRotate
* F_PI18000
; // 1/100th degrees
1521 double nCos
= cos( nRealOrient
);
1522 double nSin
= sin( nRealOrient
);
1524 long nSkew
= (long) ( nRowHeight
* nCos
/ nSin
);
1528 case SVX_ROTATE_MODE_BOTTOM
:
1532 case SVX_ROTATE_MODE_CENTER
:
1539 case SVX_ROTATE_MODE_TOP
:
1545 // added to avoid warnings
1550 aPoints
[0] = Point( nTopLeft
, nTop
);
1551 aPoints
[1] = Point( nTopRight
, nTop
);
1552 aPoints
[2] = Point( nBotRight
, nBottom
);
1553 aPoints
[3] = Point( nBotLeft
, nBottom
);
1555 const SvxBrushItem
* pBackground
= pInfo
->pBackground
;
1557 pBackground
= (const SvxBrushItem
*) &pPattern
->GetItem(
1558 ATTR_BACKGROUND
, pCondSet
);
1561 // high contrast for cell borders and backgrounds -> empty background
1562 pBackground
= ScGlobal::GetEmptyBrushItem();
1564 const Color
& rColor
= pBackground
->GetColor();
1565 if ( rColor
.GetTransparency() != 255 )
1567 // #95879# draw background only for the changed row itself
1568 // (background doesn't extend into other cells).
1569 // For the borders (rotated and normal), clipping should be
1570 // set if the row isn't changed, but at least the borders
1571 // don't cover the cell contents.
1572 if ( rThisRowInfo
.bChanged
)
1574 Polygon
aPoly( 4, aPoints
);
1576 // ohne Pen wird bei DrawPolygon rechts und unten
1577 // ein Pixel weggelassen...
1578 if ( rColor
.GetTransparency() == 0 )
1579 pDev
->SetLineColor(rColor
);
1581 pDev
->SetLineColor();
1582 pDev
->SetFillColor(rColor
);
1583 pDev
->DrawPolygon( aPoly
);
1587 svx::frame::Style aTopLine
, aBottomLine
, aLeftLine
, aRightLine
;
1589 if ( nX
< nX1
|| nX
> nX2
) // Attribute in FillInfo nicht gesetzt
1591 //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
1592 const SvxBorderLine
* pLeftLine
;
1593 const SvxBorderLine
* pTopLine
;
1594 const SvxBorderLine
* pRightLine
;
1595 const SvxBorderLine
* pBottomLine
;
1596 pDoc
->GetBorderLines( nX
, nY
, nTab
,
1597 &pLeftLine
, &pTopLine
, &pRightLine
, &pBottomLine
);
1598 aTopLine
.Set( pTopLine
, nPPTY
);
1599 aBottomLine
.Set( pBottomLine
, nPPTY
);
1600 aLeftLine
.Set( pLeftLine
, nPPTX
);
1601 aRightLine
.Set( pRightLine
, nPPTX
);
1605 size_t nCol
= lclGetArrayColFromCellInfoX( nArrX
, nX1
, nX2
, bLayoutRTL
);
1606 aTopLine
= rArray
.GetCellStyleTop( nCol
, nRow
);
1607 aBottomLine
= rArray
.GetCellStyleBottom( nCol
, nRow
);
1608 aLeftLine
= rArray
.GetCellStyleLeft( nCol
, nRow
);
1609 aRightLine
= rArray
.GetCellStyleRight( nCol
, nRow
);
1610 // in RTL mode the array is already mirrored -> swap back left/right borders
1612 std::swap( aLeftLine
, aRightLine
);
1615 lcl_HorizLine( *pDev
, aPoints
[bLayoutRTL
?1:0], aPoints
[bLayoutRTL
?0:1], aTopLine
, pForceColor
);
1616 lcl_HorizLine( *pDev
, aPoints
[bLayoutRTL
?2:3], aPoints
[bLayoutRTL
?3:2], aBottomLine
, pForceColor
);
1618 lcl_VertLine( *pDev
, aPoints
[0], aPoints
[3], aLeftLine
, aTopLine
, aBottomLine
, pForceColor
);
1619 lcl_VertLine( *pDev
, aPoints
[1], aPoints
[2], aRightLine
, aTopLine
, aBottomLine
, pForceColor
);
1622 nPosX
+= nColWidth
* nLayoutSign
;
1625 // erst hinterher im zweiten Schritt die Linien fuer normale Ausgabe loeschen
1627 nX
= nX1
> 0 ? (nX1
-1) : static_cast<SCCOL
>(0);
1628 for (; nX
<=nX2
+1; nX
++) // sichtbarer Teil +- 1
1630 USHORT nArrX
= nX
+ 1;
1631 CellInfo
& rInfo
= rThisRowInfo
.pCellInfo
[nArrX
];
1632 if ( rInfo
.nRotateDir
> SC_ROTDIR_STANDARD
&&
1633 !rInfo
.bHOverlapped
&& !rInfo
.bVOverlapped
)
1635 pPattern
= rInfo
.pPatternAttr
;
1636 pCondSet
= rInfo
.pConditionSet
;
1637 SvxRotateMode eRotMode
= (SvxRotateMode
)((const SvxRotateModeItem
&)
1638 pPattern
->GetItem(ATTR_ROTATE_MODE
, pCondSet
)).GetValue();
1640 size_t nCol
= lclGetArrayColFromCellInfoX( nArrX
, nX1
, nX2
, bLayoutRTL
);
1642 // horizontal: angrenzende Linie verlaengern
1643 // (nur, wenn die gedrehte Zelle eine Umrandung hat)
1644 USHORT nDir
= rInfo
.nRotateDir
;
1645 if ( rArray
.GetCellStyleTop( nCol
, nRow
).Prim() && eRotMode
!= SVX_ROTATE_MODE_TOP
)
1647 svx::frame::Style
aStyle( lcl_FindHorLine( pDoc
, nX
, nY
, nTab
, nDir
, TRUE
), nPPTY
);
1648 rArray
.SetCellStyleTop( nCol
, nRow
, aStyle
);
1650 rArray
.SetCellStyleBottom( nCol
, nRow
- 1, aStyle
);
1652 if ( rArray
.GetCellStyleBottom( nCol
, nRow
).Prim() && eRotMode
!= SVX_ROTATE_MODE_BOTTOM
)
1654 svx::frame::Style
aStyle( lcl_FindHorLine( pDoc
, nX
, nY
, nTab
, nDir
, FALSE
), nPPTY
);
1655 rArray
.SetCellStyleBottom( nCol
, nRow
, aStyle
);
1656 if( nRow
+ 1 < rArray
.GetRowCount() )
1657 rArray
.SetCellStyleTop( nCol
, nRow
+ 1, aStyle
);
1660 // always remove vertical borders
1661 if( !rArray
.IsMergedOverlappedLeft( nCol
, nRow
) )
1663 rArray
.SetCellStyleLeft( nCol
, nRow
, svx::frame::Style() );
1665 rArray
.SetCellStyleRight( nCol
- 1, nRow
, svx::frame::Style() );
1667 if( !rArray
.IsMergedOverlappedRight( nCol
, nRow
) )
1669 rArray
.SetCellStyleRight( nCol
, nRow
, svx::frame::Style() );
1670 if( nCol
+ 1 < rArray
.GetColCount() )
1671 rArray
.SetCellStyleLeft( nCol
+ 1, nRow
, svx::frame::Style() );
1674 // remove diagonal borders
1675 rArray
.SetCellStyleTLBR( nCol
, nRow
, svx::frame::Style() );
1676 rArray
.SetCellStyleBLTR( nCol
, nRow
, svx::frame::Style() );
1680 nPosY
+= nRowHeight
;
1686 pDev
->SetClipRegion();
1691 PolyPolygon
ScOutputData::GetChangedArea()
1695 Rectangle aDrawingRect
;
1696 aDrawingRect
.Left() = nScrX
;
1697 aDrawingRect
.Right() = nScrX
+nScrW
-1;
1702 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1704 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1706 if ( pThisRowInfo
->bChanged
)
1710 aDrawingRect
.Top() = nPosY
;
1713 aDrawingRect
.Bottom() = nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
1717 aPoly
.Insert( Polygon( pDev
->PixelToLogic(aDrawingRect
) ) );
1720 nPosY
+= pRowInfo
[nArrY
].nHeight
;
1724 aPoly
.Insert( Polygon( pDev
->PixelToLogic(aDrawingRect
) ) );
1729 BOOL
ScOutputData::SetChangedClip()
1733 Rectangle aDrawingRect
;
1734 aDrawingRect
.Left() = nScrX
;
1735 aDrawingRect
.Right() = nScrX
+nScrW
-1;
1740 for (nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1742 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1744 if ( pThisRowInfo
->bChanged
)
1748 aDrawingRect
.Top() = nPosY
;
1751 aDrawingRect
.Bottom() = nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
1755 aPoly
.Insert( Polygon( pDev
->PixelToLogic(aDrawingRect
) ) );
1758 nPosY
+= pRowInfo
[nArrY
].nHeight
;
1762 aPoly
.Insert( Polygon( pDev
->PixelToLogic(aDrawingRect
) ) );
1764 BOOL bRet
= (aPoly
.Count() != 0);
1766 pDev
->SetClipRegion(Region(aPoly
));
1770 void ScOutputData::FindChanged()
1775 BOOL bWasIdleDisabled
= pDoc
->IsIdleDisabled();
1776 pDoc
->DisableIdle( TRUE
);
1777 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1778 pRowInfo
[nArrY
].bChanged
= FALSE
;
1780 BOOL bProgress
= FALSE
;
1781 for (nArrY
=0; nArrY
<nArrCount
; nArrY
++)
1783 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1784 for (nX
=nX1
; nX
<=nX2
; nX
++)
1786 ScBaseCell
* pCell
= pThisRowInfo
->pCellInfo
[nX
+1].pCell
;
1788 if (pCell
->GetCellType() == CELLTYPE_FORMULA
)
1790 ScFormulaCell
* pFCell
= (ScFormulaCell
*)pCell
;
1791 if ( !bProgress
&& pFCell
->GetDirty() )
1793 ScProgress::CreateInterpretProgress( pDoc
, TRUE
);
1796 if (!pFCell
->IsRunning())
1798 (void)pFCell
->GetValue();
1799 if (pFCell
->IsChanged())
1801 pThisRowInfo
->bChanged
= TRUE
;
1802 if ( pThisRowInfo
->pCellInfo
[nX
+1].bMerged
)
1804 SCSIZE nOverY
= nArrY
+ 1;
1805 while ( nOverY
<nArrCount
&&
1806 pRowInfo
[nOverY
].pCellInfo
[nX
+1].bVOverlapped
)
1808 pRowInfo
[nOverY
].bChanged
= TRUE
;
1818 ScProgress::DeleteInterpretProgress();
1819 pDoc
->DisableIdle( bWasIdleDisabled
);
1822 #ifdef OLD_SELECTION_PAINT
1823 void ScOutputData::DrawMark( Window
* pWin
)
1826 ScInvertMerger
aInvert( pWin
);
1827 //! additional method AddLineRect for ScInvertMerger?
1830 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
1832 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
1833 if (pThisRowInfo
->bChanged
)
1837 nPosX
+= nMirrorW
- 1; // always in pixels
1839 aRect
= Rectangle( Point( nPosX
,nPosY
), Size(1, pThisRowInfo
->nHeight
) );
1841 aRect
.Left() = aRect
.Right() + 1;
1843 aRect
.Right() = aRect
.Left() - 1;
1845 BOOL bOldMarked
= FALSE
;
1846 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
1848 if (pThisRowInfo
->pCellInfo
[nX
+1].bMarked
!= bOldMarked
)
1850 if (bOldMarked
&& aRect
.Right() >= aRect
.Left())
1851 aInvert
.AddRect( aRect
);
1854 aRect
.Right() = nPosX
;
1856 aRect
.Left() = nPosX
;
1858 bOldMarked
= pThisRowInfo
->pCellInfo
[nX
+1].bMarked
;
1863 nPosX
-= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
1864 aRect
.Left() = nPosX
+1;
1868 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
1869 aRect
.Right() = nPosX
-1;
1872 if (bOldMarked
&& aRect
.Right() >= aRect
.Left())
1873 aInvert
.AddRect( aRect
);
1875 nPosY
+= pThisRowInfo
->nHeight
;
1880 void ScOutputData::DrawRefMark( SCCOL nRefStartX
, SCROW nRefStartY
,
1881 SCCOL nRefEndX
, SCROW nRefEndY
,
1882 const Color
& rColor
, BOOL bHandle
)
1884 PutInOrder( nRefStartX
, nRefEndX
);
1885 PutInOrder( nRefStartY
, nRefEndY
);
1887 if ( nRefStartX
== nRefEndX
&& nRefStartY
== nRefEndY
)
1888 pDoc
->ExtendMerge( nRefStartX
, nRefStartY
, nRefEndX
, nRefEndY
, nTab
);
1890 if ( nRefStartX
<= nVisX2
&& nRefEndX
>= nVisX1
&&
1891 nRefStartY
<= nVisY2
&& nRefEndY
>= nVisY1
)
1895 long nMaxX
= nScrX
+nScrW
-1;
1896 long nMaxY
= nScrY
+nScrH
-1;
1903 long nLayoutSign
= bLayoutRTL
? -1 : 1;
1906 BOOL bBottom
= FALSE
;
1908 BOOL bRight
= FALSE
;
1911 BOOL bNoStartY
= ( nY1
< nRefStartY
);
1912 BOOL bNoEndY
= FALSE
;
1913 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++) // loop to end for bNoEndY check
1915 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
1917 if ( nY
==nRefStartY
|| (nY
>nRefStartY
&& bNoStartY
) )
1924 nMaxY
= nPosY
+ pRowInfo
[nArrY
].nHeight
- 2;
1927 if ( nY
>nRefEndY
&& bNoEndY
)
1932 bNoStartY
= ( nY
< nRefStartY
);
1933 bNoEndY
= ( nY
< nRefEndY
);
1934 nPosY
+= pRowInfo
[nArrY
].nHeight
;
1939 nPosX
+= nMirrorW
- 1; // always in pixels
1941 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
1943 if ( nX
==nRefStartX
)
1950 nMaxX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 2 ) * nLayoutSign
;
1953 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
1956 if ( nMaxX
* nLayoutSign
>= nMinX
* nLayoutSign
&&
1959 pDev
->SetLineColor( rColor
);
1960 if (bTop
&& bBottom
&& bLeft
&& bRight
)
1962 pDev
->SetFillColor();
1963 pDev
->DrawRect( Rectangle( nMinX
, nMinY
, nMaxX
, nMaxY
) );
1968 pDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMaxX
,nMinY
) );
1970 pDev
->DrawLine( Point( nMinX
,nMaxY
), Point( nMaxX
,nMaxY
) );
1972 pDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMinX
,nMaxY
) );
1974 pDev
->DrawLine( Point( nMaxX
,nMinY
), Point( nMaxX
,nMaxY
) );
1976 if ( bHandle
&& bRight
&& bBottom
)
1978 pDev
->SetLineColor();
1979 pDev
->SetFillColor( rColor
);
1980 pDev
->DrawRect( Rectangle( nMaxX
-3*nLayoutSign
, nMaxY
-3, nMaxX
+nLayoutSign
, nMaxY
+1 ) );
1986 void ScOutputData::DrawOneChange( SCCOL nRefStartX
, SCROW nRefStartY
,
1987 SCCOL nRefEndX
, SCROW nRefEndY
,
1988 const Color
& rColor
, USHORT nType
)
1990 PutInOrder( nRefStartX
, nRefEndX
);
1991 PutInOrder( nRefStartY
, nRefEndY
);
1993 if ( nRefStartX
== nRefEndX
&& nRefStartY
== nRefEndY
)
1994 pDoc
->ExtendMerge( nRefStartX
, nRefStartY
, nRefEndX
, nRefEndY
, nTab
);
1996 if ( nRefStartX
<= nVisX2
+ 1 && nRefEndX
>= nVisX1
&&
1997 nRefStartY
<= nVisY2
+ 1 && nRefEndY
>= nVisY1
) // +1 because it touches next cells left/top
2001 long nMaxX
= nScrX
+nScrW
-1;
2002 long nMaxY
= nScrY
+nScrH
-1;
2009 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2012 BOOL bBottom
= FALSE
;
2014 BOOL bRight
= FALSE
;
2017 BOOL bNoStartY
= ( nY1
< nRefStartY
);
2018 BOOL bNoEndY
= FALSE
;
2019 for (SCSIZE nArrY
=1; nArrY
<nArrCount
; nArrY
++) // loop to end for bNoEndY check
2021 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2023 if ( nY
==nRefStartY
|| (nY
>nRefStartY
&& bNoStartY
) )
2030 nMaxY
= nPosY
+ pRowInfo
[nArrY
].nHeight
- 1;
2033 if ( nY
>nRefEndY
&& bNoEndY
)
2038 bNoStartY
= ( nY
< nRefStartY
);
2039 bNoEndY
= ( nY
< nRefEndY
);
2040 nPosY
+= pRowInfo
[nArrY
].nHeight
;
2045 nPosX
+= nMirrorW
- 1; // always in pixels
2047 for (SCCOL nX
=nX1
; nX
<=nX2
+1; nX
++)
2049 if ( nX
==nRefStartX
)
2051 nMinX
= nPosX
- nLayoutSign
;
2056 nMaxX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 1 ) * nLayoutSign
;
2059 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2062 if ( nMaxX
* nLayoutSign
>= nMinX
* nLayoutSign
&&
2065 if ( nType
== SC_CAT_DELETE_ROWS
)
2066 bLeft
= bRight
= bBottom
= FALSE
; //! dicke Linie ???
2067 else if ( nType
== SC_CAT_DELETE_COLS
)
2068 bTop
= bBottom
= bRight
= FALSE
; //! dicke Linie ???
2070 pDev
->SetLineColor( rColor
);
2071 if (bTop
&& bBottom
&& bLeft
&& bRight
)
2073 pDev
->SetFillColor();
2074 pDev
->DrawRect( Rectangle( nMinX
, nMinY
, nMaxX
, nMaxY
) );
2080 pDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMaxX
,nMinY
) );
2081 if ( nType
== SC_CAT_DELETE_ROWS
)
2082 pDev
->DrawLine( Point( nMinX
,nMinY
+1 ), Point( nMaxX
,nMinY
+1 ) );
2085 pDev
->DrawLine( Point( nMinX
,nMaxY
), Point( nMaxX
,nMaxY
) );
2088 pDev
->DrawLine( Point( nMinX
,nMinY
), Point( nMinX
,nMaxY
) );
2089 if ( nType
== SC_CAT_DELETE_COLS
)
2090 pDev
->DrawLine( Point( nMinX
+nLayoutSign
,nMinY
), Point( nMinX
+nLayoutSign
,nMaxY
) );
2093 pDev
->DrawLine( Point( nMaxX
,nMinY
), Point( nMaxX
,nMaxY
) );
2095 if ( bLeft
&& bTop
)
2097 pDev
->SetLineColor();
2098 pDev
->SetFillColor( rColor
);
2099 pDev
->DrawRect( Rectangle( nMinX
+nLayoutSign
, nMinY
+1, nMinX
+3*nLayoutSign
, nMinY
+3 ) );
2105 void ScOutputData::DrawChangeTrack()
2107 ScChangeTrack
* pTrack
= pDoc
->GetChangeTrack();
2108 ScChangeViewSettings
* pSettings
= pDoc
->GetChangeViewSettings();
2109 if ( !pTrack
|| !pTrack
->GetFirst() || !pSettings
|| !pSettings
->ShowChanges() )
2110 return; // nix da oder abgeschaltet
2112 ScActionColorChanger
aColorChanger(*pTrack
);
2114 // Clipping passiert von aussen
2115 //! ohne Clipping, nur betroffene Zeilen painten ??!??!?
2119 if ( nEndX
< MAXCOL
) ++nEndX
; // auch noch von der naechsten Zelle, weil die Markierung
2120 if ( nEndY
< MAXROW
) ++nEndY
; // in die jeweils vorhergehende Zelle hineinragt
2121 ScRange
aViewRange( nX1
, nY1
, nTab
, nEndX
, nEndY
, nTab
);
2122 const ScChangeAction
* pAction
= pTrack
->GetFirst();
2125 ScChangeActionType eActionType
;
2126 if ( pAction
->IsVisible() )
2128 eActionType
= pAction
->GetType();
2129 const ScBigRange
& rBig
= pAction
->GetBigRange();
2130 if ( rBig
.aStart
.Tab() == nTab
)
2132 ScRange aRange
= rBig
.MakeRange();
2134 if ( eActionType
== SC_CAT_DELETE_ROWS
)
2135 aRange
.aEnd
.SetRow( aRange
.aStart
.Row() );
2136 else if ( eActionType
== SC_CAT_DELETE_COLS
)
2137 aRange
.aEnd
.SetCol( aRange
.aStart
.Col() );
2139 if ( aRange
.Intersects( aViewRange
) &&
2140 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *pDoc
) )
2142 aColorChanger
.Update( *pAction
);
2143 Color
aColor( aColorChanger
.GetColor() );
2144 DrawOneChange( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2145 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aColor
, sal::static_int_cast
<USHORT
>(eActionType
) );
2149 if ( eActionType
== SC_CAT_MOVE
&&
2150 ((const ScChangeActionMove
*)pAction
)->
2151 GetFromRange().aStart
.Tab() == nTab
)
2153 ScRange aRange
= ((const ScChangeActionMove
*)pAction
)->
2154 GetFromRange().MakeRange();
2155 if ( aRange
.Intersects( aViewRange
) &&
2156 ScViewUtil::IsActionShown( *pAction
, *pSettings
, *pDoc
) )
2158 aColorChanger
.Update( *pAction
);
2159 Color
aColor( aColorChanger
.GetColor() );
2160 DrawOneChange( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
2161 aRange
.aEnd
.Col(), aRange
.aEnd
.Row(), aColor
, sal::static_int_cast
<USHORT
>(eActionType
) );
2166 pAction
= pAction
->GetNext();
2170 void ScOutputData::DrawNoteMarks()
2174 long nInitPosX
= nScrX
;
2176 nInitPosX
+= nMirrorW
- 1; // always in pixels
2177 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2180 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2182 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2183 if ( pThisRowInfo
->bChanged
)
2185 long nPosX
= nInitPosX
;
2186 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2188 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2189 ScBaseCell
* pCell
= pInfo
->pCell
;
2190 BOOL bIsMerged
= FALSE
;
2192 if ( nX
==nX1
&& pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
2194 // find start of merged cell
2196 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2199 pDoc
->ExtendOverlapped( nMergeX
, nMergeY
, nX
, nY
, nTab
);
2200 pCell
= pDoc
->GetCell( ScAddress(nMergeX
,nMergeY
,nTab
) );
2201 // use origin's pCell for NotePtr test below
2204 if ( pCell
&& pCell
->HasNote() && ( bIsMerged
||
2205 ( !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
) ) )
2209 pDev
->SetLineColor();
2211 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2212 if ( bUseStyleColor
&& rStyleSettings
.GetHighContrastMode() )
2213 pDev
->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
2215 pDev
->SetFillColor(COL_LIGHTRED
);
2220 long nMarkX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- 4 ) * nLayoutSign
;
2221 if ( bIsMerged
|| pInfo
->bMerged
)
2223 // if merged, add widths of all cells
2224 SCCOL nNextX
= nX
+ 1;
2225 while ( nNextX
<= nX2
+ 1 && pThisRowInfo
->pCellInfo
[nNextX
+1].bHOverlapped
)
2227 nMarkX
+= pRowInfo
[0].pCellInfo
[nNextX
+1].nWidth
* nLayoutSign
;
2231 if ( bLayoutRTL
? ( nMarkX
>= 0 ) : ( nMarkX
< nScrX
+nScrW
) )
2232 pDev
->DrawRect( Rectangle( nMarkX
,nPosY
,nMarkX
+2*nLayoutSign
,nPosY
+2 ) );
2235 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2238 nPosY
+= pThisRowInfo
->nHeight
;
2242 void ScOutputData::AddPDFNotes()
2244 vcl::PDFExtOutDevData
* pPDFData
= PTR_CAST( vcl::PDFExtOutDevData
, pDev
->GetExtOutDevData() );
2245 if ( !pPDFData
|| !pPDFData
->GetIsExportNotes() )
2248 long nInitPosX
= nScrX
;
2251 Size aOnePixel
= pDev
->PixelToLogic(Size(1,1));
2252 long nOneX
= aOnePixel
.Width();
2253 nInitPosX
+= nMirrorW
- nOneX
;
2255 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2258 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2260 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2261 if ( pThisRowInfo
->bChanged
)
2263 long nPosX
= nInitPosX
;
2264 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2266 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2267 ScBaseCell
* pCell
= pInfo
->pCell
;
2268 BOOL bIsMerged
= FALSE
;
2269 SCROW nY
= pRowInfo
[nArrY
].nRowNo
;
2273 if ( nX
==nX1
&& pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
)
2275 // find start of merged cell
2277 pDoc
->ExtendOverlapped( nMergeX
, nMergeY
, nX
, nY
, nTab
);
2278 pCell
= pDoc
->GetCell( ScAddress(nMergeX
,nMergeY
,nTab
) );
2279 // use origin's pCell for NotePtr test below
2282 if ( pCell
&& pCell
->HasNote() && ( bIsMerged
||
2283 ( !pInfo
->bHOverlapped
&& !pInfo
->bVOverlapped
) ) )
2285 long nNoteWidth
= (long)( SC_CLIPMARK_SIZE
* nPPTX
);
2286 long nNoteHeight
= (long)( SC_CLIPMARK_SIZE
* nPPTY
);
2288 long nMarkX
= nPosX
+ ( pRowInfo
[0].pCellInfo
[nX
+1].nWidth
- nNoteWidth
) * nLayoutSign
;
2289 if ( bIsMerged
|| pInfo
->bMerged
)
2291 // if merged, add widths of all cells
2292 SCCOL nNextX
= nX
+ 1;
2293 while ( nNextX
<= nX2
+ 1 && pThisRowInfo
->pCellInfo
[nNextX
+1].bHOverlapped
)
2295 nMarkX
+= pRowInfo
[0].pCellInfo
[nNextX
+1].nWidth
* nLayoutSign
;
2299 if ( bLayoutRTL
? ( nMarkX
>= 0 ) : ( nMarkX
< nScrX
+nScrW
) )
2301 Rectangle
aNoteRect( nMarkX
, nPosY
, nMarkX
+nNoteWidth
*nLayoutSign
, nPosY
+nNoteHeight
);
2302 const ScPostIt
* pNote
= pCell
->GetNote();
2304 // Note title is the cell address (as on printed note pages)
2306 ScAddress
aAddress( nMergeX
, nMergeY
, nTab
);
2307 aAddress
.Format( aTitle
, SCA_VALID
, pDoc
, pDoc
->GetAddressConvention() );
2309 // Content has to be a simple string without line breaks
2310 String aContent
= pNote
->GetText();
2312 while ( (nPos
=aContent
.Search('\n')) != STRING_NOTFOUND
)
2313 aContent
.SetChar( nPos
, ' ' );
2316 aNote
.Title
= aTitle
;
2317 aNote
.Contents
= aContent
;
2318 pPDFData
->CreateNote( aNoteRect
, aNote
);
2322 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2325 nPosY
+= pThisRowInfo
->nHeight
;
2329 void ScOutputData::DrawClipMarks()
2334 Color
aArrowFillCol( COL_LIGHTRED
);
2336 ULONG nOldDrawMode
= pDev
->GetDrawMode();
2337 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
2338 if ( bUseStyleColor
&& rStyleSettings
.GetHighContrastMode() )
2340 // use DrawMode to change the arrow's outline color
2341 pDev
->SetDrawMode( nOldDrawMode
| DRAWMODE_SETTINGSLINE
);
2342 // use text color also for the fill color
2343 aArrowFillCol
.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
2346 long nInitPosX
= nScrX
;
2348 nInitPosX
+= nMirrorW
- 1; // always in pixels
2349 long nLayoutSign
= bLayoutRTL
? -1 : 1;
2351 Rectangle aCellRect
;
2353 for (SCSIZE nArrY
=1; nArrY
+1<nArrCount
; nArrY
++)
2355 RowInfo
* pThisRowInfo
= &pRowInfo
[nArrY
];
2356 if ( pThisRowInfo
->bChanged
)
2358 SCROW nY
= pThisRowInfo
->nRowNo
;
2359 long nPosX
= nInitPosX
;
2360 for (SCCOL nX
=nX1
; nX
<=nX2
; nX
++)
2362 CellInfo
* pInfo
= &pThisRowInfo
->pCellInfo
[nX
+1];
2363 if (pInfo
->nClipMark
)
2365 if (pInfo
->bHOverlapped
|| pInfo
->bVOverlapped
)
2367 // merge origin may be outside of visible area - use document functions
2371 long nStartPosX
= nPosX
;
2372 long nStartPosY
= nPosY
;
2374 while ( nOverX
> 0 && ( ((const ScMergeFlagAttr
*)pDoc
->GetAttr(
2375 nOverX
, nOverY
, nTab
, ATTR_MERGE_FLAG
))->GetValue() & SC_MF_HOR
) )
2378 nStartPosX
-= nLayoutSign
* (long) ( pDoc
->GetColWidth(nOverX
,nTab
) * nPPTX
);
2381 while ( nOverY
> 0 && ( ((const ScMergeFlagAttr
*)pDoc
->GetAttr(
2382 nOverX
, nOverY
, nTab
, ATTR_MERGE_FLAG
))->GetValue() & SC_MF_VER
) )
2385 nStartPosY
-= nLayoutSign
* (long) ( pDoc
->GetRowHeight(nOverY
,nTab
) * nPPTY
);
2388 long nOutWidth
= (long) ( pDoc
->GetColWidth(nOverX
,nTab
) * nPPTX
);
2389 long nOutHeight
= (long) ( pDoc
->GetRowHeight(nOverY
,nTab
) * nPPTY
);
2391 const ScMergeAttr
* pMerge
= (const ScMergeAttr
*)
2392 pDoc
->GetAttr( nOverX
, nOverY
, nTab
, ATTR_MERGE
);
2393 SCCOL nCountX
= pMerge
->GetColMerge();
2394 for (SCCOL i
=1; i
<nCountX
; i
++)
2395 nOutWidth
+= (long) ( pDoc
->GetColWidth(nOverX
+i
,nTab
) * nPPTX
);
2396 SCROW nCountY
= pMerge
->GetRowMerge();
2397 nOutHeight
+= (long) pDoc
->GetScaledRowHeight( nOverY
+1, nOverY
+nCountY
-1, nTab
, nPPTY
);
2400 nStartPosX
-= nOutWidth
- 1;
2401 aCellRect
= Rectangle( Point( nStartPosX
, nStartPosY
), Size( nOutWidth
, nOutHeight
) );
2405 long nOutWidth
= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
;
2406 long nOutHeight
= pThisRowInfo
->nHeight
;
2408 if ( pInfo
->bMerged
&& pInfo
->pPatternAttr
)
2412 const ScMergeAttr
* pMerge
=
2413 (ScMergeAttr
*)&pInfo
->pPatternAttr
->GetItem(ATTR_MERGE
);
2414 SCCOL nCountX
= pMerge
->GetColMerge();
2415 for (SCCOL i
=1; i
<nCountX
; i
++)
2416 nOutWidth
+= (long) ( pDoc
->GetColWidth(nOverX
+i
,nTab
) * nPPTX
);
2417 SCROW nCountY
= pMerge
->GetRowMerge();
2418 nOutHeight
+= (long) pDoc
->GetScaledRowHeight( nOverY
+1, nOverY
+nCountY
-1, nTab
, nPPTY
);
2421 long nStartPosX
= nPosX
;
2423 nStartPosX
-= nOutWidth
- 1;
2424 // #i80447# create aCellRect from two points in case nOutWidth is 0
2425 aCellRect
= Rectangle( Point( nStartPosX
, nPosY
),
2426 Point( nStartPosX
+nOutWidth
-1, nPosY
+nOutHeight
-1 ) );
2429 aCellRect
.Bottom() -= 1; // don't paint over the cell grid
2431 aCellRect
.Left() += 1;
2433 aCellRect
.Right() -= 1;
2435 long nMarkPixel
= (long)( SC_CLIPMARK_SIZE
* nPPTX
);
2436 Size
aMarkSize( nMarkPixel
, (nMarkPixel
-1)*2 );
2438 if ( pInfo
->nClipMark
& ( bLayoutRTL
? SC_CLIPMARK_RIGHT
: SC_CLIPMARK_LEFT
) )
2441 Rectangle aMarkRect
= aCellRect
;
2442 aMarkRect
.Right() = aCellRect
.Left()+nMarkPixel
-1;
2445 pDev
->SetLineColor(); pDev
->SetFillColor(COL_YELLOW
);
2446 pDev
->DrawRect(aMarkRect
);
2449 SvxFont::DrawArrow( *pDev
, aMarkRect
, aMarkSize
, aArrowFillCol
, TRUE
);
2451 if ( pInfo
->nClipMark
& ( bLayoutRTL
? SC_CLIPMARK_LEFT
: SC_CLIPMARK_RIGHT
) )
2454 Rectangle aMarkRect
= aCellRect
;
2455 aMarkRect
.Left() = aCellRect
.Right()-nMarkPixel
+1;
2458 pDev
->SetLineColor(); pDev
->SetFillColor(COL_LIGHTGREEN
);
2459 pDev
->DrawRect(aMarkRect
);
2462 SvxFont::DrawArrow( *pDev
, aMarkRect
, aMarkSize
, aArrowFillCol
, FALSE
);
2465 nPosX
+= pRowInfo
[0].pCellInfo
[nX
+1].nWidth
* nLayoutSign
;
2468 nPosY
+= pThisRowInfo
->nHeight
;
2471 pDev
->SetDrawMode(nOldDrawMode
);