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