summaryrefslogtreecommitdiff
path: root/sw/source/core/text/pormulti.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/text/pormulti.cxx')
-rw-r--r--sw/source/core/text/pormulti.cxx313
1 files changed, 189 insertions, 124 deletions
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index c51fb973ad29..9fb6011f0db5 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -31,6 +31,7 @@
#include <charfmt.hxx>
#include <layfrm.hxx>
#include <SwPortionHandler.hxx>
+#include <EnhancedPDFExportHelper.hxx>
#include "pormulti.hxx"
#include "inftxt.hxx"
#include "itrpaint.hxx"
@@ -119,7 +120,7 @@ void SwMultiPortion::CalcSize( SwTextFormatter& rLine, SwTextFormatInfo &rInf )
SetAscent( nTmp );
}
-tools::Long SwMultiPortion::CalcSpacing( tools::Long , const SwTextSizeInfo & ) const
+SwTwips SwMultiPortion::CalcSpacing( tools::Long , const SwTextSizeInfo & ) const
{
return 0;
}
@@ -134,6 +135,31 @@ void SwMultiPortion::HandlePortion( SwPortionHandler& rPH ) const
rPH.Text( GetLen(), GetWhichPor() );
}
+void SwMultiPortion::dumpAsXml(xmlTextWriterPtr pWriter, const OUString& rText,
+ TextFrameIndex& nOffset) const
+{
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwMultiPortion"));
+ dumpAsXmlAttributes(pWriter, rText, nOffset);
+ // Intentionally not incrementing nOffset here, one of the child portions will do that.
+
+ const SwLineLayout* pLine = &GetRoot();
+ while (pLine)
+ {
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwLineLayout"));
+ pLine->dumpAsXmlAttributes(pWriter, rText, nOffset);
+ const SwLinePortion* pPor = pLine->GetFirstPortion();
+ while (pPor)
+ {
+ pPor->dumpAsXml(pWriter, rText, nOffset);
+ pPor = pPor->GetNextPortion();
+ }
+ (void)xmlTextWriterEndElement(pWriter);
+ pLine = pLine->GetNext();
+ }
+
+ (void)xmlTextWriterEndElement(pWriter);
+}
+
// sets the tabulator-flag, if there's any tabulator-portion inside.
void SwMultiPortion::ActualizeTabulator()
{
@@ -193,7 +219,7 @@ SwBidiPortion::SwBidiPortion(TextFrameIndex const nEnd, sal_uInt8 nLv)
SetDirection( DIR_LEFT2RIGHT );
}
-tools::Long SwBidiPortion::CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeInfo& rInf ) const
+SwTwips SwBidiPortion::CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeInfo& rInf ) const
{
return HasTabulator() ? 0 : sal_Int32(GetSpaceCnt(rInf)) * nSpaceAdd / SPACING_PRECISION_FACTOR;
}
@@ -351,12 +377,12 @@ void SwDoubleLinePortion::PaintBracket( SwTextPaintInfo &rInf,
aBlank.Width( nChWidth );
aBlank.Height( m_pBracket->nHeight );
{
- std::unique_ptr<SwFont> pTmpFnt( new SwFont( *rInf.GetFont() ) );
+ SwFont aTmpFnt( *rInf.GetFont() );
SwFontScript nAct = bOpen ? m_pBracket->nPreScript : m_pBracket->nPostScript;
if( SW_SCRIPTS > nAct )
- pTmpFnt->SetActual( nAct );
- pTmpFnt->SetProportion( 100 );
- SwFontSave aSave( rInf, pTmpFnt.get() );
+ aTmpFnt.SetActual( nAct );
+ aTmpFnt.SetProportion( 100 );
+ SwFontSave aSave( rInf, &aTmpFnt );
aBlank.Paint( rInf );
}
if( bOpen )
@@ -384,21 +410,21 @@ void SwDoubleLinePortion::SetBrackets( const SwDoubleLinePortion& rDouble )
void SwDoubleLinePortion::FormatBrackets( SwTextFormatInfo &rInf, SwTwips& nMaxWidth )
{
nMaxWidth -= rInf.X();
- std::unique_ptr<SwFont> pTmpFnt( new SwFont( *rInf.GetFont() ) );
- pTmpFnt->SetProportion( 100 );
+ SwFont aTmpFnt( *rInf.GetFont() );
+ aTmpFnt.SetProportion( 100 );
m_pBracket->nAscent = 0;
m_pBracket->nHeight = 0;
if( m_pBracket->cPre )
{
OUString aStr( m_pBracket->cPre );
- SwFontScript nActualScr = pTmpFnt->GetActual();
+ SwFontScript nActualScr = aTmpFnt.GetActual();
if( SW_SCRIPTS > m_pBracket->nPreScript )
- pTmpFnt->SetActual( m_pBracket->nPreScript );
- SwFontSave aSave( rInf, pTmpFnt.get() );
+ aTmpFnt.SetActual( m_pBracket->nPreScript );
+ SwFontSave aSave( rInf, &aTmpFnt );
SwPosSize aSize = rInf.GetTextSize( aStr );
m_pBracket->nAscent = rInf.GetAscent();
m_pBracket->nHeight = aSize.Height();
- pTmpFnt->SetActual( nActualScr );
+ aTmpFnt.SetActual( nActualScr );
if( nMaxWidth > aSize.Width() )
{
m_pBracket->nPreWidth = aSize.Width();
@@ -417,8 +443,8 @@ void SwDoubleLinePortion::FormatBrackets( SwTextFormatInfo &rInf, SwTwips& nMaxW
{
OUString aStr( m_pBracket->cPost );
if( SW_SCRIPTS > m_pBracket->nPostScript )
- pTmpFnt->SetActual( m_pBracket->nPostScript );
- SwFontSave aSave( rInf, pTmpFnt.get() );
+ aTmpFnt.SetActual( m_pBracket->nPostScript );
+ SwFontSave aSave( rInf, &aTmpFnt );
SwPosSize aSize = rInf.GetTextSize( aStr );
const sal_uInt16 nTmpAsc = rInf.GetAscent();
if( nTmpAsc > m_pBracket->nAscent )
@@ -479,7 +505,7 @@ void SwDoubleLinePortion::CalcBlanks( SwTextFormatInfo &rInf )
rInf.SetIdx( nStart );
}
-tools::Long SwDoubleLinePortion::CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeInfo & ) const
+SwTwips SwDoubleLinePortion::CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeInfo & ) const
{
return HasTabulator() ? 0 : sal_Int32(GetSpaceCnt()) * nSpaceAdd / SPACING_PRECISION_FACTOR;
}
@@ -592,7 +618,7 @@ SwRubyPortion::SwRubyPortion( const SwMultiCreator& rCreate, const SwFont& rFnt,
}
OUString aStr = rRuby.GetText().copy( sal_Int32(nOffs) );
- SwFieldPortion *pField = new SwFieldPortion( aStr, std::move(pRubyFont) );
+ SwFieldPortion *pField = new SwFieldPortion( std::move(aStr), std::move(pRubyFont) );
pField->SetNextOffset( nOffs );
pField->SetFollow( true );
@@ -654,9 +680,9 @@ void SwRubyPortion::Adjust_( SwTextFormatInfo &rInf )
TextFrameIndex nSub(0);
switch ( m_nAdjustment )
{
- case css::text::RubyAdjust_CENTER: nRight = static_cast<sal_uInt16>(nLineDiff / 2);
+ case css::text::RubyAdjust_CENTER: nRight = o3tl::narrowing<sal_uInt16>(nLineDiff / 2);
[[fallthrough]];
- case css::text::RubyAdjust_RIGHT: nLeft = static_cast<sal_uInt16>(nLineDiff - nRight); break;
+ case css::text::RubyAdjust_RIGHT: nLeft = o3tl::narrowing<sal_uInt16>(nLineDiff - nRight); break;
case css::text::RubyAdjust_BLOCK: nSub = TextFrameIndex(1);
[[fallthrough]];
case css::text::RubyAdjust_INDENT_BLOCK:
@@ -683,8 +709,8 @@ void SwRubyPortion::Adjust_( SwTextFormatInfo &rInf )
}
if( nLineDiff > 1 )
{
- nRight = static_cast<sal_uInt16>(nLineDiff / 2);
- nLeft = static_cast<sal_uInt16>(nLineDiff - nRight);
+ nRight = o3tl::narrowing<sal_uInt16>(nLineDiff / 2);
+ nLeft = o3tl::narrowing<sal_uInt16>(nLineDiff - nRight);
}
break;
}
@@ -846,12 +872,14 @@ namespace sw {
}
if (m_pMerged)
{
- while (m_CurrentExtent < m_pMerged->extents.size())
+ const auto nExtentsSize = m_pMerged->extents.size();
+ while (m_CurrentExtent < nExtentsSize)
{
sw::Extent const& rExtent(m_pMerged->extents[m_CurrentExtent]);
if (SwpHints const*const pHints = rExtent.pNode->GetpSwpHints())
{
- while (m_CurrentHint < pHints->Count())
+ auto nHintsCount = pHints->Count();
+ while (m_CurrentHint < nHintsCount)
{
SwTextAttr const*const pHint(pHints->Get(m_CurrentHint));
if (rExtent.nEnd < pHint->GetStart())
@@ -867,7 +895,7 @@ namespace sw {
}
}
++m_CurrentExtent;
- if (m_CurrentExtent < m_pMerged->extents.size() &&
+ if (m_CurrentExtent < nExtentsSize &&
rExtent.pNode != m_pMerged->extents[m_CurrentExtent].pNode)
{
m_CurrentHint = 0; // reset
@@ -904,7 +932,7 @@ namespace sw {
// interrupts the first attribute.
// E.g. a ruby portion interrupts a 2-line-attribute, a 2-line-attribute
// with different brackets interrupts another 2-line-attribute.
-std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &rPos,
+std::optional<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &rPos,
SwMultiPortion const * pMulti ) const
{
SwScriptInfo& rSI = const_cast<SwParaPortion*>(GetParaPortion())->GetScriptInfo();
@@ -936,26 +964,26 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
{
rPos = bFieldBidi ? rPos + TextFrameIndex(1) : rSI.NextDirChg(rPos, &nCurrLevel);
if (TextFrameIndex(COMPLETE_STRING) == rPos)
- return nullptr;
- std::unique_ptr<SwMultiCreator> pRet(new SwMultiCreator);
- pRet->pItem = nullptr;
- pRet->pAttr = nullptr;
- pRet->nStartOfAttr = TextFrameIndex(-1);
- pRet->nId = SwMultiCreatorId::Bidi;
- pRet->nLevel = nCurrLevel + 1;
- return pRet;
+ return {};
+ SwMultiCreator aRet;
+ aRet.pItem = nullptr;
+ aRet.pAttr = nullptr;
+ aRet.nStartOfAttr = TextFrameIndex(-1);
+ aRet.nId = SwMultiCreatorId::Bidi;
+ aRet.nLevel = nCurrLevel + 1;
+ return aRet;
}
// a bidi portion can only contain other bidi portions
if ( pMulti )
- return nullptr;
+ return {};
// need the node that contains input rPos
std::pair<SwTextNode const*, sal_Int32> startPos(m_pFrame->MapViewToModel(rPos));
const SvxCharRotateItem* pActiveRotateItem(nullptr);
- const SfxPoolItem* pNodeRotateItem(nullptr);
+ const SvxCharRotateItem* pNodeRotateItem(nullptr);
const SvxTwoLinesItem* pActiveTwoLinesItem(nullptr);
- const SfxPoolItem* pNodeTwoLinesItem(nullptr);
+ const SvxTwoLinesItem* pNodeTwoLinesItem(nullptr);
SwTextAttr const* pActiveTwoLinesHint(nullptr);
SwTextAttr const* pActiveRotateHint(nullptr);
const SwTextAttr *pRuby = nullptr;
@@ -1004,59 +1032,57 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
}
}
}
- else if (pNode) // !pAttr && pNode means the node changed
+ // !pAttr && pNode means the node changed
+ if (startPos.first->GetIndex() < pNode->GetIndex())
+ {
+ break; // only one node initially
+ }
+ if (startPos.first->GetIndex() == pNode->GetIndex())
{
- if (startPos.first->GetIndex() < pNode->GetIndex())
+ iterAtStartOfNode.Assign(iter);
+ if (SfxItemState::SET == pNode->GetSwAttrSet().GetItemState(
+ RES_CHRATR_ROTATE, true, &pNodeRotateItem) &&
+ pNodeRotateItem->GetValue())
{
- break; // only one node initially
+ pActiveRotateItem = pNodeRotateItem;
}
- if (startPos.first->GetIndex() == pNode->GetIndex())
+ else
{
- iterAtStartOfNode.Assign(iter);
- if (SfxItemState::SET == pNode->GetSwAttrSet().GetItemState(
- RES_CHRATR_ROTATE, true, &pNodeRotateItem) &&
- static_cast<const SvxCharRotateItem*>(pNodeRotateItem)->GetValue())
- {
- pActiveRotateItem = static_cast<const SvxCharRotateItem*>(pNodeRotateItem);
- }
- else
- {
- pNodeRotateItem = nullptr;
- }
- if (SfxItemState::SET == startPos.first->GetSwAttrSet().GetItemState(
- RES_CHRATR_TWO_LINES, true, &pNodeTwoLinesItem) &&
- static_cast<const SvxTwoLinesItem*>(pNodeTwoLinesItem)->GetValue())
- {
- pActiveTwoLinesItem = static_cast<const SvxTwoLinesItem*>(pNodeTwoLinesItem);
- }
- else
- {
- pNodeTwoLinesItem = nullptr;
- }
+ pNodeRotateItem = nullptr;
+ }
+ if (SfxItemState::SET == startPos.first->GetSwAttrSet().GetItemState(
+ RES_CHRATR_TWO_LINES, true, &pNodeTwoLinesItem) &&
+ pNodeTwoLinesItem->GetValue())
+ {
+ pActiveTwoLinesItem = pNodeTwoLinesItem;
+ }
+ else
+ {
+ pNodeTwoLinesItem = nullptr;
}
}
}
if (!pRuby && !pActiveTwoLinesItem && !pActiveRotateItem)
- return nullptr;
+ return {};
if( pRuby )
{ // The winner is ... a ruby attribute and so
// the end of the multiportion is the end of the ruby attribute.
rPos = m_pFrame->MapModelToView(startPos.first, *pRuby->End());
- std::unique_ptr<SwMultiCreator> pRet(new SwMultiCreator);
- pRet->pItem = nullptr;
- pRet->pAttr = pRuby;
- pRet->nStartOfAttr = m_pFrame->MapModelToView(startPos.first, pRet->pAttr->GetStart());
- pRet->nId = SwMultiCreatorId::Ruby;
- pRet->nLevel = GetTextFrame()->IsRightToLeft() ? 1 : 0;
- return pRet;
+ SwMultiCreator aRet;
+ aRet.pItem = nullptr;
+ aRet.pAttr = pRuby;
+ aRet.nStartOfAttr = m_pFrame->MapModelToView(startPos.first, aRet.pAttr->GetStart());
+ aRet.nId = SwMultiCreatorId::Ruby;
+ aRet.nLevel = GetTextFrame()->IsRightToLeft() ? 1 : 0;
+ return aRet;
}
if (pActiveTwoLinesHint ||
- (pNodeTwoLinesItem && pNodeTwoLinesItem == pActiveTwoLinesItem &&
+ (pNodeTwoLinesItem && SfxPoolItem::areSame(pNodeTwoLinesItem, pActiveTwoLinesItem) &&
rPos < TextFrameIndex(GetText().getLength())))
{ // The winner is a 2-line-attribute,
// the end of the multiportion depends on the following attributes...
- std::unique_ptr<SwMultiCreator> pRet(new SwMultiCreator);
+ SwMultiCreator aRet;
// We note the endpositions of the 2-line attributes in aEnd as stack
std::deque<TextFrameIndex> aEnd;
@@ -1068,31 +1094,31 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
if (pActiveTwoLinesHint)
{
- pRet->pItem = nullptr;
- pRet->pAttr = pActiveTwoLinesHint;
- pRet->nStartOfAttr = m_pFrame->MapModelToView(startPos.first, pRet->pAttr->GetStart());
+ aRet.pItem = nullptr;
+ aRet.pAttr = pActiveTwoLinesHint;
+ aRet.nStartOfAttr = m_pFrame->MapModelToView(startPos.first, aRet.pAttr->GetStart());
if (pNodeTwoLinesItem)
{
aEnd.push_front(m_pFrame->MapModelToView(startPos.first, startPos.first->Len()));
- bOn = static_cast<const SvxTwoLinesItem*>(pNodeTwoLinesItem)->GetEndBracket() ==
+ bOn = pNodeTwoLinesItem->GetEndBracket() ==
pActiveTwoLinesItem->GetEndBracket() &&
- static_cast<const SvxTwoLinesItem*>(pNodeTwoLinesItem)->GetStartBracket() ==
+ pNodeTwoLinesItem->GetStartBracket() ==
pActiveTwoLinesItem->GetStartBracket();
}
else
{
- aEnd.push_front(m_pFrame->MapModelToView(startPos.first, *pRet->pAttr->End()));
+ aEnd.push_front(m_pFrame->MapModelToView(startPos.first, *aRet.pAttr->End()));
}
}
else
{
- pRet->pItem = pNodeTwoLinesItem;
- pRet->pAttr = nullptr;
- pRet->nStartOfAttr = TextFrameIndex(-1);
+ aRet.pItem = pNodeTwoLinesItem;
+ aRet.pAttr = nullptr;
+ aRet.nStartOfAttr = TextFrameIndex(-1);
aEnd.push_front(m_pFrame->MapModelToView(startPos.first, startPos.first->Len()));
}
- pRet->nId = SwMultiCreatorId::Double;
- pRet->nLevel = GetTextFrame()->IsRightToLeft() ? 1 : 0;
+ aRet.nId = SwMultiCreatorId::Double;
+ aRet.nLevel = GetTextFrame()->IsRightToLeft() ? 1 : 0;
// pActiveTwoLinesHint is the last 2-line-attribute, which contains
// the actual position.
@@ -1134,9 +1160,8 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
}
else
{
- pNodeTwoLinesItem = nullptr;
- pNode->GetSwAttrSet().GetItemState(
- RES_CHRATR_TWO_LINES, true, &pNodeTwoLinesItem);
+ pNodeTwoLinesItem = pNode->GetSwAttrSet().GetItemIfSet(
+ RES_CHRATR_TWO_LINES);
nTmpStart = m_pFrame->MapModelToView(pNode, 0);
nTmpEnd = m_pFrame->MapModelToView(pNode, pNode->Len());
assert(rPos <= nTmpEnd); // next node must not have smaller index
@@ -1171,7 +1196,7 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
}
// A ruby attribute stops the 2-line immediately
if (pTmp && RES_TXTATR_CJK_RUBY == pTmp->Which())
- return pRet;
+ return aRet;
if (pTmp ? lcl_Has2Lines(*pTmp, pActiveTwoLinesItem, bTwo)
: lcl_Check2Lines(pNodeTwoLinesItem, pActiveTwoLinesItem, bTwo))
{ // We have an interesting attribute...
@@ -1198,15 +1223,15 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
}
if( bOn && !aEnd.empty() )
rPos = aEnd.back();
- return pRet;
+ return aRet;
}
if (pActiveRotateHint ||
- (pNodeRotateItem && pNodeRotateItem == pActiveRotateItem &&
+ (pNodeRotateItem && SfxPoolItem::areSame(pNodeRotateItem, pActiveRotateItem) &&
rPos < TextFrameIndex(GetText().getLength())))
{ // The winner is a rotate-attribute,
// the end of the multiportion depends on the following attributes...
- std::unique_ptr<SwMultiCreator> pRet(new SwMultiCreator);
- pRet->nId = SwMultiCreatorId::Rotate;
+ SwMultiCreator aRet;
+ aRet.nId = SwMultiCreatorId::Rotate;
// We note the endpositions of the 2-line attributes in aEnd as stack
std::deque<TextFrameIndex> aEnd;
@@ -1239,9 +1264,8 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
}
else
{
- pNodeTwoLinesItem = nullptr;
- pNode->GetSwAttrSet().GetItemState(
- RES_CHRATR_TWO_LINES, true, &pNodeTwoLinesItem);
+ pNodeTwoLinesItem = pNode->GetSwAttrSet().GetItemIfSet(
+ RES_CHRATR_TWO_LINES);
nTmpStart = m_pFrame->MapModelToView(pNode, 0);
nTmpEnd = m_pFrame->MapModelToView(pNode, pNode->Len());
assert(n2Start <= nTmpEnd); // next node must not have smaller index
@@ -1299,25 +1323,25 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
bOn = true;
if (pActiveRotateHint)
{
- pRet->pItem = nullptr;
- pRet->pAttr = pActiveRotateHint;
- pRet->nStartOfAttr = m_pFrame->MapModelToView(startPos.first, pRet->pAttr->GetStart());
+ aRet.pItem = nullptr;
+ aRet.pAttr = pActiveRotateHint;
+ aRet.nStartOfAttr = m_pFrame->MapModelToView(startPos.first, aRet.pAttr->GetStart());
if (pNodeRotateItem)
{
aEnd.push_front(m_pFrame->MapModelToView(startPos.first, startPos.first->Len()));
- bOn = static_cast<const SvxCharRotateItem*>(pNodeRotateItem)->GetValue() ==
+ bOn = pNodeRotateItem->GetValue() ==
pActiveRotateItem->GetValue();
}
else
{
- aEnd.push_front(m_pFrame->MapModelToView(startPos.first, *pRet->pAttr->End()));
+ aEnd.push_front(m_pFrame->MapModelToView(startPos.first, *aRet.pAttr->End()));
}
}
else
{
- pRet->pItem = pNodeRotateItem;
- pRet->pAttr = nullptr;
- pRet->nStartOfAttr = TextFrameIndex(-1);
+ aRet.pItem = pNodeRotateItem;
+ aRet.pAttr = nullptr;
+ aRet.nStartOfAttr = TextFrameIndex(-1);
aEnd.push_front(m_pFrame->MapModelToView(startPos.first, startPos.first->Len()));
}
for (sw::MergedAttrIterMulti iter = iterAtStartOfNode; ; )
@@ -1340,9 +1364,8 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
}
else
{
- pNodeRotateItem = nullptr;
- pNode->GetSwAttrSet().GetItemState(
- RES_CHRATR_ROTATE, true, &pNodeRotateItem);
+ pNodeRotateItem = pNode->GetSwAttrSet().GetItemIfSet(
+ RES_CHRATR_ROTATE);
nTmpStart = m_pFrame->MapModelToView(pNode, 0);
nTmpEnd = m_pFrame->MapModelToView(pNode, pNode->Len());
assert(rPos <= nTmpEnd); // next node must not have smaller index
@@ -1394,9 +1417,9 @@ std::unique_ptr<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &
rPos = aEnd.back();
if( rPos > n2Start )
rPos = n2Start;
- return pRet;
+ return aRet;
}
- return nullptr;
+ return {};
}
namespace {
@@ -1557,7 +1580,7 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
SwSpaceManipulator aManip( GetInfo(), rMulti );
- std::unique_ptr<SwFontSave> pFontSave;
+ std::optional<SwFontSave> oFontSave;
std::unique_ptr<SwFont> pTmpFnt;
if( rMulti.IsDouble() )
@@ -1568,16 +1591,19 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
SetPropFont( 50 );
pTmpFnt->SetProportion( GetPropFont() );
}
- pFontSave.reset(new SwFontSave( GetInfo(), pTmpFnt.get(), this ));
+ oFontSave.emplace( GetInfo(), pTmpFnt.get(), this );
}
else
{
- pFontSave = nullptr;
pTmpFnt = nullptr;
}
if( rMulti.HasBrackets() )
{
+ // WP is mandatory
+ Por_Info const por(rMulti, *this, 1);
+ SwTaggedPDFHelper const tag(nullptr, nullptr, &por, *GetInfo().GetOut());
+
TextFrameIndex const nTmpOldIdx = GetInfo().GetIdx();
GetInfo().SetIdx(static_cast<SwDoubleLinePortion&>(rMulti).GetBrackets()->nStart);
SeekAndChg( GetInfo() );
@@ -1636,8 +1662,18 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
OSL_ENSURE( nullptr == GetInfo().GetUnderFnt() || rMulti.IsBidi(),
" Only BiDi portions are allowed to use the common underlining font" );
- if ( rMulti.IsRuby() )
+ ::std::optional<SwTaggedPDFHelper> oTag;
+ if (rMulti.IsDouble())
+ {
+ Por_Info const por(rMulti, *this, 2);
+ oTag.emplace(nullptr, nullptr, &por, *GetInfo().GetOut());
+ }
+ else if (rMulti.IsRuby())
+ {
+ Por_Info const por(rMulti, *this, bRubyTop ? 1 : 2);
+ oTag.emplace(nullptr, nullptr, &por, *GetInfo().GetOut());
GetInfo().SetRuby( rMulti.OnTop() );
+ }
do
{
@@ -1679,7 +1715,7 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
}
else if ( rMulti.IsRuby() && rMulti.OnRight() && GetInfo().IsRuby() )
{
- SwTwips nLineDiff = std::max(( rMulti.GetRoot().Height() - pPor->Width() ) / 2, 0 );
+ SwTwips nLineDiff = std::max(( rMulti.GetRoot().Height() - pPor->Width() ) / 2, static_cast<SwTwips>(0) );
GetInfo().Y( nOfst + nLineDiff );
// Draw the ruby text on top of the preserved space.
GetInfo().X( GetInfo().X() - pPor->Height() );
@@ -1740,7 +1776,12 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
PaintMultiPortion( rPaint, static_cast<SwMultiPortion&>(*pPor), &rMulti );
}
else
+ {
+ Por_Info const por(*pPor, *this, 0);
+ SwTaggedPDFHelper const tag(nullptr, nullptr, &por, *GetInfo().GetOut());
+
pPor->Paint( GetInfo() );
+ }
bFirst &= !pPor->GetLen();
if( pNext || !pPor->IsMarginPortion() )
@@ -1799,9 +1840,20 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
// We switch to the baseline of the next inner line
nOfst += rMulti.GetRoot().Height();
}
+ if (rMulti.IsRuby())
+ {
+ oTag.reset();
+ Por_Info const por(rMulti, *this, bRubyTop ? 2 : 1);
+ oTag.emplace(nullptr, nullptr, &por, *GetInfo().GetOut());
+ }
}
} while( pPor );
+ if (rMulti.IsDouble())
+ {
+ oTag.reset();
+ }
+
if ( bRubyInGrid )
GetInfo().SetSnapToGrid( bOldGridModeAllowed );
@@ -1817,6 +1869,10 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
if( rMulti.HasBrackets() )
{
+ // WP is mandatory
+ Por_Info const por(rMulti, *this, 1);
+ SwTaggedPDFHelper const tag(nullptr, nullptr, &por, *GetInfo().GetOut());
+
TextFrameIndex const nTmpOldIdx = GetInfo().GetIdx();
GetInfo().SetIdx(static_cast<SwDoubleLinePortion&>(rMulti).GetBrackets()->nStart);
SeekAndChg( GetInfo() );
@@ -1828,7 +1884,7 @@ void SwTextPainter::PaintMultiPortion( const SwRect &rPaint,
// Restore the saved values
GetInfo().X( nOldX );
GetInfo().SetLen( nOldLen );
- pFontSave.reset();
+ oFontSave.reset();
pTmpFnt.reset();
SetPropFont( 0 );
}
@@ -1898,16 +1954,17 @@ bool SwTextFormatter::BuildMultiPortion( SwTextFormatInfo &rInf,
}
SeekAndChg( rInf );
- std::unique_ptr<SwFontSave> xFontSave;
+ std::optional<SwFontSave> oFontSave;
+ std::unique_ptr<SwFont> xTmpFont;
if( rMulti.IsDouble() )
{
- SwFont* pTmpFnt = new SwFont( *rInf.GetFont() );
+ xTmpFont.reset(new SwFont( *rInf.GetFont() ));
if( rMulti.IsDouble() )
{
SetPropFont( 50 );
- pTmpFnt->SetProportion( GetPropFont() );
+ xTmpFont->SetProportion( GetPropFont() );
}
- xFontSave.reset(new SwFontSave(rInf, pTmpFnt, this));
+ oFontSave.emplace(rInf, xTmpFont.get(), this);
}
SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
@@ -1995,7 +2052,7 @@ bool SwTextFormatter::BuildMultiPortion( SwTextFormatInfo &rInf,
// save some values
const OUString* pOldText = &(rInf.GetText());
const SwTwips nOldPaintOfst = rInf.GetPaintOfst();
- std::shared_ptr<vcl::TextLayoutCache> const pOldCachedVclData(rInf.GetCachedVclData());
+ std::shared_ptr<const vcl::text::TextLayoutCache> const pOldCachedVclData(rInf.GetCachedVclData());
rInf.SetCachedVclData(nullptr);
OUString const aMultiStr( rInf.GetText().copy(0, sal_Int32(nMultiLen + rInf.GetIdx())) );
@@ -2285,6 +2342,9 @@ bool SwTextFormatter::BuildMultiPortion( SwTextFormatInfo &rInf,
// we try to keep our ruby portion together
lcl_TruncateMultiPortion( rMulti, rInf, nStartIdx );
pTmp = nullptr;
+ // A follow field portion may still be waiting. If nobody wants
+ // it, we delete it.
+ delete pNextSecond;
}
}
else if( rMulti.HasRotation() )
@@ -2354,10 +2414,15 @@ bool SwTextFormatter::BuildMultiPortion( SwTextFormatInfo &rInf,
SeekAndChg( rInf );
delete pFirstRest;
delete pSecondRest;
- xFontSave.reset();
+ oFontSave.reset();
return bRet;
}
+static bool IsIncompleteRuby(const SwMultiPortion& rHelpMulti)
+{
+ return rHelpMulti.IsRuby() && static_cast<const SwRubyPortion&>(rHelpMulti).GetRubyOffset() < TextFrameIndex(COMPLETE_STRING);
+}
+
// When a fieldportion at the end of line breaks and needs a following
// fieldportion in the next line, then the "restportion" of the formatinfo
// has to be set. Normally this happens during the formatting of the first
@@ -2453,7 +2518,7 @@ SwLinePortion* SwTextFormatter::MakeRestPortion( const SwLineLayout* pLine,
return pRest;
nPosition = nMultiPos + pHelpMulti->GetLen();
- std::unique_ptr<SwMultiCreator> pCreate = GetInfo().GetMultiCreator( nMultiPos, nullptr );
+ std::optional<SwMultiCreator> pCreate = GetInfo().GetMultiCreator( nMultiPos, nullptr );
if ( !pCreate )
{
@@ -2466,19 +2531,19 @@ SwLinePortion* SwTextFormatter::MakeRestPortion( const SwLineLayout* pLine,
if (!pCreate)
return pRest;
- if( pRest || nMultiPos > nPosition || ( pHelpMulti->IsRuby() &&
- static_cast<const SwRubyPortion*>(pHelpMulti)->GetRubyOffset() < TextFrameIndex(COMPLETE_STRING)))
+ if( pRest || nMultiPos > nPosition || IsIncompleteRuby(*pHelpMulti))
{
SwMultiPortion* pTmp;
if( pHelpMulti->IsDouble() )
pTmp = new SwDoubleLinePortion( *pCreate, nMultiPos );
else if( pHelpMulti->IsBidi() )
pTmp = new SwBidiPortion( nMultiPos, pCreate->nLevel );
- else if( pHelpMulti->IsRuby() )
+ else if (IsIncompleteRuby(*pHelpMulti) && pCreate->pAttr)
{
+ TextFrameIndex nRubyOffset = static_cast<const SwRubyPortion*>(pHelpMulti)->GetRubyOffset();
pTmp = new SwRubyPortion( *pCreate, *GetInfo().GetFont(),
m_pFrame->GetDoc().getIDocumentSettingAccess(),
- nMultiPos, static_cast<const SwRubyPortion*>(pHelpMulti)->GetRubyOffset(),
+ nMultiPos, nRubyOffset,
GetInfo() );
}
else if( pHelpMulti->HasRotation() )
@@ -2510,7 +2575,7 @@ SwLinePortion* SwTextFormatter::MakeRestPortion( const SwLineLayout* pLine,
SwTextCursorSave::SwTextCursorSave( SwTextCursor* pCursor,
SwMultiPortion* pMulti,
SwTwips nY,
- sal_uInt16& nX,
+ SwTwips& nX,
TextFrameIndex const nCurrStart,
tools::Long nSpaceAdd )
: pTextCursor(pCursor),
@@ -2544,7 +2609,7 @@ SwTextCursorSave::SwTextCursorSave( SwTextCursor* pCursor,
}
if( nSpaceAdd > 0 && !pMulti->HasTabulator() )
- pCursor->m_pCurr->Width( static_cast<sal_uInt16>(nWidth + nSpaceAdd * sal_Int32(nSpaceCnt) / SPACING_PRECISION_FACTOR) );
+ pCursor->m_pCurr->Width( o3tl::narrowing<sal_uInt16>(nWidth + nSpaceAdd * sal_Int32(nSpaceCnt) / SPACING_PRECISION_FACTOR) );
// For a BidiPortion we have to calculate the offset from the
// end of the portion