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