summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/paintfrm.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/paintfrm.cxx')
-rw-r--r--sw/source/core/layout/paintfrm.cxx6650
1 files changed, 6650 insertions, 0 deletions
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
new file mode 100644
index 000000000000..82513c75d32c
--- /dev/null
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -0,0 +1,6650 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <hintids.hxx>
+#include <vcl/sound.hxx>
+#include <tools/poly.hxx>
+#include <svl/svstdarr.hxx>
+#include <svx/xoutbmp.hxx>
+#include <sfx2/progress.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/prntitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <svx/framelink.hxx>
+#include <vcl/graph.hxx>
+#include <svx/svdpagv.hxx>
+#include <tgrditem.hxx>
+#include <switerator.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtclds.hxx>
+#include <tools/shl.hxx>
+#include <comcore.hrc>
+#include <swmodule.hxx>
+#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <cntfrm.hxx>
+#include <viewsh.hxx>
+#include <section.hxx>
+#include <sectfrm.hxx>
+#include <doc.hxx>
+#include <viewimp.hxx>
+#include <dflyobj.hxx>
+#include <flyfrm.hxx>
+#include <frmtool.hxx>
+#include <viewopt.hxx>
+#include <dview.hxx>
+#include <dcontact.hxx>
+#include <txtfrm.hxx>
+#include <ftnfrm.hxx>
+#include <tabfrm.hxx>
+#include <rowfrm.hxx>
+#include <cellfrm.hxx>
+#include <notxtfrm.hxx>
+#include <swregion.hxx>
+#include <layact.hxx>
+#include <pagedesc.hxx>
+#include <ptqueue.hxx>
+#include <noteurl.hxx>
+#include <virtoutp.hxx>
+#include <lineinfo.hxx>
+#include <dbg_lay.hxx>
+#include <accessibilityoptions.hxx>
+#include <docsh.hxx>
+#include <swtable.hxx>
+#include <svx/svdogrp.hxx>
+#include <sortedobjs.hxx>
+#include <EnhancedPDFExportHelper.hxx>
+#include <ndole.hxx>
+#include <svtools/chartprettypainter.hxx>
+#include <PostItMgr.hxx>
+#include <tools/color.hxx>
+#include <vcl/svapp.hxx>
+
+#define COL_NOTES_SIDEPANE RGB_COLORDATA(230,230,230)
+#define COL_NOTES_SIDEPANE_BORDER RGB_COLORDATA(200,200,200)
+#define COL_NOTES_SIDEPANE_SCROLLAREA RGB_COLORDATA(230,230,220)
+
+#include <svtools/borderhelper.hxx>
+
+#include "pagefrm.hrc"
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/processor2d/baseprocessor2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
+#include <svx/sdr/contact/objectcontacttools.hxx>
+#include <svx/unoapi.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+using namespace ::editeng;
+using namespace ::com::sun::star;
+
+#define GETOBJSHELL() ((SfxObjectShell*)rSh.GetDoc()->GetDocShell())
+
+//Tabellenhilfslinien an?
+#define IS_SUBS_TABLE \
+ (pGlobalShell->GetViewOptions()->IsTable() && \
+ !pGlobalShell->GetViewOptions()->IsPagePreview()&&\
+ !pGlobalShell->GetViewOptions()->IsReadonly()&&\
+ !pGlobalShell->GetViewOptions()->IsFormView() &&\
+ SwViewOption::IsTableBoundaries())
+//sonstige Hilfslinien an?
+#define IS_SUBS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
+ !pGlobalShell->GetViewOptions()->IsReadonly() && \
+ !pGlobalShell->GetViewOptions()->IsFormView() &&\
+ SwViewOption::IsDocBoundaries())
+//Hilfslinien fuer Bereiche
+#define IS_SUBS_SECTION (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
+ !pGlobalShell->GetViewOptions()->IsReadonly()&&\
+ !pGlobalShell->GetViewOptions()->IsFormView() &&\
+ SwViewOption::IsSectionBoundaries())
+#define IS_SUBS_FLYS (!pGlobalShell->GetViewOptions()->IsPagePreview() && \
+ !pGlobalShell->GetViewOptions()->IsReadonly()&&\
+ !pGlobalShell->GetViewOptions()->IsFormView() &&\
+ SwViewOption::IsObjectBoundaries())
+
+#define SW_MAXBORDERCACHE 20
+
+//Klassendeklarationen. Hier weil sie eben nur in diesem File benoetigt
+//werden.
+
+#define SUBCOL_PAGE 0x01 //Helplines of the page
+#define SUBCOL_BREAK 0x02 //Helpline for a page or column break
+#define SUBCOL_TAB 0x08 //Helplines inside tables
+#define SUBCOL_FLY 0x10 //Helplines inside fly frames
+#define SUBCOL_SECT 0x20 //Helplines inside sections
+
+//----- Klassen zum Sammeln von Umrandungen und Hilfslinien ---
+class SwLineRect : public SwRect
+{
+ Color aColor;
+ SvxBorderStyle nStyle;
+ const SwTabFrm *pTab;
+ sal_uInt8 nSubColor; //Hilfslinien einfaerben
+ sal_Bool bPainted; //schon gepaintet?
+ sal_uInt8 nLock; //Um die Linien zum Hell-Layer abzugrenzen.
+public:
+ SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderStyle nStyle,
+ const SwTabFrm *pT , const sal_uInt8 nSCol );
+
+ const Color *GetColor() const { return &aColor;}
+ SvxBorderStyle GetStyle() const { return nStyle; }
+ const SwTabFrm *GetTab() const { return pTab; }
+ void SetPainted() { bPainted = sal_True; }
+ void Lock( sal_Bool bLock ) { if ( bLock )
+ ++nLock;
+ else if ( nLock )
+ --nLock;
+ }
+ sal_Bool IsPainted() const { return bPainted; }
+ sal_Bool IsLocked() const { return nLock != 0; }
+ sal_uInt8 GetSubColor() const { return nSubColor;}
+
+ sal_Bool MakeUnion( const SwRect &rRect );
+};
+
+SV_DECL_VARARR( SwLRects, SwLineRect, 100, 100 )
+
+class SwLineRects : public SwLRects
+{
+ sal_uInt16 nLastCount; //unuetze Durchlaeufe im PaintLines verhindern.
+public:
+ SwLineRects() : nLastCount( 0 ) {}
+ void AddLineRect( const SwRect& rRect, const Color *pColor, const SvxBorderStyle nStyle,
+ const SwTabFrm *pTab, const sal_uInt8 nSCol );
+ void ConnectEdges( OutputDevice *pOut );
+ void PaintLines ( OutputDevice *pOut );
+ void LockLines( sal_Bool bLock );
+
+ /// OD 13.08.2002 - correct type of function
+ sal_uInt16 Free() const { return nFree; }
+};
+
+class SwSubsRects : public SwLineRects
+{
+ void RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects ); //;-)
+public:
+ void PaintSubsidiary( OutputDevice *pOut, const SwLineRects *pRects );
+
+ inline void Ins( const SwRect &rRect, const sal_uInt8 nSCol );
+};
+
+//----------------- End Klassen Umrandungen ----------------------
+
+static ViewShell *pGlobalShell = 0;
+
+//Wenn durchsichtige FlyInCnts im PaintBackground gepainted werden so soll der
+//Hintergrund nicht mehr retouchiert werden.
+//static sal_Bool bLockFlyBackground = sal_False;
+
+//Wenn vom Fly ein Metafile abgezogen wird, so soll nur der FlyInhalt und vor
+//nur hintergrund vom FlyInhalt gepaintet werden.
+static sal_Bool bFlyMetafile = sal_False;
+static OutputDevice *pFlyMetafileOut = 0;
+
+//Die Retouche fuer Durchsichtige Flys wird vom Hintergrund der Flys
+//erledigt. Dabei darf der Fly selbst natuerlich nicht ausgespart werden.
+//siehe PaintBackground und lcl_SubtractFlys()
+static SwFlyFrm *pRetoucheFly = 0;
+static SwFlyFrm *pRetoucheFly2 = 0;
+
+//Groesse eines Pixel und die Haelfte davon. Wird jeweils bei Eintritt in
+//SwRootFrm::Paint neu gesetzt.
+static long nPixelSzW = 0, nPixelSzH = 0;
+static long nHalfPixelSzW = 0, nHalfPixelSzH = 0;
+static long nMinDistPixelW = 0, nMinDistPixelH = 0;
+
+//Aktueller Zoomfaktor
+static double aScaleX = 1.0;
+static double aScaleY = 1.0;
+static double aMinDistScale = 0.73;
+static double aEdgeScale = 0.5;
+
+//In pLines werden Umrandungen waehrend des Paint gesammelt und soweit
+//moeglich zusammengefasst.
+//In pSubsLines werden Hilfslinien gesammelt und zusammengefasst. Diese
+//werden vor der Ausgabe mit pLines abgeglichen, so dass moeglichst keine
+//Umrandungen von den Hilfslinen verdeckt werden.
+//bTablines ist waerend des Paints einer Tabelle sal_True.
+static SwLineRects *pLines = 0;
+static SwSubsRects *pSubsLines = 0;
+// OD 18.11.2002 #99672# - global variable for sub-lines of body, header, footer,
+// section and footnote frames.
+static SwSubsRects *pSpecSubsLines = 0;
+
+static SfxProgress *pProgress = 0;
+
+static SwFlyFrm *pFlyOnlyDraw = 0;
+
+//Damit die Flys auch fuer den Hack richtig gepaintet werden koennen.
+static sal_Bool bTableHack = sal_False;
+
+//Um das teure Ermitteln der RetoucheColor zu optimieren
+Color aGlobalRetoucheColor;
+
+//Statics fuer Umrandungsalignment setzen.
+// OD 05.05.2003 #107169# - adjustment for 'small' twip-to-pixel relations:
+// For 'small' twip-to-pixel relations (less then 2:1)
+// values of <nHalfPixelSzW> and <nHalfPixelSzH> are set to ZERO.
+void SwCalcPixStatics( OutputDevice *pOut )
+{
+ // OD 30.04.2003 #107169# - determine 'small' twip-to-pixel relation
+ sal_Bool bSmallTwipToPxRelW = sal_False;
+ sal_Bool bSmallTwipToPxRelH = sal_False;
+ {
+ Size aCheckTwipToPxRelSz( pOut->PixelToLogic( Size( 100, 100 )) );
+ if ( (aCheckTwipToPxRelSz.Width()/100.0) < 2.0 )
+ {
+ bSmallTwipToPxRelW = sal_True;
+ }
+ if ( (aCheckTwipToPxRelSz.Height()/100.0) < 2.0 )
+ {
+ bSmallTwipToPxRelH = sal_True;
+ }
+ }
+
+ Size aSz( pOut->PixelToLogic( Size( 1,1 )) );
+
+ nPixelSzW = aSz.Width();
+ if( !nPixelSzW )
+ nPixelSzW = 1;
+ nPixelSzH = aSz.Height();
+ if( !nPixelSzH )
+ nPixelSzH = 1;
+
+ // OD 06.05.2003 #107169# - consider 'small' twip-to-pixel relations
+ if ( !bSmallTwipToPxRelW )
+ {
+ nHalfPixelSzW = nPixelSzW / 2 + 1;
+ }
+ else
+ {
+ nHalfPixelSzW = 0;
+ }
+ // OD 06.05.2003 #107169# - consider 'small' twip-to-pixel relations
+ if ( !bSmallTwipToPxRelH )
+ {
+ nHalfPixelSzH = nPixelSzH / 2 + 1;
+ }
+ else
+ {
+ nHalfPixelSzH = 0;
+ }
+
+ nMinDistPixelW = nPixelSzW * 2 + 1;
+ nMinDistPixelH = nPixelSzH * 2 + 1;
+
+ const MapMode &rMap = pOut->GetMapMode();
+ aScaleX = rMap.GetScaleX();
+ aScaleY = rMap.GetScaleY();
+}
+
+//Zum Sichern der statics, damit das Paint (quasi) reentrant wird.
+class SwSavePaintStatics
+{
+ sal_Bool bSFlyMetafile,
+ bSPageOnly;
+ ViewShell *pSGlobalShell;
+ OutputDevice *pSFlyMetafileOut;
+ SwFlyFrm *pSRetoucheFly,
+ *pSRetoucheFly2,
+ *pSFlyOnlyDraw;
+ SwLineRects *pSLines;
+ SwSubsRects *pSSubsLines;
+ // --> OD 2005-07-04 #123196#
+ SwSubsRects* pSSpecSubsLines;
+ // <--
+ SfxProgress *pSProgress;
+ long nSPixelSzW,
+ nSPixelSzH,
+ nSHalfPixelSzW,
+ nSHalfPixelSzH,
+ nSMinDistPixelW,
+ nSMinDistPixelH;
+ Color aSGlobalRetoucheColor;
+ double aSScaleX,
+ aSScaleY;
+public:
+ SwSavePaintStatics();
+ ~SwSavePaintStatics();
+};
+
+SwSavePaintStatics::SwSavePaintStatics() :
+ bSFlyMetafile ( bFlyMetafile ),
+ pSGlobalShell ( pGlobalShell ),
+ pSFlyMetafileOut ( pFlyMetafileOut ),
+ pSRetoucheFly ( pRetoucheFly ),
+ pSRetoucheFly2 ( pRetoucheFly2 ),
+ pSFlyOnlyDraw ( pFlyOnlyDraw ),
+ pSLines ( pLines ),
+ pSSubsLines ( pSubsLines ),
+ // --> OD 2005-07-04 #123196#
+ pSSpecSubsLines ( pSpecSubsLines ),
+ // <--
+ pSProgress ( pProgress ),
+ nSPixelSzW ( nPixelSzW ),
+ nSPixelSzH ( nPixelSzH ),
+ nSHalfPixelSzW ( nHalfPixelSzW ),
+ nSHalfPixelSzH ( nHalfPixelSzH ),
+ nSMinDistPixelW ( nMinDistPixelW ),
+ nSMinDistPixelH ( nMinDistPixelH ),
+ aSGlobalRetoucheColor( aGlobalRetoucheColor ),
+ aSScaleX ( aScaleX ),
+ aSScaleY ( aScaleY )
+{
+ bFlyMetafile = sal_False;
+ pFlyMetafileOut = 0;
+ pRetoucheFly = 0;
+ pRetoucheFly2 = 0;
+ nPixelSzW = nPixelSzH =
+ nHalfPixelSzW = nHalfPixelSzH =
+ nMinDistPixelW = nMinDistPixelH = 0;
+ aScaleX = aScaleY = 1.0;
+ aMinDistScale = 0.73;
+ aEdgeScale = 0.5;
+ pLines = 0;
+ pSubsLines = 0;
+ // --> OD 2005-07-04 #123196#
+ pSpecSubsLines = 0L;
+ // <--
+ pProgress = 0;
+}
+
+SwSavePaintStatics::~SwSavePaintStatics()
+{
+ pGlobalShell = pSGlobalShell;
+ bFlyMetafile = bSFlyMetafile;
+ pFlyMetafileOut = pSFlyMetafileOut;
+ pRetoucheFly = pSRetoucheFly;
+ pRetoucheFly2 = pSRetoucheFly2;
+ pFlyOnlyDraw = pSFlyOnlyDraw;
+ pLines = pSLines;
+ pSubsLines = pSSubsLines;
+ // --> OD 2005-07-04 #123196#
+ pSpecSubsLines = pSSpecSubsLines;
+ // <--
+ pProgress = pSProgress;
+ nPixelSzW = nSPixelSzW;
+ nPixelSzH = nSPixelSzH;
+ nHalfPixelSzW = nSHalfPixelSzW;
+ nHalfPixelSzH = nSHalfPixelSzH;
+ nMinDistPixelW = nSMinDistPixelW;
+ nMinDistPixelH = nSMinDistPixelH;
+ aGlobalRetoucheColor = aSGlobalRetoucheColor;
+ aScaleX = aSScaleX;
+ aScaleY = aSScaleY;
+}
+
+//----------------- Implementierungen fuer Tabellenumrandung --------------
+
+SV_IMPL_VARARR( SwLRects, SwLineRect );
+
+SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderStyle nStyl,
+ const SwTabFrm *pT, const sal_uInt8 nSCol ) :
+ SwRect( rRect ),
+ nStyle( nStyl ),
+ pTab( pT ),
+ nSubColor( nSCol ),
+ bPainted( sal_False ),
+ nLock( 0 )
+{
+ if ( pCol != NULL )
+ aColor = *pCol;
+}
+
+sal_Bool SwLineRect::MakeUnion( const SwRect &rRect )
+{
+ //Es wurde bereits ausserhalb geprueft, ob die Rechtecke die gleiche
+ //Ausrichtung (horizontal bzw. vertikal), Farbe usw. besitzen.
+ if ( Height() > Width() ) //Vertikale Linie
+ {
+ if ( Left() == rRect.Left() && Width() == rRect.Width() )
+ {
+ //Zusammenfassen wenn kein Luecke zwischen den Linien ist.
+ const long nAdd = nPixelSzW + nHalfPixelSzW;
+ if ( Bottom() + nAdd >= rRect.Top() &&
+ Top() - nAdd <= rRect.Bottom() )
+ {
+ Bottom( Max( Bottom(), rRect.Bottom() ) );
+ Top ( Min( Top(), rRect.Top() ) );
+ return sal_True;
+ }
+ }
+ }
+ else
+ {
+ if ( Top() == rRect.Top() && Height() == rRect.Height() )
+ {
+ //Zusammenfassen wenn kein Luecke zwischen den Linien ist.
+ const long nAdd = nPixelSzW + nHalfPixelSzW;
+ if ( Right() + nAdd >= rRect.Left() &&
+ Left() - nAdd <= rRect.Right() )
+ {
+ Right( Max( Right(), rRect.Right() ) );
+ Left ( Min( Left(), rRect.Left() ) );
+ return sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+void SwLineRects::AddLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderStyle nStyle,
+ const SwTabFrm *pTab, const sal_uInt8 nSCol )
+{
+ //Rueckwaerts durch, weil Linien die zusammengefasst werden koennen i.d.R.
+ //im gleichen Kontext gepaintet werden.
+ for ( sal_uInt16 i = Count(); i ; )
+ {
+ SwLineRect &rLRect = operator[](--i);
+ //Pruefen von Ausrichtung, Farbe, Tabelle.
+ if ( rLRect.GetTab() == pTab &&
+ !rLRect.IsPainted() && rLRect.GetSubColor() == nSCol &&
+ (rLRect.Height() > rLRect.Width()) == (rRect.Height() > rRect.Width()) &&
+ ((!rLRect.GetColor() && !pCol) ||
+ (rLRect.GetColor() && pCol && *rLRect.GetColor() == *pCol)) )
+ {
+ if ( rLRect.MakeUnion( rRect ) )
+ return;
+ }
+ }
+ Insert( SwLineRect( rRect, pCol, nStyle, pTab, nSCol ), Count() );
+}
+
+void SwLineRects::ConnectEdges( OutputDevice *pOut )
+{
+ if ( pOut->GetOutDevType() != OUTDEV_PRINTER )
+ {
+ //Fuer einen zu kleinen Zoom arbeite ich nicht.
+ if ( aScaleX < aEdgeScale || aScaleY < aEdgeScale )
+ return;
+ }
+
+ static const long nAdd = 20;
+
+ SvPtrarr aCheck( 64, 64 );
+
+ for ( int i = 0; i < (int)Count(); ++i )
+ {
+ SwLineRect &rL1 = operator[](sal_uInt16(i));
+ if ( !rL1.GetTab() || rL1.IsPainted() || rL1.IsLocked() )
+ continue;
+
+ aCheck.Remove( 0, aCheck.Count() );
+
+ const sal_Bool bVert = rL1.Height() > rL1.Width();
+ long nL1a, nL1b, nL1c, nL1d;
+
+ if ( bVert )
+ {
+ nL1a = rL1.Top(); nL1b = rL1.Left();
+ nL1c = rL1.Right(); nL1d = rL1.Bottom();
+ }
+ else
+ {
+ nL1a = rL1.Left(); nL1b = rL1.Top();
+ nL1c = rL1.Bottom(); nL1d = rL1.Right();
+ }
+
+ //Alle moeglicherweise mit i1 zu verbindenden Linien einsammeln.
+ for ( sal_uInt16 i2 = 0; i2 < Count(); ++i2 )
+ {
+ SwLineRect &rL2 = operator[](i2);
+ if ( rL2.GetTab() != rL1.GetTab() ||
+ rL2.IsPainted() ||
+ rL2.IsLocked() ||
+ (bVert == (rL2.Height() > rL2.Width())) )
+ continue;
+
+ long nL2a, nL2b, nL2c, nL2d;
+ if ( bVert )
+ {
+ nL2a = rL2.Top(); nL2b = rL2.Left();
+ nL2c = rL2.Right(); nL2d = rL2.Bottom();
+ }
+ else
+ {
+ nL2a = rL2.Left(); nL2b = rL2.Top();
+ nL2c = rL2.Bottom(); nL2d = rL2.Right();
+ }
+
+ if ( (nL1a - nAdd < nL2d && nL1d + nAdd > nL2a) &&
+ ((nL1b > nL2b && nL1c < nL2c) ||
+ (nL1c >= nL2c && nL1b - nAdd < nL2c) ||
+ (nL1b <= nL2b && nL1c + nAdd > nL2b)) )
+ {
+ SwLineRect *pMSC = &rL2;
+ aCheck.Insert( pMSC, aCheck.Count() );
+ }
+ }
+ if ( aCheck.Count() < 2 )
+ continue;
+
+ sal_Bool bRemove = sal_False;
+
+ //Fuer jede Linie jede alle folgenden checken.
+ for ( sal_uInt16 k = 0; !bRemove && k < aCheck.Count(); ++k )
+ {
+ SwLineRect &rR1 = (SwLineRect&)*(SwLineRect*)aCheck[k];
+
+ for ( sal_uInt16 k2 = k+1; !bRemove && k2 < aCheck.Count(); ++k2 )
+ {
+ SwLineRect &rR2 = (SwLineRect&)*(SwLineRect*)aCheck[k2];
+ if ( bVert )
+ {
+ SwLineRect *pLA = 0;
+ SwLineRect *pLB = 0;
+ if ( rR1.Top() < rR2.Top() )
+ {
+ pLA = &rR1; pLB = &rR2;
+ }
+ else if ( rR1.Top() > rR2.Top() )
+ {
+ pLA = &rR2; pLB = &rR1;
+ }
+ //beschreiben k1 und k2 eine Doppellinie?
+ if ( pLA && pLA->Bottom() + 60 > pLB->Top() )
+ {
+ if ( rL1.Top() < pLA->Top() )
+ {
+ if ( rL1.Bottom() == pLA->Bottom() )
+ continue; //kleiner Irrtum (woher?)
+
+ SwRect aIns( rL1 );
+ aIns.Bottom( pLA->Bottom() );
+ if ( !rL1.IsInside( aIns ) )
+ continue;
+ const sal_uInt16 nTmpFree = Free();
+ Insert( SwLineRect( aIns, rL1.GetColor(), SOLID,
+ rL1.GetTab(), SUBCOL_TAB ), Count() );
+ if ( !nTmpFree )
+ {
+ --i;
+ k = aCheck.Count();
+ break;
+ }
+ }
+
+ if ( rL1.Bottom() > pLB->Bottom() )
+ rL1.Top( pLB->Top() ); //i1 nach oben verlaengern
+ else
+ bRemove = sal_True; //abbrechen, i1 entfernen
+ }
+ }
+ else
+ {
+ SwLineRect *pLA = 0;
+ SwLineRect *pLB = 0;
+ if ( rR1.Left() < rR2.Left() )
+ {
+ pLA = &rR1; pLB = &rR2;
+ }
+ else if ( rR1.Left() > rR2.Left() )
+ {
+ pLA = &rR2; pLB = &rR1;
+ }
+ //Liegt eine 'doppellinie' vor?
+ if ( pLA && pLA->Right() + 60 > pLB->Left() )
+ {
+ if ( rL1.Left() < pLA->Left() )
+ {
+ if ( rL1.Right() == pLA->Right() )
+ continue; //kleiner irrtum
+
+ SwRect aIns( rL1 );
+ aIns.Right( pLA->Right() );
+ if ( !rL1.IsInside( aIns ) )
+ continue;
+ const sal_uInt16 nTmpFree = Free();
+ Insert( SwLineRect( aIns, rL1.GetColor(), SOLID,
+ rL1.GetTab(), SUBCOL_TAB ), Count() );
+ if ( !nTmpFree )
+ {
+ --i;
+ k = aCheck.Count();
+ break;
+ }
+ }
+ if ( rL1.Right() > pLB->Right() )
+ rL1.Left( pLB->Left() );
+ else
+ bRemove = sal_True;
+ }
+ }
+ }
+ }
+ if ( bRemove )
+ {
+ Remove( static_cast<sal_uInt16>(i), 1 );
+ --i; //keinen auslassen!
+ }
+ }
+}
+
+inline void SwSubsRects::Ins( const SwRect &rRect, const sal_uInt8 nSCol )
+{
+ //Linien die kuerzer als die breiteste Linienbreite sind werden
+ //nicht aufgenommen.
+ if ( rRect.Height() > DEF_LINE_WIDTH_4 || rRect.Width() > DEF_LINE_WIDTH_4 )
+ Insert( SwLineRect( rRect, 0, SOLID, 0, nSCol ), Count());
+}
+
+void SwSubsRects::RemoveSuperfluousSubsidiaryLines( const SwLineRects &rRects )
+{
+ //Alle Hilfslinien, die sich mit irgendwelchen Umrandungen decken werden
+ //entfernt bzw. zerstueckelt..
+ for ( sal_uInt16 i = 0; i < Count(); ++i )
+ {
+ // OD 18.11.2002 #99672# - get a copy instead of a reference, because
+ // an <insert> may destroy the object due to a necessary array resize.
+ const SwLineRect aSubsLineRect = SwLineRect( operator[](i) );
+
+ // OD 19.12.2002 #106318# - add condition <aSubsLineRect.IsLocked()>
+ // in order to consider only border lines, which are *not* locked.
+ if ( aSubsLineRect.IsPainted() ||
+ aSubsLineRect.IsLocked() )
+ continue;
+
+ const bool bVerticalSubs = aSubsLineRect.Height() > aSubsLineRect.Width();
+ SwRect aSubsRect( aSubsLineRect );
+ if ( bVerticalSubs )
+ {
+ aSubsRect.Left ( aSubsRect.Left() - (nPixelSzW+nHalfPixelSzW) );
+ aSubsRect.Right ( aSubsRect.Right() + (nPixelSzW+nHalfPixelSzW) );
+ }
+ else
+ {
+ aSubsRect.Top ( aSubsRect.Top() - (nPixelSzH+nHalfPixelSzH) );
+ aSubsRect.Bottom( aSubsRect.Bottom() + (nPixelSzH+nHalfPixelSzH) );
+ }
+ for ( sal_uInt16 k = 0; k < rRects.Count(); ++k )
+ {
+ SwLineRect &rLine = rRects[k];
+
+ // OD 20.12.2002 #106318# - do *not* consider painted or locked
+ // border lines.
+ // OD 20.01.2003 #i1837# - locked border lines have to be considered.
+ if ( rLine.IsLocked () )
+ continue;
+
+ if ( !bVerticalSubs == ( rLine.Height() > rLine.Width() ) ) //same direction?
+ continue;
+
+ if ( aSubsRect.IsOver( rLine ) )
+ {
+ if ( bVerticalSubs ) // Vertical?
+ {
+ if ( aSubsRect.Left() <= rLine.Right() &&
+ aSubsRect.Right() >= rLine.Left() )
+ {
+ long nTmp = rLine.Top()-(nPixelSzH+1);
+ if ( aSubsLineRect.Top() < nTmp )
+ {
+ SwRect aNewSubsRect( aSubsLineRect );
+ aNewSubsRect.Bottom( nTmp );
+ Insert( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
+ aSubsLineRect.GetSubColor() ), Count());
+ }
+ nTmp = rLine.Bottom()+nPixelSzH+1;
+ if ( aSubsLineRect.Bottom() > nTmp )
+ {
+ SwRect aNewSubsRect( aSubsLineRect );
+ aNewSubsRect.Top( nTmp );
+ Insert( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
+ aSubsLineRect.GetSubColor() ), Count());
+ }
+ Remove( i, 1 );
+ --i;
+ break;
+ }
+ }
+ else //Horizontal
+ {
+ if ( aSubsRect.Top() <= rLine.Bottom() &&
+ aSubsRect.Bottom() >= rLine.Top() )
+ {
+ long nTmp = rLine.Left()-(nPixelSzW+1);
+ if ( aSubsLineRect.Left() < nTmp )
+ {
+ SwRect aNewSubsRect( aSubsLineRect );
+ aNewSubsRect.Right( nTmp );
+ Insert( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
+ aSubsLineRect.GetSubColor() ), Count());
+ }
+ nTmp = rLine.Right()+nPixelSzW+1;
+ if ( aSubsLineRect.Right() > nTmp )
+ {
+ SwRect aNewSubsRect( aSubsLineRect );
+ aNewSubsRect.Left( nTmp );
+ Insert( SwLineRect( aNewSubsRect, 0, aSubsLineRect.GetStyle(), 0,
+ aSubsLineRect.GetSubColor() ), Count());
+ }
+ Remove( i, 1 );
+ --i;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void SwLineRects::LockLines( sal_Bool bLock )
+{
+ for ( sal_uInt16 i = 0; i < Count(); ++i )
+ operator[](i).Lock( bLock );
+}
+
+void lcl_DrawDashedRect( OutputDevice * pOut, SwLineRect & rLRect )
+{
+ double nHalfLWidth = rLRect.Height( );
+ if ( nHalfLWidth > 1 )
+ {
+ nHalfLWidth = nHalfLWidth / 2;
+ }
+ else
+ {
+ nHalfLWidth = 1;
+ }
+
+ long startX = rLRect.Left( );
+ long startY = rLRect.Top( ) + nHalfLWidth;
+ long endX = rLRect.Left( ) + rLRect.Width( );
+ long endY = rLRect.Top( ) + nHalfLWidth;
+
+ if ( rLRect.Height( ) > rLRect.Width( ) )
+ {
+ nHalfLWidth = rLRect.Width( );
+ if ( nHalfLWidth > 1 )
+ {
+ nHalfLWidth = nHalfLWidth / 2;
+ }
+ else
+ {
+ nHalfLWidth = 1;
+ }
+ startX = rLRect.Left( ) + nHalfLWidth;
+ startY = rLRect.Top( );
+ endX = rLRect.Left( ) + nHalfLWidth;
+ endY = rLRect.Top( ) + rLRect.Height( );
+ }
+
+ svtools::DrawLine( *pOut, Point( startX, startY ), Point( endX, endY ),
+ sal_uInt32( nHalfLWidth * 2 ), rLRect.GetStyle( ) );
+}
+
+void SwLineRects::PaintLines( OutputDevice *pOut )
+{
+ //Painten der Umrandungen. Leider muessen wir zweimal durch.
+ //Einmal fuer die innenliegenden und einmal fuer die Aussenkanten
+ //der Tabellen.
+ if ( Count() != nLastCount )
+ {
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
+ // <--
+
+ // OD 2004-04-23 #116347#
+ pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
+ pOut->SetFillColor();
+ pOut->SetLineColor();
+ ConnectEdges( pOut );
+ const Color *pLast = 0;
+
+ sal_Bool bPaint2nd = sal_False;
+ sal_uInt16 nMinCount = Count();
+ sal_uInt16 i;
+
+ for ( i = 0; i < Count(); ++i )
+ {
+ SwLineRect &rLRect = operator[](i);
+
+ if ( rLRect.IsPainted() )
+ continue;
+
+ if ( rLRect.IsLocked() )
+ {
+ nMinCount = Min( nMinCount, i );
+ continue;
+ }
+
+ //Jetzt malen oder erst in der zweiten Runde?
+ sal_Bool bPaint = sal_True;
+ if ( rLRect.GetTab() )
+ {
+ if ( rLRect.Height() > rLRect.Width() )
+ {
+ //Senkrechte Kante, ueberlappt sie mit der TabellenKante?
+ SwTwips nLLeft = rLRect.Left() - 30,
+ nLRight = rLRect.Right() + 30,
+ nTLeft = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Left(),
+ nTRight = rLRect.GetTab()->Frm().Left() + rLRect.GetTab()->Prt().Right();
+ if ( (nTLeft >= nLLeft && nTLeft <= nLRight) ||
+ (nTRight>= nLLeft && nTRight<= nLRight) )
+ bPaint = sal_False;
+ }
+ else
+ { //Waagerechte Kante, ueberlappt sie mit der Tabellenkante?
+ SwTwips nLTop = rLRect.Top() - 30,
+ nLBottom = rLRect.Bottom() + 30,
+ nTTop = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Top(),
+ nTBottom = rLRect.GetTab()->Frm().Top() + rLRect.GetTab()->Prt().Bottom();
+ if ( (nTTop >= nLTop && nTTop <= nLBottom) ||
+ (nTBottom >= nLTop && nTBottom <= nLBottom) )
+ bPaint = sal_False;
+ }
+ }
+ if ( bPaint )
+ {
+ if ( !pLast || *pLast != *rLRect.GetColor() )
+ {
+ pLast = rLRect.GetColor();
+
+ sal_uLong nOldDrawMode = pOut->GetDrawMode();
+ if( pGlobalShell->GetWin() &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ pOut->SetDrawMode( 0 );
+
+ pOut->SetLineColor( *pLast );
+ pOut->SetFillColor( *pLast );
+ pOut->SetDrawMode( nOldDrawMode );
+ }
+
+ if( !rLRect.IsEmpty() )
+ lcl_DrawDashedRect( pOut, rLRect );
+ rLRect.SetPainted();
+ }
+ else
+ bPaint2nd = sal_True;
+ }
+ if ( bPaint2nd )
+ for ( i = 0; i < Count(); ++i )
+ {
+ SwLineRect &rLRect = operator[](i);
+ if ( rLRect.IsPainted() )
+ continue;
+
+ if ( rLRect.IsLocked() )
+ {
+ nMinCount = Min( nMinCount, i );
+ continue;
+ }
+
+ if ( !pLast || *pLast != *rLRect.GetColor() )
+ {
+ pLast = rLRect.GetColor();
+
+ sal_uLong nOldDrawMode = pOut->GetDrawMode();
+ if( pGlobalShell->GetWin() &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pOut->SetDrawMode( 0 );
+ }
+
+ pOut->SetFillColor( *pLast );
+ pOut->SetDrawMode( nOldDrawMode );
+ }
+ if( !rLRect.IsEmpty() )
+ lcl_DrawDashedRect( pOut, rLRect );
+ rLRect.SetPainted();
+ }
+ nLastCount = nMinCount;
+ pOut->Pop();
+ }
+}
+
+void SwSubsRects::PaintSubsidiary( OutputDevice *pOut,
+ const SwLineRects *pRects )
+{
+ if ( Count() )
+ {
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
+ // <--
+
+ //Alle Hilfslinien, die sich fast decken entfernen (Tabellen)
+ for ( sal_uInt16 i = 0; i < Count(); ++i )
+ {
+ SwLineRect &rLi = operator[](i);
+ const bool bVerticalSubs = rLi.Height() > rLi.Width();
+
+ for ( sal_uInt16 k = i+1; k < Count(); ++k )
+ {
+ SwLineRect &rLk = operator[](k);
+ if ( rLi.SSize() == rLk.SSize() )
+ {
+ if ( bVerticalSubs == ( rLk.Height() > rLk.Width() ) )
+ {
+ if ( bVerticalSubs )
+ {
+ long nLi = rLi.Right();
+ long nLk = rLk.Right();
+ if ( rLi.Top() == rLk.Top() &&
+ ((nLi < rLk.Left() && nLi+21 > rLk.Left()) ||
+ (nLk < rLi.Left() && nLk+21 > rLi.Left())))
+ {
+ Remove( k, 1 );
+ //Nicht mit der inneren Schleife weiter, weil
+ //das Array schrumpfen koennte!
+ --i; k = Count();
+ }
+ }
+ else
+ {
+ long nLi = rLi.Bottom();
+ long nLk = rLk.Bottom();
+ if ( rLi.Left() == rLk.Left() &&
+ ((nLi < rLk.Top() && nLi+21 > rLk.Top()) ||
+ (nLk < rLi.Top() && nLk+21 > rLi.Top())))
+ {
+ Remove( k, 1 );
+ --i; k = Count();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( pRects && pRects->Count() )
+ RemoveSuperfluousSubsidiaryLines( *pRects );
+
+ if ( Count() )
+ {
+ // OD 2004-04-23 #116347#
+ pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
+ pOut->SetLineColor();
+
+ // OD 14.01.2003 #106660# - reset draw mode in high contrast
+ // mode in order to get fill color set at output device.
+ // Recover draw mode after draw of lines.
+ // Necessary for the subsidiary lines painted by the fly frames.
+ sal_uLong nOldDrawMode = pOut->GetDrawMode();
+ if( pGlobalShell->GetWin() &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pOut->SetDrawMode( 0 );
+ }
+
+ for ( sal_uInt16 i = 0; i < Count(); ++i )
+ {
+ SwLineRect &rLRect = operator[](i);
+ // OD 19.12.2002 #106318# - add condition <!rLRect.IsLocked()>
+ // to prevent paint of locked subsidiary lines.
+ if ( !rLRect.IsPainted() &&
+ !rLRect.IsLocked() )
+ {
+ const Color *pCol = 0;
+ switch ( rLRect.GetSubColor() )
+ {
+ case SUBCOL_PAGE: pCol = &SwViewOption::GetDocBoundariesColor(); break;
+ case SUBCOL_FLY: pCol = &SwViewOption::GetObjectBoundariesColor(); break;
+ case SUBCOL_TAB: pCol = &SwViewOption::GetTableBoundariesColor(); break;
+ case SUBCOL_SECT: pCol = &SwViewOption::GetSectionBoundColor(); break;
+ case SUBCOL_BREAK: pCol = &SwViewOption::GetPageBreakColor(); break;
+ }
+
+ if ( pOut->GetFillColor() != *pCol )
+ pOut->SetFillColor( *pCol );
+ pOut->DrawRect( rLRect.SVRect() );
+
+ rLRect.SetPainted();
+ }
+ }
+
+ // OD 14.01.2003 #106660# - recovering draw mode
+ pOut->SetDrawMode( nOldDrawMode );
+
+ pOut->Pop();
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+//Diverse Functions die in diesem File so verwendet werden.
+
+// OD 20.02.2003 - Note: function <SwAlignRect(..)> also used outside this file.
+// OD 29.04.2003 #107169# - correction: adjust rectangle on pixel level in order
+// to assure, that the border 'leaves its original pixel', if it has to.
+// No prior adjustments for odd relation between pixel and twip.
+void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh )
+{
+ if( !rRect.HasArea() )
+ return;
+
+ // OD 03.09.2002 #102450#
+ // Assure that view shell (parameter <pSh>) exists, if the output device
+ // is taken from this view shell --> no output device, no alignment.
+ // Output device taken from view shell <pSh>, if <bFlyMetafile> not set.
+ if ( !bFlyMetafile && !pSh )
+ {
+ return;
+ }
+
+ const OutputDevice *pOut = bFlyMetafile ?
+ pFlyMetafileOut : pSh->GetOut();
+
+ // OD 28.04.2003 #107169# - hold original rectangle in pixel
+ const Rectangle aOrgPxRect = pOut->LogicToPixel( rRect.SVRect() );
+ // OD 29.04.2003 #107169# - determine pixel-center rectangle in twip
+ const SwRect aPxCenterRect( pOut->PixelToLogic( aOrgPxRect ) );
+
+ // OD 06.05.2003 #107169# - perform adjustments on pixel level.
+ SwRect aAlignedPxRect( aOrgPxRect );
+ if ( rRect.Top() > aPxCenterRect.Top() )
+ {
+ // 'leave pixel overlapping on top'
+ aAlignedPxRect.Top( aAlignedPxRect.Top() + 1 );
+ }
+
+ if ( rRect.Bottom() < aPxCenterRect.Bottom() )
+ {
+ // 'leave pixel overlapping on bottom'
+ aAlignedPxRect.Bottom( aAlignedPxRect.Bottom() - 1 );
+ }
+
+ if ( rRect.Left() > aPxCenterRect.Left() )
+ {
+ // 'leave pixel overlapping on left'
+ aAlignedPxRect.Left( aAlignedPxRect.Left() + 1 );
+ }
+
+ if ( rRect.Right() < aPxCenterRect.Right() )
+ {
+ // 'leave pixel overlapping on right'
+ aAlignedPxRect.Right( aAlignedPxRect.Right() - 1 );
+ }
+
+ // OD 11.10.2002 #103636# - consider negative width/height
+ // check, if aligned SwRect has negative width/height.
+ // If Yes, adjust it to width/height = 0 twip.
+ // NOTE: A SwRect with negative width/height can occur, if the width/height
+ // of the given SwRect in twip was less than a pixel in twip and that
+ // the alignment calculates that the aligned SwRect should not contain
+ // the pixels the width/height is on.
+ if ( aAlignedPxRect.Width() < 0 )
+ {
+ aAlignedPxRect.Width(0);
+ }
+ if ( aAlignedPxRect.Height() < 0 )
+ {
+ aAlignedPxRect.Height(0);
+ }
+ // OD 30.04.2003 #107169# - consider zero width/height
+ // For converting a rectangle from pixel to logic it needs a width/height.
+ // Thus, set width/height to one, if it's zero and correct this on the twip
+ // level after the conversion.
+ sal_Bool bZeroWidth = sal_False;
+ if ( aAlignedPxRect.Width() == 0 )
+ {
+ aAlignedPxRect.Width(1);
+ bZeroWidth = sal_True;
+ }
+ sal_Bool bZeroHeight = sal_False;
+ if ( aAlignedPxRect.Height() == 0 )
+ {
+ aAlignedPxRect.Height(1);
+ bZeroHeight = sal_True;
+ }
+
+ rRect = pOut->PixelToLogic( aAlignedPxRect.SVRect() );
+
+ // OD 30.04.2003 #107169# - consider zero width/height and adjust calculated
+ // aligned twip rectangle.
+ // OD 19.05.2003 #109667# - reset width/height to zero; previous negative
+ // width/height haven't to be considered.
+ if ( bZeroWidth )
+ {
+ rRect.Width(0);
+ }
+ if ( bZeroHeight )
+ {
+ rRect.Height(0);
+ }
+}
+
+/** OD 19.05.2003 #109667# - helper method for twip adjustments on pixel base
+
+ method compares the x- or y-pixel position of two twip-point. If the x-/y-pixel
+ positions are the same, the x-/y-pixel position of the second twip point is
+ adjusted by a given amount of pixels.
+
+ @author OD
+*/
+void lcl_CompPxPosAndAdjustPos( const OutputDevice& _rOut,
+ const Point& _rRefPt,
+ Point& _rCompPt,
+ const sal_Bool _bChkXPos,
+ const sal_Int8 _nPxAdjustment )
+{
+ const Point aRefPxPt = _rOut.LogicToPixel( _rRefPt );
+ Point aCompPxPt = _rOut.LogicToPixel( _rCompPt );
+
+ if ( _bChkXPos )
+ {
+ if ( aCompPxPt.X() == aRefPxPt.X() )
+ {
+ aCompPxPt.X() += _nPxAdjustment ;
+ const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
+ _rCompPt.X() = aAdjustedCompPt.X();
+ }
+ }
+ else
+ {
+ if ( aCompPxPt.Y() == aRefPxPt.Y() )
+ {
+ aCompPxPt.Y() += _nPxAdjustment ;
+ const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
+ _rCompPt.Y() = aAdjustedCompPt.Y();
+ }
+ }
+}
+
+/** OD 25.09.2002 #99739# - method to pixel-align rectangle for drawing graphic object
+
+ Because for drawing a graphic left-top-corner and size coordinations are
+ used, these coordinations have to be determined on pixel level.
+ Thus, convert rectangle to pixel and then convert left-top-corner and
+ size of pixel rectangle back to logic.
+ This calculation is necessary, because there exists a different between
+ the convert from logic to pixel of a normal rectangle with its left-top-
+ and right-bottom-corner and the same convert of the same rectangle
+ with left-top-corner and size.
+ Call this method before each <GraphicObject.Draw(...)>
+
+ @author OD
+*/
+void SwAlignGrfRect( SwRect *pGrfRect, const OutputDevice &rOut )
+{
+ Rectangle aPxRect = rOut.LogicToPixel( pGrfRect->SVRect() );
+ pGrfRect->Pos( rOut.PixelToLogic( aPxRect.TopLeft() ) );
+ pGrfRect->SSize( rOut.PixelToLogic( aPxRect.GetSize() ) );
+}
+
+long MA_FASTCALL lcl_AlignWidth( const long nWidth )
+{
+ if ( nWidth )
+ {
+ const long nW = nWidth % nPixelSzW;
+
+ if ( !nW || nW > nHalfPixelSzW )
+ return Max(1L, nWidth - nHalfPixelSzW);
+ }
+ return nWidth;
+}
+
+long MA_FASTCALL lcl_AlignHeight( const long nHeight )
+{
+ if ( nHeight )
+ {
+ const long nH = nHeight % nPixelSzH;
+
+ if ( !nH || nH > nHalfPixelSzH )
+ return Max(1L, nHeight - nHalfPixelSzH);
+ }
+ return nHeight;
+}
+
+long MA_FASTCALL lcl_MinHeightDist( const long nDist )
+{
+ if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale )
+ return nDist;
+ return ::lcl_AlignHeight( Max( nDist, nMinDistPixelH ));
+}
+
+long MA_FASTCALL lcl_MinWidthDist( const long nDist )
+{
+ if ( aScaleX < aMinDistScale || aScaleY < aMinDistScale )
+ return nDist;
+ return ::lcl_AlignWidth( Max( nDist, nMinDistPixelW ));
+}
+
+//Ermittelt PrtArea plus Umrandung plus Schatten.
+void MA_FASTCALL lcl_CalcBorderRect( SwRect &rRect, const SwFrm *pFrm,
+ const SwBorderAttrs &rAttrs,
+ const sal_Bool bShadow )
+{
+ // OD 23.01.2003 #106386# - special handling for cell frames.
+ // The printing area of a cell frame is completely enclosed in the frame area
+ // and a cell frame has no shadow. Thus, for cell frames the calculated
+ // area equals the frame area.
+ // Notes: Borders of cell frames in R2L text direction will switch its side
+ // - left border is painted on the right; right border on the left.
+ // See <lcl_PaintLeftLine> and <lcl_PaintRightLine>.
+ if( pFrm->IsSctFrm() )
+ {
+ rRect = pFrm->Prt();
+ rRect.Pos() += pFrm->Frm().Pos();
+ }
+ else if ( pFrm->IsCellFrm() )
+ rRect = pFrm->Frm();
+ else
+ {
+ rRect = pFrm->Prt();
+ rRect.Pos() += pFrm->Frm().Pos();
+
+ if ( rAttrs.IsLine() || rAttrs.IsBorderDist() ||
+ (bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE) )
+ {
+ //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
+ SwRectFn fnRect = pFrm->IsVertical() ? ( pFrm->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+
+ const SvxBoxItem &rBox = rAttrs.GetBox();
+ const sal_Bool bTop = 0 != (pFrm->*fnRect->fnGetTopMargin)();
+ if ( bTop )
+ {
+ SwTwips nDiff = rBox.GetTop() ?
+ rBox.CalcLineSpace( BOX_LINE_TOP ) :
+ ( rAttrs.IsBorderDist() ?
+ // OD 23.01.2003 #106386# - increase of distance by
+ // one twip is incorrect.
+ rBox.GetDistance( BOX_LINE_TOP ) : 0 );
+ if( nDiff )
+ (rRect.*fnRect->fnSubTop)( nDiff );
+ }
+
+ const sal_Bool bBottom = 0 != (pFrm->*fnRect->fnGetBottomMargin)();
+ if ( bBottom )
+ {
+ SwTwips nDiff = 0;
+ // --> collapsing borders FME 2005-05-27 #i29550#
+ if ( pFrm->IsTabFrm() &&
+ ((SwTabFrm*)pFrm)->IsCollapsingBorders() )
+ {
+ // For collapsing borders, we have to add the height of
+ // the height of the last line
+ nDiff = ((SwTabFrm*)pFrm)->GetBottomLineSize();
+ }
+ // <-- collapsing
+ else
+ {
+ nDiff = rBox.GetBottom() ?
+ rBox.CalcLineSpace( BOX_LINE_BOTTOM ) :
+ ( rAttrs.IsBorderDist() ?
+ // OD 23.01.2003 #106386# - increase of distance by
+ // one twip is incorrect.
+ rBox.GetDistance( BOX_LINE_BOTTOM ) : 0 );
+ }
+ if( nDiff )
+ (rRect.*fnRect->fnAddBottom)( nDiff );
+ }
+
+ if ( rBox.GetLeft() )
+ (rRect.*fnRect->fnSubLeft)( rBox.CalcLineSpace( BOX_LINE_LEFT ) );
+ else if ( rAttrs.IsBorderDist() )
+ // OD 23.01.2003 #106386# - increase of distance by one twip is incorrect.
+ (rRect.*fnRect->fnSubLeft)( rBox.GetDistance( BOX_LINE_LEFT ) );
+
+ if ( rBox.GetRight() )
+ (rRect.*fnRect->fnAddRight)( rBox.CalcLineSpace( BOX_LINE_RIGHT ) );
+ else if ( rAttrs.IsBorderDist() )
+ // OD 23.01.2003 #106386# - increase of distance by one twip is incorrect.
+ (rRect.*fnRect->fnAddRight)( rBox.GetDistance( BOX_LINE_RIGHT ) );
+
+ if ( bShadow && rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
+ {
+ const SvxShadowItem &rShadow = rAttrs.GetShadow();
+ if ( bTop )
+ (rRect.*fnRect->fnSubTop)(rShadow.CalcShadowSpace(SHADOW_TOP));
+ (rRect.*fnRect->fnSubLeft)(rShadow.CalcShadowSpace(SHADOW_LEFT));
+ if ( bBottom )
+ (rRect.*fnRect->fnAddBottom)
+ (rShadow.CalcShadowSpace( SHADOW_BOTTOM ));
+ (rRect.*fnRect->fnAddRight)(rShadow.CalcShadowSpace(SHADOW_RIGHT));
+ }
+ }
+ }
+
+ ::SwAlignRect( rRect, pGlobalShell );
+}
+
+void MA_FASTCALL lcl_ExtendLeftAndRight( SwRect& _rRect,
+ const SwFrm& _rFrm,
+ const SwBorderAttrs& _rAttrs,
+ const SwRectFn& _rRectFn )
+{
+ // OD 21.05.2003 #108789# - extend left/right border/shadow rectangle to
+ // bottom of previous frame/to top of next frame, if border/shadow is joined
+ // with previous/next frame.
+ if ( _rAttrs.JoinedWithPrev( _rFrm ) )
+ {
+ const SwFrm* pPrevFrm = _rFrm.GetPrev();
+ (_rRect.*_rRectFn->fnSetTop)( (pPrevFrm->*_rRectFn->fnGetPrtBottom)() );
+ }
+ if ( _rAttrs.JoinedWithNext( _rFrm ) )
+ {
+ const SwFrm* pNextFrm = _rFrm.GetNext();
+ (_rRect.*_rRectFn->fnSetBottom)( (pNextFrm->*_rRectFn->fnGetPrtTop)() );
+ }
+}
+
+void MA_FASTCALL lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage,
+ const SwRect &rRect, SwRegionRects &rRegion )
+{
+ const SwSortedObjs& rObjs = *pPage->GetSortedObjs();
+ const SwFlyFrm* pSelfFly = pFrm->IsInFly() ? pFrm->FindFlyFrm() : pRetoucheFly2;
+ if ( !pRetoucheFly )
+ pRetoucheFly = pRetoucheFly2;
+
+ for ( sal_uInt16 j = 0; (j < rObjs.Count()) && rRegion.Count(); ++j )
+ {
+ const SwAnchoredObject* pAnchoredObj = rObjs[j];
+ const SdrObject* pSdrObj = pAnchoredObj->GetDrawObj();
+
+ // OD 2004-01-15 #110582# - do not consider invisible objects
+ if ( !pPage->GetFmt()->GetDoc()->IsVisibleLayerId( pSdrObj->GetLayer() ) )
+ continue;
+
+ if ( !pAnchoredObj->ISA(SwFlyFrm) )
+ continue;
+
+ const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
+
+ if ( pSelfFly == pFly || pRetoucheFly == pFly || !rRect.IsOver( pFly->Frm() ) )
+ continue;
+
+ if ( !pFly->GetFmt()->GetPrint().GetValue() &&
+ (OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() ||
+ pGlobalShell->IsPreView()))
+ continue;
+
+ const sal_Bool bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly ) ?
+ sal_True : sal_False;
+
+ //Bei zeichengebundenem Fly nur diejenigen betrachten, in denen er
+ //nicht selbst verankert ist.
+ //#33429# Warum nur bei zeichengebundenen? Es macht doch nie Sinn
+ //Rahmen abzuziehen in denen er selbst verankert ist oder?
+ if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
+ continue;
+
+ //#57194# Und warum gilt das nicht analog fuer den RetoucheFly?
+ if ( pRetoucheFly && pRetoucheFly->IsLowerOf( pFly ) )
+ continue;
+
+#if OSL_DEBUG_LEVEL > 1
+ //Flys, die innerhalb des eigenen verankert sind, muessen eine
+ //groessere OrdNum haben oder Zeichengebunden sein.
+ if ( pSelfFly && bLowerOfSelf )
+ {
+ OSL_ENSURE( pFly->IsFlyInCntFrm() ||
+ pSdrObj->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(),
+ "Fly with wrong z-Order" );
+ }
+#endif
+
+ sal_Bool bStopOnHell = sal_True;
+ if ( pSelfFly )
+ {
+ const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
+ if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
+ {
+ if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
+ //Im gleichen Layer werden nur obenliegende beachtet.
+ continue;
+ }
+ else
+ {
+ if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
+ //Aus anderem Layer interessieren uns nur nicht transparente
+ //oder innenliegende
+ continue;
+ bStopOnHell = sal_False;
+ }
+ }
+ if ( pRetoucheFly )
+ {
+ const SdrObject *pTmp = pRetoucheFly->GetVirtDrawObj();
+ if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
+ {
+ if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
+ //Im gleichen Layer werden nur obenliegende beachtet.
+ continue;
+ }
+ else
+ {
+ if ( !pFly->IsLowerOf( pRetoucheFly ) && !pFly->GetFmt()->GetOpaque().GetValue() )
+ //Aus anderem Layer interessieren uns nur nicht transparente
+ //oder innenliegende
+ continue;
+ bStopOnHell = sal_False;
+ }
+ }
+
+ //Wenn der Inhalt des Fly Transparent ist, wird er nicht abgezogen, es sei denn
+ //er steht im Hell-Layer (#31941#)
+ const IDocumentDrawModelAccess* pIDDMA = pFly->GetFmt()->getIDocumentDrawModelAccess();
+ sal_Bool bHell = pSdrObj->GetLayer() == pIDDMA->GetHellId();
+ if ( (bStopOnHell && bHell) ||
+ /// OD 05.08.2002 - change internal order of condition
+ /// first check "!bHell", then "..->Lower()" and "..->IsNoTxtFrm()"
+ /// have not to be performed, if frame is in "Hell"
+ ( !bHell && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() &&
+ ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
+ ((SwNoTxtFrm*)pFly->Lower())->HasAnimation() ||
+ pFly->GetFmt()->GetSurround().IsContour()
+ )
+ )
+ )
+ continue;
+
+ // OD 08.10.2002 #103898#
+ // Own if-statements for transparent background/shadow of fly frames
+ // (#99657#) in order to handle special conditions.
+ if ( pFly->IsBackgroundTransparent() )
+ {
+ // Background <pFly> is transparent drawn. Thus normally, its region
+ // have not to be substracted from given region.
+ // But, if method is called for a fly frame and
+ // <pFly> is a direct lower of this fly frame and
+ // <pFly> inherites its transparent background brush from its parent,
+ // then <pFly> frame area have to be subtracted from given region.
+ // NOTE: Because in Status Quo transparent backgrounds can only be
+ // assigned to fly frames, the handle of this special case
+ // avoids drawing of transparent areas more than once, if
+ // a fly frame inherites a transparent background from its
+ // parent fly frame.
+ if ( pFrm->IsFlyFrm() &&
+ (pFly->GetAnchorFrm()->FindFlyFrm() == pFrm) &&
+ static_cast<const SwFlyFrmFmt*>(pFly->GetFmt())->IsBackgroundBrushInherited()
+ )
+ {
+ SwRect aRect;
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ ::lcl_CalcBorderRect( aRect, pFly, rAttrs, sal_True );
+ rRegion -= aRect;
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ if ( pFly->IsShadowTransparent() )
+ {
+ continue;
+ }
+
+ if ( bHell && pFly->GetAnchorFrm()->IsInFly() )
+ {
+ //Damit die Umrandung nicht vom Hintergrund des anderen Flys
+ //zerlegt wird.
+ SwRect aRect;
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ ::lcl_CalcBorderRect( aRect, pFly, rAttrs, sal_True );
+ rRegion -= aRect;
+ }
+ else
+ {
+ SwRect aRect( pFly->Prt() );
+ aRect += pFly->Frm().Pos();
+ rRegion -= aRect;
+ }
+ }
+ if ( pRetoucheFly == pRetoucheFly2 )
+ pRetoucheFly = 0;
+}
+
+//---------------- Ausgabe fuer das BrushItem ----------------
+
+/** lcl_DrawGraphicBackgrd - local help method to draw a background for a graphic
+
+ OD 17.10.2002 #103876#
+ Under certain circumstances we have to draw a background for a graphic.
+ This method takes care of the conditions and draws the background with the
+ corresponding color.
+ Method introduced for bug fix #103876# in order to optimize drawing tiled
+ background graphics. Previously, this code was integrated in method
+ <lcl_DrawGraphic>.
+ Method implemented as a inline, checking the conditions and calling method
+ method <lcl_implDrawGraphicBackgrd(..)> for the intrinsic drawing.
+
+ @author OD
+
+ @param _rBackgrdBrush
+ background brush contain the color the background has to be drawn.
+
+ @param _pOut
+ output device the background has to be drawn in.
+
+ @param _rPaintRect
+ paint retangle in the output device, which has to be drawn with the background.
+ rectangle have to be aligned by method ::SwAlignRect
+
+ @param _rGraphicObj
+ graphic object, for which the background has to be drawn. Used for checking
+ the transparency of its bitmap, its type and if the graphic is drawn transparent
+
+ @param _bNumberingGraphic
+ boolean indicating that graphic is used as a numbering.
+
+ @param _bBackgrdAlreadyDrawn
+ boolean (optional; default: false) indicating, if the background is already drawn.
+*/
+void lcl_implDrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush,
+ OutputDevice* _pOut,
+ const SwRect& _rAlignedPaintRect,
+ const GraphicObject& _rGraphicObj )
+{
+ /// determine color of background
+ /// If color of background brush is not "no fill"/"auto fill" or
+ /// <bFlyMetafile> is set, use color of background brush, otherwise
+ /// use global retouche color.
+ const Color aColor( ( (_rBackgrdBrush.GetColor() != COL_TRANSPARENT) || bFlyMetafile )
+ ? _rBackgrdBrush.GetColor()
+ : aGlobalRetoucheColor );
+
+ /// determine, if background color have to be drawn transparent
+ /// and calculate transparency percent value
+ sal_Int8 nTransparencyPercent = 0;
+ bool bDrawTransparent = false;
+ if ( aColor.GetTransparency() != 0 )
+ /// background color is transparent --> draw transparent.
+ {
+ bDrawTransparent = true;
+ nTransparencyPercent = (aColor.GetTransparency()*100 + 0x7F)/0xFF;
+ }
+ else if ( (_rGraphicObj.GetAttr().GetTransparency() != 0) &&
+ (_rBackgrdBrush.GetColor() == COL_TRANSPARENT) )
+ /// graphic is drawn transparent and background color is
+ /// "no fill"/"auto fill" --> draw transparent
+ {
+ bDrawTransparent = true;
+ nTransparencyPercent = (_rGraphicObj.GetAttr().GetTransparency()*100 + 0x7F)/0xFF;
+ }
+
+ if ( bDrawTransparent )
+ {
+ /// draw background transparent
+ if( _pOut->GetFillColor() != aColor.GetRGBColor() )
+ _pOut->SetFillColor( aColor.GetRGBColor() );
+ PolyPolygon aPoly( _rAlignedPaintRect.SVRect() );
+ _pOut->DrawTransparent( aPoly, nTransparencyPercent );
+ }
+ else
+ {
+ /// draw background opaque
+ if ( _pOut->GetFillColor() != aColor )
+ _pOut->SetFillColor( aColor );
+ _pOut->DrawRect( _rAlignedPaintRect.SVRect() );
+ }
+}
+
+inline void lcl_DrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush,
+ OutputDevice* _pOut,
+ const SwRect& _rAlignedPaintRect,
+ const GraphicObject& _rGraphicObj,
+ bool _bNumberingGraphic,
+ bool _bBackgrdAlreadyDrawn = false )
+{
+ /// draw background with background color, if
+ /// (1) graphic is not used as a numbering AND
+ /// (2) background is not already drawn AND
+ /// (3) intrinsic graphic is transparent OR intrinsic graphic doesn't exists
+ if ( !_bNumberingGraphic &&
+ !_bBackgrdAlreadyDrawn &&
+ ( _rGraphicObj.IsTransparent() || _rGraphicObj.GetType() == GRAPHIC_NONE )
+ )
+ {
+ lcl_implDrawGraphicBackgrd( _rBackgrdBrush, _pOut, _rAlignedPaintRect, _rGraphicObj );
+ }
+}
+
+/// OD 06.08.2002 #99657# - Note: the transparency of the background graphic
+/// is saved in SvxBrushItem.GetGraphicObject(<shell>).GetAttr().Set/GetTransparency()
+/// and is considered in the drawing of the graphic.
+/// Thus, to provide transparent background graphic for text frames nothing
+/// has to be coded.
+/// OD 25.09.2002 #99739# - use align rectangle for drawing graphic
+/// OD 25.09.2002 #99739# - pixel-align coordinations for drawing graphic.
+/// OD 17.10.2002 #103876# - outsource code for drawing background of the graphic
+/// with a background color in method <lcl_DrawGraphicBackgrd>
+/// Also, change type of <bGrfNum> and <bClip> from <sal_Bool> to <bool>.
+void lcl_DrawGraphic( const SvxBrushItem& rBrush, OutputDevice *pOut,
+ ViewShell &rSh, const SwRect &rGrf, const SwRect &rOut,
+ bool bClip, bool bGrfNum,
+ bool bBackgrdAlreadyDrawn = false )
+ /// OD 02.09.2002 #99657#
+ /// add parameter <bBackgrdAlreadyDrawn> to indicate
+ /// that the background is already drawn.
+{
+ /// OD 25.09.2002 #99739# - calculate align rectangle from parameter <rGrf>
+ /// and use aligned rectangle <aAlignedGrfRect> in the following code
+ SwRect aAlignedGrfRect = rGrf;
+ ::SwAlignRect( aAlignedGrfRect, &rSh );
+
+ /// OD 17.10.2002 #103876# - change type from <sal_Bool> to <bool>.
+ const bool bNotInside = bClip && !rOut.IsInside( aAlignedGrfRect );
+ if ( bNotInside )
+ {
+ pOut->Push( PUSH_CLIPREGION );
+ pOut->IntersectClipRegion( rOut.SVRect() );
+ }
+
+ //Hier kein Link, wir wollen die Grafik synchron laden!
+ ((SvxBrushItem&)rBrush).SetDoneLink( Link() );
+ GraphicObject *pGrf = (GraphicObject*)rBrush.GetGraphicObject();
+
+ /// OD 17.10.2002 #103876# - outsourcing drawing of background with a background color.
+ ::lcl_DrawGraphicBackgrd( rBrush, pOut, aAlignedGrfRect, *pGrf, bGrfNum, bBackgrdAlreadyDrawn );
+
+ /// OD 25.09.2002 #99739# -
+ /// Because for drawing a graphic left-top-corner and size coordinations are
+ /// used, these coordinations have to be determined on pixel level.
+ ::SwAlignGrfRect( &aAlignedGrfRect, *pOut );
+ pGrf->DrawWithPDFHandling( *pOut, aAlignedGrfRect.Pos(), aAlignedGrfRect.SSize() );
+
+ if ( bNotInside )
+ pOut->Pop();
+} // end of method <lcl_DrawGraphic>
+
+void MA_FASTCALL DrawGraphic( const SvxBrushItem *pBrush,
+ OutputDevice *pOutDev,
+ const SwRect &rOrg,
+ const SwRect &rOut,
+ const sal_uInt8 nGrfNum,
+ const sal_Bool bConsiderBackgroundTransparency )
+ /// OD 05.08.2002 #99657# - add 6th parameter to indicate that method should
+ /// consider background transparency, saved in the color of the brush item
+{
+ ViewShell &rSh = *pGlobalShell;
+ /// OD 17.10.2002 #103876# - change type from <sal_Bool> to <bool>
+ bool bReplaceGrfNum = GRFNUM_REPLACE == nGrfNum;
+ bool bGrfNum = GRFNUM_NO != nGrfNum;
+ Size aGrfSize;
+ SvxGraphicPosition ePos = GPOS_NONE;
+ if( pBrush && !bReplaceGrfNum )
+ {
+ if( rSh.GetViewOptions()->IsGraphic() )
+ {
+ //#125488#: load graphic directly in PDF import
+ // --> OD 2006-08-25 #i68953# - also during print load graphic directly.
+ if ( (rSh).GetViewOptions()->IsPDFExport() ||
+ rSh.GetOut()->GetOutDevType() == OUTDEV_PRINTER )
+ // <--
+ {
+ ((SvxBrushItem*)pBrush)->PurgeMedium();
+ ((SvxBrushItem*)pBrush)->SetDoneLink( Link() );
+ }
+ else
+ ((SvxBrushItem*)pBrush)->SetDoneLink( STATIC_LINK(
+ rSh.GetDoc(), SwDoc, BackgroundDone ) );
+ //SfxObjectShell &rObjSh = *GETOBJSHELL();
+ const Graphic* pGrf = pBrush->GetGraphic();
+ if( pGrf && GRAPHIC_NONE != pGrf->GetType() )
+ {
+ ePos = pBrush->GetGraphicPos();
+ if( pGrf->IsSupportedGraphic() )
+ // don't the use the specific output device! Bug 94802
+ aGrfSize = ::GetGraphicSizeTwip( *pGrf, 0 );
+ }
+ }
+ else
+ bReplaceGrfNum = bGrfNum;
+ }
+
+ SwRect aGrf;
+ aGrf.SSize( aGrfSize );
+ sal_Bool bDraw = sal_True;
+ sal_Bool bRetouche = sal_True;
+ switch ( ePos )
+ {
+ case GPOS_LT:
+ aGrf.Pos() = rOrg.Pos();
+ break;
+
+ case GPOS_MT:
+ aGrf.Pos().Y() = rOrg.Top();
+ aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
+ break;
+
+ case GPOS_RT:
+ aGrf.Pos().Y() = rOrg.Top();
+ aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_LM:
+ aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
+ aGrf.Pos().X() = rOrg.Left();
+ break;
+
+ case GPOS_MM:
+ aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
+ aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
+ break;
+
+ case GPOS_RM:
+ aGrf.Pos().Y() = rOrg.Top() + rOrg.Height()/2 - aGrfSize.Height()/2;
+ aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_LB:
+ aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
+ aGrf.Pos().X() = rOrg.Left();
+ break;
+
+ case GPOS_MB:
+ aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
+ aGrf.Pos().X() = rOrg.Left() + rOrg.Width()/2 - aGrfSize.Width()/2;
+ break;
+
+ case GPOS_RB:
+ aGrf.Pos().Y() = rOrg.Bottom() - aGrfSize.Height();
+ aGrf.Pos().X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_AREA:
+ aGrf = rOrg;
+ /// OD 05.09.2002 #102912#
+ /// In spite the fact that the background graphic have to fill the complete
+ /// area, it has been checked, if the graphic will completely fill out
+ /// the region to be painted <rOut> and thus, nothing has to be retouched.
+ /// For example, this is the case for a fly frame without a background
+ /// brush positioned on the border of the page and inherited the
+ /// background brush from the page.
+ bRetouche = !rOut.IsInside( aGrf );
+ break;
+
+ case GPOS_TILED:
+ {
+ // OD 17.10.2002 #103876# - draw background of tiled graphic
+ // before drawing tiled graphic in loop
+ // determine graphic object
+ GraphicObject* pGraphicObj = const_cast< GraphicObject* >(pBrush->GetGraphicObject());
+ // calculate aligned paint rectangle
+ SwRect aAlignedPaintRect = rOut;
+ ::SwAlignRect( aAlignedPaintRect, &rSh );
+ // OD 25.10.2002 #103876# - draw background color for aligned paint rectangle
+ lcl_DrawGraphicBackgrd( *pBrush, pOutDev, aAlignedPaintRect, *pGraphicObj, bGrfNum );
+
+ // set left-top-corner of background graphic to left-top-corner of the
+ // area, from which the background brush is determined.
+ aGrf.Pos() = rOrg.Pos();
+ // setup clipping at output device
+ pOutDev->Push( PUSH_CLIPREGION );
+ pOutDev->IntersectClipRegion( rOut.SVRect() );
+ // OD 28.10.2002 #103876# - use new method <GraphicObject::DrawTiled(::)>
+ {
+ // calculate paint offset
+ Point aPaintOffset( aAlignedPaintRect.Pos() - aGrf.Pos() );
+ // draw background graphic tiled for aligned paint rectangle
+ // --> OD 2005-02-15 #i42643# - apply fix #104004# for Calc
+ // also for Writer - see /sc/source/view/printfun.cxx
+ // For PDF export, every draw operation for bitmaps takes a
+ // noticeable amount of place (~50 characters). Thus, optimize
+ // between tile bitmap size and number of drawing operations here.
+ //
+ // A_out
+ // n_chars = k1 * ---------- + k2 * A_bitmap
+ // A_bitmap
+ //
+ // minimum n_chars is obtained for (derive for A_bitmap,
+ // set to 0, take positive solution):
+ // k1
+ // A_bitmap = Sqrt( ---- A_out )
+ // k2
+ //
+ // where k1 is the number of chars per draw operation, and
+ // k2 is the number of chars per bitmap pixel.
+ // This is approximately 50 and 7 for current PDF writer, respectively.
+ //
+ const double k1( 50 );
+ const double k2( 7 );
+ const Size aSize( aAlignedPaintRect.SSize() );
+ const double Abitmap( k1/k2 * static_cast<double>(aSize.Width())*aSize.Height() );
+
+ pGraphicObj->DrawTiled( pOutDev,
+ aAlignedPaintRect.SVRect(),
+ aGrf.SSize(),
+ Size( aPaintOffset.X(), aPaintOffset.Y() ),
+ NULL, GRFMGR_DRAW_STANDARD,
+ ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
+ // <--
+ }
+ // reset clipping at output device
+ pOutDev->Pop();
+ // set <bDraw> and <bRetouche> to false, indicating that background
+ // graphic and background are already drawn.
+ bDraw = bRetouche = sal_False;
+ }
+ break;
+
+ case GPOS_NONE:
+ bDraw = sal_False;
+ break;
+
+ default: OSL_ENSURE( !pOutDev, "new Graphic position?" );
+ }
+
+ /// OD 02.09.2002 #99657#
+ /// init variable <bGrfBackgrdAlreadDrawn> to indicate, if background of
+ /// graphic is already drawn or not.
+ bool bGrfBackgrdAlreadyDrawn = false;
+ if ( bRetouche )
+ {
+ // OD 2004-04-23 #116347#
+ pOutDev->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
+ pOutDev->SetLineColor();
+
+ // OD 07.08.2002 #99657# #GetTransChg#
+ // check, if a existing background graphic (not filling the complete
+ // background) is transparent drawn and the background color is
+ // "no fill" respectively "auto fill", if background transparency
+ // has to be considered.
+ // If YES, memorise transparency of background graphic.
+ // check also, if background graphic bitmap is transparent.
+ bool bTransparentGrfWithNoFillBackgrd = false;
+ sal_Int32 nGrfTransparency = 0;
+ bool bGrfIsTransparent = false;
+ if ( (ePos != GPOS_NONE) &&
+ (ePos != GPOS_TILED) && (ePos != GPOS_AREA)
+ )
+ {
+ GraphicObject *pGrf = (GraphicObject*)pBrush->GetGraphicObject();
+ if ( bConsiderBackgroundTransparency )
+ {
+ GraphicAttr pGrfAttr = pGrf->GetAttr();
+ if ( (pGrfAttr.GetTransparency() != 0) &&
+ ( pBrush && (pBrush->GetColor() == COL_TRANSPARENT) )
+ )
+ {
+ bTransparentGrfWithNoFillBackgrd = true;
+ nGrfTransparency = pGrfAttr.GetTransparency();
+ }
+ }
+ if ( pGrf->IsTransparent() )
+ {
+ bGrfIsTransparent = true;
+ }
+ }
+
+ /// OD 06.08.2002 #99657# #GetTransChg# - to get color of brush,
+ /// check background color against COL_TRANSPARENT ("no fill"/"auto fill")
+ /// instead of checking, if transparency is not set.
+ const Color aColor( pBrush &&
+ ( !(pBrush->GetColor() == COL_TRANSPARENT) ||
+ bFlyMetafile )
+ ? pBrush->GetColor()
+ : aGlobalRetoucheColor );
+
+ /// OD 08.08.2002 #99657# - determine, if background region have to be
+ /// drawn transparent.
+ /// background region has to be drawn transparent, if
+ /// background transparency have to be considered
+ /// AND
+ /// ( background color is transparent OR
+ /// background graphic is transparent and background color is "no fill"
+ /// )
+ sal_Bool bDrawTransparent = bConsiderBackgroundTransparency &&
+ ( ( aColor.GetTransparency() != 0) ||
+ bTransparentGrfWithNoFillBackgrd );
+
+ // --> OD 2008-06-02 #i75614#
+ // reset draw mode in high contrast mode in order to get fill color set
+ const sal_uLong nOldDrawMode = pOutDev->GetDrawMode();
+ if ( pGlobalShell->GetWin() &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pOutDev->SetDrawMode( 0 );
+ }
+ // <--
+
+ /// OD 06.08.2002 #99657# - if background region have to be drawn
+ /// transparent, set only the RGB values of the background color as
+ /// the fill color for the output device.
+ if ( bDrawTransparent )
+ {
+ if( pOutDev->GetFillColor() != aColor.GetRGBColor() )
+ pOutDev->SetFillColor( aColor.GetRGBColor() );
+ }
+ else
+ {
+ if( pOutDev->GetFillColor() != aColor )
+ pOutDev->SetFillColor( aColor );
+ }
+
+ // --> OD 2008-06-02 #i75614#
+ // restore draw mode
+ pOutDev->SetDrawMode( nOldDrawMode );
+ // <--
+
+ /// OD 02.09.2002 #99657#
+ if ( bDrawTransparent )
+ {
+ /// background region have to be drawn transparent.
+ /// Thus, create a poly-polygon from the region and draw it with
+ /// the corresponding transparency precent.
+ PolyPolygon aDrawPoly( rOut.SVRect() );
+ if ( aGrf.HasArea() )
+ {
+ if ( !bGrfIsTransparent )
+ {
+ /// substract area of background graphic from draw area
+ /// OD 08.10.2002 #103898# - consider only that part of the
+ /// graphic area that is overlapping with draw area.
+ SwRect aTmpGrf = aGrf;
+ aTmpGrf.Intersection( rOut );
+ if ( aTmpGrf.HasArea() )
+ {
+ Polygon aGrfPoly( aTmpGrf.SVRect() );
+ aDrawPoly.Insert( aGrfPoly );
+ }
+ }
+ else
+ bGrfBackgrdAlreadyDrawn = true;
+ }
+ /// calculate transparency percent:
+ /// ( <transparency value[0x01..0xFF]>*100 + 0x7F ) / 0xFF
+ /// If there is a background graphic with a background color "no fill"/"auto fill",
+ /// the transparency value is taken from the background graphic,
+ /// otherwise take the transparency value from the color.
+ sal_Int8 nTransparencyPercent = static_cast<sal_Int8>(
+ (( bTransparentGrfWithNoFillBackgrd ? nGrfTransparency : aColor.GetTransparency()
+ )*100 + 0x7F)/0xFF);
+ /// draw poly-polygon transparent
+ pOutDev->DrawTransparent( aDrawPoly, nTransparencyPercent );
+ }
+ else
+ {
+ SwRegionRects aRegion( rOut, 4 );
+ if ( !bGrfIsTransparent )
+ aRegion -= aGrf;
+ else
+ bGrfBackgrdAlreadyDrawn = true;
+ /// loop rectangles of background region, which has to be drawn
+ for( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
+ {
+ pOutDev->DrawRect( aRegion[i].SVRect() );
+ }
+ }
+ pOutDev ->Pop();
+ }
+
+ if( bDraw && aGrf.IsOver( rOut ) )
+ /// OD 02.09.2002 #99657#
+ /// add parameter <bGrfBackgrdAlreadyDrawn>
+ lcl_DrawGraphic( *pBrush, pOutDev, rSh, aGrf, rOut, true, bGrfNum,
+ bGrfBackgrdAlreadyDrawn );
+
+ if( bReplaceGrfNum )
+ {
+ const BitmapEx& rBmp = ViewShell::GetReplacementBitmap( false );
+ Font aTmp( pOutDev->GetFont() );
+ Graphic::DrawEx( pOutDev, aEmptyStr, aTmp, rBmp, rOrg.Pos(), rOrg.SSize() );
+ }
+}
+
+//------------------------------------------------------------------------
+
+/** local help method for SwRootFrm::Paint(..) - Adjust given rectangle to pixel size
+
+ By OD at 27.09.2002 for #103636#
+ In order to avoid paint errors caused by multiple alignments - e.g. method
+ ::SwAlignRect(..) - and other changes to the rectangle to be painted,
+ this method is called for the rectangle to be painted in order to
+ adjust it to the pixel it is overlapping.
+
+ @author OD
+*/
+void lcl_AdjustRectToPixelSize( SwRect& io_aSwRect, const OutputDevice &aOut )
+{
+ /// local constant object of class <Size> to determine number of Twips
+ /// representing a pixel.
+ const Size aTwipToPxSize( aOut.PixelToLogic( Size( 1,1 )) );
+
+ /// local object of class <Rectangle> in Twip coordinates
+ /// calculated from given rectangle aligned to pixel centers.
+ const Rectangle aPxCenterRect = aOut.PixelToLogic(
+ aOut.LogicToPixel( io_aSwRect.SVRect() ) );
+
+ /// local constant object of class <Rectangle> representing given rectangle
+ /// in pixel.
+ const Rectangle aOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
+
+ /// calculate adjusted rectangle from pixel centered rectangle.
+ /// Due to rounding differences <aPxCenterRect> doesn't exactly represents
+ /// the Twip-centers. Thus, adjust borders by half of pixel width/height plus 1.
+ /// Afterwards, adjust calculated Twip-positions of the all borders.
+ Rectangle aSizedRect = aPxCenterRect;
+ aSizedRect.Left() -= (aTwipToPxSize.Width()/2 + 1);
+ aSizedRect.Right() += (aTwipToPxSize.Width()/2 + 1);
+ aSizedRect.Top() -= (aTwipToPxSize.Height()/2 + 1);
+ aSizedRect.Bottom() += (aTwipToPxSize.Height()/2 + 1);
+
+ /// adjust left()
+ while ( (aOut.LogicToPixel(aSizedRect)).Left() < aOrgPxRect.Left() )
+ {
+ ++aSizedRect.Left();
+ }
+ /// adjust right()
+ while ( (aOut.LogicToPixel(aSizedRect)).Right() > aOrgPxRect.Right() )
+ {
+ --aSizedRect.Right();
+ }
+ /// adjust top()
+ while ( (aOut.LogicToPixel(aSizedRect)).Top() < aOrgPxRect.Top() )
+ {
+ ++aSizedRect.Top();
+ }
+ /// adjust bottom()
+ while ( (aOut.LogicToPixel(aSizedRect)).Bottom() > aOrgPxRect.Bottom() )
+ {
+ --aSizedRect.Bottom();
+ }
+
+ io_aSwRect = SwRect( aSizedRect );
+
+#if OSL_DEBUG_LEVEL > 1
+ Rectangle aTestOrgPxRect = aOut.LogicToPixel( io_aSwRect.SVRect() );
+ Rectangle aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
+ OSL_ENSURE( aTestOrgPxRect == aTestNewPxRect,
+ "Error in lcl_AlignRectToPixelSize(..): Adjusted rectangle has incorrect position or size");
+ Rectangle aTestNewRect( aSizedRect );
+ /// check Left()
+ --aSizedRect.Left();
+ aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
+ OSL_ENSURE( aTestOrgPxRect.Left() >= (aTestNewPxRect.Left()+1),
+ "Error in lcl_AlignRectToPixelSize(..): Left() not correct adjusted");
+ ++aSizedRect.Left();
+ /// check Right()
+ ++aSizedRect.Right();
+ aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
+ OSL_ENSURE( aTestOrgPxRect.Right() <= (aTestNewPxRect.Right()-1),
+ "Error in lcl_AlignRectToPixelSize(..): Right() not correct adjusted");
+ --aSizedRect.Right();
+ /// check Top()
+ --aSizedRect.Top();
+ aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
+ OSL_ENSURE( aTestOrgPxRect.Top() >= (aTestNewPxRect.Top()+1),
+ "Error in lcl_AlignRectToPixelSize(..): Top() not correct adjusted");
+ ++aSizedRect.Top();
+ /// check Bottom()
+ ++aSizedRect.Bottom();
+ aTestNewPxRect = aOut.LogicToPixel( aSizedRect );
+ OSL_ENSURE( aTestOrgPxRect.Bottom() <= (aTestNewPxRect.Bottom()-1),
+ "Error in lcl_AlignRectToPixelSize(..): Bottom() not correct adjusted");
+ --aSizedRect.Bottom();
+#endif
+}
+
+//
+// FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES START
+//
+
+struct SwLineEntry
+{
+ SwTwips mnKey;
+ SwTwips mnStartPos;
+ SwTwips mnEndPos;
+
+ svx::frame::Style maAttribute;
+
+ enum OverlapType { NO_OVERLAP, OVERLAP1, OVERLAP2, OVERLAP3 };
+
+public:
+ SwLineEntry( SwTwips nKey,
+ SwTwips nStartPos,
+ SwTwips nEndPos,
+ const svx::frame::Style& rAttribute );
+
+ OverlapType Overlaps( const SwLineEntry& rComp ) const;
+};
+
+SwLineEntry::SwLineEntry( SwTwips nKey,
+ SwTwips nStartPos,
+ SwTwips nEndPos,
+ const svx::frame::Style& rAttribute )
+ : mnKey( nKey ),
+ mnStartPos( nStartPos ),
+ mnEndPos( nEndPos ),
+ maAttribute( rAttribute )
+{
+}
+
+/*
+
+ 1. ---------- rOld
+ ---------- rNew
+
+ 2. ---------- rOld
+ ------------- rNew
+
+ 3. ------- rOld
+ ------------- rNew
+
+ 4. ------------- rOld
+ ---------- rNew
+
+ 5. ---------- rOld
+ ---- rNew
+
+ 6. ---------- rOld
+ ---------- rNew
+
+ 7. ------------- rOld
+ ---------- rNew
+
+ 8. ---------- rOld
+ ------------- rNew
+
+ 9. ---------- rOld
+ ---------- rNew
+*/
+
+SwLineEntry::OverlapType SwLineEntry::Overlaps( const SwLineEntry& rNew ) const
+{
+ SwLineEntry::OverlapType eRet = OVERLAP3;
+
+ if ( mnStartPos >= rNew.mnEndPos || mnEndPos <= rNew.mnStartPos )
+ eRet = NO_OVERLAP;
+
+ // 1, 2, 3
+ else if ( mnEndPos < rNew.mnEndPos )
+ eRet = OVERLAP1;
+
+ // 4, 5, 6, 7
+ else if ( mnStartPos <= rNew.mnStartPos && mnEndPos >= rNew.mnEndPos )
+ eRet = OVERLAP2;
+
+ // 8, 9
+ return eRet;
+}
+
+struct lt_SwLineEntry
+{
+ bool operator()( const SwLineEntry& e1, const SwLineEntry& e2 ) const
+ {
+ return e1.mnStartPos < e2.mnStartPos;
+ }
+};
+
+typedef std::set< SwLineEntry, lt_SwLineEntry > SwLineEntrySet;
+typedef std::set< SwLineEntry, lt_SwLineEntry >::iterator SwLineEntrySetIter;
+typedef std::set< SwLineEntry, lt_SwLineEntry >::const_iterator SwLineEntrySetConstIter;
+typedef std::map< SwTwips, SwLineEntrySet > SwLineEntryMap;
+typedef std::map< SwTwips, SwLineEntrySet >::iterator SwLineEntryMapIter;
+typedef std::map< SwTwips, SwLineEntrySet >::const_iterator SwLineEntryMapConstIter;
+
+class SwTabFrmPainter
+{
+ SwLineEntryMap maVertLines;
+ SwLineEntryMap maHoriLines;
+ const SwTabFrm& mrTabFrm;
+
+ void Insert( SwLineEntry&, bool bHori );
+ void Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem );
+ void HandleFrame( const SwLayoutFrm& rFrm );
+ void FindStylesForLine( const Point&,
+ const Point&,
+ svx::frame::Style*,
+ bool bHori ) const;
+
+public:
+ SwTabFrmPainter( const SwTabFrm& rTabFrm );
+
+ void PaintLines( OutputDevice& rDev, const SwRect& rRect ) const;
+};
+
+SwTabFrmPainter::SwTabFrmPainter( const SwTabFrm& rTabFrm )
+ : mrTabFrm( rTabFrm )
+{
+ HandleFrame( rTabFrm );
+}
+
+void SwTabFrmPainter::HandleFrame( const SwLayoutFrm& rLayoutFrm )
+{
+ // Add border lines of cell frames. Skip covered cells. Skip cells
+ // in special row span row, which do not have a negative row span:
+ if ( rLayoutFrm.IsCellFrm() && !rLayoutFrm.IsCoveredCell() )
+ {
+ const SwCellFrm* pThisCell = static_cast<const SwCellFrm*>(&rLayoutFrm);
+ const SwRowFrm* pRowFrm = static_cast<const SwRowFrm*>(pThisCell->GetUpper());
+ const long nRowSpan = pThisCell->GetTabBox()->getRowSpan();
+ if ( !pRowFrm->IsRowSpanLine() || nRowSpan > 1 || nRowSpan < -1 )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), &rLayoutFrm );
+ const SwBorderAttrs& rAttrs = *aAccess.Get();
+ const SvxBoxItem& rBox = rAttrs.GetBox();
+ Insert( rLayoutFrm, rBox );
+ }
+ }
+
+ // Recurse into lower layout frames, but do not recurse into lower tabframes.
+ const SwFrm* pLower = rLayoutFrm.Lower();
+ while ( pLower )
+ {
+ const SwLayoutFrm* pLowerLayFrm = dynamic_cast<const SwLayoutFrm*>(pLower);
+ if ( pLowerLayFrm && !pLowerLayFrm->IsTabFrm() )
+ HandleFrame( *pLowerLayFrm );
+
+ pLower = pLower->GetNext();
+ }
+}
+
+void SwTabFrmPainter::PaintLines( OutputDevice& rDev, const SwRect& rRect ) const
+{
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, rDev );
+ // <--
+
+ const SwFrm* pTmpFrm = &mrTabFrm;
+ const bool bVert = pTmpFrm->IsVertical();
+
+ SwLineEntryMapConstIter aIter = maHoriLines.begin();
+ bool bHori = true;
+
+ // color for subsidiary lines:
+ const Color& rCol( SwViewOption::GetTableBoundariesColor() );
+
+ // high contrast mode:
+ // overrides the color of non-subsidiary lines.
+ const Color* pHCColor = 0;
+ sal_uLong nOldDrawMode = rDev.GetDrawMode();
+ if( pGlobalShell->GetWin() &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pHCColor = &SwViewOption::GetFontColor();
+ rDev.SetDrawMode( 0 );
+ }
+
+ // set clip region:
+ rDev.Push( PUSH_CLIPREGION );
+ Size aSize( rRect.SSize() );
+ // Hack! Necessary, because the layout is not pixel aligned!
+ aSize.Width() += nPixelSzW; aSize.Height() += nPixelSzH;
+ rDev.SetClipRegion( Rectangle( rRect.Pos(), aSize ) );
+
+ // The following stuff if necessary to have the new table borders fit
+ // into a ::SwAlignRect adjusted world.
+ const SwTwips nTwipXCorr = bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-)
+ const SwTwips nTwipYCorr = !bVert ? 0 : Max( 0L, nHalfPixelSzW - 2 ); // 1 < 2 < 3 ;-)
+ const SwFrm* pUpper = mrTabFrm.GetUpper();
+ SwRect aUpper( pUpper->Prt() );
+ aUpper.Pos() += pUpper->Frm().Pos();
+ SwRect aUpperAligned( aUpper );
+ ::SwAlignRect( aUpperAligned, pGlobalShell );
+
+ while ( true )
+ {
+ if ( bHori && aIter == maHoriLines.end() )
+ {
+ aIter = maVertLines.begin();
+ bHori = false;
+ }
+
+ if ( !bHori && aIter == maVertLines.end() )
+ break;
+
+ const SwLineEntrySet& rEntrySet = (*aIter).second;
+ SwLineEntrySetConstIter aSetIter = rEntrySet.begin();
+ while ( aSetIter != rEntrySet.end() )
+ {
+ const SwLineEntry& rEntry = *aSetIter;
+ const svx::frame::Style& rEntryStyle( (*aSetIter).maAttribute );
+
+ Point aStart, aEnd;
+ if ( bHori )
+ {
+ aStart.X() = rEntry.mnStartPos;
+ aStart.Y() = rEntry.mnKey;
+ aEnd.X() = rEntry.mnEndPos;
+ aEnd.Y() = rEntry.mnKey;
+ }
+ else
+ {
+ aStart.X() = rEntry.mnKey;
+ aStart.Y() = rEntry.mnStartPos;
+ aEnd.X() = rEntry.mnKey;
+ aEnd.Y() = rEntry.mnEndPos;
+ }
+
+ SwRect aRepaintRect( aStart, aEnd );
+
+ // the repaint rectangle has to be moved a bit for the centered lines:
+ SwTwips nRepaintRectSize = !rEntryStyle.GetWidth() ? 1 : rEntryStyle.GetWidth();
+ if ( bHori )
+ {
+ aRepaintRect.Height( 2 * nRepaintRectSize );
+ aRepaintRect.Pos().Y() -= nRepaintRectSize;
+ }
+ else
+ {
+ aRepaintRect.Width( 2 * nRepaintRectSize );
+ aRepaintRect.Pos().X() -= nRepaintRectSize;
+ }
+
+ if ( rRect.IsOver( aRepaintRect ) )
+ {
+ svx::frame::Style aStyles[ 7 ];
+ aStyles[ 0 ] = rEntryStyle;
+ FindStylesForLine( aStart, aEnd, aStyles, bHori );
+
+ // subsidiary lines
+ const Color* pTmpColor = 0;
+ if ( 0 == aStyles[ 0 ].GetWidth() )
+ {
+ if ( IS_SUBS_TABLE && pGlobalShell->GetWin() )
+ aStyles[ 0 ].Set( rCol, rCol, rCol, false, 1, 0, 0 );
+ }
+ else
+ pTmpColor = pHCColor;
+
+ // The line sizes stored in the line style have to be adjusted as well.
+ // This will guarantee that lines with the same twip size will have the
+ // same pixel size.
+ for ( int i = 0; i < 7; ++i )
+ {
+ sal_uInt16 nPrim = aStyles[ i ].Prim();
+ sal_uInt16 nDist = aStyles[ i ].Dist();
+ sal_uInt16 nSecn = aStyles[ i ].Secn();
+
+ if ( nPrim > 0 )
+ nPrim = (sal_uInt16)( Max( 1L, nPixelSzH * ( nPrim / nPixelSzH ) ) );
+ if ( nDist > 0 )
+ nDist = (sal_uInt16)( Max( 1L, nPixelSzH * ( nDist / nPixelSzH ) ) );
+ if ( nSecn > 0 )
+ nSecn = (sal_uInt16)( Max( 1L, nPixelSzH * ( nSecn / nPixelSzH ) ) );
+
+ aStyles[ i ].Set( nPrim, nDist, nSecn );
+ }
+
+ // The (twip) positions will be adjusted to meet these requirements:
+ // 1. The y coordinates are located in the middle of the pixel grid
+ // 2. The x coordinated are located at the beginning of the pixel grid
+ // This is done, because the horizontal lines are painted "at beginning",
+ // whereas the vertical lines are painted "centered". By making the line
+ // sizes a multiple of one pixel size, we can assure, that all lines having
+ // the same twip size have the same pixel size, independent of their position
+ // on the screen.
+ Point aPaintStart = rDev.PixelToLogic( rDev.LogicToPixel( aStart ) );
+ Point aPaintEnd = rDev.PixelToLogic( rDev.LogicToPixel( aEnd ) );
+
+ if( pGlobalShell->GetWin() )
+ {
+ // The table borders do not use SwAlignRect, but all the other frames do.
+ // Therefore we tweak the outer borders a bit to achieve that the outer
+ // borders match the subsidiary lines of the upper:
+ if ( aStart.X() == aUpper.Left() )
+ aPaintStart.X() = aUpperAligned.Left();
+ else if ( aStart.X() == aUpper._Right() )
+ aPaintStart.X() = aUpperAligned._Right();
+ if ( aStart.Y() == aUpper.Top() )
+ aPaintStart.Y() = aUpperAligned.Top();
+ else if ( aStart.Y() == aUpper._Bottom() )
+ aPaintStart.Y() = aUpperAligned._Bottom();
+
+ if ( aEnd.X() == aUpper.Left() )
+ aPaintEnd.X() = aUpperAligned.Left();
+ else if ( aEnd.X() == aUpper._Right() )
+ aPaintEnd.X() = aUpperAligned._Right();
+ if ( aEnd.Y() == aUpper.Top() )
+ aPaintEnd.Y() = aUpperAligned.Top();
+ else if ( aEnd.Y() == aUpper._Bottom() )
+ aPaintEnd.Y() = aUpperAligned._Bottom();
+ }
+
+ aPaintStart.X() -= nTwipXCorr; // nHalfPixelSzW - 2 to assure that we do not leave the pixel
+ aPaintEnd.X() -= nTwipXCorr;
+ aPaintStart.Y() -= nTwipYCorr;
+ aPaintEnd.Y() -= nTwipYCorr;
+
+ // Here comes the painting stuff: Thank you, DR, great job!!!
+ if ( bHori )
+ {
+ mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
+ aPaintStart,
+ aPaintEnd,
+ aStyles[ 0 ], // current style
+ aStyles[ 1 ], // aLFromT
+ aStyles[ 2 ], // aLFromL
+ aStyles[ 3 ], // aLFromB
+ aStyles[ 4 ], // aRFromT
+ aStyles[ 5 ], // aRFromR
+ aStyles[ 6 ], // aRFromB
+ pTmpColor
+ )
+ );
+ }
+ else
+ {
+ mrTabFrm.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
+ aPaintEnd,
+ aPaintStart,
+ aStyles[ 0 ], // current style
+ aStyles[ 4 ], // aBFromL
+ aStyles[ 5 ], // aBFromB
+ aStyles[ 6 ], // aBFromR
+ aStyles[ 1 ], // aTFromL
+ aStyles[ 2 ], // aTFromT
+ aStyles[ 3 ], // aTFromR
+ pTmpColor
+ )
+ );
+ }
+ }
+
+ ++aSetIter;
+ }
+
+ ++aIter;
+ }
+
+ // restore output device:
+ rDev.Pop();
+ rDev.SetDrawMode( nOldDrawMode );
+}
+
+// Finds the lines that join the line defined by (StartPoint, EndPoint) in either
+// StartPoint or Endpoint. The styles of these lines are required for DR's magic
+// line painting functions.
+void SwTabFrmPainter::FindStylesForLine( const Point& rStartPoint,
+ const Point& rEndPoint,
+ svx::frame::Style* pStyles,
+ bool bHori ) const
+{
+ // pStyles[ 1 ] = bHori ? aLFromT : TFromL
+ // pStyles[ 2 ] = bHori ? aLFromL : TFromT,
+ // pStyles[ 3 ] = bHori ? aLFromB : TFromR,
+ // pStyles[ 4 ] = bHori ? aRFromT : BFromL,
+ // pStyles[ 5 ] = bHori ? aRFromR : BFromB,
+ // pStyles[ 6 ] = bHori ? aRFromB : BFromR,
+
+ SwLineEntryMapConstIter aMapIter = maVertLines.find( rStartPoint.X() );
+ OSL_ENSURE( aMapIter != maVertLines.end(), "FindStylesForLine: Error" );
+ const SwLineEntrySet& rVertSet = (*aMapIter).second;
+ SwLineEntrySetConstIter aIter = rVertSet.begin();
+
+ while ( aIter != rVertSet.end() )
+ {
+ const SwLineEntry& rEntry = *aIter;
+ if ( bHori )
+ {
+ if ( rStartPoint.Y() == rEntry.mnStartPos )
+ pStyles[ 3 ] = rEntry.maAttribute;
+ else if ( rStartPoint.Y() == rEntry.mnEndPos )
+ pStyles[ 1 ] = rEntry.maAttribute;
+ }
+ else
+ {
+ if ( rStartPoint.Y() == rEntry.mnEndPos )
+ pStyles[ 2 ] = rEntry.maAttribute;
+ else if ( rEndPoint.Y() == rEntry.mnStartPos )
+ pStyles[ 5 ] = rEntry.maAttribute;
+ }
+ ++aIter;
+ }
+
+ aMapIter = maHoriLines.find( rStartPoint.Y() );
+ OSL_ENSURE( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" );
+ const SwLineEntrySet& rHoriSet = (*aMapIter).second;
+ aIter = rHoriSet.begin();
+
+ while ( aIter != rHoriSet.end() )
+ {
+ const SwLineEntry& rEntry = *aIter;
+ if ( bHori )
+ {
+ if ( rStartPoint.X() == rEntry.mnEndPos )
+ pStyles[ 2 ] = rEntry.maAttribute;
+ else if ( rEndPoint.X() == rEntry.mnStartPos )
+ pStyles[ 5 ] = rEntry.maAttribute;
+ }
+ else
+ {
+ if ( rStartPoint.X() == rEntry.mnEndPos )
+ pStyles[ 1 ] = rEntry.maAttribute;
+ else if ( rStartPoint.X() == rEntry.mnStartPos )
+ pStyles[ 3 ] = rEntry.maAttribute;
+ }
+ ++aIter;
+ }
+
+ if ( bHori )
+ {
+ aMapIter = maVertLines.find( rEndPoint.X() );
+ OSL_ENSURE( aMapIter != maVertLines.end(), "FindStylesForLine: Error" );
+ const SwLineEntrySet& rVertSet2 = (*aMapIter).second;
+ aIter = rVertSet2.begin();
+
+ while ( aIter != rVertSet2.end() )
+ {
+ const SwLineEntry& rEntry = *aIter;
+ if ( rEndPoint.Y() == rEntry.mnStartPos )
+ pStyles[ 6 ] = rEntry.maAttribute;
+ else if ( rEndPoint.Y() == rEntry.mnEndPos )
+ pStyles[ 4 ] = rEntry.maAttribute;
+ ++aIter;
+ }
+ }
+ else
+ {
+ aMapIter = maHoriLines.find( rEndPoint.Y() );
+ OSL_ENSURE( aMapIter != maHoriLines.end(), "FindStylesForLine: Error" );
+ const SwLineEntrySet& rHoriSet2 = (*aMapIter).second;
+ aIter = rHoriSet2.begin();
+
+ while ( aIter != rHoriSet2.end() )
+ {
+ const SwLineEntry& rEntry = *aIter;
+ if ( rEndPoint.X() == rEntry.mnEndPos )
+ pStyles[ 4 ] = rEntry.maAttribute;
+ else if ( rEndPoint.X() == rEntry.mnStartPos )
+ pStyles[ 6 ] = rEntry.maAttribute;
+ ++aIter;
+ }
+ }
+}
+
+void SwTabFrmPainter::Insert( const SwFrm& rFrm, const SvxBoxItem& rBoxItem )
+{
+ std::vector< const SwFrm* > aTestVec;
+ aTestVec.push_back( &rFrm );
+ aTestVec.push_back( &rFrm );
+ aTestVec.push_back( &rFrm );
+
+ // build 4 line entries for the 4 borders:
+ SwRect aBorderRect = rFrm.Frm();
+ if ( rFrm.IsTabFrm() )
+ {
+ aBorderRect = rFrm.Prt();
+ aBorderRect.Pos() += rFrm.Frm().Pos();
+ }
+
+ const SwTwips nLeft = aBorderRect._Left();
+ const SwTwips nRight = aBorderRect._Right();
+ const SwTwips nTop = aBorderRect._Top();
+ const SwTwips nBottom = aBorderRect._Bottom();
+
+ svx::frame::Style aL( rBoxItem.GetLeft() );
+ svx::frame::Style aR( rBoxItem.GetRight() );
+ svx::frame::Style aT( rBoxItem.GetTop() );
+ svx::frame::Style aB( rBoxItem.GetBottom() );
+
+ const SwTwips nHalfTopWidth = aT.GetWidth() / 2;
+
+ aR.MirrorSelf();
+ aB.MirrorSelf();
+
+ bool bVert = mrTabFrm.IsVertical();
+ bool bR2L = mrTabFrm.IsRightToLeft();
+
+ aL.SetRefMode( svx::frame::REFMODE_CENTERED );
+ aR.SetRefMode( svx::frame::REFMODE_CENTERED );
+ aT.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
+ aB.SetRefMode( !bVert ? svx::frame::REFMODE_BEGIN : svx::frame::REFMODE_END );
+
+ SwLineEntry aLeft ( nLeft, nTop + nHalfTopWidth, nBottom + nHalfTopWidth, bVert ? aB : ( bR2L ? aR : aL ) );
+ SwLineEntry aRight ( nRight, nTop + nHalfTopWidth, nBottom + nHalfTopWidth, bVert ? aT : ( bR2L ? aL : aR ) );
+ SwLineEntry aTop ( nTop + nHalfTopWidth, nLeft, nRight, bVert ? aL : aT );
+ SwLineEntry aBottom( nBottom + nHalfTopWidth, nLeft, nRight, bVert ? aR : aB );
+
+ Insert( aLeft, false );
+ Insert( aRight, false );
+ Insert( aTop, true );
+ Insert( aBottom, true );
+
+ const SwRowFrm* pThisRowFrm = dynamic_cast<const SwRowFrm*>(rFrm.GetUpper());
+
+ // special case: #i9860#
+ // first line in follow table without repeated headlines
+ if ( pThisRowFrm &&
+ pThisRowFrm->GetUpper() == &mrTabFrm &&
+ mrTabFrm.IsFollow() &&
+ !mrTabFrm.GetTable()->GetRowsToRepeat() &&
+ (!pThisRowFrm->GetPrev() || static_cast<const SwRowFrm*>(pThisRowFrm->GetPrev())->IsRowSpanLine()) &&
+ !rBoxItem.GetTop() &&
+ rBoxItem.GetBottom() )
+ {
+ SwLineEntry aFollowTop( !bVert ? nTop : nRight, !bVert ? nLeft : nTop, !bVert ? nRight : nBottom, aB );
+ Insert( aFollowTop, !bVert );
+ }
+}
+
+void SwTabFrmPainter::Insert( SwLineEntry& rNew, bool bHori )
+{
+ // get all lines from structure, that have key entry of pLE
+ SwLineEntryMap* pLine2 = bHori ? &maHoriLines : &maVertLines;
+ const SwTwips nKey = rNew.mnKey;
+ SwLineEntryMapIter aMapIter = pLine2->find( nKey );
+
+ SwLineEntrySet* pLineSet = aMapIter != pLine2->end() ? &((*aMapIter).second) : 0;
+ if ( !pLineSet )
+ {
+ SwLineEntrySet aNewSet;
+ (*pLine2)[ nKey ] = aNewSet;
+ pLineSet = &(*pLine2)[ nKey ];
+ }
+ SwLineEntrySetIter aIter = pLineSet->begin();
+
+ while ( pLineSet && aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos )
+ {
+ const SwLineEntry& rOld = *aIter;
+ const SwLineEntry::OverlapType nOverlapType = rOld.Overlaps( rNew );
+
+ const svx::frame::Style& rOldAttr = rOld.maAttribute;
+ const svx::frame::Style& rNewAttr = rNew.maAttribute;
+ const svx::frame::Style& rCmpAttr = rNewAttr > rOldAttr ? rNewAttr : rOldAttr;
+
+ if ( SwLineEntry::OVERLAP1 == nOverlapType )
+ {
+ OSL_ENSURE( rNew.mnStartPos >= rOld.mnStartPos, "Overlap type 3? How this?" );
+
+ // new left segment
+ const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
+
+ // new middle segment
+ const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rOld.mnEndPos, rCmpAttr );
+
+ // new right segment
+ rNew.mnStartPos = rOld.mnEndPos;
+
+ // update current lines set
+ pLineSet->erase( aIter );
+ if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
+ if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
+
+ aIter = pLineSet->begin();
+
+ continue; // start over
+ }
+ else if ( SwLineEntry::OVERLAP2 == nOverlapType )
+ {
+ // new left segment
+ const SwLineEntry aLeft( nKey, rOld.mnStartPos, rNew.mnStartPos, rOldAttr );
+
+ // new middle segment
+ const SwLineEntry aMiddle( nKey, rNew.mnStartPos, rNew.mnEndPos, rCmpAttr );
+
+ // new right segment
+ const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr );
+
+ // update current lines set
+ pLineSet->erase( aIter );
+ if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
+ if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
+ if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
+
+ rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
+
+ break; // we are finished
+ }
+ else if ( SwLineEntry::OVERLAP3 == nOverlapType )
+ {
+ // new left segment
+ const SwLineEntry aLeft( nKey, rNew.mnStartPos, rOld.mnStartPos, rNewAttr );
+
+ // new middle segment
+ const SwLineEntry aMiddle( nKey, rOld.mnStartPos, rNew.mnEndPos, rCmpAttr );
+
+ // new right segment
+ const SwLineEntry aRight( nKey, rNew.mnEndPos, rOld.mnEndPos, rOldAttr );
+
+ // update current lines set
+ pLineSet->erase( aIter );
+ if ( aLeft.mnStartPos < aLeft.mnEndPos ) pLineSet->insert( aLeft );
+ if ( aMiddle.mnStartPos < aMiddle.mnEndPos ) pLineSet->insert( aMiddle );
+ if ( aRight.mnStartPos < aRight.mnEndPos ) pLineSet->insert( aRight );
+
+ rNew.mnStartPos = rNew.mnEndPos; // rNew should not be inserted!
+
+ break; // we are finished
+ }
+
+ ++aIter;
+ }
+
+ if ( rNew.mnStartPos < rNew.mnEndPos ) // insert rest
+ pLineSet->insert( rNew );
+}
+
+//
+// FUNCTIONS USED FOR COLLAPSING TABLE BORDER LINES END
+//
+
+/*************************************************************************
+|*
+|* SwRootFrm::Paint()
+|*
+|* Beschreibung
+|* Fuer jede sichtbare Seite, die von Rect ber?hrt wird einmal Painten.
+|* 1. Umrandungen und Hintergruende Painten.
+|* 2. Den Draw Layer (Ramen und Zeichenobjekte) der unter dem Dokument
+|* liegt painten (Hoelle).
+|* 3. Den Dokumentinhalt (Text) Painten.
+|* 4. Den Drawlayer der ueber dem Dokuemnt liegt painten.
+|*
+|*************************************************************************/
+
+void
+SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const
+{
+ OSL_ENSURE( Lower() && Lower()->IsPageFrm(), "Lower der Root keine Seite." );
+
+ PROTOCOL( this, PROT_FILE_INIT, 0, 0)
+
+ sal_Bool bResetRootPaint = sal_False;
+ ViewShell *pSh = pCurrShell;
+
+ if ( pSh->GetWin() )
+ {
+ if ( pSh->GetOut() == pSh->GetWin() && !pSh->GetWin()->IsVisible() )
+ {
+ return;
+ }
+ if ( SwRootFrm::bInPaint )
+ {
+ SwPaintQueue::Add( pSh, rRect );
+ return;
+ }
+ }
+ else
+ SwRootFrm::bInPaint = bResetRootPaint = sal_True;
+
+ SwSavePaintStatics *pStatics = 0;
+ if ( pGlobalShell )
+ pStatics = new SwSavePaintStatics();
+ pGlobalShell = pSh;
+
+ if( !pSh->GetWin() )
+ pProgress = SfxProgress::GetActiveProgress( (SfxObjectShell*) pSh->GetDoc()->GetDocShell() );
+
+ ::SwCalcPixStatics( pSh->GetOut() );
+ aGlobalRetoucheColor = pSh->Imp()->GetRetoucheColor();
+
+ //Ggf. eine Action ausloesen um klare Verhaeltnisse zu schaffen.
+ //Durch diesen Kunstgriff kann in allen Paints davon ausgegangen werden,
+ //das alle Werte gueltigt sind - keine Probleme, keine Sonderbehandlung(en).
+ // --> OD 2008-10-07 #i92745#
+ // Extend check on certain states of the 'current' <ViewShell> instance to
+ // all existing <ViewShell> instances.
+ bool bPerformLayoutAction( true );
+ {
+ ViewShell* pTmpViewShell = pSh;
+ do {
+ if ( pTmpViewShell->IsInEndAction() ||
+ pTmpViewShell->IsPaintInProgress() ||
+ ( pTmpViewShell->Imp()->IsAction() &&
+ pTmpViewShell->Imp()->GetLayAction().IsActionInProgress() ) )
+ {
+ bPerformLayoutAction = false;
+ }
+
+ pTmpViewShell = static_cast<ViewShell*>(pTmpViewShell->GetNext());
+ } while ( bPerformLayoutAction && pTmpViewShell != pSh );
+ }
+ if ( bPerformLayoutAction )
+ // <--
+ {
+ ((SwRootFrm*)this)->ResetTurbo();
+ SwLayAction aAction( (SwRootFrm*)this, pSh->Imp() );
+ aAction.SetPaint( sal_False );
+ aAction.SetComplete( sal_False );
+ aAction.SetReschedule( pProgress ? sal_True : sal_False );
+ aAction.Action();
+ ((SwRootFrm*)this)->ResetTurboFlag();
+ if ( !pSh->ActionPend() )
+ pSh->Imp()->DelRegion();
+ }
+
+ SwRect aRect( rRect );
+ aRect.Intersection( pSh->VisArea() );
+
+ const sal_Bool bExtraData = ::IsExtraData( GetFmt()->GetDoc() );
+
+ pLines = new SwLineRects; //Sammler fuer Umrandungen.
+
+ // #104289#. During painting, something (OLE) can
+ // load the linguistic, which in turn can cause a reformat
+ // of the document. Dangerous! We better set this flag to
+ // avoid the reformat.
+ const sal_Bool bOldAction = IsCallbackActionEnabled();
+ ((SwRootFrm*)this)->SetCallbackActionEnabled( sal_False );
+
+ const SwPageFrm *pPage = pSh->Imp()->GetFirstVisPage();
+
+ const bool bBookMode = pGlobalShell->GetViewOptions()->IsViewLayoutBookMode();
+ if ( bBookMode && pPage->GetPrev() && static_cast<const SwPageFrm*>(pPage->GetPrev())->IsEmptyPage() )
+ pPage = static_cast<const SwPageFrm*>(pPage->GetPrev());
+
+ const bool bLTR = IsLeftToRightViewLayout();
+
+ // #i68597#
+ const bool bGridPainting(pSh->GetWin() && pSh->Imp()->HasDrawView() && pSh->Imp()->GetDrawView()->IsGridVisible());
+
+ // --> OD 2008-05-16 #i84659#
+// while ( pPage && !::IsShortCut( aRect, pPage->Frm() ) )
+ while ( pPage )
+ // <--
+ {
+ // Paint right shadow in single page mode, or if we're on last page of
+ // the doc, or if ???Lower()??? or if we're on a page with no right
+ // sibling (OnRightPage should be renamed as OnEvenPage since it does
+ // not take reading direction into account)
+ const bool bPaintRightShadow = !bBookMode || (!pPage->GetNext()) || (pPage == Lower()) || (!bLTR && !pPage->OnRightPage()) || (bLTR && pPage->OnRightPage());
+ // Have a full bottom shadow on side by side pages.
+ // TODO Do not draw full shadow if our sibling hasn't the
+ // same orientation
+ const bool bFullBottomShadow = bBookMode && pPage->GetPrev() &&
+ ((!bLTR && !pPage->OnRightPage()) || (bLTR && pPage->OnRightPage()));
+ const bool bRightSidebar = pPage->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT;
+
+ if ( !pPage->IsEmptyPage() )
+ {
+ SwRect aPaintRect;
+ SwPageFrm::GetBorderAndShadowBoundRect( pPage->Frm(), pSh, aPaintRect, bRightSidebar );
+
+ if ( aRect.IsOver( aPaintRect ) )
+ // <--
+ {
+ if ( pSh->GetWin() )
+ {
+ pSubsLines = new SwSubsRects;
+ // OD 18.11.2002 #99672# - create array for special sub-lines
+ pSpecSubsLines = new SwSubsRects;
+ }
+
+ aPaintRect._Intersection( aRect );
+
+ if ( bExtraData &&
+ pSh->GetWin() && pSh->IsInEndAction() )
+ {
+ // enlarge paint rectangle to complete page width, subtract
+ // current paint area and invalidate the resulting region.
+ SWRECTFN( pPage )
+ SwRect aPageRectTemp( aPaintRect );
+ (aPageRectTemp.*fnRect->fnSetLeftAndWidth)(
+ (pPage->Frm().*fnRect->fnGetLeft)(),
+ (pPage->Frm().*fnRect->fnGetWidth)() );
+ aPageRectTemp._Intersection( pSh->VisArea() );
+ Region aPageRectRegion( aPageRectTemp.SVRect() );
+ aPageRectRegion.Exclude( aPaintRect.SVRect() );
+ pSh->GetWin()->Invalidate( aPageRectRegion, INVALIDATE_CHILDREN );
+ }
+ // <--
+
+ // --> OD 2007-08-20 #i80793#
+ // enlarge paint rectangle for objects overlapping the same pixel
+ // in all cases and before the DrawingLayer overlay is initialized.
+ lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
+ // <--
+
+ // #i68597#
+ // moved paint pre-process for DrawingLayer overlay here since the above
+ // code dependent from bExtraData may expand the PaintRect
+ {
+ // #i75172# if called from ViewShell::ImplEndAction it sould no longer
+ // really be used but handled by ViewShell::ImplEndAction already
+ const Region aDLRegion(aPaintRect.SVRect());
+ pSh->DLPrePaint2(aDLRegion);
+ }
+
+ if(OUTDEV_WINDOW == pGlobalShell->GetOut()->GetOutDevType())
+ {
+ /// OD 27.09.2002 #103636# - changed method SwLayVout::Enter(..)
+ /// 2nd parameter is no longer <const> and will be set to the
+ /// rectangle the virtual output device is calculated from <aPaintRect>,
+ /// if the virtual output is used.
+ pVout->Enter( pSh, aPaintRect, !bNoVirDev );
+
+ /// OD 27.09.2002 #103636# - adjust paint rectangle to pixel size
+ /// Thus, all objects overlapping on pixel level with the unadjusted
+ /// paint rectangle will be considered in the paint.
+ lcl_AdjustRectToPixelSize( aPaintRect, *(pSh->GetOut()) );
+ }
+
+ // maybe this can be put in the above scope. Since we are not sure, just leave it ATM
+ pVout->SetOrgRect( aPaintRect );
+
+ /// OD 29.08.2002 #102450#
+ /// determine background color of page for <PaintLayer> method
+ /// calls, paint <hell> or <heaven>
+ const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
+
+ pPage->PaintBaBo( aPaintRect, pPage, sal_True );
+
+ if ( pSh->Imp()->HasDrawView() )
+ {
+ pLines->LockLines( sal_True );
+ // OD 29.08.2002 #102450# - add 3rd parameter
+ // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
+ const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
+ pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), pPrintData, aPaintRect,
+ &aPageBackgrdColor, (pPage->IsRightToLeft() ? true : false) );
+ pLines->PaintLines( pSh->GetOut() );
+ pLines->LockLines( sal_False );
+ }
+
+ if( pSh->GetWin() )
+ {
+ // OD 18.11.2002 #99672# - collect sub-lines
+ pPage->RefreshSubsidiary( aPaintRect );
+ // OD 18.11.2002 #99672# - paint special sub-lines
+ pSpecSubsLines->PaintSubsidiary( pSh->GetOut(), NULL );
+ }
+
+ pPage->Paint( aPaintRect );
+
+ // OD 20.12.2002 #94627# - no paint of page border and shadow, if
+ // writer is in place mode.
+ if( pSh->GetWin() && pSh->GetDoc()->GetDocShell() &&
+ !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
+ {
+ // OD 12.02.2003 #i9719#, #105645# - use new method
+ // <SwPageFrm::PaintBorderAndShadow(..)>.
+ SwPageFrm::PaintBorderAndShadow( pPage->Frm(), pSh, bPaintRightShadow, bFullBottomShadow, bRightSidebar );
+ SwPageFrm::PaintNotesSidebar( pPage->Frm(), pSh, pPage->GetPhyPageNum(), bRightSidebar);
+ }
+
+ pLines->PaintLines( pSh->GetOut() );
+
+ if ( pSh->Imp()->HasDrawView() )
+ {
+ /// OD 29.08.2002 #102450# - add 3rd parameter
+ // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
+ pSh->Imp()->PaintLayer( pSh->GetDoc()->GetHeavenId(), pPrintData, aPaintRect,
+ &aPageBackgrdColor,
+ (pPage->IsRightToLeft() ? true : false) );
+ }
+
+ if ( bExtraData )
+ pPage->RefreshExtraData( aPaintRect );
+
+ if ( pSh->GetWin() )
+ {
+ pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines );
+ DELETEZ( pSubsLines );
+ DELETEZ( pSpecSubsLines );
+ }
+ pVout->Leave();
+
+ // #i68597#
+ // needed to move grid painting inside Begin/EndDrawLayer bounds and to change
+ // output rect for it accordingly
+ if(bGridPainting)
+ {
+ SdrPaintView* pPaintView = pSh->Imp()->GetDrawView();
+ SdrPageView* pPageView = pPaintView->GetSdrPageView();
+ pPageView->DrawPageViewGrid(*pSh->GetOut(), aPaintRect.SVRect(), SwViewOption::GetTextGridColor() );
+ }
+
+ // #i68597#
+ // moved paint post-process for DrawingLayer overlay here, see above
+ {
+ pSh->DLPostPaint2(true);
+ }
+ }
+ }
+ else if ( bBookMode && pSh->GetWin() && !pSh->GetDoc()->GetDocShell()->IsInPlaceActive() )
+ {
+ // paint empty page
+ SwRect aPaintRect;
+ SwRect aEmptyPageRect( pPage->Frm() );
+
+ // code from vprint.cxx
+ const SwPageFrm& rFormatPage = pPage->GetFormatPage();
+ aEmptyPageRect.SSize() = rFormatPage.Frm().SSize();
+
+ SwPageFrm::GetBorderAndShadowBoundRect( aEmptyPageRect, pSh, aPaintRect, bRightSidebar );
+ aPaintRect._Intersection( aRect );
+
+ if ( aRect.IsOver( aEmptyPageRect ) )
+ {
+ // #i75172# if called from ViewShell::ImplEndAction it sould no longer
+ // really be used but handled by ViewShell::ImplEndAction already
+ {
+ const Region aDLRegion(aPaintRect.SVRect());
+ pSh->DLPrePaint2(aDLRegion);
+ }
+
+ if( pSh->GetOut()->GetFillColor() != aGlobalRetoucheColor )
+ pSh->GetOut()->SetFillColor( aGlobalRetoucheColor );
+
+ pSh->GetOut()->SetLineColor(); // OD 20.02.2003 #107369# - no line color
+ // OD 20.02.2003 #107369# - use aligned page rectangle
+ {
+ SwRect aTmpPageRect( aEmptyPageRect );
+ ::SwAlignRect( aTmpPageRect, pSh );
+ aEmptyPageRect = aTmpPageRect;
+ }
+
+ pSh->GetOut()->DrawRect( aEmptyPageRect.SVRect() );
+
+ // paint empty page text
+ const Font& rEmptyPageFont = SwPageFrm::GetEmptyPageFont();
+ const Font aOldFont( pSh->GetOut()->GetFont() );
+
+ pSh->GetOut()->SetFont( rEmptyPageFont );
+ pSh->GetOut()->DrawText( aEmptyPageRect.SVRect(), SW_RESSTR( STR_EMPTYPAGE ),
+ TEXT_DRAW_VCENTER |
+ TEXT_DRAW_CENTER |
+ TEXT_DRAW_CLIP );
+
+ pSh->GetOut()->SetFont( aOldFont );
+ // paint shadow and border for empty page
+ // OD 19.02.2003 #107369# - use new method to paint page border and
+ // shadow
+ SwPageFrm::PaintBorderAndShadow( aEmptyPageRect, pSh, bPaintRightShadow, bFullBottomShadow, bRightSidebar );
+ SwPageFrm::PaintNotesSidebar( aEmptyPageRect, pSh, pPage->GetPhyPageNum(), bRightSidebar);
+
+ {
+ pSh->DLPostPaint2(true);
+ }
+ }
+ }
+
+ OSL_ENSURE( !pPage->GetNext() || pPage->GetNext()->IsPageFrm(),
+ "Nachbar von Seite keine Seite." );
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+
+ DELETEZ( pLines );
+
+ if ( bResetRootPaint )
+ SwRootFrm::bInPaint = sal_False;
+ if ( pStatics )
+ delete pStatics;
+ else
+ {
+ pProgress = 0;
+ pGlobalShell = 0;
+ }
+
+ ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction );
+}
+
+/*************************************************************************
+|*
+|* SwLayoutFrm::Paint()
+|*
+|*************************************************************************/
+
+void MA_FASTCALL lcl_EmergencyFormatFtnCont( SwFtnContFrm *pCont )
+{
+ //Es kann sein, dass der Cont vernichtet wird.
+ SwCntntFrm *pCnt = pCont->ContainsCntnt();
+ while ( pCnt && pCnt->IsInFtn() )
+ {
+ pCnt->Calc();
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+}
+
+class SwShortCut
+{
+ SwRectDist fnCheck;
+ long nLimit;
+public:
+ SwShortCut( const SwFrm& rFrm, const SwRect& rRect );
+ sal_Bool Stop( const SwRect& rRect ) const
+ { return (rRect.*fnCheck)( nLimit ) > 0; }
+};
+
+SwShortCut::SwShortCut( const SwFrm& rFrm, const SwRect& rRect )
+{
+ sal_Bool bVert = rFrm.IsVertical();
+ sal_Bool bR2L = rFrm.IsRightToLeft();
+ if( rFrm.IsNeighbourFrm() && bVert == bR2L )
+ {
+ if( bVert )
+ {
+ fnCheck = &SwRect::GetBottomDistance;
+ nLimit = rRect.Top();
+ }
+ else
+ {
+ fnCheck = &SwRect::GetLeftDistance;
+ nLimit = rRect.Left() + rRect.Width();
+ }
+ }
+ else if( bVert == rFrm.IsNeighbourFrm() )
+ {
+ fnCheck = &SwRect::GetTopDistance;
+ nLimit = rRect.Top() + rRect.Height();
+ }
+ else
+ {
+ //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
+ if ( rFrm.IsVertLR() )
+ {
+ fnCheck = &SwRect::GetLeftDistance;
+ nLimit = rRect.Right();
+ }
+ else
+ {
+ fnCheck = &SwRect::GetRightDistance;
+ nLimit = rRect.Left();
+ }
+ }
+}
+
+void SwLayoutFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
+{
+ ViewShell *pSh = getRootFrm()->GetCurrShell();
+
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ Frm_Info aFrmInfo( *this );
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, &aFrmInfo, 0, *pSh->GetOut() );
+ // <--
+
+ const SwFrm *pFrm = Lower();
+ if ( !pFrm )
+ return;
+
+ SwShortCut aShortCut( *pFrm, rRect );
+ sal_Bool bCnt;
+ if ( sal_True == (bCnt = pFrm->IsCntntFrm()) )
+ pFrm->Calc();
+
+ if ( pFrm->IsFtnContFrm() )
+ {
+ ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm );
+ pFrm = Lower();
+ }
+
+ const SwPageFrm *pPage = 0;
+ const sal_Bool bWin = pGlobalShell->GetWin() ? sal_True : sal_False;
+
+ while ( IsAnLower( pFrm ) )
+ {
+ SwRect aPaintRect( pFrm->PaintArea() );
+ if( aShortCut.Stop( aPaintRect ) )
+ break;
+ if ( bCnt && pProgress )
+ pProgress->Reschedule();
+
+ //Wenn ein Frm es explizit will muss retouchiert werden.
+ //Erst die Retouche, denn selbige koennte die aligned'en Raender
+ //plaetten.
+ if ( pFrm->IsRetouche() )
+ {
+ if ( pFrm->IsRetoucheFrm() && bWin && !pFrm->GetNext() )
+ { if ( !pPage )
+ pPage = FindPageFrm();
+ pFrm->Retouche( pPage, rRect );
+ }
+ pFrm->ResetRetouche();
+ }
+
+ if ( rRect.IsOver( aPaintRect ) )
+ {
+ if ( bCnt && pFrm->IsCompletePaint() &&
+ !rRect.IsInside( aPaintRect ) && GetpApp()->AnyInput( INPUT_KEYBOARD ) )
+ {
+ //fix(8104): Es kann vorkommen, dass die Verarbeitung nicht
+ //vollstaendig war, aber trotzdem Teile des Absatzes gepaintet
+ //werden. In der Folge werden dann evtl. wiederum andere Teile
+ //des Absatzes garnicht mehr gepaintet. Einziger Ausweg scheint
+ //hier ein Invalidieren der Windows zu sein.
+ //Um es nicht alzu Heftig werden zu lassen versuche ich hier
+ //das Rechteck zu begrenzen indem der gewuenschte Teil gepaintet
+ //und nur die uebrigen Absatzanteile invalidiert werden.
+ if ( aPaintRect.Left() == rRect.Left() &&
+ aPaintRect.Right() == rRect.Right() )
+ {
+ aPaintRect.Bottom( rRect.Top() - 1 );
+ if ( aPaintRect.Height() > 0 )
+ pGlobalShell->InvalidateWindows(aPaintRect);
+ aPaintRect.Top( rRect.Bottom() + 1 );
+ aPaintRect.Bottom( pFrm->Frm().Bottom() );
+ if ( aPaintRect.Height() > 0 )
+ pGlobalShell->InvalidateWindows(aPaintRect);
+ aPaintRect.Top( pFrm->Frm().Top() );
+ aPaintRect.Bottom( pFrm->Frm().Bottom() );
+ }
+ else
+ {
+ pGlobalShell->InvalidateWindows( aPaintRect );
+ pFrm = pFrm->GetNext();
+ if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) )
+ pFrm->Calc();
+ continue;
+ }
+ }
+ pFrm->ResetCompletePaint();
+ aPaintRect._Intersection( rRect );
+
+ pFrm->Paint( aPaintRect );
+
+ if ( Lower() && Lower()->IsColumnFrm() )
+ {
+ //Ggf. die Spaltentrennlinien malen. Fuer den Seitenbody ist
+ //nicht der Upper sondern die Seite Zustaendig.
+ const SwFrmFmt *pFmt = GetUpper() && GetUpper()->IsPageFrm()
+ ? GetUpper()->GetFmt()
+ : GetFmt();
+ const SwFmtCol &rCol = pFmt->GetCol();
+ if ( rCol.GetLineAdj() != COLADJ_NONE )
+ {
+ if ( !pPage )
+ pPage = pFrm->FindPageFrm();
+
+ PaintColLines( aPaintRect, rCol, pPage );
+ }
+ }
+ }
+ if ( !bCnt && pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() )
+ ::lcl_EmergencyFormatFtnCont( (SwFtnContFrm*)pFrm->GetNext() );
+
+ pFrm = pFrm->GetNext();
+ if ( pFrm && (sal_True == (bCnt = pFrm->IsCntntFrm())) )
+ pFrm->Calc();
+ }
+}
+
+/** FlyFrm::IsBackgroundTransparent - for feature #99657#
+
+ OD 12.08.2002
+ determines, if background of fly frame has to be drawn transparent
+ declaration found in /core/inc/flyfrm.cxx
+ OD 08.10.2002 #103898# - If the background of the fly frame itself is not
+ transparent and the background is inherited from its parent/grandparent,
+ the background brush, used for drawing, has to be investigated for transparency.
+
+ @author OD
+
+ @return true, if background is transparent drawn.
+*/
+sal_Bool SwFlyFrm::IsBackgroundTransparent() const
+{
+ sal_Bool bBackgroundTransparent = GetFmt()->IsBackgroundTransparent();
+ if ( !bBackgroundTransparent &&
+ static_cast<const SwFlyFrmFmt*>(GetFmt())->IsBackgroundBrushInherited() )
+ {
+ const SvxBrushItem* pBackgrdBrush = 0;
+ const Color* pSectionTOXColor = 0;
+ SwRect aDummyRect;
+ if ( GetBackgroundBrush( pBackgrdBrush, pSectionTOXColor, aDummyRect, false) )
+ {
+ if ( pSectionTOXColor &&
+ (pSectionTOXColor->GetTransparency() != 0) &&
+ (pSectionTOXColor->GetColor() != COL_TRANSPARENT) )
+ {
+ bBackgroundTransparent = sal_True;
+ }
+ else if ( pBackgrdBrush )
+ {
+ if ( (pBackgrdBrush->GetColor().GetTransparency() != 0) &&
+ (pBackgrdBrush->GetColor() != COL_TRANSPARENT) )
+ {
+ bBackgroundTransparent = sal_True;
+ }
+ else
+ {
+ const GraphicObject *pTmpGrf =
+ static_cast<const GraphicObject*>(pBackgrdBrush->GetGraphicObject());
+ if ( (pTmpGrf) &&
+ (pTmpGrf->GetAttr().GetTransparency() != 0)
+ )
+ {
+ bBackgroundTransparent = sal_True;
+ }
+ }
+ }
+ }
+ }
+
+ return bBackgroundTransparent;
+};
+
+/** FlyFrm::IsShadowTransparent - for feature #99657#
+
+ OD 13.08.2002
+ determine, if shadow color of fly frame has to be drawn transparent
+ declaration found in /core/inc/flyfrm.cxx
+
+ @author OD
+
+ @return true, if shadow color is transparent.
+*/
+sal_Bool SwFlyFrm::IsShadowTransparent() const
+{
+ return GetFmt()->IsShadowTransparent();
+};
+
+/*************************************************************************
+|*
+|* SwFlyFrm::IsPaint()
+|*
+|*************************************************************************/
+
+sal_Bool SwFlyFrm::IsPaint( SdrObject *pObj, const ViewShell *pSh )
+{
+ SdrObjUserCall *pUserCall;
+
+ if ( 0 == ( pUserCall = GetUserCall(pObj) ) )
+ return sal_True;
+
+ //Attributabhaengig nicht fuer Drucker oder PreView painten
+ sal_Bool bPaint = pFlyOnlyDraw ||
+ ((SwContact*)pUserCall)->GetFmt()->GetPrint().GetValue();
+ if ( !bPaint )
+ bPaint = pSh->GetWin() && !pSh->IsPreView();
+
+ if ( bPaint )
+ {
+ //Das Paint kann evtl. von von uebergeordneten Flys verhindert werden.
+ SwFrm *pAnch = 0;
+ if ( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
+ if ( pFlyOnlyDraw && pFlyOnlyDraw == pFly )
+ return sal_True;
+
+ //Die Anzeige eines Zwischenstadiums vermeiden, Flys die nicht mit
+ //der Seite auf der sie verankert sind ueberlappen werden auch
+ //nicht gepaintet.
+ //HACK: Ausnahme: Drucken von Rahmen in Tabellen, diese koennen
+ //bei uebergrossen Tabellen (HTML) schon mal auserhalb der Seite
+ //stehen.
+ SwPageFrm *pPage = pFly->FindPageFrm();
+ if ( pPage )
+ {
+ if ( pPage->Frm().IsOver( pFly->Frm() ) )
+ pAnch = pFly->AnchorFrm();
+ else if ( bTableHack &&
+ pFly->Frm().Top() >= pFly->GetAnchorFrm()->Frm().Top() &&
+ pFly->Frm().Top() < pFly->GetAnchorFrm()->Frm().Bottom() &&
+ long(pSh->GetOut()) ==
+ long(pSh->getIDocumentDeviceAccess()->getPrinter( false ) ) )
+ {
+ pAnch = pFly->AnchorFrm();
+ }
+ }
+
+ }
+ else
+ {
+ // OD 13.10.2003 #i19919# - consider 'virtual' drawing objects
+ // OD 2004-03-29 #i26791#
+ pAnch = ((SwDrawContact*)pUserCall)->GetAnchorFrm( pObj );
+ if ( pAnch )
+ {
+ if ( !pAnch->GetValidPosFlag() )
+ pAnch = 0;
+ else if ( long(pSh->GetOut()) == long(pSh->getIDocumentDeviceAccess()->getPrinter( false )))
+ {
+ //HACK: fuer das Drucken muessen wir ein paar Objekte
+ //weglassen, da diese sonst doppelt gedruckt werden.
+ //Die Objekte sollen gedruckt werden, wenn der TableHack
+ //gerade greift. In der Folge duerfen sie nicht gedruckt werden
+ //wenn sie mit der Seite dran sind, ueber der sie von der
+ //Position her gerade schweben.
+ const SwPageFrm *pPage = pAnch->FindPageFrm();
+ if ( !bTableHack &&
+ !pPage->Frm().IsOver( pObj->GetCurrentBoundRect() ) )
+ pAnch = 0;
+ }
+ }
+ else
+ {
+ // OD 02.07.2003 #108784# - debug assert
+ if ( !pObj->ISA(SdrObjGroup) )
+ {
+ OSL_FAIL( "<SwFlyFrm::IsPaint(..)> - paint of drawing object without anchor frame!?" );
+ }
+ }
+ }
+ if ( pAnch )
+ {
+ if ( pAnch->IsInFly() )
+ bPaint = SwFlyFrm::IsPaint( pAnch->FindFlyFrm()->GetVirtDrawObj(),
+ pSh );
+ else if ( pFlyOnlyDraw )
+ bPaint = sal_False;
+ }
+ else
+ bPaint = sal_False;
+ }
+ return bPaint;
+}
+
+/*************************************************************************
+|* SwCellFrm::Paint( const SwRect& ) const
+|*************************************************************************/
+void SwCellFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
+{
+ if ( GetLayoutRowSpan() >= 1 )
+ SwLayoutFrm::Paint( rRect );
+}
+
+/*************************************************************************
+|*
+|* SwFlyFrm::Paint()
+|*
+|*************************************************************************/
+
+//Weiter unten definiert
+void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay,
+ const SwRect &rRect, const SwPageFrm *pPage );
+
+void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
+{
+ //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die
+ //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben.
+ //z.B. #33066#
+ pLines->LockLines(sal_True);
+
+ SwRect aRect( rRect );
+ aRect._Intersection( Frm() );
+
+ OutputDevice* pOut = pGlobalShell->GetOut();
+ pOut->Push( PUSH_CLIPREGION );
+ pOut->SetClipRegion();
+ const SwPageFrm* pPage = FindPageFrm();
+
+ const SwNoTxtFrm *pNoTxt = Lower() && Lower()->IsNoTxtFrm()
+ ? (SwNoTxtFrm*)Lower() : 0;
+
+ bool bIsChart = false; //#i102950# don't paint additional borders for charts
+ //check whether we have a chart
+ if(pNoTxt)
+ {
+ const SwNoTxtNode* pNoTNd = dynamic_cast<const SwNoTxtNode*>(pNoTxt->GetNode());
+ if( pNoTNd )
+ {
+ SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTNd->GetOLENode());
+ if( pOLENd && ChartPrettyPainter::IsChart( pOLENd->GetOLEObj().GetObject() ) )
+ bIsChart = true;
+ }
+ }
+
+ {
+ bool bContour = GetFmt()->GetSurround().IsContour();
+ PolyPolygon aPoly;
+ if ( bContour )
+ {
+ // OD 16.04.2003 #i13147# - add 2nd parameter with value <sal_True>
+ // to indicate that method is called for paint in order to avoid
+ // load of the intrinsic graphic.
+ bContour = GetContour( aPoly, sal_True );
+ }
+
+ // --> OD 2005-06-08 #i47804# - distinguish complete background paint
+ // and margin paint.
+ // paint complete background for Writer text fly frames
+ bool bPaintCompleteBack( !pNoTxt );
+ // <--
+ // paint complete background for transparent graphic and contour,
+ // if own background color exists.
+ const bool bIsGraphicTransparent = pNoTxt ? pNoTxt->IsTransparent() : false;
+ if ( !bPaintCompleteBack &&
+ ( bIsGraphicTransparent|| bContour ) )
+ {
+ const SvxBrushItem &rBack = GetFmt()->GetBackground();
+ // OD 07.08.2002 #99657# #GetTransChg#
+ // to determine, if background has to be painted, by checking, if
+ // background color is not COL_TRANSPARENT ("no fill"/"auto fill")
+ // or a background graphic exists.
+ bPaintCompleteBack = !(rBack.GetColor() == COL_TRANSPARENT) ||
+ rBack.GetGraphicPos() != GPOS_NONE;
+ }
+ // paint of margin needed.
+ const bool bPaintMarginOnly( !bPaintCompleteBack &&
+ Prt().SSize() != Frm().SSize() );
+
+ // --> OD 2005-06-08 #i47804# - paint background of parent fly frame
+ // for transparent graphics in layer Hell, if parent fly frame isn't
+ // in layer Hell. It's only painted the intersection between the
+ // parent fly frame area and the paint area <aRect>
+ const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
+
+ if ( bIsGraphicTransparent &&
+ GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() &&
+ GetAnchorFrm()->FindFlyFrm() )
+ {
+ const SwFlyFrm* pParentFlyFrm = GetAnchorFrm()->FindFlyFrm();
+ if ( pParentFlyFrm->GetDrawObj()->GetLayer() !=
+ pIDDMA->GetHellId() )
+ {
+ SwFlyFrm* pOldRet = pRetoucheFly2;
+ pRetoucheFly2 = const_cast<SwFlyFrm*>(this);
+
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pParentFlyFrm );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ SwRect aPaintRect( aRect );
+ aPaintRect._Intersection( pParentFlyFrm->Frm() );
+ pParentFlyFrm->PaintBackground( aPaintRect, pPage, rAttrs, sal_False, sal_False );
+
+ pRetoucheFly2 = pOldRet;
+ }
+ }
+
+ if ( bPaintCompleteBack || bPaintMarginOnly )
+ {
+ //#24926# JP 01.02.96, PaintBaBo in teilen hier, damit PaintBorder
+ //das orig. Rect bekommt, aber PaintBackground das begrenzte.
+
+ // OD 2004-04-23 #116347#
+ pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
+ pOut->SetLineColor();
+
+ pPage = FindPageFrm();
+
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+
+ // paint background
+ {
+ SwRegionRects aRegion( aRect );
+ // --> OD 2007-12-13 #i80822#
+ // suppress painting of background in printing area for
+ // non-transparent graphics.
+ if ( bPaintMarginOnly ||
+ ( pNoTxt && !bIsGraphicTransparent ) )
+ // <--
+ {
+ //Was wir eigentlich Painten wollen ist der schmale Streifen
+ //zwischen PrtArea und aeusserer Umrandung.
+ SwRect aTmp( Prt() ); aTmp += Frm().Pos();
+ aRegion -= aTmp;
+ }
+ if ( bContour )
+ {
+ pOut->Push();
+ // --> OD 2007-12-13 #i80822#
+ // apply clip region under the same conditions, which are
+ // used in <SwNoTxtFrm::Paint(..)> to set the clip region
+ // for painting the graphic/OLE. Thus, the clip region is
+ // also applied for the PDF export.
+ ViewShell *pSh = getRootFrm()->GetCurrShell();
+ if ( !pOut->GetConnectMetaFile() || !pSh || !pSh->GetWin() )
+ // <--
+ {
+ pOut->SetClipRegion( aPoly );
+ }
+ for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
+ PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
+ pOut->Pop();
+ }
+ else
+ for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
+ PaintBackground( aRegion[i], pPage, rAttrs, sal_False, sal_True );
+ }
+
+ // OD 06.08.2002 #99657# - paint border before painting background
+ // paint border
+ {
+ SwRect aTmp( rRect );
+ PaintBorder( aTmp, pPage, rAttrs );
+ }
+
+ pOut->Pop();
+ }
+ }
+
+ // OD 19.12.2002 #106318# - fly frame will paint it's subsidiary lines and
+ // the subsidiary lines of its lowers on its own, due to overlapping with
+ // other fly frames or other objects.
+ if( pGlobalShell->GetWin()
+ && !bIsChart ) //#i102950# don't paint additional borders for charts
+ {
+ bool bSubsLineRectsCreated;
+ if ( pSubsLines )
+ {
+ // Lock already existing subsidiary lines
+ pSubsLines->LockLines( sal_True );
+ bSubsLineRectsCreated = false;
+ }
+ else
+ {
+ // create new subsidiardy lines
+ pSubsLines = new SwSubsRects;
+ bSubsLineRectsCreated = true;
+ }
+
+ bool bSpecSubsLineRectsCreated;
+ if ( pSpecSubsLines )
+ {
+ // Lock already existing special subsidiary lines
+ pSpecSubsLines->LockLines( sal_True );
+ bSpecSubsLineRectsCreated = false;
+ }
+ else
+ {
+ // create new special subsidiardy lines
+ pSpecSubsLines = new SwSubsRects;
+ bSpecSubsLineRectsCreated = true;
+ }
+ // Add subsidiary lines of fly frame and its lowers
+ RefreshLaySubsidiary( pPage, aRect );
+ // paint subsidiary lines of fly frame and its lowers
+ pSpecSubsLines->PaintSubsidiary( pOut, NULL );
+ pSubsLines->PaintSubsidiary( pOut, pLines );
+ if ( !bSubsLineRectsCreated )
+ // unlock subsidiary lines
+ pSubsLines->LockLines( sal_False );
+ else
+ // delete created subsidiary lines container
+ DELETEZ( pSubsLines );
+
+ if ( !bSpecSubsLineRectsCreated )
+ // unlock special subsidiary lines
+ pSpecSubsLines->LockLines( sal_False );
+ else
+ {
+ // delete created special subsidiary lines container
+ DELETEZ( pSpecSubsLines );
+ }
+ }
+
+ SwLayoutFrm::Paint( aRect );
+
+ Validate();
+
+ // OD 19.12.2002 #106318# - first paint lines added by fly frame paint
+ // and then unlock other lines.
+ pLines->PaintLines( pOut );
+ pLines->LockLines( sal_False );
+
+ pOut->Pop();
+
+ if ( pProgress && pNoTxt )
+ pProgress->Reschedule();
+}
+/*************************************************************************
+|*
+|* SwTabFrm::Paint()
+|*
+|*************************************************************************/
+
+void SwTabFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
+{
+ if ( pGlobalShell->GetViewOptions()->IsTable() )
+ {
+ // --> collapsing borders FME 2005-05-27 #i29550#
+ if ( IsCollapsingBorders() )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+
+ // paint shadow
+ if ( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE )
+ {
+ SwRect aRect;
+ ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
+ PaintShadow( rRect, aRect, rAttrs );
+ }
+
+ // paint lines
+ SwTabFrmPainter aHelper( *this );
+ aHelper.PaintLines( *pGlobalShell->GetOut(), rRect );
+ }
+ // <-- collapsing
+
+ SwLayoutFrm::Paint( rRect );
+ }
+ // OD 10.01.2003 #i6467# - no light grey rectangle for page preview
+ else if ( pGlobalShell->GetWin() && !pGlobalShell->IsPreView() )
+ {
+ // OD 10.01.2003 #i6467# - intersect output rectangle with table frame
+ SwRect aTabRect( Prt() );
+ aTabRect.Pos() += Frm().Pos();
+ SwRect aTabOutRect( rRect );
+ aTabOutRect.Intersection( aTabRect );
+ pGlobalShell->GetViewOptions()->
+ DrawRect( pGlobalShell->GetOut(), aTabOutRect, COL_LIGHTGRAY );
+ }
+ ((SwTabFrm*)this)->ResetComplete();
+}
+
+/*************************************************************************
+|*
+|* SwFrm::PaintShadow()
+|*
+|* Beschreibung Malt einen Schatten wenns das FrmFormat fordert.
+|* Der Schatten wird immer an den auesseren Rand des OutRect gemalt.
+|* Das OutRect wird ggf. so verkleinert, dass auf diesem das
+|* malen der Umrandung stattfinden kann.
+|*
+|*************************************************************************/
+/// OD 23.08.2002 #99657#
+/// draw full shadow rectangle for frames with transparent drawn backgrounds.
+void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
+ const SwBorderAttrs &rAttrs ) const
+{
+ const SvxShadowItem &rShadow = rAttrs.GetShadow();
+ const long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth() );
+ const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth() );
+
+ SwRects aRegion( 2, 2 );
+ SwRect aOut( rOutRect );
+
+ const sal_Bool bCnt = IsCntntFrm();
+ const sal_Bool bTop = !bCnt || rAttrs.GetTopLine ( *(this) ) ? sal_True : sal_False;
+ const sal_Bool bBottom = !bCnt || rAttrs.GetBottomLine( *(this) ) ? sal_True : sal_False;
+
+ SvxShadowLocation eLoc = rShadow.GetLocation();
+
+ SWRECTFN( this )
+ if( IsVertical() )
+ {
+ switch( eLoc )
+ {
+ case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
+ case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
+ case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
+ case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_TOPLEFT; break;
+ default: break;
+ }
+ }
+
+ /// OD 23.08.2002 #99657# - determine, if full shadow rectangle have to
+ /// be drawn or only two shadow rectangles beside the frame.
+ /// draw full shadow rectangle, if frame background is drawn transparent.
+ /// Status Quo:
+ /// SwLayoutFrm can have transparent drawn backgrounds. Thus,
+ /// "asked" their frame format.
+ sal_Bool bDrawFullShadowRectangle =
+ ( IsLayoutFrm() &&
+ (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent()
+ );
+ switch ( eLoc )
+ {
+ case SVX_SHADOW_BOTTOMRIGHT:
+ {
+ if ( bDrawFullShadowRectangle )
+ {
+ /// OD 06.08.2002 #99657# - draw full shadow rectangle
+ aOut.Top( aOut.Top() + nHeight );
+ aOut.Left( aOut.Left() + nWidth );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+ else
+ {
+ aOut.Top ( aOut.Bottom() - nHeight );
+ aOut.Left( aOut.Left() + nWidth );
+ if ( bBottom )
+ aRegion.Insert( aOut, aRegion.Count() );
+ aOut.Left( aOut.Right() - nWidth );
+ aOut.Top ( rOutRect.Top() + nHeight );
+ if ( bBottom )
+ aOut.Bottom( aOut.Bottom() - nHeight );
+ if ( bCnt && (!bTop || !bBottom) )
+ ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+
+ rOutRect.Right ( rOutRect.Right() - nWidth );
+ rOutRect.Bottom( rOutRect.Bottom()- nHeight );
+ }
+ break;
+ case SVX_SHADOW_TOPLEFT:
+ {
+ if ( bDrawFullShadowRectangle )
+ {
+ /// OD 06.08.2002 #99657# - draw full shadow rectangle
+ aOut.Bottom( aOut.Bottom() - nHeight );
+ aOut.Right( aOut.Right() - nWidth );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+ else
+ {
+ aOut.Bottom( aOut.Top() + nHeight );
+ aOut.Right ( aOut.Right() - nWidth );
+ if ( bTop )
+ aRegion.Insert( aOut, aRegion.Count() );
+ aOut.Right ( aOut.Left() + nWidth );
+ aOut.Bottom( rOutRect.Bottom() - nHeight );
+ if ( bTop )
+ aOut.Top( aOut.Top() + nHeight );
+ if ( bCnt && (!bBottom || !bTop) )
+ ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+
+ rOutRect.Left( rOutRect.Left() + nWidth );
+ rOutRect.Top( rOutRect.Top() + nHeight );
+ }
+ break;
+ case SVX_SHADOW_TOPRIGHT:
+ {
+ if ( bDrawFullShadowRectangle )
+ {
+ /// OD 06.08.2002 #99657# - draw full shadow rectangle
+ aOut.Bottom( aOut.Bottom() - nHeight);
+ aOut.Left( aOut.Left() + nWidth );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+ else
+ {
+ aOut.Bottom( aOut.Top() + nHeight );
+ aOut.Left ( aOut.Left()+ nWidth );
+ if ( bTop )
+ aRegion.Insert( aOut, aRegion.Count() );
+ aOut.Left ( aOut.Right() - nWidth );
+ aOut.Bottom( rOutRect.Bottom() - nHeight );
+ if ( bTop )
+ aOut.Top( aOut.Top() + nHeight );
+ if ( bCnt && (!bBottom || bTop) )
+ ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+
+ rOutRect.Right( rOutRect.Right() - nWidth );
+ rOutRect.Top( rOutRect.Top() + nHeight );
+ }
+ break;
+ case SVX_SHADOW_BOTTOMLEFT:
+ {
+ if ( bDrawFullShadowRectangle )
+ {
+ /// OD 06.08.2002 #99657# - draw full shadow rectangle
+ aOut.Top( aOut.Top() + nHeight );
+ aOut.Right( aOut.Right() - nWidth );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+ else
+ {
+ aOut.Top ( aOut.Bottom()- nHeight );
+ aOut.Right( aOut.Right() - nWidth );
+ if ( bBottom )
+ aRegion.Insert( aOut, aRegion.Count() );
+ aOut.Right( aOut.Left() + nWidth );
+ aOut.Top( rOutRect.Top() + nHeight );
+ if ( bBottom )
+ aOut.Bottom( aOut.Bottom() - nHeight );
+ if ( bCnt && (!bTop || !bBottom) )
+ ::lcl_ExtendLeftAndRight( aOut, *(this), rAttrs, fnRect );
+ aRegion.Insert( aOut, aRegion.Count() );
+ }
+
+ rOutRect.Left( rOutRect.Left() + nWidth );
+ rOutRect.Bottom( rOutRect.Bottom() - nHeight );
+ }
+ break;
+ default:
+ OSL_ENSURE( !this, "new ShadowLocation() ?" );
+ break;
+ }
+
+ OutputDevice *pOut = pGlobalShell->GetOut();
+
+ sal_uLong nOldDrawMode = pOut->GetDrawMode();
+ Color aShadowColor( rShadow.GetColor() );
+ if( aRegion.Count() && pGlobalShell->GetWin() &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ // Is heigh contrast mode, the output device has already set the
+ // DRAWMODE_SETTINGSFILL flag. This causes the SetFillColor function
+ // to ignore the setting of a new color. Therefore we have to reset
+ // the drawing mode
+ pOut->SetDrawMode( 0 );
+ aShadowColor = SwViewOption::GetFontColor();
+ }
+
+ if ( pOut->GetFillColor() != aShadowColor )
+ pOut->SetFillColor( aShadowColor );
+
+ pOut->SetDrawMode( nOldDrawMode );
+
+ for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
+ {
+ SwRect &rOut = aRegion[i];
+ aOut = rOut;
+ // OD 30.09.2002 #103636# - no SwAlign of shadow rectangle
+ // no alignment necessary, because (1) <rRect> is already aligned
+ // and because (2) paint of border and background will occur later.
+ // Thus, (1) assures that no conflicts with neighbour object will occure
+ // and (2) assures that border and background is not affected by the
+ // shadow paint.
+ /*
+ ::SwAlignRect( aOut, pGlobalShell );
+ */
+ if ( rRect.IsOver( aOut ) && aOut.Height() > 0 && aOut.Width() > 0 )
+ {
+ aOut._Intersection( rRect );
+ pOut->DrawRect( aOut.SVRect() );
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFrm::PaintBorderLine()
+|*
+|*************************************************************************/
+
+void SwFrm::PaintBorderLine( const SwRect& rRect,
+ const SwRect& rOutRect,
+ const SwPageFrm *pPage,
+ const Color *pColor,
+ const SvxBorderStyle nStyle ) const
+{
+ if ( !rOutRect.IsOver( rRect ) )
+ return;
+
+ SwRect aOut( rOutRect );
+ aOut._Intersection( rRect );
+
+ const SwTabFrm *pTab = IsCellFrm() ? FindTabFrm() : 0;
+ sal_uInt8 nSubCol = ( IsCellFrm() || IsRowFrm() ) ? SUBCOL_TAB :
+ ( IsInSct() ? SUBCOL_SECT :
+ ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
+ if( pColor && pGlobalShell->GetWin() &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pColor = &SwViewOption::GetFontColor();
+ }
+
+ if ( pPage->GetSortedObjs() )
+ {
+ SwRegionRects aRegion( aOut, 4, 1 );
+ ::lcl_SubtractFlys( this, pPage, aOut, aRegion );
+ for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
+ pLines->AddLineRect( aRegion[i], pColor, nStyle, pTab, nSubCol );
+ }
+ else
+ pLines->AddLineRect( aOut, pColor, nStyle, pTab, nSubCol );
+}
+
+/*************************************************************************
+|*
+|* SwFrm::PaintBorderLines()
+|*
+|* Beschreibung Nur alle Linien einfach oder alle Linien doppelt!!!!
+|*
+|*************************************************************************/
+
+// OD 29.04.2003 #107169# - method called for left and right border rectangles.
+// For a printer output device perform adjustment for non-overlapping top and
+// bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate
+// printer output device.
+// NOTE: For printer output device left/right border rectangle <_iorRect>
+// has to be already non-overlapping the outer top/bottom border rectangle.
+void MA_FASTCALL lcl_SubTopBottom( SwRect& _iorRect,
+ const SvxBoxItem& _rBox,
+ const SwBorderAttrs& _rAttrs,
+ const SwFrm& _rFrm,
+ const SwRectFn& _rRectFn,
+ const sal_Bool _bPrtOutputDev )
+{
+ const sal_Bool bCnt = _rFrm.IsCntntFrm();
+ if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() &&
+ ( !bCnt || _rAttrs.GetTopLine( _rFrm ) )
+ )
+ {
+ // substract distance between outer and inner line.
+ SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance() );
+ // OD 19.05.2003 #109667# - non-overlapping border rectangles:
+ // adjust x-/y-position, if inner top line is a hair line (width = 1)
+ sal_Bool bIsInnerTopLineHairline = sal_False;
+ if ( !_bPrtOutputDev )
+ {
+ // additionally substract width of top outer line
+ // --> left/right inner/outer line doesn't overlap top outer line.
+ nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth() );
+ }
+ else
+ {
+ // OD 29.04.2003 #107169# - additionally substract width of top inner line
+ // --> left/right inner/outer line doesn't overlap top inner line.
+ nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth() );
+ bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1;
+ }
+ (_iorRect.*_rRectFn->fnSubTop)( -nDist );
+ // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line
+ // is a hair line
+ if ( bIsInnerTopLineHairline )
+ {
+ if ( _rFrm.IsVertical() )
+ {
+ // right of border rectangle has to be checked and adjusted
+ Point aCompPt( _iorRect.Right(), 0 );
+ Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_True, -1 );
+ _iorRect.Right( aCompPt.X() );
+ }
+ else
+ {
+ // top of border rectangle has to be checked and adjusted
+ Point aCompPt( 0, _iorRect.Top() );
+ Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_False, +1 );
+ _iorRect.Top( aCompPt.Y() );
+ }
+ }
+ }
+
+ if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() &&
+ ( !bCnt || _rAttrs.GetBottomLine( _rFrm ) )
+ )
+ {
+ // substract distance between outer and inner line.
+ SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance() );
+ // OD 19.05.2003 #109667# - non-overlapping border rectangles:
+ // adjust x-/y-position, if inner bottom line is a hair line (width = 1)
+ sal_Bool bIsInnerBottomLineHairline = sal_False;
+ if ( !_bPrtOutputDev )
+ {
+ // additionally substract width of bottom outer line
+ // --> left/right inner/outer line doesn't overlap bottom outer line.
+ nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth() );
+ }
+ else
+ {
+ // OD 29.04.2003 #107169# - additionally substract width of bottom inner line
+ // --> left/right inner/outer line doesn't overlap bottom inner line.
+ nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth() );
+ bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1;
+ }
+ (_iorRect.*_rRectFn->fnAddBottom)( -nDist );
+ // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner
+ // bottom line is a hair line.
+ if ( bIsInnerBottomLineHairline )
+ {
+ if ( _rFrm.IsVertical() )
+ {
+ // left of border rectangle has to be checked and adjusted
+ Point aCompPt( _iorRect.Left(), 0 );
+ Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_True, +1 );
+ _iorRect.Left( aCompPt.X() );
+ }
+ else
+ {
+ // bottom of border rectangle has to be checked and adjusted
+ Point aCompPt( 0, _iorRect.Bottom() );
+ Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_False, -1 );
+ _iorRect.Bottom( aCompPt.Y() );
+ }
+ }
+ }
+}
+
+// method called for top and bottom border rectangles.
+void MA_FASTCALL lcl_SubLeftRight( SwRect& rRect,
+ const SvxBoxItem& rBox,
+ const SwRectFn& rRectFn )
+{
+ if ( rBox.GetLeft() && rBox.GetLeft()->GetInWidth() )
+ {
+ const long nDist = ::lcl_MinWidthDist( rBox.GetLeft()->GetDistance() )
+ + ::lcl_AlignWidth( rBox.GetLeft()->GetOutWidth() );
+ (rRect.*rRectFn->fnSubLeft)( -nDist );
+ }
+
+ if ( rBox.GetRight() && rBox.GetRight()->GetInWidth() )
+ {
+ const long nDist = ::lcl_MinWidthDist( rBox.GetRight()->GetDistance() )
+ + ::lcl_AlignWidth( rBox.GetRight()->GetOutWidth() );
+ (rRect.*rRectFn->fnAddRight)( -nDist );
+ }
+}
+
+sal_uInt16 lcl_GetLineWidth( const SvxBorderLine* pLine )
+{
+ sal_uInt16 result = 0;
+
+ if ( pLine != NULL )
+ result = pLine->GetScaledWidth();
+
+ return result;
+}
+
+double lcl_GetExtent( const SvxBorderLine* pSideLine, const SvxBorderLine* pOppositeLine )
+{
+ double nExtent = 0.0;
+
+ if ( pSideLine && !pSideLine->isEmpty() )
+ nExtent = -lcl_GetLineWidth( pSideLine ) / 2.0;
+ else if ( pOppositeLine )
+ nExtent = lcl_GetLineWidth( pOppositeLine ) / 2.0;
+
+ return nExtent;
+}
+
+// OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine>
+// into new method <lcl_PaintLeftRightLine(..)>
+void lcl_PaintLeftRightLine( const sal_Bool _bLeft,
+ const SwFrm& _rFrm,
+ const SwPageFrm& /*_rPage*/,
+ const SwRect& _rOutRect,
+ const SwRect& /*_rRect*/,
+ const SwBorderAttrs& _rAttrs,
+ const SwRectFn& _rRectFn )
+{
+ const SvxBoxItem& rBox = _rAttrs.GetBox();
+ const sal_Bool bR2L = _rFrm.IsCellFrm() && _rFrm.IsRightToLeft();
+ const SvxBorderLine* pLeftRightBorder = 0;
+ const SvxBorderLine* pTopBorder = rBox.GetTop();
+ const SvxBorderLine* pBottomBorder = rBox.GetBottom();
+
+ if ( _bLeft )
+ {
+ pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft();
+ }
+ else
+ {
+ pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight();
+ }
+ // OD 06.05.2003 #107169# - init boolean indicating printer output device.
+ const sal_Bool bPrtOutputDev =
+ ( OUTDEV_PRINTER == pGlobalShell->GetOut()->GetOutDevType() );
+
+ if ( !pLeftRightBorder )
+ {
+ return;
+ }
+
+ SwRect aRect( _rOutRect );
+ if ( _bLeft )
+ {
+ (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( lcl_GetLineWidth( pLeftRightBorder ) ) -
+ (aRect.*_rRectFn->fnGetWidth)() );
+ }
+ else
+ {
+ (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( lcl_GetLineWidth( pLeftRightBorder ) ) -
+ (aRect.*_rRectFn->fnGetWidth)() );
+ }
+
+ const sal_Bool bCnt = _rFrm.IsCntntFrm();
+
+ if ( bCnt )
+ {
+ ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn );
+
+ // No Top / bottom borders for joint borders
+ if ( _rAttrs.JoinedWithPrev( _rFrm ) ) pTopBorder = NULL;
+ if ( _rAttrs.JoinedWithNext( _rFrm ) ) pBottomBorder = NULL;
+ }
+
+ // OD 06.05.2003 #107169# - adjustments for printer output device
+ if ( bPrtOutputDev )
+ {
+ // substract width of outer top line.
+ if ( rBox.GetTop() && (!bCnt || _rAttrs.GetTopLine( _rFrm )) )
+ {
+ long nDist = ::lcl_AlignHeight( rBox.GetTop()->GetOutWidth() );
+ (aRect.*_rRectFn->fnSubTop)( -nDist );
+ // OD 19.05.2003 #109667# - If outer top line is hair line, calculated
+ // top has to be adjusted.
+ if ( nDist == 1 )
+ {
+ if ( _rFrm.IsVertical() )
+ {
+ // right of border rectangle has to be checked and adjusted
+ Point aCompPt( aRect.Right(), 0 );
+ Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_True, -1 );
+ aRect.Right( aCompPt.X() );
+ }
+ else
+ {
+ // top of border rectangle has to be checked and adjusted
+ Point aCompPt( 0, aRect.Top() );
+ Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_False, +1 );
+ aRect.Top( aCompPt.Y() );
+ }
+ }
+ }
+ // substract width of outer bottom line.
+ if ( rBox.GetBottom() && (!bCnt || _rAttrs.GetBottomLine( _rFrm )) )
+ {
+ long nDist = ::lcl_AlignHeight( rBox.GetBottom()->GetOutWidth());
+ (aRect.*_rRectFn->fnAddBottom)( -nDist );
+ // OD 19.05.2003 #109667# - If outer bottom line is hair line, calculated
+ // top has to be adjusted.
+ if ( nDist == 1 )
+ {
+ if ( _rFrm.IsVertical() )
+ {
+ // left of border rectangle has to be checked and adjusted
+ Point aCompPt( aRect.Left(), 0 );
+ Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_True, +1 );
+ aRect.Left( aCompPt.X() );
+ }
+ else
+ {
+ // bottom of border rectangle has to be checked and adjusted
+ Point aCompPt( 0, aRect.Bottom() );
+ Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
+ lcl_CompPxPosAndAdjustPos( *(pGlobalShell->GetOut()),
+ aRefPt, aCompPt,
+ sal_False, -1 );
+ aRect.Bottom( aCompPt.Y() );
+ }
+ }
+ }
+ }
+
+ if ( !pLeftRightBorder->GetInWidth() )
+ {
+ // OD 06.05.2003 #107169# - add 6th parameter
+ ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrm, _rRectFn, bPrtOutputDev );
+ }
+
+ // TODO Postpone the processing of the primitives
+ if ( lcl_GetLineWidth( pLeftRightBorder ) > 0 )
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aSequence( 1 );
+
+ double nExtentIS = lcl_GetExtent( pTopBorder, NULL );
+ double nExtentIE = lcl_GetExtent( pBottomBorder, NULL );
+ double nExtentOS = lcl_GetExtent( NULL, pTopBorder );
+ double nExtentOE = lcl_GetExtent( NULL, pBottomBorder );
+
+ if ( !_bLeft )
+ {
+ nExtentIS = lcl_GetExtent( NULL, pTopBorder );
+ nExtentIE = lcl_GetExtent( NULL, pBottomBorder );
+ nExtentOS = lcl_GetExtent( pTopBorder, NULL );
+ nExtentOE = lcl_GetExtent( pBottomBorder, NULL );
+ }
+
+ basegfx::B2DPoint aStart( aRect.Left() + aRect.Width() / 2.0, aRect.Top() + lcl_GetLineWidth( pTopBorder ) / 2.0 );
+ basegfx::B2DPoint aEnd( aRect.Left() + aRect.Width() / 2.0, aRect.Bottom() - lcl_GetLineWidth( pBottomBorder ) / 2.0 );
+
+ double nLeftWidth = !_bLeft ? pLeftRightBorder->GetOutWidth() : pLeftRightBorder->GetInWidth( );
+ double nRightWidth = !_bLeft ? pLeftRightBorder->GetInWidth() : pLeftRightBorder->GetOutWidth( );
+ Color aLeftColor = _bLeft ? pLeftRightBorder->GetColorOut( _bLeft ) : pLeftRightBorder->GetColorIn( _bLeft );
+ Color aRightColor = _bLeft ? pLeftRightBorder->GetColorIn( _bLeft ) : pLeftRightBorder->GetColorOut( _bLeft );
+
+ aSequence[0] = new drawinglayer::primitive2d::BorderLinePrimitive2D(
+ aStart, aEnd, nLeftWidth, pLeftRightBorder->GetDistance(), nRightWidth,
+ nExtentIS, nExtentIE, nExtentOS, nExtentOE,
+ aLeftColor.getBColor(), aRightColor.getBColor(),
+ pLeftRightBorder->GetColorGap().getBColor(),
+ pLeftRightBorder->HasGapColor(), pLeftRightBorder->GetStyle( ) );
+
+ _rFrm.ProcessPrimitives( aSequence );
+ }
+}
+
+// OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine>
+// into <lcl_PaintTopLine>
+void lcl_PaintTopBottomLine( const sal_Bool _bTop,
+ const SwFrm& _rFrm,
+ const SwPageFrm& /*_rPage*/,
+ const SwRect& _rOutRect,
+ const SwRect& /*_rRect*/,
+ const SwBorderAttrs& _rAttrs,
+ const SwRectFn& _rRectFn )
+{
+ const SvxBoxItem& rBox = _rAttrs.GetBox();
+ const SvxBorderLine* pTopBottomBorder = 0;
+ const SvxBorderLine* pLeftBorder = rBox.GetLeft();
+ const SvxBorderLine* pRightBorder = rBox.GetRight();
+ if ( _bTop )
+ {
+ pTopBottomBorder = rBox.GetTop();
+ }
+ else
+ {
+ pTopBottomBorder = rBox.GetBottom();
+ }
+
+ if ( !pTopBottomBorder )
+ {
+ return;
+ }
+
+ SwRect aRect( _rOutRect );
+ if ( _bTop )
+ {
+ (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( lcl_GetLineWidth( pTopBottomBorder ) ) -
+ (aRect.*_rRectFn->fnGetHeight)() );
+ }
+ else
+ {
+ (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( lcl_GetLineWidth( pTopBottomBorder ) ) -
+ (aRect.*_rRectFn->fnGetHeight)() );
+ }
+
+ // TODO Postpone the processing of the primitives
+ if ( lcl_GetLineWidth( pTopBottomBorder ) > 0 )
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aSequence( 1 );
+
+ double nExtentIS = lcl_GetExtent( pRightBorder, NULL );
+ double nExtentIE = lcl_GetExtent( pLeftBorder, NULL );
+ double nExtentOS = lcl_GetExtent( NULL, pRightBorder );
+ double nExtentOE = lcl_GetExtent( NULL, pLeftBorder );
+
+ if ( !_bTop )
+ {
+ nExtentIS = lcl_GetExtent( NULL, pRightBorder );
+ nExtentIE = lcl_GetExtent( NULL, pLeftBorder );
+ nExtentOS = lcl_GetExtent( pRightBorder, NULL );
+ nExtentOE = lcl_GetExtent( pLeftBorder, NULL );
+ }
+
+ basegfx::B2DPoint aStart( aRect.Right() - lcl_GetLineWidth( pRightBorder ) / 2.0, aRect.Top() + aRect.Height() / 2.0 );
+ basegfx::B2DPoint aEnd( aRect.Left() + lcl_GetLineWidth( pLeftBorder ) / 2.0, aRect.Top() + aRect.Height() / 2.0 );
+
+ double nLeftWidth = !_bTop ? pTopBottomBorder->GetOutWidth() : pTopBottomBorder->GetInWidth( );
+ double nRightWidth = !_bTop ? pTopBottomBorder->GetInWidth() : pTopBottomBorder->GetOutWidth( );
+ Color aLeftColor = _bTop ? pTopBottomBorder->GetColorOut( _bTop ) : pTopBottomBorder->GetColorIn( _bTop );
+ Color aRightColor = _bTop ? pTopBottomBorder->GetColorIn( _bTop ) : pTopBottomBorder->GetColorOut( _bTop );
+
+ aSequence[0] = new drawinglayer::primitive2d::BorderLinePrimitive2D(
+ aStart, aEnd, nLeftWidth, pTopBottomBorder->GetDistance(), nRightWidth,
+ nExtentIS, nExtentIE, nExtentOS, nExtentOE,
+ aLeftColor.getBColor(), aRightColor.getBColor(),
+ pTopBottomBorder->GetColorGap().getBColor(),
+ pTopBottomBorder->HasGapColor(), pTopBottomBorder->GetStyle( ) );
+
+ _rFrm.ProcessPrimitives( aSequence );
+ }
+}
+
+/*************************************************************************
+|*
+|* const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
+|*
+|* No comment. #i15844#
+|*
+|*************************************************************************/
+
+const SwFrm* lcl_HasNextCell( const SwFrm& rFrm )
+{
+ OSL_ENSURE( rFrm.IsCellFrm(),
+ "lcl_HasNextCell( const SwFrm& rFrm ) should be called with SwCellFrm" );
+
+ const SwFrm* pTmpFrm = &rFrm;
+ do
+ {
+ if ( pTmpFrm->GetNext() )
+ return pTmpFrm->GetNext();
+
+ pTmpFrm = pTmpFrm->GetUpper()->GetUpper();
+ }
+ while ( pTmpFrm->IsCellFrm() );
+
+ return 0;
+}
+
+/*************************************************************************
+|*
+|* SwFrm::PaintBorder()
+|*
+|* Beschreibung Malt Schatten und Umrandung
+|*
+|*************************************************************************/
+
+/** local method to determine cell frame, from which the border attributes
+ for paint of top/bottom border has to be used.
+
+ OD 21.02.2003 #b4779636#, #107692#
+
+ @author OD
+
+ @param _pCellFrm
+ input parameter - constant pointer to cell frame for which the cell frame
+ for the border attributes has to be determined.
+
+ @param _rCellBorderAttrs
+ input parameter - constant reference to the border attributes of cell frame
+ <_pCellFrm>.
+
+ @param _bTop
+ input parameter - boolean, that controls, if cell frame for top border or
+ for bottom border has to be determined.
+
+ @return constant pointer to cell frame, for which the border attributes has
+ to be used
+*/
+const SwFrm* lcl_GetCellFrmForBorderAttrs( const SwFrm* _pCellFrm,
+ const SwBorderAttrs& _rCellBorderAttrs,
+ const bool _bTop )
+{
+ OSL_ENSURE( _pCellFrm, "No cell frame available, dying soon" );
+
+ // determine, if cell frame is at bottom/top border of a table frame and
+ // the table frame has/is a follow.
+ const SwFrm* pTmpFrm = _pCellFrm;
+ bool bCellAtBorder = true;
+ bool bCellAtLeftBorder = !_pCellFrm->GetPrev();
+ bool bCellAtRightBorder = !_pCellFrm->GetNext();
+ while( !pTmpFrm->IsRowFrm() || !pTmpFrm->GetUpper()->IsTabFrm() )
+ {
+ pTmpFrm = pTmpFrm->GetUpper();
+ if ( pTmpFrm->IsRowFrm() &&
+ (_bTop ? pTmpFrm->GetPrev() : pTmpFrm->GetNext())
+ )
+ {
+ bCellAtBorder = false;
+ }
+ if ( pTmpFrm->IsCellFrm() )
+ {
+ if ( pTmpFrm->GetPrev() )
+ {
+ bCellAtLeftBorder = false;
+ }
+ if ( pTmpFrm->GetNext() )
+ {
+ bCellAtRightBorder = false;
+ }
+ }
+ }
+ OSL_ENSURE( pTmpFrm && pTmpFrm->IsRowFrm(), "No RowFrm available" );
+
+ const SwLayoutFrm* pParentRowFrm = static_cast<const SwLayoutFrm*>(pTmpFrm);
+ const SwTabFrm* pParentTabFrm =
+ static_cast<const SwTabFrm*>(pParentRowFrm->GetUpper());
+
+ const bool bCellNeedsAttribute = bCellAtBorder &&
+ ( _bTop ?
+ // bCellInFirstRowWithMaster
+ ( !pParentRowFrm->GetPrev() &&
+ pParentTabFrm->IsFollow() &&
+ 0 == pParentTabFrm->GetTable()->GetRowsToRepeat() ) :
+ // bCellInLastRowWithFollow
+ ( !pParentRowFrm->GetNext() &&
+ pParentTabFrm->GetFollow() )
+ );
+
+ const SwFrm* pRet = _pCellFrm;
+ if ( bCellNeedsAttribute )
+ {
+ // determine, if cell frame has no borders inside the table.
+ const SwFrm* pNextCell = 0;
+ bool bNoBordersInside = false;
+
+ if ( bCellAtLeftBorder && ( 0 != ( pNextCell = lcl_HasNextCell( *_pCellFrm ) ) ) )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNextCell );
+ const SwBorderAttrs &rBorderAttrs = *aAccess.Get();
+ const SvxBoxItem& rBorderBox = rBorderAttrs.GetBox();
+ bCellAtRightBorder = !lcl_HasNextCell( *pNextCell );
+ bNoBordersInside =
+ ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) &&
+ !rBorderBox.GetLeft() &&
+ ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
+ ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
+ }
+ else
+ {
+ const SvxBoxItem& rBorderBox = _rCellBorderAttrs.GetBox();
+ bNoBordersInside =
+ ( !rBorderBox.GetTop() || !pParentRowFrm->GetPrev() ) &&
+ ( !rBorderBox.GetLeft() || bCellAtLeftBorder ) &&
+ ( !rBorderBox.GetRight() || bCellAtRightBorder ) &&
+ ( !rBorderBox.GetBottom() || !pParentRowFrm->GetNext() );
+ }
+
+ if ( bNoBordersInside )
+ {
+ if ( _bTop && !_rCellBorderAttrs.GetBox().GetTop() )
+ {
+ // #b4779636#-hack:
+ // Cell frame has no top border and no border inside the table, but
+ // it is at the top border of a table frame, which is a follow.
+ // Thus, use border attributes of cell frame in first row of complete table.
+ // First, determine first table frame of complete table.
+ SwTabFrm* pMasterTabFrm = pParentTabFrm->FindMaster( true );
+ // determine first row of complete table.
+ const SwFrm* pFirstRow = pMasterTabFrm->GetLower();
+ // return first cell in first row
+ SwFrm* pLowerCell = const_cast<SwFrm*>(pFirstRow->GetLower());
+ while ( !pLowerCell->IsCellFrm() ||
+ ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
+ )
+ {
+ pLowerCell = pLowerCell->GetLower();
+ }
+ OSL_ENSURE( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
+ pRet = pLowerCell;
+ }
+ else if ( !_bTop && !_rCellBorderAttrs.GetBox().GetBottom() )
+ {
+ // #b4779636#-hack:
+ // Cell frame has no bottom border and no border inside the table,
+ // but it is at the bottom border of a table frame, which has a follow.
+ // Thus, use border attributes of cell frame in last row of complete table.
+ // First, determine last table frame of complete table.
+ SwTabFrm* pLastTabFrm = const_cast<SwTabFrm*>(pParentTabFrm->GetFollow());
+ while ( pLastTabFrm->GetFollow() )
+ {
+ pLastTabFrm = pLastTabFrm->GetFollow();
+ }
+ // determine last row of complete table.
+ SwFrm* pLastRow = pLastTabFrm->GetLastLower();
+ // return first bottom border cell in last row
+ SwFrm* pLowerCell = const_cast<SwFrm*>(pLastRow->GetLower());
+ while ( !pLowerCell->IsCellFrm() ||
+ ( pLowerCell->GetLower() && pLowerCell->GetLower()->IsRowFrm() )
+ )
+ {
+ if ( pLowerCell->IsRowFrm() )
+ {
+ while ( pLowerCell->GetNext() )
+ {
+ pLowerCell = pLowerCell->GetNext();
+ }
+ }
+ pLowerCell = pLowerCell->GetLower();
+ }
+ OSL_ENSURE( pLowerCell && pLowerCell->IsCellFrm(), "No CellFrm available" );
+ pRet = pLowerCell;
+ }
+ }
+ }
+
+ return pRet;
+}
+
+void SwFrm::ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DSequence& rSequence ) const
+{
+ basegfx::B2DRange aViewRange;
+
+ SdrPage *pDrawPage = getRootFrm()->GetCurrShell()->Imp()->GetPageView()->GetPage();
+ const drawinglayer::geometry::ViewInformation2D aNewViewInfos(
+ basegfx::B2DHomMatrix( ),
+ getRootFrm()->GetCurrShell()->GetOut()->GetViewTransformation(),
+ aViewRange,
+ GetXDrawPageForSdrPage( pDrawPage ),
+ 0.0,
+ uno::Sequence< beans::PropertyValue >() );
+
+ drawinglayer::processor2d::BaseProcessor2D * pProcessor2D =
+ sdr::contact::createBaseProcessor2DFromOutputDevice(
+ *getRootFrm()->GetCurrShell()->GetOut(),
+ aNewViewInfos );
+
+ if ( pProcessor2D )
+ {
+ pProcessor2D->process( rSequence );
+ delete pProcessor2D;
+ }
+}
+
+void SwFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
+ const SwBorderAttrs &rAttrs ) const
+{
+ //fuer (Row,Body,Ftn,Root,Column,NoTxt) gibt's hier nix zu tun
+ if ( (GetType() & 0x90C5) )
+ return;
+
+ if ( (GetType() & 0x2000) && //Cell
+ !pGlobalShell->GetViewOptions()->IsTable() )
+ return;
+
+ // --> collapsing borders FME 2005-05-27 #i29550#
+ if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
+ {
+ const SwTabFrm* pTabFrm = FindTabFrm();
+ if ( pTabFrm->IsCollapsingBorders() )
+ return;
+
+ if ( pTabFrm->GetTable()->IsNewModel() && ( !IsCellFrm() || IsCoveredCell() ) )
+ return;
+ }
+ // <--
+
+ const bool bLine = rAttrs.IsLine() ? true : false;
+ const bool bShadow = rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE;
+
+ // OD 24.02.2003 #b4779636#, #107692# - flag to control,
+ // if #b4779636#-hack has to be used.
+ const bool bb4779636HackActive = true;
+ // OD 21.02.2003 #b4779636#, #107692#
+ const SwFrm* pCellFrmForBottomBorderAttrs = 0;
+ const SwFrm* pCellFrmForTopBorderAttrs = 0;
+ bool bFoundCellForTopOrBorderAttrs = false;
+ if ( bb4779636HackActive && IsCellFrm() )
+ {
+ pCellFrmForBottomBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, false );
+ if ( pCellFrmForBottomBorderAttrs != this )
+ bFoundCellForTopOrBorderAttrs = true;
+ pCellFrmForTopBorderAttrs = lcl_GetCellFrmForBorderAttrs( this, rAttrs, true );
+ if ( pCellFrmForTopBorderAttrs != this )
+ bFoundCellForTopOrBorderAttrs = true;
+ }
+
+ // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
+ // for #b4779636#-hack
+ if ( bLine || bShadow || bFoundCellForTopOrBorderAttrs )
+ {
+ //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt,
+ //so braucht kein Rand gepainted werden.
+ //Fuer die PrtArea muss der Aligned'e Wert zugrunde gelegt werden,
+ //anderfalls wuerden u.U. Teile nicht verarbeitet.
+ SwRect aRect( Prt() );
+ aRect += Frm().Pos();
+ ::SwAlignRect( aRect, pGlobalShell );
+ // OD 27.09.2002 #103636# - new local boolean variable in order to
+ // suspend border paint under special cases - see below.
+ // NOTE: This is a fix for the implementation of feature #99657#.
+ bool bDrawOnlyShadowForTransparentFrame = false;
+ if ( aRect.IsInside( rRect ) )
+ {
+ // OD 27.09.2002 #103636# - paint shadow, if background is transparent.
+ // Because of introduced transparent background for fly frame #99657#,
+ // the shadow have to be drawn if the background is transparent,
+ // in spite the fact that the paint rectangle <rRect> lies fully
+ // in the printing area.
+ // NOTE to chosen solution:
+ // On transparent background, continue processing, but suspend
+ // drawing of border by setting <bDrawOnlyShadowForTransparentFrame>
+ // to true.
+ if ( IsLayoutFrm() &&
+ static_cast<const SwLayoutFrm*>(this)->GetFmt()->IsBackgroundTransparent() )
+ {
+ bDrawOnlyShadowForTransparentFrame = true;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ if ( !pPage )
+ pPage = FindPageFrm();
+
+ ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_True );
+ rAttrs.SetGetCacheLine( sal_True );
+ if ( bShadow )
+ PaintShadow( rRect, aRect, rAttrs );
+ // OD 27.09.2002 #103636# - suspend drawing of border
+ // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
+ // OD 24.02.2003 #b4779636#, #107692# - add condition <bFoundCellForTopOrBorderAttrs>
+ // for #b4779636#-hack.
+ if ( ( bLine || bFoundCellForTopOrBorderAttrs ) &&
+ !bDrawOnlyShadowForTransparentFrame )
+ {
+ const SwFrm* pDirRefFrm = IsCellFrm() ? FindTabFrm() : this;
+ SWRECTFN( pDirRefFrm )
+ ::lcl_PaintLeftRightLine ( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
+ ::lcl_PaintLeftRightLine ( sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
+ if ( !IsCntntFrm() || rAttrs.GetTopLine( *(this) ) )
+ {
+ // OD 21.02.2003 #b4779636#, #107692# -
+ // #b4779636#-hack: If another cell frame for top border
+ // paint is found, paint its top border.
+ if ( IsCellFrm() && pCellFrmForTopBorderAttrs != this )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(),
+ pCellFrmForTopBorderAttrs );
+ const SwBorderAttrs &rTopAttrs = *aAccess.Get();
+ ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rTopAttrs, fnRect );
+ }
+ else
+ {
+ ::lcl_PaintTopBottomLine( sal_True, *(this), *(pPage), aRect, rRect, rAttrs, fnRect );
+ }
+ }
+ if ( !IsCntntFrm() || rAttrs.GetBottomLine( *(this) ) )
+ {
+ // OD 21.02.2003 #b4779636#, #107692# -
+ // #b4779636#-hack: If another cell frame for bottom border
+ // paint is found, paint its bottom border.
+ if ( IsCellFrm() && pCellFrmForBottomBorderAttrs != this )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(),
+ pCellFrmForBottomBorderAttrs );
+ const SwBorderAttrs &rBottomAttrs = *aAccess.Get();
+ ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rBottomAttrs, fnRect);
+ }
+ else
+ {
+ ::lcl_PaintTopBottomLine(sal_False, *(this), *(pPage), aRect, rRect, rAttrs, fnRect);
+ }
+ }
+ }
+ rAttrs.SetGetCacheLine( sal_False );
+ }
+}
+/*************************************************************************
+|*
+|* SwFtnContFrm::PaintBorder()
+|*
+|* Beschreibung Spezialimplementierung wg. der Fussnotenlinie.
+|* Derzeit braucht nur der obere Rand beruecksichtigt werden.
+|* Auf andere Linien und Schatten wird verzichtet.
+|*
+|*************************************************************************/
+
+void SwFtnContFrm::PaintBorder( const SwRect& rRect, const SwPageFrm *pPage,
+ const SwBorderAttrs & ) const
+{
+ //Wenn das Rechteck vollstandig innerhalb der PrtArea liegt, so gibt es
+ //keinen Rand zu painten.
+ SwRect aRect( Prt() );
+ aRect.Pos() += Frm().Pos();
+ if ( !aRect.IsInside( rRect ) )
+ PaintLine( rRect, pPage );
+}
+/*************************************************************************
+|*
+|* SwFtnContFrm::PaintLine()
+|*
+|* Beschreibung Fussnotenline malen.
+|*
+|*************************************************************************/
+
+void SwFtnContFrm::PaintLine( const SwRect& rRect,
+ const SwPageFrm *pPage ) const
+{
+ //Laenge der Linie ergibt sich aus der prozentualen Angabe am PageDesc.
+ //Die Position ist ebenfalls am PageDesc angegeben.
+ //Der Pen steht direkt im PageDesc.
+
+ if ( !pPage )
+ pPage = FindPageFrm();
+ const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo();
+
+ SWRECTFN( this )
+ SwTwips nPrtWidth = (Prt().*fnRect->fnGetWidth)();
+ Fraction aFract( nPrtWidth, 1 );
+ const SwTwips nWidth = (long)(aFract *= rInf.GetWidth());
+
+ SwTwips nX = (this->*fnRect->fnGetPrtLeft)();
+ switch ( rInf.GetAdj() )
+ {
+ case FTNADJ_CENTER:
+ nX += nPrtWidth/2 - nWidth/2; break;
+ case FTNADJ_RIGHT:
+ nX += nPrtWidth - nWidth; break;
+ case FTNADJ_LEFT:
+ /* do nothing */; break;
+ default:
+ OSL_ENSURE( !this, "Neues Adjustment fuer Fussnotenlinie?" );
+ }
+ SwTwips nLineWidth = rInf.GetLineWidth();
+ const SwRect aLineRect = bVert ?
+ SwRect( Point(Frm().Left()+Frm().Width()-rInf.GetTopDist()-nLineWidth,
+ nX), Size( nLineWidth, nWidth ) )
+ : SwRect( Point( nX, Frm().Pos().Y() + rInf.GetTopDist() ),
+ Size( nWidth, rInf.GetLineWidth()));
+ if ( aLineRect.HasArea() )
+ PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor(),
+ rInf.GetLineStyle() );
+}
+
+/*************************************************************************
+|*
+|* SwLayoutFrm::PaintColLines()
+|*
+|* Beschreibung Painted die Trennlinien fuer die innenliegenden
+|* Spalten.
+|*
+|*************************************************************************/
+
+void SwLayoutFrm::PaintColLines( const SwRect &rRect, const SwFmtCol &rFmtCol,
+ const SwPageFrm *pPage ) const
+{
+ const SwFrm *pCol = Lower();
+ if ( !pCol || !pCol->IsColumnFrm() )
+ return;
+ //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
+ SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+
+ SwRect aLineRect = Prt();
+ aLineRect += Frm().Pos();
+
+ SwTwips nTop = ((aLineRect.*fnRect->fnGetHeight)()*rFmtCol.GetLineHeight())
+ / 100 - (aLineRect.*fnRect->fnGetHeight)();
+ SwTwips nBottom = 0;
+
+ switch ( rFmtCol.GetLineAdj() )
+ {
+ case COLADJ_CENTER:
+ nBottom = nTop / 2; nTop -= nBottom; break;
+ case COLADJ_TOP:
+ nBottom = nTop; nTop = 0; break;
+ case COLADJ_BOTTOM:
+ break;
+ default:
+ OSL_ENSURE( !this, "Neues Adjustment fuer Spaltenlinie?" );
+ }
+
+ if( nTop )
+ (aLineRect.*fnRect->fnSubTop)( nTop );
+ if( nBottom )
+ (aLineRect.*fnRect->fnAddBottom)( nBottom );
+
+ SwTwips nPenHalf = rFmtCol.GetLineWidth();
+ (aLineRect.*fnRect->fnSetWidth)( nPenHalf );
+ nPenHalf /= 2;
+
+ //Damit uns nichts verlorengeht muessen wir hier etwas grosszuegiger sein.
+ SwRect aRect( rRect );
+ (aRect.*fnRect->fnSubLeft)( nPenHalf + nPixelSzW );
+ (aRect.*fnRect->fnAddRight)( nPenHalf + nPixelSzW );
+ SwRectGet fnGetX = IsRightToLeft() ? fnRect->fnGetLeft : fnRect->fnGetRight;
+ while ( pCol->GetNext() )
+ {
+ (aLineRect.*fnRect->fnSetPosX)
+ ( (pCol->Frm().*fnGetX)() - nPenHalf );
+ if ( aRect.IsOver( aLineRect ) )
+ PaintBorderLine( aRect, aLineRect , pPage, &rFmtCol.GetLineColor(),
+ rFmtCol.GetLineStyle() );
+ pCol = pCol->GetNext();
+ }
+}
+
+void SwPageFrm::PaintGrid( OutputDevice* pOut, SwRect &rRect ) const
+{
+ if( !bHasGrid || pRetoucheFly || pRetoucheFly2 )
+ return;
+ GETGRID( this )
+ if( pGrid && ( OUTDEV_PRINTER != pOut->GetOutDevType() ?
+ pGrid->GetDisplayGrid() : pGrid->GetPrintGrid() ) )
+ {
+ const SwLayoutFrm* pBody = FindBodyCont();
+ if( pBody )
+ {
+ SwRect aGrid( pBody->Prt() );
+ aGrid += pBody->Frm().Pos();
+
+ SwRect aInter( aGrid );
+ aInter.Intersection( rRect );
+ if( aInter.HasArea() )
+ {
+ sal_Bool bGrid = pGrid->GetRubyTextBelow();
+ sal_Bool bCell = GRID_LINES_CHARS == pGrid->GetGridType();
+ long nGrid = pGrid->GetBaseHeight();
+ const SwDoc* pDoc = GetFmt()->GetDoc();
+ long nGridWidth = GETGRIDWIDTH(pGrid,pDoc); //for textgrid refactor
+ long nRuby = pGrid->GetRubyHeight();
+ long nSum = nGrid + nRuby;
+ const Color *pCol = &pGrid->GetColor();
+
+ SwTwips nRight = aInter.Left() + aInter.Width();
+ SwTwips nBottom = aInter.Top() + aInter.Height();
+ if( IsVertical() )
+ {
+ SwTwips nOrig = aGrid.Left() + aGrid.Width();
+ SwTwips nY = nOrig + nSum *
+ ( ( nOrig - aInter.Left() ) / nSum );
+ SwRect aTmp( Point( nY, aInter.Top() ),
+ Size( 1, aInter.Height() ) );
+ SwTwips nX = aGrid.Top() + nGrid *
+ ( ( aInter.Top() - aGrid.Top() )/ nGrid );
+ if( nX < aInter.Top() )
+ nX += nGrid;
+ SwTwips nGridBottom = aGrid.Top() + aGrid.Height();
+ sal_Bool bLeft = aGrid.Top() >= aInter.Top();
+ sal_Bool bRight = nGridBottom <= nBottom;
+ sal_Bool bBorder = bLeft || bRight;
+ while( nY > nRight )
+ {
+ aTmp.Pos().X() = nY;
+ if( bGrid )
+ {
+ nY -= nGrid;
+ SwTwips nPosY = Max( aInter.Left(), nY );
+ SwTwips nHeight = Min(nRight, aTmp.Pos().X())-nPosY;
+ if( nHeight > 0 )
+ {
+ if( bCell )
+ {
+ SwRect aVert( Point( nPosY, nX ),
+ Size( nHeight, 1 ) );
+ while( aVert.Top() <= nBottom )
+ {
+ PaintBorderLine(rRect,aVert,this,pCol);
+ aVert.Pos().Y() += nGrid;
+ }
+ }
+ else if( bBorder )
+ {
+ SwRect aVert( Point( nPosY, aGrid.Top() ),
+ Size( nHeight, 1 ) );
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().Y() = nGridBottom;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ else
+ {
+ nY -= nRuby;
+ if( bBorder )
+ {
+ SwTwips nPos = Max( aInter.Left(), nY );
+ SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
+ SwRect aVert( Point( nPos, aGrid.Top() ),
+ Size( nW, 1 ) );
+ if( nW > 0 )
+ {
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().Y() = nGridBottom;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ bGrid = !bGrid;
+ }
+ while( nY >= aInter.Left() )
+ {
+ aTmp.Pos().X() = nY;
+ PaintBorderLine( rRect, aTmp, this, pCol);
+ if( bGrid )
+ {
+ nY -= nGrid;
+ SwTwips nHeight = aTmp.Pos().X()
+ - Max(aInter.Left(), nY );
+ if( nHeight > 0 )
+ {
+ if( bCell )
+ {
+ SwRect aVert( Point(aTmp.Pos().X()-nHeight,
+ nX ), Size( nHeight, 1 ) );
+ while( aVert.Top() <= nBottom )
+ {
+ PaintBorderLine(rRect,aVert,this,pCol);
+ aVert.Pos().Y() += nGrid;
+ }
+ }
+ else if( bBorder )
+ {
+ SwRect aVert( Point(aTmp.Pos().X()-nHeight,
+ aGrid.Top() ), Size( nHeight, 1 ) );
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().Y() = nGridBottom;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ else
+ {
+ nY -= nRuby;
+ if( bBorder )
+ {
+ SwTwips nPos = Max( aInter.Left(), nY );
+ SwTwips nW = Min(nRight, aTmp.Pos().X()) - nPos;
+ SwRect aVert( Point( nPos, aGrid.Top() ),
+ Size( nW, 1 ) );
+ if( nW > 0 )
+ {
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().Y() = nGridBottom;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ bGrid = !bGrid;
+ }
+ }
+ else
+ {
+ SwTwips nOrig = aGrid.Top();
+ SwTwips nY = nOrig + nSum *( (aInter.Top()-nOrig)/nSum );
+ SwRect aTmp( Point( aInter.Left(), nY ),
+ Size( aInter.Width(), 1 ) );
+ //for textgrid refactor
+ SwTwips nX = aGrid.Left() + nGridWidth *
+ ( ( aInter.Left() - aGrid.Left() )/ nGridWidth );
+ if( nX < aInter.Left() )
+ nX += nGridWidth;
+ SwTwips nGridRight = aGrid.Left() + aGrid.Width();
+ sal_Bool bLeft = aGrid.Left() >= aInter.Left();
+ sal_Bool bRight = nGridRight <= nRight;
+ sal_Bool bBorder = bLeft || bRight;
+ while( nY < aInter.Top() )
+ {
+ aTmp.Pos().Y() = nY;
+ if( bGrid )
+ {
+ nY += nGrid;
+ SwTwips nPosY = Max( aInter.Top(), aTmp.Pos().Y() );
+ SwTwips nHeight = Min(nBottom, nY ) - nPosY;
+ if( nHeight )
+ {
+ if( bCell )
+ {
+ SwRect aVert( Point( nX, nPosY ),
+ Size( 1, nHeight ) );
+ while( aVert.Left() <= nRight )
+ {
+ PaintBorderLine(rRect,aVert,this,pCol);
+ aVert.Pos().X() += nGridWidth; //for textgrid refactor
+ }
+ }
+ else if ( bBorder )
+ {
+ SwRect aVert( Point( aGrid.Left(), nPosY ),
+ Size( 1, nHeight ) );
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().X() = nGridRight;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ else
+ {
+ nY += nRuby;
+ if( bBorder )
+ {
+ SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
+ SwTwips nH = Min( nBottom, nY ) - nPos;
+ SwRect aVert( Point( aGrid.Left(), nPos ),
+ Size( 1, nH ) );
+ if( nH > 0 )
+ {
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().X() = nGridRight;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ bGrid = !bGrid;
+ }
+ while( nY <= nBottom )
+ {
+ aTmp.Pos().Y() = nY;
+ PaintBorderLine( rRect, aTmp, this, pCol);
+ if( bGrid )
+ {
+ nY += nGrid;
+ SwTwips nHeight = Min(nBottom, nY) - aTmp.Pos().Y();
+ if( nHeight )
+ {
+ if( bCell )
+ {
+ SwRect aVert( Point( nX, aTmp.Pos().Y() ),
+ Size( 1, nHeight ) );
+ while( aVert.Left() <= nRight )
+ {
+ PaintBorderLine( rRect, aVert, this, pCol);
+ aVert.Pos().X() += nGridWidth; //for textgrid refactor
+ }
+ }
+ else if( bBorder )
+ {
+ SwRect aVert( Point( aGrid.Left(),
+ aTmp.Pos().Y() ), Size( 1, nHeight ) );
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().X() = nGridRight;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ else
+ {
+ nY += nRuby;
+ if( bBorder )
+ {
+ SwTwips nPos = Max(aInter.Top(),aTmp.Pos().Y());
+ SwTwips nH = Min( nBottom, nY ) - nPos;
+ SwRect aVert( Point( aGrid.Left(), nPos ),
+ Size( 1, nH ) );
+ if( nH > 0 )
+ {
+ if( bLeft )
+ PaintBorderLine(rRect,aVert,this,pCol);
+ if( bRight )
+ {
+ aVert.Pos().X() = nGridRight;
+ PaintBorderLine(rRect,aVert,this,pCol);
+ }
+ }
+ }
+ }
+ bGrid = !bGrid;
+ }
+ }
+ }
+ }
+ }
+}
+
+/** paint margin area of a page
+
+ OD 20.11.2002 for #104598#:
+ implement paint of margin area; margin area will be painted for a
+ view shell with a window and if the document is not in online layout.
+
+ @author OD
+
+ @param _rOutputRect
+ input parameter - constant instance reference of the rectangle, for
+ which an output has to be generated.
+
+ @param _pViewShell
+ input parameter - instance of the view shell, on which the output
+ has to be generated.
+*/
+void SwPageFrm::PaintMarginArea( const SwRect& _rOutputRect,
+ ViewShell* _pViewShell ) const
+{
+ if ( _pViewShell->GetWin() &&
+ !_pViewShell->GetViewOptions()->getBrowseMode() )
+ {
+ SwRect aPgPrtRect( Prt() );
+ aPgPrtRect.Pos() += Frm().Pos();
+ if ( !aPgPrtRect.IsInside( _rOutputRect ) )
+ {
+ SwRect aPgRect = Frm();
+ aPgRect._Intersection( _rOutputRect );
+ if(aPgRect.Height() < 0 || aPgRect.Width() <= 0) // No intersection
+ return;
+ SwRegionRects aPgRegion( aPgRect );
+ aPgRegion -= aPgPrtRect;
+ const SwPageFrm* pPage = static_cast<const SwPageFrm*>(this);
+ if ( pPage->GetSortedObjs() )
+ ::lcl_SubtractFlys( this, pPage, aPgRect, aPgRegion );
+ if ( aPgRegion.Count() )
+ {
+ OutputDevice *pOut = _pViewShell->GetOut();
+ if ( pOut->GetFillColor() != aGlobalRetoucheColor )
+ pOut->SetFillColor( aGlobalRetoucheColor );
+ for ( sal_uInt16 i = 0; i < aPgRegion.Count(); ++i )
+ {
+ if ( 1 < aPgRegion.Count() )
+ {
+ ::SwAlignRect( aPgRegion[i], pGlobalShell );
+ if( !aPgRegion[i].HasArea() )
+ continue;
+ }
+ pOut->DrawRect(aPgRegion[i].SVRect());
+ }
+ }
+ }
+ }
+}
+
+const sal_Int8 SwPageFrm::mnShadowPxWidth = 10;
+
+/** determine rectangle for right page shadow
+
+ OD 12.02.2003 for #i9719# and #105645#
+
+ @author OD
+*/
+/*static*/ void SwPageFrm::GetRightShadowRect( const SwRect& _rPageRect,
+ ViewShell* _pViewShell,
+ SwRect& _orRightShadowRect,
+ bool bRightSidebar )
+{
+ SwRect aAlignedPageRect( _rPageRect );
+ ::SwAlignRect( aAlignedPageRect, _pViewShell );
+ SwRect aPagePxRect =
+ _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
+ const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
+
+ _orRightShadowRect.Chg(
+ Point( aPagePxRect.Right() + 1, aPagePxRect.Top() + mnShadowPxWidth + 1 ),
+ Size( mnShadowPxWidth, aPagePxRect.Height() - mnShadowPxWidth - 1 ) );
+
+ if (bRightSidebar && pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
+ {
+ _orRightShadowRect.Pos(_orRightShadowRect.Left() + pMgr->GetSidebarWidth(true)
+ + pMgr->GetSidebarBorderWidth(true), _orRightShadowRect.Top());
+ }
+
+}
+
+/** determine rectangle for bottom page shadow
+
+ OD 12.02.2003 for #i9719# and #105645#
+
+ @author OD
+*/
+/*static*/ void SwPageFrm::GetBottomShadowRect( const SwRect& _rPageRect,
+ ViewShell* _pViewShell,
+ SwRect& _orBottomShadowRect,
+ bool bFullBottomShadow,
+ bool bRightSidebar )
+{
+ const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
+ SwRect aAlignedPageRect( _rPageRect );
+ ::SwAlignRect( aAlignedPageRect, _pViewShell );
+ SwRect aPagePxRect =
+ _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
+
+ // Shadow is shifted when not full
+ long lShadowAdjustment = (bFullBottomShadow ? 0 : 1 + mnShadowPxWidth);
+
+ _orBottomShadowRect.Chg(
+ Point( aPagePxRect.Left() + lShadowAdjustment, aPagePxRect.Bottom() + 1 ),
+ Size( aPagePxRect.Width() - lShadowAdjustment, mnShadowPxWidth ) );
+
+ if(pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
+ {
+ // Notes are displayed, we've to extend borders
+ SwTwips aSidebarTotalWidth = pMgr->GetSidebarWidth(true) + pMgr->GetSidebarBorderWidth(true);
+ if(bRightSidebar)
+ _orBottomShadowRect.Right( _orBottomShadowRect.Right() + aSidebarTotalWidth );
+ else
+ _orBottomShadowRect.Left( _orBottomShadowRect.Left() - aSidebarTotalWidth );
+ }
+}
+
+/** paint page border and shadow
+
+ OD 12.02.2003 for #i9719# and #105645#
+ implement paint of page border and shadow
+
+ @author OD
+*/
+/*static*/ void SwPageFrm::PaintBorderAndShadow( const SwRect& _rPageRect,
+ ViewShell* _pViewShell,
+ bool bPaintRightShadow,
+ bool bFullBottomShadow,
+ bool bRightSidebar )
+{
+ // No shadow in prefs
+ if( !SwViewOption::IsShadow() ) return;
+
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *_pViewShell->GetOut() );
+ // <--
+
+ static BitmapEx aPageTopRightShadow;
+ static BitmapEx aPageBottomRightShadow;
+ static BitmapEx aPageBottomLeftShadow;
+ static BitmapEx aPageBottomShadowBase;
+ static BitmapEx aPageRightShadowBase;
+ static Color aShadowColor;
+
+
+ if(aShadowColor != SwViewOption::GetShadowColor() ) {
+ aShadowColor = SwViewOption::GetShadowColor();
+ AlphaMask aMask( SW_RES( BMP_PAGE_BOTTOM_RIGHT_SHADOW_MASK ) );
+ Bitmap aFilledSquare( Size( mnShadowPxWidth, mnShadowPxWidth ), 24 );
+ aFilledSquare.Erase( aShadowColor );
+
+ aPageBottomRightShadow = BitmapEx( aFilledSquare, aMask );
+ aMask.Rotate( 900, 255 );
+ aPageTopRightShadow = BitmapEx( aFilledSquare, aMask );
+ aMask.Rotate( 1800, 255);
+ aPageBottomLeftShadow = BitmapEx( aFilledSquare, aMask );
+
+ aFilledSquare = Bitmap( Size( 1, mnShadowPxWidth ), 24 );
+ aFilledSquare.Erase( aShadowColor );
+ aMask = Bitmap( SW_RES( BMP_PAGE_BOTTOM_SHADOW_MASK ) );
+ aPageBottomShadowBase = BitmapEx( aFilledSquare, aMask );
+
+ aFilledSquare = Bitmap( Size( mnShadowPxWidth, 1 ), 24 );
+ aFilledSquare.Erase( aShadowColor );
+ aMask = Bitmap( SW_RES( BMP_PAGE_RIGHT_SHADOW_MASK ) );
+ aPageRightShadowBase = BitmapEx( aFilledSquare, aMask );
+ }
+
+ SwRect aPaintRect;
+ OutputDevice *pOut = _pViewShell->GetOut();
+
+ // paint right shadow
+ if ( bPaintRightShadow )
+ {
+ SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aPaintRect, bRightSidebar );
+ BitmapEx aPageRightShadow = aPageRightShadowBase;
+ aPageRightShadow.Scale( 1, aPaintRect.Height() );
+ pOut->DrawBitmapEx( pOut->PixelToLogic( aPaintRect.Pos() ), aPageRightShadow );
+ pOut->DrawBitmapEx( pOut->PixelToLogic( Point( aPaintRect.Left(), aPaintRect.Top() - mnShadowPxWidth ) ), aPageTopRightShadow );
+ pOut->DrawBitmapEx( pOut->PixelToLogic( aPaintRect.BottomLeft() ), aPageBottomRightShadow );
+ }
+
+ // paint bottom shadow
+ SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aPaintRect, bFullBottomShadow, bRightSidebar );
+ if(!bFullBottomShadow)
+ {
+ pOut->DrawBitmapEx( pOut->PixelToLogic( Point( aPaintRect.Left() - mnShadowPxWidth, aPaintRect.Top() ) ), aPageBottomLeftShadow );
+ }
+ BitmapEx aPageBottomShadow = aPageBottomShadowBase;
+ aPageBottomShadow.Scale( aPaintRect.Width(), 1 );
+ pOut->DrawBitmapEx( pOut->PixelToLogic( aPaintRect.Pos() ), aPageBottomShadow);
+}
+
+//mod #i6193# paint sidebar for notes
+//IMPORTANT: if you change the rects here, also change SwPostItMgr::ScrollbarHit
+/*static*/void SwPageFrm::PaintNotesSidebar(const SwRect& _rPageRect, ViewShell* _pViewShell, sal_uInt16 nPageNum, bool bRight)
+{
+ //TOOD: cut out scrollbar area and arrows out of sidepane rect, otherwise it could flicker when pressing arrow buttons
+ if (!_pViewShell )
+ return;
+
+ SwRect aPageRect( _rPageRect );
+ SwAlignRect( aPageRect, _pViewShell );
+
+ const SwPostItMgr *pMgr = _pViewShell->GetPostItMgr();
+ if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes()) // do not show anything in print preview
+ {
+ sal_Int32 nScrollerHeight = pMgr->GetSidebarScrollerHeight();
+ const Rectangle &aVisRect = _pViewShell->VisArea().SVRect();
+ //draw border and sidepane
+ _pViewShell->GetOut()->SetLineColor();
+ if (!bRight)
+ {
+ _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
+ _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()))) ;
+ if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ _pViewShell->GetOut()->SetFillColor(COL_BLACK);
+ else
+ _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
+ _pViewShell->GetOut()->DrawRect(Rectangle(Point(aPageRect.Left()-pMgr->GetSidebarWidth()-pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()))) ;
+ }
+ else
+ {
+ _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_BORDER);
+ SwRect aSidebarBorder(aPageRect.TopRight(),Size(pMgr->GetSidebarBorderWidth(),aPageRect.Height()));
+ _pViewShell->GetOut()->DrawRect(aSidebarBorder.SVRect());
+ if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ _pViewShell->GetOut()->SetFillColor(COL_BLACK);
+ else
+ _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE);
+ SwRect aSidebar(Point(aPageRect.Right()+pMgr->GetSidebarBorderWidth(),aPageRect.Top()),Size(pMgr->GetSidebarWidth(),aPageRect.Height()));
+ _pViewShell->GetOut()->DrawRect(aSidebar.SVRect());
+ }
+ if (pMgr->ShowScrollbar(nPageNum))
+ {
+ // draw scrollbar area and arrows
+ Point aPointBottom;
+ Point aPointTop;
+ aPointBottom = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() - pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height()) :
+ Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Bottom()- _pViewShell->GetOut()->PixelToLogic(Size(0,2+pMgr->GetSidebarScrollerHeight())).Height());
+ aPointTop = !bRight ? Point(aPageRect.Left() - pMgr->GetSidebarWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height()) :
+ Point(aPageRect.Right() + pMgr->GetSidebarBorderWidth() + _pViewShell->GetOut()->PixelToLogic(Size(2,0)).Width(),aPageRect.Top() + _pViewShell->GetOut()->PixelToLogic(Size(0,2)).Height());
+ Size aSize(pMgr->GetSidebarWidth() - _pViewShell->GetOut()->PixelToLogic(Size(4,0)).Width(), _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()) ;
+ Rectangle aRectBottom(aPointBottom,aSize);
+ Rectangle aRectTop(aPointTop,aSize);
+
+ if (aRectBottom.IsOver(aVisRect))
+ {
+
+ if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ _pViewShell->GetOut()->SetLineColor(COL_WHITE);
+ _pViewShell->GetOut()->SetFillColor(COL_BLACK);
+ }
+ else
+ {
+ _pViewShell->GetOut()->SetLineColor(COL_BLACK);
+ _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
+ }
+ _pViewShell->GetOut()->DrawRect(aRectBottom);
+ _pViewShell->GetOut()->DrawLine(aPointBottom + Point(pMgr->GetSidebarWidth()/3,0), aPointBottom + Point(pMgr->GetSidebarWidth()/3 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
+
+ _pViewShell->GetOut()->SetLineColor();
+ Point aMiddleFirst(aPointBottom + Point(pMgr->GetSidebarWidth()/6,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
+ Point aMiddleSecond(aPointBottom + Point(pMgr->GetSidebarWidth()/3*2,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
+ PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell,pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
+ }
+ if (aRectTop.IsOver(aVisRect))
+ {
+ if (Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ _pViewShell->GetOut()->SetLineColor(COL_WHITE);
+ _pViewShell->GetOut()->SetFillColor(COL_BLACK);
+ }
+ else
+ {
+ _pViewShell->GetOut()->SetLineColor(COL_BLACK);
+ _pViewShell->GetOut()->SetFillColor(COL_NOTES_SIDEPANE_SCROLLAREA);
+ }
+ _pViewShell->GetOut()->DrawRect(aRectTop);
+ _pViewShell->GetOut()->DrawLine(aPointTop + Point(pMgr->GetSidebarWidth()/3*2,0), aPointTop + Point(pMgr->GetSidebarWidth()/3*2 , _pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()));
+
+ _pViewShell->GetOut()->SetLineColor();
+ Point aMiddleFirst(aPointTop + Point(pMgr->GetSidebarWidth()/3,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
+ Point aMiddleSecond(aPointTop + Point(pMgr->GetSidebarWidth()/6*5,_pViewShell->GetOut()->PixelToLogic(Size(0,nScrollerHeight)).Height()/2));
+ PaintNotesSidebarArrows(aMiddleFirst,aMiddleSecond,_pViewShell, pMgr->GetArrowColor(KEY_PAGEUP,nPageNum), pMgr->GetArrowColor(KEY_PAGEDOWN,nPageNum));
+ }
+ }
+ }
+}
+
+/*static*/ void SwPageFrm::PaintNotesSidebarArrows(const Point &aMiddleFirst, const Point &aMiddleSecond, ViewShell* _pViewShell, const Color aColorUp, const Color aColorDown)
+{
+ Polygon aTriangleUp(3);
+ Polygon aTriangleDown(3);
+
+ aTriangleUp.SetPoint(aMiddleFirst + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
+ aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),1);
+ aTriangleUp.SetPoint(aMiddleFirst + Point(_pViewShell->GetOut()->PixelToLogic(Size(3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
+
+ aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(-3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),0);
+ aTriangleDown.SetPoint(aMiddleSecond + Point(_pViewShell->GetOut()->PixelToLogic(Size(+3,0)).Width(),_pViewShell->GetOut()->PixelToLogic(Size(0,-3)).Height()),1);
+ aTriangleDown.SetPoint(aMiddleSecond + Point(0,_pViewShell->GetOut()->PixelToLogic(Size(0,3)).Height()),2);
+
+ _pViewShell->GetOut()->SetFillColor(aColorUp);
+ _pViewShell->GetOut()->DrawPolygon(aTriangleUp);
+ _pViewShell->GetOut()->SetFillColor(aColorDown);
+ _pViewShell->GetOut()->DrawPolygon(aTriangleDown);
+}
+
+/** get bound rectangle of border and shadow for repaints
+
+ OD 12.02.2003 for #i9719# and #105645#
+
+ author OD
+*/
+/*static*/ void SwPageFrm::GetBorderAndShadowBoundRect( const SwRect& _rPageRect,
+ ViewShell* _pViewShell,
+ SwRect& _orBorderAndShadowBoundRect,
+ bool bRightSidebar )
+{
+ SwRect aAlignedPageRect( _rPageRect );
+ ::SwAlignRect( aAlignedPageRect, _pViewShell );
+ SwRect aPagePxRect =
+ _pViewShell->GetOut()->LogicToPixel( aAlignedPageRect.SVRect() );
+
+ SwRect aTmpRect;
+ SwPageFrm::GetRightShadowRect( _rPageRect, _pViewShell, aTmpRect, bRightSidebar );
+
+ aPagePxRect.Right( aTmpRect.Right() );
+
+ // Always ask for full shadow
+ SwPageFrm::GetBottomShadowRect( _rPageRect, _pViewShell, aTmpRect, true, bRightSidebar );
+ aPagePxRect.Bottom( aTmpRect.Bottom() );
+ aPagePxRect.Left( aTmpRect.Left() );
+
+ _orBorderAndShadowBoundRect = _pViewShell->GetOut()->PixelToLogic( aPagePxRect.SVRect() );
+}
+
+/*static*/ void SwPageFrm::AddSidebarBorders(SwRect &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
+{
+ const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
+ if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
+ {
+ if (!bRightSidebar)
+ aRect.SetLeftAndWidth(aRect.Left() - pMgr->GetSidebarWidth(bPx) - pMgr->GetSidebarBorderWidth(bPx), aRect.Width() + pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
+ else
+ aRect.AddRight(pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
+ }
+}
+
+/*static*/ void SwPageFrm::AddSidebarBorders(Rectangle &aRect, ViewShell* _pViewShell, bool bRightSidebar, bool bPx)
+{
+ const SwPostItMgr *pMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
+ if (pMgr && pMgr->ShowNotes() && pMgr->HasNotes())
+ {
+ if (!bRightSidebar)
+ aRect.Left() -= (pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx));
+ else
+ aRect.Right() += pMgr->GetSidebarWidth(bPx) + pMgr->GetSidebarBorderWidth(bPx);
+ }
+}
+
+/*static*/ SwTwips SwPageFrm::GetSidebarBorderWidth( const ViewShell* _pViewShell )
+{
+ const SwPostItMgr* pPostItMgr = _pViewShell ? _pViewShell->GetPostItMgr() : 0;
+ const SwTwips nRet = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ? pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() : 0;
+ return nRet;
+}
+
+/*************************************************************************
+|*
+|* SwFrm::PaintBaBo()
+|*
+|*************************************************************************/
+
+void SwFrm::PaintBaBo( const SwRect& rRect, const SwPageFrm *pPage,
+ const sal_Bool bLowerBorder ) const
+{
+ if ( !pPage )
+ pPage = FindPageFrm();
+
+ OutputDevice *pOut = pGlobalShell->GetOut();
+
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pOut );
+ // <--
+
+ // OD 2004-04-23 #116347#
+ pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
+ pOut->SetLineColor();
+
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)this );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+
+ // OD 20.11.2002 #104598# - take care of page margin area
+ // Note: code move from <SwFrm::PaintBackground(..)> to new method
+ // <SwPageFrm::Paintmargin(..)>.
+ if ( IsPageFrm() )
+ {
+ static_cast<const SwPageFrm*>(this)->PaintMarginArea( rRect, pGlobalShell );
+ }
+
+ // paint background
+ {
+ PaintBackground( rRect, pPage, rAttrs, sal_False, bLowerBorder );
+ }
+
+ // OD 06.08.2002 #99657# - paint border before painting background
+ // paint grid for page frame and paint border
+ {
+ SwRect aRect( rRect );
+ if( IsPageFrm() )
+ ((SwPageFrm*)this)->PaintGrid( pOut, aRect );
+ PaintBorder( aRect, pPage, rAttrs );
+ }
+
+ pOut->Pop();
+}
+
+/*************************************************************************
+|*
+|* SwFrm::PaintBackground()
+|*
+|*************************************************************************/
+/// OD 05.09.2002 #102912#
+/// Do not paint background for fly frames without a background brush by
+/// calling <PaintBaBo> at the page or at the fly frame its anchored
+void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
+ const SwBorderAttrs & rAttrs,
+ const sal_Bool bLowerMode,
+ const sal_Bool bLowerBorder ) const
+{
+ // OD 20.01.2003 #i1837# - no paint of table background, if corresponding
+ // option is *not* set.
+ if( IsTabFrm() &&
+ !pGlobalShell->GetViewOptions()->IsTable() )
+ {
+ return;
+ }
+
+ // nothing to do for covered table cells:
+ if( IsCellFrm() && IsCoveredCell() )
+ return;
+
+ ViewShell *pSh = pGlobalShell;
+
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
+ // <--
+
+ const SvxBrushItem* pItem;
+ /// OD 05.09.2002 #102912#
+ /// temporary background brush for a fly frame without a background brush
+ SvxBrushItem* pTmpBackBrush = 0;
+ const Color* pCol;
+ SwRect aOrigBackRect;
+ const sal_Bool bPageFrm = IsPageFrm();
+ sal_Bool bLowMode = sal_True;
+
+ sal_Bool bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, bLowerMode );
+ //- Ausgabe wenn ein eigener Hintergrund mitgebracht wird.
+ bool bNoFlyBackground = !bFlyMetafile && !bBack && IsFlyFrm();
+ if ( bNoFlyBackground )
+ {
+ // OD 05.09.2002 #102912# - Fly frame has no background.
+ // Try to find background brush at parents, if previous call of
+ // <GetBackgroundBrush> disabled this option with the parameter <bLowerMode>
+ if ( bLowerMode )
+ {
+ bBack = GetBackgroundBrush( pItem, pCol, aOrigBackRect, false );
+ }
+ // If still no background found for the fly frame, initialize the
+ // background brush <pItem> with global retouche color and set <bBack>
+ // to sal_True, that fly frame will paint its background using this color.
+ if ( !bBack )
+ {
+ // OD 10.01.2003 #i6467# - on print output, pdf output and
+ // in embedded mode not editing color COL_WHITE is used instead of
+ // the global retouche color.
+ if ( pSh->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
+ pSh->GetViewOptions()->IsPDFExport() ||
+ ( pSh->GetDoc()->GetDocShell()->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED &&
+ !pSh->GetDoc()->GetDocShell()->IsInPlaceActive()
+ )
+ )
+ {
+ pTmpBackBrush = new SvxBrushItem( Color( COL_WHITE ), RES_BACKGROUND );
+ }
+ else
+ {
+ pTmpBackBrush = new SvxBrushItem( aGlobalRetoucheColor, RES_BACKGROUND);
+ }
+ pItem = pTmpBackBrush;
+ bBack = true;
+ }
+ }
+
+ SwRect aPaintRect( Frm() );
+ if( IsTxtFrm() || IsSctFrm() )
+ aPaintRect = UnionFrm( sal_True );
+
+ if ( aPaintRect.IsOver( rRect ) )
+ {
+ if ( bBack || bPageFrm || !bLowerMode )
+ {
+ const sal_Bool bBrowse = pSh->GetViewOptions()->getBrowseMode();
+ SwRect aRect;
+ if ( (bPageFrm && bBrowse) ||
+ (IsTxtFrm() && Prt().SSize() == Frm().SSize()) )
+ {
+ aRect = Frm();
+ ::SwAlignRect( aRect, pGlobalShell );
+ }
+ else
+ {
+ ::lcl_CalcBorderRect( aRect, this, rAttrs, sal_False );
+ if ( (IsTxtFrm() || IsTabFrm()) && GetPrev() )
+ {
+ if ( GetPrev()->GetAttrSet()->GetBackground() ==
+ GetAttrSet()->GetBackground() )
+ {
+ aRect.Top( Frm().Top() );
+ }
+ }
+ }
+ aRect.Intersection( rRect );
+
+ OutputDevice *pOut = pSh->GetOut();
+
+ if ( aRect.HasArea() )
+ {
+ SvxBrushItem* pNewItem = 0;
+ SwRegionRects aRegion( aRect );
+ if( pCol )
+ {
+ pNewItem = new SvxBrushItem( *pCol, RES_BACKGROUND );
+ pItem = pNewItem;
+ }
+ if ( pPage->GetSortedObjs() )
+ ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
+
+ {
+ /// OD 06.08.2002 #99657# - determine, if background transparency
+ /// have to be considered for drawing.
+ /// --> Status Quo: background transparency have to be
+ /// considered for fly frames
+ const sal_Bool bConsiderBackgroundTransparency = IsFlyFrm();
+ for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
+ {
+ if ( 1 < aRegion.Count() )
+ {
+ ::SwAlignRect( aRegion[i], pGlobalShell );
+ if( !aRegion[i].HasArea() )
+ continue;
+ }
+ /// OD 06.08.2002 #99657# - add 6th parameter to indicate, if
+ /// background transparency have to be considered
+ /// Set missing 5th parameter to the default value GRFNUM_NO
+ /// - see declaration in /core/inc/frmtool.hxx.
+ ::DrawGraphic( pItem, pOut, aOrigBackRect, aRegion[i], GRFNUM_NO,
+ bConsiderBackgroundTransparency );
+ }
+ }
+ if( pCol )
+ delete pNewItem;
+ }
+ }
+ else
+ bLowMode = bLowerMode ? sal_True : sal_False;
+ }
+
+ /// OD 05.09.2002 #102912#
+ /// delete temporary background brush.
+ delete pTmpBackBrush;
+
+ //Jetzt noch Lower und dessen Nachbarn.
+ //Wenn ein Frn dabei die Kette verlaesst also nicht mehr Lower von mir ist
+ //so hoert der Spass auf.
+ const SwFrm *pFrm = GetLower();
+ if ( pFrm )
+ {
+ SwRect aFrmRect;
+ SwRect aRect( PaintArea() );
+ aRect._Intersection( rRect );
+ SwRect aBorderRect( aRect );
+ SwShortCut aShortCut( *pFrm, aBorderRect );
+ do
+ { if ( pProgress )
+ pProgress->Reschedule();
+
+ aFrmRect = pFrm->PaintArea();
+ if ( aFrmRect.IsOver( aBorderRect ) )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFrm );
+ const SwBorderAttrs &rTmpAttrs = *aAccess.Get();
+ /// OD 06.08.2002 #99657# - paint border before painting background
+ if ( bLowerBorder )
+ pFrm->PaintBorder( aBorderRect, pPage, rTmpAttrs );
+ if ( ( pFrm->IsLayoutFrm() && bLowerBorder ) ||
+ aFrmRect.IsOver( aRect ) )
+ pFrm->PaintBackground( aRect, pPage, rTmpAttrs, bLowMode,
+ bLowerBorder );
+ }
+ pFrm = pFrm->GetNext();
+ } while ( pFrm && pFrm->GetUpper() == this &&
+ !aShortCut.Stop( aFrmRect ) );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::RefreshSubsidiary()
+|*
+|* Beschreibung Erneuert alle Hilfslinien der Seite.
+|*
+|*************************************************************************/
+
+void SwPageFrm::RefreshSubsidiary( const SwRect &rRect ) const
+{
+ if ( IS_SUBS || IS_SUBS_TABLE || IS_SUBS_SECTION || IS_SUBS_FLYS )
+ {
+ SwRect aRect( rRect );
+ // OD 18.02.2003 #104989# - Not necessary and incorrect alignment of
+ // the output rectangle.
+ //::SwAlignRect( aRect, pGlobalShell );
+ if ( aRect.HasArea() )
+ {
+ //Beim Paint ueber die Root wird das Array von dort gesteuert.
+ //Anderfalls kuemmern wir uns selbst darum.
+ sal_Bool bDelSubs = sal_False;
+ if ( !pSubsLines )
+ {
+ pSubsLines = new SwSubsRects;
+ // OD 20.12.2002 #106318# - create container for special subsidiary lines
+ pSpecSubsLines = new SwSubsRects;
+ bDelSubs = sal_True;
+ }
+
+ RefreshLaySubsidiary( this, aRect );
+
+ if ( bDelSubs )
+ {
+ // OD 20.12.2002 #106318# - paint special subsidiary lines
+ // and delete its container
+ pSpecSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), NULL );
+ DELETEZ( pSpecSubsLines );
+
+ pSubsLines->PaintSubsidiary( pGlobalShell->GetOut(), pLines );
+ DELETEZ( pSubsLines );
+ }
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwLayoutFrm::RefreshLaySubsidiary()
+|*
+|*************************************************************************/
+void SwLayoutFrm::RefreshLaySubsidiary( const SwPageFrm *pPage,
+ const SwRect &rRect ) const
+{
+ const sal_Bool bNoLowerColumn = !Lower() || !Lower()->IsColumnFrm();
+ const sal_Bool bSubsOpt = IS_SUBS;
+ const sal_Bool bSubsTable = ((GetType() & (FRM_ROW | FRM_CELL)) && IS_SUBS_TABLE);
+ const sal_Bool bSubsOther = (GetType() & (FRM_HEADER | FRM_FOOTER | FRM_FTN )) && bSubsOpt;
+ const sal_Bool bSubsSect = IsSctFrm() &&
+ bNoLowerColumn &&
+ IS_SUBS_SECTION;
+ const sal_Bool bSubsFly = IS_SUBS_FLYS &&
+ (GetType() & FRM_FLY) &&
+ bNoLowerColumn &&
+ (!Lower() || !Lower()->IsNoTxtFrm() ||
+ !((SwNoTxtFrm*)Lower())->HasAnimation());
+ sal_Bool bSubsBody = sal_False;
+ if ( GetType() & FRM_BODY )
+ {
+ if ( IsPageBodyFrm() )
+ bSubsBody = bSubsOpt && bNoLowerColumn; //nur ohne Spalten
+ else //Spaltenbody
+ {
+ if ( GetUpper()->GetUpper()->IsSctFrm() )
+ bSubsBody = IS_SUBS_SECTION;
+ else
+ bSubsBody = bSubsOpt;
+ }
+ }
+
+ if ( bSubsOther || bSubsSect || bSubsBody || bSubsTable || bSubsFly )
+ PaintSubsidiaryLines( pPage, rRect );
+
+ const SwFrm *pLow = Lower();
+ if( !pLow )
+ return;
+ SwShortCut aShortCut( *pLow, rRect );
+ while( pLow && !aShortCut.Stop( pLow->Frm() ) )
+ {
+ if ( pLow->Frm().IsOver( rRect ) && pLow->Frm().HasArea() )
+ {
+ if ( pLow->IsLayoutFrm() )
+ ((const SwLayoutFrm*)pLow)->RefreshLaySubsidiary( pPage, rRect);
+ else if ( pLow->GetDrawObjs() )
+ {
+ const SwSortedObjs& rObjs = *(pLow->GetDrawObjs());
+ for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
+ {
+ const SwAnchoredObject* pAnchoredObj = rObjs[i];
+ if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
+ pAnchoredObj->GetDrawObj()->GetLayer() ) &&
+ pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ const SwFlyFrm *pFly =
+ static_cast<const SwFlyFrm*>(pAnchoredObj);
+ if ( pFly->IsFlyInCntFrm() && pFly->Frm().IsOver( rRect ) )
+ {
+ if ( !pFly->Lower() || !pFly->Lower()->IsNoTxtFrm() ||
+ !((SwNoTxtFrm*)pFly->Lower())->HasAnimation())
+ pFly->RefreshLaySubsidiary( pPage, rRect );
+ }
+ }
+ }
+ }
+ }
+ pLow = pLow->GetNext();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwLayoutFrm::PaintSubsidiaryLines()
+|*
+|* Beschreibung Hilfslinien um die PrtAreas malen
+|* Nur die LayoutFrm's die direkt Cntnt enthalten.
+|*
+|*************************************************************************/
+
+//Malt die angegebene Linie, achtet darauf, dass keine Flys uebermalt werden.
+
+typedef long Size::* SizePtr;
+typedef long Point::* PointPtr;
+
+PointPtr pX = &Point::nA;
+PointPtr pY = &Point::nB;
+SizePtr pWidth = &Size::nA;
+SizePtr pHeight = &Size::nB;
+
+// OD 18.11.2002 #99672# - new parameter <_pSubsLines>
+void MA_FASTCALL lcl_RefreshLine( const SwLayoutFrm *pLay,
+ const SwPageFrm *pPage,
+ const Point &rP1,
+ const Point &rP2,
+ const sal_uInt8 nSubColor,
+ SwLineRects* _pSubsLines )
+{
+ //In welche Richtung gehts? Kann nur Horizontal oder Vertikal sein.
+ OSL_ENSURE( ((rP1.X() == rP2.X()) || (rP1.Y() == rP2.Y())),
+ "Schraege Hilfslinien sind nicht erlaubt." );
+ const PointPtr pDirPt = rP1.X() == rP2.X() ? pY : pX;
+ const PointPtr pOthPt = pDirPt == pX ? pY : pX;
+ const SizePtr pDirSz = pDirPt == pX ? pWidth : pHeight;
+ const SizePtr pOthSz = pDirSz == pWidth ? pHeight : pWidth;
+ Point aP1( rP1 ),
+ aP2( rP2 );
+
+ while ( aP1.*pDirPt < aP2.*pDirPt )
+ { //Der Startpunkt wird jetzt, falls er in einem Fly sitzt, direkt
+ //hinter den Fly gesetzt.
+ //Wenn der Endpunkt in einem Fly sitzt oder zwischen Start und Endpunkt
+ //ein Fly sitzt, so wird der Endpunkt eben an den Start herangezogen.
+ //Auf diese art und weise wird eine Portion nach der anderen
+ //ausgegeben.
+
+ //Wenn ich selbst ein Fly bin, weiche ich nur denjenigen Flys aus,
+ //die 'ueber' mir sitzen; d.h. die in dem Array hinter mir stehen.
+ //Auch wenn ich in einem Fly sitze oder in einem Fly im Fly usw. weiche
+ //ich keinem dieser Flys aus.
+ SwOrderIter aIter( pPage );
+ const SwFlyFrm *pMyFly = pLay->FindFlyFrm();
+ if ( pMyFly )
+ {
+ aIter.Current( pMyFly->GetVirtDrawObj() );
+ while ( 0 != (pMyFly = pMyFly->GetAnchorFrm()->FindFlyFrm()) )
+ {
+ if ( aIter()->GetOrdNum() > pMyFly->GetVirtDrawObj()->GetOrdNum() )
+ aIter.Current( pMyFly->GetVirtDrawObj() );
+ }
+ }
+ else
+ aIter.Bottom();
+
+ while ( aIter() )
+ {
+ const SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)aIter();
+ const SwFlyFrm *pFly = pObj ? pObj->GetFlyFrm() : 0;
+
+ //Mir selbst weiche ich natuerlich nicht aus. Auch wenn ich
+ //_in_ dem Fly sitze weiche ich nicht aus.
+ if ( !pFly || (pFly == pLay || pFly->IsAnLower( pLay )) )
+ {
+ aIter.Next();
+ continue;
+ }
+
+ // OD 19.12.2002 #106318# - do *not* consider fly frames with
+ // a transparent background.
+ // OD 2004-02-12 #110582#-2 - do *not* consider fly frame, which
+ // belongs to a invisible layer
+ if ( pFly->IsBackgroundTransparent() ||
+ !pFly->GetFmt()->GetDoc()->IsVisibleLayerId( pObj->GetLayer() ) )
+ {
+ aIter.Next();
+ continue;
+ }
+
+ //Sitzt das Obj auf der Linie
+ const Rectangle &rBound = pObj->GetCurrentBoundRect();
+ const Point aDrPt( rBound.TopLeft() );
+ const Size aDrSz( rBound.GetSize() );
+ if ( rP1.*pOthPt >= aDrPt.*pOthPt &&
+ rP1.*pOthPt <= (aDrPt.*pOthPt + aDrSz.*pOthSz) )
+ {
+ if ( aP1.*pDirPt >= aDrPt.*pDirPt &&
+ aP1.*pDirPt <= (aDrPt.*pDirPt + aDrSz.*pDirSz) )
+ aP1.*pDirPt = aDrPt.*pDirPt + aDrSz.*pDirSz;
+
+ if ( aP2.*pDirPt >= aDrPt.*pDirPt &&
+ aP1.*pDirPt < (aDrPt.*pDirPt - 1) )
+ aP2.*pDirPt = aDrPt.*pDirPt - 1;
+ }
+ aIter.Next();
+ }
+
+ if ( aP1.*pDirPt < aP2.*pDirPt )
+ {
+ SwRect aRect( aP1, aP2 );
+ // OD 18.11.2002 #99672# - use parameter <_pSubsLines> instead of
+ // global variable <pSubsLines>.
+ _pSubsLines->AddLineRect( aRect, 0, SOLID, 0, nSubColor );
+ }
+ aP1 = aP2;
+ aP1.*pDirPt += 1;
+ aP2 = rP2;
+ }
+}
+
+void SwLayoutFrm::PaintSubsidiaryLines( const SwPageFrm *pPage,
+ const SwRect &rRect ) const
+{
+ bool bNewTableModel = false;
+
+ // --> collapsing borders FME 2005-05-27 #i29550#
+ if ( IsTabFrm() || IsCellFrm() || IsRowFrm() )
+ {
+ const SwTabFrm* pTabFrm = FindTabFrm();
+ if ( pTabFrm->IsCollapsingBorders() )
+ return;
+
+ bNewTableModel = pTabFrm->GetTable()->IsNewModel();
+ // in the new table model, we have an early return for all cell-related
+ // frames, except from non-covered table cells
+ if ( bNewTableModel )
+ if ( IsTabFrm() ||
+ IsRowFrm() ||
+ ( IsCellFrm() && IsCoveredCell() ) )
+ return;
+ }
+ // <-- collapsing
+
+ const bool bFlys = pPage->GetSortedObjs() ? true : false;
+
+ const bool bCell = IsCellFrm() ? true : false;
+ // use frame area for cells
+ // OD 13.02.2003 #i3662# - for section use also frame area
+ const bool bUseFrmArea = bCell || IsSctFrm();
+ SwRect aOriginal( bUseFrmArea ? Frm() : Prt() );
+ if ( !bUseFrmArea )
+ aOriginal.Pos() += Frm().Pos();
+
+ // OD 13.02.2003 #i3662# - enlarge top of column body frame's printing area
+ // in sections to top of section frame.
+ const bool bColBodyInSection = IsBodyFrm() &&
+ !IsPageBodyFrm() &&
+ GetUpper()->GetUpper()->IsSctFrm();
+ if ( bColBodyInSection )
+ {
+ if ( IsVertical() )
+ aOriginal.Right( GetUpper()->GetUpper()->Frm().Right() );
+ else
+ aOriginal.Top( GetUpper()->GetUpper()->Frm().Top() );
+ }
+
+ ::SwAlignRect( aOriginal, pGlobalShell );
+
+ if ( !aOriginal.IsOver( rRect ) )
+ return;
+
+ SwRect aOut( aOriginal );
+ aOut._Intersection( rRect );
+ // OD 13.02.2003 #i3662# - do not intersect *enlarged* column body frame's
+ // printing area with the paint area of the body frame. Otherwise enlargement
+ // will get lost.
+ if ( !bColBodyInSection )
+ {
+ aOut.Intersection( PaintArea() );
+ }
+
+ const SwTwips nRight = aOut.Right();
+ const SwTwips nBottom= aOut.Bottom();
+
+ const Point aRT( nRight, aOut.Top() );
+ const Point aRB( nRight, nBottom );
+ const Point aLB( aOut.Left(), nBottom );
+
+ sal_uInt8 nSubColor = ( bCell || IsRowFrm() ) ? SUBCOL_TAB :
+ ( IsInSct() ? SUBCOL_SECT :
+ ( IsInFly() ? SUBCOL_FLY : SUBCOL_PAGE ) );
+
+ // OD 05.11.2002 #102406# - body frames are responsible for page/column breaks.
+ sal_Bool bBreak = sal_False;
+ if ( IsBodyFrm() )
+ {
+ const SwCntntFrm *pCnt = ContainsCntnt();
+ if ( pCnt )
+ {
+ // OD 05.11.2002 #102406# - adjust setting of <bBreak>.
+ bBreak = pCnt->IsPageBreak( sal_True ) ||
+ ( IsColBodyFrm() && pCnt->IsColBreak( sal_True ) );
+ }
+ }
+
+ // OD 18.11.2002 #99672# - collect body, header, footer, footnote and section
+ // sub-lines in <pSpecSubsLine> array.
+ const bool bSpecialSublines = IsBodyFrm() || IsHeaderFrm() || IsFooterFrm() ||
+ IsFtnFrm() || IsSctFrm();
+ SwLineRects* pUsedSubsLines = bSpecialSublines ? pSpecSubsLines : pSubsLines;
+
+ // NOTE: for cell frames only left and right (horizontal layout) respectively
+ // top and bottom (vertical layout) lines painted.
+ // NOTE2: this does not hold for the new table model!!! We paint the top border
+ // of each non-covered table cell.
+ const bool bVert = IsVertical() ? true : false;
+ if ( bFlys )
+ {
+ // OD 14.11.2002 #104822# - add control for drawing left and right lines
+ if ( !bCell || bNewTableModel || !bVert )
+ {
+ if ( aOriginal.Left() == aOut.Left() )
+ ::lcl_RefreshLine( this, pPage, aOut.Pos(), aLB, nSubColor,
+ pUsedSubsLines );
+ // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
+ if ( aOriginal.Right() == nRight )
+ ::lcl_RefreshLine( this, pPage, aRT, aRB,
+ (bBreak && bVert) ? SUBCOL_BREAK : nSubColor,
+ pUsedSubsLines );
+ }
+ // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
+ if ( !bCell || bNewTableModel || bVert )
+ {
+ if ( aOriginal.Top() == aOut.Top() )
+ // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
+ ::lcl_RefreshLine( this, pPage, aOut.Pos(), aRT,
+ (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor,
+ pUsedSubsLines );
+ if ( aOriginal.Bottom() == nBottom )
+ ::lcl_RefreshLine( this, pPage, aLB, aRB, nSubColor,
+ pUsedSubsLines );
+ }
+ }
+ else
+ {
+ // OD 14.11.2002 #104822# - add control for drawing left and right lines
+ if ( !bCell || bNewTableModel || !bVert )
+ {
+ if ( aOriginal.Left() == aOut.Left() )
+ {
+ const SwRect aRect( aOut.Pos(), aLB );
+ pUsedSubsLines->AddLineRect( aRect, 0, SOLID, 0, nSubColor );
+ }
+ // OD 14.11.2002 #104821# - in vertical layout set page/column break at right
+ if ( aOriginal.Right() == nRight )
+ {
+ const SwRect aRect( aRT, aRB );
+ pUsedSubsLines->AddLineRect( aRect, 0, SOLID, 0,
+ (bBreak && bVert) ? SUBCOL_BREAK : nSubColor );
+ }
+ }
+ // OD 14.11.2002 #104822# - adjust control for drawing top and bottom lines
+ if ( !bCell || bNewTableModel || bVert )
+ {
+ if ( aOriginal.Top() == aOut.Top() )
+ {
+ // OD 14.11.2002 #104821# - in horizontal layout set page/column break at top
+ const SwRect aRect( aOut.Pos(), aRT );
+ pUsedSubsLines->AddLineRect( aRect, 0, SOLID, 0,
+ (bBreak && !bVert) ? SUBCOL_BREAK : nSubColor );
+ }
+ if ( aOriginal.Bottom() == nBottom )
+ {
+ const SwRect aRect( aLB, aRB );
+ pUsedSubsLines->AddLineRect( aRect, 0, SOLID, 0, nSubColor );
+ }
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::RefreshExtraData(), SwLayoutFrm::RefreshExtraData()
+|*
+|* Beschreibung Erneuert alle Extradaten (Zeilennummern usw) der Seite.
+|* Grundsaetzlich sind nur diejenigen Objekte beruecksichtig,
+|* die in die seitliche Ausdehnung des Rects ragen.
+|*
+|*************************************************************************/
+
+void SwPageFrm::RefreshExtraData( const SwRect &rRect ) const
+{
+ const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
+ sal_Bool bLineInFly = (rInfo.IsPaintLineNumbers() && rInfo.IsCountInFlys())
+ || (sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE;
+
+ SwRect aRect( rRect );
+ ::SwAlignRect( aRect, pGlobalShell );
+ if ( aRect.HasArea() )
+ {
+ SwLayoutFrm::RefreshExtraData( aRect );
+
+ if ( bLineInFly && GetSortedObjs() )
+ for ( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i )
+ {
+ const SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
+ if ( pFly->Frm().Top() <= aRect.Bottom() &&
+ pFly->Frm().Bottom() >= aRect.Top() )
+ pFly->RefreshExtraData( aRect );
+ }
+ }
+ }
+}
+
+void SwLayoutFrm::RefreshExtraData( const SwRect &rRect ) const
+{
+
+ const SwLineNumberInfo &rInfo = GetFmt()->GetDoc()->GetLineNumberInfo();
+ sal_Bool bLineInBody = rInfo.IsPaintLineNumbers(),
+ bLineInFly = bLineInBody && rInfo.IsCountInFlys(),
+ bRedLine = (sal_Int16)SW_MOD()->GetRedlineMarkPos()!=text::HoriOrientation::NONE;
+
+ const SwCntntFrm *pCnt = ContainsCntnt();
+ while ( pCnt && IsAnLower( pCnt ) )
+ {
+ if ( pCnt->IsTxtFrm() && ( bRedLine ||
+ ( !pCnt->IsInTab() &&
+ ((bLineInBody && pCnt->IsInDocBody()) ||
+ (bLineInFly && pCnt->IsInFly())) ) ) &&
+ pCnt->Frm().Top() <= rRect.Bottom() &&
+ pCnt->Frm().Bottom() >= rRect.Top() )
+ {
+ ((SwTxtFrm*)pCnt)->PaintExtraData( rRect );
+ }
+ if ( bLineInFly && pCnt->GetDrawObjs() )
+ for ( sal_uInt32 i = 0; i < pCnt->GetDrawObjs()->Count(); ++i )
+ {
+ const SwAnchoredObject* pAnchoredObj = (*pCnt->GetDrawObjs())[i];
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
+ if ( pFly->IsFlyInCntFrm() &&
+ pFly->Frm().Top() <= rRect.Bottom() &&
+ pFly->Frm().Bottom() >= rRect.Top() )
+ pFly->RefreshExtraData( rRect );
+ }
+ }
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+}
+
+/** SwPageFrm::GetDrawBackgrdColor - for #102450#
+
+ determine the color, that is respectively will be drawn as background
+ for the page frame.
+ Using existing method SwFrm::GetBackgroundBrush to determine the color
+ that is set at the page frame respectively is parent. If none is found
+ return the global retouche color
+
+ @author OD
+
+ @return Color
+*/
+const Color& SwPageFrm::GetDrawBackgrdColor() const
+{
+ const SvxBrushItem* pBrushItem;
+ const Color* pDummyColor;
+ SwRect aDummyRect;
+ if ( GetBackgroundBrush( pBrushItem, pDummyColor, aDummyRect, true) )
+ return pBrushItem->GetColor();
+ else
+ return aGlobalRetoucheColor;
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::GetEmptyPageFont()
+|*
+|* create/return font used to paint the "empty page" string
+|*
+|*************************************************************************/
+
+const Font& SwPageFrm::GetEmptyPageFont()
+{
+ static Font* pEmptyPgFont = 0;
+ if ( 0 == pEmptyPgFont )
+ {
+ pEmptyPgFont = new Font;
+ pEmptyPgFont->SetSize( Size( 0, 80 * 20 )); // == 80 pt
+ pEmptyPgFont->SetWeight( WEIGHT_BOLD );
+ pEmptyPgFont->SetStyleName( aEmptyStr );
+ pEmptyPgFont->SetName( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "Helvetica" )) );
+ pEmptyPgFont->SetFamily( FAMILY_SWISS );
+ pEmptyPgFont->SetTransparent( sal_True );
+ pEmptyPgFont->SetColor( COL_GRAY );
+ }
+
+ return *pEmptyPgFont;
+}
+
+/*************************************************************************
+|*
+|* SwFrm::Retouche
+|*
+|* Beschreibung Retouche fuer einen Bereich.
+|* Retouche wird nur dann durchgefuehrt, wenn der Frm der letzte seiner
+|* Kette ist. Der Gesamte Bereich des Upper unterhalb des Frm wird
+|* per PaintBackground gecleared.
+|*
+|*************************************************************************/
+
+void SwFrm::Retouche( const SwPageFrm * pPage, const SwRect &rRect ) const
+{
+ if ( bFlyMetafile )
+ return;
+
+ OSL_ENSURE( GetUpper(), "Retoucheversuch ohne Upper." );
+ OSL_ENSURE( getRootFrm()->GetCurrShell() && pGlobalShell->GetWin(), "Retouche auf dem Drucker?" );
+
+ SwRect aRetouche( GetUpper()->PaintArea() );
+ aRetouche.Top( Frm().Top() + Frm().Height() );
+ aRetouche.Intersection( pGlobalShell->VisArea() );
+
+ if ( aRetouche.HasArea() )
+ {
+ //Uebergebenes Rect ausparen. Dafuer brauchen wir leider eine Region
+ //zum ausstanzen.
+ SwRegionRects aRegion( aRetouche );
+ aRegion -= rRect;
+ ViewShell *pSh = getRootFrm()->GetCurrShell();
+
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pSh->GetOut() );
+ // <--
+
+ for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
+ {
+ SwRect &rRetouche = aRegion[i];
+
+ GetUpper()->PaintBaBo( rRetouche, pPage, sal_True );
+
+ //Hoelle und Himmel muessen auch refreshed werden.
+ //Um Rekursionen zu vermeiden muss mein Retouche Flag zuerst
+ //zurueckgesetzt werden!
+ ResetRetouche();
+ SwRect aRetouchePart( rRetouche );
+ if ( aRetouchePart.HasArea() )
+ {
+ // OD 30.08.2002 #102450#
+ // determine background color of page for <PaintLayer> method
+ // calls, painting <hell> or <heaven>
+ const Color aPageBackgrdColor = pPage->GetDrawBackgrdColor();
+ // OD 29.08.2002 #102450#
+ // add 3rd parameter to <PaintLayer> method calls
+ // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
+ const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
+
+ pSh->Imp()->PaintLayer( pIDDMA->GetHellId(), 0,
+ aRetouchePart, &aPageBackgrdColor,
+ (pPage->IsRightToLeft() ? true : false) );
+ pSh->Imp()->PaintLayer( pIDDMA->GetHeavenId(), 0,
+ aRetouchePart, &aPageBackgrdColor,
+ (pPage->IsRightToLeft() ? true : false) );
+ }
+
+ SetRetouche();
+
+ //Da wir uns ausserhalb aller Paint-Bereiche begeben muessen hier
+ //leider die Hilfslinien erneuert werden.
+ pPage->RefreshSubsidiary( aRetouchePart );
+ }
+ }
+ if ( ViewShell::IsLstEndAction() )
+ ResetRetouche();
+}
+
+/** SwFrm::GetBackgroundBrush
+
+ @descr
+ determine the background brush for the frame:
+ the background brush is taken from it-self or from its parent (anchor/upper).
+ Normally, the background brush is taken, which has no transparent color or
+ which has a background graphic. But there are some special cases:
+ (1) No background brush is taken from a page frame, if view option "IsPageBack"
+ isn't set.
+ (2) Background brush from a index section is taken under special conditions.
+ In this case parameter <rpCol> is set to the index shading color.
+ (3) New (OD 20.08.2002) - Background brush is taken, if on background drawing
+ of the frame transparency is considered and its color is not "no fill"/"auto fill"
+ ---- old description in german:
+ Beschreibung Liefert die Backgroundbrush fuer den Bereich des
+ des Frm. Die Brush wird entweder von ihm selbst oder von einem
+ Upper vorgegeben, die erste Brush wird benutzt.
+ Ist fuer keinen Frm eine Brush angegeben, so wird sal_False zurueck-
+ geliefert.
+
+ @param rpBrush
+ output parameter - constant reference pointer the found background brush
+
+ @param rpCol
+ output parameter - constant reference pointer to the color of the index shading
+ set under special conditions, if background brush is taken from an index section.
+
+ @param rOrigRect
+ in-/output parameter - reference to the retangle the background brush is
+ considered for - adjusted to the frame, from which the background brush is
+ taken.
+
+ @parem bLowerMode
+ input parameter - boolean indicating, if background brush should *not* be
+ taken from parent.
+
+ @return true, if a background brush for the frame is found
+*/
+sal_Bool SwFrm::GetBackgroundBrush( const SvxBrushItem* & rpBrush,
+ const Color*& rpCol,
+ SwRect &rOrigRect,
+ sal_Bool bLowerMode ) const
+{
+ const SwFrm *pFrm = this;
+ ViewShell *pSh = getRootFrm()->GetCurrShell();
+ const SwViewOption *pOpt = pSh->GetViewOptions();
+ rpBrush = 0;
+ rpCol = NULL;
+ do
+ { if ( pFrm->IsPageFrm() && !pOpt->IsPageBack() )
+ return sal_False;
+
+ const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
+ if( pFrm->IsSctFrm() )
+ {
+ const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
+ /// OD 20.08.2002 #99657# #GetTransChg#
+ /// Note: If frame <pFrm> is a section of the index and
+ /// it its background color is "no fill"/"auto fill" and
+ /// it has no background graphic and
+ /// we are not in the page preview and
+ /// we are not in read-only mode and
+ /// option "index shadings" is set and
+ /// the output is not the printer
+ /// then set <rpCol> to the color of the index shading
+ if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
+ TOX_CONTENT_SECTION == pSection->GetType() ) &&
+ (rBack.GetColor() == COL_TRANSPARENT) &&
+ ///rBack.GetColor().GetTransparency() &&
+ rBack.GetGraphicPos() == GPOS_NONE &&
+ !pOpt->IsPagePreview() &&
+ !pOpt->IsReadonly() &&
+ // --> FME 2004-06-29 #114856# Formular view
+ !pOpt->IsFormView() &&
+ // <--
+ SwViewOption::IsIndexShadings() &&
+ !pOpt->IsPDFExport() &&
+ pSh->GetOut()->GetOutDevType() != OUTDEV_PRINTER )
+ {
+ rpCol = &SwViewOption::GetIndexShadingsColor();
+ }
+ }
+
+ /// OD 20.08.2002 #99657#
+ /// determine, if background draw of frame <pFrm> considers transparency
+ /// --> Status Quo: background transparency have to be
+ /// considered for fly frames
+ const sal_Bool bConsiderBackgroundTransparency = pFrm->IsFlyFrm();
+ /// OD 20.08.2002 #99657#
+ /// add condition:
+ /// If <bConsiderBackgroundTransparency> is set - see above -,
+ /// return brush of frame <pFrm>, if its color is *not* "no fill"/"auto fill"
+ if ( !rBack.GetColor().GetTransparency() ||
+ rBack.GetGraphicPos() != GPOS_NONE ||
+ rpCol ||
+ (bConsiderBackgroundTransparency && (rBack.GetColor() != COL_TRANSPARENT))
+ )
+ {
+ rpBrush = &rBack;
+ if ( pFrm->IsPageFrm() &&
+ pSh->GetViewOptions()->getBrowseMode() )
+ rOrigRect = pFrm->Frm();
+ else
+ {
+ if ( pFrm->Frm().SSize() != pFrm->Prt().SSize() )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ ::lcl_CalcBorderRect( rOrigRect, pFrm, rAttrs, sal_False );
+ }
+ else
+ {
+ rOrigRect = pFrm->Prt();
+ rOrigRect += pFrm->Frm().Pos();
+ }
+ }
+ return sal_True;
+ }
+
+ if ( bLowerMode )
+ /// Do not try to get background brush from parent (anchor/upper)
+ return sal_False;
+
+ /// get parent frame - anchor or upper - for next loop
+ if ( pFrm->IsFlyFrm() )
+ /// OD 20.08.2002 - use "static_cast" instead of "old C-cast"
+ pFrm = (static_cast<const SwFlyFrm*>(pFrm))->GetAnchorFrm();
+ ///pFrm = ((SwFlyFrm*)pFrm)->GetAnchor();
+ else
+ pFrm = pFrm->GetUpper();
+
+ } while ( pFrm );
+
+ return sal_False;
+}
+
+/*************************************************************************
+|*
+|* SwFrmFmt::GetGraphic()
+|*
+|*************************************************************************/
+
+void SetOutDevAndWin( ViewShell *pSh, OutputDevice *pO,
+ Window *pW, sal_uInt16 nZoom )
+{
+ pSh->pOut = pO;
+ pSh->pWin = pW;
+ pSh->pOpt->SetZoom( nZoom );
+}
+
+Graphic SwFrmFmt::MakeGraphic( ImageMap* )
+{
+ return Graphic();
+}
+
+Graphic SwFlyFrmFmt::MakeGraphic( ImageMap* pMap )
+{
+ Graphic aRet;
+ //irgendeinen Fly suchen!
+ SwIterator<SwFrm,SwFmt> aIter( *this );
+ SwFrm *pFirst = aIter.First();
+ ViewShell *pSh;
+ if ( pFirst && 0 != ( pSh = pFirst->getRootFrm()->GetCurrShell()) )
+ {
+ ViewShell *pOldGlobal = pGlobalShell;
+ pGlobalShell = pSh;
+
+ sal_Bool bNoteURL = pMap &&
+ SFX_ITEM_SET != GetAttrSet().GetItemState( RES_URL, sal_True );
+ if( bNoteURL )
+ {
+ OSL_ENSURE( !pNoteURL, "MakeGraphic: pNoteURL already used? " );
+ pNoteURL = new SwNoteURL;
+ }
+ SwFlyFrm *pFly = (SwFlyFrm*)pFirst;
+
+ OutputDevice *pOld = pSh->GetOut();
+ VirtualDevice aDev( *pOld );
+ aDev.EnableOutput( sal_False );
+
+ GDIMetaFile aMet;
+ MapMode aMap( pOld->GetMapMode().GetMapUnit() );
+ aDev.SetMapMode( aMap );
+ aMet.SetPrefMapMode( aMap );
+
+ ::SwCalcPixStatics( pSh->GetOut() );
+ aMet.SetPrefSize( pFly->Frm().SSize() );
+
+ aMet.Record( &aDev );
+ aDev.SetLineColor();
+ aDev.SetFillColor();
+ aDev.SetFont( pOld->GetFont() );
+
+ //Rechteck ggf. ausdehnen, damit die Umrandunge mit aufgezeichnet werden.
+ SwRect aOut( pFly->Frm() );
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFly );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ if ( rAttrs.CalcRightLine() )
+ aOut.SSize().Width() += 2*nPixelSzW;
+ if ( rAttrs.CalcBottomLine() )
+ aOut.SSize().Height()+= 2*nPixelSzH;
+
+ // #i92711# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
+ const Region aRepaintRegion(aOut.SVRect());
+ pSh->DLPrePaint2(aRepaintRegion);
+
+ Window *pWin = pSh->GetWin();
+ sal_uInt16 nZoom = pSh->GetViewOptions()->GetZoom();
+ ::SetOutDevAndWin( pSh, &aDev, 0, 100 );
+ bFlyMetafile = sal_True;
+ pFlyMetafileOut = pWin;
+
+ SwViewImp *pImp = pSh->Imp();
+ pFlyOnlyDraw = pFly;
+ pLines = new SwLineRects;
+
+ // OD 09.12.2002 #103045# - determine page, fly frame is on
+ const SwPageFrm* pFlyPage = pFly->FindPageFrm();
+ // OD 30.08.2002 #102450#
+ // determine color of page, the fly frame is on, for <PaintLayer> method
+ // calls, painting <hell> or <heaven>
+ const Color aPageBackgrdColor = pFlyPage->GetDrawBackgrdColor();
+ // OD 30.08.2002 #102450# - add 3rd parameter
+ // OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
+ const IDocumentDrawModelAccess* pIDDMA = pSh->getIDocumentDrawModelAccess();
+ pImp->PaintLayer( pIDDMA->GetHellId(), 0, aOut, &aPageBackgrdColor,
+ (pFlyPage->IsRightToLeft() ? true : false) );
+ pLines->PaintLines( &aDev );
+ if ( pFly->IsFlyInCntFrm() )
+ pFly->Paint( aOut );
+ pLines->PaintLines( &aDev );
+ /// OD 30.08.2002 #102450# - add 3rd parameter
+ pImp->PaintLayer( pIDDMA->GetHeavenId(), 0, aOut, &aPageBackgrdColor,
+ (pFlyPage->IsRightToLeft() ? true : false) );
+ pLines->PaintLines( &aDev );
+ DELETEZ( pLines );
+ pFlyOnlyDraw = 0;
+
+ pFlyMetafileOut = 0;
+ bFlyMetafile = sal_False;
+ ::SetOutDevAndWin( pSh, pOld, pWin, nZoom );
+
+ // #i92711# end Pre/PostPaint encapsulation when pOut is back and content is painted
+ pSh->DLPostPaint2(true);
+
+ aMet.Stop();
+ aMet.Move( -pFly->Frm().Left(), -pFly->Frm().Top() );
+ aRet = Graphic( aMet );
+
+ if( bNoteURL )
+ {
+ OSL_ENSURE( pNoteURL, "MakeGraphic: Good Bye, NoteURL." );
+ pNoteURL->FillImageMap( pMap, pFly->Frm().Pos(), aMap );
+ delete pNoteURL;
+ pNoteURL = NULL;
+ }
+ pGlobalShell = pOldGlobal;
+ }
+ return aRet;
+}
+
+Graphic SwDrawFrmFmt::MakeGraphic( ImageMap* )
+{
+ Graphic aRet;
+ SdrModel *pMod = getIDocumentDrawModelAccess()->GetDrawModel();
+ if ( pMod )
+ {
+ SdrObject *pObj = FindSdrObject();
+ SdrView *pView = new SdrView( pMod );
+ SdrPageView *pPgView = pView->ShowSdrPage(pView->GetModel()->GetPage(0));
+ pView->MarkObj( pObj, pPgView );
+ aRet = pView->GetMarkedObjBitmap();
+ pView->HideSdrPage();
+ delete pView;
+ }
+ return aRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */