summaryrefslogtreecommitdiff
path: root/sw/source/core/text/frminf.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/text/frminf.cxx')
-rw-r--r--sw/source/core/text/frminf.cxx378
1 files changed, 378 insertions, 0 deletions
diff --git a/sw/source/core/text/frminf.cxx b/sw/source/core/text/frminf.cxx
new file mode 100644
index 000000000000..530c93a51825
--- /dev/null
+++ b/sw/source/core/text/frminf.cxx
@@ -0,0 +1,378 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <pam.hxx> // GetSpaces
+#include <frminf.hxx> // SwTxtFrminfo
+#include <itrtxt.hxx> // SwTxtMargin
+
+/*************************************************************************
+ * SwTxtMargin::GetTxtStart()
+ *************************************************************************/
+
+xub_StrLen SwTxtMargin::GetTxtStart() const
+{
+ const XubString &rTxt = GetInfo().GetTxt();
+ const xub_StrLen nTmpPos = nStart;
+ const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
+ xub_StrLen i;
+
+ for( i = nTmpPos; 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 nTmpPos = nStart;
+ const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
+ long i;
+ for( i = nEnd - 1; i >= nTmpPos; --i )
+ {
+ xub_Unicode aChar = rTxt.GetChar( static_cast<xub_StrLen>(i) );
+ if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar )
+ return static_cast<xub_StrLen>(i + 1);
+ }
+ return static_cast<xub_StrLen>(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
+{
+ xub_StrLen 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
+{
+ SWRECTFN( pFrm )
+ SwFrmSwapper aSwapper( pFrm, sal_True );
+
+ SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
+ SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
+
+ SwTwips nStt, nNext;
+ SwRect aRect;
+ if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar ) )
+ {
+ if ( bVert )
+ pFrm->SwitchHorizontalToVertical( aRect );
+
+ nStt = (aRect.*fnRect->fnGetLeft)();
+ }
+ else
+ nStt = aLine.GetLineStart();
+
+ if( !bCenter )
+ return nStt - (pFrm->Frm().*fnRect->fnGetLeft)();
+
+ if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar+1 ) )
+ {
+ if ( bVert )
+ pFrm->SwitchHorizontalToVertical( aRect );
+
+ nNext = (aRect.*fnRect->fnGetLeft)();
+ }
+ else
+ nNext = aLine.GetLineStart();
+
+ return (( nNext + nStt ) / 2 ) - (pFrm->Frm().*fnRect->fnGetLeft)();
+}
+
+/*************************************************************************
+ * 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;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */