1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: frminf.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <pam.hxx> // GetSpaces
37 #include <frminf.hxx> // SwTxtFrminfo
38 #include <itrtxt.hxx> // SwTxtMargin
40 /*************************************************************************
41 * SwTxtMargin::GetTxtStart()
42 *************************************************************************/
44 xub_StrLen
SwTxtMargin::GetTxtStart() const
46 const XubString
&rTxt
= GetInfo().GetTxt();
47 const xub_StrLen nTmpPos
= nStart
;
48 const xub_StrLen nEnd
= nTmpPos
+ pCurr
->GetLen();
51 for( i
= nTmpPos
; i
< nEnd
; ++i
)
53 const xub_Unicode aChar
= rTxt
.GetChar( i
);
54 if( CH_TAB
!= aChar
&& ' ' != aChar
)
60 /*************************************************************************
61 * SwTxtMargin::GetTxtEnd()
62 *************************************************************************/
64 xub_StrLen
SwTxtMargin::GetTxtEnd() const
66 const XubString
&rTxt
= GetInfo().GetTxt();
67 const xub_StrLen nTmpPos
= nStart
;
68 const xub_StrLen nEnd
= nTmpPos
+ pCurr
->GetLen();
70 for( i
= nEnd
- 1; i
>= nTmpPos
; --i
)
72 xub_Unicode aChar
= rTxt
.GetChar( static_cast<xub_StrLen
>(i
) );
73 if( CH_TAB
!= aChar
&& CH_BREAK
!= aChar
&& ' ' != aChar
)
74 return static_cast<xub_StrLen
>(i
+ 1);
76 return static_cast<xub_StrLen
>(i
+ 1);
79 /*************************************************************************
80 * SwTxtFrmInfo::IsOneLine()
81 *************************************************************************/
83 // Passt der Absatz in eine Zeile?
84 sal_Bool
SwTxtFrmInfo::IsOneLine() const
86 const SwLineLayout
*pLay
= pFrm
->GetPara();
91 // 6575: bei Follows natuerlich sal_False
92 if( pFrm
->GetFollow() )
94 pLay
= pLay
->GetNext();
99 pLay
= pLay
->GetNext();
105 /*************************************************************************
106 * SwTxtFrmInfo::IsFilled()
107 *************************************************************************/
109 // Ist die Zeile zu X% gefuellt?
110 sal_Bool
SwTxtFrmInfo::IsFilled( const sal_uInt8 nPercent
) const
112 const SwLineLayout
*pLay
= pFrm
->GetPara();
117 long nWidth
= pFrm
->Prt().Width();
120 return KSHORT(nWidth
) <= pLay
->Width();
124 /*************************************************************************
125 * SwTxtFrmInfo::GetLineStart()
126 *************************************************************************/
128 // Wo beginnt der Text (ohne whitespaces)? ( Dokument global )
129 SwTwips
SwTxtFrmInfo::GetLineStart( const SwTxtCursor
&rLine
) const
131 xub_StrLen nTxtStart
= rLine
.GetTxtStart();
133 if( rLine
.GetStart() == nTxtStart
)
134 nStart
= rLine
.GetLineStart();
138 if( ((SwTxtCursor
&)rLine
).GetCharRect( &aRect
, nTxtStart
) )
139 nStart
= aRect
.Left();
141 nStart
= rLine
.GetLineStart();
147 /*************************************************************************
148 * SwTxtFrmInfo::GetLineStart()
149 *************************************************************************/
151 // Wo beginnt der Text (ohne whitespaces)? (rel. im Frame)
152 SwTwips
SwTxtFrmInfo::GetLineStart() const
154 SwTxtSizeInfo
aInf( (SwTxtFrm
*)pFrm
);
155 SwTxtCursor
aLine( (SwTxtFrm
*)pFrm
, &aInf
);
156 return GetLineStart( aLine
) - pFrm
->Frm().Left() - pFrm
->Prt().Left();
159 // errechne die Position des Zeichens und gebe die Mittelposition zurueck
160 SwTwips
SwTxtFrmInfo::GetCharPos( xub_StrLen nChar
, sal_Bool bCenter
) const
163 SwFrmSwapper
aSwapper( pFrm
, sal_True
);
165 SwTxtSizeInfo
aInf( (SwTxtFrm
*)pFrm
);
166 SwTxtCursor
aLine( (SwTxtFrm
*)pFrm
, &aInf
);
170 if( ((SwTxtCursor
&)aLine
).GetCharRect( &aRect
, nChar
) )
173 pFrm
->SwitchHorizontalToVertical( aRect
);
175 nStt
= (aRect
.*fnRect
->fnGetLeft
)();
178 nStt
= aLine
.GetLineStart();
181 return nStt
- (pFrm
->Frm().*fnRect
->fnGetLeft
)();
183 if( ((SwTxtCursor
&)aLine
).GetCharRect( &aRect
, nChar
+1 ) )
186 pFrm
->SwitchHorizontalToVertical( aRect
);
188 nNext
= (aRect
.*fnRect
->fnGetLeft
)();
191 nNext
= aLine
.GetLineStart();
193 return (( nNext
+ nStt
) / 2 ) - (pFrm
->Frm().*fnRect
->fnGetLeft
)();
196 /*************************************************************************
197 * SwTxtFrmInfo::GetSpaces()
198 *************************************************************************/
200 SwPaM
*AddPam( SwPaM
*pPam
, const SwTxtFrm
* pTxtFrm
,
201 const xub_StrLen nPos
, const xub_StrLen nLen
)
205 // Es koennte auch der erste sein.
206 if( pPam
->HasMark() )
208 // liegt die neue Position genau hinter der aktuellen, dann
209 // erweiter den Pam einfach
210 if( nPos
== pPam
->GetPoint()->nContent
.GetIndex() )
212 pPam
->GetPoint()->nContent
+= nLen
;
215 pPam
= new SwPaM( *pPam
);
218 SwIndex
&rContent
= pPam
->GetPoint()->nContent
;
219 rContent
.Assign( (SwTxtNode
*)pTxtFrm
->GetTxtNode(), nPos
);
226 // Sammelt die whitespaces am Zeilenbeginn und -ende im Pam
227 void SwTxtFrmInfo::GetSpaces( SwPaM
&rPam
, sal_Bool bWithLineBreak
) const
229 SwTxtSizeInfo
aInf( (SwTxtFrm
*)pFrm
);
230 SwTxtMargin
aLine( (SwTxtFrm
*)pFrm
, &aInf
);
232 sal_Bool bFirstLine
= sal_True
;
235 if( aLine
.GetCurr()->GetLen() )
237 xub_StrLen nPos
= aLine
.GetTxtStart();
238 // Bug 49649: von der ersten Line die Blanks/Tabs NICHT
240 if( !bFirstLine
&& nPos
> aLine
.GetStart() )
241 pPam
= AddPam( pPam
, pFrm
, aLine
.GetStart(),
242 nPos
- aLine
.GetStart() );
244 // Bug 49649: von der letzten Line die Blanks/Tabs NICHT
246 if( aLine
.GetNext() )
248 nPos
= aLine
.GetTxtEnd();
250 if( nPos
< aLine
.GetEnd() )
252 MSHORT nOff
= !bWithLineBreak
&& CH_BREAK
==
253 aLine
.GetInfo().GetChar( aLine
.GetEnd() - 1 )
255 pPam
= AddPam( pPam
, pFrm
, nPos
, aLine
.GetEnd() - nPos
- nOff
);
259 bFirstLine
= sal_False
;
261 while( aLine
.Next() );
264 /*************************************************************************
265 * SwTxtFrmInfo::IsBullet()
266 *************************************************************************/
268 // Ist an der Textposition ein Bullet/Symbol etc?
269 // Fonts: CharSet, SYMBOL und DONTKNOW
270 sal_Bool
SwTxtFrmInfo::IsBullet( xub_StrLen nTxtStart
) const
272 SwTxtSizeInfo
aInf( (SwTxtFrm
*)pFrm
);
273 SwTxtMargin
aLine( (SwTxtFrm
*)pFrm
, &aInf
);
274 aInf
.SetIdx( nTxtStart
);
275 return aLine
.IsSymbol( nTxtStart
);
278 /*************************************************************************
279 * SwTxtFrmInfo::GetFirstIndent()
280 *************************************************************************/
282 // Ermittelt Erstzeileneinzug
283 // Voraussetzung fuer pos. oder neg. EZE ist, dass alle
284 // Zeilen ausser der ersten Zeile den selben linken Rand haben.
285 // Wir wollen nicht so knauserig sein und arbeiten mit einer Toleranz
286 // von TOLERANCE Twips.
290 SwTwips
SwTxtFrmInfo::GetFirstIndent() const
292 SwTxtSizeInfo
aInf( (SwTxtFrm
*)pFrm
);
293 SwTxtCursor
aLine( (SwTxtFrm
*)pFrm
, &aInf
);
294 const SwTwips nFirst
= GetLineStart( aLine
);
298 SwTwips nLeft
= GetLineStart( aLine
);
299 while( aLine
.Next() )
301 if( aLine
.GetCurr()->GetLen() )
303 const SwTwips nCurrLeft
= GetLineStart( aLine
);
304 if( nLeft
+ TOLERANCE
< nCurrLeft
||
305 nLeft
- TOLERANCE
> nCurrLeft
)
310 // Vorerst wird nur +1, -1 und 0 returnt.
311 if( nLeft
== nFirst
)
320 /*************************************************************************
321 * SwTxtFrmInfo::GetBigIndent()
322 *************************************************************************/
324 KSHORT
SwTxtFrmInfo::GetBigIndent( xub_StrLen
& rFndPos
,
325 const SwTxtFrm
*pNextFrm
) const
327 SwTxtSizeInfo
aInf( (SwTxtFrm
*)pFrm
);
328 SwTxtCursor
aLine( (SwTxtFrm
*)pFrm
, &aInf
);
329 SwTwips nNextIndent
= 0;
334 SwTxtSizeInfo
aNxtInf( (SwTxtFrm
*)pNextFrm
);
335 SwTxtCursor
aNxtLine( (SwTxtFrm
*)pNextFrm
, &aNxtInf
);
336 nNextIndent
= GetLineStart( aNxtLine
);
340 // ich bin mehrzeilig
343 nNextIndent
= GetLineStart( aLine
);
348 if( nNextIndent
<= GetLineStart( aLine
) )
351 const Point
aPoint( nNextIndent
, aLine
.Y() );
352 rFndPos
= aLine
.GetCrsrOfst( 0, aPoint
, sal_False
);
356 // steht vor einem "nicht Space"
357 const XubString
& rTxt
= aInf
.GetTxt();
358 xub_Unicode aChar
= rTxt
.GetChar( rFndPos
);
359 if( CH_TAB
== aChar
|| CH_BREAK
== aChar
|| ' ' == aChar
||
360 (( CH_TXTATR_BREAKWORD
== aChar
|| CH_TXTATR_INWORD
== aChar
) &&
361 aInf
.HasHint( rFndPos
) ) )
364 // und hinter einem "Space"
365 aChar
= rTxt
.GetChar( rFndPos
- 1 );
366 if( CH_TAB
!= aChar
&& CH_BREAK
!= aChar
&&
367 ( ( CH_TXTATR_BREAKWORD
!= aChar
&& CH_TXTATR_INWORD
!= aChar
) ||
368 !aInf
.HasHint( rFndPos
- 1 ) ) &&
369 // mehr als 2 Blanks !!
370 ( ' ' != aChar
|| ' ' != rTxt
.GetChar( rFndPos
- 2 ) ) )
374 return aLine
.GetCharRect( &aRect
, rFndPos
)
375 ? KSHORT( aRect
.Left() - pFrm
->Frm().Left() - pFrm
->Prt().Left())