Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <pam.hxx> // GetSpaces
30 : : #include <frminf.hxx> // SwTxtFrminfo
31 : : #include <itrtxt.hxx> // SwTxtMargin
32 : :
33 : : /*************************************************************************
34 : : * SwTxtMargin::GetTxtStart()
35 : : *************************************************************************/
36 : :
37 : 0 : xub_StrLen SwTxtMargin::GetTxtStart() const
38 : : {
39 : 0 : const XubString &rTxt = GetInfo().GetTxt();
40 : 0 : const xub_StrLen nTmpPos = nStart;
41 : 0 : const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
42 : : xub_StrLen i;
43 : :
44 [ # # ]: 0 : for( i = nTmpPos; i < nEnd; ++i )
45 : : {
46 : 0 : const xub_Unicode aChar = rTxt.GetChar( i );
47 [ # # ][ # # ]: 0 : if( CH_TAB != aChar && ' ' != aChar )
48 : 0 : return i;
49 : : }
50 : 0 : return i;
51 : : }
52 : :
53 : : /*************************************************************************
54 : : * SwTxtMargin::GetTxtEnd()
55 : : *************************************************************************/
56 : :
57 : 0 : xub_StrLen SwTxtMargin::GetTxtEnd() const
58 : : {
59 : 0 : const XubString &rTxt = GetInfo().GetTxt();
60 : 0 : const xub_StrLen nTmpPos = nStart;
61 : 0 : const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
62 : : long i;
63 [ # # ]: 0 : for( i = nEnd - 1; i >= nTmpPos; --i )
64 : : {
65 : 0 : xub_Unicode aChar = rTxt.GetChar( static_cast<xub_StrLen>(i) );
66 [ # # ][ # # ]: 0 : if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar )
[ # # ]
67 : 0 : return static_cast<xub_StrLen>(i + 1);
68 : : }
69 : 0 : return static_cast<xub_StrLen>(i + 1);
70 : : }
71 : :
72 : : /*************************************************************************
73 : : * SwTxtFrmInfo::IsOneLine()
74 : : *************************************************************************/
75 : :
76 : : // Does the paragraph fit into one line?
77 : 0 : sal_Bool SwTxtFrmInfo::IsOneLine() const
78 : : {
79 : 0 : const SwLineLayout *pLay = pFrm->GetPara();
80 [ # # ]: 0 : if( !pLay )
81 : 0 : return sal_False;
82 : : else
83 : : {
84 : : // For follows sal_False of course
85 [ # # ]: 0 : if( pFrm->GetFollow() )
86 : 0 : return sal_False;
87 : 0 : pLay = pLay->GetNext();
88 [ # # ]: 0 : while( pLay )
89 : : {
90 [ # # ]: 0 : if( pLay->GetLen() )
91 : 0 : return sal_False;
92 : 0 : pLay = pLay->GetNext();
93 : : }
94 : 0 : return sal_True;
95 : : }
96 : : }
97 : :
98 : : /*************************************************************************
99 : : * SwTxtFrmInfo::IsFilled()
100 : : *************************************************************************/
101 : :
102 : : // Is the line filled for X percent?
103 : 0 : sal_Bool SwTxtFrmInfo::IsFilled( const sal_uInt8 nPercent ) const
104 : : {
105 : 0 : const SwLineLayout *pLay = pFrm->GetPara();
106 [ # # ]: 0 : if( !pLay )
107 : 0 : return sal_False;
108 : : else
109 : : {
110 : 0 : long nWidth = pFrm->Prt().Width();
111 : 0 : nWidth *= nPercent;
112 : 0 : nWidth /= 100;
113 : 0 : return KSHORT(nWidth) <= pLay->Width();
114 : : }
115 : : }
116 : :
117 : : /*************************************************************************
118 : : * SwTxtFrmInfo::GetLineStart()
119 : : *************************************************************************/
120 : :
121 : : // Where does the text start (without whitespace)? (document global)
122 : 0 : SwTwips SwTxtFrmInfo::GetLineStart( const SwTxtCursor &rLine ) const
123 : : {
124 : 0 : xub_StrLen nTxtStart = rLine.GetTxtStart();
125 : : SwTwips nStart;
126 [ # # ]: 0 : if( rLine.GetStart() == nTxtStart )
127 : 0 : nStart = rLine.GetLineStart();
128 : : else
129 : : {
130 : 0 : SwRect aRect;
131 [ # # ][ # # ]: 0 : if( ((SwTxtCursor&)rLine).GetCharRect( &aRect, nTxtStart ) )
132 : 0 : nStart = aRect.Left();
133 : : else
134 [ # # ]: 0 : nStart = rLine.GetLineStart();
135 : : }
136 : 0 : return nStart;
137 : : }
138 : :
139 : :
140 : : /*************************************************************************
141 : : * SwTxtFrmInfo::GetLineStart()
142 : : *************************************************************************/
143 : :
144 : : // Where does the text start (without whitespace)? (relative in the Frame)
145 : 0 : SwTwips SwTxtFrmInfo::GetLineStart() const
146 : : {
147 [ # # ]: 0 : SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
148 [ # # ]: 0 : SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
149 [ # # ][ # # ]: 0 : return GetLineStart( aLine ) - pFrm->Frm().Left() - pFrm->Prt().Left();
150 : : }
151 : :
152 : : // Calculates the character's position and returns the middle position
153 : 0 : SwTwips SwTxtFrmInfo::GetCharPos( xub_StrLen nChar, sal_Bool bCenter ) const
154 : : {
155 [ # # ][ # # ]: 0 : SWRECTFN( pFrm )
[ # # ][ # # ]
[ # # ]
156 [ # # ]: 0 : SwFrmSwapper aSwapper( pFrm, sal_True );
157 : :
158 [ # # ]: 0 : SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
159 [ # # ]: 0 : SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
160 : :
161 : : SwTwips nStt, nNext;
162 : 0 : SwRect aRect;
163 [ # # ][ # # ]: 0 : if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar ) )
164 : : {
165 [ # # ]: 0 : if ( bVert )
166 [ # # ]: 0 : pFrm->SwitchHorizontalToVertical( aRect );
167 : :
168 [ # # ][ # # ]: 0 : nStt = (aRect.*fnRect->fnGetLeft)();
169 : : }
170 : : else
171 [ # # ]: 0 : nStt = aLine.GetLineStart();
172 : :
173 [ # # ]: 0 : if( !bCenter )
174 [ # # ][ # # ]: 0 : return nStt - (pFrm->Frm().*fnRect->fnGetLeft)();
175 : :
176 [ # # ][ # # ]: 0 : if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar+1 ) )
177 : : {
178 [ # # ]: 0 : if ( bVert )
179 [ # # ]: 0 : pFrm->SwitchHorizontalToVertical( aRect );
180 : :
181 [ # # ][ # # ]: 0 : nNext = (aRect.*fnRect->fnGetLeft)();
182 : : }
183 : : else
184 [ # # ]: 0 : nNext = aLine.GetLineStart();
185 : :
186 [ # # ][ # # ]: 0 : return (( nNext + nStt ) / 2 ) - (pFrm->Frm().*fnRect->fnGetLeft)();
[ # # ][ # # ]
187 : : }
188 : :
189 : : /*************************************************************************
190 : : * SwTxtFrmInfo::GetSpaces()
191 : : *************************************************************************/
192 : :
193 : 0 : SwPaM *AddPam( SwPaM *pPam, const SwTxtFrm* pTxtFrm,
194 : : const xub_StrLen nPos, const xub_StrLen nLen )
195 : : {
196 [ # # ]: 0 : if( nLen )
197 : : {
198 : : // It could be the first
199 [ # # ]: 0 : if( pPam->HasMark() )
200 : : {
201 : : // If the new position is right after the current one, then
202 : : // simply extend the Pam
203 [ # # ]: 0 : if( nPos == pPam->GetPoint()->nContent.GetIndex() )
204 : : {
205 : 0 : pPam->GetPoint()->nContent += nLen;
206 : 0 : return pPam;
207 : : }
208 [ # # ]: 0 : pPam = new SwPaM( *pPam );
209 : : }
210 : :
211 : 0 : SwIndex &rContent = pPam->GetPoint()->nContent;
212 [ # # ]: 0 : rContent.Assign( (SwTxtNode*)pTxtFrm->GetTxtNode(), nPos );
213 : 0 : pPam->SetMark();
214 : 0 : rContent += nLen;
215 : : }
216 : 0 : return pPam;
217 : : }
218 : :
219 : : // Accumulates the whitespace at line start and end in the Pam
220 : 0 : void SwTxtFrmInfo::GetSpaces( SwPaM &rPam, sal_Bool bWithLineBreak ) const
221 : : {
222 [ # # ]: 0 : SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
223 [ # # ]: 0 : SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
224 : 0 : SwPaM *pPam = &rPam;
225 : 0 : sal_Bool bFirstLine = sal_True;
226 [ # # ]: 0 : do {
227 : :
228 [ # # ]: 0 : if( aLine.GetCurr()->GetLen() )
229 : : {
230 : 0 : xub_StrLen nPos = aLine.GetTxtStart();
231 : : // Do NOT include the blanks/tabs from the first line
232 : : // in the selection
233 [ # # ][ # # ]: 0 : if( !bFirstLine && nPos > aLine.GetStart() )
[ # # ]
234 : 0 : pPam = AddPam( pPam, pFrm, aLine.GetStart(),
235 [ # # ]: 0 : nPos - aLine.GetStart() );
236 : :
237 : : // Do NOT include the blanks/tabs from the last line
238 : : // in the selection
239 [ # # ]: 0 : if( aLine.GetNext() )
240 : : {
241 : 0 : nPos = aLine.GetTxtEnd();
242 : :
243 [ # # ]: 0 : if( nPos < aLine.GetEnd() )
244 : : {
245 : : MSHORT nOff = !bWithLineBreak && CH_BREAK ==
246 : 0 : aLine.GetInfo().GetChar( aLine.GetEnd() - 1 )
247 [ # # # # ]: 0 : ? 1 : 0;
248 [ # # ]: 0 : pPam = AddPam( pPam, pFrm, nPos, aLine.GetEnd() - nPos - nOff );
249 : : }
250 : : }
251 : : }
252 : 0 : bFirstLine = sal_False;
253 : : }
254 [ # # ][ # # ]: 0 : while( aLine.Next() );
255 : 0 : }
256 : :
257 : : /*************************************************************************
258 : : * SwTxtFrmInfo::IsBullet()
259 : : *************************************************************************/
260 : :
261 : : // Is there a bullet/symbol etc. at the text position?
262 : : // Fonts: CharSet, SYMBOL und DONTKNOW
263 : 0 : sal_Bool SwTxtFrmInfo::IsBullet( xub_StrLen nTxtStart ) const
264 : : {
265 [ # # ]: 0 : SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
266 [ # # ]: 0 : SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
267 : 0 : aInf.SetIdx( nTxtStart );
268 [ # # ][ # # ]: 0 : return aLine.IsSymbol( nTxtStart );
269 : : }
270 : :
271 : : /*************************************************************************
272 : : * SwTxtFrmInfo::GetFirstIndent()
273 : : *************************************************************************/
274 : :
275 : : // Get first line indent
276 : : // The precondition for a positive or negative first line indent:
277 : : // All lines (except for the first one) have the same left margin.
278 : : // We do not want to be so picky and work with a tolerance of TOLERANCE twips.
279 : :
280 : 0 : SwTwips SwTxtFrmInfo::GetFirstIndent() const
281 : : {
282 [ # # ]: 0 : SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
283 [ # # ]: 0 : SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
284 [ # # ]: 0 : const SwTwips nFirst = GetLineStart( aLine );
285 : 0 : const SwTwips TOLERANCE = 20;
286 : :
287 [ # # ][ # # ]: 0 : if( !aLine.Next() )
288 : 0 : return 0;
289 : :
290 [ # # ]: 0 : SwTwips nLeft = GetLineStart( aLine );
291 [ # # ][ # # ]: 0 : while( aLine.Next() )
292 : : {
293 [ # # ]: 0 : if( aLine.GetCurr()->GetLen() )
294 : : {
295 [ # # ]: 0 : const SwTwips nCurrLeft = GetLineStart( aLine );
296 [ # # ][ # # ]: 0 : if( nLeft + TOLERANCE < nCurrLeft ||
297 : : nLeft - TOLERANCE > nCurrLeft )
298 : 0 : return 0;
299 : : }
300 : : }
301 : :
302 : : // At first we only return +1, -1 and 0
303 [ # # ]: 0 : if( nLeft == nFirst )
304 : 0 : return 0;
305 : : else
306 [ # # ]: 0 : if( nLeft > nFirst )
307 : 0 : return -1;
308 : : else
309 [ # # ]: 0 : return +1;
310 : : }
311 : :
312 : : /*************************************************************************
313 : : * SwTxtFrmInfo::GetBigIndent()
314 : : *************************************************************************/
315 : :
316 : 0 : KSHORT SwTxtFrmInfo::GetBigIndent( xub_StrLen& rFndPos,
317 : : const SwTxtFrm *pNextFrm ) const
318 : : {
319 [ # # ]: 0 : SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
320 [ # # ]: 0 : SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
321 : 0 : SwTwips nNextIndent = 0;
322 : :
323 [ # # ]: 0 : if( pNextFrm )
324 : : {
325 : : // I'm a single line
326 [ # # ]: 0 : SwTxtSizeInfo aNxtInf( (SwTxtFrm*)pNextFrm );
327 [ # # ]: 0 : SwTxtCursor aNxtLine( (SwTxtFrm*)pNextFrm, &aNxtInf );
328 [ # # ][ # # ]: 0 : nNextIndent = GetLineStart( aNxtLine );
329 : : }
330 : : else
331 : : {
332 : : // I'm multi-line
333 [ # # ][ # # ]: 0 : if( aLine.Next() )
334 : : {
335 [ # # ]: 0 : nNextIndent = GetLineStart( aLine );
336 [ # # ]: 0 : aLine.Prev();
337 : : }
338 : : }
339 : :
340 [ # # ][ # # ]: 0 : if( nNextIndent <= GetLineStart( aLine ) )
341 : 0 : return 0;
342 : :
343 : 0 : const Point aPoint( nNextIndent, aLine.Y() );
344 [ # # ]: 0 : rFndPos = aLine.GetCrsrOfst( 0, aPoint, sal_False );
345 [ # # ]: 0 : if( 1 >= rFndPos )
346 : 0 : return 0;
347 : :
348 : : // Is on front of a non-space
349 : 0 : const XubString& rTxt = aInf.GetTxt();
350 : 0 : xub_Unicode aChar = rTxt.GetChar( rFndPos );
351 [ # # ][ # # ]: 0 : if( CH_TAB == aChar || CH_BREAK == aChar || ' ' == aChar ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
352 : : (( CH_TXTATR_BREAKWORD == aChar || CH_TXTATR_INWORD == aChar ) &&
353 [ # # ]: 0 : aInf.HasHint( rFndPos ) ) )
354 : 0 : return 0;
355 : :
356 : : // and after a space
357 : 0 : aChar = rTxt.GetChar( rFndPos - 1 );
358 [ # # ][ # # ]: 0 : if( CH_TAB != aChar && CH_BREAK != aChar &&
[ # # ][ # # ]
[ # # # # ]
[ # # ][ # # ]
359 : : ( ( CH_TXTATR_BREAKWORD != aChar && CH_TXTATR_INWORD != aChar ) ||
360 [ # # ]: 0 : !aInf.HasHint( rFndPos - 1 ) ) &&
361 : : // More than two Blanks!
362 : 0 : ( ' ' != aChar || ' ' != rTxt.GetChar( rFndPos - 2 ) ) )
363 : 0 : return 0;
364 : :
365 : 0 : SwRect aRect;
366 [ # # ]: 0 : return aLine.GetCharRect( &aRect, rFndPos )
367 : 0 : ? KSHORT( aRect.Left() - pFrm->Frm().Left() - pFrm->Prt().Left())
368 [ # # ][ # # ]: 0 : : 0;
369 : : }
370 : :
371 : :
372 : :
373 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|