/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
nDivider, how often do we want a substring; 0 == never nX, line number's x position pFnt, line number's font nLineNr, the first line number bLineNum is set back to false if the numbering is completely outside of the paint rect
*/
m_nDivider = !m_rLineInf.GetDivider().isEmpty() ? m_rLineInf.GetDividerCountBy() : 0;
m_nX = pFrame->getFrameArea().Left();
SwCharFormat* pFormat = m_rLineInf.GetCharFormat( const_cast<IDocumentStylePoolAccess&>(pFrame->GetDoc().getIDocumentStylePoolAccess()) );
assert(pFormat && "PaintExtraData without CharFormat");
m_pFnt.reset( new SwFont(&pFormat->GetAttrSet(), &pFrame->GetDoc().getIDocumentSettingAccess()) );
m_pFnt->Invalidate();
m_pFnt->ChgPhysFnt( m_pSh, *m_pSh->GetOut() );
m_pFnt->SetVertical( 0_deg10, pFrame->IsVertical() );
}
void SwExtraPainter::PaintExtra( SwTwips nY, tools::Long nAsc, tools::Long nMax, bool bRed, const OUString* pRedlineText )
{ const OUString aTmp( pRedlineText // Tracked change is stronger than the line number
? *pRedlineText
: ( HasNumber() // Line number is stronger than the divider
? m_rLineInf.GetNumType().GetNumStr( m_nLineNr )
: m_rLineInf.GetDivider() ) );
// Get script type of line numbering:
m_pFnt->SetActual( SwScriptInfo::WhichFont(0, aTmp) );
if ( pRedlineText )
{
m_pFnt->SetColor(m_pSh->GetViewOptions()->GetNonPrintingCharacterColor()); // don't strike out text in Insertions In Margin mode if ( !m_pSh->GetViewOptions()->IsShowChangesInMargin2() )
m_pFnt->SetStrikeout( STRIKEOUT_SINGLE );
m_pFnt->SetSize( Size( 0, 200), m_pFnt->GetActual() );
}
// paint redline or word spacing indicator void SwExtraPainter::PaintRedline( SwTwips nY, tools::Long nMax, sal_Int16 nWordSpacing )
{
Point aStart( m_nRedX, nY );
Point aEnd( m_nRedX, nY + nMax );
constbool bIsShowChangesInMargin = pSh->GetViewOptions()->IsShowChangesInMargin(); do
{ // A comment from SwTextFormatter::CalcRealHeight: // The dummy flag is set on lines that only contain flyportions. Unfortunately an empty // line can be at the end of a paragraph (empty paragraphs or behind a Shift-Return). if (!aLine.GetCurr()->IsDummy()
|| (!aLine.GetCurr()->GetNext()
&& aLine.GetStart()
>= TextFrameIndex(aLine.GetTextFrame()->GetText().getLength())))
{
SwTwips nExtraSpaceSize = aLine.GetCurr()->GetFirstPortion()->ExtraSpaceSize(); if ( nExtraSpaceSize && bWordSpacingIndicator )
aExtra.PaintRedline( aLine.Y(), aLine.GetLineHeight(), nExtraSpaceSize );
SwRect aRet( getFramePrintArea() ); if ( IsEmpty() || !HasPara() )
aRet += getFrameArea().Pos(); else
{ // We return the right paint rect. Use the calculated PaintOfst as the // left margin
SwRepaint& rRepaint = GetPara()->GetRepaint();
tools::Long l;
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
rRepaint.Chg( GetUpper()->getFrameArea().Pos() + GetUpper()->getFramePrintArea().Pos(), GetUpper()->getFramePrintArea().SSize() );
l = rRepaint.GetRightOfst(); if( l && l > rRepaint.Right() )
rRepaint.Right( l );
rRepaint.SetOffset( 0 );
aRet = rRepaint;
// In case our left edge is the same as the body frame's left edge, // then extend the rectangle to include the page margin as well, // otherwise some font will be clipped.
SwLayoutFrame* pBodyFrame = GetUpper(); if (pBodyFrame->IsBodyFrame() && aRet.Left() == (pBodyFrame->getFrameArea().Left() + pBodyFrame->getFramePrintArea().Left())) if (SwLayoutFrame* pPageFrame = pBodyFrame->GetUpper())
aRet.Left(pPageFrame->getFrameArea().Left());
if ( IsRightToLeft() )
SwitchLTRtoRTL( aRet );
if ( IsVertical() )
SwitchHorizontalToVertical( aRet );
}
ResetRepaint();
if (GetTextNodeForParaProps()->GetSwAttrSet().GetParaGrid().GetValue() &&
IsInDocBody() )
{
SwTextGridItem const*const pGrid(GetGridItem(FindPageFrame())); if ( pGrid )
{ // center character in grid line
aPos.AdjustY(( pGrid->GetBaseHeight() -
pFnt->GetHeight( pSh, *pSh->GetOut() ) ) / 2 );
if ( ! pGrid->GetRubyTextBelow() )
aPos.AdjustY(pGrid->GetRubyHeight() );
}
}
// Don't show the paragraph mark for collapsed paragraphs, when they are hidden // No paragraph marker in the non-last part of a split fly anchor, either. if ( EmptyHeight( ) > 1 && !HasNonLastSplitFlyDrawObj() )
{
SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), CH_PAR, 0, 1 );
aDrawInf.SetPos( aPos );
aDrawInf.SetSpace( 0 );
aDrawInf.SetKanaComp( 0 );
aDrawInf.SetWrong( nullptr );
aDrawInf.SetGrammarCheck( nullptr );
aDrawInf.SetSmartTags( nullptr );
aDrawInf.SetFrame( this );
aDrawInf.SetFont( pFnt.get() );
aDrawInf.SetSnapToGrid( false );
// show redline color and settings drawing a background pilcrow, // but keep also other formattings (with neutral pilcrow color) if ( eRedline != RedlineType::None )
{
pFnt->DrawText_( aDrawInf ); if ( eRedline == RedlineType::Delete )
pFnt->SetStrikeout( STRIKEOUT_NONE ); else
pFnt->SetUnderline( LINESTYLE_NONE );
}
// It can happen that the IdleCollector withdrew my cached information if( !HasPara() )
{
OSL_ENSURE( isFrameAreaPositionValid(), "+SwTextFrame::PaintSwFrame: no Calc()" );
// #i29062# pass info that we are currently // painting. const_cast<SwTextFrame*>(this)->GetFormatted( true ); if( IsEmpty() )
{
PaintEmpty( rRect, false ); return;
} if( !HasPara() )
{
OSL_ENSURE( false, "+SwTextFrame::PaintSwFrame: missing format information" ); return;
}
}
// tdf140219-2.odt text frame with only fly portions and a follow is not // actually a paragraph - delay creating all structured elements to follow. boolconst isPDFTaggingEnabled(!HasFollow() || GetPara()->HasContentPortions());
::std::optional<SwTaggedPDFHelper> oTaggedPDFHelperNumbering; if (isPDFTaggingEnabled)
{
Num_Info aNumInfo(*this);
oTaggedPDFHelperNumbering.emplace(&aNumInfo, nullptr, nullptr, rRenderContext);
}
// Lbl unfortunately must be able to contain multiple numbering portions // that may be on multiple lines of text (but apparently always in the // master frame), so it gets complicated.
::std::optional<SwTaggedPDFHelper> oTaggedLabel; // Paragraph tag - if there is a list label, opening should be delayed.
::std::optional<SwTaggedPDFHelper> oTaggedParagraph;
if (isPDFTaggingEnabled
&& (GetTextNodeForParaProps()->IsOutline()
|| !GetPara()->HasNumberingPortion(SwParaPortion::FootnoteToo)))
{ // no Lbl needed => open paragraph tag now
Frame_Info aFrameInfo(*this, false);
oTaggedParagraph.emplace(nullptr, &aFrameInfo, nullptr, rRenderContext);
}
// We don't want to be interrupted while painting. // Do that after thr Format()!
TextFrameLockGuard aLock(const_cast<SwTextFrame*>(this));
// We only paint the part of the TextFrame which changed, is within the // range and was requested to paint. // One could think that the area rRect _needs_ to be painted, although // rRepaint is set. Indeed, we cannot avoid this problem from a formal // perspective. Luckily we can assume rRepaint to be empty when we need // paint the while Frame.
SwTextLineAccess aAccess( this );
SwParaPortion *pPara = aAccess.GetPara();
SwRepaint &rRepaint = pPara->GetRepaint();
// Switch off recycling when in the FlyContentFrame. // A DrawRect is called for repainting the line anyways. if( rRepaint.GetOffset() )
{ const SwFlyFrame *pFly = FindFlyFrame(); if( pFly && pFly->IsFlyInContentFrame() )
rRepaint.SetOffset( 0 );
}
// Ge the String for painting. The length is of special interest.
// Rectangle
OSL_ENSURE( ! IsSwapped(), "A frame is swapped before Paint" );
SwRect aOldRect( rRect );
SwTextPainter aLine( const_cast<SwTextFrame*>(this), &aInf ); // Optimization: if no free flying Frame overlaps into our line, the // SwTextFly just switches off
aInf.GetTextFly().Relax();
OutputDevice* pOut = aInf.GetOut(); constbool bOnWin = pSh->GetWin() != nullptr;
SwSaveClip aClip( bOnWin || IsUndersized() ? pOut : nullptr );
// Output loop: For each Line ... (which is still visible) ... // adapt rRect (Top + 1, Bottom - 1) // Because the Iterator attaches the Lines without a gap to each other
aLine.TwipsToLine( rRect.Top() + 1 );
tools::Long nBottom = rRect.Bottom();
do
{
aLine.DrawTextLine(rRect, aClip, IsUndersized(), oTaggedLabel, oTaggedParagraph, isPDFTaggingEnabled);
} while( aLine.Next() && aLine.Y() <= nBottom );
// Once is enough: if( aLine.IsPaintDrop() )
aLine.PaintDropPortion();
if( rRepaint.HasArea() )
rRepaint.Clear();
}
PaintParagraphStylesHighlighting();
const_cast<SwRect&>(rRect) = aOldRect;
OSL_ENSURE( ! IsSwapped(), "A frame is swapped after Paint" );
assert(!oTaggedLabel); // must have been closed if opened
assert(!isPDFTaggingEnabled || oTaggedParagraph || rRect.GetIntersection(getFrameArea()) != getFrameArea()); // must have been created during complete paint (PDF export is always complete paint)
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.