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 : :
30 : : #include "hintids.hxx"
31 : : #include "ndtxt.hxx"
32 : : #include "frmfmt.hxx"
33 : : #include "paratr.hxx"
34 : : #include "flyfrm.hxx"
35 : : #include "pam.hxx"
36 : : #include "swselectionlist.hxx"
37 : : #include <sortedobjs.hxx>
38 : : #include <editeng/protitem.hxx>
39 : : #include <editeng/adjitem.hxx>
40 : : #include <editeng/lspcitem.hxx>
41 : : #include <editeng/lrspitem.hxx>
42 : : #include <frmatr.hxx>
43 : : #include <pagedesc.hxx> // SwPageDesc
44 : : #include <tgrditem.hxx>
45 : : #include <IDocumentSettingAccess.hxx>
46 : : #include <pagefrm.hxx>
47 : :
48 : : #include "itrtxt.hxx"
49 : : #include "txtfrm.hxx"
50 : : #include "flyfrms.hxx"
51 : : #include "porglue.hxx" // SwFlyCnt
52 : : #include "porfld.hxx" // SwFldPortion::IsFollow()
53 : : #include "porfly.hxx" // GetFlyCrsrOfst()
54 : : #include "pordrop.hxx"
55 : : #include "crstate.hxx" // SwCrsrMoveState
56 : : #include <pormulti.hxx> // SwMultiPortion
57 : : // #i111284#
58 : : #include <numrule.hxx>
59 : :
60 : : // Nicht reentrant !!!
61 : : // wird in GetCharRect gesetzt und im UnitUp/Down ausgewertet.
62 : : sal_Bool SwTxtCursor::bRightMargin = sal_False;
63 : :
64 : :
65 : : /*************************************************************************
66 : : * lcl_GetCharRectInsideField
67 : : *
68 : : * After calculating the position of a character during GetCharRect
69 : : * this function allows to find the coordinates of a position (defined
70 : : * in pCMS->pSpecialPos) inside a special portion (e.g., a field)
71 : : *************************************************************************/
72 : 0 : void lcl_GetCharRectInsideField( SwTxtSizeInfo& rInf, SwRect& rOrig,
73 : : const SwCrsrMoveState& rCMS,
74 : : const SwLinePortion& rPor )
75 : : {
76 : : OSL_ENSURE( rCMS.pSpecialPos, "Information about special pos missing" );
77 : :
78 [ # # ][ # # ]: 0 : if ( rPor.InFldGrp() && ((SwFldPortion&)rPor).GetExp().Len() )
[ # # ]
79 : : {
80 : 0 : const sal_uInt16 nCharOfst = rCMS.pSpecialPos->nCharOfst;
81 : 0 : sal_uInt16 nFldIdx = 0;
82 : 0 : sal_uInt16 nFldLen = 0;
83 : :
84 : 0 : const XubString* pString = 0;
85 : 0 : const SwLinePortion* pPor = &rPor;
86 : 0 : do
87 : : {
88 [ # # ]: 0 : if ( pPor->InFldGrp() )
89 : : {
90 : 0 : pString = &((SwFldPortion*)pPor)->GetExp();
91 : 0 : nFldLen = pString->Len();
92 : : }
93 : : else
94 : : {
95 : 0 : pString = 0;
96 : 0 : nFldLen = 0;
97 : : }
98 : :
99 [ # # ][ # # ]: 0 : if ( ! pPor->GetPortion() || nFldIdx + nFldLen > nCharOfst )
[ # # ]
100 : 0 : break;
101 : :
102 : 0 : nFldIdx = nFldIdx + nFldLen;
103 : 0 : rOrig.Pos().X() += pPor->Width();
104 : 0 : pPor = pPor->GetPortion();
105 : :
106 : : } while ( sal_True );
107 : :
108 : : OSL_ENSURE( nCharOfst >= nFldIdx, "Request of position inside field failed" );
109 : 0 : sal_uInt16 nLen = nCharOfst - nFldIdx + 1;
110 : :
111 [ # # ]: 0 : if ( pString )
112 : : {
113 : : // get script for field portion
114 : 0 : rInf.GetFont()->SetActual( SwScriptInfo::WhichFont( 0, pString, 0 ) );
115 : :
116 : 0 : xub_StrLen nOldLen = pPor->GetLen();
117 : 0 : ((SwLinePortion*)pPor)->SetLen( nLen - 1 );
118 : 0 : const SwTwips nX1 = pPor->GetLen() ?
119 [ # # ][ # # ]: 0 : pPor->GetTxtSize( rInf ).Width() :
[ # # ]
120 [ # # ]: 0 : 0;
121 : :
122 : 0 : SwTwips nX2 = 0;
123 [ # # ]: 0 : if ( rCMS.bRealWidth )
124 : : {
125 : 0 : ((SwLinePortion*)pPor)->SetLen( nLen );
126 : 0 : nX2 = pPor->GetTxtSize( rInf ).Width();
127 : : }
128 : :
129 : 0 : ((SwLinePortion*)pPor)->SetLen( nOldLen );
130 : :
131 : 0 : rOrig.Pos().X() += nX1;
132 : : rOrig.Width( ( nX2 > nX1 ) ?
133 : : ( nX2 - nX1 ) :
134 [ # # ]: 0 : 1 );
135 : : }
136 : : }
137 : : else
138 : : {
139 : : // special cases: no common fields, e.g., graphic number portion,
140 : : // FlyInCntPortions, Notes
141 [ # # ][ # # ]: 0 : rOrig.Width( rCMS.bRealWidth && rPor.Width() ? rPor.Width() : 1 );
142 : : }
143 : 0 : }
144 : :
145 : : // #i111284#
146 : : namespace {
147 : 94315 : bool AreListLevelIndentsApplicableAndLabelAlignmentActive( const SwTxtNode& rTxtNode )
148 : : {
149 : 94315 : bool bRet( false );
150 : :
151 [ + + ]: 94315 : if ( rTxtNode.AreListLevelIndentsApplicable() )
152 : : {
153 : : const SwNumFmt& rNumFmt =
154 : 579 : rTxtNode.GetNumRule()->Get( static_cast<sal_uInt16>(rTxtNode.GetActualListLevel()) );
155 [ + + ]: 579 : if ( rNumFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
156 : : {
157 : 351 : bRet = true;
158 : : }
159 : : }
160 : :
161 : 94315 : return bRet;
162 : : }
163 : : } // end of anonymous namespace
164 : :
165 : : /*************************************************************************
166 : : * SwTxtMargin::CtorInitTxtMargin()
167 : : *************************************************************************/
168 : 94315 : void SwTxtMargin::CtorInitTxtMargin( SwTxtFrm *pNewFrm, SwTxtSizeInfo *pNewInf )
169 : : {
170 : 94315 : CtorInitTxtIter( pNewFrm, pNewInf );
171 : :
172 : 94315 : pInf = pNewInf;
173 : 94315 : GetInfo().SetFont( GetFnt() );
174 : 94315 : const SwTxtNode *pNode = pFrm->GetTxtNode();
175 : :
176 : 94315 : const SvxLRSpaceItem &rSpace = pFrm->GetTxtNode()->GetSwAttrSet().GetLRSpace();
177 : : // #i95907#
178 : : // #i111284#
179 : : const bool bListLevelIndentsApplicableAndLabelAlignmentActive(
180 : 94315 : AreListLevelIndentsApplicableAndLabelAlignmentActive( *(pFrm->GetTxtNode()) ) );
181 : :
182 : : //
183 : : // Carefully adjust the text formatting ranges.
184 : : //
185 : : // This whole area desperately needs some rework. There are
186 : : // quite a couple of values that need to be considered:
187 : : // 1. paragraph indent
188 : : // 2. paragraph first line indent
189 : : // 3. numbering indent
190 : : // 4. numbering spacing to text
191 : : // 5. paragraph border
192 : : // Note: These values have already been used during calculation
193 : : // of the printing area of the paragraph.
194 : 94315 : const int nLMWithNum = pNode->GetLeftMarginWithNum( sal_True );
195 [ - + ]: 94315 : if ( pFrm->IsRightToLeft() )
196 : : {
197 : : // this calculation is identical this the calculation for L2R layout - see below
198 : 0 : nLeft = pFrm->Frm().Left() +
199 : 0 : pFrm->Prt().Left() +
200 : : nLMWithNum -
201 : 0 : pNode->GetLeftMarginWithNum( sal_False ) -
202 : : // #i95907#
203 : : // #i111284#
204 : : // rSpace.GetLeft() +
205 : : // rSpace.GetTxtLeft();
206 : : ( bListLevelIndentsApplicableAndLabelAlignmentActive
207 : : ? 0
208 [ # # ]: 0 : : ( rSpace.GetLeft() - rSpace.GetTxtLeft() ) );
209 : : }
210 : : else
211 : : {
212 : : // #i95907#
213 : : // #i111284#
214 [ + + + + ]: 188279 : if ( bListLevelIndentsApplicableAndLabelAlignmentActive ||
[ + + ]
215 : 93964 : !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) )
216 : : {
217 : : // this calculation is identical this the calculation for R2L layout - see above
218 : 94259 : nLeft = pFrm->Frm().Left() +
219 : 94259 : pFrm->Prt().Left() +
220 : : nLMWithNum -
221 : 94259 : pNode->GetLeftMarginWithNum( sal_False ) -
222 : : // #i95907#
223 : : // #i111284#
224 : : ( bListLevelIndentsApplicableAndLabelAlignmentActive
225 : : ? 0
226 [ + + ]: 94259 : : ( rSpace.GetLeft() - rSpace.GetTxtLeft() ) );
227 : : }
228 : : else
229 : : {
230 : 56 : nLeft = pFrm->Frm().Left() +
231 : 56 : Max( long( rSpace.GetTxtLeft() + nLMWithNum ),
232 : 112 : pFrm->Prt().Left() );
233 : : }
234 : : }
235 : :
236 : 94315 : nRight = pFrm->Frm().Left() + pFrm->Prt().Left() + pFrm->Prt().Width();
237 : :
238 [ + - ][ + + ]: 94643 : if( nLeft >= nRight &&
[ + + + -
+ - ]
239 : : // #i53066# Omit adjustment of nLeft for numbered
240 : : // paras inside cells inside new documents:
241 : 164 : ( pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) ||
242 : 164 : !pFrm->IsInTab() ||
243 : : !nLMWithNum ) )
244 : : {
245 : 164 : nLeft = pFrm->Prt().Left() + pFrm->Frm().Left();
246 [ + + ]: 164 : if( nLeft >= nRight ) // z.B. bei grossen Absatzeinzuegen in schmalen Tabellenspalten
247 : 146 : nRight = nLeft + 1; // einen goennen wir uns immer
248 : : }
249 : :
250 [ + + ][ + - ]: 94315 : if( pFrm->IsFollow() && pFrm->GetOfst() )
[ + + ]
251 : 22673 : nFirst = nLeft;
252 : : else
253 : : {
254 : 71642 : short nFLOfst = 0;
255 : 71642 : long nFirstLineOfs = 0;
256 [ + - ]: 142561 : if( !pNode->GetFirstLineOfsWithNum( nFLOfst ) &&
[ + + - + ]
[ - + ]
257 : 70919 : rSpace.IsAutoFirst() )
258 : : {
259 : 0 : nFirstLineOfs = GetFnt()->GetSize( GetFnt()->GetActual() ).Height();
260 : 0 : const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing();
261 [ # # ]: 0 : if( pSpace )
262 : : {
263 [ # # # # ]: 0 : switch( pSpace->GetLineSpaceRule() )
264 : : {
265 : : case SVX_LINE_SPACE_AUTO:
266 : 0 : break;
267 : : case SVX_LINE_SPACE_MIN:
268 : : {
269 [ # # ]: 0 : if( nFirstLineOfs < KSHORT( pSpace->GetLineHeight() ) )
270 : 0 : nFirstLineOfs = pSpace->GetLineHeight();
271 : 0 : break;
272 : : }
273 : : case SVX_LINE_SPACE_FIX:
274 : 0 : nFirstLineOfs = pSpace->GetLineHeight();
275 : 0 : break;
276 : : default: OSL_FAIL( ": unknown LineSpaceRule" );
277 : : }
278 [ # # # # ]: 0 : switch( pSpace->GetInterLineSpaceRule() )
279 : : {
280 : : case SVX_INTER_LINE_SPACE_OFF:
281 : 0 : break;
282 : : case SVX_INTER_LINE_SPACE_PROP:
283 : : {
284 : 0 : long nTmp = pSpace->GetPropLineSpace();
285 : : // 50% ist das Minimum, bei 0% schalten wir auf
286 : : // den Defaultwert 100% um ...
287 [ # # ]: 0 : if( nTmp < 50 )
288 [ # # ]: 0 : nTmp = nTmp ? 50 : 100;
289 : :
290 : 0 : nTmp *= nFirstLineOfs;
291 : 0 : nTmp /= 100;
292 [ # # ]: 0 : if( !nTmp )
293 : 0 : ++nTmp;
294 : 0 : nFirstLineOfs = (KSHORT)nTmp;
295 : 0 : break;
296 : : }
297 : : case SVX_INTER_LINE_SPACE_FIX:
298 : : {
299 : 0 : nFirstLineOfs += pSpace->GetInterLineSpace();
300 : 0 : break;
301 : : }
302 : : default: OSL_FAIL( ": unknown InterLineSpaceRule" );
303 : : }
304 : : }
305 : : }
306 : : else
307 : 71642 : nFirstLineOfs = nFLOfst;
308 : :
309 : : // #i95907#
310 : : // #i111284#
311 [ + - ][ + - ]: 142933 : if ( pFrm->IsRightToLeft() ||
[ + + ][ + + ]
[ + + ]
312 : : bListLevelIndentsApplicableAndLabelAlignmentActive ||
313 [ + - ][ + - ]: 71291 : !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) )
314 : : {
315 : 71586 : nFirst = nLeft + nFirstLineOfs;
316 : : }
317 : : else
318 : : {
319 : 56 : nFirst = pFrm->Frm().Left() +
320 : 56 : Max( rSpace.GetTxtLeft() + nLMWithNum+ nFirstLineOfs,
321 : 112 : pFrm->Prt().Left() );
322 : : }
323 : :
324 : : // Note: <SwTxtFrm::GetAdditionalFirstLineOffset()> returns a negative
325 : : // value for the new list label postion and space mode LABEL_ALIGNMENT
326 : : // and label alignment CENTER and RIGHT in L2R layout respectively
327 : : // label alignment LEFT and CENTER in R2L layout
328 : 71642 : nFirst += pFrm->GetAdditionalFirstLineOffset();
329 : :
330 [ - + ]: 71642 : if( nFirst >= nRight )
331 : 71642 : nFirst = nRight - 1;
332 : : }
333 : 94315 : const SvxAdjustItem& rAdjust = pFrm->GetTxtNode()->GetSwAttrSet().GetAdjust();
334 : 94315 : nAdjust = static_cast<sal_uInt16>(rAdjust.GetAdjust());
335 : :
336 : : // left is left and right is right
337 [ - + ]: 94315 : if ( pFrm->IsRightToLeft() )
338 : : {
339 [ # # ]: 0 : if ( SVX_ADJUST_LEFT == nAdjust )
340 : 0 : nAdjust = SVX_ADJUST_RIGHT;
341 [ # # ]: 0 : else if ( SVX_ADJUST_RIGHT == nAdjust )
342 : 0 : nAdjust = SVX_ADJUST_LEFT;
343 : : }
344 : :
345 : 94315 : bOneBlock = rAdjust.GetOneWord() == SVX_ADJUST_BLOCK;
346 : 94315 : bLastBlock = rAdjust.GetLastBlock() == SVX_ADJUST_BLOCK;
347 : 94315 : bLastCenter = rAdjust.GetLastBlock() == SVX_ADJUST_CENTER;
348 : :
349 : : // #i91133#
350 : 94315 : mnTabLeft = pNode->GetLeftMarginForTabCalculation();
351 : :
352 : : #if OSL_DEBUG_LEVEL > 1
353 : : static sal_Bool bOne = sal_False;
354 : : static sal_Bool bLast = sal_False;
355 : : static sal_Bool bCenter = sal_False;
356 : : bOneBlock |= bOne;
357 : : bLastBlock |= bLast;
358 : : bLastCenter |= bCenter;
359 : : #endif
360 : 94315 : DropInit();
361 : 94315 : }
362 : :
363 : : /*************************************************************************
364 : : * SwTxtMargin::DropInit()
365 : : *************************************************************************/
366 : 94315 : void SwTxtMargin::DropInit()
367 : : {
368 : 94315 : nDropLeft = nDropLines = nDropHeight = nDropDescent = 0;
369 : 94315 : const SwParaPortion *pPara = GetInfo().GetParaPortion();
370 [ + - ]: 94315 : if( pPara )
371 : : {
372 : 94315 : const SwDropPortion *pPorDrop = pPara->FindDropPortion();
373 [ - + ]: 94315 : if ( pPorDrop )
374 : : {
375 : 0 : nDropLeft = pPorDrop->GetDropLeft();
376 : 0 : nDropLines = pPorDrop->GetLines();
377 : 0 : nDropHeight = pPorDrop->GetDropHeight();
378 : 0 : nDropDescent = pPorDrop->GetDropDescent();
379 : : }
380 : : }
381 : 94315 : }
382 : :
383 : : /*************************************************************************
384 : : * SwTxtMargin::GetLineStart()
385 : : *************************************************************************/
386 : :
387 : : // Unter Beruecksichtigung des Erstzeileneinzuges und der angebenen Breite.
388 : 97416 : SwTwips SwTxtMargin::GetLineStart() const
389 : : {
390 : 97416 : SwTwips nRet = GetLeftMargin();
391 [ + + ]: 99745 : if( GetAdjust() != SVX_ADJUST_LEFT &&
[ + + + + ]
392 : 2329 : !pCurr->GetFirstPortion()->IsMarginPortion() )
393 : : {
394 : : // Wenn die erste Portion ein Margin ist, dann wird das
395 : : // Adjustment durch die Portions ausgedrueckt.
396 [ + + ]: 883 : if( GetAdjust() == SVX_ADJUST_RIGHT )
397 : 6 : nRet = Right() - CurrWidth();
398 [ + + ]: 877 : else if( GetAdjust() == SVX_ADJUST_CENTER )
399 : 874 : nRet += (GetLineWidth() - CurrWidth()) / 2;
400 : : }
401 : 97416 : return nRet;
402 : : }
403 : :
404 : : /*************************************************************************
405 : : * SwTxtCursor::CtorInitTxtCursor()
406 : : *************************************************************************/
407 : 80630 : void SwTxtCursor::CtorInitTxtCursor( SwTxtFrm *pNewFrm, SwTxtSizeInfo *pNewInf )
408 : : {
409 : 80630 : CtorInitTxtMargin( pNewFrm, pNewInf );
410 : : // 6096: Vorsicht, die Iteratoren sind abgeleitet!
411 : : // GetInfo().SetOut( GetInfo().GetWin() );
412 : 80630 : }
413 : :
414 : : /*************************************************************************
415 : : * SwTxtCursor::GetEndCharRect()
416 : : *************************************************************************/
417 : :
418 : : // 1170: Antikbug: Shift-Ende vergisst das letzte Zeichen ...
419 : :
420 : 0 : sal_Bool SwTxtCursor::GetEndCharRect( SwRect* pOrig, const xub_StrLen nOfst,
421 : : SwCrsrMoveState* pCMS, const long nMax )
422 : : {
423 : : // 1170: Mehrdeutigkeit von Dokumentpositionen
424 : 0 : bRightMargin = sal_True;
425 [ # # ]: 0 : CharCrsrToLine(nOfst);
426 : :
427 : : // Etwas verdreht: nOfst bezeichnet die Position hinter dem letzten
428 : : // Zeichen der letzten Zeile == Position vor dem ersten Zeichen der
429 : : // Zeile in der wir gerade stehen:
430 [ # # ][ # # ]: 0 : if( nOfst != GetStart() || !pCurr->GetLen() )
[ # # ]
431 : : {
432 : : // 8810: Masterzeile RightMargin, danach LeftMargin
433 [ # # ]: 0 : const sal_Bool bRet = GetCharRect( pOrig, nOfst, pCMS, nMax );
434 [ # # ][ # # ]: 0 : bRightMargin = nOfst >= GetEnd() && nOfst < GetInfo().GetTxt().Len();
435 : 0 : return bRet;
436 : : }
437 : :
438 [ # # ][ # # ]: 0 : if( !GetPrev() || !GetPrev()->GetLen() || !PrevLine() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
439 [ # # ]: 0 : return GetCharRect( pOrig, nOfst, pCMS, nMax );
440 : :
441 : : // Adjustierung ggf. nachholen
442 [ # # ]: 0 : GetAdjusted();
443 : :
444 : 0 : KSHORT nX = 0;
445 : 0 : KSHORT nLast = 0;
446 : 0 : SwLinePortion *pPor = pCurr->GetFirstPortion();
447 : :
448 : : KSHORT nTmpHeight, nTmpAscent;
449 [ # # ]: 0 : CalcAscentAndHeight( nTmpAscent, nTmpHeight );
450 : 0 : KSHORT nPorHeight = nTmpHeight;
451 : 0 : KSHORT nPorAscent = nTmpAscent;
452 : :
453 : : // Die letzte Text/EndPortion der Zeile suchen
454 [ # # ]: 0 : while( pPor )
455 : : {
456 : 0 : nX = nX + pPor->Width();
457 [ # # ][ # # : 0 : if( pPor->InTxtGrp() || ( pPor->GetLen() && !pPor->IsFlyPortion()
# # # # ]
[ # # ][ # # ]
458 : 0 : && !pPor->IsHolePortion() ) || pPor->IsBreakPortion() )
459 : : {
460 : 0 : nLast = nX;
461 : 0 : nPorHeight = pPor->Height();
462 : 0 : nPorAscent = pPor->GetAscent();
463 : : }
464 : 0 : pPor = pPor->GetPortion();
465 : : }
466 : :
467 : 0 : const Size aCharSize( 1, nTmpHeight );
468 [ # # ]: 0 : pOrig->Pos( GetTopLeft() );
469 : 0 : pOrig->SSize( aCharSize );
470 : 0 : pOrig->Pos().X() += nLast;
471 : 0 : const SwTwips nTmpRight = Right() - 1;
472 [ # # ]: 0 : if( pOrig->Left() > nTmpRight )
473 : 0 : pOrig->Pos().X() = nTmpRight;
474 : :
475 [ # # ][ # # ]: 0 : if ( pCMS && pCMS->bRealHeight )
476 : : {
477 [ # # ]: 0 : if ( nTmpAscent > nPorAscent )
478 : 0 : pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
479 : : else
480 : 0 : pCMS->aRealHeight.X() = 0;
481 : : OSL_ENSURE( nPorHeight, "GetCharRect: Missing Portion-Height" );
482 : 0 : pCMS->aRealHeight.Y() = nPorHeight;
483 : : }
484 : :
485 : 0 : return sal_True;
486 : : }
487 : :
488 : : /*************************************************************************
489 : : * void SwTxtCursor::_GetCharRect(..)
490 : : * internal function, called by SwTxtCursor::GetCharRect() to calculate
491 : : * the relative character position in the current line.
492 : : * pOrig referes to x and y coordinates, width and height of the cursor
493 : : * pCMS is used for restricting the cursor, if there are different font
494 : : * heights in one line ( first value = offset to y of pOrig, second
495 : : * value = real height of (shortened) cursor
496 : : *************************************************************************/
497 : :
498 : 55003 : void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
499 : : SwCrsrMoveState* pCMS )
500 : : {
501 : 55003 : const XubString &rText = GetInfo().GetTxt();
502 [ + - ]: 55003 : SwTxtSizeInfo aInf( GetInfo(), rText, nStart );
503 [ + + ]: 55003 : if( GetPropFont() )
504 [ + - ]: 50 : aInf.GetFont()->SetProportion( GetPropFont() );
505 : : KSHORT nTmpAscent, nTmpHeight; // Zeilenhoehe
506 [ + - ]: 55003 : CalcAscentAndHeight( nTmpAscent, nTmpHeight );
507 : 55003 : const Size aCharSize( 1, nTmpHeight );
508 : 55003 : const Point aCharPos;
509 : 55003 : pOrig->Pos( aCharPos );
510 : 55003 : pOrig->SSize( aCharSize );
511 : :
512 : : // If we are looking for a position inside a field which covers
513 : : // more than one line we may not skip any "empty portions" at the
514 : : // beginning of a line
515 : : const sal_Bool bInsideFirstField = pCMS && pCMS->pSpecialPos &&
516 : : ( pCMS->pSpecialPos->nLineOfst ||
517 : : SP_EXTEND_RANGE_BEFORE ==
518 [ - + ][ # # ]: 55003 : pCMS->pSpecialPos->nExtendRange );
[ # # ][ + + ]
519 : :
520 [ + + ][ - + ]: 55003 : sal_Bool bWidth = pCMS && pCMS->bRealWidth;
521 [ + + ][ + + ]: 55003 : if( !pCurr->GetLen() && !pCurr->Width() )
[ + + ]
522 : : {
523 [ + - ][ + + ]: 1315 : if ( pCMS && pCMS->bRealHeight )
524 : : {
525 : 1309 : pCMS->aRealHeight.X() = 0;
526 : 1309 : pCMS->aRealHeight.Y() = nTmpHeight;
527 : : }
528 : : }
529 : : else
530 : : {
531 : 53688 : KSHORT nPorHeight = nTmpHeight;
532 : 53688 : KSHORT nPorAscent = nTmpAscent;
533 : 53688 : SwTwips nX = 0;
534 : 53688 : SwTwips nTmpFirst = 0;
535 : 53688 : SwLinePortion *pPor = pCurr->GetFirstPortion();
536 : 53688 : SwBidiPortion* pLastBidiPor = 0;
537 : 53688 : SwTwips nLastBidiPorWidth = 0;
538 : 53688 : std::deque<sal_uInt16>* pKanaComp = pCurr->GetpKanaComp();
539 : 53688 : MSHORT nSpaceIdx = 0;
540 : 53688 : size_t nKanaIdx = 0;
541 [ + - ][ + + ]: 53688 : long nSpaceAdd = pCurr->IsSpaceAdd() ? pCurr->GetLLSpaceAdd( 0 ) : 0;
542 : :
543 : 53688 : sal_Bool bNoTxt = sal_True;
544 : :
545 : : // Zuerst werden alle Portions ohne Len am Zeilenanfang uebersprungen.
546 : : // Ausnahme bilden die fiesen Spezialportions aus WhichFirstPortion:
547 : : // Num, ErgoSum, FtnNum, FeldReste
548 : : // 8477: aber auch die einzige Textportion einer leeren Zeile mit
549 : : // Right/Center-Adjustment! Also nicht nur pPor->GetExpandPortion() ...
550 [ + + ][ + + ]: 54795 : while( pPor && !pPor->GetLen() && ! bInsideFirstField )
[ + - ][ + + ]
551 : : {
552 : 1107 : nX += pPor->Width();
553 [ + + ][ - + ]: 1107 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ - + ][ + - ]
554 [ # # ]: 0 : nX += pPor->CalcSpacing( nSpaceAdd, aInf );
555 [ + + ]: 1107 : if( bNoTxt )
556 : 637 : nTmpFirst = nX;
557 : : // 8670: EndPortions zaehlen hier einmal als TxtPortions.
558 : : // if( pPor->InTxtGrp() || pPor->IsBreakPortion() )
559 [ + + ][ + - ]: 1107 : if( pPor->InTxtGrp() || pPor->IsBreakPortion() || pPor->InTabGrp() )
[ + + ][ + + ]
560 : : {
561 : 555 : bNoTxt = sal_False;
562 : 555 : nTmpFirst = nX;
563 : : }
564 [ - + ][ # # ]: 1107 : if( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() )
[ - + ]
565 : : {
566 [ # # ]: 0 : if ( pCurr->IsSpaceAdd() )
567 : : {
568 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
569 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
570 : : else
571 : 0 : nSpaceAdd = 0;
572 : : }
573 : :
574 [ # # ][ # # ]: 0 : if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
[ # # ]
575 : 0 : ++nKanaIdx;
576 : : }
577 [ + + ]: 1107 : if( pPor->InFixMargGrp() )
578 : : {
579 [ + + ]: 741 : if( pPor->IsMarginPortion() )
580 : 513 : bNoTxt = sal_False;
581 : : else
582 : : {
583 : : // fix margin portion => next SpaceAdd, KanaComp value
584 [ - + ]: 228 : if ( pCurr->IsSpaceAdd() )
585 : : {
586 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
587 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
588 : : else
589 : 0 : nSpaceAdd = 0;
590 : : }
591 : :
592 [ - + ][ # # ]: 228 : if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
[ - + ]
593 : 0 : ++nKanaIdx;
594 : : }
595 : : }
596 : 1107 : pPor = pPor->GetPortion();
597 : : }
598 : :
599 [ + + ]: 53688 : if( !pPor )
600 : : {
601 : : // Es sind nur Spezialportions unterwegs.
602 : 239 : nX = nTmpFirst;
603 : : }
604 : : else
605 : : {
606 [ + - ][ + - : 107568 : if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
+ + + - ]
[ + - ]
607 : 54119 : (!pPor->InFldGrp() || pPor->GetAscent() ) )
608 : : {
609 : 53449 : nPorHeight = pPor->Height();
610 : 53449 : nPorAscent = pPor->GetAscent();
611 : : }
612 [ + + ][ + + ]: 103805 : while( pPor && !pPor->IsBreakPortion() && ( aInf.GetIdx() < nOfst ||
[ + + ][ - +
# # # # ]
[ + + ]
613 : 0 : ( bWidth && ( pPor->IsKernPortion() || pPor->IsMultiPortion() ) ) ) )
614 : : {
615 [ + - ][ + - : 110234 : if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
+ + + - ]
[ + - ]
616 : 56278 : (!pPor->InFldGrp() || pPor->GetAscent() ) )
617 : : {
618 : 53956 : nPorHeight = pPor->Height();
619 : 53956 : nPorAscent = pPor->GetAscent();
620 : : }
621 : :
622 : : // If we are behind the portion, we add the portion width to
623 : : // nX. Special case: nOfst = aInf.GetIdx() + pPor->GetLen().
624 : : // For common portions (including BidiPortions) we want to add
625 : : // the portion width to nX. For MultiPortions, nExtra = 0,
626 : : // therefore we go to the 'else' branch and start a recursion.
627 : 53956 : const sal_uInt8 nExtra = pPor->IsMultiPortion() &&
628 : 1351 : ! ((SwMultiPortion*)pPor)->IsBidi() &&
629 [ - + ]: 55307 : ! bWidth ? 0 : 1;
[ + + + - ]
630 [ + + ]: 53956 : if ( aInf.GetIdx() + pPor->GetLen() < nOfst + nExtra )
631 : : {
632 [ + - ][ + + ]: 50356 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ - + ][ - + ]
633 : 0 : nX += pPor->PrtWidth() +
634 [ # # ]: 0 : pPor->CalcSpacing( nSpaceAdd, aInf );
635 : : else
636 : : {
637 [ + + ][ + - ]: 50356 : if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
[ + + ]
638 : : {
639 : : // update to current SpaceAdd, KanaComp values
640 [ - + ]: 12 : if ( pCurr->IsSpaceAdd() )
641 : : {
642 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
643 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
644 : : else
645 : 0 : nSpaceAdd = 0;
646 : : }
647 : :
648 [ - + # # ]: 12 : if ( pKanaComp &&
[ - + ]
649 : 0 : ( nKanaIdx + 1 ) < pKanaComp->size()
650 : : )
651 : 0 : ++nKanaIdx;
652 : : }
653 [ - + ]: 50356 : if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
[ # # # # ]
[ + - ]
654 : 0 : !pPor->GetPortion()->IsMarginPortion() ) )
655 : 50356 : nX += pPor->PrtWidth();
656 : : }
657 [ + + ]: 50356 : if( pPor->IsMultiPortion() )
658 : : {
659 [ - + ]: 947 : if ( ((SwMultiPortion*)pPor)->HasTabulator() )
660 : : {
661 [ # # ]: 0 : if ( pCurr->IsSpaceAdd() )
662 : : {
663 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
664 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
665 : : else
666 : 0 : nSpaceAdd = 0;
667 : : }
668 : :
669 [ # # ][ # # ]: 0 : if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
[ # # ]
670 : 0 : ++nKanaIdx;
671 : : }
672 : :
673 : : // if we are right behind a BidiPortion, we have to
674 : : // hold a pointer to the BidiPortion in order to
675 : : // find the correct cursor position, depending on the
676 : : // cursor level
677 [ - + # # ]: 947 : if ( ((SwMultiPortion*)pPor)->IsBidi() &&
[ - + ]
678 : 0 : aInf.GetIdx() + pPor->GetLen() == nOfst )
679 : : {
680 : 0 : pLastBidiPor = (SwBidiPortion*)pPor;
681 : 0 : nLastBidiPorWidth = pLastBidiPor->Width() +
682 [ # # ]: 0 : pLastBidiPor->CalcSpacing( nSpaceAdd, aInf );;
683 : : }
684 : : }
685 : :
686 : 50356 : aInf.SetIdx( aInf.GetIdx() + pPor->GetLen() );
687 : 50356 : pPor = pPor->GetPortion();
688 : : }
689 : : else
690 : : {
691 [ + + ]: 3600 : if( pPor->IsMultiPortion() )
692 : : {
693 [ + - ]: 404 : nTmpAscent = AdjustBaseLine( *pCurr, pPor );
694 : 404 : GetInfo().SetMulti( sal_True );
695 : 404 : pOrig->Pos().Y() += nTmpAscent - nPorAscent;
696 : :
697 [ + + ][ + - ]: 404 : if( pCMS && pCMS->b2Lines )
698 : : {
699 : 140 : sal_Bool bRecursion = sal_True;
700 [ + - ]: 140 : if ( ! pCMS->p2Lines )
701 : : {
702 [ + - ]: 140 : pCMS->p2Lines = new Sw2LinesPos;
703 : 140 : pCMS->p2Lines->aLine = SwRect(aCharPos, aCharSize);
704 : 140 : bRecursion = sal_False;
705 : : }
706 : :
707 [ - + ]: 140 : if( ((SwMultiPortion*)pPor)->HasRotation() )
708 : : {
709 [ # # ]: 0 : if( ((SwMultiPortion*)pPor)->IsRevers() )
710 : 0 : pCMS->p2Lines->nMultiType = MT_ROT_270;
711 : : else
712 : 0 : pCMS->p2Lines->nMultiType = MT_ROT_90;
713 : : }
714 [ + + ]: 140 : else if( ((SwMultiPortion*)pPor)->IsDouble() )
715 : 30 : pCMS->p2Lines->nMultiType = MT_TWOLINE;
716 [ - + ]: 110 : else if( ((SwMultiPortion*)pPor)->IsBidi() )
717 : 0 : pCMS->p2Lines->nMultiType = MT_BIDI;
718 : : else
719 : 110 : pCMS->p2Lines->nMultiType = MT_RUBY;
720 : :
721 : 140 : SwTwips nTmpWidth = pPor->Width();
722 [ - + ]: 140 : if( nSpaceAdd )
723 [ # # ]: 0 : nTmpWidth += pPor->CalcSpacing(nSpaceAdd, aInf);
724 : :
725 : 140 : SwRect aRect( Point(aCharPos.X() + nX, pOrig->Top() ),
726 : 280 : Size( nTmpWidth, pPor->Height() ) );
727 : :
728 [ + - ]: 140 : if ( ! bRecursion )
729 : 140 : pCMS->p2Lines->aPortion = aRect;
730 : : else
731 : 140 : pCMS->p2Lines->aPortion2 = aRect;
732 : : }
733 : :
734 : : // In a multi-portion we use GetCharRect()-function
735 : : // recursively and must add the x-position
736 : : // of the multi-portion.
737 : 404 : xub_StrLen nOldStart = nStart;
738 : 404 : SwTwips nOldY = nY;
739 : 404 : sal_uInt8 nOldProp = GetPropFont();
740 : 404 : nStart = aInf.GetIdx();
741 : 404 : SwLineLayout* pOldCurr = pCurr;
742 : 404 : pCurr = &((SwMultiPortion*)pPor)->GetRoot();
743 [ + + ]: 404 : if( ((SwMultiPortion*)pPor)->IsDouble() )
744 : 50 : SetPropFont( 50 );
745 : :
746 [ + - ][ + - ]: 404 : GETGRID( GetTxtFrm()->FindPageFrm() )
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ - + ]
747 [ - + ][ # # ]: 404 : const sal_Bool bHasGrid = pGrid && GetInfo().SnapToGrid();
748 : : const sal_uInt16 nRubyHeight = bHasGrid ?
749 [ - + ]: 404 : pGrid->GetRubyHeight() : 0;
750 : :
751 [ + - ][ + - : 1162 : if( nStart + pCurr->GetLen() <= nOfst && GetNext() &&
+ + + + ]
[ + + ]
752 : 404 : ( ! ((SwMultiPortion*)pPor)->IsRuby() ||
753 : 354 : ((SwMultiPortion*)pPor)->OnTop() ) )
754 : : {
755 : : sal_uInt16 nOffset;
756 : : // in grid mode we may only add the height of the
757 : : // ruby line if ruby line is on top
758 [ - + # # : 252 : if ( bHasGrid &&
# # ][ - + ]
759 : 0 : ((SwMultiPortion*)pPor)->IsRuby() &&
760 : 0 : ((SwMultiPortion*)pPor)->OnTop() )
761 : 0 : nOffset = nRubyHeight;
762 : : else
763 : 252 : nOffset = GetLineHeight();
764 : :
765 : 252 : pOrig->Pos().Y() += nOffset;
766 [ + - ]: 252 : Next();
767 : : }
768 : :
769 : : sal_Bool bSpaceChg = ((SwMultiPortion*)pPor)->
770 [ + - ]: 404 : ChgSpaceAdd( pCurr, nSpaceAdd );
771 : 404 : Point aOldPos = pOrig->Pos();
772 : :
773 : : // Ok, for ruby portions in grid mode we have to
774 : : // temporarily set the inner line height to the
775 : : // outer line height because that value is needed
776 : : // for the adjustment inside the recursion
777 : 404 : const sal_uInt16 nOldRubyHeight = pCurr->Height();
778 : 404 : const sal_uInt16 nOldRubyRealHeight = pCurr->GetRealHeight();
779 : : const sal_Bool bChgHeight =
780 [ - + ][ + + ]: 404 : ((SwMultiPortion*)pPor)->IsRuby() && bHasGrid;
781 : :
782 [ - + ]: 404 : if ( bChgHeight )
783 : : {
784 : 0 : pCurr->Height( pOldCurr->Height() - nRubyHeight );
785 : 0 : pCurr->SetRealHeight( pOldCurr->GetRealHeight() -
786 : 0 : nRubyHeight );
787 : : }
788 : :
789 [ + - ]: 404 : SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
790 [ - + ]: 404 : if ( ((SwMultiPortion*)pPor)->IsBidi() )
791 : : {
792 : : aLayoutModeModifier.Modify(
793 [ # # ]: 0 : ((SwBidiPortion*)pPor)->GetLevel() % 2 );
794 : : }
795 : :
796 [ + - ]: 404 : _GetCharRect( pOrig, nOfst, pCMS );
797 : :
798 [ - + ]: 404 : if ( bChgHeight )
799 : : {
800 : 0 : pCurr->Height( nOldRubyHeight );
801 : 0 : pCurr->SetRealHeight( nOldRubyRealHeight );
802 : : }
803 : :
804 : : // if we are still in the first row of
805 : : // our 2 line multiportion, we use the FirstMulti flag
806 : : // to indicate this
807 [ + + ]: 404 : if ( ((SwMultiPortion*)pPor)->IsDouble() )
808 : : {
809 : : // the recursion may have damaged our font size
810 : 50 : SetPropFont( nOldProp );
811 [ + - ]: 50 : if ( !nOldProp )
812 : 50 : nOldProp = 100;
813 [ + - ]: 50 : GetInfo().GetFont()->SetProportion( 100 );
814 : :
815 [ - + ]: 50 : if ( pCurr == &((SwMultiPortion*)pPor)->GetRoot() )
816 : : {
817 : 0 : GetInfo().SetFirstMulti( sal_True );
818 : :
819 : : // we want to treat a double line portion like a
820 : : // single line portion, if there is no text in
821 : : // the second line
822 [ # # ]: 0 : if ( !pCurr->GetNext() ||
[ # # # # ]
823 : 0 : !pCurr->GetNext()->GetLen() )
824 : 0 : GetInfo().SetMulti( sal_False );
825 : : }
826 : : }
827 : : // ruby portions are treated like single line portions
828 [ - + # # ]: 354 : else if( ((SwMultiPortion*)pPor)->IsRuby() ||
[ + - ]
829 : 0 : ((SwMultiPortion*)pPor)->IsBidi() )
830 : 354 : GetInfo().SetMulti( sal_False );
831 : :
832 : : // calculate cursor values
833 [ - + ]: 404 : if( ((SwMultiPortion*)pPor)->HasRotation() )
834 : : {
835 : 0 : GetInfo().SetMulti( sal_False );
836 : 0 : long nTmp = pOrig->Width();
837 : 0 : pOrig->Width( pOrig->Height() );
838 : 0 : pOrig->Height( nTmp );
839 : 0 : nTmp = pOrig->Left() - aOldPos.X();
840 : :
841 : : // if we travel into our rotated portion from
842 : : // a line below, we have to take care, that the
843 : : // y coord in pOrig is less than line height:
844 [ # # ]: 0 : if ( nTmp )
845 : 0 : nTmp--;
846 : :
847 : 0 : pOrig->Pos().X() = nX + aOldPos.X();
848 [ # # ]: 0 : if( ((SwMultiPortion*)pPor)->IsRevers() )
849 : 0 : pOrig->Pos().Y() = aOldPos.Y() + nTmp;
850 : : else
851 : 0 : pOrig->Pos().Y() = aOldPos.Y()
852 : 0 : + pPor->Height() - nTmp - pOrig->Height();
853 [ # # ][ # # ]: 0 : if ( pCMS && pCMS->bRealHeight )
854 : : {
855 : 0 : pCMS->aRealHeight.Y() = -pCMS->aRealHeight.Y();
856 : : // result for rotated multi portion is not
857 : : // correct for reverse (270 degree) portions
858 [ # # ]: 0 : if( ((SwMultiPortion*)pPor)->IsRevers() )
859 : : {
860 [ # # ]: 0 : if ( SvxParaVertAlignItem::AUTOMATIC ==
861 : 0 : GetLineInfo().GetVertAlign() )
862 : : // if vertical alignment is set to auto,
863 : : // we switch from base line alignment
864 : : // to centered alignment
865 : 0 : pCMS->aRealHeight.X() =
866 : 0 : ( pOrig->Width() +
867 : 0 : pCMS->aRealHeight.Y() ) / 2;
868 : : else
869 : 0 : pCMS->aRealHeight.X() =
870 : 0 : ( pOrig->Width() -
871 : 0 : pCMS->aRealHeight.X() +
872 : 0 : pCMS->aRealHeight.Y() );
873 : : }
874 : : }
875 : : }
876 : : else
877 : : {
878 : 404 : pOrig->Pos().Y() += aOldPos.Y();
879 [ - + ]: 404 : if ( ((SwMultiPortion*)pPor)->IsBidi() )
880 : : {
881 : 0 : const SwTwips nPorWidth = pPor->Width() +
882 [ # # ]: 0 : pPor->CalcSpacing( nSpaceAdd, aInf );
883 : 0 : const SwTwips nInsideOfst = pOrig->Pos().X();
884 : 0 : pOrig->Pos().X() = nX + nPorWidth -
885 : 0 : nInsideOfst - pOrig->Width();
886 : : }
887 : : else
888 : 404 : pOrig->Pos().X() += nX;
889 : :
890 [ + - ][ + + ]: 404 : if( ((SwMultiPortion*)pPor)->HasBrackets() )
891 : 40 : pOrig->Pos().X() +=
892 : 80 : ((SwDoubleLinePortion*)pPor)->PreWidth();
893 : : }
894 : :
895 [ - + ]: 404 : if( bSpaceChg )
896 [ # # ]: 0 : SwDoubleLinePortion::ResetSpaceAdd( pCurr );
897 : :
898 : 404 : pCurr = pOldCurr;
899 : 404 : nStart = nOldStart;
900 : 404 : nY = nOldY;
901 : 404 : bPrev = sal_False;
902 : :
903 [ + - ]: 55407 : return;
904 : : }
905 [ + - ]: 3196 : if ( pPor->PrtWidth() )
906 : : {
907 : 3196 : xub_StrLen nOldLen = pPor->GetLen();
908 : 3196 : pPor->SetLen( nOfst - aInf.GetIdx() );
909 : 3196 : aInf.SetLen( pPor->GetLen() );
910 [ + - ][ + - ]: 3196 : if( nX || !pPor->InNumberGrp() )
[ + + ]
911 : : {
912 [ + - ]: 3196 : SeekAndChg( aInf );
913 : 3196 : const sal_Bool bOldOnWin = aInf.OnWin();
914 : 3196 : aInf.SetOnWin( sal_False ); // keine BULLETs!
915 : 3196 : SwTwips nTmp = nX;
916 : 3196 : aInf.SetKanaComp( pKanaComp );
917 : 3196 : aInf.SetKanaIdx( nKanaIdx );
918 [ + - ]: 3196 : nX += pPor->GetTxtSize( aInf ).Width();
919 : 3196 : aInf.SetOnWin( bOldOnWin );
920 [ + - ][ - + ]: 3196 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ - + ][ + - ]
921 [ # # ]: 0 : nX += pPor->CalcSpacing( nSpaceAdd, aInf );
922 [ - + ]: 3196 : if( bWidth )
923 : : {
924 : 0 : pPor->SetLen( pPor->GetLen() + 1 );
925 : 0 : aInf.SetLen( pPor->GetLen() );
926 : 0 : aInf.SetOnWin( sal_False ); // keine BULLETs!
927 [ # # ]: 0 : nTmp += pPor->GetTxtSize( aInf ).Width();
928 : 0 : aInf.SetOnWin( bOldOnWin );
929 [ # # ][ # # ]: 0 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ # # ][ # # ]
930 [ # # ]: 0 : nTmp += pPor->CalcSpacing(nSpaceAdd, aInf);
931 : 0 : pOrig->Width( nTmp - nX );
932 : : }
933 : : }
934 : 3196 : pPor->SetLen( nOldLen );
935 : : }
936 : 3196 : bWidth = sal_False;
937 : 3196 : break;
938 : : }
939 : : }
940 : : }
941 : :
942 [ + + ]: 53284 : if( pPor )
943 : : {
944 : : OSL_ENSURE( !pPor->InNumberGrp() || bInsideFirstField, "Number surprise" );
945 : 10570 : sal_Bool bEmptyFld = sal_False;
946 [ + + ][ + + ]: 10570 : if( pPor->InFldGrp() && pPor->GetLen() )
[ + + ]
947 : : {
948 : 53 : SwFldPortion *pTmp = (SwFldPortion*)pPor;
949 [ - + ][ # # ]: 53 : while( pTmp->HasFollow() && !pTmp->GetExp().Len() )
[ - + ]
950 : : {
951 : 0 : KSHORT nAddX = pTmp->Width();
952 : 0 : SwLinePortion *pNext = pTmp->GetPortion();
953 [ # # ][ # # ]: 0 : while( pNext && !pNext->InFldGrp() )
[ # # ]
954 : : {
955 : : OSL_ENSURE( !pNext->GetLen(), "Where's my field follow?" );
956 : 0 : nAddX = nAddX + pNext->Width();
957 : 0 : pNext = pNext->GetPortion();
958 : : }
959 [ # # ]: 0 : if( !pNext )
960 : 0 : break;
961 : 0 : pTmp = (SwFldPortion*)pNext;
962 : 0 : nPorHeight = pTmp->Height();
963 : 0 : nPorAscent = pTmp->GetAscent();
964 : 0 : nX += nAddX;
965 : 0 : bEmptyFld = sal_True;
966 : : }
967 : : }
968 : : // 8513: Felder im Blocksatz, ueberspringen
969 [ + + ][ + + ]: 10652 : while( pPor && !pPor->GetLen() && ! bInsideFirstField &&
[ + - + -
+ - + - +
- ]
[ + - + + ]
[ + + ]
970 : 28 : ( pPor->IsFlyPortion() || pPor->IsKernPortion() ||
971 : 28 : pPor->IsBlankPortion() || pPor->InTabGrp() ||
972 : 14 : ( !bEmptyFld && pPor->InFldGrp() ) ) )
973 : : {
974 [ + - ][ + - ]: 12 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ - + ][ - + ]
975 : 0 : nX += pPor->PrtWidth() +
976 [ # # ]: 0 : pPor->CalcSpacing( nSpaceAdd, aInf );
977 : : else
978 : : {
979 [ - + ][ # # ]: 12 : if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
[ - + ]
980 : : {
981 [ # # ]: 0 : if ( pCurr->IsSpaceAdd() )
982 : : {
983 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
984 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
985 : : else
986 : 0 : nSpaceAdd = 0;
987 : : }
988 : :
989 [ # # ][ # # ]: 0 : if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
[ # # ]
990 : 0 : ++nKanaIdx;
991 : : }
992 [ - + ]: 12 : if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
[ # # # # ]
[ + - ]
993 : 0 : !pPor->GetPortion()->IsMarginPortion() ) )
994 : 12 : nX += pPor->PrtWidth();
995 : : }
996 [ - + # # ]: 12 : if( pPor->IsMultiPortion() &&
[ - + ]
997 : 0 : ((SwMultiPortion*)pPor)->HasTabulator() )
998 : : {
999 [ # # ]: 0 : if ( pCurr->IsSpaceAdd() )
1000 : : {
1001 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
1002 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
1003 : : else
1004 : 0 : nSpaceAdd = 0;
1005 : : }
1006 : :
1007 [ # # ][ # # ]: 0 : if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
[ # # ]
1008 : 0 : ++nKanaIdx;
1009 : : }
1010 [ + - ]: 12 : if( !pPor->IsFlyPortion() )
1011 : : {
1012 : 12 : nPorHeight = pPor->Height();
1013 : 12 : nPorAscent = pPor->GetAscent();
1014 : : }
1015 : 12 : pPor = pPor->GetPortion();
1016 : : }
1017 : :
1018 [ + + ][ + + ]: 10570 : if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() &&
[ - + # #
# # ][ - + ]
1019 : 0 : pPor->GetPortion() && pPor->GetPortion()->InFixGrp() )
1020 : : {
1021 : : // Alle Sonderportions muessen uebersprungen werden
1022 : : // Beispiel: zu-[FLY]sammen, 'u' == 19, 's' == 20; Right()
1023 : : // Ohne den Ausgleich landen wir vor '-' mit dem
1024 : : // Ausgleich vor 's'.
1025 [ # # ][ # # ]: 0 : while( pPor && !pPor->GetLen() )
[ # # ]
1026 : : {
1027 : 0 : nX += pPor->Width();
1028 [ # # ]: 0 : if( !pPor->IsMarginPortion() )
1029 : : {
1030 : 0 : nPorHeight = pPor->Height();
1031 : 0 : nPorAscent = pPor->GetAscent();
1032 : : }
1033 : 0 : pPor = pPor->GetPortion();
1034 : : }
1035 : : }
1036 [ + + ][ + + ]: 10570 : if( pPor && pCMS )
1037 : : {
1038 [ - + ][ # # ]: 7409 : if( pCMS->bFieldInfo && pPor->InFldGrp() && pPor->Width() )
[ # # ][ - + ]
1039 : 0 : pOrig->Width( pPor->Width() );
1040 [ - + ]: 7409 : if( pPor->IsDropPortion() )
1041 : : {
1042 : 0 : nPorAscent = ((SwDropPortion*)pPor)->GetDropHeight();
1043 : : // The drop height is only calculated, if we have more than
1044 : : // one line. Otherwise it is 0.
1045 [ # # ]: 0 : if ( ! nPorAscent)
1046 : 0 : nPorAscent = pPor->Height();
1047 : 0 : nPorHeight = nPorAscent;
1048 : : pOrig->Height( nPorHeight +
1049 : 0 : ((SwDropPortion*)pPor)->GetDropDescent() );
1050 [ # # ]: 0 : if( nTmpHeight < pOrig->Height() )
1051 : : {
1052 : 0 : nTmpAscent = nPorAscent;
1053 : 0 : nTmpHeight = sal_uInt16( pOrig->Height() );
1054 : : }
1055 : : }
1056 [ - + ][ # # ]: 7409 : if( bWidth && pPor->PrtWidth() && pPor->GetLen() &&
[ # # # # ]
[ - + ]
1057 : 0 : aInf.GetIdx() == nOfst )
1058 : : {
1059 [ # # ]: 0 : if( !pPor->IsFlyPortion() && pPor->Height() &&
[ # # # # ]
[ # # ]
1060 : 0 : pPor->GetAscent() )
1061 : : {
1062 : 0 : nPorHeight = pPor->Height();
1063 : 0 : nPorAscent = pPor->GetAscent();
1064 : : }
1065 : : SwTwips nTmp;
1066 [ # # ]: 0 : if( 2 > pPor->GetLen() )
1067 : : {
1068 : 0 : nTmp = pPor->Width();
1069 [ # # ][ # # ]: 0 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ # # ][ # # ]
1070 [ # # ]: 0 : nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
1071 : : }
1072 : : else
1073 : : {
1074 : 0 : const sal_Bool bOldOnWin = aInf.OnWin();
1075 : 0 : xub_StrLen nOldLen = pPor->GetLen();
1076 : 0 : pPor->SetLen( 1 );
1077 : 0 : aInf.SetLen( pPor->GetLen() );
1078 [ # # ]: 0 : SeekAndChg( aInf );
1079 : 0 : aInf.SetOnWin( sal_False ); // keine BULLETs!
1080 : 0 : aInf.SetKanaComp( pKanaComp );
1081 : 0 : aInf.SetKanaIdx( nKanaIdx );
1082 [ # # ]: 0 : nTmp = pPor->GetTxtSize( aInf ).Width();
1083 : 0 : aInf.SetOnWin( bOldOnWin );
1084 [ # # ][ # # ]: 0 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ # # ][ # # ]
1085 [ # # ]: 0 : nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
1086 : 0 : pPor->SetLen( nOldLen );
1087 : : }
1088 : 0 : pOrig->Width( nTmp );
1089 : : }
1090 : :
1091 : : // travel inside field portion?
1092 [ - + ]: 7409 : if ( pCMS->pSpecialPos )
1093 : : {
1094 : : // apply attributes to font
1095 [ # # ]: 0 : Seek( nOfst );
1096 [ # # ]: 0 : lcl_GetCharRectInsideField( aInf, *pOrig, *pCMS, *pPor );
1097 : : }
1098 : : }
1099 : : }
1100 : :
1101 : : // special case: We are at the beginning of a BidiPortion or
1102 : : // directly behind a BidiPortion
1103 [ + + ][ + - ]: 60925 : if ( pCMS &&
[ + + + +
- + ][ - + ]
1104 : : ( pLastBidiPor ||
1105 : : ( pPor &&
1106 : 7409 : pPor->IsMultiPortion() &&
1107 : 232 : ((SwMultiPortion*)pPor)->IsBidi() ) ) )
1108 : : {
1109 : : // we determine if the cursor has to blink before or behind
1110 : : // the bidi portion
1111 [ # # ]: 0 : if ( pLastBidiPor )
1112 : : {
1113 : 0 : const sal_uInt8 nPortionLevel = pLastBidiPor->GetLevel();
1114 : :
1115 [ # # ]: 0 : if ( pCMS->nCursorBidiLevel >= nPortionLevel )
1116 : : {
1117 : : // we came from inside the bidi portion, we want to blink
1118 : : // behind the portion
1119 : 0 : pOrig->Pos().X() -= nLastBidiPorWidth;
1120 : :
1121 : : // Again, there is a special case: logically behind
1122 : : // the portion can actually mean that the cursor is inside
1123 : : // the portion. This can happen is the last portion
1124 : : // inside the bidi portion is a nested bidi portion
1125 : : SwLineLayout& rLineLayout =
1126 : 0 : ((SwMultiPortion*)pLastBidiPor)->GetRoot();
1127 : :
1128 [ # # ]: 0 : const SwLinePortion *pLast = rLineLayout.FindLastPortion();
1129 [ # # ]: 0 : if ( pLast->IsMultiPortion() )
1130 : : {
1131 : : OSL_ENSURE( ((SwMultiPortion*)pLast)->IsBidi(),
1132 : : "Non-BidiPortion inside BidiPortion" );
1133 : 0 : pOrig->Pos().X() += pLast->Width() +
1134 [ # # ]: 0 : pLast->CalcSpacing( nSpaceAdd, aInf );
1135 : : }
1136 : : }
1137 : : }
1138 : : else
1139 : : {
1140 : 0 : const sal_uInt8 nPortionLevel = ((SwBidiPortion*)pPor)->GetLevel();
1141 : :
1142 [ # # ]: 0 : if ( pCMS->nCursorBidiLevel >= nPortionLevel )
1143 : : {
1144 : : // we came from inside the bidi portion, we want to blink
1145 : : // behind the portion
1146 : 0 : pOrig->Pos().X() += pPor->Width() +
1147 [ # # ]: 0 : pPor->CalcSpacing( nSpaceAdd, aInf );
1148 : : }
1149 : : }
1150 : : }
1151 : :
1152 : 53284 : pOrig->Pos().X() += nX;
1153 : :
1154 [ + + ][ + + ]: 53284 : if ( pCMS && pCMS->bRealHeight )
1155 : : {
1156 [ + - ]: 48707 : nTmpAscent = AdjustBaseLine( *pCurr, 0, nPorHeight, nPorAscent );
1157 [ + + ]: 48707 : if ( nTmpAscent > nPorAscent )
1158 : 458 : pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
1159 : : else
1160 : 48249 : pCMS->aRealHeight.X() = 0;
1161 : : OSL_ENSURE( nPorHeight, "GetCharRect: Missing Portion-Height" );
1162 [ + + ]: 48707 : if ( nTmpHeight > nPorHeight )
1163 : 652 : pCMS->aRealHeight.Y() = nPorHeight;
1164 : : else
1165 : 54599 : pCMS->aRealHeight.Y() = nTmpHeight;
1166 : : }
1167 [ + + ]: 55003 : }
1168 : : }
1169 : :
1170 : : /*************************************************************************
1171 : : * SwTxtCursor::GetCharRect()
1172 : : *************************************************************************/
1173 : :
1174 : 54599 : sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
1175 : : SwCrsrMoveState* pCMS, const long nMax )
1176 : : {
1177 [ + - ]: 54599 : CharCrsrToLine(nOfst);
1178 : :
1179 : : // Indicates that a position inside a special portion (field, number portion)
1180 : : // is requested.
1181 [ + + ][ - + ]: 54599 : const sal_Bool bSpecialPos = pCMS && pCMS->pSpecialPos;
1182 : 54599 : xub_StrLen nFindOfst = nOfst;
1183 : :
1184 [ - + ]: 54599 : if ( bSpecialPos )
1185 : : {
1186 : 0 : const sal_uInt8 nExtendRange = pCMS->pSpecialPos->nExtendRange;
1187 : :
1188 : : OSL_ENSURE( ! pCMS->pSpecialPos->nLineOfst || SP_EXTEND_RANGE_BEFORE != nExtendRange,
1189 : : "LineOffset AND Number Portion?" );
1190 : :
1191 : : // portions which are behind the string
1192 [ # # ]: 0 : if ( SP_EXTEND_RANGE_BEHIND == nExtendRange )
1193 : 0 : ++nFindOfst;
1194 : :
1195 : : // skip lines for fields which cover more than one line
1196 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < pCMS->pSpecialPos->nLineOfst; i++ )
1197 [ # # ]: 0 : Next();
1198 : : }
1199 : :
1200 : : // Adjustierung ggf. nachholen
1201 [ + - ]: 54599 : GetAdjusted();
1202 : :
1203 [ + - ]: 54599 : const Point aCharPos( GetTopLeft() );
1204 : 54599 : sal_Bool bRet = sal_True;
1205 : :
1206 [ + - ]: 54599 : _GetCharRect( pOrig, nFindOfst, pCMS );
1207 : :
1208 : 54599 : const SwTwips nTmpRight = Right() - 12;
1209 : :
1210 : 54599 : pOrig->Pos().X() += aCharPos.X();
1211 : 54599 : pOrig->Pos().Y() += aCharPos.Y();
1212 : :
1213 [ + + ][ + + ]: 54599 : if( pCMS && pCMS->b2Lines && pCMS->p2Lines )
[ + + ]
1214 : : {
1215 : 140 : pCMS->p2Lines->aLine.Pos().X() += aCharPos.X();
1216 : 140 : pCMS->p2Lines->aLine.Pos().Y() += aCharPos.Y();
1217 : 140 : pCMS->p2Lines->aPortion.Pos().X() += aCharPos.X();
1218 : 140 : pCMS->p2Lines->aPortion.Pos().Y() += aCharPos.Y();
1219 : : }
1220 : :
1221 [ + + ]: 54599 : if( pOrig->Left() > nTmpRight )
1222 : 6 : pOrig->Pos().X() = nTmpRight;
1223 : :
1224 [ + + ]: 54599 : if( nMax )
1225 : : {
1226 [ + + ]: 51529 : if( pOrig->Top() + pOrig->Height() > nMax )
1227 : : {
1228 [ + + ]: 176 : if( pOrig->Top() > nMax )
1229 : 40 : pOrig->Top( nMax );
1230 : 176 : pOrig->Height( nMax - pOrig->Top() );
1231 : : }
1232 [ + + ][ + + ]: 51529 : if ( pCMS && pCMS->bRealHeight && pCMS->aRealHeight.Y() >= 0 )
[ + - ][ + + ]
1233 : : {
1234 : 50016 : long nTmp = pCMS->aRealHeight.X() + pOrig->Top();
1235 [ - + ]: 50016 : if( nTmp >= nMax )
1236 : : {
1237 : 0 : pCMS->aRealHeight.X() = nMax - pOrig->Top();
1238 : 0 : pCMS->aRealHeight.Y() = 0;
1239 : : }
1240 [ + + ]: 50016 : else if( nTmp + pCMS->aRealHeight.Y() > nMax )
1241 : 134 : pCMS->aRealHeight.Y() = nMax - nTmp;
1242 : : }
1243 : : }
1244 : 54599 : long nOut = pOrig->Right() - GetTxtFrm()->Frm().Right();
1245 [ - + ]: 54599 : if( nOut > 0 )
1246 : : {
1247 [ # # ]: 0 : if( GetTxtFrm()->Frm().Width() < GetTxtFrm()->Prt().Left()
1248 : 0 : + GetTxtFrm()->Prt().Width() )
1249 : 0 : nOut += GetTxtFrm()->Frm().Width() - GetTxtFrm()->Prt().Left()
1250 : 0 : - GetTxtFrm()->Prt().Width();
1251 [ # # ]: 0 : if( nOut > 0 )
1252 : 0 : pOrig->Pos().X() -= nOut + 10;
1253 : : }
1254 : 54599 : return bRet;
1255 : : }
1256 : :
1257 : : /*************************************************************************
1258 : : * SwTxtCursor::GetCrsrOfst()
1259 : : *
1260 : : * Return: Offset im String
1261 : : *************************************************************************/
1262 : 222 : xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
1263 : : const MSHORT nChgNode, SwCrsrMoveState* pCMS ) const
1264 : : {
1265 : : // Adjustierung ggf. nachholen
1266 [ + - ]: 222 : GetAdjusted();
1267 : :
1268 : 222 : const XubString &rText = GetInfo().GetTxt();
1269 : 222 : xub_StrLen nOffset = 0;
1270 : :
1271 : : // x ist der horizontale Offset innerhalb der Zeile.
1272 : 222 : SwTwips x = rPoint.X();
1273 [ + - ]: 222 : const SwTwips nLeftMargin = GetLineStart();
1274 [ + - ]: 222 : SwTwips nRightMargin = GetLineEnd();
1275 [ + + ]: 222 : if( nRightMargin == nLeftMargin )
1276 : 2 : nRightMargin += 30;
1277 : :
1278 : 222 : const sal_Bool bLeftOver = x < nLeftMargin;
1279 [ + + ]: 222 : if( bLeftOver )
1280 : 2 : x = nLeftMargin;
1281 : 222 : const sal_Bool bRightOver = x > nRightMargin;
1282 [ + + ]: 222 : if( bRightOver )
1283 : 158 : x = nRightMargin;
1284 : :
1285 [ + - ][ - + ]: 222 : sal_Bool bRightAllowed = pCMS && ( pCMS->eState == MV_NONE );
1286 : :
1287 : : // Bis hierher in Dokumentkoordinaten.
1288 : 222 : x -= nLeftMargin;
1289 : :
1290 : 222 : KSHORT nX = KSHORT( x );
1291 : :
1292 : : // Wenn es in der Zeile Attributwechsel gibt, den Abschnitt
1293 : : // suchen, in dem nX liegt.
1294 : 222 : SwLinePortion *pPor = pCurr->GetFirstPortion();
1295 : 222 : xub_StrLen nCurrStart = nStart;
1296 : 222 : sal_Bool bHolePortion = sal_False;
1297 : 222 : sal_Bool bLastHyph = sal_False;
1298 : :
1299 : 222 : std::deque<sal_uInt16> *pKanaComp = pCurr->GetpKanaComp();
1300 : 222 : xub_StrLen nOldIdx = GetInfo().GetIdx();
1301 : 222 : MSHORT nSpaceIdx = 0;
1302 : 222 : size_t nKanaIdx = 0;
1303 [ # # ][ - + ]: 222 : long nSpaceAdd = pCurr->IsSpaceAdd() ? pCurr->GetLLSpaceAdd( 0 ) : 0;
1304 [ - + ][ # # ]: 222 : short nKanaComp = pKanaComp ? (*pKanaComp)[0] : 0;
1305 : :
1306 : : // nWidth ist die Breite der Zeile, oder die Breite des
1307 : : // Abschnitts mit dem Fontwechsel, in dem nX liegt.
1308 : :
1309 : 222 : KSHORT nWidth = pPor->Width();
1310 [ - + ][ - + ]: 222 : if ( pCurr->IsSpaceAdd() || pKanaComp )
[ + - ]
1311 : : {
1312 [ # # ][ # # ]: 0 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ # # ][ # # ]
1313 : : {
1314 : 0 : ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
1315 [ # # ]: 0 : nWidth = nWidth + sal_uInt16( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) );
1316 : : }
1317 [ # # ][ # # : 0 : if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) ||
# # # # ]
[ # # ]
1318 : 0 : ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() )
1319 : : )
1320 : : {
1321 [ # # ]: 0 : if ( pCurr->IsSpaceAdd() )
1322 : : {
1323 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
1324 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
1325 : : else
1326 : 0 : nSpaceAdd = 0;
1327 : : }
1328 : :
1329 [ # # ]: 0 : if( pKanaComp )
1330 : : {
1331 [ # # ]: 0 : if ( nKanaIdx + 1 < pKanaComp->size() )
1332 [ # # ]: 0 : nKanaComp = (*pKanaComp)[++nKanaIdx];
1333 : : else
1334 : 0 : nKanaComp = 0;
1335 : : }
1336 : : }
1337 : : }
1338 : :
1339 : : KSHORT nWidth30;
1340 [ - + ]: 222 : if ( pPor->IsPostItsPortion() )
1341 [ # # ]: 0 : nWidth30 = 30 + pPor->GetViewWidth( GetInfo() ) / 2;
1342 : : else
1343 : 2 : nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp() ?
1344 : : 30 :
1345 [ + + - + : 224 : nWidth;
# # ]
1346 : :
1347 [ + + ][ + + ]: 224 : while( pPor->GetPortion() && nWidth30 < nX && !pPor->IsBreakPortion() )
[ + - ][ + + ]
1348 : : {
1349 : 2 : nX = nX - nWidth;
1350 : 2 : nCurrStart = nCurrStart + pPor->GetLen();
1351 : 2 : bHolePortion = pPor->IsHolePortion();
1352 : 2 : pPor = pPor->GetPortion();
1353 : 2 : nWidth = pPor->Width();
1354 [ - + ][ - + ]: 2 : if ( pCurr->IsSpaceAdd() || pKanaComp )
[ + - ]
1355 : : {
1356 [ # # ][ # # ]: 0 : if ( pPor->InSpaceGrp() && nSpaceAdd )
[ # # ][ # # ]
1357 : : {
1358 : 0 : ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
1359 [ # # ]: 0 : nWidth = nWidth + sal_uInt16( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) );
1360 : : }
1361 : :
1362 [ # # ][ # # : 0 : if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) ||
# # # # ]
[ # # ]
1363 : 0 : ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() )
1364 : : )
1365 : : {
1366 [ # # ]: 0 : if ( pCurr->IsSpaceAdd() )
1367 : : {
1368 [ # # ][ # # ]: 0 : if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
1369 [ # # ]: 0 : nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
1370 : : else
1371 : 0 : nSpaceAdd = 0;
1372 : : }
1373 : :
1374 [ # # ]: 0 : if ( pKanaComp )
1375 : : {
1376 [ # # ]: 0 : if( nKanaIdx + 1 < pKanaComp->size() )
1377 [ # # ]: 0 : nKanaComp = (*pKanaComp)[++nKanaIdx];
1378 : : else
1379 : 0 : nKanaComp = 0;
1380 : : }
1381 : : }
1382 : : }
1383 : :
1384 [ - + ]: 2 : if ( pPor->IsPostItsPortion() )
1385 [ # # ]: 0 : nWidth30 = 30 + pPor->GetViewWidth( GetInfo() ) / 2;
1386 : : else
1387 : 0 : nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp() ?
1388 : : 30 :
1389 [ - + # # : 2 : nWidth;
# # ]
1390 [ + - ][ + - ]: 2 : if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
[ + - ]
1391 : 2 : bLastHyph = pPor->InHyphGrp();
1392 : : }
1393 : :
1394 : 222 : const sal_Bool bLastPortion = (0 == pPor->GetPortion());
1395 : :
1396 [ + + ]: 222 : if( nX==nWidth )
1397 : : {
1398 : 156 : SwLinePortion *pNextPor = pPor->GetPortion();
1399 [ - + ][ # # ]: 156 : while( pNextPor && pNextPor->InFldGrp() && !pNextPor->Width() )
[ # # ][ - + ]
1400 : : {
1401 : 0 : nCurrStart = nCurrStart + pPor->GetLen();
1402 : 0 : pPor = pNextPor;
1403 [ # # ][ # # ]: 0 : if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
[ # # ]
1404 : 0 : bLastHyph = pPor->InHyphGrp();
1405 : 0 : pNextPor = pPor->GetPortion();
1406 : : }
1407 : : }
1408 : :
1409 : 222 : ((SwTxtSizeInfo&)GetInfo()).SetIdx( nOldIdx );
1410 : :
1411 : 222 : xub_StrLen nLength = pPor->GetLen();
1412 : :
1413 [ - + ][ + - ]: 222 : sal_Bool bFieldInfo = pCMS && pCMS->bFieldInfo;
1414 : :
1415 [ - + ][ # # ]: 222 : if( bFieldInfo && ( nWidth30 < nX || bRightOver || bLeftOver ||
[ # # ][ # #
# # # # #
# ][ # # ]
[ - + ]
1416 : 0 : ( pPor->InNumberGrp() && !pPor->IsFtnNumPortion() ) ||
1417 : 0 : ( pPor->IsMarginPortion() && nWidth > nX + 30 ) ) )
1418 : 0 : ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
1419 : :
1420 : :
1421 : : // #i27615#
1422 [ + - ]: 222 : if (pCMS)
1423 : : {
1424 [ - + ]: 222 : if( pCMS->bInFrontOfLabel)
1425 : : {
1426 [ # # ]: 0 : if (! (2 * nX < nWidth && pPor->InNumberGrp() &&
1427 [ # # # # ]: 0 : !pPor->IsFtnNumPortion()))
[ # # ]
1428 : 0 : pCMS->bInFrontOfLabel = sal_False;
1429 : : }
1430 : : }
1431 : :
1432 : : // 7684: Wir sind genau auf der HyphPortion angelangt und muessen dafuer
1433 : : // sorgen, dass wir in dem String landen.
1434 : : // 7993: Wenn die Laenge 0 ist muessen wir raus...
1435 [ + + ]: 222 : if( !nLength )
1436 : : {
1437 [ + - ]: 4 : if( pCMS )
1438 : : {
1439 [ + + ][ - + ]: 4 : if( pPor->IsFlyPortion() && bFieldInfo )
[ - + ]
1440 : 0 : ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True;
1441 : :
1442 [ + + ][ - + ]: 4 : if (!bRightOver && nX)
1443 : : {
1444 [ # # ]: 0 : if( pPor->IsFtnNumPortion())
1445 : 0 : ((SwCrsrMoveState*)pCMS)->bFtnNoInfo = sal_True;
1446 [ # # ]: 0 : else if (pPor->InNumberGrp() ) // #i23726#
1447 : : {
1448 : 0 : ((SwCrsrMoveState*)pCMS)->nInNumPostionOffset = nX;
1449 : 0 : ((SwCrsrMoveState*)pCMS)->bInNumPortion = sal_True;
1450 : : }
1451 : : }
1452 : : }
1453 [ + - ]: 4 : if( !nCurrStart )
1454 : 4 : return 0;
1455 : :
1456 : : // 7849, 7816: auf pPor->GetHyphPortion kann nicht verzichtet werden!
1457 [ # # ][ # # ]: 0 : if( bHolePortion || ( !bRightAllowed && bLastHyph ) ||
[ # # # #
# # # # ]
[ # # ]
1458 : 0 : ( pPor->IsMarginPortion() && !pPor->GetPortion() &&
1459 : : // 46598: In der letzten Zeile eines zentrierten Absatzes wollen
1460 : : // wir auch mal hinter dem letzten Zeichen landen.
1461 : 0 : nCurrStart < rText.Len() ) )
1462 : 0 : --nCurrStart;
1463 [ # # ][ # # ]: 0 : else if( pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow()
[ # # ][ # # ]
1464 : : && nWidth > nX )
1465 : : {
1466 [ # # ]: 0 : if( bFieldInfo )
1467 : 0 : --nCurrStart;
1468 : : else
1469 : : {
1470 : 0 : KSHORT nHeight = pPor->Height();
1471 [ # # ][ # # ]: 0 : if ( !nHeight || nHeight > nWidth )
1472 : 0 : nHeight = nWidth;
1473 [ # # ][ # # ]: 0 : if( nChgNode && nWidth - nHeight/2 > nX )
1474 : 0 : --nCurrStart;
1475 : : }
1476 : : }
1477 : 0 : return nCurrStart;
1478 : : }
1479 [ + - ]: 218 : if ( 1 == nLength )
1480 : : {
1481 [ + - ]: 218 : if ( nWidth )
1482 : : {
1483 : : // Sonst kommen wir nicht mehr in zeichengeb. Rahmen hinein...
1484 [ + - ][ + - ]: 218 : if( !( nChgNode && pPos && pPor->IsFlyCntPortion() ) )
[ - + ][ - + ]
1485 : : {
1486 [ # # # # : 0 : if ( pPor->InFldGrp() ||
# # ][ # # ]
1487 : 0 : ( pPor->IsMultiPortion() &&
1488 : 0 : ((SwMultiPortion*)pPor)->IsBidi() ) )
1489 : : {
1490 : 0 : KSHORT nHeight = 0;
1491 [ # # ]: 0 : if( !bFieldInfo )
1492 : : {
1493 : 0 : nHeight = pPor->Height();
1494 [ # # ][ # # ]: 0 : if ( !nHeight || nHeight > nWidth )
1495 : 0 : nHeight = nWidth;
1496 : : }
1497 : :
1498 [ # # # # : 0 : if( nWidth - nHeight/2 <= nX &&
# # ][ # # ]
1499 : 0 : ( ! pPor->InFldGrp() ||
1500 : 0 : !((SwFldPortion*)pPor)->HasFollow() ) )
1501 : 0 : ++nCurrStart;
1502 : : }
1503 [ # # ][ # # : 0 : else if ( ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
# # # # ]
[ # # ][ # #
# # # # ]
[ # # ][ # # ]
[ # # ]
1504 : 0 : !pPor->GetPortion()->IsMarginPortion() &&
1505 : 0 : !pPor->GetPortion()->IsHolePortion() ) )
1506 : : && ( nWidth/2 < nX ) &&
1507 : : ( !bFieldInfo ||
1508 : 0 : ( pPor->GetPortion() &&
1509 : 0 : pPor->GetPortion()->IsPostItsPortion() ) )
1510 : : && ( bRightAllowed || !bLastHyph ))
1511 : 0 : ++nCurrStart;
1512 : :
1513 : : // if we want to get the position inside the field, we should not return
1514 [ # # ][ # # ]: 0 : if ( !pCMS || !pCMS->pSpecialPos )
1515 : 0 : return nCurrStart;
1516 : : }
1517 : : }
1518 : : else
1519 : : {
1520 [ # # ]: 0 : if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() ||
[ # # # # ]
[ # # ]
1521 : 0 : pPor->InToxRefGrp() )
1522 : 0 : return nCurrStart;
1523 [ # # ]: 0 : if ( pPor->InFldGrp() )
1524 : : {
1525 [ # # ][ # # ]: 0 : if( bRightOver && !((SwFldPortion*)pPor)->HasFollow() )
[ # # ]
1526 : 0 : ++nCurrStart;
1527 : 0 : return nCurrStart;
1528 : : }
1529 : : }
1530 : : }
1531 : :
1532 [ + + ][ + - ]: 218 : if( bLastPortion && (pCurr->GetNext() || pFrm->GetFollow() ) )
[ - + ][ - + ]
1533 : 0 : --nLength;
1534 : :
1535 [ + + ][ + - : 374 : if( nWidth > nX ||
- + # # ]
[ + + ]
1536 : 156 : ( nWidth == nX && pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsDouble() ) )
1537 : : {
1538 [ - + ]: 62 : if( pPor->IsMultiPortion() )
1539 : : {
1540 : : // In a multi-portion we use GetCrsrOfst()-function recursively
1541 : 0 : SwTwips nTmpY = rPoint.Y() - pCurr->GetAscent() + pPor->GetAscent();
1542 : : // if we are in the first line of a double line portion, we have
1543 : : // to add a value to nTmpY for not staying in this line
1544 : : // we also want to skip the first line, if we are inside ruby
1545 [ # # ][ # # : 0 : if ( ( ((SwTxtSizeInfo*)pInf)->IsMulti() &&
# # # # #
# ]
1546 : 0 : ((SwTxtSizeInfo*)pInf)->IsFirstMulti() ) ||
1547 : 0 : ( ((SwMultiPortion*)pPor)->IsRuby() &&
1548 : 0 : ((SwMultiPortion*)pPor)->OnTop() ) )
1549 : 0 : nTmpY += ((SwMultiPortion*)pPor)->Height();
1550 : :
1551 : : // Important for cursor traveling in ruby portions:
1552 : : // We have to set nTmpY to 0 in order to stay in the first row
1553 : : // if the phonetic line is the second row
1554 [ # # # # ]: 0 : if ( ((SwMultiPortion*)pPor)->IsRuby() &&
[ # # ]
1555 : 0 : ! ((SwMultiPortion*)pPor)->OnTop() )
1556 : 0 : nTmpY = 0;
1557 : :
1558 : : SwTxtCursorSave aSave( (SwTxtCursor*)this, (SwMultiPortion*)pPor,
1559 [ # # ]: 0 : nTmpY, nX, nCurrStart, nSpaceAdd );
1560 : :
1561 [ # # ]: 0 : SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
1562 [ # # ]: 0 : if ( ((SwMultiPortion*)pPor)->IsBidi() )
1563 : : {
1564 : 0 : const sal_uInt8 nBidiLevel = ((SwBidiPortion*)pPor)->GetLevel();
1565 [ # # ]: 0 : aLayoutModeModifier.Modify( nBidiLevel % 2 );
1566 : : }
1567 : :
1568 [ # # ]: 0 : if( ((SwMultiPortion*)pPor)->HasRotation() )
1569 : : {
1570 : 0 : nTmpY -= nY;
1571 [ # # ]: 0 : if( !((SwMultiPortion*)pPor)->IsRevers() )
1572 : 0 : nTmpY = pPor->Height() - nTmpY;
1573 [ # # ]: 0 : if( nTmpY < 0 )
1574 : 0 : nTmpY = 0;
1575 : 0 : nX = (KSHORT)nTmpY;
1576 : : }
1577 : :
1578 [ # # ][ # # ]: 0 : if( ((SwMultiPortion*)pPor)->HasBrackets() )
1579 : : {
1580 : 0 : sal_uInt16 nPreWidth = ((SwDoubleLinePortion*)pPor)->PreWidth();
1581 [ # # ]: 0 : if ( nX > nPreWidth )
1582 : 0 : nX = nX - nPreWidth;
1583 : : else
1584 : 0 : nX = 0;
1585 : : }
1586 : :
1587 [ # # ]: 0 : return GetCrsrOfst( pPos, Point( GetLineStart() + nX, rPoint.Y() ),
1588 [ # # ][ # # ]: 0 : nChgNode, pCMS );
[ # # ]
1589 : : }
1590 [ - + ]: 62 : if( pPor->InTxtGrp() )
1591 : : {
1592 : : sal_uInt8 nOldProp;
1593 [ # # ]: 0 : if( GetPropFont() )
1594 : : {
1595 [ # # ]: 0 : ((SwFont*)GetFnt())->SetProportion( GetPropFont() );
1596 : 0 : nOldProp = GetFnt()->GetPropr();
1597 : : }
1598 : : else
1599 : 0 : nOldProp = 0;
1600 : : {
1601 [ # # ]: 0 : SwTxtSizeInfo aSizeInf( GetInfo(), rText, nCurrStart );
1602 [ # # ]: 0 : ((SwTxtCursor*)this)->SeekAndChg( aSizeInf );
1603 [ # # ]: 0 : SwTxtSlot aDiffTxt( &aSizeInf, ((SwTxtPortion*)pPor), false, false );
1604 : 0 : SwFontSave aSave( aSizeInf, pPor->IsDropPortion() ?
1605 [ # # ][ # # ]: 0 : ((SwDropPortion*)pPor)->GetFnt() : NULL );
1606 : :
1607 : 0 : SwParaPortion* pPara = (SwParaPortion*)GetInfo().GetParaPortion();
1608 : : OSL_ENSURE( pPara, "No paragraph!" );
1609 : :
1610 : : SwDrawTextInfo aDrawInf( aSizeInf.GetVsh(),
1611 : 0 : *aSizeInf.GetOut(),
1612 : 0 : &pPara->GetScriptInfo(),
1613 : 0 : aSizeInf.GetTxt(),
1614 : 0 : aSizeInf.GetIdx(),
1615 : 0 : pPor->GetLen() );
1616 : 0 : aDrawInf.SetOfst( nX );
1617 : :
1618 [ # # ]: 0 : if ( nSpaceAdd )
1619 : : {
1620 : : xub_StrLen nCharCnt;
1621 : : // #i41860# Thai justified alignemt needs some
1622 : : // additional information:
1623 : 0 : aDrawInf.SetNumberOfBlanks( pPor->InTxtGrp() ?
1624 [ # # ]: 0 : static_cast<const SwTxtPortion*>(pPor)->GetSpaceCnt( aSizeInf, nCharCnt ) :
1625 [ # # ]: 0 : 0 );
1626 : : }
1627 : :
1628 [ # # ][ # # ]: 0 : if ( pPor->InFldGrp() && pCMS && pCMS->pSpecialPos )
[ # # ][ # # ]
1629 : 0 : aDrawInf.SetLen( STRING_LEN ); // SMARTTAGS
1630 : :
1631 : 0 : aDrawInf.SetSpace( nSpaceAdd );
1632 : 0 : aDrawInf.SetFont( aSizeInf.GetFont() );
1633 : 0 : aDrawInf.SetFrm( pFrm );
1634 : 0 : aDrawInf.SetSnapToGrid( aSizeInf.SnapToGrid() );
1635 [ # # ][ # # ]: 0 : aDrawInf.SetPosMatchesBounds( pCMS && pCMS->bPosMatchesBounds );
1636 : :
1637 [ # # ][ # # : 0 : if ( SW_CJK == aSizeInf.GetFont()->GetActual() &&
# # # # ]
1638 : 0 : pPara->GetScriptInfo().CountCompChg() &&
1639 : 0 : ! pPor->InFldGrp() )
1640 : 0 : aDrawInf.SetKanaComp( nKanaComp );
1641 : :
1642 [ # # ]: 0 : nLength = aSizeInf.GetFont()->_GetCrsrOfst( aDrawInf );
1643 : :
1644 : : // get position inside field portion?
1645 [ # # ][ # # ]: 0 : if ( pPor->InFldGrp() && pCMS && pCMS->pSpecialPos )
[ # # ][ # # ]
1646 : : {
1647 : 0 : pCMS->pSpecialPos->nCharOfst = nLength;
1648 : 0 : nLength = 0; // SMARTTAGS
1649 : : }
1650 : :
1651 : : // set cursor bidi level
1652 [ # # ]: 0 : if ( pCMS )
1653 : : ((SwCrsrMoveState*)pCMS)->nCursorBidiLevel =
1654 : 0 : aDrawInf.GetCursorBidiLevel();
1655 : :
1656 [ # # ][ # # : 0 : if( bFieldInfo && nLength == pPor->GetLen() &&
# # # # ]
[ # # ]
1657 : 0 : ( ! pPor->GetPortion() ||
1658 : 0 : ! pPor->GetPortion()->IsPostItsPortion() ) )
1659 [ # # ][ # # ]: 0 : --nLength;
1660 : : }
1661 [ # # ]: 0 : if( nOldProp )
1662 [ # # ]: 0 : ((SwFont*)GetFnt())->SetProportion( nOldProp );
1663 : : }
1664 : : else
1665 : : {
1666 [ + - ][ + - ]: 124 : if( nChgNode && pPos && pPor->IsFlyCntPortion()
[ + - - + ]
[ - + ]
1667 : 62 : && !( (SwFlyCntPortion*)pPor )->IsDraw() )
1668 : : {
1669 : : // JP 24.11.94: liegt die Pos nicht im Fly, dann
1670 : : // darf nicht mit STRING_LEN returnt werden!
1671 : : // (BugId: 9692 + Aenderung in feshview)
1672 : 0 : SwFlyInCntFrm *pTmp = ( (SwFlyCntPortion*)pPor )->GetFlyFrm();
1673 : 0 : sal_Bool bChgNode = 1 < nChgNode;
1674 [ # # ]: 0 : if( !bChgNode )
1675 : : {
1676 [ # # ]: 0 : SwFrm* pLower = pTmp->GetLower();
1677 [ # # ][ # # ]: 0 : if( pLower && (pLower->IsTxtFrm() || pLower->IsLayoutFrm()) )
[ # # ][ # # ]
1678 : 0 : bChgNode = sal_True;
1679 : : }
1680 : 0 : Point aTmpPoint( rPoint );
1681 : :
1682 [ # # ][ # # ]: 0 : if ( pFrm->IsRightToLeft() )
1683 [ # # ]: 0 : pFrm->SwitchLTRtoRTL( aTmpPoint );
1684 : :
1685 [ # # ][ # # ]: 0 : if ( pFrm->IsVertical() )
1686 [ # # ]: 0 : pFrm->SwitchHorizontalToVertical( aTmpPoint );
1687 : :
1688 [ # # ][ # # ]: 0 : if( bChgNode && pTmp->Frm().IsInside( aTmpPoint ) &&
[ # # ][ # # ]
[ # # ]
1689 [ # # ]: 0 : !( pTmp->IsProtected() ) )
1690 : : {
1691 : : nLength = ((SwFlyCntPortion*)pPor)->
1692 [ # # ]: 0 : GetFlyCrsrOfst( nX, aTmpPoint, pPos, pCMS );
1693 : : // Sobald der Frame gewechselt wird, muessen wir aufpassen, dass
1694 : : // unser Font wieder im OutputDevice steht.
1695 : : // vgl. Paint und new SwFlyCntPortion !
1696 [ # # ]: 0 : ((SwTxtSizeInfo*)pInf)->SelectFont();
1697 : :
1698 : : // 6776: Das pIter->GetCrsrOfst returnt
1699 : : // aus einer Verschachtelung mit STRING_LEN.
1700 : 0 : return STRING_LEN;
1701 : : }
1702 : : }
1703 : : else
1704 [ + - ]: 62 : nLength = pPor->GetCrsrOfst( nX );
1705 : : }
1706 : : }
1707 : 218 : nOffset = nCurrStart + nLength;
1708 : :
1709 : : // 7684: Wir sind vor der HyphPortion angelangt und muessen dafuer
1710 : : // sorgen, dass wir in dem String landen.
1711 : : // Bei Zeilenenden vor FlyFrms muessen ebenso behandelt werden.
1712 : :
1713 [ + + ][ + - ]: 222 : if( nOffset && pPor->GetLen() == nLength && pPor->GetPortion() &&
[ + + - +
# # ][ - + ]
1714 : 4 : !pPor->GetPortion()->GetLen() && pPor->GetPortion()->InHyphGrp() )
1715 : 0 : --nOffset;
1716 : :
1717 : 222 : return nOffset;
1718 : : }
1719 : :
1720 : : /** Looks for text portions which are inside the given rectangle
1721 : :
1722 : : For a rectangular text selection every text portions which is inside the given
1723 : : rectangle has to be put into the SwSelectionList as SwPaM
1724 : : From these SwPaM the SwCursors will be created.
1725 : :
1726 : : @param rSelList
1727 : : The container for the overlapped text portions
1728 : :
1729 : : @param rRect
1730 : : A rectangle in document coordinates, text inside this rectangle has to be
1731 : : selected.
1732 : :
1733 : : @return [ true, false ]
1734 : : true if any overlapping text portion has been found and put into list
1735 : : false if no portion overlaps, the list has been unchanged
1736 : : */
1737 : 0 : bool SwTxtFrm::FillSelection( SwSelectionList& rSelList, const SwRect& rRect ) const
1738 : : {
1739 : 0 : bool bRet = false;
1740 : : // PaintArea() instead Frm() for negative indents
1741 [ # # ]: 0 : SwRect aTmpFrm( PaintArea() );
1742 [ # # ][ # # ]: 0 : if( !rRect.IsOver( aTmpFrm ) )
1743 : 0 : return false;
1744 [ # # ][ # # ]: 0 : if( rSelList.checkContext( this ) )
1745 : : {
1746 : 0 : SwRect aRect( aTmpFrm );
1747 [ # # ]: 0 : aRect.Intersection( rRect );
1748 : : // rNode without const to create SwPaMs
1749 : 0 : SwCntntNode &rNode = const_cast<SwCntntNode&>( *GetNode() );
1750 [ # # ]: 0 : SwNodeIndex aIdx( rNode );
1751 [ # # ][ # # ]: 0 : SwPosition aPosL( aIdx, SwIndex( &rNode, 0 ) );
[ # # ]
1752 [ # # ]: 0 : if( IsEmpty() )
1753 : : {
1754 [ # # ][ # # ]: 0 : SwPaM *pPam = new SwPaM( aPosL, aPosL );
1755 [ # # ]: 0 : rSelList.insertPaM( pPam );
1756 : : }
1757 [ # # ][ # # ]: 0 : else if( aRect.HasArea() )
1758 : : {
1759 : 0 : xub_StrLen nOld = STRING_LEN;
1760 [ # # ]: 0 : SwPosition aPosR( aPosL );
1761 : 0 : Point aPoint;
1762 [ # # ]: 0 : SwTxtInfo aInf( const_cast<SwTxtFrm*>(this) );
1763 [ # # ]: 0 : SwTxtIter aLine( const_cast<SwTxtFrm*>(this), &aInf );
1764 : : // We have to care for top-to-bottom layout, where right becomes top etc.
1765 [ # # ][ # # ]: 0 : SWRECTFN( this )
[ # # ][ # # ]
[ # # ]
1766 [ # # ][ # # ]: 0 : SwTwips nTop = (aRect.*fnRect->fnGetTop)();
1767 [ # # ][ # # ]: 0 : SwTwips nBottom = (aRect.*fnRect->fnGetBottom)();
1768 [ # # ][ # # ]: 0 : SwTwips nLeft = (aRect.*fnRect->fnGetLeft)();
1769 [ # # ][ # # ]: 0 : SwTwips nRight = (aRect.*fnRect->fnGetRight)();
1770 : 0 : SwTwips nY = aLine.Y(); // Top position of the first line
1771 : 0 : SwTwips nLastY = nY;
1772 [ # # ][ # # ]: 0 : while( nY < nTop && aLine.Next() ) // line above rectangle
[ # # ][ # # ]
1773 : : {
1774 : 0 : nLastY = nY;
1775 : 0 : nY = aLine.Y();
1776 : : }
1777 : 0 : bool bLastLine = false;
1778 [ # # ][ # # ]: 0 : if( nY < nTop && !aLine.GetNext() )
[ # # ]
1779 : : {
1780 : 0 : bLastLine = true;
1781 : 0 : nY += aLine.GetLineHeight();
1782 : : }
1783 [ # # ]: 0 : do // check the lines for overlapping
1784 : : {
1785 [ # # ]: 0 : if( nLastY < nTop ) // if the last line was above rectangle
1786 : 0 : nLastY = nTop;
1787 [ # # ]: 0 : if( nY > nBottom ) // if the current line leaves the rectangle
1788 : 0 : nY = nBottom;
1789 [ # # ]: 0 : if( nY >= nLastY ) // gotcha: overlapping
1790 : : {
1791 : 0 : nLastY += nY;
1792 : 0 : nLastY /= 2;
1793 [ # # ]: 0 : if( bVert )
1794 : : {
1795 : 0 : aPoint.X() = nLastY;
1796 : 0 : aPoint.Y() = nLeft;
1797 : : }
1798 : : else
1799 : : {
1800 : 0 : aPoint.X() = nLeft;
1801 : 0 : aPoint.Y() = nLastY;
1802 : : }
1803 : : // Looking for the position of the left border of the rectangle
1804 : : // in this text line
1805 : 0 : SwCrsrMoveState aState( MV_UPDOWN );
1806 [ # # ][ # # ]: 0 : if( GetCrsrOfst( &aPosL, aPoint, &aState ) )
1807 : : {
1808 [ # # ]: 0 : if( bVert )
1809 : : {
1810 : 0 : aPoint.X() = nLastY;
1811 : 0 : aPoint.Y() = nRight;
1812 : : }
1813 : : else
1814 : : {
1815 : 0 : aPoint.X() = nRight;
1816 : 0 : aPoint.Y() = nLastY;
1817 : : }
1818 : : // If we get a right position and if the left position
1819 : : // is not the same like the left position of the line before
1820 : : // which cound happen e.g. for field portions or fly frames
1821 : : // a SwPaM will be inserted with these positions
1822 [ # # ]: 0 : if( GetCrsrOfst( &aPosR, aPoint, &aState ) &&
[ # # # # ]
[ # # ]
1823 : 0 : nOld != aPosL.nContent.GetIndex() )
1824 : : {
1825 [ # # ][ # # ]: 0 : SwPaM *pPam = new SwPaM( aPosL, aPosR );
1826 [ # # ]: 0 : rSelList.insertPaM( pPam );
1827 : 0 : nOld = aPosL.nContent.GetIndex();
1828 : : }
1829 : : }
1830 : : }
1831 [ # # ][ # # ]: 0 : if( aLine.Next() )
1832 : : {
1833 : 0 : nLastY = nY;
1834 : 0 : nY = aLine.Y();
1835 : : }
1836 [ # # ]: 0 : else if( !bLastLine )
1837 : : {
1838 : 0 : bLastLine = true;
1839 : 0 : nLastY = nY;
1840 : 0 : nY += aLine.GetLineHeight();
1841 : : }
1842 : : else
1843 : 0 : break;
1844 [ # # ][ # # ]: 0 : }while( nLastY < nBottom );
1845 [ # # ][ # # ]: 0 : }
1846 : : }
1847 [ # # ]: 0 : if( GetDrawObjs() )
1848 : : {
1849 : 0 : const SwSortedObjs &rObjs = *GetDrawObjs();
1850 [ # # ][ # # ]: 0 : for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
1851 : : {
1852 [ # # ]: 0 : const SwAnchoredObject* pAnchoredObj = rObjs[i];
1853 [ # # ][ # # ]: 0 : if( !pAnchoredObj->ISA(SwFlyFrm) )
[ # # ]
1854 : 0 : continue;
1855 [ # # ]: 0 : const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
1856 [ # # ][ # # ]: 0 : if( pFly->IsFlyInCntFrm() && pFly->FillSelection( rSelList, rRect ) )
[ # # ][ # # ]
1857 : 0 : bRet = true;
1858 : : }
1859 : : }
1860 : 0 : return bRet;
1861 : : }
1862 : :
1863 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|