LibreOffice Module sw (master) 1
itrcrsr.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <ndtxt.hxx>
21#include <doc.hxx>
22#include <paratr.hxx>
23#include <flyfrm.hxx>
24#include <pam.hxx>
25#include <swselectionlist.hxx>
26#include <sortedobjs.hxx>
28#include <editeng/lspcitem.hxx>
29#include <editeng/lrspitem.hxx>
30#include <frmatr.hxx>
31#include <tgrditem.hxx>
33#include <pagefrm.hxx>
34
35#include "itrtxt.hxx"
36#include <txtfrm.hxx>
37#include <flyfrms.hxx>
38#include "porfld.hxx"
39#include "porfly.hxx"
40#include "pordrop.hxx"
41#include <crstate.hxx>
42#include "pormulti.hxx"
43#include <numrule.hxx>
44#include <com/sun/star/i18n/ScriptType.hpp>
45
46// Not reentrant !!!
47// is set in GetCharRect and is interpreted in UnitUp/Down.
49
50// After calculating the position of a character during GetCharRect
51// this function allows to find the coordinates of a position (defined
52// in pCMS->pSpecialPos) inside a special portion (e.g., a field)
54 const SwCursorMoveState& rCMS,
55 const SwLinePortion& rPor )
56{
57 OSL_ENSURE( rCMS.m_pSpecialPos, "Information about special pos missing" );
58
59 if ( rPor.InFieldGrp() && !static_cast<const SwFieldPortion&>(rPor).GetExp().isEmpty() )
60 {
61 const sal_Int32 nCharOfst = rCMS.m_pSpecialPos->nCharOfst;
62 sal_Int32 nFieldIdx = 0;
63 sal_Int32 nFieldLen = 0;
64
65 OUString sString;
66 const OUString* pString = nullptr;
67 const SwLinePortion* pPor = &rPor;
68 do
69 {
70 if ( pPor->InFieldGrp() )
71 {
72 sString = static_cast<const SwFieldPortion*>(pPor)->GetExp();
73 pString = &sString;
74 nFieldLen = pString->getLength();
75 }
76 else
77 {
78 pString = nullptr;
79 nFieldLen = 0;
80 }
81
82 if ( ! pPor->GetNextPortion() || nFieldIdx + nFieldLen > nCharOfst )
83 break;
84
85 nFieldIdx = nFieldIdx + nFieldLen;
86 rOrig.Pos().AdjustX(pPor->Width() );
87 pPor = pPor->GetNextPortion();
88
89 } while ( true );
90
91 OSL_ENSURE( nCharOfst >= nFieldIdx, "Request of position inside field failed" );
92 sal_Int32 nLen = nCharOfst - nFieldIdx + 1;
93
94 if ( pString )
95 {
96 // get script for field portion
97 rInf.GetFont()->SetActual( SwScriptInfo::WhichFont(0, *pString) );
98
99 TextFrameIndex const nOldLen = pPor->GetLen();
100 const_cast<SwLinePortion*>(pPor)->SetLen(TextFrameIndex(nLen - 1));
101 const SwTwips nX1 = pPor->GetLen() ?
102 pPor->GetTextSize( rInf ).Width() :
103 0;
104
105 SwTwips nX2 = 0;
106 if ( rCMS.m_bRealWidth )
107 {
108 const_cast<SwLinePortion*>(pPor)->SetLen(TextFrameIndex(nLen));
109 nX2 = pPor->GetTextSize( rInf ).Width();
110 }
111
112 const_cast<SwLinePortion*>(pPor)->SetLen( nOldLen );
113
114 rOrig.Pos().AdjustX(nX1 );
115 rOrig.Width( ( nX2 > nX1 ) ?
116 ( nX2 - nX1 ) :
117 1 );
118 }
119 }
120 else
121 {
122 // special cases: no common fields, e.g., graphic number portion,
123 // FlyInCntPortions, Notes
124 rOrig.Width( rCMS.m_bRealWidth && rPor.Width() ? rPor.Width() : 1 );
125 }
126}
127
128// #i111284#
129namespace {
130 bool IsLabelAlignmentActive( const SwTextNode& rTextNode )
131 {
132 bool bRet( false );
133
134 if ( rTextNode.GetNumRule() )
135 {
136 int nListLevel = rTextNode.GetActualListLevel();
137
138 if (nListLevel < 0)
139 nListLevel = 0;
140
141 if (nListLevel >= MAXLEVEL)
142 nListLevel = MAXLEVEL - 1;
143
144 const SwNumFormat& rNumFormat =
145 rTextNode.GetNumRule()->Get( o3tl::narrowing<sal_uInt16>(nListLevel) );
147 {
148 bRet = true;
149 }
150 }
151
152 return bRet;
153 }
154} // end of anonymous namespace
155
157{
158 CtorInitTextIter( pNewFrame, pNewInf );
159
160 m_pInf = pNewInf;
161 GetInfo().SetFont( GetFnt() );
162 const SwTextNode *const pNode = m_pFrame->GetTextNodeForParaProps();
163
164 const SvxLRSpaceItem &rSpace = pNode->GetSwAttrSet().GetLRSpace();
165 // #i95907#
166 // #i111284#
167 const SwTextNode *pTextNode = m_pFrame->GetTextNodeForParaProps();
168 const bool bLabelAlignmentActive = IsLabelAlignmentActive( *pTextNode );
169 const bool bListLevelIndentsApplicable = pTextNode->AreListLevelIndentsApplicable();
170 const bool bListLevelIndentsApplicableAndLabelAlignmentActive = bListLevelIndentsApplicable && bLabelAlignmentActive;
171
172 // Carefully adjust the text formatting ranges.
173
174 // This whole area desperately needs some rework. There are
175 // quite a couple of values that need to be considered:
176 // 1. paragraph indent
177 // 2. paragraph first line indent
178 // 3. numbering indent
179 // 4. numbering spacing to text
180 // 5. paragraph border
181 // Note: These values have already been used during calculation
182 // of the printing area of the paragraph.
183 const int nLMWithNum = pNode->GetLeftMarginWithNum( true );
184 if ( m_pFrame->IsRightToLeft() )
185 {
186 // this calculation is identical this the calculation for L2R layout - see below
189 nLMWithNum -
190 pNode->GetLeftMarginWithNum() -
191 // #i95907#
192 // #i111284#
193 // rSpace.GetLeft() + rSpace.GetTextLeft();
194 ( bListLevelIndentsApplicableAndLabelAlignmentActive
195 ? 0
196 : ( rSpace.GetLeft() - rSpace.GetTextLeft() ) );
197 }
198 else
199 {
200 // #i95907#
201 // #i111284#
202 if ( bListLevelIndentsApplicableAndLabelAlignmentActive ||
204 {
205 // this calculation is identical this the calculation for R2L layout - see above
208 nLMWithNum -
209 pNode->GetLeftMarginWithNum() -
210 // #i95907#
211 // #i111284#
212 ( bListLevelIndentsApplicableAndLabelAlignmentActive
213 ? 0
214 : ( rSpace.GetLeft() - rSpace.GetTextLeft() ) );
215 }
216 else
217 {
219 std::max( tools::Long( rSpace.GetTextLeft() + nLMWithNum ),
221 }
222 }
223
225
226 if( mnLeft >= mnRight &&
227 // #i53066# Omit adjustment of nLeft for numbered
228 // paras inside cells inside new documents:
230 !m_pFrame->IsInTab() ||
231 ( !nLMWithNum && (!bLabelAlignmentActive || bListLevelIndentsApplicable) ) ) )
232 {
234 if( mnLeft >= mnRight ) // e.g. with large paragraph indentations in slim table columns
235 mnRight = mnLeft + 1; // einen goennen wir uns immer
236 }
237
238 if( m_pFrame->IsFollow() && m_pFrame->GetOffset() )
239 mnFirst = mnLeft;
240 else
241 {
242 short nFLOfst = 0;
243 tools::Long nFirstLineOfs = 0;
244 if( !pNode->GetFirstLineOfsWithNum( nFLOfst ) &&
245 rSpace.IsAutoFirst() )
246 {
247 nFirstLineOfs = GetFnt()->GetSize( GetFnt()->GetActual() ).Height();
248 LanguageType const aLang = m_pFrame->GetLangOfChar(
249 TextFrameIndex(0), css::i18n::ScriptType::ASIAN);
250 if (aLang != LANGUAGE_KOREAN && aLang != LANGUAGE_JAPANESE)
251 nFirstLineOfs<<=1;
252
253 // tdf#129448: Auto first-line indent should not be effected by line space.
254 // Below is for compatibility with old documents.
256 {
258 if( pSpace )
259 {
260 switch( pSpace->GetLineSpaceRule() )
261 {
262 case SvxLineSpaceRule::Auto:
263 break;
264 case SvxLineSpaceRule::Min:
265 {
266 if( nFirstLineOfs < pSpace->GetLineHeight() )
267 nFirstLineOfs = pSpace->GetLineHeight();
268 break;
269 }
270 case SvxLineSpaceRule::Fix:
271 nFirstLineOfs = pSpace->GetLineHeight();
272 break;
273 default: OSL_FAIL( ": unknown LineSpaceRule" );
274 }
275 switch( pSpace->GetInterLineSpaceRule() )
276 {
277 case SvxInterLineSpaceRule::Off:
278 break;
279 case SvxInterLineSpaceRule::Prop:
280 {
281 tools::Long nTmp = pSpace->GetPropLineSpace();
282 // 50% is the minimum, at 0% we switch to
283 // the default value 100%...
284 if( nTmp < 50 )
285 nTmp = nTmp ? 50 : 100;
286
287 nTmp *= nFirstLineOfs;
288 nTmp /= 100;
289 if( !nTmp )
290 ++nTmp;
291 nFirstLineOfs = nTmp;
292 break;
293 }
294 case SvxInterLineSpaceRule::Fix:
295 {
296 nFirstLineOfs += pSpace->GetInterLineSpace();
297 break;
298 }
299 default: OSL_FAIL( ": unknown InterLineSpaceRule" );
300 }
301 }
302 }
303 }
304 else
305 nFirstLineOfs = nFLOfst;
306
307 // #i95907#
308 // #i111284#
309 if ( m_pFrame->IsRightToLeft() ||
310 bListLevelIndentsApplicableAndLabelAlignmentActive ||
312 {
313 if ( nFirstLineOfs < 0 && m_pFrame->IsInTab() &&
316 !bListLevelIndentsApplicableAndLabelAlignmentActive )
317 {
318 // tdf#130218 always show hanging indent in narrow table cells
319 // to avoid hiding the text content of the first line
320 mnLeft -= nFirstLineOfs;
321 }
322
323 mnFirst = mnLeft + nFirstLineOfs;
324 }
325 else
326 {
328 std::max( rSpace.GetTextLeft() + nLMWithNum+ nFirstLineOfs,
330 }
331
332 // Note: <SwTextFrame::GetAdditionalFirstLineOffset()> returns a negative
333 // value for the new list label position and space mode LABEL_ALIGNMENT
334 // and label alignment CENTER and RIGHT in L2R layout respectively
335 // label alignment LEFT and CENTER in R2L layout
337
338 if( mnFirst >= mnRight )
339 mnFirst = mnRight - 1;
340 }
342 mnAdjust = rAdjust.GetAdjust();
343
344 // left is left and right is right
345 if ( m_pFrame->IsRightToLeft() )
346 {
347 if ( SvxAdjust::Left == mnAdjust )
348 mnAdjust = SvxAdjust::Right;
349 else if ( SvxAdjust::Right == mnAdjust )
350 mnAdjust = SvxAdjust::Left;
351 }
352
353 m_bOneBlock = rAdjust.GetOneWord() == SvxAdjust::Block;
354 m_bLastBlock = rAdjust.GetLastBlock() == SvxAdjust::Block;
355 m_bLastCenter = rAdjust.GetLastBlock() == SvxAdjust::Center;
356
357 // #i91133#
359
360 DropInit();
361}
362
364{
366 const SwParaPortion *pPara = GetInfo().GetParaPortion();
367 if( pPara )
368 {
369 const SwDropPortion *pPorDrop = pPara->FindDropPortion();
370 if ( pPorDrop )
371 {
372 mnDropLeft = pPorDrop->GetDropLeft();
373 mnDropLines = pPorDrop->GetLines();
374 mnDropHeight = pPorDrop->GetDropHeight();
375 mnDropDescent = pPorDrop->GetDropDescent();
376 }
377 }
378}
379
380// The function is interpreting / observing / evaluating / keeping / respecting the first line indention and the specified width.
382{
383 SwTwips nRet = GetLeftMargin();
384 if( GetAdjust() != SvxAdjust::Left &&
386 {
387 // If the first portion is a Margin, then the
388 // adjustment is expressed by the portions.
389 if( GetAdjust() == SvxAdjust::Right )
390 nRet = Right() - CurrWidth();
391 else if( GetAdjust() == SvxAdjust::Center )
392 nRet += (GetLineWidth() - CurrWidth()) / 2;
393 }
394 return nRet;
395}
396
398{
399 CtorInitTextMargin( pNewFrame, pNewInf );
400 // 6096: Attention, the iterators are derived!
401 // GetInfo().SetOut( GetInfo().GetWin() );
402}
403
404// tdf#120715 tdf#43100: Make width for some HolePortions, so cursor will be able to move into it.
405// It should not change the layout, so this should be called after the layout is calculated.
407{
409 SwLinePortion* pNextPos;
410 while (pPos)
411 {
412 pNextPos = pPos->GetNextPortion();
413 // Do it only if it is the last portion that able to handle the cursor,
414 // else the next portion would miscalculate the cursor position
415 if (pPos->ExtraBlankWidth() && (!pNextPos || pNextPos->IsMarginPortion()))
416 {
417 pPos->Width(pPos->Width() + pPos->ExtraBlankWidth());
418 pPos->ExtraBlankWidth(0);
419 }
420 pPos = pNextPos;
421 }
422}
423
424// 1170: Ancient bug: Shift-End forgets the last character ...
426 SwCursorMoveState* pCMS, const tools::Long nMax )
427{
428 // 1170: Ambiguity of document positions
429 s_bRightMargin = true;
430 CharCursorToLine(nOfst);
431
432 // Somehow twisted: nOfst names the position behind the last
433 // character of the last line == This is the position in front of the first character
434 // of the line, in which we are situated:
435 if( nOfst != GetStart() || !m_pCurr->GetLen() )
436 {
437 // 8810: Master line RightMargin, after that LeftMargin
438 GetCharRect( pOrig, nOfst, pCMS, nMax );
439 s_bRightMargin = nOfst >= GetEnd() && nOfst < TextFrameIndex(GetInfo().GetText().getLength());
440 return;
441 }
442
443 if( !GetPrev() || !GetPrev()->GetLen() || !PrevLine() )
444 {
445 GetCharRect( pOrig, nOfst, pCMS, nMax );
446 return;
447 }
448
449 // If necessary, as catch up, do the adjustment
450 GetAdjusted();
451
452 tools::Long nX = 0;
453 tools::Long nLast = 0;
455
456 SwTwips nTmpHeight, nTmpAscent;
457 CalcAscentAndHeight( nTmpAscent, nTmpHeight );
458 sal_uInt16 nPorHeight = nTmpHeight;
459 sal_uInt16 nPorAscent = nTmpAscent;
460
461 // Search for the last Text/EndPortion of the line
462 while( pPor )
463 {
464 nX = nX + pPor->Width();
465 if( pPor->InTextGrp() || ( pPor->GetLen() && !pPor->IsFlyPortion()
466 && !pPor->IsHolePortion() ) || pPor->IsBreakPortion() )
467 {
468 nLast = nX;
469 nPorHeight = pPor->Height();
470 nPorAscent = pPor->GetAscent();
471 }
472 pPor = pPor->GetNextPortion();
473 }
474
475 const Size aCharSize( 1, nTmpHeight );
476 pOrig->Pos( GetTopLeft() );
477 pOrig->SSize( aCharSize );
478 pOrig->Pos().AdjustX(nLast );
479 const SwTwips nTmpRight = Right() - 1;
480 if( pOrig->Left() > nTmpRight )
481 pOrig->Pos().setX( nTmpRight );
482
483 if ( pCMS && pCMS->m_bRealHeight )
484 {
485 if ( nTmpAscent > nPorAscent )
486 pCMS->m_aRealHeight.setX( nTmpAscent - nPorAscent );
487 else
488 pCMS->m_aRealHeight.setX( 0 );
489 OSL_ENSURE( nPorHeight, "GetCharRect: Missing Portion-Height" );
490 pCMS->m_aRealHeight.setY( nPorHeight );
491 }
492}
493
494// internal function, called by SwTextCursor::GetCharRect() to calculate
495// the relative character position in the current line.
496// pOrig refers to x and y coordinates, width and height of the cursor
497// pCMS is used for restricting the cursor, if there are different font
498// heights in one line ( first value = offset to y of pOrig, second
499// value = real height of (shortened) cursor
501 SwCursorMoveState* pCMS )
502{
503 const OUString aText = GetInfo().GetText();
504 SwTextSizeInfo aInf( GetInfo(), &aText, m_nStart );
505 if( GetPropFont() )
506 aInf.GetFont()->SetProportion( GetPropFont() );
507 SwTwips nTmpAscent, nTmpHeight; // Line height
508 CalcAscentAndHeight( nTmpAscent, nTmpHeight );
509 const Size aCharSize( 1, nTmpHeight );
510 const Point aCharPos;
511 pOrig->Pos( aCharPos );
512 pOrig->SSize( aCharSize );
513
514 // If we are looking for a position inside a field which covers
515 // more than one line we may not skip any "empty portions" at the
516 // beginning of a line
517 const bool bInsideFirstField = pCMS && pCMS->m_pSpecialPos &&
518 ( pCMS->m_pSpecialPos->nLineOfst ||
521
522 bool bWidth = pCMS && pCMS->m_bRealWidth;
523 if( !m_pCurr->GetLen() && !m_pCurr->Width() )
524 {
525 if ( pCMS && pCMS->m_bRealHeight )
526 {
527 pCMS->m_aRealHeight.setX( 0 );
528 pCMS->m_aRealHeight.setY( nTmpHeight );
529 }
530 }
531 else
532 {
533 SwTwips nPorHeight = nTmpHeight;
534 SwTwips nPorAscent = nTmpAscent;
535 SwTwips nX = 0;
536 SwTwips nTmpFirst = 0;
538 SwBidiPortion* pLastBidiPor = nullptr;
539 TextFrameIndex nLastBidiIdx(-1);
540 SwTwips nLastBidiPorWidth = 0;
541 std::deque<sal_uInt16>* pKanaComp = m_pCurr->GetpKanaComp();
542 sal_uInt16 nSpaceIdx = 0;
543 size_t nKanaIdx = 0;
544 tools::Long nSpaceAdd = m_pCurr->IsSpaceAdd() ? m_pCurr->GetLLSpaceAdd( 0 ) : 0;
545
546 bool bNoText = true;
547
548 // First all portions without Len at beginning of line are skipped.
549 // Exceptions are the mean special portions from WhichFirstPortion:
550 // Num, ErgoSum, FootnoteNum, FieldRests
551 // 8477: but also the only Textportion of an empty line with
552 // Right/Center-Adjustment! So not just pPor->GetExpandPortion() ...
553 while( pPor && !pPor->GetLen() && ! bInsideFirstField )
554 {
555 nX += pPor->Width();
556 if ( pPor->InSpaceGrp() && nSpaceAdd )
557 nX += pPor->CalcSpacing( nSpaceAdd, aInf );
558 if( bNoText )
559 nTmpFirst = nX;
560 // 8670: EndPortions count once as TextPortions.
561 // if( pPor->InTextGrp() || pPor->IsBreakPortion() )
562 if( pPor->InTextGrp() || pPor->IsBreakPortion() || pPor->InTabGrp() )
563 {
564 bNoText = false;
565 nTmpFirst = nX;
566 }
567 if( pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->HasTabulator() )
568 {
569 if ( m_pCurr->IsSpaceAdd() )
570 {
571 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
572 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
573 else
574 nSpaceAdd = 0;
575 }
576
577 if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
578 ++nKanaIdx;
579 }
580 if( pPor->InFixMargGrp() )
581 {
582 if( pPor->IsMarginPortion() )
583 bNoText = false;
584 else
585 {
586 // fix margin portion => next SpaceAdd, KanaComp value
587 if ( m_pCurr->IsSpaceAdd() )
588 {
589 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
590 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
591 else
592 nSpaceAdd = 0;
593 }
594
595 if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
596 ++nKanaIdx;
597 }
598 }
599 pPor = pPor->GetNextPortion();
600 }
601
602 if( !pPor )
603 {
604 // There's just Spezialportions.
605 nX = nTmpFirst;
606 }
607 else
608 {
609 if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
610 (!pPor->InFieldGrp() || pPor->GetAscent() ) )
611 {
612 nPorHeight = pPor->Height();
613 nPorAscent = pPor->GetAscent();
614 }
615 while( pPor && !pPor->IsBreakPortion() && ( aInf.GetIdx() < nOfst ||
616 ( bWidth && ( pPor->IsKernPortion() || pPor->IsMultiPortion() ) ) ) )
617 {
618 if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
619 (!pPor->InFieldGrp() || pPor->GetAscent() ) )
620 {
621 nPorHeight = pPor->Height();
622 nPorAscent = pPor->GetAscent();
623 }
624
625 // If we are behind the portion, we add the portion width to
626 // nX. Special case: nOfst = aInf.GetIdx() + pPor->GetLen().
627 // For common portions (including BidiPortions) we want to add
628 // the portion width to nX. For MultiPortions, nExtra = 0,
629 // therefore we go to the 'else' branch and start a recursion.
630 const TextFrameIndex nExtra( (pPor->IsMultiPortion()
631 && !static_cast<SwMultiPortion*>(pPor)->IsBidi()
632 && !bWidth)
633 ? 0 : 1 );
634 if ( aInf.GetIdx() + pPor->GetLen() < nOfst + nExtra )
635 {
636 if ( pPor->InSpaceGrp() && nSpaceAdd )
637 nX += pPor->PrtWidth() +
638 pPor->CalcSpacing( nSpaceAdd, aInf );
639 else
640 {
641 if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
642 {
643 // update to current SpaceAdd, KanaComp values
644 if ( m_pCurr->IsSpaceAdd() )
645 {
646 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
647 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
648 else
649 nSpaceAdd = 0;
650 }
651
652 if ( pKanaComp &&
653 ( nKanaIdx + 1 ) < pKanaComp->size()
654 )
655 ++nKanaIdx;
656 }
657 if ( !pPor->IsFlyPortion() || ( pPor->GetNextPortion() &&
658 !pPor->GetNextPortion()->IsMarginPortion() ) )
659 nX += pPor->PrtWidth();
660 }
661 if( pPor->IsMultiPortion() )
662 {
663 if ( static_cast<SwMultiPortion*>(pPor)->HasTabulator() )
664 {
665 if ( m_pCurr->IsSpaceAdd() )
666 {
667 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
668 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
669 else
670 nSpaceAdd = 0;
671 }
672
673 if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
674 ++nKanaIdx;
675 }
676
677 // if we are right behind a BidiPortion, we have to
678 // hold a pointer to the BidiPortion in order to
679 // find the correct cursor position, depending on the
680 // cursor level
681 if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() &&
682 aInf.GetIdx() + pPor->GetLen() == nOfst )
683 {
684 pLastBidiPor = static_cast<SwBidiPortion*>(pPor);
685 nLastBidiIdx = aInf.GetIdx();
686 nLastBidiPorWidth = pLastBidiPor->Width() +
687 pLastBidiPor->CalcSpacing( nSpaceAdd, aInf );
688 }
689 }
690
691 aInf.SetIdx( aInf.GetIdx() + pPor->GetLen() );
692 pPor = pPor->GetNextPortion();
693 }
694 else
695 {
696 if( pPor->IsMultiPortion() )
697 {
698 nTmpAscent = AdjustBaseLine( *m_pCurr, pPor );
699 GetInfo().SetMulti( true );
700 pOrig->Pos().AdjustY(nTmpAscent - nPorAscent );
701
702 if( pCMS && pCMS->m_b2Lines )
703 {
704 const bool bRecursion (pCMS->m_p2Lines);
705 if ( !bRecursion )
706 {
707 pCMS->m_p2Lines.reset(new Sw2LinesPos);
708 pCMS->m_p2Lines->aLine = SwRect(aCharPos, aCharSize);
709 }
710
711 if( static_cast<SwMultiPortion*>(pPor)->HasRotation() )
712 {
713 if( static_cast<SwMultiPortion*>(pPor)->IsRevers() )
714 pCMS->m_p2Lines->nMultiType = MultiPortionType::ROT_270;
715 else
716 pCMS->m_p2Lines->nMultiType = MultiPortionType::ROT_90;
717 }
718 else if( static_cast<SwMultiPortion*>(pPor)->IsDouble() )
719 pCMS->m_p2Lines->nMultiType = MultiPortionType::TWOLINE;
720 else if( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
721 pCMS->m_p2Lines->nMultiType = MultiPortionType::BIDI;
722 else
723 pCMS->m_p2Lines->nMultiType = MultiPortionType::RUBY;
724
725 SwTwips nTmpWidth = pPor->Width();
726 if( nSpaceAdd )
727 nTmpWidth += pPor->CalcSpacing(nSpaceAdd, aInf);
728
729 SwRect aRect( Point(aCharPos.X() + nX, pOrig->Top() ),
730 Size( nTmpWidth, pPor->Height() ) );
731
732 if ( ! bRecursion )
733 pCMS->m_p2Lines->aPortion = aRect;
734 else
735 pCMS->m_p2Lines->aPortion2 = aRect;
736 }
737
738 // In a multi-portion we use GetCharRect()-function
739 // recursively and must add the x-position
740 // of the multi-portion.
741 TextFrameIndex const nOldStart = m_nStart;
742 SwTwips nOldY = m_nY;
743 sal_uInt8 nOldProp = GetPropFont();
744 m_nStart = aInf.GetIdx();
745 SwLineLayout* pOldCurr = m_pCurr;
746 m_pCurr = &static_cast<SwMultiPortion*>(pPor)->GetRoot();
747 if( static_cast<SwMultiPortion*>(pPor)->IsDouble() )
748 SetPropFont( 50 );
749
750 SwTextGridItem const*const pGrid(
751 GetGridItem(GetTextFrame()->FindPageFrame()));
752 const bool bHasGrid = pGrid && GetInfo().SnapToGrid();
753 const sal_uInt16 nRubyHeight = bHasGrid ?
754 pGrid->GetRubyHeight() : 0;
755
756 if( m_nStart + m_pCurr->GetLen() <= nOfst && GetNext() &&
757 ( ! static_cast<SwMultiPortion*>(pPor)->IsRuby() ||
758 static_cast<SwMultiPortion*>(pPor)->OnTop() ) )
759 {
760 sal_uInt16 nOffset;
761 // in grid mode we may only add the height of the
762 // ruby line if ruby line is on top
763 if ( bHasGrid &&
764 static_cast<SwMultiPortion*>(pPor)->IsRuby() &&
765 static_cast<SwMultiPortion*>(pPor)->OnTop() )
766 nOffset = nRubyHeight;
767 else
768 nOffset = GetLineHeight();
769
770 pOrig->Pos().AdjustY(nOffset );
771 Next();
772 }
773
774 const bool bSpaceChg = static_cast<SwMultiPortion*>(pPor)->
775 ChgSpaceAdd( m_pCurr, nSpaceAdd );
776 Point aOldPos = pOrig->Pos();
777
778 // Ok, for ruby portions in grid mode we have to
779 // temporarily set the inner line height to the
780 // outer line height because that value is needed
781 // for the adjustment inside the recursion
782 const sal_uInt16 nOldRubyHeight = m_pCurr->Height();
783 const sal_uInt16 nOldRubyRealHeight = m_pCurr->GetRealHeight();
784 const bool bChgHeight =
785 static_cast<SwMultiPortion*>(pPor)->IsRuby() && bHasGrid;
786
787 if ( bChgHeight )
788 {
789 m_pCurr->Height( pOldCurr->Height() - nRubyHeight );
790 m_pCurr->SetRealHeight( pOldCurr->GetRealHeight() -
791 nRubyHeight );
792 }
793
794 SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
795 if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
796 {
797 aLayoutModeModifier.Modify(
798 static_cast<SwBidiPortion*>(pPor)->GetLevel() % 2 );
799 }
800
801 GetCharRect_( pOrig, nOfst, pCMS );
802
803 if ( bChgHeight )
804 {
805 m_pCurr->Height( nOldRubyHeight );
806 m_pCurr->SetRealHeight( nOldRubyRealHeight );
807 }
808
809 // if we are still in the first row of
810 // our 2 line multiportion, we use the FirstMulti flag
811 // to indicate this
812 if ( static_cast<SwMultiPortion*>(pPor)->IsDouble() )
813 {
814 // the recursion may have damaged our font size
815 SetPropFont( nOldProp );
816 GetInfo().GetFont()->SetProportion( 100 );
817
818 if ( m_pCurr == &static_cast<SwMultiPortion*>(pPor)->GetRoot() )
819 {
820 GetInfo().SetFirstMulti( true );
821
822 // we want to treat a double line portion like a
823 // single line portion, if there is no text in
824 // the second line
825 if ( !m_pCurr->GetNext() ||
826 !m_pCurr->GetNext()->GetLen() )
827 GetInfo().SetMulti( false );
828 }
829 }
830 // ruby portions are treated like single line portions
831 else if( static_cast<SwMultiPortion*>(pPor)->IsRuby() ||
832 static_cast<SwMultiPortion*>(pPor)->IsBidi() )
833 GetInfo().SetMulti( false );
834
835 // calculate cursor values
836 if( static_cast<SwMultiPortion*>(pPor)->HasRotation() )
837 {
838 GetInfo().SetMulti( false );
839 tools::Long nTmp = pOrig->Width();
840 pOrig->Width( pOrig->Height() );
841 pOrig->Height( nTmp );
842 nTmp = pOrig->Left() - aOldPos.X();
843
844 // if we travel into our rotated portion from
845 // a line below, we have to take care, that the
846 // y coord in pOrig is less than line height:
847 if ( nTmp )
848 nTmp--;
849
850 pOrig->Pos().setX( nX + aOldPos.X() );
851 if( static_cast<SwMultiPortion*>(pPor)->IsRevers() )
852 pOrig->Pos().setY( aOldPos.Y() + nTmp );
853 else
854 pOrig->Pos().setY( aOldPos.Y()
855 + pPor->Height() - nTmp - pOrig->Height() );
856 if ( pCMS && pCMS->m_bRealHeight )
857 {
858 pCMS->m_aRealHeight.setY( -pCMS->m_aRealHeight.Y() );
859 // result for rotated multi portion is not
860 // correct for reverse (270 degree) portions
861 if( static_cast<SwMultiPortion*>(pPor)->IsRevers() )
862 {
864 GetLineInfo().GetVertAlign() )
865 // if vertical alignment is set to auto,
866 // we switch from base line alignment
867 // to centered alignment
868 pCMS->m_aRealHeight.setX(
869 ( pOrig->Width() +
870 pCMS->m_aRealHeight.Y() ) / 2 );
871 else
872 pCMS->m_aRealHeight.setX(
873 pOrig->Width() -
874 pCMS->m_aRealHeight.X() +
875 pCMS->m_aRealHeight.Y() );
876 }
877 }
878 }
879 else
880 {
881 pOrig->Pos().AdjustY(aOldPos.Y() );
882 if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
883 {
884 const SwTwips nPorWidth = pPor->Width() +
885 pPor->CalcSpacing( nSpaceAdd, aInf );
886 const SwTwips nInsideOfst = pOrig->Pos().X();
887 pOrig->Pos().setX( nX + nPorWidth -
888 nInsideOfst - pOrig->Width() );
889 }
890 else
891 pOrig->Pos().AdjustX(nX );
892
893 if( static_cast<SwMultiPortion*>(pPor)->HasBrackets() )
894 pOrig->Pos().AdjustX(
895 static_cast<SwDoubleLinePortion*>(pPor)->PreWidth() );
896 }
897
898 if( bSpaceChg )
900
901 m_pCurr = pOldCurr;
902 m_nStart = nOldStart;
903 m_nY = nOldY;
904 m_bPrev = false;
905
906 return;
907 }
908 if ( pPor->PrtWidth() )
909 {
910 // tdf#30731: To get the correct nOfst width, we need
911 // to send the whole portion string to GetTextSize()
912 // and ask it to return the width of nOfst by calling
913 // SetMeasureLen(). Cutting the string at nOfst can
914 // give the wrong width if nOfst is in e.g. the middle
915 // of a ligature. See SwFntObj::DrawText().
916 TextFrameIndex const nOldLen = pPor->GetLen();
917 aInf.SetLen( pPor->GetLen() );
918 pPor->SetLen( nOfst - aInf.GetIdx() );
919 aInf.SetMeasureLen(pPor->GetLen());
920 if (aInf.GetLen() < aInf.GetMeasureLen())
921 {
922 pPor->SetLen(aInf.GetMeasureLen());
923 aInf.SetLen(pPor->GetLen());
924 }
925 if( nX || !pPor->InNumberGrp() )
926 {
927 SeekAndChg( aInf );
928 const bool bOldOnWin = aInf.OnWin();
929 aInf.SetOnWin( false ); // no BULLETs!
930 SwTwips nTmp = nX;
931 aInf.SetKanaComp( pKanaComp );
932 aInf.SetKanaIdx( nKanaIdx );
933 nX += pPor->GetTextSize( aInf ).Width();
934 aInf.SetOnWin( bOldOnWin );
935 if ( pPor->InSpaceGrp() && nSpaceAdd )
936 nX += pPor->CalcSpacing( nSpaceAdd, aInf );
937 if( bWidth )
938 {
939 pPor->SetLen(pPor->GetLen() + TextFrameIndex(1));
940 aInf.SetMeasureLen(pPor->GetLen());
941 if (aInf.GetLen() < aInf.GetMeasureLen())
942 {
943 pPor->SetLen(aInf.GetMeasureLen());
944 aInf.SetLen(pPor->GetLen());
945 }
946 aInf.SetOnWin( false ); // no BULLETs!
947 nTmp += pPor->GetTextSize( aInf ).Width();
948 aInf.SetOnWin( bOldOnWin );
949 if ( pPor->InSpaceGrp() && nSpaceAdd )
950 nTmp += pPor->CalcSpacing(nSpaceAdd, aInf);
951 pOrig->Width( nTmp - nX );
952 }
953 }
954 pPor->SetLen( nOldLen );
955
956 // Shift the cursor with the right border width
957 // Note: nX remains positive because GetTextSize() also include the width of the right border
958 if( aInf.GetIdx() < nOfst && nOfst < aInf.GetIdx() + pPor->GetLen() )
959 {
960 // Find the current drop portion part and use its right border
961 if( pPor->IsDropPortion() && static_cast<SwDropPortion*>(pPor)->GetLines() > 1 )
962 {
963 SwDropPortion* pDrop = static_cast<SwDropPortion*>(pPor);
964 const SwDropPortionPart* pCurrPart = pDrop->GetPart();
965 TextFrameIndex nSumLength(0);
966 while( pCurrPart && (nSumLength += pCurrPart->GetLen()) < nOfst - aInf.GetIdx() )
967 {
968 pCurrPart = pCurrPart->GetFollow();
969 }
970 if( pCurrPart && nSumLength != nOfst - aInf.GetIdx() &&
971 pCurrPart->GetFont().GetRightBorder() && !pCurrPart->GetJoinBorderWithNext() )
972 {
973 nX -= pCurrPart->GetFont().GetRightBorderSpace();
974 }
975 }
976 else if( GetInfo().GetFont()->GetRightBorder() && !pPor->GetJoinBorderWithNext())
977 {
979 }
980 }
981 }
982 bWidth = false;
983 break;
984 }
985 }
986 }
987
988 if( pPor )
989 {
990 OSL_ENSURE( !pPor->InNumberGrp() || bInsideFirstField, "Number surprise" );
991 bool bEmptyField = false;
992 if( pPor->InFieldGrp() && pPor->GetLen() )
993 {
994 SwFieldPortion *pTmp = static_cast<SwFieldPortion*>(pPor);
995 while( pTmp->HasFollow() && pTmp->GetExp().isEmpty() )
996 {
997 sal_uInt16 nAddX = pTmp->Width();
998 SwLinePortion *pNext = pTmp->GetNextPortion();
999 while( pNext && !pNext->InFieldGrp() )
1000 {
1001 OSL_ENSURE( !pNext->GetLen(), "Where's my field follow?" );
1002 nAddX = nAddX + pNext->Width();
1003 pNext = pNext->GetNextPortion();
1004 }
1005 if( !pNext )
1006 break;
1007 pTmp = static_cast<SwFieldPortion*>(pNext);
1008 nPorHeight = pTmp->Height();
1009 nPorAscent = pTmp->GetAscent();
1010 nX += nAddX;
1011 bEmptyField = true;
1012 }
1013 }
1014 // 8513: Fields in justified text, skipped
1015 while( pPor && !pPor->GetLen() && ! bInsideFirstField &&
1016 ( pPor->IsFlyPortion() || pPor->IsKernPortion() ||
1017 pPor->IsBlankPortion() || pPor->InTabGrp() ||
1018 ( !bEmptyField && pPor->InFieldGrp() ) ) )
1019 {
1020 if ( pPor->InSpaceGrp() && nSpaceAdd )
1021 nX += pPor->PrtWidth() +
1022 pPor->CalcSpacing( nSpaceAdd, aInf );
1023 else
1024 {
1025 if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
1026 {
1027 if ( m_pCurr->IsSpaceAdd() )
1028 {
1029 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
1030 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
1031 else
1032 nSpaceAdd = 0;
1033 }
1034
1035 if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
1036 ++nKanaIdx;
1037 }
1038 if ( !pPor->IsFlyPortion() || ( pPor->GetNextPortion() &&
1039 !pPor->GetNextPortion()->IsMarginPortion() ) )
1040 nX += pPor->PrtWidth();
1041 }
1042 if( pPor->IsMultiPortion() &&
1043 static_cast<SwMultiPortion*>(pPor)->HasTabulator() )
1044 {
1045 if ( m_pCurr->IsSpaceAdd() )
1046 {
1047 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
1048 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
1049 else
1050 nSpaceAdd = 0;
1051 }
1052
1053 if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
1054 ++nKanaIdx;
1055 }
1056 if( !pPor->IsFlyPortion() )
1057 {
1058 nPorHeight = pPor->Height();
1059 nPorAscent = pPor->GetAscent();
1060 }
1061 pPor = pPor->GetNextPortion();
1062 }
1063
1064 if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() &&
1065 pPor->GetNextPortion() && pPor->GetNextPortion()->InFixGrp() )
1066 {
1067 // All special portions have to be skipped
1068 // Taking the German word "zusammen" as example: zu-[FLY]sammen, 'u' == 19, 's' == 20; Right()
1069 // Without the adjustment we end up in front of '-', with the
1070 // adjustment in front of the 's'.
1071 while( pPor && !pPor->GetLen() )
1072 {
1073 nX += pPor->Width();
1074 if( !pPor->IsMarginPortion() )
1075 {
1076 nPorHeight = pPor->Height();
1077 nPorAscent = pPor->GetAscent();
1078 }
1079 pPor = pPor->GetNextPortion();
1080 }
1081 }
1082 if( pPor && pCMS )
1083 {
1084 if( pCMS->m_bFieldInfo && pPor->InFieldGrp() && pPor->Width() )
1085 pOrig->Width( pPor->Width() );
1086 if( pPor->IsDropPortion() )
1087 {
1088 nPorAscent = static_cast<SwDropPortion*>(pPor)->GetDropHeight();
1089 // The drop height is only calculated, if we have more than
1090 // one line. Otherwise it is 0.
1091 if ( ! nPorAscent)
1092 nPorAscent = pPor->Height();
1093 nPorHeight = nPorAscent;
1094 pOrig->Height( nPorHeight +
1095 static_cast<SwDropPortion*>(pPor)->GetDropDescent() );
1096 if( nTmpHeight < pOrig->Height() )
1097 {
1098 nTmpAscent = nPorAscent;
1099 nTmpHeight = sal_uInt16( pOrig->Height() );
1100 }
1101 }
1102 if( bWidth && pPor->PrtWidth() && pPor->GetLen() &&
1103 aInf.GetIdx() == nOfst )
1104 {
1105 if( !pPor->IsFlyPortion() && pPor->Height() &&
1106 pPor->GetAscent() )
1107 {
1108 nPorHeight = pPor->Height();
1109 nPorAscent = pPor->GetAscent();
1110 }
1111 SwTwips nTmp;
1112 if (TextFrameIndex(2) > pPor->GetLen())
1113 {
1114 nTmp = pPor->Width();
1115 if ( pPor->InSpaceGrp() && nSpaceAdd )
1116 nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
1117 }
1118 else
1119 {
1120 const bool bOldOnWin = aInf.OnWin();
1121 TextFrameIndex const nOldLen = pPor->GetLen();
1122 aInf.SetLen( pPor->GetLen() );
1123 pPor->SetLen( TextFrameIndex(1) );
1124 aInf.SetMeasureLen(pPor->GetLen());
1125 if (aInf.GetLen() < aInf.GetMeasureLen())
1126 {
1127 pPor->SetLen(aInf.GetMeasureLen());
1128 aInf.SetLen(pPor->GetLen());
1129 }
1130 SeekAndChg( aInf );
1131 aInf.SetOnWin( false ); // no BULLETs!
1132 aInf.SetKanaComp( pKanaComp );
1133 aInf.SetKanaIdx( nKanaIdx );
1134 nTmp = pPor->GetTextSize( aInf ).Width();
1135 aInf.SetOnWin( bOldOnWin );
1136 if ( pPor->InSpaceGrp() && nSpaceAdd )
1137 nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
1138 pPor->SetLen( nOldLen );
1139 }
1140 pOrig->Width( nTmp );
1141 }
1142
1143 // travel inside field portion?
1144 if ( pCMS->m_pSpecialPos )
1145 {
1146 // apply attributes to font
1147 Seek( nOfst );
1148 lcl_GetCharRectInsideField( aInf, *pOrig, *pCMS, *pPor );
1149 }
1150 }
1151 }
1152
1153 // special case: We are at the beginning of a BidiPortion or
1154 // directly behind a BidiPortion
1155 if ( pCMS &&
1156 ( pLastBidiPor ||
1157 ( pPor &&
1158 pPor->IsMultiPortion() &&
1159 static_cast<SwMultiPortion*>(pPor)->IsBidi() ) ) )
1160 {
1161 // we determine if the cursor has to blink before or behind
1162 // the bidi portion
1163 if ( pLastBidiPor )
1164 {
1165 const sal_uInt8 nPortionLevel = pLastBidiPor->GetLevel();
1166
1167 if ( pCMS->m_nCursorBidiLevel >= nPortionLevel )
1168 {
1169 // we came from inside the bidi portion, we want to blink
1170 // behind the portion
1171 pOrig->Pos().AdjustX( -nLastBidiPorWidth );
1172
1173 // Again, there is a special case: logically behind
1174 // the portion can actually mean that the cursor is inside
1175 // the portion. This can happen is the last portion
1176 // inside the bidi portion is a nested bidi portion
1177 SwLineLayout& rLineLayout =
1178 static_cast<SwMultiPortion*>(pLastBidiPor)->GetRoot();
1179
1180 const SwLinePortion *pLast = rLineLayout.FindLastPortion();
1181 if ( pLast->IsMultiPortion() )
1182 {
1183 OSL_ENSURE( static_cast<const SwMultiPortion*>(pLast)->IsBidi(),
1184 "Non-BidiPortion inside BidiPortion" );
1185 TextFrameIndex const nIdx = aInf.GetIdx();
1186 // correct the index before using CalcSpacing.
1187 aInf.SetIdx(nLastBidiIdx);
1188 pOrig->Pos().AdjustX(pLast->Width() +
1189 pLast->CalcSpacing( nSpaceAdd, aInf ) );
1190 aInf.SetIdx(nIdx);
1191 }
1192 }
1193 }
1194 else
1195 {
1196 const sal_uInt8 nPortionLevel = static_cast<SwBidiPortion*>(pPor)->GetLevel();
1197
1198 if ( pCMS->m_nCursorBidiLevel >= nPortionLevel )
1199 {
1200 // we came from inside the bidi portion, we want to blink
1201 // behind the portion
1202 pOrig->Pos().AdjustX(pPor->Width() +
1203 pPor->CalcSpacing( nSpaceAdd, aInf ) );
1204 }
1205 }
1206 }
1207
1208 pOrig->Pos().AdjustX(nX );
1209
1210 if ( pCMS && pCMS->m_bRealHeight )
1211 {
1212 nTmpAscent = AdjustBaseLine( *m_pCurr, nullptr, nPorHeight, nPorAscent );
1213 if ( nTmpAscent > nPorAscent )
1214 pCMS->m_aRealHeight.setX( nTmpAscent - nPorAscent );
1215 else
1216 pCMS->m_aRealHeight.setX( 0 );
1217 OSL_ENSURE( nPorHeight, "GetCharRect: Missing Portion-Height" );
1218 if ( nTmpHeight > nPorHeight )
1219 pCMS->m_aRealHeight.setY( nPorHeight );
1220 else
1221 pCMS->m_aRealHeight.setY( nTmpHeight );
1222 }
1223 }
1224}
1225
1227 SwCursorMoveState* pCMS, const tools::Long nMax )
1228{
1229 CharCursorToLine(nOfst);
1230
1231 // Indicates that a position inside a special portion (field, number portion)
1232 // is requested.
1233 const bool bSpecialPos = pCMS && pCMS->m_pSpecialPos;
1234 TextFrameIndex nFindOfst = nOfst;
1235
1236 if ( bSpecialPos )
1237 {
1238 const SwSPExtendRange nExtendRange = pCMS->m_pSpecialPos->nExtendRange;
1239
1240 OSL_ENSURE( ! pCMS->m_pSpecialPos->nLineOfst || SwSPExtendRange::BEFORE != nExtendRange,
1241 "LineOffset AND Number Portion?" );
1242
1243 // portions which are behind the string
1244 if ( SwSPExtendRange::BEHIND == nExtendRange )
1245 ++nFindOfst;
1246
1247 // skip lines for fields which cover more than one line
1248 for ( sal_uInt16 i = 0; i < pCMS->m_pSpecialPos->nLineOfst; i++ )
1249 Next();
1250 }
1251
1252 // If necessary, as catch up, do the adjustment
1253 GetAdjusted();
1254
1255 const Point aCharPos( GetTopLeft() );
1256
1257 GetCharRect_( pOrig, nFindOfst, pCMS );
1258
1259 pOrig->Pos().AdjustX(aCharPos.X() );
1260 pOrig->Pos().AdjustY(aCharPos.Y() );
1261
1262 if( pCMS && pCMS->m_b2Lines && pCMS->m_p2Lines )
1263 {
1264 pCMS->m_p2Lines->aLine.Pos().AdjustX(aCharPos.X() );
1265 pCMS->m_p2Lines->aLine.Pos().AdjustY(aCharPos.Y() );
1266 pCMS->m_p2Lines->aPortion.Pos().AdjustX(aCharPos.X() );
1267 pCMS->m_p2Lines->aPortion.Pos().AdjustY(aCharPos.Y() );
1268 }
1269
1270 if( nMax )
1271 {
1272 if( pOrig->Top() + pOrig->Height() > nMax )
1273 {
1274 if( pOrig->Top() > nMax )
1275 pOrig->Top( nMax );
1276 pOrig->Height( nMax - pOrig->Top() );
1277 }
1278 if ( pCMS && pCMS->m_bRealHeight && pCMS->m_aRealHeight.Y() >= 0 )
1279 {
1280 tools::Long nTmp = pCMS->m_aRealHeight.X() + pOrig->Top();
1281 if( nTmp >= nMax )
1282 {
1283 pCMS->m_aRealHeight.setX( nMax - pOrig->Top() );
1284 pCMS->m_aRealHeight.setY( 0 );
1285 }
1286 else if( nTmp + pCMS->m_aRealHeight.Y() > nMax )
1287 pCMS->m_aRealHeight.setY( nMax - nTmp );
1288 }
1289 }
1290}
1291
1296static bool ConsiderNextPortionForCursorOffset(const SwLinePortion* pPor, SwTwips nWidth30, sal_uInt16 nX)
1297{
1298 if (!pPor->GetNextPortion() || pPor->IsBreakPortion())
1299 {
1300 return false;
1301 }
1302
1303 // tdf#138592: consider all following zero-width text portions of current text portion,
1304 // like combining characters.
1305 if (nWidth30 == nX && pPor->IsTextPortion() && pPor->GetNextPortion()->IsTextPortion()
1306 && pPor->GetNextPortion()->Width() == 0)
1307 return true;
1308
1309 // If we're past the target position, stop the iteration in general.
1310 // Exception: don't stop the iteration between as-char fly portions and their comments.
1311 if (nWidth30 >= nX && (!pPor->IsFlyCntPortion() || !pPor->GetNextPortion()->IsPostItsPortion()))
1312 {
1313 // Normally returns false.
1314
1315 // Another exception: If the cursor is at the very end of the portion, and the next portion is a comment,
1316 // then place the cursor after the zero-width comment. This is primarily to benefit the very end of a line.
1317 return nWidth30 == nX && pPor->GetNextPortion()->IsPostItsPortion();
1318 }
1319
1320 return true;
1321}
1322
1323// Return: Offset in String
1325 bool bChgNode, SwCursorMoveState* pCMS ) const
1326{
1327 // If necessary, as catch up, do the adjustment
1328 GetAdjusted();
1329
1330 const OUString &rText = GetInfo().GetText();
1331 TextFrameIndex nOffset(0);
1332
1333 // x is the horizontal offset within the line.
1334 SwTwips x = rPoint.X();
1337 ( GetCurr()->IsHanging() ? GetCurr()->GetHangingMargin() : 0 );
1338 if( nRightMargin == nLeftMargin )
1339 nRightMargin += 30;
1340
1341 const bool bLeftOver = x < nLeftMargin;
1342 if( bLeftOver )
1343 x = nLeftMargin;
1344 const bool bRightOver = x > nRightMargin;
1345 const bool bRightAllowed = pCMS && ( pCMS->m_eState == CursorMoveState::NONE );
1346
1347 // Until here everything in document coordinates.
1348 x -= nLeftMargin;
1349
1350 SwTwips nX = x;
1351
1352 // If there are attribute changes in the line, search for the paragraph,
1353 // in which nX is situated.
1355 TextFrameIndex nCurrStart = m_nStart;
1356 bool bHolePortion = false;
1357 bool bLastHyph = false;
1358
1359 std::deque<sal_uInt16> *pKanaComp = m_pCurr->GetpKanaComp();
1360 TextFrameIndex const nOldIdx = GetInfo().GetIdx();
1361 sal_uInt16 nSpaceIdx = 0;
1362 size_t nKanaIdx = 0;
1363 tools::Long nSpaceAdd = m_pCurr->IsSpaceAdd() ? m_pCurr->GetLLSpaceAdd( 0 ) : 0;
1364 short nKanaComp = pKanaComp ? (*pKanaComp)[0] : 0;
1365
1366 // nWidth is the width of the line, or the width of
1367 // the paragraph with the font change, in which nX is situated.
1368
1369 SwTwips nWidth = pPor->Width();
1370 if ( m_pCurr->IsSpaceAdd() || pKanaComp )
1371 {
1372 if ( pPor->InSpaceGrp() && nSpaceAdd )
1373 {
1374 const_cast<SwTextSizeInfo&>(GetInfo()).SetIdx( nCurrStart );
1375 nWidth = nWidth + sal_uInt16( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) );
1376 }
1377 if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) ||
1378 ( pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->HasTabulator() )
1379 )
1380 {
1381 if ( m_pCurr->IsSpaceAdd() )
1382 {
1383 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
1384 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
1385 else
1386 nSpaceAdd = 0;
1387 }
1388
1389 if( pKanaComp )
1390 {
1391 if ( nKanaIdx + 1 < pKanaComp->size() )
1392 nKanaComp = (*pKanaComp)[++nKanaIdx];
1393 else
1394 nKanaComp = 0;
1395 }
1396 }
1397 }
1398
1399 SwTwips nWidth30;
1400 if ( pPor->IsPostItsPortion() )
1401 nWidth30 = 0;
1402 else
1403 nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFieldGrp() ?
1404 30 :
1405 nWidth;
1406
1407 while (ConsiderNextPortionForCursorOffset(pPor, nWidth30, nX))
1408 {
1409 nX = nX - nWidth;
1410 nCurrStart = nCurrStart + pPor->GetLen();
1411 bHolePortion = pPor->IsHolePortion();
1412 pPor = pPor->GetNextPortion();
1413 nWidth = pPor->Width();
1414 if ( m_pCurr->IsSpaceAdd() || pKanaComp )
1415 {
1416 if ( pPor->InSpaceGrp() && nSpaceAdd )
1417 {
1418 const_cast<SwTextSizeInfo&>(GetInfo()).SetIdx( nCurrStart );
1419 nWidth = nWidth + sal_uInt16( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) );
1420 }
1421
1422 if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) ||
1423 ( pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->HasTabulator() )
1424 )
1425 {
1426 if ( m_pCurr->IsSpaceAdd() )
1427 {
1428 if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
1429 nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx );
1430 else
1431 nSpaceAdd = 0;
1432 }
1433
1434 if ( pKanaComp )
1435 {
1436 if( nKanaIdx + 1 < pKanaComp->size() )
1437 nKanaComp = (*pKanaComp)[++nKanaIdx];
1438 else
1439 nKanaComp = 0;
1440 }
1441 }
1442 }
1443
1444 if ( pPor->IsPostItsPortion() )
1445 nWidth30 = 0;
1446 else
1447 nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFieldGrp() ?
1448 30 :
1449 nWidth;
1450 if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
1451 bLastHyph = pPor->InHyphGrp();
1452 }
1453
1454 const bool bLastPortion = (nullptr == pPor->GetNextPortion());
1455
1456 if( nX==nWidth )
1457 {
1458 SwLinePortion *pNextPor = pPor->GetNextPortion();
1459 while( pNextPor && pNextPor->InFieldGrp() && !pNextPor->Width() )
1460 {
1461 nCurrStart = nCurrStart + pPor->GetLen();
1462 pPor = pNextPor;
1463 if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
1464 bLastHyph = pPor->InHyphGrp();
1465 pNextPor = pPor->GetNextPortion();
1466 }
1467 }
1468
1469 const_cast<SwTextSizeInfo&>(GetInfo()).SetIdx( nOldIdx );
1470
1471 TextFrameIndex nLength = pPor->GetLen();
1472
1473 const bool bFieldInfo = pCMS && pCMS->m_bFieldInfo;
1474
1475 if( bFieldInfo && ( nWidth30 < nX || bRightOver || bLeftOver ||
1476 ( pPor->InNumberGrp() && !pPor->IsFootnoteNumPortion() ) ||
1477 ( pPor->IsMarginPortion() && nWidth > nX + 30 ) ) )
1478 pCMS->m_bPosCorr = true;
1479
1480 // #i27615#
1481 if (pCMS && pCMS->m_bInFrontOfLabel)
1482 {
1483 if (2 * nX >= nWidth || !pPor->InNumberGrp() || pPor->IsFootnoteNumPortion())
1484 pCMS->m_bInFrontOfLabel = false;
1485 }
1486
1487 // 7684: We are exactly ended up at their HyphPortion. It is our task to
1488 // provide, that we end up in the String.
1489 // 7993: If length = 0, then we must exit...
1490 if( !nLength )
1491 {
1492 if( pCMS )
1493 {
1494 if( pPor->IsFlyPortion() && bFieldInfo )
1495 pCMS->m_bPosCorr = true;
1496
1497 if (!bRightOver && nX)
1498 {
1499 if( pPor->IsFootnoteNumPortion())
1500 pCMS->m_bFootnoteNoInfo = true;
1501 else if (pPor->InNumberGrp() ) // #i23726#
1502 {
1503 pCMS->m_nInNumPortionOffset = nX;
1504 pCMS->m_bInNumPortion = true;
1505 }
1506 }
1507 }
1508 if( !nCurrStart )
1509 return TextFrameIndex(0);
1510
1511 // 7849, 7816: pPor->GetHyphPortion is mandatory!
1512 if( bHolePortion || ( !bRightAllowed && bLastHyph ) ||
1513 ( pPor->IsMarginPortion() && !pPor->GetNextPortion() &&
1514 // 46598: Consider the situation: We might end up behind the last character,
1515 // in the last line of a centered paragraph
1516 nCurrStart < TextFrameIndex(rText.getLength())))
1517 --nCurrStart;
1518 else if( pPor->InFieldGrp() && static_cast<SwFieldPortion*>(pPor)->IsFollow()
1519 && nWidth > nX )
1520 {
1521 if( bFieldInfo )
1522 --nCurrStart;
1523 else
1524 {
1525 sal_uInt16 nHeight = pPor->Height();
1526 if ( !nHeight || nHeight > nWidth )
1527 nHeight = nWidth;
1528 if( bChgNode && nWidth - nHeight/2 > nX )
1529 --nCurrStart;
1530 }
1531 }
1532 return nCurrStart;
1533 }
1534 if (TextFrameIndex(1) == nLength || pPor->InFieldGrp())
1535 {
1536 if ( nWidth )
1537 {
1538 // no quick return for as-character frames, we want to peek inside
1539 if (!(bChgNode && pPos && pPor->IsFlyCntPortion())
1540 // if we want to get the position inside the field, we should not return
1541 && (!pCMS || !pCMS->m_pSpecialPos))
1542 {
1543 if ( pPor->InFieldGrp() ||
1544 ( pPor->IsMultiPortion() &&
1545 static_cast<SwMultiPortion*>(pPor)->IsBidi() ) )
1546 {
1547 sal_uInt16 nHeight = 0;
1548 if( !bFieldInfo )
1549 {
1550 nHeight = pPor->Height();
1551 if ( !nHeight || nHeight > nWidth )
1552 nHeight = nWidth;
1553 }
1554
1555 if( nWidth - nHeight/2 <= nX &&
1556 ( ! pPor->InFieldGrp() ||
1557 !static_cast<SwFieldPortion*>(pPor)->HasFollow() ) )
1558 {
1559 if (pPor->InFieldGrp())
1560 {
1561 nCurrStart += static_cast<SwFieldPortion*>(pPor)->GetFieldLen();
1562 }
1563 else
1564 {
1565 ++nCurrStart;
1566 }
1567 }
1568 }
1569 else if ( ( !pPor->IsFlyPortion() || ( pPor->GetNextPortion() &&
1570 !pPor->GetNextPortion()->IsMarginPortion() &&
1571 !pPor->GetNextPortion()->IsHolePortion() ) )
1572 && ( nWidth/2 < nX ) &&
1573 ( !bFieldInfo ||
1574 ( pPor->GetNextPortion() &&
1575 pPor->GetNextPortion()->IsPostItsPortion() ) )
1576 && ( bRightAllowed || !bLastHyph ))
1577 ++nCurrStart;
1578
1579 return nCurrStart;
1580 }
1581 }
1582 else
1583 {
1584 if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() ||
1585 pPor->InToxRefGrp() )
1586 {
1587 SwPostItsPortion* pPostItsPortion = pPor->IsPostItsPortion() ? dynamic_cast<SwPostItsPortion*>(pPor) : nullptr;
1588 if (pPostItsPortion)
1589 {
1590 if (!pPostItsPortion->IsScript()) // tdf#141079
1591 {
1592 // Offset would be nCurrStart + nLength below, do the same for post-it portions.
1593 nCurrStart += pPor->GetLen();
1594 }
1595 }
1596 return nCurrStart;
1597 }
1598 if ( pPor->InFieldGrp() )
1599 {
1600 if( bRightOver && !static_cast<SwFieldPortion*>(pPor)->HasFollow() )
1601 {
1602 nCurrStart += static_cast<SwFieldPortion*>(pPor)->GetFieldLen();
1603 }
1604 return nCurrStart;
1605 }
1606 }
1607 }
1608
1609 // Skip space at the end of the line
1610 if( bLastPortion && (m_pCurr->GetNext() || m_pFrame->GetFollow() )
1611 && rText[sal_Int32(nCurrStart + nLength) - 1] == ' ' )
1612 --nLength;
1613
1614 if( nWidth > nX ||
1615 ( nWidth == nX && pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->IsDouble() ) )
1616 {
1617 if( pPor->IsMultiPortion() )
1618 {
1619 // In a multi-portion we use GetModelPositionForViewPoint()-function recursively
1620 SwTwips nTmpY = rPoint.Y() - m_pCurr->GetAscent() + pPor->GetAscent();
1621 // if we are in the first line of a double line portion, we have
1622 // to add a value to nTmpY for not staying in this line
1623 // we also want to skip the first line, if we are inside ruby
1624 if ( ( static_cast<SwTextSizeInfo*>(m_pInf)->IsMulti() &&
1625 static_cast<SwTextSizeInfo*>(m_pInf)->IsFirstMulti() ) ||
1626 ( static_cast<SwMultiPortion*>(pPor)->IsRuby() &&
1627 static_cast<SwMultiPortion*>(pPor)->OnTop() ) )
1628 nTmpY += static_cast<SwMultiPortion*>(pPor)->Height();
1629
1630 // Important for cursor traveling in ruby portions:
1631 // We have to set nTmpY to 0 in order to stay in the first row
1632 // if the phonetic line is the second row
1633 if ( static_cast<SwMultiPortion*>(pPor)->IsRuby() &&
1634 ! static_cast<SwMultiPortion*>(pPor)->OnTop() )
1635 nTmpY = 0;
1636
1637 SwTextCursorSave aSave( const_cast<SwTextCursor*>(this), static_cast<SwMultiPortion*>(pPor),
1638 nTmpY, nX, nCurrStart, nSpaceAdd );
1639
1640 SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
1641 if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
1642 {
1643 const sal_uInt8 nBidiLevel = static_cast<SwBidiPortion*>(pPor)->GetLevel();
1644 aLayoutModeModifier.Modify( nBidiLevel % 2 );
1645 }
1646
1647 if( static_cast<SwMultiPortion*>(pPor)->HasRotation() )
1648 {
1649 nTmpY -= m_nY;
1650 if( !static_cast<SwMultiPortion*>(pPor)->IsRevers() )
1651 nTmpY = pPor->Height() - nTmpY;
1652 if( nTmpY < 0 )
1653 nTmpY = 0;
1654 nX = o3tl::narrowing<sal_uInt16>(nTmpY);
1655 }
1656
1657 if( static_cast<SwMultiPortion*>(pPor)->HasBrackets() )
1658 {
1659 const sal_uInt16 nPreWidth = static_cast<SwDoubleLinePortion*>(pPor)->PreWidth();
1660 if ( nX > nPreWidth )
1661 nX = nX - nPreWidth;
1662 else
1663 nX = 0;
1664 }
1665
1666 return GetModelPositionForViewPoint( pPos, Point( GetLineStart() + nX, rPoint.Y() ),
1667 bChgNode, pCMS );
1668 }
1669 if( pPor->InTextGrp() || pPor->IsHolePortion() )
1670 {
1671 sal_uInt8 nOldProp;
1672 if( GetPropFont() )
1673 {
1674 const_cast<SwFont*>(GetFnt())->SetProportion( GetPropFont() );
1675 nOldProp = GetFnt()->GetPropr();
1676 }
1677 else
1678 nOldProp = 0;
1679 {
1680 SwTextSizeInfo aSizeInf( GetInfo(), &rText, nCurrStart );
1681 const_cast<SwTextCursor*>(this)->SeekAndChg( aSizeInf );
1682 SwTextSlot aDiffText( &aSizeInf, pPor, false, false );
1683 SwFontSave aSave( aSizeInf, pPor->IsDropPortion() ?
1684 static_cast<SwDropPortion*>(pPor)->GetFnt() : nullptr );
1685
1686 SwParaPortion* pPara = const_cast<SwParaPortion*>(GetInfo().GetParaPortion());
1687 OSL_ENSURE( pPara, "No paragraph!" );
1688
1689 // protect against bugs elsewhere
1690 SAL_WARN_IF( aSizeInf.GetIdx().get() + pPor->GetLen().get() > aSizeInf.GetText().getLength(), "sw", "portion and text are out of sync" );
1691 TextFrameIndex nSafeLen( std::min(pPor->GetLen().get(), aSizeInf.GetText().getLength() - aSizeInf.GetIdx().get()) );
1692
1693 SwDrawTextInfo aDrawInf( aSizeInf.GetVsh(),
1694 *aSizeInf.GetOut(),
1695 &pPara->GetScriptInfo(),
1696 aSizeInf.GetText(),
1697 aSizeInf.GetIdx(),
1698 nSafeLen );
1699
1700 // Drop portion works like a multi portion, just its parts are not portions
1701 if( pPor->IsDropPortion() && static_cast<SwDropPortion*>(pPor)->GetLines() > 1 )
1702 {
1703 SwDropPortion* pDrop = static_cast<SwDropPortion*>(pPor);
1704 const SwDropPortionPart* pCurrPart = pDrop->GetPart();
1705 sal_uInt16 nSumWidth = 0;
1706 sal_uInt16 nSumBorderWidth = 0;
1707 // Shift offset with the right and left border of previous parts and left border of actual one
1708 while (pCurrPart && nSumWidth <= nX - sal_Int32(nCurrStart))
1709 {
1710 nSumWidth += pCurrPart->GetWidth();
1711 if( pCurrPart->GetFont().GetLeftBorder() && !pCurrPart->GetJoinBorderWithPrev() )
1712 {
1713 nSumBorderWidth += pCurrPart->GetFont().GetLeftBorderSpace();
1714 }
1715 if (nSumWidth <= nX - sal_Int32(nCurrStart) && pCurrPart->GetFont().GetRightBorder() &&
1716 !pCurrPart->GetJoinBorderWithNext() )
1717 {
1718 nSumBorderWidth += pCurrPart->GetFont().GetRightBorderSpace();
1719 }
1720 pCurrPart = pCurrPart->GetFollow();
1721 }
1722 nX = std::max(static_cast<SwTwips>(0), nX - nSumBorderWidth);
1723 }
1724 // Shift the offset with the left border width
1725 else if( GetInfo().GetFont()->GetLeftBorder() && !pPor->GetJoinBorderWithPrev() )
1726 {
1727 nX = std::max(static_cast<SwTwips>(0), nX - GetInfo().GetFont()->GetLeftBorderSpace());
1728 }
1729
1730 aDrawInf.SetOffset( nX );
1731
1732 if ( nSpaceAdd )
1733 {
1734 TextFrameIndex nCharCnt(0);
1735 // #i41860# Thai justified alignment needs some
1736 // additional information:
1737 aDrawInf.SetNumberOfBlanks( pPor->InTextGrp() ?
1738 static_cast<const SwTextPortion*>(pPor)->GetSpaceCnt( aSizeInf, nCharCnt ) :
1739 TextFrameIndex(0) );
1740 }
1741
1742 if ( pPor->InFieldGrp() && pCMS && pCMS->m_pSpecialPos )
1744
1745 aDrawInf.SetSpace( nSpaceAdd );
1746 aDrawInf.SetFont( aSizeInf.GetFont() );
1747 aDrawInf.SetFrame( m_pFrame );
1748 aDrawInf.SetSnapToGrid( aSizeInf.SnapToGrid() );
1749 aDrawInf.SetPosMatchesBounds( pCMS && pCMS->m_bPosMatchesBounds );
1750
1751 if ( SwFontScript::CJK == aSizeInf.GetFont()->GetActual() &&
1752 pPara->GetScriptInfo().CountCompChg() &&
1753 ! pPor->InFieldGrp() )
1754 aDrawInf.SetKanaComp( nKanaComp );
1755
1756 nLength = aSizeInf.GetFont()->GetModelPositionForViewPoint_( aDrawInf );
1757
1758 // get position inside field portion?
1759 if ( pPor->InFieldGrp() && pCMS && pCMS->m_pSpecialPos )
1760 {
1761 pCMS->m_pSpecialPos->nCharOfst = sal_Int32(nLength);
1763 }
1764
1765 // set cursor bidi level
1766 if ( pCMS )
1767 pCMS->m_nCursorBidiLevel =
1768 aDrawInf.GetCursorBidiLevel();
1769
1770 if( bFieldInfo && nLength == pPor->GetLen() &&
1771 ( ! pPor->GetNextPortion() ||
1772 ! pPor->GetNextPortion()->IsPostItsPortion() ) )
1773 --nLength;
1774 }
1775 if( nOldProp )
1776 const_cast<SwFont*>(GetFnt())->SetProportion( nOldProp );
1777 }
1778 else
1779 {
1780 sw::FlyContentPortion* pFlyPor(nullptr);
1781 if(bChgNode && pPos && (pFlyPor = dynamic_cast<sw::FlyContentPortion*>(pPor)))
1782 {
1783 // JP 24.11.94: if the Position is not in Fly, then
1784 // we many not return with COMPLETE_STRING as value!
1785 // (BugId: 9692 + Change in feshview)
1786 SwFlyInContentFrame *pTmp = pFlyPor->GetFlyFrame();
1787 SwFrame* pLower = pTmp->GetLower();
1788 // Allow non-text-frames to get SwGrfNode for as-char anchored images into pPos
1789 // instead of the closest SwTextNode, to be consistent with at-char behavior.
1790 bool bChgNodeInner = pLower
1791 && (pLower->IsTextFrame() || pLower->IsLayoutFrame() || pLower->IsNoTextFrame());
1792 Point aTmpPoint( rPoint );
1793
1794 if ( m_pFrame->IsRightToLeft() )
1795 m_pFrame->SwitchLTRtoRTL( aTmpPoint );
1796
1797 if ( m_pFrame->IsVertical() )
1799
1800 if( bChgNodeInner && pTmp->getFrameArea().Contains( aTmpPoint ) &&
1801 !( pTmp->IsProtected() ) )
1802 {
1803 pFlyPor->GetFlyCursorOfst(aTmpPoint, *pPos, pCMS);
1804 // After a change of the frame, our font must be still
1805 // available for/in the OutputDevice.
1806 // For comparison: Paint and new SwFlyCntPortion !
1807 static_cast<SwTextSizeInfo*>(m_pInf)->SelectFont();
1808
1809 // 6776: The pIter->GetModelPositionForViewPoint is returning here
1810 // from a nesting with COMPLETE_STRING.
1812 }
1813 }
1814 else
1816 }
1817 }
1818 nOffset = nCurrStart + nLength;
1819
1820 // 7684: We end up in front of the HyphPortion. We must assure
1821 // that we end up in the string.
1822 // If we are at end of line in front of FlyFrames, we must proceed the same way.
1823 if( nOffset && pPor->GetLen() == nLength && pPor->GetNextPortion() &&
1824 !pPor->GetNextPortion()->GetLen() && pPor->GetNextPortion()->InHyphGrp() )
1825 --nOffset;
1826
1827 return nOffset;
1828}
1829
1847bool SwTextFrame::FillSelection( SwSelectionList& rSelList, const SwRect& rRect ) const
1848{
1849 bool bRet = false;
1850 // GetPaintArea() instead getFrameArea() for negative indents
1851 SwRect aTmpFrame( GetPaintArea() );
1852 if( !rRect.Overlaps( aTmpFrame ) )
1853 return false;
1854 if( rSelList.checkContext( this ) )
1855 {
1856 SwRect aRect( aTmpFrame );
1857 aRect.Intersection( rRect );
1859 if( IsEmpty() )
1860 {
1861 SwPaM *pPam = new SwPaM( aPosL, aPosL );
1862 rSelList.insertPaM( pPam );
1863 }
1864 else if( aRect.HasArea() )
1865 {
1866 SwPosition aOld(aPosL.GetNodes().GetEndOfContent());
1867 SwPosition aPosR( aPosL );
1868 Point aPoint;
1869 SwTextInfo aInf( const_cast<SwTextFrame*>(this) );
1870 SwTextIter aLine( const_cast<SwTextFrame*>(this), &aInf );
1871 // We have to care for top-to-bottom layout, where right becomes top etc.
1872 SwRectFnSet aRectFnSet(this);
1873 SwTwips nTop = aRectFnSet.GetTop(aRect);
1874 SwTwips nBottom = aRectFnSet.GetBottom(aRect);
1875 SwTwips nLeft = aRectFnSet.GetLeft(aRect);
1876 SwTwips nRight = aRectFnSet.GetRight(aRect);
1877 SwTwips nY = aLine.Y(); // Top position of the first line
1878 SwTwips nLastY = nY;
1879 while( nY < nTop && aLine.Next() ) // line above rectangle
1880 {
1881 nLastY = nY;
1882 nY = aLine.Y();
1883 }
1884 bool bLastLine = false;
1885 if( nY < nTop && !aLine.GetNext() )
1886 {
1887 bLastLine = true;
1888 nY += aLine.GetLineHeight();
1889 }
1890 do // check the lines for overlapping
1891 {
1892 if( nLastY < nTop ) // if the last line was above rectangle
1893 nLastY = nTop;
1894 if( nY > nBottom ) // if the current line leaves the rectangle
1895 nY = nBottom;
1896 if( nY >= nLastY ) // gotcha: overlapping
1897 {
1898 nLastY += nY;
1899 nLastY /= 2;
1900 if( aRectFnSet.IsVert() )
1901 {
1902 aPoint.setX( nLastY );
1903 aPoint.setY( nLeft );
1904 }
1905 else
1906 {
1907 aPoint.setX( nLeft );
1908 aPoint.setY( nLastY );
1909 }
1910 // Looking for the position of the left border of the rectangle
1911 // in this text line
1913 if( GetModelPositionForViewPoint( &aPosL, aPoint, &aState ) )
1914 {
1915 if( aRectFnSet.IsVert() )
1916 {
1917 aPoint.setX( nLastY );
1918 aPoint.setY( nRight );
1919 }
1920 else
1921 {
1922 aPoint.setX( nRight );
1923 aPoint.setY( nLastY );
1924 }
1925 // If we get a right position and if the left position
1926 // is not the same like the left position of the line before
1927 // which could happen e.g. for field portions or fly frames
1928 // a SwPaM will be inserted with these positions
1929 if( GetModelPositionForViewPoint( &aPosR, aPoint, &aState ) &&
1930 aOld != aPosL)
1931 {
1932 SwPaM *pPam = new SwPaM( aPosL, aPosR );
1933 rSelList.insertPaM( pPam );
1934 aOld = aPosL;
1935 }
1936 }
1937 }
1938 if( aLine.Next() )
1939 {
1940 nLastY = nY;
1941 nY = aLine.Y();
1942 }
1943 else if( !bLastLine )
1944 {
1945 bLastLine = true;
1946 nLastY = nY;
1947 nY += aLine.GetLineHeight();
1948 }
1949 else
1950 break;
1951 }while( nLastY < nBottom );
1952 }
1953 }
1954 if( GetDrawObjs() )
1955 {
1956 const SwSortedObjs &rObjs = *GetDrawObjs();
1957 for (SwAnchoredObject* pAnchoredObj : rObjs)
1958 {
1959 const SwFlyFrame* pFly = pAnchoredObj->DynCastFlyFrame();
1960 if( !pFly )
1961 continue;
1962 if( pFly->IsFlyInContentFrame() && pFly->FillSelection( rSelList, rRect ) )
1963 bRet = true;
1964 }
1965 }
1966 return bRet;
1967}
1968
1969/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ IGNORE_FIRST_LINE_INDENT_IN_NUMBERING
@ AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
constexpr tools::Long Height() const
SvxAdjust GetLastBlock() const
SvxAdjust GetAdjust() const
SvxAdjust GetOneWord() const
bool IsAutoFirst() const
tools::Long GetTextLeft() const
tools::Long GetLeft() const
sal_uInt16 GetPropLineSpace() const
SvxInterLineSpaceRule GetInterLineSpaceRule() const
SvxLineSpaceRule GetLineSpaceRule() const
sal_uInt16 GetLineHeight() const
short GetInterLineSpace() const
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
wrapper class for the positioning of Writer fly frames and drawing objects
SwFont * GetFnt()
Definition: itratr.hxx:103
void SetPropFont(const sal_uInt8 nNew)
Definition: itratr.hxx:107
sal_uInt8 GetPropFont() const
Definition: itratr.hxx:106
bool Seek(TextFrameIndex nPos)
Enables the attributes used at char pos nPos in the logical font.
Definition: itratr.cxx:302
const SvxAdjustItem & GetAdjust(bool=true) const
Definition: paratr.hxx:194
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:44
virtual tools::Long CalcSpacing(tools::Long nSpaceAdd, const SwTextSizeInfo &rInf) const override
Definition: pormulti.cxx:221
sal_uInt8 GetLevel() const
Definition: pormulti.hxx:226
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:765
static void ResetSpaceAdd(SwLineLayout *pCurr)
Definition: pormulti.cxx:551
void SetPosMatchesBounds(bool bNew)
Definition: drawfont.hxx:620
void SetNumberOfBlanks(TextFrameIndex const nNew)
Definition: drawfont.hxx:556
void SetSnapToGrid(bool bNew)
Definition: drawfont.hxx:610
void SetOffset(sal_Int32 nNew)
Definition: drawfont.hxx:504
sal_uInt8 GetCursorBidiLevel() const
Definition: drawfont.hxx:352
void SetFont(SwFont *pNew)
Definition: drawfont.hxx:478
void SetKanaComp(short nNew)
Definition: drawfont.hxx:569
void SetLen(TextFrameIndex const nNew)
Definition: drawfont.hxx:492
void SetFrame(const SwTextFrame *pNewFrame)
Definition: drawfont.hxx:176
void SetSpace(tools::Long nNew)
Definition: drawfont.hxx:538
bool GetJoinBorderWithPrev() const
Definition: pordrop.hxx:57
bool GetJoinBorderWithNext() const
Definition: pordrop.hxx:58
TextFrameIndex GetLen() const
Definition: pordrop.hxx:53
SwFont & GetFont() const
Definition: pordrop.hxx:52
SwDropPortionPart * GetFollow() const
Definition: pordrop.hxx:50
sal_uInt16 GetWidth() const
Definition: pordrop.hxx:54
Text portion for the Format -> Paragraph -> Drop Caps functionality.
Definition: pordrop.hxx:65
sal_uInt16 GetDropHeight() const
Definition: pordrop.hxx:93
sal_uInt16 GetDropDescent() const
Definition: pordrop.hxx:94
SwFont * GetFnt() const
Definition: pordrop.hxx:102
sal_uInt16 GetLines() const
Definition: pordrop.hxx:91
sal_uInt16 GetDropLeft() const
Definition: pordrop.hxx:95
SwDropPortionPart * GetPart() const
Definition: pordrop.hxx:97
bool IsFollow() const
Definition: porfld.hxx:83
bool HasFollow() const
Definition: porfld.hxx:95
const OUString & GetExp() const
Definition: porfld.hxx:73
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
virtual const SwFlyFrame * DynCastFlyFrame() const override
Definition: fly.cxx:2989
bool IsFlyInContentFrame() const
Definition: flyfrm.hxx:215
const std::optional< editeng::SvxBorderLine > & GetRightBorder() const
Definition: swfont.hxx:345
const Size & GetSize(SwFontScript nWhich) const
Definition: swfont.hxx:206
sal_uInt16 GetRightBorderSpace() const
Definition: swfont.hxx:892
void SetProportion(const sal_uInt8 nNewPropr)
Definition: swfont.hxx:769
SwFontScript GetActual() const
Definition: swfont.hxx:184
sal_uInt8 GetPropr() const
Definition: swfont.hxx:281
TextFrameIndex GetModelPositionForViewPoint_(SwDrawTextInfo &rInf)
Definition: swfont.hxx:315
const std::optional< editeng::SvxBorderLine > & GetLeftBorder() const
Definition: swfont.hxx:346
sal_uInt16 GetLeftBorderSpace() const
Definition: swfont.hxx:907
void SetActual(SwFontScript nNew)
Definition: swfont.hxx:751
const SwRect & getFrameArea() const
Definition: frame.hxx:179
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
Base class of the Writer layout elements.
Definition: frame.hxx:315
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed.
Definition: ssfrm.cxx:593
bool IsTextFrame() const
Definition: frame.hxx:1234
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
bool IsInTab() const
Definition: frame.hxx:955
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1639
SwFrame * GetLower()
Definition: findfrm.cxx:194
bool IsRightToLeft() const
Definition: frame.hxx:987
bool IsVertical() const
Definition: frame.hxx:973
bool IsNoTextFrame() const
Definition: frame.hxx:1238
bool IsLayoutFrame() const
Definition: frame.hxx:1170
virtual bool FillSelection(SwSelectionList &rList, const SwRect &rRect) const override
Definition: trvlfrm.cxx:367
void Modify(bool bChgToRTL)
Definition: txtfrm.cxx:711
const SvxLineSpacingItem * GetLineSpacing() const
Definition: inftxt.hxx:79
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:79
bool IsHanging() const
Definition: porlay.hxx:145
SwLineLayout * GetNext()
Definition: porlay.hxx:159
SwLinePortion * GetFirstPortion() const
Definition: porlay.cxx:849
tools::Long GetLLSpaceAdd(sal_uInt16 nIdx)
Definition: porlay.hxx:195
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:239
SwTwips GetHangingMargin() const
Definition: porlay.hxx:176
void SetRealHeight(SwTwips nNew)
Definition: porlay.hxx:168
SwTwips GetRealHeight() const
Definition: porlay.hxx:169
bool IsSpaceAdd() const
Definition: porlay.hxx:183
std::deque< sal_uInt16 > * GetpKanaComp() const
Definition: porlay.hxx:202
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:52
bool InToxRefOrFieldGrp() const
Definition: porlin.hxx:113
void PrtWidth(SwTwips nNewWidth)
Definition: porlin.hxx:83
bool IsBlankPortion() const
Definition: porlin.hxx:120
bool IsTextPortion() const
Definition: porlin.hxx:139
bool IsMarginPortion() const
Definition: porlin.hxx:133
bool InTextGrp() const
Definition: porlin.hxx:105
virtual TextFrameIndex GetModelPositionForViewPoint(sal_uInt16 nOfst) const
the parameter is actually SwTwips apparently?
Definition: porlin.cxx:223
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:75
bool GetJoinBorderWithPrev() const
Definition: porlin.hxx:177
bool InNumberGrp() const
Definition: porlin.hxx:109
bool IsPostItsPortion() const
Definition: porlin.hxx:137
TextFrameIndex GetLen() const
Definition: porlin.hxx:77
SwLinePortion * FindLastPortion()
Definition: porlin.cxx:179
bool IsKernPortion() const
Definition: porlin.hxx:141
bool GetJoinBorderWithNext() const
Definition: porlin.hxx:178
bool InToxRefGrp() const
Definition: porlin.hxx:112
bool InHyphGrp() const
Definition: porlin.hxx:108
SwTwips & GetAscent()
Definition: porlin.hxx:80
bool InSpaceGrp() const
Definition: porlin.hxx:116
bool IsDropPortion() const
Definition: porlin.hxx:130
bool InTabGrp() const
Definition: porlin.hxx:107
virtual tools::Long CalcSpacing(tools::Long nSpaceAdd, const SwTextSizeInfo &rInf) const
Definition: porlin.cxx:306
bool IsBreakPortion() const
Definition: porlin.hxx:121
bool InFixGrp() const
Definition: porlin.hxx:110
void SetLen(TextFrameIndex const nLen)
Definition: porlin.hxx:78
bool IsMultiPortion() const
Definition: porlin.hxx:143
bool IsHolePortion() const
Definition: porlin.hxx:135
bool InFieldGrp() const
Definition: porlin.hxx:111
virtual SwPosSize GetTextSize(const SwTextSizeInfo &rInfo) const
Definition: porlin.cxx:231
bool IsFlyPortion() const
Definition: porlin.hxx:134
bool IsFootnoteNumPortion() const
Definition: porlin.hxx:128
SwTwips ExtraBlankWidth() const
Definition: porlin.hxx:87
bool IsFlyCntPortion() const
Definition: porlin.hxx:119
bool InFixMargGrp() const
Definition: porlin.hxx:115
bool IsDouble() const
Definition: pormulti.hxx:130
bool IsRuby() const
Definition: pormulti.hxx:131
bool HasRotation() const
Definition: pormulti.hxx:146
bool IsBidi() const
Definition: pormulti.hxx:132
bool HasTabulator() const
Definition: pormulti.hxx:123
bool IsRevers() const
Definition: pormulti.hxx:147
const IDocumentSettingAccess * getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: node.cxx:2153
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:87
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
Definition: porlay.hxx:251
const SwDropPortion * FindDropPortion() const
Definition: porlay.cxx:2686
SwScriptInfo & GetScriptInfo()
Definition: porlay.hxx:291
SwTwips Width() const
Definition: possiz.hxx:51
SwTwips Height() const
Definition: possiz.hxx:49
bool IsScript() const
Definition: porexp.hxx:75
bool IsVert() const
Definition: frame.hxx:1366
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1376
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1378
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1377
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1379
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:57
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool HasArea() const
Definition: swrect.hxx:300
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Pos(const Point &rNew)
Definition: swrect.hxx:171
void SSize(const Size &rNew)
Definition: swrect.hxx:180
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
bool Overlaps(const SwRect &rRect) const
Definition: swrect.hxx:374
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:900
size_t CountCompChg() const
Definition: scriptinfo.hxx:163
This class is used as parameter for creation of a block cursor selection.
void insertPaM(SwPaM *pPam)
Adds a text portion to the selection list.
bool checkContext(const SwFrame *pCheck)
Checks if the context of the list is equal to the context of the frame.
class for collecting anchored objects
Definition: sortedobjs.hxx:49
void GetAdjusted() const
Definition: itrtxt.hxx:250
const SwLineLayout * CharCursorToLine(TextFrameIndex const nPos)
Definition: itrtxt.cxx:203
TextFrameIndex GetModelPositionForViewPoint(SwPosition *pPos, const Point &rPoint, bool bChgNode, SwCursorMoveState *=nullptr) const
Definition: itrcrsr.cxx:1324
static bool s_bRightMargin
Definition: itrtxt.hxx:268
void GetCharRect_(SwRect *, TextFrameIndex, SwCursorMoveState *)
Definition: itrcrsr.cxx:500
SwTwips AdjustBaseLine(const SwLineLayout &rLine, const SwLinePortion *pPor, SwTwips nPorHeight=0, SwTwips nAscent=0, const bool bAutoToCentered=false) const
Definition: itrtxt.cxx:215
void AddExtraBlankWidth()
Definition: itrcrsr.cxx:406
void GetCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const tools::Long nMax=0)
Definition: itrcrsr.cxx:1226
void GetEndCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const tools::Long nMax=0)
Definition: itrcrsr.cxx:425
void CtorInitTextCursor(SwTextFrame *pFrame, SwTextSizeInfo *pInf)
Definition: itrcrsr.cxx:397
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:861
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1246
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1343
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:444
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:683
SwTwips GetAdditionalFirstLineOffset() const
Definition: txtfrm.hxx:645
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout.
Definition: txtfrm.cxx:473
virtual bool FillSelection(SwSelectionList &rList, const SwRect &rRect) const override
Looks for text portions which are inside the given rectangle.
Definition: itrcrsr.cxx:1847
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1303
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
In nOffset returns the offset of the char within the set text buffer, which is closest to the positio...
Definition: frmcrsr.cxx:661
bool IsEmpty() const
Definition: txtfrm.hxx:527
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
SwParaPortion * GetParaPortion()
Definition: inftxt.hxx:121
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:89
SwTwips Y() const
Definition: itrtxt.hxx:90
const SwLineLayout * GetNext() const
Definition: itrtxt.hxx:84
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:88
SwTwips m_nY
Definition: itrtxt.hxx:39
const SwLineLayout * PrevLine()
Definition: itrtxt.cxx:171
bool m_bLastCenter
Definition: itrtxt.hxx:48
SwLineLayout * m_pCurr
Definition: itrtxt.hxx:36
SwTwips GetLineHeight() const
Definition: itrtxt.hxx:116
const SwLineLayout * Next()
Definition: itrtxt.cxx:108
SwTextFrame * m_pFrame
Definition: itrtxt.hxx:34
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
SwTextFrame * GetTextFrame()
Definition: itrtxt.hxx:134
TextFrameIndex m_nStart
Definition: itrtxt.hxx:41
void CalcAscentAndHeight(SwTwips &rAscent, SwTwips &rHeight) const
Definition: itrtxt.cxx:64
const SwLineInfo & GetLineInfo() const
Definition: itrtxt.hxx:128
bool m_bLastBlock
Definition: itrtxt.hxx:47
SwTextInfo * m_pInf
Definition: itrtxt.hxx:35
bool m_bPrev
Definition: itrtxt.hxx:44
SwLineInfo m_aLineInf
Definition: itrtxt.hxx:33
bool m_bOneBlock
Definition: itrtxt.hxx:46
const SwLineLayout * GetPrev()
Definition: itrtxt.cxx:83
bool SeekAndChg(SwTextSizeInfo &rInf)
Definition: itrtxt.hxx:311
void CtorInitTextIter(SwTextFrame *pFrame, SwTextInfo *pInf)
Definition: itrtxt.cxx:35
SwTwips GetLineEnd() const
Definition: itrtxt.hxx:185
void CtorInitTextMargin(SwTextFrame *pFrame, SwTextSizeInfo *pInf)
Definition: itrcrsr.cxx:156
SwTwips mnLeft
Definition: itrtxt.hxx:144
SwTextSizeInfo & GetInfo()
Definition: itrtxt.hxx:216
SwTwips mnTabLeft
Definition: itrtxt.hxx:153
sal_uInt16 mnDropDescent
Definition: itrtxt.hxx:149
sal_uInt16 mnDropHeight
Definition: itrtxt.hxx:148
SwTwips mnFirst
Definition: itrtxt.hxx:146
void DropInit()
Definition: itrcrsr.cxx:363
Point GetTopLeft() const
Definition: itrtxt.hxx:186
SwTwips Right() const
Definition: itrtxt.hxx:181
SvxAdjust mnAdjust
Definition: itrtxt.hxx:151
sal_uInt16 mnDropLeft
Definition: itrtxt.hxx:147
sal_uInt16 mnDropLines
Definition: itrtxt.hxx:150
SwTwips GetLeftMargin() const
Definition: itrtxt.hxx:329
sal_uInt16 GetDropHeight() const
Definition: itrtxt.hxx:205
SwTwips CurrWidth() const
Definition: itrtxt.hxx:183
SvxAdjust GetAdjust() const
Definition: itrtxt.hxx:190
SwTwips GetLineStart() const
Definition: itrcrsr.cxx:381
sal_uInt16 GetLineWidth() const
Definition: itrtxt.hxx:191
SwTwips mnRight
Definition: itrtxt.hxx:145
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:111
tools::Long GetLeftMarginWithNum(bool bTextLeft=false) const
Returns the additional indents of this text node and its numbering.
Definition: ndtxt.cxx:3275
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2919
int GetActualListLevel(SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4240
bool GetFirstLineOfsWithNum(short &rFirstOffset) const
Returns the combined first line indent of this text node and its numbering.
Definition: ndtxt.cxx:3318
tools::Long GetLeftMarginForTabCalculation() const
return left margin for tab stop position calculation
Definition: ndtxt.cxx:3422
bool AreListLevelIndentsApplicable() const
Determines, if the list level indent attributes can be applied to the paragraph.
Definition: ndtxt.cxx:4606
This portion represents a part of the paragraph string.
Definition: portxt.hxx:27
TextFrameIndex GetSpaceCnt(const SwTextSizeInfo &rInf, TextFrameIndex &rCnt) const
Definition: portxt.cxx:578
vcl::RenderContext * GetOut()
Definition: inftxt.hxx:225
SwViewShell * GetVsh()
Definition: inftxt.hxx:222
void SetMulti(const bool bNew)
Definition: inftxt.hxx:205
void SetLen(const TextFrameIndex nNew)
Definition: inftxt.hxx:276
TextFrameIndex GetMeasureLen() const
Definition: inftxt.hxx:277
void SetMeasureLen(const TextFrameIndex nNew)
Definition: inftxt.hxx:278
SwFont * GetFont()
Definition: inftxt.hxx:232
bool OnWin() const
Definition: inftxt.hxx:193
void SetIdx(const TextFrameIndex nNew)
Definition: inftxt.hxx:274
void SetFont(SwFont *pNew)
Definition: inftxt.hxx:234
void SetKanaIdx(sal_uInt16 nNew)
Definition: inftxt.hxx:324
void SetFirstMulti(const bool bNew)
Definition: inftxt.hxx:207
void SetKanaComp(std::deque< sal_uInt16 > *pNew)
Definition: inftxt.hxx:326
TextFrameIndex GetLen() const
Definition: inftxt.hxx:275
void SetOnWin(const bool bNew)
Definition: inftxt.hxx:194
const OUString & GetText() const
Definition: inftxt.hxx:240
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:273
bool SnapToGrid() const
Definition: inftxt.hxx:216
bool IsMulti() const
Definition: inftxt.hxx:204
For the text replacement and restoration of SwTextSizeInfo.
Definition: inftxt.hxx:678
void GetFlyCursorOfst(Point &rPoint, SwPosition &rPos, SwCursorMoveState *pCMS) const
Definition: porfly.hxx:79
SwFlyInContentFrame * GetFlyFrame()
Definition: porfly.hxx:78
SwSPExtendRange
SwSpecialPos.
Definition: crstate.hxx:104
@ UpDown
Cursor Up/Down.
float x
static bool ConsiderNextPortionForCursorOffset(const SwLinePortion *pPor, SwTwips nWidth30, sal_uInt16 nX)
Determines if SwTextCursor::GetModelPositionForViewPoint() should consider the next portion when calc...
Definition: itrcrsr.cxx:1296
static void lcl_GetCharRectInsideField(SwTextSizeInfo &rInf, SwRect &rOrig, const SwCursorMoveState &rCMS, const SwLinePortion &rPor)
Definition: itrcrsr.cxx:53
#define LANGUAGE_JAPANESE
#define LANGUAGE_KOREAN
#define SAL_WARN_IF(condition, area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
tools::Long const nRightMargin
tools::Long const nLeftMargin
double getLength(const B2DPolygon &rCandidate)
int i
long Long
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2595
bool m_bPosCorr
Point had to be corrected.
Definition: crstate.hxx:143
bool m_bInNumPortion
point is in number portion #i23726#
Definition: crstate.hxx:163
bool m_bFootnoteNoInfo
recognized footnote numbering
Definition: crstate.hxx:144
int m_nInNumPortionOffset
distance from number portion's start
Definition: crstate.hxx:164
bool m_b2Lines
Check 2line portions and fill p2Lines.
Definition: crstate.hxx:150
sal_uInt8 m_nCursorBidiLevel
Definition: crstate.hxx:139
CursorMoveState m_eState
Definition: crstate.hxx:138
bool m_bRealHeight
should the real height be calculated?
Definition: crstate.hxx:141
std::unique_ptr< Sw2LinesPos > m_p2Lines
for selections inside/around 2line portions
Definition: crstate.hxx:135
SwSpecialPos * m_pSpecialPos
for positions inside fields
Definition: crstate.hxx:136
bool m_bRealWidth
Calculation of the width required.
Definition: crstate.hxx:149
bool m_bFieldInfo
should be fields recognized?
Definition: crstate.hxx:142
bool m_bInFrontOfLabel
cursor in front of label
Definition: crstate.hxx:162
Point m_aRealHeight
contains then the position/height of the cursor
Definition: crstate.hxx:137
bool m_bPosMatchesBounds
GetModelPositionForViewPoint should not return the next position if screen position is inside second ...
Definition: crstate.hxx:152
Marks a position in the document model.
Definition: pam.hxx:37
const SwNodes & GetNodes() const
Definition: pam.hxx:78
SwSPExtendRange nExtendRange
Definition: crstate.hxx:112
sal_uInt16 nLineOfst
Definition: crstate.hxx:111
sal_Int32 nCharOfst
Definition: crstate.hxx:110
UNDERLYING_TYPE get() const
tools::Long GetLen(const Point &rPnt)
tools::Long SwTwips
Definition: swtypes.hxx:51
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
unsigned char sal_uInt8
HFONT SelectFont(HDC hDC, HFONT hFont)
sal_Int32 nLength