editeng/inc/editdoc.hxx             |   38 ++--
 editeng/qa/unit/core-test.cxx       |    4 
 editeng/source/editeng/editdbg.cxx  |   32 ++--
 editeng/source/editeng/editdoc.cxx  |  114 ++++++--------
 editeng/source/editeng/editeng.cxx  |   33 ++--
 editeng/source/editeng/impedit.cxx  |   16 +-
 editeng/source/editeng/impedit.hxx  |    8 -
 editeng/source/editeng/impedit2.cxx |  213 ++++++++++++--------------
 editeng/source/editeng/impedit3.cxx |  288 +++++++++++++++++-------------------
 editeng/source/editeng/impedit4.cxx |   79 ++++-----
 editeng/source/editeng/impedit5.cxx |   10 -
 11 files changed, 396 insertions(+), 439 deletions(-)

New commits:
commit 35f03f26799747894d1534796b6cb227bd4f233b
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Tue May 4 10:56:49 2021 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Tue May 4 13:19:01 2021 +0200

    speed up loading large ODS a little
    
    by flattening the ParaPortionList, which reduces allocations
    
    Change-Id: I7b350335e336f92bb048905c2b2f06378c8a3423
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115061
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/editeng/inc/editdoc.hxx b/editeng/inc/editdoc.hxx
index 9b35cfeaa028..7017516445f6 100644
--- a/editeng/inc/editdoc.hxx
+++ b/editeng/inc/editdoc.hxx
@@ -433,8 +433,10 @@ class TextPortionList
     PortionsType maPortions;
 
 public:
-            TextPortionList();
-            ~TextPortionList();
+   TextPortionList();
+    ~TextPortionList();
+    TextPortionList(TextPortionList&&) = default;
+    TextPortionList& operator=(TextPortionList&&) = default;
 
     void    Reset();
     sal_Int32 FindPortion(
@@ -475,9 +477,7 @@ private:
     bool            bInvalid:1;   // for skillful formatting
 
 public:
-                    EditLine();
-                    EditLine( const EditLine& );
-                    ~EditLine();
+    EditLine();
 
     bool            IsIn( sal_Int32 nIndex ) const
                         { return ( (nIndex >= nStart ) && ( nIndex < nEnd ) ); 
}
@@ -532,7 +532,6 @@ public:
 
     EditLine*       Clone() const;
 
-    EditLine&   operator = ( const EditLine& rLine );
     friend bool operator == ( const EditLine& r1,  const EditLine& r2  );
 };
 
@@ -544,8 +543,10 @@ class EditLineList
     LinesType maLines;
 
 public:
-            EditLineList();
-            ~EditLineList();
+    EditLineList();
+    ~EditLineList();
+    EditLineList(EditLineList&&) = default;
+    EditLineList& operator=(EditLineList&&) = default;
 
     void Reset();
     void DeleteFromLine(sal_Int32 nDelFrom);
@@ -582,11 +583,11 @@ private:
     bool                bVisible            : 1;    // Belongs to the node!
     bool                bForceRepaint       : 1;
 
-                        ParaPortion( const ParaPortion& ) = delete;
-
 public:
-                        ParaPortion( ContentNode* pNode );
-                        ~ParaPortion();
+    ParaPortion( ContentNode* pNode );
+    ~ParaPortion();
+    ParaPortion( ParaPortion&& ) = default;
+    ParaPortion& operator=( ParaPortion&& ) = default;
 
     sal_Int32 GetLineNumber( sal_Int32 nIndex ) const;
 
@@ -633,7 +634,7 @@ public:
 class ParaPortionList
 {
     mutable sal_Int32 nLastCache;
-    std::vector<std::unique_ptr<ParaPortion>> maPortions;
+    std::vector<ParaPortion> maPortions;
 public:
                     ParaPortionList();
                     ~ParaPortionList();
@@ -646,13 +647,12 @@ public:
     ParaPortion* SafeGetObject(sal_Int32 nPos);
 
     sal_Int32 GetPos(const ParaPortion* p) const;
-    ParaPortion* operator[](sal_Int32 nPos);
-    const ParaPortion* operator[](sal_Int32 nPos) const;
+    ParaPortion& operator[](sal_Int32 nPos);
+    const ParaPortion& operator[](sal_Int32 nPos) const;
 
-    std::unique_ptr<ParaPortion> Release(sal_Int32 nPos);
-    void Remove(sal_Int32 nPos);
-    void Insert(sal_Int32 nPos, std::unique_ptr<ParaPortion> p);
-    void Append(std::unique_ptr<ParaPortion> p);
+    ParaPortion Remove(sal_Int32 nPos);
+    ParaPortion& Insert(sal_Int32 nPos, ParaPortion&& p);
+    void Append(ParaPortion&& p);
     sal_Int32 Count() const;
 
 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 57fb3b1cb768..70e86b7119fa 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -191,8 +191,8 @@ void Test::testLineSpacing()
         aEditEngine.QuickSetAttribs(*pSet, aSelection);
 
         // Assert changes
-        ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
-        ContentNode* const pNode = pParaPortion->GetNode();
+        ParaPortion& rParaPortion = aEditEngine.GetParaPortions()[0];
+        ContentNode* const pNode = rParaPortion.GetNode();
         const SvxLineSpacingItem& rLSItem = 
pNode->GetContentAttribs().GetItem(EE_PARA_SBL);
         CPPUNIT_ASSERT_EQUAL(SvxInterLineSpaceRule::Prop, 
rLSItem.GetInterLineSpaceRule());
         CPPUNIT_ASSERT_EQUAL(nSpace, rLSItem.GetPropLineSpace());
diff --git a/editeng/source/editeng/editdbg.cxx 
b/editeng/source/editeng/editdbg.cxx
index c54d01aa2fa4..9a005809d617 100644
--- a/editeng/source/editeng/editdbg.cxx
+++ b/editeng/source/editeng/editdbg.cxx
@@ -335,22 +335,22 @@ void EditEngine::DumpData(const EditEngine* pEE, bool 
bInfoBox)
     fprintf( fp, 
"\n================================================================================"
 );
     for ( sal_Int32 nPortion = 0; nPortion < 
pEE->pImpEditEngine->GetParaPortions().Count(); nPortion++)
     {
-        ParaPortion* pPPortion = 
pEE->pImpEditEngine->GetParaPortions()[nPortion];
+        ParaPortion& rPPortion = 
pEE->pImpEditEngine->GetParaPortions()[nPortion];
         fprintf( fp, "\nParagraph %" SAL_PRIdINT32 ": Length = %" 
SAL_PRIdINT32 ", Invalid = %i\nText = '%s'",
-                 nPortion, pPPortion->GetNode()->Len(), pPPortion->IsInvalid(),
-                 OUStringToOString(pPPortion->GetNode()->GetString(), 
RTL_TEXTENCODING_UTF8).getStr() );
+                 nPortion, rPPortion.GetNode()->Len(), rPPortion.IsInvalid(),
+                 OUStringToOString(rPPortion.GetNode()->GetString(), 
RTL_TEXTENCODING_UTF8).getStr() );
         fprintf( fp, "\nVorlage:" );
-        SfxStyleSheet* pStyle = pPPortion->GetNode()->GetStyleSheet();
+        SfxStyleSheet* pStyle = rPPortion.GetNode()->GetStyleSheet();
         if ( pStyle )
             fprintf( fp, " %s", OUStringToOString( pStyle->GetName(), 
RTL_TEXTENCODING_UTF8).getStr() );
         fprintf( fp, "\nParagraph attribute:" );
-        DbgOutItemSet( fp, 
pPPortion->GetNode()->GetContentAttribs().GetItems(), false, false );
+        DbgOutItemSet( fp, 
rPPortion.GetNode()->GetContentAttribs().GetItems(), false, false );
 
         fprintf( fp, "\nCharacter attribute:" );
         bool bZeroAttr = false;
-        for ( sal_Int32 z = 0; z < 
pPPortion->GetNode()->GetCharAttribs().Count(); ++z )
+        for ( sal_Int32 z = 0; z < 
rPPortion.GetNode()->GetCharAttribs().Count(); ++z )
         {
-            const std::unique_ptr<EditCharAttrib>& rAttr = 
pPPortion->GetNode()->GetCharAttribs().GetAttribs()[z];
+            const std::unique_ptr<EditCharAttrib>& rAttr = 
rPPortion.GetNode()->GetCharAttribs().GetAttribs()[z];
             OStringBuffer aCharAttribs;
             aCharAttribs.append("\nA");
             aCharAttribs.append(nPortion);
@@ -370,20 +370,20 @@ void EditEngine::DumpData(const EditEngine* pEE, bool 
bInfoBox)
         if ( bZeroAttr )
             fprintf( fp, "\nNULL-Attribute!" );
 
-        const sal_Int32 nTextPortions = pPPortion->GetTextPortions().Count();
+        const sal_Int32 nTextPortions = rPPortion.GetTextPortions().Count();
         OStringBuffer aPortionStr("\nText portions: #");
         aPortionStr.append(nTextPortions);
         aPortionStr.append(" \nA");
         aPortionStr.append(nPortion);
         aPortionStr.append(": Paragraph Length = ");
-        aPortionStr.append(pPPortion->GetNode()->Len());
+        aPortionStr.append(rPPortion.GetNode()->Len());
         aPortionStr.append("\nA");
         aPortionStr.append(nPortion);
         aPortionStr.append(": ");
         sal_Int32 n = 0;
         for ( sal_Int32 z = 0; z < nTextPortions; ++z )
         {
-            TextPortion& rPortion = pPPortion->GetTextPortions()[z];
+            TextPortion& rPortion = rPPortion.GetTextPortions()[z];
             aPortionStr.append(' ');
             aPortionStr.append(rPortion.GetLen());
             aPortionStr.append('(');
@@ -399,23 +399,23 @@ void EditEngine::DumpData(const EditEngine* pEE, bool 
bInfoBox)
         aPortionStr.append(nPortion);
         aPortionStr.append(": Total length: ");
         aPortionStr.append(n);
-        if ( pPPortion->GetNode()->Len() != n )
+        if ( rPPortion.GetNode()->Len() != n )
             aPortionStr.append(" => Error !!!");
         fprintf(fp, "%s", aPortionStr.getStr());
 
         fprintf( fp, "\n\nLines:" );
         // First the content ...
-        for ( sal_Int32 nLine = 0; nLine < pPPortion->GetLines().Count(); 
nLine++ )
+        for ( sal_Int32 nLine = 0; nLine < rPPortion.GetLines().Count(); 
nLine++ )
         {
-            EditLine& rLine = pPPortion->GetLines()[nLine];
+            EditLine& rLine = rPPortion.GetLines()[nLine];
 
-            OString 
aLine(OUStringToOString(pPPortion->GetNode()->Copy(rLine.GetStart(), 
rLine.GetEnd() - rLine.GetStart()), RTL_TEXTENCODING_ASCII_US));
+            OString 
aLine(OUStringToOString(rPPortion.GetNode()->Copy(rLine.GetStart(), 
rLine.GetEnd() - rLine.GetStart()), RTL_TEXTENCODING_ASCII_US));
             fprintf( fp, "\nLine %" SAL_PRIdINT32 "\t>%s<", nLine, 
aLine.getStr() );
         }
         // then the internal data ...
-        for ( sal_Int32 nLine = 0; nLine < pPPortion->GetLines().Count(); 
nLine++ )
+        for ( sal_Int32 nLine = 0; nLine < rPPortion.GetLines().Count(); 
nLine++ )
         {
-            EditLine& rLine = pPPortion->GetLines()[nLine];
+            EditLine& rLine = rPPortion.GetLines()[nLine];
             fprintf( fp, "\nLine %" SAL_PRIdINT32 ":\tStart: %" SAL_PRIdINT32 
",\tEnd: %" SAL_PRIdINT32, nLine, rLine.GetStart(), rLine.GetEnd() );
             fprintf( fp, "\t\tPortions: %" SAL_PRIdINT32 " - %" SAL_PRIdINT32 
".\tHight: %i, Ascent=%i", rLine.GetStartPortion(), rLine.GetEndPortion(), 
rLine.GetHeight(), rLine.GetMaxAscent() );
         }
diff --git a/editeng/source/editeng/editdoc.cxx 
b/editeng/source/editeng/editdoc.cxx
index d429cbe1e762..84ef4feae971 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -369,7 +369,6 @@ TextPortionList::TextPortionList()
 
 TextPortionList::~TextPortionList()
 {
-    Reset();
 }
 
 void TextPortionList::Reset()
@@ -685,52 +684,65 @@ ParaPortionList::~ParaPortionList()
 
 sal_Int32 ParaPortionList::GetPos(const ParaPortion* p) const
 {
-    return FastGetPos(maPortions, p, nLastCache);
-}
+    sal_Int32 nArrayLen = maPortions.size();
 
-ParaPortion* ParaPortionList::operator [](sal_Int32 nPos)
-{
-    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
+    // Through certain filter code-paths we do a lot of appends, which in
+    // turn call GetPos - creating some N^2 nightmares. If we have a
+    // non-trivially large list, do a few checks from the end first.
+    if (nLastCache > 16 && nArrayLen > 16)
+    {
+        sal_Int32 nEnd;
+        if (nLastCache > nArrayLen - 2)
+            nEnd = nArrayLen;
+        else
+            nEnd = nLastCache + 2;
+
+        for (sal_Int32 nIdx = nLastCache - 2; nIdx < nEnd; ++nIdx)
+        {
+            if (&maPortions.at(nIdx) == p)
+            {
+                nLastCache = nIdx;
+                return nIdx;
+            }
+        }
+    }
+    // The world's lamest linear search from svarray...
+    for (sal_Int32 nIdx = 0; nIdx < nArrayLen; ++nIdx)
+        if (&maPortions.at(nIdx) == p)
+        {
+            nLastCache = nIdx;
+            return nLastCache;
+        }
+
+    // XXX "not found" condition for sal_Int32 indexes
+    return EE_PARA_NOT_FOUND;
 }
 
-const ParaPortion* ParaPortionList::operator [](sal_Int32 nPos) const
+ParaPortion& ParaPortionList::operator [](sal_Int32 nPos)
 {
-    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
+    return maPortions[nPos];
 }
 
-std::unique_ptr<ParaPortion> ParaPortionList::Release(sal_Int32 nPos)
+const ParaPortion& ParaPortionList::operator [](sal_Int32 nPos) const
 {
-    if (nPos < 0 || static_cast<sal_Int32>(maPortions.size()) <= nPos)
-    {
-        SAL_WARN( "editeng", "ParaPortionList::Release - out of bounds pos " 
<< nPos);
-        return nullptr;
-    }
-    std::unique_ptr<ParaPortion> p = std::move(maPortions[nPos]);
-    maPortions.erase(maPortions.begin()+nPos);
-    return p;
+    return maPortions[nPos];
 }
 
-void ParaPortionList::Remove(sal_Int32 nPos)
+ParaPortion ParaPortionList::Remove(sal_Int32 nPos)
 {
-    if (nPos < 0 || static_cast<sal_Int32>(maPortions.size()) <= nPos)
-    {
-        SAL_WARN( "editeng", "ParaPortionList::Remove - out of bounds pos " << 
nPos);
-        return;
-    }
-    maPortions.erase(maPortions.begin()+nPos);
+    auto it = maPortions.begin()+nPos;
+    ParaPortion val = std::move(*it);
+    maPortions.erase(it);
+    return val;
 }
 
-void ParaPortionList::Insert(sal_Int32 nPos, std::unique_ptr<ParaPortion> p)
+ParaPortion& ParaPortionList::Insert(sal_Int32 nPos, ParaPortion&& p)
 {
-    if (nPos < 0 || static_cast<sal_Int32>(maPortions.size()) < nPos)
-    {
-        SAL_WARN( "editeng", "ParaPortionList::Insert - out of bounds pos " << 
nPos);
-        return;
-    }
     maPortions.insert(maPortions.begin()+nPos, std::move(p));
+    return maPortions[nPos];
 }
 
-void ParaPortionList::Append(std::unique_ptr<ParaPortion> p)
+void ParaPortionList::Append(ParaPortion&& p)
 {
     maPortions.push_back(std::move(p));
 }
@@ -756,10 +768,9 @@ tools::Long ParaPortionList::GetYOffset(const ParaPortion* 
pPPortion) const
     tools::Long nHeight = 0;
     for (const auto & rPortion : maPortions)
     {
-        const ParaPortion* pTmpPortion = rPortion.get();
-        if ( pTmpPortion == pPPortion )
+        if ( pPPortion == &rPortion )
             return nHeight;
-        nHeight += pTmpPortion->GetHeight();
+        nHeight += rPortion.GetHeight();
     }
     OSL_FAIL( "GetYOffset: Portion not found" );
     return nHeight;
@@ -770,7 +781,7 @@ sal_Int32 ParaPortionList::FindParagraph(tools::Long 
nYOffset) const
     tools::Long nY = 0;
     for (size_t i = 0, n = maPortions.size(); i < n; ++i)
     {
-        nY += maPortions[i]->GetHeight(); // should also be correct even in 
bVisible!
+        nY += maPortions[i].GetHeight(); // should also be correct even in 
bVisible!
         if ( nY > nYOffset )
             return i <= SAL_MAX_INT32 ? static_cast<sal_Int32>(i) : 
SAL_MAX_INT32;
     }
@@ -779,12 +790,12 @@ sal_Int32 ParaPortionList::FindParagraph(tools::Long 
nYOffset) const
 
 const ParaPortion* ParaPortionList::SafeGetObject(sal_Int32 nPos) const
 {
-    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
+    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
&maPortions[nPos] : nullptr;
 }
 
 ParaPortion* ParaPortionList::SafeGetObject(sal_Int32 nPos)
 {
-    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
+    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
&maPortions[nPos] : nullptr;
 }
 
 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
@@ -928,26 +939,6 @@ EditLine::EditLine() :
 {
 }
 
-EditLine::EditLine( const EditLine& r ) :
-    nTxtWidth(0),
-    nStartPosX(0),
-    nStart(r.nStart),
-    nEnd(r.nEnd),
-    nStartPortion(r.nStartPortion),
-    nEndPortion(r.nEndPortion),
-    nHeight(0),
-    nTxtHeight(0),
-    nMaxAscent(0),
-    bHangingPunctuation(r.bHangingPunctuation),
-    bInvalid(true)
-{
-}
-
-EditLine::~EditLine()
-{
-}
-
-
 EditLine* EditLine::Clone() const
 {
     EditLine* pL = new EditLine;
@@ -982,15 +973,6 @@ bool operator == ( const EditLine& r1,  const EditLine& r2 
 )
     return true;
 }
 
-EditLine& EditLine::operator = ( const EditLine& r )
-{
-    nEnd = r.nEnd;
-    nStart = r.nStart;
-    nEndPortion = r.nEndPortion;
-    nStartPortion = r.nStartPortion;
-    return *this;
-}
-
 
 void EditLine::SetHeight( sal_uInt16 nH, sal_uInt16 nTxtH )
 {
diff --git a/editeng/source/editeng/editeng.cxx 
b/editeng/source/editeng/editeng.cxx
index 3f11d39b300b..65eb808eb504 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -681,12 +681,12 @@ bool EditEngine::IsIdleFormatterActive() const
 
 ParaPortion* EditEngine::FindParaPortion(ContentNode const * pNode)
 {
-    return pImpEditEngine->FindParaPortion(pNode);
+    return &pImpEditEngine->FindParaPortion(pNode);
 }
 
 const ParaPortion* EditEngine::FindParaPortion(ContentNode const * pNode) const
 {
-    return pImpEditEngine->FindParaPortion(pNode);
+    return &pImpEditEngine->FindParaPortion(pNode);
 }
 
 const ParaPortion* EditEngine::GetPrevVisPortion(const ParaPortion* 
pCurPortion) const
@@ -1903,7 +1903,7 @@ void EditEngine::SetControlWord( EEControlBits nWord )
         for ( sal_Int32 n = 0; n < nNodes; n++ )
         {
             ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n );
-            const ParaPortion* pPortion = pImpEditEngine->GetParaPortions()[n];
+            const ParaPortion& rPortion = pImpEditEngine->GetParaPortions()[n];
             bool bWrongs = false;
             if (pNode->GetWrongList() != nullptr)
                 bWrongs = !pNode->GetWrongList()->empty();
@@ -1913,10 +1913,10 @@ void EditEngine::SetControlWord( EEControlBits nWord )
                 pImpEditEngine->aInvalidRect.SetLeft( 0 );
                 pImpEditEngine->aInvalidRect.SetRight( 
pImpEditEngine->GetPaperSize().Width() );
                 pImpEditEngine->aInvalidRect.SetTop( nY+1 );
-                pImpEditEngine->aInvalidRect.SetBottom( 
nY+pPortion->GetHeight()-1 );
+                pImpEditEngine->aInvalidRect.SetBottom( nY + 
rPortion.GetHeight()-1 );
                 pImpEditEngine->UpdateViews( pImpEditEngine->pActiveView );
             }
-            nY += pPortion->GetHeight();
+            nY += rPortion.GetHeight();
         }
     }
 }
@@ -2023,12 +2023,11 @@ bool EditEngine::IsTextPos( const Point& rPaperPos, 
sal_uInt16 nBorder )
         EditPaM aPaM = pImpEditEngine->GetPaM( aDocPos, false );
         if ( aPaM.GetNode() )
         {
-            const ParaPortion* pParaPortion = pImpEditEngine->FindParaPortion( 
aPaM.GetNode() );
-            DBG_ASSERT( pParaPortion, "ParaPortion?" );
+            const ParaPortion& rParaPortion = pImpEditEngine->FindParaPortion( 
aPaM.GetNode() );
 
-            sal_Int32 nLine = pParaPortion->GetLineNumber( aPaM.GetIndex() );
-            const EditLine& rLine = pParaPortion->GetLines()[nLine];
-            Range aLineXPosStartEnd = pImpEditEngine->GetLineXPosStartEnd( 
pParaPortion, &rLine );
+            sal_Int32 nLine = rParaPortion.GetLineNumber( aPaM.GetIndex() );
+            const EditLine& rLine = rParaPortion.GetLines()[nLine];
+            Range aLineXPosStartEnd = pImpEditEngine->GetLineXPosStartEnd( 
&rParaPortion, &rLine );
             if ( ( aDocPos.X() >= aLineXPosStartEnd.Min() - nBorder ) &&
                  ( aDocPos.X() <= aLineXPosStartEnd.Max() + nBorder ) )
             {
@@ -2275,8 +2274,8 @@ bool EditEngine::ShouldCreateBigTextObject() const
     sal_Int32 nParas = pImpEditEngine->GetEditDoc().Count();
     for ( sal_Int32 nPara = 0; nPara < nParas; nPara++  )
     {
-        ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions()[nPara];
-        nTextPortions = nTextPortions + 
pParaPortion->GetTextPortions().Count();
+        ParaPortion& rParaPortion = pImpEditEngine->GetParaPortions()[nPara];
+        nTextPortions = nTextPortions + rParaPortion.GetTextPortions().Count();
     }
     return nTextPortions >= pImpEditEngine->GetBigTextObjectStart();
 }
@@ -2433,11 +2432,11 @@ ParagraphInfos EditEngine::GetParagraphInfos( sal_Int32 
nPara )
     aInfos.bValid = pImpEditEngine->IsFormatted();
     if ( pImpEditEngine->IsFormatted() )
     {
-        const ParaPortion* pParaPortion = 
pImpEditEngine->GetParaPortions()[nPara];
-        const EditLine* pLine = (pParaPortion && 
pParaPortion->GetLines().Count()) ?
-                &pParaPortion->GetLines()[0] : nullptr;
-        DBG_ASSERT( pParaPortion && pLine, "GetParagraphInfos - Paragraph out 
of range" );
-        if ( pParaPortion && pLine )
+        const ParaPortion& rParaPortion = 
pImpEditEngine->GetParaPortions()[nPara];
+        const EditLine* pLine = rParaPortion.GetLines().Count() ?
+                &rParaPortion.GetLines()[0] : nullptr;
+        DBG_ASSERT( pLine, "GetParagraphInfos - Paragraph out of range" );
+        if ( pLine )
         {
             aInfos.nFirstLineHeight = pLine->GetHeight();
             aInfos.nFirstLineTextHeight = pLine->GetTxtHeight();
diff --git a/editeng/source/editeng/impedit.cxx 
b/editeng/source/editeng/impedit.cxx
index bdf55d241b68..ef5277bbc049 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -1121,7 +1121,7 @@ tools::Rectangle ImpEditView::GetEditCursor() const
     if (nPara == EE_PARA_NOT_FOUND) // #i94322
         return tools::Rectangle();
 
-    const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
+    const ParaPortion& rParaPortion = pEditEngine->GetParaPortions()[nPara];
 
     GetCursorFlags nShowCursorFlags = nExtraCursorFlags | 
GetCursorFlags::TextOnly;
 
@@ -1134,7 +1134,7 @@ tools::Rectangle ImpEditView::GetEditCursor() const
         nShowCursorFlags |= GetCursorFlags::PreferPortionStart;
     }
 
-    return ImplGetEditCursor(aPaM, nShowCursorFlags, nTextPortionStart, 
pParaPortion);
+    return ImplGetEditCursor(aPaM, nShowCursorFlags, nTextPortionStart, 
&rParaPortion);
 }
 
 void ImpEditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor )
@@ -1168,7 +1168,7 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
     if (nPara == EE_PARA_NOT_FOUND) // #i94322
         return;
 
-    const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
+    const ParaPortion& rParaPortion = pEditEngine->GetParaPortions()[nPara];
 
     GetCursorFlags nShowCursorFlags = nExtraCursorFlags | 
GetCursorFlags::TextOnly;
 
@@ -1181,7 +1181,7 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
         nShowCursorFlags |= GetCursorFlags::PreferPortionStart;
     }
 
-    tools::Rectangle aEditCursor = ImplGetEditCursor(aPaM, nShowCursorFlags, 
nTextPortionStart, pParaPortion);
+    tools::Rectangle aEditCursor = ImplGetEditCursor(aPaM, nShowCursorFlags, 
nTextPortionStart, &rParaPortion);
 
     if ( bGotoCursor  ) // && 
(!pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) )
     {
@@ -1417,8 +1417,8 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
         CursorDirection nCursorDir = CursorDirection::NONE;
         if ( IsInsertMode() && !aEditSelection.HasRange() && ( 
pEditEngine->pImpEditEngine->HasDifferentRTLLevels( aPaM.GetNode() ) ) )
         {
-            sal_uInt16 nTextPortion = 
pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), 
nTextPortionStart, bool(nShowCursorFlags & GetCursorFlags::PreferPortionStart) 
);
-            const TextPortion& rTextPortion = 
pParaPortion->GetTextPortions()[nTextPortion];
+            sal_uInt16 nTextPortion = 
rParaPortion.GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, 
bool(nShowCursorFlags & GetCursorFlags::PreferPortionStart) );
+            const TextPortion& rTextPortion = 
rParaPortion.GetTextPortions()[nTextPortion];
             if (rTextPortion.IsRightToLeft())
                 nCursorDir = CursorDirection::RTL;
             else
@@ -1842,8 +1842,8 @@ bool ImpEditView::IsBulletArea( const Point& rPos, 
sal_Int32* pPara )
         sal_Int32 nPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
         tools::Rectangle aBulletArea = pEditEngine->GetBulletArea( nPara );
         tools::Long nY = pEditEngine->GetDocPosTopLeft( nPara ).Y();
-        const ParaPortion* pParaPortion = 
pEditEngine->GetParaPortions()[nPara];
-        nY += pParaPortion->GetFirstLineOffset();
+        const ParaPortion& rParaPortion = 
pEditEngine->GetParaPortions()[nPara];
+        nY += rParaPortion.GetFirstLineOffset();
         if ( ( aDocPos.Y() > ( nY + aBulletArea.Top() ) ) &&
              ( aDocPos.Y() < ( nY + aBulletArea.Bottom() ) ) &&
              ( aDocPos.X() > ( aBulletArea.Left() ) ) &&
diff --git a/editeng/source/editeng/impedit.hxx 
b/editeng/source/editeng/impedit.hxx
index 39e52c9f7a4b..21de40ed4f54 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -754,8 +754,8 @@ private:
 
     void                CheckIdleFormatter();
 
-    inline const ParaPortion* FindParaPortion( const ContentNode* pNode ) 
const;
-    inline ParaPortion* FindParaPortion( ContentNode const * pNode );
+    inline const ParaPortion& FindParaPortion( const ContentNode* pNode ) 
const;
+    inline ParaPortion& FindParaPortion( ContentNode const * pNode );
 
     css::uno::Reference< css::datatransfer::XTransferable > 
CreateTransferable( const EditSelection& rSelection );
 
@@ -1208,14 +1208,14 @@ inline SfxUndoManager* 
ImpEditEngine::SetUndoManager(SfxUndoManager* pNew)
     return pRetval;
 }
 
-inline const ParaPortion* ImpEditEngine::FindParaPortion( const ContentNode* 
pNode ) const
+inline const ParaPortion& ImpEditEngine::FindParaPortion( const ContentNode* 
pNode ) const
 {
     sal_Int32 nPos = aEditDoc.GetPos( pNode );
     DBG_ASSERT( nPos < GetParaPortions().Count(), "Portionloser Node?" );
     return GetParaPortions()[ nPos ];
 }
 
-inline ParaPortion* ImpEditEngine::FindParaPortion( ContentNode const * pNode )
+inline ParaPortion& ImpEditEngine::FindParaPortion( ContentNode const * pNode )
 {
     sal_Int32 nPos = aEditDoc.GetPos( pNode );
     DBG_ASSERT( nPos < GetParaPortions().Count(), "Portionloser Node?" );
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 2ea63b8d3cf5..207de9d1ca30 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -236,7 +236,7 @@ void ImpEditEngine::InitDoc(bool bKeepParaAttribs)
 
     GetParaPortions().Reset();
 
-    GetParaPortions().Insert(0, std::make_unique<ParaPortion>( aEditDoc[0] ));
+    GetParaPortions().Insert(0, ParaPortion( aEditDoc[0] ));
 
     bFormatted = false;
 
@@ -376,8 +376,8 @@ bool ImpEditEngine::Command( const CommandEvent& rCEvt, 
EditView* pView )
                 }
             }
 
-            ParaPortion* pPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
-            pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
+            ParaPortion& rPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
+            rPortion.MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
 
             bool bWasCursorOverwrite = mpIMEInfos->bWasCursorOverwrite;
 
@@ -442,8 +442,8 @@ bool ImpEditEngine::Command( const CommandEvent& rCEvt, 
EditView* pView )
                     mpIMEInfos->nLen = pData->GetText().getLength();
                 }
 
-                ParaPortion* pPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
-                pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
+                ParaPortion& rPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
+                rPortion.MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
                 FormatAndUpdate( pView );
             }
 
@@ -742,9 +742,8 @@ void ImpEditEngine::ParaAttribsChanged( ContentNode const * 
pNode, bool bIgnoreU
     aEditDoc.SetModified( true );
     bFormatted = false;
 
-    ParaPortion* pPortion = FindParaPortion( pNode );
-    OSL_ENSURE( pPortion, "ParaAttribsChanged: Portion?" );
-    pPortion->MarkSelectionInvalid( 0 );
+    ParaPortion& rPortion = FindParaPortion( pNode );
+    rPortion.MarkSelectionInvalid( 0 );
 
     sal_Int32 nPara = aEditDoc.GetPos( pNode );
     if ( bIgnoreUndoCheck || pEditEngine->IsInUndo() )
@@ -1229,15 +1228,14 @@ EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, 
EditView const * pView )
 {
     assert(pView && "No View - No Cursor Movement!");
 
-    const ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
-    OSL_ENSURE( pPPortion, "No matching portion found: CursorUp ");
-    sal_Int32 nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
-    const EditLine& rLine = pPPortion->GetLines()[nLine];
+    const ParaPortion& rPPortion = FindParaPortion( rPaM.GetNode() );
+    sal_Int32 nLine = rPPortion.GetLineNumber( rPaM.GetIndex() );
+    const EditLine& rLine = rPPortion.GetLines()[nLine];
 
     tools::Long nX;
     if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
     {
-        nX = GetXPos( pPPortion, &rLine, rPaM.GetIndex() );
+        nX = GetXPos( &rPPortion, &rLine, rPaM.GetIndex() );
         pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
     }
     else
@@ -1246,8 +1244,8 @@ EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, 
EditView const * pView )
     EditPaM aNewPaM( rPaM );
     if ( nLine )    // same paragraph
     {
-        const EditLine& rPrevLine = pPPortion->GetLines()[nLine-1];
-        aNewPaM.SetIndex( GetChar( pPPortion, &rPrevLine, nX ) );
+        const EditLine& rPrevLine = rPPortion.GetLines()[nLine-1];
+        aNewPaM.SetIndex( GetChar( &rPPortion, &rPrevLine, nX ) );
         // If a previous automatically wrapped line, and one has to be exactly
         // at the end of this line, the cursor lands on the current line at the
         // beginning. See Problem: Last character of an automatically wrapped
@@ -1257,7 +1255,7 @@ EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, 
EditView const * pView )
     }
     else    // previous paragraph
     {
-        const ParaPortion* pPrevPortion = GetPrevVisPortion( pPPortion );
+        const ParaPortion* pPrevPortion = GetPrevVisPortion( &rPPortion );
         if ( pPrevPortion )
         {
             const EditLine& rLine2 = 
pPrevPortion->GetLines()[pPrevPortion->GetLines().Count()-1];
@@ -1273,32 +1271,31 @@ EditPaM ImpEditEngine::CursorDown( const EditPaM& rPaM, 
EditView const * pView )
 {
     OSL_ENSURE( pView, "No View - No Cursor Movement!" );
 
-    const ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
-    OSL_ENSURE( pPPortion, "No matching portion found: CursorDown" );
-    sal_Int32 nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
+    const ParaPortion& rPPortion = FindParaPortion( rPaM.GetNode() );
+    sal_Int32 nLine = rPPortion.GetLineNumber( rPaM.GetIndex() );
 
     tools::Long nX;
     if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
     {
-        const EditLine& rLine = pPPortion->GetLines()[nLine];
-        nX = GetXPos( pPPortion, &rLine, rPaM.GetIndex() );
+        const EditLine& rLine = rPPortion.GetLines()[nLine];
+        nX = GetXPos( &rPPortion, &rLine, rPaM.GetIndex() );
         pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
     }
     else
         nX = pView->pImpEditView->nTravelXPos;
 
     EditPaM aNewPaM( rPaM );
-    if ( nLine < pPPortion->GetLines().Count()-1 )
+    if ( nLine < rPPortion.GetLines().Count()-1 )
     {
-        const EditLine& rNextLine = pPPortion->GetLines()[nLine+1];
-        aNewPaM.SetIndex( GetChar( pPPortion, &rNextLine, nX ) );
+        const EditLine& rNextLine = rPPortion.GetLines()[nLine+1];
+        aNewPaM.SetIndex( GetChar( &rPPortion, &rNextLine, nX ) );
         // Special treatment, see CursorUp ...
-        if ( ( aNewPaM.GetIndex() == rNextLine.GetEnd() ) && ( 
aNewPaM.GetIndex() > rNextLine.GetStart() ) && ( aNewPaM.GetIndex() < 
pPPortion->GetNode()->Len() ) )
+        if ( ( aNewPaM.GetIndex() == rNextLine.GetEnd() ) && ( 
aNewPaM.GetIndex() > rNextLine.GetStart() ) && ( aNewPaM.GetIndex() < 
rPPortion.GetNode()->Len() ) )
             aNewPaM = CursorLeft( aNewPaM );
     }
     else    // next paragraph
     {
-        const ParaPortion* pNextPortion = GetNextVisPortion( pPPortion );
+        const ParaPortion* pNextPortion = GetNextVisPortion( &rPPortion );
         if ( pNextPortion )
         {
             const EditLine& rLine = pNextPortion->GetLines()[0];
@@ -1316,10 +1313,9 @@ EditPaM ImpEditEngine::CursorDown( const EditPaM& rPaM, 
EditView const * pView )
 
 EditPaM ImpEditEngine::CursorStartOfLine( const EditPaM& rPaM )
 {
-    const ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
-    OSL_ENSURE( pCurPortion, "No Portion for the PaM ?" );
-    sal_Int32 nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
-    const EditLine& rLine = pCurPortion->GetLines()[nLine];
+    const ParaPortion& rCurPortion = FindParaPortion( rPaM.GetNode() );
+    sal_Int32 nLine = rCurPortion.GetLineNumber( rPaM.GetIndex() );
+    const EditLine& rLine = rCurPortion.GetLines()[nLine];
 
     EditPaM aNewPaM( rPaM );
     aNewPaM.SetIndex( rLine.GetStart() );
@@ -1328,10 +1324,9 @@ EditPaM ImpEditEngine::CursorStartOfLine( const EditPaM& 
rPaM )
 
 EditPaM ImpEditEngine::CursorEndOfLine( const EditPaM& rPaM )
 {
-    const ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
-    OSL_ENSURE( pCurPortion, "No Portion for the PaM ?" );
-    sal_Int32 nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
-    const EditLine& rLine = pCurPortion->GetLines()[nLine];
+    const ParaPortion& rCurPortion = FindParaPortion( rPaM.GetNode() );
+    sal_Int32 nLine = rCurPortion.GetLineNumber( rPaM.GetIndex() );
+    const EditLine& rLine = rCurPortion.GetLines()[nLine];
 
     EditPaM aNewPaM( rPaM );
     aNewPaM.SetIndex( rLine.GetEnd() );
@@ -2125,25 +2120,25 @@ EditSelection ImpEditEngine::ImpMoveParagraphs( Range 
aOldPositions, sal_Int32 n
 
     if ( nNewPos == 0 ) // Move to Start
     {
-        pRecalc1 = GetParaPortions()[0];
-        pRecalc2 = GetParaPortions()[aOldPositions.Min()];
+        pRecalc1 = &GetParaPortions()[0];
+        pRecalc2 = &GetParaPortions()[aOldPositions.Min()];
 
     }
     else if ( nNewPos == nParaCount )
     {
-        pRecalc1 = GetParaPortions()[nParaCount-1];
-        pRecalc2 = GetParaPortions()[aOldPositions.Max()];
+        pRecalc1 = &GetParaPortions()[nParaCount-1];
+        pRecalc2 = &GetParaPortions()[aOldPositions.Max()];
     }
 
     if ( aOldPositions.Min() == 0 ) // Move from Start
     {
-        pRecalc3 = GetParaPortions()[0];
-        pRecalc4 = GetParaPortions()[aOldPositions.Max()+1];
+        pRecalc3 = &GetParaPortions()[0];
+        pRecalc4 = &GetParaPortions()[aOldPositions.Max()+1];
     }
     else if ( aOldPositions.Max() == (nParaCount-1) )
     {
-        pRecalc3 = GetParaPortions()[aOldPositions.Max()];
-        pRecalc4 = GetParaPortions()[aOldPositions.Min()-1];
+        pRecalc3 = &GetParaPortions()[aOldPositions.Max()];
+        pRecalc4 = &GetParaPortions()[aOldPositions.Min()-1];
     }
 
     MoveParagraphsInfo aMoveParagraphsInfo( aOldPositions.Min(), 
aOldPositions.Max(), nNewPos );
@@ -2159,9 +2154,9 @@ EditSelection ImpEditEngine::ImpMoveParagraphs( Range 
aOldPositions, sal_Int32 n
     for (tools::Long i = aOldPositions.Min(); i <= aOldPositions.Max(); i++  )
     {
         // always aOldPositions.Min(), since Remove().
-        std::unique_ptr<ParaPortion> pTmpPortion = 
GetParaPortions().Release(aOldPositions.Min());
+        ParaPortion aTmpPortion = 
GetParaPortions().Remove(aOldPositions.Min());
         aEditDoc.Release( aOldPositions.Min() );
-        aTmpPortionList.Append(std::move(pTmpPortion));
+        aTmpPortionList.Append(std::move(aTmpPortion));
     }
 
     sal_Int32 nRealNewPos = pDestPortion ? GetParaPortions().GetPos( 
pDestPortion ) : GetParaPortions().Count();
@@ -2170,17 +2165,17 @@ EditSelection ImpEditEngine::ImpMoveParagraphs( Range 
aOldPositions, sal_Int32 n
     sal_Int32 i = 0;
     while( aTmpPortionList.Count() > 0 )
     {
-        std::unique_ptr<ParaPortion> pTmpPortion = aTmpPortionList.Release(0);
+        ParaPortion aTmpPortion = aTmpPortionList.Remove(0);
         if ( i == 0 )
-            aSelection.Min().SetNode( pTmpPortion->GetNode() );
+            aSelection.Min().SetNode( aTmpPortion.GetNode() );
 
-        aSelection.Max().SetNode( pTmpPortion->GetNode() );
-        aSelection.Max().SetIndex( pTmpPortion->GetNode()->Len() );
+        aSelection.Max().SetNode( aTmpPortion.GetNode() );
+        aSelection.Max().SetIndex( aTmpPortion.GetNode()->Len() );
 
-        ContentNode* pN = pTmpPortion->GetNode();
+        ContentNode* pN = aTmpPortion.GetNode();
         aEditDoc.Insert(nRealNewPos+i, pN);
 
-        GetParaPortions().Insert(nRealNewPos+i, std::move(pTmpPortion));
+        GetParaPortions().Insert(nRealNewPos+i, std::move(aTmpPortion));
         ++i;
     }
 
@@ -2254,8 +2249,7 @@ EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* 
pLeft, ContentNode* pR
     ParaAttribsChanged( pLeft, true );
 
     // First search for Portions since pRight is gone after ConnectParagraphs.
-    ParaPortion* pLeftPortion = FindParaPortion( pLeft );
-    OSL_ENSURE( pLeftPortion, "Blind Portion in ImpConnectParagraphs(1)" );
+    ParaPortion& rLeftPortion = FindParaPortion( pLeft );
 
     if ( GetStatus().DoOnlineSpelling() )
     {
@@ -2282,7 +2276,7 @@ EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* 
pLeft, ContentNode* pR
     EditPaM aPaM = aEditDoc.ConnectParagraphs( pLeft, pRight );
     GetParaPortions().Remove( nParagraphTobeDeleted );
 
-    pLeftPortion->MarkSelectionInvalid( aPaM.GetIndex() );
+    rLeftPortion.MarkSelectionInvalid( aPaM.GetIndex() );
 
     // the right node is deleted by EditDoc:ConnectParagraphs().
     if ( GetTextRanger() )
@@ -2292,9 +2286,9 @@ EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* 
pLeft, ContentNode* pR
         // the change of the total text height too late...
         for ( sal_Int32 n = nParagraphTobeDeleted; n < 
GetParaPortions().Count(); n++ )
         {
-            ParaPortion* pPP = GetParaPortions()[n];
-            pPP->MarkSelectionInvalid( 0 );
-            pPP->GetLines().Reset();
+            ParaPortion& rPP = GetParaPortions()[n];
+            rPP.MarkSelectionInvalid( 0 );
+            rPP.GetLines().Reset();
         }
     }
 
@@ -2429,26 +2423,23 @@ EditPaM ImpEditEngine::ImpDeleteSelection(const 
EditSelection& rCurSel)
     {
         // The Rest of the StartNodes...
         ImpRemoveChars( aStartPaM, aStartPaM.GetNode()->Len() - 
aStartPaM.GetIndex() );
-        ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
-        OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(3)" );
-        pPortion->MarkSelectionInvalid( aStartPaM.GetIndex() );
+        ParaPortion& rPortion = FindParaPortion( aStartPaM.GetNode() );
+        rPortion.MarkSelectionInvalid( aStartPaM.GetIndex() );
 
         // The beginning of the EndNodes...
         const sal_Int32 nChars = aEndPaM.GetIndex();
         aEndPaM.SetIndex( 0 );
         ImpRemoveChars( aEndPaM, nChars );
-        pPortion = FindParaPortion( aEndPaM.GetNode() );
-        OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(4)" );
-        pPortion->MarkSelectionInvalid( 0 );
+        ParaPortion& rPortion2 = FindParaPortion( aEndPaM.GetNode() );
+        rPortion2.MarkSelectionInvalid( 0 );
         // Join together...
         aStartPaM = ImpConnectParagraphs( aStartPaM.GetNode(), 
aEndPaM.GetNode() );
     }
     else
     {
         ImpRemoveChars( aStartPaM, aEndPaM.GetIndex() - aStartPaM.GetIndex() );
-        ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
-        OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(5)" );
-        pPortion->MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - 
aEndPaM.GetIndex() );
+        ParaPortion& rPortion = FindParaPortion( aStartPaM.GetNode() );
+        rPortion.MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - 
aEndPaM.GetIndex() );
     }
 
     UpdateSelections();
@@ -2653,9 +2644,8 @@ EditPaM ImpEditEngine::InsertTextUserInput( const 
EditSelection& rCurSel,
         }
 
         aEditDoc.InsertText( aPaM, OUString(c) );
-        ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
-        OSL_ENSURE( pPortion, "Blind Portion in InsertText" );
-        pPortion->MarkInvalid( aPaM.GetIndex(), 1 );
+        ParaPortion& rPortion = FindParaPortion( aPaM.GetNode() );
+        rPortion.MarkInvalid( aPaM.GetIndex(), 1 );
         aPaM.SetIndex( aPaM.GetIndex()+1 );   // does not do EditDoc-Method 
anymore
     }
 
@@ -2738,8 +2728,7 @@ EditPaM ImpEditEngine::ImpInsertText(const EditSelection& 
aCurSel, const OUStrin
                     nStart2 = nEnd2+1;
                 }
             }
-            ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
-            OSL_ENSURE( pPortion, "Blind Portion in InsertText" );
+            ParaPortion& rPortion = FindParaPortion( aPaM.GetNode() );
 
             if ( GetStatus().DoOnlineSpelling() )
             {
@@ -2748,10 +2737,10 @@ EditPaM ImpEditEngine::ImpInsertText(const 
EditSelection& aCurSel, const OUStrin
                 if (pWrongs && !pWrongs->empty())
                     pWrongs->ClearWrongs( aCurWord.Min().GetIndex(), 
aPaM.GetIndex(), aPaM.GetNode() );
                 // ... and mark both words as 'to be checked again'
-                pPortion->MarkInvalid( aCurWord.Min().GetIndex(), 
aLine.getLength() );
+                rPortion.MarkInvalid( aCurWord.Min().GetIndex(), 
aLine.getLength() );
             }
             else
-                pPortion->MarkInvalid( aCurPaM.GetIndex(), aLine.getLength() );
+                rPortion.MarkInvalid( aCurPaM.GetIndex(), aLine.getLength() );
         }
         if ( nEnd < aText.getLength() )
             aPaM = ImpInsertParaBreak( aPaM );
@@ -2803,9 +2792,8 @@ EditPaM ImpEditEngine::ImpInsertFeature(const 
EditSelection& rCurSel, const SfxP
     aPaM = aEditDoc.InsertFeature( aPaM, rItem );
     UpdateFields();
 
-    ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
-    OSL_ENSURE( pPortion, "Blind Portion in InsertFeature" );
-    pPortion->MarkInvalid( aPaM.GetIndex()-1, 1 );
+    ParaPortion& rPortion = FindParaPortion( aPaM.GetNode() );
+    rPortion.MarkInvalid( aPaM.GetIndex()-1, 1 );
 
     TextModified();
 
@@ -2867,16 +2855,14 @@ EditPaM ImpEditEngine::ImpInsertParaBreak( EditPaM& 
rPaM, bool bKeepEndingAttrib
         pRWrongs->SetInvalidRange(0, 1);  // Only test the first word
     }
 
-    ParaPortion* pPortion = FindParaPortion( rPaM.GetNode() );
-    OSL_ENSURE( pPortion, "Blind Portion in ImpInsertParaBreak" );
-    pPortion->MarkInvalid( rPaM.GetIndex(), 0 );
+    ParaPortion& rPortion = FindParaPortion( rPaM.GetNode() );
+    rPortion.MarkInvalid( rPaM.GetIndex(), 0 );
 
     // Optimization: Do not place unnecessarily many getPos to Listen!
     // Here, as in undo, but also in all other methods.
-    sal_Int32 nPos = GetParaPortions().GetPos( pPortion );
-    ParaPortion* pNewPortion = new ParaPortion( aPaM.GetNode() );
-    GetParaPortions().Insert(nPos+1, 
std::unique_ptr<ParaPortion>(pNewPortion));
-    ParaAttribsChanged( pNewPortion->GetNode() );
+    sal_Int32 nPos = GetParaPortions().GetPos( &rPortion );
+    ParaPortion& rNewPortion = GetParaPortions().Insert(nPos+1, 
ParaPortion(aPaM.GetNode()));
+    ParaAttribsChanged( rNewPortion.GetNode() );
     if ( IsCallParaInsertedOrDeleted() )
         GetEditEnginePtr()->ParagraphInserted( nPos+1 );
 
@@ -2907,7 +2893,7 @@ EditPaM ImpEditEngine::ImpFastInsertParagraph( sal_Int32 
nPara )
 
     aEditDoc.Insert(nPara, pNode);
 
-    GetParaPortions().Insert(nPara, std::make_unique<ParaPortion>( pNode ));
+    GetParaPortions().Insert(nPara, ParaPortion( pNode ));
     if ( IsCallParaInsertedOrDeleted() )
         GetEditEnginePtr()->ParagraphInserted( nPara );
 
@@ -2999,9 +2985,8 @@ bool ImpEditEngine::UpdateFields()
         if ( bChangesInPara )
         {
             // If possible be more precise when invalidate.
-            ParaPortion* pPortion = GetParaPortions()[nPara];
-            OSL_ENSURE( pPortion, "NULL-Pointer in Doc" );
-            pPortion->MarkSelectionInvalid( 0 );
+            ParaPortion& rPortion = GetParaPortions()[nPara];
+            rPortion.MarkSelectionInvalid( 0 );
         }
     }
     return bChanges;
@@ -3024,16 +3009,16 @@ tools::Rectangle ImpEditEngine::PaMtoEditCursor( 
EditPaM aPaM, GetCursorFlags nF
     tools::Long nY = 0;
     for ( sal_Int32 nPortion = 0; nPortion < GetParaPortions().Count(); 
nPortion++ )
     {
-        ParaPortion* pPortion = GetParaPortions()[nPortion];
-        ContentNode* pNode = pPortion->GetNode();
+        ParaPortion& rPortion = GetParaPortions()[nPortion];
+        ContentNode* pNode = rPortion.GetNode();
         OSL_ENSURE( pNode, "Invalid Node in Portion!" );
         if ( pNode != aPaM.GetNode() )
         {
-            nY += pPortion->GetHeight();
+            nY += rPortion.GetHeight();
         }
         else
         {
-            aEditCursor = GetEditCursor( pPortion, aPaM.GetIndex(), nFlags );
+            aEditCursor = GetEditCursor( &rPortion, aPaM.GetIndex(), nFlags );
             aEditCursor.AdjustTop(nY );
             aEditCursor.AdjustBottom(nY );
             return aEditCursor;
@@ -3052,7 +3037,7 @@ EditPaM ImpEditEngine::GetPaM( Point aDocPos, bool bSmart 
)
     sal_Int32 nPortion;
     for ( nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
     {
-        ParaPortion* pPortion = GetParaPortions()[nPortion];
+        ParaPortion* pPortion = &GetParaPortions()[nPortion];
         const tools::Long nTmpHeight = pPortion->GetHeight();     // should 
also be correct for !bVisible!
         nY += nTmpHeight;
         if ( nY > aDocPos.Y() )
@@ -3074,12 +3059,12 @@ EditPaM ImpEditEngine::GetPaM( Point aDocPos, bool 
bSmart )
     }
     // Then search for the last visible:
     nPortion = GetParaPortions().Count()-1;
-    while ( nPortion && !GetParaPortions()[nPortion]->IsVisible() )
+    while ( nPortion && !GetParaPortions()[nPortion].IsVisible() )
         nPortion--;
 
-    OSL_ENSURE( GetParaPortions()[nPortion]->IsVisible(), "No visible 
paragraph found: GetPaM" );
-    aPaM.SetNode( GetParaPortions()[nPortion]->GetNode() );
-    aPaM.SetIndex( GetParaPortions()[nPortion]->GetNode()->Len() );
+    OSL_ENSURE( GetParaPortions()[nPortion].IsVisible(), "No visible paragraph 
found: GetPaM" );
+    aPaM.SetNode( GetParaPortions()[nPortion].GetNode() );
+    aPaM.SetIndex( GetParaPortions()[nPortion].GetNode()->Len() );
     return aPaM;
 }
 
@@ -3121,20 +3106,19 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 
nPara, bool bIgnoreExtraSpace
 
     // Over all the paragraphs ...
 
-    OSL_ENSURE( 0 <= nPara && nPara < GetParaPortions().Count(), 
"CalcParaWidth: Out of range" );
-    ParaPortion* pPortion = GetParaPortions()[nPara];
-    if ( pPortion && pPortion->IsVisible() )
+    ParaPortion& rPortion = GetParaPortions()[nPara];
+    if ( rPortion.IsVisible() )
     {
-        const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pPortion->GetNode() );
-        sal_Int32 nSpaceBeforeAndMinLabelWidth = 
GetSpaceBeforeAndMinLabelWidth( pPortion->GetNode() );
+        const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( rPortion.GetNode() );
+        sal_Int32 nSpaceBeforeAndMinLabelWidth = 
GetSpaceBeforeAndMinLabelWidth( rPortion.GetNode() );
 
 
         // On the lines of the paragraph ...
 
-        sal_Int32 nLines = pPortion->GetLines().Count();
+        sal_Int32 nLines = rPortion.GetLines().Count();
         for ( sal_Int32 nLine = 0; nLine < nLines; nLine++ )
         {
-            EditLine& rLine = pPortion->GetLines()[nLine];
+            EditLine& rLine = rPortion.GetLines()[nLine];
             // nCurWidth = pLine->GetStartPosX();
             // For Center- or Right- alignment it depends on the paper
             // width, here not preferred. I general, it is best not leave it
@@ -3145,15 +3129,15 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 
nPara, bool bIgnoreExtraSpace
             {
                 tools::Long nFI = GetXValue( rLRItem.GetTextFirstLineOffset() 
);
                 nCurWidth -= nFI;
-                if ( pPortion->GetBulletX() > nCurWidth )
+                if ( rPortion.GetBulletX() > nCurWidth )
                 {
                     nCurWidth += nFI;   // LI?
-                    if ( pPortion->GetBulletX() > nCurWidth )
-                        nCurWidth = pPortion->GetBulletX();
+                    if ( rPortion.GetBulletX() > nCurWidth )
+                        nCurWidth = rPortion.GetBulletX();
                 }
             }
             nCurWidth += GetXValue( rLRItem.GetRight() );
-            nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace );
+            nCurWidth += CalcLineWidth( &rPortion, &rLine, bIgnoreExtraSpace );
             if ( nCurWidth > nMaxWidth )
             {
                 nMaxWidth = nCurWidth;
@@ -3232,11 +3216,11 @@ sal_uInt32 ImpEditEngine::CalcTextHeight( sal_uInt32* 
pHeightNTP )
     sal_uInt32 nPH;
     sal_uInt32 nEmptyHeight = 0;
     for ( sal_Int32 nPortion = 0; nPortion < GetParaPortions().Count(); 
nPortion++ ) {
-        ParaPortion* pPortion = GetParaPortions()[nPortion];
-        nPH = pPortion->GetHeight();
+        ParaPortion& rPortion = GetParaPortions()[nPortion];
+        nPH = rPortion.GetHeight();
         nY += nPH;
         if( pHeightNTP ) {
-            if ( pPortion->IsEmpty() )
+            if ( rPortion.IsEmpty() )
                 nEmptyHeight += nPH;
             else
                 nEmptyHeight = 0;
@@ -3363,22 +3347,21 @@ void ImpEditEngine::UpdateSelections()
                 {
                     nPara = GetParaPortions().Count()-1;
                 }
-                assert(GetParaPortions()[nPara] && "Empty Document in 
UpdateSelections ?");
                 // Do not end up from a hidden paragraph:
                 sal_Int32 nCurPara = nPara;
                 sal_Int32 nLastPara = GetParaPortions().Count()-1;
-                while ( nPara <= nLastPara && 
!GetParaPortions()[nPara]->IsVisible() )
+                while ( nPara <= nLastPara && 
!GetParaPortions()[nPara].IsVisible() )
                     nPara++;
                 if ( nPara > nLastPara ) // then also backwards ...
                 {
                     nPara = nCurPara;
-                    while ( nPara && !GetParaPortions()[nPara]->IsVisible() )
+                    while ( nPara && !GetParaPortions()[nPara].IsVisible() )
                         nPara--;
                 }
-                OSL_ENSURE( GetParaPortions()[nPara]->IsVisible(), "No visible 
paragraph found: UpdateSelections" );
+                OSL_ENSURE( GetParaPortions()[nPara].IsVisible(), "No visible 
paragraph found: UpdateSelections" );
 
-                ParaPortion* pParaPortion = GetParaPortions()[nPara];
-                EditSelection aTmpSelection( EditPaM( pParaPortion->GetNode(), 
0 ) );
+                ParaPortion& rParaPortion = GetParaPortions()[nPara];
+                EditSelection aTmpSelection( EditPaM( rParaPortion.GetNode(), 
0 ) );
                 pView->pImpEditView->SetEditSelection( aTmpSelection );
                 bChanged=true;
                 break;  // for loop
diff --git a/editeng/source/editeng/impedit3.cxx 
b/editeng/source/editeng/impedit3.cxx
index 195886cdacb7..b5a1fe828cf3 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -354,7 +354,7 @@ bool ImpEditEngine::IsPageOverflow( ) const
 void ImpEditEngine::FormatFullDoc()
 {
     for ( sal_Int32 nPortion = 0; nPortion < GetParaPortions().Count(); 
nPortion++ )
-        GetParaPortions()[nPortion]->MarkSelectionInvalid( 0 );
+        GetParaPortions()[nPortion].MarkSelectionInvalid( 0 );
     FormatDoc();
 }
 
@@ -378,11 +378,11 @@ void ImpEditEngine::FormatDoc()
     aInvalidRect = tools::Rectangle();  // make empty
     for ( sal_Int32 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
     {
-        ParaPortion* pParaPortion = GetParaPortions()[nPara];
-        if ( pParaPortion->MustRepaint() || ( pParaPortion->IsInvalid() && 
pParaPortion->IsVisible() ) )
+        ParaPortion& rParaPortion = GetParaPortions()[nPara];
+        if ( rParaPortion.MustRepaint() || ( rParaPortion.IsInvalid() && 
rParaPortion.IsVisible() ) )
         {
             // No formatting should be necessary for MustRepaint()!
-            if ( ( pParaPortion->MustRepaint() && !pParaPortion->IsInvalid() )
+            if ( ( rParaPortion.MustRepaint() && !rParaPortion.IsInvalid() )
                     || CreateLines( nPara, nY ) )
             {
                 if ( !bGrow && GetTextRanger() )
@@ -390,9 +390,9 @@ void ImpEditEngine::FormatDoc()
                     // For a change in height all below must be reformatted...
                     for ( sal_Int32 n = nPara+1; n < 
GetParaPortions().Count(); n++ )
                     {
-                        ParaPortion* pPP = GetParaPortions()[n];
-                        pPP->MarkSelectionInvalid( 0 );
-                        pPP->GetLines().Reset();
+                        ParaPortion& rPP = GetParaPortions()[n];
+                        rPP.MarkSelectionInvalid( 0 );
+                        rPP.GetLines().Reset();
                     }
                 }
                 bGrow = true;
@@ -407,7 +407,7 @@ void ImpEditEngine::FormatDoc()
                     }
 
                 }
-                pParaPortion->SetMustRepaint( false );
+                rParaPortion.SetMustRepaint( false );
             }
 
             // InvalidRect set only once...
@@ -415,20 +415,20 @@ void ImpEditEngine::FormatDoc()
             {
                 // For Paperwidth 0 (AutoPageSize) it would otherwise be 
Empty()...
                 tools::Long nWidth = std::max( tools::Long(1), ( !IsVertical() 
? aPaperSize.Width() : aPaperSize.Height() ) );
-                Range aInvRange( GetInvalidYOffsets( pParaPortion ) );
+                Range aInvRange( GetInvalidYOffsets( &rParaPortion ) );
                 aInvalidRect = tools::Rectangle( Point( 0, nY+aInvRange.Min() 
),
                     Size( nWidth, aInvRange.Len() ) );
             }
             else
             {
-                aInvalidRect.SetBottom( nY + pParaPortion->GetHeight() );
+                aInvalidRect.SetBottom( nY + rParaPortion.GetHeight() );
             }
         }
         else if ( bGrow )
         {
-            aInvalidRect.SetBottom( nY + pParaPortion->GetHeight() );
+            aInvalidRect.SetBottom( nY + rParaPortion.GetHeight() );
         }
-        nY += pParaPortion->GetHeight();
+        nY += rParaPortion.GetHeight();
     }
 
     // One can also get into the formatting through UpdateMode ON=>OFF=>ON...
@@ -531,11 +531,11 @@ void ImpEditEngine::CheckAutoPageSize()
         {
             // Only paragraphs which are not aligned to the left need to be
             // reformatted, the height can not be changed here anymore.
-            ParaPortion* pParaPortion = GetParaPortions()[nPara];
+            ParaPortion& rParaPortion = GetParaPortions()[nPara];
             SvxAdjust eJustification = GetJustification( nPara );
             if ( eJustification != SvxAdjust::Left )
             {
-                pParaPortion->MarkSelectionInvalid( 0 );
+                rParaPortion.MarkSelectionInvalid( 0 );
                 CreateLines( nPara, 0 );  // 0: For AutoPageSize no TextRange!
             }
         }
@@ -600,28 +600,28 @@ static sal_Int32 ImplCalculateFontIndependentLineSpacing( 
const sal_Int32 nFontH
 
 bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
 {
-    ParaPortion* pParaPortion = GetParaPortions()[nPara];
+    ParaPortion& rParaPortion = GetParaPortions()[nPara];
 
     // sal_Bool: Changes in the height of paragraph Yes / No - 
sal_True/sal_False
-    assert( pParaPortion->GetNode() && "Portion without Node in CreateLines" );
-    DBG_ASSERT( pParaPortion->IsVisible(), "Invisible paragraphs not 
formatted!" );
-    DBG_ASSERT( pParaPortion->IsInvalid(), "CreateLines: Portion not invalid!" 
);
+    assert( rParaPortion.GetNode() && "Portion without Node in CreateLines" );
+    DBG_ASSERT( rParaPortion.IsVisible(), "Invisible paragraphs not 
formatted!" );
+    DBG_ASSERT( rParaPortion.IsInvalid(), "CreateLines: Portion not invalid!" 
);
 
-    bool bProcessingEmptyLine = ( pParaPortion->GetNode()->Len() == 0 );
-    bool bEmptyNodeWithPolygon = ( pParaPortion->GetNode()->Len() == 0 ) && 
GetTextRanger();
+    bool bProcessingEmptyLine = ( rParaPortion.GetNode()->Len() == 0 );
+    bool bEmptyNodeWithPolygon = ( rParaPortion.GetNode()->Len() == 0 ) && 
GetTextRanger();
 
 
     // Fast special treatment for empty paragraphs...
 
-    if ( ( pParaPortion->GetNode()->Len() == 0 ) && !GetTextRanger() )
+    if ( ( rParaPortion.GetNode()->Len() == 0 ) && !GetTextRanger() )
     {
         // fast special treatment...
-        if ( pParaPortion->GetTextPortions().Count() )
-            pParaPortion->GetTextPortions().Reset();
-        if ( pParaPortion->GetLines().Count() )
-            pParaPortion->GetLines().Reset();
-        CreateAndInsertEmptyLine( pParaPortion );
-        return FinishCreateLines( pParaPortion );
+        if ( rParaPortion.GetTextPortions().Count() )
+            rParaPortion.GetTextPortions().Reset();
+        if ( rParaPortion.GetLines().Count() )
+            rParaPortion.GetLines().Reset();
+        CreateAndInsertEmptyLine( &rParaPortion );
+        return FinishCreateLines( &rParaPortion );
     }
 
 
@@ -631,16 +631,16 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     // Always format for 100%:
     bool bMapChanged = ImpCheckRefMapMode();
 
-    if ( pParaPortion->GetLines().Count() == 0 )
+    if ( rParaPortion.GetLines().Count() == 0 )
     {
         EditLine* pL = new EditLine;
-        pParaPortion->GetLines().Append(pL);
+        rParaPortion.GetLines().Append(pL);
     }
 
 
     // Get Paragraph attributes...
 
-    ContentNode* const pNode = pParaPortion->GetNode();
+    ContentNode* const pNode = rParaPortion.GetNode();
 
     bool bRightToLeftPara = IsRightToLeft( nPara );
 
@@ -653,30 +653,30 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     const SvxLineSpacingItem& rLSItem = pNode->GetContentAttribs().GetItem( 
EE_PARA_SBL );
     const bool bScriptSpace = pNode->GetContentAttribs().GetItem( 
EE_PARA_ASIANCJKSPACING ).GetValue();
 
-    const short nInvalidDiff = pParaPortion->GetInvalidDiff();
-    const sal_Int32 nInvalidStart = pParaPortion->GetInvalidPosStart();
+    const short nInvalidDiff = rParaPortion.GetInvalidDiff();
+    const sal_Int32 nInvalidStart = rParaPortion.GetInvalidPosStart();
     const sal_Int32 nInvalidEnd =  nInvalidStart + std::abs( nInvalidDiff );
 
     bool bQuickFormat = false;
     if ( !bEmptyNodeWithPolygon && !HasScriptType( nPara, 
i18n::ScriptType::COMPLEX ) )
     {
-        if ( ( pParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff > 0 ) &&
+        if ( ( rParaPortion.IsSimpleInvalid() ) && ( nInvalidDiff > 0 ) &&
              ( pNode->GetString().indexOf( CH_FEATURE, nInvalidStart ) > 
nInvalidEnd ) )
         {
             bQuickFormat = true;
         }
-        else if ( ( pParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff < 0 ) )
+        else if ( ( rParaPortion.IsSimpleInvalid() ) && ( nInvalidDiff < 0 ) )
         {
             // check if delete over the portion boundaries was done...
             sal_Int32 nStart = nInvalidStart;  // DOUBLE !!!!!!!!!!!!!!!
             sal_Int32 nEnd = nStart - nInvalidDiff;  // negative
             bQuickFormat = true;
             sal_Int32 nPos = 0;
-            sal_Int32 nPortions = pParaPortion->GetTextPortions().Count();
+            sal_Int32 nPortions = rParaPortion.GetTextPortions().Count();
             for ( sal_Int32 nTP = 0; nTP < nPortions; nTP++ )
             {
                 // There must be no start / end in the deleted area.
-                const TextPortion& rTP = pParaPortion->GetTextPortions()[ nTP 
];
+                const TextPortion& rTP = rParaPortion.GetTextPortions()[ nTP ];
                 nPos = nPos + rTP.GetLen();
                 if ( ( nPos > nStart ) && ( nPos < nEnd ) )
                 {
@@ -697,17 +697,17 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     if ( bEmptyNodeWithPolygon )
     {
         TextPortion* pDummyPortion = new TextPortion( 0 );
-        pParaPortion->GetTextPortions().Reset();
-        pParaPortion->GetTextPortions().Append(pDummyPortion);
+        rParaPortion.GetTextPortions().Reset();
+        rParaPortion.GetTextPortions().Append(pDummyPortion);
     }
     else if ( bQuickFormat )
     {
         // faster Method:
-        RecalcTextPortion( pParaPortion, nInvalidStart, nInvalidDiff );
+        RecalcTextPortion( &rParaPortion, nInvalidStart, nInvalidDiff );
     }
     else    // nRealInvalidStart can be before InvalidStart, since Portions 
were deleted...
     {
-        CreateTextPortions( pParaPortion, nRealInvalidStart );
+        CreateTextPortions( &rParaPortion, nRealInvalidStart );
     }
 
 
@@ -715,10 +715,10 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     // Flag the line => do not remove it !
 
 
-    sal_Int32 nLine = pParaPortion->GetLines().Count()-1;
+    sal_Int32 nLine = rParaPortion.GetLines().Count()-1;
     for ( sal_Int32 nL = 0; nL <= nLine; nL++ )
     {
-        EditLine& rLine = pParaPortion->GetLines()[nL];
+        EditLine& rLine = rParaPortion.GetLines()[nL];
         if ( rLine.GetEnd() > nRealInvalidStart )  // not nInvalidStart!
         {
             nLine = nL;
@@ -728,20 +728,20 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     }
     // Begin one line before...
     // If it is typed at the end, the line in front cannot change.
-    if ( nLine && ( !pParaPortion->IsSimpleInvalid() || ( nInvalidEnd < 
pNode->Len() ) || ( nInvalidDiff <= 0 ) ) )
+    if ( nLine && ( !rParaPortion.IsSimpleInvalid() || ( nInvalidEnd < 
pNode->Len() ) || ( nInvalidDiff <= 0 ) ) )
         nLine--;
 
-    EditLine* pLine = &pParaPortion->GetLines()[nLine];
+    EditLine* pLine = &rParaPortion.GetLines()[nLine];
 
     static tools::Rectangle aZeroArea { Point(), Point() };
     tools::Rectangle aBulletArea( aZeroArea );
     if ( !nLine )
     {
-        aBulletArea = GetEditEnginePtr()->GetBulletArea( 
GetParaPortions().GetPos( pParaPortion ) );
+        aBulletArea = GetEditEnginePtr()->GetBulletArea( 
GetParaPortions().GetPos( &rParaPortion ) );
         if ( !aBulletArea.IsWidthEmpty() && aBulletArea.Right() > 0 )
-            pParaPortion->SetBulletX( static_cast<sal_Int32>(GetXValue( 
aBulletArea.Right() )) );
+            rParaPortion.SetBulletX( static_cast<sal_Int32>(GetXValue( 
aBulletArea.Right() )) );
         else
-            pParaPortion->SetBulletX( 0 ); // if Bullet is set incorrectly
+            rParaPortion.SetBulletX( 0 ); // if Bullet is set incorrectly
     }
 
 
@@ -779,9 +779,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             tools::Long nFI = GetXValue( rLRItem.GetTextFirstLineOffset() );
             nStartX += nFI;
 
-            if ( !nLine && ( pParaPortion->GetBulletX() > nStartX ) )
+            if ( !nLine && ( rParaPortion.GetBulletX() > nStartX ) )
             {
-                    nStartX = pParaPortion->GetBulletX();
+                    nStartX = rParaPortion.GetBulletX();
             }
         }
 
@@ -824,7 +824,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         {
             GetTextRanger()->SetVertical( IsVertical() );
 
-            tools::Long nTextY = nStartPosY + GetEditCursor( pParaPortion, 
pLine->GetStart() ).Top();
+            tools::Long nTextY = nStartPosY + GetEditCursor( &rParaPortion, 
pLine->GetStart() ).Top();
             if ( !bSameLineAgain )
             {
                 SeekCursor( pNode, nTmpPos+1, aTmpFont );
@@ -902,7 +902,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         const EditCharAttrib* pNextFeature = 
pNode->GetCharAttribs().FindFeature( pLine->GetStart() );
         while ( ( nTmpWidth < nXWidth ) && !bEOL )
         {
-            const sal_Int32 nTextPortions = 
pParaPortion->GetTextPortions().Count();
+            const sal_Int32 nTextPortions = 
rParaPortion.GetTextPortions().Count();
             assert(nTextPortions > 0);
             bContinueLastPortion = (nTmpPortion >= nTextPortions);
             if (bContinueLastPortion)
@@ -920,17 +920,17 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             }
 
             nPortionStart = nTmpPos;
-            pPortion = &pParaPortion->GetTextPortions()[nTmpPortion];
+            pPortion = &rParaPortion.GetTextPortions()[nTmpPortion];
             if ( !bContinueLastPortion && pPortion->GetKind() == 
PortionKind::HYPHENATOR )
             {
                 // Throw away a Portion, if necessary correct the one before,
                 // if the Hyph portion has swallowed a character...
                 sal_Int32 nTmpLen = pPortion->GetLen();
-                pParaPortion->GetTextPortions().Remove( nTmpPortion );
+                rParaPortion.GetTextPortions().Remove( nTmpPortion );
                 if (nTmpPortion && nTmpLen)
                 {
                     nTmpPortion--;
-                    TextPortion& rPrev = 
pParaPortion->GetTextPortions()[nTmpPortion];
+                    TextPortion& rPrev = 
rParaPortion.GetTextPortions()[nTmpPortion];
                     DBG_ASSERT( rPrev.GetKind() == PortionKind::TEXT, 
"Portion?!" );
                     nTmpWidth -= rPrev.GetSize().Width();
                     nTmpPos = nTmpPos - rPrev.GetLen();
@@ -938,8 +938,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     rPrev.GetSize().setWidth( -1 );
                 }
 
-                assert( nTmpPortion < pParaPortion->GetTextPortions().Count() 
&& "No more Portions left!" );
-                pPortion = &pParaPortion->GetTextPortions()[nTmpPortion];
+                assert( nTmpPortion < rParaPortion.GetTextPortions().Count() 
&& "No more Portions left!" );
+                pPortion = &rParaPortion.GetTextPortions()[nTmpPortion];
             }
 
             if (bContinueLastPortion)
@@ -1153,7 +1153,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 if (bContinueLastPortion)
                 {
                      Size aSize( aTmpFont.QuickGetTextSize( GetRefDevice(),
-                            pParaPortion->GetNode()->GetString(), nTmpPos, 
nPortionLen, pBuf.get() ));
+                            rParaPortion.GetNode()->GetString(), nTmpPos, 
nPortionLen, pBuf.get() ));
                      pPortion->GetSize().AdjustWidth(aSize.Width() );
                      if (pPortion->GetSize().Height() < aSize.Height())
                          pPortion->GetSize().setHeight( aSize.Height() );
@@ -1161,7 +1161,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 else
                 {
                     pPortion->GetSize() = aTmpFont.QuickGetTextSize( 
GetRefDevice(),
-                            pParaPortion->GetNode()->GetString(), nTmpPos, 
nPortionLen, pBuf.get() );
+                            rParaPortion.GetNode()->GetString(), nTmpPos, 
nPortionLen, pBuf.get() );
                 }
 
                 // #i9050# Do Kerning also behind portions...
@@ -1210,7 +1210,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 tools::Long nWidthAfterTab = 0;
                 for ( sal_Int32 n = aCurrentTab.nTabPortion+1; n <= 
nTmpPortion; n++  )
                 {
-                    const TextPortion& rTP = 
pParaPortion->GetTextPortions()[n];
+                    const TextPortion& rTP = rParaPortion.GetTextPortions()[n];
                     nWidthAfterTab += rTP.GetSize().Width();
                 }
                 tools::Long nW = nWidthAfterTab;   // Length before tab 
position
@@ -1223,13 +1223,13 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 }
                 else if ( aCurrentTab.aTabStop.GetAdjustment() == 
SvxTabAdjust::Decimal )
                 {
-                    OUString aText = GetSelected( EditSelection(  EditPaM( 
pParaPortion->GetNode(), nTmpPos ),
-                                                                EditPaM( 
pParaPortion->GetNode(), nTmpPos + nPortionLen ) ) );
+                    OUString aText = GetSelected( EditSelection(  EditPaM( 
rParaPortion.GetNode(), nTmpPos ),
+                                                                EditPaM( 
rParaPortion.GetNode(), nTmpPos + nPortionLen ) ) );
                     sal_Int32 nDecPos = aText.indexOf( 
aCurrentTab.aTabStop.GetDecimal() );
                     if ( nDecPos != -1 )
                     {
-                        nW -= 
pParaPortion->GetTextPortions()[nTmpPortion].GetSize().Width();
-                        nW += aTmpFont.QuickGetTextSize( GetRefDevice(), 
pParaPortion->GetNode()->GetString(), nTmpPos, nDecPos ).Width();
+                        nW -= 
rParaPortion.GetTextPortions()[nTmpPortion].GetSize().Width();
+                        nW += aTmpFont.QuickGetTextSize( GetRefDevice(), 
rParaPortion.GetNode()->GetString(), nTmpPos, nDecPos ).Width();
                         aCurrentTab.bValid = false;
                     }
                 }
@@ -1243,7 +1243,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     nW = nMaxW;
                     aCurrentTab.bValid = false;
                 }
-                TextPortion& rTabPortion = 
pParaPortion->GetTextPortions()[aCurrentTab.nTabPortion];
+                TextPortion& rTabPortion = 
rParaPortion.GetTextPortions()[aCurrentTab.nTabPortion];
                 rTabPortion.GetSize().setWidth( aCurrentTab.nTabPos - 
aCurrentTab.nStartPosX - nW - nStartX );
                 nTmpWidth = aCurrentTab.nStartPosX + 
rTabPortion.GetSize().Width() + nWidthAfterTab;
             }
@@ -1282,8 +1282,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             {
                 DBG_ASSERT( pPortion->GetKind() == PortionKind::TEXT, "Len>1, 
but no TextPortion?" );
                 nTmpWidth -= pPortion->GetSize().Width();
-                sal_Int32 nP = SplitTextPortion( pParaPortion, nTmpPos, pLine 
);
-                nTmpWidth += 
pParaPortion->GetTextPortions()[nP].GetSize().Width();
+                sal_Int32 nP = SplitTextPortion( &rParaPortion, nTmpPos, pLine 
);
+                nTmpWidth += 
rParaPortion.GetTextPortions()[nP].GetSize().Width();
             }
         }
         else if ( nTmpWidth >= nXWidth )
@@ -1323,8 +1323,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             bEOL = true;
             bEOC = true;
             pLine->SetEnd( nPortionEnd );
-            assert( pParaPortion->GetTextPortions().Count() && "No 
TextPortions?" );
-            pLine->SetEndPortion( pParaPortion->GetTextPortions().Count() - 1 
);
+            assert( rParaPortion.GetTextPortions().Count() && "No 
TextPortions?" );
+            pLine->SetEndPortion( rParaPortion.GetTextPortions().Count() - 1 );
         }
 
         if ( aStatus.OneCharPerLine() )
@@ -1356,7 +1356,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     pNode, pPortion, nPortionStart, pDXArray, 10000, true);
             }
             if( pPortion )
-                ImpBreakLine( pParaPortion, pLine, pPortion, nPortionStart,
+                ImpBreakLine( &rParaPortion, pLine, pPortion, nPortionStart,
                                                 nRemainingWidth, bCanHyphenate 
&& bHyphenatePara );
         }
 
@@ -1365,7 +1365,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
 
 
         // CalcTextSize should be replaced by a continuous registering!
-        Size aTextSize = pLine->CalcTextSize( *pParaPortion );
+        Size aTextSize = pLine->CalcTextSize( rParaPortion );
 
         if ( aTextSize.Height() == 0 )
         {
@@ -1387,7 +1387,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         sal_Int32 nTPos = pLine->GetStart();
         for ( sal_Int32 nP = pLine->GetStartPortion(); nP <= 
pLine->GetEndPortion(); nP++ )
         {
-            const TextPortion& rTP = pParaPortion->GetTextPortions()[nP];
+            const TextPortion& rTP = rParaPortion.GetTextPortions()[nP];
             // problem with hard font height attribute, when everything but 
the line break has this attribute
             if ( rTP.GetKind() != PortionKind::LINEBREAK )
             {
@@ -1479,8 +1479,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             tools::Long nRemainingWidth = nMaxLineWidth - aTextSize.Width();
             if ( nRemainingWidth > 0 )
             {
-                ImplExpandCompressedPortions( pLine, pParaPortion, 
nRemainingWidth );
-                aTextSize = pLine->CalcTextSize( *pParaPortion );
+                ImplExpandCompressedPortions( pLine, &rParaPortion, 
nRemainingWidth );
+                aTextSize = pLine->CalcTextSize( rParaPortion );
             }
         }
 
@@ -1489,7 +1489,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             // Width from HangingPunctuation was set to 0 in ImpBreakLine,
             // check for rel width now, maybe create compression...
             tools::Long n = nMaxLineWidth - aTextSize.Width();
-            TextPortion& rTP = 
pParaPortion->GetTextPortions()[pLine->GetEndPortion()];
+            TextPortion& rTP = 
rParaPortion.GetTextPortions()[pLine->GetEndPortion()];
             sal_Int32 nPosInArray = pLine->GetEnd()-1-pLine->GetStart();
             tools::Long nNewValue = ( nPosInArray ? pLine->GetCharPosArray()[ 
nPosInArray-1 ] : 0 ) + n;
             pLine->GetCharPosArray()[ nPosInArray ] = nNewValue;
@@ -1521,7 +1521,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 tools::Long nRemainingSpace = nMaxLineWidth - 
aTextSize.Width();
                 pLine->SetStartPosX( nStartX );
                 if ( nRemainingSpace > 0 && (!bEOC || bDistLastLine) )
-                    ImpAdjustBlocks( pParaPortion, pLine, nRemainingSpace );
+                    ImpAdjustBlocks( &rParaPortion, pLine, nRemainingSpace );
             }
             break;
             default:
@@ -1555,7 +1555,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         }
 
         // for <0 think over !
-        if ( pParaPortion->IsSimpleInvalid() )
+        if ( rParaPortion.IsSimpleInvalid() )
         {
             // Change through simple Text changes...
             // Do not cancel formatting since Portions possibly have to be 
split
@@ -1582,7 +1582,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                         if (bQuickFormat)
                         {
                             bLineBreak = false;
-                            
pParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
+                            rParaPortion.CorrectValuesBehindLastFormattedLine( 
nLine );
                             break;
                         }
                     }
@@ -1595,7 +1595,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     if ( nEnd == ( aSaveLine.GetEnd() + nInvalidDiff ) )
                     {
                         bLineBreak = false;
-                        pParaPortion->CorrectValuesBehindLastFormattedLine( 
nLine );
+                        rParaPortion.CorrectValuesBehindLastFormattedLine( 
nLine );
                         break;
                     }
                 }
@@ -1611,8 +1611,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
 
             // Next line or maybe a new line...
             pLine = nullptr;
-            if ( nLine < pParaPortion->GetLines().Count()-1 )
-                pLine = &pParaPortion->GetLines()[++nLine];
+            if ( nLine < rParaPortion.GetLines().Count()-1 )
+                pLine = &rParaPortion.GetLines()[++nLine];
             if ( pLine && ( nIndex >= pNode->Len() ) )
             {
                 nDelFromLine = nLine;
@@ -1623,16 +1623,16 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 if ( nIndex < pNode->Len() )
                 {
                     pLine = new EditLine;
-                    pParaPortion->GetLines().Insert(++nLine, pLine);
+                    rParaPortion.GetLines().Insert(++nLine, pLine);
                 }
                 else if ( nIndex && bLineBreak && GetTextRanger() )
                 {
                     // normally CreateAndInsertEmptyLine would be called, but 
I want to use
                     // CreateLines, so I need Polygon code only here...
                     TextPortion* pDummyPortion = new TextPortion( 0 );
-                    pParaPortion->GetTextPortions().Append(pDummyPortion);
+                    rParaPortion.GetTextPortions().Append(pDummyPortion);
                     pLine = new EditLine;
-                    pParaPortion->GetLines().Insert(++nLine, pLine);
+                    rParaPortion.GetLines().Insert(++nLine, pLine);
                     bForceOneRun = true;
                     bProcessingEmptyLine = true;
                 }
@@ -1649,16 +1649,16 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     }   // while ( Index < Len )
 
     if ( nDelFromLine >= 0 )
-        pParaPortion->GetLines().DeleteFromLine( nDelFromLine );
+        rParaPortion.GetLines().DeleteFromLine( nDelFromLine );
 
-    DBG_ASSERT( pParaPortion->GetLines().Count(), "No line after CreateLines!" 
);
+    DBG_ASSERT( rParaPortion.GetLines().Count(), "No line after CreateLines!" 
);
 
     if ( bLineBreak )
-        CreateAndInsertEmptyLine( pParaPortion );
+        CreateAndInsertEmptyLine( &rParaPortion );
 
     pBuf.reset();
 
-    bool bHeightChanged = FinishCreateLines( pParaPortion );
+    bool bHeightChanged = FinishCreateLines( &rParaPortion );
 
     if ( bMapChanged )
         GetRefDevice()->Pop();
@@ -2597,9 +2597,9 @@ void ImpEditEngine::SetTextRanger( 
std::unique_ptr<TextRanger> pRanger )
 
     for ( sal_Int32 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
     {
-        ParaPortion* pParaPortion = GetParaPortions()[nPara];
-        pParaPortion->MarkSelectionInvalid( 0 );
-        pParaPortion->GetLines().Reset();
+        ParaPortion& rParaPortion = GetParaPortions()[nPara];
+        rParaPortion.MarkSelectionInvalid( 0 );
+        rParaPortion.GetLines().Reset();
     }
 
     FormatFullDoc();
@@ -2960,7 +2960,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
     tools::Long nFirstVisYPos = - pOutDev->GetMapMode().GetOrigin().Y();
 
     DBG_ASSERT( GetParaPortions().Count(), "No ParaPortion?!" );
-    SvxFont aTmpFont( 
GetParaPortions()[0]->GetNode()->GetCharAttribs().GetDefFont() );
+    SvxFont aTmpFont( 
GetParaPortions()[0].GetNode()->GetCharAttribs().GetDefFont() );
     vcl::PDFExtOutDevData* const pPDFExtOutDevData = dynamic_cast< 
vcl::PDFExtOutDevData* >( pOutDev->GetExtOutDevData() );
 
     // In the case of rotated text is aStartPos considered TopLeft because
@@ -2988,18 +2988,17 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
 
     for ( sal_Int32 n = 0; n < GetParaPortions().Count(); n++ )
     {
-        const ParaPortion* const pPortion = GetParaPortions()[n];
-        assert( pPortion && "NULL-Pointer in TokenList in Paint" );
+        const ParaPortion& rPortion = GetParaPortions()[n];
         // if when typing idle formatting,  asynchronous Paint.
         // Invisible Portions may be invalid.
-        if ( pPortion->IsVisible() && pPortion->IsInvalid() )
+        if ( rPortion.IsVisible() && rPortion.IsInvalid() )
             return;
 
         if ( pPDFExtOutDevData )
             pPDFExtOutDevData->BeginStructureElement( 
vcl::PDFWriter::Paragraph );
 
-        const tools::Long nParaHeight = pPortion->GetHeight();
-        if ( pPortion->IsVisible() && (
+        const tools::Long nParaHeight = rPortion.GetHeight();
+        if ( rPortion.IsVisible() && (
                 ( !IsVertical() && ( ( aStartPos.Y() + nParaHeight ) > 
aClipRect.Top() ) ) ||
                 ( IsVertical() && IsTopToBottom() && ( ( aStartPos.X() - 
nParaHeight ) < aClipRect.Right() ) ) ||
                 ( IsVertical() && !IsTopToBottom() && ( ( aStartPos.X() + 
nParaHeight ) > aClipRect.Left() ) ) ) )
@@ -3009,31 +3008,31 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
 
             // Over the lines of the paragraph...
 
-            const sal_Int32 nLines = pPortion->GetLines().Count();
+            const sal_Int32 nLines = rPortion.GetLines().Count();
             const sal_Int32 nLastLine = nLines-1;
 
             bool bEndOfParagraphWritten(false);
 
             if ( !IsVertical() )
-                aStartPos.AdjustY(pPortion->GetFirstLineOffset() );
+                aStartPos.AdjustY(rPortion.GetFirstLineOffset() );
             else
             {
                 if( IsTopToBottom() )
-                    aStartPos.AdjustX( -(pPortion->GetFirstLineOffset()) );
+                    aStartPos.AdjustX( -(rPortion.GetFirstLineOffset()) );
                 else
-                    aStartPos.AdjustX(pPortion->GetFirstLineOffset() );
+                    aStartPos.AdjustX(rPortion.GetFirstLineOffset() );
             }
 
             const Point aParaStart( aStartPos );
 
-            const SvxLineSpacingItem& rLSItem = 
pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+            const SvxLineSpacingItem& rLSItem = 
rPortion.GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
             sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Fix )
                                 ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
             bool bPaintBullet (false);
 
             for ( sal_Int32 nLine = 0; nLine < nLines; nLine++ )
             {
-                const EditLine* const pLine = &pPortion->GetLines()[nLine];
+                const EditLine* const pLine = &rPortion.GetLines()[nLine];
                 assert( pLine && "NULL-Pointer in the line iterator in 
UpdateViews" );
                 sal_Int32 nIndex = pLine->GetStart();
                 aTmpPos = aStartPos;
@@ -3092,10 +3091,10 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
 
                     for ( sal_Int32 nPortion = pLine->GetStartPortion(); 
nPortion <= pLine->GetEndPortion(); nPortion++ )
                     {
-                        DBG_ASSERT( pPortion->GetTextPortions().Count(), "Line 
without Textportion in Paint!" );
-                        const TextPortion& rTextPortion = 
pPortion->GetTextPortions()[nPortion];
+                        DBG_ASSERT( rPortion.GetTextPortions().Count(), "Line 
without Textportion in Paint!" );
+                        const TextPortion& rTextPortion = 
rPortion.GetTextPortions()[nPortion];
 
-                        const tools::Long nPortionXOffset = GetPortionXOffset( 
pPortion, pLine, nPortion );
+                        const tools::Long nPortionXOffset = GetPortionXOffset( 
&rPortion, pLine, nPortion );
                         if ( !IsVertical() )
                         {
                             aTmpPos.setX( aStartPos.X() + nPortionXOffset );
@@ -3124,7 +3123,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                             case PortionKind::FIELD:
                             case PortionKind::HYPHENATOR:
                             {
-                                SeekCursor( pPortion->GetNode(), nIndex+1, 
aTmpFont, pOutDev );
+                                SeekCursor( rPortion.GetNode(), nIndex+1, 
aTmpFont, pOutDev );
 
                                 bool bDrawFrame = false;
 
@@ -3172,7 +3171,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
 
                                 if ( rTextPortion.GetKind() == 
PortionKind::TEXT )
                                 {
-                                    aText = pPortion->GetNode()->GetString();
+                                    aText = rPortion.GetNode()->GetString();
                                     nTextStart = nIndex;
                                     nTextLen = rTextPortion.GetLen();
                                     pDXArray = pLine->GetCharPosArray().data() 
+ (nIndex - pLine->GetStart());
@@ -3291,7 +3290,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                                 }
                                 else if ( rTextPortion.GetKind() == 
PortionKind::FIELD )
                                 {
-                                    const EditCharAttrib* pAttr = 
pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                    const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
                                     assert( pAttr && "Field not found");
                                     DBG_ASSERT( dynamic_cast< const 
SvxFieldItem* >( pAttr->GetItem() ) !=  nullptr, "Field of the wrong type! ");
                                     aText = static_cast<const 
EditCharAttribField*>(pAttr)->GetFieldValue();
@@ -3403,7 +3402,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
 
                                     if(GetStatus().DoOnlineSpelling() && 
rTextPortion.GetLen())
                                     {
-                                        WrongList* pWrongs = 
pPortion->GetNode()->GetWrongList();
+                                        WrongList* pWrongs = 
rPortion.GetNode()->GetWrongList();
 
                                         if(pWrongs && !pWrongs->empty())
                                         {
@@ -3450,7 +3449,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
 
                                     if(PortionKind::FIELD == 
rTextPortion.GetKind())
                                     {
-                                        const EditCharAttrib* pAttr = 
pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                        const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
                                         const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
 
                                         if(pFieldItem)
@@ -3462,7 +3461,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                                     // support for EOC, EOW, EOS TEXT 
comments. To support that,
                                     // the locale is needed. With the locale 
and a XBreakIterator it is
                                     // possible to re-create the text marking 
info on primitive level
-                                    const lang::Locale 
aLocale(GetLocale(EditPaM(pPortion->GetNode(), nIndex + 1)));
+                                    const lang::Locale 
aLocale(GetLocale(EditPaM(rPortion.GetNode(), nIndex + 1)));
 
                                     // create EOL and EOP bools
                                     const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
@@ -3537,20 +3536,20 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                                             // base line of the original font 
height...
                                             // But only if there was something 
underlined before!
                                             bool bSpecialUnderline = false;
-                                            EditCharAttrib* pPrev = 
pPortion->GetNode()->GetCharAttribs().FindAttrib( EE_CHAR_ESCAPEMENT, nIndex );
+                                            EditCharAttrib* pPrev = 
rPortion.GetNode()->GetCharAttribs().FindAttrib( EE_CHAR_ESCAPEMENT, nIndex );
                                             if ( pPrev )
                                             {
                                                 SvxFont aDummy;
                                                 // Underscore in front?
                                                 if ( pPrev->GetStart() )
                                                 {
-                                                    SeekCursor( 
pPortion->GetNode(), pPrev->GetStart(), aDummy );
+                                                    SeekCursor( 
rPortion.GetNode(), pPrev->GetStart(), aDummy );
                                                     if ( aDummy.GetUnderline() 
!= LINESTYLE_NONE )
                                                         bSpecialUnderline = 
true;
                                                 }
-                                                if ( !bSpecialUnderline && ( 
pPrev->GetEnd() < pPortion->GetNode()->Len() ) )
+                                                if ( !bSpecialUnderline && ( 
pPrev->GetEnd() < rPortion.GetNode()->Len() ) )
                                                 {
-                                                    SeekCursor( 
pPortion->GetNode(), pPrev->GetEnd()+1, aDummy );
+                                                    SeekCursor( 
rPortion.GetNode(), pPrev->GetEnd()+1, aDummy );
                                                     if ( aDummy.GetUnderline() 
!= LINESTYLE_NONE )
                                                         bSpecialUnderline = 
true;
                                                 }
@@ -3610,7 +3609,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                                         {
                                             if ( rTextPortion.GetKind() == 
PortionKind::FIELD )
                                             {
-                                                const EditCharAttrib* pAttr = 
pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                                const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
                                                 const SvxFieldItem* pFieldItem 
= dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
                                                 if( pFieldItem )
                                                 {
@@ -3632,7 +3631,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                                         }
                                     }
 
-                                    const WrongList* const pWrongList = 
pPortion->GetNode()->GetWrongList();
+                                    const WrongList* const pWrongList = 
rPortion.GetNode()->GetWrongList();
                                     if ( GetStatus().DoOnlineSpelling() && 
pWrongList && !pWrongList->empty() && rTextPortion.GetLen() )
                                     {
                                         {//#105750# adjust LinePos for 
superscript or subscript text
@@ -3651,7 +3650,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                                         }
                                         Color aOldColor( 
pOutDev->GetLineColor() );
                                         pOutDev->SetLineColor( 
GetColorConfig().GetColorValue( svtools::SPELL ).nColor );
-                                        lcl_DrawRedLines( pOutDev, 
aTmpFont.GetFontSize().Height(), aRedLineTmpPos, static_cast<size_t>(nIndex), 
static_cast<size_t>(nIndex) + rTextPortion.GetLen(), pDXArray, 
pPortion->GetNode()->GetWrongList(), nOrientation, aOrigin, IsVertical(), 
rTextPortion.IsRightToLeft() );
+                                        lcl_DrawRedLines( pOutDev, 
aTmpFont.GetFontSize().Height(), aRedLineTmpPos, static_cast<size_t>(nIndex), 
static_cast<size_t>(nIndex) + rTextPortion.GetLen(), pDXArray, 
rPortion.GetNode()->GetWrongList(), nOrientation, aOrigin, IsVertical(), 
rTextPortion.IsRightToLeft() );
                                         pOutDev->SetLineColor( aOldColor );
                                     }
                                 }
@@ -3665,7 +3664,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                                     // add a meta file comment if we record to 
a metafile
                                     if( bMetafileValid )
                                     {
-                                        const EditCharAttrib* pAttr = 
pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                        const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
                                         assert( pAttr && "Field not found" );
 
                                         const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
@@ -3687,7 +3686,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
                             {
                                 if ( rTextPortion.GetExtraValue() && ( 
rTextPortion.GetExtraValue() != ' ' ) )
                                 {
-                                    SeekCursor( pPortion->GetNode(), nIndex+1, 
aTmpFont, pOutDev );
+                                    SeekCursor( rPortion.GetNode(), nIndex+1, 
aTmpFont, pOutDev );
                                     aTmpFont.SetTransparent( false );
                                     aTmpFont.SetEscapement( 0 );
                                     aTmpFont.SetPhysFont( pOutDev );
@@ -3782,7 +3781,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, 
tools::Rectangle aClipRect, Po
 
             if ( !aStatus.IsOutliner() )
             {
-                const SvxULSpaceItem& rULItem = 
pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+                const SvxULSpaceItem& rULItem = 
rPortion.GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
                 tools::Long nUL = GetYValue( rULItem.GetLower() );
                 if ( !IsVertical() )
                     aStartPos.AdjustY(nUL );
@@ -3909,7 +3908,7 @@ void ImpEditEngine::InsertContent( ContentNode* pNode, 
sal_Int32 nPos )
 {
     DBG_ASSERT( pNode, "NULL-Pointer in InsertContent! " );
     DBG_ASSERT( IsInUndo(), "InsertContent only for Undo()!" );
-    GetParaPortions().Insert(nPos, std::make_unique<ParaPortion>( pNode ));
+    GetParaPortions().Insert(nPos, ParaPortion( pNode ));
     aEditDoc.Insert(nPos, pNode);
     if ( IsCallParaInsertedOrDeleted() )
         GetEditEnginePtr()->ParagraphInserted( nPos );
@@ -4045,18 +4044,18 @@ void ImpEditEngine::InvalidateFromParagraph( sal_Int32 
nFirstInvPara )
 {
     // The following paragraphs are not invalidated, since ResetHeight()
     // => size change => all the following are re-issued anyway.
-    ParaPortion* pTmpPortion;
     if ( nFirstInvPara != 0 )
     {
-        pTmpPortion = GetParaPortions()[nFirstInvPara-1];
-        pTmpPortion->MarkInvalid( pTmpPortion->GetNode()->Len(), 0 );
+        ParaPortion& rTmpPortion = GetParaPortions()[nFirstInvPara-1];
+        rTmpPortion.MarkInvalid( rTmpPortion.GetNode()->Len(), 0 );
+        rTmpPortion.ResetHeight();
     }
     else
     {
-        pTmpPortion = GetParaPortions()[0];
-        pTmpPortion->MarkSelectionInvalid( 0 );
+        ParaPortion& rTmpPortion = GetParaPortions()[0];
+        rTmpPortion.MarkSelectionInvalid( 0 );
+        rTmpPortion.ResetHeight();
     }
-    pTmpPortion->ResetHeight();
 }
 
 IMPL_LINK_NOARG(ImpEditEngine, StatusTimerHdl, Timer *, void)
@@ -4079,19 +4078,17 @@ void ImpEditEngine::CallStatusHdl()
 
 ContentNode* ImpEditEngine::GetPrevVisNode( ContentNode const * pCurNode )
 {
-    const ParaPortion* pPortion = FindParaPortion( pCurNode );
-    DBG_ASSERT( pPortion, "GetPrevVisibleNode: No matching portion!" );
-    pPortion = GetPrevVisPortion( pPortion );
-    if ( pPortion )
-        return pPortion->GetNode();
+    const ParaPortion& rPortion1 = FindParaPortion( pCurNode );
+    const ParaPortion* pPortion2 = GetPrevVisPortion( &rPortion1 );
+    if ( pPortion2 )
+        return pPortion2->GetNode();
     return nullptr;
 }
 
 ContentNode* ImpEditEngine::GetNextVisNode( ContentNode const * pCurNode )
 {
-    const ParaPortion* pPortion = FindParaPortion( pCurNode );
-    DBG_ASSERT( pPortion, "GetNextVisibleNode: No matching portion!" );
-    pPortion = GetNextVisPortion( pPortion );
+    const ParaPortion& rPortion = FindParaPortion( pCurNode );
+    const ParaPortion* pPortion = GetNextVisPortion( &rPortion );
     if ( pPortion )
         return pPortion->GetNode();
     return nullptr;
@@ -4100,10 +4097,9 @@ ContentNode* ImpEditEngine::GetNextVisNode( ContentNode 
const * pCurNode )
 const ParaPortion* ImpEditEngine::GetPrevVisPortion( const ParaPortion* 
pCurPortion ) const
 {
     sal_Int32 nPara = GetParaPortions().GetPos( pCurPortion );
-    DBG_ASSERT( nPara < GetParaPortions().Count() , "Portion not found: 
GetPrevVisPortion" );
-    const ParaPortion* pPortion = nPara ? GetParaPortions()[--nPara] : nullptr;
+    const ParaPortion* pPortion = nPara ? &GetParaPortions()[--nPara] : 
nullptr;
     while ( pPortion && !pPortion->IsVisible() )
-        pPortion = nPara ? GetParaPortions()[--nPara] : nullptr;
+        pPortion = nPara ? &GetParaPortions()[--nPara] : nullptr;
 
     return pPortion;
 }
@@ -4132,7 +4128,7 @@ tools::Long ImpEditEngine::CalcVertLineSpacing(Point& 
rStartPos) const
             // All paragraphs must have the block justification set.
             return 0;
 
-        const ParaPortion* pPortion = rParaPortions[i];
+        const ParaPortion* pPortion = &rParaPortions[i];
         nTotalOccupiedHeight += pPortion->GetFirstLineOffset();
 
         const SvxLineSpacingItem& rLSItem = 
pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_SBL);
@@ -4215,7 +4211,7 @@ void ImpEditEngine::FormatAndUpdate( EditView* pCurView, 
bool bCalledFromUndo )
         if (bCalledFromUndo)
             // in order to make bullet points that have had their styles 
changed, redraw themselves
             for ( sal_Int32 nPortion = 0; nPortion < 
GetParaPortions().Count(); nPortion++ )
-                GetParaPortions()[nPortion]->MarkInvalid( 0, 0 );
+                GetParaPortions()[nPortion].MarkInvalid( 0, 0 );
         FormatDoc();
         UpdateViews( pCurView );
     }
@@ -4634,8 +4630,8 @@ void 
ImpEditEngine::ImplUpdateOverflowingParaNum(sal_uInt32 nPaperHeight)
     sal_uInt32 nPH;
 
     for ( sal_Int32 nPara = 0; nPara < GetParaPortions().Count(); nPara++ ) {
-        ParaPortion* pPara = GetParaPortions()[nPara];
-        nPH = pPara->GetHeight();
+        ParaPortion& rPara = GetParaPortions()[nPara];
+        nPH = rPara.GetHeight();
         nY += nPH;
         if ( nY > nPaperHeight /*nCurTextHeight*/ ) // found first paragraph 
overflowing
         {
@@ -4654,13 +4650,13 @@ void 
ImpEditEngine::ImplUpdateOverflowingLineNum(sal_uInt32 nPaperHeight,
     sal_uInt32 nY = nHeightBeforeOverflowingPara;
     sal_uInt32 nLH;
 
-    ParaPortion *pPara = GetParaPortions()[nOverflowingPara];
+    ParaPortion& rPara = GetParaPortions()[nOverflowingPara];
 
     // Like UpdateOverflowingParaNum but for each line in the first
     //  overflowing paragraph.
-    for ( sal_Int32 nLine = 0; nLine < pPara->GetLines().Count(); nLine++ ) {

... etc. - the rest is truncated
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to