1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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();
35 for( i
= nTmpPos
; i
< nEnd
; ++i
)
37 const sal_Unicode aChar
= rTxt
.GetChar( i
);
38 if( CH_TAB
!= aChar
&& ' ' != aChar
)
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();
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();
75 // For follows sal_False of course
76 if( pFrm
->GetFollow() )
78 pLay
= pLay
->GetNext();
83 pLay
= pLay
->GetNext();
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();
101 long nWidth
= pFrm
->Prt().Width();
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();
117 if( rLine
.GetStart() == nTxtStart
)
118 nStart
= rLine
.GetLineStart();
122 if( ((SwTxtCursor
&)rLine
).GetCharRect( &aRect
, nTxtStart
) )
123 nStart
= aRect
.Left();
125 nStart
= rLine
.GetLineStart();
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
147 SwFrmSwapper
aSwapper( pFrm
, sal_True
);
149 SwTxtSizeInfo
aInf( (SwTxtFrm
*)pFrm
);
150 SwTxtCursor
aLine( (SwTxtFrm
*)pFrm
, &aInf
);
154 if( ((SwTxtCursor
&)aLine
).GetCharRect( &aRect
, nChar
) )
157 pFrm
->SwitchHorizontalToVertical( aRect
);
159 nStt
= (aRect
.*fnRect
->fnGetLeft
)();
162 nStt
= aLine
.GetLineStart();
165 return nStt
- (pFrm
->Frm().*fnRect
->fnGetLeft
)();
167 if( ((SwTxtCursor
&)aLine
).GetCharRect( &aRect
, nChar
+1 ) )
170 pFrm
->SwitchHorizontalToVertical( aRect
);
172 nNext
= (aRect
.*fnRect
->fnGetLeft
)();
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
)
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
;
199 pPam
= new SwPaM( *pPam
);
202 SwIndex
&rContent
= pPam
->GetPoint()->nContent
;
203 rContent
.Assign( (SwTxtNode
*)pTxtFrm
->GetTxtNode(), nPos
);
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
);
216 sal_Bool bFirstLine
= sal_True
;
219 if( aLine
.GetCurr()->GetLen() )
221 xub_StrLen nPos
= aLine
.GetTxtStart();
222 // Do NOT include the blanks/tabs from the first line
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
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 )
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;
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
)
293 // At first we only return +1, -1 and 0
294 if( nLeft
== nFirst
)
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;
317 SwTxtSizeInfo
aNxtInf( (SwTxtFrm
*)pNextFrm
);
318 SwTxtCursor
aNxtLine( (SwTxtFrm
*)pNextFrm
, &aNxtInf
);
319 nNextIndent
= GetLineStart( aNxtLine
);
326 nNextIndent
= GetLineStart( aLine
);
331 if( nNextIndent
<= GetLineStart( aLine
) )
334 const Point
aPoint( nNextIndent
, aLine
.Y() );
335 rFndPos
= aLine
.GetCrsrOfst( 0, aPoint
, sal_False
);
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
) ) )
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 ) ) )
357 return aLine
.GetCharRect( &aRect
, rFndPos
)
358 ? KSHORT( aRect
.Left() - pFrm
->Frm().Left() - pFrm
->Prt().Left())
364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */