/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include // GetSpaces #include #include // SwTxtFrminfo #include // 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(i) ); if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar ) return static_cast(i + 1); } return static_cast(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; }