Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / sw / source / core / text / frminf.cxx
blobc8f13c27b589bd36f3eeb01e1f3596c9c025da1a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <pam.hxx> // GetSpaces
21 #include <frminf.hxx> // SwTxtFrminfo
22 #include <itrtxt.hxx> // SwTxtMargin
24 /*************************************************************************
25 * SwTxtMargin::GetTxtStart()
26 *************************************************************************/
28 xub_StrLen SwTxtMargin::GetTxtStart() const
30 const XubString &rTxt = GetInfo().GetTxt();
31 const xub_StrLen nTmpPos = nStart;
32 const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
33 xub_StrLen i;
35 for( i = nTmpPos; i < nEnd; ++i )
37 const sal_Unicode aChar = rTxt.GetChar( i );
38 if( CH_TAB != aChar && ' ' != aChar )
39 return i;
41 return i;
44 /*************************************************************************
45 * SwTxtMargin::GetTxtEnd()
46 *************************************************************************/
48 xub_StrLen SwTxtMargin::GetTxtEnd() const
50 const XubString &rTxt = GetInfo().GetTxt();
51 const xub_StrLen nTmpPos = nStart;
52 const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
53 long i;
54 for( i = nEnd - 1; i >= nTmpPos; --i )
56 sal_Unicode aChar = rTxt.GetChar( static_cast<xub_StrLen>(i) );
57 if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar )
58 return static_cast<xub_StrLen>(i + 1);
60 return static_cast<xub_StrLen>(i + 1);
63 /*************************************************************************
64 * SwTxtFrmInfo::IsOneLine()
65 *************************************************************************/
67 // Does the paragraph fit into one line?
68 sal_Bool SwTxtFrmInfo::IsOneLine() const
70 const SwLineLayout *pLay = pFrm->GetPara();
71 if( !pLay )
72 return sal_False;
73 else
75 // For follows sal_False of course
76 if( pFrm->GetFollow() )
77 return sal_False;
78 pLay = pLay->GetNext();
79 while( pLay )
81 if( pLay->GetLen() )
82 return sal_False;
83 pLay = pLay->GetNext();
85 return sal_True;
89 /*************************************************************************
90 * SwTxtFrmInfo::IsFilled()
91 *************************************************************************/
93 // Is the line filled for X percent?
94 sal_Bool SwTxtFrmInfo::IsFilled( const sal_uInt8 nPercent ) const
96 const SwLineLayout *pLay = pFrm->GetPara();
97 if( !pLay )
98 return sal_False;
99 else
101 long nWidth = pFrm->Prt().Width();
102 nWidth *= nPercent;
103 nWidth /= 100;
104 return KSHORT(nWidth) <= pLay->Width();
108 /*************************************************************************
109 * SwTxtFrmInfo::GetLineStart()
110 *************************************************************************/
112 // Where does the text start (without whitespace)? (document global)
113 SwTwips SwTxtFrmInfo::GetLineStart( const SwTxtCursor &rLine ) const
115 xub_StrLen nTxtStart = rLine.GetTxtStart();
116 SwTwips nStart;
117 if( rLine.GetStart() == nTxtStart )
118 nStart = rLine.GetLineStart();
119 else
121 SwRect aRect;
122 if( ((SwTxtCursor&)rLine).GetCharRect( &aRect, nTxtStart ) )
123 nStart = aRect.Left();
124 else
125 nStart = rLine.GetLineStart();
127 return nStart;
131 /*************************************************************************
132 * SwTxtFrmInfo::GetLineStart()
133 *************************************************************************/
135 // Where does the text start (without whitespace)? (relative in the Frame)
136 SwTwips SwTxtFrmInfo::GetLineStart() const
138 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
139 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
140 return GetLineStart( aLine ) - pFrm->Frm().Left() - pFrm->Prt().Left();
143 // Calculates the character's position and returns the middle position
144 SwTwips SwTxtFrmInfo::GetCharPos( xub_StrLen nChar, sal_Bool bCenter ) const
146 SWRECTFN( pFrm )
147 SwFrmSwapper aSwapper( pFrm, sal_True );
149 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
150 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
152 SwTwips nStt, nNext;
153 SwRect aRect;
154 if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar ) )
156 if ( bVert )
157 pFrm->SwitchHorizontalToVertical( aRect );
159 nStt = (aRect.*fnRect->fnGetLeft)();
161 else
162 nStt = aLine.GetLineStart();
164 if( !bCenter )
165 return nStt - (pFrm->Frm().*fnRect->fnGetLeft)();
167 if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar+1 ) )
169 if ( bVert )
170 pFrm->SwitchHorizontalToVertical( aRect );
172 nNext = (aRect.*fnRect->fnGetLeft)();
174 else
175 nNext = aLine.GetLineStart();
177 return (( nNext + nStt ) / 2 ) - (pFrm->Frm().*fnRect->fnGetLeft)();
180 /*************************************************************************
181 * SwTxtFrmInfo::GetSpaces()
182 *************************************************************************/
184 SwPaM *AddPam( SwPaM *pPam, const SwTxtFrm* pTxtFrm,
185 const xub_StrLen nPos, const xub_StrLen nLen )
187 if( nLen )
189 // It could be the first
190 if( pPam->HasMark() )
192 // If the new position is right after the current one, then
193 // simply extend the Pam
194 if( nPos == pPam->GetPoint()->nContent.GetIndex() )
196 pPam->GetPoint()->nContent += nLen;
197 return pPam;
199 pPam = new SwPaM( *pPam );
202 SwIndex &rContent = pPam->GetPoint()->nContent;
203 rContent.Assign( (SwTxtNode*)pTxtFrm->GetTxtNode(), nPos );
204 pPam->SetMark();
205 rContent += nLen;
207 return pPam;
210 // Accumulates the whitespace at line start and end in the Pam
211 void SwTxtFrmInfo::GetSpaces( SwPaM &rPam, sal_Bool bWithLineBreak ) const
213 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
214 SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
215 SwPaM *pPam = &rPam;
216 sal_Bool bFirstLine = sal_True;
217 do {
219 if( aLine.GetCurr()->GetLen() )
221 xub_StrLen nPos = aLine.GetTxtStart();
222 // Do NOT include the blanks/tabs from the first line
223 // in the selection
224 if( !bFirstLine && nPos > aLine.GetStart() )
225 pPam = AddPam( pPam, pFrm, aLine.GetStart(),
226 nPos - aLine.GetStart() );
228 // Do NOT include the blanks/tabs from the last line
229 // in the selection
230 if( aLine.GetNext() )
232 nPos = aLine.GetTxtEnd();
234 if( nPos < aLine.GetEnd() )
236 MSHORT nOff = !bWithLineBreak && CH_BREAK ==
237 aLine.GetInfo().GetChar( aLine.GetEnd() - 1 )
238 ? 1 : 0;
239 pPam = AddPam( pPam, pFrm, nPos, aLine.GetEnd() - nPos - nOff );
243 bFirstLine = sal_False;
245 while( aLine.Next() );
248 /*************************************************************************
249 * SwTxtFrmInfo::IsBullet()
250 *************************************************************************/
252 // Is there a bullet/symbol etc. at the text position?
253 // Fonts: CharSet, SYMBOL und DONTKNOW
254 sal_Bool SwTxtFrmInfo::IsBullet( xub_StrLen nTxtStart ) const
256 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
257 SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
258 aInf.SetIdx( nTxtStart );
259 return aLine.IsSymbol( nTxtStart );
262 /*************************************************************************
263 * SwTxtFrmInfo::GetFirstIndent()
264 *************************************************************************/
266 // Get first line indent
267 // The precondition for a positive or negative first line indent:
268 // All lines (except for the first one) have the same left margin.
269 // We do not want to be so picky and work with a tolerance of TOLERANCE twips.
271 SwTwips SwTxtFrmInfo::GetFirstIndent() const
273 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
274 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
275 const SwTwips nFirst = GetLineStart( aLine );
276 const SwTwips TOLERANCE = 20;
278 if( !aLine.Next() )
279 return 0;
281 SwTwips nLeft = GetLineStart( aLine );
282 while( aLine.Next() )
284 if( aLine.GetCurr()->GetLen() )
286 const SwTwips nCurrLeft = GetLineStart( aLine );
287 if( nLeft + TOLERANCE < nCurrLeft ||
288 nLeft - TOLERANCE > nCurrLeft )
289 return 0;
293 // At first we only return +1, -1 and 0
294 if( nLeft == nFirst )
295 return 0;
296 else
297 if( nLeft > nFirst )
298 return -1;
299 else
300 return +1;
303 /*************************************************************************
304 * SwTxtFrmInfo::GetBigIndent()
305 *************************************************************************/
307 KSHORT SwTxtFrmInfo::GetBigIndent( xub_StrLen& rFndPos,
308 const SwTxtFrm *pNextFrm ) const
310 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
311 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
312 SwTwips nNextIndent = 0;
314 if( pNextFrm )
316 // I'm a single line
317 SwTxtSizeInfo aNxtInf( (SwTxtFrm*)pNextFrm );
318 SwTxtCursor aNxtLine( (SwTxtFrm*)pNextFrm, &aNxtInf );
319 nNextIndent = GetLineStart( aNxtLine );
321 else
323 // I'm multi-line
324 if( aLine.Next() )
326 nNextIndent = GetLineStart( aLine );
327 aLine.Prev();
331 if( nNextIndent <= GetLineStart( aLine ) )
332 return 0;
334 const Point aPoint( nNextIndent, aLine.Y() );
335 rFndPos = aLine.GetCrsrOfst( 0, aPoint, sal_False );
336 if( 1 >= rFndPos )
337 return 0;
339 // Is on front of a non-space
340 const XubString& rTxt = aInf.GetTxt();
341 sal_Unicode aChar = rTxt.GetChar( rFndPos );
342 if( CH_TAB == aChar || CH_BREAK == aChar || ' ' == aChar ||
343 (( CH_TXTATR_BREAKWORD == aChar || CH_TXTATR_INWORD == aChar ) &&
344 aInf.HasHint( rFndPos ) ) )
345 return 0;
347 // and after a space
348 aChar = rTxt.GetChar( rFndPos - 1 );
349 if( CH_TAB != aChar && CH_BREAK != aChar &&
350 ( ( CH_TXTATR_BREAKWORD != aChar && CH_TXTATR_INWORD != aChar ) ||
351 !aInf.HasHint( rFndPos - 1 ) ) &&
352 // More than two Blanks!
353 ( ' ' != aChar || ' ' != rTxt.GetChar( rFndPos - 2 ) ) )
354 return 0;
356 SwRect aRect;
357 return aLine.GetCharRect( &aRect, rFndPos )
358 ? KSHORT( aRect.Left() - pFrm->Frm().Left() - pFrm->Prt().Left())
359 : 0;
364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */