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