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