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  int nVirtPageNum = 0;
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  nVirtPageNum = 1;
142  ePos = ePos == LINENUMBER_POS_INSIDE ?
144  }
145  else
146  {
147  nVirtPageNum = 2;
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( !nVirtPageNum )
168  nVirtPageNum = pFrame->FindPageFrame()->OnRightPage() ? 1 : 2;
169  if( nVirtPageNum % 2 )
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.GetOfst() )
429  rRepaint.Left( rRepaint.GetOfst() );
430 
431  l = rRepaint.GetRightOfst();
432  if( l && l > rRepaint.Right() )
433  rRepaint.Right( l );
434  rRepaint.SetOfst( 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.GetTextFirstLineOfst() > 0 )
519  aPos.AdjustX(rSpace.GetTextFirstLineOfst() );
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  const OUString aTmp( CH_PAR );
549  SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), aTmp, 0, 1 );
550  aDrawInf.SetPos( aPos );
551  aDrawInf.SetSpace( 0 );
552  aDrawInf.SetKanaComp( 0 );
553  aDrawInf.SetWrong( nullptr );
554  aDrawInf.SetGrammarCheck( nullptr );
555  aDrawInf.SetSmartTags( nullptr );
556  aDrawInf.SetFrame( this );
557  aDrawInf.SetFont( pFnt.get() );
558  aDrawInf.SetSnapToGrid( false );
559 
560  pFnt->SetColor(NON_PRINTING_CHARACTER_COLOR);
561  pFnt->DrawText_( aDrawInf );
562  }
563  }
564  return true;
565  }
566  }
567  else
568  return true;
569  return false;
570 }
571 
572 void SwTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const
573 {
574  ResetRepaint();
575 
576  // #i16816# tagged pdf support
578 
579  Num_Info aNumInfo( *this );
580  SwTaggedPDFHelper aTaggedPDFHelperNumbering( &aNumInfo, nullptr, nullptr, rRenderContext );
581 
582  Frame_Info aFrameInfo( *this );
583  SwTaggedPDFHelper aTaggedPDFHelperParagraph( nullptr, &aFrameInfo, nullptr, rRenderContext );
584 
585  if( IsEmpty() && PaintEmpty( rRect, true ) )
586  return;
587 
588  if( IsLocked() || IsHiddenNow() || ! getFramePrintArea().HasArea() )
589  return;
590 
591  // It can happen that the IdleCollector withdrew my cached information
592  if( !HasPara() )
593  {
594  OSL_ENSURE( isFrameAreaPositionValid(), "+SwTextFrame::PaintSwFrame: no Calc()" );
595 
596  // #i29062# pass info that we are currently
597  // painting.
598  const_cast<SwTextFrame*>(this)->GetFormatted( true );
599  if( IsEmpty() )
600  {
601  PaintEmpty( rRect, false );
602  return;
603  }
604  if( !HasPara() )
605  {
606  OSL_ENSURE( false, "+SwTextFrame::PaintSwFrame: missing format information" );
607  return;
608  }
609  }
610 
611  // We don't want to be interrupted while painting.
612  // Do that after thr Format()!
613  TextFrameLockGuard aLock(const_cast<SwTextFrame*>(this));
614 
615  // We only paint the part of the TextFrame which changed, is within the
616  // range and was requested to paint.
617  // One could think that the area rRect _needs_ to be painted, although
618  // rRepaint is set. Indeed, we cannot avoid this problem from a formal
619  // perspective. Luckily we can assume rRepaint to be empty when we need
620  // paint the while Frame.
621  SwTextLineAccess aAccess( this );
622  SwParaPortion *pPara = aAccess.GetPara();
623 
624  SwRepaint &rRepaint = pPara->GetRepaint();
625 
626  // Switch off recycling when in the FlyContentFrame.
627  // A DrawRect is called for repainting the line anyways.
628  if( rRepaint.GetOfst() )
629  {
630  const SwFlyFrame *pFly = FindFlyFrame();
631  if( pFly && pFly->IsFlyInContentFrame() )
632  rRepaint.SetOfst( 0 );
633  }
634 
635  // Ge the String for painting. The length is of special interest.
636 
637  // Rectangle
638  OSL_ENSURE( ! IsSwapped(), "A frame is swapped before Paint" );
639  SwRect aOldRect( rRect );
640 
641  {
642  SwSwapIfNotSwapped swap(const_cast<SwTextFrame *>(this));
643 
644  if ( IsVertical() )
645  SwitchVerticalToHorizontal( const_cast<SwRect&>(rRect) );
646 
647  if ( IsRightToLeft() )
648  SwitchRTLtoLTR( const_cast<SwRect&>(rRect) );
649 
650  SwTextPaintInfo aInf( const_cast<SwTextFrame*>(this), rRect );
651  sw::WrongListIterator iterWrong(*this, &SwTextNode::GetWrong);
653  sw::WrongListIterator iterSmartTags(*this, &SwTextNode::GetSmartTags);
654  if (iterWrong.LooksUseful())
655  {
656  aInf.SetWrongList( &iterWrong );
657  }
658  if (iterGrammar.LooksUseful())
659  {
660  aInf.SetGrammarCheckList( &iterGrammar );
661  }
662  if (iterSmartTags.LooksUseful())
663  {
664  aInf.SetSmartTags( &iterSmartTags );
665  }
666  aInf.GetTextFly().SetTopRule();
667 
668  SwTextPainter aLine( const_cast<SwTextFrame*>(this), &aInf );
669  // Optimization: if no free flying Frame overlaps into our line, the
670  // SwTextFly just switches off
671  aInf.GetTextFly().Relax();
672 
673  OutputDevice* pOut = aInf.GetOut();
674  const bool bOnWin = pSh->GetWin() != nullptr;
675 
676  SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : nullptr );
677 
678  // Output loop: For each Line ... (which is still visible) ...
679  // adapt rRect (Top + 1, Bottom - 1)
680  // Because the Iterator attaches the Lines without a gap to each other
681  aLine.TwipsToLine( rRect.Top() + 1 );
682  long nBottom = rRect.Bottom();
683 
684  bool bNoPrtLine = 0 == GetMinPrtLine();
685  if( !bNoPrtLine )
686  {
687  while ( aLine.Y() < GetMinPrtLine() && aLine.Next() )
688  ;
689  bNoPrtLine = aLine.Y() >= GetMinPrtLine();
690  }
691  if( bNoPrtLine )
692  {
693  do
694  {
695  aLine.DrawTextLine( rRect, aClip, IsUndersized() );
696 
697  } while( aLine.Next() && aLine.Y() <= nBottom );
698  }
699 
700  // Once is enough:
701  if( aLine.IsPaintDrop() )
702  aLine.PaintDropPortion();
703 
704  if( rRepaint.HasArea() )
705  rRepaint.Clear();
706  }
707 
708  const_cast<SwRect&>(rRect) = aOldRect;
709 
710  OSL_ENSURE( ! IsSwapped(), "A frame is swapped after Paint" );
711 
712 }
713 
714 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
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:579
bool PaintEmpty(const SwRect &, bool bCheck) const
Definition: frmpaint.cxx:456
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:718
SwTwips EmptyHeight() const
Definition: porrst.cxx:204
bool IsInDocBody() const
Definition: frame.hxx:919
bool IsInFly() const
Definition: frame.hxx:937
const SwLineNumberInfo & GetLineNumberInfo() const
Definition: lineinfo.cxx:49
SwTwips GetOfst() const
Definition: porlay.hxx:70
long AdjustX(long nHorzMove)
bool IsSwapped() const
Definition: txtfrm.hxx:528
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:812
short GetTextFirstLineOfst() const
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:472
sal_uIntPtr sal_uLong
FAMILY_DONTKNOW
const SwRect & getFramePrintArea() const
Definition: frame.hxx:176
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:440
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:50
virtual void PaintSwFrame(vcl::RenderContext &rRenderContext, SwRect const &, SwPrintData const *const pPrintData=nullptr) const override
Definition: frmpaint.cxx:572
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
long SwTwips
Definition: swtypes.hxx:49
const SwLineLayout * Next()
Definition: itrtxt.cxx:106
void Pos(const Point &rNew)
Definition: swrect.hxx:167
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
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:317
static bool IsShowChanges(const RedlineFlags eM)
bool IsVertLRBT() const
Definition: frame.hxx:959
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1348
void Top(const long nTop)
Definition: swrect.hxx:202
const SwRect & getFrameArea() const
Definition: frame.hxx:175
static long GetMinPrtLine()
Definition: txtfrm.hxx:604
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:425
sal_uLong GetThisLines() const
Definition: txtfrm.hxx:661
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:51
bool IsPaintDrop() const
Definition: itrpaint.hxx:56
oslFileHandle & pOut
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
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:410
bool IsEmpty() const
Definition: txtfrm.hxx:511
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:447
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1291
#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:2054
long AdjustY(long nVertMove)
vcl::RenderContext * GetOut()
Definition: inftxt.hxx:231
SwTextFly & GetTextFly()
Definition: inftxt.hxx:390
Mutex aLock
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
sal_uLong GetAllLines() const
For displaying the line numbers.
Definition: txtfrm.hxx:660
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:923
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2514
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:298
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
SwGrammarMarkUp * GetGrammarCheck()
Definition: txtedt.cxx:2180
bool IsUndersized() const
Definition: flowfrm.hxx:158
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3352
#define NON_PRINTING_CHARACTER_COLOR
Definition: txtfrm.hxx:50
void Modify(bool bChgToRTL)
Definition: txtfrm.cxx:710
sal_uInt16 GetLineHeight() const
Definition: itrtxt.hxx:116
SwWrongList * GetSmartTags()
Definition: txtedt.cxx:2205
const IDocumentSettingAccess * getIDocumentSettingAccess() const
Provides access to the document setting interface.
Definition: node.cxx:2052
bool isFrameAreaPositionValid() const
Definition: frame.hxx:162
bool HasSwAttrSet() const
Definition: node.hxx:444
bool IsLocked() const
Definition: txtfrm.hxx:507
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:682
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:334
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
Definition: txtfrm.hxx:728
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:80
void SetSize(const Size &rSize, const SwFontScript nWhich)
Definition: swfont.hxx:737
SwRepaint & GetRepaint()
Definition: porlay.hxx:264
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
Definition: number.cxx:1259
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 ResetRepaint() const
Definition: txtfrm.hxx:868
const SvxParaGridItem & GetParaGrid(bool=true) const
Definition: paratr.hxx:206
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:175
bool IsRightToLeft() const
Definition: frame.hxx:963
void SetWrongList(sw::WrongListIterator *const pNew)
Definition: inftxt.hxx:454
SwWrongList * GetWrong()
Definition: txtedt.cxx:2157
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:450
void Clear()
Definition: swrect.hxx:298
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
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
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:1182
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:204
void Chg(const Point &rNP, const Size &rNS)
Definition: swrect.hxx:162
static constexpr size_type npos
Definition: docary.hxx:331
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
void PaintDropPortion()
Definition: txtdrop.cxx:653
void DrawTextLine(const SwRect &rPaint, SwSaveClip &rClip, const bool bUnderSz)
Definition: itrpaint.cxx:119
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
const SwFormatLineNumber & GetLineNumber(bool=true) const
Definition: fmtline.hxx:64