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 MV_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->GetOfst() &&
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->GetOfst()) == 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->GetOfst() != 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->GetOfst() )
128  return false;
129  nNew = TextFrameIndex(0);
130  }
131  pFrame->SetOfst( 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()->GetOfst() )
147  pRet = pRet->GetFollow();
148  return *pRet;
149 }
150 
152 {
154  SwTextFrame *pFoll = this;
155  while( pFoll->GetFollow() )
156  {
157  if (nPos > pFoll->GetFollow()->GetOfst())
158  pFoll = pFoll->GetFollow();
159  else
160  {
161  if (nPos == pFoll->GetFollow()->GetOfst()
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  * GetCursorOfst() 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 && ( MV_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->GetOfst() < 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( aRectFnSet.GetPrtBottom(*pFrame), nUpperMaxY );
386  else
387  nMaxY = std::max( aRectFnSet.GetPrtBottom(*pFrame), nUpperMaxY );
388  }
389  else
390  nMaxY = std::min( 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 );
428  SwCursorMoveState aTmpState( MV_SETONLYTEXT );
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  long X() const { return rPoint.X(); }
538  long Y() const { return rPoint.Y(); }
539  long Left() const { return aFrame.Left(); }
540  long Right() const { return aFrame.Right(); }
541  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 
549 bool SwTextFrame::GetCursorOfst_(SwPosition* pPos, const Point& rPoint,
550  const bool bChgFrame, SwCursorMoveState* pCMS ) const
551 {
552  // GetCursorOfst_ is called by GetCursorOfst 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.GetCursorOfst(pPos, rPoint, bChgFrame, pCMS);
605 
606  if( pCMS && pCMS->m_eState == MV_NONE && aLine.GetEnd() == nOffset )
607  pCMS->m_eState = MV_RIGHTMARGIN;
608 
609  // pPos is a pure IN parameter and must not be evaluated.
610  // pIter->GetCursorOfst returns from a nesting with COMPLETE_STRING.
611  // If SwTextIter::GetCursorOfst calls GetCursorOfst 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 && MV_UPDOWN == pCMS->m_eState);
665  return GetCursorOfst_( 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->GetOfst() && !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 brakes
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 bRight;
748 public:
749  SwSetToRightMargin() : bRight( false ) { }
750  ~SwSetToRightMargin() { SwTextCursor::SetRightMargin( bRight ); }
751  void SetRight( const bool bNew ) { bRight = bNew; }
752 };
753 
754 }
755 
756 bool SwTextFrame::UnitUp_( SwPaM *pPam, const SwTwips nOffset,
757  bool bSetInReadOnly ) const
758 {
759  // Set the RightMargin if needed
760  SwSetToRightMargin aSet;
761 
762  if( IsInTab() &&
763  pPam->GetNode().StartOfSectionNode() !=
764  pPam->GetNode( false ).StartOfSectionNode() )
765  {
766  // If the PaM is located within different boxes, we have a table selection,
767  // which is handled by the base class.
768  return SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
769  }
770 
771  const_cast<SwTextFrame*>(this)->GetFormatted();
772  const TextFrameIndex nPos = MapModelToViewPos(*pPam->GetPoint());
773  SwRect aCharBox;
774 
775  if( !IsEmpty() && !IsHiddenNow() )
776  {
778  do
779  {
780  if (nFormat != TextFrameIndex(COMPLETE_STRING) && !IsFollow())
781  sw_ChangeOffset( const_cast<SwTextFrame*>(this), nFormat );
782 
783  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
784  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
785 
786  // Optimize away flys with no flow and IsDummy()
787  if( nPos )
788  aLine.CharCursorToLine( nPos );
789  else
790  aLine.Top();
791 
792  const SwLineLayout *pPrevLine = aLine.GetPrevLine();
793  const TextFrameIndex nStart = aLine.GetStart();
794  aLine.GetCharRect( &aCharBox, nPos );
795 
796  bool bSecondOfDouble = ( aInf.IsMulti() && ! aInf.IsFirstMulti() );
797  bool bPrevLine = ( pPrevLine && pPrevLine != aLine.GetCurr() );
798 
799  if( !pPrevLine && !bSecondOfDouble && GetOfst() && !IsFollow() )
800  {
801  nFormat = GetOfst();
802  TextFrameIndex nDiff = aLine.GetLength();
803  if( !nDiff )
805  if( nFormat > nDiff )
806  nFormat = nFormat - nDiff;
807  else
808  nFormat = TextFrameIndex(0);
809  continue;
810  }
811 
812  // We select the target line for the cursor, in case we are in a
813  // double line portion, prev line = curr line
814  if( bPrevLine && !bSecondOfDouble )
815  {
816  aLine.PrevLine();
817  while ( aLine.GetStart() == nStart &&
818  nullptr != ( pPrevLine = aLine.GetPrevLine() ) &&
819  pPrevLine != aLine.GetCurr() )
820  aLine.PrevLine();
821  }
822 
823  if ( bPrevLine || bSecondOfDouble )
824  {
825  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
826  aCharBox.Pos().setX( aCharBox.Pos().X() - 150 );
827 
828  // See comment in SwTextFrame::GetCursorOfst()
829 #if OSL_DEBUG_LEVEL > 0
830  const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
831 #endif
832  // The node should not be changed
833  TextFrameIndex nTmpOfst = aLine.GetCursorOfst(pPam->GetPoint(),
834  aCharBox.Pos(), false );
835 #if OSL_DEBUG_LEVEL > 0
836  OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
837  "SwTextFrame::UnitUp: illegal node change" );
838 #endif
839 
840  // We make sure that we move up.
841  if( nTmpOfst >= nStart && nStart && !bSecondOfDouble )
842  {
843  nTmpOfst = nStart;
844  aSet.SetRight( true );
845  }
846  *pPam->GetPoint() = MapViewToModelPos(nTmpOfst);
847  return true;
848  }
849 
850  if ( IsFollow() )
851  {
852  aLine.GetCharRect( &aCharBox, nPos );
853  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
854  }
855  break;
856  } while ( true );
857  }
858  /* If 'this' is a follow and a prev failed, we need to go to the
859  * last line of the master, which is us.
860  * Or: If we are a follow with follow, we need to get the master.
861  */
862  if ( IsFollow() )
863  {
864  const SwTextFrame *pTmpPrev = FindMaster();
865  TextFrameIndex nOffs = GetOfst();
866  if( pTmpPrev )
867  {
869  const bool bProtectedAllowed = pSh && pSh->GetViewOptions()->IsCursorInProtectedArea();
870  const SwTextFrame *pPrevPrev = pTmpPrev;
871  // We skip protected frames and frames without content here
872  while( pPrevPrev && ( pPrevPrev->GetOfst() == nOffs ||
873  ( !bProtectedAllowed && pPrevPrev->IsProtected() ) ) )
874  {
875  pTmpPrev = pPrevPrev;
876  nOffs = pTmpPrev->GetOfst();
877  if ( pPrevPrev->IsFollow() )
878  pPrevPrev = pTmpPrev->FindMaster();
879  else
880  pPrevPrev = nullptr;
881  }
882  if ( !pPrevPrev )
883  return pTmpPrev->SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
884  aCharBox.Pos().setY( pPrevPrev->getFrameArea().Bottom() - 1 );
885  return pPrevPrev->GetKeyCursorOfst( pPam->GetPoint(), aCharBox.Pos() );
886  }
887  }
888  return SwContentFrame::UnitUp( pPam, nOffset, bSetInReadOnly );
889 }
890 
891 // Used for Bidi. nPos is the logical position in the string, bLeft indicates
892 // if left arrow or right arrow was pressed. The return values are:
893 // nPos: the new visual position
894 // bLeft: whether the break iterator has to add or subtract from the
895 // current position
896 static void lcl_VisualMoveRecursion(const SwLineLayout& rCurrLine, TextFrameIndex nIdx,
897  TextFrameIndex & nPos, bool& bRight,
898  sal_uInt8& nCursorLevel, sal_uInt8 nDefaultDir )
899 {
900  const SwLinePortion* pPor = rCurrLine.GetFirstPortion();
901  const SwLinePortion* pLast = nullptr;
902 
903  // What's the current portion?
904  while ( pPor && nIdx + pPor->GetLen() <= nPos )
905  {
906  nIdx = nIdx + pPor->GetLen();
907  pLast = pPor;
908  pPor = pPor->GetNextPortion();
909  }
910 
911  if ( bRight )
912  {
913  bool bRecurse = pPor && pPor->IsMultiPortion() &&
914  static_cast<const SwMultiPortion*>(pPor)->IsBidi();
915 
916  // 1. special case: at beginning of bidi portion
917  if ( bRecurse && nIdx == nPos )
918  {
919  nPos = nPos + pPor->GetLen();
920 
921  // leave bidi portion
922  if ( nCursorLevel != nDefaultDir )
923  {
924  bRecurse = false;
925  }
926  else
927  // special case:
928  // buffer: abcXYZ123 in LTR paragraph
929  // view: abc123ZYX
930  // cursor is between c and X in the buffer and cursor level = 0
931  nCursorLevel++;
932  }
933 
934  // 2. special case: at beginning of portion after bidi portion
935  else if ( pLast && pLast->IsMultiPortion() &&
936  static_cast<const SwMultiPortion*>(pLast)->IsBidi() && nIdx == nPos )
937  {
938  // enter bidi portion
939  if ( nCursorLevel != nDefaultDir )
940  {
941  bRecurse = true;
942  nIdx = nIdx - pLast->GetLen();
943  pPor = pLast;
944  }
945  }
946 
947  // Recursion
948  if ( bRecurse )
949  {
950  const SwLineLayout& rLine = static_cast<const SwMultiPortion*>(pPor)->GetRoot();
951  TextFrameIndex nTmpPos = nPos - nIdx;
952  bool bTmpForward = ! bRight;
953  sal_uInt8 nTmpCursorLevel = nCursorLevel;
954  lcl_VisualMoveRecursion(rLine, TextFrameIndex(0), nTmpPos, bTmpForward,
955  nTmpCursorLevel, nDefaultDir + 1 );
956 
957  nPos = nTmpPos + nIdx;
958  bRight = bTmpForward;
959  nCursorLevel = nTmpCursorLevel;
960  }
961 
962  // go forward
963  else
964  {
965  bRight = true;
966  nCursorLevel = nDefaultDir;
967  }
968 
969  }
970  else
971  {
972  bool bRecurse = pPor && pPor->IsMultiPortion() && static_cast<const SwMultiPortion*>(pPor)->IsBidi();
973 
974  // 1. special case: at beginning of bidi portion
975  if ( bRecurse && nIdx == nPos )
976  {
977  // leave bidi portion
978  if ( nCursorLevel == nDefaultDir )
979  {
980  bRecurse = false;
981  }
982  }
983 
984  // 2. special case: at beginning of portion after bidi portion
985  else if ( pLast && pLast->IsMultiPortion() &&
986  static_cast<const SwMultiPortion*>(pLast)->IsBidi() && nIdx == nPos )
987  {
988  nPos = nPos - pLast->GetLen();
989 
990  // enter bidi portion
991  if ( nCursorLevel % 2 == nDefaultDir % 2 )
992  {
993  bRecurse = true;
994  nIdx = nIdx - pLast->GetLen();
995  pPor = pLast;
996 
997  // special case:
998  // buffer: abcXYZ123 in LTR paragraph
999  // view: abc123ZYX
1000  // cursor is behind 3 in the buffer and cursor level = 2
1001  if ( nDefaultDir + 2 == nCursorLevel )
1002  nPos = nPos + pLast->GetLen();
1003  }
1004  }
1005 
1006  // go forward
1007  if ( bRecurse )
1008  {
1009  const SwLineLayout& rLine = static_cast<const SwMultiPortion*>(pPor)->GetRoot();
1010  TextFrameIndex nTmpPos = nPos - nIdx;
1011  bool bTmpForward = ! bRight;
1012  sal_uInt8 nTmpCursorLevel = nCursorLevel;
1013  lcl_VisualMoveRecursion(rLine, TextFrameIndex(0), nTmpPos, bTmpForward,
1014  nTmpCursorLevel, nDefaultDir + 1 );
1015 
1016  // special case:
1017  // buffer: abcXYZ123 in LTR paragraph
1018  // view: abc123ZYX
1019  // cursor is between Z and 1 in the buffer and cursor level = 2
1020  if ( nTmpPos == pPor->GetLen() && nTmpCursorLevel == nDefaultDir + 1 )
1021  {
1022  nTmpPos = nTmpPos - pPor->GetLen();
1023  nTmpCursorLevel = nDefaultDir;
1024  bTmpForward = ! bTmpForward;
1025  }
1026 
1027  nPos = nTmpPos + nIdx;
1028  bRight = bTmpForward;
1029  nCursorLevel = nTmpCursorLevel;
1030  }
1031 
1032  // go backward
1033  else
1034  {
1035  bRight = false;
1036  nCursorLevel = nDefaultDir;
1037  }
1038  }
1039 }
1040 
1042  bool& bForward, bool bInsertCursor )
1043 {
1044  if( IsEmpty() || IsHiddenNow() )
1045  return;
1046 
1047  GetFormatted();
1048 
1049  SwTextSizeInfo aInf(this);
1050  SwTextCursor aLine(this, &aInf);
1051 
1052  if( nPos )
1053  aLine.CharCursorToLine( nPos );
1054  else
1055  aLine.Top();
1056 
1057  const SwLineLayout* pLine = aLine.GetCurr();
1058  const TextFrameIndex nStt = aLine.GetStart();
1059  const TextFrameIndex nLen = pLine->GetLen();
1060 
1061  // We have to distinguish between an insert and overwrite cursor:
1062  // The insert cursor position depends on the cursor level:
1063  // buffer: abcXYZdef in LTR paragraph
1064  // display: abcZYXdef
1065  // If cursor is between c and X in the buffer and cursor level is 0,
1066  // the cursor blinks between c and Z and -> sets the cursor between Z and Y.
1067  // If the cursor level is 1, the cursor blinks between X and d and
1068  // -> sets the cursor between d and e.
1069  // The overwrite cursor simply travels to the next visual character.
1070  if ( bInsertCursor )
1071  {
1072  lcl_VisualMoveRecursion( *pLine, nStt, nPos, bForward,
1073  nCursorLevel, IsRightToLeft() ? 1 : 0 );
1074  return;
1075  }
1076 
1077  const sal_uInt8 nDefaultDir = static_cast<sal_uInt8>(IsRightToLeft() ? UBIDI_RTL : UBIDI_LTR);
1078  const bool bVisualRight = ( nDefaultDir == UBIDI_LTR && bForward ) ||
1079  ( nDefaultDir == UBIDI_RTL && ! bForward );
1080 
1081  // Bidi functions from icu 2.0
1082 
1083  const sal_Unicode* pLineString = GetText().getStr();
1084 
1085  UErrorCode nError = U_ZERO_ERROR;
1086  UBiDi* pBidi = ubidi_openSized( sal_Int32(nLen), 0, &nError );
1087  ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString),
1088  sal_Int32(nLen), nDefaultDir, nullptr, &nError );
1089 
1090  TextFrameIndex nTmpPos(0);
1091  bool bOutOfBounds = false;
1092 
1093  if ( nPos < nStt + nLen )
1094  {
1095  nTmpPos = TextFrameIndex(ubidi_getVisualIndex( pBidi, sal_Int32(nPos), &nError ));
1096 
1097  // visual indices are always LTR aligned
1098  if ( bVisualRight )
1099  {
1100  if (nTmpPos + TextFrameIndex(1) < nStt + nLen)
1101  ++nTmpPos;
1102  else
1103  {
1104  nPos = nDefaultDir == UBIDI_RTL ? TextFrameIndex(0) : nStt + nLen;
1105  bOutOfBounds = true;
1106  }
1107  }
1108  else
1109  {
1110  if ( nTmpPos )
1111  --nTmpPos;
1112  else
1113  {
1114  nPos = nDefaultDir == UBIDI_RTL ? nStt + nLen : TextFrameIndex(0);
1115  bOutOfBounds = true;
1116  }
1117  }
1118  }
1119  else
1120  {
1121  nTmpPos = nDefaultDir == UBIDI_LTR ? nPos - TextFrameIndex(1) : TextFrameIndex(0);
1122  }
1123 
1124  if ( ! bOutOfBounds )
1125  {
1126  nPos = TextFrameIndex(ubidi_getLogicalIndex( pBidi, sal_Int32(nTmpPos), &nError ));
1127 
1128  if ( bForward )
1129  {
1130  if ( nPos )
1131  --nPos;
1132  else
1133  {
1134  ++nPos;
1135  bForward = ! bForward;
1136  }
1137  }
1138  else
1139  ++nPos;
1140  }
1141 
1142  ubidi_close( pBidi );
1143 }
1144 
1145 bool SwTextFrame::UnitDown_(SwPaM *pPam, const SwTwips nOffset,
1146  bool bSetInReadOnly ) const
1147 {
1148 
1149  if ( IsInTab() &&
1150  pPam->GetNode().StartOfSectionNode() !=
1151  pPam->GetNode( false ).StartOfSectionNode() )
1152  {
1153  // If the PaM is located within different boxes, we have a table selection,
1154  // which is handled by the base class.
1155  return SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1156  }
1157  const_cast<SwTextFrame*>(this)->GetFormatted();
1158  const TextFrameIndex nPos = MapModelToViewPos(*pPam->GetPoint());
1159  SwRect aCharBox;
1160  const SwContentFrame *pTmpFollow = nullptr;
1161 
1162  if ( IsVertical() )
1163  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1164 
1165  if ( !IsEmpty() && !IsHiddenNow() )
1166  {
1168  do
1169  {
1170  if (nFormat != TextFrameIndex(COMPLETE_STRING) && !IsFollow() &&
1171  !sw_ChangeOffset( const_cast<SwTextFrame*>(this), nFormat ) )
1172  break;
1173 
1174  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
1175  SwTextCursor aLine( const_cast<SwTextFrame*>(this), &aInf );
1176  nFormat = aLine.GetEnd();
1177 
1178  aLine.CharCursorToLine( nPos );
1179 
1180  const SwLineLayout* pNextLine = aLine.GetNextLine();
1181  const TextFrameIndex nStart = aLine.GetStart();
1182  aLine.GetCharRect( &aCharBox, nPos );
1183 
1184  bool bFirstOfDouble = ( aInf.IsMulti() && aInf.IsFirstMulti() );
1185 
1186  if( pNextLine || bFirstOfDouble )
1187  {
1188  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
1189 #if OSL_DEBUG_LEVEL > 0
1190  // See comment in SwTextFrame::GetCursorOfst()
1191  const sal_uLong nOldNode = pPam->GetPoint()->nNode.GetIndex();
1192 #endif
1193  if ( pNextLine && ! bFirstOfDouble )
1194  aLine.NextLine();
1195 
1196  TextFrameIndex nTmpOfst = aLine.GetCursorOfst( pPam->GetPoint(),
1197  aCharBox.Pos(), false );
1198 #if OSL_DEBUG_LEVEL > 0
1199  OSL_ENSURE( nOldNode == pPam->GetPoint()->nNode.GetIndex(),
1200  "SwTextFrame::UnitDown: illegal node change" );
1201 #endif
1202 
1203  // We make sure that we move down.
1204  if( nTmpOfst <= nStart && ! bFirstOfDouble )
1205  nTmpOfst = nStart + TextFrameIndex(1);
1206  *pPam->GetPoint() = MapViewToModelPos(nTmpOfst);
1207 
1208  if ( IsVertical() )
1209  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1210 
1211  return true;
1212  }
1213  if( nullptr != ( pTmpFollow = GetFollow() ) )
1214  { // Skip protected follows
1215  const SwContentFrame* pTmp = pTmpFollow;
1217  if( !pSh || !pSh->GetViewOptions()->IsCursorInProtectedArea() )
1218  {
1219  while( pTmpFollow && pTmpFollow->IsProtected() )
1220  {
1221  pTmp = pTmpFollow;
1222  pTmpFollow = pTmpFollow->GetFollow();
1223  }
1224  }
1225  if( !pTmpFollow ) // Only protected ones left
1226  {
1227  if ( IsVertical() )
1228  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1229  return pTmp->SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1230  }
1231 
1232  aLine.GetCharRect( &aCharBox, nPos );
1233  aCharBox.SSize().setWidth( aCharBox.SSize().Width() / 2 );
1234  }
1235  else if( !IsFollow() )
1236  {
1237  TextFrameIndex nTmpLen(aInf.GetText().getLength());
1238  if( aLine.GetEnd() < nTmpLen )
1239  {
1240  if( nFormat <= GetOfst() )
1241  {
1242  nFormat = std::min(GetOfst() + TextFrameIndex(MIN_OFFSET_STEP),
1243  nTmpLen );
1244  if( nFormat <= GetOfst() )
1245  break;
1246  }
1247  continue;
1248  }
1249  }
1250  break;
1251  } while( true );
1252  }
1253  else
1254  pTmpFollow = GetFollow();
1255 
1256  if ( IsVertical() )
1257  const_cast<SwTextFrame*>(this)->SwapWidthAndHeight();
1258 
1259  // We take a shortcut for follows
1260  if( pTmpFollow )
1261  {
1262  aCharBox.Pos().setY( pTmpFollow->getFrameArea().Top() + 1 );
1263  return static_cast<const SwTextFrame*>(pTmpFollow)->GetKeyCursorOfst( pPam->GetPoint(),
1264  aCharBox.Pos() );
1265  }
1266  return SwContentFrame::UnitDown( pPam, nOffset, bSetInReadOnly );
1267 }
1268 
1269 bool SwTextFrame::UnitUp(SwPaM *pPam, const SwTwips nOffset,
1270  bool bSetInReadOnly ) const
1271 {
1272  /* We call ContentNode::GertFrame() in CursorSh::Up().
1273  * This _always returns the master.
1274  * In order to not mess with cursor travelling, we correct here
1275  * in SwTextFrame.
1276  * We calculate UnitUp for pFrame. pFrame is either a master (= this) or a
1277  * follow (!= this).
1278  */
1279  const SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *(pPam->GetPoint()),
1281  const bool bRet = pFrame->UnitUp_( pPam, nOffset, bSetInReadOnly );
1282 
1283  // No SwTextCursor::SetRightMargin( false );
1284  // Instead we have a SwSetToRightMargin in UnitUp_
1285  return bRet;
1286 }
1287 
1288 bool SwTextFrame::UnitDown(SwPaM *pPam, const SwTwips nOffset,
1289  bool bSetInReadOnly ) const
1290 {
1291  const SwTextFrame *pFrame = GetAdjFrameAtPos(const_cast<SwTextFrame*>(this), *(pPam->GetPoint()),
1293  const bool bRet = pFrame->UnitDown_( pPam, nOffset, bSetInReadOnly );
1295  return bRet;
1296 }
1297 
1299 {
1300  if( !rFill.bColumn && GetUpper()->IsColBodyFrame() ) // ColumnFrames now with BodyFrame
1301  {
1302  const SwColumnFrame* pTmp =
1303  static_cast<const SwColumnFrame*>(GetUpper()->GetUpper()->GetUpper()->Lower()); // The 1st column
1304  // The first SwFrame in BodyFrame of the first column
1305  const SwFrame* pFrame = static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower();
1306  sal_uInt16 nNextCol = 0;
1307  // In which column do we end up in?
1308  while( rFill.X() > pTmp->getFrameArea().Right() && pTmp->GetNext() )
1309  {
1310  pTmp = static_cast<const SwColumnFrame*>(pTmp->GetNext());
1311  if( static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower() ) // ColumnFrames now with BodyFrame
1312  {
1313  pFrame = static_cast<const SwLayoutFrame*>(pTmp->Lower())->Lower();
1314  nNextCol = 0;
1315  }
1316  else
1317  ++nNextCol; // Empty columns require column brakes
1318  }
1319  if( pTmp != GetUpper()->GetUpper() ) // Did we end up in another column?
1320  {
1321  if( !pFrame )
1322  return;
1323  if( nNextCol )
1324  {
1325  while( pFrame->GetNext() )
1326  pFrame = pFrame->GetNext();
1327  }
1328  else
1329  {
1330  while( pFrame->GetNext() && pFrame->getFrameArea().Bottom() < rFill.Y() )
1331  pFrame = pFrame->GetNext();
1332  }
1333  // No filling, if the last frame in the targeted column does
1334  // not contain a paragraph, but e.g. a table
1335  if( pFrame->IsTextFrame() )
1336  {
1337  rFill.Fill().nColumnCnt = nNextCol;
1338  rFill.bColumn = true;
1339  if( rFill.pPos )
1340  {
1341  SwTextFrame const*const pTextFrame(static_cast<const SwTextFrame*>(pFrame));
1342  *rFill.pPos = pTextFrame->MapViewToModelPos(
1343  TextFrameIndex(pTextFrame->GetText().getLength()));
1344  }
1345  if( nNextCol )
1346  {
1347  rFill.aFrame = pTmp->getFramePrintArea();
1348  rFill.aFrame += pTmp->getFrameArea().Pos();
1349  }
1350  else
1351  rFill.aFrame = pFrame->getFrameArea();
1352  static_cast<const SwTextFrame*>(pFrame)->FillCursorPos( rFill );
1353  }
1354  return;
1355  }
1356  }
1357  std::unique_ptr<SwFont> pFnt;
1360  SwTwips nDiff = rFill.Y() - getFrameArea().Bottom();
1361  if( nDiff < nFirst )
1362  nDiff = -1;
1363  else
1364  pColl = &pColl->GetNextTextFormatColl();
1365  SwAttrSet aSet(const_cast<SwDoc&>(GetDoc()).GetAttrPool(), aTextFormatCollSetRange );
1366  const SwAttrSet* pSet = &pColl->GetAttrSet();
1368  if (GetTextNodeForParaProps()->HasSwAttrSet())
1369  {
1370  // sw_redlinehide: pSet is mostly used for para props, but there are
1371  // accesses to char props via pFnt - why does it use only the node's
1372  // props for this, and not hints?
1373  aSet.Put( *GetTextNodeForParaProps()->GetpSwAttrSet() );
1374  aSet.SetParent( pSet );
1375  pSet = &aSet;
1376  pFnt.reset(new SwFont( pSet, &GetDoc().getIDocumentSettingAccess() ));
1377  }
1378  else
1379  {
1380  SwFontAccess aFontAccess( pColl, pSh );
1381  pFnt.reset(new SwFont( aFontAccess.Get()->GetFont() ));
1382  pFnt->CheckFontCacheId( pSh, pFnt->GetActual() );
1383  }
1384  OutputDevice* pOut = pSh->GetOut();
1385  if( !pSh->GetViewOptions()->getBrowseMode() || pSh->GetViewOptions()->IsPrtFormat() )
1387 
1388  pFnt->SetFntChg( true );
1389  pFnt->ChgPhysFnt( pSh, *pOut );
1390 
1391  SwTwips nLineHeight = pFnt->GetHeight( pSh, *pOut );
1392 
1393  bool bFill = false;
1394  if( nLineHeight )
1395  {
1396  bFill = true;
1397  const SvxULSpaceItem &rUL = pSet->GetULSpace();
1398  SwTwips nDist = std::max( rUL.GetLower(), rUL.GetUpper() );
1399  if( rFill.Fill().nColumnCnt )
1400  {
1401  rFill.aFrame.Height( nLineHeight );
1402  nDiff = rFill.Y() - rFill.Bottom();
1403  nFirst = 0;
1404  }
1405  else if( nDist < nFirst )
1406  nFirst = nFirst - nDist;
1407  else
1408  nFirst = 0;
1409  nDist = std::max( nDist, GetLineSpace() );
1410  nDist += nLineHeight;
1411  nDiff -= nFirst;
1412 
1413  if( nDiff > 0 )
1414  {
1415  nDiff /= nDist;
1416  rFill.Fill().nParaCnt = static_cast<sal_uInt16>(nDiff + 1);
1417  rFill.nLineWidth = 0;
1418  rFill.bInner = false;
1419  rFill.bEmpty = true;
1420  rFill.SetOrient( text::HoriOrientation::LEFT );
1421  }
1422  else
1423  nDiff = -1;
1424  if( rFill.bInner )
1425  bFill = false;
1426  else
1427  {
1428  const SvxTabStopItem &rRuler = pSet->GetTabStops();
1429  const SvxLRSpaceItem &rLRSpace = pSet->GetLRSpace();
1430 
1431  SwRect &rRect = rFill.Fill().aCursor;
1432  rRect.Top( rFill.Bottom() + (nDiff+1) * nDist - nLineHeight );
1433  if( nFirst && nDiff > -1 )
1434  rRect.Top( rRect.Top() + nFirst );
1435  rRect.Height( nLineHeight );
1436  SwTwips nLeft = rFill.Left() + rLRSpace.GetLeft() +
1438  SwTwips nRight = rFill.Right() - rLRSpace.GetRight();
1439  SwTwips nCenter = ( nLeft + nRight ) / 2;
1440  rRect.Left( nLeft );
1441  if( FILL_MARGIN == rFill.Mode() )
1442  {
1443  if( rFill.bEmpty )
1444  {
1445  rFill.SetOrient( text::HoriOrientation::LEFT );
1446  if( rFill.X() < nCenter )
1447  {
1448  if( rFill.X() > ( nLeft + 2 * nCenter ) / 3 )
1449  {
1450  rFill.SetOrient( text::HoriOrientation::CENTER );
1451  rRect.Left( nCenter );
1452  }
1453  }
1454  else if( rFill.X() > ( nRight + 2 * nCenter ) / 3 )
1455  {
1456  rFill.SetOrient( text::HoriOrientation::RIGHT );
1457  rRect.Left( nRight );
1458  }
1459  else
1460  {
1461  rFill.SetOrient( text::HoriOrientation::CENTER );
1462  rRect.Left( nCenter );
1463  }
1464  }
1465  else
1466  bFill = false;
1467  }
1468  else
1469  {
1470  SwTwips nSpace = 0;
1471  if( FILL_TAB != rFill.Mode() )
1472  {
1473  const OUString aTmp(" ");
1474  SwDrawTextInfo aDrawInf( pSh, *pOut, aTmp, 0, 2 );
1475  nSpace = pFnt->GetTextSize_( aDrawInf ).Width()/2;
1476  }
1477  if( rFill.X() >= nRight )
1478  {
1479  if( FILL_INDENT != rFill.Mode() && ( rFill.bEmpty ||
1480  rFill.X() > rFill.nLineWidth + FILL_MIN_DIST ) )
1481  {
1482  rFill.SetOrient( text::HoriOrientation::RIGHT );
1483  rRect.Left( nRight );
1484  }
1485  else
1486  bFill = false;
1487  }
1488  else if( FILL_INDENT == rFill.Mode() )
1489  {
1490  SwTwips nIndent = rFill.X();
1491  if( !rFill.bEmpty || nIndent > nRight )
1492  bFill = false;
1493  else
1494  {
1495  nIndent -= rFill.Left();
1496  if( nIndent >= 0 && nSpace )
1497  {
1498  nIndent /= nSpace;
1499  nIndent *= nSpace;
1500  rFill.SetTab( sal_uInt16( nIndent ) );
1501  rRect.Left( nIndent + rFill.Left() );
1502  }
1503  else
1504  bFill = false;
1505  }
1506  }
1507  else if( rFill.X() > nLeft )
1508  {
1509  SwTwips nTextLeft = rFill.Left() + rLRSpace.GetTextLeft() +
1511  rFill.nLineWidth += rFill.bFirstLine ? nLeft : nTextLeft;
1512  SwTwips nLeftTab;
1513  SwTwips nRightTab = nLeft;
1514  sal_uInt16 nSpaceCnt = 0;
1515  sal_uInt16 nSpaceOnlyCnt = 0;
1516  sal_uInt16 nTabCnt = 0;
1517  sal_uInt16 nIdx = 0;
1518  do
1519  {
1520  nLeftTab = nRightTab;
1521  if( nIdx < rRuler.Count() )
1522  {
1523  const SvxTabStop &rTabStop = rRuler.operator[](nIdx);
1524  nRightTab = nTextLeft + rTabStop.GetTabPos();
1525  if( nLeftTab < nTextLeft && nRightTab > nTextLeft )
1526  nRightTab = nTextLeft;
1527  else
1528  ++nIdx;
1529  if( nRightTab > rFill.nLineWidth )
1530  ++nTabCnt;
1531  }
1532  else
1533  {
1534  const SvxTabStopItem& rTab =
1536  const SwTwips nDefTabDist = rTab[0].GetTabPos();
1537  nRightTab = nLeftTab - nTextLeft;
1538  nRightTab /= nDefTabDist;
1539  nRightTab = nRightTab * nDefTabDist + nTextLeft;
1540  while ( nRightTab <= nLeftTab )
1541  nRightTab += nDefTabDist;
1542  if( nRightTab > rFill.nLineWidth )
1543  ++nTabCnt;
1544  while ( nRightTab < rFill.X() )
1545  {
1546  nRightTab += nDefTabDist;
1547  if( nRightTab > rFill.nLineWidth )
1548  ++nTabCnt;
1549  }
1550  if( nLeftTab < nRightTab - nDefTabDist )
1551  nLeftTab = nRightTab - nDefTabDist;
1552  }
1553  if( nRightTab > nRight )
1554  nRightTab = nRight;
1555  }
1556  while( rFill.X() > nRightTab );
1557  --nTabCnt;
1558  if( FILL_TAB_SPACE == rFill.Mode() )
1559  {
1560  if( nSpace > 0 )
1561  {
1562  if( !nTabCnt )
1563  nLeftTab = rFill.nLineWidth;
1564  while( nLeftTab < rFill.X() )
1565  {
1566  nLeftTab += nSpace;
1567  ++nSpaceCnt;
1568  }
1569  if( nSpaceCnt )
1570  {
1571  nLeftTab -= nSpace;
1572  --nSpaceCnt;
1573  }
1574  if( rFill.X() - nLeftTab > nRightTab - rFill.X() )
1575  {
1576  nSpaceCnt = 0;
1577  ++nTabCnt;
1578  rRect.Left( nRightTab );
1579  }
1580  else
1581  {
1582  if( rFill.X() - nLeftTab > nSpace/2 )
1583  {
1584  ++nSpaceCnt;
1585  rRect.Left( nLeftTab + nSpace );
1586  }
1587  else
1588  rRect.Left( nLeftTab );
1589  }
1590  }
1591  else if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
1592  rRect.Left( nLeftTab );
1593  else
1594  {
1595  if( nRightTab >= nRight )
1596  {
1597  rFill.SetOrient( text::HoriOrientation::RIGHT );
1598  rRect.Left( nRight );
1599  nTabCnt = 0;
1600  nSpaceCnt = 0;
1601  }
1602  else
1603  {
1604  rRect.Left( nRightTab );
1605  ++nTabCnt;
1606  }
1607  }
1608  }
1609  else if( FILL_SPACE == rFill.Mode() )
1610  {
1611  SwTwips nLeftSpace = nLeft;
1612  while( nLeftSpace < rFill.X() )
1613  {
1614  nLeftSpace += nSpace;
1615  ++nSpaceOnlyCnt;
1616  }
1617  rRect.Left( nLeftSpace );
1618  }
1619  else
1620  {
1621  if( rFill.X() - nLeftTab < nRightTab - rFill.X() )
1622  rRect.Left( nLeftTab );
1623  else
1624  {
1625  if( nRightTab >= nRight )
1626  {
1627  rFill.SetOrient( text::HoriOrientation::RIGHT );
1628  rRect.Left( nRight );
1629  nTabCnt = 0;
1630  nSpaceCnt = 0;
1631  }
1632  else
1633  {
1634  rRect.Left( nRightTab );
1635  ++nTabCnt;
1636  }
1637  }
1638  }
1639  rFill.SetTab( nTabCnt );
1640  rFill.SetSpace( nSpaceCnt );
1641  rFill.SetSpaceOnly( nSpaceOnlyCnt );
1642  if( bFill )
1643  {
1644  if( std::abs( rFill.X() - nCenter ) <=
1645  std::abs( rFill.X() - rRect.Left() ) )
1646  {
1647  rFill.SetOrient( text::HoriOrientation::CENTER );
1648  rFill.SetTab( 0 );
1649  rFill.SetSpace( 0 );
1650  rFill.SetSpaceOnly( 0 );
1651  rRect.Left( nCenter );
1652  }
1653  if( !rFill.bEmpty )
1654  rFill.nLineWidth += FILL_MIN_DIST;
1655  if( rRect.Left() < rFill.nLineWidth )
1656  bFill = false;
1657  }
1658  }
1659  }
1660  // Do we extend over the page's/column's/etc. lower edge?
1661  const SwFrame* pUp = GetUpper();
1662  if( pUp->IsInSct() )
1663  {
1664  if( pUp->IsSctFrame() )
1665  pUp = pUp->GetUpper();
1666  else if( pUp->IsColBodyFrame() &&
1667  pUp->GetUpper()->GetUpper()->IsSctFrame() )
1668  pUp = pUp->GetUpper()->GetUpper()->GetUpper();
1669  }
1670  SwRectFnSet aRectFnSet(this);
1671  SwTwips nLimit = aRectFnSet.GetPrtBottom(*pUp);
1672  SwTwips nRectBottom = rRect.Bottom();
1673  if ( aRectFnSet.IsVert() )
1674  nRectBottom = SwitchHorizontalToVertical( nRectBottom );
1675 
1676  if( aRectFnSet.YDiff( nLimit, nRectBottom ) < 0 )
1677  bFill = false;
1678  else
1679  rRect.Width( 1 );
1680  }
1681  }
1682  const_cast<SwCursorMoveState*>(rFill.pCMS)->m_bFillRet = bFill;
1683 }
1684 
1685 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long GetLeft() const
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
Base class of the Writer layout elements.
Definition: frame.hxx:295
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
bool IsFirstMulti() const
Definition: inftxt.hxx:212
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
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
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:543
SwFillCursorPos & Fill() const
Definition: frmcrsr.cxx:542
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
sal_uInt16 Count() const
sal_uInt16 GetLineNr() const
Definition: itrtxt.hxx:87
Marks a position in the document model.
Definition: pam.hxx:35
long GetLeftMarginWithNum(bool bTextLeft=false) const
Returns the additional indents of this text node and its numbering.
Definition: ndtxt.cxx:3152
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:943
SwFont & GetFont()
Definition: swfntcch.hxx:58
bool m_bRealHeight
should the real height be calculated?
Definition: crstate.hxx:141
by left paragraph indention
Definition: crstate.hxx:34
sal_uInt16 nParaCnt
number of paragraphs to insert
Definition: crstate.hxx:40
long AdjustX(long nHorzMove)
bool IsSwapped() const
Definition: txtfrm.hxx:528
static bool IsRightMargin()
Definition: itrtxt.hxx:295
const SvxTabStopItem & GetTabStops(bool=true) const
Definition: paratr.hxx:190
fill with spaces and tabs
Definition: crstate.hxx:31
const SwLineLayout * NextLine()
Definition: itrtxt.cxx:122
bool HasPara() const
Definition: txtfrm.hxx:812
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:237
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:88
stay with the cursor inside text
Definition: crstate.hxx:127
friend bool sw_ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmcrsr.cxx:108
SwRect aCursor
position and size of the ShadowCursor
Definition: crstate.hxx:39
SwNodeIndex nNode
Definition: pam.hxx:37
void Refresh(const SwFrame *pFrame)
Definition: frame.hxx:1335
SwModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:457
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:471
default
Definition: crstate.hxx:123
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const override
Definition: frmcrsr.cxx:1288
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
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:176
sal_uInt16 nSpaceCnt
number of spaces to insert
Definition: crstate.hxx:42
long GetLineSpace(const bool _bNoPropLineSpacing=false) const
Returns the additional line spacing for the next paragraph.
Definition: txtfrm.cxx:3675
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:440
bool HasFollow() const
Definition: flowfrm.hxx:165
void Height(long nNew)
Definition: swrect.hxx:189
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
long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1354
TextFrameIndex GetOfst() const
Definition: txtfrm.hxx:428
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const override
Definition: frmcrsr.cxx:1269
#define FILL_MIN_DIST
Definition: frmcrsr.cxx:519
Cursor Up/Down.
Definition: crstate.hxx:124
long SwTwips
Definition: swtypes.hxx:49
bool IsVert() const
Definition: frame.hxx:1343
static void SetRightMargin(const bool bNew)
Definition: itrtxt.hxx:294
void Pos(const Point &rNew)
Definition: swrect.hxx:167
SwPosition * pPos
Definition: frmcrsr.cxx:525
SwTwips FirstLeft() const
Definition: itrtxt.hxx:182
SwFillMode const eMode
desired fill-up rule
Definition: crstate.hxx:46
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1280
bool IsInside(TextFrameIndex nPos) const
Respect the Follows.
Definition: txtfrm.hxx:822
void SetTab(sal_uInt16 nNew)
Definition: frmcrsr.cxx:543
long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1385
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:128
bool IsMulti() const
Definition: inftxt.hxx:210
sal_uInt16 const aTextFormatCollSetRange[]
Definition: init.cxx:150
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:167
long Bottom() const
Definition: frmcrsr.cxx:541
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1347
long YDiff(long n1, long n2) const
Definition: frame.hxx:1399
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:392
long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1386
void Top(const long nTop)
Definition: swrect.hxx:202
const SwRect & getFrameArea() const
Definition: frame.hxx:175
void setX(long nX)
SwFlyFrame * GetPrevLink() const
Definition: flyfrm.hxx:172
bool getBrowseMode() const
Definition: viewopt.hxx:433
void FillCursorPos(SwFillData &rFill) const
Definition: frmcrsr.cxx:1298
bool IsInTab() const
Definition: frame.hxx:931
#define RES_PARATR_TABSTOP
Definition: hintids.hxx:260
sal_uInt16 nSpaceOnlyCnt
number of spaces to insert ("only spaces, no tabs" mode)
Definition: crstate.hxx:43
default, fill with tabs
Definition: crstate.hxx:30
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:1210
const SwLineLayout * GetNextLine() const
Definition: itrtxt.cxx:132
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:964
oslFileHandle & pOut
SwFillMode
Definition: crstate.hxx:28
bool IsSctFrame() const
Definition: frame.hxx:1190
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1087
void Right(const long nRight)
Definition: swrect.hxx:198
void setY(long nY)
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:969
SwAttrPool * GetPool() const
Definition: swatrset.hxx:190
if(nullptr==pCandidateA||nullptr==pCandidateB)
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:848
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:674
bool IsEmpty() const
Definition: txtfrm.hxx:511
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1290
bool IsCursorInProtectedArea() const
Definition: viewopt.hxx:370
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1256
void SetTop(SwRect &rRect, long nNew) const
Definition: frame.hxx:1362
sal_uInt16 nTabCnt
number of tabs respectively size of indentation
Definition: crstate.hxx:41
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:114
TextFrameIndex GetCursorOfst(SwPosition *pPos, const Point &rPoint, bool bChgNode, SwCursorMoveState *=nullptr) const
Definition: itrcrsr.cxx:1275
const SwLineLayout * GetPrevLine()
Definition: itrtxt.cxx:142
long AdjustY(long nVertMove)
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
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:42
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:923
long Left() const
Definition: frmcrsr.cxx:539
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwTextFrame * GetFrameAtPos(const SwPosition &rPos)
Definition: frmcrsr.cxx:151
SwLinePortion * GetFirstPortion() const
Definition: porlay.cxx:667
bool GetCursorOfst_(SwPosition *pPos, const Point &rPoint, const bool bChgFrame, SwCursorMoveState *=nullptr) const
Definition: frmcrsr.cxx:549
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
void TwipsToLine(const SwTwips)
Definition: itrtxt.cxx:298
SwTextFrame & GetFrameAtOfst(TextFrameIndex nOfst)
Definition: frmcrsr.cxx:143
bool HasArea() const
Definition: swrect.hxx:290
bool IsUndersized() const
Definition: flowfrm.hxx:158
const SwLineLayout * GetPrev()
Definition: itrtxt.cxx:81
SvxInterLineSpaceRule GetInterLineSpaceRule() const
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3351
sal_uInt16 GetLineHeight() const
Definition: itrtxt.hxx:116
const SvxLineSpacingItem & GetLineSpacing(bool=true) const
Definition: paratr.hxx:178
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
SwRect aFrame
Definition: frmcrsr.cxx:523
bool IsLocked() const
Definition: txtfrm.hxx:507
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:74
A page of the document layout.
Definition: pagefrm.hxx:40
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
long X() const
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:539
const OUString & GetText() const
Definition: inftxt.hxx:246
std::unique_ptr< Sw2LinesPos > m_p2Lines
for selections inside/around 2line portions
Definition: crstate.hxx:135
void SetParent(const SfxItemSet *pNew)
bool UnitUp_(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: frmcrsr.cxx:756
bool IsMultiPortion() const
Definition: porlin.hxx:134
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:50
bool GetAutoPos(SwRect &, const SwPosition &) const
A slimmer version of GetCharRect for autopositioning Frames.
Definition: frmcrsr.cxx:366
const SwLineLayout * Prev()
Definition: itrtxt.cxx:88
void Left(const long nLeft)
Definition: swrect.hxx:193
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Bottom(const long nBottom)
Definition: swrect.hxx:207
SwFontObj * Get()
Definition: swfntcch.cxx:56
void SetSpaceOnly(sal_uInt16 nNew)
Definition: frmcrsr.cxx:545
void SetOfst(TextFrameIndex nNewOfst)
Definition: txtfrm.hxx:858
long Y() const
Definition: frmcrsr.cxx:538
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
Definition: txtfrm.hxx:728
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
TextFrameIndex GetLength() const
Definition: itrtxt.hxx:86
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:679
unsigned char sal_uInt8
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
void Width(long nNew)
Definition: swrect.hxx:185
void GetEndCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const long nMax=0)
Definition: itrcrsr.cxx:390
void SwapWidthAndHeight()
Swaps width and height of the text frame.
Definition: txtfrm.cxx:418
bool IsRightToLeft() const
Definition: frame.hxx:963
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:1344
long X() const
Definition: frmcrsr.cxx:537
SwFlyFrame * GetNextLink() const
Definition: flyfrm.hxx:173
virtual OutputDevice * getReferenceDevice(bool bCreate) const =0
Returns the current reference device.
sal_uInt16 Width() const
Definition: possiz.hxx:46
const SwLineLayout * PrevLine()
Definition: itrtxt.cxx:168
CursorMoveState m_eState
Definition: crstate.hxx:138
bool IsPrtFormat() const
Definition: viewopt.hxx:502
double getLength(const B2DPolygon &rCandidate)
at right margin
Definition: crstate.hxx:125
void GetCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const long nMax=0)
Definition: itrcrsr.cxx:1168
static void lcl_VisualMoveRecursion(const SwLineLayout &rCurrLine, TextFrameIndex nIdx, TextFrameIndex &nPos, bool &bRight, sal_uInt8 &nCursorLevel, sal_uInt8 nDefaultDir)
Definition: frmcrsr.cxx:896
long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1358
#define FAR_AWAY
Definition: frmtool.hxx:52
void PrepareVisualMove(TextFrameIndex &nPos, sal_uInt8 &nCursorLevel, bool &bRight, bool bInsertCursor)
Prepares the cursor position for a visual cursor move (BiDi).
Definition: frmcrsr.cxx:1041
long Right() const
Definition: frmcrsr.cxx:540
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
long GetRight() const
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:1145
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
bool IsVertical() const
Definition: frame.hxx:949
long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1353
#define MIN_OFFSET_STEP
Definition: frmcrsr.cxx:49
const SwLineLayout * CharCursorToLine(TextFrameIndex const nPos)
Definition: itrtxt.cxx:200
SwDoc & GetDoc()
Definition: txtfrm.hxx:450
virtual bool GetCursorOfst(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
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
fill with spaces
Definition: crstate.hxx:32
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:89
long const nRightMargin
sal_uInt16 GetDropLines() const
Definition: itrtxt.hxx:202
SwTwips nLineWidth
Definition: frmcrsr.cxx:527
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:72
bool sw_ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmcrsr.cxx:108
long GetTextLeft() const
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:204
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...
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1235
only align left, center, right
Definition: crstate.hxx:33
const Point & rPoint
Definition: frmcrsr.cxx:526
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
long Y() const
sal_uInt16 nPos
const SwCursorMoveState * pCMS
Definition: frmcrsr.cxx:524
SwTextFormatColl & GetNextTextFormatColl() const
Definition: fmtcol.hxx:97
sal_uInt16 GetUpper() const
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1625
bool bInner
Definition: frmcrsr.cxx:529
SwFrame * GetNext()
Definition: frame.hxx:654
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:836
sal_uInt16 nColumnCnt
number of necessary column breaks
Definition: crstate.hxx:44