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