LibreOffice Module sw (master)  1
frmcrsr.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 <pam.hxx>
22 #include <frmatr.hxx>
23 #include <frmtool.hxx>
24 #include <viewopt.hxx>
25 #include <paratr.hxx>
26 #include <rootfrm.hxx>
27 #include <pagefrm.hxx>
28 #include <colfrm.hxx>
29 #include <swtypes.hxx>
30 #include <editeng/lrspitem.hxx>
31 #include <editeng/tstpitem.hxx>
32 #include <editeng/ulspitem.hxx>
33 #include <editeng/lspcitem.hxx>
34 #include "pormulti.hxx"
35 #include <doc.hxx>
37 #include <sortedobjs.hxx>
38 
39 #include <unicode/ubidi.h>
40 
41 #include <txtfrm.hxx>
42 #include "inftxt.hxx"
43 #include "itrtxt.hxx"
44 #include <crstate.hxx>
45 #include <viewsh.hxx>
46 #include <swfntcch.hxx>
47 #include <flyfrm.hxx>
48 
49 #define MIN_OFFSET_STEP 10
50 
51 using namespace ::com::sun::star;
52 
53 /*
54  * - SurvivalKit: For how long do we get past the last char of the line.
55  * - RightMargin abstains from adjusting position with -1
56  * - GetCharRect returns a GetEndCharRect for CursorMoveState::RightMargin
57  * - GetEndCharRect sets bRightMargin to true
58  * - SwTextCursor::bRightMargin is set to false by CharCursorToLine
59  */
60 
61 namespace
62 {
63 
64 SwTextFrame *GetAdjFrameAtPos( SwTextFrame *pFrame, const SwPosition &rPos,
65  const bool bRightMargin, const bool bNoScroll = true )
66 {
67  // RightMargin in the last master line
68  TextFrameIndex const nOffset = pFrame->MapModelToViewPos(rPos);
69  SwTextFrame *pFrameAtPos = pFrame;
70  if( !bNoScroll || pFrame->GetFollow() )
71  {
72  pFrameAtPos = pFrame->GetFrameAtPos( rPos );
73  if (nOffset < pFrameAtPos->GetOffset() &&
74  !pFrameAtPos->IsFollow() )
75  {
76  assert(pFrameAtPos->MapModelToViewPos(rPos) == nOffset);
77  TextFrameIndex nNew(nOffset);
78  if (nNew < TextFrameIndex(MIN_OFFSET_STEP))
79  nNew = TextFrameIndex(0);
80  else
82  sw_ChangeOffset( pFrameAtPos, nNew );
83  }
84  }
85  while( pFrame != pFrameAtPos )
86  {
87  pFrame = pFrameAtPos;
88  pFrame->GetFormatted();
89  pFrameAtPos = pFrame->GetFrameAtPos( rPos );
90  }
91 
92  if( nOffset && bRightMargin )
93  {
94  while (pFrameAtPos &&
95  pFrameAtPos->MapViewToModelPos(pFrameAtPos->GetOffset()) == rPos &&
96  pFrameAtPos->IsFollow() )
97  {
98  pFrameAtPos->GetFormatted();
99  pFrameAtPos = pFrameAtPos->FindMaster();
100  }
101  OSL_ENSURE( pFrameAtPos, "+GetCharRect: no frame with my rightmargin" );
102  }
103  return pFrameAtPos ? pFrameAtPos : pFrame;
104 }
105 
106 }
107 
109 {
110  // Do not scroll in areas and outside of flies
111  OSL_ENSURE( !pFrame->IsFollow(), "Illegal Scrolling by Follow!" );
112  if( pFrame->GetOffset() != nNew && !pFrame->IsInSct() )
113  {
114  SwFlyFrame *pFly = pFrame->FindFlyFrame();
115  // Attention: if e.g. in a column frame the size is still invalid
116  // we must not scroll around just like that
117  if ( ( pFly && pFly->isFrameAreaDefinitionValid() &&
118  !pFly->GetNextLink() && !pFly->GetPrevLink() ) ||
119  ( !pFly && pFrame->IsInTab() ) )
120  {
121  SwViewShell* pVsh = pFrame->getRootFrame()->GetCurrShell();
122  if( pVsh )
123  {
124  if( pVsh->GetRingContainer().size() > 1 ||
125  ( pFrame->GetDrawObjs() && pFrame->GetDrawObjs()->size() ) )
126  {
127  if( !pFrame->GetOffset() )
128  return false;
129  nNew = TextFrameIndex(0);
130  }
131  pFrame->SetOffset( nNew );
132  pFrame->SetPara( nullptr );
133  pFrame->GetFormatted();
134  if( pFrame->getFrameArea().HasArea() )
135  pFrame->getRootFrame()->GetCurrShell()->InvalidateWindows( pFrame->getFrameArea() );
136  return true;
137  }
138  }
139  }
140  return false;
141 }
142 
144 {
145  SwTextFrame* pRet = this;
146  while( pRet->HasFollow() && nWhere >= pRet->GetFollow()->GetOffset() )
147  pRet = pRet->GetFollow();
148  return *pRet;
149 }
150 
152 {
154  SwTextFrame *pFoll = this;
155  while( pFoll->GetFollow() )
156  {
157  if (nPos > pFoll->GetFollow()->GetOffset())
158  pFoll = pFoll->GetFollow();
159  else
160  {
161  if (nPos == pFoll->GetFollow()->GetOffset()
163  pFoll = pFoll->GetFollow();
164  else
165  break;
166  }
167  }
168  return pFoll;
169 }
170 
171 /*
172  * GetCharRect() returns the char's char line described by aPos.
173  * GetModelPositionForViewPoint() does the reverse: It goes from a document coordinate to
174  * a Pam.
175  * Both are virtual in the frame base class and thus are redefined here.
176  */
177 
178 bool SwTextFrame::GetCharRect( SwRect& rOrig, const SwPosition &rPos,
179  SwCursorMoveState *pCMS, bool bAllowFarAway ) const
180 {
181  OSL_ENSURE( ! IsVertical() || ! IsSwapped(),"SwTextFrame::GetCharRect with swapped frame" );
182 
183  if( IsLocked() || IsHiddenNow() )
184  return false;
185 
186  // Find the right frame first. We need to keep in mind that:
187  // - the cached information could be invalid (GetPara() == 0)
188  // - we could have a Follow
189  // - the Follow chain grows dynamically; the one we end up in
190  // needs to be formatted
191 
192  // Optimisation: reading ahead saves us a GetAdjFrameAtPos
193  const bool bRightMargin = pCMS && ( CursorMoveState::RightMargin == pCMS->m_eState );
194  const bool bNoScroll = pCMS && pCMS->m_bNoScroll;
195  SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), rPos, bRightMargin,
196  bNoScroll );
197  pFrame->GetFormatted();
198 
199  const SwFrame* pTmpFrame = pFrame->GetUpper();
200  if (pTmpFrame->getFrameArea().Top() == FAR_AWAY && !bAllowFarAway)
201  return false;
202 
203  SwRectFnSet aRectFnSet(pFrame);
204  const SwTwips nUpperMaxY = aRectFnSet.GetPrtBottom(*pTmpFrame);
205  const SwTwips nFrameMaxY = aRectFnSet.GetPrtBottom(*pFrame);
206 
207  // nMaxY is an absolute value
208  SwTwips nMaxY = aRectFnSet.IsVert() ?
209  ( aRectFnSet.IsVertL2R() ? std::min( nFrameMaxY, nUpperMaxY ) : std::max( nFrameMaxY, nUpperMaxY ) ) :
210  std::min( nFrameMaxY, nUpperMaxY );
211 
212  bool bRet = false;
213 
214  if ( pFrame->IsEmpty() || ! aRectFnSet.GetHeight(pFrame->getFramePrintArea()) )
215  {
216  Point aPnt1 = pFrame->getFrameArea().Pos() + pFrame->getFramePrintArea().Pos();
217  SwTextNode const*const pTextNd(GetTextNodeForParaProps());
218  short nFirstOffset;
219  pTextNd->GetFirstLineOfsWithNum( nFirstOffset );
220 
221  Point aPnt2;
222  if ( aRectFnSet.IsVert() )
223  {
224  if( nFirstOffset > 0 )
225  aPnt1.AdjustY(nFirstOffset );
226  if ( aPnt1.X() < nMaxY && !aRectFnSet.IsVertL2R() )
227  aPnt1.setX( nMaxY );
228  aPnt2.setX( aPnt1.X() + pFrame->getFramePrintArea().Width() );
229  aPnt2.setY( aPnt1.Y() );
230  if( aPnt2.X() < nMaxY )
231  aPnt2.setX( nMaxY );
232  }
233  else
234  {
235  if( nFirstOffset > 0 )
236  aPnt1.AdjustX(nFirstOffset );
237 
238  if( aPnt1.Y() > nMaxY )
239  aPnt1.setY( nMaxY );
240  aPnt2.setX( aPnt1.X() );
241  aPnt2.setY( aPnt1.Y() + pFrame->getFramePrintArea().Height() );
242  if( aPnt2.Y() > nMaxY )
243  aPnt2.setY( nMaxY );
244  }
245 
246  rOrig = SwRect( aPnt1, aPnt2 );
247 
248  if ( pCMS )
249  {
250  pCMS->m_aRealHeight.setX( 0 );
251  pCMS->m_aRealHeight.setY( aRectFnSet.IsVert() ? -rOrig.Width() : rOrig.Height() );
252  }
253 
254  if ( pFrame->IsRightToLeft() )
255  pFrame->SwitchLTRtoRTL( rOrig );
256 
257  bRet = true;
258  }
259  else
260  {
261  if( !pFrame->HasPara() )
262  return false;
263 
264  SwFrameSwapper aSwapper( pFrame, true );
265  if ( aRectFnSet.IsVert() )
266  nMaxY = pFrame->SwitchVerticalToHorizontal( nMaxY );
267 
268  bool bGoOn = true;
269  TextFrameIndex const nOffset = MapModelToViewPos(rPos);
270  assert(nOffset != TextFrameIndex(COMPLETE_STRING)); // not going to end well
271  TextFrameIndex nNextOfst;
272 
273  do
274  {
275  {
276  SwTextSizeInfo aInf( pFrame );
277  SwTextCursor aLine( pFrame, &aInf );
278  nNextOfst = aLine.GetEnd();
279  // See comment in AdjustFrame
280  // Include the line's last char?
281  if (bRightMargin)
282  aLine.GetEndCharRect( &rOrig, nOffset, pCMS, nMaxY );
283  else
284  aLine.GetCharRect( &rOrig, nOffset, pCMS, nMaxY );
285  bRet = true;
286  }
287 
288  if ( pFrame->IsRightToLeft() )
289  pFrame->SwitchLTRtoRTL( rOrig );
290 
291  if ( aRectFnSet.IsVert() )
292  pFrame->SwitchHorizontalToVertical( rOrig );
293 
294  if( pFrame->IsUndersized() && pCMS && !pFrame->GetNext() &&
295  aRectFnSet.GetBottom(rOrig) == nUpperMaxY &&
296  pFrame->GetOffset() < nOffset &&
297  !pFrame->IsFollow() && !bNoScroll &&
298  TextFrameIndex(pFrame->GetText().getLength()) != nNextOfst)
299  {
300  bGoOn = sw_ChangeOffset( pFrame, nNextOfst );
301  }
302  else
303  bGoOn = false;
304  } while ( bGoOn );
305 
306  if ( pCMS )
307  {
308  if ( pFrame->IsRightToLeft() )
309  {
310  if( pCMS->m_b2Lines && pCMS->m_p2Lines)
311  {
312  pFrame->SwitchLTRtoRTL( pCMS->m_p2Lines->aLine );
313  pFrame->SwitchLTRtoRTL( pCMS->m_p2Lines->aPortion );
314  }
315  }
316 
317  if ( aRectFnSet.IsVert() )
318  {
319  if ( pCMS->m_bRealHeight )
320  {
321  pCMS->m_aRealHeight.setY( -pCMS->m_aRealHeight.Y() );
322  if ( pCMS->m_aRealHeight.Y() < 0 )
323  {
324  // writing direction is from top to bottom
325  pCMS->m_aRealHeight.setX( rOrig.Width() -
326  pCMS->m_aRealHeight.X() +
327  pCMS->m_aRealHeight.Y() );
328  }
329  }
330  if( pCMS->m_b2Lines && pCMS->m_p2Lines)
331  {
332  pFrame->SwitchHorizontalToVertical( pCMS->m_p2Lines->aLine );
333  pFrame->SwitchHorizontalToVertical( pCMS->m_p2Lines->aPortion );
334  }
335  }
336 
337  }
338  }
339  if( bRet )
340  {
341  SwPageFrame *pPage = pFrame->FindPageFrame();
342  OSL_ENSURE( pPage, "Text escaped from page?" );
343  const SwTwips nOrigTop = aRectFnSet.GetTop(rOrig);
344  const SwTwips nPageTop = aRectFnSet.GetTop(pPage->getFrameArea());
345  const SwTwips nPageBott = aRectFnSet.GetBottom(pPage->getFrameArea());
346 
347  // We have the following situation: if the frame is in an invalid
348  // sectionframe, it's possible that the frame is outside the page.
349  // If we restrict the cursor position to the page area, we enforce
350  // the formatting of the page, of the section frame and the frame itself.
351  if( aRectFnSet.YDiff( nPageTop, nOrigTop ) > 0 )
352  aRectFnSet.SetTop( rOrig, nPageTop );
353 
354  if ( aRectFnSet.YDiff( nOrigTop, nPageBott ) > 0 )
355  aRectFnSet.SetTop( rOrig, nPageBott );
356  }
357 
358  return bRet;
359 }
360 
361 /*
362  * GetAutoPos() looks up the char's char line which is described by rPos
363  * and is used by the auto-positioned frame.
364  */
365 
366 bool SwTextFrame::GetAutoPos( SwRect& rOrig, const SwPosition &rPos ) const
367 {
368  if( IsHiddenNow() )
369  return false;
370 
371  TextFrameIndex const nOffset = MapModelToViewPos(rPos);
372  SwTextFrame* pFrame = &(const_cast<SwTextFrame*>(this)->GetFrameAtOfst( nOffset ));
373 
374  pFrame->GetFormatted();
375  const SwFrame* pTmpFrame = pFrame->GetUpper();
376 
377  SwRectFnSet aRectFnSet(pTmpFrame);
378  SwTwips nUpperMaxY = aRectFnSet.GetPrtBottom(*pTmpFrame);
379 
380  // nMaxY is in absolute value
381  SwTwips nMaxY;
382  if ( aRectFnSet.IsVert() )
383  {
384  if ( aRectFnSet.IsVertL2R() )
385  nMaxY = std::min( SwTwips(aRectFnSet.GetPrtBottom(*pFrame)), nUpperMaxY );
386  else
387  nMaxY = std::max( SwTwips(aRectFnSet.GetPrtBottom(*pFrame)), nUpperMaxY );
388  }
389  else
390  nMaxY = std::min( SwTwips(aRectFnSet.GetPrtBottom(*pFrame)), nUpperMaxY );
391  if ( pFrame->IsEmpty() || ! aRectFnSet.GetHeight(pFrame->getFramePrintArea()) )
392  {
393  Point aPnt1 = pFrame->getFrameArea().Pos() + pFrame->getFramePrintArea().Pos();
394  Point aPnt2;
395  if ( aRectFnSet.IsVert() )
396  {
397  if ( aPnt1.X() < nMaxY && !aRectFnSet.IsVertL2R() )
398  aPnt1.setX( nMaxY );
399 
400  aPnt2.setX( aPnt1.X() + pFrame->getFramePrintArea().Width() );
401  aPnt2.setY( aPnt1.Y() );
402  if( aPnt2.X() < nMaxY )
403  aPnt2.setX( nMaxY );
404  }
405  else
406  {
407  if( aPnt1.Y() > nMaxY )
408  aPnt1.setY( nMaxY );
409  aPnt2.setX( aPnt1.X() );
410  aPnt2.setY( aPnt1.Y() + pFrame->getFramePrintArea().Height() );
411  if( aPnt2.Y() > nMaxY )
412  aPnt2.setY( nMaxY );
413  }
414  rOrig = SwRect( aPnt1, aPnt2 );
415  return true;
416  }
417  else
418  {
419  if( !pFrame->HasPara() )
420  return false;
421 
422  SwFrameSwapper aSwapper( pFrame, true );
423  if ( aRectFnSet.IsVert() )
424  nMaxY = pFrame->SwitchVerticalToHorizontal( nMaxY );
425 
426  SwTextSizeInfo aInf( pFrame );
427  SwTextCursor aLine( pFrame, &aInf );
429  aTmpState.m_bRealHeight = true;
430  aLine.GetCharRect( &rOrig, nOffset, &aTmpState, nMaxY );
431  if( aTmpState.m_aRealHeight.X() >= 0 )
432  {
433  rOrig.Pos().AdjustY(aTmpState.m_aRealHeight.X() );
434  rOrig.Height( aTmpState.m_aRealHeight.Y() );
435  }
436 
437  if ( pFrame->IsRightToLeft() )
438  pFrame->SwitchLTRtoRTL( rOrig );
439 
440  if ( aRectFnSet.IsVert() )
441  pFrame->SwitchHorizontalToVertical( rOrig );
442 
443  return true;
444  }
445 }
446 
453 bool SwTextFrame::GetTopOfLine( SwTwips& _onTopOfLine,
454  const SwPosition& _rPos ) const
455 {
456  bool bRet = true;
457 
458  // get position offset
459  TextFrameIndex const nOffset = MapModelToViewPos(_rPos);
460 
461  if (TextFrameIndex(GetText().getLength()) < nOffset)
462  {
463  bRet = false;
464  }
465  else
466  {
467  SwRectFnSet aRectFnSet(this);
468  if ( IsEmpty() || !aRectFnSet.GetHeight(getFramePrintArea()) )
469  {
470  // consider upper space amount considered
471  // for previous frame and the page grid.
472  _onTopOfLine = aRectFnSet.GetPrtTop(*this);
473  }
474  else
475  {
476  // determine formatted text frame that contains the requested position
477  SwTextFrame* pFrame = &(const_cast<SwTextFrame*>(this)->GetFrameAtOfst( nOffset ));
478  pFrame->GetFormatted();
479  aRectFnSet.Refresh(pFrame);
480  // If proportional line spacing is applied
481  // to the text frame, the top of the anchor character is also the
482  // top of the line.
483  // Otherwise the line layout determines the top of the line
484  const SvxLineSpacingItem& rSpace = GetAttrSet()->GetLineSpacing();
485  if ( rSpace.GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop )
486  {
487  SwRect aCharRect;
488  if ( GetAutoPos( aCharRect, _rPos ) )
489  {
490  _onTopOfLine = aRectFnSet.GetTop(aCharRect);
491  }
492  else
493  {
494  bRet = false;
495  }
496  }
497  else
498  {
499  // assure that text frame is in a horizontal layout
500  SwFrameSwapper aSwapper( pFrame, true );
501  // determine text line that contains the requested position
502  SwTextSizeInfo aInf( pFrame );
503  SwTextCursor aLine( pFrame, &aInf );
504  aLine.CharCursorToLine( nOffset );
505  // determine top of line
506  _onTopOfLine = aLine.Y();
507  if ( aRectFnSet.IsVert() )
508  {
509  _onTopOfLine = pFrame->SwitchHorizontalToVertical( _onTopOfLine );
510  }
511  }
512  }
513  }
514 
515  return bRet;
516 }
517 
518 // Minimum distance of non-empty lines is a little less than 2 cm
519 #define FILL_MIN_DIST 1100
520 
522 {
526  const Point& rPoint;
528  bool bFirstLine : 1;
529  bool bInner : 1;
530  bool bColumn : 1;
531  bool bEmpty : 1;
532  SwFillData( const SwCursorMoveState *pC, SwPosition* pP, const SwRect& rR,
533  const Point& rPt ) : aFrame( rR ), pCMS( pC ), pPos( pP ), rPoint( rPt ),
534  nLineWidth( 0 ), bFirstLine( true ), bInner( false ), bColumn( false ),
535  bEmpty( true ){}
536  SwFillMode Mode() const { return pCMS->m_pFill->eMode; }
537  tools::Long X() const { return rPoint.X(); }
538  tools::Long Y() const { return rPoint.Y(); }
539  tools::Long Left() const { return aFrame.Left(); }
540  tools::Long Right() const { return aFrame.Right(); }
541  tools::Long Bottom() const { return aFrame.Bottom(); }
542  SwFillCursorPos &Fill() const { return *pCMS->m_pFill; }
543  void SetTab( sal_uInt16 nNew ) { pCMS->m_pFill->nTabCnt = nNew; }
544  void SetSpace( sal_uInt16 nNew ) { pCMS->m_pFill->nSpaceCnt = nNew; }
545  void SetSpaceOnly( sal_uInt16 nNew ) { pCMS->m_pFill->nSpaceOnlyCnt = nNew; }
546  void SetOrient( const sal_Int16 eNew ){ pCMS->m_pFill->eOrient = eNew; }
547 };
548 
550  const bool bChgFrame, SwCursorMoveState* pCMS ) const
551 {
552  // GetModelPositionForViewPoint_ is called by GetModelPositionForViewPoint and GetKeyCursorOfst.
553  // Never just a return false.
554 
555  if( IsLocked() || IsHiddenNow() )
556  return false;
557 
558  const_cast<SwTextFrame*>(this)->GetFormatted();
559 
560  Point aOldPoint( rPoint );
561 
562  if ( IsVertical() )
563  {
564  SwitchVerticalToHorizontal( const_cast<Point&>(rPoint) );
565  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
566  }
567 
568  if ( IsRightToLeft() )
569  SwitchRTLtoLTR( const_cast<Point&>(rPoint) );
570 
571  std::unique_ptr<SwFillData> pFillData;
572  if ( pCMS && pCMS->m_pFill )
573  pFillData.reset(new SwFillData( pCMS, pPos, getFrameArea(), rPoint ));
574 
575  if ( IsEmpty() )
576  {
577  *pPos = MapViewToModelPos(TextFrameIndex(0));
578  if( pCMS && pCMS->m_bFieldInfo )
579  {
580  SwTwips nDiff = rPoint.X() - getFrameArea().Left() - getFramePrintArea().Left();
581  if( nDiff > 50 || nDiff < 0 )
582  pCMS->m_bPosCorr = true;
583  }
584  }
585  else
586  {
587  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
588  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
589 
590  // See comment in AdjustFrame()
592  aLine.TwipsToLine( rPoint.Y() );
593  while( aLine.Y() + aLine.GetLineHeight() > nMaxY )
594  {
595  if( !aLine.Prev() )
596  break;
597  }
598 
599  if( aLine.GetDropLines() >= aLine.GetLineNr() && 1 != aLine.GetLineNr()
600  && rPoint.X() < aLine.FirstLeft() + aLine.GetDropLeft() )
601  while( aLine.GetLineNr() > 1 )
602  aLine.Prev();
603 
604  TextFrameIndex nOffset = aLine.GetModelPositionForViewPoint(pPos, rPoint, bChgFrame, pCMS);
605 
606  if( pCMS && pCMS->m_eState == CursorMoveState::NONE && aLine.GetEnd() == nOffset )
608 
609  // pPos is a pure IN parameter and must not be evaluated.
610  // pIter->GetModelPositionForViewPoint returns from a nesting with COMPLETE_STRING.
611  // If SwTextIter::GetModelPositionForViewPoint calls GetModelPositionForViewPoint further by itself
612  // nNode changes the position.
613  // In such cases, pPos must not be calculated.
614  if (TextFrameIndex(COMPLETE_STRING) != nOffset)
615  {
616  *pPos = MapViewToModelPos(nOffset);
617  if( pFillData )
618  {
619  if (TextFrameIndex(GetText().getLength()) > nOffset ||
620  rPoint.Y() < getFrameArea().Top() )
621  pFillData->bInner = true;
622  pFillData->bFirstLine = aLine.GetLineNr() < 2;
623  if (GetText().getLength())
624  {
625  pFillData->bEmpty = false;
626  pFillData->nLineWidth = aLine.GetCurr()->Width();
627  }
628  }
629  }
630  }
631  bool bChgFillData = false;
632  if( pFillData && FindPageFrame()->getFrameArea().IsInside( aOldPoint ) )
633  {
634  FillCursorPos( *pFillData );
635  bChgFillData = true;
636  }
637 
638  if ( IsVertical() )
639  {
640  if ( bChgFillData )
641  SwitchHorizontalToVertical( pFillData->Fill().aCursor.Pos() );
642  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
643  }
644 
645  if ( IsRightToLeft() && bChgFillData )
646  {
647  SwitchLTRtoRTL( pFillData->Fill().aCursor.Pos() );
648  const sal_Int16 eOrient = pFillData->pCMS->m_pFill->eOrient;
649 
650  if ( text::HoriOrientation::LEFT == eOrient )
651  pFillData->SetOrient( text::HoriOrientation::RIGHT );
652  else if ( text::HoriOrientation::RIGHT == eOrient )
653  pFillData->SetOrient( text::HoriOrientation::LEFT );
654  }
655 
656  const_cast<Point&>(rPoint) = aOldPoint;
657 
658  return true;
659 }
660 
662  SwCursorMoveState* pCMS, bool ) const
663 {
664  const bool bChgFrame = !(pCMS && CursorMoveState::UpDown == pCMS->m_eState);
665  return GetModelPositionForViewPoint_( pPos, rPoint, bChgFrame, pCMS );
666 }
667 
668 /*
669  * Layout-oriented cursor movement to the line start.
670  */
671 
673 {
674  assert(GetMergedPara() || &pPam->GetNode() == static_cast<SwContentNode const*>(GetDep()));
675 
676  SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *pPam->GetPoint(),
678  pFrame->GetFormatted();
679  TextFrameIndex nIndx;
680  if ( pFrame->IsEmpty() )
681  nIndx = TextFrameIndex(0);
682  else
683  {
684  SwTextSizeInfo aInf( pFrame );
685  SwTextCursor aLine( pFrame, &aInf );
686 
687  aLine.CharCursorToLine(pFrame->MapModelToViewPos(*pPam->GetPoint()));
688  nIndx = aLine.GetStart();
689  if( pFrame->GetOffset() && !pFrame->IsFollow() && !aLine.GetPrev() )
690  {
691  sw_ChangeOffset(pFrame, TextFrameIndex(0));
692  nIndx = TextFrameIndex(0);
693  }
694  }
695  *pPam->GetPoint() = pFrame->MapViewToModelPos(nIndx);
697  return true;
698 }
699 
700 /*
701  * To the line end: That's the position before the last char of the line.
702  * Exception: In the last line, it should be able to place the cursor after
703  * the last char in order to append text.
704  */
705 
706 bool SwTextFrame::RightMargin(SwPaM *pPam, bool bAPI) const
707 {
708  assert(GetMergedPara() || &pPam->GetNode() == static_cast<SwContentNode const*>(GetDep()));
709 
710  SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *pPam->GetPoint(),
712  pFrame->GetFormatted();
714  if (!IsEmpty())
715  {
716  SwTextSizeInfo aInf( pFrame );
717  SwTextCursor aLine( pFrame, &aInf );
718 
720  nRightMargin = aLine.GetStart() + aLine.GetCurr()->GetLen();
721 
722  // We skip hard line breaks
723  if( aLine.GetCurr()->GetLen() &&
724  CH_BREAK == aInf.GetText()[sal_Int32(nRightMargin) - 1])
725  --nRightMargin;
726  else if( !bAPI && (aLine.GetNext() || pFrame->GetFollow()) )
727  {
728  while( nRightMargin > aLine.GetStart() &&
729  ' ' == aInf.GetText()[sal_Int32(nRightMargin) - 1])
730  --nRightMargin;
731  }
732  }
733  *pPam->GetPoint() = pFrame->MapViewToModelPos(nRightMargin);
735  return true;
736 }
737 
738 // The following two methods try to put the Cursor into the next/successive
739 // line. If we do not have a preceding/successive line we forward the call
740 // to the base class.
741 // The Cursor's horizontal justification is done afterwards by the CursorShell.
742 
743 namespace {
744 
745 class SwSetToRightMargin
746 {
747  bool m_bRight;
748 
749 public:
750  SwSetToRightMargin()
751  : m_bRight(false)
752  {
753  }
754  ~SwSetToRightMargin() { SwTextCursor::SetRightMargin(m_bRight); }
755  void SetRight(const bool bNew) { m_bRight = bNew; }
756 };
757 
758 }
759 
760 bool SwTextFrame::UnitUp_( SwPaM *pPam, const SwTwips nOffset,
761  bool bSetInReadOnly ) const
762 {
763  // Set the RightMargin if needed
764  SwSetToRightMargin aSet;
765 
766  if( IsInTab() &&
767  pPam->GetNode().StartOfSectionNode() !=
768  pPam->GetNode( false ).StartOfSectionNode() )
769  {
770  // If the PaM is located within different boxes, we have a table selection,
771  // which is handled by the base class.
772  return SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
773  }
774 
775  const_cast<SwTextFrame*>(this)->GetFormatted();
776  const TextFrameIndex nPos = MapModelToViewPos(*pPam->GetPoint());
777  SwRect aCharBox;
778 
779  if( !IsEmpty() && !IsHiddenNow() )
780  {
782  do
783  {
784  if (nFormat != TextFrameIndex(COMPLETE_STRING) && !IsFollow())
785  sw_ChangeOffset( const_cast<SwTextFrame*>(this), nFormat );
786 
787  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
788  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
789 
790  // Optimize away flys with no flow and IsDummy()
791  if( nPos )
792  aLine.CharCursorToLine( nPos );
793  else
794  aLine.Top();
795 
796  const SwLineLayout *pPrevLine = aLine.GetPrevLine();
797  const TextFrameIndex nStart = aLine.GetStart();
798  aLine.GetCharRect( &aCharBox, nPos );
799 
800  bool bSecondOfDouble = ( aInf.IsMulti() && ! aInf.IsFirstMulti() );
801  bool bPrevLine = ( pPrevLine && pPrevLine != aLine.GetCurr() );
802 
803  if( !pPrevLine && !bSecondOfDouble && GetOffset() && !IsFollow() )
804  {
805  nFormat = GetOffset();
806  TextFrameIndex nDiff = aLine.GetLength();
807  if( !nDiff )
809  if( nFormat > nDiff )
810  nFormat = nFormat - nDiff;
811  else
812  nFormat = TextFrameIndex(0);
813  continue;
814  }
815 
816  // We select the target line for the cursor, in case we are in a
817  // double line portion, prev line = curr line
818  if( bPrevLine && !bSecondOfDouble )
819  {
820  aLine.PrevLine();
821  while ( aLine.GetStart() == nStart &&
822  nullptr != ( pPrevLine = aLine.GetPrevLine() ) &&
823  pPrevLine != aLine.GetCurr() )
824  aLine.PrevLine();
825  }
826 
827  if ( bPrevLine || bSecondOfDouble )
828  {
829  aCharBox.Width( aCharBox.SSize().Width() / 2 );
830  aCharBox.Pos().setX( aCharBox.Pos().X() - 150 );
831 
832  // See comment in SwTextFrame::GetModelPositionForViewPoint()
833 #if OSL_DEBUG_LEVEL > 0
834  const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
835 #endif
836  // The node should not be changed
837  TextFrameIndex nTmpOfst = aLine.GetModelPositionForViewPoint(pPam->GetPoint(),
838  aCharBox.Pos(), false );
839 #if OSL_DEBUG_LEVEL > 0
840  OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
841  "SwTextFrame::UnitUp: illegal node change" );
842 #endif
843 
844  // We make sure that we move up.
845  if( nTmpOfst >= nStart && nStart && !bSecondOfDouble )
846  {
847  nTmpOfst = nStart;
848  aSet.SetRight( true );
849  }
850  *pPam->GetPoint() = MapViewToModelPos(nTmpOfst);
851  return true;
852  }
853 
854  if ( IsFollow() )
855  {
856  aLine.GetCharRect( &aCharBox, nPos );
857  aCharBox.Width( aCharBox.SSize().Width() / 2 );
858  }
859  break;
860  } while ( true );
861  }
862  /* If 'this' is a follow and a prev failed, we need to go to the
863  * last line of the master, which is us.
864  * Or: If we are a follow with follow, we need to get the master.
865  */
866  if ( IsFollow() )
867  {
868  const SwTextFrame *pTmpPrev = FindMaster();
869  TextFrameIndex nOffs = GetOffset();
870  if( pTmpPrev )
871  {
873  const bool bProtectedAllowed = pSh && pSh->GetViewOptions()->IsCursorInProtectedArea();
874  const SwTextFrame *pPrevPrev = pTmpPrev;
875  // We skip protected frames and frames without content here
876  while( pPrevPrev && ( pPrevPrev->GetOffset() == nOffs ||
877  ( !bProtectedAllowed && pPrevPrev->IsProtected() ) ) )
878  {
879  pTmpPrev = pPrevPrev;
880  nOffs = pTmpPrev->GetOffset();
881  if ( pPrevPrev->IsFollow() )
882  pPrevPrev = pTmpPrev->FindMaster();
883  else
884  pPrevPrev = nullptr;
885  }
886  if ( !pPrevPrev )
887  return pTmpPrev->SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
888  aCharBox.Pos().setY( pPrevPrev->getFrameArea().Bottom() - 1 );
889  return pPrevPrev->GetKeyCursorOfst( pPam->GetPoint(), aCharBox.Pos() );
890  }
891  }
892  return SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
893 }
894 
895 // Used for Bidi. nPos is the logical position in the string, bLeft indicates
896 // if left arrow or right arrow was pressed. The return values are:
897 // nPos: the new visual position
898 // bLeft: whether the break iterator has to add or subtract from the
899 // current position
900 static void lcl_VisualMoveRecursion(const SwLineLayout& rCurrLine, TextFrameIndex nIdx,
901  TextFrameIndex & nPos, bool& bRight,
902  sal_uInt8& nCursorLevel, sal_uInt8 nDefaultDir )
903 {
904  const SwLinePortion* pPor = rCurrLine.GetFirstPortion();
905  const SwLinePortion* pLast = nullptr;
906 
907  // What's the current portion?
908  while ( pPor && nIdx + pPor->GetLen() <= nPos )
909  {
910  nIdx = nIdx + pPor->GetLen();
911  pLast = pPor;
912  pPor = pPor->GetNextPortion();
913  }
914 
915  if ( bRight )
916  {
917  bool bRecurse = pPor && pPor->IsMultiPortion() &&
918  static_cast<const SwMultiPortion*>(pPor)->IsBidi();
919 
920  // 1. special case: at beginning of bidi portion
921  if ( bRecurse && nIdx == nPos )
922  {
923  nPos = nPos + pPor->GetLen();
924 
925  // leave bidi portion
926  if ( nCursorLevel != nDefaultDir )
927  {
928  bRecurse = false;
929  }
930  else
931  // special case:
932  // buffer: abcXYZ123 in LTR paragraph
933  // view: abc123ZYX
934  // cursor is between c and X in the buffer and cursor level = 0
935  nCursorLevel++;
936  }
937 
938  // 2. special case: at beginning of portion after bidi portion
939  else if ( pLast && pLast->IsMultiPortion() &&
940  static_cast<const SwMultiPortion*>(pLast)->IsBidi() && nIdx == nPos )
941  {
942  // enter bidi portion
943  if ( nCursorLevel != nDefaultDir )
944  {
945  bRecurse = true;
946  nIdx = nIdx - pLast->GetLen();
947  pPor = pLast;
948  }
949  }
950 
951  // Recursion
952  if ( bRecurse )
953  {
954  const SwLineLayout& rLine = static_cast<const SwMultiPortion*>(pPor)->GetRoot();
955  TextFrameIndex nTmpPos = nPos - nIdx;
956  bool bTmpForward = ! bRight;
957  sal_uInt8 nTmpCursorLevel = nCursorLevel;
958  lcl_VisualMoveRecursion(rLine, TextFrameIndex(0), nTmpPos, bTmpForward,
959  nTmpCursorLevel, nDefaultDir + 1 );
960 
961  nPos = nTmpPos + nIdx;
962  bRight = bTmpForward;
963  nCursorLevel = nTmpCursorLevel;
964  }
965 
966  // go forward
967  else
968  {
969  bRight = true;
970  nCursorLevel = nDefaultDir;
971  }
972 
973  }
974  else
975  {
976  bool bRecurse = pPor && pPor->IsMultiPortion() && static_cast<const SwMultiPortion*>(pPor)->IsBidi();
977 
978  // 1. special case: at beginning of bidi portion
979  if ( bRecurse && nIdx == nPos )
980  {
981  // leave bidi portion
982  if ( nCursorLevel == nDefaultDir )
983  {
984  bRecurse = false;
985  }
986  }
987 
988  // 2. special case: at beginning of portion after bidi portion
989  else if ( pLast && pLast->IsMultiPortion() &&
990  static_cast<const SwMultiPortion*>(pLast)->IsBidi() && nIdx == nPos )
991  {
992  nPos = nPos - pLast->GetLen();
993 
994  // enter bidi portion
995  if ( nCursorLevel % 2 == nDefaultDir % 2 )
996  {
997  bRecurse = true;
998  nIdx = nIdx - pLast->GetLen();
999  pPor = pLast;
1000 
1001  // special case:
1002  // buffer: abcXYZ123 in LTR paragraph
1003  // view: abc123ZYX
1004  // cursor is behind 3 in the buffer and cursor level = 2
1005  if ( nDefaultDir + 2 == nCursorLevel )
1006  nPos = nPos + pLast->GetLen();
1007  }
1008  }
1009 
1010  // go forward
1011  if ( bRecurse )
1012  {
1013  const SwLineLayout& rLine = static_cast<const SwMultiPortion*>(pPor)->GetRoot();
1014  TextFrameIndex nTmpPos = nPos - nIdx;
1015  bool bTmpForward = ! bRight;
1016  sal_uInt8 nTmpCursorLevel = nCursorLevel;
1017  lcl_VisualMoveRecursion(rLine, TextFrameIndex(0), nTmpPos, bTmpForward,
1018  nTmpCursorLevel, nDefaultDir + 1 );
1019 
1020  // special case:
1021  // buffer: abcXYZ123 in LTR paragraph
1022  // view: abc123ZYX
1023  // cursor is between Z and 1 in the buffer and cursor level = 2
1024  if ( nTmpPos == pPor->GetLen() && nTmpCursorLevel == nDefaultDir + 1 )
1025  {
1026  nTmpPos = nTmpPos - pPor->GetLen();
1027  nTmpCursorLevel = nDefaultDir;
1028  bTmpForward = ! bTmpForward;
1029  }
1030 
1031  nPos = nTmpPos + nIdx;
1032  bRight = bTmpForward;
1033  nCursorLevel = nTmpCursorLevel;
1034  }
1035 
1036  // go backward
1037  else
1038  {
1039  bRight = false;
1040  nCursorLevel = nDefaultDir;
1041  }
1042  }
1043 }
1044 
1046  bool& bForward, bool bInsertCursor )
1047 {
1048  if( IsEmpty() || IsHiddenNow() )
1049  return;
1050 
1051  GetFormatted();
1052 
1053  SwTextSizeInfo aInf(this);
1054  SwTextCursor aLine(this, &aInf);
1055 
1056  if( nPos )
1057  aLine.CharCursorToLine( nPos );
1058  else
1059  aLine.Top();
1060 
1061  const SwLineLayout* pLine = aLine.GetCurr();
1062  const TextFrameIndex nStt = aLine.GetStart();
1063  const TextFrameIndex nLen = pLine->GetLen();
1064 
1065  // We have to distinguish between an insert and overwrite cursor:
1066  // The insert cursor position depends on the cursor level:
1067  // buffer: abcXYZdef in LTR paragraph
1068  // display: abcZYXdef
1069  // If cursor is between c and X in the buffer and cursor level is 0,
1070  // the cursor blinks between c and Z and -> sets the cursor between Z and Y.
1071  // If the cursor level is 1, the cursor blinks between X and d and
1072  // -> sets the cursor between d and e.
1073  // The overwrite cursor simply travels to the next visual character.
1074  if ( bInsertCursor )
1075  {
1076  lcl_VisualMoveRecursion( *pLine, nStt, nPos, bForward,
1077  nCursorLevel, IsRightToLeft() ? 1 : 0 );
1078  return;
1079  }
1080 
1081  const sal_uInt8 nDefaultDir = static_cast<sal_uInt8>(IsRightToLeft() ? UBIDI_RTL : UBIDI_LTR);
1082  const bool bVisualRight = ( nDefaultDir == UBIDI_LTR && bForward ) ||
1083  ( nDefaultDir == UBIDI_RTL && ! bForward );
1084 
1085  // Bidi functions from icu 2.0
1086 
1087  const sal_Unicode* pLineString = GetText().getStr();
1088 
1089  UErrorCode nError = U_ZERO_ERROR;
1090  UBiDi* pBidi = ubidi_openSized( sal_Int32(nLen), 0, &nError );
1091  ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString),
1092  sal_Int32(nLen), nDefaultDir, nullptr, &nError );
1093 
1094  TextFrameIndex nTmpPos(0);
1095  bool bOutOfBounds = false;
1096 
1097  if ( nPos < nStt + nLen )
1098  {
1099  nTmpPos = TextFrameIndex(ubidi_getVisualIndex( pBidi, sal_Int32(nPos), &nError ));
1100 
1101  // visual indices are always LTR aligned
1102  if ( bVisualRight )
1103  {
1104  if (nTmpPos + TextFrameIndex(1) < nStt + nLen)
1105  ++nTmpPos;
1106  else
1107  {
1108  nPos = nDefaultDir == UBIDI_RTL ? TextFrameIndex(0) : nStt + nLen;
1109  bOutOfBounds = true;
1110  }
1111  }
1112  else
1113  {
1114  if ( nTmpPos )
1115  --nTmpPos;
1116  else
1117  {
1118  nPos = nDefaultDir == UBIDI_RTL ? nStt + nLen : TextFrameIndex(0);
1119  bOutOfBounds = true;
1120  }
1121  }
1122  }
1123  else
1124  {
1125  nTmpPos = nDefaultDir == UBIDI_LTR ? nPos - TextFrameIndex(1) : TextFrameIndex(0);
1126  }
1127 
1128  if ( ! bOutOfBounds )
1129  {
1130  nPos = TextFrameIndex(ubidi_getLogicalIndex( pBidi, sal_Int32(nTmpPos), &nError ));
1131 
1132  if ( bForward )
1133  {
1134  if ( nPos )
1135  --nPos;
1136  else
1137  {
1138  ++nPos;
1139  bForward = ! bForward;
1140  }
1141  }
1142  else
1143  ++nPos;
1144  }
1145 
1146  ubidi_close( pBidi );
1147 }
1148 
1149 bool SwTextFrame::UnitDown_(SwPaM *pPam, const SwTwips nOffset,
1150  bool bSetInReadOnly ) const
1151 {
1152 
1153  if ( IsInTab() &&
1154  pPam->GetNode().StartOfSectionNode() !=
1155  pPam->GetNode( false ).StartOfSectionNode() )
1156  {
1157  // If the PaM is located within different boxes, we have a table selection,
1158  // which is handled by the base class.
1159  return SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1160  }
1161  const_cast<SwTextFrame*>(this)->GetFormatted();
1162  const TextFrameIndex nPos = MapModelToViewPos(*pPam->GetPoint());
1163  SwRect aCharBox;
1164  const SwContentFrame *pTmpFollow = nullptr;
1165 
1166  if ( IsVertical() )
1167  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1168 
1169  if ( !IsEmpty() && !IsHiddenNow() )
1170  {
1172  do
1173  {
1174  if (nFormat != TextFrameIndex(COMPLETE_STRING) && !IsFollow() &&
1175  !sw_ChangeOffset( const_cast<SwTextFrame*>(this), nFormat ) )
1176  break;
1177 
1178  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
1179  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
1180  nFormat = aLine.GetEnd();
1181 
1182  aLine.CharCursorToLine( nPos );
1183 
1184  const SwLineLayout* pNextLine = aLine.GetNextLine();
1185  const TextFrameIndex nStart = aLine.GetStart();
1186  aLine.GetCharRect( &aCharBox, nPos );
1187 
1188  bool bFirstOfDouble = ( aInf.IsMulti() && aInf.IsFirstMulti() );
1189 
1190  if( pNextLine || bFirstOfDouble )
1191  {
1192  aCharBox.Width( aCharBox.SSize().Width() / 2 );
1193 #if OSL_DEBUG_LEVEL > 0
1194  // See comment in SwTextFrame::GetModelPositionForViewPoint()
1195  const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
1196 #endif
1197  if ( pNextLine && ! bFirstOfDouble )
1198  aLine.NextLine();
1199 
1200  TextFrameIndex nTmpOfst = aLine.GetModelPositionForViewPoint( pPam->GetPoint(),
1201  aCharBox.Pos(), false );
1202 #if OSL_DEBUG_LEVEL > 0
1203  OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
1204  "SwTextFrame::UnitDown: illegal node change" );
1205 #endif
1206 
1207  // We make sure that we move down.
1208  if( nTmpOfst <= nStart && ! bFirstOfDouble )
1209  nTmpOfst = nStart + TextFrameIndex(1);
1210  *pPam->GetPoint() = MapViewToModelPos(nTmpOfst);
1211 
1212  if ( IsVertical() )
1213  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1214 
1215  return true;
1216  }
1217  pTmpFollow = GetFollow();
1218  if( nullptr != pTmpFollow )
1219  { // Skip protected follows
1220  const SwContentFrame* pTmp = pTmpFollow;
1222  if( !pSh || !pSh->GetViewOptions()->IsCursorInProtectedArea() )
1223  {
1224  while( pTmpFollow && pTmpFollow->IsProtected() )
1225  {
1226  pTmp = pTmpFollow;
1227  pTmpFollow = pTmpFollow->GetFollow();
1228  }
1229  }
1230  if( !pTmpFollow ) // Only protected ones left
1231  {
1232  if ( IsVertical() )
1233  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1234  return pTmp->SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1235  }
1236 
1237  aLine.GetCharRect( &aCharBox, nPos );
1238  aCharBox.Width( aCharBox.SSize().Width() / 2 );
1239  }
1240  else if( !IsFollow() )
1241  {
1242  TextFrameIndex nTmpLen(aInf.GetText().getLength());
1243  if( aLine.GetEnd() < nTmpLen )
1244  {
1245  if( nFormat <= GetOffset() )
1246  {
1247  nFormat = std::min(GetOffset() + TextFrameIndex(MIN_OFFSET_STEP),
1248  nTmpLen );
1249  if( nFormat <= GetOffset() )
1250  break;
1251  }
1252  continue;
1253  }
1254  }
1255  break;
1256  } while( true );
1257  }
1258  else
1259  pTmpFollow = GetFollow();
1260 
1261  if ( IsVertical() )
1262  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1263 
1264  // We take a shortcut for follows
1265  if( pTmpFollow )
1266  {
1267  aCharBox.Pos().setY( pTmpFollow->getFrameArea().Top() + 1 );
1268  return static_cast<const SwTextFrame*>(pTmpFollow)->GetKeyCursorOfst( pPam->GetPoint(),
1269  aCharBox.Pos() );
1270  }
1271  return SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1272 }
1273 
1274 bool SwTextFrame::UnitUp(SwPaM *pPam, const SwTwips nOffset,
1275  bool bSetInReadOnly ) const
1276 {
1277  /* We call ContentNode::GertFrame() in CursorSh::Up().
1278  * This _always returns the master.
1279  * In order to not mess with cursor travelling, we correct here
1280  * in SwTextFrame.
1281  * We calculate UnitUp for pFrame. pFrame is either a master (= this) or a
1282  * follow (!= this).
1283  */
1284  const SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *(pPam->GetPoint()),
1286  const bool bRet = pFrame->UnitUp_( pPam, nOffset, bSetInReadOnly );
1287 
1288  // No SwTextCursor::SetRightMargin( false );
1289  // Instead we have a SwSetToRightMargin in UnitUp_
1290  return bRet;
1291 }
1292 
1293 bool SwTextFrame::UnitDown(SwPaM *pPam, const SwTwips nOffset,
1294  bool bSetInReadOnly ) const
1295 {
1296  const SwTextFrame *pFrame = GetAdjFrameAtPos(const_cast<SwTextFrame*>(this), *(pPam->GetPoint()),
1298  const bool bRet = pFrame->UnitDown_( pPam, nOffset, bSetInReadOnly );
1300  return bRet;
1301 }
1302 
1304 {
1305  if( !rFill.bColumn && GetUpper()->IsColBodyFrame() ) // ColumnFrames now with BodyFrame
1306  {
1307  const SwColumnFrame* pTmp =
1308  static_cast<const SwColumnFrame*>(GetUpper()->GetUpper()->GetUpper()->Lower()); // The 1st column
1309  // The first SwFrame in BodyFrame of the first column
1310  const SwFrame* pFrame = static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower();
1311  sal_uInt16 nNextCol = 0;
1312  // In which column do we end up in?
1313  while( rFill.X() > pTmp->getFrameArea().Right() && pTmp->GetNext() )
1314  {
1315  pTmp = static_cast<const SwColumnFrame*>(pTmp->GetNext());
1316  if( static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower() ) // ColumnFrames now with BodyFrame
1317  {
1318  pFrame = static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower();
1319  nNextCol = 0;
1320  }
1321  else
1322  ++nNextCol; // Empty columns require column brakes
1323  }
1324  if( pTmp != GetUpper()->GetUpper() ) // Did we end up in another column?
1325  {
1326  if( !pFrame )
1327  return;
1328  if( nNextCol )
1329  {
1330  while( pFrame->GetNext() )
1331  pFrame = pFrame->GetNext();
1332  }
1333  else
1334  {
1335  while( pFrame->GetNext() && pFrame->getFrameArea().Bottom() < rFill.Y() )
1336  pFrame = pFrame->GetNext();
1337  }
1338  // No filling, if the last frame in the targeted column does
1339  // not contain a paragraph, but e.g. a table
1340  if( pFrame->IsTextFrame() )
1341  {
1342  rFill.Fill().nColumnCnt = nNextCol;
1343  rFill.bColumn = true;
1344  if( rFill.pPos )
1345  {
1346  SwTextFrame const*const pTextFrame(static_cast<const SwTextFrame*>(pFrame));
1347  *rFill.pPos = pTextFrame->MapViewToModelPos(
1348  TextFrameIndex(pTextFrame->GetText().getLength()));
1349  }
1350  if( nNextCol )
1351  {
1352  rFill.aFrame = pTmp->getFramePrintArea();
1353  rFill.aFrame += pTmp->getFrameArea().Pos();
1354  }
1355  else
1356  rFill.aFrame = pFrame->getFrameArea();
1357  static_cast<const SwTextFrame*>(pFrame)->FillCursorPos( rFill );
1358  }
1359  return;
1360  }
1361  }
1362  std::unique_ptr<SwFont> pFnt;
1365  SwTwips nDiff = rFill.Y() - getFrameArea().Bottom();
1366  if( nDiff < nFirst )
1367  nDiff = -1;
1368  else
1369  pColl = &pColl->GetNextTextFormatColl();
1370  SwAttrSet aSet(const_cast<SwDoc&>(GetDoc()).GetAttrPool(), aTextFormatCollSetRange );
1371  const SwAttrSet* pSet = &pColl->GetAttrSet();
1373  if (GetTextNodeForParaProps()->HasSwAttrSet())
1374  {
1375  // sw_redlinehide: pSet is mostly used for para props, but there are
1376  // accesses to char props via pFnt - why does it use only the node's
1377  // props for this, and not hints?
1378  aSet.Put( *GetTextNodeForParaProps()->GetpSwAttrSet() );
1379  aSet.SetParent( pSet );
1380  pSet = &aSet;
1381  pFnt.reset(new SwFont( pSet, &GetDoc().getIDocumentSettingAccess() ));
1382  }
1383  else
1384  {
1385  SwFontAccess aFontAccess( pColl, pSh );
1386  pFnt.reset(new SwFont( aFontAccess.Get()->GetFont() ));
1387  pFnt->CheckFontCacheId( pSh, pFnt->GetActual() );
1388  }
1389  OutputDevice* pOut = pSh->GetOut();
1390  if( !pSh->GetViewOptions()->getBrowseMode() || pSh->GetViewOptions()->IsPrtFormat() )
1392 
1393  pFnt->SetFntChg( true );
1394  pFnt->ChgPhysFnt( pSh, *pOut );
1395 
1396  SwTwips nLineHeight = pFnt->GetHeight( pSh, *pOut );
1397 
1398  bool bFill = false;
1399  if( nLineHeight )
1400  {
1401  bFill = true;
1402  const SvxULSpaceItem &rUL = pSet->GetULSpace();
1403  SwTwips nDist = std::max( rUL.GetLower(), rUL.GetUpper() );
1404  if( rFill.Fill().nColumnCnt )
1405  {
1406  rFill.aFrame.Height( nLineHeight );
1407  nDiff = rFill.Y() - rFill.Bottom();
1408  nFirst = 0;
1409  }
1410  else if( nDist < nFirst )
1411  nFirst = nFirst - nDist;
1412  else
1413  nFirst = 0;
1414  nDist = std::max( nDist, SwTwips(GetLineSpace()) );
1415  nDist += nLineHeight;
1416  nDiff -= nFirst;
1417 
1418  if( nDiff > 0 )
1419  {
1420  nDiff /= nDist;
1421  rFill.Fill().nParaCnt = static_cast<sal_uInt16>(nDiff + 1);
1422  rFill.nLineWidth = 0;
1423  rFill.bInner = false;
1424  rFill.bEmpty = true;
1425  rFill.SetOrient( text::HoriOrientation::LEFT );
1426  }
1427  else
1428  nDiff = -1;
1429  if( rFill.bInner )
1430  bFill = false;
1431  else
1432  {
1433  const SvxTabStopItem &rRuler = pSet->GetTabStops();
1434  const SvxLRSpaceItem &rLRSpace = pSet->GetLRSpace();
1435 
1436  SwRect &rRect = rFill.Fill().aCursor;
1437  rRect.Top( rFill.Bottom() + (nDiff+1) * nDist - nLineHeight );
1438  if( nFirst && nDiff > -1 )
1439  rRect.Top( rRect.Top() + nFirst );
1440  rRect.Height( nLineHeight );
1441  SwTwips nLeft = rFill.Left() + rLRSpace.GetLeft() +
1443  SwTwips nRight = rFill.Right() - rLRSpace.GetRight();
1444  SwTwips nCenter = ( nLeft + nRight ) / 2;
1445  rRect.Left( nLeft );
1446  if( SwFillMode::Margin == rFill.Mode() )
1447  {
1448  if( rFill.bEmpty )
1449  {
1450  rFill.SetOrient( text::HoriOrientation::LEFT );
1451  if( rFill.X() < nCenter )
1452  {
1453  if( rFill.X() > ( nLeft + 2 * nCenter ) / 3 )
1454  {
1455  rFill.SetOrient( text::HoriOrientation::CENTER );
1456  rRect.Left( nCenter );
1457  }
1458  }
1459  else if( rFill.X() > ( nRight + 2 * nCenter ) / 3 )
1460  {
1461  rFill.SetOrient( text::HoriOrientation::RIGHT );
1462  rRect.Left( nRight );
1463  }
1464  else
1465  {
1466  rFill.SetOrient( text::HoriOrientation::CENTER );
1467  rRect.Left( nCenter );
1468  }
1469  }
1470  else
1471  bFill = false;
1472  }
1473  else
1474  {
1475  SwTwips nSpace = 0;
1476  if( SwFillMode::Tab != rFill.Mode() )
1477  {
1478  SwDrawTextInfo aDrawInf( pSh, *pOut, " ", 0, 2 );
1479  nSpace = pFnt->GetTextSize_( aDrawInf ).Width()/2;
1480  }
1481  if( rFill.X() >= nRight )
1482  {
1483  if( SwFillMode::Indent != rFill.Mode() && ( rFill.bEmpty ||
1484  rFill.X() > rFill.nLineWidth + FILL_MIN_DIST ) )
1485  {
1486  rFill.SetOrient( text::HoriOrientation::RIGHT );
1487  rRect.Left( nRight );
1488  }
1489  else
1490  bFill = false;
1491  }
1492  else if( SwFillMode::Indent == rFill.Mode() )
1493  {
1494  SwTwips nIndent = rFill.X();
1495  if( !rFill.bEmpty || nIndent > nRight )
1496  bFill = false;
1497  else
1498  {
1499  nIndent -= rFill.Left();
1500  if( nIndent >= 0 && nSpace )
1501  {
1502  nIndent /= nSpace;
1503  nIndent *= nSpace;
1504  rFill.SetTab( sal_uInt16( nIndent ) );
1505  rRect.Left( nIndent + rFill.Left() );
1506  }
1507  else
1508  bFill = false;
1509  }
1510  }
1511  else if( rFill.X() > nLeft )
1512  {
1513  SwTwips nTextLeft = rFill.Left() + rLRSpace.GetTextLeft() +
1515  rFill.nLineWidth += rFill.bFirstLine ? nLeft : nTextLeft;
1516  SwTwips nLeftTab;
1517  SwTwips nRightTab = nLeft;
1518  sal_uInt16 nSpaceCnt = 0;
1519  sal_uInt16 nSpaceOnlyCnt = 0;
1520  sal_uInt16 nTabCnt = 0;
1521  sal_uInt16 nIdx = 0;
1522  do
1523  {
1524  nLeftTab = nRightTab;
1525  if( nIdx < rRuler.Count() )
1526  {
1527  const SvxTabStop &rTabStop = rRuler.operator[](nIdx);
1528  nRightTab = nTextLeft + rTabStop.GetTabPos();
1529  if( nLeftTab < nTextLeft && nRightTab > nTextLeft )
1530  nRightTab = nTextLeft;
1531  else
1532  ++nIdx;
1533  if( nRightTab > rFill.nLineWidth )
1534  ++nTabCnt;
1535  }
1536  else
1537  {
1538  const SvxTabStopItem& rTab =
1540  const SwTwips nDefTabDist = rTab[0].GetTabPos();
1541  nRightTab = nLeftTab - nTextLeft;
1542  nRightTab /= nDefTabDist;
1543  nRightTab = nRightTab * nDefTabDist + nTextLeft;
1544  while ( nRightTab <= nLeftTab )
1545  nRightTab += nDefTabDist;
1546  if( nRightTab > rFill.nLineWidth )
1547  ++nTabCnt;
1548  while ( nRightTab < rFill.X() )
1549  {
1550  nRightTab += nDefTabDist;
1551  if( nRightTab > rFill.nLineWidth )
1552  ++nTabCnt;
1553  }
1554  if( nLeftTab < nRightTab - nDefTabDist )
1555  nLeftTab = nRightTab - nDefTabDist;
1556  }
1557  if( nRightTab > nRight )
1558  nRightTab = nRight;
1559  }
1560  while( rFill.X() > nRightTab );
1561  --nTabCnt;
1562  if( SwFillMode::TabSpace == rFill.Mode() )
1563  {
1564  if( nSpace > 0 )
1565  {
1566  if( !nTabCnt )
1567  nLeftTab = rFill.nLineWidth;
1568  while( nLeftTab < rFill.X() )
1569  {
1570  nLeftTab += nSpace;
1571  ++nSpaceCnt;
1572  }
1573  if( nSpaceCnt )
1574  {
1575  nLeftTab -= nSpace;
1576  --nSpaceCnt;
1577  }
1578  if( rFill.X() - nLeftTab > nRightTab - rFill.X() )
1579  {
1580  nSpaceCnt = 0;
1581  ++nTabCnt;
1582  rRect.Left( nRightTab );
1583  }
1584  else
1585  {
1586  if( rFill.X() - nLeftTab > nSpace/2 )
1587  {
1588  ++nSpaceCnt;
1589  rRect.Left( nLeftTab + nSpace );
1590  }
1591  else
1592  rRect.Left( nLeftTab );
1593  }
1594  }
1595  else if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
1596  rRect.Left( nLeftTab );
1597  else
1598  {
1599  if( nRightTab >= nRight )
1600  {
1601  rFill.SetOrient( text::HoriOrientation::RIGHT );
1602  rRect.Left( nRight );
1603  nTabCnt = 0;
1604  nSpaceCnt = 0;
1605  }
1606  else
1607  {
1608  rRect.Left( nRightTab );
1609  ++nTabCnt;
1610  }
1611  }
1612  }
1613  else if( SwFillMode::Space == rFill.Mode() )
1614  {
1615  SwTwips nLeftSpace = nLeft;
1616  while( nLeftSpace < rFill.X() )
1617  {
1618  nLeftSpace += nSpace;
1619  ++nSpaceOnlyCnt;
1620  }
1621  rRect.Left( nLeftSpace );
1622  }
1623  else
1624  {
1625  if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
1626  rRect.Left( nLeftTab );
1627  else
1628  {
1629  if( nRightTab >= nRight )
1630  {
1631  rFill.SetOrient( text::HoriOrientation::RIGHT );
1632  rRect.Left( nRight );
1633  nTabCnt = 0;
1634  nSpaceCnt = 0;
1635  }
1636  else
1637  {
1638  rRect.Left( nRightTab );
1639  ++nTabCnt;
1640  }
1641  }
1642  }
1643  rFill.SetTab( nTabCnt );
1644  rFill.SetSpace( nSpaceCnt );
1645  rFill.SetSpaceOnly( nSpaceOnlyCnt );
1646  if( bFill )
1647  {
1648  if( std::abs( rFill.X() - nCenter ) <=
1649  std::abs( rFill.X() - rRect.Left() ) )
1650  {
1651  rFill.SetOrient( text::HoriOrientation::CENTER );
1652  rFill.SetTab( 0 );
1653  rFill.SetSpace( 0 );
1654  rFill.SetSpaceOnly( 0 );
1655  rRect.Left( nCenter );
1656  }
1657  if( !rFill.bEmpty )
1658  rFill.nLineWidth += FILL_MIN_DIST;
1659  if( rRect.Left() < rFill.nLineWidth )
1660  bFill = false;
1661  }
1662  }
1663  }
1664  // Do we extend over the page's/column's/etc. lower edge?
1665  const SwFrame* pUp = GetUpper();
1666  if( pUp->IsInSct() )
1667  {
1668  if( pUp->IsSctFrame() )
1669  pUp = pUp->GetUpper();
1670  else if( pUp->IsColBodyFrame() &&
1671  pUp->GetUpper()->GetUpper()->IsSctFrame() )
1672  pUp = pUp->GetUpper()->GetUpper()->GetUpper();
1673  }
1674  SwRectFnSet aRectFnSet(this);
1675  SwTwips nLimit = aRectFnSet.GetPrtBottom(*pUp);
1676  SwTwips nRectBottom = rRect.Bottom();
1677  if ( aRectFnSet.IsVert() )
1678  nRectBottom = SwitchHorizontalToVertical( nRectBottom );
1679 
1680  if( aRectFnSet.YDiff( nLimit, nRectBottom ) < 0 )
1681  bFill = false;
1682  else
1683  rRect.Width( 1 );
1684  }
1685  }
1686  const_cast<SwCursorMoveState*>(rFill.pCMS)->m_bFillRet = bFill;
1687 }
1688 
1689 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:338
TextFrameIndex GetModelPositionForViewPoint(SwPosition *pPos, const Point &rPoint, bool bChgNode, SwCursorMoveState *=nullptr) const
Definition: itrcrsr.cxx:1295
void SetTop(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1367
Base class of the Writer layout elements.
Definition: frame.hxx:298
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
bool IsFirstMulti() const
Definition: inftxt.hxx:205
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:157
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:44
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout...
Definition: txtfrm.cxx:578
bool m_bFieldInfo
should be fields recognized?
Definition: crstate.hxx:142
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
void Right(const tools::Long nRight)
Definition: swrect.hxx:200
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:548
SwFillCursorPos & Fill() const
Definition: frmcrsr.cxx:542
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
sal_uInt16 Count() const
sal_uInt16 GetLineNr() const
Definition: itrtxt.hxx:87
Marks a position in the document model.
Definition: pam.hxx:35
constexpr TypedWhichId< SvxTabStopItem > RES_PARATR_TABSTOP(68)
void SetOrient(const sal_Int16 eNew)
Definition: frmcrsr.cxx:546
sal_Int16 eOrient
paragraph alignment
Definition: crstate.hxx:45
sal_uInt16 GetLower() const
bool IsInSct() const
Definition: frame.hxx:948
SwFont & GetFont()
Definition: swfntcch.hxx:58
bool m_bRealHeight
should the real height be calculated?
Definition: crstate.hxx:141
sal_uInt16 nParaCnt
number of paragraphs to insert
Definition: crstate.hxx:40
bool IsSwapped() const
Definition: txtfrm.hxx:532
static bool IsRightMargin()
Definition: itrtxt.hxx:295
const SvxTabStopItem & GetTabStops(bool=true) const
Definition: paratr.hxx:205
const SwLineLayout * NextLine()
Definition: itrtxt.cxx:124
bool HasPara() const
Definition: txtfrm.hxx:816
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:238
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:88
friend bool sw_ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmcrsr.cxx:108
SwRect aCursor
position and size of the ShadowCursor
Definition: crstate.hxx:39
void Left(const tools::Long nLeft)
Definition: swrect.hxx:195
SwNodeIndex nNode
Definition: pam.hxx:37
void Refresh(const SwFrame *pFrame)
Definition: frame.hxx:1340
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:471
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const override
Definition: frmcrsr.cxx:1293
bool GetFirstLineOfsWithNum(short &rFirstOffset) const
Returns the combined first line indent of this text node and its numbering.
Definition: ndtxt.cxx:3195
sal_uIntPtr sal_uLong
long Long
tools::Long GetRight() const
virtual bool LeftMargin(SwPaM *) const override
Layout oriented cursor travelling: Left border, right border, previous Line, following Line...
Definition: frmcrsr.cxx:672
const SwRect & getFramePrintArea() const
Definition: frame.hxx:179
sal_uInt16 nSpaceCnt
number of spaces to insert
Definition: crstate.hxx:42
only align left, center, right
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:447
bool HasFollow() const
Definition: flowfrm.hxx:165
virtual bool GetCharRect(SwRect &rRect, const SwPosition &rPos, SwCursorMoveState *pCMS=nullptr, bool bAllowFarAway=true) const override
Returns the screen position of rPos.
Definition: frmcrsr.cxx:178
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
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const override
Definition: frmcrsr.cxx:1274
#define FILL_MIN_DIST
Definition: frmcrsr.cxx:519
tools::Long X() const
Definition: frmcrsr.cxx:537
bool IsVert() const
Definition: frame.hxx:1348
static void SetRightMargin(const bool bNew)
Definition: itrtxt.hxx:294
void Pos(const Point &rNew)
Definition: swrect.hxx:169
SwPosition * pPos
Definition: frmcrsr.cxx:525
SwTwips FirstLeft() const
Definition: itrtxt.hxx:182
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1285
bool IsInside(TextFrameIndex nPos) const
Respect the Follows.
Definition: txtfrm.hxx:826
void SetTab(sal_uInt16 nNew)
Definition: frmcrsr.cxx:543
SwTwips Y() const
Definition: itrtxt.hxx:90
virtual bool RightMargin(SwPaM *, bool bAPI=false) const override
Definition: frmcrsr.cxx:706
void SetPara(SwParaPortion *pNew, bool bDelete=true)
Definition: txtcache.cxx:129
bool IsMulti() const
Definition: inftxt.hxx:203
sal_uInt16 const aTextFormatCollSetRange[]
Definition: init.cxx:149
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:170
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1352
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1358
sal_uInt16 sal_Unicode
bool bFirstLine
Definition: frmcrsr.cxx:528
SwFillMode Mode() const
Definition: frmcrsr.cxx:536
bool GetKeyCursorOfst(SwPosition *pPos, const Point &rPoint) const
Makes sure that the Frame is not switched (e.g.
Definition: txtfrm.hxx:399
const SwRect & getFrameArea() const
Definition: frame.hxx:178
SwFlyFrame * GetPrevLink() const
Definition: flyfrm.hxx:173
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
bool getBrowseMode() const
Definition: viewopt.hxx:472
Cursor Up/Down.
void FillCursorPos(SwFillData &rFill) const
Definition: frmcrsr.cxx:1303
bool IsInTab() const
Definition: frame.hxx:936
by left paragraph indentation
sal_uInt16 nSpaceOnlyCnt
number of spaces to insert ("only spaces, no tabs" mode)
Definition: crstate.hxx:43
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
sal_Int32 & GetTabPos()
void SetSpace(sal_uInt16 nNew)
Definition: frmcrsr.cxx:544
bool IsTextFrame() const
Definition: frame.hxx:1215
const SwLineLayout * GetNextLine() const
Definition: itrtxt.cxx:134
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:966
oslFileHandle & pOut
void Width(tools::Long nNew)
Definition: swrect.hxx:187
SwFillMode
Definition: crstate.hxx:28
SwFillMode eMode
desired fill-up rule
Definition: crstate.hxx:46
bool IsSctFrame() const
Definition: frame.hxx:1195
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1092
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:971
SwAttrPool * GetPool() const
Definition: swatrset.hxx:190
bool bEmpty
Definition: frmcrsr.cxx:531
SwFillData(const SwCursorMoveState *pC, SwPosition *pP, const SwRect &rR, const Point &rPt)
Definition: frmcrsr.cxx:532
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:852
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:435
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:675
tools::Long Right() const
Definition: frmcrsr.cxx:540
bool IsEmpty() const
Definition: txtfrm.hxx:518
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
tools::Long Y() const
Definition: frmcrsr.cxx:538
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1295
tools::Long GetTextLeft() const
bool IsCursorInProtectedArea() const
Definition: viewopt.hxx:409
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1259
sal_uInt16 nTabCnt
number of tabs respectively size of indentation
Definition: crstate.hxx:41
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:114
const SwLineLayout * GetPrevLine()
Definition: itrtxt.cxx:144
sw::BroadcastingModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:460
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1391
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:132
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:78
size_t size() const
Definition: ring.hxx:173
const SwPosition * GetPoint() const
Definition: pam.hxx:207
void Top()
Definition: itrtxt.hxx:99
size_t size() const
Definition: sortedobjs.cxx:43
SwPageFrame * FindPageFrame()
Definition: frame.hxx:663
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:918
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwTextFrame * GetFrameAtPos(const SwPosition &rPos)
Definition: frmcrsr.cxx:151
SwLinePortion * GetFirstPortion() const
Definition: porlay.cxx:699
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1363
tools::Long GetLeft() const
SwLayoutFrame * GetUpper()
Definition: frame.hxx:661
void TwipsToLine(const SwTwips)
Definition: itrtxt.cxx:300
SwTextFrame & GetFrameAtOfst(TextFrameIndex nOfst)
Definition: frmcrsr.cxx:143
bool HasArea() const
Definition: swrect.hxx:288
tools::Long Left() const
Definition: frmcrsr.cxx:539
bool GetModelPositionForViewPoint_(SwPosition *pPos, const Point &rPoint, const bool bChgFrame, SwCursorMoveState *=nullptr) const
Definition: frmcrsr.cxx:549
bool IsUndersized() const
Definition: flowfrm.hxx:158
const SwLineLayout * GetPrev()
Definition: itrtxt.cxx:82
tools::Long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1390
SvxInterLineSpaceRule GetInterLineSpaceRule() const
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3355
sal_uInt16 GetLineHeight() const
Definition: itrtxt.hxx:116
tools::Long GetLeftMarginWithNum(bool bTextLeft=false) const
Returns the additional indents of this text node and its numbering.
Definition: ndtxt.cxx:3152
const SvxLineSpacingItem & GetLineSpacing(bool=true) const
Definition: paratr.hxx:193
bool GetTopOfLine(SwTwips &_onTopOfLine, const SwPosition &_rPos) const
Determine top of line for given position in the text frame.
Definition: frmcrsr.cxx:453
ring_container GetRingContainer()
Definition: ring.hxx:240
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1404
SwRect aFrame
Definition: frmcrsr.cxx:523
bool IsLocked() const
Definition: txtfrm.hxx:514
Point m_aRealHeight
contains then the position/height of the cursor
Definition: crstate.hxx:137
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
TextFrameIndex GetLen() const
Definition: porlin.hxx:73
A page of the document layout.
Definition: pagefrm.hxx:41
bool m_bNoScroll
No scrolling of undersized textframes.
Definition: crstate.hxx:151
bool m_b2Lines
Check 2line portions and fill p2Lines.
Definition: crstate.hxx:150
stay with the cursor inside text
tools::Long SwTwips
Definition: swtypes.hxx:49
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:543
const OUString & GetText() const
Definition: inftxt.hxx:239
std::unique_ptr< Sw2LinesPos > m_p2Lines
for selections inside/around 2line portions
Definition: crstate.hxx:135
tools::Long Bottom() const
Definition: frmcrsr.cxx:541
void GetEndCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const tools::Long nMax=0)
Definition: itrcrsr.cxx:400
void SetParent(const SfxItemSet *pNew)
bool UnitUp_(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: frmcrsr.cxx:760
bool IsMultiPortion() const
Definition: porlin.hxx:135
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:681
SwFillCursorPos * m_pFill
for automatic filling with tabs etc
Definition: crstate.hxx:134
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:49
bool GetAutoPos(SwRect &, const SwPosition &) const
A slimmer version of GetCharRect for autopositioning Frames.
Definition: frmcrsr.cxx:366
const SwLineLayout * Prev()
Definition: itrtxt.cxx:89
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:209
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
SwFontObj * Get()
Definition: swfntcch.cxx:56
void SetSpaceOnly(sal_uInt16 nNew)
Definition: frmcrsr.cxx:545
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
Definition: txtfrm.hxx:732
default, fill with tabs
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:46
bool bColumn
Definition: frmcrsr.cxx:530
sal_uInt16 GetDropLeft() const
Definition: itrtxt.hxx:204
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
void SetOffset(TextFrameIndex nNewOfst)
Definition: txtfrm.hxx:862
TextFrameIndex GetLength() const
Definition: itrtxt.hxx:86
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:738
unsigned char sal_uInt8
fill with spaces and tabs
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
tools::Long GetLineSpace(const bool _bNoPropLineSpacing=false) const
Returns the additional line spacing for the next paragraph.
Definition: txtfrm.cxx:3679
void GetCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const tools::Long nMax=0)
Definition: itrcrsr.cxx:1178
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
void SwapWidthAndHeight()
Swaps width and height of the text frame.
Definition: txtfrm.cxx:418
bool IsRightToLeft() const
Definition: frame.hxx:968
void Top(const tools::Long nTop)
Definition: swrect.hxx:204
bool IsColBodyFrame() const
These SwFrame inlines are here, so that frame.hxx does not need to include layfrm.hxx.
Definition: layfrm.hxx:209
bool IsVertL2R() const
Definition: frame.hxx:1349
SwFlyFrame * GetNextLink() const
Definition: flyfrm.hxx:174
virtual OutputDevice * getReferenceDevice(bool bCreate) const =0
Returns the current reference device.
sal_uInt16 Width() const
Definition: possiz.hxx:51
tools::Long const nRightMargin
const SwLineLayout * PrevLine()
Definition: itrtxt.cxx:170
CursorMoveState m_eState
Definition: crstate.hxx:138
bool IsPrtFormat() const
Definition: viewopt.hxx:541
double getLength(const B2DPolygon &rCandidate)
static void lcl_VisualMoveRecursion(const SwLineLayout &rCurrLine, TextFrameIndex nIdx, TextFrameIndex &nPos, bool &bRight, sal_uInt8 &nCursorLevel, sal_uInt8 nDefaultDir)
Definition: frmcrsr.cxx:900
#define FAR_AWAY
Definition: frmtool.hxx:53
void PrepareVisualMove(TextFrameIndex &nPos, sal_uInt8 &nCursorLevel, bool &bRight, bool bInsertCursor)
Prepares the cursor position for a visual cursor move (BiDi).
Definition: frmcrsr.cxx:1045
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:718
bool m_bPosCorr
Point had to be corrected.
Definition: crstate.hxx:143
const SwLineLayout * GetNext() const
Definition: itrtxt.hxx:84
bool UnitDown_(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: frmcrsr.cxx:1149
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
bool IsVertical() const
Definition: frame.hxx:954
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1359
#define MIN_OFFSET_STEP
Definition: frmcrsr.cxx:49
const SwLineLayout * CharCursorToLine(TextFrameIndex const nPos)
Definition: itrtxt.cxx:202
SwDoc & GetDoc()
Definition: txtfrm.hxx:457
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:120
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:89
sal_uInt16 GetDropLines() const
Definition: itrtxt.hxx:202
SwTwips nLineWidth
Definition: frmcrsr.cxx:527
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:71
bool sw_ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmcrsr.cxx:108
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
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...
void Height(tools::Long nNew)
Definition: swrect.hxx:191
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1238
const Point & rPoint
Definition: frmcrsr.cxx:526
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:662
sal_uInt16 nPos
const SwCursorMoveState * pCMS
Definition: frmcrsr.cxx:524
fill with spaces
SwTextFormatColl & GetNextTextFormatColl() const
Definition: fmtcol.hxx:102
sal_uInt16 GetUpper() const
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1628
bool bInner
Definition: frmcrsr.cxx:529
SwFrame * GetNext()
Definition: frame.hxx:659
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:839
sal_uInt16 nColumnCnt
number of necessary column breaks
Definition: crstate.hxx:44