summaryrefslogtreecommitdiff
path: root/sw/source/core/text
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 23:08:29 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 23:08:29 +0000
commit84a3db80b4fd66c6854b3135b5f69b61fd828e62 (patch)
tree4475006ca87946e71c44668b20330b2d2729f638 /sw/source/core/text
parent7b0b5cdfeed656b279bc32cd929630d5fc25878b (diff)
initial import
Diffstat (limited to 'sw/source/core/text')
-rw-r--r--sw/source/core/text/blink.cxx205
-rw-r--r--sw/source/core/text/frmcrsr.cxx1240
-rw-r--r--sw/source/core/text/frmform.cxx1919
-rw-r--r--sw/source/core/text/frminf.cxx409
-rw-r--r--sw/source/core/text/frmpaint.cxx738
-rw-r--r--sw/source/core/text/guess.cxx492
-rw-r--r--sw/source/core/text/guess.hxx123
-rw-r--r--sw/source/core/text/inftxt.cxx1176
-rw-r--r--sw/source/core/text/inftxt.hxx807
-rw-r--r--sw/source/core/text/itradj.cxx578
-rw-r--r--sw/source/core/text/itratr.cxx833
-rw-r--r--sw/source/core/text/itratr.hxx149
-rw-r--r--sw/source/core/text/itrcrsr.cxx923
-rw-r--r--sw/source/core/text/itrform2.cxx1491
-rw-r--r--sw/source/core/text/itrform2.hxx236
-rw-r--r--sw/source/core/text/itrpaint.cxx548
-rw-r--r--sw/source/core/text/itrpaint.hxx97
-rw-r--r--sw/source/core/text/itrtxt.cxx489
-rw-r--r--sw/source/core/text/itrtxt.hxx363
-rw-r--r--sw/source/core/text/makefile.mk185
-rw-r--r--sw/source/core/text/noteurl.cxx129
-rw-r--r--sw/source/core/text/pordrop.hxx122
-rw-r--r--sw/source/core/text/porexp.cxx332
-rw-r--r--sw/source/core/text/porexp.hxx131
-rw-r--r--sw/source/core/text/porfld.cxx854
-rw-r--r--sw/source/core/text/porfld.hxx240
-rw-r--r--sw/source/core/text/porfly.cxx585
-rw-r--r--sw/source/core/text/porfly.hxx140
-rw-r--r--sw/source/core/text/porftn.hxx150
-rw-r--r--sw/source/core/text/porglue.cxx363
-rw-r--r--sw/source/core/text/porglue.hxx174
-rw-r--r--sw/source/core/text/porhyph.hxx141
-rw-r--r--sw/source/core/text/porlay.cxx504
-rw-r--r--sw/source/core/text/porlay.hxx390
-rw-r--r--sw/source/core/text/porlin.cxx405
-rw-r--r--sw/source/core/text/porlin.hxx329
-rw-r--r--sw/source/core/text/porref.cxx139
-rw-r--r--sw/source/core/text/porref.hxx106
-rw-r--r--sw/source/core/text/porrst.cxx547
-rw-r--r--sw/source/core/text/porrst.hxx149
-rw-r--r--sw/source/core/text/portab.hxx159
-rw-r--r--sw/source/core/text/portox.cxx140
-rw-r--r--sw/source/core/text/portox.hxx108
-rw-r--r--sw/source/core/text/portxt.cxx745
-rw-r--r--sw/source/core/text/portxt.hxx139
-rw-r--r--sw/source/core/text/possiz.hxx120
-rw-r--r--sw/source/core/text/redlnitr.cxx558
-rw-r--r--sw/source/core/text/redlnitr.hxx150
-rw-r--r--sw/source/core/text/txtcache.cxx277
-rw-r--r--sw/source/core/text/txtcache.hxx113
-rw-r--r--sw/source/core/text/txtcfg.hxx209
-rw-r--r--sw/source/core/text/txtdrop.cxx800
-rw-r--r--sw/source/core/text/txtfld.cxx534
-rw-r--r--sw/source/core/text/txtfly.cxx1913
-rw-r--r--sw/source/core/text/txtfly.hxx275
-rw-r--r--sw/source/core/text/txtfrm.cxx1834
-rw-r--r--sw/source/core/text/txtftn.cxx1542
-rw-r--r--sw/source/core/text/txthyph.cxx910
-rw-r--r--sw/source/core/text/txtinit.cxx151
-rw-r--r--sw/source/core/text/txtio.cxx1134
-rw-r--r--sw/source/core/text/txtpaint.cxx144
-rw-r--r--sw/source/core/text/txtpaint.hxx259
-rw-r--r--sw/source/core/text/txttab.cxx537
-rw-r--r--sw/source/core/text/widorp.cxx525
-rw-r--r--sw/source/core/text/widorp.hxx125
-rw-r--r--sw/source/core/text/wrong.cxx370
66 files changed, 32702 insertions, 0 deletions
diff --git a/sw/source/core/text/blink.cxx b/sw/source/core/text/blink.cxx
new file mode 100644
index 000000000000..01a5668ebca9
--- /dev/null
+++ b/sw/source/core/text/blink.cxx
@@ -0,0 +1,205 @@
+/*************************************************************************
+ *
+ * $RCSfile: blink.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+#include "viewsh.hxx"
+#include "rootfrm.hxx" // GetOleShell()
+#include "segmentc.hxx"
+
+#include "txtfrm.hxx" // FindRootFrm()
+#include "blink.hxx"
+#include "porlin.hxx"
+#include "porlay.hxx" // SwLineLayout
+
+// Sichtbare Zeit:
+#define BLINK_ON_TIME 2400L
+// Nihct sichtbare Zeit:
+#define BLINK_OFF_TIME 800L
+
+/*************************************************************************
+ * pBlink zeigt auf die Instanz, bei der sich blinkende Portions anmelden
+ * muessen, ggf. muss pBlink erst per new SwBlink angelegt werden.
+ * Diese werden dann rhythmisch zum Repaint angeregt und koennen abfragen,
+ * ob sie zur Zeit sichtbar oder unsichtbar sein sollen ( IsVisible() ).
+ *************************************************************************/
+SwBlink *pBlink = NULL;
+
+
+// Liste von blinkenden Portions
+SV_IMPL_OP_PTRARR_SORT( SwBlinkList, SwBlinkPortionPtr )
+
+SwBlink::SwBlink()
+{
+ bVisible = sal_True;
+ // Den Timer vorbereiten
+ aTimer.SetTimeout( BLINK_ON_TIME );
+ aTimer.SetTimeoutHdl( LINK(this, SwBlink, Blinker) );
+}
+
+SwBlink::~SwBlink( )
+{
+ aTimer.Stop();
+}
+
+/*************************************************************************
+ * SwBlink::Blinker (Timerablauf):
+ * Sichtbar/unsichtbar-Flag toggeln.
+ * Repaint-Rechtecke der Blinkportions ermitteln und an ihren OleShells
+ * invalidieren.
+ *************************************************************************/
+
+IMPL_LINK( SwBlink, Blinker, Timer *, pTimer )
+{
+ bVisible = !bVisible;
+ if( bVisible )
+ aTimer.SetTimeout( BLINK_ON_TIME );
+ else
+ aTimer.SetTimeout( BLINK_OFF_TIME );
+ if( aList.Count() )
+ {
+
+ for( MSHORT nPos = 0; nPos < aList.Count(); )
+ {
+ const SwBlinkPortion* pTmp = aList[ nPos ];
+ if( pTmp->GetRootFrm() &&
+ ((SwRootFrm*)pTmp->GetRootFrm())->GetCurrShell() )
+ {
+ ++nPos;
+ Rectangle aRefresh( Point( pTmp->GetPos().X(), pTmp->GetPos().Y()
+ - pTmp->GetPortion()->GetAscent() ),
+ pTmp->GetPortion()->SvLSize() );
+ aRefresh.Right() += ( aRefresh.Bottom()- aRefresh.Top() ) / 8;
+ ((SwRootFrm*)pTmp->GetRootFrm())
+ ->GetCurrShell()->InvalidateWindows( aRefresh );
+ }
+ else // Portions ohne Shell koennen aus der Liste entfernt werden.
+ aList.Remove( nPos );
+ }
+ }
+ else // Wenn die Liste leer ist, kann der Timer gestoppt werden.
+ aTimer.Stop();
+ return sal_True;
+}
+
+void SwBlink::Insert( const SwLinePortion* pPor, const Point& rPoint,
+ const SwTxtFrm *pTxtFrm )
+{
+ SwBlinkPortion *pBlinkPor = new SwBlinkPortion( pPor );
+ MSHORT nPos;
+ if( aList.Seek_Entry( pBlinkPor, &nPos ) )
+ {
+ aList[ nPos ]->SetPos( rPoint );
+ delete pBlinkPor;
+ }
+ else
+ {
+ pBlinkPor->SetPos( rPoint );
+ pBlinkPor->SetRootFrm( pTxtFrm->FindRootFrm() );
+ aList.Insert( pBlinkPor );
+ pTxtFrm->SetBlinkPor();
+ if( pPor->IsLayPortion() || pPor->IsParaPortion() )
+ ((SwLineLayout*)pPor)->SetBlinking( sal_True );
+
+ if( !aTimer.IsActive() )
+ aTimer.Start();
+ }
+}
+
+void SwBlink::Replace( const SwLinePortion* pOld, const SwLinePortion* pNew )
+{
+ SwBlinkPortion aBlink( pOld );
+ MSHORT nPos;
+ if( aList.Seek_Entry( &aBlink, &nPos ) )
+ {
+ SwBlinkPortion* pTmp = new SwBlinkPortion( aList[ nPos ], pNew );
+ aList.Remove( nPos );
+ aList.Insert( pTmp );
+ }
+}
+
+void SwBlink::Delete( const SwLinePortion* pPor )
+{
+ SwBlinkPortion aBlink( pPor );
+ MSHORT nPos;
+ if( aList.Seek_Entry( &aBlink, &nPos ) )
+ aList.Remove( nPos );
+}
+
+void SwBlink::FrmDelete( const SwRootFrm* pRoot )
+{
+ for( MSHORT nPos = 0; nPos < aList.Count(); )
+ {
+ if( pRoot == aList[ nPos ]->GetRootFrm() )
+ aList.Remove( nPos );
+ else
+ ++nPos;
+ }
+}
+
+
diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx
new file mode 100644
index 000000000000..b9646d63870b
--- /dev/null
+++ b/sw/source/core/text/frmcrsr.cxx
@@ -0,0 +1,1240 @@
+/*************************************************************************
+ *
+ * $RCSfile: frmcrsr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "ndtxt.hxx" // GetNode()
+#include "pam.hxx" // SwPosition
+#include "frmtool.hxx"
+#include "doc.hxx"
+#include "viewopt.hxx"
+#include "paratr.hxx"
+#include "pagefrm.hxx"
+#include "colfrm.hxx"
+#include "txttypes.hxx"
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include <sfx2/printer.hxx>
+#endif
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include <svx/lrspitem.hxx>
+#endif
+
+#ifndef _SVX_TSPTITEM_HXX //autogen
+#include <svx/tstpitem.hxx>
+#endif
+
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include <svx/ulspitem.hxx>
+#endif
+
+#include "frmsh.hxx"
+#include "txtcfg.hxx"
+#include "txtfrm.hxx" // SwTxtFrm
+#include "inftxt.hxx" // SwTxtSizeInfo
+#include "itrtxt.hxx" // SwTxtCursor
+#include "crstate.hxx" // SwTxtCursor
+#include "viewsh.hxx" // InvalidateWindows
+#include "swfntcch.hxx" // SwFontAccess
+#include "flyfrm.hxx"
+
+#ifdef DEBUG
+#include "txtpaint.hxx"
+#endif
+
+#define MIN_OFFSET_STEP 10
+
+/*
+ * 1170-SurvivalKit: Wie gelangt man hinter das letzte Zeichen der Zeile.
+ * - RightMargin verzichtet auf den Positionsausgleich mit -1
+ * - GetCharRect liefert bei MV_RIGHTMARGIN ein GetEndCharRect
+ * - GetEndCharRect setzt bRightMargin auf sal_True
+ * - SwTxtCursor::bRightMargin wird per CharCrsrToLine auf sal_False gesetzt
+ */
+
+/*************************************************************************
+ * GetAdjFrmAtPos()
+ *************************************************************************/
+
+SwTxtFrm *GetAdjFrmAtPos( SwTxtFrm *pFrm, const SwPosition &rPos,
+ const sal_Bool bRightMargin )
+{
+ // 8810: vgl. 1170, RightMargin in der letzten Masterzeile...
+ const xub_StrLen nOffset = rPos.nContent.GetIndex();
+ SwTxtFrm *pFrmAtPos = pFrm->GetFrmAtPos( rPos );
+ while( pFrm != pFrmAtPos )
+ {
+ pFrm = pFrmAtPos;
+ pFrm->GetFormatted();
+ pFrmAtPos = (SwTxtFrm*)pFrm->GetFrmAtPos( rPos );
+ }
+
+ if( nOffset && bRightMargin )
+ {
+ while( pFrmAtPos && pFrmAtPos->GetOfst() == nOffset )
+ {
+ pFrmAtPos->GetFormatted();
+ pFrmAtPos = pFrmAtPos->FindMaster();
+ }
+ ASSERT( pFrmAtPos, "+GetCharRect: no frame with my rightmargin" );
+ }
+ return pFrmAtPos ? pFrmAtPos : pFrm;
+}
+
+sal_Bool lcl_ChangeOffset( SwTxtFrm* pFrm, xub_StrLen nNew )
+{
+ // In Bereichen und ausserhalb von Flies wird nicht mehr gescrollt.
+ ASSERT( !pFrm->IsFollow(), "Illegal Scrolling by Follow!" );
+ if( pFrm->GetOfst() != nNew && !pFrm->IsInSct() )
+ {
+ SwFlyFrm *pFly = pFrm->FindFlyFrm();
+ // Vorsicht, wenn z.B. bei einem spaltigen Rahmen die Groesse noch invalide ist,
+ // duerfen wir nicht mal eben herumscrollen
+ if ( ( pFly && pFly->IsValid() &&
+ !pFly->GetNextLink() && !pFly->GetPrevLink() ) ||
+ ( !pFly && pFrm->IsInTab() ) )
+ {
+ ViewShell* pVsh = pFrm->GetShell();
+ if( pVsh )
+ {
+ if( pVsh->GetNext() != pVsh ||
+ ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) )
+ {
+ if( !pFrm->GetOfst() )
+ return sal_False;
+ nNew = 0;
+ }
+ pFrm->SetOfst( nNew );
+ pFrm->SetPara( 0 );
+ pFrm->GetFormatted();
+ pFrm->GetShell()->InvalidateWindows( pFrm->Frm() );
+ return sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+ * GetFrmAtOfst(), GetFrmAtPos()
+ *************************************************************************/
+
+SwTxtFrm *SwTxtFrm::GetFrmAtOfst( const xub_StrLen nWhere )
+{
+ SwTxtFrm *pRet = this;
+ while( pRet->HasFollow() && nWhere >= pRet->GetFollow()->GetOfst() )
+ pRet = pRet->GetFollow();
+ return pRet;
+}
+
+SwTxtFrm *SwTxtFrm::GetFrmAtPos( const SwPosition &rPos )
+{
+ SwTxtFrm *pFoll = (SwTxtFrm*)this;
+ while( pFoll->GetFollow() )
+ {
+ if( rPos.nContent.GetIndex() > pFoll->GetFollow()->GetOfst() )
+ pFoll = pFoll->GetFollow();
+ else
+ {
+ if( rPos.nContent.GetIndex() == pFoll->GetFollow()->GetOfst()
+ && !SwTxtCursor::IsRightMargin() )
+ pFoll = pFoll->GetFollow();
+ else
+ break;
+ }
+ }
+ if( rPos.nContent.GetIndex() < pFoll->GetOfst() && !pFoll->IsFollow() )
+ {
+ // Der Offset wird verschoben, bis die gewuenschte Position sichtbar
+ // wird und MIN_OFFSET_STEP weitere Zeichen.
+ xub_StrLen nNew = rPos.nContent.GetIndex();
+ if( nNew < MIN_OFFSET_STEP )
+ nNew = 0;
+ else
+ nNew -= MIN_OFFSET_STEP;
+ lcl_ChangeOffset( pFoll, nNew );
+ }
+ return pFoll;
+}
+
+/*************************************************************************
+ * SwTxtFrm::GetCharRect()
+ *************************************************************************/
+
+/*
+ * GetCharRect() findet die Characterzelle des Characters, dass
+ * durch aPos beschrieben wird. GetCrsrOfst() findet den
+ * umgekehrten Weg: Von einer Dokumentkoordinate zu einem Pam.
+ * Beide sind virtuell in der Framebasisklasse und werden deshalb
+ * immer angezogen.
+ */
+
+sal_Bool SwTxtFrm::GetCharRect( SwRect& rOrig, const SwPosition &rPos,
+ SwCrsrMoveState *pCMS ) const
+{
+ if( IsLocked() || IsHiddenNow() )
+ return sal_False;
+
+ //Erstmal den richtigen Frm finden, dabei muss beachtet werden, dass:
+ //- die gecachten Informationen verworfen sein koennen (GetPara() == 0)
+ //- das ein Follow gemeint sein kann
+ //- das die Kette der Follows dynamisch waechst; der in den wir
+ // schliesslich gelangen muss aber Formatiert sein.
+
+ // opt: reading ahead erspart uns ein GetAdjFrmAtPos
+ const sal_Bool bRightMargin = pCMS && ( MV_RIGHTMARGIN == pCMS->eState );
+ SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, rPos, bRightMargin );
+
+ pFrm->GetFormatted();
+ const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
+ SwTwips nUpperMaxY = pTmpFrm->Frm().Top() + pTmpFrm->Prt().Bottom();
+ SwTwips nMaxY = Min( pFrm->Frm().Top() + pFrm->Prt().Bottom(), nUpperMaxY );
+
+ if ( pFrm->IsEmpty() || !pFrm->Prt().Height() )
+ {
+ Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+ short nFirstOffset;
+ pTxtNd->GetFirstLineOfsWithNum( nFirstOffset );
+ if( nFirstOffset > 0 )
+ aPnt1.X() += nFirstOffset;
+ if( aPnt1.Y() > nMaxY )
+ aPnt1.Y() = nMaxY;
+ Point aPnt2( aPnt1.X(), aPnt1.Y() + pFrm->Prt().Height() );
+ if( aPnt2.Y() > nMaxY )
+ aPnt2.Y() = nMaxY;
+ rOrig = SwRect( aPnt1, aPnt2 );
+ if ( pCMS )
+ {
+ pCMS->aRealHeight.X() = 0;
+ pCMS->aRealHeight.Y() = rOrig.Height();
+ }
+ return sal_True;
+ }
+ else
+ {
+ if( !pFrm->HasPara() )
+ return sal_False;
+ sal_Bool bGoOn = sal_True;
+ sal_Bool bRet;
+ sal_Bool bPrvLine;
+ xub_StrLen nOffset = rPos.nContent.GetIndex();
+ xub_StrLen nNextOfst;
+ do
+ {
+ {
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+ nNextOfst = aLine.GetEnd();
+ // Siehe Kommentar in AdjustFrm
+ // 1170: das letzte Zeichen der Zeile mitnehmen?
+ bRet = bRightMargin ? aLine.GetEndCharRect( &rOrig, nOffset, pCMS, nMaxY )
+ : aLine.GetCharRect( &rOrig, nOffset, pCMS, nMaxY );
+ bPrvLine = pCMS && aLine.GetPrev() && !pFrm->GetNext();
+
+ }
+ if( pFrm->IsUndersized() && bPrvLine && rOrig.Bottom() == nUpperMaxY &&
+ pFrm->GetOfst() < nOffset && !pFrm->IsFollow() )
+ bGoOn = lcl_ChangeOffset( pFrm, nNextOfst );
+ else
+ bGoOn = sal_False;
+ } while ( bGoOn );
+ return bRet;
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::GetAutoPos()
+ *************************************************************************/
+
+/*
+ * GetAutoPos() findet die Characterzelle des Characters, dass
+ * durch aPos beschrieben wird und wird von autopositionierten Rahmen genutzt.
+ */
+
+sal_Bool SwTxtFrm::GetAutoPos( SwRect& rOrig, const SwPosition &rPos ) const
+{
+ if( IsHiddenNow() )
+ return sal_False;
+
+ xub_StrLen nOffset = rPos.nContent.GetIndex();
+ SwTxtFrm *pFrm = ((SwTxtFrm*)this)->GetFrmAtOfst( nOffset );
+
+ pFrm->GetFormatted();
+ const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper();
+ SwTwips nUpperMaxY = pTmpFrm->Frm().Top() + pTmpFrm->Prt().Bottom();
+ SwTwips nMaxY = Min( pFrm->Frm().Top() + pFrm->Prt().Bottom(), nUpperMaxY );
+
+ if ( pFrm->IsEmpty() || !pFrm->Prt().Height() )
+ {
+ Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+ if( aPnt1.Y() > nMaxY )
+ aPnt1.Y() = nMaxY;
+ Point aPnt2( aPnt1.X(), aPnt1.Y() + pFrm->Prt().Height() );
+ if( aPnt2.Y() > nMaxY )
+ aPnt2.Y() = nMaxY;
+ rOrig = SwRect( aPnt1, aPnt2 );
+ return sal_True;
+ }
+ else
+ {
+ if( !pFrm->HasPara() )
+ return sal_False;
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+ return aLine.GetCharRect( &rOrig, nOffset, NULL, nMaxY );
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::_GetCrsrOfst()
+ *************************************************************************/
+
+// Minimaler Abstand von nichtleeren Zeilen etwas weniger als 2 cm
+#define FILL_MIN_DIST 1100
+
+struct SwFillData
+{
+ SwRect aFrm;
+ const SwCrsrMoveState *pCMS;
+ SwPosition* pPos;
+ const Point& rPoint;
+ SwTwips nLineWidth;
+ sal_Bool bFirstLine : 1;
+ sal_Bool bInner : 1;
+ sal_Bool bColumn : 1;
+ sal_Bool bEmpty : 1;
+ SwFillData( const SwCrsrMoveState *pC, SwPosition* pP, const SwRect& rR,
+ const Point& rPt ) : aFrm( rR ), pCMS( pC ), pPos( pP ), rPoint( rPt ),
+ nLineWidth( 0 ), bFirstLine( sal_True ), bInner( sal_False ), bColumn( sal_False ),
+ bEmpty( sal_True ){}
+ const SwFillMode Mode() const { return pCMS->pFill->eMode; }
+ const long X() const { return rPoint.X(); }
+ const long Y() const { return rPoint.Y(); }
+ const long Left() const { return aFrm.Left(); }
+ const long Right() const { return aFrm.Right(); }
+ const long Bottom() const { return aFrm.Bottom(); }
+ SwFillCrsrPos &Fill() const { return *pCMS->pFill; }
+ void SetTab( MSHORT nNew ) { pCMS->pFill->nTabCnt = nNew; }
+ void SetSpace( MSHORT nNew ) { pCMS->pFill->nSpaceCnt = nNew; }
+ void SetOrient( const SwHoriOrient eNew ){ pCMS->pFill->eOrient = eNew; }
+};
+
+sal_Bool SwTxtFrm::_GetCrsrOfst(SwPosition* pPos, const Point& rPoint,
+ const sal_Bool bChgFrm, const SwCrsrMoveState* pCMS ) const
+{
+ // 8804: _GetCrsrOfst wird vom GetCrsrOfst und GetKeyCrsrOfst gerufen.
+ // In keinem Fall nur ein return sal_False.
+
+ if( IsLocked() || IsHiddenNow() )
+ return sal_False;
+
+ SwFillData *pFillData = ( pCMS && pCMS->pFill ) ?
+ new SwFillData( pCMS, pPos, Frm(), rPoint ) : NULL;
+
+ ((SwTxtFrm*)this)->GetFormatted();
+ if ( IsEmpty() )
+ {
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+ pPos->nNode = *pTxtNd;
+ pPos->nContent.Assign( pTxtNd, 0 );
+ if( pCMS && pCMS->bFieldInfo )
+ {
+ SwTwips nDiff = rPoint.X() - Frm().Left() - Prt().Left();
+ if( nDiff > 50 || nDiff < 0 )
+ ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
+ }
+ }
+ else
+ {
+ SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+ SwTxtCursor aLine( ((SwTxtFrm*)this), &aInf );
+
+ // Siehe Kommentar in AdjustFrm()
+ SwTwips nMaxY = Frm().Top() + Prt().Top() + Prt().Height();
+ aLine.TwipsToLine( rPoint.Y() );
+ while( aLine.Y() + aLine.GetLineHeight() > nMaxY )
+ {
+ DBG_LOOP;
+ if( !aLine.Prev() )
+ break;
+ }
+
+ xub_StrLen nOffset = aLine.GetCrsrOfst( pPos, rPoint, bChgFrm, pCMS );
+
+ if( pCMS && pCMS->eState == MV_NONE && aLine.GetEnd() == nOffset )
+ ((SwCrsrMoveState*)pCMS)->eState = MV_RIGHTMARGIN;
+
+ // 6776: pPos ist ein reiner IN-Parameter, der nicht ausgewertet werden darf.
+ // Das pIter->GetCrsrOfst returnt aus einer Verschachtelung mit STRING_LEN.
+ // Wenn SwTxtIter::GetCrsrOfst von sich aus weitere GetCrsrOfst
+ // ruft, so aendert sich nNode der Position. In solchen Faellen
+ // darf pPos nicht berechnet werden.
+ if( STRING_LEN != nOffset )
+ {
+#ifdef USED
+ // 8626: bei Up/Down darf diese Zeile nicht verlassen werden.
+ if( pCMS && MV_UPDOWN == pCMS->eState )
+ {
+ const xub_StrLen nEnd = aLine.GetEnd();
+ if( nOffset >= nEnd && nEnd )
+ {
+ // Man muss hinter das letzte Zeichen kommen duerfen?!
+ nOffset = nEnd - 1; // UnitUp-Korrektur
+ }
+ else
+ if( nOffset < aLine.GetStart() )
+ nOffset = aLine.GetStart(); // UnitDown-Korrektur
+ }
+#endif
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode();
+ pPos->nNode = *pTxtNd;
+ pPos->nContent.Assign( pTxtNd, nOffset );
+ if( pFillData )
+ {
+ if( pTxtNd->GetTxt().Len() > nOffset ||
+ rPoint.Y() < Frm().Top() )
+ pFillData->bInner = sal_True;
+ pFillData->bFirstLine = aLine.GetLineNr() < 2;
+ if( pTxtNd->GetTxt().Len() )
+ {
+ pFillData->bEmpty = sal_False;
+ pFillData->nLineWidth = aLine.GetCurr()->Width();
+ }
+ }
+
+ }
+ }
+ if( pFillData && FindPageFrm()->Frm().IsInside( rPoint ) )
+ FillCrsrPos( *pFillData );
+ return sal_True;
+}
+
+/*************************************************************************
+ * virtual SwTxtFrm::GetCrsrOfst()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& rPoint,
+ const SwCrsrMoveState* pCMS ) const
+{
+ MSHORT nChgFrm = 2;
+ if( pCMS )
+ {
+ if( MV_UPDOWN == pCMS->eState )
+ nChgFrm = 0;
+ else if( MV_SETONLYTEXT == pCMS->eState ||
+ MV_TBLSEL == pCMS->eState )
+ nChgFrm = 1;
+ }
+ return _GetCrsrOfst( pPos, rPoint, nChgFrm, pCMS );
+}
+
+/*************************************************************************
+ * SwTxtFrm::LeftMargin()
+ *************************************************************************/
+
+/*
+ * Layout-orientierte Cursorbewegungen
+ */
+
+/*
+ * an den Zeilenanfang
+ */
+
+sal_Bool SwTxtFrm::LeftMargin(SwPaM *pPam) const
+{
+ if( ((const SwNode*)pPam->GetNode()) != GetNode() )
+ pPam->pPoint->nNode = *((SwTxtFrm*)this)->GetTxtNode();
+
+ SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->pPoint),
+ SwTxtCursor::IsRightMargin() );
+ pFrm->GetFormatted();
+ xub_StrLen nIndx;
+ if ( pFrm->IsEmpty() )
+ nIndx = 0;
+ else
+ {
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+
+ aLine.CharCrsrToLine(pPam->pPoint->nContent.GetIndex());
+ nIndx = aLine.GetStart();
+ if( pFrm->GetOfst() && !pFrm->IsFollow() && !aLine.GetPrev() )
+ {
+ lcl_ChangeOffset( pFrm, 0 );
+ nIndx = 0;
+ }
+ }
+ pPam->pPoint->nContent = SwIndex( pFrm->GetTxtNode(), nIndx );
+ SwTxtCursor::SetRightMargin( sal_False );
+ return sal_True;
+}
+
+/*************************************************************************
+ * SwTxtFrm::RightMargin()
+ *************************************************************************/
+
+/*
+ * An das Zeilenende:Das ist die Position vor dem letzten
+ * Character in der Zeile. Ausnahme: In der letzten Zeile soll
+ * der Cursor auch hinter dem letzten Character stehen koennen,
+ * um Text anhaengen zu koennen.
+ *
+ */
+
+sal_Bool SwTxtFrm::RightMargin(SwPaM *pPam, sal_Bool bAPI) const
+{
+ if( ((const SwNode*)pPam->GetNode()) != GetNode() )
+ pPam->pPoint->nNode = *((SwTxtFrm*)this)->GetTxtNode();
+
+ SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->pPoint),
+ SwTxtCursor::IsRightMargin() );
+ pFrm->GetFormatted();
+ xub_StrLen nRightMargin;
+ if ( IsEmpty() )
+ nRightMargin = 0;
+ else
+ {
+ SwTxtSizeInfo aInf( pFrm );
+ SwTxtCursor aLine( pFrm, &aInf );
+
+ aLine.CharCrsrToLine(pPam->pPoint->nContent.GetIndex());
+ nRightMargin = aLine.GetStart() + aLine.GetCurr()->GetLen();
+
+ // Harte Zeilenumbrueche lassen wir hinter uns.
+ if( aLine.GetCurr()->GetLen() &&
+ CH_BREAK == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
+ --nRightMargin;
+ if( !bAPI && (aLine.GetNext() || pFrm->GetFollow()) )
+ {
+ while( nRightMargin > aLine.GetStart() &&
+ ' ' == aInf.GetTxt().GetChar( nRightMargin - 1 ) )
+ --nRightMargin;
+ }
+ }
+ pPam->pPoint->nContent = SwIndex( pFrm->GetTxtNode(), nRightMargin );
+ SwTxtCursor::SetRightMargin( !bAPI );
+ return sal_True;
+}
+
+/*************************************************************************
+ * SwTxtFrm::_UnitUp()
+ *************************************************************************/
+
+//Die beiden folgenden Methoden versuchen zunaechst den Crsr in die
+//nachste/folgende Zeile zu setzen. Gibt es im Frame keine vorhergehende/
+//folgende Zeile, so wird der Aufruf an die Basisklasse weitergeleitet.
+//Die Horizontale Ausrichtung des Crsr wird hinterher von der CrsrShell
+//vorgenommen.
+
+class SwSetToRightMargin
+{
+ sal_Bool bRight;
+public:
+ inline SwSetToRightMargin() : bRight( sal_False ) { }
+ inline ~SwSetToRightMargin() { SwTxtCursor::SetRightMargin( bRight ); }
+ inline void SetRight( const sal_Bool bNew ) { bRight = bNew; }
+};
+
+sal_Bool SwTxtFrm::_UnitUp( SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+ // 8626: Im Notfall den RightMargin setzen.
+ SwSetToRightMargin aSet;
+
+ if( IsInTab() &&
+ pPam->GetNode( sal_True )->StartOfSectionNode() !=
+ pPam->GetNode( sal_False )->StartOfSectionNode() )
+ {
+ //Wenn der PaM in unterschiedlichen Boxen sitzt, so handelt es sich um
+ //eine Tabellenselektion; diese wird von der Basisklasse abgearbeitet.
+ return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+ }
+
+ ((SwTxtFrm*)this)->GetFormatted();
+ const xub_StrLen nPos = pPam->pPoint->nContent.GetIndex();
+ SwRect aCharBox;
+
+ if( !IsEmpty() && !IsHiddenNow() )
+ {
+ xub_StrLen nFormat = STRING_LEN;
+ do
+ {
+ if( nFormat != STRING_LEN && !IsFollow() )
+ lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat );
+
+ SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+ SwTxtCursor aLine( ((SwTxtFrm*)this), &aInf );
+
+ // 8116: Flys ohne Umlauf und IsDummy(); hier wegoptimiert
+ if( nPos )
+ aLine.CharCrsrToLine( nPos );
+ else
+ aLine.Top();
+
+ const SwLineLayout *pPrevLine = aLine.GetPrevLine();
+ if( !pPrevLine && GetOfst() && !IsFollow() )
+ {
+ nFormat = GetOfst();
+ xub_StrLen nDiff = aLine.GetLength();
+ if( !nDiff )
+ nDiff = MIN_OFFSET_STEP;
+ if( nFormat > nDiff )
+ nFormat -= nDiff;
+ else
+ nFormat = 0;
+ continue;
+ }
+ if( pPrevLine && pPrevLine != aLine.GetCurr() )
+ {
+ const xub_StrLen nStart = aLine.GetStart();
+ SwRect aCharBox;
+ aLine.GetCharRect( &aCharBox, nPos );
+ aLine.PrevLine();
+ while ( aLine.GetStart() == nStart &&
+ 0 != ( pPrevLine = aLine.GetPrevLine() ) &&
+ pPrevLine != aLine.GetCurr() )
+ aLine.PrevLine();
+ aCharBox.SSize().Width() /= 2;
+
+ // siehe Kommentar in SwTxtFrm::GetCrsrOfst()
+#ifndef PRODUCT
+ const xub_StrLen nOldNode = pPam->pPoint->nNode.GetIndex();
+#endif
+ // Der Node soll nicht gewechselt werden
+ xub_StrLen nOfst = aLine.GetCrsrOfst( pPam->pPoint,
+ aCharBox.Pos(), sal_False );
+ ASSERT( nOldNode == pPam->pPoint->nNode.GetIndex(),
+ "SwTxtFrm::UnitUp: illegal node change" )
+
+ // 7684: Wir stellen sicher, dass wir uns nach oben bewegen.
+ if( nOfst >= nStart && nStart )
+ {
+ // nOfst = nStart - 1;
+ nOfst = nStart;
+ aSet.SetRight( sal_True );
+ }
+ pPam->pPoint->nContent =
+ SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nOfst );
+ return sal_True;
+ }
+ if ( IsFollow() )
+ {
+ aLine.GetCharRect( &aCharBox, nPos );
+ aCharBox.SSize().Width() /= 2;
+ }
+ break;
+ } while ( sal_True );
+ }
+ /* Wenn this ein Follow ist und ein Prev miszlang, so
+ * muessen wir in die letzte Zeile des Master ... und der sind wir.
+ * Oder wir sind ein Follow mit Follow, dann muessen wir uns den
+ * Master extra besorgen...
+ */
+ if ( IsFollow() )
+ {
+ const SwTxtFrm *pPrev = FindMaster();
+ xub_StrLen nOffs = GetOfst();
+ if( pPrev )
+ {
+ ViewShell *pSh = GetShell();
+ sal_Bool bProtectedAllowed = pSh && pSh->GetViewOptions()->IsCursorInProtectedArea();
+ const SwTxtFrm *pPrevPrev = pPrev;
+ // Hier werden geschuetzte Frames und Frame ohne Inhalt ausgelassen
+ while( pPrevPrev && ( pPrevPrev->GetOfst() == nOffs ||
+ ( !bProtectedAllowed && pPrevPrev->IsProtected() ) ) )
+ {
+ pPrev = pPrevPrev;
+ nOffs = pPrev->GetOfst();
+ if ( pPrevPrev->IsFollow() )
+ pPrevPrev = pPrev->FindMaster();
+ else
+ pPrevPrev = NULL;
+ }
+ if ( !pPrevPrev )
+ return pPrev->SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+ aCharBox.Pos().Y() = pPrevPrev->Frm().Bottom() - 1;
+ return pPrevPrev->GetKeyCrsrOfst( pPam->pPoint, aCharBox.Pos() );
+ }
+ }
+ return SwCntntFrm::UnitUp( pPam, nOffset, bSetInReadOnly );
+}
+
+/*************************************************************************
+ * SwTxtFrm::_UnitDown()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::_UnitDown(SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+
+ if ( IsInTab() &&
+ pPam->GetNode( sal_True )->StartOfSectionNode() !=
+ pPam->GetNode( sal_False )->StartOfSectionNode() )
+ {
+ //Wenn der PaM in unterschiedlichen Boxen sitzt, so handelt es sich um
+ //eine Tabellenselektion; diese wird von der Basisklasse abgearbeitet.
+ return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+ }
+ ((SwTxtFrm*)this)->GetFormatted();
+ const xub_StrLen nPos = pPam->pPoint->nContent.GetIndex();
+ SwRect aCharBox;
+ const SwCntntFrm *pFollow;
+ if ( !IsEmpty() && !IsHiddenNow() )
+ {
+ xub_StrLen nFormat = STRING_LEN;
+ do
+ {
+ if( nFormat != STRING_LEN && !IsFollow() &&
+ !lcl_ChangeOffset( ((SwTxtFrm*)this), nFormat ) )
+ break;
+
+ SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+ SwTxtCursor aLine( ((SwTxtFrm*)this), &aInf );
+ nFormat = aLine.GetEnd();
+
+ aLine.CharCrsrToLine( nPos );
+ if( aLine.GetNextLine() )
+ {
+ const xub_StrLen nStart = aLine.GetStart();
+ SwRect aCharBox;
+ aLine.GetCharRect( &aCharBox, nPos );
+ aLine.NextLine();
+ aCharBox.SSize().Width() /= 2;
+#ifndef PRODUCT
+ // siehe Kommentar in SwTxtFrm::GetCrsrOfst()
+ const xub_StrLen nOldNode = pPam->pPoint->nNode.GetIndex();
+#endif
+ xub_StrLen nOfst = aLine.GetCrsrOfst( pPam->pPoint,
+ aCharBox.Pos(), sal_False );
+ ASSERT( nOldNode == pPam->pPoint->nNode.GetIndex(),
+ "SwTxtFrm::UnitDown: illegal node change" )
+
+ // 7684: Wir stellen sicher, dass wir uns nach unten bewegen.
+ if( nOfst <= nStart )
+ nOfst = nStart + 1;
+ pPam->pPoint->nContent =
+ SwIndex( ((SwTxtFrm*)this)->GetTxtNode(), nOfst );
+ return sal_True;
+ }
+ if( 0 != ( pFollow = GetFollow() ) )
+ { // geschuetzte Follows auslassen
+ const SwCntntFrm* pTmp = pFollow;
+ ViewShell *pSh = GetShell();
+ if( !pSh || !pSh->GetViewOptions()->IsCursorInProtectedArea() )
+ {
+ while( pFollow && pFollow->IsProtected() )
+ {
+ pTmp = pFollow;
+ pFollow = pFollow->GetFollow();
+ }
+ }
+ if( !pFollow ) // nur noch geschuetzte
+ return pTmp->SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+ aLine.GetCharRect( &aCharBox, nPos );
+ aCharBox.SSize().Width() /= 2;
+ }
+ else if( !IsFollow() )
+ {
+ xub_StrLen nTmpLen = aInf.GetTxt().Len();
+ if( aLine.GetEnd() < nTmpLen )
+ {
+ if( nFormat <= GetOfst() )
+ {
+ nFormat = Min( xub_StrLen( GetOfst() + MIN_OFFSET_STEP ),
+ nTmpLen );
+ if( nFormat <= GetOfst() )
+ break;
+ }
+ continue;
+ }
+ }
+ break;
+ } while( sal_True );
+ }
+ else
+ pFollow = GetFollow();
+
+ // Bei Follows schlagen wir eine Abkuerzung
+ if( pFollow )
+ {
+ aCharBox.Pos().Y() = pFollow->Frm().Top() + 1;
+ return ((SwTxtFrm*)pFollow)->GetKeyCrsrOfst( pPam->pPoint,
+ aCharBox.Pos() );
+ }
+ return SwCntntFrm::UnitDown( pPam, nOffset, bSetInReadOnly );
+}
+
+/*************************************************************************
+ * virtual SwTxtFrm::UnitUp()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::UnitUp(SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+ /* Im CrsrSh::Up() wird CntntNode::GetFrm() gerufen.
+ * Dies liefert _immer_ den Master zurueck.
+ * Um das Cursortravelling nicht zu belasten, korrigieren wir
+ * hier im SwTxtFrm.
+ * Wir ermittelt UnitUp fuer pFrm, pFrm ist entweder ein Master (=this)
+ * oder ein Follow (!=this)
+ */
+ const SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, *(pPam->GetPoint()),
+ SwTxtCursor::IsRightMargin() );
+ const sal_Bool bRet = pFrm->_UnitUp( pPam, nOffset, bSetInReadOnly );
+
+ // 8626: kein SwTxtCursor::SetRightMargin( sal_False );
+ // statt dessen steht ein SwSetToRightMargin im _UnitUp
+ return bRet;
+}
+
+/*************************************************************************
+ * virtual SwTxtFrm::UnitDown()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::UnitDown(SwPaM *pPam, const SwTwips nOffset,
+ sal_Bool bSetInReadOnly ) const
+{
+ const SwTxtFrm *pFrm = GetAdjFrmAtPos((SwTxtFrm*)this, *(pPam->GetPoint()),
+ SwTxtCursor::IsRightMargin() );
+ const sal_Bool bRet = pFrm->_UnitDown( pPam, nOffset, bSetInReadOnly );
+ SwTxtCursor::SetRightMargin( sal_False );
+ return bRet;
+}
+
+void SwTxtFrm::FillCrsrPos( SwFillData& rFill ) const
+{
+ if( !rFill.bColumn && GetUpper()->IsColBodyFrm() ) // ColumnFrms jetzt mit BodyFrm
+ {
+ const SwColumnFrm* pTmp =
+ (SwColumnFrm*)GetUpper()->GetUpper()->GetUpper()->Lower(); // die 1. Spalte
+ // der erste SwFrm im BodyFrm der ersten Spalte
+ const SwFrm* pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
+ MSHORT nNextCol = 0;
+ // In welcher Spalte landen wir?
+ while( rFill.X() > pTmp->Frm().Right() && pTmp->GetNext() )
+ {
+ pTmp = (SwColumnFrm*)pTmp->GetNext();
+ if( ((SwLayoutFrm*)pTmp->Lower())->Lower() ) // ColumnFrms jetzt mit BodyFrm
+ {
+ pFrm = ((SwLayoutFrm*)pTmp->Lower())->Lower();
+ nNextCol = 0;
+ }
+ else
+ ++nNextCol; // leere Spalten erfordern Spaltenumbrueche
+ }
+ if( pTmp != GetUpper()->GetUpper() ) // Sind wir in einer anderen Spalte gelandet?
+ {
+ if( !pFrm )
+ return;
+ if( nNextCol )
+ {
+ while( pFrm->GetNext() )
+ pFrm = pFrm->GetNext();
+ }
+ else
+ {
+ while( pFrm->GetNext() && pFrm->Frm().Bottom() < rFill.Y() )
+ pFrm = pFrm->GetNext();
+ }
+ // Kein Fuellen, wenn als letzter Frame in der anvisierten
+ // Spalte kein Absatz, sondern z.B. eine Tabelle steht
+ if( pFrm->IsTxtFrm() )
+ {
+ rFill.Fill().nColumnCnt = nNextCol;
+ rFill.bColumn = sal_True;
+ if( rFill.pPos )
+ {
+ SwTxtNode* pTxtNd = ((SwTxtFrm*)pFrm)->GetTxtNode();
+ rFill.pPos->nNode = *pTxtNd;
+ rFill.pPos->nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
+ }
+ if( nNextCol )
+ {
+ rFill.aFrm = pTmp->Prt();
+ rFill.aFrm += pTmp->Frm().Pos();
+ }
+ else
+ rFill.aFrm = pFrm->Frm();
+ ((SwTxtFrm*)pFrm)->FillCrsrPos( rFill );
+ }
+ return;
+ }
+ }
+ sal_Bool bFill = sal_True;
+ SwFont *pFnt;
+ SwTxtFmtColl* pColl = GetTxtNode()->GetTxtColl();
+ MSHORT nFirst = GetTxtNode()->GetSwAttrSet().GetULSpace().GetLower();
+ SwTwips nDiff = rFill.Y() - Frm().Bottom();
+ if( nDiff < nFirst )
+ nDiff = -1;
+ else
+ pColl = &pColl->GetNextTxtFmtColl();
+ SwAttrSet aSet( ((SwDoc*)GetTxtNode()->GetDoc())->GetAttrPool(), aTxtFmtCollSetRange );
+ const SwAttrSet* pSet = &pColl->GetAttrSet();
+ ViewShell *pSh = GetShell();
+ if( GetTxtNode()->HasSwAttrSet() )
+ {
+ aSet.Put( *GetTxtNode()->GetpSwAttrSet() );
+ aSet.SetParent( pSet );
+ pSet = &aSet;
+ pFnt = new SwFont( pSet );
+ }
+ else
+ {
+ SwFontAccess aFontAccess( pColl, pSh );
+ pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
+ pFnt->ChkMagic( pSh, pFnt->GetActual() );
+ }
+ OutputDevice *pOut = pSh->GetOut();
+ if ( !GetTxtNode()->GetDoc()->IsBrowseMode() ||
+ ( pSh->GetViewOptions()->IsPrtFormat() ) )
+ {
+ Printer *pPrt = GetTxtNode()->GetDoc()->GetPrt();
+ if ( pPrt && pPrt->IsValid() )
+ pOut = pPrt;
+ }
+ pFnt->SetFntChg( sal_True );
+ pFnt->ChgPhysFnt( pSh, pOut );
+
+ SwTwips nLineHeight = pFnt->GetHeight( pSh, pOut );
+
+ if( nLineHeight )
+ {
+ const SvxULSpaceItem &rUL = pSet->GetULSpace();
+ SwTwips nDist = Max( rUL.GetLower(), rUL.GetUpper() );
+ if( rFill.Fill().nColumnCnt )
+ {
+ rFill.aFrm.Height( nLineHeight );
+ nDiff = rFill.Y() - rFill.Bottom();
+ nFirst = 0;
+ }
+ else if( nDist < nFirst )
+ nFirst -= nDist;
+ else
+ nFirst = 0;
+ nDist = Max( nDist, long( GetLineSpace() ) );
+ nDist += nLineHeight;
+ nDiff -= nFirst;
+
+ if( nDiff > 0 )
+ {
+ nDiff /= nDist;
+ rFill.Fill().nParaCnt = nDiff + 1;
+ rFill.nLineWidth = 0;
+ rFill.bInner = sal_False;
+ rFill.bEmpty = sal_True;
+ rFill.SetOrient( HORI_LEFT );
+ }
+ else
+ nDiff = -1;
+ if( rFill.bInner )
+ bFill = sal_False;
+ else
+ {
+ const SvxTabStopItem &rRuler = pSet->GetTabStops();
+ const SvxLRSpaceItem &rLRSpace = pSet->GetLRSpace();
+
+ SwRect &rRect = rFill.Fill().aCrsr;
+ rRect.Top( rFill.Bottom() + (nDiff+1) * nDist - nLineHeight );
+ if( nFirst && nDiff > -1 )
+ rRect.Top( rRect.Top() + nFirst );
+ rRect.Height( nLineHeight );
+ SwTwips nLeft = rFill.Left() + rLRSpace.GetLeft() +
+ GetTxtNode()->GetLeftMarginWithNum( sal_False );
+ SwTwips nRight = rFill.Right() - rLRSpace.GetRight();
+ SwTwips nCenter = ( nLeft + nRight ) / 2;
+ rRect.Left( nLeft );
+ if( FILL_MARGIN == rFill.Mode() )
+ {
+ if( rFill.bEmpty )
+ {
+ rFill.SetOrient( HORI_LEFT );
+ if( rFill.X() < nCenter )
+ {
+ if( rFill.X() > ( nLeft + 2 * nCenter ) / 3 )
+ {
+ rFill.SetOrient( HORI_CENTER );
+ rRect.Left( nCenter );
+ }
+ }
+ else if( rFill.X() > ( nRight + 2 * nCenter ) / 3 )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ }
+ else
+ {
+ rFill.SetOrient( HORI_CENTER );
+ rRect.Left( nCenter );
+ }
+ }
+ else
+ bFill = sal_False;
+ }
+ else
+ {
+ SwTwips nSpace;
+ if( FILL_TAB != rFill.Mode() )
+ {
+static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
+ const XubString aTmp( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
+ nSpace = pFnt->_GetTxtSize( pSh, pOut, aTmp, 0, 2 ).Width()/2;
+ }
+ if( rFill.X() >= nRight )
+ {
+ if( FILL_INDENT != rFill.Mode() && ( rFill.bEmpty ||
+ rFill.X() > rFill.nLineWidth + FILL_MIN_DIST ) )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ }
+ else
+ bFill = sal_False;
+ }
+ else if( FILL_INDENT == rFill.Mode() )
+ {
+ SwTwips nIndent = rFill.X();
+ if( !rFill.bEmpty || nIndent > nRight )
+ bFill = sal_False;
+ else
+ {
+ nIndent -= rFill.Left();
+ if( nIndent >= 0 && nSpace )
+ {
+ nIndent /= nSpace;
+ nIndent *= nSpace;
+ rFill.SetTab( MSHORT( nIndent ) );
+ rRect.Left( nIndent + rFill.Left() );
+ }
+ else
+ bFill = sal_False;
+ }
+ }
+ else if( rFill.X() > nLeft )
+ {
+ SwTwips nTxtLeft = rFill.Left() + rLRSpace.GetTxtLeft() +
+ GetTxtNode()->GetLeftMarginWithNum( sal_True );
+ rFill.nLineWidth += rFill.bFirstLine ? nLeft : nTxtLeft;
+ SwTwips nLeftTab = nLeft;
+ SwTwips nRightTab = nLeft;
+ MSHORT nSpaceCnt = 0;
+ MSHORT nTabCnt = 0;
+ MSHORT nIdx = 0;
+ do
+ {
+ nLeftTab = nRightTab;
+ if( nIdx < rRuler.Count() )
+ {
+ const SvxTabStop &rTabStop = rRuler.operator[](nIdx);
+ nRightTab = nTxtLeft + rTabStop.GetTabPos();
+ if( nLeftTab < nTxtLeft && nRightTab > nTxtLeft )
+ nRightTab = nTxtLeft;
+ else
+ ++nIdx;
+ if( nRightTab > rFill.nLineWidth )
+ ++nTabCnt;
+ }
+ else
+ {
+ const SvxTabStopItem& rTab =
+ (const SvxTabStopItem &)pSet->
+ GetPool()->GetDefaultItem( RES_PARATR_TABSTOP );
+ MSHORT nDefTabDist = (MSHORT)rTab.GetStart()->GetTabPos();
+ nRightTab = nLeftTab - nTxtLeft;
+ nRightTab /= nDefTabDist;
+ nRightTab = nRightTab * nDefTabDist + nTxtLeft;
+ while ( nRightTab <= nLeftTab )
+ nRightTab += nDefTabDist;
+ if( nRightTab > rFill.nLineWidth )
+ ++nTabCnt;
+ while ( nRightTab < rFill.X() )
+ {
+ nRightTab += nDefTabDist;
+ if( nRightTab > rFill.nLineWidth )
+ ++nTabCnt;
+ }
+ if( nLeftTab < nRightTab - nDefTabDist )
+ nLeftTab = nRightTab - nDefTabDist;
+ }
+ if( nRightTab > nRight )
+ nRightTab = nRight;
+ }
+ while( rFill.X() > nRightTab );
+ --nTabCnt;
+ if( FILL_TAB != rFill.Mode() )
+ {
+ if( nSpace > 0 )
+ {
+ if( !nTabCnt )
+ nLeftTab = rFill.nLineWidth;
+ while( nLeftTab < rFill.X() )
+ {
+ nLeftTab += nSpace;
+ ++nSpaceCnt;
+ }
+ if( nSpaceCnt )
+ {
+ nLeftTab -= nSpace;
+ --nSpaceCnt;
+ }
+ if( rFill.X() - nLeftTab > nRightTab - rFill.X() )
+ {
+ nSpaceCnt = 0;
+ ++nTabCnt;
+ rRect.Left( nRightTab );
+ }
+ else
+ {
+ if( rFill.X() - nLeftTab > nSpace/2 )
+ {
+ ++nSpaceCnt;
+ rRect.Left( nLeftTab + nSpace );
+ }
+ else
+ rRect.Left( nLeftTab );
+ }
+ }
+ else if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
+ rRect.Left( nLeftTab );
+ else
+ {
+ if( nRightTab >= nRight )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ nTabCnt = 0;
+ nSpaceCnt = 0;
+ }
+ else
+ {
+ rRect.Left( nRightTab );
+ ++nTabCnt;
+ }
+ }
+ }
+ else
+ {
+ if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
+ rRect.Left( nLeftTab );
+ else
+ {
+ if( nRightTab >= nRight )
+ {
+ rFill.SetOrient( HORI_RIGHT );
+ rRect.Left( nRight );
+ nTabCnt = 0;
+ nSpaceCnt = 0;
+ }
+ else
+ {
+ rRect.Left( nRightTab );
+ ++nTabCnt;
+ }
+ }
+ }
+ rFill.SetTab( nTabCnt );
+ rFill.SetSpace( nSpaceCnt );
+ if( bFill )
+ {
+ if( Abs( rFill.X() - nCenter ) <=
+ Abs( rFill.X() - rRect.Left() ) )
+ {
+ rFill.SetOrient( HORI_CENTER );
+ rFill.SetTab( 0 );
+ rFill.SetSpace( 0 );
+ rRect.Left( nCenter );
+ }
+ if( !rFill.bEmpty )
+ rFill.nLineWidth += FILL_MIN_DIST;
+ if( rRect.Left() < rFill.nLineWidth )
+ bFill = sal_False;
+ }
+ }
+ }
+ // Gehen wir ueber die Unterkante der Seite/Spalte etc. hinaus?
+ const SwFrm* pUp = GetUpper();
+ if( pUp->IsInSct() )
+ {
+ if( pUp->IsSctFrm() )
+ pUp = pUp->GetUpper();
+ else if( pUp->IsColBodyFrm() &&
+ pUp->GetUpper()->GetUpper()->IsSctFrm() )
+ pUp = pUp->GetUpper()->GetUpper()->GetUpper();
+ }
+ if( pUp->Frm().Top() + pUp->Prt().Bottom() < rRect.Bottom() )
+ bFill = sal_False;
+ else
+ rRect.Width( 1 );
+ }
+ }
+ else
+ bFill = sal_False;
+ ((SwCrsrMoveState*)rFill.pCMS)->bFillRet = bFill;
+ delete pFnt;
+}
+
+
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
new file mode 100644
index 000000000000..14d9fcb1e7b1
--- /dev/null
+++ b/sw/source/core/text/frmform.cxx
@@ -0,0 +1,1919 @@
+/*************************************************************************
+ *
+ * $RCSfile: frmform.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _SVX_KEEPITEM_HXX //autogen
+#include <svx/keepitem.hxx>
+#endif
+#ifndef _SVX_HYZNITEM_HXX //autogen
+#include <svx/hyznitem.hxx>
+#endif
+
+#ifndef _PAGEFRM_HXX
+#include <pagefrm.hxx> // ChangeFtnRef
+#endif
+#ifndef _NDTXT_HXX
+#include <ndtxt.hxx> // MakeFrm()
+#endif
+#ifndef _DCONTACT_HXX
+#include <dcontact.hxx> // SwDrawContact
+#endif
+#ifndef _DFLYOBJ_HXX
+#include <dflyobj.hxx> // SwVirtFlyDrawObj
+#endif
+#ifndef _FLYFRM_HXX
+#include <flyfrm.hxx>
+#endif
+#ifndef _FTNFRM_HXX
+#include <ftnfrm.hxx> // SwFtnFrm
+#endif
+#ifndef _TXTFTN_HXX
+#include <txtftn.hxx>
+#endif
+#ifndef _FMTFTN_HXX
+#include <fmtftn.hxx>
+#endif
+#ifndef _PARATR_HXX
+#include <paratr.hxx>
+#endif
+#ifndef _VIEWOPT_HXX
+#include <viewopt.hxx> // SwViewOptions
+#endif
+#ifndef _VIEWSH_HXX
+#include <viewsh.hxx> // ViewShell
+#endif
+#ifndef _FRMATR_HXX
+#include <frmatr.hxx>
+#endif
+#ifndef _FLYFRMS_HXX
+#include <flyfrms.hxx>
+#endif
+#ifndef _FRMSH_HXX
+#include <frmsh.hxx>
+#endif
+#ifndef _TXATBASE_HXX
+#include <txatbase.hxx>
+#endif
+#ifndef _TXTCFG_HXX
+#include <txtcfg.hxx>
+#endif
+#ifndef _ITRFORM2_HXX
+#include <itrform2.hxx> // SwTxtFormatter
+#endif
+#ifndef _TXTFRM_HXX
+#include <txtfrm.hxx> // SwTxtFrm
+#endif
+#ifndef _WIDORP_HXX
+#include <widorp.hxx> // Widows and Orphans
+#endif
+#ifndef _TXTCACHE_HXX
+#include <txtcache.hxx>
+#endif
+#ifndef _PORRST_HXX
+#include <porrst.hxx> // SwEmptyPortion
+#endif
+#ifndef _BLINK_HXX
+#include <blink.hxx> // pBlink
+#endif
+#ifndef _PORFLD_HXX
+#include <porfld.hxx> // SwFldPortion
+#endif
+#ifndef _SECTFRM_HXX
+#include <sectfrm.hxx> // SwSectionFrm
+#endif
+
+#ifndef PRODUCT
+#ifndef _FRMFMT_HXX
+#include <frmfmt.hxx> // SwFrmFmt
+#endif
+#endif
+
+extern FASTBOOL IsInProgress( const SwFlyFrm *pFly );
+
+class FormatLevel
+{
+ static MSHORT nLevel;
+public:
+ inline FormatLevel() { ++nLevel; }
+ inline ~FormatLevel() { --nLevel; }
+ inline MSHORT GetLevel() const { return nLevel; }
+ static sal_Bool LastLevel() { return 10 < nLevel; }
+};
+MSHORT FormatLevel::nLevel = 0;
+
+/*************************************************************************
+ * ValidateTxt/Frm()
+ *************************************************************************/
+
+void ValidateTxt( SwFrm *pFrm ) // Freund vom Frame
+{
+ if ( pFrm->Frm().Width() == pFrm->GetUpper()->Prt().Width() )
+ pFrm->bValidSize = sal_True;
+/*
+ pFrm->bValidPrtArea = sal_True;
+ //Die Position validieren um nicht unnoetige (Test-)Moves zu provozieren.
+ //Dabei darf allerdings nicht eine tatsaechlich falsche Coordinate
+ //validiert werden.
+ if ( !pFrm->bValidPos )
+ {
+ //Leider muessen wir dazu die korrekte Position berechnen.
+ Point aOld( pFrm->Frm().Pos() );
+ pFrm->MakePos();
+ if ( aOld != pFrm->Pos() )
+ {
+ pFrm->Frm().Pos( aOld );
+ pFrm->bValidPos = sal_False;
+ }
+ }
+*/
+}
+
+void SwTxtFrm::ValidateFrm()
+{
+ // Umgebung validieren, um Oszillationen zu verhindern.
+
+ if ( !IsInFly() )
+ { //Innerhalb eines Flys nur this validieren, der Rest sollte eigentlich
+ //nur fuer Fussnoten notwendig sein und die gibt es innerhalb von
+ //Flys nicht. Fix fuer 5544
+ SwSectionFrm* pSct = FindSctFrm();
+ if( pSct )
+ {
+ if( !pSct->IsColLocked() )
+ pSct->ColLock();
+ else
+ pSct = NULL;
+ }
+
+ SwFrm *pUp = GetUpper();
+ pUp->Calc();
+ if( pSct )
+ pSct->ColUnlock();
+ }
+ ValidateTxt( this );
+
+ //MA: mindestens das MustFit-Flag muessen wir retten!
+ ASSERT( HasPara(), "ResetPreps(), missing ParaPortion." );
+ SwParaPortion *pPara = GetPara();
+ const sal_Bool bMustFit = pPara->IsPrepMustFit();
+ ResetPreps();
+ pPara->SetPrepMustFit( bMustFit );
+}
+
+/*************************************************************************
+ * ValidateBodyFrm()
+ *************************************************************************/
+
+// nach einem RemoveFtn muss der BodyFrm und alle innenliegenden kalkuliert
+// werden, damit die DeadLine richtig sitzt.
+// Erst wird nach aussen hin gesucht, beim Rueckweg werden alle kalkuliert.
+
+void _ValidateBodyFrm( SwFrm *pFrm )
+{
+ if( pFrm )
+ {
+ if( !pFrm->IsBodyFrm() && pFrm->GetUpper() )
+ _ValidateBodyFrm( pFrm->GetUpper() );
+ if( !pFrm->IsSctFrm() )
+ pFrm->Calc();
+ else
+ {
+ sal_Bool bOld = ((SwSectionFrm*)pFrm)->IsCntntLocked();
+ ((SwSectionFrm*)pFrm)->SetCntntLock( sal_True );
+ pFrm->Calc();
+ if( !bOld )
+ ((SwSectionFrm*)pFrm)->SetCntntLock( sal_False );
+ }
+ }
+}
+
+void SwTxtFrm::ValidateBodyFrm()
+{
+ //siehe Kommtar in ValidateFrm()
+ if ( !IsInFly() && !( IsInSct() && FindSctFrm()->Lower()->IsColumnFrm() ) )
+ _ValidateBodyFrm( GetUpper() );
+}
+
+/*************************************************************************
+ * SwTxtFrm::FindBodyFrm()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::_GetDropRect( SwRect &rRect ) const
+{
+ ASSERT( HasPara(), "SwTxtFrm::_GetDropRect: try again next year." );
+ SwTxtSizeInfo aInf( (SwTxtFrm*)this );
+ SwTxtMargin aLine( (SwTxtFrm*)this, &aInf );
+ if( aLine.GetDropLines() )
+ {
+ rRect.Top( aLine.Y() );
+ rRect.Left( aLine.GetLineStart() );
+ rRect.Height( aLine.GetDropHeight() );
+ rRect.Width( aLine.GetDropLeft() );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+ * SwTxtFrm::FindBodyFrm()
+ *************************************************************************/
+
+const SwBodyFrm *SwTxtFrm::FindBodyFrm() const
+{
+ if ( IsInDocBody() )
+ {
+ const SwFrm *pFrm = GetUpper();
+ while( pFrm && !pFrm->IsBodyFrm() )
+ pFrm = pFrm->GetUpper();
+ return (const SwBodyFrm*)pFrm;
+ }
+ return 0;
+}
+
+/*************************************************************************
+ * SwTxtFrm::CalcFollow()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::CalcFollow( const xub_StrLen nTxtOfst )
+{
+ ASSERT( HasFollow(), "CalcFollow: missing Follow." );
+
+ SwTxtFrm *pFollow = GetFollow();
+
+ SwParaPortion *pPara = GetPara();
+ sal_Bool bFollowFld = pPara ? pPara->IsFollowField() : sal_False;
+
+ if( !pFollow->GetOfst() || pFollow->GetOfst() != nTxtOfst ||
+ bFollowFld || pFollow->IsFieldFollow() || !pFollow->Prt().Height() )
+ {
+#ifndef PRODUCT
+ const SwFrm *pOldUp = GetUpper();
+#endif
+
+ SwTwips nOldBottom = GetUpper()->Frm().Bottom();
+ SwTwips nMyPos = Frm().Top();
+
+ const SwPageFrm *pPage = 0;
+ sal_Bool bOldInvaCntnt,
+ bOldInvaLayout;
+ if ( !IsInFly() && GetNext() )
+ {
+ pPage = FindPageFrm();
+ //Minimieren - sprich ggf. zuruecksetzen - der Invalidierungen s.u.
+ bOldInvaCntnt = pPage->IsInvalidCntnt();
+ bOldInvaLayout = pPage->IsInvalidLayout();
+ }
+
+ pFollow->_SetOfst( nTxtOfst );
+ pFollow->SetFieldFollow( bFollowFld );
+ if( HasFtn() || pFollow->HasFtn() )
+ {
+ ValidateFrm();
+ ValidateBodyFrm();
+ if( pPara )
+ {
+ *(pPara->GetReformat()) = SwCharRange();
+ *(pPara->GetDelta()) = 0;
+ }
+ }
+
+ //Der Fussnotenbereich darf sich keinesfalls vergrossern.
+ SwSaveFtnHeight aSave( FindFtnBossFrm( sal_True ), LONG_MAX );
+
+ ((SwTxtFrm*)pFollow)->CalcFtnFlag();
+ if ( !pFollow->GetNext() && !pFollow->HasFtn() )
+ nOldBottom = LONG_MAX;
+
+ while( sal_True )
+ {
+ if( !FormatLevel::LastLevel() )
+ {
+ // Weenn der Follow in einem spaltigen Bereich oder einem
+ // spaltigen Rahmen steckt, muss zunaechst dieser kalkuliert
+ // werden, da das FormatWidthCols() nicht funktioniert, wenn
+ // es aus dem MakeAll des _gelockten_ Follows heraus gerufen
+ // wird.
+ SwSectionFrm* pSct = pFollow->FindSctFrm();
+ if( pSct && !pSct->IsAnLower( this ) )
+ {
+ if( pSct->GetFollow() )
+ pSct->SimpleFormat();
+ else if( !pSct->Frm().Height() )
+ break;
+ }
+ pFollow->Calc();
+
+ // Der Follow merkt anhand seiner Frm().Height(), dass was schief
+ // gelaufen ist.
+ ASSERT( !pFollow->GetPrev(), "SwTxtFrm::CalcFollow: cheesy follow" );
+ if( pFollow->GetPrev() )
+ {
+ pFollow->Prepare( PREP_CLEAR );
+ pFollow->Calc();
+ ASSERT( !pFollow->GetPrev(), "SwTxtFrm::CalcFollow: very cheesy follow" );
+ }
+
+ //Sicherstellen, dass der Follow gepaintet wird.
+ pFollow->SetCompletePaint();
+ }
+
+ pPara = GetPara();
+ //Solange der Follow wg. Orphans Zeilen angefordert, bekommt er
+ //diese und wird erneut formatiert, falls moeglich.
+ if( pPara && pPara->IsPrepWidows() )
+ CalcPreps();
+ else
+ break;
+ }
+
+ if( HasFtn() || pFollow->HasFtn() )
+ {
+ ValidateBodyFrm();
+ ValidateFrm();
+ if( pPara )
+ {
+ *(pPara->GetReformat()) = SwCharRange();
+ *(pPara->GetDelta()) = 0;
+ }
+ }
+
+ if ( pPage )
+ {
+ if ( !bOldInvaCntnt )
+ pPage->ValidateCntnt();
+ if ( !bOldInvaLayout && !IsInSct() )
+ pPage->ValidateLayout();
+ }
+
+#ifndef PRODUCT
+ ASSERT( pOldUp == GetUpper(), "SwTxtFrm::CalcFollow: heavy follow" );
+#endif
+
+ if( nOldBottom < GetUpper()->Frm().Bottom() && !GetUpper()->IsSctFrm()
+ && GetUpper()->Frm().Bottom() - nOldBottom != Frm().Top() - nMyPos )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+ * SwTxtFrm::AdjustFrm()
+ *************************************************************************/
+
+void SwTxtFrm::AdjustFrm( const SwTwips nChgHght, sal_Bool bHasToFit )
+{
+ if( IsUndersized() )
+ {
+ if( GetOfst() && !IsFollow() ) // ein gescrollter Absatz (undersized)
+ return;
+ SetUndersized( nChgHght == 0 || bHasToFit );
+ }
+ // Die Size-Variable des Frames wird durch Grow inkrementiert
+ // oder durch Shrink dekrementiert. Wenn die Groesse
+ // unveraendert ist, soll nichts passieren!
+ if( nChgHght >= 0)
+ {
+ if( nChgHght && !bHasToFit )
+ {
+ if( IsInFtn() && !IsInSct() )
+ {
+ SwTwips nReal = Grow( nChgHght, pHeight, sal_True );
+ if( nReal < nChgHght )
+ {
+ SwTwips nBot = Frm().Top() + Frm().Height() + nChgHght
+ - nReal;
+ SwFrm* pCont = FindFtnFrm()->GetUpper();
+ if( nBot > pCont->Frm().Top() + pCont->Frm().Height() )
+ {
+ Frm().SSize().Height() += nChgHght;
+ Prt().SSize().Height() += nChgHght;
+ return;
+ }
+ }
+ }
+
+ Grow( nChgHght, pHeight );
+
+ if ( IsInFly() )
+ {
+ //MA 06. May. 93: Wenn einer der Upper ein Fly ist, so ist es
+ //sehr wahrscheinlich, dass dieser Fly durch das Grow seine
+ //Position veraendert - also muss auch meine Position korrigiert
+ //werden (sonst ist die Pruefung s.u. nicht aussagekraeftig).
+ //Die Vorgaenger muessen berechnet werden, damit die Position
+ //korrekt berechnet werden kann.
+ if ( GetPrev() )
+ {
+ SwFrm *pPre = GetUpper()->Lower();
+ do
+ { pPre->Calc();
+ pPre = pPre->GetNext();
+ } while ( pPre && pPre != this );
+ }
+ const Point aOldPos( Frm().Pos() );
+ MakePos();
+ if ( aOldPos != Frm().Pos() )
+ CalcFlys( sal_True ); //#43679# Fly in Fly in ...
+ }
+ }
+ // Ein Grow() wird von der Layout-Seite immer akzeptiert,
+ // also auch, wenn die FixSize des umgebenden Layoutframes
+ // dies nicht zulassen sollte. Wir ueberpruefen diesen
+ // Fall und korrigieren die Werte.
+ // MA 06. May. 93: Der Frm darf allerdings auch im Notfall nicht
+ // weiter geschrumpft werden als es seine Groesse zulaesst.
+ SwTwips nRstHeight = GetUpper()->Frm().Top()
+ + GetUpper()->Prt().Top()
+ + GetUpper()->Prt().Height()
+ - Frm().Top();
+ //In Tabellenzellen kann ich mir evtl. noch ein wenig dazuholen, weil
+ //durch eine vertikale Ausrichtung auch oben noch Raum sein kann.
+ if ( IsInTab() )
+ {
+ long nAdd = GetUpper()->Lower()->Frm().Top() -
+ (GetUpper()->Frm().Top() + GetUpper()->Prt().Top());
+ nRstHeight += nAdd;
+ }
+
+/* ------------------------------------
+ * #50964#: nRstHeight < 0 bedeutet, dass der TxtFrm komplett ausserhalb seines
+ * Upper liegt. Dies kann passieren, wenn er innerhalb eines FlyAtCntFrm liegt, der
+ * durch das Grow() die Seite gewechselt hat. In so einem Fall ist es falsch, der
+ * folgenden Grow-Versuch durchzufuehren. Im Bugfall fuehrte dies sogar zur
+ * Endlosschleife.
+ * -----------------------------------*/
+ if( nRstHeight < Frm().Height() )
+ {
+ //Kann sein, dass ich die richtige Grosse habe, der Upper aber zu
+ //klein ist und der Upper noch Platz schaffen kann.
+ if( ( nRstHeight > 0 || ( IsInFtn() && IsInSct() ) ) && !bHasToFit )
+ nRstHeight += GetUpper()->Grow( Frm().Height()-nRstHeight, pHeight );
+ // In spaltigen Bereichen wollen wir moeglichst nicht zu gross werden, damit
+ // nicht ueber GetNextSctLeaf weitere Bereiche angelegt werden. Stattdessen
+ // schrumpfen wir und notieren bUndersized, damit FormatWidthCols die richtige
+ // Spaltengroesse ermitteln kann.
+ if ( nRstHeight < Frm().Height() )
+ {
+ if( bHasToFit || !IsMoveable() ||
+ ( IsInSct() && !FindSctFrm()->MoveAllowed(this) ) )
+ {
+ SetUndersized( sal_True );
+ Shrink( Min( (Frm().Height() - nRstHeight), Prt().Height()),
+ pHeight );
+ }
+ else
+ SetUndersized( sal_False );
+ }
+ }
+ }
+ else if ( nChgHght )
+ Shrink( -nChgHght, pHeight );
+}
+
+/*************************************************************************
+ * SwTxtFrm::AdjustFollow()
+ *************************************************************************/
+
+/* AdjustFollow erwartet folgende Situation:
+ * Der SwTxtIter steht am unteren Ende des Masters, der Offset wird
+ * im Follow eingestellt.
+ * nOffset haelt den Offset im Textstring, ab dem der Master abschliesst
+ * und der Follow beginnt. Wenn er 0 ist, wird der FolgeFrame geloescht.
+ */
+
+void SwTxtFrm::_AdjustFollow( SwTxtFormatter &rLine,
+ const xub_StrLen nOffset, const xub_StrLen nEnd,
+ const sal_uInt8 nMode )
+{
+ // Wir haben den Rest der Textmasse: alle Follows loeschen
+ // Sonderfall sind DummyPortions()
+ if( HasFollow() && !(nMode & 1) && nOffset == nEnd )
+ {
+ while( GetFollow() )
+ {
+ if( ((SwTxtFrm*)GetFollow())->IsLocked() )
+ {
+ ASSERT( sal_False, "+SwTxtFrm::JoinFrm: Follow ist locked." );
+ return;
+ }
+ JoinFrm();
+ }
+ return;
+ }
+
+ // Tanz auf dem Vulkan: Wir formatieren eben schnell noch einmal
+ // die letzte Zeile fuer das QuoVadis-Geraffel. Selbstverstaendlich
+ // kann sich dadurch auch der Offset verschieben:
+ const xub_StrLen nNewOfst = ( IsInFtn() && ( !GetIndNext() || HasFollow() ) ) ?
+ rLine.FormatQuoVadis(nOffset) : nOffset;
+
+ if( !(nMode & 1) )
+ {
+ // Wir klauen unseren Follows Textmasse, dabei kann es passieren,
+ // dass wir einige Follows Joinen muessen.
+ while( GetFollow() && GetFollow()->GetFollow() &&
+ nNewOfst >= GetFollow()->GetFollow()->GetOfst() )
+ {
+ DBG_LOOP;
+ JoinFrm();
+ }
+ }
+
+ // Der Ofst hat sich verschoben.
+ if( GetFollow() )
+ {
+#ifdef DEBUG
+ static sal_Bool bTest = sal_False;
+ if( !bTest || ( nMode & 1 ) )
+#endif
+ if ( nMode )
+ GetFollow()->ManipOfst( 0 );
+
+ if ( CalcFollow( nNewOfst ) ) // CalcFollow erst zum Schluss, dort erfolgt ein SetOfst
+ rLine.SetOnceMore( sal_True );
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::JoinFrm()
+ *************************************************************************/
+
+SwCntntFrm *SwTxtFrm::JoinFrm()
+{
+ ASSERT( GetFollow(), "+SwTxtFrm::JoinFrm: no follow" );
+ SwTxtFrm *pFoll = GetFollow();
+
+ SwTxtFrm *pNxt = pFoll->GetFollow();
+
+ // Alle Fussnoten des zu zerstoerenden Follows werden auf uns
+ // umgehaengt.
+ xub_StrLen nStart = pFoll->GetOfst();
+ if ( pFoll->HasFtn() )
+ {
+ const SwpHints *pHints = pFoll->GetTxtNode()->GetpSwpHints();
+ if( pHints )
+ {
+ SwFtnBossFrm *pFtnBoss = 0;
+ SwFtnBossFrm *pEndBoss = 0;
+ for( MSHORT i = 0; i < pHints->Count(); ++i )
+ {
+ const SwTxtAttr *pHt = (*pHints)[i];
+ if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nStart )
+ {
+ if( pHt->GetFtn().IsEndNote() )
+ {
+ if( !pEndBoss )
+ pEndBoss = pFoll->FindFtnBossFrm();
+ pEndBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
+ }
+ else
+ {
+ if( !pFtnBoss )
+ pFtnBoss = pFoll->FindFtnBossFrm( sal_True );
+ pFtnBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
+ }
+ SetFtn( sal_True );
+ }
+ }
+ }
+ }
+
+#ifndef PRODUCT
+ else
+ {
+ pFoll->CalcFtnFlag();
+ ASSERT( !pFoll->HasFtn(), "Missing FtnFlag." );
+ }
+#endif
+
+ pFoll->MoveFlyInCnt( this, nStart, STRING_LEN );
+ pFoll->Cut();
+ delete pFoll;
+ pFollow = pNxt;
+ return pNxt;
+}
+
+/*************************************************************************
+ * SwTxtFrm::SplitFrm()
+ *************************************************************************/
+
+SwCntntFrm *SwTxtFrm::SplitFrm( const xub_StrLen nTxtPos )
+{
+ // Durch das Paste wird ein Modify() an mich verschickt.
+ // Damit meine Daten nicht verschwinden, locke ich mich.
+ SwTxtFrmLocker aLock( this );
+ SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm());
+ pNew->bIsFollow = sal_True;
+
+ pNew->SetFollow( GetFollow() );
+ SetFollow( pNew );
+
+ pNew->Paste( GetUpper(), GetNext() );
+
+ // Wenn durch unsere Aktionen Fussnoten in pNew landen,
+ // so muessen sie umgemeldet werden.
+ if ( HasFtn() )
+ {
+ const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
+ if( pHints )
+ {
+ SwFtnBossFrm *pFtnBoss = 0;
+ SwFtnBossFrm *pEndBoss = 0;
+ for( MSHORT i = 0; i < pHints->Count(); ++i )
+ {
+ const SwTxtAttr *pHt = (*pHints)[i];
+ if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nTxtPos )
+ {
+ if( pHt->GetFtn().IsEndNote() )
+ {
+ if( !pEndBoss )
+ pEndBoss = FindFtnBossFrm();
+ pEndBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
+ }
+ else
+ {
+ if( !pFtnBoss )
+ pFtnBoss = FindFtnBossFrm( sal_True );
+ pFtnBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
+ }
+ pNew->SetFtn( sal_True );
+ }
+ }
+ }
+ }
+
+#ifndef PRODUCT
+ else
+ {
+ CalcFtnFlag( nTxtPos-1 );
+ ASSERT( !HasFtn(), "Missing FtnFlag." );
+ }
+#endif
+
+ MoveFlyInCnt( pNew, nTxtPos, STRING_LEN );
+
+ // Kein SetOfst oder CalcFollow, weil gleich ohnehin ein AdjustFollow folgt.
+#ifdef USED
+ CalcFollow( nNewOfst );
+#endif
+
+ pNew->ManipOfst( nTxtPos );
+ return pNew;
+}
+
+
+/*************************************************************************
+ * virtual SwTxtFrm::SetOfst()
+ *************************************************************************/
+
+void SwTxtFrm::_SetOfst( const xub_StrLen nNewOfst )
+{
+#ifdef DBGTXT
+ // Es gibt tatsaechlich einen Sonderfall, in dem ein SetOfst(0)
+ // zulaessig ist: bug 3496
+ ASSERT( nNewOfst, "!SwTxtFrm::SetOfst: missing JoinFrm()." );
+#endif
+
+ // Die Invalidierung unseres Follows ist nicht noetig.
+ // Wir sind ein Follow, werden gleich formatiert und
+ // rufen von dort aus das SetOfst() !
+ nOfst = nNewOfst;
+ SwParaPortion *pPara = GetPara();
+ if( pPara )
+ {
+ SwCharRange &rReformat = *(pPara->GetReformat());
+ rReformat.Start() = 0;
+ rReformat.Len() = GetTxt().Len();
+ *(pPara->GetDelta()) = rReformat.Len();
+ }
+ InvalidateSize();
+}
+
+/*************************************************************************
+ * SwTxtFrm::CalcPreps
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::CalcPreps()
+{
+ SwParaPortion *pPara = GetPara();
+ if ( !pPara )
+ return sal_False;
+ sal_Bool bPrep = pPara->IsPrep();
+ sal_Bool bPrepWidows = pPara->IsPrepWidows();
+ sal_Bool bPrepAdjust = pPara->IsPrepAdjust();
+ sal_Bool bPrepMustFit = pPara->IsPrepMustFit();
+ ResetPreps();
+
+ sal_Bool bRet = sal_False;
+ if( bPrep && !pPara->GetReformat()->Len() )
+ {
+ // PREP_WIDOWS bedeutet, dass im Follow die Orphans-Regel
+ // zuschlug.
+ // Es kann in unguenstigen Faellen vorkommen, dass auch ein
+ // PrepAdjust vorliegt (3680)!
+ if( bPrepWidows )
+ {
+ if( !GetFollow() )
+ {
+ ASSERT( GetFollow(), "+SwTxtFrm::CalcPreps: no credits" );
+ return sal_False;
+ }
+
+ // Wir muessen uns auf zwei Faelle einstellen:
+ // Wir konnten dem Follow noch ein paar Zeilen abgeben,
+ // -> dann muessen wir schrumpfen
+ // oder wir muessen auf die naechste Seite
+ // -> dann lassen wir unseren Frame zu gross werden.
+
+ SwTwips nChgHeight = GetParHeight();
+ if( nChgHeight >= Prt().Height() )
+ {
+ if( bPrepMustFit )
+ {
+ GetFollow()->SetJustWidow( sal_True );
+ GetFollow()->Prepare( PREP_CLEAR );
+ }
+ else
+ {
+ SwTwips nTmp = LONG_MAX - (Frm().Top()+10000);
+ SwTwips nDiff = nTmp - Frm().Height();
+ Frm().Height( nTmp );
+ Prt().Height( Prt().Height() + nDiff );
+ SetWidow( sal_True );
+ }
+ }
+ else
+ {
+ ASSERT( nChgHeight < Prt().Height(),
+ "+SwTxtFrm::CalcPrep: wanna shrink" );
+ nChgHeight = Prt().Height() - nChgHeight;
+ GetFollow()->SetJustWidow( sal_True );
+ GetFollow()->Prepare( PREP_CLEAR );
+ Shrink( nChgHeight, pHeight );
+ SwRect &rRepaint = *(pPara->GetRepaint());
+ rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
+ // 6792: Rrand < LRand und Repaint
+ if( 0 >= rRepaint.Width() )
+ rRepaint.Width(1);
+ }
+ bRet = sal_True;
+ }
+
+ else if ( bPrepAdjust )
+ {
+ if ( HasFtn() )
+ {
+ if( !CalcPrepFtnAdjust() )
+ {
+ if( bPrepMustFit )
+ {
+ SwTxtLineAccess aAccess( this );
+ aAccess.GetPara()->SetPrepMustFit( sal_True );
+ }
+ return sal_False;
+ }
+ }
+
+ SwTxtFormatInfo aInf( this );
+ SwTxtFormatter aLine( this, &aInf );
+
+ WidowsAndOrphans aFrmBreak( this );
+ // Egal was die Attribute meinen, bei MustFit wird
+ // der Absatz im Notfall trotzdem gesplittet...
+ if( bPrepMustFit )
+ {
+ aFrmBreak.SetKeep( sal_False );
+ aFrmBreak.ClrOrphLines();
+ }
+ // Bevor wir FormatAdjust aufrufen muessen wir dafuer
+ // sorgen, dass die Zeilen, die unten raushaengen
+ // auch tatsaechlich abgeschnitten werden.
+ sal_Bool bBreak = aFrmBreak.IsBreakNow( aLine );
+ bRet = sal_True;
+ while( !bBreak && aLine.Next() )
+ bBreak = aFrmBreak.IsBreakNow( aLine );
+ if( bBreak )
+ {
+ // Es gibt Komplikationen: wenn TruncLines gerufen wird,
+ // veraendern sich ploetzlich die Bedingungen in
+ // IsInside, so dass IsBreakNow andere Ergebnisse
+ // liefern kann. Aus diesem Grund wird rFrmBreak bekannt
+ // gegeben, dass da wo rLine steht, das Ende erreicht
+ // ist. Mal sehen, ob's klappt ...
+ aLine.TruncLines();
+ aFrmBreak.SetRstHeight( aLine );
+ FormatAdjust( aLine, aFrmBreak, aInf.GetTxt().Len(), aInf.IsStop() );
+ }
+ else
+ {
+ if( !GetFollow() )
+ FormatAdjust( aLine, aFrmBreak,
+ aInf.GetTxt().Len(), aInf.IsStop() );
+ else if ( !aFrmBreak.IsKeepAlways() )
+ {
+ // Siehe Bug: 2320
+ // Vor dem Master wird eine Zeile geloescht, der Follow
+ // koennte eine Zeile abgeben.
+ const SwCharRange aFollowRg( GetFollow()->GetOfst(), 1 );
+ *(pPara->GetReformat()) += aFollowRg;
+ // Es soll weitergehen!
+ bRet = sal_False;
+ }
+ }
+
+ // Eine letzte Ueberpruefung, falls das FormatAdjust() nichts
+ // brachte, muessen wir amputieren.
+ if( bPrepMustFit )
+ {
+ const SwTwips nMust = GetUpper()->Frm().Top()
+ + GetUpper()->Prt().Top() + GetUpper()->Prt().Height();
+ const SwTwips nIs = Frm().Top() + Frm().Height();
+ if( nIs > nMust )
+ {
+ Shrink( nIs - nMust, pHeight );
+ if( Prt().Height() < 0 )
+ Prt().Height( 0 );
+ SetUndersized( sal_True );
+ }
+ }
+ }
+ }
+ pPara->SetPrepMustFit( bPrepMustFit );
+ return bRet;
+}
+
+/*************************************************************************
+ * SwTxtFrm::FormatAdjust()
+ *************************************************************************/
+
+// Hier werden die Fussnoten und "als Zeichen"-gebundenen Objekte umgehaengt
+#define CHG_OFFSET( pFrm, nNew )\
+ {\
+ if( pFrm->GetOfst() < nNew )\
+ pFrm->MoveFlyInCnt( this, 0, nNew );\
+ else if( pFrm->GetOfst() > nNew )\
+ MoveFlyInCnt( pFrm, nNew, STRING_LEN );\
+ }
+
+void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine,
+ WidowsAndOrphans &rFrmBreak,
+ const xub_StrLen nStrLen, const sal_Bool bDummy )
+{
+ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+
+ xub_StrLen nEnd = rLine.GetStart();
+
+ // Wir muessen fuer eindeutige Verhaeltnisse sorgen
+ // rFrmBreak.SetRstHeight( rLine );
+
+ // rLine.GetStart(): die letzte Zeile von rLine,
+ // ist bereits die Zeile, die nicht
+ // mehr passte. Ihr Anfang ist das Ende des Masters.
+ // @@@if( !GetFollow() && nEnd < nStrLen )
+ // (nEnd < nStrLen || rFrmBreak.IsBreakNow(rLine));
+
+ sal_Bool bHasToFit = pPara->IsPrepMustFit();
+
+ // Das StopFlag wird durch Fussnoten gesetzt,
+ // die auf die naechste Seite wollen.
+ sal_uInt8 nNew = ( !GetFollow() && nEnd < nStrLen &&
+ ( rLine.IsStop() || ( bHasToFit ?
+ ( rLine.GetLineNr() > 1 && !rFrmBreak.IsInside( rLine ) )
+ : rFrmBreak.IsBreakNow( rLine ) ) ) ) ? 1 : 0;
+ if( nNew )
+ SplitFrm( nEnd );
+
+ const SwFrm *pBodyFrm = (const SwFrm*)(FindBodyFrm());
+ const long nBodyHeight = pBodyFrm ? pBodyFrm->Frm().Height() : 0;
+
+ // Wenn die aktuellen Werte berechnet wurden, anzeigen, dass
+ // sie jetzt gueltig sind.
+ *(pPara->GetReformat()) = SwCharRange();
+ sal_Bool bDelta = *pPara->GetDelta() != 0;
+ *(pPara->GetDelta()) = 0;
+
+ if( rLine.IsStop() )
+ {
+ rLine.TruncLines( sal_True );
+ nNew = 1;
+ }
+
+ // FindBreak schneidet die letzte Zeile ab.
+ if( !rFrmBreak.FindBreak( this, rLine, bHasToFit ) )
+ {
+ // Wenn wir bis zum Ende durchformatiert haben, wird nEnd auf das Ende
+ // gesetzt. In AdjustFollow wird dadurch ggf. JoinFrm() ausgefuehrt.
+ // Ansonsten ist nEnd das Ende der letzten Zeile im Master.
+ xub_StrLen nOld = nEnd;
+ nEnd = rLine.GetEnd();
+ if( GetFollow() )
+ {
+ if( nNew && nOld < nEnd )
+ RemoveFtn( nOld, nEnd - nOld );
+ CHG_OFFSET( GetFollow(), nEnd )
+ if( !bDelta )
+ GetFollow()->ManipOfst( nEnd );
+ }
+ }
+ else
+ { // Wenn wir Zeilen abgeben, darf kein Join auf den Folows gerufen werden,
+ // im Gegenteil, es muss ggf. sogar ein Follow erzeugt werden.
+ // Dies muss auch geschehen, wenn die Textmasse komplett im Master
+ // bleibt, denn es könnte ja ein harter Zeilenumbruch noch eine weitere
+ // Zeile (ohne Textmassse) notwendig machen!
+ nEnd = rLine.GetEnd();
+ if( GetFollow() )
+ {
+ if( GetFollow()->GetOfst() != nEnd || GetFollow()->IsFieldFollow() )
+ nNew |= 3;
+ CHG_OFFSET( GetFollow(), nEnd )
+ GetFollow()->ManipOfst( nEnd );
+ }
+ else
+ {
+ SplitFrm( nEnd );
+ nNew |= 3;
+ }
+ // Wenn sich die Resthoehe geaendert hat, z.B. durch RemoveFtn()
+ // dann muessen wir auffuellen, um Oszillationen zu vermeiden!
+ if( bDummy && pBodyFrm && nBodyHeight < pBodyFrm->Frm().Height() )
+ rLine.MakeDummyLine();
+ }
+
+ // In AdjustFrm() stellen wir uns selbst per Grow/Shrink ein,
+ // in AdjustFollow() stellen wir unseren FolgeFrame ein.
+
+ const SwTwips nDocPrtTop = Frm().Top() + Prt().Top();
+ const SwTwips nOldHeight = Prt().SSize().Height();
+ const SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
+
+ AdjustFrm( nChg, bHasToFit );
+
+ if( HasFollow() || IsInFtn() )
+ _AdjustFollow( rLine, nEnd, nStrLen, nNew );
+ pPara->SetPrepMustFit( sal_False );
+}
+
+/*************************************************************************
+ * SwTxtFrm::FormatLine()
+ *************************************************************************/
+
+// bPrev zeigt an, ob Reformat.Start() wegen Prev() vorgezogen wurde.
+// Man weiss sonst nicht, ob man Repaint weiter einschraenken kann oder nicht.
+
+
+sal_Bool SwTxtFrm::FormatLine( SwTxtFormatter &rLine, const sal_Bool bPrev )
+{
+ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+ // Nach rLine.FormatLine() haelt nStart den neuen Wert,
+ // waehrend in pOldStart der alte Offset gepflegt wird.
+ // Ueber diesen Weg soll das nDelta ersetzt werden.
+ // *pOldStart += rLine.GetCurr()->GetLen();
+ const SwLineLayout *pOldCur = rLine.GetCurr();
+ const xub_StrLen nOldLen = pOldCur->GetLen();
+ const KSHORT nOldAscent = pOldCur->GetAscent();
+ const KSHORT nOldHeight = pOldCur->Height();
+ const KSHORT nOldWidth = pOldCur->Width();
+ const sal_Bool bOldHyph = pOldCur->IsEndHyph();
+ SwTwips nOldTop = 0;
+ SwTwips nOldBottom;
+ if( rLine.GetCurr()->IsClipping() )
+ rLine.CalcUnclipped( nOldTop, nOldBottom );
+
+ const xub_StrLen nNewStart = rLine.FormatLine( rLine.GetStart() );
+
+ ASSERT( Frm().Pos() + Prt().Pos() == rLine.GetFirstPos(),
+ "SwTxtFrm::FormatLine: frame leaves orbit." );
+ ASSERT( rLine.GetCurr()->Height(),
+ "SwTxtFrm::FormatLine: line height is zero" );
+
+ // Das aktuelle Zeilenumbruchobjekt.
+ const SwLineLayout *pNew = rLine.GetCurr();
+
+ sal_Bool bUnChg = nOldLen == pNew->GetLen() &&
+ bOldHyph == pNew->IsEndHyph();
+ if ( bUnChg && !bPrev )
+ {
+ // 6672: Toleranz von SLOPPY_TWIPS (5 Twips); vgl. 6922
+ const KSHORT nWidthDiff = nOldWidth > pNew->Width()
+ ? nOldWidth - pNew->Width()
+ : pNew->Width() - nOldWidth;
+ bUnChg = nOldHeight == pNew->Height() &&
+ nOldAscent == pNew->GetAscent() &&
+ nWidthDiff <= SLOPPY_TWIPS;
+ }
+
+ // rRepaint wird berechnet:
+ const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight();
+ SwRepaint &rRepaint = *(pPara->GetRepaint());
+ if( bUnChg && rRepaint.Top() == rLine.Y()
+ && (bPrev || nNewStart <= pPara->GetReformat()->Start())
+ && ( nNewStart < GetTxtNode()->GetTxt().Len() ) )
+ {
+ rRepaint.Top( nBottom );
+ rRepaint.Height( 0 );
+ }
+ else
+ {
+ if( nOldTop )
+ {
+ if( nOldTop < rRepaint.Top() )
+ rRepaint.Top( nOldTop );
+ if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() )
+ {
+ rRepaint.Bottom( nOldBottom - 1 );
+ rLine.SetUnclipped( sal_True );
+ }
+ }
+ if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() )
+ {
+ SwTwips nTmpTop, nTmpBottom;
+ rLine.CalcUnclipped( nTmpTop, nTmpBottom );
+ if( nTmpTop < rRepaint.Top() )
+ rRepaint.Top( nTmpTop );
+ if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() )
+ {
+ rRepaint.Bottom( nTmpBottom - 1 );
+ rLine.SetUnclipped( sal_True );
+ }
+ }
+ else
+ {
+ if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() )
+ {
+ rRepaint.Bottom( nBottom - 1 );
+ rLine.SetUnclipped( sal_False );
+ }
+ }
+ if ( rRepaint.GetOfst() )
+ {
+ SwTwips nRght = Max( nOldWidth, pNew->Width() );
+ ViewShell *pSh = GetShell();
+ const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : 0;
+ if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) )
+ nRght += ( Max( nOldAscent, pNew->GetAscent() ) );
+ else
+ nRght += ( Max( nOldAscent, pNew->GetAscent() ) / 4);
+ rRepaint.SetRightOfst( rLine.GetLeftMargin() + nRght );
+ }
+ }
+ if( !bUnChg )
+ rLine.SetChanges();
+
+ // Die gute, alte nDelta-Berechnung:
+ *(pPara->GetDelta()) -= long(pNew->GetLen()) - long(nOldLen);
+
+ // Stop!
+ if( rLine.IsStop() )
+ return sal_False;
+
+ // Unbedingt noch eine Zeile
+ if( rLine.IsNewLine() )
+ return sal_True;
+
+ // bis zum Ende des Strings ?
+ if( nNewStart >= GetTxtNode()->GetTxt().Len() )
+ return sal_False;
+
+ if( rLine.GetInfo().IsShift() )
+ return sal_True;
+
+ // Ende des Reformats erreicht ?
+ const xub_StrLen nEnd = pPara->GetReformat()->Start() +
+ pPara->GetReformat()->Len();
+
+ if( nNewStart <= nEnd )
+ return sal_True;
+
+ return 0 != *(pPara->GetDelta());
+
+// Dieser Bereich ist so sensibel, da behalten wir mal die alte Version:
+#ifdef USED
+ // nDelta abgearbeitet ?
+ if( 0 == *(pPara->GetDelta()) )
+ return sal_False;
+
+ // Wenn die Zeilen ausgeglichen sind, ist alles ok.
+ if( bUnChg )
+ return sal_False;
+
+ return sal_True;
+#endif
+}
+
+/*************************************************************************
+ * SwTxtFrm::_Format()
+ *************************************************************************/
+
+void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf,
+ const sal_Bool bAdjust )
+{
+ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+ rLine.SetUnclipped( sal_False );
+
+ // Das war dem C30 zu kompliziert: aString( GetTxt() );
+ const XubString &rString = GetTxtNode()->GetTxt();
+ const xub_StrLen nStrLen = rString.Len();
+
+ SwCharRange &rReformat = *(pPara->GetReformat());
+ SwRepaint &rRepaint = *(pPara->GetRepaint());
+ SwRepaint *pFreeze = NULL;
+
+ // Aus Performancegruenden wird in Init() rReformat auf STRING_LEN gesetzt.
+ // Fuer diesen Fall wird rReformat angepasst.
+ if( rReformat.Len() > nStrLen )
+ rReformat.Len() = nStrLen;
+
+ // Optimiert:
+ xub_StrLen nEnd = rReformat.Start() + rReformat.Len();
+ if( nEnd > nStrLen )
+ {
+ rReformat.Len() = nStrLen - rReformat.Start();
+ nEnd = nStrLen;
+ }
+
+ SwTwips nOldBottom;
+ if( GetOfst() && !IsFollow() )
+ {
+ rLine.Bottom();
+ nOldBottom = rLine.Y();
+ rLine.Top();
+ }
+ else
+ nOldBottom = 0;
+ rLine.CharToLine( rReformat.Start() );
+
+ // Worte koennen durch Fortfall oder Einfuegen eines Space
+ // auf die Zeile vor der editierten hinausgezogen werden,
+ // deshalb muss diese ebenfalls formatiert werden.
+ // Optimierung: Wenn rReformat erst hinter dem ersten Wort der
+ // Zeile beginnt, so kann diese Zeile die vorige nicht mehr beeinflussen.
+ // AMA: Leider doch, Textgroessenaenderungen + FlyFrames, die Rueckwirkung
+ // kann im Extremfall mehrere Zeilen (Frames!!!) betreffen!
+
+ sal_Bool bPrev = rLine.GetPrev() &&
+ ( FindBrk( rString, rLine.GetStart(),
+ rReformat.Start() + 1 ) >= rReformat.Start() ||
+ rLine.GetCurr()->IsRest() );
+ if( bPrev )
+ {
+ while( rLine.Prev() )
+ if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() )
+ {
+ if( !rLine.GetStart() )
+ rLine.Top(); // damit NumDone nicht durcheinander kommt
+ break;
+ }
+ xub_StrLen nNew = rLine.GetStart() + rLine.GetLength();
+ if( nNew )
+ {
+ --nNew;
+ if( CH_BREAK == rString.GetChar( nNew ) )
+ {
+ ++nNew;
+ rLine.Next();
+ bPrev = sal_False;
+ }
+ }
+ rReformat.Len() += rReformat.Start() - nNew;
+ rReformat.Start() = nNew;
+ }
+
+ rRepaint.SetOfst( 0 );
+ rRepaint.SetRightOfst( 0 );
+ rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
+ rRepaint.Top( rLine.Y() );
+ // 6792: Rrand < LRand und Repaint
+ if( 0 >= rRepaint.Width() )
+ rRepaint.Width(1);
+ WidowsAndOrphans aFrmBreak( this, rInf.IsTest() ? 1 : 0 );
+
+ // rLine steht jetzt auf der ersten Zeile, die formatiert werden
+ // muss. Das Flag bFirst sorgt dafuer, dass nicht Next() gerufen wird.
+ // Das ganze sieht verdreht aus, aber es muss sichergestellt werden,
+ // dass bei IsBreakNow rLine auf der Zeile zum stehen kommt, die
+ // nicht mehr passt.
+ sal_Bool bFirst = sal_True;
+ sal_Bool bFormat = sal_True;
+
+ // 5383: Das CharToLine() kann uns auch in den roten Bereich fuehren.
+ // In diesem Fall muessen wir zurueckwandern, bis die Zeile, die
+ // nicht mehr passt in rLine eingestellt ist. Ansonsten geht Textmasse
+ // verloren, weil der Ofst im Follow falsch eingestellt wird.
+
+ sal_Bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 )
+ && aFrmBreak.IsBreakNow( rLine );
+ if( bBreak )
+ {
+ sal_Bool bPrevDone = 0 != rLine.Prev();
+ while( bPrevDone && aFrmBreak.IsBreakNow(rLine) )
+ bPrevDone = 0 != rLine.Prev();
+ if( bPrevDone )
+ {
+ aFrmBreak.SetKeep( sal_False );
+ rLine.Next();
+ }
+ rLine.TruncLines();
+
+ // auf Nummer sicher:
+ bBreak = aFrmBreak.IsBreakNow(rLine) &&
+ ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 );
+ }
+
+ /* Bedeutung der folgenden Flags:
+ Ist das Watch(End/Mid)Hyph-Flag gesetzt, so muss formatiert werden, wenn
+ eine Trennung am (Zeilenende/Fly) vorliegt, sofern MaxHyph erreicht ist.
+ Das Jump(End/Mid)Flag bedeutet, dass die naechste Zeile, bei der keine
+ Trennung (Zeilenende/Fly) vorliegt, formatiert werden muss, da jetzt
+ umgebrochen werden koennte, was vorher moeglicherweise durch MaxHyph
+ verboten war.
+ Watch(End/Mid)Hyph wird gesetzt, wenn die letzte formatierte Zeile eine
+ Trennstelle erhalten hat, vorher aber keine hatte,
+ Jump(End/Mid)Hyph, wenn eine Trennstelle verschwindet.
+ */
+ sal_Bool bJumpEndHyph = sal_False,
+ bWatchEndHyph = sal_False,
+ bJumpMidHyph = sal_False,
+ bWatchMidHyph = sal_False;
+
+ const SwAttrSet& rAttrSet = GetTxtNode()->GetSwAttrSet();
+ sal_Bool bMaxHyph = ( 0 !=
+ ( rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens() ) );
+ if ( bMaxHyph )
+ rLine.InitCntHyph();
+
+ if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOfst() )
+ {
+ SwFldPortion* pRest = rLine.GetFieldRest( rInf );
+ if( pRest )
+ {
+ SwTxtFrm *pMaster = FindMaster();
+ ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
+ const SwFldPortion *pFld = pMaster->GetRestPortion();
+ if( pFld )
+ {
+ pRest->TakeNextOffset( pFld );
+ rInf.SetRest( pRest );
+ }
+ else
+ delete pRest;
+ }
+ else
+ SetFieldFollow( sal_False );
+ }
+
+ /* Zum Abbruchkriterium:
+ * Um zu erkennen, dass eine Zeile nicht mehr auf die Seite passt,
+ * muss sie formatiert werden. Dieser Ueberhang wird z.B. in AdjustFollow
+ * wieder entfernt.
+ * Eine weitere Komplikation: wenn wir der Master sind, so muessen
+ * wir die Zeilen durchgehen, da es ja sein kann, dass eine Zeile
+ * vom Follow in den Master rutschen kann.
+ */
+ do
+ {
+ DBG_LOOP;
+ if( bFirst )
+ bFirst = sal_False;
+ else
+ {
+ if ( bMaxHyph )
+ {
+ if ( rLine.GetCurr()->IsEndHyph() )
+ rLine.CntEndHyph()++;
+ else
+ rLine.CntEndHyph() = 0;
+ if ( rLine.GetCurr()->IsMidHyph() )
+ rLine.CntMidHyph()++;
+ else
+ rLine.CntMidHyph() = 0;
+ }
+ if( !rLine.Next() )
+ {
+ if( !bFormat )
+ rLine.MakeRestPortion();
+ rLine.Insert( new SwLineLayout() );
+ rLine.Next();
+ bFormat = sal_True;
+ }
+ }
+ if ( !bFormat && bMaxHyph &&
+ (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) )
+ {
+ if ( rLine.GetCurr()->IsEndHyph() )
+ {
+ if ( bWatchEndHyph )
+ bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
+ }
+ else
+ {
+ bFormat = bJumpEndHyph;
+ bWatchEndHyph = sal_False;
+ bJumpEndHyph = sal_False;
+ }
+ if ( rLine.GetCurr()->IsMidHyph() )
+ {
+ if ( bWatchMidHyph && !bFormat )
+ bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
+ }
+ else
+ {
+ bFormat = bFormat || bJumpMidHyph;
+ bWatchMidHyph = sal_False;
+ bJumpMidHyph = sal_False;
+ }
+ }
+ if( bFormat )
+ {
+ sal_Bool bOldEndHyph = rLine.GetCurr()->IsEndHyph();
+ sal_Bool bOldMidHyph = rLine.GetCurr()->IsMidHyph();
+ bFormat = FormatLine( rLine, bPrev );
+ //9334: Es kann nur ein bPrev geben... (???)
+ bPrev = sal_False;
+ if ( bMaxHyph )
+ {
+ if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph )
+ {
+ bWatchEndHyph = !bOldEndHyph;
+ bJumpEndHyph = bOldEndHyph;
+ }
+ if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph )
+ {
+ bWatchMidHyph = !bOldMidHyph;
+ bJumpMidHyph = bOldMidHyph;
+ }
+ }
+ }
+
+ if( !rInf.IsNewLine() )
+ {
+ if( !bFormat )
+ bFormat = 0 != rInf.GetRest();
+ if( rInf.IsStop() || rInf.GetIdx() >= nStrLen )
+ break;
+ if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph &&
+ !bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) )
+ {
+ if( GetFollow() )
+ {
+ while( rLine.Next() )
+ ; //Nothing
+ pFreeze = new SwRepaint( rRepaint ); // to minimize painting
+ }
+ else
+ break;
+ }
+ }
+ bBreak = aFrmBreak.IsBreakNow(rLine);
+ }while( !bBreak );
+
+ if( pFreeze )
+ {
+ rRepaint = *pFreeze;
+ delete pFreeze;
+ }
+
+ if( !rLine.IsStop() )
+ {
+ // Wurde aller Text formatiert und gibt es noch weitere
+ // Zeilenobjekte, dann sind diese jetzt ueberfluessig,
+ // weil der Text kuerzer geworden ist.
+ if( rLine.GetStart() + rLine.GetLength() >= nStrLen &&
+ rLine.GetCurr()->GetNext() )
+ {
+ rLine.TruncLines();
+ rLine.SetTruncLines( sal_True );
+ }
+ }
+
+ if( !rInf.IsTest() )
+ {
+ // Bei OnceMore lohnt sich kein FormatAdjust
+ if( bAdjust || !rLine.GetDropFmt() || !rLine.CalcOnceMore() )
+ FormatAdjust( rLine, aFrmBreak, nStrLen, rInf.IsStop() );
+ if( rRepaint.HasArea() )
+ SetRepaint();
+ rLine.SetTruncLines( sal_False );
+ if( nOldBottom ) // Bei "gescollten" Absaetzen wird
+ { // noch ueberprueft, ob durch Schrumpfen
+ rLine.Bottom(); // das Scrolling ueberfluessig wurde.
+ SwTwips nNewBottom = rLine.Y();
+ if( nNewBottom < nOldBottom )
+ _SetOfst( 0 );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::Format()
+ *************************************************************************/
+
+void SwTxtFrm::FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf )
+{
+ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
+ if( !pPara )
+ return;
+
+ // ggf gegen pPara
+ KSHORT nOld = ((const SwTxtMargin&)rLine).GetDropHeight();
+ sal_Bool bShrink = sal_False,
+ bGrow = sal_False,
+ bGoOn = rLine.IsOnceMore();
+ sal_uInt8 nGo = 0;
+ while( bGoOn )
+ {
+#ifdef DBGTXT
+ aDbstream << "OnceMore!" << endl;
+#endif
+ ++nGo;
+ rInf.Init();
+ rLine.Top();
+ if( !rLine.GetDropFmt() )
+ rLine.SetOnceMore( sal_False );
+ SwCharRange aRange( 0, rInf.GetTxt().Len() );
+ *(pPara->GetReformat()) = aRange;
+ _Format( rLine, rInf );
+
+ bGoOn = rLine.IsOnceMore();
+ if( bGoOn )
+ {
+ const KSHORT nNew = ((const SwTxtMargin&)rLine).GetDropHeight();
+ if( nOld == nNew )
+ bGoOn = sal_False;
+ else
+ {
+ if( nOld > nNew )
+ bShrink = sal_True;
+ else
+ bGrow = sal_True;
+
+ if( bShrink == bGrow || 5 < nGo )
+ bGoOn = sal_False;
+
+ nOld = nNew;
+ }
+
+ // 6107: Wenn was schief ging, muss noch einmal formatiert werden.
+ if( !bGoOn )
+ {
+ rInf.CtorInit( this );
+ rLine.CtorInit( this, &rInf );
+ rLine.SetDropLines( 1 );
+ rLine.CalcDropHeight( 1 );
+ SwCharRange aRange( 0, rInf.GetTxt().Len() );
+ *(pPara->GetReformat()) = aRange;
+ _Format( rLine, rInf, sal_True );
+ // 8047: Wir painten alles...
+ SetCompletePaint();
+ }
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::_Format()
+ *************************************************************************/
+
+
+void SwTxtFrm::_Format( SwParaPortion *pPara )
+{
+ const xub_StrLen nStrLen = GetTxt().Len();
+
+ // AMA: Wozu soll das gut sein? Scheint mir zuoft zu einem kompletten
+ // Formatieren und Repainten zu fuehren???
+// if ( !(*pPara->GetDelta()) )
+// *(pPara->GetDelta()) = nStrLen;
+// else
+ if ( !nStrLen )
+ {
+ // Leere Zeilen werden nicht lange gequaelt:
+ // pPara wird blank geputzt
+ // entspricht *pPara = SwParaPortion;
+ sal_Bool bMustFit = pPara->IsPrepMustFit();
+ pPara->Truncate();
+ pPara->FormatReset();
+ if( pBlink && pPara->IsBlinking() )
+ pBlink->Delete( pPara );
+ pPara->ResetFlags();
+ pPara->SetPrepMustFit( bMustFit );
+ }
+
+ SwTxtFormatInfo aInf( this );
+ SwTxtFormatter aLine( this, &aInf );
+
+ _Format( aLine, aInf );
+
+ if( aLine.IsOnceMore() )
+ FormatOnceMore( aLine, aInf );
+
+ if( 1 < aLine.GetDropLines() )
+ {
+ if( SVX_ADJUST_LEFT != aLine.GetAdjust() &&
+ SVX_ADJUST_BLOCK != aLine.GetAdjust() )
+ {
+ aLine.CalcDropAdjust();
+ aLine.SetPaintDrop( sal_True );
+ }
+
+ if( aLine.IsPaintDrop() )
+ {
+ aLine.CalcDropRepaint();
+ aLine.SetPaintDrop( sal_False );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::Format()
+ *************************************************************************/
+
+/*
+ * Format berechnet die Groesse des Textframes und ruft, wenn
+ * diese feststeht, Shrink() oder Grow(), um die Framegroesse dem
+ * evtl. veraenderten Platzbedarf anzupassen.
+ */
+
+void SwTxtFrm::Format( const SwBorderAttrs * )
+{
+ DBG_LOOP;
+#ifdef DEBUG
+ const XubString aXXX = GetTxtNode()->GetTxt();
+ const SwTwips nDbgY = Frm().Top();
+ const SwPageFrm *pDbgPage = FindPageFrm();
+ const MSHORT nDbgPageNr = pDbgPage->GetPhyPageNum();
+ // Um zu gucken, ob es einen Ftn-Bereich gibt.
+ const SwFrm *pDbgFtnCont = (const SwFrm*)(FindPageFrm()->FindFtnCont());
+
+#ifndef PRODUCT
+ // nStopAt laesst sich vom CV bearbeiten.
+ static MSHORT nStopAt = 0;
+ if( nStopAt == GetFrmId() )
+ {
+ int i = GetFrmId();
+ }
+#endif
+#endif
+
+#ifdef DEBUG_FTN
+ //Fussnote darf nicht auf einer Seite vor ihrer Referenz stehen.
+ if( IsInFtn() )
+ {
+ const SwFtnFrm *pFtn = (SwFtnFrm*)GetUpper();
+ const SwPageFrm *pFtnPage = pFtn->GetRef()->FindPageFrm();
+ const MSHORT nFtnPageNr = pFtnPage->GetPhyPageNum();
+ if( !IsLocked() )
+ {
+ if( nFtnPageNr > nDbgPageNr )
+ {
+ SwTxtFrmLocker aLock(this);
+ ASSERT( nFtnPageNr <= nDbgPageNr, "!Ftn steht vor der Referenz." );
+ MSHORT i = 0;
+ }
+ }
+ }
+#endif
+
+ MSHORT nRepeat = 0;
+ do
+ {
+ // Vom Berichtsautopiloten oder ueber die BASIC-Schnittstelle kommen
+ // gelegentlich TxtFrms mit einer Breite <=0.
+ if( Prt().Width() <= 0 )
+ {
+ // Wenn MustFit gesetzt ist, schrumpfen wir ggf. auf die Unterkante
+ // des Uppers, ansonsten nehmen wir einfach eine Standardgroesse
+ // von 12 Pt. ein (240 Twip).
+ SwTxtLineAccess aAccess( this );
+ if( aAccess.GetPara()->IsPrepMustFit() )
+ {
+ const SwTwips nMust = GetUpper()->Frm().Top()
+ + GetUpper()->Frm().Height();
+ const SwTwips nIs = Frm().Top() + Frm().Height();
+ if( nIs > nMust )
+ Shrink( nIs - nMust, pHeight );
+ }
+ else if( 240 < Frm().Height() )
+ Shrink( Frm().Height() - 240, pHeight );
+ else if( 240 > Frm().Height() )
+ Grow( 240 - Frm().Height(), pHeight );
+ if( Prt().Top() > Frm().Height() )
+ Prt().Top( Frm().Height() );
+ if( Prt().Height() < 0 )
+ Prt().Height( 0 );
+ return;
+ }
+ sal_Bool bChkAtCnt = sal_False;
+ const xub_StrLen nStrLen = GetTxtNode()->GetTxt().Len();
+ if ( nStrLen || !FormatEmpty() )
+ {
+
+ SetEmpty( sal_False );
+ // Um nicht durch verschachtelte Formats irritiert zu werden.
+ FormatLevel aLevel;
+ if( 12 == aLevel.GetLevel() )
+ return;
+
+ // Die Formatinformationen duerfen u.U. nicht veraendert werden.
+ if( IsLocked() )
+ return;
+
+ // Waehrend wir formatieren, wollen wir nicht gestoert werden.
+ SwTxtFrmLocker aLock(this);
+
+#ifdef DEBUG
+ //MA 25. Jan. 94 Das Flag stimmt sehr haufig beim Eintritt nicht. Das muss
+ // bei naechster Gelegenheit geprueft und gefixt werden.
+ const sal_Bool bOldFtnFlag = HasFtn();
+ CalcFtnFlag();
+ if ( bOldFtnFlag != HasFtn() )
+ {int bla = 5;}
+#endif
+
+ // 8708: Vorsicht, das Format() kann auch durch GetFormatted()
+ // angestossen werden.
+ if( IsHiddenNow() )
+ {
+ if( Prt().Height() )
+ {
+ HideHidden();
+ Shrink( Prt().Height(), pHeight );
+ }
+ ChgThisLines();
+ return;
+ }
+
+ SwTxtLineAccess aAccess( this );
+ const sal_Bool bNew = !aAccess.SwTxtLineAccess::IsAvailable();
+
+ if( CalcPreps() )
+ ; // nothing
+ // Wir returnen, wenn schon formatiert wurde, nicht aber, wenn
+ // der TxtFrm gerade erzeugt wurde und ueberhaupt keine Format-
+ // informationen vorliegen.
+ else if( !bNew && !aAccess.GetPara()->GetReformat()->Len() )
+ {
+ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
+ {
+ aAccess.GetPara()->SetPrepAdjust( sal_True );
+ aAccess.GetPara()->SetPrep( sal_True );
+ CalcPreps();
+ }
+ SetWidow( sal_False );
+ }
+ else if( GetOfst() && GetOfst() > GetTxtNode()->GetTxt().Len() )
+ {
+ SwTxtFrm *pMaster = FindMaster();
+ ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" );
+ if( pMaster )
+ pMaster->Prepare( PREP_FOLLOW_FOLLOWS );
+ }
+ else
+ {
+ const sal_Bool bOrphan = IsWidow();
+ _Format( aAccess.GetPara() );
+ if( bOrphan )
+ {
+ ValidateFrm();
+ SetWidow( sal_False );
+ }
+ bChkAtCnt = sal_True;
+ }
+ if( IsEmptyMaster() )
+ {
+ SwFrm* pPre = GetPrev();
+ if( pPre && pPre->GetAttrSet()->GetKeep().GetValue() )
+ pPre->InvalidatePos();
+ }
+ }
+ MSHORT nMaxRepeat = 2;
+ if( bChkAtCnt && nRepeat < nMaxRepeat )
+ {
+ sal_Bool bRepeat = sal_False;
+ MSHORT nRepAdd = 0;
+ SwDrawObjs *pObjs;
+ SwTxtFrm *pMaster = IsFollow() ? FindMaster() : this;
+ if( pMaster )
+ {
+ if ( 0 != (pObjs = pMaster->GetDrawObjs()) )
+ {
+ MSHORT nAutoCnt = 0;
+ for ( int i = 0; i < int(pObjs->Count()); ++i )
+ {
+ SdrObject *pO = (*pObjs)[MSHORT(i)];
+ if ( pO->IsWriterFlyFrame() )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+ if( pFly->IsAutoPos() && !::IsInProgress( pFly ) )
+ {
+ ++nAutoCnt;
+ ASSERT( pFly->IsFlyAtCntFrm(), "Not at content, but autopos.?" );
+ ((SwFlyAtCntFrm*)pFly)->CheckCharRect();
+ if( !pFly->IsValid() )
+ {
+ SwTwips nOldTop = pFly->Frm().Top();
+ pFly->Calc();
+ bRepeat = sal_True;
+ if( !nRepAdd && nOldTop >= pFly->Frm().Top() )
+ nRepAdd = 1;
+ }
+ }
+ }
+ }
+ if( nAutoCnt > 11 )
+ nMaxRepeat = nAutoCnt/4;
+ }
+ }
+ if( bRepeat )
+ nRepeat += nRepAdd;
+ else
+ nRepeat = 0;
+ }
+ else
+ nRepeat = 0;
+ } while( nRepeat );
+
+ ChgThisLines();
+
+#ifdef DEBUG
+ // Hier ein Instrumentarium, um ungewoehnlichen Master/Follow-Kombinationen,
+ // insbesondere bei Fussnoten, auf die Schliche zu kommen
+ if( IsFollow() || GetFollow() )
+ {
+ SwTxtFrm *pTmpFrm = IsFollow() ? FindMaster() : this;
+ const SwPageFrm *pTmpPage = pTmpFrm->FindPageFrm();
+ MSHORT nPgNr = pTmpPage->GetPhyPageNum();
+ MSHORT nLast;
+ MSHORT nDummy = 0; // nur zum Breakpoint setzen
+ while( pTmpFrm->GetFollow() )
+ {
+ pTmpFrm = pTmpFrm->GetFollow();
+ nLast = nPgNr;
+ pTmpPage = pTmpFrm->FindPageFrm();
+ nPgNr = pTmpPage->GetPhyPageNum();
+ if( nLast > nPgNr )
+ ++nDummy; // schon fast eine Assertion wert
+ else if( nLast == nPgNr )
+ ++nDummy; // bei Spalten voellig normal, aber sonst!?
+ else if( nLast < nPgNr - 1 )
+ ++nDummy; // kann schon mal temporaer vorkommen
+ }
+ }
+#endif
+}
+
+/*************************************************************************
+ * SwTxtFrm::FormatQuick()
+ *************************************************************************/
+// 6995:
+// return sal_False: Prepare(), HasPara(), InvalidateRanges(),
+
+sal_Bool SwTxtFrm::FormatQuick()
+{
+ DBG_LOOP;
+#ifdef DEBUG
+ const XubString aXXX = GetTxtNode()->GetTxt();
+ const SwTwips nDbgY = Frm().Top();
+#ifndef PRODUCT
+ // nStopAt laesst sich vom CV bearbeiten.
+ static MSHORT nStopAt = 0;
+ if( nStopAt == GetFrmId() )
+ {
+ int i = GetFrmId();
+ }
+#endif
+#endif
+
+ if( IsEmpty() && FormatEmpty() )
+ return sal_True;
+ // Wir sind sehr waehlerisch:
+ if( HasPara() || IsWidow() || IsLocked()
+ || !GetValidSizeFlag() || (Prt().Height() && IsHiddenNow()) )
+ return sal_False;
+
+ SwTxtLineAccess aAccess( this );
+ SwParaPortion *pPara = aAccess.GetPara();
+ if( !pPara )
+ return sal_False;
+
+ SwTxtFrmLocker aLock(this);
+ SwTxtFormatInfo aInf( this, sal_False, sal_True );
+ if( 0 != aInf.MaxHyph() ) // 27483: MaxHyphen beachten!
+ return sal_False;
+
+ SwTxtFormatter aLine( this, &aInf );
+
+ // DropCaps sind zu kompliziert...
+ if( aLine.GetDropFmt() )
+ return sal_False;
+
+ xub_StrLen nStart = GetOfst();
+ const xub_StrLen nEnd = GetFollow()
+ ? GetFollow()->GetOfst() : aInf.GetTxt().Len();
+ do
+ { DBG_LOOP;
+ nStart = aLine.FormatLine( nStart );
+ if( aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd) )
+ aLine.Insert( new SwLineLayout() );
+ } while( aLine.Next() );
+
+ // Last exit: die Hoehen muessen uebereinstimmen.
+ Point aTopLeft( Frm().Pos() );
+ aTopLeft += Prt().Pos();
+ const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
+ const SwTwips nOldHeight = aTopLeft.Y() + Prt().Height();
+ if( nNewHeight != nOldHeight && !IsUndersized() )
+ {
+#ifdef DEBUG
+// Achtung: Durch FormatLevel==12 kann diese Situation auftreten, don't panic!
+// ASSERT( nNewHeight == nOldHeight, "!FormatQuick: rosebud" );
+#endif
+ xub_StrLen nStrt = GetOfst();
+ _InvalidateRange( SwCharRange( nStrt, nEnd - nStrt) );
+ return sal_False;
+ }
+
+ if( pFollow && nStart != ((SwTxtFrm*)pFollow)->GetOfst() )
+ return sal_False; // kann z.B. durch Orphans auftreten (35083,35081)
+
+ // Geschafft, wir sind durch ...
+
+ // Repaint setzen
+ pPara->GetRepaint()->Pos( aTopLeft );
+ pPara->GetRepaint()->SSize( Prt().SSize() );
+
+ // Reformat loeschen
+ *(pPara->GetReformat()) = SwCharRange();
+ *(pPara->GetDelta()) = 0;
+
+ return sal_True;
+}
+
+
diff --git a/sw/source/core/text/frminf.cxx b/sw/source/core/text/frminf.cxx
new file mode 100644
index 000000000000..444928fd9c68
--- /dev/null
+++ b/sw/source/core/text/frminf.cxx
@@ -0,0 +1,409 @@
+/*************************************************************************
+ *
+ * $RCSfile: frminf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _PAM_HXX
+#include <pam.hxx> // GetSpaces
+#endif
+#ifndef _TXTCFG_HXX
+#include <txtcfg.hxx>
+#endif
+#ifndef _FRMINF_HXX
+#include <frminf.hxx> // SwTxtFrminfo
+#endif
+#ifndef _ITRTXT_HXX
+#include <itrtxt.hxx> // SwTxtMargin
+#endif
+#ifndef _SWFONT_HXX
+#include <swfont.hxx> // IsBullet()
+#endif
+
+
+/*************************************************************************
+ * SwTxtMargin::GetTxtStart()
+ *************************************************************************/
+
+xub_StrLen SwTxtMargin::GetTxtStart() const
+{
+ const XubString &rTxt = GetInfo().GetTxt();
+ const xub_StrLen nPos = nStart;
+ const xub_StrLen nEnd = nPos + pCurr->GetLen();
+ for( xub_StrLen i = nPos; i < nEnd; ++i )
+ {
+ const xub_Unicode aChar = rTxt.GetChar( i );
+ if( CH_TAB != aChar && ' ' != aChar )
+ return i;
+ }
+ return i;
+}
+
+/*************************************************************************
+ * SwTxtMargin::GetTxtEnd()
+ *************************************************************************/
+
+xub_StrLen SwTxtMargin::GetTxtEnd() const
+{
+ const XubString &rTxt = GetInfo().GetTxt();
+ const xub_StrLen nPos = nStart;
+ const xub_StrLen nEnd = nPos + pCurr->GetLen();
+ for( long i = nEnd - 1; i >= nPos; --i )
+ {
+ xub_Unicode aChar = rTxt.GetChar( i );
+ if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar )
+ return i + 1;
+ }
+ return i + 1;
+}
+
+/*************************************************************************
+ * SwTxtFrmInfo::IsOneLine()
+ *************************************************************************/
+
+// Passt der Absatz in eine Zeile?
+sal_Bool SwTxtFrmInfo::IsOneLine() const
+{
+ const SwLineLayout *pLay = pFrm->GetPara();
+ if( !pLay )
+ return sal_False;
+ else
+ {
+ // 6575: bei Follows natuerlich sal_False
+ if( pFrm->GetFollow() )
+ return sal_False;
+ pLay = pLay->GetNext();
+ while( pLay )
+ {
+ if( pLay->GetLen() )
+ return sal_False;
+ pLay = pLay->GetNext();
+ }
+ return sal_True;
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrmInfo::IsFilled()
+ *************************************************************************/
+
+// Ist die Zeile zu X% gefuellt?
+sal_Bool SwTxtFrmInfo::IsFilled( const sal_uInt8 nPercent ) const
+{
+ const SwLineLayout *pLay = pFrm->GetPara();
+ if( !pLay )
+ return sal_False;
+ else
+ {
+ long nWidth = pFrm->Prt().Width();
+ nWidth *= nPercent;
+ nWidth /= 100;
+ return KSHORT(nWidth) <= pLay->Width();
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrmInfo::GetLineStart()
+ *************************************************************************/
+
+// Wo beginnt der Text (ohne whitespaces)? ( Dokument global )
+SwTwips SwTxtFrmInfo::GetLineStart( const SwTxtCursor &rLine ) const
+{
+ SwTwips nTxtStart = rLine.GetTxtStart();
+ SwTwips nStart;
+ if( rLine.GetStart() == nTxtStart )
+ nStart = rLine.GetLineStart();
+ else
+ {
+ SwRect aRect;
+ if( ((SwTxtCursor&)rLine).GetCharRect( &aRect, nTxtStart ) )
+ nStart = aRect.Left();
+ else
+ nStart = rLine.GetLineStart();
+ }
+ return nStart;
+}
+
+
+/*************************************************************************
+ * SwTxtFrmInfo::GetLineStart()
+ *************************************************************************/
+
+// Wo beginnt der Text (ohne whitespaces)? (rel. im Frame)
+SwTwips SwTxtFrmInfo::GetLineStart() const
+{
+ SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+ SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+ return GetLineStart( aLine ) - pFrm->Frm().Left() - pFrm->Prt().Left();
+}
+
+// errechne die Position des Zeichens und gebe die Mittelposition zurueck
+SwTwips SwTxtFrmInfo::GetCharPos( xub_StrLen nChar, sal_Bool bCenter ) const
+{
+ SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+ SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+
+ SwTwips nStt, nNext;
+ SwRect aRect;
+ if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar ) )
+ nStt = aRect.Left();
+ else
+ nStt = aLine.GetLineStart();
+
+ if( !bCenter )
+ return nStt - pFrm->Frm().Left();
+
+ if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar+1 ) )
+ nNext = aRect.Left();
+ else
+ nNext = aLine.GetLineStart();
+
+ return (( nNext + nStt ) / 2 ) - pFrm->Frm().Left();
+}
+
+/*************************************************************************
+ * SwTxtFrmInfo::GetSpaces()
+ *************************************************************************/
+
+SwPaM *AddPam( SwPaM *pPam, const SwTxtFrm* pTxtFrm,
+ const xub_StrLen nPos, const xub_StrLen nLen )
+{
+ if( nLen )
+ {
+ // Es koennte auch der erste sein.
+ if( pPam->HasMark() )
+ {
+ // liegt die neue Position genau hinter der aktuellen, dann
+ // erweiter den Pam einfach
+ if( nPos == pPam->GetPoint()->nContent.GetIndex() )
+ {
+ pPam->GetPoint()->nContent += nLen;
+ return pPam;
+ }
+ pPam = new SwPaM( *pPam );
+ }
+
+ SwIndex &rContent = pPam->GetPoint()->nContent;
+ rContent.Assign( (SwTxtNode*)pTxtFrm->GetTxtNode(), nPos );
+ pPam->SetMark();
+ rContent += nLen;
+ }
+ return pPam;
+}
+
+// Sammelt die whitespaces am Zeilenbeginn und -ende im Pam
+void SwTxtFrmInfo::GetSpaces( SwPaM &rPam, sal_Bool bWithLineBreak ) const
+{
+ SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+ SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
+ SwPaM *pPam = &rPam;
+ sal_Bool bFirstLine = sal_True;
+ do {
+
+ if( aLine.GetCurr()->GetLen() )
+ {
+ xub_StrLen nPos = aLine.GetTxtStart();
+ // Bug 49649: von der ersten Line die Blanks/Tabs NICHT
+ // mit selektieren
+ if( !bFirstLine && nPos > aLine.GetStart() )
+ pPam = AddPam( pPam, pFrm, aLine.GetStart(),
+ nPos - aLine.GetStart() );
+
+ // Bug 49649: von der letzten Line die Blanks/Tabs NICHT
+ // mit selektieren
+ if( aLine.GetNext() )
+ {
+ nPos = aLine.GetTxtEnd();
+
+ if( nPos < aLine.GetEnd() )
+ {
+ MSHORT nOff = !bWithLineBreak && CH_BREAK ==
+ aLine.GetInfo().GetChar( aLine.GetEnd() - 1 )
+ ? 1 : 0;
+ pPam = AddPam( pPam, pFrm, nPos, aLine.GetEnd() - nPos - nOff );
+ }
+ }
+ }
+ bFirstLine = sal_False;
+ }
+ while( aLine.Next() );
+}
+
+/*************************************************************************
+ * SwTxtFrmInfo::IsBullet()
+ *************************************************************************/
+
+// Ist an der Textposition ein Bullet/Symbol etc?
+// Fonts: CharSet, SYMBOL und DONTKNOW
+sal_Bool SwTxtFrmInfo::IsBullet( xub_StrLen nTxtStart ) const
+{
+ SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+ SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
+ aInf.SetIdx( nTxtStart );
+ return aLine.IsSymbol( nTxtStart );
+}
+
+/*************************************************************************
+ * SwTxtFrmInfo::GetFirstIndent()
+ *************************************************************************/
+
+// Ermittelt Erstzeileneinzug
+// Voraussetzung fuer pos. oder neg. EZE ist, dass alle
+// Zeilen ausser der ersten Zeile den selben linken Rand haben.
+// Wir wollen nicht so knauserig sein und arbeiten mit einer Toleranz
+// von TOLERANCE Twips.
+
+#define TOLERANCE 20
+
+SwTwips SwTxtFrmInfo::GetFirstIndent() const
+{
+ SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+ SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+ const SwTwips nFirst = GetLineStart( aLine );
+ if( !aLine.Next() )
+ return 0;
+
+ SwTwips nLeft = GetLineStart( aLine );
+ while( aLine.Next() )
+ {
+ if( aLine.GetCurr()->GetLen() )
+ {
+ const SwTwips nCurrLeft = GetLineStart( aLine );
+ if( nLeft + TOLERANCE < nCurrLeft ||
+ nLeft - TOLERANCE > nCurrLeft )
+ return 0;
+ }
+ }
+
+ // Vorerst wird nur +1, -1 und 0 returnt.
+ if( nLeft == nFirst )
+ return 0;
+ else
+ if( nLeft > nFirst )
+ return -1;
+ else
+ return +1;
+}
+
+/*************************************************************************
+ * SwTxtFrmInfo::GetBigIndent()
+ *************************************************************************/
+
+KSHORT SwTxtFrmInfo::GetBigIndent( xub_StrLen& rFndPos,
+ const SwTxtFrm *pNextFrm ) const
+{
+ SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+ SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+ SwTwips nNextIndent = 0;
+
+ if( pNextFrm )
+ {
+ // ich bin einzeilig
+ SwTxtSizeInfo aNxtInf( (SwTxtFrm*)pNextFrm );
+ SwTxtCursor aNxtLine( (SwTxtFrm*)pNextFrm, &aNxtInf );
+ nNextIndent = GetLineStart( aNxtLine );
+ }
+ else
+ {
+ // ich bin mehrzeilig
+ if( aLine.Next() )
+ {
+ nNextIndent = GetLineStart( aLine );
+ aLine.Prev();
+ }
+ }
+
+ if( nNextIndent <= GetLineStart( aLine ) )
+ return 0;
+
+ const Point aPoint( nNextIndent, aLine.Y() );
+ rFndPos = aLine.GetCrsrOfst( 0, aPoint, sal_False );
+ if( 1 >= rFndPos )
+ return 0;
+
+ // steht vor einem "nicht Space"
+ const XubString& rTxt = aInf.GetTxt();
+ xub_Unicode aChar = rTxt.GetChar( rFndPos );
+ if( CH_TAB == aChar || CH_BREAK == aChar || ' ' == aChar ||
+ (( CH_TXTATR_BREAKWORD == aChar || CH_TXTATR_INWORD == aChar ) &&
+ aInf.HasHint( rFndPos ) ) )
+ return 0;
+
+ // und hinter einem "Space"
+ aChar = rTxt.GetChar( rFndPos - 1 );
+ if( CH_TAB != aChar && CH_BREAK != aChar &&
+ ( ( CH_TXTATR_BREAKWORD != aChar && CH_TXTATR_INWORD != aChar ) ||
+ !aInf.HasHint( rFndPos - 1 ) ) &&
+ // mehr als 2 Blanks !!
+ ( ' ' != aChar || ' ' != rTxt.GetChar( rFndPos - 2 ) ) )
+ return 0;
+
+ SwRect aRect;
+ return aLine.GetCharRect( &aRect, rFndPos )
+ ? KSHORT( aRect.Left() - pFrm->Frm().Left() - pFrm->Prt().Left())
+ : 0;
+}
+
+
+
diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx
new file mode 100644
index 000000000000..964d5a73bdb9
--- /dev/null
+++ b/sw/source/core/text/frmpaint.cxx
@@ -0,0 +1,738 @@
+/*************************************************************************
+ *
+ * $RCSfile: frmpaint.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:24 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _SV_SOUND_HXX //autogen
+#include <vcl/sound.hxx>
+#endif
+#ifndef _SV_SYSTEM_HXX //autogen
+#include <vcl/system.hxx>
+#endif
+
+#ifndef _SHL_HXX
+#include <tools/shl.hxx> // SW_MOD
+#endif
+
+#ifndef _FMTLINE_HXX
+#include <fmtline.hxx>
+#endif
+#ifndef _LINEINFO_HXX
+#include <lineinfo.hxx>
+#endif
+#ifndef _CHARFMT_HXX
+#include <charfmt.hxx>
+#endif
+#ifndef _PAGEFRM_HXX
+#include <pagefrm.hxx>
+#endif
+#ifndef _VIEWSH_HXX
+#include <viewsh.hxx> // ViewShell
+#endif
+#ifndef _VIEWIMP_HXX
+#include <viewimp.hxx> // SwViewImp
+#endif
+#ifndef _VIEWOPT_HXX
+#include <viewopt.hxx> // SwViewOption
+#endif
+#ifndef _FRMTOOL_HXX
+#include <frmtool.hxx> // DrawGraphic
+#endif
+#ifndef _FRMSH_HXX
+#include <frmsh.hxx>
+#endif
+#ifndef _TXTCFG_HXX
+#include <txtcfg.hxx>
+#endif
+#ifndef _TXTFRM_HXX
+#include <txtfrm.hxx> // SwTxtFrm
+#endif
+#ifndef _ITRPAINT_HXX
+#include <itrpaint.hxx> // SwTxtPainter
+#endif
+#ifndef _TXTPAINT_HXX
+#include <txtpaint.hxx> // SwSaveClip
+#endif
+#ifndef _TXTCACHE_HXX
+#include <txtcache.hxx> // SwTxtLineAccess
+#endif
+#ifndef _SWFNTCCH_HXX
+#include <swfntcch.hxx> // SwFontAccess
+#endif
+#ifndef _DRAWFONT_HXX
+#include <drawfont.hxx> // SwDrawTextInfo
+#endif
+#ifndef _FLYFRM_HXX
+#include <flyfrm.hxx> // SwFlyFrm
+#endif
+#ifndef _REDLNITR_HXX
+#include <redlnitr.hxx> // SwRedlineItr
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx> // SwDoc
+#endif
+#ifndef _SWMODULE_HXX
+#include <swmodule.hxx> // SW_MOD
+#endif
+#ifndef _TABFRM_HXX
+#include <tabfrm.hxx> // SwTabFrm (Redlining)
+#endif
+#include "scrrect.hxx"
+
+// steht im number.cxx
+extern const sal_Char __FAR_DATA sBulletFntName[];
+
+extern FASTBOOL bOneBeepOnly;
+
+sal_Bool bInitFont = sal_True;
+
+#define REDLINE_DISTANCE 567/4
+#define REDLINE_MINDIST 567/10
+
+class SwExtraPainter
+{
+ SwSaveClip aClip;
+ SwRect aRect;
+ ViewShell *pSh;
+ SwFont* pFnt;
+ const SwLineNumberInfo &rLineInf;
+ SwTwips nX;
+ SwTwips nRedX;
+ ULONG nLineNr;
+ MSHORT nDivider;
+ sal_Bool bGoLeft;
+ sal_Bool bLineNum;
+ inline sal_Bool IsClipChg() { return aClip.IsChg(); }
+public:
+ SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh,
+ const SwLineNumberInfo &rLnInf, const SwRect &rRct, MSHORT nStart,
+ SwHoriOrient eHor, sal_Bool bLnNm );
+ ~SwExtraPainter() { delete pFnt; }
+ inline SwFont* GetFont() const { return pFnt; }
+ inline void IncLineNr() { ++nLineNr; }
+ inline sal_Bool HasNumber() { return !( nLineNr % rLineInf.GetCountBy() ); }
+ inline HasDivider() { if( !nDivider ) return sal_False;
+ return !(nLineNr % rLineInf.GetDividerCountBy()); }
+
+ void PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed );
+ void PaintRedline( SwTwips nY, long nMax );
+};
+
+
+SwExtraPainter::SwExtraPainter( const SwTxtFrm *pFrm, ViewShell *pVwSh,
+ const SwLineNumberInfo &rLnInf, const SwRect &rRct, MSHORT nStart,
+ SwHoriOrient eHor, sal_Bool bLnNm )
+ : pSh( pVwSh ), pFnt( 0 ), rLineInf( rLnInf ), aRect( rRct ),
+ aClip( pVwSh->GetWin() || pFrm->IsUndersized() ? pVwSh->GetOut() : 0 ),
+ nLineNr( 1L ), bLineNum( bLnNm )
+{
+ if( pFrm->IsUndersized() )
+ {
+ SwTwips nBottom = pFrm->Frm().Bottom();
+ if( aRect.Bottom() > nBottom )
+ aRect.Bottom( nBottom );
+ }
+ MSHORT nVirtPageNum = 0;
+ if( bLineNum )
+ { /* initialisiert die Member, die bei Zeilennumerierung notwendig sind:
+
+ nDivider, wie oft ist ein Teilerstring gewuenscht, 0 == nie;
+ nX, X-Position der Zeilennummern;
+ pFnt, der Font der Zeilennummern;
+ nLineNr, die erste Zeilennummer;
+ bLineNum wird ggf.wieder auf sal_False gesetzt, wenn die Numerierung sich
+ komplett ausserhalb des Paint-Rechtecks aufhaelt. */
+ nDivider = rLineInf.GetDivider().Len() ? rLineInf.GetDividerCountBy() : 0;
+ nX = pFrm->Frm().Left();
+ SwCharFmt* pFmt = rLineInf.GetCharFmt( *((SwDoc*)pFrm->GetNode()->GetDoc()) );
+ ASSERT( pFmt, "PaintExtraData without CharFmt" );
+ pFnt = new SwFont( &pFmt->GetAttrSet() );
+ pFnt->Invalidate();
+ pFnt->ChgPhysFnt( pSh, pSh->GetOut() );
+ nLineNr += pFrm->GetAllLines() - pFrm->GetThisLines();
+ LineNumberPosition ePos = rLineInf.GetPos();
+ if( ePos != LINENUMBER_POS_LEFT && ePos != LINENUMBER_POS_RIGHT )
+ {
+ nVirtPageNum = pFrm->FindPageFrm()->GetVirtPageNum();
+ if( nVirtPageNum % 2 )
+ ePos = ePos == LINENUMBER_POS_INSIDE ?
+ LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
+ else
+ ePos = ePos == LINENUMBER_POS_OUTSIDE ?
+ LINENUMBER_POS_LEFT : LINENUMBER_POS_RIGHT;
+ }
+ if( LINENUMBER_POS_LEFT == ePos )
+ {
+ bGoLeft = sal_True;
+ nX -= rLineInf.GetPosFromLeft();
+ if( nX < aRect.Left() )
+ bLineNum = sal_False;
+ }
+ else
+ {
+ bGoLeft = sal_False;
+ nX += pFrm->Frm().Width() + rLineInf.GetPosFromLeft();
+ if( nX > aRect.Right() )
+ bLineNum = sal_False;
+ }
+ }
+ if( eHor != HORI_NONE )
+ {
+ if( HORI_INSIDE == eHor || HORI_OUTSIDE == eHor )
+ {
+ if( !nVirtPageNum )
+ nVirtPageNum = pFrm->FindPageFrm()->GetVirtPageNum();
+ if( nVirtPageNum % 2 )
+ eHor = eHor == HORI_INSIDE ? HORI_LEFT : HORI_RIGHT;
+ else
+ eHor = eHor == HORI_OUTSIDE ? HORI_LEFT : HORI_RIGHT;
+ }
+ const SwFrm* pTmpFrm = pFrm->FindTabFrm();
+ if( !pTmpFrm )
+ pTmpFrm = pFrm;
+ nRedX = HORI_LEFT == eHor ? pTmpFrm->Frm().Left() - REDLINE_DISTANCE :
+ pTmpFrm->Frm().Right() + REDLINE_DISTANCE;
+ }
+}
+
+/*************************************************************************
+ * SwExtraPainter::PaintExtra()
+ **************************************************************************/
+
+void SwExtraPainter::PaintExtra( SwTwips nY, long nAsc, long nMax, sal_Bool bRed )
+{
+ //Zeilennummer ist staerker als der Teiler
+ XubString aTmp( HasNumber() ? rLineInf.GetNumType().GetNumStr( nLineNr )
+ : rLineInf.GetDivider() );
+
+ SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), aTmp, 0, aTmp.Len(), 0, sal_False );
+ aDrawInf.SetSpace( 0 );
+ aDrawInf.SetWrong( NULL );
+ aDrawInf.SetLeft( 0 );
+ aDrawInf.SetRight( LONG_MAX );
+ sal_Bool bTooBig = pFnt->GetSize( pFnt->GetActual() ).Height() > nMax &&
+ pFnt->GetHeight( pSh, pSh->GetOut() ) > nMax;
+ SwFont* pTmpFnt;
+ if( bTooBig )
+ {
+ pTmpFnt = new SwFont( *GetFont() );
+ if( nMax >= 20 )
+ {
+ nMax *= 17;
+ nMax /= 20;
+ }
+ pTmpFnt->SetSize( Size( 0, nMax ), pTmpFnt->GetActual() );
+ }
+ else
+ pTmpFnt = GetFont();
+ Point aTmpPos( nX, nY + nAsc );
+ if( !IsClipChg() )
+ {
+ Size aSize = pTmpFnt->_GetTxtSize( pSh, pSh->GetOut(), aTmp );
+ if( bGoLeft )
+ aTmpPos.X() -= aSize.Width();
+ SwRect aRct( aTmpPos, aSize );
+ if( !aRect.IsInside( aRct ) && !aRct.Intersection( aRect ).IsEmpty() )
+ aClip.ChgClip( aRect );
+ }
+ else if( bGoLeft )
+ aTmpPos.X() -= pTmpFnt->_GetTxtSize( pSh, pSh->GetOut(), aTmp ).Width();
+ aDrawInf.SetPos( aTmpPos );
+ pTmpFnt->_DrawText( aDrawInf );
+ if( bTooBig )
+ delete pTmpFnt;
+ if( bRed )
+ {
+ long nDiff = bGoLeft ? nRedX - nX : nX - nRedX;
+ if( nDiff > REDLINE_MINDIST )
+ PaintRedline( nY, nMax );
+ }
+}
+
+void SwExtraPainter::PaintRedline( SwTwips nY, long nMax )
+{
+ Point aStart( nRedX, nY );
+ Point aEnd( nRedX, nY + nMax );
+ if( !IsClipChg() )
+ {
+ SwRect aRct( aStart, aEnd );
+ if( !aRect.IsInside( aRct ) && !aRct.Intersection( aRect ).IsEmpty() )
+ aClip.ChgClip( aRect );
+ }
+ const Color aOldCol( pSh->GetOut()->GetLineColor() );
+ pSh->GetOut()->SetLineColor( SW_MOD()->GetRedlineMarkColor() );
+ pSh->GetOut()->DrawLine( aStart, aEnd );
+ pSh->GetOut()->SetLineColor( aOldCol );
+}
+
+void SwTxtFrm::PaintExtraData( const SwRect &rRect ) const
+{
+ if( Frm().Top() > rRect.Bottom() || Frm().Bottom() < rRect.Top() )
+ return;
+ const SwTxtNode& rTxtNode = *GetTxtNode();
+ const SwLineNumberInfo &rLineInf = rTxtNode.GetDoc()->GetLineNumberInfo();
+ const SwFmtLineNumber &rLineNum = GetAttrSet()->GetLineNumber();
+ sal_Bool bLineNum = !IsInTab() && rLineInf.IsPaintLineNumbers() &&
+ ( !IsInFly() || rLineInf.IsCountInFlys() ) && rLineNum.IsCount();
+ SwHoriOrient eHor = (SwHoriOrient)SW_MOD()->GetRedlineMarkPos();
+ sal_Bool bRedLine = eHor != HORI_NONE;
+ if ( bLineNum || bRedLine )
+ {
+ if( IsLocked() || IsHiddenNow() || !Prt().Height() )
+ return;
+ ViewShell *pSh = GetShell();
+ SwExtraPainter aExtra( this, pSh, rLineInf, rRect,
+ rLineNum.GetStartValue(), eHor, bLineNum );
+
+ if( HasPara() )
+ {
+ SwTxtFrmLocker aLock((SwTxtFrm*)this);
+
+ SwTxtLineAccess aAccess( (SwTxtFrm*)this );
+ SwParaPortion *pPara = aAccess.GetPara();
+
+ OutputDevice *pOldRef = pSh->GetReferenzDevice();
+ pSh->SetReferenzDevice( NULL );
+ SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect );
+ pSh->SetReferenzDevice( pOldRef );
+
+ SwTxtPainter aLine( (SwTxtFrm*)this, &aInf );
+ sal_Bool bNoDummy = !aLine.GetNext(); // Nur eine Leerzeile!
+
+ while( aLine.Y() + aLine.GetLineHeight() <= rRect.Top() )
+ {
+ if( !aLine.GetCurr()->IsDummy() &&
+ ( rLineInf.IsCountBlankLines() ||
+ aLine.GetCurr()->HasCntnt() ) )
+ aExtra.IncLineNr();
+ if( !aLine.Next() )
+ return;
+ }
+
+ long nBottom = rRect.Bottom();
+
+ sal_Bool bNoPrtLine;
+ if( !( bNoPrtLine = 0 == GetMinPrtLine() ) )
+ {
+ while ( aLine.Y() < GetMinPrtLine() )
+ {
+ if( ( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
+ && !aLine.GetCurr()->IsDummy() )
+ aExtra.IncLineNr();
+ if( !aLine.Next() )
+ break;
+ }
+ bNoPrtLine = aLine.Y() >= GetMinPrtLine();
+ }
+ if( bNoPrtLine )
+ {
+ do
+ {
+ if( bNoDummy || !aLine.GetCurr()->IsDummy() )
+ {
+ sal_Bool bRed = bRedLine && aLine.GetCurr()->HasRedline();
+ if( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasCntnt() )
+ {
+ if( bLineNum &&
+ ( aExtra.HasNumber() || aExtra.HasDivider() ) )
+ {
+ KSHORT nTmpHeight, nTmpAscent;
+ aLine.CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+ aExtra.PaintExtra( aLine.Y(), nTmpAscent,
+ nTmpHeight, bRed );
+ bRed = sal_False;
+ }
+ aExtra.IncLineNr();
+ }
+ if( bRed )
+ aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight() );
+ }
+ } while( aLine.Next() && aLine.Y() <= nBottom );
+ }
+ }
+ else
+ {
+ bRedLine &= (MSHRT_MAX!=rTxtNode.GetDoc()->GetRedlinePos(rTxtNode));
+
+ if( bLineNum && rLineInf.IsCountBlankLines() &&
+ ( aExtra.HasNumber() || aExtra.HasDivider() ) )
+ {
+ aExtra.PaintExtra( Frm().Top()+Prt().Top(), aExtra.GetFont()
+ ->GetAscent( pSh, pSh->GetOut() ), Prt().Height(), bRedLine );
+ }
+ else if( bRedLine )
+ aExtra.PaintRedline( Frm().Top()+Prt().Top(), Prt().Height() );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::Paint()
+ *************************************************************************/
+
+SwRect SwTxtFrm::Paint()
+{
+#ifdef DEBUG
+ const SwTwips nDbgY = Frm().Top();
+#endif
+
+ // finger layout
+ ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
+
+ SwRect aRet( Prt() );
+ if ( IsEmpty() || !HasPara() )
+ aRet += Frm().Pos();
+ else
+ {
+ // AMA: Wir liefern jetzt mal das richtige Repaintrechteck zurueck,
+ // d.h. als linken Rand den berechneten PaintOfst!
+ SwRepaint *pRepaint = GetPara()->GetRepaint();
+ long l;
+ if( pRepaint->GetOfst() )
+ {
+ pRepaint->Left( pRepaint->GetOfst() );
+ pRepaint->SetOfst( 0 );
+ l = pRepaint->GetRightOfst();
+ if ( l && l < pRepaint->Right() )
+ pRepaint->Right( l );
+ }
+ l = Frm().Bottom();
+ if ( pRepaint->Bottom() > l )
+ pRepaint->Bottom( l );
+ aRet = *pRepaint;
+ }
+ ResetRepaint();
+ return aRet;
+}
+
+/*************************************************************************
+ * SwTxtFrm::Paint()
+ *************************************************************************/
+
+sal_Bool SwTxtFrm::PaintEmpty( const SwRect &rRect, sal_Bool bCheck ) const
+{
+ ViewShell *pSh = GetShell();
+ if( pSh && ( pSh->GetViewOptions()->IsParagraph() || bInitFont ) )
+ {
+ bInitFont = sal_False;
+ SwTxtFly aTxtFly( this );
+ aTxtFly.SetTopRule();
+ SwRect aRect;
+ if( bCheck && aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
+ return sal_False;
+ else if( OUTDEV_PRINTER != pSh->GetOut()->GetOutDevType() )
+ {
+ SwFont *pFnt;
+ const SwTxtNode& rTxtNode = *GetTxtNode();
+ if ( rTxtNode.HasSwAttrSet() )
+ {
+ const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() );
+ pFnt = new SwFont( pAttrSet );
+ }
+ else
+ {
+//FEATURE::CONDCOLL
+// SwFontAccess aFontAccess( GetTxtNode()->GetFmtColl() );
+ SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh );
+//FEATURE::CONDCOLL
+ pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
+ }
+
+ const SwDoc* pDoc = rTxtNode.GetDoc();
+ if( ::IsShowChanges( pDoc->GetRedlineMode() ) )
+ {
+ MSHORT nRedlPos = pDoc->GetRedlinePos( rTxtNode );
+ if( MSHRT_MAX != nRedlPos )
+ SwRedlineItr aRedln( rTxtNode, *pFnt, nRedlPos, sal_True );
+ }
+
+ if( pSh->GetViewOptions()->IsParagraph() && Prt().Height() )
+ {
+ const sal_Bool bAlter =
+ ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet( SW_LATIN ) )
+#if defined( PM2 )
+ || ( System::GetCharSet() != CHARSET_IBMPC_850 )
+#endif
+ ;
+
+ if( bAlter && COMPARE_EQUAL !=
+ pFnt->GetName( SW_LATIN ).CompareToAscii( sBulletFntName ) )
+ {
+ pFnt->SetFamily( FAMILY_DONTKNOW, SW_LATIN );
+ pFnt->SetName( XubString( sBulletFntName,
+ RTL_TEXTENCODING_MS_1252 ), SW_LATIN );
+ pFnt->SetStyleName( aEmptyStr, SW_LATIN );
+ pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, SW_LATIN );
+ }
+ pFnt->Invalidate();
+ pFnt->ChgPhysFnt( pSh, pSh->GetOut() );
+ Point aPos = Frm().Pos() + Prt().Pos();
+ SwSaveClip *pClip;
+ if( IsUndersized() )
+ {
+ pClip = new SwSaveClip( pSh->GetOut() );
+ pClip->ChgClip( rRect );
+ }
+ else
+ pClip = NULL;
+ aPos.Y() += pFnt->GetAscent( pSh, pSh->GetOut() );
+ const XubString aTmp( sal_Char( bAlter ? CH_PAR_ALTER : CH_PAR ),
+ RTL_TEXTENCODING_MS_1252 );
+ SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), aTmp, 0, 1, 0,
+ sal_False );
+ aDrawInf.SetLeft( rRect.Left() );
+ aDrawInf.SetRight( rRect.Right() );
+ aDrawInf.SetPos( aPos );
+ aDrawInf.SetSpace( 0 );
+ aDrawInf.SetWrong( NULL );
+ pFnt->_DrawText( aDrawInf );
+ delete pClip;
+ }
+ delete pFnt;
+ return sal_True;
+ }
+ }
+ else
+ return sal_True;
+ return sal_False;
+}
+
+/*************************************************************************
+ * SwTxtFrm::Paint()
+ *************************************************************************/
+
+void SwTxtFrm::Paint(const SwRect &rRect ) const
+{
+ ResetRepaint();
+ DBG_LOOP_RESET;
+ if( !IsEmpty() || !PaintEmpty( rRect, sal_True ) )
+ {
+#ifdef DEBUG
+ const SwTwips nDbgY = Frm().Top();
+#endif
+
+#ifdef DBGTXT
+ if( IsDbg( this ) )
+ DBTXTFRM << "Paint()" << endl;
+#endif
+ if( IsLocked() || IsHiddenNow() || !Prt().Height() )
+ return;
+
+ //Kann gut sein, dass mir der IdleCollector mir die gecachten
+ //Informationen entzogen hat.
+ if( !HasPara() )
+ {
+ ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" );
+ ((SwTxtFrm*)this)->GetFormatted();
+ if( IsEmpty() )
+ {
+ PaintEmpty( rRect, sal_False );
+ return;
+ }
+ if( !HasPara() )
+ {
+ ASSERT( !this, "+SwTxtFrm::Paint: missing format information" );
+ return;
+ }
+ }
+
+ // Waehrend wir painten, wollen wir nicht gestoert werden.
+ // Aber erst hinter dem Format() !
+ SwTxtFrmLocker aLock((SwTxtFrm*)this);
+
+ //Hier wird ggf. nur der Teil des TxtFrm ausgegeben, der sich veraendert
+ //hat und der in dem Bereich liegt, dessen Ausgabe angefordert wurde.
+ //Man kann jetzt auf die Idee kommen, dass der Bereich rRect ausgegeben
+ //werden _muss_ obwohl rRepaint gesetzt ist; in der Tat kann dieses
+ //Problem nicht formal vermieden werden. Gluecklicherweise koennen
+ //wir davon ausgehen, dass rRepaint immer dann leer ist, wenn der Frm
+ //komplett gepainted werden muss.
+ SwTxtLineAccess aAccess( (SwTxtFrm*)this );
+ SwParaPortion *pPara = aAccess.GetPara();
+
+ SwRepaint &rRepaint = *(pPara->GetRepaint());
+
+ // Das Recycling muss abgeschaltet werden, wenn wir uns im
+ // FlyCntFrm befinden, weil ein DrawRect fuer die Retusche der
+ // Zeile aufgerufen wird.
+ if( rRepaint.GetOfst() )
+ {
+ const SwFlyFrm *pFly = FindFlyFrm();
+ if( pFly && pFly->IsFlyInCntFrm() )
+ rRepaint.SetOfst( 0 );
+ }
+
+ // Hier holen wir uns den String fuer die Ausgabe, besonders
+ // die Laenge ist immer wieder interessant.
+
+ ViewShell *pSh = GetShell();
+ OutputDevice *pOldRef = pSh->GetReferenzDevice();
+ pSh->SetReferenzDevice( NULL );
+ SwTxtPaintInfo aInf( (SwTxtFrm*)this, rRect );
+ pSh->SetReferenzDevice( pOldRef );
+ aInf.SetWrongList( ( (SwTxtNode*)GetTxtNode() )->GetWrong() );
+ aInf.GetTxtFly()->SetTopRule();
+
+ SwTxtPainter aLine( (SwTxtFrm*)this, &aInf );
+ // Eine Optimierung, die sich lohnt: wenn kein freifliegender Frame
+ // in unsere Zeile ragt, schaltet sich der SwTxtFly einfach ab:
+ aInf.GetTxtFly()->Relax();
+
+ OutputDevice *pOut = aInf.GetOut();
+ const sal_Bool bOnWin = pSh->GetWin() != 0;
+
+ SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : 0 );
+
+ // Ausgabeschleife: Fuer jede Zeile ... (die noch zu sehen ist) ...
+ // rRect muss angepasst werden (Top+1, Bottom-1), weil der Iterator
+ // die Zeilen nahtlos aneinanderfuegt.
+ aLine.TwipsToLine( rRect.Top() + 1 );
+ long nBottom = rRect.Bottom();
+
+ sal_Bool bNoPrtLine;
+ if( !( bNoPrtLine = 0 == GetMinPrtLine() ) )
+ {
+ while ( aLine.Y() < GetMinPrtLine() && aLine.Next() )
+ ;
+ bNoPrtLine = aLine.Y() >= GetMinPrtLine();
+ }
+ if( bNoPrtLine )
+ {
+ do
+ { DBG_LOOP;
+ aLine.DrawTextLine( rRect, aClip, IsUndersized() );
+
+ } while( aLine.Next() && aLine.Y() <= nBottom );
+ }
+
+ // Einmal reicht:
+ if( aLine.IsPaintDrop() )
+ {
+#if NIE
+ if( !bRetouche )
+ {
+ const SvxBrushItem *pItem; SwRect aOrigRect;
+ GetBackgroundBrush( pItem, aOrigRect, sal_False, sal_True );
+ aInf.SetBack( pItem, aOrigRect );
+ }
+#endif
+ aLine.PaintDropPortion();
+ }
+
+#ifdef USED
+ if( pSh && pSh->GetViewOptions()->IsTest2() )
+ aInf.GetTxtFly()->ShowContour( pOut );
+#endif
+
+ // "Beep"
+ if( bOneBeepOnly && bOnWin &&
+ Frm().Top() + Prt().Top() + Prt().Height() < aLine.Y() &&
+ ( GetFollow() || IsFollow() || GetNext() ) )
+ {
+ bOneBeepOnly = sal_False;
+ Sound::Beep();
+ }
+ if( rRepaint.HasArea() )
+ rRepaint.Clear();
+ }
+}
+
+void SwTxtFrm::CriticalLines( const OutputDevice& rOut, SwStripes &rStripes,
+ long nOffs)
+{
+ GetFormatted();
+ if( HasPara() )
+ {
+ SwStripe aStripe( Frm().Top(), Prt().Top() );
+ if( Prt().Top() )
+ {
+ rStripes.Insert( aStripe, rStripes.Count() );
+ aStripe.Y() += Prt().Top();
+ }
+ SwLineLayout* pLay = GetPara();
+ do
+ {
+ SwTwips nBase = aStripe.GetY() + pLay->GetAscent();
+ if( rOut.LogicToPixel( Point( 0, nBase ) ).Y() !=
+ rOut.LogicToPixel( Point( 0, nBase - nOffs ) ).Y() +
+ rOut.LogicToPixel( Size( 0, nOffs ) ).Height() )
+ {
+ aStripe.Height() = pLay->GetRealHeight();
+ rStripes.Insert( aStripe, rStripes.Count() );
+ }
+ aStripe.Y() += pLay->GetRealHeight();
+ pLay = pLay->GetNext();
+ } while( pLay );
+ if( Prt().Top() + Prt().Height() < Frm().Height() )
+ {
+ aStripe.Height() = Frm().Height() - Prt().Top() - Prt().Height();
+ rStripes.Insert( aStripe, rStripes.Count() );
+ }
+ }
+ else if( Frm().Height() )
+ rStripes.Insert(SwStripe(Frm().Top(),Frm().Height()), rStripes.Count());
+}
+
+
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
new file mode 100644
index 000000000000..83f3420666ec
--- /dev/null
+++ b/sw/source/core/text/guess.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ * $RCSfile: guess.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include <ctype.h>
+
+#include "errhdl.hxx" // ASSERTs
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "guess.hxx"
+#include "inftxt.hxx" // SwTxtSizeInfo, SwTxtFormatInfo
+#include "swfont.hxx"
+#include "breakit.hxx"
+#include "viewsh.hxx"
+
+#ifndef _COM_SUN_STAR_TEXT_BREAKTYPE_HPP_
+#include <com/sun/star/text/BreakType.hpp>
+#endif
+
+#ifndef _WORDSEL_HXX //autogen
+#include <svtools/wordsel.hxx>
+#endif
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::linguistic;
+
+inline sal_Bool IsDelim( const xub_Unicode cCh )
+{
+ return ' ' == cCh;
+}
+
+/*************************************************************************
+ * SwTxtGuess::IsWordEnd
+ *************************************************************************/
+
+
+sal_Bool SwTxtGuess::IsWordEnd( const SwTxtSizeInfo &rInf, const xub_StrLen nPos )
+{
+ const xub_StrLen nEnd = rInf.GetIdx() + rInf.GetLen();
+
+ ASSERT( nPos <= nEnd, "WordEnd hinter Text?" );
+
+ // Das letzte Zeichen gilt immer als Wortende
+ if ( nPos >= nEnd )
+ return sal_True;
+
+ const XubString& rTxt = rInf.GetTxt();
+ xub_Unicode aChr = rTxt.GetChar( nPos );
+ xub_Unicode aChr1 = rTxt.GetChar( nPos + 1 );
+
+ // Bindestriche sind potentielle Wortenden mit folgenden Ausnahmen:
+ // es folgt ein weiterer Bindestrich
+ // es folgt Textmasse, vor dem Bindestrich sind nur Bindestriche und
+ // davor ein Blank ...
+ if( '-' == aChr )
+ {
+ if ( IsDelim( aChr1 ) )
+ return sal_True;
+ if ( !nPos || '-' == aChr1 )
+ return sal_False;
+ for ( xub_StrLen nCnt = nPos; nCnt && '-' == aChr; )
+ aChr = rTxt.GetChar( --nCnt );
+ return ( !IsDelim( aChr ) && '-' != aChr );
+ }
+
+ // sal_True, wenn nPos kein Blank ist, aber der darauffolgende
+ if( !IsDelim( aChr ) && IsDelim( aChr1 ) )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+
+/*************************************************************************
+ * _GetFwdWordEnd()
+ *
+ * Es wird die letzte Position im Wort zurueckgeliefert:
+ * Aus "123 456" wird "123" nicht "123 " !!!
+ * Sonderfaelle bei "-"
+ *************************************************************************/
+
+xub_StrLen _GetFwdWordEnd( const XubString& rTxt, xub_StrLen nFound,
+ const xub_StrLen nMaxPos )
+{
+ if( nFound == nMaxPos )
+ return nMaxPos;
+
+ // Suche von links nach rechts
+ // Die Spaces vor einem Wort gehoeren dazu:
+ for( ++nFound; nFound < nMaxPos && IsDelim( rTxt.GetChar( nFound ) ); ++nFound )
+ ;
+
+ if ( nFound == nMaxPos )
+ return nMaxPos;
+
+ // Sonderfall: Bindestrich
+ if ( '-' == rTxt.GetChar( nFound ) )
+ {
+ // Mal gucken, was vor den Bindestrichen los ist
+ for ( ; nFound && '-' == rTxt.GetChar( nFound ); --nFound )
+ ;
+ // Ist vor uns ein Wortteil oder Nichts?
+ const sal_Bool bPartOfWord = nFound && !IsDelim( rTxt.GetChar( nFound ) );
+ // Und wieder hinter die Bindestriche
+ for ( ++nFound; nFound && '-' == rTxt.GetChar( nFound ); ++nFound )
+ ;
+ if ( nFound > nMaxPos )
+ return nMaxPos;
+ if ( bPartOfWord || IsDelim( rTxt.GetChar( nFound ) ) )
+ return nFound - 1;
+ }
+
+ // Beim naechsten Space ist Schluss
+ for( ; nFound < nMaxPos; ++nFound )
+ {
+ if( IsDelim( rTxt.GetChar( nFound ) ) )
+ return nFound - 1;
+ if( '-' == rTxt.GetChar( nFound ) )
+ {
+ while ( '-' == rTxt.GetChar( nFound ) )
+ ++nFound;
+ if ( nFound > nMaxPos )
+ return nMaxPos;
+ else
+ return nFound - 1;
+ }
+ }
+ return nFound;
+}
+
+/*************************************************************************
+ * _GetBwdWordEnd()
+ *
+ * Es wird die letzte Position im Wort zurueckgeliefert:
+ * Aus "123 456" wird "123" nicht "123 " !!!
+ * Sonderfaelle bei "-"
+ *************************************************************************/
+
+xub_StrLen _GetBwdWordEnd( const XubString& rTxt, xub_StrLen nFound,
+ const xub_StrLen nMin )
+{
+ const xub_StrLen nStart = nFound;
+ if( !nFound )
+ return 0;
+
+ // Suche von rechts nach links
+ // Bloede Striche
+ for( ; nFound && '-' == rTxt.GetChar( nFound ); --nFound )
+ ;
+
+ // Bis zum Anfang der Textmasse.
+ for( ; nFound && !IsDelim( rTxt.GetChar( nFound ) ); --nFound )
+ {
+ if( '-' == rTxt.GetChar(nFound) && !ispunct( rTxt.GetChar(nFound+1) ) )
+ break;
+ }
+
+ if ( '-' == rTxt.GetChar( nFound ) )
+ {
+ xub_StrLen nOldFound = nFound;
+ // Mal gucken, was vor den Bindestrichen los ist
+ for ( ; nFound && '-' == rTxt.GetChar( nFound ); --nFound )
+ ;
+ // Ist vor uns ein Wortteil?
+ if( nFound && !IsDelim( rTxt.GetChar( nFound ) ) )
+ return nOldFound;
+ }
+
+ // Die Spaces hinter einem Wort gehoeren nicht dazu:
+ for( ; nFound > nMin; --nFound )
+ {
+ if( !IsDelim( rTxt.GetChar( nFound ) ) )
+ break;
+ }
+ if( nMin == nFound )
+ {
+ if( IsDelim( rTxt.GetChar( nFound ) ) )
+ {
+ while( ++nFound < nStart && IsDelim( rTxt.GetChar( nFound ) ) )
+ ;
+ --nFound;
+ }
+ else if( nMin )
+ --nFound;
+ }
+
+ return nFound;
+}
+
+/*************************************************************************
+ * SwTxtGuess::GetWordEnd
+ *************************************************************************/
+
+// Liefert die Wortgrenze je nach Suchrichtung zurueck.
+// Wortdelimitter sind (nach dem letzten Projekt-Parteitag) nur
+// noch Blanks.
+// Fuehrende Blanks gehoeren zum Wort, aus "XXX YYY" wird
+// "XXX" und " YYY".
+
+xub_StrLen SwTxtGuess::GetWordEnd( const SwTxtFormatInfo &rInf,
+ const xub_StrLen nPos, const sal_Bool bFwd ) const
+{
+ const xub_StrLen nMaxPos = rInf.GetIdx() + rInf.GetLen() - 1;
+ const xub_StrLen nIdx = nPos < nMaxPos ? nPos : nMaxPos;
+ return bFwd ? _GetFwdWordEnd( rInf.GetTxt(), nIdx, nMaxPos )
+ : _GetBwdWordEnd( rInf.GetTxt(), nIdx, rInf.GetLineStart() );
+}
+
+/*************************************************************************
+ * SwTxtGuess::Guess
+ *
+ * Nach Guess muessen folgende Verhaeltnisse vorliegen:
+ * Bsp: "XXX YYY", Umbruch beim 2.Space
+ * GetLeftPos() liefert das Ende des noch passenden Wortes: "XXX", 3
+ * GetRightPos() liefert den Beginn des nicht mehr passenden Wortes: " YYY"
+ * Wenn das Wort ganz passte, dann ist GetLeftPos() == GetRightPos().
+ * Etwas Verwirrung stiftet der Unterschied zwischen Position und Laenge:
+ * GetWord() arbeitet ausschliesslich mit String-Positionen, waehrend
+ * die Breiten per GetTxtSize() und damit ueber Laengen ermittelt werden.
+ * Die Laenge ist (nach Abzug des Offsets) immer genau um 1 groesser
+ * als die Position.
+ * Liefert zurueck, ob es noch passte...
+ *************************************************************************/
+
+sal_Bool SwTxtGuess::Guess( const SwTxtFormatInfo &rInf, const KSHORT nPorHeight )
+{
+ nLeftPos = nRightPos = rInf.GetIdx();
+ // Leere Strings sind immer 0
+ if( !rInf.GetLen() || !rInf.GetTxt().Len() )
+ {
+ nHeight = rInf.GetTxtHeight();
+ return sal_False;
+ }
+ ASSERT( rInf.GetIdx() < rInf.GetTxt().Len(),
+ "+SwTxtGuess::Guess: invalid SwTxtFormatInfo" );
+
+ nHeight = nPorHeight;
+
+ KSHORT nLineWidth = rInf.Width() - rInf.X();
+ const xub_StrLen nMaxLen = Min( xub_StrLen(rInf.GetTxt().Len() - rInf.GetIdx()),
+ rInf.GetLen() );
+ // Sonderfall: Zeichen breiter als Zeile
+ if( !nMaxLen || !nLineWidth )
+ {
+ nHeight = rInf.GetTxtHeight();
+ return sal_False;
+ }
+
+ if( !nHeight )
+ {
+ ASSERT( nHeight, "+SwTxtGuess::Guess: no height" );
+ nHeight = rInf.GetTxtHeight();
+ if( !nHeight )
+ nHeight = 1;
+ }
+
+ KSHORT nItalic = 0;
+ if( ITALIC_NONE != rInf.GetFont()->GetItalic() && !rInf.NotEOL() )
+ {
+#ifdef DEBUG
+ static MSHORT nDiv = 12;
+ nItalic = nHeight / nDiv;
+#else
+#ifdef MAC
+ nItalic = nHeight / 4;
+#else
+ nItalic = nHeight / 12;
+#endif
+#endif
+ if( nItalic >= nLineWidth )
+ {
+ nLeftWidth = nRightWidth = nItalic;
+ nLeftPos = nRightPos = rInf.GetIdx();
+ return sal_False;
+ }
+ else
+ nLineWidth -= nItalic;
+ }
+
+ // Kein GetTextBreak, wenn vermutlich alles passt
+ if ( long ( nLineWidth ) * 2 > long ( nMaxLen ) * nHeight )
+ {
+ nLeftWidth = rInf.GetTxtSize( rInf.GetIdx(), nMaxLen ).Width();
+
+ if ( nLeftWidth <= nLineWidth )
+ {
+ // Die Vermutung hat sich bewahrheitet
+ nLeftPos = nRightPos = rInf.GetIdx() + nMaxLen - 1;
+ nHeight = rInf.GetTxtHeight();
+ if( nItalic && ( nLeftPos + 1 ) >= rInf.GetTxt().Len() )
+ nLeftWidth += nItalic;
+ nRightWidth = nLeftWidth;
+ return sal_True;
+ }
+#ifdef DEBUG
+ nRightWidth = nLeftWidth; // nur zum Breakpoint setzen,
+ // Vermutung schlug fehl, teuer!
+#endif
+ }
+
+ nHeight = rInf.GetTxtHeight();
+
+ sal_Bool bHyph = rInf.IsHyphenate() && !rInf.IsHyphForbud();
+ xub_StrLen nHyphPos = 0;
+
+ if( bHyph )
+ nRightPos = rInf.GetTxtBreak( nLineWidth, rInf.GetIdx(), nMaxLen,
+ nHyphPos );
+ else
+ nRightPos = rInf.GetTxtBreak( nLineWidth, rInf.GetIdx(), nMaxLen );
+
+ if( nRightPos > rInf.GetIdx() + nMaxLen )
+ {
+ // passt noch auf die Zeile
+ nLeftPos = nRightPos = rInf.GetIdx() + nMaxLen - 1;
+ if( bHyph )
+ nHyphPos = nLeftPos;
+ nLeftWidth = nRightWidth =
+ rInf.GetTxtSize( rInf.GetIdx(), nMaxLen ).Width();
+ // Der folgende Vergleich sollte eigenlich immer sal_True ergeben, sonst
+ // hat es wohl bei GetTxtBreak einen Pixel-Rundungsfehler gegeben...
+ if ( nLeftWidth <= nLineWidth )
+ {
+ if( nItalic && ( nLeftPos + 1 ) >= rInf.GetTxt().Len() )
+ {
+ nLeftWidth += nItalic;
+ nRightWidth = nLeftWidth;
+ }
+ return sal_True;
+ }
+ }
+
+ if( IsDelim( rInf.GetChar( nRightPos ) ) )
+ {
+ nLeftPos = nRightPos;
+ while( nRightPos && IsDelim( rInf.GetChar( --nRightPos ) ) )
+ --nLeftPos;
+ }
+ else
+ {
+ nLeftPos = nRightPos;
+ if( pBreakIt->xBreak.is() )
+ {
+ LineBreakHyphenationOptions aHyphOpt;
+ Reference< XHyphenator > xHyph;
+ if( bHyph )
+ {
+ xHyph = rInf.GetVsh() ? rInf.GetVsh()->GetHyphenator()
+ : ::GetHyphenator();
+ aHyphOpt = LineBreakHyphenationOptions( xHyph, nHyphPos );
+ }
+ LineBreakResults aResult = pBreakIt->xBreak->getLineBreak( rInf.GetTxt(),
+ nRightPos, pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ),
+ rInf.GetIdx(), aHyphOpt, LineBreakUserOptions() );
+ nLeftPos = aResult.breakIndex;
+ if( nLeftPos == STRING_LEN )
+ nLeftPos = 0;
+ bHyph = aResult.breakType == BreakType::HYPHENATION;
+ if( bHyph )
+ xHyphWord = aResult.rHyphenatedWord;
+ else
+ xHyphWord = NULL;
+
+ if( nLeftPos )
+ {
+#ifdef DEBUG
+ static BOOL bTest = FALSE;
+ if( bTest && bHyph && nHyphPos )
+ {
+ WordSelection::ResetWordDelimiter();
+ xub_StrLen nWrdStart = WordSelection::GoStartWord( rInf.GetTxt(), nHyphPos );
+ xub_StrLen nLen = WordSelection::GoEndWord( rInf.GetTxt(), nWrdStart ) - nWrdStart;
+ if( nLen )
+
+ {
+ XubString aSelTxt( rInf.GetTxt().Copy(nWrdStart, nLen) );
+ MSHORT nMinTrail = 0;
+ if( nWrdStart + nLen > nHyphPos )
+ nMinTrail = nWrdStart + nLen - nHyphPos - 1;
+ xHyphWord = ((SwTxtFormatInfo&)rInf).HyphWord( aSelTxt, nMinTrail );
+ if( xHyphWord.is() )
+ nHyphPos = xHyphWord->getHyphenationPos() + nWrdStart;
+ }
+ }
+ else
+#endif
+ {
+ xub_StrLen nX = nLeftPos;
+ while( nX && IsDelim( rInf.GetChar( --nX ) ) )
+ nLeftPos = nX;
+ }
+ }
+ }
+ }
+ // nLeftPos = GetPrevEnd( rInf, nRightPos ); OLD_ITERATOR
+
+ if ( nLeftPos < rInf.GetIdx() )
+ nLeftPos = rInf.GetIdx();
+
+ if( !SwTxtGuess::IsWordEnd( rInf, nRightPos ) )
+ nRightPos = GetNextEnd( rInf, nRightPos );
+
+ nLeftWidth =
+ rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() ).Width();
+ // OLD_ITERATOR
+ // rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() + 1 ).Width();
+
+ bHyph = bHyph && ( nHyphPos > nLeftPos );
+
+ // Sicher ist sicher, robust gg. Rundungfehler in GetTxtBreak ...
+ if ( nLeftWidth > nLineWidth )
+ {
+ rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() + 1 ).Width();
+ bHyph = sal_False;
+ nLeftPos = GetPrevEnd( rInf, nLeftPos );
+ if ( nLeftPos < rInf.GetIdx() )
+ nLeftPos = rInf.GetIdx();
+ nRightPos = GetNextEnd( rInf, nLeftPos );
+ nLeftWidth =
+ rInf.GetTxtSize( rInf.GetIdx(), nLeftPos - rInf.GetIdx() + 1 ).Width();
+ }
+ nLeftWidth += nItalic;
+ nRightWidth = nLeftWidth;
+ return sal_False;
+}
+
+
diff --git a/sw/source/core/text/guess.hxx b/sw/source/core/text/guess.hxx
new file mode 100644
index 000000000000..32a13fb09ce2
--- /dev/null
+++ b/sw/source/core/text/guess.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * $RCSfile: guess.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _GUESS_HXX
+#define _GUESS_HXX
+
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+#ifndef _STRING_HXX //autogen
+#include <tools/string.hxx>
+#endif
+#ifndef _COM_SUN_STAR_LINGUISTIC_XHYPHENATEDWORD_HPP_
+#include <com/sun/star/linguistic/XHyphenatedWord.hpp>
+#endif
+
+#include "txttypes.hxx"
+#include "breakit.hxx"
+
+class SwTxtSizeInfo;
+class SwTxtFormatInfo;
+
+using namespace ::com::sun::star;
+
+/*************************************************************************
+ * class SwTxtGuess
+ *************************************************************************/
+
+class SwTxtGuess
+{
+ uno::Reference< linguistic::XHyphenatedWord > xHyphWord;
+ xub_StrLen nLeftPos; // untere Kante: Idx
+ xub_StrLen nRightPos; // obere Kante: Idx
+ KSHORT nLeftWidth; // untere Kante: Width
+ KSHORT nRightWidth; // obere Kante: Width
+ KSHORT nHeight; // die GetTxtSize()-Hoehe.
+ xub_StrLen GetWordEnd( const SwTxtFormatInfo &rInf,
+ const xub_StrLen nPos, const sal_Bool bFwd = sal_True ) const;
+public:
+ inline SwTxtGuess(): nLeftPos(0), nLeftWidth(0), nRightPos(0),
+ nRightWidth(0), nHeight(0)
+
+ { }
+
+ // liefert zuerueck, ob es noch passte
+ sal_Bool Guess( const SwTxtFormatInfo &rInf, const KSHORT nHeight );
+
+ inline xub_StrLen LeftPos() const { return nLeftPos; }
+ inline KSHORT LeftWidth() const { return nLeftWidth; }
+ inline xub_StrLen RightPos() const { return nRightPos; }
+ inline KSHORT RightWidth() const { return nRightWidth; }
+ inline KSHORT Height() const { return nHeight; }
+ inline uno::Reference< linguistic::XHyphenatedWord > HyphWord() const
+ { return xHyphWord; }
+
+ inline xub_StrLen GetPrevEnd( const SwTxtFormatInfo &rInf,
+ const xub_StrLen nPos ) const
+ { return GetWordEnd( rInf, nPos, sal_False ); }
+ inline xub_StrLen GetNextEnd( const SwTxtFormatInfo &rInf,
+ const xub_StrLen nPos ) const
+ { return GetWordEnd( rInf, nPos, sal_True ); }
+ static sal_Bool IsWordEnd( const SwTxtSizeInfo &rInf, const xub_StrLen nPos );
+};
+
+
+#endif
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
new file mode 100644
index 000000000000..54572000cdc6
--- /dev/null
+++ b/sw/source/core/text/inftxt.cxx
@@ -0,0 +1,1176 @@
+/*************************************************************************
+ *
+ * $RCSfile: inftxt.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include <sfx2/printer.hxx>
+#endif
+#ifndef _SVX_HYZNITEM_HXX //autogen
+#include <svx/hyznitem.hxx>
+#endif
+#ifndef _SVX_ESCPITEM_HXX //autogen
+#include <svx/escpitem.hxx>
+#endif
+
+#ifndef _SVX_SPLWRAP_HXX
+#include <svx/splwrap.hxx>
+#endif
+#ifndef _OFF_APP_HXX
+#include <offmgr/app.hxx>
+#endif
+#ifndef _LINGU_LNGPROPS_HHX_
+#include <lingu/lngprops.hxx>
+#endif
+#ifndef _UNO_LINGU_HXX
+#include <svx/unolingu.hxx>
+#endif
+
+#ifndef _TXATBASE_HXX //autogen
+#include <txatbase.hxx>
+#endif
+#ifndef _FMTINFMT_HXX //autogen
+#include <fmtinfmt.hxx>
+#endif
+#ifndef _SWMODULE_HXX //autogen
+#include <swmodule.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX //autogen
+#include <vcl/wrkwin.hxx>
+#endif
+#ifndef _SHL_HXX //autogen
+#include <tools/shl.hxx>
+#endif
+#ifndef _SV_SYSTEM_HXX //autogen
+#include <vcl/system.hxx>
+#endif
+#ifndef _VIEWSH_HXX
+#include <viewsh.hxx> // ViewShell
+#endif
+#ifndef _VIEWOPT_HXX
+#include <viewopt.hxx> // SwViewOptions
+#endif
+#ifndef _FRMTOOL_HXX
+#include <frmtool.hxx> // DrawGraphic
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx> // SwDoc
+#endif
+#ifndef _PARATR_HXX
+#include <paratr.hxx> // SwFmtDrop
+#endif
+#ifndef _ROOTFRM_HXX
+#include <rootfrm.hxx> // SwRootFrm
+#endif
+#ifndef _INFTXT_HXX
+#include <inftxt.hxx> // SwTxtInfo
+#endif
+#ifndef _SWFONT_HXX
+#include <swfont.hxx> // SwFont
+#endif
+#ifndef _TXTFLY_HXX
+#include <txtfly.hxx> // SwTxtPaintInfo
+#endif
+#ifndef _BLINK_HXX
+#include <blink.hxx> // SwBlink
+#endif
+#ifndef _NOTEURL_HXX
+#include <noteurl.hxx> // SwNoteURL
+#endif
+#ifndef _DRAWFONT_HXX
+#include <drawfont.hxx> // SwDrawTextInfo
+#endif
+#ifndef _PORFTN_HXX
+#include <porftn.hxx> // SwFtnPortion
+#endif
+#ifndef _FRMSH_HXX
+#include <frmsh.hxx>
+#endif
+
+using namespace ::com::sun::star;
+#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+
+// steht im number.cxx
+extern const sal_Char __FAR_DATA sBulletFntName[];
+
+extern void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh );
+
+#ifndef PRODUCT
+// Test2: WYSIWYG++
+// Test4: WYSIWYG debug
+static sal_Bool bDbgLow = sal_False;
+#endif
+
+#ifndef PRODUCT
+
+sal_Bool SwTxtSizeInfo::IsOptCalm() const { return !GetOpt().IsTest3(); }
+
+sal_Bool SwTxtSizeInfo::IsOptLow() const { return bDbgLow; }
+
+sal_Bool SwTxtSizeInfo::IsOptDbg() const { return GetOpt().IsTest4(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest1() const { return GetOpt().IsTest1(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest2() const { return GetOpt().IsTest2(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest3() const { return GetOpt().IsTest3(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest4() const { return GetOpt().IsTest4(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest5() const { return GetOpt().IsTest5(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest6() const { return GetOpt().IsTest6(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest7() const { return GetOpt().IsTest7(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest8() const { return GetOpt().IsTest8(); }
+
+#endif
+
+/*************************************************************************
+ * SwLineInfo::SwLineInfo()
+ *************************************************************************/
+
+void SwLineInfo::CtorInit( const SwAttrSet& rAttrSet )
+{
+ pRuler = &rAttrSet.GetTabStops();
+ pSpace = &rAttrSet.GetLineSpacing();
+ nDefTabStop = MSHRT_MAX;
+}
+
+/*************************************************************************
+ * SwTxtInfo::CtorInit()
+ *************************************************************************/
+
+void SwTxtInfo::CtorInit( SwTxtFrm *pFrm )
+{
+ pPara = pFrm->GetPara();
+ nTxtStart = pFrm->GetOfst();
+ if( !pPara )
+ {
+ ASSERT( pPara, "+SwTxtInfo::CTOR: missing paragraph information" );
+ pFrm->Format();
+ pPara = pFrm->GetPara();
+ }
+}
+
+SwTxtInfo::SwTxtInfo( const SwTxtInfo &rInf )
+ : pPara( ((SwTxtInfo&)rInf).GetParaPortion() ),
+ nTxtStart( rInf.GetTxtStart() )
+{ }
+
+#ifndef PRODUCT
+/*************************************************************************
+ * ChkOutDev()
+ *************************************************************************/
+// Sonderbehandlung: wenn pVsh->GetPrt() null ist, ist alles erlaubt
+
+void ChkOutDev( const SwTxtSizeInfo &rInf )
+{
+ const OutputDevice *pOut = rInf.GetOut();
+ const OutputDevice *pWin = rInf.GetWin();
+ const OutputDevice *pPrt = rInf.GetPrt();
+ ASSERT( pOut &&
+ ( !(rInf.GetVsh() && rInf.GetVsh()->GetPrt()) ||
+ (!pWin || OUTDEV_WINDOW == pWin->GetOutDevType()
+ || OUTDEV_VIRDEV == pWin->GetOutDevType() ) &&
+ (!pPrt || pPrt == pWin || OUTDEV_PRINTER == pPrt->GetOutDevType())
+ || ( OUTDEV_VIRDEV == pOut->GetOutDevType() ) ),
+ "ChkOutDev: invalid output device" );
+}
+#endif // PRODUCT
+
+inline xub_StrLen GetMinLen( const SwTxtSizeInfo &rInf )
+{
+ const xub_StrLen nInfLen = rInf.GetIdx() + rInf.GetLen();
+ return Min( rInf.GetTxt().Len(), nInfLen );
+}
+
+SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew )
+ : SwTxtInfo( rNew ),
+ pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
+ pOut(((SwTxtSizeInfo&)rNew).GetOut()),
+ pWin(((SwTxtSizeInfo&)rNew).GetWin()),
+ pPrt(((SwTxtSizeInfo&)rNew).GetPrt()),
+ pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
+ pFrm(rNew.pFrm),
+ pOpt(&rNew.GetOpt()),
+ pTxt(&rNew.GetTxt()),
+ nIdx(rNew.GetIdx()),
+ nLen(rNew.GetLen()),
+ bOnWin( rNew.OnWin() ),
+ bNotEOL( rNew.NotEOL() ),
+ bURLNotify( rNew.URLNotify() ),
+ bStopUnderFlow( rNew.StopUnderFlow() )
+{
+#ifndef PRODUCT
+ ChkOutDev( *this );
+#endif
+}
+
+void SwTxtSizeInfo::_SelectOut()
+{
+ ASSERT( pVsh, "Where's my ViewShell?" );
+ pOut = pVsh->GetOut();
+ if( bOnWin )
+ pWin = pOut;
+}
+
+void SwTxtSizeInfo::CtorInit( SwTxtFrm *pFrame, SwFont *pNewFnt,
+ const xub_StrLen nNewIdx, const xub_StrLen nNewLen )
+{
+ pFrm = pFrame;
+ SwTxtInfo::CtorInit( pFrm );
+ const SwTxtNode *pNd = pFrm->GetTxtNode();
+ pVsh = pFrm->GetShell();
+ if ( pVsh )
+ pOut = pVsh->GetOut();
+ else
+ {
+ //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
+ if ( pNd->GetDoc()->IsBrowseMode() ) //?!?!?!?
+ //in Ermangelung eines Besseren kann hier ja wohl nur noch das
+ //AppWin genommen werden?
+ pOut = GetpApp()->GetDefaultDevice();
+ else
+ pOut = pNd->GetDoc()->GetPrt(); //Muss es geben (oder sal_True uebergeben?)
+ }
+ pOpt = pVsh ? pVsh->GetViewOptions() : SW_MOD()->GetViewOption(pNd->GetDoc()->IsHTMLMode());//Options vom Module wg. StarONE
+ //Hier auf GetWin() abfragen nicht auf GetOut != PRINTER (SwFlyFrmFmt::MakeGraphic)
+ bOnWin = pVsh && ( pVsh->GetWin() ||
+ ( pOut && OUTDEV_PRINTER != pOut->GetOutDevType() && pOpt->IsPrtFormat() ) );
+ pWin = bOnWin ? pOut : 0;
+
+ // bURLNotify wird gesetzt, wenn MakeGraphic dies vorbereitet
+ bURLNotify = pNoteURL && !bOnWin
+ && (pOut && OUTDEV_PRINTER != pOut->GetOutDevType());
+
+
+ pFnt = pNewFnt;
+
+ if( 0 == ( pPrt = pVsh ? pVsh->GetReferenzDevice():0 ) )
+ pPrt = pNd->GetDoc()->GetPrt();
+ else
+ {
+ ASSERT( !bOnWin, "SwTxtSizeInfo: Funny ReferenzDevice" );
+ if( ((Printer*)pPrt)->IsValid() )
+ pOut = pPrt;
+ }
+ if ( pPrt && !((Printer*)pPrt)->IsValid() )
+ pPrt = 0;
+ pTxt = &pNd->GetTxt();
+#ifndef PRODUCT
+ ChkOutDev( *this );
+#endif
+ if( pVsh && pNd->GetDoc()->IsBrowseMode() &&
+ !pVsh->GetViewOptions()->IsPrtFormat() )
+ pPrt = pOut;
+ nIdx = nNewIdx;
+ nLen = nNewLen;
+ bNotEOL = sal_False;
+ bStopUnderFlow = sal_False;
+ bSpecialUnderline = sal_False;
+ SetLen( GetMinLen( *this ) );
+}
+
+SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew, const XubString &rTxt,
+ const xub_StrLen nIdx, const xub_StrLen nLen )
+ : SwTxtInfo( rNew ),
+ pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
+ pOut(((SwTxtSizeInfo&)rNew).GetOut()),
+ pWin(((SwTxtSizeInfo&)rNew).GetWin()),
+ pPrt(((SwTxtSizeInfo&)rNew).GetPrt()),
+ pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
+ pFrm( rNew.pFrm ),
+ pOpt(&rNew.GetOpt()),
+ pTxt(&rTxt),
+ nIdx(nIdx),
+ nLen(nLen),
+ bOnWin( rNew.OnWin() ),
+ bNotEOL( rNew.NotEOL() ),
+ bURLNotify( rNew.URLNotify() ),
+ bStopUnderFlow( rNew.StopUnderFlow() )
+{
+#ifndef PRODUCT
+ ChkOutDev( *this );
+#endif
+ SetLen( GetMinLen( *this ) );
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::SelectFont()
+ *************************************************************************/
+
+void SwTxtSizeInfo::SelectFont()
+{
+ // 8731: Der Weg muss ueber ChgPhysFnt gehen, sonst geraet
+ // der FontMetricCache durcheinander. In diesem Fall steht pLastMet
+ // auf dem alten Wert.
+ // Falsch: GetOut()->SetFont( GetFont()->GetFnt() );
+ GetFont()->Invalidate();
+ GetFont()->ChgPhysFnt( pVsh, GetOut() );
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::_NoteAnimation()
+ *************************************************************************/
+
+void SwTxtSizeInfo::_NoteAnimation()
+{
+ ASSERT( bOnWin, "NoteAnimation: Wrong Call" );
+ if( SwRootFrm::FlushVout() )
+ {
+ pOut = pVsh->GetOut();
+ pWin = pOut;
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::CtorInit()
+ *************************************************************************/
+
+void SwTxtPaintInfo::CtorInit( SwTxtFrm *pFrame, const SwRect &rPaint )
+{
+ SwTxtSizeInfo::CtorInit( pFrame );
+ aTxtFly.CtorInit( pFrame ),
+ aPaintRect = rPaint;
+ nSpaceIdx = 0;
+ pSpaceAdd = NULL;
+ pWrongList = NULL;
+#ifdef PRODUCT
+ pBrushItem = 0;
+#else
+ pBrushItem = ((SvxBrushItem*)-1);
+#endif
+}
+
+SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt )
+ : SwTxtSizeInfo( rInf, rTxt ),
+ aTxtFly( *rInf.GetTxtFly() ),
+ aPos( rInf.GetPos() ),
+ aPaintRect( rInf.GetPaintRect() ),
+ nSpaceIdx( rInf.GetSpaceIdx() ),
+ pSpaceAdd( rInf.GetpSpaceAdd() ),
+ pWrongList( rInf.GetpWrongList() ),
+ pBrushItem( rInf.GetBrushItem() )
+{ }
+
+SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf )
+ : SwTxtSizeInfo( rInf ),
+ aTxtFly( *rInf.GetTxtFly() ),
+ aPos( rInf.GetPos() ),
+ aPaintRect( rInf.GetPaintRect() ),
+ nSpaceIdx( rInf.GetSpaceIdx() ),
+ pSpaceAdd( rInf.GetpSpaceAdd() ),
+ pWrongList( rInf.GetpWrongList() ),
+ pBrushItem( rInf.GetBrushItem() )
+{ }
+
+/*************************************************************************
+ * SwTxtPaintInfo::_DrawText()
+ *************************************************************************/
+
+void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPor,
+ const xub_StrLen nStart, const xub_StrLen nLen,
+ const sal_Bool bKern, const sal_Bool bWrong )
+{
+ if( !nLen )
+ return;
+ if( GetFont()->IsBlink() && OnWin() && rPor.Width() )
+ {
+ if( !pBlink )
+ pBlink = new SwBlink();
+ pBlink->Insert( &rPor, aPos, GetTxtFrm() );
+ if( !pBlink->IsVisible() )
+ return;
+ }
+
+ short nSpaceAdd = ( rPor.IsBlankPortion() || rPor.IsDropPortion() ||
+ rPor.InNumberGrp() ) ? 0 : GetSpaceAdd();
+
+ const sal_Bool bBullet = OnWin() && GetOpt().IsBlank() && IsNoSymbol();
+ sal_Bool bTmpWrong = bWrong && OnWin() && GetOpt().IsOnlineSpell()
+ && !GetOpt().IsHideSpell();
+ SwDrawTextInfo aDrawInf( pFrm->GetShell(), *pOut,
+ rText, nStart, nLen, rPor.Width(), bBullet );
+ aDrawInf.SetLeft( GetPaintRect().Left() );
+ aDrawInf.SetRight( GetPaintRect().Right() );
+ aDrawInf.SetSpecialUnderline( bSpecialUnderline );
+ aDrawInf.SetSpace( nSpaceAdd );
+
+ if( GetTxtFly()->IsOn() )
+ {
+ // aPos muss als TopLeft vorliegen, weil die ClipRects sonst
+ // nicht berechnet werden koennen.
+ const Point aPoint( aPos.X(), aPos.Y() - rPor.GetAscent() );
+ const Size aSize( rPor.Width(), rPor.Height() );
+ aDrawInf.SetFont( pFnt );
+ aDrawInf.SetPos( aPoint );
+ aDrawInf.SetSize( aSize );
+ aDrawInf.SetAscent( rPor.GetAscent() );
+ aDrawInf.SetKern( bKern ? rPor.Width() : 0 );
+ aDrawInf.SetSpace( nSpaceAdd );
+ aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
+ GetTxtFly()->DrawTextOpaque( aDrawInf );
+ }
+ else
+ {
+ aDrawInf.SetPos( aPos );
+ if( bKern )
+ pFnt->_DrawStretchText( aDrawInf );
+ else
+ {
+ aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
+ aDrawInf.SetSpace( nSpaceAdd );
+ pFnt->_DrawText( aDrawInf );
+ }
+ }
+}
+
+/*************************************************************************
+ * GetDrawPos()
+ *************************************************************************/
+inline Point GetDrawPos( const Point &rPos, const SwLinePortion &rPor )
+{
+ // Bei Baselineausgabe muss der Ascent der Portion abgezogen werden.
+ // DrawRects sind immer per TopLeft.
+ return Point( rPos.X(), rPos.Y() - rPor.GetAscent() );
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawRect()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawRect( const SwRect &rRect, sal_Bool bNoGraphic,
+ sal_Bool bRetouche ) const
+{
+ if ( OnWin() || !bRetouche )
+ {
+ if( aTxtFly.IsOn() )
+ ((SwTxtPaintInfo*)this)->GetTxtFly()->
+ DrawFlyRect( pOut, rRect, *this, bNoGraphic );
+ else if ( bNoGraphic )
+ pOut->DrawRect( rRect.SVRect() );
+ else
+ {
+ ASSERT( ((SvxBrushItem*)-1) != pBrushItem, "DrawRect: Uninitialized BrushItem!" );
+ ::DrawGraphic( pBrushItem, pOut, aItemRect, rRect );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawRect()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawRect( const SwLinePortion &rPor ) const
+{
+ const Size aSize( rPor.Width(), rPor.Height() );
+ const SwRect aRect( GetDrawPos( aPos, rPor ), aSize );
+ DrawRect( aRect );
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawTab()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawTab( const SwLinePortion &rPor ) const
+{
+ if( OnWin() )
+ {
+ const Size aSize( rPor.Width(), rPor.Height() );
+ const Rectangle aRect( GetDrawPos( aPos, rPor ), aSize );
+#ifndef PRODUCT
+#ifdef DEBUG
+ if( IsOptDbg() )
+ pWin->DrawRect( aRect );
+#endif
+#endif
+ pOpt->PaintTab( pWin, aRect );
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawLineBreak()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawLineBreak( const SwLinePortion &rPor ) const
+{
+ if( OnWin() )
+ {
+ const Size aSize( pOpt->GetLineBreakWidth(pWin), rPor.Height() );
+ const Rectangle aRect( GetDrawPos( aPos, rPor ), aSize );
+ pOpt->PaintLineBreak( pWin, aRect );
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawPostIts()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawPostIts( const SwLinePortion &rPor, sal_Bool bScript ) const
+{
+ if( OnWin() && pOpt->IsPostIts() )
+ {
+ const Size aSize( pOpt->GetPostItsWidth( pWin ),
+ pFnt->GetHeight( pVsh, GetOut() ) );
+ const Point aTmp( aPos.X(), aPos.Y() - pFnt->GetAscent( pVsh, GetOut() ) );
+ const Rectangle aRect( aTmp, aSize );
+ pOpt->PaintPostIts( pWin, aRect, bScript ? COL_LIGHTGREEN : COL_YELLOW );
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawBackGround()
+ *************************************************************************/
+
+SwRect lcl_CalcRect( const SwTxtPaintInfo *pInf, const SwLinePortion &rPor )
+{
+ SwRect aRect( GetDrawPos( pInf->GetPos(), rPor ),
+ Size( rPor.Width(), rPor.Height() ) );
+ if( rPor.InTxtGrp() && pInf->GetSpaceAdd() )
+ aRect.Width( aRect.Width() +
+ ((SwTxtPortion&)rPor).CalcSpacing( pInf->GetSpaceAdd(), *pInf ) );
+
+ if( aRect.HasArea() )
+ {
+ ::SwAlignRect( aRect, (ViewShell*)pInf->GetVsh() );
+
+ if ( pInf->GetOut()->IsClipRegion() )
+ {
+ SwRect aClip( pInf->GetOut()->GetClipRegion().GetBoundRect() );
+ aRect.Intersection( aClip );
+ }
+ }
+ return aRect;
+}
+
+void SwTxtPaintInfo::DrawBackground( const SwLinePortion &rPor ) const
+{
+ ASSERT( OnWin(), "SwTxtPaintInfo::DrawBackground: printer polution ?" );
+
+ SwRect aRect = lcl_CalcRect( this, rPor );
+
+ if ( aRect.HasArea() )
+ {
+ OutputDevice *pOut = (OutputDevice*)GetOut();
+ Color aCol( COL_LIGHTGRAY );
+ const Color aOldColor( pOut->GetFillColor() );
+ sal_Bool bChgBrsh;
+ if( 0 != (bChgBrsh = aOldColor != aCol) )
+ pOut->SetFillColor( aCol );
+
+ DrawRect( aRect, sal_True );
+
+ if ( bChgBrsh )
+ pOut->SetFillColor( aOldColor );
+ }
+}
+
+void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const
+{
+ ASSERT( pFnt->GetBackColor(), "DrawBackBrush: Lost Color" );
+ SwRect aRect = lcl_CalcRect( this, rPor );
+
+ if( GetSpaceAdd() < 0 )
+ {
+ if( !rPor.GetPortion() || rPor.GetPortion()->InFixMargGrp() )
+ aRect.Width( aRect.Width() + GetSpaceAdd() );
+ }
+
+ if ( aRect.HasArea() )
+ {
+ OutputDevice *pOut = (OutputDevice*)GetOut();
+ const Color aOldColor( pOut->GetFillColor() );
+ sal_Bool bChgColor;
+ if( 0 != ( bChgColor = aOldColor != *pFnt->GetBackColor() ) )
+ pOut->SetFillColor( *pFnt->GetBackColor() );
+ DrawRect( aRect, sal_True, sal_False );
+ if( bChgColor )
+ pOut->SetFillColor( aOldColor );
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawViewOpt()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
+ const MSHORT nWhich ) const
+{
+ if( OnWin() )
+ {
+ sal_Bool bDraw = sal_False;
+ switch( nWhich )
+ {
+ case POR_FTN: if ( GetOpt().IsFootNote() )bDraw = sal_True; break;
+ case POR_TOX: if ( GetOpt().IsTox() ) bDraw = sal_True; break;
+ case POR_REF: if ( GetOpt().IsRef() ) bDraw = sal_True; break;
+ case POR_QUOVADIS:
+ case POR_NUMBER:
+ case POR_FLD:
+ case POR_URL:
+ case POR_HIDDEN: if ( GetOpt().IsField() ) bDraw = sal_True; break;
+ case POR_TAB: if ( GetOpt().IsTab() ) bDraw = sal_True; break;
+ case POR_SOFTHYPH: if ( GetOpt().IsSoftHyph() )bDraw = sal_True; break;
+ case POR_BLANK: if ( GetOpt().IsHardBlank())bDraw = sal_True; break;
+ default:
+ {
+ ASSERT( !this, "SwTxtPaintInfo::DrawViewOpt: don't know how to draw this" );
+ break;
+ }
+ }
+ if ( bDraw )
+ DrawBackground( rPor );
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::_NotifyURL()
+ *************************************************************************/
+
+void SwTxtPaintInfo::_NotifyURL( const SwLinePortion &rPor ) const
+{
+ ASSERT( pNoteURL, "NotifyURL: pNoteURL gone with the wind!" );
+ SwRect aRect = lcl_CalcRect( this, rPor );
+ if( aRect.HasArea() )
+ {
+ SwTxtNode *pNd = (SwTxtNode*)GetTxtFrm()->GetTxtNode();
+ SwIndex aIndex( pNd, GetIdx() );
+ SwTxtAttr *pAttr = pNd->GetTxtAttr( aIndex, RES_TXTATR_INETFMT );
+ if( pAttr )
+ {
+ const SwFmtINetFmt& rFmt = pAttr->GetINetFmt();
+ pNoteURL->InsertURLNote( rFmt.GetValue(), rFmt.GetTargetFrame(),
+ aRect );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::InitHyph()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::InitHyph( const sal_Bool bAutoHyph )
+{
+ const SwAttrSet& rAttrSet = GetTxtFrm()->GetTxtNode()->GetSwAttrSet();
+ const SvxHyphenZoneItem &rAttr = rAttrSet.GetHyphenZone();
+ MaxHyph() = rAttr.GetMaxHyphens();
+ sal_Bool bAuto = bAutoHyph || rAttr.IsHyphen();
+ if( bAuto || bInterHyph )
+ {
+ uno::Reference< beans::XPropertySet > xProp( ::GetLinguPropertySet() );
+ nHyphStart = nHyphWrdStart = STRING_LEN;
+ nHyphWrdLen = 0;
+
+ // save hyphenation relevant Lingu properties for later restoration
+ // before changing them
+ if( xProp.is() && !bRestoreHyphOptions )
+ {
+ // paraex.hxx zeigt, dass im Attribut nMinLead = nMinTrail = 0
+ // initialisiert wird.
+
+ sal_Int16 nTemp;
+ xProp->getPropertyValue( C2U(UPN_HYPH_MIN_LEADING) ) >>= nTemp;
+ nMinLeading = nTemp;
+ xProp->getPropertyValue( C2U(UPN_HYPH_MIN_LEADING) ) >>= nTemp;
+ nMinTrailing = nTemp;
+ // nMinWordLength = ; noch nicht am Absatz verwendet
+ INT16 nNewMinLeading = Max(rAttr.GetMinLead(), sal_uInt8(2));
+ INT16 nNewMinTrailing = rAttr.GetMinTrail();
+ bRestoreHyphOptions = (nMinLeading != nNewMinLeading) ||
+ (nMinTrailing != nNewMinTrailing);
+
+ if (bRestoreHyphOptions)
+ {
+ uno::Any aTemp;
+ aTemp <<= nNewMinLeading;
+ xProp->setPropertyValue( C2U(UPN_HYPH_MIN_LEADING), aTemp );
+ aTemp <<= nNewMinTrailing;
+ xProp->setPropertyValue( C2U(UPN_HYPH_MIN_TRAILING), aTemp );
+ }
+ }
+ }
+ return bAuto;
+}
+/*************************************************************************
+ * SwTxtFormatInfo::RestoreHyphOptions()
+ *************************************************************************/
+
+void SwTxtFormatInfo::RestoreHyphOptions()
+{
+ uno::Reference< beans::XPropertySet > xProp( ::GetLinguPropertySet() );
+ if (xProp.is())
+ {
+ uno::Any aVal;
+ aVal <<= (sal_Int16)nMinLeading;
+ xProp->setPropertyValue( C2U(UPN_HYPH_MIN_LEADING), aVal );
+ aVal <<= (sal_Int16)nMinTrailing;
+ xProp->setPropertyValue( C2U(UPN_HYPH_MIN_TRAILING), aVal );
+ //xProp->setPropertyValue( C2U(UPN_HYPH_MIN_WORDLENGTH), );
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::CtorInit()
+ *************************************************************************/
+
+void SwTxtFormatInfo::CtorInit( SwTxtFrm *pNewFrm, const sal_Bool bNewInterHyph,
+ const sal_Bool bNewQuick, const sal_Bool bTst )
+{
+ SwTxtPaintInfo::CtorInit( pNewFrm, SwRect() );
+ bQuick = bNewQuick;
+ bInterHyph = bNewInterHyph;
+
+ //! needs to be done in this order
+ nMinLeading = 2;
+ nMinTrailing = 2;
+ nMinWordLength = 0;
+ bRestoreHyphOptions = sal_False;
+ bAutoHyph = InitHyph();
+
+ bIgnoreFly = sal_False;
+ bShift = sal_False;
+ bDropInit = sal_False;
+ bTestFormat = bTst;
+ nLeft = 0;
+ nRight = 0;
+ nFirst = 0;
+ nRealWidth = 0;
+ nForcedLeftMargin = 0;
+ pRest = 0;
+ nLineHeight = 0;
+ SetLineStart(0);
+ Init();
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::IsHyphenate()
+ *************************************************************************/
+// Trennen oder nicht trennen, das ist hier die Frage:
+// - in keinem Fall trennen, wenn der Hyphenator ERROR zurueckliefert,
+// oder wenn als Sprache NOLANGUAGE eingestellt ist.
+// - ansonsten immer trennen, wenn interaktive Trennung vorliegt
+// - wenn keine interakt. Trennung, dann nur trennen, wenn im ParaFmt
+// automatische Trennung eingestellt ist.
+
+sal_Bool SwTxtFormatInfo::IsHyphenate() const
+{
+ if( !bInterHyph && !bAutoHyph )
+ return sal_False;
+
+ LanguageType eTmp = GetFont()->GetLanguage();
+ if( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp )
+ return sal_False;
+ uno::Reference< linguistic::XHyphenator > xHyph = GetVsh() ? GetVsh()->GetHyphenator() :
+ OFF_APP()->GetHyphenator();
+
+ if (bInterHyph && xHyph.is())
+ SvxSpellWrapper::CheckHyphLang( xHyph, eTmp );
+
+ if( !xHyph.is() || !xHyph->hasLocale( SvxCreateLocale(eTmp) ) )
+ return sal_False;
+ return sal_True;
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::GetDropFmt()
+ *************************************************************************/
+
+// Dropcaps vom SwTxtFormatter::CTOR gerufen.
+const SwFmtDrop *SwTxtFormatInfo::GetDropFmt() const
+{
+ const SwFmtDrop *pDrop = &GetTxtFrm()->GetTxtNode()->GetSwAttrSet().GetDrop();
+ if( 1 >= pDrop->GetLines() ||
+ ( !pDrop->GetChars() && !pDrop->GetWholeWord() ) )
+ pDrop = 0;
+ return pDrop;
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::Init()
+ *************************************************************************/
+
+void SwTxtFormatInfo::Init()
+{
+ // Nicht initialisieren: pRest, nLeft, nRight, nFirst, nRealWidth
+ X(0);
+ bArrowDone = bFull = bFtnDone = bErgoDone = bNumDone = bNoEndHyph =
+ bNoMidHyph = bStop = bNewLine = bUnderFlow = sal_False;
+ pRoot = 0;
+ pLast = 0;
+ pFly = 0;
+ pLastFld = 0;
+ pLastTab = 0;
+ pUnderFlow = 0;
+ cTabDecimal = 0;
+ nWidth = nRealWidth;
+ nForcedLeftMargin = 0;
+ nSoftHyphPos = 0;
+ cHookChar = 0;
+ SetIdx(0);
+ SetLen( GetTxt().Len() );
+ SetPaintOfst(0);
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::_CheckFtnPortion()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::_CheckFtnPortion( SwLineLayout* pCurr )
+{
+ KSHORT nHeight = pCurr->GetRealHeight();
+ SwLinePortion *pPor = pCurr->GetPortion();
+ sal_Bool bRet = sal_False;
+ while( pPor )
+ {
+ if( pPor->IsFtnPortion() && nHeight > ((SwFtnPortion*)pPor)->Orig() )
+ {
+ bRet = sal_True;
+ SetLineHeight( nHeight );
+ break;
+ }
+ pPor = pPor->GetPortion();
+ }
+ return bRet;
+}
+
+
+
+
+/*************************************************************************
+ * SwTxtFormatInfo::ScanPortionEnd()
+ *************************************************************************/
+xub_StrLen SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nEnd, sal_Bool bSkip )
+{
+ cHookChar = 0;
+ const xub_Unicode cTabDec = GetLastTab() ? (sal_Unicode)GetTabDecimal() : 0;
+ xub_StrLen i = GetIdx();
+ if ( bSkip && i < nEnd )
+ ++i;
+
+ for( ; i < nEnd; ++i )
+ {
+ const xub_Unicode cPos = GetChar( i );
+ switch( cPos )
+ {
+ case CH_TXTATR_BREAKWORD:
+ case CH_TXTATR_INWORD:
+ if( !HasHint( i ))
+ break;
+ // no break;
+
+ case CHAR_SOFTHYPHEN:
+ case CHAR_HARDHYPHEN:
+ case CHAR_HARDBLANK:
+ case CH_TAB:
+ case CH_BREAK:
+ cHookChar = cPos;
+ return i;
+
+ default:
+ if( cTabDec == cPos )
+ {
+ cHookChar = cPos;
+ return i;
+ }
+ }
+ }
+/*
+JP 07.08.00: old
+ if ( cTabDec )
+ for( ; i < nEnd; ++i )
+ {
+ const xub_Unicode cPos = GetChar( i );
+ if( cTabDec == cPos || CH_TAB == cPos || CH_BREAK == cPos ||
+ (( CH_TXTATR_BREAKWORD == cPos || CH_TXTATR_INWORD == cPos )
+ && HasHint( i ) ) )
+ {
+ cHookChar = cPos;
+ return i;
+ }
+ }
+ else
+ for( ; i < nEnd; ++i )
+ {
+ const xub_Unicode cPos = GetChar( i );
+ if( CH_TAB == cPos || CH_BREAK == cPos ||
+ ( ( CH_TXTATR_BREAKWORD == cPos || CH_TXTATR_INWORD == cPos )
+ && HasHint( i ) ) )
+ {
+ cHookChar = cPos;
+ return i;
+ }
+ }
+*/
+ return i;
+}
+
+/*************************************************************************
+ * class SwTxtSlot
+ *************************************************************************/
+
+SwTxtSlot::SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor )
+{
+ bOn = pPor->GetExpTxt( *pNew, aTxt );
+
+ // Der Text wird ausgetauscht...
+ if( bOn )
+ {
+ pInf = (SwTxtSizeInfo*)pNew;
+ nIdx = pInf->GetIdx();
+ nLen = pInf->GetLen();
+ pInf->SetLen( pPor->GetLen() );
+ pOldTxt = &(pInf->GetTxt());
+ pInf->SetTxt( aTxt );
+ pInf->SetIdx( 0 );
+ }
+}
+
+/*************************************************************************
+ * SwTxtSlot::~SwTxtSlot()
+ *************************************************************************/
+
+SwTxtSlot::~SwTxtSlot()
+{
+ if( bOn )
+ {
+ pInf->SetTxt( *pOldTxt );
+ pInf->SetIdx( nIdx );
+ pInf->SetLen( nLen );
+ }
+}
+
+/*************************************************************************
+ * class SwTxtSlotLen
+ *************************************************************************/
+
+SwTxtSlotLen::SwTxtSlotLen( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor,
+ const sal_Char *pCh )
+{
+ if( pCh )
+ {
+ aTxt = XubString( pCh, RTL_TEXTENCODING_MS_1252 );
+ bOn = sal_True;
+ }
+ else
+ bOn = pPor->GetExpTxt( *pNew, aTxt );
+
+ // Der Text wird ausgetauscht...
+ if( bOn )
+ {
+ pInf = (SwTxtSizeInfo*)pNew;
+ nIdx = pInf->GetIdx();
+ nLen = pInf->GetLen();
+ pOldTxt = &(pInf->GetTxt());
+ pInf->SetTxt( aTxt );
+ pInf->SetIdx( 0 );
+ pInf->SetLen( pInf->GetTxt().Len() );
+ }
+}
+
+/*************************************************************************
+ * SwTxtSlotLen::~SwTxtSlotLen()
+ *************************************************************************/
+
+SwTxtSlotLen::~SwTxtSlotLen()
+{
+ if( bOn )
+ {
+ pInf->SetTxt( *pOldTxt );
+ pInf->SetIdx( nIdx );
+ pInf->SetLen( nLen );
+ }
+}
+
+/*************************************************************************
+ * SwFontSave::SwFontSave()
+ *************************************************************************/
+
+SwFontSave::SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pNewFnt )
+ : pFnt( pNewFnt ? ((SwTxtSizeInfo&)rInf).GetFont() : 0 )
+{
+ if( pFnt )
+ {
+ pInf = &((SwTxtSizeInfo&)rInf);
+ if( pFnt->DifferentMagic( pNewFnt, pFnt->GetActual() ) )
+ {
+ pNewFnt->SetTransparent( sal_True );
+ pNewFnt->SetAlign( ALIGN_BASELINE );
+ pInf->SetFont( pNewFnt );
+ }
+ else
+ pFnt = 0;
+ pNewFnt->Invalidate();
+ pNewFnt->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() );
+ }
+}
+
+/*************************************************************************
+ * SwFontSave::~SwFontSave()
+ *************************************************************************/
+
+SwFontSave::~SwFontSave()
+{
+ if( pFnt )
+ {
+ // SwFont zurueckstellen
+ pFnt->Invalidate();
+ pInf->SetFont( pFnt );
+ }
+}
+
+/*************************************************************************
+ * SwDefFontSave::SwDefFontSave()
+ *************************************************************************/
+
+SwDefFontSave::SwDefFontSave( const SwTxtSizeInfo &rInf )
+ : pFnt( ((SwTxtSizeInfo&)rInf).GetFont() )
+{
+ bAlter = pFnt->GetFixKerning() ||
+ ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet(pFnt->GetActual()) )
+#if defined( PM2 )
+ || ( System::GetCharSet() != CHARSET_IBMPC_850 )
+#endif
+ ;
+
+ if( bAlter && COMPARE_EQUAL !=
+ pFnt->GetName( pFnt->GetActual() ).CompareToAscii( sBulletFntName ) )
+ {
+ pNewFnt = new SwFont( *pFnt );
+ pNewFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
+ pNewFnt->SetName( XubString( sBulletFntName,
+ RTL_TEXTENCODING_MS_1252 ), pFnt->GetActual() );
+ pNewFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
+ pNewFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
+ pNewFnt->SetFixKerning( 0 );
+ pInf = &((SwTxtSizeInfo&)rInf);
+ pNewFnt->Invalidate();
+ pInf->SetFont( pNewFnt );
+ }
+ else
+ {
+ pFnt = 0;
+ pNewFnt = 0;
+ }
+}
+
+/*************************************************************************
+ * SwDefFontSave::~SwDefFontSave()
+ *************************************************************************/
+
+SwDefFontSave::~SwDefFontSave()
+{
+ if( pFnt )
+ {
+ delete pNewFnt;
+ // SwFont zurueckstellen
+ pFnt->Invalidate();
+ pInf->SetFont( pFnt );
+ }
+}
+
+/*************************************************************************
+ * SwFtnSave::~SwFtnSave()
+ *************************************************************************/
+
+SwFtnSave::~SwFtnSave()
+{
+ if( pFnt )
+ {
+ // SwFont zurueckstellen
+ *pFnt = *pOld;
+ pFnt->GetTox() = pOld->GetTox();
+ pFnt->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() );
+ delete pOld;
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::ChgHyph()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::ChgHyph( const sal_Bool bNew )
+{
+ const sal_Bool bOld = bAutoHyph;
+ if( bAutoHyph != bNew )
+ {
+ bAutoHyph = bNew;
+ InitHyph( bNew );
+ // 5744: Sprache am Hyphenator einstellen.
+ if( pFnt )
+ pFnt->ChgPhysFnt( pVsh, pOut );
+ }
+ return bOld;
+}
+
+
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
new file mode 100644
index 000000000000..914c7e163237
--- /dev/null
+++ b/sw/source/core/text/inftxt.hxx
@@ -0,0 +1,807 @@
+/*************************************************************************
+ *
+ * $RCSfile: inftxt.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _INFTXT_HXX
+#define _INFTXT_HXX
+
+#include <com/sun/star/linguistic/XHyphenatedWord.hpp>
+
+#include "swtypes.hxx"
+#include "txttypes.hxx"
+#include "swrect.hxx"
+
+#include "txtfly.hxx"
+#include "swfont.hxx"
+#include "porlay.hxx"
+#include "txtfrm.hxx"
+#include "ndtxt.hxx"
+#include "txttypes.hxx"
+
+class Font;
+class OutputDevice;
+class SvxBrushItem;
+class SvxLineSpacingItem;
+class SvxTabStop;
+class SvxTabStopItem;
+class SwAttrSet;
+class SwField;
+class SwFldPortion;
+class SwFlyPortion;
+class SwFmtDrop;
+class SwFtnPortion;
+class SwLineHeightRule;
+class SwLineLayout;
+class SwLinePortion;
+class SwLineSpaceRule;
+class SwParaPortion;
+class SwTabPortion;
+class SwTxtFrm;
+class SwTxtSizeInfo;
+class SwViewOption;
+class ViewShell;
+class SwTxtFtn;
+
+/* Minimum: Prozentwert fuers kernen */
+#define MINKERNPERCENT 5
+#define ARROW_WIDTH 200
+
+#ifndef PRODUCT
+#define OPTCALM( rInf ) (rInf).IsOptCalm()
+#define OPTLOW( rInf ) (rInf).IsOptLow()
+#define OPTDBG( rInf ) (rInf).IsOptDbg()
+#else
+#define OPTCALM( rInf ) sal_True
+#define OPTLOW( rInf ) sal_False
+#define OPTDBG( rInf ) sal_False
+#endif
+
+/*************************************************************************
+ * class SwLineInfo
+ *************************************************************************/
+
+// Beruecksichtigt das Attribut LineSpace bei der Hoehen/Ascentberechnung.
+
+class SwLineInfo
+{
+ friend class SwTxtIter;
+
+ const SvxTabStopItem *pRuler;
+ const SvxLineSpacingItem *pSpace;
+ KSHORT nDefTabStop;
+ void CtorInit( const SwAttrSet& rAttrSet );
+ inline SwLineInfo() {}
+public:
+ inline SwLineInfo( const SwAttrSet& rAttrSet )
+ { CtorInit( rAttrSet ); }
+ // Liefert den Tabstop, der auf LinePos folgt, oder 0.
+ const SvxTabStop *GetTabStop( const KSHORT nLinePos,
+ const KSHORT nLeft,
+ const KSHORT nRight ) const;
+ inline const SvxLineSpacingItem *GetLineSpacing() const { return pSpace; }
+ inline KSHORT GetDefTabStop() const { return nDefTabStop; }
+ inline void SetDefTabStop( KSHORT nNew ) const
+ { ( (SwLineInfo*)this )->nDefTabStop = nNew; }
+// friend ostream &operator<<( ostream &rOS, const SwLineInfo &rInf );
+ friend SvStream &operator<<( SvStream &rOS, const SwLineInfo &rInf );
+};
+
+/*************************************************************************
+ * class SwTxtInfo
+ *************************************************************************/
+
+class SwTxtInfo
+{
+ // Implementation in txthyph.cxx
+ friend void SetParaPortion( SwTxtInfo *pInf, SwParaPortion *pRoot );
+ SwParaPortion *pPara;
+ xub_StrLen nTxtStart; // TxtOfst bei Follows
+
+protected:
+ inline SwTxtInfo() { }
+public:
+ void CtorInit( SwTxtFrm *pFrm );
+ SwTxtInfo( const SwTxtInfo &rInf );
+ inline SwTxtInfo( SwTxtFrm *pFrm ) { CtorInit( pFrm ); }
+ inline SwParaPortion *GetParaPortion() { return pPara; }
+ inline const SwParaPortion *GetParaPortion() const { return pPara; }
+ inline xub_StrLen GetTxtStart() const { return nTxtStart; }
+
+ friend SvStream &operator<<( SvStream &rOS, const SwTxtInfo &rInf );
+};
+
+/*************************************************************************
+ * class SwTxtSizeInfo
+ *************************************************************************/
+
+class SwTxtSizeInfo : public SwTxtInfo
+{
+protected:
+ ViewShell *pVsh;
+ OutputDevice *pOut;
+ OutputDevice *pWin;
+ OutputDevice *pPrt;
+ SwFont *pFnt;
+ SwTxtFrm *pFrm;
+ const SwViewOption *pOpt;
+ const XubString *pTxt;
+ xub_StrLen nIdx, nLen;
+ sal_Bool bOnWin : 1;
+ sal_Bool bNotEOL : 1;
+ sal_Bool bURLNotify : 1;
+ sal_Bool bStopUnderFlow : 1;// Underflow gestoppt z.B. von einer FlyPortion
+ sal_Bool bSpecialUnderline : 1; // Hoch/Tief-Unterstreichung auf der Grundlinie
+ sal_Bool bArrowDone : 1; // Pfeil nach links bei gescrollten Absaetzen
+ sal_Bool bFtnInside : 1; // the current line contains a footnote
+
+protected:
+ void _NoteAnimation();
+ void CtorInit( SwTxtFrm *pFrm, SwFont *pFnt = 0,
+ const xub_StrLen nIdx = 0,
+ const xub_StrLen nLen = STRING_LEN );
+ SwTxtSizeInfo() {}
+ void _SelectOut();
+public:
+ SwTxtSizeInfo( const SwTxtSizeInfo &rInf );
+ SwTxtSizeInfo( const SwTxtSizeInfo &rInf, const XubString &rTxt,
+ const xub_StrLen nIdx = 0,
+ const xub_StrLen nLen = STRING_LEN );
+
+ inline SwTxtSizeInfo( SwTxtFrm *pFrm, SwFont *pFnt = 0,
+ const xub_StrLen nIdx = 0,
+ const xub_StrLen nLen = STRING_LEN )
+ { CtorInit( pFrm, pFnt, nIdx, nLen ); }
+
+ inline sal_Bool OnWin() const { return bOnWin; }
+ inline void SetOnWin( const sal_Bool bNew ) { bOnWin = bNew; }
+ inline sal_Bool NotEOL() const { return bNotEOL; }
+ inline void SetNotEOL( const sal_Bool bNew ) { bNotEOL = bNew; }
+ inline sal_Bool URLNotify() const { return bURLNotify; }
+ inline void SetURLNotify( const sal_Bool bNew ) { bURLNotify = bNew; }
+ inline sal_Bool StopUnderFlow() const { return bStopUnderFlow; }
+ inline void SetStopUnderFlow( const sal_Bool bNew ) { bStopUnderFlow = bNew; }
+ inline sal_Bool SpecialUnderline() const { return bSpecialUnderline; }
+ inline void SetSpecialUnderline( const sal_Bool bNew )
+ { bSpecialUnderline = bNew; }
+ inline ViewShell *GetVsh() { return pVsh; }
+ inline const ViewShell *GetVsh() const { return pVsh; }
+ inline OutputDevice *GetOut() { return pOut; }
+ inline const OutputDevice *GetOut() const { return pOut; }
+ inline OutputDevice *GetWin() { return pWin; }
+ inline const OutputDevice *GetWin() const { return pWin; }
+ inline OutputDevice *GetPrt() { return pPrt; }
+ inline const OutputDevice *GetPrt() const { return pPrt; }
+ inline void SetWin( OutputDevice *pNewWin );
+ inline void SetPrt( OutputDevice *pNewPrt );
+ inline void SetPrtOut() { pOut = pPrt; bOnWin = sal_False; }
+ inline void SetWinOut() { pOut = pWin; bOnWin = sal_True; }
+ inline SwFont *GetFont() { return pFnt; }
+ inline const SwFont *GetFont() const { return pFnt; }
+ inline void SetFont( SwFont *pNew ) { pFnt = pNew; }
+ void SelectFont();
+ inline void SelectOut() const
+ { if( pVsh ) ((SwTxtSizeInfo*)this)->_SelectOut(); }
+
+ inline const SwViewOption &GetOpt() const { return *pOpt; }
+ inline const XubString &GetTxt() const { return *pTxt; }
+ inline const xub_Unicode GetChar( const xub_StrLen nPos ) const
+ { return pTxt->GetChar( nPos ); }
+
+ inline KSHORT GetTxtHeight() const;
+ inline SwPosSize GetTxtSize( const OutputDevice *pOut,
+ const XubString &rTxt, const xub_StrLen nIdx,
+ const xub_StrLen nLen ) const;
+ inline SwPosSize GetTxtSize() const;
+ inline SwPosSize GetTxtSize( const xub_StrLen nIdx, const xub_StrLen nLen )
+ const;
+ inline SwPosSize GetTxtSize( const XubString &rTxt ) const;
+ inline xub_StrLen GetTxtBreak( long nTxtWidth, const xub_StrLen nNewIdx,
+ const xub_StrLen nNewLen ) const;
+ inline xub_StrLen GetTxtBreak( long nTxtWidth, const xub_StrLen nNewIdx,
+ const xub_StrLen nNewLen, xub_StrLen& rExtraCharPos ) const;
+ inline KSHORT GetAscent() const;
+
+ inline xub_StrLen GetIdx() const { return nIdx; }
+ inline void SetIdx( const xub_StrLen nNew ) { nIdx = nNew; }
+ inline xub_StrLen GetLen() const { return nLen; }
+ inline void SetLen( const xub_StrLen nNew ) { nLen = nNew; }
+ inline void SetTxt( const XubString &rNew ){ pTxt = &rNew; }
+
+ friend SvStream &operator<<( SvStream &rOS, const SwTxtSizeInfo &rInf );
+
+// 7780: Keine Bullets beim Symbol-Zeichensatz!
+ inline sal_Bool IsNoSymbol() const
+ { return RTL_TEXTENCODING_SYMBOL != pFnt->GetCharSet( pFnt->GetActual() ); }
+
+ inline void NoteAnimation() const
+ { if( OnWin() ) ((SwTxtSizeInfo*)this)->_NoteAnimation(); }
+ // Home is where Your heart is...
+ inline SwTxtFrm *GetTxtFrm() { return pFrm; }
+ inline const SwTxtFrm *GetTxtFrm() const { return pFrm; }
+
+ inline sal_Bool HasHint( xub_StrLen nPos ) const
+ { return _HasHint( pFrm->GetTxtNode(), nPos ); }
+ static sal_Bool _HasHint( const SwTxtNode* pTxtNode, xub_StrLen nPos );
+
+#ifndef PRODUCT
+ sal_Bool IsOptCalm() const;
+ sal_Bool IsOptLow() const;
+ sal_Bool IsOptDbg() const;
+ sal_Bool IsOptTest1() const;
+ sal_Bool IsOptTest2() const;
+ sal_Bool IsOptTest3() const;
+ sal_Bool IsOptTest4() const;
+ sal_Bool IsOptTest5() const;
+ sal_Bool IsOptTest6() const;
+ sal_Bool IsOptTest7() const;
+ sal_Bool IsOptTest8() const;
+#endif
+};
+
+/*************************************************************************
+ * class SwTxtPaintInfo
+ *************************************************************************/
+
+class SwTxtPaintInfo : public SwTxtSizeInfo
+{
+ SwWrongList *pWrongList;
+ SvShorts *pSpaceAdd;
+ const SvxBrushItem *pBrushItem; // Fuer den Hintergrund
+ SwRect aItemRect; // ebenfalls fuer den Hintergrund
+ SwTxtFly aTxtFly; // FlyFrm-Berechnung
+ Point aPos; // Ausgabeposition
+ SwRect aPaintRect; // Original Ausgaberechteck (aus Layout-Paint)
+
+ MSHORT nSpaceIdx;
+ void _DrawText( const XubString &rText, const SwLinePortion &rPor,
+ const xub_StrLen nIdx, const xub_StrLen nLen,
+ const sal_Bool bKern, const sal_Bool bWrong = sal_False );
+
+ SwTxtPaintInfo &operator=(const SwTxtPaintInfo&);
+ void _NotifyURL( const SwLinePortion &rPor ) const;
+ void _DrawBackBrush( const SwLinePortion &rPor ) const;
+
+protected:
+#ifdef PRODUCT
+ SwTxtPaintInfo() { pFrm = 0; pWrongList = 0; pSpaceAdd = 0; pBrushItem = 0; }
+#else
+ SwTxtPaintInfo() { pFrm = 0; pWrongList = 0; pSpaceAdd = 0;
+ pBrushItem = ((SvxBrushItem*)-1); }
+#endif
+public:
+ SwTxtPaintInfo( const SwTxtPaintInfo &rInf );
+ SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt );
+
+ void CtorInit( SwTxtFrm *pFrame, const SwRect &rPaint );
+
+ void SetBack( const SvxBrushItem *pItem,
+ const SwRect &rRect ) { pBrushItem = pItem; aItemRect = rRect;}
+ const SvxBrushItem *GetBrushItem() const { return pBrushItem; }
+ const SwRect &GetBrushRect() const { return aItemRect; }
+
+ inline SwTxtPaintInfo( SwTxtFrm *pFrame, const SwRect &rPaint )
+ { CtorInit( pFrame, rPaint ); }
+
+ inline SwTwips X() const { return aPos.X(); }
+ inline void X( const long nNew ) { aPos.X() = nNew; }
+ inline SwTwips Y() const { return aPos.Y(); }
+ inline void Y( const SwTwips nNew ) { aPos.Y() = nNew; }
+
+ inline SwTxtFly *GetTxtFly() { return &aTxtFly; }
+ inline const SwTxtFly *GetTxtFly() const { return &aTxtFly; }
+ inline void DrawText( const XubString &rText, const SwLinePortion &rPor,
+ const xub_StrLen nIdx = 0,
+ const xub_StrLen nLen = STRING_LEN,
+ const sal_Bool bKern = sal_False) const;
+ inline void DrawText( const SwLinePortion &rPor, const xub_StrLen nLen,
+ const sal_Bool bKern = sal_False ) const;
+ inline void DrawWrongText( const SwLinePortion &rPor, const xub_StrLen nLen,
+ const sal_Bool bKern = sal_False ) const;
+ void DrawRect( const SwRect &rRect, sal_Bool bNoGraphic = sal_False,
+ sal_Bool bRetouche = sal_True ) const;
+ void DrawRect( const SwLinePortion &rPor ) const;
+ void DrawTab( const SwLinePortion &rPor ) const;
+ void DrawLineBreak( const SwLinePortion &rPor ) const;
+ void DrawPostIts( const SwLinePortion &rPor, sal_Bool bScript ) const;
+ void DrawBackground( const SwLinePortion &rPor ) const;
+ void DrawViewOpt( const SwLinePortion &rPor, const MSHORT nWhich ) const;
+ inline void DrawBackBrush( const SwLinePortion &rPor ) const
+ { if( pFnt->GetBackColor() ) _DrawBackBrush( rPor ); }
+
+ inline void NotifyURL( const SwLinePortion &rPor ) const
+ { if( URLNotify() ) _NotifyURL( rPor ); }
+
+ inline SwTwips GetPaintOfst() const;
+ inline void SetPaintOfst( const SwTwips nNew );
+ inline const Point &GetPos() const { return aPos; }
+ inline void SetPos( const Point &rNew ) { aPos = rNew; }
+
+ inline const SwRect &GetPaintRect() const { return aPaintRect; }
+ inline void SetPaintRect( const SwRect &rNew ) { aPaintRect = rNew; }
+
+ friend SvStream &operator<<( SvStream &rOS, const SwTxtPaintInfo &rInf );
+
+ inline const MSHORT GetSpaceIdx() const { return nSpaceIdx; }
+ inline void ResetSpaceIdx(){nSpaceIdx = 0; }
+ inline void IncSpaceIdx() { ++nSpaceIdx; }
+ inline void SetSpaceAdd( SvShorts *pNew ){ pSpaceAdd = pNew; }
+ inline SvShorts* GetpSpaceAdd() const { return pSpaceAdd; }
+ inline const short GetSpaceAdd() const
+ { return ( pSpaceAdd && nSpaceIdx < pSpaceAdd->Count() )
+ ? (*pSpaceAdd)[nSpaceIdx] : 0; }
+ inline void SetWrongList( SwWrongList *pNew ){ pWrongList = pNew; }
+ inline SwWrongList* GetpWrongList() const { return pWrongList; }
+
+};
+
+/*************************************************************************
+ * class SwTxtFormatInfo
+ *************************************************************************/
+
+class SwTxtFormatInfo : public SwTxtPaintInfo
+{
+ SwLineLayout *pRoot; // die Root der aktuellen Zeile (pCurr)
+ SwLinePortion *pLast; // die letzte Portion
+ SwFlyPortion *pFly; // die nachfolgende FlyPortion
+ SwFldPortion *pLastFld; // umgebrochenes Feld
+ SwLinePortion *pUnderFlow; // Unterlaufsituation: letzte Portion
+ SwLinePortion *pRest; // Rest ist der Beginn der naechsten Zeile
+
+ SwTabPortion *pLastTab; // die _letzte_ TabPortion
+
+ xub_StrLen nSoftHyphPos; // SoftHyphPos fuer Hyphenate
+ xub_StrLen nHyphStart; // TxtPos, an der die interakt.Tr.z.Z. steht
+ xub_StrLen nHyphWrdStart; // gefundene Wort-Position
+ xub_StrLen nHyphWrdLen; // gefundene Wort-Laenge
+ xub_StrLen nLineStart; // aktueller Zeilenbeginn im rTxt
+ KSHORT nLeft; // linker Rand
+ KSHORT nRight; // rechter Rand
+ KSHORT nFirst; // EZE
+ KSHORT nRealWidth; // "echte" Zeilenbreite
+ KSHORT nWidth; // "virtuelle" Zeilenbreite
+ KSHORT nLineHeight; // endgueltige Hoehe nach CalcLine
+ KSHORT nForcedLeftMargin; // Verschiebung des linken Rands wg. Rahmen
+
+ INT16 nMinLeading; // minimum number of chars before hyphenation point
+ INT16 nMinTrailing; // minimum number of chars after hyphenation point
+ INT16 nMinWordLength; // minimum length of word to be hyphenated
+ sal_Bool bRestoreHyphOptions : 1;
+ sal_Bool bFull : 1; // Zeile ist voll
+ sal_Bool bFtnDone : 1; // Ftn bereits formatiert
+ sal_Bool bErgoDone : 1; // ErgoDone bereits formatiert
+ sal_Bool bNumDone : 1; // bNumDone bereits formatiert
+ sal_Bool bStop : 1; // Sofort abbrechen, Zeile verwerfen.
+ sal_Bool bNewLine : 1; // Noch eine weitere Zeile formatieren.
+ sal_Bool bShift : 1; // Positionsaend.: Repaint bis auf Weiteres
+ sal_Bool bUnderFlow : 1; // Kontext: UnderFlow() ?
+ sal_Bool bInterHyph: 1; // interaktive Trennung ?
+ sal_Bool bAutoHyph : 1; // automatische Trennung ?
+ sal_Bool bDropInit : 1; // DropWidth einstellen.
+ sal_Bool bQuick : 1; // FormatQuick()
+ sal_Bool bNoEndHyph : 1; // Trennung am Zeilenende abgeschaltet wg. MaxHyphens
+ sal_Bool bNoMidHyph : 1; // Trennung vor Flies abgeschaltet wg. MaxHyphens
+ sal_Bool bIgnoreFly: 1; // FitToContent ignoriert Flies
+
+ xub_Unicode cTabDecimal; // das _aktuelle_ Dezimalzeichen
+ xub_Unicode cHookChar; // fuer Tabs in Feldern etc.
+ sal_uInt8 nMaxHyph; // max. Zeilenanz. aufeinanderfolg. Trenn.
+ sal_Bool bTestFormat; // Testformatierung aus WouldFit, keine Benachrichtigungen etc.
+
+ // Hyphenating ...
+ sal_Bool InitHyph( const sal_Bool bAuto = sal_False );
+ sal_Bool _CheckFtnPortion( SwLineLayout* pCurr );
+
+public:
+ void CtorInit( SwTxtFrm *pFrm,
+ const sal_Bool bInterHyph = sal_False, const sal_Bool bQuick = sal_False, const sal_Bool bTst = sal_False );
+ inline SwTxtFormatInfo( SwTxtFrm *pFrame, const sal_Bool bInterHyph = sal_False, const sal_Bool bQuick = sal_False,
+ const sal_Bool bTst = sal_False )
+ { CtorInit( pFrame, bInterHyph, bQuick, bTst ); }
+
+ inline KSHORT Width() const { return nWidth; }
+ inline void Width( const KSHORT nNew ) { nWidth = nNew; }
+ void Init();
+
+ // liefert die erste veraenderte Position im Absatz zurueck
+ inline xub_StrLen GetReformatStart() const;
+
+ // Raender
+ inline KSHORT Left() const { return nLeft; }
+ inline void Left( const KSHORT nNew ) { nLeft = nNew; }
+ inline KSHORT Right() const { return nRight; }
+ inline void Right( const KSHORT nNew ) { nRight = nNew; }
+ inline KSHORT First() const { return nFirst; }
+ inline void First( const KSHORT nNew ) { nFirst = nNew; }
+ inline KSHORT CurrLeft() const { return (nLineStart ? nLeft : nFirst); }
+ inline KSHORT RealWidth() const { return nRealWidth; }
+ inline void RealWidth( const KSHORT nNew ) { nRealWidth = nNew; }
+ inline KSHORT ForcedLeftMargin() const { return nForcedLeftMargin; }
+ inline void ForcedLeftMargin( const KSHORT nN ) { nForcedLeftMargin = nN; }
+
+ inline sal_uInt8 &MaxHyph() { return nMaxHyph; }
+ inline const sal_uInt8 &MaxHyph() const { return nMaxHyph; }
+
+ inline SwLineLayout *GetRoot() { return pRoot; }
+ inline const SwLineLayout *GetRoot() const { return pRoot; }
+
+ inline void SetRoot( SwLineLayout *pNew ) { pRoot = pNew; }
+ inline SwLinePortion *GetLast() { return pLast; }
+ inline void SetLast( SwLinePortion *pNewLast ) { pLast = pNewLast; }
+ inline sal_Bool IsFull() const { return bFull; }
+ inline void SetFull( const sal_Bool bNew ) { bFull = bNew; }
+ inline sal_Bool IsHyphForbud() const
+ { return pFly ? bNoMidHyph : bNoEndHyph; }
+ inline void SetHyphForbud( const sal_Bool bNew )
+ { if ( pFly ) bNoMidHyph = bNew; else bNoEndHyph = bNew; }
+ inline void ChkNoHyph( const sal_uInt8 bEnd, const sal_uInt8 bMid )
+ { bNoEndHyph = (nMaxHyph && bEnd >= nMaxHyph);
+ bNoMidHyph = (nMaxHyph && bMid >= nMaxHyph); }
+ inline sal_Bool IsIgnoreFly() const { return bIgnoreFly; }
+ inline void SetIgnoreFly( const sal_Bool bNew ) { bIgnoreFly = bNew; }
+ inline sal_Bool IsStop() const { return bStop; }
+ inline void SetStop( const sal_Bool bNew ) { bStop = bNew; }
+ inline SwLinePortion *GetRest() { return pRest; }
+ inline void SetRest( SwLinePortion *pNewRest ) { pRest = pNewRest; }
+ inline sal_Bool IsNewLine() const { return bNewLine; }
+ inline void SetNewLine( const sal_Bool bNew ) { bNewLine = bNew; }
+ inline sal_Bool IsShift() const { return bShift; }
+ inline void SetShift( const sal_Bool bNew ) { bShift = bNew; }
+ inline sal_Bool IsInterHyph() const { return bInterHyph; }
+ inline sal_Bool IsAutoHyph() const { return bAutoHyph; }
+ inline sal_Bool IsUnderFlow() const { return bUnderFlow; }
+ inline void ClrUnderFlow() { bUnderFlow = sal_False; }
+ inline sal_Bool IsDropInit() const { return bDropInit; }
+ inline void SetDropInit( const sal_Bool bNew ) { bDropInit = bNew; }
+ inline sal_Bool IsQuick() const { return bQuick; }
+ inline sal_Bool IsTest() const { return bTestFormat; }
+
+ inline xub_StrLen GetLineStart() const { return nLineStart; }
+ inline void SetLineStart( const xub_StrLen nNew ) { nLineStart = nNew; }
+ inline KSHORT GetLineHeight() const { return nLineHeight; }
+ inline void SetLineHeight( const KSHORT nNew ) { nLineHeight = nNew; }
+
+ inline const SwLinePortion *GetUnderFlow() const { return pUnderFlow; }
+ inline SwLinePortion *GetUnderFlow() { return pUnderFlow; }
+ inline void SetUnderFlow( SwLinePortion *pNew )
+ { pUnderFlow = pNew; bUnderFlow = sal_True; }
+ inline xub_StrLen GetSoftHyphPos() const { return nSoftHyphPos; }
+ inline void SetSoftHyphPos( const xub_StrLen nNew ) { nSoftHyphPos = nNew; }
+
+ inline void SetParaFtn();
+
+ // FlyFrms
+ inline SwFlyPortion *GetFly() { return pFly; }
+ inline void SetFly( SwFlyPortion *pNew ) { pFly = pNew; }
+
+ inline const SwAttrSet& GetCharAttr() const;
+
+ // Tabs
+ inline SwTabPortion *GetLastTab() { return pLastTab; }
+ inline void SetLastTab( SwTabPortion *pNew ) { pLastTab = pNew; }
+ inline xub_Unicode GetTabDecimal() const { return cTabDecimal; }
+ inline void SetTabDecimal( const xub_Unicode cNew ) { cTabDecimal = cNew;}
+
+ // Last*
+ inline SwFldPortion *GetLastFld() { return pLastFld; }
+ inline void SetLastFld( SwFldPortion *pNew ) { pLastFld = pNew; }
+
+ inline void ClearHookChar() { cHookChar = 0; }
+ inline void SetHookChar( const xub_Unicode cNew ) { cHookChar = cNew; }
+ inline xub_Unicode GetHookChar() const { return cHookChar; }
+
+ // Done-Flags
+ inline sal_Bool IsFtnDone() const { return bFtnDone; }
+ inline void SetFtnDone( const sal_Bool bNew ) { bFtnDone = bNew; }
+ inline sal_Bool IsErgoDone() const { return bErgoDone; }
+ inline void SetErgoDone( const sal_Bool bNew ) { bErgoDone = bNew; }
+ inline sal_Bool IsNumDone() const { return bNumDone; }
+ inline void SetNumDone( const sal_Bool bNew ) { bNumDone = bNew; }
+ inline sal_Bool IsArrowDone() const { return bArrowDone; }
+ inline void SetArrowDone( const sal_Bool bNew ) { bArrowDone = bNew; }
+ inline sal_Bool IsFtnInside() const { return bFtnInside; }
+ inline void SetFtnInside( const sal_Bool bNew ) { bFtnInside = bNew; }
+
+
+ // Fuer SwTxtPortion::Hyphenate
+ inline sal_Bool IsSoftHyph( const xub_StrLen nPos ) const;
+ sal_Bool ChgHyph( const sal_Bool bNew );
+
+ // Soll die Trennhilfe angeschmissen werden?
+ sal_Bool IsHyphenate() const;
+ inline void SetHyphStart( const xub_StrLen nNew ) { nHyphStart = nNew; }
+ inline xub_StrLen GetHyphStart() const { return nHyphStart; }
+ inline void SetHyphWrdStart( const xub_StrLen nNew ) { nHyphWrdStart = nNew; }
+ inline xub_StrLen GetHyphWrdStart() const { return nHyphWrdStart; }
+ inline void SetHyphWrdLen( const xub_StrLen nNew ) { nHyphWrdLen = nNew; }
+ inline xub_StrLen GetHyphWrdLen() const { return nHyphWrdLen; }
+
+ inline sal_Bool IsRestoreHyphOptions() const { return bRestoreHyphOptions; }
+ void RestoreHyphOptions();
+ // ruft HyphenateWord() des Hyphenators
+ ::com::sun::star::uno::Reference< ::com::sun::star::linguistic::XHyphenatedWord>
+ HyphWord( const String &rTxt, const USHORT nMinTrail );
+
+ sal_Bool CheckFtnPortion( SwLineLayout* pCurr )
+ { return IsFtnInside() && _CheckFtnPortion( pCurr ); }
+
+ // Dropcaps vom SwTxtFormatter::CTOR gerufen.
+ const SwFmtDrop *GetDropFmt() const;
+
+ // setzt die FormatInfo wieder in den Anfangszustand
+ void Reset( const SwTxtFrm *pFrame); // , const sal_Bool bAll );
+
+ // Sucht ab nIdx bis nEnd nach Tabs, TabDec, TXTATR und BRK.
+ // Return: gefundene Position, setzt ggf. cHookChar
+ xub_StrLen ScanPortionEnd( const xub_StrLen nEnd, sal_Bool bSkip = sal_False );
+
+// friend ostream &operator<<( ostream &rOS, const SwTxtFormatInfo &rInf );
+ friend SvStream &operator<<( SvStream &rOS, const SwTxtFormatInfo &rInf );
+};
+
+/*************************************************************************
+ * class SwTxtSlot
+ *************************************************************************/
+
+// Fuer die Textersetzung und Restaurierung der SwTxtSizeInfo.
+// Die Art und Weise ist etwas kriminell, rInf ist const und wird
+// trotzdem veraendert. Da rInf im DTOR wieder restauriert wird,
+// ist dies zulaessig, es handelt sich um ein "logisches const".
+// Die beiden Klassen SwTxtSlot und SwTxtSlotLen sind Zwillinge, sie
+// unterscheiden sich nur im Ctor in der Zuweisung der Textlaenge
+// an pInf. Aenderungen muessen in beiden gepflegt werden!
+
+class SwTxtSlot
+{
+ const XubString *pOldTxt;
+ XubString aTxt;
+ xub_StrLen nIdx;
+ xub_StrLen nLen;
+ sal_Bool bOn;
+protected:
+ SwTxtSizeInfo *pInf;
+public:
+ SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor );
+ ~SwTxtSlot();
+ inline sal_Bool IsOn() const { return bOn; }
+};
+
+class SwTxtSlotLen
+{
+ const XubString *pOldTxt;
+ XubString aTxt;
+ xub_StrLen nIdx;
+ xub_StrLen nLen;
+ sal_Bool bOn;
+protected:
+ SwTxtSizeInfo *pInf;
+public:
+ // Der Ersetzungstring kommt wahlweise aus der Portion via GetExpText()
+ // oder aus dem char Pointer pCh, wenn dieser ungleich NULL ist.
+ SwTxtSlotLen( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor,
+ const sal_Char *pCh = NULL );
+ ~SwTxtSlotLen();
+ inline sal_Bool IsOn() const { return bOn; }
+};
+
+/*************************************************************************
+ * class SwFontSave
+ *************************************************************************/
+
+class SwFontSave
+{
+ SwTxtSizeInfo *pInf;
+ SwFont *pFnt;
+ SwFont *pNewFnt;
+public:
+ SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pFnt );
+ ~SwFontSave();
+};
+
+/*************************************************************************
+ * class SwDefFontSave
+ *************************************************************************/
+
+class SwDefFontSave
+{
+ SwTxtSizeInfo *pInf;
+ SwFont *pFnt;
+ SwFont *pNewFnt;
+ sal_Bool bAlter;
+public:
+ SwDefFontSave( const SwTxtSizeInfo &rInf );
+ ~SwDefFontSave();
+ inline sal_Bool IsAlter(){ return bAlter; }
+};
+
+/*************************************************************************
+ * class SwFtnSave
+ *************************************************************************/
+
+class SwFtnSave
+{
+ SwTxtSizeInfo *pInf;
+ SwFont *pFnt;
+ SwFont *pOld;
+ short nEsc;
+ sal_uInt8 nPropr;
+public:
+ SwFtnSave( const SwTxtSizeInfo &rInf, const SwTxtFtn *pTxtFtn );
+ ~SwFtnSave();
+};
+
+/*************************************************************************
+ * Inline-Implementationen
+ *************************************************************************/
+
+inline KSHORT SwTxtSizeInfo::GetAscent() const
+{
+ return ((SwFont*)GetFont())->GetAscent( pVsh, GetOut() );
+}
+
+inline KSHORT SwTxtSizeInfo::GetTxtHeight() const
+{
+ return ((SwFont*)GetFont())->GetHeight( pVsh, GetOut() );
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize( const OutputDevice *pOutDev,
+ const XubString &rTxt,
+ const xub_StrLen nIdx,
+ const xub_StrLen nLen ) const
+{
+ return pFnt->_GetTxtSize( pVsh, pOutDev, rTxt, nIdx, nLen );
+}
+
+inline void SwTxtSizeInfo::SetWin( OutputDevice *pNewWin )
+{
+ if( pOut == pWin )
+ pOut = pNewWin;
+ pWin = pNewWin;
+}
+
+inline void SwTxtSizeInfo::SetPrt( OutputDevice *pNewPrt )
+{
+ if( pOut == pPrt )
+ pOut = pNewPrt;
+ pPrt = pNewPrt;
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize() const
+{
+ return GetTxtSize( pOut, *pTxt, nIdx, nLen );
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize( const XubString &rTxt ) const
+{
+ return GetTxtSize( pOut, rTxt, 0, rTxt.Len() );
+}
+
+inline SwPosSize SwTxtSizeInfo::GetTxtSize( const xub_StrLen nNewIdx,
+ const xub_StrLen nNewLen ) const
+{
+ return GetTxtSize( pOut, *pTxt, nNewIdx, nNewLen );
+}
+
+inline xub_StrLen SwTxtSizeInfo::GetTxtBreak( long nTxtWidth,
+ const xub_StrLen nNewIdx, const xub_StrLen nNewLen ) const
+{
+ return pFnt->GetTxtBreak( pVsh, pOut, *pTxt, nTxtWidth, nNewIdx, nNewLen );
+}
+
+inline xub_StrLen SwTxtSizeInfo::GetTxtBreak( long nTxtWidth, const xub_StrLen
+ nNewIdx, const xub_StrLen nNewLen, xub_StrLen& rExtraCharPos ) const
+{
+ return pFnt->GetTxtBreak( pVsh, pOut, *pTxt, nTxtWidth, rExtraCharPos,
+ nNewIdx, nNewLen );
+}
+
+inline SwTwips SwTxtPaintInfo::GetPaintOfst() const
+{
+ return GetParaPortion()->GetRepaint()->GetOfst();
+}
+
+inline void SwTxtPaintInfo::SetPaintOfst( const SwTwips nNew )
+{
+ GetParaPortion()->GetRepaint()->SetOfst( nNew );
+}
+
+
+inline void SwTxtPaintInfo::DrawText( const XubString &rText,
+ const SwLinePortion &rPor,
+ const xub_StrLen nStart, const xub_StrLen nLen,
+ const sal_Bool bKern ) const
+{
+ ((SwTxtPaintInfo*)this)->_DrawText( rText, rPor, nStart, nLen, bKern );
+}
+
+inline void SwTxtPaintInfo::DrawText( const SwLinePortion &rPor,
+ const xub_StrLen nLen, const sal_Bool bKern ) const
+{
+ ((SwTxtPaintInfo*)this)->_DrawText( *pTxt, rPor, nIdx, nLen, bKern );
+}
+
+inline void SwTxtPaintInfo::DrawWrongText( const SwLinePortion &rPor,
+ const xub_StrLen nLen, const sal_Bool bKern ) const
+{
+ ((SwTxtPaintInfo*)this)->_DrawText( *pTxt, rPor, nIdx, nLen, bKern, sal_True );
+}
+
+inline xub_StrLen SwTxtFormatInfo::GetReformatStart() const
+{
+ return GetParaPortion()->GetReformat()->Start();
+}
+
+inline const SwAttrSet& SwTxtFormatInfo::GetCharAttr() const
+{
+ return GetTxtFrm()->GetTxtNode()->GetSwAttrSet();
+}
+
+inline void SwTxtFormatInfo::SetParaFtn()
+{
+ GetTxtFrm()->SetFtn( sal_True );
+}
+
+inline sal_Bool SwTxtFormatInfo::IsSoftHyph( const xub_StrLen nPos ) const
+{
+ return CHAR_SOFTHYPHEN == GetTxtFrm()->GetTxtNode()->GetTxt().GetChar(nPos);
+}
+
+
+
+#endif
+
diff --git a/sw/source/core/text/itradj.cxx b/sw/source/core/text/itradj.cxx
new file mode 100644
index 000000000000..6d247d5f8cc7
--- /dev/null
+++ b/sw/source/core/text/itradj.cxx
@@ -0,0 +1,578 @@
+/*************************************************************************
+ *
+ * $RCSfile: itradj.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "frame.hxx" // CalcFlyAdjust()
+#include "paratr.hxx"
+#ifdef DEBUG
+# include "ndtxt.hxx" // pSwpHints, Ausgabeoperator
+#endif
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "itrtxt.hxx"
+#include "porglue.hxx"
+#include "porlay.hxx"
+#include "porfly.hxx" // CalcFlyAdjust()
+#include "pordrop.hxx" // CalcFlyAdjust()
+
+
+/*************************************************************************
+ * SwTxtAdjuster::FormatBlock()
+ *************************************************************************/
+
+void SwTxtAdjuster::FormatBlock( )
+{
+ // In der letzten Zeile gibt's keinen Blocksatz.
+ // Und bei Tabulatoren aus Tradition auch nicht.
+ // 7701: wenn Flys im Spiel sind, geht's weiter
+
+ const SwLinePortion *pFly = 0;
+
+ sal_Bool bSkip = !IsLastBlock() &&
+ nStart + pCurr->GetLen() >= GetInfo().GetTxt().Len();
+
+ // ????: mehrzeilige Felder sind fies: wir muessen kontrollieren,
+ // ob es noch andere Textportions im Absatz gibt.
+ if( bSkip )
+ {
+ const SwLineLayout *pLay = pCurr->GetNext();
+ while( pLay && !pLay->GetLen() )
+ {
+ const SwLinePortion *pPor = pCurr->GetFirstPortion();
+ while( pPor && bSkip )
+ {
+ if( pPor->InTxtGrp() )
+ bSkip = sal_False;
+ pPor = pPor->GetPortion();
+ }
+ pLay = bSkip ? pLay->GetNext() : 0;
+ }
+ }
+
+ if( bSkip )
+ {
+ if( !GetInfo().GetParaPortion()->HasFly() )
+ {
+ if( IsLastCenter() )
+ CalcFlyAdjust( pCurr );
+ pCurr->FinishSpaceAdd();
+ return;
+ }
+ else
+ {
+ const SwLinePortion *pTmpFly = NULL;
+
+ // 7701: beim letzten Fly soll Schluss sein
+ const SwLinePortion *pPos = pCurr->GetFirstPortion();
+ while( pPos )
+ {
+ // Ich suche jetzt den letzten Fly, hinter dem noch Text ist:
+ if( pPos->IsFlyPortion() )
+ pTmpFly = pPos; // Ein Fly wurde gefunden
+ else if ( pTmpFly && pPos->InTxtGrp() )
+ {
+ pFly = pTmpFly; // Ein Fly mit nachfolgendem Text!
+ pTmpFly = NULL;
+ }
+ pPos = pPos->GetPortion();
+ }
+ // 8494: Wenn keiner gefunden wurde, ist sofort Schluss!
+ if( !pFly )
+ {
+ if( IsLastCenter() )
+ CalcFlyAdjust( pCurr );
+ pCurr->FinishSpaceAdd();
+ return;
+ }
+ }
+ }
+
+ const nOldIdx = GetInfo().GetIdx();
+ GetInfo().SetIdx( nStart );
+ CalcNewBlock( pCurr, pFly );
+ GetInfo().SetIdx( nOldIdx );
+ GetInfo().GetParaPortion()->GetRepaint()->SetOfst(0);
+}
+
+/*************************************************************************
+ * SwTxtAdjuster::CalcBlockAdjust()
+ *
+ * CalcBlockAdjust() darf erst nach CalcLine() gerufen werden !
+ * Aufgespannt wird immer zwischen zwei RandPortions oder FixPortions
+ * (Tabs und Flys). Dabei werden die Glues gezaehlt und ExpandBlock gerufen.
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcNewBlock( SwLineLayout *pCurr,
+ const SwLinePortion *pStopAt )
+{
+ ASSERT( SVX_ADJUST_BLOCK == GetAdjust(), "CalcNewBlock: Why?" );
+ ASSERT( pCurr->Height(), "SwTxtAdjuster::CalcBlockAdjust: missing CalcLine()" );
+
+ pCurr->InitSpaceAdd();
+ MSHORT nNull = 0;
+ xub_StrLen nGluePortion = 0;
+ xub_StrLen nCharCnt = 0;
+ MSHORT nSpaceIdx = 0;
+
+ // Nicht vergessen:
+ // CalcRightMargin() setzt pCurr->Width() auf die Zeilenbreite !
+ CalcRightMargin( pCurr );
+
+ SwLinePortion *pPos = pCurr->GetPortion();
+
+ while( pPos )
+ {
+ if ( pPos->IsBreakPortion() && !IsLastBlock() )
+ {
+ pCurr->FinishSpaceAdd();
+ break;
+ }
+ if ( pPos->InTxtGrp() )
+ nGluePortion += ((SwTxtPortion*)pPos)->GetSpaceCnt( GetInfo(), nCharCnt );
+
+ if( pPos->InGlueGrp() )
+ {
+ if( pPos->InFixMargGrp() )
+ {
+ if ( nSpaceIdx == pCurr->GetSpaceAdd().Count() )
+ pCurr->GetSpaceAdd().Insert( nNull, nSpaceIdx );
+ if( nGluePortion )
+ {
+ ( pCurr->GetSpaceAdd() )[nSpaceIdx] =
+ ( (SwGluePortion*)pPos )->GetPrtGlue() / nGluePortion;
+ pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() );
+ }
+ else if ( IsOneBlock() && nCharCnt > 1 )
+ {
+ ( pCurr->GetSpaceAdd() )[nSpaceIdx] =
+ - ( (SwGluePortion*)pPos )->GetPrtGlue() / (nCharCnt-1);
+ pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() );
+ }
+ nSpaceIdx++;
+ nGluePortion = 0;
+ nCharCnt = 0;
+ }
+ else
+ ++nGluePortion;
+ }
+ GetInfo().SetIdx( GetInfo().GetIdx() + pPos->GetLen() );
+ if ( pPos == pStopAt )
+ {
+ if ( nSpaceIdx == pCurr->GetSpaceAdd().Count() )
+ pCurr->GetSpaceAdd().Insert( nNull, nSpaceIdx );
+ else
+ pCurr->GetSpaceAdd()[nSpaceIdx] = 0;
+ break;
+ }
+ pPos = pPos->GetPortion();
+ }
+}
+
+/*************************************************************************
+ * SwTxtAdjuster::CalcRightMargin()
+ *************************************************************************/
+
+SwMarginPortion *SwTxtAdjuster::CalcRightMargin( SwLineLayout *pCurr )
+{
+ const long nRealWidth = GetLineWidth();
+ const long nHeight = GetLineHeight();
+ KSHORT nPrtWidth = pCurr->PrtWidth();
+
+ SwLinePortion *pLast = pCurr->FindLastPortion();
+
+ // Fuer jeden FlyFrm, der in den rechten Rand hineinragt,
+ // wird eine FlyPortion angelegt.
+ const long nLeftMar = GetLeftMargin();
+ SwRect aCurrRect( nLeftMar + nPrtWidth, Y(),
+ nRealWidth - nPrtWidth, nHeight );
+
+ SwFlyPortion *pFly = CalcFlyPortion( nRealWidth, aCurrRect );
+ while( pFly && long( nPrtWidth )< nRealWidth )
+ {
+ pLast->Append( pFly );
+ pLast = pFly;
+ if( pFly->Fix() > nPrtWidth )
+ pFly->Width( ( pFly->Fix() - nPrtWidth) + pFly->Width() + 1);
+ nPrtWidth += pFly->Width() + 1;
+ aCurrRect.Left( nLeftMar + nPrtWidth );
+ pFly = CalcFlyPortion( nRealWidth, aCurrRect );
+ }
+ if( pFly )
+ delete pFly;
+
+ SwMarginPortion *pRight = new SwMarginPortion( 0 );
+ pLast->Append( pRight );
+
+ if( long( nPrtWidth )< nRealWidth )
+ pRight->PrtWidth( KSHORT( nRealWidth - nPrtWidth ) );
+
+ // pCurr->Width() wird auf die reale Groesse gesetzt,
+ // da jetzt die MarginPortions eingehaengt sind.
+ // Dieser Trick hat wundersame Auswirkungen.
+ // Wenn pCurr->Width() == nRealWidth ist, dann wird das gesamte
+ // Adjustment implizit ausgecontert. GetLeftMarginAdjust() und
+ // IsBlocksatz() sind der Meinung, sie haetten eine mit Zeichen
+ // gefuellte Zeile.
+
+ pCurr->PrtWidth( KSHORT( nRealWidth ) );
+ return pRight;
+}
+
+/*************************************************************************
+ * SwTxtAdjuster::CalcFlyAdjust()
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcFlyAdjust( SwLineLayout *pCurr )
+{
+ const SwRect aLineRect( GetLeftMargin(), Y(),
+ ((SwFrm*)pFrm)->Prt().Width(), GetLineHeight() );
+ // 1) Es wird ein linker Rand eingefuegt:
+ SwMarginPortion *pLeft = pCurr->CalcLeftMargin();
+ SwGluePortion *pGlue = pLeft; // die letzte GluePortion
+
+
+ // 2) Es wird ein rechter Rand angehaengt:
+ // CalcRightMargin berechnet auch eventuelle Ueberlappungen mit
+ // FlyFrms.
+ CalcRightMargin( pCurr );
+
+#ifdef USED
+ pCurr->PackFlys();
+#endif
+
+ SwLinePortion *pPos = pLeft->GetPortion();
+ xub_StrLen nLen = 0;
+
+ // Wenn wir nur eine Zeile vorliegen haben und die Textportion zusammen
+ // haengend ist und wenn zentriert wird, dann ...
+
+ sal_Bool bComplete = 0 == nStart;
+
+ while( pPos )
+ {
+ if( pPos->InFixMargGrp() )
+ {
+ if( SVX_ADJUST_RIGHT == GetAdjust() )
+ {
+ ((SwGluePortion*)pPos)->MoveAllGlue( pGlue );
+ }
+ else
+ {
+ // Eine schlaue Idee von MA:
+ // Fuer die erste Textportion wird rechtsbuendig eingestellt,
+ // fuer die letzte linksbuendig.
+
+ // Die erste Textportion kriegt den ganzen Glue
+ // Aber nur, wenn wir mehr als eine Zeile besitzen.
+ if( bComplete && GetInfo().GetTxt().Len() == nLen )
+ {
+ ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue );
+ }
+ else
+ {
+ if( pLeft == pGlue )
+ {
+ // Wenn es nur einen linken und rechten Rand gibt,
+ // dann teilen sich die Raender den Glue.
+ if( nLen + pPos->GetLen() >= pCurr->GetLen() )
+ ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue );
+ else
+ ((SwGluePortion*)pPos)->MoveAllGlue( pGlue );
+ }
+ else
+ {
+ // Die letzte Textportion behaelt sein Glue
+ if( !pPos->IsMarginPortion() )
+ ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue );
+ }
+ }
+ }
+ pGlue = (SwFlyPortion*)pPos;
+ bComplete = sal_False;
+ }
+ nLen += pPos->GetLen();
+ pPos = pPos->GetPortion();
+ }
+
+ if( SVX_ADJUST_RIGHT == GetAdjust() )
+ pLeft->AdjustRight();
+
+#ifdef DEBUG
+ // um einen Breakpoint setzen zu koennen:
+ nLen = 0;
+#endif
+}
+
+/*************************************************************************
+ * SwTxtAdjuster::CalcAdjLine()
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcAdjLine( SwLineLayout *pCurr )
+{
+ ASSERT( pCurr->IsFormatAdj(), "CalcAdjLine: Why?" );
+
+ pCurr->SetFormatAdj(sal_False);
+ switch( GetAdjust() )
+ {
+ case SVX_ADJUST_RIGHT:
+ case SVX_ADJUST_CENTER:
+ {
+ CalcFlyAdjust( pCurr );
+ GetInfo().GetParaPortion()->GetRepaint()->SetOfst( 0 );
+ break;
+ }
+ case SVX_ADJUST_BLOCK:
+ {
+ // 8311: In Zeilen mit LineBreaks gibt es keinen Blocksatz!
+ if( pCurr->GetLen() &&
+ CH_BREAK == GetInfo().GetChar( nStart + pCurr->GetLen() - 1 ) &&
+ !IsLastBlock() )
+ {
+ if( IsLastCenter() )
+ {
+ CalcFlyAdjust( pCurr );
+ GetInfo().GetParaPortion()->GetRepaint()->SetOfst( 0 );
+ break;
+ }
+ return;
+ }
+ FormatBlock();
+ break;
+ }
+ default : return;
+ }
+
+#ifdef DEBUG
+/*
+ if( OPTDBG( *pInf ) )
+ {
+ pCurr->DebugPortions( aDbstream, pInf->GetTxt(), nStart );
+ if( GetHints() )
+ {
+ const SwpHints &rHt = *GetHints();
+ aDbstream << rHt;
+ SwAttrIter::Dump( aDbstream );
+ }
+ }
+ */
+#endif
+}
+
+/*************************************************************************
+ * SwTxtAdjuster::CalcFlyPortion()
+ *
+ * Die Berechnung hat es in sich: nCurrWidth geibt die Breite _vor_ dem
+ * aufaddieren des Wortes das noch auf die Zeile passt! Aus diesem Grund
+ * stimmt die Breite der FlyPortion auch, wenn die Blockierungssituation
+ * bFirstWord && !WORDFITS eintritt.
+ *************************************************************************/
+
+SwFlyPortion *SwTxtAdjuster::CalcFlyPortion( const long nRealWidth,
+ const SwRect &rCurrRect )
+{
+ SwTxtFly aTxtFly( (SwCntntFrm*)GetTxtFrm() );
+
+ const KSHORT nCurrWidth = pCurr->PrtWidth();
+ SwFlyPortion *pFlyPortion = 0;
+ // aFlyRect ist dokumentglobal !
+
+ SwRect aFlyRect( aTxtFly.GetFrm( rCurrRect ) );
+
+ // Wenn ein Frame ueberlappt, wird eine Portion eroeffnet.
+ if( aFlyRect.HasArea() )
+ {
+ // aLocal ist framelokal
+ SwRect aLocal( aFlyRect );
+ aLocal.Pos( aLocal.Left() - GetLeftMargin(), aLocal.Top() );
+ if( nCurrWidth > KSHORT( aLocal.Left() ) )
+ aLocal.Left( nCurrWidth );
+
+ // Wenn das Rechteck breiter als die Zeile ist, stutzen
+ // wir es ebenfalls zurecht.
+ KSHORT nLocalWidth = KSHORT( aLocal.Left() + aLocal.Width() );
+ if( nRealWidth < long( nLocalWidth ) )
+ aLocal.Width( nRealWidth - aLocal.Left() );
+ GetInfo().GetParaPortion()->SetFly( sal_True );
+ pFlyPortion = new SwFlyPortion( aLocal );
+ pFlyPortion->Height( KSHORT( rCurrRect.Height() ) );
+ // Die Width koennte kleiner sein als die FixWidth, daher:
+ pFlyPortion->AdjFixWidth();
+ }
+ return pFlyPortion;
+}
+
+/*************************************************************************
+ * SwTxtPainter::_CalcDropAdjust()
+ *************************************************************************/
+
+// 6721: Drops und Adjustment
+// CalcDropAdjust wird ggf. am Ende von Format() gerufen.
+
+void SwTxtAdjuster::CalcDropAdjust()
+{
+ ASSERT( 1<GetDropLines() && SVX_ADJUST_LEFT!=GetAdjust() && SVX_ADJUST_BLOCK!=GetAdjust(),
+ "CalcDropAdjust: No reason for DropAdjustment." )
+
+ const MSHORT nLineNr = GetLineNr();
+
+ // 1) Dummies ueberspringen
+ Top();
+
+ if( !pCurr->IsDummy() || NextLine() )
+ {
+ // Erst adjustieren.
+ GetAdjusted();
+
+ SwLinePortion *pPor = pCurr->GetFirstPortion();
+
+ // 2) Sicherstellen, dass die DropPortion dabei ist.
+ // 3) pLeft: Die GluePor vor der DropPor
+ if( pPor->InGlueGrp() && pPor->GetPortion()
+ && pPor->GetPortion()->IsDropPortion() )
+ {
+ const SwLinePortion *pDropPor = (SwDropPortion*) pPor->GetPortion();
+ SwGluePortion *pLeft = (SwGluePortion*) pPor;
+
+ // 4) pRight: Die GluePor hinter der DropPor suchen
+ pPor = pPor->GetPortion();
+ while( pPor && !pPor->InFixMargGrp() )
+ pPor = pPor->GetPortion();
+
+ SwGluePortion *pRight = ( pPor && pPor->InGlueGrp() ) ?
+ (SwGluePortion*) pPor : 0;
+ if( pRight && pRight != pLeft )
+ {
+ // 5) nMinLeft berechnen. Wer steht am weitesten links?
+ const KSHORT nDropLineStart =
+ KSHORT(GetLineStart()) + pLeft->Width() + pDropPor->Width();
+ KSHORT nMinLeft = nDropLineStart;
+ for( MSHORT i = 1; i < GetDropLines(); ++i )
+ {
+ if( NextLine() )
+ {
+ // Erst adjustieren.
+ GetAdjusted();
+
+ pPor = pCurr->GetFirstPortion();
+ const SwMarginPortion *pMar = pPor->IsMarginPortion() ?
+ (SwMarginPortion*)pPor : 0;
+ if( !pMar )
+ nMinLeft = 0;
+ else
+ {
+ const KSHORT nLineStart =
+ KSHORT(GetLineStart()) + pMar->Width();
+ if( nMinLeft > nLineStart )
+ nMinLeft = nLineStart;
+ }
+ }
+ }
+
+ // 6) Den Glue zwischen pLeft und pRight neu verteilen.
+ if( nMinLeft < nDropLineStart )
+ {
+ // Glue wird immer von pLeft nach pRight abgegeben,
+ // damit der Text nach links wandert.
+ const short nGlue = nDropLineStart - nMinLeft;
+ if( !nMinLeft )
+ pLeft->MoveAllGlue( pRight );
+ else
+ pLeft->MoveGlue( pRight, nGlue );
+#ifdef DBGTXT
+ aDbstream << "Drop adjusted: " << nGlue << endl;
+#endif
+ }
+ }
+ }
+ }
+
+ if( nLineNr != GetLineNr() )
+ {
+ Top();
+ while( nLineNr != GetLineNr() && Next() )
+ ;
+ }
+}
+
+/*************************************************************************
+ * SwTxtAdjuster::CalcDropRepaint()
+ *************************************************************************/
+
+void SwTxtAdjuster::CalcDropRepaint()
+{
+ Top();
+ SwRepaint &rRepaint = *GetInfo().GetParaPortion()->GetRepaint();
+ if( rRepaint.Top() > Y() )
+ rRepaint.Top( Y() );
+ for( MSHORT i = 1; i < GetDropLines(); ++i )
+ NextLine();
+ const SwTwips nBottom = Y() + GetLineHeight() - 1;
+ if( rRepaint.Bottom() < nBottom )
+ rRepaint.Bottom( nBottom );
+}
+
+
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
new file mode 100644
index 000000000000..1fe21f20d74c
--- /dev/null
+++ b/sw/source/core/text/itratr.cxx
@@ -0,0 +1,833 @@
+/*************************************************************************
+ *
+ * $RCSfile: itratr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _SFX_PRINTER_HXX //autogen
+#include <sfx2/printer.hxx>
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include <svx/lrspitem.hxx>
+#endif
+#ifndef _WINDOW_HXX //autogen
+#include <vcl/window.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <vcl/svapp.hxx>
+#endif
+
+#ifndef _FMTANCHR_HXX //autogen
+#include <fmtanchr.hxx>
+#endif
+#ifndef _FMTFSIZE_HXX //autogen
+#include <fmtfsize.hxx>
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include <fmtornt.hxx>
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include <fmtflcnt.hxx>
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include <fmtcntnt.hxx>
+#endif
+#ifndef _FMTFTN_HXX //autogen
+#include <fmtftn.hxx>
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include <fmthbsh.hxx>
+#endif
+#ifndef _FRMATR_HXX
+#include <frmatr.hxx>
+#endif
+#ifndef _FRMFMT_HXX //autogen
+#include <frmfmt.hxx>
+#endif
+#ifndef _FMTFLD_HXX
+#include <fmtfld.hxx>
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx>
+#endif
+#ifndef _VIEWSH_HXX
+#include <viewsh.hxx> // ViewShell
+#endif
+#ifndef _ROOTFRM_HXX
+#include <rootfrm.hxx>
+#endif
+#ifndef _DOCARY_HXX
+#include <docary.hxx>
+#endif
+#ifndef _NDTXT_HXX
+#include <ndtxt.hxx>
+#endif
+#ifndef _DCONTACT_HXX
+#include <dcontact.hxx>
+#endif
+#ifndef _FLDBAS_HXX
+#include <fldbas.hxx> // SwField
+#endif
+#ifndef _PAM_HXX
+#include <pam.hxx> // SwPosition (lcl_MinMaxNode)
+#endif
+#ifndef _TXATBASE_HXX
+#include <txatbase.hxx>
+#endif
+#ifndef _ITRATR_HXX
+#include <itratr.hxx>
+#endif
+#ifndef _SWFONT_HXX
+#include <swfont.hxx>
+#endif
+#ifndef _HTMLTBL_HXX
+#include <htmltbl.hxx>
+#endif
+#ifndef _SWTABLE_HXX
+#include <swtable.hxx>
+#endif
+#ifndef _REDLNITR_HXX
+#include <redlnitr.hxx>
+#endif
+#ifndef _FMTSRND_HXX
+#include <fmtsrnd.hxx>
+#endif
+
+/*************************************************************************
+ * SwAttrIter::Chg()
+ *************************************************************************/
+
+void SwAttrIter::Chg( SwTxtAttr *pHt )
+{
+ if( pRedln && pRedln->IsOn() )
+ pRedln->ChangeTxtAttr( pFnt, *pHt, sal_True );
+ else
+ pHt->ChgFnt( pFnt );
+ nChgCnt++;
+}
+
+/*************************************************************************
+ * SwAttrIter::Rst()
+ *************************************************************************/
+
+void SwAttrIter::Rst( SwTxtAttr *pHt )
+{
+ if( pRedln && pRedln->IsOn() )
+ pRedln->ChangeTxtAttr( pFnt, *pHt, sal_False );
+ else
+ pHt->RstFnt( pFnt );
+ nChgCnt--;
+}
+
+/*************************************************************************
+ * virtual SwAttrIter::~SwAttrIter()
+ *************************************************************************/
+
+SwAttrIter::~SwAttrIter()
+{
+ delete pRedln;
+ delete pFnt;
+}
+
+/*************************************************************************
+ * SwAttrIter::GetAttr()
+ *
+ * Liefert fuer eine Position das Attribut, wenn das Attribut genau auf
+ * der Position nPos liegt und kein EndIndex besitzt.
+ * GetAttr() wird fuer Attribute benoetigt, die die Formatierung beeinflussen
+ * sollen, ohne dabei den Inhalt des Strings zu veraendern. Solche "entarteten"
+ * Attribute sind z.B. Felder (die expandierten Text bereit halten) und
+ * zeilengebundene Frames. Um Mehrdeutigkeiten zwischen verschiedenen
+ * solcher Attribute zu vermeiden, werden beim Anlegen eines Attributs
+ * an der Startposition ein Sonderzeichen in den String einfuegt.
+ * Der Formatierer stoesst auf das Sonderzeichen und holt sich per
+ * GetAttr() das entartete Attribut.
+ *************************************************************************/
+
+SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPos ) const
+{
+ if( pHints )
+ {
+ for( MSHORT i = 0; i < pHints->Count(); ++i )
+ {
+ SwTxtAttr *pPos = pHints->GetHt(i);
+ xub_StrLen nStart = *pPos->GetStart();
+ if( nPos < nStart )
+ return 0;
+ if( nPos == nStart && !pPos->GetEnd() )
+ return pPos;
+ }
+ }
+ return 0;
+}
+
+/*************************************************************************
+ * SwAttrIter::SeekAndChg()
+ *************************************************************************/
+
+sal_Bool SwAttrIter::SeekAndChg( const xub_StrLen nNewPos, OutputDevice *pOut )
+{
+ sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
+ if ( pLastOut != pOut )
+ {
+ pLastOut = pOut;
+ pFnt->SetFntChg( sal_True );
+ bChg = sal_True;
+ }
+ if( bChg )
+ {
+ // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
+ // des gewuenschten Fonts ...
+ if ( !nChgCnt )
+ pFnt->SetMagic( pMagicNo, nFntIdx, pFnt->GetActual() );
+ pFnt->ChgPhysFnt( pShell, pOut );
+ }
+ return bChg;
+}
+
+sal_Bool SwAttrIter::IsSymbol( const xub_StrLen nNewPos )
+{
+ Seek( nNewPos );
+ if ( !nChgCnt )
+ pFnt->SetMagic( pMagicNo, nFntIdx, pFnt->GetActual() );
+ return pFnt->IsSymbol( pShell );
+}
+
+/*************************************************************************
+ * SwAttrIter::SeekStartAndChg()
+ *************************************************************************/
+
+sal_Bool SwAttrIter::SeekStartAndChg( OutputDevice *pOut, const sal_Bool bParaFont )
+{
+ // Gehe zurueck auf Start ...
+ pFnt->SetFnt( pAttrSet );
+ pFnt->GetTox() = 0;
+ pFnt->GetRef() = 0;
+ nStartIndex = nEndIndex = nPos = nChgCnt = 0;
+ if( pRedln )
+ {
+ pRedln->Clear( pFnt );
+ if( !bParaFont )
+ nChgCnt += pRedln->Seek( *pFnt, 0, STRING_LEN );
+ else
+ pRedln->Reset();
+ }
+
+ if ( pHints && !bParaFont )
+ {
+ SwTxtAttr *pTxtAttr;
+ // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
+ // das TextAttribut an Position 0 beginnt ...
+ while ( ( nStartIndex < pHints->GetStartCount() ) &&
+ !(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) )
+ {
+ // oeffne die TextAttribute
+ Chg( pTxtAttr );
+ nStartIndex++;
+ }
+ }
+
+ register sal_Bool bChg = pFnt->IsFntChg();
+ if ( pLastOut != pOut )
+ {
+ pLastOut = pOut;
+ pFnt->SetFntChg( sal_True );
+ bChg = sal_True;
+ }
+ if( bChg )
+ {
+ // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
+ // des gewuenschten Fonts ...
+ if ( !nChgCnt )
+ pFnt->SetMagic( pMagicNo, nFntIdx, pFnt->GetActual() );
+ pFnt->ChgPhysFnt( pShell, pOut );
+ }
+ return bChg;
+}
+
+/*************************************************************************
+ * SwAttrIter::SeekFwd()
+ *************************************************************************/
+
+// AMA: Neuer AttrIter Nov 94
+
+void SwAttrIter::SeekFwd( const xub_StrLen nNewPos )
+{
+ SwTxtAttr *pTxtAttr;
+
+ if ( nStartIndex ) // wenn ueberhaupt schon Attribute geoeffnet wurden...
+ {
+ // Schliesse Attr, die z. Z. geoeffnet sind, vor nNewPos+1 aber enden.
+
+ // Solange wir noch nicht am Ende des EndArrays angekommen sind &&
+ // das TextAttribut vor oder an der neuen Position endet ...
+ while ( ( nEndIndex < pHints->GetEndCount() ) &&
+ (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
+ {
+ // schliesse die TextAttribute, deren StartPos vor
+ // oder an der alten nPos lag, die z.Z. geoeffnet sind.
+ if (*pTxtAttr->GetStart() <= nPos) Rst( pTxtAttr );
+ nEndIndex++;
+ }
+ }
+ else // ueberlies die nicht geoeffneten Enden
+ {
+ while ( ( nEndIndex < pHints->GetEndCount() ) &&
+ (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
+ {
+ nEndIndex++;
+ }
+ }
+ // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
+ // das TextAttribut vor oder an der neuen Position beginnt ...
+ while ( ( nStartIndex < pHints->GetStartCount() ) &&
+ (*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos))
+ {
+ // oeffne die TextAttribute, deren Ende hinter der neuen Position liegt
+ if ( *pTxtAttr->GetAnyEnd() > nNewPos ) Chg( pTxtAttr );
+ nStartIndex++;
+ }
+
+}
+
+/*************************************************************************
+ * SwAttrIter::Seek()
+ *************************************************************************/
+
+sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos )
+{
+ if( pHints )
+ {
+ if( !nNewPos || nNewPos < nPos )
+ {
+ // Gehe zurueck auf Start ...
+ if( pRedln )
+ pRedln->Clear( NULL );
+ pFnt->SetFnt( pAttrSet );
+ pFnt->GetTox() = 0;
+ pFnt->GetRef() = 0;
+ nStartIndex = nEndIndex = nPos = 0;
+ nChgCnt = 0;
+ }
+ SeekFwd( nNewPos );
+ }
+ if( pRedln )
+ nChgCnt += pRedln->Seek( *pFnt, nNewPos, nPos );
+ nPos = nNewPos;
+ return pFnt->IsFntChg();
+}
+
+/*************************************************************************
+ * SwAttrIter::GetNextAttr()
+ *************************************************************************/
+
+xub_StrLen SwAttrIter::GetNextAttr( ) const
+{
+ xub_StrLen nNext = STRING_LEN;
+ if( pHints )
+ {
+ if (pHints->GetStartCount() > nStartIndex) // Gibt es noch Starts?
+ nNext = (*pHints->GetStart(nStartIndex)->GetStart());
+ if (pHints->GetEndCount() > nEndIndex) // Gibt es noch Enden?
+ {
+ xub_StrLen nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd());
+ if ( nNextEnd<nNext ) nNext = nNextEnd; // Wer ist naeher?
+ }
+ }
+ if( pRedln )
+ return pRedln->GetNextRedln( nNext );
+ return nNext;
+}
+
+#ifdef DEBUG
+/*************************************************************************
+ * SwAttrIter::Dump()
+ *************************************************************************/
+
+void SwAttrIter::Dump( SvStream &rOS ) const
+{
+// Noch nicht an den neuen Attributiterator angepasst ...
+}
+
+#endif
+
+class SwMinMaxArgs
+{
+public:
+ OutputDevice *pOut;
+ ULONG &rMin;
+ ULONG &rMax;
+ ULONG &rAbsMin;
+ long nRowWidth;
+ long nWordWidth;
+ long nWordAdd;
+ SwMinMaxArgs( OutputDevice *pOutI, ULONG& rMinI, ULONG &rMaxI, ULONG &rAbsI )
+ : pOut( pOutI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI )
+ { nRowWidth = nWordWidth = nWordAdd = 0; }
+ void Minimum( long nNew ) { if( (long)rMin < nNew ) rMin = nNew; }
+ void NewWord() { nWordAdd = nWordWidth = 0; }
+};
+
+sal_Bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const XubString &rTxt,
+ xub_StrLen nIdx, xub_StrLen nEnd )
+{
+ sal_Bool bRet = sal_False;
+ while( nIdx < nEnd )
+ {
+ xub_StrLen nStop = nIdx;
+ while( nStop < nEnd && CH_BLANK != rTxt.GetChar( nStop ) )
+ ++nStop;
+ sal_Bool bClear = nStop == nIdx;
+ if ( bClear )
+ {
+ rArg.NewWord();
+ while( nStop < nEnd && CH_BLANK == rTxt.GetChar( nStop ) )
+ ++nStop;
+ }
+ long nAktWidth = pFnt->_GetTxtSize( 0, rArg.pOut, rTxt, nIdx,
+ nStop - nIdx ).Width();
+ rArg.nRowWidth += nAktWidth;
+ if( bClear )
+ rArg.NewWord();
+ else
+ {
+ rArg.nWordWidth += nAktWidth;
+ if( (long)rArg.rAbsMin < rArg.nWordWidth )
+ rArg.rAbsMin = rArg.nWordWidth;
+ rArg.Minimum( rArg.nWordWidth + rArg.nWordAdd );
+ bRet = sal_True;
+ }
+ nIdx = nStop;
+ }
+ return bRet;
+}
+
+sal_Bool SwTxtNode::IsSymbol( const xub_StrLen nBegin ) const
+{
+ sal_Bool bRet = sal_False;
+ OutputDevice *pOut = GetDoc()->GetPrt();
+ if( !pOut )
+ pOut = GetpApp()->GetDefaultDevice();
+ if( pOut )
+ {
+ SwAttrIter aIter( *(SwTxtNode*)this );
+ aIter.SeekAndChg( nBegin, pOut );
+ bRet = aIter.GetFnt()->IsSymbol( GetDoc()->GetRootFrm() ?
+ GetDoc()->GetRootFrm()->GetCurrShell() : 0 );
+ }
+ return bRet;
+}
+
+class SwMinMaxNodeArgs
+{
+public:
+ ULONG nMaxWidth; // Summe aller Rahmenbreite
+ long nMinWidth; // Breitester Rahmen
+ long nLeftRest; // noch nicht von Rahmen ueberdeckter Platz im l. Rand
+ long nRightRest; // noch nicht von Rahmen ueberdeckter Platz im r. Rand
+ long nLeftDiff; // Min/Max-Differenz des Rahmens im linken Rand
+ long nRightDiff; // Min/Max-Differenz des Rahmens im rechten Rand
+ ULONG nIndx; // Indexnummer des Nodes
+ void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; }
+};
+
+sal_Bool lcl_MinMaxNode( const SwFrmFmtPtr& rpNd, void* pArgs )
+{
+ const SwFmtAnchor& rFmtA = ((SwFrmFmt*)rpNd)->GetAnchor();
+ if ( (FLY_AT_CNTNT == rFmtA.GetAnchorId() ||
+ FLY_AUTO_CNTNT == rFmtA.GetAnchorId()) &&
+ ((SwMinMaxNodeArgs*)pArgs)->nIndx ==
+ rFmtA.GetCntntAnchor()->nNode.GetIndex() )
+ {
+ long nMin, nMax;
+ SwHTMLTableLayout *pLayout = 0;
+ MSHORT nWhich = ((SwFrmFmt*)rpNd)->Which();
+ if( RES_DRAWFRMFMT != nWhich )
+ {
+ // Enthaelt der Rahmen zu Beginn oder am Ende eine Tabelle?
+ SwDoc *pDoc = ((SwFrmFmt*)rpNd)->GetDoc();
+
+ const SwFmtCntnt& rFlyCntnt = ((SwFrmFmt*)rpNd)->GetCntnt();
+ ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
+ SwTableNode* pTblNd = pDoc->GetNodes()[nStt+1]->GetTableNode();
+ if( !pTblNd )
+ {
+ SwNode *pNd = pDoc->GetNodes()[nStt];
+ pNd = pDoc->GetNodes()[pNd->EndOfSectionIndex()-1];
+ if( pNd->IsEndNode() )
+ pTblNd = pNd->StartOfSectionNode()->GetTableNode();
+ }
+
+ if( pTblNd )
+ pLayout = pTblNd->GetTable().GetHTMLTableLayout();
+ }
+
+ const SwFmtHoriOrient& rOrient = ((SwFrmFmt*)rpNd)->GetHoriOrient();
+ SwHoriOrient eHoriOri = rOrient.GetHoriOrient();
+
+ long nDiff;
+ if( pLayout )
+ {
+ nMin = pLayout->GetMin();
+ nMax = pLayout->GetMax();
+ nDiff = nMax - nMin;
+ }
+ else
+ {
+ if( RES_DRAWFRMFMT == nWhich )
+ {
+ const SdrObject* pSObj = rpNd->FindSdrObject();
+ if( pSObj )
+ nMin = pSObj->GetBoundRect().GetWidth();
+ else
+ nMin = 0;
+
+ }
+ else
+ {
+ const SwFmtFrmSize &rSz = ( (SwFrmFmt*)rpNd )->GetFrmSize();
+ nMin = rSz.GetWidth();
+ }
+ nMax = nMin;
+ nDiff = 0;
+ }
+
+ const SvxLRSpaceItem &rLR = ( (SwFrmFmt*)rpNd )->GetLRSpace();
+ nMin += rLR.GetLeft();
+ nMin += rLR.GetRight();
+ nMax += rLR.GetLeft();
+ nMax += rLR.GetRight();
+
+ if( SURROUND_THROUGHT == ((SwFrmFmt*)rpNd)->GetSurround().GetSurround() )
+ {
+ ( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
+ return sal_True;
+ }
+
+ // Rahmen, die recht bzw. links ausgerichtet sind, gehen nur
+ // teilweise in die Max-Berechnung ein, da der Rand schon berueck-
+ // sichtigt wird. Nur wenn die Rahmen in den Textkoerper ragen,
+ // wird dieser Teil hinzuaddiert.
+ switch( eHoriOri )
+ {
+ case HORI_RIGHT:
+ {
+ if( nDiff )
+ {
+ ((SwMinMaxNodeArgs*)pArgs)->nRightRest -=
+ ((SwMinMaxNodeArgs*)pArgs)->nRightDiff;
+ ((SwMinMaxNodeArgs*)pArgs)->nRightDiff = nDiff;
+ }
+ if( FRAME!=rOrient.GetRelationOrient() )
+ {
+ if( ((SwMinMaxNodeArgs*)pArgs)->nRightRest > 0 )
+ ((SwMinMaxNodeArgs*)pArgs)->nRightRest = 0;
+ }
+ ((SwMinMaxNodeArgs*)pArgs)->nRightRest -= nMin;
+ break;
+ }
+ case HORI_LEFT:
+ {
+ if( nDiff )
+ {
+ ((SwMinMaxNodeArgs*)pArgs)->nLeftRest -=
+ ((SwMinMaxNodeArgs*)pArgs)->nLeftDiff;
+ ((SwMinMaxNodeArgs*)pArgs)->nLeftDiff = nDiff;
+ }
+ if( FRAME!=rOrient.GetRelationOrient() &&
+ ((SwMinMaxNodeArgs*)pArgs)->nLeftRest < 0 )
+ ((SwMinMaxNodeArgs*)pArgs)->nLeftRest = 0;
+ ((SwMinMaxNodeArgs*)pArgs)->nLeftRest -= nMin;
+ break;
+ }
+ default:
+ {
+ ( (SwMinMaxNodeArgs*)pArgs )->nMaxWidth += nMax;
+ ( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
+ }
+ }
+ }
+ return sal_True;
+}
+
+#define FLYINCNT_MIN_WIDTH 284
+
+void SwTxtNode::GetMinMaxSize( ULONG nIndex, ULONG& rMin, ULONG &rMax,
+ ULONG& rAbsMin, OutputDevice* pOut ) const
+{
+ if( !pOut )
+ {
+ ViewShell* pSh;
+ GetDoc()->GetEditShell( &pSh );
+ if( pSh )
+ pOut = pSh->GetWin();
+ if( !pOut )
+ pOut = GetpApp()->GetDefaultDevice();
+ }
+
+ MapMode aOldMap( pOut->GetMapMode() );
+ pOut->SetMapMode( MapMode( MAP_TWIP ) );
+
+ rMin = 0;
+ rMax = 0;
+ rAbsMin = 0;
+
+ const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
+ long nLROffset = rSpace.GetTxtLeft() + GetLeftMarginWithNum( sal_True );
+ short nFLOffs;
+ // Bei Numerierung ist ein neg. Erstzeileneinzug vermutlich
+ // bereits gefuellt...
+ if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
+ nLROffset = nFLOffs;
+
+ SwMinMaxNodeArgs aNodeArgs;
+ aNodeArgs.nMinWidth = 0;
+ aNodeArgs.nMaxWidth = 0;
+ aNodeArgs.nLeftRest = nLROffset;
+ aNodeArgs.nRightRest = rSpace.GetRight();
+ aNodeArgs.nLeftDiff = 0;
+ aNodeArgs.nRightDiff = 0;
+ if( nIndex )
+ {
+ SwSpzFrmFmts* pTmp = (SwSpzFrmFmts*)GetDoc()->GetSpzFrmFmts();
+ if( pTmp )
+ {
+ aNodeArgs.nIndx = nIndex;
+ pTmp->ForEach( &lcl_MinMaxNode, &aNodeArgs );
+ }
+ }
+ if( aNodeArgs.nLeftRest < 0 )
+ aNodeArgs.Minimum( nLROffset - aNodeArgs.nLeftRest );
+ aNodeArgs.nLeftRest -= aNodeArgs.nLeftDiff;
+ if( aNodeArgs.nLeftRest < 0 )
+ aNodeArgs.nMaxWidth -= aNodeArgs.nLeftRest;
+
+ if( aNodeArgs.nRightRest < 0 )
+ aNodeArgs.Minimum( rSpace.GetRight() - aNodeArgs.nRightRest );
+ aNodeArgs.nRightRest -= aNodeArgs.nRightDiff;
+ if( aNodeArgs.nRightRest < 0 )
+ aNodeArgs.nMaxWidth -= aNodeArgs.nRightRest;
+
+ SwAttrIter aIter( *(SwTxtNode*)this );
+ xub_StrLen nIdx = 0;
+ aIter.SeekAndChg( nIdx, pOut );
+ xub_StrLen nLen = aText.Len();
+ long nAktWidth = 0;
+ MSHORT nAdd = 0;
+ SwMinMaxArgs aArg( pOut, rMin, rMax, rAbsMin );
+ while( nIdx < nLen )
+ {
+ xub_StrLen nNextChg = aIter.GetNextAttr();
+ xub_StrLen nStop = nIdx;
+ SwTxtAttr *pHint = NULL;
+ xub_Unicode cChar = CH_BLANK;
+ while( nStop < nLen && nStop < nNextChg &&
+ CH_TAB != ( cChar = aText.GetChar( nStop ) ) &&
+ CH_BREAK != cChar && !pHint )
+ {
+ if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
+ || ( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
+ ++nStop;
+ }
+ if( lcl_MinMaxString( aArg, aIter.GetFnt(), aText, nIdx, nStop ) )
+ nAdd = 20;
+ nIdx = nStop;
+ aIter.SeekAndChg( nIdx, pOut );
+ switch( cChar )
+ {
+ case CH_BREAK :
+ {
+ if( (long)rMax < aArg.nRowWidth )
+ rMax = aArg.nRowWidth;
+ aArg.nRowWidth = 0;
+ aArg.NewWord();
+ aIter.SeekAndChg( ++nIdx, pOut );
+ }
+ break;
+ case CH_TAB :
+ {
+ aArg.NewWord();
+ aIter.SeekAndChg( ++nIdx, pOut );
+ }
+ break;
+
+ case CH_TXTATR_BREAKWORD:
+ case CH_TXTATR_INWORD:
+ {
+ if( !pHint )
+ break;
+ long nOldWidth = aArg.nWordWidth;
+ long nOldAdd = aArg.nWordAdd;
+ aArg.NewWord();
+
+ switch( pHint->Which() )
+ {
+ case RES_TXTATR_FLYCNT :
+ {
+ SwFrmFmt *pFrmFmt = pHint->GetFlyCnt().GetFrmFmt();
+ const SvxLRSpaceItem &rLR = pFrmFmt->GetLRSpace();
+ if( RES_DRAWFRMFMT == pFrmFmt->Which() )
+ {
+ const SdrObject* pSObj = pFrmFmt->FindSdrObject();
+ if( pSObj )
+ nAktWidth = pSObj->GetBoundRect().GetWidth();
+ else
+ nAktWidth = 0;
+ }
+ else
+ {
+ const SwFmtFrmSize& rTmpSize = pFrmFmt->GetFrmSize();
+ if( RES_FLYFRMFMT == pFrmFmt->Which()
+ && rTmpSize.GetWidthPercent() )
+ {
+/*-----------------24.01.97 14:09----------------------------------------------
+ * Hier ein HACK fuer folgende Situation: In dem Absatz befindet sich
+ * ein Textrahmen mit relativer Groesse. Dann nehmen wir mal als minimale
+ * Breite 0,5 cm und als maximale KSHRT_MAX.
+ * Sauberer und vielleicht spaeter notwendig waere es, ueber den Inhalt
+ * des Textrahmens zu iterieren und GetMinMaxSize rekursiv zu rufen.
+ * --------------------------------------------------------------------------*/
+ nAktWidth = FLYINCNT_MIN_WIDTH; // 0,5 cm
+ if( (long)rMax < KSHRT_MAX )
+ rMax = KSHRT_MAX;
+ }
+ else
+ nAktWidth = pFrmFmt->GetFrmSize().GetWidth();
+ }
+ nAktWidth += rLR.GetLeft();
+ nAktWidth += rLR.GetRight();
+ aArg.nWordAdd = nOldWidth + nOldAdd;
+ aArg.nWordWidth = nAktWidth;
+ aArg.nRowWidth += nAktWidth;
+ if( (long)rAbsMin < aArg.nWordWidth )
+ rAbsMin = aArg.nWordWidth;
+ aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
+ break;
+ }
+ case RES_TXTATR_FTN :
+ {
+ const XubString aTxt = pHint->GetFtn().GetNumStr();
+ if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
+ aTxt.Len() ) )
+ nAdd = 20;
+ break;
+ }
+ case RES_TXTATR_FIELD :
+ {
+ SwField *pFld = (SwField*)pHint->GetFld().GetFld();
+ const String aTxt = pFld->GetCntnt( FALSE );
+ if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
+ aTxt.Len() ) )
+ nAdd = 20;
+ break;
+ }
+ case RES_TXTATR_HARDBLANK :
+ {
+ XubString sTmp( pHint->GetHardBlank().GetChar() );
+ nAktWidth = aIter.GetFnt()->_GetTxtSize(
+ GetDoc()->GetRootFrm() ? GetDoc()->GetRootFrm()->GetCurrShell() : 0,
+ pOut, sTmp, 0, 1 ).Width();
+ aArg.nWordWidth = nOldWidth + nAktWidth;
+ aArg.nWordAdd = nOldAdd;
+ aArg.nRowWidth += nAktWidth;
+ if( (long)rAbsMin < aArg.nWordWidth )
+ rAbsMin = aArg.nWordWidth;
+ aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
+ break;
+ }
+ default: aArg.nWordWidth = nOldWidth;
+ aArg.nWordAdd = nOldAdd;
+
+ }
+ aIter.SeekAndChg( ++nIdx, pOut );
+ }
+ break;
+ }
+ }
+ if( (long)rMax < aArg.nRowWidth )
+ rMax = aArg.nRowWidth;
+
+ nLROffset += rSpace.GetRight();
+
+ rAbsMin += nLROffset;
+ rAbsMin += nAdd;
+ rMin += nLROffset;
+ rMin += nAdd;
+ if( (long)rMin < aNodeArgs.nMinWidth )
+ rMin = aNodeArgs.nMinWidth;
+ if( (long)rAbsMin < aNodeArgs.nMinWidth )
+ rAbsMin = aNodeArgs.nMinWidth;
+ rMax += aNodeArgs.nMaxWidth;
+ rMax += nLROffset;
+ rMax += nAdd;
+ if( rMax < rMin ) // z.B. Rahmen mit Durchlauf gehen zunaechst nur
+ rMax = rMin; // in das Minimum ein
+ pOut->SetMapMode( aOldMap );
+}
+
+
diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx
new file mode 100644
index 000000000000..8e608164471b
--- /dev/null
+++ b/sw/source/core/text/itratr.hxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * $RCSfile: itratr.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRATR_HXX
+#define _ITRATR_HXX
+
+
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+#include "txttypes.hxx"
+
+class OutputDevice;
+class SwFont;
+class SwpHints;
+class SwTxtAttr;
+class SwAttrSet;
+class SwTxtNode;
+class SwRedlineItr;
+class ViewShell;
+
+/*************************************************************************
+ * class SwAttrIter
+ *************************************************************************/
+
+class SwAttrIter
+{
+protected:
+ ViewShell *pShell;
+ SwFont *pFnt;
+ SwpHints *pHints;
+ const SwAttrSet* pAttrSet; // das Char-Attribut-Set
+
+private:
+ xub_StrLen nStartIndex, nEndIndex, nPos;
+ MSHORT nChgCnt, nFntIdx;
+ const void* pMagicNo;
+ OutputDevice *pLastOut;
+ SwRedlineItr *pRedln;
+ void SeekFwd( const xub_StrLen nPos );
+
+protected:
+ void Chg( SwTxtAttr *pHt );
+ void Rst( SwTxtAttr *pHt );
+ void CtorInit( SwTxtNode& rTxtNode );
+ inline SwAttrIter() : pFnt(0), pLastOut(0), pMagicNo(0), nChgCnt(0),
+ nFntIdx(0), pShell(0), pRedln( 0 ) { }
+
+public:
+ // Konstruktor, Destruktor
+ inline SwAttrIter( SwTxtNode& rTxtNode )
+ : pFnt(0), pLastOut(0), pMagicNo(0), nChgCnt(0), pRedln(0), nFntIdx(0)
+ { CtorInit( rTxtNode ); }
+
+ virtual ~SwAttrIter();
+
+ inline SwRedlineItr *GetRedln() { return pRedln; }
+ // Liefert im Parameter die Position des naechsten Wechsels vor oder an
+ // der uebergebenen Characterposition zurueck. Liefert sal_False, wenn vor
+ // oder an dieser Position kein Wechsel mehr erfolgt, sal_True sonst.
+ xub_StrLen GetNextAttr( ) const;
+ // Macht die an der Characterposition i gueltigen Attribute im
+ // logischen Font wirksam.
+ sal_Bool Seek( const xub_StrLen nPos );
+ // Bastelt den Font an der gew. Position via Seek und fragt ihn,
+ // ob er ein Symbolfont ist.
+ sal_Bool IsSymbol( const xub_StrLen nPos );
+
+ // Fuehrt ChgPhysFnt aus, wenn Seek() sal_True zurueckliefert.
+ sal_Bool SeekAndChg( const xub_StrLen nPos, OutputDevice *pOut );
+ sal_Bool SeekStartAndChg( OutputDevice *pOut, const sal_Bool bParaFont = sal_False );
+
+ // Gibt es ueberhaupt Attributwechsel ?
+ inline sal_Bool HasHints() const { return 0 != pHints; }
+
+ // liefert fuer eine Position das Attribut
+ SwTxtAttr *GetAttr( const xub_StrLen nPos ) const;
+
+ inline const SwAttrSet* GetAttrSet() const { return pAttrSet; }
+
+// inline SwpHints *GetHints() { return pHints; }
+ inline const SwpHints *GetHints() const { return pHints; }
+
+ inline SwFont *GetFnt() { return pFnt; }
+ inline const SwFont *GetFnt() const { return pFnt; }
+#ifdef DEBUG
+ void Dump( SvStream &rOS ) const;
+#endif
+};
+
+
+#endif
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
new file mode 100644
index 000000000000..974cb4d40619
--- /dev/null
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -0,0 +1,923 @@
+/*************************************************************************
+ *
+ * $RCSfile: itrcrsr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "errhdl.hxx"
+#include "ndtxt.hxx"
+#include "frmfmt.hxx"
+#include "paratr.hxx"
+#include "flyfrm.hxx"
+
+#ifndef _SVX_PROTITEM_HXX //autogen
+#include <svx/protitem.hxx>
+#endif
+#ifndef _SVX_ADJITEM_HXX //autogen
+#include <svx/adjitem.hxx>
+#endif
+#ifndef _SVX_LSPCITEM_HXX //autogen
+#include <svx/lspcitem.hxx>
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include <svx/lrspitem.hxx>
+#endif
+
+#ifndef _FRMATR_HXX
+#include <frmatr.hxx>
+#endif
+#include "txtcfg.hxx"
+#include "itrtxt.hxx"
+
+#include "txtfrm.hxx"
+#include "flyfrms.hxx"
+#include "porglue.hxx" // SwFlyCnt
+#include "porfld.hxx" // SwFldPortion::IsFollow()
+#include "porfly.hxx" // GetFlyCrsrOfst()
+#include "pordrop.hxx"
+#include "crstate.hxx" // SwCrsrMoveState
+
+// Nicht reentrant !!!
+// wird in GetCharRect gesetzt und im UnitUp/Down ausgewertet.
+sal_Bool SwTxtCursor::bRightMargin = sal_False;
+
+/*************************************************************************
+ * SwTxtMargin::CtorInit()
+ *************************************************************************/
+void SwTxtMargin::CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pNewInf )
+{
+ SwTxtIter::CtorInit( pFrm, pNewInf );
+
+ pInf = pNewInf;
+ GetInfo().SetFont( GetFnt() );
+ SwTxtNode *pNode = pFrm->GetTxtNode();
+
+ const SvxLRSpaceItem &rSpace =
+ pFrm->GetTxtNode()->GetSwAttrSet().GetLRSpace();
+ nRight = pFrm->Frm().Left() + pFrm->Prt().Left() + pFrm->Prt().Width();
+ nLeft = Max( long( rSpace.GetTxtLeft() + pNode->GetLeftMarginWithNum(sal_True)),
+ pFrm->Prt().Left() ) + pFrm->Frm().Left();
+ if( nLeft >= nRight )
+ nLeft = pFrm->Prt().Left() + pFrm->Frm().Left();
+ if( nLeft >= nRight ) // z.B. bei grossen Absatzeinzuegen in schmalen Tabellenspalten
+ nRight = nLeft + 1; // einen goennen wir uns immer
+ if( pFrm->IsFollow() && pFrm->GetOfst() )
+ nFirst = nLeft;
+ else
+ {
+ short nFLOfst;
+ long nFirstLineOfs;
+ if( !pNode->GetFirstLineOfsWithNum( nFLOfst ) &&
+ rSpace.IsAutoFirst() )
+ {
+ nFirstLineOfs = GetFnt()->GetSize( GetFnt()->GetActual() ).Height();
+ const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing();
+ if( pSpace )
+ {
+ switch( pSpace->GetLineSpaceRule() )
+ {
+ case SVX_LINE_SPACE_AUTO:
+ break;
+ case SVX_LINE_SPACE_MIN:
+ {
+ if( nFirstLineOfs < KSHORT( pSpace->GetLineHeight() ) )
+ nFirstLineOfs = pSpace->GetLineHeight();
+ break;
+ }
+ case SVX_LINE_SPACE_FIX:
+ nFirstLineOfs = pSpace->GetLineHeight();
+ break;
+ default: ASSERT( sal_False, ": unknown LineSpaceRule" );
+ }
+ switch( pSpace->GetInterLineSpaceRule() )
+ {
+ case SVX_INTER_LINE_SPACE_OFF:
+ break;
+ case SVX_INTER_LINE_SPACE_PROP:
+ {
+ long nTmp = pSpace->GetPropLineSpace();
+ // 50% ist das Minimum, bei 0% schalten wir auf
+ // den Defaultwert 100% um ...
+ if( nTmp < 50 )
+ nTmp = nTmp ? 50 : 100;
+
+ nTmp *= nFirstLineOfs;
+ nTmp /= 100;
+ if( !nTmp )
+ ++nTmp;
+ nFirstLineOfs = (KSHORT)nTmp;
+ break;
+ }
+ case SVX_INTER_LINE_SPACE_FIX:
+ {
+ nFirstLineOfs += pSpace->GetInterLineSpace();
+ break;
+ }
+ default: ASSERT( sal_False, ": unknown InterLineSpaceRule" );
+ }
+ }
+ }
+ else
+ nFirstLineOfs = nFLOfst;
+ nFirst = Max( rSpace.GetTxtLeft() + pNode->GetLeftMarginWithNum( sal_True )
+ + nFirstLineOfs, pFrm->Prt().Left() ) + pFrm->Frm().Left();
+ if( nFirst >= nRight )
+ nFirst = nRight - 1;
+ }
+ const SvxAdjustItem& rAdjust = pFrm->GetTxtNode()->GetSwAttrSet().GetAdjust();
+ nAdjust = rAdjust.GetAdjust();
+ bOneBlock = rAdjust.GetOneWord() == SVX_ADJUST_BLOCK;
+ bLastBlock = rAdjust.GetLastBlock() == SVX_ADJUST_BLOCK;
+ bLastCenter = rAdjust.GetLastBlock() == SVX_ADJUST_CENTER;
+#ifdef DEBUG
+ static sal_Bool bOne = sal_False;
+ static sal_Bool bLast = sal_False;
+ static sal_Bool bCenter = sal_False;
+ bOneBlock |= bOne;
+ bLastBlock |= bLast;
+ bLastCenter |= bCenter;
+#endif
+ DropInit();
+}
+
+/*************************************************************************
+ * SwTxtMargin::DropInit()
+ *************************************************************************/
+void SwTxtMargin::DropInit()
+{
+ nDropLeft = nDropLines = nDropHeight = nDropDescent = 0;
+ const SwParaPortion *pPara = GetInfo().GetParaPortion();
+ if( pPara )
+ {
+ const SwDropPortion *pPorDrop = pPara->FindDropPortion();
+ if ( pPorDrop )
+ {
+ nDropLeft = pPorDrop->GetDropLeft();
+ nDropLines = pPorDrop->GetLines();
+ nDropHeight = pPorDrop->GetDropHeight();
+ nDropDescent = pPorDrop->GetDropDescent();
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtMargin::GetLineStart()
+ *************************************************************************/
+
+// Unter Beruecksichtigung des Erstzeileneinzuges und der angebenen Breite.
+SwTwips SwTxtMargin::GetLineStart() const
+{
+ SwTwips nRet = GetLeftMargin();
+ if( GetAdjust() != SVX_ADJUST_LEFT &&
+ !pCurr->GetFirstPortion()->IsMarginPortion() )
+ {
+ // Wenn die erste Portion ein Margin ist, dann wird das
+ // Adjustment durch die Portions ausgedrueckt.
+ if( GetAdjust() == SVX_ADJUST_RIGHT )
+ nRet = Right() - CurrWidth();
+ else if( GetAdjust() == SVX_ADJUST_CENTER )
+ nRet += (GetLineWidth() - CurrWidth()) / 2;
+ }
+ return nRet;
+}
+
+/*************************************************************************
+ * SwTxtCursor::CtorInit()
+ *************************************************************************/
+void SwTxtCursor::CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+{
+ SwTxtMargin::CtorInit( pFrm, pInf );
+ // 6096: Vorsicht, die Iteratoren sind abgeleitet!
+ // GetInfo().SetOut( GetInfo().GetWin() );
+}
+
+/*************************************************************************
+ * SwTxtCursor::GetEndCharRect()
+ *************************************************************************/
+
+// 1170: Antikbug: Shift-Ende vergisst das letzte Zeichen ...
+
+sal_Bool SwTxtCursor::GetEndCharRect( SwRect* pOrig, const xub_StrLen nOfst,
+ SwCrsrMoveState* pCMS, const long nMax )
+{
+ // 1170: Mehrdeutigkeit von Dokumentpositionen
+ bRightMargin = sal_True;
+ CharCrsrToLine(nOfst);
+
+ // Etwas verdreht: nOfst bezeichnet die Position hinter dem letzten
+ // Zeichen der letzten Zeile == Position vor dem ersten Zeichen der
+ // Zeile in der wir gerade stehen:
+ if( nOfst != GetStart() || !pCurr->GetLen() )
+ {
+ // 8810: Masterzeile RightMargin, danach LeftMargin
+ const sal_Bool bRet = GetCharRect( pOrig, nOfst, pCMS, nMax );
+ bRightMargin = nOfst >= GetEnd() && nOfst < GetInfo().GetTxt().Len();
+ return bRet;
+ }
+
+ if( !GetPrev() || !GetPrev()->GetLen() || !PrevLine() )
+ return GetCharRect( pOrig, nOfst, pCMS, nMax );
+
+ // Adjustierung ggf. nachholen
+ GetAdjusted();
+
+ KSHORT nX = 0;
+ KSHORT nLast = 0;
+ SwLinePortion *pPor = pCurr->GetFirstPortion();
+
+ KSHORT nTmpHeight, nTmpAscent;
+ CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+ KSHORT nPorHeight = nTmpHeight;
+ KSHORT nPorAscent = nTmpAscent;
+
+ // Die letzte Text/EndPortion der Zeile suchen
+ while( pPor )
+ {
+ nX += pPor->Width();
+ if( pPor->InTxtGrp() || ( pPor->GetLen() && !pPor->IsFlyPortion()
+ && !pPor->IsHolePortion() ) || pPor->IsBreakPortion() )
+ {
+ nLast = nX;
+ nPorHeight = pPor->Height();
+ nPorAscent = pPor->GetAscent();
+ }
+ pPor = pPor->GetPortion();
+ }
+
+ const Size aCharSize( 1, nTmpHeight );
+ pOrig->Pos( GetTopLeft() );
+ pOrig->SSize( aCharSize );
+ pOrig->Pos().X() += nLast;
+ const SwTwips nRight = Right() - 1;
+ if( pOrig->Left() > nRight )
+ pOrig->Pos().X() = nRight;
+
+ if ( pCMS && pCMS->bRealHeight )
+ {
+ if ( nTmpAscent > nPorAscent )
+ pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
+ else
+ pCMS->aRealHeight.X() = 0;
+ ASSERT( nPorHeight, "GetCharRect: Missing Portion-Height" );
+ pCMS->aRealHeight.Y() = nPorHeight;
+ }
+
+ return sal_True;
+}
+
+/*************************************************************************
+ * SwTxtCursor::GetCharRect()
+ *
+ * Tabs: Ist das aktuelle Zeichen das Tabzeichen, dann liefert
+ * GetCharRect() das SwRect hinter dem letzten Character in
+ * der vorhergehenden Portion. Ist das aktuelle Zeichen das
+ * Zeichen nach dem Tabzeichen, so wird das SwRect am Anfang
+ * der Portion-Box geliefert, weil das Tabzeichen selber
+ * unsichtbar ist. Oder andersherum: Wenn eine Portion mit einem
+ * Tabzeichen beginnt, dann darf dieses Tabzeichen bei der
+ * Berechnung des x-Offset der Characterbox innerhalb der Portion
+ * nicht beruecksichtigt werden.
+ *
+ *************************************************************************/
+sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
+ SwCrsrMoveState* pCMS, const long nMax )
+{
+ BOOL bDropIt = pCMS && pCMS->bDropIt;
+ CharCrsrToLine(nOfst);
+
+ // Adjustierung ggf. nachholen
+ GetAdjusted();
+
+ const XubString &rText = GetInfo().GetTxt();
+ SwTxtSizeInfo aInf( GetInfo(), rText, nStart );
+ KSHORT nTmpAscent, nTmpHeight; // Zeilenhoehe
+ CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+ const Size aCharSize( 1, nTmpHeight );
+ const Point aCharPos( GetTopLeft() );
+ pOrig->Pos( aCharPos );
+ pOrig->SSize( aCharSize );
+ sal_Bool bRet = sal_True;
+ if( !pCurr->GetLen() && !pCurr->Width() )
+ {
+ if ( pCMS && pCMS->bRealHeight )
+ {
+ pCMS->aRealHeight.X() = 0;
+ pCMS->aRealHeight.Y() = nTmpHeight;
+ }
+ }
+ else
+ {
+ KSHORT nPorHeight = nTmpHeight;
+ KSHORT nPorAscent = nTmpAscent;
+ KSHORT nX = 0;
+ KSHORT nFirst = 0;
+ SwLinePortion *pPor = pCurr->GetFirstPortion();
+ SvShorts *pSpaceAdd = pCurr->GetpSpaceAdd();
+ MSHORT nSpaceIdx = 0;
+ short nSpaceAdd = pSpaceAdd ? (*pSpaceAdd)[0] : 0;
+ sal_Bool bNoTxt = sal_True;
+
+ // Zuerst werden alle Portions ohne Len am Zeilenanfang uebersprungen.
+ // Ausnahme bilden die fiesen Spezialportions aus WhichFirstPortion:
+ // Num, ErgoSum, FtnNum, FeldReste
+ // 8477: aber auch die einzige Textportion einer leeren Zeile mit
+ // Right/Center-Adjustment! Also nicht nur pPor->GetExpandPortion() ...
+
+ while( pPor && !pPor->GetLen() )
+ {
+ nX += pPor->Width();
+ if ( pPor->InTxtGrp() && nSpaceAdd )
+ nX += ( (SwTxtPortion*)pPor )->CalcSpacing( nSpaceAdd, aInf );
+ if( bNoTxt )
+ nFirst = nX;
+ // 8670: EndPortions zaehlen hier einmal als TxtPortions.
+ if( pPor->InTxtGrp() || pPor->IsBreakPortion() )
+ {
+ bNoTxt = sal_False;
+ nFirst = nX;
+ }
+ if( pPor->InFixMargGrp() )
+ {
+ if( pPor->IsMarginPortion() )
+ bNoTxt = sal_False;
+ if( pSpaceAdd )
+ {
+ if( nSpaceAdd < 0 )
+ nX += nSpaceAdd;
+ if ( ++nSpaceIdx < pSpaceAdd->Count() )
+ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+ else
+ nSpaceAdd = 0;
+ }
+ }
+ pPor = pPor->GetPortion();
+ }
+
+ if( !pPor )
+ {
+ // Es sind nur Spezialportions unterwegs.
+ nX = nFirst;
+ }
+ else
+ {
+ if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
+ (!pPor->InFldGrp() || pPor->GetAscent() ) )
+ {
+ nPorHeight = pPor->Height();
+ nPorAscent = pPor->GetAscent();
+ }
+ while( pPor && aInf.GetIdx() < nOfst && !pPor->IsBreakPortion() )
+ {
+ if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
+ (!pPor->InFldGrp() || pPor->GetAscent() ) )
+ {
+ nPorHeight = pPor->Height();
+ nPorAscent = pPor->GetAscent();
+ }
+ if ( aInf.GetIdx() + pPor->GetLen() <= nOfst )
+ {
+ if ( pPor->InTxtGrp() && nSpaceAdd )
+ nX += pPor->PrtWidth() + ( (SwTxtPortion*)pPor )->
+ CalcSpacing( nSpaceAdd, aInf );
+ else
+ {
+ if( pPor->InFixMargGrp() && pSpaceAdd )
+ {
+ if( nSpaceAdd < 0 )
+ nX += nSpaceAdd;
+ if ( ++nSpaceIdx < pSpaceAdd->Count() )
+ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+ else
+ nSpaceAdd = 0;
+ }
+ if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
+ !pPor->GetPortion()->IsMarginPortion() ) )
+ nX += pPor->PrtWidth();
+ }
+ aInf.SetIdx( aInf.GetIdx() + pPor->GetLen() );
+ pPor = pPor->GetPortion();
+ }
+ else
+ {
+ if ( pPor->PrtWidth() )
+ {
+ xub_StrLen nOldLen = pPor->GetLen();
+ pPor->SetLen( nOfst - aInf.GetIdx() );
+ aInf.SetLen( pPor->GetLen() );
+ if( nX || ( !pPor->InNumberGrp() &&
+ ( bDropIt || !pPor->IsDropPortion() ) ) )
+ {
+ SeekAndChg( aInf );
+ const sal_Bool bOldOnWin = aInf.OnWin();
+ aInf.SetOnWin( sal_False ); // keine BULLETs!
+ nX += pPor->GetTxtSize( aInf ).Width();
+ aInf.SetOnWin( bOldOnWin );
+ if ( pPor->InTxtGrp() && nSpaceAdd )
+ nX += ( (SwTxtPortion*)pPor )->CalcSpacing(
+ nSpaceAdd, aInf );
+ }
+ pPor->SetLen( nOldLen );
+ }
+ break;
+ }
+ }
+ }
+
+ if( pPor )
+ {
+ // Bei manchen Portions gibts es kein links (Number, DropCap)
+ if( pPor->InNumberGrp() || ( pPor->IsDropPortion() && !bDropIt ) )
+ {
+ nX += pPor->Width();
+ if( pPor->GetPortion() && pPor->GetPortion()->IsMarginPortion() )
+ {
+ nX += pPor->GetPortion()->Width();
+ nPorHeight = pPor->GetPortion()->Height();
+ nPorAscent = pPor->GetPortion()->GetAscent();
+ }
+ else
+ bRet = sal_False;
+ }
+ else
+ {
+ sal_Bool bEmptyFld = sal_False;
+ if( pPor->InFldGrp() && pPor->GetLen() )
+ {
+ SwFldPortion *pTmp = (SwFldPortion*)pPor;
+ while( pTmp->HasFollow() && !pTmp->GetExp().Len() )
+ {
+ KSHORT nAddX = pTmp->Width();
+ SwLinePortion *pNext = pTmp->GetPortion();
+ while( pNext && !pNext->InFldGrp() )
+ {
+ if( pNext->GetLen() )
+ pNext = NULL; // Gibt's das ueberhaupt?
+ else
+ {
+ nAddX += pNext->Width();
+ pNext = pNext->GetPortion();
+ }
+ }
+ if( !pNext )
+ break;
+ pTmp = (SwFldPortion*)pNext;
+ nPorHeight = pTmp->Height();
+ nPorAscent = pTmp->GetAscent();
+ nX += nAddX;
+ bEmptyFld = sal_True;
+ }
+ }
+ // 8513: Felder im Blocksatz, ueberspringen
+ while( pPor && !pPor->GetLen() && ( pPor->IsFlyPortion() ||
+ ( !bEmptyFld && pPor->InFldGrp() ) ) )
+ {
+ if ( pPor->InTxtGrp() && nSpaceAdd )
+ nX += pPor->PrtWidth() + ( (SwTxtPortion*)pPor )->
+ CalcSpacing( nSpaceAdd, aInf );
+ else
+ {
+ if( pPor->InFixMargGrp() && pSpaceAdd )
+ {
+ if( nSpaceAdd < 0 )
+ nX += nSpaceAdd;
+ if ( ++nSpaceIdx < pSpaceAdd->Count() )
+ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+ else
+ nSpaceAdd = 0;
+ }
+ if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
+ !pPor->GetPortion()->IsMarginPortion() ) )
+ nX += pPor->PrtWidth();
+ }
+ if( !pPor->IsFlyPortion() )
+ {
+ nPorHeight = pPor->Height();
+ nPorAscent = pPor->GetAscent();
+ }
+ pPor = pPor->GetPortion();
+ }
+ }
+
+ if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() &&
+ pPor->GetPortion() && pPor->GetPortion()->InFixGrp() )
+ {
+ // Alle Sonderportions muessen uebersprungen werden
+ // Beispiel: zu-[FLY]sammen, 'u' == 19, 's' == 20; Right()
+ // Ohne den Ausgleich landen wir vor '-' mit dem
+ // Ausgleich vor 's'.
+ while( pPor && !pPor->GetLen() )
+ {
+ DBG_LOOP;
+ nX += pPor->Width();
+ if( !pPor->IsMarginPortion() )
+ {
+ nPorHeight = pPor->Height();
+ nPorAscent = pPor->GetAscent();
+ }
+ pPor = pPor->GetPortion();
+ }
+ }
+ if( pPor && pCMS )
+ {
+ if( pCMS->bFieldInfo && pPor->InFldGrp() && pPor->Width() )
+ pOrig->Width( pPor->Width() );
+ if( pPor->IsDropPortion() && bDropIt )
+ pOrig->Height( ((SwDropPortion*)pPor)->GetDropHeight() +
+ ((SwDropPortion*)pPor)->GetDropDescent());
+ }
+ }
+ // Es darf nicht vorzeitig returnt werden.
+ // 6798: nicht auf pOrig->Right() rumhuehnern.
+ pOrig->Pos().X() += nX;
+
+ // Hier muesste eigentlich "-1 LogicToPixel" stehen, dies erscheint
+ // mir aber zu teuer, deshalb ein Wert (-12), mit dem es sich hoffentlich
+ // leben laesst?
+ const SwTwips nRight = Right() - 12;
+
+ if( pOrig->Left() > nRight )
+ pOrig->Pos().X() = nRight;
+
+ if ( pCMS && pCMS->bRealHeight )
+ {
+ if ( nTmpAscent > nPorAscent )
+ pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
+ else
+ pCMS->aRealHeight.X() = 0;
+ ASSERT( nPorHeight, "GetCharRect: Missing Portion-Height" );
+ if ( nTmpHeight > nPorHeight )
+ pCMS->aRealHeight.Y() = nPorHeight;
+ else
+ pCMS->aRealHeight.Y() = nTmpHeight;
+ }
+ }
+ if( nMax )
+ {
+ if( pOrig->Bottom() > nMax )
+ {
+ if( pOrig->Top() > nMax )
+ pOrig->Top( nMax );
+ pOrig->Bottom( nMax );
+ }
+ if ( pCMS && pCMS->bRealHeight )
+ {
+ long nTmp = pCMS->aRealHeight.X() + pOrig->Top();
+ if( nTmp >= nMax )
+ {
+ pCMS->aRealHeight.X() = nMax - pOrig->Top();
+ pCMS->aRealHeight.Y() = 0;
+ }
+ else if( nTmp + pCMS->aRealHeight.Y() > nMax )
+ pCMS->aRealHeight.Y() = nMax - nTmp;
+ }
+ }
+ long nOut = pOrig->Right() - GetTxtFrm()->Frm().Right();
+ if( nOut > 0 )
+ {
+ if( GetTxtFrm()->Frm().Width() < GetTxtFrm()->Prt().Left()
+ + GetTxtFrm()->Prt().Width() )
+ nOut += GetTxtFrm()->Frm().Width() - GetTxtFrm()->Prt().Left()
+ - GetTxtFrm()->Prt().Width();
+ if( nOut > 0 )
+ pOrig->Pos().X() -= nOut + 10;
+ }
+ return bRet;
+}
+
+/*************************************************************************
+ * SwTxtCursor::GetCrsrOfst()
+ *
+ * Return: Offset im String
+ *************************************************************************/
+xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
+ const MSHORT nChgNode, const SwCrsrMoveState* pCMS ) const
+{
+ // Adjustierung ggf. nachholen
+ GetAdjusted();
+
+ const XubString &rText = GetInfo().GetTxt();
+ xub_StrLen nOffset = 0;
+
+ // x ist der horizontale Offset innerhalb der Zeile.
+ SwTwips x = rPoint.X();
+ CONST SwTwips nLeftMargin = GetLineStart();
+ SwTwips nRightMargin = GetLineEnd();
+ if( nRightMargin == nLeftMargin )
+ nRightMargin += 30;
+
+ if(x < nLeftMargin)
+ x = nLeftMargin;
+ sal_Bool bRightOver = x > nRightMargin;
+ if( bRightOver )
+ x = nRightMargin;
+
+ sal_Bool bRightAllowed = pCMS && ( pCMS->eState == MV_NONE );
+
+ // Bis hierher in Dokumentkoordinaten.
+ x -= nLeftMargin;
+
+ KSHORT nX = KSHORT( x );
+
+ // Wenn es in der Zeile Attributwechsel gibt, den Abschnitt
+ // suchen, in dem nX liegt.
+ SwLinePortion *pPor = pCurr->GetFirstPortion();
+ xub_StrLen nCurrStart = nStart;
+ sal_Bool bLastPortion;
+ sal_Bool bHolePortion = sal_False;
+ sal_Bool bLastHyph = sal_False;
+
+ SvShorts *pSpaceAdd = pCurr->GetpSpaceAdd();
+ xub_StrLen nOldIdx = GetInfo().GetIdx();
+ MSHORT nSpaceIdx = 0;
+ short nSpaceAdd = pSpaceAdd ? (*pSpaceAdd)[0] : 0;
+
+ // nWidth ist die Breite der Zeile, oder die Breite des
+ // Abschnitts mit dem Fontwechsel, in dem nX liegt.
+
+ KSHORT nWidth = pPor->Width();
+ if ( pSpaceAdd )
+ {
+ if ( pPor->InTxtGrp() && nSpaceAdd )
+ {
+ ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
+ nWidth += ((SwTxtPortion*)pPor)->CalcSpacing( nSpaceAdd, GetInfo() );
+ }
+ else if( pPor->InFixMargGrp() )
+ {
+ if ( ++nSpaceIdx < pSpaceAdd->Count() )
+ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+ else
+ nSpaceAdd = 0;
+ }
+
+ }
+
+ KSHORT nWidth30 = !nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp()
+ ? 30 : nWidth;
+
+ while(!(bLastPortion = (0 == pPor->GetPortion())) && nWidth30 < nX &&
+ !pPor->IsBreakPortion() )
+ {
+ if ( pPor->IsPostItsPortion() && pPor->GetViewWidth( GetInfo() )/2 > nX )
+ break;
+
+ nX -= nWidth;
+ nCurrStart += pPor->GetLen();
+ bHolePortion = pPor->IsHolePortion();
+ pPor = pPor->GetPortion();
+ nWidth = pPor->Width();
+ if ( pSpaceAdd )
+ {
+ if ( pPor->InTxtGrp() && nSpaceAdd )
+ {
+ ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
+ nWidth += ((SwTxtPortion*)pPor)->CalcSpacing( nSpaceAdd, GetInfo() );
+ }
+ else if( pPor->InFixMargGrp() )
+ {
+ if ( ++nSpaceIdx < pSpaceAdd->Count() )
+ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx];
+ else
+ nSpaceAdd = 0;
+ }
+ }
+ nWidth30 = !nWidth && pPor->GetLen() && ( pPor->InToxRefOrFldGrp() ||
+ pPor->IsPostItsPortion() ) ? 30 : nWidth;
+ if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
+ bLastHyph = pPor->InHyphGrp();
+ }
+
+ if( nX==nWidth )
+ {
+ SwLinePortion *pNextPor = pPor->GetPortion();
+ while( pNextPor && pNextPor->InFldGrp() && !pNextPor->Width() )
+ {
+ nCurrStart += pPor->GetLen();
+ pPor = pNextPor;
+ if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
+ bLastHyph = pPor->InHyphGrp();
+ pNextPor = pPor->GetPortion();
+ }
+ }
+
+ ((SwTxtSizeInfo&)GetInfo()).SetIdx( nOldIdx );
+
+ xub_StrLen nLength = pPor->GetLen();
+
+ sal_Bool bFieldInfo = pCMS && pCMS->bFieldInfo;
+
+ if( bFieldInfo && ( nWidth30 < nX || bRightOver ||
+ ( pPor->InNumberGrp() && !pPor->IsFtnNumPortion() ) ||
+ ( pPor->IsMarginPortion() && nWidth > nX + 30 ) ) )
+ ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
+
+ // 7684: Wir sind genau auf der HyphPortion angelangt und muessen dafuer
+ // sorgen, dass wir in dem String landen.
+ // 7993: Wenn die Laenge 0 ist muessen wir raus...
+ if( !nLength )
+ {
+ if( pCMS )
+ {
+ if( pPor->IsFlyPortion() && bFieldInfo )
+ ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
+
+ if( pPor->IsFtnNumPortion() && !bRightOver && nX )
+ ((SwCrsrMoveState*)pCMS)->bFtnNoInfo = sal_True;
+ }
+ if( !nCurrStart )
+ return 0;
+
+ // 7849, 7816: auf pPor->GetHyphPortion kann nicht verzichtet werden!
+ if( bHolePortion || ( !bRightAllowed && bLastHyph ) ||
+ ( pPor->IsMarginPortion() && !pPor->GetPortion() &&
+ // 46598: In der letzten Zeile eines zentrierten Absatzes wollen
+ // wir auch mal hinter dem letzten Zeichen landen.
+ nCurrStart < rText.Len() ) )
+ --nCurrStart;
+ else if( pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow()
+ && nWidth > nX )
+ {
+ if( bFieldInfo )
+ --nCurrStart;
+ else
+ {
+ KSHORT nHeight = pPor->Height();
+ if ( !nHeight || nHeight > nWidth )
+ nHeight = nWidth;
+ if( nChgNode && nWidth - nHeight/2 > nX )
+ --nCurrStart;
+ }
+ }
+ return nCurrStart;
+ }
+ if ( 1 == nLength )
+ {
+ if ( nWidth )
+ {
+ // Sonst kommen wir nicht mehr in zeichengeb. Rahmen hinein...
+ if( !( nChgNode && pPos && pPor->IsFlyCntPortion() ) )
+ {
+ if ( pPor->InFldGrp() )
+ {
+ KSHORT nHeight = 0;
+ if( !bFieldInfo )
+ {
+ nHeight = pPor->Height();
+ if ( !nHeight || nHeight > nWidth )
+ nHeight = nWidth;
+ }
+ if( !((SwFldPortion*)pPor)->HasFollow() &&
+ nWidth - nHeight/2 <= nX )
+ ++nCurrStart;
+ }
+ else if( ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
+ !pPor->GetPortion()->IsMarginPortion() &&
+ !pPor->GetPortion()->IsHolePortion() ) )
+ && ( nWidth/2 < nX ) && !bFieldInfo
+ && ( bRightAllowed || !bLastHyph ))
+ ++nCurrStart;
+ return nCurrStart;
+ }
+ }
+ else
+ {
+ if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() ||
+ pPor->InToxRefGrp() )
+ return nCurrStart;
+ if ( pPor->InFldGrp() )
+ {
+ if( bRightOver && !((SwFldPortion*)pPor)->HasFollow() )
+ ++nCurrStart;
+ return nCurrStart;
+ }
+ }
+ }
+
+ if( bLastPortion && (pCurr->GetNext() || pFrm->GetFollow() ) )
+ --nLength;
+
+ if( nWidth > nX )
+ {
+ if( pPor->InTxtGrp() )
+ {
+ SwTxtSizeInfo aSizeInf( GetInfo(), rText, nCurrStart );
+ ((SwTxtCursor*)this)->SeekAndChg( aSizeInf );
+ SwTxtSlot aDiffTxt( &aSizeInf, ((SwTxtPortion*)pPor) );
+// nLength = aSizeInf.GetCrsrOfst( nX, nSpaceAdd );
+ nLength = aSizeInf.GetFont()->_GetCrsrOfst( aSizeInf.GetVsh(),
+ aSizeInf.GetOut(),
+ aSizeInf.GetTxt(), nX, aSizeInf.GetIdx(),
+ pPor->GetLen(), nSpaceAdd );
+ if( bFieldInfo && nLength == pPor->GetLen() )
+ --nLength;
+ }
+ else
+ {
+ if( nChgNode && pPos && pPor->IsFlyCntPortion()
+ && !( (SwFlyCntPortion*)pPor )->IsDraw() )
+ {
+ // JP 24.11.94: liegt die Pos nicht im Fly, dann
+ // darf nicht mit STRING_LEN returnt werden!
+ // (BugId: 9692 + Aenderung in feshview)
+ SwFlyInCntFrm *pTmp = ( (SwFlyCntPortion*)pPor )->GetFlyFrm();
+ sal_Bool bChgNode = 1 < nChgNode;
+ if( !bChgNode )
+ {
+ SwFrm* pLower = pTmp->GetLower();
+ if( pLower && (pLower->IsTxtFrm() || pLower->IsLayoutFrm()) )
+ bChgNode = sal_True;
+ }
+ if( bChgNode && pTmp->Frm().IsInside( rPoint ) &&
+ !( pTmp->IsProtected() ) )
+ {
+ nLength = ((SwFlyCntPortion*)pPor)->
+ GetFlyCrsrOfst( nX, rPoint, pPos, pCMS );
+ // Sobald der Frame gewechselt wird, muessen wir aufpassen, dass
+ // unser Font wieder im OutputDevice steht.
+ // vgl. Paint und new SwFlyCntPortion !
+ ((SwTxtSizeInfo*)pInf)->SelectFont();
+
+ // 6776: Das pIter->GetCrsrOfst returnt
+ // aus einer Verschachtelung mit STRING_LEN.
+ return STRING_LEN;
+ }
+ }
+ else
+ nLength = pPor->GetCrsrOfst( nX );
+ }
+ }
+ nOffset = nCurrStart + nLength;
+
+ // 7684: Wir sind vor der HyphPortion angelangt und muessen dafuer
+ // sorgen, dass wir in dem String landen.
+ // Bei Zeilenenden vor FlyFrms muessen ebenso behandelt werden.
+
+ if( nOffset && pPor->GetLen() == nLength && pPor->GetPortion() &&
+ !pPor->GetPortion()->GetLen() && pPor->GetPortion()->InHyphGrp() )
+ --nOffset;
+
+ return nOffset;
+}
+
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
new file mode 100644
index 000000000000..454f81b70085
--- /dev/null
+++ b/sw/source/core/text/itrform2.cxx
@@ -0,0 +1,1491 @@
+/*************************************************************************
+ *
+ * $RCSfile: itrform2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _LAYFRM_HXX
+#include <layfrm.hxx> // GetFrmRstHeight, etc
+#endif
+#ifndef _VIEWSH_HXX
+#include <viewsh.hxx>
+#endif
+#ifndef _VIEWOPT_HXX
+#include <viewopt.hxx> // SwViewOptions
+#endif
+#ifndef _PARATR_HXX
+#include <paratr.hxx> // SwFmtDrop
+#endif
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx> // CH_TXTATR
+#endif
+#ifndef _TXTCFG_HXX
+#include <txtcfg.hxx>
+#endif
+#ifndef _ITRFORM2_HXX
+#include <itrform2.hxx>
+#endif
+#ifndef _SWFONT_HXX
+#include <swfont.hxx> // IsTox, IsRef, SetLingu
+#endif
+#ifndef _PORRST_HXX
+#include <porrst.hxx>
+#endif
+#ifndef _PORTAB_HXX
+#include <portab.hxx> // pLastTab->
+#endif
+#ifndef _PORFLY_HXX
+#include <porfly.hxx> // CalcFlyWidth
+#endif
+#ifndef _PORTOX_HXX
+#include <portox.hxx> // WhichTxtPortion
+#endif
+#ifndef _PORREF_HXX
+#include <porref.hxx> // WhichTxtPortion
+#endif
+#ifndef _PORFLD_HXX
+#include <porfld.hxx> // SwNumberPortion fuer CalcAscent()
+#endif
+#ifndef _PORFTN_HXX
+#include <porftn.hxx> // SwFtnPortion
+#endif
+#ifndef _POREXP_HXX
+#include <porexp.hxx>
+#endif
+#ifndef _PORHYPH_HXX
+#include <porhyph.hxx>
+#endif
+#ifndef _GUESS_HXX
+#include <guess.hxx> // Recycle()
+#endif
+#ifndef _TXTFRM_HXX
+#include <txtfrm.hxx> // GetFrmRstHeight, etc
+#endif
+#ifndef _BLINK_HXX
+#include <blink.hxx> // pBlink
+#endif
+#ifndef _FTNFRM_HXX
+#include <ftnfrm.hxx> // WhichFirstPortion() -> mal Verlagern.
+#endif
+#ifndef _REDLNITR_HXX
+#include <redlnitr.hxx> // SwRedlineItr
+#endif
+
+#ifdef DEBUG
+#ifndef _NDTXT_HXX
+#include <ndtxt.hxx> // pSwpHints, Ausgabeoperator
+#endif
+#endif
+
+
+
+#define MAX_TXTPORLEN 300
+
+inline void ClearFly( SwTxtFormatInfo &rInf )
+{
+ if( rInf.GetFly() )
+ {
+ delete rInf.GetFly();
+ rInf.SetFly(0);
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::CtorInit()
+ *************************************************************************/
+
+void SwTxtFormatter::CtorInit( SwTxtFrm *pFrm, SwTxtFormatInfo *pNewInf )
+{
+ SwTxtPainter::CtorInit( pFrm, pNewInf );
+ pInf = pNewInf;
+ pDropFmt = GetInfo().GetDropFmt();
+
+ bOnceMore = sal_False;
+ bChanges = sal_False;
+ bTruncLines = sal_False;
+ nNextChg = 0;
+ nCntEndHyph = 0;
+ nCntMidHyph = 0;
+
+ if( nStart > GetInfo().GetTxt().Len() )
+ {
+ ASSERT( !this, "+SwTxtFormatter::CTOR: bad offset" );
+ nStart = GetInfo().GetTxt().Len();
+ }
+
+}
+
+/*************************************************************************
+ * SwTxtFormatter::DTOR
+ *************************************************************************/
+
+SwTxtFormatter::~SwTxtFormatter()
+{
+ // restore hyphenation options if necessary
+ if (GetInfo().IsRestoreHyphOptions())
+ {
+ GetInfo().RestoreHyphOptions();
+ }
+
+ // Auesserst unwahrscheinlich aber denkbar.
+ // z.B.: Feld spaltet sich auf, Widows schlagen zu
+ if( GetInfo().GetRest() )
+ {
+ delete GetInfo().GetRest();
+ GetInfo().SetRest(0);
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::Insert()
+ *************************************************************************/
+
+void SwTxtFormatter::Insert( SwLineLayout *pLay )
+{
+ // Einfuegen heute mal ausnahmsweise hinter dem aktuellen Element.
+ if ( pCurr )
+ {
+ pLay->SetNext( pCurr->GetNext() );
+ pCurr->SetNext( pLay );
+ }
+ else
+ pCurr = pLay;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::GetFrmRstHeight()
+ *************************************************************************/
+
+KSHORT SwTxtFormatter::GetFrmRstHeight() const
+{
+ // 8725: Uns interessiert die Resthoehe bezogen auf die Seite.
+ // Wenn wir in einer Tabelle stehen, dann ist pFrm->GetUpper() nicht
+ // die Seite. GetFrmRstHeight() wird im Zusammenhang mit den Ftn
+ // gerufen.
+ // Falsch: const SwFrm *pUpper = pFrm->GetUpper();
+ const SwFrm *pPage = (const SwFrm*)pFrm->FindPageFrm();
+ const SwTwips nHeight = pPage->Frm().Top()
+ + pPage->Prt().Top()
+ + pPage->Prt().Height() - Y();
+ if( 0 > nHeight )
+ return pCurr->Height();
+ else
+ return KSHORT( nHeight );
+}
+
+/*************************************************************************
+ * SwTxtFormatter::Recycle()
+ *************************************************************************/
+
+/* Recycle dient nicht nur der Optimierung, sondern soll gleichzeitig
+ * unsere Probleme mit dem WYSIWYG (flackern und tanzen) loesen helfen.
+ * Recycle betrachtet den Bereich einer Zeile _vor_ nReformat.
+ * 4 Faelle koennen auftreten:
+ * 1) pCurr ist hinter nReformat
+ * Init, sal_False
+ * 2) pCurr wurde nagelneu angelegt
+ * -> pPos == 0, sal_False
+ * 3) pCurr hatte Portions und nReformat liegt in der Zeile
+ * -> pPos != 0, sal_True
+ * 4) pCurr hatte Portions und nReformat liegt aber _nicht_ in der Zeile
+ * -> pPos == 0, sal_True
+ * Fall 4 sollte u.U. in ein ASSERT laufen.
+ *
+ * sal_True, wenn recyclet wurde ...
+ */
+
+void SwTxtFormatter::Recycle( SwTxtFormatInfo &rInf )
+{
+#ifndef PRODUCT
+ // Durch das 0 setzen wird Recycle() ausgelassen.
+ if( OPTLOW( rInf ) )
+ pCurr->SetLen(0);
+#endif
+ // GetRest() liefert den (Feld-)Ueberhang der vorigen Zeile zurueck.
+ // Dann gibt es natuerlich nichts zu recyclen ..
+ if( rInf.GetRest() || HasChanges() )
+ {
+ FormatReset( rInf );
+ return;
+ }
+
+ // Optimierung fuer Zeilen, die aus dem Rennen sind
+ xub_StrLen nReformat = rInf.GetReformatStart();
+
+ // Bei rechtsbuendig, zentriert und Blocksatz wird returnt ...
+ sal_Bool bRecycle = IsFirstReformat() && pCurr->GetLen();
+ if( bRecycle )
+ {
+ switch( GetAdjust() )
+ {
+ case SVX_ADJUST_BLOCK:
+ {
+ if( IsLastBlock() || IsLastCenter() )
+ bRecycle = sal_False;
+ else
+ {
+ // ????: Blank in der letzten Masterzeile (blocksat.sdw)
+ bRecycle = 0 == pCurr->GetNext() && !pFrm->GetFollow();
+ if ( bRecycle )
+ {
+ SwLinePortion *pPos = pCurr->GetFirstPortion();
+ while ( pPos && !pPos->IsFlyPortion() )
+ pPos = pPos->GetPortion();
+ bRecycle = !pPos;
+ }
+ }
+ }
+ break;
+ case SVX_ADJUST_CENTER:
+ case SVX_ADJUST_RIGHT:
+ {
+ bRecycle = sal_False;
+ }
+ break;
+ default: ;
+ }
+ }
+
+ // Schon wieder ein Sonderfall: unsichtbare SoftHyphs
+ if( bRecycle && STRING_LEN != nReformat )
+ {
+ const xub_Unicode cCh = rInf.GetTxt().GetChar( nReformat );
+ bRecycle = ( CH_TXTATR_BREAKWORD != cCh && CH_TXTATR_INWORD != cCh )
+ || !rInf.HasHint( nReformat );
+ }
+
+ if( !bRecycle )
+ {
+ FormatReset( rInf );
+ return;
+ }
+
+ // alle Portions retten, die vor nReformat liegen.
+ // pPos kann nie 0 werden.
+ SwLinePortion *pPos = pCurr->GetFirstPortion();
+ SwLinePortion *pLast = pPos;
+
+ // bTabFlag warnt uns vor rechtsbdg. Tabs
+ sal_Bool bTabFlag = pPos->InTabGrp() && !pPos->IsTabLeftPortion();
+
+ while( pPos->GetPortion() && rInf.GetIdx() + pPos->GetLen() < nReformat )
+ {
+ DBG_LOOP;
+ pPos->Move( rInf );
+ pLast = pPos;
+ pPos = pPos->GetPortion();
+
+ if ( bTabFlag )
+ bTabFlag = !( pLast->IsTabLeftPortion() || pLast->IsFlyPortion() );
+
+ bTabFlag = bTabFlag || (pPos->InTabGrp() && !pPos->IsTabLeftPortion());
+ if( pPos->IsFtnPortion() )
+ rInf.SetFtnInside( sal_True );
+ }
+
+ // bBrkBefore ist sal_True, wenn die BrkPos vor oder auf nReformat liegt,
+ // d.h. dass die pPos in jedem Fall neuformatiert werden muss.
+ SwTxtGuess aGuess;
+ rInf.SetLen( nReformat );
+
+ // 6736: Worte hinter Flys, Blank einfuegen.
+ // 6820: Rechtstabs und Blanks
+ xub_StrLen nPrevEnd = nReformat ?
+ aGuess.GetPrevEnd( rInf, nReformat - 1 ) + 1: 0;
+ if ( 1 == nPrevEnd )
+ --nPrevEnd;
+
+ const sal_Bool bBrkBefore = bTabFlag || pLast->InTabnLftGrp() ||
+ pPos->IsQuoVadisPortion() ||
+ ( pLast->IsFlyPortion() && (!nReformat || rInf.GetIdx() >= nPrevEnd) );
+ // Wenn pLast nicht recyclebar ist (R/Z/D-Tabs und SoftHyphs etc)
+ // dann muss diese Portion mit in die Neuformatierung aufgenommen
+ // werden. D.h: pLast wandert um einen zurueck und rInf muss
+ // um den entsprechenden Betrag zurueckgestellt werden.
+
+ if( bBrkBefore )
+ {
+ // 13713: Bei nicht recyclebaren Tabs (rechtsbdg. etc.) muss man
+ // bis zur letzten Nichttextportion zurueckgehen!
+ if( pPos == pLast )
+ pLast = pLast->FindPrevPortion( pCurr );
+ while( pLast != pCurr &&
+ ( !pLast->MayRecycle() || pPos->IsFlyPortion() || bTabFlag ) )
+ {
+ if ( bTabFlag )
+ bTabFlag = pLast->InTxtGrp();
+ else
+ bTabFlag = pLast->InTabGrp();
+
+ rInf.SetIdx( rInf.GetIdx() - pLast->GetLen() );
+ rInf.X( rInf.X() - pLast->Width() );
+ pPos = pLast;
+ pLast = pLast->FindPrevPortion( pCurr );
+ }
+ }
+
+ // Wunder der Technik: der PaintOfst ist die Position in der
+ // Zeile, wo es gleich weiter geht.
+ long nPOfst = 0;
+
+ if ( pPos->InTxtGrp() && rInf.GetIdx() < nPrevEnd &&
+ rInf.GetIdx() + pPos->GetLen() > nPrevEnd )
+ {
+ SwRect aRect;
+ GetCharRect( &aRect, nPrevEnd );
+ nPOfst = aRect.Left();
+ }
+ else
+ nPOfst = rInf.X() + GetLeftMargin();
+
+// AMA-Test: Problem, wenn diese Portion in die naechste Zeile rutscht,
+// behauptet IsFirstReformat, dass die Zeile recycled werden kann, weil
+// Reformat-Start in der Zeile liegt ( aber erst durch das Rutschen! ).
+// Loesung: wir drehen am Reformat-Start
+ rInf.GetParaPortion()->GetReformat()->LeftMove( rInf.GetIdx() );
+#ifdef DEBUG
+ SwTwips nOffset = rInf.X() + GetLeftMargin();
+#endif
+ pPos = pLast == pPos ? pCurr : pLast;
+
+ // nach pPos die Sintflut
+ pPos->Truncate();
+
+ // 9118: pLast ist eine NumPortion, SetNumDone ist nicht sal_True
+ // Alternative: alle Flags setzen...
+ if( pPos == pCurr || !rInf.GetIdx() || pPos->IsErgoSumPortion() )
+ {
+ if( pPos->IsGrfNumPortion() )
+ {
+ if( nReformat && !((SwGrfNumPortion*)pPos)->IsHide() )
+ rInf.SetNumDone( sal_True );
+ else
+ {
+ nPOfst = 0;
+ FormatReset( rInf );
+ }
+ }
+ else
+ FormatReset( rInf );
+ }
+
+ if ( nPOfst )
+ rInf.SetPaintOfst( nPOfst );
+ rInf.SetLen(0);
+
+ // Wir muessen die pCurr-Daten, die sonst waehrend der Fahrt
+ // in NewTxtPortion() ermittelt werden, auf Vordermann bringen.
+ pLast = pCurr->GetPortion();
+ if( pLast )
+ {
+ pCurr->Init( pLast );
+ while( pLast )
+ {
+ DBG_LOOP;
+ if( pCurr->Height() < pLast->Height() )
+ pCurr->Height( pLast->Height() );
+ if( pCurr->GetAscent() < pLast->GetAscent() )
+ pCurr->SetAscent( pLast->GetAscent() );
+ pLast = pLast->GetPortion();
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::UnderFlow()
+ *************************************************************************/
+
+SwLinePortion *SwTxtFormatter::UnderFlow( SwTxtFormatInfo &rInf )
+{
+ // Werte sichern und rInf initialisieren.
+ SwLinePortion *pUnderFlow = rInf.GetUnderFlow();
+ if( !pUnderFlow )
+ return 0;
+
+ // Wir formatieren rueckwaerts, d.h. dass Attributwechsel in der
+ // naechsten Zeile durchaus noch einmal drankommen koennen.
+ // Zu beobachten in 8081.sdw, wenn man in der ersten Zeile Text eingibt.
+ nNextChg = 0;
+
+ const xub_StrLen nSoftHyphPos = rInf.GetSoftHyphPos();
+
+ // 8358, 8359: Flys sichern und auf 0 setzen, sonst GPF
+ // 3983: Nicht ClearFly(rInf) !
+ SwFlyPortion *pFly = rInf.GetFly();
+ rInf.SetFly( 0 );
+
+ FeedInf( rInf );
+ rInf.SetLast( pCurr );
+ // pUnderFlow braucht nicht deletet werden, weil es im folgenden
+ // Truncate() untergehen wird.
+ rInf.SetUnderFlow(0);
+ rInf.SetSoftHyphPos( nSoftHyphPos );
+
+ // Wir suchen die Portion mit der Unterlaufposition
+ SwLinePortion *pPor = pCurr->GetFirstPortion();
+ if( pPor != pUnderFlow )
+ {
+ // pPrev wird die letzte Portion vor pUnderFlow,
+ // die noch eine echte Breite hat.
+ // Ausnahme: SoftHyphPortions duerfen dabei natuerlich
+ // nicht vergessen werden, obwohl sie keine Breite haben.
+ SwLinePortion *pPrev = pPor;
+ while( pPor && pPor != pUnderFlow )
+ {
+ DBG_LOOP;
+ if( pPor->Width() || pPor->IsSoftHyphPortion() )
+ {
+ while( pPrev != pPor )
+ {
+ pPrev->Move( rInf );
+ rInf.SetLast( pPrev );
+ pPrev = pPrev->GetPortion();
+ ASSERT( pPrev, "UnderFlow: Loosing control!" );
+ };
+ }
+ pPor = pPor->GetPortion();
+ }
+ pPor = pPrev;
+ if( pPor && // Flies + Initialen werden nicht beim UnderFlow mitgenommen
+ ( pPor->IsFlyPortion() || pPor->IsDropPortion() ||
+ pPor->IsFlyCntPortion() ) )
+ {
+ pPor->Move( rInf );
+ rInf.SetLast( pPor );
+ rInf.SetStopUnderFlow( sal_True );
+ pPor = pUnderFlow;
+ }
+ }
+
+ // Was? Die Unterlaufsituation ist nicht in der Portion-Kette ?
+ ASSERT( pPor, "SwTxtFormatter::UnderFlow: overflow but underflow" );
+
+ if( rInf.IsFtnInside() && pPor && !rInf.IsQuick() )
+ {
+ SwLinePortion *pTmp = pPor->GetPortion();
+ while( pTmp )
+ {
+ if( pTmp->IsFtnPortion() )
+ ((SwFtnPortion*)pTmp)->ClearFtn();
+ pTmp = pTmp->GetPortion();
+ }
+ }
+
+ /*-----------------14.12.94 09:45-------------------
+ * 9849: Schnellschuss
+ * --------------------------------------------------*/
+ if ( pPor==rInf.GetLast() )
+ {
+ // Hier landen wir, wenn die UnderFlow-ausloesende Portion sich
+ // ueber die ganze Zeile erstreckt, z. B. wenn ein Wort ueber
+ // mehrere Zeilen geht und in der zweiten Zeile in einen Fly
+ // hineinlaeuft!
+ rInf.SetFly( pFly ); // wg. 28300
+ pPor->Truncate();
+ return pPor; // Reicht das?
+ }
+ /*---------------------------------------------------
+ * Ende des Schnellschusses wg. 9849
+ * --------------------------------------------------*/
+
+ // 4656: X + Width == 0 bei SoftHyph > Zeile ?!
+ if( !pPor || !(rInf.X() + pPor->Width()) )
+ {
+ delete pFly;
+ return 0;
+ }
+
+ // Vorbereitungen auf's Format()
+ // Wir muessen die Kette hinter pLast abknipsen, weil
+ // nach dem Format() ein Insert erfolgt.
+ SeekAndChg( rInf );
+
+ rInf.Width( rInf.X() + (pPor->Width() ? pPor->Width() - 1 : 0) );
+ rInf.SetLen( pPor->GetLen() );
+ rInf.SetFull( sal_False );
+ if( pFly )
+ {
+ // Aus folgendem Grund muss die FlyPortion neu berechnet werden:
+ // Wenn durch einen grossen Font in der Mitte der Zeile die Grundlinie
+ // abgesenkt wird und dadurch eine Ueberlappung mit eine Fly entsteht,
+ // so hat die FlyPortion eine falsche Groesse/Fixsize.
+ rInf.SetFly( pFly );
+ CalcFlyWidth( rInf );
+ }
+ rInf.GetLast()->SetPortion(0);
+
+ // Eine Ausnahme bildet das SwLineLayout, dass sich beim
+ // ersten Portionwechsel aufspaltet. Hier nun der umgekehrte Weg:
+ if( rInf.GetLast() == pCurr )
+ {
+ if( pPor->InTxtGrp() && !pPor->InExpGrp() )
+ {
+ MSHORT nOldWhich = pCurr->GetWhichPor();
+ *(SwLinePortion*)pCurr = *pPor;
+ pCurr->SetPortion( pPor->GetPortion() );
+ pCurr->SetWhichPor( nOldWhich );
+ pPor->SetPortion( 0 );
+ delete pPor;
+ pPor = pCurr;
+ }
+ }
+ pPor->Truncate();
+ delete rInf.GetRest();
+ rInf.SetRest(0);
+ return pPor;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::InsertPortion()
+ *************************************************************************/
+
+void SwTxtFormatter::InsertPortion( SwTxtFormatInfo &rInf,
+ SwLinePortion *pPor ) const
+{
+ // Die neue Portion wird eingefuegt,
+ // bei dem LineLayout ist allerdings alles anders...
+ if( pPor == pCurr )
+ {
+ if( pCurr->GetPortion() )
+ pPor = pCurr->GetPortion();
+ }
+ else
+ {
+ SwLinePortion *pLast = rInf.GetLast();
+ if( pLast->GetPortion() )
+ {
+ while( pLast->GetPortion() )
+ pLast = pLast->GetPortion();
+ rInf.SetLast( pLast );
+ }
+ pLast->Insert( pPor );
+
+ // Maxima anpassen:
+ // Der PaintOfst muss zurueckgesetzt werden.
+ // Unterlaufsituation in Kombination mit Recycle()
+ if( pCurr->Height() < pPor->Height() )
+ {
+ pCurr->Height( pPor->Height() );
+ if( IsFirstReformat() )
+ rInf.SetPaintOfst(0);
+ }
+ if( pCurr->GetAscent() < pPor->GetAscent() )
+ {
+ pCurr->SetAscent( pPor->GetAscent() );
+ if( IsFirstReformat() )
+ rInf.SetPaintOfst(0);
+ }
+ }
+
+ // manchmal werden ganze Ketten erzeugt (z.B. durch Hyphenate)
+ rInf.SetLast( pPor );
+ while( pPor )
+ {
+ DBG_LOOP;
+ pPor->Move( rInf );
+ rInf.SetLast( pPor );
+ pPor = pPor->GetPortion();
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::BuildPortion()
+ *************************************************************************/
+
+void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf )
+{
+ ASSERT( rInf.GetTxt().Len() < STRING_LEN,
+ "SwTxtFormatter::BuildPortions: bad text length in info" );
+
+ rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
+
+ // Es durchaus sein, dass pCurr durch Recycle() Daten enthaelt.
+ // Erst NewTxtPortion() entscheidet, ob pCurr in pPor landet.
+ // Wir muessen in jedem Fall dafuer sorgen, dass der Font eingestellt
+ // wird. In CalcAscent geschieht dies automatisch.
+ rInf.SetLast( pCurr->FindLastPortion() );
+ rInf.ForcedLeftMargin( 0 );
+ if( rInf.GetLast() == pCurr )
+ {
+ if( !pCurr->GetAscent() && !pCurr->Height() )
+ CalcAscent( rInf, pCurr );
+
+ SeekAndChg( rInf );
+
+ // In CalcFlyWidth wird Width() verkuerzt, wenn eine FlyPortion vorliegt.
+ ASSERT( !rInf.X(), "SwTxtFormatter::BuildPortion X=0?" );
+ CalcFlyWidth( rInf );
+ SwFlyPortion *pFly = rInf.GetFly();
+ if( pFly )
+ {
+ if ( 0 < pFly->Fix() )
+ ClearFly( rInf );
+ else
+ rInf.SetFull(sal_True);
+ }
+ }
+
+ SwLinePortion *pPor = NewPortion( rInf );
+ sal_Bool bFull;
+ rInf.Y( Y() );
+
+ while( pPor && !rInf.IsStop() )
+ {
+ ASSERT( rInf.GetLen() < STRING_LEN &&
+ rInf.GetIdx() <= rInf.GetTxt().Len(),
+ "SwTxtFormatter::BuildPortions: bad length in info" );
+ DBG_LOOP;
+ bFull = pPor->Format( rInf );
+
+ // Vorsicht: ein Fly im Blocksatz, dann kann das Repaint nur komplett
+ // hinter ihm oder vom Zeilenbeginn sein.
+#ifdef DEBUG
+ KSHORT nWhere = rInf.X();
+ long nLeft = GetLeftMargin();
+ SwTwips nPaintOfs = rInf.GetPaintOfst();
+#endif
+ if ( pPor->IsFlyPortion() && ( SVX_ADJUST_BLOCK == GetAdjust() )
+ && ( rInf.X() + GetLeftMargin() >= rInf.GetPaintOfst() ) )
+ rInf.SetPaintOfst( 0 );
+
+ if ( pPor->IsFlyCntPortion() )
+ SetFlyInCntBase();
+
+ rInf.SetFull( bFull );
+ // 5964: bUnderFlow muss zurueckgesetzt werden, sonst wird beim
+ // naechsten Softhyphen wieder umgebrochen!
+ if ( !bFull )
+ rInf.ClrUnderFlow();
+
+ // Restportions von mehrzeiligen Feldern haben bisher noch
+ // nicht den richtigen Ascent.
+ if ( !pPor->GetLen() && !pPor->IsFlyPortion()
+ && !pPor->IsGrfNumPortion() )
+ CalcAscent( rInf, pPor );
+
+ InsertPortion( rInf, pPor );
+ pPor = NewPortion( rInf );
+ }
+
+ if( !rInf.IsStop() )
+ {
+ // der letzte rechte, zentrierte, dezimale Tab
+ SwTabPortion *pLastTab = rInf.GetLastTab();
+ if( pLastTab )
+ pLastTab->FormatEOL( rInf );
+ else if( rInf.GetLast() && rInf.GetLast()->IsKernPortion() )
+ rInf.GetLast()->FormatEOL( rInf );
+ }
+ if( pCurr->GetPortion() && pCurr->GetPortion()->InNumberGrp()
+ && ((SwNumberPortion*)pCurr->GetPortion())->IsHide() )
+ rInf.SetNumDone( sal_False );
+
+ // 3260, 3860: Fly auf jeden Fall loeschen!
+ ClearFly( rInf );
+}
+
+/*************************************************************************
+ * SwTxtFormatter::CalcAdjustLine()
+ *************************************************************************/
+
+void SwTxtFormatter::CalcAdjustLine( SwLineLayout *pCurr )
+{
+ if( SVX_ADJUST_LEFT != GetAdjust() )
+ {
+ pCurr->SetFormatAdj(sal_True);
+ if( IsFlyInCntBase() )
+ {
+ CalcAdjLine( pCurr );
+ // 23348: z.B. bei zentrierten Flys muessen wir den RefPoint
+ // auf jeden Fall umsetzen, deshalb bAllWays = sal_True
+ UpdatePos( pCurr, sal_True );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::CalcAscent()
+ *************************************************************************/
+
+void SwTxtFormatter::CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor )
+{
+ if ( pPor->InFldGrp() && ((SwFldPortion*)pPor)->GetFont() )
+ {
+ // Numerierungen + InterNetFlds koennen einen eigenen Font beinhalten,
+ // dann ist ihre Groesse unabhaengig von harten Attributierungen.
+ SwFont* pFldFnt = ((SwFldPortion*)pPor)->pFnt;
+ SwFontSave aSave( rInf, pFldFnt );
+ ((SwFldPortion*)pPor)->Height( pFldFnt->GetHeight( rInf.GetVsh(), rInf.GetOut() ) );
+ ((SwFldPortion*)pPor)->SetAscent( pFldFnt->GetAscent( rInf.GetVsh(), rInf.GetOut() ) );
+ }
+ else
+ {
+ const SwLinePortion *pLast = rInf.GetLast();
+ sal_Bool bChg;
+
+ // Fallunterscheidung: in leeren Zeilen werden die Attribute
+ // per SeekStart angeschaltet.
+ const sal_Bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx();
+ if ( pPor->IsQuoVadisPortion() )
+ bChg = SeekStartAndChg( rInf, sal_True );
+ else
+ {
+ if( bFirstPor )
+ {
+ if( rInf.GetTxt().Len() )
+ {
+ if ( pPor->GetLen() || !rInf.GetIdx()
+ || ( pCurr != pLast && !pLast->IsFlyPortion() )
+ || !pCurr->IsRest() ) // statt !rInf.GetRest()
+ bChg = SeekAndChg( rInf );
+ else
+ bChg = SeekAndChgBefore( rInf );
+ }
+ else
+ bChg = SeekStartAndChg( rInf );
+ }
+ else
+ bChg = SeekAndChg( rInf );
+ }
+ if( bChg || bFirstPor || !pPor->GetAscent()
+ || !rInf.GetLast()->InTxtGrp() )
+ {
+ pPor->SetAscent( rInf.GetAscent() );
+ pPor->Height( rInf.GetTxtHeight() );
+ }
+ else
+ {
+ pPor->Height( pLast->Height() );
+ pPor->SetAscent( pLast->GetAscent() );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::WhichTxtPor()
+ *************************************************************************/
+
+SwTxtPortion *SwTxtFormatter::WhichTxtPor( SwTxtFormatInfo &rInf ) const
+{
+ SwTxtPortion *pPor = 0;
+ if( GetFnt()->IsTox() )
+ pPor = new SwToxPortion;
+ else
+ {
+ if( GetFnt()->IsRef() )
+ pPor = new SwRefPortion;
+ else
+ {
+ // Erst zum Schluss !
+ // Wenn pCurr keine Breite hat, kann sie trotzdem schon Inhalt haben,
+ // z.B. bei nicht darstellbaren Zeichen.
+ if( !rInf.X() && !pCurr->GetPortion() && !pCurr->GetLen() &&
+ !GetFnt()->IsURL() )
+ pPor = pCurr;
+ else
+ {
+ pPor = new SwTxtPortion;
+ if( GetFnt()->IsURL() )
+ pPor->SetWhichPor( POR_URL );
+ }
+ }
+ }
+ return pPor;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::NewTxtPortion()
+ *************************************************************************/
+// Die Laenge wird ermittelt, folgende Portion-Grenzen sind definiert:
+// 1) Tabs
+// 2) Linebreaks
+// 3) CH_TXTATR_BREAKWORD / CH_TXTATR_INWORD
+// 4) naechster Attributwechsel
+
+SwTxtPortion *SwTxtFormatter::NewTxtPortion( SwTxtFormatInfo &rInf )
+{
+ // Wenn wir am Zeilenbeginn stehen, nehmen wir pCurr
+ // Wenn pCurr nicht von SwTxtPortion abgeleitet ist,
+ // muessen wir duplizieren ...
+ Seek( rInf.GetIdx() );
+ SwTxtPortion *pPor = WhichTxtPor( rInf );
+
+ nNextChg = 0;
+
+// if( nNextChg <= rInf.GetIdx() )
+ {
+ // maximal bis zum naechsten Attributwchsel.
+ xub_StrLen nNextAttr = GetNextAttr();
+ nNextChg = Min( nNextAttr, rInf.GetTxt().Len() );
+ if ( nNextChg > 1 + rInf.GetIdx() && ' ' == rInf.GetChar( nNextChg-1 ) )
+ --nNextChg;
+
+#define GUESS_NEXTCHG
+#ifdef GUESS_NEXTCHG
+ // 7515, 7516, 3470, 6441 : Turbo-Boost
+ // Es wird unterstellt, dass die Buchstaben eines Fonts nicht
+ // groesser als doppelt so breit wie hoch sind.
+ // 7659: Ganz verrueckt: man muss sich auf den Ascent beziehen.
+ // Falle: GetSize() enthaelt die Wunschhoehe, die reale Hoehe
+ // ergibt sich erst im CalcAscent!
+ // 7697: Das Verhaeltnis ist noch krasser: ein Blank im Times
+ // New Roman besitzt einen Ascent von 182, eine Hoehe von 200
+ // und eine Breite von 53! Daraus folgt, dass eine Zeile mit
+ // vielen Blanks falsch eingeschaetzt wird. Wir erhoehen von
+ // Faktor 2 auf 8 (wg. negativen Kernings).
+
+// if( !pPor->GetAscent() )
+ pPor->SetLen(1);
+ CalcAscent( rInf, pPor );
+
+ const SwFont* pFnt = rInf.GetFont();
+ KSHORT nExpect = Min( KSHORT( ((Font *)pFnt)->GetSize().Height() ),
+ KSHORT( pPor->GetAscent() ) ) / 8;
+ if ( !nExpect )
+ nExpect = 1;
+ nExpect = rInf.GetIdx() + ((rInf.Width() - rInf.X()) / nExpect);
+ if( nExpect > rInf.GetIdx() && nNextChg > nExpect )
+ nNextChg = Min( nExpect, rInf.GetTxt().Len() );
+
+#endif /* GUESS_NEXTCHG */
+
+ // 4294: Vorsicht vor STRING_LEN-Ueberrundungen !
+ if( MAX_TXTPORLEN < nNextChg && STRING_LEN - MAX_TXTPORLEN > rInf.GetIdx() )
+ {
+ const xub_StrLen nMaxChg = rInf.GetIdx() + MAX_TXTPORLEN;
+ if( nMaxChg < nNextChg )
+ {
+ // 6441: uebel ist, wenn die Portion passt...
+ const KSHORT nWidth =
+ rInf.GetTxtSize(rInf.GetIdx(), MAX_TXTPORLEN ).Width();
+ if( nWidth > rInf.Width() )
+ nNextChg = Min( nMaxChg, rInf.GetTxt().Len() );
+ }
+ }
+ nNextChg = rInf.ScanPortionEnd( nNextChg );
+ }
+ pPor->SetLen( nNextChg - rInf.GetIdx() );
+ rInf.SetLen( pPor->GetLen() );
+ return pPor;
+}
+
+
+/*************************************************************************
+ * SwTxtFormatter::WhichFirstPortion()
+ *************************************************************************/
+
+SwLinePortion *SwTxtFormatter::WhichFirstPortion(SwTxtFormatInfo &rInf) const
+{
+ SwLinePortion *pPor = 0;
+
+ if( rInf.GetRest() )
+ {
+ // 5010: Tabs und Felder
+ if( '\0' != rInf.GetHookChar() )
+ return 0;
+
+ pPor = rInf.GetRest();
+ if( pPor->IsErgoSumPortion() )
+ rInf.SetErgoDone(sal_True);
+ else
+ if( pPor->IsFtnNumPortion() )
+ rInf.SetFtnDone(sal_True);
+ else
+ if( pPor->InNumberGrp() )
+ rInf.SetNumDone(sal_True);
+ if( pPor )
+ {
+ rInf.SetRest(0);
+ pCurr->SetRest( sal_True );
+ return pPor;
+ }
+ }
+
+ // ???? und ????: im Follow duerfen wir schon stehen,
+ // entscheidend ist, ob pFrm->GetOfst() == 0 ist!
+ if( rInf.GetIdx() )
+ {
+ // Nun koennen auch FtnPortions und ErgoSumPortions
+ // verlaengert werden.
+
+ // 1) Die ErgoSumTexte
+ if( !rInf.IsErgoDone() )
+ {
+ if( pFrm->IsInFtn() && !pFrm->GetIndPrev() )
+ pPor = (SwLinePortion*)NewErgoSumPortion( rInf );
+ rInf.SetErgoDone( sal_True );
+ }
+ if( !pPor && !rInf.IsArrowDone() )
+ {
+ if( pFrm->GetOfst() && !pFrm->IsFollow() &&
+ rInf.GetIdx() == pFrm->GetOfst() )
+ pPor = new SwArrowPortion( *pCurr );
+ rInf.SetArrowDone( sal_True );
+ }
+
+ // 2) Die Zeilenreste (mehrzeilige Felder)
+ if( !pPor )
+ {
+ pPor = rInf.GetRest();
+ // 6922: Nur bei pPor natuerlich.
+ if( pPor )
+ {
+ pCurr->SetRest( sal_True );
+ rInf.SetRest(0);
+ }
+ }
+ }
+ else
+ {
+ // 1) Die Fussnotenzahlen
+ if( !rInf.IsFtnDone() )
+ {
+ sal_Bool bFtnNum = pFrm->IsFtnNumFrm();
+ rInf.GetParaPortion()->SetFtnNum( bFtnNum );
+ if( bFtnNum )
+ pPor = (SwLinePortion*)NewFtnNumPortion( rInf );
+ rInf.SetFtnDone( sal_True );
+ }
+
+ // 2) Die ErgoSumTexte gibt es natuerlich auch im TextMaster,
+ // entscheidend ist, ob der SwFtnFrm ein Follow ist.
+ if( !rInf.IsErgoDone() && !pPor )
+ {
+ if( pFrm->IsInFtn() && !pFrm->GetIndPrev() )
+ pPor = (SwLinePortion*)NewErgoSumPortion( rInf );
+ rInf.SetErgoDone( sal_True );
+ }
+
+ // 3) Die Numerierungen
+ if( !rInf.IsNumDone() && !pPor )
+ {
+ // Wenn wir im Follow stehen, dann natuerlich nicht.
+ if( GetTxtFrm()->GetTxtNode()->GetNum() ||
+ GetTxtFrm()->GetTxtNode()->GetOutlineNum() )
+ {
+ pPor = (SwLinePortion*)NewNumberPortion( rInf );
+ }
+ rInf.SetNumDone( sal_True );
+ }
+ // 3) Die DropCaps
+ if( !pPor && GetDropFmt() )
+ pPor = (SwLinePortion*)NewDropPortion( rInf );
+ }
+ return pPor;
+}
+
+sal_Bool lcl_OldFieldRest( const SwLineLayout* pCurr )
+{
+ if( !pCurr->GetNext() )
+ return sal_False;
+ const SwLinePortion *pPor = pCurr->GetNext()->GetPortion();
+ sal_Bool bRet = sal_False;
+ while( pPor && !bRet && !pPor->GetLen() )
+ {
+ bRet = pPor->InFldGrp();
+ pPor = pPor->GetPortion();
+ }
+ return bRet;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::NewPortion()
+ *************************************************************************/
+
+/* NewPortion stellt rInf.nLen ein.
+ * Eine SwTxtPortion wird begrenzt durch ein tab, break, txtatr,
+ * attrwechsel.
+ * Drei Faelle koennen eintreten:
+ * 1) Die Zeile ist voll und der Umbruch wurde nicht emuliert
+ * -> return 0;
+ * 2) Die Zeile ist voll und es wurde ein Umbruch emuliert
+ * -> Breite neu einstellen und return new FlyPortion
+ * 3) Es muss eine neue Portion gebaut werden.
+ * -> CalcFlyWidth emuliert ggf. die Breite und return Portion
+ */
+
+SwLinePortion *SwTxtFormatter::NewPortion( SwTxtFormatInfo &rInf )
+{
+
+ // Underflow hat Vorrang
+ rInf.SetStopUnderFlow( sal_False );
+ if( rInf.GetUnderFlow() )
+ {
+ ASSERT( rInf.IsFull(), "SwTxtFormatter::NewPortion: underflow but not full" );
+ return UnderFlow( rInf );
+ }
+
+ // Wenn die Zeile voll ist, koennten noch Flys oder
+ // UnderFlow-LinePortions warten ...
+ if( rInf.IsFull() )
+ {
+ // ????: LineBreaks und Flys (bug05.sdw)
+ // 8450: IsDummy()
+ if( rInf.IsNewLine() && (!rInf.GetFly() || !pCurr->IsDummy()) )
+ return 0;
+
+ // Wenn der Text an den Fly gestossen ist, oder wenn
+ // der Fly als erstes drankommt, weil er ueber dem linken
+ // Rand haengt, wird GetFly() returnt.
+ // Wenn IsFull() und kein GetFly() vorhanden ist, gibt's
+ // naturgemaesz eine 0.
+ if( rInf.GetFly() )
+ {
+ if( rInf.GetLast()->IsBreakPortion() )
+ {
+ delete rInf.GetFly();
+ rInf.SetFly( 0 );
+ }
+ return rInf.GetFly();
+ }
+ // Ein fieser Sonderfall: ein Rahmen ohne Umlauf kreuzt den
+ // Ftn-Bereich. Wir muessen die Ftn-Portion als Zeilenrest
+ // bekanntgeben, damit SwTxtFrm::Format nicht abbricht
+ // (die Textmasse wurde ja durchformatiert).
+ if( rInf.GetRest() )
+ rInf.SetNewLine( sal_True );
+ else
+ {
+ // Wenn die naechste Zeile mit einem Rest eines Feldes beginnt,
+ // jetzt aber kein Rest mehr anliegt,
+ // muss sie auf jeden Fall neu formatiert werden!
+ if( lcl_OldFieldRest( GetCurr() ) )
+ rInf.SetNewLine( sal_True );
+ else
+ {
+ SwLinePortion *pFirst = WhichFirstPortion( rInf );
+ if( pFirst )
+ {
+ rInf.SetNewLine( sal_True );
+ if( pFirst->InNumberGrp() )
+ rInf.SetNumDone( sal_False) ;
+ delete pFirst;
+ }
+ }
+ }
+
+ // Wenn die Zeile voll ist und ein Blank am Zeilenende
+ // steht, dann muss es in einer HolePortion verborgen werden
+ // (trailing blank).
+ // 8518: keine HolePortions bei mehrzeiligen Feldern.
+ if( rInf.GetIdx() < rInf.GetTxt().Len() &&
+ rInf.GetIdx() && ' ' == rInf.GetChar( rInf.GetIdx() )
+ && !rInf.GetLast()->IsHolePortion() && !rInf.GetRest()
+ && CH_BREAK != rInf.GetChar( rInf.GetIdx() - 1 ) )
+ {
+ SwHolePortion *pHole = new SwHolePortion( *rInf.GetLast() );
+ xub_StrLen nCnt = rInf.GetIdx();
+ xub_StrLen nLen = rInf.GetTxt().Len();
+ while ( nCnt < nLen && ' ' == rInf.GetChar( nCnt ) )
+ nCnt++;
+ pHole->SetLen( nCnt - rInf.GetIdx() );
+ return pHole;
+ }
+ return 0;
+ }
+
+ SwLinePortion *pPor = WhichFirstPortion( rInf );
+ if( !pPor )
+ {
+ // 5010: Tabs und Felder
+ xub_Unicode cChar = rInf.GetHookChar();
+
+ if( cChar )
+ {
+ /* Wir holen uns nocheinmal cChar, um sicherzustellen, dass das
+ * Tab jetzt wirklich ansteht und nicht auf die naechste Zeile
+ * gewandert ist ( so geschehen hinter Rahmen ).
+ * Wenn allerdings eine FldPortion im Rest wartet, muessen wir
+ * das cChar natuerlich aus dem Feldinhalt holen, z.B. bei
+ * DezimalTabs und Feldern (22615)
+ */
+ if( !rInf.GetRest() || !rInf.GetRest()->InFldGrp() )
+ cChar = rInf.GetChar( rInf.GetIdx() );
+ rInf.SetHookChar(0);
+ }
+ else
+ {
+ if( rInf.GetIdx() >= rInf.GetTxt().Len() )
+ {
+ rInf.SetFull(sal_True);
+ CalcFlyWidth( rInf );
+ return pPor;
+ }
+ cChar = rInf.GetChar( rInf.GetIdx() );
+ }
+
+ switch( cChar )
+ {
+ case CH_TAB : pPor = NewTabPortion( rInf ); break;
+ case CH_BREAK : pPor = new SwBreakPortion( *rInf.GetLast() ); break;
+
+ case CHAR_SOFTHYPHEN: // soft hyphen
+ pPor = new SwSoftHyphPortion; break;
+
+ case CHAR_HARDBLANK: // no-break space
+ pPor = new SwBlankPortion( ' ' ); break;
+ case CHAR_HARDHYPHEN: // non-breaking hyphen
+ pPor = new SwBlankPortion( '-' ); break;
+
+ case CH_TXTATR_BREAKWORD:
+ case CH_TXTATR_INWORD:
+ if( rInf.HasHint( rInf.GetIdx() ) )
+ {
+ pPor = NewExtraPortion( rInf );
+ break;
+ }
+ // No break
+ default :
+ {
+ if( rInf.GetLastTab() && cChar == rInf.GetTabDecimal() )
+ rInf.SetFull( rInf.GetLastTab()->Format( rInf ) );
+
+ if( rInf.GetRest() )
+ {
+ if( rInf.IsFull() )
+ {
+ rInf.SetNewLine(sal_True);
+ return 0;
+ }
+ pPor = rInf.GetRest();
+ rInf.SetRest(0);
+ }
+ else
+ {
+ if( rInf.IsFull() )
+ return 0;
+ pPor = NewTxtPortion( rInf );
+ }
+ break;
+ }
+ }
+
+ // Wenn eine Portion erzeugt wird, obwohl eine RestPortion ansteht,
+ // dann haben wir es mit einem Feld zu tun, das sich aufgesplittet
+ // hat, weil z.B. ein Tab enthalten ist.
+ if( pPor && rInf.GetRest() )
+ pPor->SetLen( 0 );
+
+ // robust:
+ if( !pPor || rInf.IsStop() )
+ {
+ delete pPor;
+ return 0;
+ }
+ }
+
+ // Der Font wird im Outputdevice eingestellt,
+ // der Ascent und die Hoehe werden berechnet.
+ if( !pPor->GetAscent() && !pPor->Height() )
+ CalcAscent( rInf, pPor );
+ rInf.SetLen( pPor->GetLen() );
+
+ // In CalcFlyWidth wird Width() verkuerzt, wenn eine FlyPortion vorliegt.
+ CalcFlyWidth( rInf );
+
+ // Man darf nicht vergessen, dass pCurr als GetLast() vernuenftige
+ // Werte bereithalten muss:
+ if( !pCurr->Height() )
+ {
+ ASSERT( pCurr->Height(), "SwTxtFormatter::NewPortion: limbo dance" );
+ pCurr->Height( pPor->Height() );
+ pCurr->SetAscent( pPor->GetAscent() );
+ }
+
+ ASSERT( !pPor || pPor->Height(),
+ "SwTxtFormatter::NewPortion: something went wrong");
+ if( pPor->IsPostItsPortion() && rInf.X() >= rInf.Width() && rInf.GetFly() )
+ {
+ delete pPor;
+ pPor = rInf.GetFly();
+ }
+ return pPor;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::FormatLine()
+ *************************************************************************/
+
+xub_StrLen SwTxtFormatter::FormatLine( const xub_StrLen nStart )
+{
+ SwHookOut aHook( &GetInfo() );
+ if( GetInfo().GetLen() < GetInfo().GetTxt().Len() )
+ GetInfo().SetLen( GetInfo().GetTxt().Len() );
+
+ sal_Bool bBuild = sal_True;
+ SetFlyInCntBase( sal_False );
+ GetInfo().SetLineHeight( 0 );
+ GetInfo().SetPaintOfst( 0 );
+
+ // Recycling muss bei geaenderter Zeilenhoehe unterdrueckt werden
+ // und auch bei geaendertem Ascent (Absenken der Grundlinie).
+ const KSHORT nOldHeight = pCurr->Height();
+ const KSHORT nOldAscent = pCurr->GetAscent();
+
+ pCurr->SetEndHyph( sal_False );
+ pCurr->SetMidHyph( sal_False );
+
+ // Hier folgt bald die Unterlaufpruefung.
+ while( bBuild )
+ {
+ sal_Bool bOldNumDone = GetInfo().IsNumDone();
+ sal_Bool bOldArrowDone = GetInfo().IsArrowDone();
+ GetInfo().SetFtnInside( sal_False );
+ FeedInf( GetInfo() );
+ Recycle( GetInfo() ); // initialisiert sich oder rettet Portions
+ if( bOldNumDone )
+ GetInfo().SetNumDone( sal_True );
+ if( bOldArrowDone )
+ GetInfo().SetArrowDone( sal_True );
+ BuildPortions( GetInfo() );
+ if( GetInfo().IsStop() )
+ {
+ pCurr->SetLen( 0 );
+ pCurr->Height( GetFrmRstHeight() + 1 );
+ pCurr->SetRealHeight( GetFrmRstHeight() + 1 );
+ pCurr->Width(0);
+ pCurr->Truncate();
+ return nStart;
+ }
+ else if( GetInfo().IsDropInit() )
+ {
+ DropInit();
+ GetInfo().SetDropInit( sal_False );
+ }
+
+ pCurr->CalcLine( *this );
+ CalcRealHeight( GetInfo().IsNewLine() );
+
+ if ( IsFlyInCntBase() && !IsQuick() )
+ {
+ KSHORT nTmpAscent, nTmpHeight;
+ CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+ AlignFlyInCntBase( Y() + long( nTmpAscent ) );
+ pCurr->CalcLine( *this );
+ CalcRealHeight();
+ }
+
+ // bBuild entscheidet, ob noch eine Ehrenrunde gedreht wird
+ bBuild = !GetInfo().GetLineHeight() &&
+ ( GetInfo().GetTxtFly()->IsOn() && ChkFlyUnderflow( GetInfo() )
+ || GetInfo().CheckFtnPortion( pCurr ) );
+ if( bBuild )
+ {
+ GetInfo().SetNumDone( bOldNumDone );
+ pCurr->SetLen( 0 );
+ pCurr->Width(0);
+ pCurr->Truncate();
+ }
+ }
+
+ xub_StrLen nNewStart = nStart + pCurr->GetLen();
+ CalcAdjustLine( pCurr );
+
+ if( nOldHeight != pCurr->Height() || nOldAscent != pCurr->GetAscent() )
+ {
+ SetFlyInCntBase();
+ GetInfo().SetPaintOfst( 0 ); //geaenderte Zeilenhoehe => kein Recycling
+ // alle weiteren Zeilen muessen gepaintet und, wenn Flys im Spiel sind
+ // auch formatiert werden.
+ GetInfo().SetShift( sal_True );
+ }
+
+ if ( IsFlyInCntBase() && !IsQuick() )
+ UpdatePos( pCurr );
+
+ return nNewStart;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::FeedInf()
+ *************************************************************************/
+
+void SwTxtFormatter::FeedInf( SwTxtFormatInfo &rInf ) const
+{
+ // 3260, 3860: Fly auf jeden Fall loeschen!
+ ClearFly( rInf );
+ rInf.Init();
+
+ rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
+ rInf.SetRoot( pCurr );
+ rInf.SetLineStart( nStart );
+ rInf.SetIdx( nStart );
+ rInf.Left( KSHORT(Left()) );
+ rInf.Right( KSHORT(Right()) );
+ rInf.First( short(FirstLeft()) );
+ rInf.RealWidth( KSHORT(rInf.Right()) - KSHORT(GetLeftMargin()) );
+ rInf.Width( rInf.RealWidth() );
+ if( ((SwTxtFormatter*)this)->GetRedln() )
+ {
+ ((SwTxtFormatter*)this)->GetRedln()->Clear( ((SwTxtFormatter*)this)->GetFnt() );
+ ((SwTxtFormatter*)this)->GetRedln()->Reset();
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatter::FormatReset()
+ *************************************************************************/
+
+void SwTxtFormatter::FormatReset( SwTxtFormatInfo &rInf )
+{
+ pCurr->Truncate();
+ pCurr->Init();
+ if( pBlink && pCurr->IsBlinking() )
+ pBlink->Delete( pCurr );
+ pCurr->ResetFlags();
+ FeedInf( rInf );
+}
+
+/*************************************************************************
+ * SwTxtFormatter::CalcOnceMore()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatter::CalcOnceMore()
+{
+ if( pDropFmt )
+ {
+ const KSHORT nOldDrop = GetDropHeight();
+ CalcDropHeight( pDropFmt->GetLines() );
+ bOnceMore = nOldDrop != GetDropHeight();
+ }
+ else
+ bOnceMore = sal_False;
+ return bOnceMore;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::CalcBottomLine()
+ *************************************************************************/
+
+SwTwips SwTxtFormatter::CalcBottomLine() const
+{
+ SwTwips nRet = Y() + GetLineHeight();
+ SwTwips nMin = GetInfo().GetTxtFly()->GetMinBottom();
+ if( nMin && ++nMin > nRet )
+ {
+ SwTwips nDist = pFrm->Frm().Height() - pFrm->Prt().Height()
+ - pFrm->Prt().Top();
+ if( nRet + nDist < nMin )
+ {
+ sal_Bool bRepaint = HasTruncLines() &&
+ GetInfo().GetParaPortion()->GetRepaint()->Bottom() == nRet-1;
+ nRet = nMin - nDist;
+ if( bRepaint )
+ {
+ ((SwRepaint*)GetInfo().GetParaPortion()
+ ->GetRepaint())->Bottom( nRet-1 );
+ ((SwTxtFormatInfo&)GetInfo()).SetPaintOfst( 0 );
+ }
+ }
+ }
+ return nRet;
+}
+
+/*************************************************************************
+ * SwTxtFormatter::_CalcFitToContent()
+ *************************************************************************/
+
+KSHORT SwTxtFormatter::_CalcFitToContent()
+{
+ GetInfo().SetRoot( pCurr );
+
+ GetInfo().First( KSHORT(FirstLeft()) );
+ GetInfo().Left( KSHORT(Left()) );
+
+ SeekAndChg( GetInfo() );
+ GetInfo().SetLast( GetInfo().GetRoot() );
+
+ SwLinePortion *pPor = NewPortion( GetInfo() );
+
+ long nMaxWidth = 0;
+ long nWidth = 0;
+ long nMargin = FirstLeft();
+ sal_Bool bFull = sal_False;
+ while( pPor && !IsStop() && !bFull)
+ {
+ bFull = pPor->Format( GetInfo() );
+ GetInfo().SetLast( pPor );
+ while( pPor )
+ {
+ nWidth += pPor->Width();
+ pPor->Move( GetInfo() );
+ GetInfo().SetLast( pPor );
+ pPor = pPor->GetPortion();
+ }
+ if( bFull && 0 != ( pPor = GetInfo().GetLast() ) && pPor->IsBreakPortion() )
+ {
+ if ( nWidth && (nMaxWidth < nWidth+nMargin ) )
+ nMaxWidth = nWidth + nMargin;
+ nWidth = 0;
+ nMargin = Left();
+ bFull = sal_False;
+ GetInfo().X( KSHORT(nMargin) );
+ }
+ pPor = NewPortion( GetInfo() );
+ }
+ if ( nWidth && ( nMaxWidth < nWidth + nMargin ) )
+ nMaxWidth = nWidth + nMargin;
+ return KSHORT(nMaxWidth);
+}
+
diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx
new file mode 100644
index 000000000000..a908b7c072d2
--- /dev/null
+++ b/sw/source/core/text/itrform2.hxx
@@ -0,0 +1,236 @@
+/*************************************************************************
+ *
+ * $RCSfile: itrform2.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRFORM2_HXX
+#define _ITRFORM2_HXX
+
+#include "itrpaint.hxx"
+
+class SwFlyCntPortion;
+class SwInterHyphInfo;
+class SwDropPortion;
+class SwFmtDrop;
+class SwDrawObjs;
+class SwTxtAttr;
+class SwNumberPortion;
+class SwErgoSumPortion;
+class SwExpandPortion;
+
+/*************************************************************************
+ * class SwTxtFormatter
+ *************************************************************************/
+
+class SwTxtFormatter : public SwTxtPainter
+{
+ const SwFmtDrop *pDropFmt;
+ xub_StrLen nNextChg;
+ sal_uInt8 nCntEndHyph; // zaehlt aufeinanderfolgende Hyphens am Zeilenende
+ sal_uInt8 nCntMidHyph; // zaehlt aufeinanderfolgende Hyphens vor Flies
+ sal_Bool bOnceMore : 1; // noch 'ne Runde?
+ sal_Bool bFlyInCntBase : 1; // Base-Referenz der zeichengeb. Rahmen setzen
+ sal_Bool bChanges : 1; // Flag, fuer die Berechnung des Repaint-Rechtecks
+ sal_Bool bTruncLines : 1; // Flag, Repaint-Rechtecks ggf. erweitern
+ sal_Bool bUnclipped : 1; // Flag, ob Repaint groesser als feste Zeilenhoehe
+ SwLinePortion *NewPortion( SwTxtFormatInfo &rInf );
+ SwTxtPortion *NewTxtPortion( SwTxtFormatInfo &rInf );
+ SwLinePortion *NewExtraPortion( SwTxtFormatInfo &rInf );
+ SwTabPortion *NewTabPortion( SwTxtFormatInfo &rInf ) const;
+ SwNumberPortion *NewNumberPortion( SwTxtFormatInfo &rInf ) const;
+ SwDropPortion *NewDropPortion( SwTxtFormatInfo &rInf ) const;
+ SwNumberPortion *NewFtnNumPortion( SwTxtFormatInfo &rInf ) const;
+ SwErgoSumPortion *NewErgoSumPortion( SwTxtFormatInfo &rInf ) const;
+ SwExpandPortion *NewFldPortion( SwTxtFormatInfo &rInf, SwTxtAttr *pHt ) const;
+ SwFtnPortion *NewFtnPortion( SwTxtFormatInfo &rInf, SwTxtAttr *pHt );
+ SwFlyCntPortion *NewFlyCntPortion( SwTxtFormatInfo &rInf,
+ SwTxtAttr *pHt ) const;
+ SwLinePortion *WhichFirstPortion( SwTxtFormatInfo &rInf ) const;
+ SwTxtPortion *WhichTxtPor( SwTxtFormatInfo &rInf ) const;
+
+ // Das Herzstueck der Formatierung
+ void BuildPortions( SwTxtFormatInfo &rInf );
+
+ // Initialisierung oder Wiederverwertung alter Portions
+ void Recycle( SwTxtFormatInfo &rInf );
+
+
+ // Berechnung des emulierten rechten Rands
+ void CalcFlyWidth( SwTxtFormatInfo &rInf ) const;
+
+ // wird von SwTxtFormatter wegen UpdatePos ueberladen
+ void CalcAdjustLine( SwLineLayout *pCurr );
+
+ // uebertraegt die Daten nach rInf
+ void FeedInf( SwTxtFormatInfo &rInf ) const;
+
+ // behandelt die Unterlaufsituationen
+ SwLinePortion *UnderFlow( SwTxtFormatInfo &rInf );
+
+ // errechnet den Ascent und die Hoehe aus der Fontmetric
+ void CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor );
+
+ // wird von Recycle() gerufen.
+ void FormatReset( SwTxtFormatInfo &rInf );
+
+ // Sind wir in der ersten zu formatierenden Zeile?
+ inline sal_Bool IsFirstReformat() const
+ { return GetInfo().GetIdx() < GetInfo().GetReformatStart(); }
+
+ // durch das Adjustment aendert sich die Position der Portions
+ void UpdatePos( SwLineLayout *pCurr, sal_Bool bAllWays = sal_False ) const;
+
+ // Setze alle FlyInCntFrms auf die uebergebene BaseLine
+ void AlignFlyInCntBase( long nBaseLine ) const;
+
+ // Unterlaufbedingungen bei Flys
+ sal_Bool ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const;
+
+ // Portion einfuegen.
+ void InsertPortion( SwTxtFormatInfo &rInf, SwLinePortion *pPor ) const;
+
+ // schaetzt die Hoehe fuer die DropPortion
+ void GuessDropHeight( const MSHORT nLines );
+
+public:
+ // errechnet die Hoehe fuer die DropPortion
+ void CalcDropHeight( const MSHORT nLines );
+
+ // errechnet den Bottom des Absatzes, beruecksichtigt an diesem verankerte
+ // Objekte mit Umlauf 1. Absatz.
+ SwTwips CalcBottomLine() const;
+
+ // Beruecksichtigt zeichengebundene Objekte bei der Repaintrechteck-
+ // berechnung in Zeilen mit fester Zeilenhoehe
+ void CalcUnclipped( SwTwips& rTop, SwTwips& rBottom );
+
+ // u.a. fuer DropCaps
+ sal_Bool CalcOnceMore();
+
+ void CtorInit( SwTxtFrm *pFrm, SwTxtFormatInfo *pInf );
+ inline SwTxtFormatter( SwTxtFrm *pFrm, SwTxtFormatInfo *pInf )
+ { CtorInit( pFrm, pInf ); }
+ ~SwTxtFormatter();
+
+ xub_StrLen FormatLine( const xub_StrLen nStart );
+
+ // Wir formatieren eine Zeile fuer die interaktive Trennung
+ sal_Bool Hyphenate( SwInterHyphInfo &rInf );
+
+ // Spezialmethode fuer QuoVadis-Texte
+ // nErgo ist die Seitennummer der ErgoSum-Ftn
+ // Bei 0 ist es noch unklar.
+ xub_StrLen FormatQuoVadis( const xub_StrLen nStart );
+
+ // Die Notbremse: Formatierung abbrechen, Zeile verwerfen.
+ inline sal_Bool IsStop() const { return GetInfo().IsStop(); }
+
+ // Das Gegenstueck: Formatierung unbedingt fortsetzen.
+ inline sal_Bool IsNewLine() const { return GetInfo().IsNewLine(); }
+
+ // FormatQuick(); auffrischen von Formatinformationen
+ inline sal_Bool IsQuick() const { return GetInfo().IsQuick(); }
+
+ // erzeugt ggfs. ein SwLineLayout, dass Ftn/Fly--Oszillation unterbindet.
+ void MakeDummyLine();
+
+ // SwTxtIter-Funktionalitaet
+ void Insert( SwLineLayout *pLine );
+
+ // die noch verbleibende Hoehe bis zum Seitenrand
+ KSHORT GetFrmRstHeight() const;
+
+ // Wie breit waerest Du ohne rechte Begrenzungen (Flys etc.)?
+ KSHORT _CalcFitToContent( );
+
+ SwFldPortion *GetFieldRest( SwTxtFormatInfo &rInf ) const;
+ void MakeRestPortion();
+
+ inline const SwFmtDrop *GetDropFmt() const { return pDropFmt; }
+ inline void ClearDropFmt() { pDropFmt = 0; }
+
+ inline const sal_Bool IsOnceMore() const { return bOnceMore; }
+ inline void SetOnceMore( sal_Bool bNew ) { bOnceMore = bNew; }
+
+ inline const sal_Bool HasChanges() const { return bChanges; }
+ inline void SetChanges() { bChanges = sal_True; }
+
+ inline const sal_Bool HasTruncLines() const { return bTruncLines; }
+ inline void SetTruncLines( sal_Bool bNew ) { bTruncLines = bNew; }
+
+ inline const sal_Bool IsUnclipped() const { return bUnclipped; }
+ inline void SetUnclipped( sal_Bool bNew ) { bUnclipped = bNew; }
+
+ inline const sal_Bool IsFlyInCntBase() const { return bFlyInCntBase; }
+ inline void SetFlyInCntBase( sal_Bool bNew = sal_True ){ bFlyInCntBase = bNew; }
+
+ inline SwTxtFormatInfo &GetInfo()
+ { return (SwTxtFormatInfo&)SwTxtIter::GetInfo(); }
+ inline const SwTxtFormatInfo &GetInfo() const
+ { return (const SwTxtFormatInfo&)SwTxtIter::GetInfo(); }
+
+ inline void InitCntHyph() { CntHyphens( nCntEndHyph, nCntMidHyph ); }
+ inline const sal_uInt8 &CntEndHyph() const { return nCntEndHyph; }
+ inline const sal_uInt8 &CntMidHyph() const { return nCntMidHyph; }
+ inline sal_uInt8 &CntEndHyph() { return nCntEndHyph; }
+ inline sal_uInt8 &CntMidHyph() { return nCntMidHyph; }
+};
+
+
+
+#endif
diff --git a/sw/source/core/text/itrpaint.cxx b/sw/source/core/text/itrpaint.cxx
new file mode 100644
index 000000000000..885297f47f46
--- /dev/null
+++ b/sw/source/core/text/itrpaint.cxx
@@ -0,0 +1,548 @@
+/*************************************************************************
+ *
+ * $RCSfile: itrpaint.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "flyfrm.hxx" // SwFlyInCntFrm
+#include "viewopt.hxx" // SwViewOptions
+#include "errhdl.hxx"
+#include "txtatr.hxx" // SwINetFmt
+
+#ifndef _SV_MULTISEL_HXX //autogen
+#include <tools/multisel.hxx>
+#endif
+#ifndef _SVX_ESCPITEM_HXX //autogen
+#include <svx/escpitem.hxx>
+#endif
+#ifndef _SVX_UDLNITEM_HXX //autogen
+#include <svx/udlnitem.hxx>
+#endif
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include <svx/lrspitem.hxx>
+#endif
+
+#ifndef _TXTINET_HXX //autogen
+#include <txtinet.hxx>
+#endif
+#ifndef _FCHRFMT_HXX //autogen
+#include <fchrfmt.hxx>
+#endif
+#ifndef _FRMATR_HXX
+#include <frmatr.hxx>
+#endif
+#include "flyfrms.hxx"
+#include "viewsh.hxx"
+#include "txtcfg.hxx"
+#include "itrpaint.hxx"
+#include "txtfrm.hxx" // pFrm
+#include "txtfly.hxx"
+#include "swfont.hxx"
+#include "txtpaint.hxx"
+#include "portab.hxx" // SwTabPortion::IsFilled
+#include "porfly.hxx" // SwFlyCntPortion
+#include "porfld.hxx" // SwGrfNumPortion
+#include "frmfmt.hxx" // LRSpace
+#include "txatbase.hxx" // SwTxtAttr
+#include "charfmt.hxx" // SwFmtCharFmt
+#include "redlnitr.hxx" // SwRedlineItr
+#include "porrst.hxx" // SwArrowPortion
+
+/*************************************************************************
+ * SwTxtPainter::CtorInit()
+ *************************************************************************/
+void SwTxtPainter::CtorInit( SwTxtFrm *pFrm, SwTxtPaintInfo *pNewInf )
+{
+ SwTxtCursor::CtorInit( pFrm, pNewInf );
+ pInf = pNewInf;
+ SwFont *pFnt = GetFnt();
+ GetInfo().SetFont( pFnt );
+#ifndef PRODUCT
+ if( ALIGN_BASELINE != pFnt->GetAlign() )
+ {
+ ASSERT( ALIGN_BASELINE == pFnt->GetAlign(),
+ "+SwTxtPainter::CTOR: font alignment revolution" );
+ pFnt->SetAlign( ALIGN_BASELINE );
+ }
+#endif
+ bPaintDrop = sal_False;
+}
+
+
+/*************************************************************************
+ * SwTxtPainter::CalcPaintOfst()
+ *************************************************************************/
+SwLinePortion *SwTxtPainter::CalcPaintOfst( const SwRect &rPaint )
+{
+ SwLinePortion *pPor = pCurr->GetFirstPortion();
+ GetInfo().SetPaintOfst( 0 );
+ SwTwips nPaintOfst = rPaint.Left();
+
+ // nPaintOfst wurde exakt auf das Ende eingestellt, deswegen <=
+ // nPaintOfst ist dokumentglobal, deswegen nLeftMar aufaddieren
+ // const KSHORT nLeftMar = KSHORT(GetLeftMargin());
+ // 8310: painten von LineBreaks in leeren Zeilen.
+ if( nPaintOfst && pCurr->Width() )
+ {
+ SwLinePortion *pLast = 0;
+ // 7529 und 4757: nicht <= nPaintOfst
+ while( pPor && GetInfo().X() + pPor->Width() + (pPor->Height()/2)
+ < nPaintOfst )
+ {
+ DBG_LOOP;
+ if( pPor->InTxtGrp() && GetInfo().GetSpaceAdd() )
+ {
+ long nTmp = GetInfo().X() +pPor->Width() +((SwTxtPortion*)pPor)
+ ->CalcSpacing( GetInfo().GetSpaceAdd(), GetInfo() );
+ if( nTmp + (pPor->Height()/2) >= nPaintOfst )
+ break;
+ GetInfo().X( nTmp );
+ GetInfo().SetIdx( GetInfo().GetIdx() + pPor->GetLen() );
+ }
+ else
+ pPor->Move( GetInfo() );
+ pLast = pPor;
+ pPor = pPor->GetPortion();
+ }
+
+#ifndef USED
+ // 7529: bei PostIts auch pLast returnen.
+ if( pLast && !pLast->Width() && pLast->IsPostItsPortion() )
+ {
+ pPor = pLast;
+ GetInfo().SetIdx( GetInfo().GetIdx() - pPor->GetLen() );
+ }
+#endif
+ }
+ return pPor;
+}
+
+/*************************************************************************
+ * SwTxtPainter::DrawTextLine()
+ *
+ * Es gibt zwei Moeglichkeiten bei transparenten Font auszugeben:
+ * 1) DrawRect auf die ganze Zeile und die DrawText hinterher
+ * (objektiv schnell, subjektiv langsam).
+ * 2) Fuer jede Portion ein DrawRect mit anschliessendem DrawText
+ * ausgefuehrt (objektiv langsam, subjektiv schnell).
+ * Da der User in der Regel subjektiv urteilt, wird die 2. Methode
+ * als Default eingestellt.
+ *************************************************************************/
+void SwTxtPainter::DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip,
+ const sal_Bool bUnderSz )
+{
+ // Adjustierung ggf. nachholen
+ GetAdjusted();
+ GetInfo().SetSpaceAdd( pCurr->GetpSpaceAdd() );
+ GetInfo().ResetSpaceIdx();
+ // Die Groesse des Frames
+ GetInfo().SetIdx( GetStart() );
+ GetInfo().SetPos( GetTopLeft() );
+
+ const sal_Bool bDrawInWindow = GetInfo().OnWin();
+
+ // 6882: Leerzeilen duerfen nicht wegoptimiert werden bei Paragraphzeichen.
+ const sal_Bool bEndPor = GetInfo().GetOpt().IsParagraph() && !GetInfo().GetTxt().Len();
+
+ SwLinePortion *pPor = bEndPor ? pCurr->GetFirstPortion() : CalcPaintOfst( rPaint );
+
+ // Optimierung!
+ const SwTwips nMaxRight = Min( rPaint.Right(), Right() );
+ const SwTwips nTmpLeft = GetInfo().X();
+ if( !bEndPor && nTmpLeft >= nMaxRight )
+ return;
+
+ // DropCaps!
+ // 7538: natuerlich auch auf dem Drucker
+ if( !bPaintDrop )
+ {
+ // 8084: Optimierung, weniger Painten.
+ // AMA: Durch 8084 wurde 7538 wiederbelebt!
+ // bDrawInWindow entfernt, damit DropCaps auch gedruckt werden
+ bPaintDrop = pPor == pCurr->GetFirstPortion()
+ && GetDropLines() >= GetLineNr();
+ }
+
+ KSHORT nTmpHeight, nTmpAscent;
+ CalcAscentAndHeight( nTmpAscent, nTmpHeight );
+
+ // bClip entscheidet darueber, ob geclippt werden muss.
+ // Das Ganze muss vor der Retusche stehen
+
+ sal_Bool bClip = ( bDrawInWindow || bUnderSz ) && !rClip.IsChg();
+ if( bClip && pPor )
+ {
+ // Wenn TopLeft oder BottomLeft der Line ausserhalb liegen,
+ // muss geclippt werden. Die Ueberpruefung auf Right() erfolgt
+ // in der folgenden Ausgabeschleife...
+
+ if( GetInfo().GetPos().X() < rPaint.Left() ||
+ GetInfo().GetPos().Y() < rPaint.Top() ||
+ GetInfo().GetPos().Y() + nTmpHeight > rPaint.Top() + rPaint.Height() )
+ {
+ bClip = sal_False;
+ rClip.ChgClip( rPaint );
+ }
+#ifdef DEBUG
+ static sal_Bool bClipAlways = sal_False;
+ if( bClip && bClipAlways )
+ { bClip = sal_False;
+ rClip.ChgClip( rPaint );
+ }
+#endif
+ }
+
+ // Alignment:
+ sal_Bool bPlus = sal_False;
+ OutputDevice *pOut = GetInfo().GetOut();
+ Point aPnt1( nTmpLeft, GetInfo().GetPos().Y() );
+ if ( aPnt1.X() < rPaint.Left() )
+ aPnt1.X() = rPaint.Left();
+ if ( aPnt1.Y() < rPaint.Top() )
+ aPnt1.Y() = rPaint.Top();
+ Point aPnt2( GetInfo().GetPos().X() + nMaxRight - GetInfo().X(),
+ GetInfo().GetPos().Y() + nTmpHeight );
+ if ( aPnt2.X() > rPaint.Right() )
+ aPnt2.X() = rPaint.Right();
+ if ( aPnt2.Y() > rPaint.Bottom() )
+ {
+ aPnt2.Y() = rPaint.Bottom();
+ bPlus = sal_True;
+ }
+
+ const SwRect aLineRect( aPnt1, aPnt2 );
+
+ if( pCurr->IsClipping() )
+ {
+ rClip.ChgClip( aLineRect );
+ bClip = sal_False;
+ }
+
+ if( !pPor && !bEndPor )
+ {
+#ifdef DBGTXT
+ aDbstream << "PAINTER: done nothing" << endl;
+#endif
+ return;
+ }
+
+ // Baseline-Ausgabe auch bei nicht-TxtPortions (vgl. TabPor mit Fill)
+ const SwTwips nY = GetInfo().GetPos().Y() + nTmpAscent;
+ GetInfo().Y( nY );
+
+ // 7529: PostIts prepainten
+ if( GetInfo().OnWin() && pPor && !pPor->Width() )
+ {
+ SeekAndChg( GetInfo() );
+ pPor->PrePaint( GetInfo(), pPor );
+ }
+
+ // 7923: EndPortions geben auch Zeichen aus, deswegen den Fnt wechseln!
+ if( bEndPor )
+ SeekStartAndChg( GetInfo() );
+
+ sal_Bool bRest = pCurr->IsRest();
+ sal_Bool bFirst = sal_True;
+
+ SwArrowPortion *pArrow = NULL;
+
+ while( pPor )
+ {
+ DBG_LOOP;
+ sal_Bool bSeeked = sal_True;
+ GetInfo().SetLen( pPor->GetLen() );
+ GetInfo().SetSpecialUnderline( sal_False );
+ // Ein Sonderfall sind GluePortions, die Blanks ausgeben.
+
+ // 6168: Der Rest einer FldPortion zog sich die Attribute der naechsten
+ // Portion an, dies wird durch SeekAndChgBefore vermieden:
+ if( ( bRest && pPor->InFldGrp() && !pPor->GetLen() ) )
+ SeekAndChgBefore( GetInfo() );
+ else if ( pPor->IsQuoVadisPortion() )
+ {
+ xub_StrLen nOffset = GetInfo().GetIdx();
+ SeekStartAndChg( GetInfo(), sal_True );
+ if( GetRedln() && pCurr->HasRedline() )
+ GetRedln()->Seek( *pFnt, nOffset, 0 );
+ }
+ else if( pPor->InTxtGrp() || pPor->InFldGrp() || pPor->InTabGrp() )
+ SeekAndChg( GetInfo() );
+ else if ( !bFirst && pPor->IsBreakPortion() && GetInfo().GetOpt().IsParagraph() )
+ {
+ // Paragraphzeichen sollten den gleichen Font wie das Zeichen vor
+ // haben, es sei denn, es gibt Redlining in dem Absatz.
+ if( GetRedln() )
+ SeekAndChg( GetInfo() );
+ else
+ SeekAndChgBefore( GetInfo() );
+ }
+ else
+ bSeeked = sal_False;
+
+// bRest = sal_False;
+
+ ASSERT( GetInfo().Y() == nY, "DrawTextLine: Y() has changed" );
+
+ // Wenn das Ende der Portion hinausragt, wird geclippt.
+ // Es wird ein Sicherheitsabstand von Height-Halbe aufaddiert,
+ // damit die TTF-"f" nicht im Seitenrand haengen...
+ if(bClip && GetInfo().X() + pPor->Width() + (pPor->Height()/2) > nMaxRight)
+ { bClip = sal_False;
+ rClip.ChgClip( rPaint );
+ }
+
+ // Portions, die "unter" dem Text liegen wie PostIts
+ SwLinePortion *pNext = pPor->GetPortion();
+ if(GetInfo().OnWin() && pNext && !pNext->Width() )
+ {
+ // Fix 11289: Felder waren hier ausgeklammert wg. Last!=Owner beim
+ // Laden von Brief.sdw. Jetzt sind die Felder wieder zugelassen,
+ // durch bSeeked wird Last!=Owner vermieden.
+ if ( !bSeeked )
+ SeekAndChg( GetInfo() );
+ pNext->PrePaint( GetInfo(), pPor );
+ }
+
+ if( pFnt->GetEscapement() && UNDERLINE_NONE != pFnt->GetUnderline() )
+ CheckSpecialUnderline();
+
+ pPor->Paint( GetInfo() );
+
+ if( GetFnt()->IsURL() && pPor->InTxtGrp() )
+ GetInfo().NotifyURL( *pPor );
+
+ bFirst &= !pPor->GetLen();
+ if( pNext || !pPor->IsMarginPortion() )
+ pPor->Move( GetInfo() );
+ if( pPor->IsArrowPortion() && GetInfo().OnWin() && !pArrow )
+ pArrow = (SwArrowPortion*)pPor;
+
+ pPor = !bDrawInWindow && GetInfo().X() > nMaxRight ? 0 : pNext;
+ }
+ if( bDrawInWindow )
+ {
+ if( !GetNextLine() &&
+ GetInfo().GetVsh() && !GetInfo().GetVsh()->IsPreView() &&
+ GetInfo().GetOpt().IsParagraph() && !GetTxtFrm()->GetFollow() &&
+ GetInfo().GetIdx() >= GetInfo().GetTxt().Len() )
+ {
+ SwTmpEndPortion aEnd( *pCurr->GetFirstPortion() );
+ aEnd.Paint( GetInfo() );
+ }
+ if( bUnderSz )
+ {
+ if( GetInfo().GetVsh() && !GetInfo().GetVsh()->IsPreView() )
+ {
+ if( pArrow )
+ pArrow->PaintIt( pOut );
+ if( !GetTxtFrm()->GetFollow() )
+ {
+ SwTwips nDiff = GetInfo().Y() + nTmpHeight - nTmpAscent - GetTxtFrm()->Frm().Bottom();
+ if( nDiff > 0 && ( GetEnd() < GetInfo().GetTxt().Len() ||
+ ( nDiff > nTmpHeight/2 && GetPrevLine() ) ) )
+ {
+ SwArrowPortion aArrow( GetInfo() );
+ aArrow.PaintIt( pOut );
+ }
+ }
+ }
+ }
+ }
+ if( pCurr->IsClipping() )
+ rClip.ChgClip( rPaint );
+}
+
+void SwTxtPainter::CheckSpecialUnderline()
+{
+ sal_Bool bSpecial = sal_False;
+ if( HasHints() )
+ {
+ sal_Bool bINet = sal_False;
+ MSHORT nTmp = 0;
+ Range aRange( 0, GetInfo().GetTxt().Len() );
+ MultiSelection aUnderMulti( aRange );
+ if( bUnderPara )
+ aUnderMulti.SelectAll();
+ MultiSelection aEscMulti( aRange );
+ if( bEscPara )
+ aEscMulti.SelectAll();
+ SwTxtAttr* pTxtAttr;
+ sal_Bool bUnder = sal_False;
+ sal_Bool bEsc = sal_False;
+ while( nTmp < pHints->GetStartCount() )
+ {
+ pTxtAttr = pHints->GetStart( nTmp++ );
+ sal_Bool bUnderSelect;
+ sal_Bool bEscSelect;
+ switch ( pTxtAttr->Which() )
+ {
+ case RES_CHRATR_UNDERLINE:
+ {
+ bUnder = sal_True;
+ bUnderSelect = UNDERLINE_NONE != pTxtAttr->GetUnderline().
+ GetUnderline();
+ }
+ break;
+ case RES_CHRATR_ESCAPEMENT:
+ {
+ bEsc = sal_True;
+ bEscSelect = 0 != pTxtAttr->GetEscapement().GetEsc();
+ }
+ break;
+ case RES_TXTATR_FTN:
+ {
+ xub_StrLen nStrt = *pTxtAttr->GetStart();
+ Range aRg( nStrt, nStrt + 1 );
+ aEscMulti.Select( aRg );
+ }
+ break;
+ case RES_TXTATR_INETFMT: bINet = sal_True;
+ case RES_TXTATR_CHARFMT:
+ {
+ SwCharFmt* pFmt;
+ const SfxPoolItem* pItem;
+ if( bINet )
+ {
+ pFmt = ((SwTxtINetFmt*)pTxtAttr)->GetCharFmt();
+ bINet = sal_False;
+ }
+ else
+ pFmt = pTxtAttr->GetCharFmt().GetCharFmt();
+ if ( pFmt )
+ {
+ if( SFX_ITEM_SET == pFmt->GetAttrSet().
+ GetItemState( RES_CHRATR_ESCAPEMENT, sal_True, &pItem) )
+ {
+ bEscSelect = 0 !=
+ ((SvxEscapementItem *)pItem)->GetEsc();
+ bEsc = sal_True;
+ }
+ if( SFX_ITEM_SET == pFmt->GetAttrSet().
+ GetItemState( RES_CHRATR_UNDERLINE, sal_True, &pItem ) )
+ {
+ bUnderSelect = UNDERLINE_NONE !=
+ ((SvxUnderlineItem*)pItem)->GetUnderline();
+ bUnder = sal_True;
+ }
+ }
+ }
+ break;
+ }
+ if( bUnder || bEsc )
+ {
+ xub_StrLen nSt = *pTxtAttr->GetStart();
+ xub_StrLen nEnd = *pTxtAttr->GetEnd();
+ if( nEnd > nSt )
+ {
+ Range aTmp( nSt, nEnd - 1 );
+ if( bUnder )
+ aUnderMulti.Select( aTmp, bUnderSelect );
+ if( bEsc )
+ aEscMulti.Select( aTmp, bEscSelect );
+ }
+ bUnder = sal_False;
+ bEsc = sal_False;
+ }
+ }
+ MSHORT i;
+ xub_StrLen nEscStart = 0;
+ xub_StrLen nEscEnd = 0;
+ xub_StrLen nIndx = GetInfo().GetIdx();
+ MSHORT nCnt = (MSHORT)aEscMulti.GetRangeCount();
+ for( i = 0; i < nCnt; ++i )
+ {
+ const Range& rRange = aEscMulti.GetRange( i );
+ if( nEscEnd == rRange.Min() )
+ nEscEnd = rRange.Max();
+ else if( nIndx >= rRange.Min() )
+ {
+ nEscStart = rRange.Min();
+ nEscEnd = rRange.Max();
+ }
+ else
+ break;
+ }
+ xub_StrLen nUnderStart = 0;
+ xub_StrLen nUnderEnd = 0;
+ nCnt = (MSHORT)aUnderMulti.GetRangeCount();
+ for( i = 0; i < nCnt; ++i )
+ {
+ const Range& rRange = aUnderMulti.GetRange( i );
+ if( nUnderEnd == rRange.Min() )
+ nUnderEnd = rRange.Max();
+ else if( nIndx >= rRange.Min() )
+ {
+ nUnderStart = rRange.Min();
+ nUnderEnd = rRange.Max();
+ }
+ else
+ break;
+ }
+ bSpecial = nEscStart > nUnderStart || nEscEnd < nUnderEnd;
+ }
+ if( bSpecial || ( GetRedln() && GetRedln()->ChkSpecialUnderline() ) )
+ GetInfo().SetSpecialUnderline( sal_True );
+}
+
diff --git a/sw/source/core/text/itrpaint.hxx b/sw/source/core/text/itrpaint.hxx
new file mode 100644
index 000000000000..b403101a5fb7
--- /dev/null
+++ b/sw/source/core/text/itrpaint.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * $RCSfile: itrpaint.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRPAINT_HXX
+#define _ITRPAINT_HXX
+
+#include "itrtxt.hxx"
+
+class SwSaveClip; // SwTxtPainter
+
+/*************************************************************************
+ * class SwTxtPainter
+ *************************************************************************/
+
+class SwTxtPainter : public SwTxtCursor
+{
+ sal_Bool bPaintDrop;
+
+ SwLinePortion *CalcPaintOfst( const SwRect &rPaint );
+ void CheckSpecialUnderline();
+protected:
+ void CtorInit( SwTxtFrm *pFrm, SwTxtPaintInfo *pInf );
+ inline SwTxtPainter() { }
+public:
+ inline SwTxtPainter( SwTxtFrm *pFrm, SwTxtPaintInfo *pInf )
+ { CtorInit( pFrm, pInf ); }
+ void DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip,
+ const sal_Bool bUnderSz );
+ void PaintDropPortion();
+ inline void SetPaintDrop( const sal_Bool bNew ) { bPaintDrop = bNew; }
+ inline IsPaintDrop() const { return bPaintDrop; }
+ inline SwTxtPaintInfo &GetInfo()
+ { return (SwTxtPaintInfo&)SwTxtIter::GetInfo(); }
+ inline const SwTxtPaintInfo &GetInfo() const
+ { return (const SwTxtPaintInfo&)SwTxtIter::GetInfo(); }
+};
+
+
+
+#endif
diff --git a/sw/source/core/text/itrtxt.cxx b/sw/source/core/text/itrtxt.cxx
new file mode 100644
index 000000000000..5c297aaf7ee8
--- /dev/null
+++ b/sw/source/core/text/itrtxt.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ * $RCSfile: itrtxt.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "hintids.hxx"
+#include "ndtxt.hxx"
+#include "flyfrm.hxx"
+#include "paratr.hxx"
+#include "errhdl.hxx"
+
+#ifndef _SVX_LSPCITEM_HXX //autogen
+#include <svx/lspcitem.hxx>
+#endif
+#include "txtcfg.hxx"
+#include "itrtxt.hxx"
+#include "txtfrm.hxx"
+#include "porfly.hxx"
+
+#ifdef DEBUG
+# include "txtfrm.hxx" // GetFrmID,
+#endif
+
+/*************************************************************************
+ * SwTxtIter::CtorInit()
+ *************************************************************************/
+
+void SwTxtIter::CtorInit( SwTxtFrm *pNewFrm, SwTxtInfo *pNewInf )
+{
+#ifdef DBGTXT
+ // nStopAt laesst sich vom CV bearbeiten.
+ static MSHORT nStopAt = 0;
+ if( nStopAt == pNewFrm->GetFrmId() )
+ {
+ int i = pNewFrm->GetFrmId();
+ }
+#endif
+
+ SwTxtNode *pNode = pNewFrm->GetTxtNode();
+ SwAttrIter::CtorInit( *pNode );
+ pFrm = pNewFrm;
+ pInf = pNewInf;
+ aLineInf.CtorInit( pNode->GetSwAttrSet() );
+ aTopLeft = pFrm->Frm().Pos() + pFrm->Prt().Pos();
+ SwTxtIter::Init();
+ if( pNode->GetSwAttrSet().GetRegister().GetValue() )
+ bRegisterOn = pFrm->FillRegister( nRegStart, nRegDiff );
+ else
+ bRegisterOn = sal_False;
+ bUnderPara = UNDERLINE_NONE != pFnt->GetUnderline();
+ bEscPara = 0 != pFnt->GetEscapement();
+}
+
+/*************************************************************************
+ * SwTxtIter::Init()
+ *************************************************************************/
+
+void SwTxtIter::Init()
+{
+ pCurr = pInf->GetParaPortion();
+ nStart = pInf->GetTxtStart();
+ nY = aTopLeft.Y();
+ bPrev = sal_True;
+ pPrev = 0;
+ nLineNr = 1;
+}
+
+/*************************************************************************
+ * SwTxtIter::_GetHeightAndAscent()
+ *************************************************************************/
+
+void SwTxtIter::CalcAscentAndHeight( KSHORT &rAscent, KSHORT &rHeight ) const
+{
+ rHeight = GetLineHeight();
+ rAscent = pCurr->GetAscent() + rHeight - pCurr->Height();
+}
+
+/*************************************************************************
+ * SwTxtIter::CalcRealHeight( sal_Bool bNewLine = sal_False )
+ *************************************************************************/
+
+void SwTxtIter::CalcRealHeight( sal_Bool bNewLine )
+{
+ KSHORT nLineHeight = pCurr->Height();
+ pCurr->SetClipping( sal_False );
+ // Das Dummyflag besitzen Zeilen, die nur Flyportions enthalten, diese
+ // sollten kein Register etc. beachten. Dummerweise hat kann es eine leere
+ // Zeile am Absatzende geben (bei leeren Abs„tzen oder nach einem
+ // Shift-Return), die das Register durchaus beachten soll.
+ if( !pCurr->IsDummy() || ( !pCurr->GetNext() &&
+ GetStart() >= GetTxtFrm()->GetTxt().Len() && !bNewLine ) )
+ {
+ const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing();
+ if( pSpace )
+ {
+ switch( pSpace->GetLineSpaceRule() )
+ {
+ case SVX_LINE_SPACE_AUTO:
+ break;
+ case SVX_LINE_SPACE_MIN:
+ {
+ if( nLineHeight < KSHORT( pSpace->GetLineHeight() ) )
+ nLineHeight = pSpace->GetLineHeight();
+ break;
+ }
+ case SVX_LINE_SPACE_FIX:
+ {
+ nLineHeight = pSpace->GetLineHeight();
+ KSHORT nAsc = ( 4 * nLineHeight ) / 5; // 80%
+ if( nAsc < pCurr->GetAscent() ||
+ nLineHeight - nAsc < pCurr->Height() - pCurr->GetAscent() )
+ pCurr->SetClipping( sal_True );
+ pCurr->Height( nLineHeight );
+ pCurr->SetAscent( nAsc );
+ pInf->GetParaPortion()->SetFixLineHeight();
+ }
+ break;
+ default: ASSERT( sal_False, ": unknown LineSpaceRule" );
+ }
+ if( !IsParaLine() )
+ switch( pSpace->GetInterLineSpaceRule() )
+ {
+ case SVX_INTER_LINE_SPACE_OFF:
+ break;
+ case SVX_INTER_LINE_SPACE_PROP:
+ {
+ long nTmp = pSpace->GetPropLineSpace();
+ // 50% ist das Minimum, bei 0% schalten wir auf
+ // den Defaultwert 100% um ...
+ if( nTmp < 50 )
+ nTmp = nTmp ? 50 : 100;
+
+ nTmp *= nLineHeight;
+ nTmp /= 100;
+ if( !nTmp )
+ ++nTmp;
+ nLineHeight = (KSHORT)nTmp;
+ break;
+ }
+ case SVX_INTER_LINE_SPACE_FIX:
+ {
+ nLineHeight += pSpace->GetInterLineSpace();
+ break;
+ }
+ default: ASSERT( sal_False, ": unknown InterLineSpaceRule" );
+ }
+ }
+#ifdef DEBUG
+ KSHORT nDummy = nLineHeight + 1;
+#endif
+ if( IsRegisterOn() )
+ {
+ SwTwips nTmpY = Y() + pCurr->GetAscent()
+ + nLineHeight - pCurr->Height() - RegStart();
+ KSHORT nDiff = KSHORT( nTmpY % RegDiff() );
+ if( nDiff )
+ nLineHeight += RegDiff() - nDiff;
+ }
+ }
+ pCurr->SetRealHeight( nLineHeight );
+}
+
+/*************************************************************************
+ * SwTxtIter::_GetPrev()
+ *************************************************************************/
+
+SwLineLayout *SwTxtIter::_GetPrev()
+{
+ pPrev = 0;
+ bPrev = sal_True;
+ SwLineLayout *pLay = pInf->GetParaPortion();
+ if( pCurr == pLay )
+ return 0;
+ while( pLay->GetNext() != pCurr )
+ pLay = pLay->GetNext();
+ return pPrev = pLay;
+}
+
+/*************************************************************************
+ * SwTxtIter::GetPrev()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::GetPrev()
+{
+ if(! bPrev)
+ _GetPrev();
+ return pPrev;
+}
+
+/*************************************************************************
+ * SwTxtIter::Prev()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::Prev()
+{
+ if( !bPrev )
+ _GetPrev();
+ if( pPrev )
+ {
+ bPrev = sal_False;
+ pCurr = pPrev;
+ nStart -= pCurr->GetLen();
+ nY -= GetLineHeight();
+ if( !pCurr->IsDummy() && !(--nLineNr) )
+ ++nLineNr;
+ return pCurr;
+ }
+ else
+ return 0;
+}
+
+/*************************************************************************
+ * SwTxtIter::Next()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::Next()
+{
+ if(pCurr->GetNext())
+ {
+ pPrev = pCurr;
+ bPrev = sal_True;
+ nStart += pCurr->GetLen();
+ nY += GetLineHeight();
+ if( pCurr->GetLen() || ( nLineNr>1 && !pCurr->IsDummy() ) )
+ ++nLineNr;
+ return pCurr = pCurr->GetNext();
+ }
+ else
+ return 0;
+}
+
+/*************************************************************************
+ * SwTxtIter::NextLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::NextLine()
+{
+ const SwLineLayout *pNext = Next();
+ while( pNext && pNext->IsDummy() && pNext->GetNext() )
+ {
+ DBG_LOOP;
+ pNext = Next();
+ }
+ return pNext;
+}
+
+/*************************************************************************
+ * SwTxtIter::GetNextLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::GetNextLine() const
+{
+ const SwLineLayout *pNext = pCurr->GetNext();
+ while( pNext && pNext->IsDummy() && pNext->GetNext() )
+ {
+ DBG_LOOP;
+ pNext = pNext->GetNext();
+ }
+ return (SwLineLayout*)pNext;
+}
+
+/*************************************************************************
+ * SwTxtIter::GetPrevLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::GetPrevLine()
+{
+ const SwLineLayout *pRoot = pInf->GetParaPortion();
+ if( pRoot == pCurr )
+ return 0;
+ const SwLineLayout *pLay = pRoot;
+
+ while( pLay->GetNext() != pCurr )
+ pLay = pLay->GetNext();
+
+ if( pLay->IsDummy() )
+ {
+ const SwLineLayout *pTmp = pRoot;
+ pLay = pRoot->IsDummy() ? 0 : pRoot;
+ while( pTmp->GetNext() != pCurr )
+ {
+ if( !pTmp->IsDummy() )
+ pLay = pTmp;
+ pTmp = pTmp->GetNext();
+ }
+ }
+
+ // Wenn sich nichts getan hat, dann gibt es nur noch Dummys
+ return (SwLineLayout*)pLay;
+}
+
+/*************************************************************************
+ * SwTxtIter::PrevLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::PrevLine()
+{
+ const SwLineLayout *pPrev = Prev();
+ if( !pPrev )
+ return 0;
+
+ const SwLineLayout *pLast = pPrev;
+ while( pPrev && pPrev->IsDummy() )
+ {
+ DBG_LOOP;
+ pLast = pPrev;
+ pPrev = Prev();
+ }
+ return (SwLineLayout*)(pPrev ? pPrev : pLast);
+}
+
+/*************************************************************************
+ * SwTxtIter::Bottom()
+ *************************************************************************/
+
+void SwTxtIter::Bottom()
+{
+ while( Next() )
+ {
+ DBG_LOOP;
+ }
+}
+
+/*************************************************************************
+ * SwTxtIter::RecalcRealHeight()
+ *************************************************************************/
+
+void SwTxtIter::RecalcRealHeight()
+{
+ sal_Bool bMore = sal_True;
+ while(bMore)
+ {
+ DBG_LOOP;
+ CalcRealHeight();
+ bMore = Next() != 0;
+ }
+}
+
+/*************************************************************************
+ * SwTxtIter::CharToLine()
+ *************************************************************************/
+
+void SwTxtIter::CharToLine(const xub_StrLen nChar)
+{
+ while( nStart + pCurr->GetLen() <= nChar && Next() )
+ ;
+ while( nStart > nChar && Prev() )
+ ;
+}
+
+/*************************************************************************
+ * SwTxtIter::CharCrsrToLine()
+ *************************************************************************/
+
+// 1170: beruecksichtigt Mehrdeutigkeiten:
+const SwLineLayout *SwTxtCursor::CharCrsrToLine( const xub_StrLen nPos )
+{
+ CharToLine( nPos );
+ if( nPos != nStart )
+ bRightMargin = sal_False;
+ sal_Bool bPrev = bRightMargin && pCurr->GetLen() && GetPrev() &&
+ GetPrev()->GetLen();
+ if( bPrev && nPos && CH_BREAK == GetInfo().GetChar( nPos-1 ) )
+ bPrev = sal_False;
+ return bPrev ? PrevLine() : pCurr;
+}
+
+/*************************************************************************
+ * SwTxtIter::TwipsToLine()
+ *************************************************************************/
+
+const SwLineLayout *SwTxtIter::TwipsToLine( const SwTwips y)
+{
+ while( nY + GetLineHeight() <= y && Next() )
+ ;
+ while( nY > y && Prev() )
+ ;
+ return pCurr;
+}
+
+/*************************************************************************
+ * SwTxtIter::TruncLines()
+ *************************************************************************/
+
+void SwTxtIter::TruncLines( sal_Bool bNoteFollow )
+{
+ SwLineLayout *pDel = pCurr->GetNext();
+ if( pDel )
+ {
+ pCurr->SetNext( 0 );
+ if( GetHints() && bNoteFollow )
+ GetInfo().GetParaPortion()->SetFollowField( pDel->IsRest() );
+ delete pDel;
+ }
+ if( GetHints() )
+ pFrm->RemoveFtn( nStart + pCurr->GetLen() );
+}
+
+/*************************************************************************
+ * SwTxtIter::CntHyphens()
+ *************************************************************************/
+
+void SwTxtIter::CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const
+{
+ nEndCnt = 0;
+ nMidCnt = 0;
+ if ( bPrev && pPrev && !pPrev->IsEndHyph() && !pPrev->IsMidHyph() )
+ return;
+ SwLineLayout *pLay = pInf->GetParaPortion();
+ if( pCurr == pLay )
+ return;
+ while( pLay != pCurr )
+ {
+ DBG_LOOP;
+ if ( pLay->IsEndHyph() )
+ nEndCnt++;
+ else
+ nEndCnt = 0;
+ if ( pLay->IsMidHyph() )
+ nMidCnt++;
+ else
+ nMidCnt = 0;
+ pLay = pLay->GetNext();
+ }
+}
+
+
diff --git a/sw/source/core/text/itrtxt.hxx b/sw/source/core/text/itrtxt.hxx
new file mode 100644
index 000000000000..c77931272090
--- /dev/null
+++ b/sw/source/core/text/itrtxt.hxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * $RCSfile: itrtxt.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _ITRTXT_HXX
+#define _ITRTXT_HXX
+
+#include "swtypes.hxx"
+#include "itratr.hxx"
+#include "inftxt.hxx"
+
+class SwTxtFrm;
+struct SwPosition;
+struct SwCrsrMoveState;
+class SwMarginPortion;
+class SwFlyPortion;
+
+/*************************************************************************
+ * class SwTxtIter
+ *************************************************************************/
+
+class SwTxtIter : public SwAttrIter
+{
+protected:
+ SwLineInfo aLineInf;
+ Point aTopLeft; // erste Ausgabeposition
+ SwTxtFrm *pFrm;
+ SwTxtInfo *pInf;
+ SwLineLayout *pCurr;
+ SwLineLayout *pPrev;
+ SwTwips nY;
+ SwTwips nRegStart; // Anfangsposition (Y) des Registers
+ xub_StrLen nStart; // Start im Textstring, Ende = pCurr->GetLen()
+ KSHORT nRegDiff; // Zeilenabstand des Registers
+ MSHORT nLineNr; // Zeilennummer
+ sal_Bool bPrev : 1;
+ sal_Bool bRegisterOn : 1; // Registerhaltigkeit
+ sal_Bool bOneBlock : 1; // Blocksatz: Einzelwoerter austreiben
+ sal_Bool bLastBlock : 1; // Blocksatz: Auch die letzte Zeile
+ sal_Bool bLastCenter : 1; // Blocksatz: Letzte Zeile zentrieren
+ sal_Bool bUnderPara : 1; // Absatz unterstrichen
+ sal_Bool bEscPara : 1; // Absatz mit Escapement
+
+ SwLineLayout *_GetPrev();
+
+ // Zuruecksetzen in die erste Zeile.
+ void Init();
+ void CtorInit( SwTxtFrm *pFrm, SwTxtInfo *pInf );
+ inline SwTxtIter() { }
+
+public:
+ inline SwTxtIter( SwTxtFrm *pFrm, SwTxtInfo *pInf )
+ { CtorInit( pFrm, pInf ); }
+ inline const SwLineLayout *GetCurr() const { return pCurr; } // niemals 0!
+ inline const SwLineLayout *GetNext() const { return pCurr->GetNext(); }
+ const SwLineLayout *GetPrev();
+ inline xub_StrLen GetLength() const { return pCurr->GetLen(); }
+ inline MSHORT GetLineNr() const { return nLineNr; }
+ inline xub_StrLen GetStart() const { return nStart; }
+ inline xub_StrLen GetEnd() const { return GetStart() + GetLength(); }
+ inline SwTwips Y() const { return nY; }
+
+ inline SwTwips RegStart() const { return nRegStart; }
+ inline KSHORT RegDiff() const { return nRegDiff; }
+ inline sal_Bool IsRegisterOn() const { return bRegisterOn; }
+
+ inline SwTxtInfo &GetInfo() { return *pInf; }
+ inline const SwTxtInfo &GetInfo() const { return *pInf; }
+
+ inline void Top() { Init(); }
+ void Bottom();
+ const SwLineLayout *Next();
+ const SwLineLayout *Prev();
+
+ void RecalcRealHeight();
+
+ // Ueberspringt die Dummyzeilen der FlyFrms
+ const SwLineLayout *NextLine();
+ const SwLineLayout *PrevLine();
+ const SwLineLayout *GetNextLine() const;
+ const SwLineLayout *GetPrevLine();
+
+ void CharToLine( const xub_StrLen );
+ const SwLineLayout *TwipsToLine(const SwTwips);
+
+ // schneidet ab pCurr alle ab.
+ void TruncLines( sal_Bool bNoteFollow = sal_False );
+
+ inline KSHORT GetLineHeight() const { return pCurr->GetRealHeight(); }
+ void CalcRealHeight( sal_Bool bNewLine = sal_False );
+ void CalcAscentAndHeight( KSHORT &rAscent, KSHORT &rHeight ) const;
+
+ // 5298, viel Aerger durch die Abfrage auf pCurr == pPara
+ inline sal_Bool IsFirstTxtLine() const
+ { return nStart == GetInfo().GetTxtStart() &&
+ !( pCurr->IsDummy() && GetNextLine() ); }
+
+ // Als Ersatz fuer das alte IsFirstLine()
+ inline sal_Bool IsParaLine() const
+ { return pCurr == pInf->GetParaPortion(); }
+
+ const SwLineInfo &GetLineInfo() const { return aLineInf; }
+ inline const Point &GetFirstPos() const { return aTopLeft; }
+
+ inline sal_Bool SeekAndChg( SwTxtSizeInfo &rInf );
+ inline sal_Bool SeekAndChgBefore( SwTxtSizeInfo &rInf );
+ inline sal_Bool SeekStartAndChg( SwTxtSizeInfo &rInf, const sal_Bool bPara=sal_False );
+
+ inline SwTxtFrm *GetTxtFrm() { return pFrm; }
+ inline const SwTxtFrm *GetTxtFrm() const { return pFrm; }
+
+ // zaehlt aufeinanderfolgende Trennungen, um MaxHyphens einzuhalten
+ void CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const;
+};
+
+/*************************************************************************
+ * class SwTxtMargin
+ *************************************************************************/
+
+class SwTxtMargin : public SwTxtIter
+{
+private:
+ SwTwips nLeft;
+ SwTwips nRight;
+ SwTwips nFirst;
+ KSHORT nDropLeft;
+ KSHORT nDropHeight;
+ KSHORT nDropDescent;
+ MSHORT nDropLines;
+ MSHORT nAdjust;
+
+protected:
+ // fuer FormatQuoVadis
+ inline void Right( const KSHORT nNew ) { nRight = nNew; }
+ // fuer CalcFlyAdjust
+ inline void SetDropLeft( const KSHORT nNew ) { nDropLeft = nNew; }
+
+ void CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf );
+ inline SwTxtMargin() { }
+public:
+ inline SwTxtMargin( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+ { CtorInit( pFrm, pInf ); }
+ inline SwTwips GetLeftMargin() const;
+ inline SwTwips Left() const;
+ inline SwTwips Right() const { return nRight; }
+ inline SwTwips FirstLeft() const { return nFirst; }
+ inline SwTwips CurrWidth() const { return pCurr->PrtWidth(); }
+ SwTwips GetLineStart() const;
+ inline SwTwips GetLineEnd() const { return GetLineStart() + CurrWidth(); }
+ inline Point GetTopLeft() const { return Point( GetLineStart(), Y() ); }
+ inline sal_Bool IsOneBlock() const { return bOneBlock; }
+ inline sal_Bool IsLastBlock() const { return bLastBlock; }
+ inline sal_Bool IsLastCenter() const { return bLastCenter; }
+ inline MSHORT GetAdjust() const { return nAdjust; }
+ inline KSHORT GetLineWidth() const
+ { return KSHORT( Right() - GetLeftMargin() + 1 ); }
+ inline SwTwips GetLeftMin() const { return nFirst < nLeft ? nFirst : nLeft; }
+ inline sal_Bool HasNegFirst() const { return nFirst < nLeft; }
+
+ // DropCaps
+ inline MSHORT GetDropLines() const { return nDropLines; }
+ inline void SetDropLines( const MSHORT nNew ) { nDropLines = nNew; }
+ inline KSHORT GetDropLeft() const { return nDropLeft; }
+ inline KSHORT GetDropHeight() const { return nDropHeight; }
+ inline void SetDropHeight( const KSHORT nNew ) { nDropHeight = nNew; }
+ inline KSHORT GetDropDescent() const { return nDropDescent; }
+ inline void SetDropDescent( const KSHORT nNew ) { nDropDescent = nNew; }
+ void DropInit();
+
+ // liefert TxtPos fuer Start und Ende der aktuellen Zeile ohne whitespaces
+ // In frminf.cxx implementiert.
+ xub_StrLen GetTxtStart() const;
+ xub_StrLen GetTxtEnd() const;
+
+ inline SwTxtSizeInfo &GetInfo()
+ { return (SwTxtSizeInfo&)SwTxtIter::GetInfo(); }
+ inline const SwTxtSizeInfo &GetInfo() const
+ { return (const SwTxtSizeInfo&)SwTxtIter::GetInfo(); }
+
+};
+
+
+/*************************************************************************
+ * class SwTxtAdjuster
+ *************************************************************************/
+
+class SwTxtAdjuster : public SwTxtMargin
+{
+ // Gleicht die Portions aus, wenn Adjustment und FlyFrms vorliegen.
+ void CalcFlyAdjust( SwLineLayout *pCurr );
+
+ // spannt beim Blocksatz die Glues auf.
+ void CalcNewBlock( SwLineLayout *pCurr, const SwLinePortion *pStopAt );
+ // ruft SplitGlues und CalcBlockAdjust
+ void FormatBlock( );
+
+ // Erstellt bei kurzen Zeilen die Glue-Kette.
+ SwMarginPortion *CalcRightMargin( SwLineLayout *pCurr );
+
+ // Berechnung des Adjustments (FlyPortions)
+ SwFlyPortion *CalcFlyPortion( const long nRealWidth,
+ const SwRect &rCurrRect );
+
+protected:
+ inline SwTxtAdjuster() { }
+public:
+ inline SwTxtAdjuster( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+ { SwTxtMargin::CtorInit( pFrm, pInf ); }
+
+ // wird von SwTxtFormatter wegen UpdatePos ueberladen
+ void CalcAdjLine( SwLineLayout *pCurr );
+
+ // sorgt fuer das nachtraegliche adjustieren
+ inline void GetAdjusted() const
+ {
+ if( pCurr->IsFormatAdj() )
+ ((SwTxtAdjuster*)this)->CalcAdjLine( pCurr );
+ }
+
+ // DropCaps-Extrawurst
+ void CalcDropAdjust();
+ void CalcDropRepaint();
+};
+
+/*************************************************************************
+ * class SwTxtCursor
+ *************************************************************************/
+
+class SwTxtCursor : public SwTxtAdjuster
+{
+ // 1170: Mehrdeutigkeiten
+ static sal_Bool bRightMargin;
+protected:
+ void CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf );
+ inline SwTxtCursor() { }
+public:
+ inline SwTxtCursor( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf )
+ { CtorInit( pFrm, pInf ); }
+ sal_Bool GetCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* = 0,
+ const long nMax = 0 );
+ sal_Bool GetEndCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* = 0,
+ const long nMax = 0 );
+ xub_StrLen GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
+ const MSHORT nChgNode, const SwCrsrMoveState* = 0 ) const;
+ // 1170: beruecksichtigt Mehrdeutigkeiten; Implementierung s.u.
+ const SwLineLayout *CharCrsrToLine( const xub_StrLen nPos );
+
+ static inline void SetRightMargin( const sal_Bool bNew ){ bRightMargin = bNew; }
+ static inline sal_Bool IsRightMargin() { return bRightMargin; }
+};
+
+/*************************************************************************
+ * SwHookOut
+ *************************************************************************/
+
+class SwHookOut
+{
+ SwTxtSizeInfo *pInf;
+public:
+ inline SwHookOut( SwTxtSizeInfo *pInfo )
+ : pInf(pInfo->OnWin() && pInfo->GetPrt() ? pInfo : 0)
+ {
+ if( pInf )
+ pInf->SetPrtOut();
+ }
+ inline ~SwHookOut()
+ {
+ if( pInf )
+ pInf->SetWinOut();
+ }
+};
+
+/*************************************************************************
+ * Inline-Implementierungen
+ *************************************************************************/
+
+inline sal_Bool SwTxtIter::SeekAndChg( SwTxtSizeInfo &rInf )
+{
+ return SwAttrIter::SeekAndChg( rInf.GetIdx(), rInf.GetOut() );
+}
+
+inline sal_Bool SwTxtIter::SeekAndChgBefore( SwTxtSizeInfo &rInf )
+{
+ if ( rInf.GetIdx() )
+ return SwAttrIter::SeekAndChg( rInf.GetIdx()-1, rInf.GetOut() );
+ else
+ return SwAttrIter::SeekAndChg( rInf.GetIdx(), rInf.GetOut() );
+}
+
+inline sal_Bool SwTxtIter::SeekStartAndChg( SwTxtSizeInfo &rInf, const sal_Bool bPara )
+{
+ return SwAttrIter::SeekStartAndChg( rInf.GetOut(), bPara );
+}
+
+inline SwTwips SwTxtMargin::GetLeftMargin() const
+{
+ return IsFirstTxtLine() ? nFirst : Left();
+}
+
+inline SwTwips SwTxtMargin::Left() const
+{
+ return (nDropLines >= nLineNr && 1 != nLineNr) ? nFirst + nDropLeft : nLeft;
+}
+
+
+
+#endif
diff --git a/sw/source/core/text/makefile.mk b/sw/source/core/text/makefile.mk
new file mode 100644
index 000000000000..a3039fb031a1
--- /dev/null
+++ b/sw/source/core/text/makefile.mk
@@ -0,0 +1,185 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=sw
+TARGET=text
+
+AUTOSEG=true
+
+PROJECTPCH=core_pch
+PDBTARGET=core_pch
+PROJECTPCHSOURCE=..$/core_1st$/core_pch
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : $(PRJ)$/inc$/swpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/inc$/sw.mk
+
+INCEXT=s:\solar\inc\hm
+
+.IF "$(mydebug)" != ""
+CDEFS+=-Dmydebug
+.ENDIF
+
+.IF "$(GUI)$(COM)" == "WINMSC"
+LIBFLAGS=/NOI /NOE /PAGE:512
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES = \
+ frmcrsr.cxx \
+ frmform.cxx \
+ frminf.cxx \
+ frmpaint.cxx \
+ guess.cxx \
+ inftxt.cxx \
+ itradj.cxx \
+ itratr.cxx \
+ itrcrsr.cxx \
+ itrform2.cxx \
+ itrpaint.cxx \
+ itrtxt.cxx \
+ porexp.cxx \
+ porfld.cxx \
+ porfly.cxx \
+ porglue.cxx \
+ porlay.cxx \
+ porlin.cxx \
+ porref.cxx \
+ porrst.cxx \
+ portox.cxx \
+ portxt.cxx \
+ redlnitr.cxx \
+ txtcache.cxx \
+ txtdrop.cxx \
+ txtfld.cxx \
+ txtfly.cxx \
+ txtfrm.cxx \
+ txtftn.cxx \
+ txthyph.cxx \
+ txtinit.cxx \
+ txtpaint.cxx \
+ txttab.cxx \
+ widorp.cxx \
+ blink.cxx \
+ noteurl.cxx \
+ wrong.cxx
+
+.IF "$(product)$(cap)" == ""
+CXXFILES += \
+ txtio.cxx
+.ENDIF
+
+
+
+SLOFILES = \
+ $(SLO)$/frmcrsr.obj \
+ $(SLO)$/frmform.obj \
+ $(SLO)$/frminf.obj \
+ $(SLO)$/frmpaint.obj \
+ $(SLO)$/guess.obj \
+ $(SLO)$/inftxt.obj \
+ $(SLO)$/itradj.obj \
+ $(SLO)$/itratr.obj \
+ $(SLO)$/itrcrsr.obj \
+ $(SLO)$/itrform2.obj \
+ $(SLO)$/itrpaint.obj \
+ $(SLO)$/itrtxt.obj \
+ $(SLO)$/porexp.obj \
+ $(SLO)$/porfld.obj \
+ $(SLO)$/porfly.obj \
+ $(SLO)$/porglue.obj \
+ $(SLO)$/porlay.obj \
+ $(SLO)$/porlin.obj \
+ $(SLO)$/porref.obj \
+ $(SLO)$/porrst.obj \
+ $(SLO)$/portox.obj \
+ $(SLO)$/portxt.obj \
+ $(SLO)$/redlnitr.obj \
+ $(SLO)$/txtcache.obj \
+ $(SLO)$/txtdrop.obj \
+ $(SLO)$/txtfld.obj \
+ $(SLO)$/txtfly.obj \
+ $(SLO)$/txtfrm.obj \
+ $(SLO)$/txtftn.obj \
+ $(SLO)$/txthyph.obj \
+ $(SLO)$/txtinit.obj \
+ $(SLO)$/txtpaint.obj \
+ $(SLO)$/txttab.obj \
+ $(SLO)$/widorp.obj \
+ $(SLO)$/blink.obj \
+ $(SLO)$/noteurl.obj \
+ $(SLO)$/wrong.obj
+
+.IF "$(product)$(cap)" == ""
+SLOFILES += \
+ $(SLO)$/txtio.obj
+.ENDIF
+
+# --- Tagets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sw/source/core/text/noteurl.cxx b/sw/source/core/text/noteurl.cxx
new file mode 100644
index 000000000000..60be83e86711
--- /dev/null
+++ b/sw/source/core/text/noteurl.cxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * $RCSfile: noteurl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "swtypes.hxx"
+
+#ifndef _SV_OUTDEV_HXX //autogen
+#include <vcl/outdev.hxx>
+#endif
+#ifndef _GOODIES_IMAPRECT_HXX
+#include <svtools/imaprect.hxx>
+#endif
+#ifndef _IMAP_HXX //autogen
+#include <svtools/imap.hxx>
+#endif
+
+#include "txttypes.hxx"
+#include "noteurl.hxx"
+
+// globale Variable, wird in noteurl.Hxx bekanntgegeben
+SwNoteURL *pNoteURL = NULL;
+
+SV_IMPL_PTRARR( SwURLNoteList, SwURLNotePtr )
+
+
+void SwNoteURL::InsertURLNote( const XubString& rURL, const XubString& rTarget,
+ const SwRect& rRect )
+{
+ MSHORT i;
+ MSHORT nCount = aList.Count();
+ for( i = 0; i < nCount; i++ )
+ if( rRect == aList.GetObject(i)->GetRect() )
+ break;
+ if( i == nCount )
+ {
+ SwURLNote *pNew = new SwURLNote( rURL, rTarget, rRect );
+ aList.Insert( pNew, nCount );
+ }
+}
+
+
+void SwNoteURL::FillImageMap( ImageMap *pMap, const Point &rPos,
+ const MapMode& rMap )
+{
+ ASSERT( pMap, "FillImageMap: No ImageMap, no cookies!" );
+ MSHORT nCount = Count();
+ if( nCount )
+ {
+ MapMode aMap( MAP_100TH_MM );
+ for( MSHORT i = 0; i < nCount; ++i )
+ {
+ const SwURLNote &rNote = GetURLNote( i );
+ SwRect aSwRect( rNote.GetRect() );
+ aSwRect -= rPos;
+ Rectangle aRect( OutputDevice::LogicToLogic( aSwRect.SVRect(),
+ rMap, aMap ) );
+ IMapRectangleObject aObj( aRect, rNote.GetURL(), aEmptyStr,
+ rNote.GetTarget(), sal_True, sal_False );
+ pMap->InsertIMapObject( aObj );
+ }
+ }
+}
+
+
+
+
diff --git a/sw/source/core/text/pordrop.hxx b/sw/source/core/text/pordrop.hxx
new file mode 100644
index 000000000000..c8c7c41a0a66
--- /dev/null
+++ b/sw/source/core/text/pordrop.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * $RCSfile: pordrop.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORDROP_HXX
+#define _PORDROP_HXX
+
+#include "portxt.hxx"
+
+class SwFont;
+
+// DropCap-Cache, globale Variable, in txtinit.cxx initialisiert/zerstoert
+// und in txtdrop.cxx benutzt bei der Initialenberechnung
+
+class SwDropCapCache;
+extern SwDropCapCache *pDropCapCache;
+
+/*************************************************************************
+ * class SwDropPortion
+ *************************************************************************/
+
+class SwDropPortion : public SwTxtPortion
+{
+ friend class SwDropCapCache;
+ SwFont *pFnt; // der Font
+ MSHORT nLines; // Anzahl der Zeilen
+ KSHORT nDropHeight; // Hoehe
+ KSHORT nDropDescent; // Abstand zur naechsten Zeile
+ KSHORT nDistance; // Abstand zum Text
+ KSHORT nFix; // Fixposition
+ short nX; // X-PaintOffset
+ short nY; // Y-PaintOffset
+
+ sal_Bool FormatTxt( SwTxtFormatInfo &rInf );
+ void PaintTxt( const SwTxtPaintInfo &rInf /*, const sal_Bool bBack */) const;
+
+ inline void Fix( const KSHORT nNew ) { nFix = nNew; }
+public:
+ SwDropPortion( SwFont *pFnt, const MSHORT nLineCnt,
+ const KSHORT nDropHeight,
+ const KSHORT nDropDescent,
+ const KSHORT nDistance );
+ virtual ~SwDropPortion();
+
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ void PaintDrop( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+ virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;
+#ifdef OLDRECYCLE
+ virtual sal_Bool MayRecycle() const;
+#endif
+
+ inline MSHORT GetLines() const { return nLines; }
+ inline KSHORT GetDistance() const { return nDistance; }
+ inline KSHORT GetDropHeight() const { return nDropHeight; }
+ inline KSHORT GetDropDescent() const { return nDropDescent; }
+ inline KSHORT GetDropLeft() const { return Width() + nFix; }
+
+ static void DeleteDropCapCache();
+
+ OUTPUT_OPERATOR
+};
+
+
+#endif
diff --git a/sw/source/core/text/porexp.cxx b/sw/source/core/text/porexp.cxx
new file mode 100644
index 000000000000..c2e688f59abe
--- /dev/null
+++ b/sw/source/core/text/porexp.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * $RCSfile: porexp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _VIEWOPT_HXX
+#include <viewopt.hxx> // SwViewOptions
+#endif
+#ifndef _INFTXT_HXX
+#include <inftxt.hxx>
+#endif
+#ifndef _POREXP_HXX
+#include <porexp.hxx>
+#endif
+#ifndef _PORLAY_HXX
+#include <porlay.hxx>
+#endif
+
+/*************************************************************************
+ * class SwExpandPortion
+ *************************************************************************/
+
+xub_StrLen SwExpandPortion::GetCrsrOfst( const MSHORT nOfst ) const
+{ return SwLinePortion::GetCrsrOfst( nOfst ); }
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwExpandPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+/*************************************************************************
+ * virtual SwExpandPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwExpandPortion::GetExpTxt( const SwTxtSizeInfo &rInf,
+ XubString &rTxt ) const
+{
+ rTxt.Erase();
+ // Nicht etwa: return 0 != rTxt.Len();
+ // Weil: leere Felder ersetzen CH_TXTATR gegen einen Leerstring
+ return sal_True;
+}
+
+/*************************************************************************
+ * virtual SwExpandPortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwExpandPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+ SwTxtSlot aDiffTxt( &rInf, this );
+ return rInf.GetTxtSize();
+}
+
+/*************************************************************************
+ * virtual SwExpandPortion::Format()
+ *************************************************************************/
+
+// 5010: Exp und Tabs
+
+sal_Bool SwExpandPortion::Format( SwTxtFormatInfo &rInf )
+{
+ SwTxtSlotLen aDiffTxt( &rInf, this );
+ const xub_StrLen nFullLen = rInf.GetLen();
+
+ // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
+ // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
+ // sal_False returnen wegen SetFull ...
+ if( !nFullLen )
+ {
+ // nicht Init(), weil wir Hoehe und Ascent brauchen
+ Width(0);
+ SetLen(0);
+ return sal_False;
+ }
+ return SwTxtPortion::Format( rInf );
+}
+
+/*************************************************************************
+ * virtual SwExpandPortion::Paint()
+ *************************************************************************/
+
+void SwExpandPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ SwTxtSlotLen aDiffTxt( &rInf, this );
+ rInf.DrawBackBrush( *this );
+ rInf.DrawText( *this, rInf.GetLen(), sal_False );
+}
+
+/*************************************************************************
+ * class SwBlankPortion
+ *************************************************************************/
+
+SwLinePortion *SwBlankPortion::Compress() { return this; }
+
+/*************************************************************************
+ * SwBlankPortion::MayUnderFlow()
+ *************************************************************************/
+
+// 5497: Es gibt schon Gemeinheiten auf der Welt...
+// Wenn eine Zeile voll mit HardBlanks ist und diese ueberlaeuft,
+// dann duerfen keine Underflows generiert werden!
+// Komplikationen bei Flys...
+
+MSHORT SwBlankPortion::MayUnderFlow( const SwTxtFormatInfo &rInf,
+ xub_StrLen nIdx, sal_Bool bUnderFlow ) const
+{
+ if( rInf.StopUnderFlow() )
+ return 0;
+ const SwLinePortion *pPos = rInf.GetRoot();
+ if( pPos->GetPortion() )
+ pPos = pPos->GetPortion();
+ while( pPos && pPos->IsBlankPortion() )
+ pPos = pPos->GetPortion();
+ if( !pPos || !rInf.GetIdx() || ( !pPos->GetLen() && pPos == rInf.GetRoot() ) )
+ return 0; // Nur noch BlankPortions unterwegs
+ // Wenn vor uns ein Blank ist, brauchen wir kein Underflow ausloesen,
+ // wenn hinter uns ein Blank ist, brauchen wir kein Underflow weiterreichen
+ if( bUnderFlow && CH_BLANK == rInf.GetTxt().GetChar( nIdx + 1) )
+ return 0;
+ if( nIdx && !((SwTxtFormatInfo&)rInf).GetFly() )
+ {
+ while( pPos && !pPos->IsFlyPortion() )
+ pPos = pPos->GetPortion();
+ if( !pPos )
+ {
+ //Hier wird ueberprueft, ob es in dieser Zeile noch sinnvolle Umbrueche
+ //gibt, Blanks oder Felder etc., wenn nicht, kein Underflow.
+ //Wenn Flys im Spiel sind, lassen wir das Underflow trotzdem zu.
+ xub_StrLen nBlank = nIdx;
+ while( --nBlank > rInf.GetLineStart() )
+ {
+ const xub_Unicode cCh = rInf.GetChar( nBlank );
+ if( CH_BLANK == cCh ||
+ (( CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh )
+ && rInf.HasHint( nBlank ) ) )
+ break;
+ }
+ if( nBlank <= rInf.GetLineStart() )
+ return 0;
+ }
+ }
+ xub_Unicode cCh;
+ if( nIdx < 2 || CH_BLANK == (cCh = rInf.GetChar( nIdx - 1 )) )
+ return 1;
+ if( CH_BREAK == cCh )
+ return 0;
+ return 2;
+}
+
+/*************************************************************************
+ * virtual SwBlankPortion::FormatEOL()
+ *************************************************************************/
+// Format end of Line
+
+void SwBlankPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+ MSHORT nMay = MayUnderFlow( rInf, rInf.GetIdx() - nLineLength, sal_True );
+ if( nMay )
+ {
+ if( nMay > 1 )
+ {
+ if( rInf.GetLast() == this )
+ rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
+ rInf.X( rInf.X() - PrtWidth() );
+ rInf.SetIdx( rInf.GetIdx() - GetLen() );
+ }
+ Underflow( rInf );
+ if( rInf.GetLast()->IsKernPortion() )
+ {
+ rInf.SetLast( rInf.GetLast()->FindPrevPortion( rInf.GetRoot() ) );
+ rInf.SetUnderFlow( rInf.GetLast() );
+ }
+ }
+}
+
+/*************************************************************************
+ * virtual SwBlankPortion::Format()
+ *************************************************************************/
+
+// 7771: UnderFlows weiterreichen und selbst ausloesen!
+sal_Bool SwBlankPortion::Format( SwTxtFormatInfo &rInf )
+{
+ const sal_Bool bFull = rInf.IsUnderFlow() || SwExpandPortion::Format( rInf );
+ if( bFull && MayUnderFlow( rInf, rInf.GetIdx(), rInf.IsUnderFlow() ) )
+ {
+ Underflow( rInf );
+ if( rInf.GetLast()->IsKernPortion() )
+ {
+ rInf.SetLast( rInf.GetLast()->FindPrevPortion( rInf.GetRoot() ) );
+ rInf.SetUnderFlow( rInf.GetLast() );
+ }
+ }
+ return bFull;
+}
+
+/*************************************************************************
+ * virtual SwBlankPortion::Paint()
+ *************************************************************************/
+
+void SwBlankPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ rInf.DrawViewOpt( *this, POR_BLANK );
+ SwExpandPortion::Paint( rInf );
+}
+
+/*************************************************************************
+ * virtual SwBlankPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwBlankPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+ rTxt = cChar;
+ return sal_True;
+}
+
+
+/*************************************************************************
+ * class SwPostItsPortion
+ *************************************************************************/
+
+SwPostItsPortion::SwPostItsPortion( sal_Bool bScrpt )
+ : nViewWidth(0), bScript( bScrpt )
+{
+ nLineLength = 1;
+ SetWhichPor( POR_POSTITS );
+}
+
+void SwPostItsPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ if( rInf.OnWin() && Width() )
+ rInf.DrawPostIts( *this, IsScript() );
+}
+
+KSHORT SwPostItsPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{
+ // Nicht zu fassen: PostIts sind immer zu sehen.
+ return rInf.OnWin() ?
+ (KSHORT)rInf.GetOpt().GetPostItsWidth( rInf.GetWin() ) : 0;
+}
+
+/*************************************************************************
+ * virtual SwPostItsPortion::Format()
+ *************************************************************************/
+
+sal_Bool SwPostItsPortion::Format( SwTxtFormatInfo &rInf )
+{
+ sal_Bool bRet = SwLinePortion::Format( rInf );
+ // 32749: PostIts sollen keine Auswirkung auf Zeilenhoehe etc. haben
+ SetAscent( 1 );
+ Height( 1 );
+ return bRet;
+}
+
+/*************************************************************************
+ * virtual SwPostItsPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwPostItsPortion::GetExpTxt( const SwTxtSizeInfo &rInf,
+ XubString &rTxt ) const
+{
+ if( rInf.OnWin() && rInf.GetOpt().IsPostIts() )
+ rTxt = ' ';
+ else
+ rTxt.Erase();
+ return sal_True;
+}
+
+
+
diff --git a/sw/source/core/text/porexp.hxx b/sw/source/core/text/porexp.hxx
new file mode 100644
index 000000000000..39b05fbf364d
--- /dev/null
+++ b/sw/source/core/text/porexp.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * $RCSfile: porexp.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _POREXP_HXX
+#define _POREXP_HXX
+
+#include "portxt.hxx"
+
+/*************************************************************************
+ * class SwExpandPortion
+ *************************************************************************/
+
+class SwExpandPortion : public SwTxtPortion
+{
+public:
+ inline SwExpandPortion() { SetWhichPor( POR_EXP ); }
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+#ifdef OLDRECYCLE
+ virtual sal_Bool MayRecycle() const;
+#endif
+ OUTPUT_OPERATOR
+};
+
+
+/*************************************************************************
+ * class SwBlankPortion
+ *************************************************************************/
+
+class SwBlankPortion : public SwExpandPortion
+{
+ xub_Unicode cChar;
+public:
+ inline SwBlankPortion( xub_Unicode cCh )
+ { cChar = cCh; SetLen(1); SetWhichPor( POR_BLANK ); }
+ virtual SwLinePortion *Compress();
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ virtual void FormatEOL( SwTxtFormatInfo &rInf );
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ MSHORT MayUnderFlow( const SwTxtFormatInfo &rInf, xub_StrLen nIdx,
+ sal_Bool bUnderFlow ) const;
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwPostItsPortion
+ *************************************************************************/
+
+class SwPostItsPortion : public SwExpandPortion
+{
+ KSHORT nViewWidth;
+ sal_Bool bScript;
+public:
+ SwPostItsPortion( sal_Bool bScrpt );
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ sal_Bool IsScript() const { return bScript; }
+ OUTPUT_OPERATOR
+};
+
+
+CLASSIO( SwExpandPortion )
+CLASSIO( SwBlankPortion )
+CLASSIO( SwPostItsPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
new file mode 100644
index 000000000000..5c590ee89574
--- /dev/null
+++ b/sw/source/core/text/porfld.cxx
@@ -0,0 +1,854 @@
+/*************************************************************************
+ *
+ * $RCSfile: porfld.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _GRAPH_HXX //autogen
+#include <vcl/graph.hxx>
+#endif
+#ifndef _SVX_BRSHITEM_HXX //autogen
+#include <svx/brshitem.hxx>
+#endif
+
+#ifndef _FRMSH_HXX
+#include <frmsh.hxx>
+#endif
+#ifndef _VIEWOPT_HXX
+#include <viewopt.hxx> // SwViewOptions
+#endif
+#ifndef _ERRHDL_HXX
+#include <errhdl.hxx>
+#endif
+#ifndef _TXTCFG_HXX
+#include <txtcfg.hxx>
+#endif
+#ifndef _PORLAY_HXX
+#include <porlay.hxx>
+#endif
+#ifndef _PORFLD_HXX
+#include <porfld.hxx>
+#endif
+#ifndef _INFTXT_HXX
+#include <inftxt.hxx>
+#endif
+#ifndef _BLINK_HXX
+#include <blink.hxx> // pBlink
+#endif
+#ifndef _FRMTOOL_HXX
+#include <frmtool.hxx> // DrawGraphic
+#endif
+#ifndef _VIEWSH_HXX
+#include <viewsh.hxx>
+#endif
+#ifndef _DOCSH_HXX
+#include <docsh.hxx>
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx>
+#endif
+
+/*************************************************************************
+ * class SwFldPortion
+ *************************************************************************/
+
+SwLinePortion *SwFldPortion::Compress()
+{ return (GetLen() || aExpand.Len() || SwLinePortion::Compress()) ? this : 0; }
+
+SwFldPortion *SwFldPortion::Clone( const XubString &rExpand ) const
+{
+ SwFont *pNewFnt;
+ if( 0 != ( pNewFnt = pFnt ) )
+ pNewFnt = new SwFont( *pFnt );
+ return new SwFldPortion( rExpand, pNewFnt );
+}
+
+void SwFldPortion::TakeNextOffset( const SwFldPortion* pFld )
+{
+ ASSERT( pFld, "TakeNextOffset: Missing Source" );
+ nNextOffset = pFld->GetNextOffset();
+ aExpand.Erase( 0, nNextOffset );
+ bFollow = sal_True;
+}
+
+SwFldPortion::SwFldPortion( const XubString &rExpand, SwFont *pFnt )
+ : aExpand(rExpand), pFnt(pFnt), nViewWidth(0), nNextOffset(0),
+ bFollow( sal_False ), bHasFollow( sal_False )
+{
+ SetWhichPor( POR_FLD );
+}
+
+SwFldPortion::~SwFldPortion()
+{
+ delete pFnt;
+ if( pBlink )
+ pBlink->Delete( this );
+}
+
+/*************************************************************************
+ * virtual SwFldPortion::GetViewWidth()
+ *************************************************************************/
+
+KSHORT SwFldPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
+{
+ // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
+ // Moment errechnet werden:
+ SwFldPortion* pThis = (SwFldPortion*)this;
+ if( !Width() && rInf.OnWin() && rInf.GetOpt().IsField() )
+ {
+ if( !nViewWidth )
+ pThis->nViewWidth = rInf.GetTxtSize( ' ' ).Width();
+ }
+ else
+ pThis->nViewWidth = 0;
+ return nViewWidth;
+}
+
+/*************************************************************************
+ * virtual SwFldPortion::Format()
+ *************************************************************************/
+
+// 8653: in keinem Fall nur SetLen(0);
+
+/*************************************************************************
+ * Hilfsklasse SwFldSlot
+ **************************************************************************/
+
+class SwFldSlot
+{
+ const XubString *pOldTxt;
+ XubString aTxt;
+ xub_StrLen nIdx;
+ xub_StrLen nLen;
+ sal_Bool bOn;
+ SwTxtSizeInfo *pInf;
+public:
+ SwFldSlot( const SwTxtSizeInfo *pNew, const SwFldPortion *pPor );
+ ~SwFldSlot();
+};
+
+SwFldSlot::SwFldSlot( const SwTxtSizeInfo *pNew, const SwFldPortion *pPor )
+{
+ bOn = pPor->GetExpTxt( *pNew, aTxt );
+
+ // Der Text wird ausgetauscht...
+ if( bOn )
+ {
+ pInf = (SwTxtSizeInfo*)pNew;
+ nIdx = pInf->GetIdx();
+ nLen = pInf->GetLen();
+ pOldTxt = &(pInf->GetTxt());
+ pInf->SetLen( aTxt.Len() );
+ if( pPor->IsFollow() )
+ pInf->SetIdx( 0 );
+ else
+ {
+ XubString aTmp( aTxt );
+ aTxt = *pOldTxt;
+ aTxt.Erase( nIdx, 1 );
+ aTxt.Insert( aTmp, nIdx );
+ }
+ pInf->SetTxt( aTxt );
+ }
+}
+
+SwFldSlot::~SwFldSlot()
+{
+ if( bOn )
+ {
+ pInf->SetTxt( *pOldTxt );
+ pInf->SetIdx( nIdx );
+ pInf->SetLen( nLen );
+ }
+}
+
+sal_Bool SwFldPortion::Format( SwTxtFormatInfo &rInf )
+{
+ // Scope wegen aDiffTxt::DTOR!
+ xub_StrLen nRest;
+ sal_Bool bFull;
+ sal_Bool bEOL = sal_False;
+ long nTxtRest = rInf.GetTxt().Len() - rInf.GetIdx();
+ {
+ SwFldSlot aDiffTxt( &rInf, this );
+ const xub_StrLen nOldFullLen = rInf.GetLen();
+ const MSHORT nFollow = IsFollow() ? 0 : 1;
+ xub_StrLen nFullLen;
+ // In Numerierungen kennen wir keine Platzhalter, sondern
+ // nur "normale" Zeichen.
+ if( InNumberGrp() )
+ nFullLen = nOldFullLen;
+ else
+ {
+ nFullLen = rInf.ScanPortionEnd( rInf.GetIdx() + nOldFullLen,
+ IsFollow() ) - rInf.GetIdx();
+ if( nFullLen && CH_BREAK == aExpand.GetChar( nFullLen - 1 ) )
+ --nFullLen;
+ }
+ rInf.SetLen( nFullLen );
+ SwFontSave aSave( rInf, pFnt );
+
+ // 8674: Laenge muss 0 sein, bei bFull nach Format ist die Laenge
+ // gesetzt und wird in nRest uebertragen. Ansonsten bleibt die
+ // Laenge erhalten und wuerde auch in nRest einfliessen!
+ SetLen(0);
+
+ // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
+ // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
+ // sal_False returnen wegen SetFull ...
+ if( !nFullLen )
+ {
+ // nicht Init(), weil wir Hoehe und Ascent brauchen
+ Width(0);
+ bFull = rInf.Width() <= rInf.GetPos().X();
+ }
+ else
+ {
+ xub_StrLen nOldLineStart = rInf.GetLineStart();
+ rInf.SetLineStart( 0 );
+ rInf.SetNotEOL( nFullLen == nOldFullLen && nTxtRest > nFollow );
+ bFull = SwTxtPortion::Format( rInf );
+ rInf.SetNotEOL( sal_False );
+ rInf.SetLineStart( nOldLineStart );
+ }
+ xub_StrLen nTmpLen = GetLen();
+ bEOL = !nTmpLen && nFollow && bFull;
+ nRest = nOldFullLen - nTmpLen;
+
+ // Das Zeichen wird in der ersten Portion gehalten.
+ // Unbedingt nach Format!
+ SetLen( nFollow );
+
+ if( nRest )
+ {
+ // aExpand ist noch nicht gekuerzt worden, der neue Ofst
+ // ergibt sich durch nRest.
+ xub_StrLen nNextOfst = aExpand.Len() - nRest;
+ XubString aNew( aExpand, nNextOfst, STRING_LEN );
+ aExpand.Erase( nNextOfst, STRING_LEN );
+
+ // Trailingspace et al. !
+ switch( aNew.GetChar( 0 ))
+ {
+ case CH_BREAK : bFull = sal_True;
+ // kein break;
+ case ' ' :
+ case CH_TAB :
+ {
+ aNew.Erase( 0, 1 );
+ ++nNextOfst;
+ break;
+ }
+ default: ;
+ }
+
+ if( aNew.Len() )
+ {
+ // sal_True, weil es ein FollowFeld ist
+ // SwFont *pFont = new SwFont( rInf.GetFont()->GetFnt() );
+ SwFldPortion *pFld = Clone( aNew );
+ if( !pFld->GetFont() )
+ {
+ SwFont *pNewFnt = new SwFont( *rInf.GetFont() );
+ pNewFnt->GoMagic( rInf.GetVsh(), pNewFnt->GetActual() );
+ pFld->SetFont( pNewFnt );
+ }
+ pFld->SetFollow( sal_True );
+ SetHasFollow( sal_True );
+ // In nNextOffset steht bei einem neuangelegten Feld zunaechst
+ // der Offset, an dem es selbst im Originalstring beginnt.
+ // Wenn beim Formatieren ein FollowFeld angelegt wird, wird
+ // der Offset dieses FollowFelds in nNextOffset festgehalten.
+ nNextOffset += nNextOfst;
+ pFld->SetNextOffset( nNextOffset );
+ rInf.SetRest( pFld );
+ }
+ }
+ // 7634 mit ASSERT: bad ascent
+ if( pFnt && nTmpLen )
+ SetAscent( rInf.GetAscent() );
+ }
+
+ if( bFull && !nRest )
+ {
+ // 8788: BreakCut bei Feldern schleift
+ // vgl. BreakCut, Sonderfall Nr.2: Zeichen breiter als Zeile
+ // vgl. 5057 und 6721: Zeichen wird abgeschnitten.
+ if( 1 != GetLen() || Width() != rInf.RealWidth() )
+ {
+ aExpand.Erase();
+ SetLen(0);
+ // 7925: Wenn das Feld komplett auf die naechste Zeile muss
+ // dann wird in BreakUnderflow() ein FormatEOL() auf die
+ // TxtPortion gerufen. Der Text rInf.pTxt ist allerdings noch
+ // manipuliert, hier aber nicht.
+ bEOL = sal_True;
+ }
+ }
+ if( bEOL && rInf.GetLast() )
+ rInf.GetLast()->FormatEOL( rInf );
+ return bFull;
+}
+
+/*************************************************************************
+ * virtual SwFldPortion::Paint()
+ *************************************************************************/
+
+void SwFldPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ SwFontSave aSave( rInf, pFnt );
+
+ ASSERT( GetLen() <= 1, "SwFldPortion::Paint: rest-portion polution?" );
+ if( Width() )
+ {
+ // Dies ist eine freizuegige Auslegung der Hintergrundbelegung ...
+ rInf.DrawViewOpt( *this, POR_FLD );
+ SwExpandPortion::Paint( rInf );
+ }
+}
+
+/*************************************************************************
+ * virtual SwFldPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwFldPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+ rTxt = aExpand;
+ if( !rTxt.Len() && rInf.OnWin() && rInf.GetOpt().IsField() && !HasFollow() )
+ rTxt = ' ';
+ return sal_True;
+}
+
+/*************************************************************************
+ * virtual SwFldPortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwFldPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+ SwFontSave aSave( rInf, pFnt );
+ SwPosSize aSize( SwExpandPortion::GetTxtSize( rInf ) );
+ return aSize;
+}
+
+/*************************************************************************
+ * class SwHiddenPortion
+ *************************************************************************/
+
+SwFldPortion *SwHiddenPortion::Clone(const XubString &rExpand ) const
+{
+ SwFont *pNewFnt;
+ if( 0 != ( pNewFnt = pFnt ) )
+ pNewFnt = new SwFont( *pFnt );
+ return new SwHiddenPortion( rExpand, pNewFnt );
+}
+
+/*************************************************************************
+ * virtual SwHiddenPortion::Paint()
+ *************************************************************************/
+
+void SwHiddenPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ if( Width() )
+ {
+ rInf.DrawViewOpt( *this, POR_HIDDEN );
+ SwExpandPortion::Paint( rInf );
+ }
+}
+
+/*************************************************************************
+ * virtual SwHiddenPortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwHiddenPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+ // Nicht auf IsHidden() abfragen !
+ return SwFldPortion::GetExpTxt( rInf, rTxt );
+}
+
+/*************************************************************************
+ * class SwNumberPortion
+ *************************************************************************/
+
+SwNumberPortion::SwNumberPortion( const XubString &rExpand, SwFont *pFnt,
+ const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst )
+ : SwFldPortion( rExpand, pFnt ), nFixWidth(0), nMinDist( nMinDst )
+{
+ SetWhichPor( POR_NUMBER );
+ SetLeft( bLft );
+ SetHide( sal_False );
+ SetCenter( bCntr );
+}
+
+xub_StrLen SwNumberPortion::GetCrsrOfst( const MSHORT ) const
+{
+ return 0;
+}
+
+SwFldPortion *SwNumberPortion::Clone( const XubString &rExpand ) const
+{
+ SwFont *pNewFnt;
+ if( 0 != ( pNewFnt = pFnt ) )
+ pNewFnt = new SwFont( *pFnt );
+ return new SwNumberPortion( rExpand, pNewFnt, IsLeft(), IsCenter(),
+ nMinDist );
+}
+
+/*************************************************************************
+ * virtual SwNumberPortion::Format()
+ *************************************************************************/
+
+// 5010: Wir sind in der Lage, mehrzeilige NumFelder anzulegen!
+// 3689: Fies ist, wenn man in der Dialogbox soviel Davor-Text
+// eingibt, bis die Zeile ueberlaeuft.
+// Man muss die Fly-Ausweichmanoever beachten!
+
+sal_Bool SwNumberPortion::Format( SwTxtFormatInfo &rInf )
+{
+ SetHide( sal_False );
+ const sal_Bool bFull = SwFldPortion::Format( rInf );
+ SetLen( 0 );
+ nFixWidth = Width();
+ rInf.SetNumDone( !rInf.GetRest() );
+ if( rInf.IsNumDone() )
+ {
+ SetAscent( rInf.GetAscent() );
+ long nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
+ // Ein Vorschlag von Juergen und Volkmar:
+ // Der Textteil hinter der Numerierung sollte immer
+ // mindestens beim linken Rand beginnen.
+ if( nDiff < 0 )
+ nDiff = 0;
+ else if ( nDiff > rInf.X() )
+ nDiff -= rInf.X();
+ if( nDiff < nFixWidth + nMinDist )
+ nDiff = nFixWidth + nMinDist;
+ // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
+ // fieser Sonderfall: FlyFrm liegt in dem Bereich,
+ // den wir uns gerade unter den Nagel reissen wollen.
+ // Die NumberPortion wird als verborgen markiert.
+ if( nDiff > rInf.Width() )
+ {
+ nDiff = rInf.Width();
+ SetHide( sal_True );
+ }
+
+ if( Width() < nDiff )
+ Width( KSHORT(nDiff) );
+ }
+ return bFull;
+}
+
+void SwNumberPortion::FormatEOL( SwTxtFormatInfo &rInf )
+{
+/* Ein FormatEOL deutet daraufhin, dass der folgende Text
+ * nicht mit auf die Zeile passte. Damit die Numerierung mitwandert,
+ * wird diese NumberPortion verborgen.
+ */
+ SetHide( sal_True );
+}
+
+/*************************************************************************
+ * virtual SwNumberPortion::Paint()
+ *************************************************************************/
+
+void SwNumberPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+/* Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
+ * Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
+ */
+ if ( IsHide() && rInf.GetParaPortion() && rInf.GetParaPortion()->GetNext() )
+ {
+ SwLinePortion *pTmp = GetPortion();
+ while ( pTmp && !pTmp->InTxtGrp() )
+ pTmp = pTmp->GetPortion();
+ if ( !pTmp )
+ return;
+ }
+
+ // Dies ist eine freizuegige Auslegung der Hintergrundbelegung ...
+ rInf.DrawViewOpt( *this, POR_NUMBER );
+
+ if( aExpand.Len() )
+ {
+ const SwFont *pTmpFnt = rInf.GetFont();
+ sal_Bool bPaintSpace = ( UNDERLINE_NONE != pTmpFnt->GetUnderline() ||
+ STRIKEOUT_NONE != pTmpFnt->GetStrikeout() ) &&
+ !pTmpFnt->IsWordLineMode();
+ if( bPaintSpace && pFnt )
+ bPaintSpace = ( UNDERLINE_NONE != pFnt->GetUnderline() ||
+ STRIKEOUT_NONE != pFnt->GetStrikeout() ) &&
+ !pFnt->IsWordLineMode();
+
+ SwFontSave aSave( rInf, pFnt );
+
+ if( nFixWidth == Width() )
+ SwExpandPortion::Paint( rInf );
+ else
+ {
+ // logisches const: Width wird wieder zurueckgesetzt
+ SwLinePortion *pThis = (SwLinePortion*)this;
+ const KSHORT nOldWidth = Width();
+ bPaintSpace = bPaintSpace && nFixWidth < nOldWidth;
+ KSHORT nSpaceOffs = nFixWidth;
+ pThis->Width( nFixWidth );
+ if( IsLeft() )
+ SwExpandPortion::Paint( rInf );
+ else
+ {
+ SwTxtPaintInfo aInf( rInf );
+ KSHORT nOffset = nOldWidth - nFixWidth;
+ if( nOffset < nMinDist )
+ nOffset = 0;
+ else
+ {
+ if( IsCenter() )
+ {
+ nOffset /= 2;
+ if( nOffset < nMinDist )
+ nOffset = nOldWidth - nFixWidth - nMinDist;
+ }
+ else
+ nOffset -= nMinDist;
+ }
+ aInf.X( aInf.X() + nOffset );
+ SwExpandPortion::Paint( aInf );
+ if( bPaintSpace )
+ nSpaceOffs += nOffset;
+ }
+ if( bPaintSpace && nOldWidth > nSpaceOffs )
+ {
+ SwTxtPaintInfo aInf( rInf );
+static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
+ aInf.X( aInf.X() + nSpaceOffs );
+ pThis->Width( nOldWidth - nSpaceOffs + 12 );
+ {
+ SwTxtSlotLen aDiffTxt( &aInf, this, sDoubleSpace );
+ aInf.DrawText( *this, aInf.GetLen(), sal_True );
+ }
+ }
+ pThis->Width( nOldWidth );
+ }
+ }
+}
+
+
+/*************************************************************************
+ * class SwBulletPortion
+ *************************************************************************/
+
+SwBulletPortion::SwBulletPortion( const xub_Unicode cBullet, SwFont *pFont,
+ const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst )
+ : SwNumberPortion( XubString( cBullet ), pFont, bLft, bCntr, nMinDst )
+{
+ SetWhichPor( POR_BULLET );
+}
+
+/*************************************************************************
+ * class SwGrfNumPortion
+ *************************************************************************/
+
+#define GRFNUM_SECURE 10
+
+SwGrfNumPortion::SwGrfNumPortion(
+ SwFrm *pFrm,
+ const SvxBrushItem* pGrfBrush,
+ const SwFmtVertOrient* pGrfOrient, const Size& rGrfSize,
+ const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst ) :
+ SwNumberPortion( aEmptyStr, NULL, bLft, bCntr, nMinDst ),
+ pBrush( new SvxBrushItem() ), nId( 0 )
+{
+ SetWhichPor( POR_GRFNUM );
+ SetAnimated( sal_False );
+ bReplace = sal_False;
+ if( pGrfBrush )
+ {
+ *pBrush = *pGrfBrush;
+ SwDocShell *pSh = pFrm->GetShell()->GetDoc()->GetDocShell();
+ const Graphic* pGraph = pGrfBrush->GetGraphic( pSh );
+ if( pGraph )
+ SetAnimated( pGraph->IsAnimated() );
+ else
+ bReplace = sal_True;
+ }
+ if( pGrfOrient )
+ {
+ nYPos = pGrfOrient->GetPos();
+ eOrient = pGrfOrient->GetVertOrient();
+ }
+ else
+ {
+ nYPos = 0;
+ eOrient = VERT_TOP;
+ }
+ Width( rGrfSize.Width() + 2 * GRFNUM_SECURE );
+ nFixWidth = Width();
+ nGrfHeight = rGrfSize.Height() + 2 * GRFNUM_SECURE;
+ Height( nGrfHeight );
+ bNoPaint = sal_False;
+}
+
+SwGrfNumPortion::~SwGrfNumPortion()
+{
+ if ( IsAnimated() )
+ ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( 0, nId );
+ delete pBrush;
+}
+
+void SwGrfNumPortion::StopAnimation( OutputDevice *pOut )
+{
+ if ( IsAnimated() )
+ ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( pOut, nId );
+}
+
+sal_Bool SwGrfNumPortion::Format( SwTxtFormatInfo &rInf )
+{
+ SetHide( sal_False );
+ Width( nFixWidth );
+ const sal_Bool bFull = rInf.Width() < rInf.X() + Width();
+ const sal_Bool bFly = rInf.GetFly() ||
+ ( rInf.GetLast() && rInf.GetLast()->IsFlyPortion() );
+ SetAscent( GetRelPos() > 0 ? GetRelPos() : 0 );
+ if( GetAscent() > Height() )
+ Height( GetAscent() );
+
+ if( bFull )
+ {
+ Width( rInf.Width() - rInf.X() );
+ if( bFly )
+ {
+ SetLen( 0 );
+ SetNoPaint( sal_True );
+ rInf.SetNumDone( sal_False );
+ return sal_True;
+ }
+ }
+ rInf.SetNumDone( sal_True );
+ long nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin();
+ // Ein Vorschlag von Juergen und Volkmar:
+ // Der Textteil hinter der Numerierung sollte immer
+ // mindestens beim linken Rand beginnen.
+ if( nDiff < 0 )
+ nDiff = 0;
+ else if ( nDiff > rInf.X() )
+ nDiff -= rInf.X();
+ if( nDiff < nFixWidth + nMinDist )
+ nDiff = nFixWidth + nMinDist;
+ // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde
+ // fieser Sonderfall: FlyFrm liegt in dem Bereich,
+ // den wir uns gerade unter den Nagel reissen wollen.
+ // Die NumberPortion wird als verborgen markiert.
+ if( nDiff > rInf.Width() )
+ {
+ nDiff = rInf.Width();
+ if( bFly )
+ SetHide( sal_True );
+ }
+
+ if( Width() < nDiff )
+ Width( KSHORT(nDiff) );
+ return bFull;
+}
+
+void SwGrfNumPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ if( DontPaint() )
+ return;
+/* Eine verborgene NumberPortion wird nicht angezeigt, es sei denn, es gibt
+ * Textportions in dieser Zeile oder es gibt ueberhaupt nur eine einzige Zeile.
+ */
+ if ( IsHide() && rInf.GetParaPortion() && rInf.GetParaPortion()->GetNext() )
+ {
+ SwLinePortion *pTmp = GetPortion();
+ while ( pTmp && !pTmp->InTxtGrp() )
+ pTmp = pTmp->GetPortion();
+ if ( !pTmp )
+ return;
+ }
+ Point aPos( rInf.X() + GRFNUM_SECURE, rInf.Y() - GetRelPos() + GRFNUM_SECURE );
+ long nTmpWidth = Max( (long)0, (long)(nFixWidth - 2 * GRFNUM_SECURE) );
+ Size aSize( nTmpWidth, GetGrfHeight() - 2 * GRFNUM_SECURE );
+
+ if( nFixWidth < Width() && !IsLeft() )
+ {
+ KSHORT nOffset = Width() - nFixWidth;
+ if( nOffset < nMinDist )
+ nOffset = 0;
+ else
+ {
+ if( IsCenter() )
+ {
+ nOffset /= 2;
+ if( nOffset < nMinDist )
+ nOffset = Width() - nFixWidth - nMinDist;
+ }
+ else
+ nOffset -= nMinDist;
+ }
+ aPos.X() += nOffset;
+ }
+
+ if( bReplace )
+ {
+ KSHORT nTmpH = GetPortion() ? GetPortion()->GetAscent() : 120;
+ aSize = Size( nTmpH, nTmpH );
+ aPos.Y() = rInf.Y() - nTmpH;
+ }
+ SwRect aTmp( aPos, aSize );
+
+ sal_Bool bDraw = sal_True;
+
+ if ( IsAnimated() )
+ {
+ bDraw = !rInf.GetOpt().IsGraphic();
+ if( !nId )
+ {
+ SetId( long( rInf.GetTxtFrm() ) );
+ rInf.GetTxtFrm()->SetAnimation();
+ }
+ if( aTmp.IsOver( rInf.GetPaintRect() ) && !bDraw )
+ {
+ rInf.NoteAnimation();
+ if( OUTDEV_VIRDEV == rInf.GetOut()->GetOutDevType() )
+ {
+ ( (Graphic*) pBrush->GetGraphic() )->StopAnimation(0,nId);
+ rInf.GetTxtFrm()->GetShell()->InvalidateWindows( aTmp );
+ }
+ else
+ ( (Graphic*) pBrush->GetGraphic() )->StartAnimation(
+ (OutputDevice*)rInf.GetOut(), aPos, aSize, nId );
+ }
+ if( bDraw )
+ ( (Graphic*) pBrush->GetGraphic() )->StopAnimation( 0, nId );
+ }
+
+ if( bDraw && aTmp.HasArea() )
+ DrawGraphic( pBrush, (OutputDevice*)rInf.GetOut(),
+ aTmp, rInf.GetPaintRect(), bReplace ? GRFNUM_REPLACE : GRFNUM_YES );
+}
+
+void SwGrfNumPortion::SetBase( long nLnAscent, long nLnDescent,
+ long nFlyAsc, long nFlyDesc )
+{
+ if ( GetOrient() != VERT_NONE )
+ {
+ SetRelPos( 0 );
+ if ( GetOrient() == VERT_CENTER )
+ SetRelPos( GetGrfHeight() / 2 );
+ else if ( GetOrient() == VERT_TOP )
+ SetRelPos( GetGrfHeight() - GRFNUM_SECURE );
+ else if ( GetOrient() == VERT_BOTTOM )
+ ;
+ else if ( GetOrient() == VERT_CHAR_CENTER )
+ SetRelPos( ( GetGrfHeight() + nLnAscent - nLnDescent ) / 2 );
+ else if ( GetOrient() == VERT_CHAR_TOP )
+ SetRelPos( nLnAscent );
+ else if ( GetOrient() == VERT_CHAR_BOTTOM )
+ SetRelPos( GetGrfHeight() - nLnDescent );
+ else
+ {
+ if( GetGrfHeight() >= nFlyAsc + nFlyDesc )
+ {
+ // wenn ich genauso gross bin wie die Zeile, brauche ich mich
+ // nicht an der Zeile nicht weiter ausrichten, ich lasse
+ // dann auch den max. Ascent der Zeile unveraendert
+
+ SetRelPos( nFlyAsc );
+ }
+ else if ( GetOrient() == VERT_LINE_CENTER )
+ SetRelPos( ( GetGrfHeight() + nFlyAsc - nFlyDesc ) / 2 );
+ else if ( GetOrient() == VERT_LINE_TOP )
+ SetRelPos( nFlyAsc );
+ else if ( GetOrient() == VERT_LINE_BOTTOM )
+ SetRelPos( GetGrfHeight() - nFlyDesc );
+ }
+ }
+}
+void SwTxtFrm::StopAnimation( OutputDevice *pOut )
+{
+ ASSERT( HasAnimation(), "SwTxtFrm::StopAnimation: Which Animation?" );
+ if( HasPara() )
+ {
+ SwLineLayout *pLine = GetPara();
+ while( pLine )
+ {
+ SwLinePortion *pPor = pLine->GetPortion();
+ while( pPor )
+ {
+ if( pPor->IsGrfNumPortion() )
+ ((SwGrfNumPortion*)pPor)->StopAnimation( pOut );
+ // Die Numerierungsportion sitzt immer vor dem ersten Zeichen,
+ // deshalb koennen wir abbrechen, sobald wir eine Portion mit
+ // einer Laenge > 0 erreicht haben.
+ pPor = pPor->GetLen() ? 0 : pPor->GetPortion();
+ }
+ pLine = pLine->GetLen() ? 0 : pLine->GetNext();
+ }
+ }
+}
+
+
diff --git a/sw/source/core/text/porfld.hxx b/sw/source/core/text/porfld.hxx
new file mode 100644
index 000000000000..9570a90921f3
--- /dev/null
+++ b/sw/source/core/text/porfld.hxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * $RCSfile: porfld.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORFLD_HXX
+#define _PORFLD_HXX
+
+#include "swtypes.hxx"
+#include "porexp.hxx"
+#ifndef _FMTORNT_HXX //autogen
+#include <fmtornt.hxx>
+#endif
+
+class SwFont;
+class SvxBrushItem;
+class SwFmtVertOrient;
+class SwFrm;
+
+/*************************************************************************
+ * class SwFldPortion
+ *************************************************************************/
+
+class SwFldPortion : public SwExpandPortion
+{
+ friend class SwTxtFormatter;
+protected:
+ XubString aExpand; // das expandierte Feld
+ SwFont *pFnt; // Fuer mehrzeilige Felder
+ xub_StrLen nNextOffset; // Offset des Follows im Originalstring
+ KSHORT nViewWidth; // Screenbreite fuer leere Felder
+ sal_Bool bFollow : 1; // 2. oder weiterer Teil eines Feldes
+ sal_Bool bLeft : 1; // wird von SwNumberPortion benutzt
+ sal_Bool bHide : 1; // wird von SwNumberPortion benutzt
+ sal_Bool bCenter : 1; // wird von SwNumberPortion benutzt
+ sal_Bool bHasFollow : 1; // geht in der naechsten Zeile weiter
+ sal_Bool bAnimated : 1; // wird von SwGrfNumPortion benutzt
+ sal_Bool bNoPaint : 1; // wird von SwGrfNumPortion benutzt
+ sal_Bool bReplace : 1; // wird von SwGrfNumPortion benutzt
+
+ inline void SetFont( SwFont *pNew ) { pFnt = pNew; }
+ inline const SwFont *GetFont() const { return pFnt; }
+public:
+ SwFldPortion( const XubString &rExpand, SwFont *pFnt = 0 );
+ ~SwFldPortion();
+
+ void TakeNextOffset( const SwFldPortion* pFld );
+
+ inline const XubString &GetExp() const { return aExpand; }
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+
+ // leere Felder sind auch erlaubt
+ virtual SwLinePortion *Compress();
+
+ virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+
+ inline sal_Bool IsFollow() const { return bFollow; }
+ inline void SetFollow( sal_Bool bNew ) { bFollow = bNew; }
+
+ inline sal_Bool IsLeft() const { return bLeft; }
+ inline void SetLeft( sal_Bool bNew ) { bLeft = bNew; }
+
+ inline sal_Bool IsHide() const { return bHide; }
+ inline void SetHide( sal_Bool bNew ) { bHide = bNew; }
+
+ inline sal_Bool IsCenter() const { return bCenter; }
+ inline void SetCenter( sal_Bool bNew ) { bCenter = bNew; }
+
+ inline sal_Bool HasFollow() const { return bHasFollow; }
+ inline void SetHasFollow( sal_Bool bNew ) { bHasFollow = bNew; }
+
+ inline xub_StrLen GetNextOffset() const { return nNextOffset; }
+ inline void SetNextOffset( xub_StrLen nNew ) { nNextOffset = nNew; }
+
+ // Felder-Cloner fuer SplitGlue
+ virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+
+ // Extra-GetTxtSize wegen pFnt
+ virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwHiddenPortion
+ *************************************************************************/
+// Unterscheidung nur fuer's Painten/verstecken.
+
+class SwHiddenPortion : public SwFldPortion
+{
+public:
+ inline SwHiddenPortion( const XubString &rExpand, SwFont *pFnt = 0 )
+ : SwFldPortion( rExpand, pFnt )
+ { SetLen(1); SetWhichPor( POR_HIDDEN ); }
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+
+ // Felder-Cloner fuer SplitGlue
+ virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwNumberPortion
+ *************************************************************************/
+
+class SwNumberPortion : public SwFldPortion
+{
+protected:
+ KSHORT nFixWidth; // vgl. Glues
+ KSHORT nMinDist; // minimaler Abstand zum Text
+public:
+ SwNumberPortion( const XubString &rExpand, SwFont *pFnt,
+ const sal_Bool bLeft, const sal_Bool bCenter, const KSHORT nMinDst );
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual xub_StrLen GetCrsrOfst( const MSHORT nOfst ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+
+ // Felder-Cloner fuer SplitGlue
+ virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+ virtual void FormatEOL( SwTxtFormatInfo &rInf );
+
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwBulletPortion
+ *************************************************************************/
+
+class SwBulletPortion : public SwNumberPortion
+{
+public:
+ SwBulletPortion( const xub_Unicode cCh, SwFont *pFnt, const sal_Bool bLeft,
+ const sal_Bool bCenter, const KSHORT nMinDst );
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwBmpBulletPortion
+ *************************************************************************/
+
+class SwGrfNumPortion : public SwNumberPortion
+{
+ SvxBrushItem* pBrush;
+ long nId; //fuer StopAnimation
+ SwTwips nYPos; //Enthaelt _immer_ die aktuelle RelPos.
+ SwTwips nGrfHeight;
+ SwVertOrient eOrient;
+public:
+ SwGrfNumPortion( SwFrm *pFrm, const SvxBrushItem* pGrfBrush,
+ const SwFmtVertOrient* pGrfOrient, const Size& rGrfSize,
+ const sal_Bool bLeft, const sal_Bool bCenter, const KSHORT nMinDst );
+ ~SwGrfNumPortion();
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+
+ void SetBase( long nLnAscent, long nLnDescent,
+ long nFlyAscent, long nFlyDescent );
+
+ void StopAnimation( OutputDevice *pOut );
+
+ inline sal_Bool IsAnimated() const { return bAnimated; }
+ inline void SetAnimated( sal_Bool bNew ) { bAnimated = bNew; }
+ inline sal_Bool DontPaint() const { return bNoPaint; }
+ inline void SetNoPaint( sal_Bool bNew ) { bNoPaint = bNew; }
+ inline void SetRelPos( SwTwips nNew ) { nYPos = nNew; }
+ inline void SetId( long nNew ) const
+ { ((SwGrfNumPortion*)this)->nId = nNew; }
+ inline SwTwips GetRelPos() const { return nYPos; }
+ inline SwTwips GetGrfHeight() const { return nGrfHeight; }
+ inline SwTwips GetId() const { return nId; }
+ inline SwVertOrient GetOrient() const { return eOrient; }
+
+ OUTPUT_OPERATOR
+};
+
+CLASSIO( SwHiddenPortion )
+CLASSIO( SwNumberPortion )
+CLASSIO( SwBulletPortion )
+CLASSIO( SwGrfNumPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx
new file mode 100644
index 000000000000..0837908ea097
--- /dev/null
+++ b/sw/source/core/text/porfly.cxx
@@ -0,0 +1,585 @@
+/*************************************************************************
+ *
+ * $RCSfile: porfly.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "dcontact.hxx" // SwDrawContact
+#include "dflyobj.hxx" // SwVirtFlyDrawObj
+#include "pam.hxx" // SwPosition
+#include "flyfrm.hxx" // SwFlyInCntFrm
+#include "frmfmt.hxx" // SwFrmFmt
+#include "viewsh.hxx"
+
+#ifndef _SVX_LRSPITEM_HXX //autogen
+#include <svx/lrspitem.hxx>
+#endif
+#ifndef _SVX_ULSPITEM_HXX //autogen
+#include <svx/ulspitem.hxx>
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include <fmtanchr.hxx>
+#endif
+#ifndef _FMTFLCNT_HXX //autogen
+#include <fmtflcnt.hxx>
+#endif
+#ifndef _FMTORNT_HXX //autogen
+#include <fmtornt.hxx>
+#endif
+#ifndef _FRMATR_HXX
+#include <frmatr.hxx>
+#endif
+#include "flyfrms.hxx"
+#include "txatbase.hxx" // SwTxtAttr
+#include "porfly.hxx"
+#include "porlay.hxx" // SetFly
+#include "inftxt.hxx" // SwTxtPaintInfo
+#include "frmsh.hxx"
+
+/*************************************************************************
+ * class SwFlyPortion
+ *
+ * Wir erwarten ein framelokales SwRect !
+ *************************************************************************/
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwFlyPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+void SwFlyPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+}
+
+/*************************************************************************
+ * virtual SwFlyPortion::Format()
+ *************************************************************************/
+sal_Bool SwFlyPortion::Format( SwTxtFormatInfo &rInf )
+{
+ ASSERT( Fix() >= rInf.X(), "SwFlyPortion::Format: rush hour" );
+ // 8537: Tabs muessen expandiert werden.
+ if( rInf.GetLastTab() )
+ ((SwLinePortion*)rInf.GetLastTab())->FormatEOL( rInf );
+
+ // Der Glue wird aufgespannt.
+ rInf.GetLast()->FormatEOL( rInf );
+#ifdef USED
+ long nFirstDiff;
+
+ if( !Fix() )
+ {
+ nFirstDiff = rInf.Left() - long( rInf.First() );
+ if( rInf.GetLineStart() )
+ {
+ if( nFirstDiff < 0 )
+ nFirstDiff = 0;
+ }
+ else
+ {
+ if( nFirstDiff > 0 )
+ nFirstDiff = 0;
+ else
+ nFirstDiff = -nFirstDiff;
+ }
+ nFirstDiff += rInf.GetTxtFrm()->Prt().Left();
+ }
+ else
+ nFirstDiff = 0;
+ PrtWidth( (Fix() - rInf.X()) + PrtWidth() + nFirstDiff );
+#else
+ PrtWidth( (Fix() - rInf.X()) + PrtWidth() );
+#endif
+ if( !Width() )
+ {
+ ASSERT( Width(), "+SwFlyPortion::Format: a fly is a fly is a fly" );
+ Width(1);
+ }
+
+ // Restaurierung
+ rInf.SetFly( 0 );
+ rInf.Width( rInf.RealWidth() );
+ rInf.GetParaPortion()->SetFly( sal_True );
+
+ // trailing blank:
+ if( rInf.GetIdx() < rInf.GetTxt().Len() && 1 < rInf.GetIdx()
+ && !rInf.GetRest()
+ && ' ' == rInf.GetChar( rInf.GetIdx() )
+ && ' ' != rInf.GetChar( rInf.GetIdx() - 1 )
+ && ( !rInf.GetLast() || !rInf.GetLast()->IsBreakPortion() ) )
+ {
+ SetBlankWidth( rInf.GetTxtSize( ' ' ).Width() );
+ SetLen( 1 );
+ }
+
+ const KSHORT nNewWidth = rInf.X() + PrtWidth();
+ if( rInf.Width() <= nNewWidth )
+ {
+ Truncate();
+ if( nNewWidth > rInf.Width() )
+ {
+ PrtWidth( nNewWidth - rInf.Width() );
+ SetFixWidth( PrtWidth() );
+ }
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+ * virtual SwFlyCntPortion::Format()
+ *************************************************************************/
+sal_Bool SwFlyCntPortion::Format( SwTxtFormatInfo &rInf )
+{
+ sal_Bool bFull = rInf.Width() < rInf.X() + PrtWidth();
+
+ if( bFull )
+ {
+ // 3924: wenn die Zeile voll ist und der zeichengebundene Frame am
+ // Anfang der Zeile steht.
+ // 5157: nicht wenn einem Fly ausgewichen werden kann!
+ if( !rInf.X() && !rInf.GetFly() )
+ {
+ Width( rInf.Width() );
+ bFull = sal_False; // Damit Notizen noch in dieser Zeile landen
+ }
+ else
+ {
+ if( !rInf.GetFly() )
+ rInf.SetNewLine( sal_True );
+ Width(0);
+ SetAscent(0);
+ SetLen(0);
+ return bFull;
+ }
+ }
+
+
+ rInf.GetParaPortion()->SetFly( sal_True );
+ return bFull;
+}
+
+/*************************************************************************
+ * SwTxtFrm::MoveFlyInCnt() haengt jetzt die zeichengebundenen Objekte
+ * innerhalb des angegebenen Bereichs um, damit koennen diese vom Master
+ * zum Follow oder umgekehrt wandern.
+ *************************************************************************/
+void SwTxtFrm::MoveFlyInCnt( SwTxtFrm *pNew, xub_StrLen nStart, xub_StrLen nEnd )
+{
+ SwDrawObjs *pObjs;
+ if ( 0 != (pObjs = GetDrawObjs()) )
+ {
+ for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i )
+ {
+ SdrObject *pO = (*pObjs)[MSHORT(i)];
+ if ( pO->IsWriterFlyFrame() )
+ {
+ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
+ if( pFly->IsFlyInCntFrm() )
+ {
+ const SwFmtAnchor &rAnch = pFly->GetFmt()->GetAnchor();
+ const SwPosition *pPos = rAnch.GetCntntAnchor();
+ xub_StrLen nIdx = pPos->nContent.GetIndex();
+ if ( nIdx >= nStart && nEnd > nIdx )
+ {
+ RemoveFly( pFly );
+ pNew->AppendFly( pFly );
+ --i;
+ }
+ }
+ }
+ else
+ {
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pO);
+ const SwFmtAnchor &rAnch = pContact->GetFmt()->GetAnchor();
+ if ( FLY_IN_CNTNT == rAnch.GetAnchorId() )
+ {
+ const SwPosition *pPos = rAnch.GetCntntAnchor();
+ xub_StrLen nIdx = pPos->nContent.GetIndex();
+ if ( nIdx >= nStart && nEnd > nIdx )
+ {
+ RemoveDrawObj( pContact );
+ pNew->AppendDrawObj( pContact );
+ --i;
+ }
+ }
+ }
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtFrm::CalcFlyPos()
+ *************************************************************************/
+xub_StrLen SwTxtFrm::CalcFlyPos( SwFrmFmt* pSearch )
+{
+ SwpHints* pHints = GetTxtNode()->GetpSwpHints();
+ ASSERT( pHints, "CalcFlyPos: Why me?" );
+ if( !pHints )
+ return STRING_LEN;
+ SwTxtAttr* pFound = NULL;
+ for( MSHORT i = 0; i < pHints->Count(); i++)
+ {
+ SwTxtAttr *pHt = pHints->GetHt( i );
+ if( RES_TXTATR_FLYCNT == pHt->Which() )
+ {
+ SwFrmFmt* pFrmFmt = pHt->GetFlyCnt().GetFrmFmt();
+ if( pFrmFmt == pSearch )
+ pFound = pHt;
+ }
+ }
+ ASSERT( pHints, "CalcFlyPos: Not Found!" );
+ if( !pFound )
+ return STRING_LEN;
+ return *pFound->GetStart();
+}
+
+/*************************************************************************
+ * virtual SwFlyCntPortion::Paint()
+ *************************************************************************/
+void SwFlyCntPortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ if( bDraw )
+ {
+ if( !((SwDrawContact*)pContact)->GetAnchor() )
+ {
+ Point aAnchorPos =
+ ((SwDrawContact*)pContact)->GetMaster()->GetAnchorPos();
+ ((SwDrawContact*)pContact)->ConnectToLayout();
+ ((SwDrawContact*)pContact)->GetMaster()->SetAnchorPos( aAnchorPos );
+ }
+ }
+ else
+ {
+ // Baseline-Ausgabe !
+ // 7922: Bei CompletePaint alles painten
+ if( (GetFlyFrm()->IsCompletePaint() ||
+ GetFlyFrm()->Frm().IsOver( rInf.GetPaintRect() )) &&
+ SwFlyFrm::IsPaint( (SdrObject*)GetFlyFrm()->GetVirtDrawObj(),
+ GetFlyFrm()->GetShell() ))
+ {
+ SwRect aRect( GetFlyFrm()->Frm() );
+ if( !GetFlyFrm()->IsCompletePaint() )
+ aRect._Intersection( rInf.GetPaintRect() );
+
+ GetFlyFrm()->Paint( aRect );
+ // Es hilft alles nichts, im zeichengebundenen Frame kann wer weiss
+ // was am OutputDevice eingestellt sein, wir muessen unseren Font
+ // wieder hineinselektieren. Dass wir im const stehen, soll uns
+ // daran nicht hindern:
+ ((SwTxtPaintInfo&)rInf).SelectFont();
+ rInf.SelectOut();
+ }
+ }
+}
+
+/*************************************************************************
+ * SwFlyCntPortion::SwFlyCntPortion()
+ *
+ * Es werden die Masze vom pFly->OutRect() eingestellt.
+ * Es erfolgt ein SetBase() !
+ *************************************************************************/
+SwFlyCntPortion::SwFlyCntPortion( SwFlyInCntFrm *pFly, const Point &rBase,
+ long nLnAscent, long nLnDescent, long nFlyAsc, long nFlyDesc, sal_Bool bQuick ) :
+ pContact( pFly ),
+ bDraw( sal_False ),
+ bMax( sal_False ),
+ nAlign( 0 )
+{
+ ASSERT( pFly, "SwFlyCntPortion::SwFlyCntPortion: no SwFlyInCntFrm!" );
+ nLineLength = 1;
+ sal_uInt8 nFlags = SETBASE_ULSPACE | SETBASE_INIT;
+ if( bQuick )
+ nFlags |= SETBASE_QUICK;
+ SetBase( rBase, nLnAscent, nLnDescent, nFlyAsc, nFlyDesc, nFlags );
+ SetWhichPor( POR_FLYCNT );
+}
+SwFlyCntPortion::SwFlyCntPortion( SwDrawContact *pDrawContact,
+ const Point &rBase, long nLnAscent, long nLnDescent,
+ long nFlyAsc, long nFlyDesc, sal_Bool bQuick ) :
+ pContact( pDrawContact ),
+ bDraw( sal_True ),
+ bMax( sal_False ),
+ nAlign( 0 )
+{
+ ASSERT( pDrawContact, "SwFlyCntPortion::SwFlyCntPortion: no SwDrawContact!" );
+ if( !pDrawContact->GetAnchor() )
+ {
+ if( bQuick )
+ {
+ Point aAnchorPos = pDrawContact->GetMaster()->GetAnchorPos();
+ pDrawContact->ConnectToLayout();
+ pDrawContact->GetMaster()->SetAnchorPos( aAnchorPos );
+ }
+ else
+ pDrawContact->ConnectToLayout();
+ }
+ nLineLength = 1;
+ sal_uInt8 nFlags = SETBASE_ULSPACE | SETBASE_INIT;
+ if( bQuick )
+ nFlags |= SETBASE_QUICK;
+ SetBase( rBase, nLnAscent, nLnDescent, nFlyAsc, nFlyDesc, nFlags );
+ SetWhichPor( POR_FLYCNT );
+}
+
+const SwFrmFmt *SwFlyCntPortion::GetFrmFmt() const
+{
+ if( bDraw )
+ return GetDrawContact()->GetFmt();
+ else
+ return GetFlyFrm()->GetFmt();
+}
+
+/*************************************************************************
+ * SwFlyCntPortion::SetBase()
+ *
+ * Nach dem Setzen des RefPoints muss der Ascent neu berechnet werden,
+ * da er von der RelPos abhaengt.
+ * pFly->GetRelPos().Y() bezeichnet die relative Position zur Baseline.
+ * Bei 0 liegt der obere Rand des FlyCnt auf der Baseline der Zeile.
+ *************************************************************************/
+
+void SwFlyCntPortion::SetBase( const Point &rBase, long nLnAscent,
+ long nLnDescent, long nFlyAsc, long nFlyDesc, sal_uInt8 nFlags )
+{
+ Point aBase( rBase );
+ const SwFrmFmt* pFmt = GetFrmFmt();
+ const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+ const SwVertOrient eOri = rVert.GetVertOrient();
+ const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace();
+ const SvxULSpaceItem &rULSpace = pFmt->GetULSpace();
+
+ //Die vertikale Position wird berechnet, die relative horizontale
+ //Position ist stets 0.
+
+ Point aRelPos;
+ SdrObject *pSdrObj;
+ SwRect aBoundRect;
+ long nOldWidth;
+ if( bDraw )
+ {
+ pSdrObj = GetDrawContact()->GetMaster();
+ aBoundRect = pSdrObj->GetBoundRect();
+ }
+ else
+ {
+ aBoundRect = GetFlyFrm()->Frm();
+ nOldWidth = aBoundRect.Width();
+ }
+
+ if( nFlags & SETBASE_ULSPACE )
+ aBase.X() += rLRSpace.GetLeft();
+ aBase.Y() += rULSpace.GetUpper();
+ if( bDraw )
+ {
+ if( nFlags & SETBASE_ULSPACE )
+ aBase.X() += pSdrObj->GetSnapRect().Left() - aBoundRect.Left();
+ aBase.Y() += pSdrObj->GetSnapRect().Top() - aBoundRect.Top();
+ }
+ aBoundRect.Left( aBoundRect.Left() - rLRSpace.GetLeft() );
+ aBoundRect.Width( aBoundRect.Width() + rLRSpace.GetRight() );
+ aBoundRect.Top( aBoundRect.Top() - rULSpace.GetUpper() );
+ aBoundRect.Height( aBoundRect.Height() + rULSpace.GetLower() );
+
+ if ( eOri == VERT_NONE )
+ aRelPos.Y() = rVert.GetPos();
+ else
+ {
+ aRelPos.Y() = 0;
+ if ( eOri == VERT_CENTER )
+ aRelPos.Y() -= aBoundRect.Height() / 2;
+ else if ( eOri == VERT_TOP )
+ aRelPos.Y() -= aBoundRect.Height();
+ else if ( eOri == VERT_BOTTOM )
+ ;
+ else if ( eOri == VERT_CHAR_CENTER )
+ aRelPos.Y() -= ( aBoundRect.Height() + nLnAscent - nLnDescent ) / 2;
+ else if ( eOri == VERT_CHAR_TOP )
+ aRelPos.Y() -= nLnAscent;
+ else if ( eOri == VERT_CHAR_BOTTOM )
+ aRelPos.Y() += nLnDescent - aBoundRect.Height();
+ else
+ {
+ if( aBoundRect.Height() >= nFlyAsc + nFlyDesc )
+ {
+ // wenn ich genauso gross bin wie die Zeile, brauche ich mich
+ // nicht an der Zeile nicht weiter ausrichten, ich lasse
+ // dann auch den max. Ascent der Zeile zunaechst unveraendert
+ aRelPos.Y() -= nFlyAsc;
+ if ( eOri == VERT_LINE_CENTER )
+ SetAlign( 2 );
+ else if ( eOri == VERT_LINE_TOP )
+ SetAlign( 1 );
+ else if ( eOri == VERT_LINE_BOTTOM )
+ SetAlign( 3 );
+ }
+ else if ( eOri == VERT_LINE_CENTER )
+ {
+ aRelPos.Y() -= ( aBoundRect.Height() +nFlyAsc -nFlyDesc ) / 2;
+ SetAlign( 2 );
+ }
+ else if ( eOri == VERT_LINE_TOP )
+ {
+ aRelPos.Y() -= nFlyAsc;
+ SetAlign( 1 );
+ }
+ else if ( eOri == VERT_LINE_BOTTOM )
+ {
+ aRelPos.Y() += nFlyDesc - aBoundRect.Height();
+ SetAlign( 3 );
+ }
+ }
+ }
+
+ if( nFlags & SETBASE_INIT && aRelPos.Y() < 0 && nFlyAsc < -aRelPos.Y() )
+ aBase.Y() -= nFlyAsc + aRelPos.Y();
+
+ if( bDraw )
+ {
+ if( !( nFlags & SETBASE_QUICK ) )
+ {
+ if( rVert.GetPos() != aRelPos.Y() && eOri != VERT_NONE )
+ {
+ // Das aRelPos wird gepflegt, weil sonst SwDrawContact::_Changed
+ // auf die Idee kommen koennte, auf VERT_NONE umzuschalten.
+ SwFmtVertOrient aVert( rVert );
+ aVert.SetPos( aRelPos.Y() );
+ ((SwFrmFmt*)pFmt)->LockModify();
+ ((SwFrmFmt*)pFmt)->SetAttr( aVert );
+ ((SwFrmFmt*)pFmt)->UnlockModify();
+ }
+ Point aDiff = aRelPos + aBase - pSdrObj->GetSnapRect().TopLeft();
+ pSdrObj->ImpSetAnchorPos( aBase );
+ pSdrObj->Move( Size( aDiff.X(), aDiff.Y() ) );
+ }
+ }
+ else
+ {
+ if ( !(nFlags & SETBASE_QUICK) && (aBase != GetFlyFrm()->GetRefPoint() ||
+ aRelPos != GetFlyFrm()->GetCurRelPos()) )
+ {
+ GetFlyFrm()->SetRefPoint( aBase, aRelPos );
+ if( nOldWidth != GetFlyFrm()->Frm().Width() )
+ {
+ aBoundRect = GetFlyFrm()->Frm();
+ aBoundRect.Left( aBoundRect.Left() - rLRSpace.GetLeft() );
+ aBoundRect.Width( aBoundRect.Width() + rLRSpace.GetRight() );
+ aBoundRect.Top( aBoundRect.Top() - rULSpace.GetUpper() );
+ aBoundRect.Height( aBoundRect.Height() + rULSpace.GetLower() );
+ }
+ }
+ ASSERT( GetFlyFrm()->Frm().Height(),
+ "SwFlyCntPortion::SetBase: flyfrm has an invalid height" );
+ }
+ aRef = aBase;
+ SvLSize( aBoundRect.SSize() );
+ if( Height() )
+ {
+ if ( aRelPos.Y() < 0 )
+ {
+ nAscent = Abs( int( aRelPos.Y() ) );
+ if( nAscent > Height() )
+ Height( nAscent );
+ }
+ else
+ {
+ nAscent = 0;
+ Height( Height() + int( aRelPos.Y() ) );
+ }
+ }
+ else
+ {
+ Height( 1 );
+ nAscent = 0;
+ }
+}
+
+/*************************************************************************
+ * virtual SwFlyCntPortion::GetFlyCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwFlyCntPortion::GetFlyCrsrOfst( const KSHORT nOfst,
+ const Point &rPoint, SwPosition *pPos, const SwCrsrMoveState* pCMS ) const
+{
+ // Da die FlyCnt nicht an der Seite haengen, wird ihr
+ // GetCrsrOfst() nicht gerufen. Um die Layoutseite
+ // von unnoetiger Verwaltung zu entlasten, ruft der Absatz
+ // das GetCrsrOfst des FlyFrm, wenn es erforderlich ist.
+ Point aPoint( rPoint );
+ if( !pPos || bDraw || !( GetFlyFrm()->GetCrsrOfst( pPos, aPoint, pCMS ) ) )
+ return SwLinePortion::GetCrsrOfst( nOfst );
+ else
+ return 0;
+}
+
+/*************************************************************************
+ * virtual SwFlyCntPortion::GetCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwFlyCntPortion::GetCrsrOfst( const KSHORT nOfst ) const
+{
+ // ASSERT( !this, "SwFlyCntPortion::GetCrsrOfst: use GetFlyCrsrOfst()" );
+ return SwLinePortion::GetCrsrOfst( nOfst );
+}
+
diff --git a/sw/source/core/text/porfly.hxx b/sw/source/core/text/porfly.hxx
new file mode 100644
index 000000000000..896741ca997a
--- /dev/null
+++ b/sw/source/core/text/porfly.hxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * $RCSfile: porfly.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORFLY_HXX
+#define _PORFLY_HXX
+
+#include "porglue.hxx"
+
+class SwDrawContact;
+class SwFrmFmt;
+class SwFlyInCntFrm;
+
+/*************************************************************************
+ * class SwFlyPortion
+ *************************************************************************/
+
+class SwFlyPortion : public SwFixPortion
+{
+ KSHORT nBlankWidth;
+public:
+ inline SwFlyPortion( const SwRect &rFlyRect )
+ : SwFixPortion(rFlyRect), nBlankWidth( 0 ) { SetWhichPor( POR_FLY ); }
+ inline const KSHORT GetBlankWidth( ) const { return nBlankWidth; }
+ inline void SetBlankWidth( const KSHORT nNew ) { nBlankWidth = nNew; }
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+#ifdef OLDRECYCLE
+ virtual sal_Bool MayRecycle() const;
+#endif
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwFlyCntPortion
+ *************************************************************************/
+
+#define SETBASE_NOFLAG 0
+#define SETBASE_QUICK 1
+#define SETBASE_ULSPACE 2
+#define SETBASE_INIT 4
+
+class SwFlyCntPortion : public SwLinePortion
+{
+ void *pContact; // bDraw ? DrawContact : FlyInCntFrm
+ Point aRef; // Relativ zu diesem Point wird die AbsPos berechnet.
+ sal_Bool bDraw : 1; // DrawContact?
+ sal_Bool bMax : 1; // Zeilenausrichtung und Hoehe == Zeilenhoehe
+ sal_uInt8 nAlign : 3; // Zeilenausrichtung? Nein, oben, mitte, unten
+ virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+
+public:
+ SwFlyCntPortion( SwFlyInCntFrm *pFly, const Point &rBase, long nAscent,
+ long nDescent, long nFlyAsc, long nFlyDesc, sal_Bool bQuick = sal_False );
+ SwFlyCntPortion( SwDrawContact *pDrawContact, const Point &rBase,
+ long nAscent, long nDescent, long nFlyAsc, long nFlyDesc,
+ sal_Bool bQuick = sal_False );
+ inline const Point& GetRefPoint() const { return aRef; }
+ inline SwFlyInCntFrm *GetFlyFrm() { return (SwFlyInCntFrm*)pContact; }
+ inline const SwFlyInCntFrm *GetFlyFrm() const
+ { return (SwFlyInCntFrm*)pContact; }
+ inline SwDrawContact *GetDrawContact() { return (SwDrawContact*)pContact; }
+ inline const SwDrawContact* GetDrawContact() const
+ { return (SwDrawContact*)pContact; }
+ inline const sal_Bool IsDraw() const { return bDraw; }
+ inline const sal_Bool IsMax() const { return bMax; }
+ inline const sal_uInt8 GetAlign() const { return nAlign; }
+ inline void SetAlign( sal_uInt8 nNew ) { nAlign = nNew; }
+ inline void SetMax( sal_Bool bNew ) { bMax = bNew; }
+ void SetBase( const Point &rBase, long nLnAscent, long nLnDescent,
+ long nFlyAscent, long nFlyDescent, sal_uInt8 nFlags );
+ const SwFrmFmt *GetFrmFmt() const;
+ xub_StrLen GetFlyCrsrOfst( const KSHORT nOfst, const Point &rPoint,
+ SwPosition *pPos, const SwCrsrMoveState* pCMS ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ OUTPUT_OPERATOR
+};
+
+CLASSIO( SwFlyPortion )
+CLASSIO( SwFlyCntPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porftn.hxx b/sw/source/core/text/porftn.hxx
new file mode 100644
index 000000000000..9c2c92597388
--- /dev/null
+++ b/sw/source/core/text/porftn.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * $RCSfile: porftn.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORFTN_HXX
+#define _PORFTN_HXX
+
+#include "porfld.hxx"
+
+class SwTxtFrm;
+class SwTxtFtn;
+
+/*************************************************************************
+ * class SwFtnPortion
+ *************************************************************************/
+
+class SwFtnPortion : public SwExpandPortion
+{
+ XubString aExpand;
+ SwTxtFrm *pFrm; // um im Dtor RemoveFtn rufen zu koennen.
+ SwTxtFtn *pFtn;
+ KSHORT nOrigHeight;
+public:
+ SwFtnPortion( const XubString &rExpand, SwTxtFrm *pFrm, SwTxtFtn *pFtn,
+ KSHORT nOrig = KSHRT_MAX );
+ void ClearFtn();
+ inline KSHORT& Orig() { return nOrigHeight; }
+
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwFtnNumPortion
+ *************************************************************************/
+
+class SwFtnNumPortion : public SwNumberPortion
+{
+public:
+ inline SwFtnNumPortion( const XubString &rExpand, SwFont *pFnt )
+ : SwNumberPortion( rExpand, pFnt, sal_True, sal_False, 0 )
+ { SetWhichPor( POR_FTNNUM ); }
+ sal_Bool DiffFont( SwFont* pFont );
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwQuoVadisPortion
+ *************************************************************************/
+
+class SwQuoVadisPortion : public SwFldPortion
+{
+ XubString aErgo;
+public:
+ SwQuoVadisPortion( const XubString &rExp, const XubString& rStr );
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+
+ inline void SetNumber( const XubString& rStr ) { aErgo = rStr; }
+ inline const XubString &GetQuoTxt() const { return aExpand; }
+
+ // Felder-Cloner fuer SplitGlue
+ virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwErgoSumPortion
+ *************************************************************************/
+
+class SwErgoSumPortion : public SwFldPortion
+{
+public:
+ SwErgoSumPortion( const XubString &rExp, const XubString& rStr );
+ virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+
+ // Felder-Cloner fuer SplitGlue
+ virtual SwFldPortion *Clone( const XubString &rExpand ) const;
+ OUTPUT_OPERATOR
+};
+
+CLASSIO( SwFtnPortion )
+CLASSIO( SwFtnNumPortion )
+CLASSIO( SwQuoVadisPortion )
+CLASSIO( SwErgoSumPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porglue.cxx b/sw/source/core/text/porglue.cxx
new file mode 100644
index 000000000000..e83af0cafbc4
--- /dev/null
+++ b/sw/source/core/text/porglue.cxx
@@ -0,0 +1,363 @@
+/*************************************************************************
+ *
+ * $RCSfile: porglue.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PRECOMPILED
+#include "core_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#include "swrect.hxx"
+#include "paratr.hxx" // pTabStop, ADJ*
+#include "viewopt.hxx" // SwViewOptions
+#include "errhdl.hxx" // ASSERT
+#include "segmentc.hxx"
+
+#include "txtcfg.hxx"
+#include "porglue.hxx"
+#include "inftxt.hxx"
+#include "porlay.hxx" // SwParaPortion, SetFull
+#include "porfly.hxx" // SwParaPortion, SetFull
+
+/*************************************************************************
+ * class SwGluePortion
+ *************************************************************************/
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwGluePortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+SwGluePortion::SwGluePortion( const KSHORT nInitFixWidth )
+ : nFixWidth( nInitFixWidth )
+{
+ PrtWidth( nFixWidth );
+ SetWhichPor( POR_GLUE );
+}
+
+/*************************************************************************
+ * virtual SwGluePortion::GetCrsrOfst()
+ *************************************************************************/
+
+xub_StrLen SwGluePortion::GetCrsrOfst( const KSHORT nOfst ) const
+{
+ if( !GetLen() || nOfst > GetLen() || !Width() )
+ return SwLinePortion::GetCrsrOfst( nOfst );
+ else
+ return nOfst / (Width() / GetLen());
+}
+
+/*************************************************************************
+ * virtual SwGluePortion::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwGluePortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
+{
+ if( 1 >= GetLen() || rInf.GetLen() > GetLen() || !Width() || !GetLen() )
+ return SwPosSize(*this);
+ else
+ return SwPosSize( (Width() / GetLen()) * rInf.GetLen(), Height() );
+}
+
+/*************************************************************************
+ * virtual SwGluePortion::GetExpTxt()
+ *************************************************************************/
+
+sal_Bool SwGluePortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const
+{
+ if( GetLen() && rInf.OnWin() &&
+ rInf.GetOpt().IsBlank() && rInf.IsNoSymbol() )
+ {
+ rTxt.Fill( GetLen(), CH_BULLET );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+/*************************************************************************
+ * virtual SwGluePortion::Paint()
+ *************************************************************************/
+
+void SwGluePortion::Paint( const SwTxtPaintInfo &rInf ) const
+{
+ if( !GetLen() )
+ return;
+
+ if( rInf.GetFont()->IsPaintBlank() )
+ {
+ XubString aTxt;
+ aTxt.Fill( GetFixWidth() / GetLen(), ' ' );
+ SwTxtPaintInfo aInf( rInf, aTxt );
+ aInf.DrawText( *this, aTxt.Len(), sal_True );
+ }
+
+ if( rInf.OnWin() && rInf.GetOpt().IsBlank() && rInf.IsNoSymbol() )
+ {
+#ifndef PRODUCT
+ const xub_Unicode cChar = rInf.GetChar( rInf.GetIdx() );
+ ASSERT( CH_BLANK == cChar || CH_BULLET == cChar,
+ "SwGluePortion::Paint: blank expected" );
+#endif
+ if( 1 == GetLen() )
+ {
+ String aBullet( CH_BULLET, RTL_TEXTENCODING_MS_1252 );
+ SwPosSize aBulletSize( rInf.GetTxtSize( aBullet ) );
+ Point aPos( rInf.GetPos() );
+ aPos.X() += (Width()/2) - (aBulletSize.Width()/2);
+ SwTxtPaintInfo aInf( rInf, aBullet );
+ aInf.SetPos( aPos );
+ SwTxtPortion aBulletPor;
+ aBulletPor.Width( aBulletSize.Width() );
+ aBulletPor.Height( aBulletSize.Height() );
+ aBulletPor.SetAscent( GetAscent() );
+ aInf.DrawText( aBulletPor, aBullet.Len(), sal_True );
+ }
+ else
+ {
+ SwTxtSlotLen aSlot( &rInf, this );
+ rInf.DrawText( *this, rInf.GetLen(), sal_True );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwGluePortion::MoveGlue()
+ *************************************************************************/
+
+void SwGluePortion::MoveGlue( SwGluePortion *pTarget, const short nPrtGlue )
+{
+ short nPrt = Min( nPrtGlue, GetPrtGlue() );
+ if( 0 < nPrt )
+ {
+ pTarget->AddPrtWidth( nPrt );
+ SubPrtWidth( nPrt );
+ }
+}
+
+/*************************************************************************
+ * void SwGluePortion::Join()
+ *************************************************************************/
+
+void SwGluePortion::Join( SwGluePortion *pVictim )
+{
+ // Die GluePortion wird ausgesogen und weggespuelt ...
+ AddPrtWidth( pVictim->PrtWidth() );
+ SetLen( pVictim->GetLen() + GetLen() );
+ if( Height() < pVictim->Height() )
+ Height( pVictim->Height() );
+
+ AdjFixWidth();
+ Cut( pVictim );
+ delete pVictim;
+}
+
+/*************************************************************************
+ * class SwFixPortion
+ *************************************************************************/
+
+// Wir erwarten ein framelokales SwRect !
+SwFixPortion::SwFixPortion( const SwRect &rRect )
+ :SwGluePortion( KSHORT(rRect.Width()) ), nFix( KSHORT(rRect.Left()) )
+{
+ Height( KSHORT(rRect.Height()) );
+ SetWhichPor( POR_FIX );
+}
+
+SwFixPortion::SwFixPortion(const KSHORT nFixWidth, const KSHORT nFixPos)
+ : SwGluePortion(nFixWidth), nFix(nFixPos)
+{
+ SetWhichPor( POR_FIX );
+}
+
+/*************************************************************************
+ * class SwMarginPortion
+ *************************************************************************/
+
+SwMarginPortion::SwMarginPortion( const KSHORT nFixWidth )
+ :SwGluePortion( nFixWidth )
+{
+ SetWhichPor( POR_MARGIN );
+}
+
+#ifdef OLDRECYCLE
+
+sal_Bool SwMarginPortion::MayRecycle() const { return sal_False; }
+
+#endif
+
+/*************************************************************************
+ * SwMarginPortion::AdjustRight()
+ *
+ * In der umschliessenden Schleife werden alle Portions durchsucht,
+ * dabei werden erst die am Ende liegenden GluePortions verarbeitet.
+ * Das Ende wird nach jeder Schleife nach vorne verlegt, bis keine
+ * GluePortions mehr vorhanden sind.
+ * Es werden immer GluePortion-Paare betrachtet (pLeft und pRight),
+ * wobei Textportions zwischen pLeft und pRight hinter pRight verschoben
+ * werden, wenn pRight genuegend Glue besitzt. Bei jeder Verschiebung
+ * wandert ein Teil des Glues von pRight nach pLeft.
+ * Im naechsten Schleifendurchlauf ist pLeft das pRight und das Spiel
+ * beginnt von vorne.
+ *************************************************************************/
+
+void SwMarginPortion::AdjustRight()
+{
+ SwGluePortion *pRight = 0;
+ while( pRight != this )
+ {
+
+ // 1) Wir suchen den linken Glue
+ SwLinePortion *pPos = (SwLinePortion*)this;
+ SwGluePortion *pLeft = 0;
+ while( pPos )
+ {
+ DBG_LOOP;
+ if( pPos->InFixMargGrp() )
+ pLeft = (SwGluePortion*)pPos;
+ pPos = pPos->GetPortion();
+ if( pPos == pRight)
+ pPos = 0;
+ }
+
+ // Zwei nebeneinander liegende FlyPortions verschmelzen
+ if( pRight && pLeft->GetPortion() == pRight )
+ {
+ pRight->MoveAllGlue( pLeft );
+ pRight = 0;
+ }
+ KSHORT nRightGlue = pRight && 0 < pRight->GetPrtGlue()
+ ? KSHORT(pRight->GetPrtGlue()) : 0;
+ // 2) linken und rechten Glue ausgleichen
+ // Bei Tabs haengen wir nix um ...
+ if( pLeft && nRightGlue && !pRight->InTabGrp() )
+ {
+ // pPrev ist die Portion, die unmittelbar vor pRight liegt.
+ SwLinePortion *pPrev = pRight->FindPrevPortion( pLeft );
+
+ if ( pRight->IsFlyPortion() && pRight->GetLen() )
+ {
+ SwFlyPortion *pFly = (SwFlyPortion *)pRight;
+ if ( pFly->GetBlankWidth() < nRightGlue )
+ {
+ // Hier entsteht eine neue TxtPortion, die dass zuvor
+ // vom Fly verschluckte Blank reaktiviert.
+ nRightGlue -= pFly->GetBlankWidth();
+ pFly->SubPrtWidth( pFly->GetBlankWidth() );
+ pFly->SetLen( 0 );
+ SwTxtPortion *pNewPor = new SwTxtPortion;
+ pNewPor->SetLen( 1 );
+ pNewPor->Height( pFly->Height() );
+ pNewPor->Width( pFly->GetBlankWidth() );
+ pFly->Insert( pNewPor );
+ }
+ else
+ pPrev = pLeft;
+ }
+ while( pPrev != pLeft )
+ {
+ DBG_LOOP;
+
+ if( pPrev->PrtWidth() >= nRightGlue || pPrev->InHyphGrp() )
+ {
+ // Die Portion, die vor pRight liegt kann nicht
+ // verschoben werden, weil kein Glue mehr vorhanden ist.
+ // Wir fuehren die Abbruchbedingung herbei:
+ pPrev = pLeft;
+ }
+ else
+ {
+ nRightGlue -= pPrev->PrtWidth();
+ // pPrev wird hinter pRight verschoben.
+ // Dazu wird der Gluewert zwischen pRight und pLeft
+ // ausgeglichen.
+ pRight->MoveGlue( pLeft, short( pPrev->PrtWidth() ) );
+ // Jetzt wird die Verkettung gerichtet.
+ SwLinePortion *pPrevPrev = pPrev->FindPrevPortion( pLeft );
+ pPrevPrev->SetPortion( pRight );
+ pPrev->SetPortion( pRight->GetPortion() );
+ pRight->SetPortion( pPrev );
+ if ( pPrev->GetPortion() && pPrev->InTxtGrp()
+ && pPrev->GetPortion()->IsHolePortion() )
+ {
+ SwHolePortion *pHolePor =
+ (SwHolePortion*)pPrev->GetPortion();
+ if ( !pHolePor->GetPortion() ||
+ !pHolePor->GetPortion()->InFixMargGrp() )
+ {
+ pPrev->AddPrtWidth( pHolePor->GetBlankWidth() );
+ pPrev->SetLen( pPrev->GetLen() + 1 );
+ pPrev->SetPortion( pHolePor->GetPortion() );
+ delete pHolePor;
+ }
+ }
+ pPrev = pPrevPrev;
+ }
+ }
+ }
+ // Wenn es keinen linken Glue mehr gibt, wird die Abbruchbedingung
+ // herbeigefuehrt.
+ pRight = pLeft ? pLeft : (SwGluePortion*)this;
+ }
+}
+
+
+
diff --git a/sw/source/core/text/porglue.hxx b/sw/source/core/text/porglue.hxx
new file mode 100644
index 000000000000..8a2e0753c0cc
--- /dev/null
+++ b/sw/source/core/text/porglue.hxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * $RCSfile: porglue.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORGLUE_HXX
+#define _PORGLUE_HXX
+
+
+//#include <stdlib.h>
+
+#include "porlin.hxx"
+
+class SwRect;
+struct SwPosition;
+
+/*************************************************************************
+ * class SwGluePortion
+ *************************************************************************/
+
+class SwGluePortion : public SwLinePortion
+{
+private:
+ KSHORT nFixWidth;
+public:
+ SwGluePortion( const KSHORT nInitFixWidth );
+
+ void Join( SwGluePortion *pVictim );
+
+ inline short GetPrtGlue() const;
+ inline KSHORT GetFixWidth() const { return nFixWidth; }
+ inline void SetFixWidth( const KSHORT nNew ) { nFixWidth = nNew; }
+ void MoveGlue( SwGluePortion *pTarget, const short nPrtGlue );
+ inline void MoveAllGlue( SwGluePortion *pTarget );
+ inline void MoveHalfGlue( SwGluePortion *pTarget );
+ inline void AdjFixWidth();
+#ifdef OLDRECYCLE
+ virtual sal_Bool MayRecycle() const;
+#endif
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual xub_StrLen GetCrsrOfst( const KSHORT nOfst ) const;
+ virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const;
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwFixPortion
+ *************************************************************************/
+
+class SwFixPortion : public SwGluePortion
+{
+ KSHORT nFix; // der Width-Offset in der Zeile
+public:
+ SwFixPortion( const SwRect &rFlyRect );
+ SwFixPortion( const KSHORT nFixWidth, const KSHORT nFixPos );
+ inline void Fix( const KSHORT nNewFix ) { nFix = nNewFix; }
+ inline KSHORT Fix() const { return nFix; }
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwMarginPortion
+ *************************************************************************/
+
+class SwMarginPortion : public SwGluePortion
+{
+public:
+ SwMarginPortion( const KSHORT nFixWidth );
+ void AdjustRight();
+#ifdef OLDRECYCLE
+ virtual sal_Bool MayRecycle() const;
+#endif
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * inline SwGluePortion::GetPrtGlue()
+ *************************************************************************/
+
+inline short SwGluePortion::GetPrtGlue() const
+{ return Width() - nFixWidth; }
+
+/*************************************************************************
+ * inline SwGluePortion::AdjFixWidth()
+ * Die FixWidth darf niemals groesser sein als die Gesamtbreite !
+ *************************************************************************/
+
+inline void SwGluePortion::AdjFixWidth()
+{
+ if( nFixWidth > PrtWidth() )
+ nFixWidth = PrtWidth();
+}
+
+/*************************************************************************
+ * inline SwGluePortion::MoveGlue()
+ *************************************************************************/
+
+inline void SwGluePortion::MoveAllGlue( SwGluePortion *pTarget )
+{
+ MoveGlue( pTarget, GetPrtGlue() );
+}
+
+/*************************************************************************
+ * inline SwGluePortion::MoveHalfGlue()
+ *************************************************************************/
+
+inline void SwGluePortion::MoveHalfGlue( SwGluePortion *pTarget )
+{
+ MoveGlue( pTarget, GetPrtGlue() / 2 );
+}
+
+CLASSIO( SwGluePortion )
+CLASSIO( SwFixPortion )
+CLASSIO( SwMarginPortion )
+
+
+#endif
+
diff --git a/sw/source/core/text/porhyph.hxx b/sw/source/core/text/porhyph.hxx
new file mode 100644
index 000000000000..474a261edb81
--- /dev/null
+++ b/sw/source/core/text/porhyph.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * $RCSfile: porhyph.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-19 00:08:25 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _PORHYPH_HXX
+#define _PORHYPH_HXX
+
+#include "porexp.hxx"
+
+/*************************************************************************
+ * class SwHyphPortion
+ *************************************************************************/
+
+class SwHyphPortion : public SwExpandPortion
+{
+public:
+ inline SwHyphPortion( ) { SetWhichPor( POR_HYPH ); }
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwHyphStrPortion
+ *************************************************************************/
+
+class SwHyphStrPortion : public SwHyphPortion
+{
+ XubString aExpand;
+public:
+ inline SwHyphStrPortion( const XubString &rStr );
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwSoftHyphPortion
+ *************************************************************************/
+
+class SwSoftHyphPortion : public SwHyphPortion
+{
+ sal_Bool bExpand;
+ KSHORT nViewWidth;
+ KSHORT nHyphWidth;
+
+public:
+ SwSoftHyphPortion();
+ virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const;
+ virtual SwLinePortion *Compress();
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ virtual sal_Bool Format( SwTxtFormatInfo &rInf );
+ virtual void FormatEOL( SwTxtFormatInfo &rInf );
+ inline void SetExpand( const sal_Bool bNew ) { bExpand = bNew; }
+ sal_Bool IsExpand() const { return bExpand; }
+
+ virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const;
+ OUTPUT_OPERATOR
+};
+
+/*************************************************************************
+ * class SwSoftHyphStrPortion
+ *************************************************************************/
+
+class SwSoftHyphStrPortion : public SwHyphStrPortion
+{
+public:
+ SwSoftHyphStrPortion( const XubString &rStr );
+ virtual void Paint( const SwTxtPaintInfo &rInf ) const;
+ OUTPUT_OPERATOR
+};
+
+inline SwHyphStrPortion::SwHyphStrPortion( const XubString &rStr )
+ : aExpand( rStr )
+{
+ aExpand += '-';
+ SetWhichPor( POR_HYPHSTR );
+}
+
+CLASSIO( SwHyphPortion )
+CLASSIO( SwHyphStrPortion )
+CLASSIO( SwSoftHyphPortion )
+CLASSIO( SwSoftHyphStrPortion )
+
+
+#endif
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
new file mode 100644
index 000000000000..1742b744fa55
--- /dev/null
+++ b/sw/source/core/text/porlay.cxx
@@ -0,0 +1,504 @@