LibreOffice Module sw (master)  1
frmpaint.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 <memory>
21 #include <com/sun/star/text/HoriOrientation.hpp>
22 #include <hintids.hxx>
23 #include <editeng/pgrditem.hxx>
24 #include <editeng/lrspitem.hxx>
25 #include <pagedesc.hxx>
26 #include <tgrditem.hxx>
27 #include <paratr.hxx>
28 
29 #include <fmtline.hxx>
30 #include <lineinfo.hxx>
31 #include <charfmt.hxx>
32 #include <rootfrm.hxx>
33 #include <pagefrm.hxx>
34 #include <viewsh.hxx>
35 #include <viewimp.hxx>
36 #include <viewopt.hxx>
37 #include <frmatr.hxx>
38 #include <frmtool.hxx>
39 #include <txtfrm.hxx>
40 #include "itrpaint.hxx"
41 #include "txtpaint.hxx"
42 #include "txtcache.hxx"
43 #include <flyfrm.hxx>
44 #include "redlnitr.hxx"
45 #include <swmodule.hxx>
46 #include <tabfrm.hxx>
47 #include <numrule.hxx>
48 #include <SwGrammarMarkUp.hxx>
49 #include <wrong.hxx>
50 
52 
54 
55 #define REDLINE_DISTANCE 567/4
56 #define REDLINE_MINDIST 567/10
57 
58 using namespace ::com::sun::star;
59 
60 static bool bInitFont = true;
61 
63 {
68  std::unique_ptr<SwFont> m_pFnt;
73  sal_uInt16 m_nDivider;
74  bool m_bGoLeft;
75  bool IsClipChg() { return m_aClip.IsChg(); }
76 
77  SwExtraPainter(const SwExtraPainter&) = delete;
78  SwExtraPainter& operator=(const SwExtraPainter&) = delete;
79 
80 public:
81  SwExtraPainter( const SwTextFrame *pFrame, SwViewShell *pVwSh,
82  const SwLineNumberInfo &rLnInf, const SwRect &rRct,
83  sal_Int16 eHor, bool bLnNm );
84  SwFont* GetFont() const { return m_pFnt.get(); }
85  void IncLineNr() { ++m_nLineNr; }
86  bool HasNumber() { return !( m_nLineNr % m_rLineInf.GetCountBy() ); }
87  bool HasDivider() {
88  if( !m_nDivider ) return false;
89  return !(m_nLineNr % m_rLineInf.GetDividerCountBy());
90  }
91 
92  void PaintExtra( SwTwips nY, long nAsc, long nMax, bool bRed );
93  void PaintRedline( SwTwips nY, long nMax );
94 };
95 
97  const SwLineNumberInfo &rLnInf, const SwRect &rRct,
98  sal_Int16 eHor, bool bLineNum )
99  : m_aClip( pVwSh->GetWin() || pFrame->IsUndersized() ? pVwSh->GetOut() : nullptr )
100  , m_aRect( rRct )
101  , m_pTextFrame( pFrame )
102  , m_pSh( pVwSh )
103  , m_rLineInf( rLnInf )
104  , m_nX(0)
105  , m_nRedX(0)
106  , m_nLineNr( 1 )
107  , m_nDivider(0)
108  , m_bGoLeft(false)
109 {
110  if( pFrame->IsUndersized() )
111  {
112  SwTwips nBottom = pFrame->getFrameArea().Bottom();
113  if( m_aRect.Bottom() > nBottom )
114  m_aRect.Bottom( nBottom );
115  }
116  int nVirtPageNum = 0;
117  if( bLineNum )
118  {
119  /* Initializes the Members necessary for line numbering:
120 
121  nDivider, how often do we want a substring; 0 == never
122  nX, line number's x position
123  pFnt, line number's font
124  nLineNr, the first line number
125  bLineNum is set back to false if the numbering is completely
126  outside of the paint rect
127  */
129  m_nX = pFrame->getFrameArea().Left();
130  SwCharFormat* pFormat = m_rLineInf.GetCharFormat( const_cast<IDocumentStylePoolAccess&>(pFrame->GetDoc().getIDocumentStylePoolAccess()) );
131  OSL_ENSURE( pFormat, "PaintExtraData without CharFormat" );
132  m_pFnt.reset( new SwFont(&pFormat->GetAttrSet(), &pFrame->GetDoc().getIDocumentSettingAccess()) );
133  m_pFnt->Invalidate();
134  m_pFnt->ChgPhysFnt( m_pSh, *m_pSh->GetOut() );
135  m_pFnt->SetVertical( 0, pFrame->IsVertical() );
136  m_nLineNr += pFrame->GetAllLines() - pFrame->GetThisLines();
138  if( ePos != LINENUMBER_POS_LEFT && ePos != LINENUMBER_POS_RIGHT )
139  {
140  if( pFrame->FindPageFrame()->OnRightPage() )
141  {
142  nVirtPageNum = 1;
143  ePos = ePos == LINENUMBER_POS_INSIDE ?
145  }
146  else
147  {
148  nVirtPageNum = 2;
149  ePos = ePos == LINENUMBER_POS_OUTSIDE ?
151  }
152  }
153  if( LINENUMBER_POS_LEFT == ePos )
154  {
155  m_bGoLeft = true;
157  }
158  else
159  {
160  m_bGoLeft = false;
161  m_nX += pFrame->getFrameArea().Width() + m_rLineInf.GetPosFromLeft();
162  }
163  }
164  if( eHor != text::HoriOrientation::NONE )
165  {
166  if( text::HoriOrientation::INSIDE == eHor || text::HoriOrientation::OUTSIDE == eHor )
167  {
168  if( !nVirtPageNum )
169  nVirtPageNum = pFrame->FindPageFrame()->OnRightPage() ? 1 : 2;
170  if( nVirtPageNum % 2 )
171  eHor = eHor == text::HoriOrientation::INSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT;
172  else
173  eHor = eHor == text::HoriOrientation::OUTSIDE ? text::HoriOrientation::LEFT : text::HoriOrientation::RIGHT;
174  }
175  const SwFrame* pTmpFrame = pFrame->FindTabFrame();
176  if( !pTmpFrame )
177  pTmpFrame = pFrame;
179  pTmpFrame->getFrameArea().Right() + REDLINE_DISTANCE;
180  }
181 }
182 
183 void SwExtraPainter::PaintExtra( SwTwips nY, long nAsc, long nMax, bool bRed )
184 {
185  // Line number is stronger than the divider
186  const OUString aTmp( HasNumber() ? m_rLineInf.GetNumType().GetNumStr( m_nLineNr )
187  : m_rLineInf.GetDivider() );
188 
189  // Get script type of line numbering:
190  m_pFnt->SetActual( SwScriptInfo::WhichFont(0, aTmp) );
191 
192  SwDrawTextInfo aDrawInf( m_pSh, *m_pSh->GetOut(), aTmp, 0, aTmp.getLength() );
193  aDrawInf.SetSpace( 0 );
194  aDrawInf.SetWrong( nullptr );
195  aDrawInf.SetGrammarCheck( nullptr );
196  aDrawInf.SetSmartTags( nullptr );
197  aDrawInf.SetFrame( m_pTextFrame );
198  aDrawInf.SetFont( m_pFnt.get() );
199  aDrawInf.SetSnapToGrid( false );
200  aDrawInf.SetIgnoreFrameRTL( true );
201 
202  bool bTooBig = m_pFnt->GetSize( m_pFnt->GetActual() ).Height() > nMax &&
203  m_pFnt->GetHeight( m_pSh, *m_pSh->GetOut() ) > nMax;
204  SwFont* pTmpFnt;
205  if( bTooBig )
206  {
207  pTmpFnt = new SwFont( *GetFont() );
208  if( nMax >= 20 )
209  {
210  nMax *= 17;
211  nMax /= 20;
212  }
213  pTmpFnt->SetSize( Size( 0, nMax ), pTmpFnt->GetActual() );
214  }
215  else
216  pTmpFnt = GetFont();
217  Point aTmpPos( m_nX, nY );
218  aTmpPos.AdjustY(nAsc );
219  bool bPaint = true;
220  if( !IsClipChg() )
221  {
222  Size aSize = pTmpFnt->GetTextSize_( aDrawInf );
223  if( m_bGoLeft )
224  aTmpPos.AdjustX( -(aSize.Width()) );
225  // calculate rectangle containing the line number
226  SwRect aRct( Point( aTmpPos.X(),
227  aTmpPos.Y() - pTmpFnt->GetAscent( m_pSh, *m_pSh->GetOut() )
228  ), aSize );
229  if( !m_aRect.IsInside( aRct ) )
230  {
231  if( aRct.Intersection( m_aRect ).IsEmpty() )
232  bPaint = false;
233  else
235  }
236  }
237  else if( m_bGoLeft )
238  aTmpPos.AdjustX( -(pTmpFnt->GetTextSize_( aDrawInf ).Width()) );
239  aDrawInf.SetPos( aTmpPos );
240  if( bPaint )
241  pTmpFnt->DrawText_( aDrawInf );
242 
243  if( bTooBig )
244  delete pTmpFnt;
245  if( bRed )
246  {
247  long nDiff = m_bGoLeft ? m_nRedX - m_nX : m_nX - m_nRedX;
248  if( nDiff > REDLINE_MINDIST )
249  PaintRedline( nY, nMax );
250  }
251 }
252 
254 {
255  Point aStart( m_nRedX, nY );
256  Point aEnd( m_nRedX, nY + nMax );
257 
258  if( !IsClipChg() )
259  {
260  SwRect aRct( aStart, aEnd );
261  if( !m_aRect.IsInside( aRct ) )
262  {
263  if( aRct.Intersection( m_aRect ).IsEmpty() )
264  return;
266  }
267  }
268  const Color aOldCol( m_pSh->GetOut()->GetLineColor() );
269  m_pSh->GetOut()->SetLineColor( SW_MOD()->GetRedlineMarkColor() );
270 
271  if ( m_pTextFrame->IsVertical() )
272  {
275  }
276 
277  m_pSh->GetOut()->DrawLine( aStart, aEnd );
278  m_pSh->GetOut()->SetLineColor( aOldCol );
279 }
280 
281 void SwTextFrame::PaintExtraData( const SwRect &rRect ) const
282 {
283  if( getFrameArea().Top() > rRect.Bottom() || getFrameArea().Bottom() < rRect.Top() )
284  return;
285 
286  SwDoc const& rDoc(GetDoc());
288  const SwLineNumberInfo &rLineInf = rDoc.GetLineNumberInfo();
289  const SwFormatLineNumber &rLineNum = GetAttrSet()->GetLineNumber();
290  bool bLineNum = !IsInTab() && rLineInf.IsPaintLineNumbers() &&
291  ( !IsInFly() || rLineInf.IsCountInFlys() ) && rLineNum.IsCount();
292  sal_Int16 eHor = static_cast<sal_Int16>(SW_MOD()->GetRedlineMarkPos());
293  if (eHor != text::HoriOrientation::NONE
295  || getRootFrame()->IsHideRedlines()))
296  {
298  }
299  bool bRedLine = eHor != text::HoriOrientation::NONE;
300  if ( !bLineNum && !bRedLine )
301  return;
302 
303  if( IsLocked() || IsHiddenNow() || !getFramePrintArea().Height() )
304  return;
306 
307  SwSwapIfNotSwapped swap(const_cast<SwTextFrame *>(this));
308  SwRect rOldRect( rRect );
309 
310  if ( IsVertical() )
311  SwitchVerticalToHorizontal( const_cast<SwRect&>(rRect) );
312 
313  SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() );
314  aLayoutModeModifier.Modify( false );
315 
316  // #i16816# tagged pdf support
317  SwTaggedPDFHelper aTaggedPDFHelper( nullptr, nullptr, nullptr, *pSh->GetOut() );
318 
319  SwExtraPainter aExtra( this, pSh, rLineInf, rRect, eHor, bLineNum );
320 
321  if( HasPara() )
322  {
323  TextFrameLockGuard aLock(const_cast<SwTextFrame*>(this));
324 
325  SwTextLineAccess aAccess( this );
326  aAccess.GetPara();
327 
328  SwTextPaintInfo aInf( const_cast<SwTextFrame*>(this), rRect );
329 
330  aLayoutModeModifier.Modify( false );
331 
332  SwTextPainter aLine( const_cast<SwTextFrame*>(this), &aInf );
333  bool bNoDummy = !aLine.GetNext(); // Only one empty line!
334 
335  while( aLine.Y() + aLine.GetLineHeight() <= rRect.Top() )
336  {
337  if( !aLine.GetCurr()->IsDummy() &&
338  ( rLineInf.IsCountBlankLines() ||
339  aLine.GetCurr()->HasContent() ) )
340  aExtra.IncLineNr();
341  if( !aLine.Next() )
342  {
343  const_cast<SwRect&>(rRect) = rOldRect;
344  return;
345  }
346  }
347 
348  long nBottom = rRect.Bottom();
349 
350  bool bNoPrtLine = 0 == GetMinPrtLine();
351  if( !bNoPrtLine )
352  {
353  while ( aLine.Y() < GetMinPrtLine() )
354  {
355  if( ( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasContent() )
356  && !aLine.GetCurr()->IsDummy() )
357  aExtra.IncLineNr();
358  if( !aLine.Next() )
359  break;
360  }
361  bNoPrtLine = aLine.Y() >= GetMinPrtLine();
362  }
363  if( bNoPrtLine )
364  {
365  do
366  {
367  if( bNoDummy || !aLine.GetCurr()->IsDummy() )
368  {
369  bool bRed = bRedLine && aLine.GetCurr()->HasRedline();
370  if( rLineInf.IsCountBlankLines() || aLine.GetCurr()->HasContent() )
371  {
372  if( bLineNum &&
373  ( aExtra.HasNumber() || aExtra.HasDivider() ) )
374  {
375  sal_uInt16 nTmpHeight, nTmpAscent;
376  aLine.CalcAscentAndHeight( nTmpAscent, nTmpHeight );
377  aExtra.PaintExtra( aLine.Y(), nTmpAscent,
378  nTmpHeight, bRed );
379  bRed = false;
380  }
381  aExtra.IncLineNr();
382  }
383  if( bRed )
384  aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight() );
385  }
386  } while( aLine.Next() && aLine.Y() <= nBottom );
387  }
388  }
389  else
390  {
391  if (!GetMergedPara() &&
393  {
394  bRedLine = false;
395  }
396 
397  if( bLineNum && rLineInf.IsCountBlankLines() &&
398  ( aExtra.HasNumber() || aExtra.HasDivider() ) )
399  {
400  aExtra.PaintExtra( getFrameArea().Top()+getFramePrintArea().Top(), aExtra.GetFont()
401  ->GetAscent( pSh, *pSh->GetOut() ), getFramePrintArea().Height(), bRedLine );
402  }
403  else if( bRedLine )
404  aExtra.PaintRedline( getFrameArea().Top()+getFramePrintArea().Top(), getFramePrintArea().Height() );
405  }
406 
407  const_cast<SwRect&>(rRect) = rOldRect;
408 
409 }
410 
412 {
413  // finger layout
414  OSL_ENSURE( isFrameAreaPositionValid(), "+SwTextFrame::GetPaintSwRect: no Calc()" );
415 
416  SwRect aRet( getFramePrintArea() );
417  if ( IsEmpty() || !HasPara() )
418  aRet += getFrameArea().Pos();
419  else
420  {
421  // We return the right paint rect. Use the calculated PaintOfst as the
422  // left margin
423  SwRepaint& rRepaint = GetPara()->GetRepaint();
424  long l;
425 
426  if ( IsVertLR() && !IsVertLRBT()) // mba: the following line was added, but we don't need it for the existing directions; kept for IsVertLR(), but should be checked
428 
429  if( rRepaint.GetOfst() )
430  rRepaint.Left( rRepaint.GetOfst() );
431 
432  l = rRepaint.GetRightOfst();
433  if( l && l > rRepaint.Right() )
434  rRepaint.Right( l );
435  rRepaint.SetOfst( 0 );
436  aRet = rRepaint;
437 
438  // In case our left edge is the same as the body frame's left edge,
439  // then extend the rectangle to include the page margin as well,
440  // otherwise some font will be clipped.
441  SwLayoutFrame* pBodyFrame = GetUpper();
442  if (pBodyFrame->IsBodyFrame() && aRet.Left() == (pBodyFrame->getFrameArea().Left() + pBodyFrame->getFramePrintArea().Left()))
443  if (SwLayoutFrame* pPageFrame = pBodyFrame->GetUpper())
444  aRet.Left(pPageFrame->getFrameArea().Left());
445 
446  if ( IsRightToLeft() )
447  SwitchLTRtoRTL( aRet );
448 
449  if ( IsVertical() )
451  }
452  ResetRepaint();
453 
454  return aRet;
455 }
456 
457 bool SwTextFrame::PaintEmpty( const SwRect &rRect, bool bCheck ) const
458 {
460  if( pSh && ( pSh->GetViewOptions()->IsParagraph() || bInitFont ) )
461  {
462  bInitFont = false;
463  SwTextFly aTextFly( this );
464  aTextFly.SetTopRule();
465  SwRect aRect;
466  if( bCheck && aTextFly.IsOn() && aTextFly.IsAnyObj( aRect ) )
467  return false;
468  else if( pSh->GetWin() )
469  {
470  std::unique_ptr<SwFont> pFnt;
471  const SwTextNode& rTextNode = *GetTextNodeForParaProps();
472  if ( rTextNode.HasSwAttrSet() )
473  {
474  const SwAttrSet *pAttrSet = &( rTextNode.GetSwAttrSet() );
475  pFnt.reset(new SwFont( pAttrSet, rTextNode.getIDocumentSettingAccess() ));
476  }
477  else
478  {
479  SwFontAccess aFontAccess( &rTextNode.GetAnyFormatColl(), pSh );
480  pFnt.reset(new SwFont( aFontAccess.Get()->GetFont() ));
481  }
482 
483  const IDocumentRedlineAccess& rIDRA = rTextNode.getIDocumentRedlineAccess();
485  && !getRootFrame()->IsHideRedlines())
486  {
487  const SwRedlineTable::size_type nRedlPos = rIDRA.GetRedlinePos( rTextNode, RedlineType::Any );
488  if( SwRedlineTable::npos != nRedlPos )
489  {
490  SwAttrHandler aAttrHandler;
491  aAttrHandler.Init( rTextNode.GetSwAttrSet(),
492  *rTextNode.getIDocumentSettingAccess() );
493  SwRedlineItr aRedln(rTextNode, *pFnt, aAttrHandler, nRedlPos, SwRedlineItr::Mode::Show);
494  }
495  }
496 
497  if( pSh->GetViewOptions()->IsParagraph() && getFramePrintArea().Height() )
498  {
499  if( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet( SwFontScript::Latin ) &&
500  pFnt->GetName( SwFontScript::Latin ) != numfunc::GetDefBulletFontname() )
501  {
502  pFnt->SetFamily( FAMILY_DONTKNOW, SwFontScript::Latin );
504  pFnt->SetStyleName(OUString(), SwFontScript::Latin);
505  pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, SwFontScript::Latin );
506  }
507  pFnt->SetVertical( 0, IsVertical() );
508  SwFrameSwapper aSwapper( this, true );
509  SwLayoutModeModifier aLayoutModeModifier( *pSh->GetOut() );
510  aLayoutModeModifier.Modify( IsRightToLeft() );
511 
512  pFnt->Invalidate();
513  pFnt->ChgPhysFnt( pSh, *pSh->GetOut() );
514  Point aPos = getFrameArea().Pos() + getFramePrintArea().Pos();
515 
516  const SvxLRSpaceItem &rSpace =
518 
519  if ( rSpace.GetTextFirstLineOfst() > 0 )
520  aPos.AdjustX(rSpace.GetTextFirstLineOfst() );
521 
522  std::unique_ptr<SwSaveClip> pClip;
523  if( IsUndersized() )
524  {
525  pClip.reset(new SwSaveClip( pSh->GetOut() ));
526  pClip->ChgClip( rRect );
527  }
528 
529  aPos.AdjustY(pFnt->GetAscent( pSh, *pSh->GetOut() ) );
530 
531  if (GetTextNodeForParaProps()->GetSwAttrSet().GetParaGrid().GetValue() &&
532  IsInDocBody() )
533  {
534  SwTextGridItem const*const pGrid(GetGridItem(FindPageFrame()));
535  if ( pGrid )
536  {
537  // center character in grid line
538  aPos.AdjustY(( pGrid->GetBaseHeight() -
539  pFnt->GetHeight( pSh, *pSh->GetOut() ) ) / 2 );
540 
541  if ( ! pGrid->GetRubyTextBelow() )
542  aPos.AdjustY(pGrid->GetRubyHeight() );
543  }
544  }
545 
546  // Don't show the paragraph mark for collapsed paragraphs, when they are hidden
547  if ( EmptyHeight( ) > 1 )
548  {
549  const OUString aTmp( CH_PAR );
550  SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), aTmp, 0, 1 );
551  aDrawInf.SetPos( aPos );
552  aDrawInf.SetSpace( 0 );
553  aDrawInf.SetKanaComp( 0 );
554  aDrawInf.SetWrong( nullptr );
555  aDrawInf.SetGrammarCheck( nullptr );
556  aDrawInf.SetSmartTags( nullptr );
557  aDrawInf.SetFrame( this );
558  aDrawInf.SetFont( pFnt.get() );
559  aDrawInf.SetSnapToGrid( false );
560 
561  pFnt->SetColor(NON_PRINTING_CHARACTER_COLOR);
562  pFnt->DrawText_( aDrawInf );
563  }
564  }
565  return true;
566  }
567  }
568  else
569  return true;
570  return false;
571 }
572 
573 void SwTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const
574 {
575  ResetRepaint();
576 
577  // #i16816# tagged pdf support
579 
580  Num_Info aNumInfo( *this );
581  SwTaggedPDFHelper aTaggedPDFHelperNumbering( &aNumInfo, nullptr, nullptr, rRenderContext );
582 
583  Frame_Info aFrameInfo( *this );
584  SwTaggedPDFHelper aTaggedPDFHelperParagraph( nullptr, &aFrameInfo, nullptr, rRenderContext );
585 
586  if( IsEmpty() && PaintEmpty( rRect, true ) )
587  return;
588 
589  if( IsLocked() || IsHiddenNow() || ! getFramePrintArea().HasArea() )
590  return;
591 
592  // It can happen that the IdleCollector withdrew my cached information
593  if( !HasPara() )
594  {
595  OSL_ENSURE( isFrameAreaPositionValid(), "+SwTextFrame::PaintSwFrame: no Calc()" );
596 
597  // #i29062# pass info that we are currently
598  // painting.
599  const_cast<SwTextFrame*>(this)->GetFormatted( true );
600  if( IsEmpty() )
601  {
602  PaintEmpty( rRect, false );
603  return;
604  }
605  if( !HasPara() )
606  {
607  OSL_ENSURE( false, "+SwTextFrame::PaintSwFrame: missing format information" );
608  return;
609  }
610  }
611 
612  // We don't want to be interrupted while painting.
613  // Do that after thr Format()!
614  TextFrameLockGuard aLock(const_cast<SwTextFrame*>(this));
615 
616  // We only paint the part of the TextFrame which changed, is within the
617  // range and was requested to paint.
618  // One could think that the area rRect _needs_ to be painted, although
619  // rRepaint is set. Indeed, we cannot avoid this problem from a formal
620  // perspective. Luckily we can assume rRepaint to be empty when we need
621  // paint the while Frame.
622  SwTextLineAccess aAccess( this );
623  SwParaPortion *pPara = aAccess.GetPara();
624 
625  SwRepaint &rRepaint = pPara->GetRepaint();
626 
627  // Switch off recycling when in the FlyContentFrame.
628  // A DrawRect is called for repainting the line anyways.
629  if( rRepaint.GetOfst() )
630  {
631  const SwFlyFrame *pFly = FindFlyFrame();
632  if( pFly && pFly->IsFlyInContentFrame() )
633  rRepaint.SetOfst( 0 );
634  }
635 
636  // Ge the String for painting. The length is of special interest.
637 
638  // Rectangle
639  OSL_ENSURE( ! IsSwapped(), "A frame is swapped before Paint" );
640  SwRect aOldRect( rRect );
641 
642  {
643  SwSwapIfNotSwapped swap(const_cast<SwTextFrame *>(this));
644 
645  if ( IsVertical() )
646  SwitchVerticalToHorizontal( const_cast<SwRect&>(rRect) );
647 
648  if ( IsRightToLeft() )
649  SwitchRTLtoLTR( const_cast<SwRect&>(rRect) );
650 
651  SwTextPaintInfo aInf( const_cast<SwTextFrame*>(this), rRect );
652  sw::WrongListIterator iterWrong(*this, &SwTextNode::GetWrong);
654  sw::WrongListIterator iterSmartTags(*this, &SwTextNode::GetSmartTags);
655  if (iterWrong.LooksUseful())
656  {
657  aInf.SetWrongList( &iterWrong );
658  }
659  if (iterGrammar.LooksUseful())
660  {
661  aInf.SetGrammarCheckList( &iterGrammar );
662  }
663  if (iterSmartTags.LooksUseful())
664  {
665  aInf.SetSmartTags( &iterSmartTags );
666  }
667  aInf.GetTextFly().SetTopRule();
668 
669  SwTextPainter aLine( const_cast<SwTextFrame*>(this), &aInf );
670  // Optimization: if no free flying Frame overlaps into our line, the
671  // SwTextFly just switches off
672  aInf.GetTextFly().Relax();
673 
674  OutputDevice* pOut = aInf.GetOut();
675  const bool bOnWin = pSh->GetWin() != nullptr;
676 
677  SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : nullptr );
678 
679  // Output loop: For each Line ... (which is still visible) ...
680  // adapt rRect (Top + 1, Bottom - 1)
681  // Because the Iterator attaches the Lines without a gap to each other
682  aLine.TwipsToLine( rRect.Top() + 1 );
683  long nBottom = rRect.Bottom();
684 
685  bool bNoPrtLine = 0 == GetMinPrtLine();
686  if( !bNoPrtLine )
687  {
688  while ( aLine.Y() < GetMinPrtLine() && aLine.Next() )
689  ;
690  bNoPrtLine = aLine.Y() >= GetMinPrtLine();
691  }
692  if( bNoPrtLine )
693  {
694  do
695  {
696  aLine.DrawTextLine( rRect, aClip, IsUndersized() );
697 
698  } while( aLine.Next() && aLine.Y() <= nBottom );
699  }
700 
701  // Once is enough:
702  if( aLine.IsPaintDrop() )
703  aLine.PaintDropPortion();
704 
705  if( rRepaint.HasArea() )
706  rRepaint.Clear();
707  }
708 
709  const_cast<SwRect&>(rRect) = aOldRect;
710 
711  OSL_ENSURE( ! IsSwapped(), "A frame is swapped after Paint" );
712 
713 }
714 
715 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
OUString GetNumStr(sal_Int32 nNo) const
long Width() const
bool HasContent() const
Definition: porlay.hxx:123
Base class of the Writer layout elements.
Definition: frame.hxx:295
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:590
bool PaintEmpty(const SwRect &, bool bCheck) const
Definition: frmpaint.cxx:457
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:724
SwTwips EmptyHeight() const
Definition: porrst.cxx:207
bool IsInDocBody() const
Definition: frame.hxx:919
bool IsInFly() const
Definition: frame.hxx:937
const SwLineNumberInfo & GetLineNumberInfo() const
Definition: lineinfo.cxx:50
SwTwips GetOfst() const
Definition: porlay.hxx:70
long AdjustX(long nHorzMove)
bool IsSwapped() const
Definition: txtfrm.hxx:524
bool IsAnyObj(const SwRect &rRect) const
true when a frame or DrawObj must to be taken in account.
Definition: txtfly.cxx:412
bool HasPara() const
Definition: txtfrm.hxx:808
short GetTextFirstLineOfst() const
sal_uInt16 GetCountBy() const
Definition: lineinfo.hxx:75
SwParaPortion * GetPara()
Definition: txtcache.cxx:49
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:483
sal_uIntPtr sal_uLong
FAMILY_DONTKNOW
const SwRect & getFramePrintArea() const
Definition: frame.hxx:176
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:438
The purpose of this class is to be the universal interface between formatting/text output and the pos...
Definition: txtfly.hxx:119
Size GetTextSize_(SwDrawTextInfo &rInf)
Definition: swfont.hxx:309
Definition: doc.hxx:185
#define REDLINE_DISTANCE
Definition: frmpaint.cxx:55
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Definition: frmpaint.cxx:573
SwParaPortion * GetPara()
Definition: txtcache.cxx:89
void Height(long nNew)
Definition: swrect.hxx:189
void SetPos(const Point &rNew)
Definition: drawfont.hxx:397
bool GetRubyTextBelow() const
Definition: tgrditem.hxx:85
std::unique_ptr< SwFont > m_pFnt
Definition: frmpaint.cxx:68
long SwTwips
Definition: swtypes.hxx:49
const SwLineLayout * Next()
Definition: itrtxt.cxx:109
void Pos(const Point &rNew)
Definition: swrect.hxx:167
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
const SwLineNumberInfo & m_rLineInf
Definition: frmpaint.cxx:69
void SetGrammarCheckList(sw::WrongListIterator *const pNew)
Definition: inftxt.hxx:457
const SwTextFrame * m_pTextFrame
Definition: frmpaint.cxx:66
bool IsCountBlankLines() const
Definition: lineinfo.hxx:84
SwTwips Y() const
Definition: itrtxt.hxx:90
bool IsCountInFlys() const
Definition: lineinfo.hxx:87
css::chart::ChartAxisLabelPosition ePos
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
Definition: porlay.hxx:229
SwExtraPainter & operator=(const SwExtraPainter &)=delete
SwTwips m_nX
Definition: frmpaint.cxx:70
void DrawText_(SwDrawTextInfo &rInf)
Definition: swfont.hxx:317
static bool IsShowChanges(const RedlineFlags eM)
bool IsVertLRBT() const
Definition: frame.hxx:959
bool HasNumber()
Definition: frmpaint.cxx:86
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1357
void Top(const long nTop)
Definition: swrect.hxx:202
SwExtraPainter(const SwExtraPainter &)=delete
const SwRect & getFrameArea() const
Definition: frame.hxx:175
static long GetMinPrtLine()
Definition: txtfrm.hxx:600
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:458
sal_uLong GetThisLines() const
Definition: txtfrm.hxx:657
sal_uInt16 GetAscent(SwViewShell const *pSh, const OutputDevice &rOut)
Definition: swfont.hxx:326
bool IsInTab() const
Definition: frame.hxx:931
Used by Attribute Iterators to organize attributes on stacks to find the valid attribute in each cate...
Definition: atrhndl.hxx:40
#define REDLINE_MINDIST
Definition: frmpaint.cxx:56
SwRect & Intersection(const SwRect &rRect)
Definition: swrect.cxx:54
bool IsPaintDrop() const
Definition: itrpaint.hxx:56
bool OnRightPage() const
Definition: frame.hxx:711
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1087
void Right(const long nRight)
Definition: swrect.hxx:198
bool IsFlyInContentFrame() const
Definition: flyfrm.hxx:193
bool IsEmpty() const
Definition: swrect.hxx:294
void DrawLine(const Point &rStartPt, const Point &rEndPt)
void SetOfst(const SwTwips nNew)
Definition: porlay.hxx:71
SwFontScript GetActual() const
Definition: swfont.hxx:183
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
SwFormatColl & GetAnyFormatColl() const
Definition: node.hxx:716
SwRect GetPaintSwRect()
Page number etc.
Definition: frmpaint.cxx:411
bool IsEmpty() const
Definition: txtfrm.hxx:509
void CalcAscentAndHeight(sal_uInt16 &rAscent, sal_uInt16 &rHeight) const
Definition: itrtxt.cxx:66
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:445
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1300
sal_uInt16 GetPosFromLeft() const
Definition: lineinfo.hxx:72
void SetLineColor()
#define SW_MOD()
Definition: swmodule.hxx:256
void Init(const SwAttrSet &rAttrSet, const IDocumentSettingAccess &rIDocumentSettingAccess)
Definition: atrstck.cxx:277
bool IsDummy() const
Definition: porlay.hxx:135
const IDocumentRedlineAccess & getIDocumentRedlineAccess() const
Provides access to the document redline interface.
Definition: node.cxx:2055
long AdjustY(long nVertMove)
bool IsClipChg()
Definition: frmpaint.cxx:75
vcl::RenderContext * GetOut()
Definition: inftxt.hxx:231
SwTextFly & GetTextFly()
Definition: inftxt.hxx:390
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
sal_uLong m_nLineNr
Definition: frmpaint.cxx:72
sal_uLong GetAllLines() const
For displaying the line numbers.
Definition: txtfrm.hxx:656
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:919
SwSaveClip m_aClip
Definition: frmpaint.cxx:64
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2516
vector_type::size_type size_type
Definition: docary.hxx:330
bool IsParagraph(bool bHard=false) const
Definition: viewopt.hxx:229
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
void TwipsToLine(const SwTwips)
Definition: itrtxt.cxx:301
bool HasArea() const
Definition: swrect.hxx:290
bool Relax(const SwRect &rRect)
If there is no flying object frame standing in rRect (usually the current row), then we are turning o...
Definition: txtfly.hxx:318
const Color & GetLineColor() const
SwGrammarMarkUp * GetGrammarCheck()
Definition: txtedt.cxx:2190
bool IsUndersized() const
Definition: flowfrm.hxx:158
void IncLineNr()
Definition: frmpaint.cxx:85
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3360
#define NON_PRINTING_CHARACTER_COLOR
Definition: txtfrm.hxx:50
void Modify(bool bChgToRTL)
Definition: txtfrm.cxx:721
sal_uInt16 GetLineHeight() const
Definition: itrtxt.hxx:116
SwWrongList * GetSmartTags()
Definition: txtedt.cxx:2215
const IDocumentSettingAccess * getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: node.cxx:2053
bool isFrameAreaPositionValid() const
Definition: frame.hxx:162
bool HasSwAttrSet() const
Definition: node.hxx:444
bool IsLocked() const
Definition: txtfrm.hxx:505
SwViewShell * m_pSh
Definition: frmpaint.cxx:67
LineNumberPosition
Definition: lineinfo.hxx:29
SwTwips GetRightOfst() const
Definition: porlay.hxx:72
long X() const
SwTwips m_nRedX
Definition: frmpaint.cxx:71
bool HasDivider()
Definition: frmpaint.cxx:87
< purpose of derivation from SwClient: character style for displaying the numbers.
Definition: lineinfo.hxx:37
void SetTopRule()
Definition: txtfly.hxx:308
sal_uInt16 m_nDivider
Definition: frmpaint.cxx:73
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:693
void Left(const long nLeft)
Definition: swrect.hxx:193
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Bottom(const long nBottom)
Definition: swrect.hxx:207
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
Definition: txtfrm.hxx:724
bool IsVertLR() const
Definition: frame.hxx:955
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
bool IsPaintLineNumbers() const
Definition: lineinfo.hxx:81
void SetSize(const Size &rSize, const SwFontScript nWhich)
Definition: swfont.hxx:737
SwRepaint & GetRepaint()
Definition: porlay.hxx:264
SwFont * GetFont() const
Definition: frmpaint.cxx:84
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
Definition: number.cxx:1254
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
void Width(long nNew)
Definition: swrect.hxx:185
vcl::Window * GetWin() const
Definition: viewsh.hxx:340
void PaintExtra(SwTwips nY, long nAsc, long nMax, bool bRed)
Definition: frmpaint.cxx:183
void ResetRepaint() const
Definition: txtfrm.hxx:864
const SvxParaGridItem & GetParaGrid(bool=true) const
Definition: paratr.hxx:206
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:107
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:208
LineNumberPosition GetPos() const
Definition: lineinfo.hxx:78
bool IsRightToLeft() const
Definition: frame.hxx:963
void SetWrongList(sw::WrongListIterator *const pNew)
Definition: inftxt.hxx:454
SwCharFormat * GetCharFormat(IDocumentStylePoolAccess &rIDSPA) const
Definition: lineinfo.cxx:100
SwWrongList * GetWrong()
Definition: txtedt.cxx:2167
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:416
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
const SwLineLayout * GetNext() const
Definition: itrtxt.hxx:84
bool IsChg() const
Definition: txtpaint.hxx:48
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
bool IsVertical() const
Definition: frame.hxx:949
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
SwDoc & GetDoc()
Definition: txtfrm.hxx:448
const OUString & GetDivider() const
Definition: lineinfo.hxx:67
void Clear()
Definition: swrect.hxx:298
bool HasRedline() const
Definition: porlay.hxx:125
bool IsOn() const
Definition: txtfly.hxx:313
const sal_Unicode CH_PAR
Definition: swfont.hxx:45
void SetSpace(long nNew)
Definition: drawfont.hxx:500
bool IsCount() const
Definition: fmtline.hxx:58
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
const SvxNumberType & GetNumType() const
Definition: lineinfo.hxx:64
sal_uInt16 GetDividerCountBy() const
Definition: lineinfo.hxx:69
void PaintExtraData(const SwRect &rRect) const
Definition: frmpaint.cxx:281
SwRect m_aRect
Definition: frmpaint.cxx:65
sal_uInt16 GetBaseHeight() const
Definition: tgrditem.hxx:75
void SetSmartTags(sw::WrongListIterator *const pNew)
Definition: inftxt.hxx:460
static bool bInitFont
Definition: frmpaint.cxx:60
bool IsBodyFrame() const
Definition: frame.hxx:1182
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:204
void Chg(const Point &rNP, const Size &rNS)
Definition: swrect.hxx:162
void PaintRedline(SwTwips nY, long nMax)
Definition: frmpaint.cxx:253
static constexpr size_type npos
Definition: docary.hxx:331
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
long Y() const
void PaintDropPortion()
Definition: txtdrop.cxx:650
void DrawTextLine(const SwRect &rPaint, SwSaveClip &rClip, const bool bUnderSz)
Definition: itrpaint.cxx:136
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
void ChgClip(const SwRect &rRect, const SwTextFrame *pFrame=nullptr, bool bEnlargeRect=false)
Definition: txtpaint.hxx:44
const SwFormatLineNumber & GetLineNumber(bool=true) const
Definition: fmtline.hxx:64