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  |   24 +--
 editeng/source/editeng/impedit.cxx  |   16 +-
 editeng/source/editeng/impedit.hxx  |    8 -
 editeng/source/editeng/impedit2.cxx |  211 ++++++++++++++-------------
 editeng/source/editeng/impedit3.cxx |  278 ++++++++++++++++++------------------
 editeng/source/editeng/impedit4.cxx |   79 +++++-----
 editeng/source/editeng/impedit5.cxx |   10 -
 11 files changed, 428 insertions(+), 386 deletions(-)

New commits:
commit 383b55a38da0d92b4499f38b4d7f5ff036e0072f
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Mon Apr 18 16:30:55 2022 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Mon Apr 18 18:20:56 2022 +0200

    tdf#148620 Crash in Draw using Format > Lists > Move Down
    
    This reverts
        commit 35f03f26799747894d1534796b6cb227bd4f233b
        speed up loading large ODS a little
    since ImpEditEngine::ImpMoveParagraphs wants to manipulate
    ParaPortion's and also identify them by pointer
    
    Also convert the OSL_ASSERT in this method to an assert
    to catch such problems earlier
    
    Change-Id: Id924d00c9524223db9a96e487b331ce60e3a4fff
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133128
    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 4d4de9497b67..b37fefd40bd0 100644
--- a/editeng/inc/editdoc.hxx
+++ b/editeng/inc/editdoc.hxx
@@ -433,10 +433,8 @@ class TextPortionList
     PortionsType maPortions;
 
 public:
-   TextPortionList();
-    ~TextPortionList();
-    TextPortionList(TextPortionList&&) = default;
-    TextPortionList& operator=(TextPortionList&&) = default;
+            TextPortionList();
+            ~TextPortionList();
 
     void    Reset();
     sal_Int32 FindPortion(
@@ -477,7 +475,9 @@ private:
     bool            bInvalid:1;   // for skillful formatting
 
 public:
-    EditLine();
+                    EditLine();
+                    EditLine( const EditLine& );
+                    ~EditLine();
 
     bool            IsIn( sal_Int32 nIndex ) const
                         { return ( (nIndex >= nStart ) && ( nIndex < nEnd ) ); 
}
@@ -532,6 +532,7 @@ public:
 
     EditLine*       Clone() const;
 
+    EditLine&   operator = ( const EditLine& rLine );
     friend bool operator == ( const EditLine& r1,  const EditLine& r2  );
 };
 
@@ -543,10 +544,8 @@ class EditLineList
     LinesType maLines;
 
 public:
-    EditLineList();
-    ~EditLineList();
-    EditLineList(EditLineList&&) = default;
-    EditLineList& operator=(EditLineList&&) = default;
+            EditLineList();
+            ~EditLineList();
 
     void Reset();
     void DeleteFromLine(sal_Int32 nDelFrom);
@@ -583,11 +582,11 @@ private:
     bool                bVisible            : 1;    // Belongs to the node!
     bool                bForceRepaint       : 1;
 
+                        ParaPortion( const ParaPortion& ) = delete;
+
 public:
-    ParaPortion( ContentNode* pNode );
-    ~ParaPortion();
-    ParaPortion( ParaPortion&& ) = default;
-    ParaPortion& operator=( ParaPortion&& ) = default;
+                        ParaPortion( ContentNode* pNode );
+                        ~ParaPortion();
 
     sal_Int32 GetLineNumber( sal_Int32 nIndex ) const;
 
@@ -634,7 +633,7 @@ public:
 class ParaPortionList
 {
     mutable sal_Int32 nLastCache;
-    std::vector<ParaPortion> maPortions;
+    std::vector<std::unique_ptr<ParaPortion>> maPortions;
 public:
                     ParaPortionList();
                     ~ParaPortionList();
@@ -647,12 +646,13 @@ 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;
 
-    ParaPortion Remove(sal_Int32 nPos);
-    ParaPortion& Insert(sal_Int32 nPos, ParaPortion&& p);
-    void Append(ParaPortion&& p);
+    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);
     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 ffdec6ffb2fe..8965b8c21ba6 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -194,8 +194,8 @@ void Test::testLineSpacing()
         aEditEngine.QuickSetAttribs(*pSet, aSelection);
 
         // Assert changes
-        ParaPortion& rParaPortion = aEditEngine.GetParaPortions()[0];
-        ContentNode* const pNode = rParaPortion.GetNode();
+        ParaPortion* pParaPortion = aEditEngine.GetParaPortions()[0];
+        ContentNode* const pNode = pParaPortion->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 89bff9f34fc6..e3c8f5a2bff8 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& rPPortion = 
pEE->pImpEditEngine->GetParaPortions()[nPortion];
+        ParaPortion* pPPortion = 
pEE->pImpEditEngine->GetParaPortions()[nPortion];
         fprintf( fp, "\nParagraph %" SAL_PRIdINT32 ": Length = %" 
SAL_PRIdINT32 ", Invalid = %i\nText = '%s'",
-                 nPortion, rPPortion.GetNode()->Len(), rPPortion.IsInvalid(),
-                 OUStringToOString(rPPortion.GetNode()->GetString(), 
RTL_TEXTENCODING_UTF8).getStr() );
+                 nPortion, pPPortion->GetNode()->Len(), pPPortion->IsInvalid(),
+                 OUStringToOString(pPPortion->GetNode()->GetString(), 
RTL_TEXTENCODING_UTF8).getStr() );
         fprintf( fp, "\nVorlage:" );
-        SfxStyleSheet* pStyle = rPPortion.GetNode()->GetStyleSheet();
+        SfxStyleSheet* pStyle = pPPortion->GetNode()->GetStyleSheet();
         if ( pStyle )
             fprintf( fp, " %s", OUStringToOString( pStyle->GetName(), 
RTL_TEXTENCODING_UTF8).getStr() );
         fprintf( fp, "\nParagraph attribute:" );
-        DbgOutItemSet( fp, 
rPPortion.GetNode()->GetContentAttribs().GetItems(), false, false );
+        DbgOutItemSet( fp, 
pPPortion->GetNode()->GetContentAttribs().GetItems(), false, false );
 
         fprintf( fp, "\nCharacter attribute:" );
         bool bZeroAttr = false;
-        for ( sal_Int32 z = 0; z < 
rPPortion.GetNode()->GetCharAttribs().Count(); ++z )
+        for ( sal_Int32 z = 0; z < 
pPPortion->GetNode()->GetCharAttribs().Count(); ++z )
         {
-            const std::unique_ptr<EditCharAttrib>& rAttr = 
rPPortion.GetNode()->GetCharAttribs().GetAttribs()[z];
+            const std::unique_ptr<EditCharAttrib>& rAttr = 
pPPortion->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 = rPPortion.GetTextPortions().Count();
+        const sal_Int32 nTextPortions = pPPortion->GetTextPortions().Count();
         OStringBuffer aPortionStr("\nText portions: #");
         aPortionStr.append(nTextPortions);
         aPortionStr.append(" \nA");
         aPortionStr.append(nPortion);
         aPortionStr.append(": Paragraph Length = ");
-        aPortionStr.append(rPPortion.GetNode()->Len());
+        aPortionStr.append(pPPortion->GetNode()->Len());
         aPortionStr.append("\nA");
         aPortionStr.append(nPortion);
         aPortionStr.append(": ");
         sal_Int32 n = 0;
         for ( sal_Int32 z = 0; z < nTextPortions; ++z )
         {
-            TextPortion& rPortion = rPPortion.GetTextPortions()[z];
+            TextPortion& rPortion = pPPortion->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 ( rPPortion.GetNode()->Len() != n )
+        if ( pPPortion->GetNode()->Len() != n )
             aPortionStr.append(" => Error !!!");
         fprintf(fp, "%s", aPortionStr.getStr());
 
         fprintf( fp, "\n\nLines:" );
         // First the content ...
-        for ( sal_Int32 nLine = 0; nLine < rPPortion.GetLines().Count(); 
nLine++ )
+        for ( sal_Int32 nLine = 0; nLine < pPPortion->GetLines().Count(); 
nLine++ )
         {
-            EditLine& rLine = rPPortion.GetLines()[nLine];
+            EditLine& rLine = pPPortion->GetLines()[nLine];
 
-            OString 
aLine(OUStringToOString(rPPortion.GetNode()->Copy(rLine.GetStart(), 
rLine.GetEnd() - rLine.GetStart()), RTL_TEXTENCODING_ASCII_US));
+            OString 
aLine(OUStringToOString(pPPortion->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 < rPPortion.GetLines().Count(); 
nLine++ )
+        for ( sal_Int32 nLine = 0; nLine < pPPortion->GetLines().Count(); 
nLine++ )
         {
-            EditLine& rLine = rPPortion.GetLines()[nLine];
+            EditLine& rLine = pPPortion->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 36a7d5727434..3aa587b04ad1 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -369,6 +369,7 @@ TextPortionList::TextPortionList()
 
 TextPortionList::~TextPortionList()
 {
+    Reset();
 }
 
 void TextPortionList::Reset()
@@ -683,65 +684,52 @@ ParaPortionList::~ParaPortionList()
 
 sal_Int32 ParaPortionList::GetPos(const ParaPortion* p) const
 {
-    sal_Int32 nArrayLen = maPortions.size();
-
-    // 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;
-        }
+    return FastGetPos(maPortions, p, nLastCache);
+}
 
-    // XXX "not found" condition for sal_Int32 indexes
-    return EE_PARA_NOT_FOUND;
+ParaPortion* ParaPortionList::operator [](sal_Int32 nPos)
+{
+    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
 }
 
-ParaPortion& ParaPortionList::operator [](sal_Int32 nPos)
+const ParaPortion* ParaPortionList::operator [](sal_Int32 nPos) const
 {
-    return maPortions[nPos];
+    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
 }
 
-const ParaPortion& ParaPortionList::operator [](sal_Int32 nPos) const
+std::unique_ptr<ParaPortion> ParaPortionList::Release(sal_Int32 nPos)
 {
-    return maPortions[nPos];
+    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;
 }
 
-ParaPortion ParaPortionList::Remove(sal_Int32 nPos)
+void ParaPortionList::Remove(sal_Int32 nPos)
 {
-    auto it = maPortions.begin()+nPos;
-    ParaPortion val = std::move(*it);
-    maPortions.erase(it);
-    return val;
+    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);
 }
 
-ParaPortion& ParaPortionList::Insert(sal_Int32 nPos, ParaPortion&& p)
+void ParaPortionList::Insert(sal_Int32 nPos, std::unique_ptr<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(ParaPortion&& p)
+void ParaPortionList::Append(std::unique_ptr<ParaPortion> p)
 {
     maPortions.push_back(std::move(p));
 }
@@ -767,9 +755,10 @@ tools::Long ParaPortionList::GetYOffset(const ParaPortion* 
pPPortion) const
     tools::Long nHeight = 0;
     for (const auto & rPortion : maPortions)
     {
-        if ( pPPortion == &rPortion )
+        const ParaPortion* pTmpPortion = rPortion.get();
+        if ( pTmpPortion == pPPortion )
             return nHeight;
-        nHeight += rPortion.GetHeight();
+        nHeight += pTmpPortion->GetHeight();
     }
     OSL_FAIL( "GetYOffset: Portion not found" );
     return nHeight;
@@ -780,7 +769,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;
     }
@@ -789,12 +778,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] : nullptr;
+    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
 }
 
 ParaPortion* ParaPortionList::SafeGetObject(sal_Int32 nPos)
 {
-    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
&maPortions[nPos] : nullptr;
+    return 0 <= nPos && nPos < static_cast<sal_Int32>(maPortions.size()) ? 
maPortions[nPos].get() : nullptr;
 }
 
 #if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
@@ -938,6 +927,26 @@ 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;
@@ -972,6 +981,15 @@ 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 237c78264e72..4e87300fd006 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -694,12 +694,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
@@ -1926,7 +1926,7 @@ void EditEngine::SetControlWord( EEControlBits nWord )
         for ( sal_Int32 n = 0; n < nNodes; n++ )
         {
             ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n );
-            const ParaPortion& rPortion = pImpEditEngine->GetParaPortions()[n];
+            const ParaPortion* pPortion = pImpEditEngine->GetParaPortions()[n];
             bool bWrongs = false;
             if (pNode->GetWrongList() != nullptr)
                 bWrongs = !pNode->GetWrongList()->empty();
@@ -1936,10 +1936,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 + 
rPortion.GetHeight()-1 );
+                pImpEditEngine->aInvalidRect.SetBottom( 
nY+pPortion->GetHeight()-1 );
                 pImpEditEngine->UpdateViews( pImpEditEngine->pActiveView );
             }
-            nY += rPortion.GetHeight();
+            nY += pPortion->GetHeight();
         }
     }
 }
@@ -2281,8 +2281,8 @@ bool EditEngine::ShouldCreateBigTextObject() const
     sal_Int32 nParas = pImpEditEngine->GetEditDoc().Count();
     for ( sal_Int32 nPara = 0; nPara < nParas; nPara++  )
     {
-        ParaPortion& rParaPortion = pImpEditEngine->GetParaPortions()[nPara];
-        nTextPortions = nTextPortions + rParaPortion.GetTextPortions().Count();
+        ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions()[nPara];
+        nTextPortions = nTextPortions + 
pParaPortion->GetTextPortions().Count();
     }
     return nTextPortions >= pImpEditEngine->GetBigTextObjectStart();
 }
@@ -2439,11 +2439,11 @@ ParagraphInfos EditEngine::GetParagraphInfos( sal_Int32 
nPara )
     aInfos.bValid = pImpEditEngine->IsFormatted();
     if ( pImpEditEngine->IsFormatted() )
     {
-        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 )
+        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 )
         {
             aInfos.nFirstLineHeight = pLine->GetHeight();
             aInfos.nFirstLineTextHeight = pLine->GetTxtHeight();
diff --git a/editeng/source/editeng/impedit.cxx 
b/editeng/source/editeng/impedit.cxx
index cfd6eb5758dc..d43e3053489f 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -1155,7 +1155,7 @@ tools::Rectangle ImpEditView::GetEditCursor() const
     if (nPara == EE_PARA_NOT_FOUND) // #i94322
         return tools::Rectangle();
 
-    const ParaPortion& rParaPortion = pEditEngine->GetParaPortions()[nPara];
+    const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
 
     GetCursorFlags nShowCursorFlags = nExtraCursorFlags | 
GetCursorFlags::TextOnly;
 
@@ -1168,7 +1168,7 @@ tools::Rectangle ImpEditView::GetEditCursor() const
         nShowCursorFlags |= GetCursorFlags::PreferPortionStart;
     }
 
-    return ImplGetEditCursor(aPaM, nShowCursorFlags, nTextPortionStart, 
&rParaPortion);
+    return ImplGetEditCursor(aPaM, nShowCursorFlags, nTextPortionStart, 
pParaPortion);
 }
 
 void ImpEditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor )
@@ -1202,7 +1202,7 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
     if (nPara == EE_PARA_NOT_FOUND) // #i94322
         return;
 
-    const ParaPortion& rParaPortion = pEditEngine->GetParaPortions()[nPara];
+    const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
 
     GetCursorFlags nShowCursorFlags = nExtraCursorFlags | 
GetCursorFlags::TextOnly;
 
@@ -1215,7 +1215,7 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
         nShowCursorFlags |= GetCursorFlags::PreferPortionStart;
     }
 
-    tools::Rectangle aEditCursor = ImplGetEditCursor(aPaM, nShowCursorFlags, 
nTextPortionStart, &rParaPortion);
+    tools::Rectangle aEditCursor = ImplGetEditCursor(aPaM, nShowCursorFlags, 
nTextPortionStart, pParaPortion);
 
     if ( bGotoCursor  ) // && 
(!pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) )
     {
@@ -1464,8 +1464,8 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
         CursorDirection nCursorDir = CursorDirection::NONE;
         if ( IsInsertMode() && !aEditSelection.HasRange() && ( 
pEditEngine->pImpEditEngine->HasDifferentRTLLevels( aPaM.GetNode() ) ) )
         {
-            sal_uInt16 nTextPortion = 
rParaPortion.GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, 
bool(nShowCursorFlags & GetCursorFlags::PreferPortionStart) );
-            const TextPortion& rTextPortion = 
rParaPortion.GetTextPortions()[nTextPortion];
+            sal_uInt16 nTextPortion = 
pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), 
nTextPortionStart, bool(nShowCursorFlags & GetCursorFlags::PreferPortionStart) 
);
+            const TextPortion& rTextPortion = 
pParaPortion->GetTextPortions()[nTextPortion];
             if (rTextPortion.IsRightToLeft())
                 nCursorDir = CursorDirection::RTL;
             else
@@ -1896,8 +1896,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& rParaPortion = 
pEditEngine->GetParaPortions()[nPara];
-        nY += rParaPortion.GetFirstLineOffset();
+        const ParaPortion* pParaPortion = 
pEditEngine->GetParaPortions()[nPara];
+        nY += pParaPortion->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 e66988d60e0c..4a0134b785ba 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -765,8 +765,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 );
 
@@ -1267,14 +1267,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 94cc2d479b36..2f44eaf5468a 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -239,7 +239,7 @@ void ImpEditEngine::InitDoc(bool bKeepParaAttribs)
 
     GetParaPortions().Reset();
 
-    GetParaPortions().Insert(0, ParaPortion( aEditDoc[0] ));
+    GetParaPortions().Insert(0, std::make_unique<ParaPortion>( aEditDoc[0] ));
 
     bFormatted = false;
 
@@ -379,8 +379,8 @@ bool ImpEditEngine::Command( const CommandEvent& rCEvt, 
EditView* pView )
                 }
             }
 
-            ParaPortion& rPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
-            rPortion.MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
+            ParaPortion* pPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
+            pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
 
             bool bWasCursorOverwrite = mpIMEInfos->bWasCursorOverwrite;
 
@@ -445,8 +445,8 @@ bool ImpEditEngine::Command( const CommandEvent& rCEvt, 
EditView* pView )
                     mpIMEInfos->nLen = pData->GetText().getLength();
                 }
 
-                ParaPortion& rPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
-                rPortion.MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
+                ParaPortion* pPortion = FindParaPortion( 
mpIMEInfos->aPos.GetNode() );
+                pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex() );
                 FormatAndLayout( pView );
             }
 
@@ -772,8 +772,9 @@ void ImpEditEngine::ParaAttribsChanged( ContentNode const * 
pNode, bool bIgnoreU
     aEditDoc.SetModified( true );
     bFormatted = false;
 
-    ParaPortion& rPortion = FindParaPortion( pNode );
-    rPortion.MarkSelectionInvalid( 0 );
+    ParaPortion* pPortion = FindParaPortion( pNode );
+    OSL_ENSURE( pPortion, "ParaAttribsChanged: Portion?" );
+    pPortion->MarkSelectionInvalid( 0 );
 
     sal_Int32 nPara = aEditDoc.GetPos( pNode );
     if ( bIgnoreUndoCheck || pEditEngine->IsInUndo() )
@@ -1258,14 +1259,15 @@ EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, 
EditView const * pView )
 {
     assert(pView && "No View - No Cursor Movement!");
 
-    const ParaPortion& rPPortion = FindParaPortion( rPaM.GetNode() );
-    sal_Int32 nLine = rPPortion.GetLineNumber( rPaM.GetIndex() );
-    const EditLine& rLine = rPPortion.GetLines()[nLine];
+    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];
 
     tools::Long nX;
     if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
     {
-        nX = GetXPos( &rPPortion, &rLine, rPaM.GetIndex() );
+        nX = GetXPos( pPPortion, &rLine, rPaM.GetIndex() );
         pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
     }
     else
@@ -1274,8 +1276,8 @@ EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, 
EditView const * pView )
     EditPaM aNewPaM( rPaM );
     if ( nLine )    // same paragraph
     {
-        const EditLine& rPrevLine = rPPortion.GetLines()[nLine-1];
-        aNewPaM.SetIndex( GetChar( &rPPortion, &rPrevLine, nX ) );
+        const EditLine& rPrevLine = pPPortion->GetLines()[nLine-1];
+        aNewPaM.SetIndex( GetChar( pPPortion, &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
@@ -1285,7 +1287,7 @@ EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, 
EditView const * pView )
     }
     else    // previous paragraph
     {
-        const ParaPortion* pPrevPortion = GetPrevVisPortion( &rPPortion );
+        const ParaPortion* pPrevPortion = GetPrevVisPortion( pPPortion );
         if ( pPrevPortion )
         {
             const EditLine& rLine2 = 
pPrevPortion->GetLines()[pPrevPortion->GetLines().Count()-1];
@@ -1301,31 +1303,32 @@ EditPaM ImpEditEngine::CursorDown( const EditPaM& rPaM, 
EditView const * pView )
 {
     OSL_ENSURE( pView, "No View - No Cursor Movement!" );
 
-    const ParaPortion& rPPortion = FindParaPortion( rPaM.GetNode() );
-    sal_Int32 nLine = rPPortion.GetLineNumber( rPaM.GetIndex() );
+    const ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
+    OSL_ENSURE( pPPortion, "No matching portion found: CursorDown" );
+    sal_Int32 nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
 
     tools::Long nX;
     if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
     {
-        const EditLine& rLine = rPPortion.GetLines()[nLine];
-        nX = GetXPos( &rPPortion, &rLine, rPaM.GetIndex() );
+        const EditLine& rLine = pPPortion->GetLines()[nLine];
+        nX = GetXPos( pPPortion, &rLine, rPaM.GetIndex() );
         pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
     }
     else
         nX = pView->pImpEditView->nTravelXPos;
 
     EditPaM aNewPaM( rPaM );
-    if ( nLine < rPPortion.GetLines().Count()-1 )
+    if ( nLine < pPPortion->GetLines().Count()-1 )
     {
-        const EditLine& rNextLine = rPPortion.GetLines()[nLine+1];
-        aNewPaM.SetIndex( GetChar( &rPPortion, &rNextLine, nX ) );
+        const EditLine& rNextLine = pPPortion->GetLines()[nLine+1];
+        aNewPaM.SetIndex( GetChar( pPPortion, &rNextLine, nX ) );
         // Special treatment, see CursorUp ...
-        if ( ( aNewPaM.GetIndex() == rNextLine.GetEnd() ) && ( 
aNewPaM.GetIndex() > rNextLine.GetStart() ) && ( aNewPaM.GetIndex() < 
rPPortion.GetNode()->Len() ) )
+        if ( ( aNewPaM.GetIndex() == rNextLine.GetEnd() ) && ( 
aNewPaM.GetIndex() > rNextLine.GetStart() ) && ( aNewPaM.GetIndex() < 
pPPortion->GetNode()->Len() ) )
             aNewPaM = CursorLeft( aNewPaM );
     }
     else    // next paragraph
     {
-        const ParaPortion* pNextPortion = GetNextVisPortion( &rPPortion );
+        const ParaPortion* pNextPortion = GetNextVisPortion( pPPortion );
         if ( pNextPortion )
         {
             const EditLine& rLine = pNextPortion->GetLines()[0];
@@ -1343,9 +1346,10 @@ EditPaM ImpEditEngine::CursorDown( const EditPaM& rPaM, 
EditView const * pView )
 
 EditPaM ImpEditEngine::CursorStartOfLine( const EditPaM& rPaM )
 {
-    const ParaPortion& rCurPortion = FindParaPortion( rPaM.GetNode() );
-    sal_Int32 nLine = rCurPortion.GetLineNumber( rPaM.GetIndex() );
-    const EditLine& rLine = rCurPortion.GetLines()[nLine];
+    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];
 
     EditPaM aNewPaM( rPaM );
     aNewPaM.SetIndex( rLine.GetStart() );
@@ -1354,9 +1358,10 @@ EditPaM ImpEditEngine::CursorStartOfLine( const EditPaM& 
rPaM )
 
 EditPaM ImpEditEngine::CursorEndOfLine( const EditPaM& rPaM )
 {
-    const ParaPortion& rCurPortion = FindParaPortion( rPaM.GetNode() );
-    sal_Int32 nLine = rCurPortion.GetLineNumber( rPaM.GetIndex() );
-    const EditLine& rLine = rCurPortion.GetLines()[nLine];
+    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];
 
     EditPaM aNewPaM( rPaM );
     aNewPaM.SetIndex( rLine.GetEnd() );
@@ -2150,25 +2155,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 );
@@ -2184,28 +2189,28 @@ EditSelection ImpEditEngine::ImpMoveParagraphs( Range 
aOldPositions, sal_Int32 n
     for (tools::Long i = aOldPositions.Min(); i <= aOldPositions.Max(); i++  )
     {
         // always aOldPositions.Min(), since Remove().
-        ParaPortion aTmpPortion = 
GetParaPortions().Remove(aOldPositions.Min());
+        std::unique_ptr<ParaPortion> pTmpPortion = 
GetParaPortions().Release(aOldPositions.Min());
         aEditDoc.Release( aOldPositions.Min() );
-        aTmpPortionList.Append(std::move(aTmpPortion));
+        aTmpPortionList.Append(std::move(pTmpPortion));
     }
 
     sal_Int32 nRealNewPos = pDestPortion ? GetParaPortions().GetPos( 
pDestPortion ) : GetParaPortions().Count();
-    OSL_ENSURE( nRealNewPos != EE_PARA_NOT_FOUND, "ImpMoveParagraphs: Invalid 
Position!" );
+    assert( nRealNewPos != EE_PARA_NOT_FOUND && "ImpMoveParagraphs: Invalid 
Position!" );
 
     sal_Int32 i = 0;
     while( aTmpPortionList.Count() > 0 )
     {
-        ParaPortion aTmpPortion = aTmpPortionList.Remove(0);
+        std::unique_ptr<ParaPortion> pTmpPortion = aTmpPortionList.Release(0);
         if ( i == 0 )
-            aSelection.Min().SetNode( aTmpPortion.GetNode() );
+            aSelection.Min().SetNode( pTmpPortion->GetNode() );
 
-        aSelection.Max().SetNode( aTmpPortion.GetNode() );
-        aSelection.Max().SetIndex( aTmpPortion.GetNode()->Len() );
+        aSelection.Max().SetNode( pTmpPortion->GetNode() );
+        aSelection.Max().SetIndex( pTmpPortion->GetNode()->Len() );
 
-        ContentNode* pN = aTmpPortion.GetNode();
+        ContentNode* pN = pTmpPortion->GetNode();
         aEditDoc.Insert(nRealNewPos+i, pN);
 
-        GetParaPortions().Insert(nRealNewPos+i, std::move(aTmpPortion));
+        GetParaPortions().Insert(nRealNewPos+i, std::move(pTmpPortion));
         ++i;
     }
 
@@ -2279,7 +2284,8 @@ EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* 
pLeft, ContentNode* pR
     ParaAttribsChanged( pLeft, true );
 
     // First search for Portions since pRight is gone after ConnectParagraphs.
-    ParaPortion& rLeftPortion = FindParaPortion( pLeft );
+    ParaPortion* pLeftPortion = FindParaPortion( pLeft );
+    OSL_ENSURE( pLeftPortion, "Blind Portion in ImpConnectParagraphs(1)" );
 
     if ( GetStatus().DoOnlineSpelling() )
     {
@@ -2306,7 +2312,7 @@ EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* 
pLeft, ContentNode* pR
     EditPaM aPaM = aEditDoc.ConnectParagraphs( pLeft, pRight );
     GetParaPortions().Remove( nParagraphTobeDeleted );
 
-    rLeftPortion.MarkSelectionInvalid( aPaM.GetIndex() );
+    pLeftPortion->MarkSelectionInvalid( aPaM.GetIndex() );
 
     // the right node is deleted by EditDoc:ConnectParagraphs().
     if ( GetTextRanger() )
@@ -2316,9 +2322,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& rPP = GetParaPortions()[n];
-            rPP.MarkSelectionInvalid( 0 );
-            rPP.GetLines().Reset();
+            ParaPortion* pPP = GetParaPortions()[n];
+            pPP->MarkSelectionInvalid( 0 );
+            pPP->GetLines().Reset();
         }
     }
 
@@ -2453,23 +2459,26 @@ EditPaM ImpEditEngine::ImpDeleteSelection(const 
EditSelection& rCurSel)
     {
         // The Rest of the StartNodes...
         ImpRemoveChars( aStartPaM, aStartPaM.GetNode()->Len() - 
aStartPaM.GetIndex() );
-        ParaPortion& rPortion = FindParaPortion( aStartPaM.GetNode() );
-        rPortion.MarkSelectionInvalid( aStartPaM.GetIndex() );
+        ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
+        OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(3)" );
+        pPortion->MarkSelectionInvalid( aStartPaM.GetIndex() );
 
         // The beginning of the EndNodes...
         const sal_Int32 nChars = aEndPaM.GetIndex();
         aEndPaM.SetIndex( 0 );
         ImpRemoveChars( aEndPaM, nChars );
-        ParaPortion& rPortion2 = FindParaPortion( aEndPaM.GetNode() );
-        rPortion2.MarkSelectionInvalid( 0 );
+        pPortion = FindParaPortion( aEndPaM.GetNode() );
+        OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(4)" );
+        pPortion->MarkSelectionInvalid( 0 );
         // Join together...
         aStartPaM = ImpConnectParagraphs( aStartPaM.GetNode(), 
aEndPaM.GetNode() );
     }
     else
     {
         ImpRemoveChars( aStartPaM, aEndPaM.GetIndex() - aStartPaM.GetIndex() );
-        ParaPortion& rPortion = FindParaPortion( aStartPaM.GetNode() );
-        rPortion.MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - 
aEndPaM.GetIndex() );
+        ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
+        OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(5)" );
+        pPortion->MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - 
aEndPaM.GetIndex() );
     }
 
     UpdateSelections();
@@ -2674,8 +2683,9 @@ EditPaM ImpEditEngine::InsertTextUserInput( const 
EditSelection& rCurSel,
         }
 
         aEditDoc.InsertText( aPaM, OUString(c) );
-        ParaPortion& rPortion = FindParaPortion( aPaM.GetNode() );
-        rPortion.MarkInvalid( aPaM.GetIndex(), 1 );
+        ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
+        OSL_ENSURE( pPortion, "Blind Portion in InsertText" );
+        pPortion->MarkInvalid( aPaM.GetIndex(), 1 );
         aPaM.SetIndex( aPaM.GetIndex()+1 );   // does not do EditDoc-Method 
anymore
     }
 
@@ -2806,7 +2816,8 @@ EditPaM ImpEditEngine::ImpInsertText(const EditSelection& 
aCurSel, const OUStrin
                     nStart2 = nEnd2+1;
                 }
             }
-            ParaPortion& rPortion = FindParaPortion( aPaM.GetNode() );
+            ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
+            OSL_ENSURE( pPortion, "Blind Portion in InsertText" );
 
             if ( GetStatus().DoOnlineSpelling() )
             {
@@ -2815,10 +2826,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'
-                rPortion.MarkInvalid( aCurWord.Min().GetIndex(), 
aLine.getLength() );
+                pPortion->MarkInvalid( aCurWord.Min().GetIndex(), 
aLine.getLength() );
             }
             else
-                rPortion.MarkInvalid( aCurPaM.GetIndex(), aLine.getLength() );
+                pPortion->MarkInvalid( aCurPaM.GetIndex(), aLine.getLength() );
         }
         if ( nEnd < aText.getLength() )
             aPaM = ImpInsertParaBreak( aPaM );
@@ -2870,8 +2881,9 @@ EditPaM ImpEditEngine::ImpInsertFeature(const 
EditSelection& rCurSel, const SfxP
     aPaM = aEditDoc.InsertFeature( aPaM, rItem );
     UpdateFields();
 
-    ParaPortion& rPortion = FindParaPortion( aPaM.GetNode() );
-    rPortion.MarkInvalid( aPaM.GetIndex()-1, 1 );
+    ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
+    OSL_ENSURE( pPortion, "Blind Portion in InsertFeature" );
+    pPortion->MarkInvalid( aPaM.GetIndex()-1, 1 );
 
     TextModified();
 
@@ -2933,14 +2945,16 @@ EditPaM ImpEditEngine::ImpInsertParaBreak( EditPaM& 
rPaM, bool bKeepEndingAttrib
         pRWrongs->SetInvalidRange(0, 1);  // Only test the first word
     }
 
-    ParaPortion& rPortion = FindParaPortion( rPaM.GetNode() );
-    rPortion.MarkInvalid( rPaM.GetIndex(), 0 );
+    ParaPortion* pPortion = FindParaPortion( rPaM.GetNode() );
+    OSL_ENSURE( pPortion, "Blind Portion in ImpInsertParaBreak" );
+    pPortion->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( &rPortion );
-    ParaPortion& rNewPortion = GetParaPortions().Insert(nPos+1, 
ParaPortion(aPaM.GetNode()));
-    ParaAttribsChanged( rNewPortion.GetNode() );
+    sal_Int32 nPos = GetParaPortions().GetPos( pPortion );
+    ParaPortion* pNewPortion = new ParaPortion( aPaM.GetNode() );
+    GetParaPortions().Insert(nPos+1, 
std::unique_ptr<ParaPortion>(pNewPortion));
+    ParaAttribsChanged( pNewPortion->GetNode() );
     if ( IsCallParaInsertedOrDeleted() )
         GetEditEnginePtr()->ParagraphInserted( nPos+1 );
 
@@ -2971,7 +2985,7 @@ EditPaM ImpEditEngine::ImpFastInsertParagraph( sal_Int32 
nPara )
 
     aEditDoc.Insert(nPara, pNode);
 
-    GetParaPortions().Insert(nPara, ParaPortion( pNode ));
+    GetParaPortions().Insert(nPara, std::make_unique<ParaPortion>( pNode ));
     if ( IsCallParaInsertedOrDeleted() )
         GetEditEnginePtr()->ParagraphInserted( nPara );
 
@@ -3063,8 +3077,9 @@ bool ImpEditEngine::UpdateFields()
         if ( bChangesInPara )
         {
             // If possible be more precise when invalidate.
-            ParaPortion& rPortion = GetParaPortions()[nPara];
-            rPortion.MarkSelectionInvalid( 0 );
+            ParaPortion* pPortion = GetParaPortions()[nPara];
+            OSL_ENSURE( pPortion, "NULL-Pointer in Doc" );
+            pPortion->MarkSelectionInvalid( 0 );
         }
     }
     return bChanges;
@@ -3168,19 +3183,19 @@ void ImpEditEngine::IterateLineAreas(const 
IterateLinesAreasFunc& f, IterFlag eO
     sal_Int16 nColumn = 0;
     for (sal_Int32 n = 0, nPortions = GetParaPortions().Count(); n < 
nPortions; ++n)
     {
-        ParaPortion& rPortion = GetParaPortions()[n];
+        ParaPortion* pPortion = GetParaPortions()[n];
         bool bSkipThis = true;
-        if (rPortion.IsVisible())
+        if (pPortion->IsVisible())
         {
             // when typing idle formatting, asynchronous Paint. Invisible 
Portions may be invalid.
-            if (rPortion.IsInvalid())
+            if (pPortion->IsInvalid())
                 return;
 
             LineAreaInfo aInfo{
-                rPortion, // rPortion
+                *pPortion, // pPortion
                 nullptr, // pLine
                 0, // nHeightNeededToNotWrap
-                { aLineStart, Size{ nColumnWidth, 
rPortion.GetFirstLineOffset() } }, // aArea
+                { aLineStart, Size{ nColumnWidth, 
pPortion->GetFirstLineOffset() } }, // aArea
                 n, // nPortion
                 0, // nLine
                 nColumn // nColumn
@@ -3194,16 +3209,16 @@ void ImpEditEngine::IterateLineAreas(const 
IterateLinesAreasFunc& f, IterFlag eO
             if (!aStatus.IsOutliner())
             {
                 const SvxLineSpacingItem& rLSItem
-                    = 
rPortion.GetNode()->GetContentAttribs().GetItem(EE_PARA_SBL);
+                    = 
pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_SBL);
                 nSBL = (rLSItem.GetInterLineSpaceRule() == 
SvxInterLineSpaceRule::Fix)
                            ? GetYValue(rLSItem.GetInterLineSpace())
                            : 0;
             }
 
-            adjustYDirectionAware(aLineStart, rPortion.GetFirstLineOffset());
-            for (sal_Int32 nLine = 0, nLines = rPortion.GetLines().Count(); 
nLine < nLines; nLine++)
+            adjustYDirectionAware(aLineStart, pPortion->GetFirstLineOffset());
+            for (sal_Int32 nLine = 0, nLines = pPortion->GetLines().Count(); 
nLine < nLines; nLine++)
             {
-                EditLine& rLine = rPortion.GetLines()[nLine];
+                EditLine& rLine = pPortion->GetLines()[nLine];
                 tools::Long nLineHeight = rLine.GetHeight();
                 if (nLine != nLines - 1)
                     nLineHeight += nVertLineSpacing;
@@ -3239,7 +3254,7 @@ void ImpEditEngine::IterateLineAreas(const 
IterateLinesAreasFunc& f, IterFlag eO
             if (!aStatus.IsOutliner())
             {
                 const SvxULSpaceItem& rULItem
-                    = 
rPortion.GetNode()->GetContentAttribs().GetItem(EE_PARA_ULSPACE);
+                    = 
pPortion->GetNode()->GetContentAttribs().GetItem(EE_PARA_ULSPACE);
                 tools::Long nUL = GetYValue(rULItem.GetLower());
                 adjustYDirectionAware(aLineStart, nUL);
             }
@@ -3357,19 +3372,20 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 
nPara, bool bIgnoreExtraSpace
 
     // Over all the paragraphs ...
 
-    ParaPortion& rPortion = GetParaPortions()[nPara];
-    if ( rPortion.IsVisible() )
+    OSL_ENSURE( 0 <= nPara && nPara < GetParaPortions().Count(), 
"CalcParaWidth: Out of range" );
+    ParaPortion* pPortion = GetParaPortions()[nPara];
+    if ( pPortion && pPortion->IsVisible() )
     {
-        const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( rPortion.GetNode() );
-        sal_Int32 nSpaceBeforeAndMinLabelWidth = 
GetSpaceBeforeAndMinLabelWidth( rPortion.GetNode() );
+        const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pPortion->GetNode() );
+        sal_Int32 nSpaceBeforeAndMinLabelWidth = 
GetSpaceBeforeAndMinLabelWidth( pPortion->GetNode() );
 
 
         // On the lines of the paragraph ...
 
-        sal_Int32 nLines = rPortion.GetLines().Count();
+        sal_Int32 nLines = pPortion->GetLines().Count();
         for ( sal_Int32 nLine = 0; nLine < nLines; nLine++ )
         {
-            EditLine& rLine = rPortion.GetLines()[nLine];
+            EditLine& rLine = pPortion->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
@@ -3380,15 +3396,15 @@ sal_uInt32 ImpEditEngine::CalcParaWidth( sal_Int32 
nPara, bool bIgnoreExtraSpace
             {
                 tools::Long nFI = GetXValue( rLRItem.GetTextFirstLineOffset() 
);
                 nCurWidth -= nFI;
-                if ( rPortion.GetBulletX() > nCurWidth )
+                if ( pPortion->GetBulletX() > nCurWidth )
                 {
                     nCurWidth += nFI;   // LI?
-                    if ( rPortion.GetBulletX() > nCurWidth )
-                        nCurWidth = rPortion.GetBulletX();
+                    if ( pPortion->GetBulletX() > nCurWidth )
+                        nCurWidth = pPortion->GetBulletX();
                 }
             }
             nCurWidth += GetXValue( rLRItem.GetRight() );
-            nCurWidth += CalcLineWidth( &rPortion, &rLine, bIgnoreExtraSpace );
+            nCurWidth += CalcLineWidth( pPortion, &rLine, bIgnoreExtraSpace );
             if ( nCurWidth > nMaxWidth )
             {
                 nMaxWidth = nCurWidth;
@@ -3691,21 +3707,22 @@ 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& rParaPortion = GetParaPortions()[nPara];
-                EditSelection aTmpSelection( EditPaM( rParaPortion.GetNode(), 
0 ) );
+                ParaPortion* pParaPortion = GetParaPortions()[nPara];
+                EditSelection aTmpSelection( EditPaM( pParaPortion->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 372237ff9c70..129c4d9f6a0e 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -356,7 +356,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();
 }
 
@@ -380,20 +380,20 @@ void ImpEditEngine::FormatDoc()
 
     for ( sal_Int32 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
     {
-        ParaPortion& rParaPortion = GetParaPortions()[nPara];
-        if ( rParaPortion.MustRepaint() || ( rParaPortion.IsInvalid() && 
rParaPortion.IsVisible() ) )
+        ParaPortion* pParaPortion = GetParaPortions()[nPara];
+        if ( pParaPortion->MustRepaint() || ( pParaPortion->IsInvalid() && 
pParaPortion->IsVisible() ) )
         {
             // No formatting should be necessary for MustRepaint()!
-            if ( !rParaPortion.IsInvalid() || CreateLines( nPara, nY ) )
+            if ( !pParaPortion->IsInvalid() || CreateLines( nPara, nY ) )
             {
                 if ( !bGrow && GetTextRanger() )
                 {
                     // For a change in height all below must be reformatted...
                     for ( sal_Int32 n = nPara+1; n < 
GetParaPortions().Count(); n++ )
                     {
-                        ParaPortion& rPP = GetParaPortions()[n];
-                        rPP.MarkSelectionInvalid( 0 );
-                        rPP.GetLines().Reset();
+                        ParaPortion* pPP = GetParaPortions()[n];
+                        pPP->MarkSelectionInvalid( 0 );
+                        pPP->GetLines().Reset();
                     }
                 }
                 bGrow = true;
@@ -408,12 +408,12 @@ void ImpEditEngine::FormatDoc()
                     }
 
                 }
-                rParaPortion.SetMustRepaint( false );
+                pParaPortion->SetMustRepaint( false );
             }
 
             aRepaintParas.insert(nPara);
         }
-        nY += rParaPortion.GetHeight();
+        nY += pParaPortion->GetHeight();
     }
 
     aInvalidRect = tools::Rectangle(); // make empty
@@ -521,11 +521,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& rParaPortion = GetParaPortions()[nPara];
+            ParaPortion* pParaPortion = GetParaPortions()[nPara];
             SvxAdjust eJustification = GetJustification( nPara );
             if ( eJustification != SvxAdjust::Left )
             {
-                rParaPortion.MarkSelectionInvalid( 0 );
+                pParaPortion->MarkSelectionInvalid( 0 );
                 CreateLines( nPara, 0 );  // 0: For AutoPageSize no TextRange!
             }
         }
@@ -597,28 +597,28 @@ tools::Long ImpEditEngine::GetColumnWidth(const Size& 
rPaperSize) const
 
 bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
 {
-    ParaPortion& rParaPortion = GetParaPortions()[nPara];
+    ParaPortion* pParaPortion = GetParaPortions()[nPara];
 
     // sal_Bool: Changes in the height of paragraph Yes / No - 
sal_True/sal_False
-    assert( rParaPortion.GetNode() && "Portion without Node in CreateLines" );
-    DBG_ASSERT( rParaPortion.IsVisible(), "Invisible paragraphs not 
formatted!" );
-    DBG_ASSERT( rParaPortion.IsInvalid(), "CreateLines: Portion not invalid!" 
);
+    assert( pParaPortion->GetNode() && "Portion without Node in CreateLines" );
+    DBG_ASSERT( pParaPortion->IsVisible(), "Invisible paragraphs not 
formatted!" );
+    DBG_ASSERT( pParaPortion->IsInvalid(), "CreateLines: Portion not invalid!" 
);
 
-    bool bProcessingEmptyLine = ( rParaPortion.GetNode()->Len() == 0 );
-    bool bEmptyNodeWithPolygon = ( rParaPortion.GetNode()->Len() == 0 ) && 
GetTextRanger();
+    bool bProcessingEmptyLine = ( pParaPortion->GetNode()->Len() == 0 );
+    bool bEmptyNodeWithPolygon = ( pParaPortion->GetNode()->Len() == 0 ) && 
GetTextRanger();
 
 
     // Fast special treatment for empty paragraphs...
 
-    if ( ( rParaPortion.GetNode()->Len() == 0 ) && !GetTextRanger() )
+    if ( ( pParaPortion->GetNode()->Len() == 0 ) && !GetTextRanger() )
     {
         // fast special treatment...
-        if ( rParaPortion.GetTextPortions().Count() )
-            rParaPortion.GetTextPortions().Reset();
-        if ( rParaPortion.GetLines().Count() )
-            rParaPortion.GetLines().Reset();
-        CreateAndInsertEmptyLine( &rParaPortion );
-        return FinishCreateLines( &rParaPortion );
+        if ( pParaPortion->GetTextPortions().Count() )
+            pParaPortion->GetTextPortions().Reset();
+        if ( pParaPortion->GetLines().Count() )
+            pParaPortion->GetLines().Reset();
+        CreateAndInsertEmptyLine( pParaPortion );
+        return FinishCreateLines( pParaPortion );
     }
 
     sal_Int64 nCurrentPosY = nStartPosY;
@@ -636,16 +636,16 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     // Always format for 100%:
     bool bMapChanged = ImpCheckRefMapMode();
 
-    if ( rParaPortion.GetLines().Count() == 0 )
+    if ( pParaPortion->GetLines().Count() == 0 )
     {
         EditLine* pL = new EditLine;
-        rParaPortion.GetLines().Append(pL);
+        pParaPortion->GetLines().Append(pL);
     }
 
 
     // Get Paragraph attributes...
 
-    ContentNode* const pNode = rParaPortion.GetNode();
+    ContentNode* const pNode = pParaPortion->GetNode();
 
     bool bRightToLeftPara = IsRightToLeft( nPara );
 
@@ -658,30 +658,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 = rParaPortion.GetInvalidDiff();
-    const sal_Int32 nInvalidStart = rParaPortion.GetInvalidPosStart();
+    const short nInvalidDiff = pParaPortion->GetInvalidDiff();
+    const sal_Int32 nInvalidStart = pParaPortion->GetInvalidPosStart();
     const sal_Int32 nInvalidEnd =  nInvalidStart + std::abs( nInvalidDiff );
 
     bool bQuickFormat = false;
     if ( !bEmptyNodeWithPolygon && !HasScriptType( nPara, 
i18n::ScriptType::COMPLEX ) )
     {
-        if ( ( rParaPortion.IsSimpleInvalid() ) && ( nInvalidDiff > 0 ) &&
+        if ( ( pParaPortion->IsSimpleInvalid() ) && ( nInvalidDiff > 0 ) &&
              ( pNode->GetString().indexOf( CH_FEATURE, nInvalidStart ) > 
nInvalidEnd ) )
         {
             bQuickFormat = true;
         }
-        else if ( ( rParaPortion.IsSimpleInvalid() ) && ( nInvalidDiff < 0 ) )
+        else if ( ( pParaPortion->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 = rParaPortion.GetTextPortions().Count();
+            sal_Int32 nPortions = pParaPortion->GetTextPortions().Count();
             for ( sal_Int32 nTP = 0; nTP < nPortions; nTP++ )
             {
                 // There must be no start / end in the deleted area.
-                const TextPortion& rTP = rParaPortion.GetTextPortions()[ nTP ];
+                const TextPortion& rTP = pParaPortion->GetTextPortions()[ nTP 
];
                 nPos = nPos + rTP.GetLen();
                 if ( ( nPos > nStart ) && ( nPos < nEnd ) )
                 {
@@ -702,17 +702,17 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     if ( bEmptyNodeWithPolygon )
     {
         TextPortion* pDummyPortion = new TextPortion( 0 );
-        rParaPortion.GetTextPortions().Reset();
-        rParaPortion.GetTextPortions().Append(pDummyPortion);
+        pParaPortion->GetTextPortions().Reset();
+        pParaPortion->GetTextPortions().Append(pDummyPortion);
     }
     else if ( bQuickFormat )
     {
         // faster Method:
-        RecalcTextPortion( &rParaPortion, nInvalidStart, nInvalidDiff );
+        RecalcTextPortion( pParaPortion, nInvalidStart, nInvalidDiff );
     }
     else    // nRealInvalidStart can be before InvalidStart, since Portions 
were deleted...
     {
-        CreateTextPortions( &rParaPortion, nRealInvalidStart );
+        CreateTextPortions( pParaPortion, nRealInvalidStart );
     }
 
 
@@ -720,10 +720,10 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     // Flag the line => do not remove it !
 
 
-    sal_Int32 nLine = rParaPortion.GetLines().Count()-1;
+    sal_Int32 nLine = pParaPortion->GetLines().Count()-1;
     for ( sal_Int32 nL = 0; nL <= nLine; nL++ )
     {
-        EditLine& rLine = rParaPortion.GetLines()[nL];
+        EditLine& rLine = pParaPortion->GetLines()[nL];
         if ( rLine.GetEnd() > nRealInvalidStart )  // not nInvalidStart!
         {
             nLine = nL;
@@ -733,20 +733,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 && ( !rParaPortion.IsSimpleInvalid() || ( nInvalidEnd < 
pNode->Len() ) || ( nInvalidDiff <= 0 ) ) )
+    if ( nLine && ( !pParaPortion->IsSimpleInvalid() || ( nInvalidEnd < 
pNode->Len() ) || ( nInvalidDiff <= 0 ) ) )
         nLine--;
 
-    EditLine* pLine = &rParaPortion.GetLines()[nLine];
+    EditLine* pLine = &pParaPortion->GetLines()[nLine];
 
     static const tools::Rectangle aZeroArea { Point(), Point() };
     tools::Rectangle aBulletArea( aZeroArea );
     if ( !nLine )
     {
-        aBulletArea = GetEditEnginePtr()->GetBulletArea( 
GetParaPortions().GetPos( &rParaPortion ) );
+        aBulletArea = GetEditEnginePtr()->GetBulletArea( 
GetParaPortions().GetPos( pParaPortion ) );
         if ( !aBulletArea.IsWidthEmpty() && aBulletArea.Right() > 0 )
-            rParaPortion.SetBulletX( static_cast<sal_Int32>(GetXValue( 
aBulletArea.Right() )) );
+            pParaPortion->SetBulletX( static_cast<sal_Int32>(GetXValue( 
aBulletArea.Right() )) );
         else
-            rParaPortion.SetBulletX( 0 ); // if Bullet is set incorrectly
+            pParaPortion->SetBulletX( 0 ); // if Bullet is set incorrectly
     }
 
 
@@ -784,9 +784,9 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             tools::Long nFI = GetXValue( rLRItem.GetTextFirstLineOffset() );
             nStartX += nFI;
 
-            if ( !nLine && ( rParaPortion.GetBulletX() > nStartX ) )
+            if ( !nLine && ( pParaPortion->GetBulletX() > nStartX ) )
             {
-                    nStartX = rParaPortion.GetBulletX();
+                    nStartX = pParaPortion->GetBulletX();
             }
         }
 
@@ -826,7 +826,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         {
             GetTextRanger()->SetVertical( IsEffectivelyVertical() );
 
-            tools::Long nTextY = nStartPosY + GetEditCursor( &rParaPortion, 
pLine, pLine->GetStart(), GetCursorFlags::NONE ).Top();
+            tools::Long nTextY = nStartPosY + GetEditCursor( pParaPortion, 
pLine, pLine->GetStart(), GetCursorFlags::NONE ).Top();
             if ( !bSameLineAgain )
             {
                 SeekCursor( pNode, nTmpPos+1, aTmpFont );
@@ -904,7 +904,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 = 
rParaPortion.GetTextPortions().Count();
+            const sal_Int32 nTextPortions = 
pParaPortion->GetTextPortions().Count();
             assert(nTextPortions > 0);
             bContinueLastPortion = (nTmpPortion >= nTextPortions);
             if (bContinueLastPortion)
@@ -922,17 +922,17 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             }
 
             nPortionStart = nTmpPos;
-            pPortion = &rParaPortion.GetTextPortions()[nTmpPortion];
+            pPortion = &pParaPortion->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();
-                rParaPortion.GetTextPortions().Remove( nTmpPortion );
+                pParaPortion->GetTextPortions().Remove( nTmpPortion );
                 if (nTmpPortion && nTmpLen)
                 {
                     nTmpPortion--;
-                    TextPortion& rPrev = 
rParaPortion.GetTextPortions()[nTmpPortion];
+                    TextPortion& rPrev = 
pParaPortion->GetTextPortions()[nTmpPortion];
                     DBG_ASSERT( rPrev.GetKind() == PortionKind::TEXT, 
"Portion?!" );
                     nTmpWidth -= rPrev.GetSize().Width();
                     nTmpPos = nTmpPos - rPrev.GetLen();
@@ -940,8 +940,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     rPrev.GetSize().setWidth( -1 );
                 }
 
-                assert( nTmpPortion < rParaPortion.GetTextPortions().Count() 
&& "No more Portions left!" );
-                pPortion = &rParaPortion.GetTextPortions()[nTmpPortion];
+                assert( nTmpPortion < pParaPortion->GetTextPortions().Count() 
&& "No more Portions left!" );
+                pPortion = &pParaPortion->GetTextPortions()[nTmpPortion];
             }
 
             if (bContinueLastPortion)
@@ -1156,7 +1156,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 if (bContinueLastPortion)
                 {
                      Size aSize( aTmpFont.QuickGetTextSize( GetRefDevice(),
-                            rParaPortion.GetNode()->GetString(), nTmpPos, 
nPortionLen, &aBuf ));
+                            pParaPortion->GetNode()->GetString(), nTmpPos, 
nPortionLen, &aBuf ));
                      pPortion->GetSize().AdjustWidth(aSize.Width() );
                      if (pPortion->GetSize().Height() < aSize.Height())
                          pPortion->GetSize().setHeight( aSize.Height() );
@@ -1164,7 +1164,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 else
                 {
                     pPortion->GetSize() = aTmpFont.QuickGetTextSize( 
GetRefDevice(),
-                            rParaPortion.GetNode()->GetString(), nTmpPos, 
nPortionLen, &aBuf );
+                            pParaPortion->GetNode()->GetString(), nTmpPos, 
nPortionLen, &aBuf );
                 }
 
                 // #i9050# Do Kerning also behind portions...
@@ -1213,7 +1213,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 = rParaPortion.GetTextPortions()[n];
+                    const TextPortion& rTP = 
pParaPortion->GetTextPortions()[n];
                     nWidthAfterTab += rTP.GetSize().Width();
                 }
                 tools::Long nW = nWidthAfterTab;   // Length before tab 
position
@@ -1226,13 +1226,13 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 }
                 else if ( aCurrentTab.aTabStop.GetAdjustment() == 
SvxTabAdjust::Decimal )
                 {
-                    OUString aText = GetSelected( EditSelection(  EditPaM( 
rParaPortion.GetNode(), nTmpPos ),
-                                                                EditPaM( 
rParaPortion.GetNode(), nTmpPos + nPortionLen ) ) );
+                    OUString aText = GetSelected( EditSelection(  EditPaM( 
pParaPortion->GetNode(), nTmpPos ),
+                                                                EditPaM( 
pParaPortion->GetNode(), nTmpPos + nPortionLen ) ) );
                     sal_Int32 nDecPos = aText.indexOf( 
aCurrentTab.aTabStop.GetDecimal() );
                     if ( nDecPos != -1 )
                     {
-                        nW -= 
rParaPortion.GetTextPortions()[nTmpPortion].GetSize().Width();
-                        nW += aTmpFont.QuickGetTextSize( GetRefDevice(), 
rParaPortion.GetNode()->GetString(),
+                        nW -= 
pParaPortion->GetTextPortions()[nTmpPortion].GetSize().Width();
+                        nW += aTmpFont.QuickGetTextSize( GetRefDevice(), 
pParaPortion->GetNode()->GetString(),
                                 nTmpPos, nDecPos, nullptr ).Width();
                         aCurrentTab.bValid = false;
                     }
@@ -1247,7 +1247,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     nW = nMaxW;
                     aCurrentTab.bValid = false;
                 }
-                TextPortion& rTabPortion = 
rParaPortion.GetTextPortions()[aCurrentTab.nTabPortion];
+                TextPortion& rTabPortion = 
pParaPortion->GetTextPortions()[aCurrentTab.nTabPortion];
                 rTabPortion.GetSize().setWidth( aCurrentTab.nTabPos - 
aCurrentTab.nStartPosX - nW - nStartX );
                 nTmpWidth = aCurrentTab.nStartPosX + 
rTabPortion.GetSize().Width() + nWidthAfterTab;
             }
@@ -1286,8 +1286,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( &rParaPortion, nTmpPos, pLine 
);
-                nTmpWidth += 
rParaPortion.GetTextPortions()[nP].GetSize().Width();
+                sal_Int32 nP = SplitTextPortion( pParaPortion, nTmpPos, pLine 
);
+                nTmpWidth += 
pParaPortion->GetTextPortions()[nP].GetSize().Width();
             }
         }
         else if ( nTmpWidth >= nXWidth )
@@ -1327,8 +1327,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             bEOL = true;
             bEOC = true;
             pLine->SetEnd( nPortionEnd );
-            assert( rParaPortion.GetTextPortions().Count() && "No 
TextPortions?" );
-            pLine->SetEndPortion( rParaPortion.GetTextPortions().Count() - 1 );
+            assert( pParaPortion->GetTextPortions().Count() && "No 
TextPortions?" );
+            pLine->SetEndPortion( pParaPortion->GetTextPortions().Count() - 1 
);
         }
 
         if ( aStatus.OneCharPerLine() )
@@ -1360,7 +1360,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     pNode, pPortion, nPortionStart, pDXArray, 10000, true);
             }
             if( pPortion )
-                ImpBreakLine( &rParaPortion, pLine, pPortion, nPortionStart,
+                ImpBreakLine( pParaPortion, pLine, pPortion, nPortionStart,
                                                 nRemainingWidth, bCanHyphenate 
&& bHyphenatePara );
         }
 
@@ -1369,7 +1369,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
 
 
         // CalcTextSize should be replaced by a continuous registering!
-        Size aTextSize = pLine->CalcTextSize( rParaPortion );
+        Size aTextSize = pLine->CalcTextSize( *pParaPortion );
 
         if ( aTextSize.Height() == 0 )
         {
@@ -1391,7 +1391,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 = rParaPortion.GetTextPortions()[nP];
+            const TextPortion& rTP = pParaPortion->GetTextPortions()[nP];
             // problem with hard font height attribute, when everything but 
the line break has this attribute
             if ( rTP.GetKind() != PortionKind::LINEBREAK )
             {
@@ -1483,8 +1483,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
             tools::Long nRemainingWidth = nMaxLineWidth - aTextSize.Width();
             if ( nRemainingWidth > 0 )
             {
-                ImplExpandCompressedPortions( pLine, &rParaPortion, 
nRemainingWidth );
-                aTextSize = pLine->CalcTextSize( rParaPortion );
+                ImplExpandCompressedPortions( pLine, pParaPortion, 
nRemainingWidth );
+                aTextSize = pLine->CalcTextSize( *pParaPortion );
             }
         }
 
@@ -1493,7 +1493,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 = 
rParaPortion.GetTextPortions()[pLine->GetEndPortion()];
+            TextPortion& rTP = 
pParaPortion->GetTextPortions()[pLine->GetEndPortion()];
             sal_Int32 nPosInArray = pLine->GetEnd()-1-pLine->GetStart();
             tools::Long nNewValue = ( nPosInArray ? pLine->GetCharPosArray()[ 
nPosInArray-1 ] : 0 ) + n;
             if (o3tl::make_unsigned(nPosInArray) < 
pLine->GetCharPosArray().size())
@@ -1528,7 +1528,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( &rParaPortion, pLine, nRemainingSpace );
+                    ImpAdjustBlocks( pParaPortion, pLine, nRemainingSpace );
             }
             break;
             default:
@@ -1562,7 +1562,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
         }
 
         // for <0 think over !
-        if ( rParaPortion.IsSimpleInvalid() )
+        if ( pParaPortion->IsSimpleInvalid() )
         {
             // Change through simple Text changes...
             // Do not cancel formatting since Portions possibly have to be 
split
@@ -1589,7 +1589,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                         if (bQuickFormat)
                         {
                             bLineBreak = false;
-                            rParaPortion.CorrectValuesBehindLastFormattedLine( 
nLine );
+                            
pParaPortion->CorrectValuesBehindLastFormattedLine( nLine );
                             break;
                         }
                     }
@@ -1602,7 +1602,7 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                     if ( nEnd == ( aSaveLine.GetEnd() + nInvalidDiff ) )
                     {
                         bLineBreak = false;
-                        rParaPortion.CorrectValuesBehindLastFormattedLine( 
nLine );
+                        pParaPortion->CorrectValuesBehindLastFormattedLine( 
nLine );
                         break;
                     }
                 }
@@ -1619,8 +1619,8 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
 
             // Next line or maybe a new line...
             pLine = nullptr;
-            if ( nLine < rParaPortion.GetLines().Count()-1 )
-                pLine = &rParaPortion.GetLines()[++nLine];
+            if ( nLine < pParaPortion->GetLines().Count()-1 )
+                pLine = &pParaPortion->GetLines()[++nLine];
             if ( pLine && ( nIndex >= pNode->Len() ) )
             {
                 nDelFromLine = nLine;
@@ -1641,16 +1641,16 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
                 if ( nIndex < pNode->Len() )
                 {
                     pLine = new EditLine;
-                    rParaPortion.GetLines().Insert(++nLine, pLine);
+                    pParaPortion->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 );
-                    rParaPortion.GetTextPortions().Append(pDummyPortion);
+                    pParaPortion->GetTextPortions().Append(pDummyPortion);
                     pLine = new EditLine;
-                    rParaPortion.GetLines().Insert(++nLine, pLine);
+                    pParaPortion->GetLines().Insert(++nLine, pLine);
                     bForceOneRun = true;
                     bProcessingEmptyLine = true;
                 }
@@ -1667,14 +1667,14 @@ bool ImpEditEngine::CreateLines( sal_Int32 nPara, 
sal_uInt32 nStartPosY )
     }   // while ( Index < Len )
 
     if ( nDelFromLine >= 0 )
-        rParaPortion.GetLines().DeleteFromLine( nDelFromLine );
+        pParaPortion->GetLines().DeleteFromLine( nDelFromLine );
 
-    DBG_ASSERT( rParaPortion.GetLines().Count(), "No line after CreateLines!" 
);
+    DBG_ASSERT( pParaPortion->GetLines().Count(), "No line after CreateLines!" 
);
 
     if ( bLineBreak )
-        CreateAndInsertEmptyLine( &rParaPortion );
+        CreateAndInsertEmptyLine( pParaPortion );
 
-    bool bHeightChanged = FinishCreateLines( &rParaPortion );
+    bool bHeightChanged = FinishCreateLines( pParaPortion );
 
     if ( bMapChanged )
         GetRefDevice()->Pop();
@@ -2617,9 +2617,9 @@ void ImpEditEngine::SetTextRanger( 
std::unique_ptr<TextRanger> pRanger )
 
     for ( sal_Int32 nPara = 0; nPara < GetParaPortions().Count(); nPara++ )
     {
-        ParaPortion& rParaPortion = GetParaPortions()[nPara];
-        rParaPortion.MarkSelectionInvalid( 0 );
-        rParaPortion.GetLines().Reset();
+        ParaPortion* pParaPortion = GetParaPortions()[nPara];
+        pParaPortion->MarkSelectionInvalid( 0 );
+        pParaPortion->GetLines().Reset();
     }
 
     FormatFullDoc();
@@ -3128,7 +3128,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
     tools::Long nFirstVisYPos = - rOutDev.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* >( rOutDev.GetExtOutDevData() );
 
     // In the case of rotated text is aStartPos considered TopLeft because
@@ -3157,17 +3157,18 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
     for ( sal_Int32 n = 0; n < GetParaPortions().Count(); n++ )
     {
-        const ParaPortion& rPortion = GetParaPortions()[n];
+        const ParaPortion* const pPortion = GetParaPortions()[n];
+        assert( pPortion && "NULL-Pointer in TokenList in Paint" );
         // if when typing idle formatting,  asynchronous Paint.
         // Invisible Portions may be invalid.
-        if ( rPortion.IsVisible() && rPortion.IsInvalid() )
+        if ( pPortion->IsVisible() && pPortion->IsInvalid() )
             return;
 
         if ( pPDFExtOutDevData )
             pPDFExtOutDevData->BeginStructureElement( 
vcl::PDFWriter::Paragraph );
 
-        const tools::Long nParaHeight = rPortion.GetHeight();
-        if ( rPortion.IsVisible() && (
+        const tools::Long nParaHeight = pPortion->GetHeight();
+        if ( pPortion->IsVisible() && (
                 ( !IsEffectivelyVertical() && ( ( aStartPos.Y() + nParaHeight 
) > aClipRect.Top() ) ) ||
                 ( IsEffectivelyVertical() && IsTopToBottom() && ( ( 
aStartPos.X() - nParaHeight ) < aClipRect.Right() ) ) ||
                 ( IsEffectivelyVertical() && !IsTopToBottom() && ( ( 
aStartPos.X() + nParaHeight ) > aClipRect.Left() ) ) ) )
@@ -3177,21 +3178,21 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
             // Over the lines of the paragraph...
 
-            const sal_Int32 nLines = rPortion.GetLines().Count();
+            const sal_Int32 nLines = pPortion->GetLines().Count();
             const sal_Int32 nLastLine = nLines-1;
 
             bool bEndOfParagraphWritten(false);
 
-            adjustYDirectionAware(aStartPos, rPortion.GetFirstLineOffset());
+            adjustYDirectionAware(aStartPos, pPortion->GetFirstLineOffset());
 
-            const SvxLineSpacingItem& rLSItem = 
rPortion.GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
+            const SvxLineSpacingItem& rLSItem = 
pPortion->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 = &rPortion.GetLines()[nLine];
+                const EditLine* const pLine = &pPortion->GetLines()[nLine];
                 assert( pLine && "NULL-Pointer in the line iterator in 
UpdateViews" );
                 sal_Int32 nIndex = pLine->GetStart();
                 tools::Long nLineHeight = pLine->GetHeight();
@@ -3231,10 +3232,10 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
                     for ( sal_Int32 nPortion = pLine->GetStartPortion(); 
nPortion <= pLine->GetEndPortion(); nPortion++ )
                     {
-                        DBG_ASSERT( rPortion.GetTextPortions().Count(), "Line 
without Textportion in Paint!" );
-                        const TextPortion& rTextPortion = 
rPortion.GetTextPortions()[nPortion];
+                        DBG_ASSERT( pPortion->GetTextPortions().Count(), "Line 
without Textportion in Paint!" );
+                        const TextPortion& rTextPortion = 
pPortion->GetTextPortions()[nPortion];
 
-                        const tools::Long nPortionXOffset = GetPortionXOffset( 
&rPortion, pLine, nPortion );
+                        const tools::Long nPortionXOffset = GetPortionXOffset( 
pPortion, pLine, nPortion );
                         setXDirectionAwareFrom(aTmpPos, aStartPos);
                         adjustXDirectionAware(aTmpPos, nPortionXOffset);
                         if (isXOverflowDirectionAware(aTmpPos, aClipRect))
@@ -3246,7 +3247,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                             case PortionKind::FIELD:
                             case PortionKind::HYPHENATOR:
                             {
-                                SeekCursor( rPortion.GetNode(), nIndex+1, 
aTmpFont, &rOutDev );
+                                SeekCursor( pPortion->GetNode(), nIndex+1, 
aTmpFont, &rOutDev );
 
                                 bool bDrawFrame = false;
 
@@ -3294,7 +3295,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
                                 if ( rTextPortion.GetKind() == 
PortionKind::TEXT )
                                 {
-                                    aText = rPortion.GetNode()->GetString();
+                                    aText = pPortion->GetNode()->GetString();
                                     nTextStart = nIndex;
                                     nTextLen = rTextPortion.GetLen();
                                     pDXArray = 
o3tl::span(pLine->GetCharPosArray().data() + (nIndex - pLine->GetStart()),
@@ -3375,7 +3376,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                 }
                                 else if ( rTextPortion.GetKind() == 
PortionKind::FIELD )
                                 {
-                                    const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                    const EditCharAttrib* pAttr = 
pPortion->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();
@@ -3471,7 +3472,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
                                     if(GetStatus().DoOnlineSpelling() && 
rTextPortion.GetLen())
                                     {
-                                        WrongList* pWrongs = 
rPortion.GetNode()->GetWrongList();
+                                        WrongList* pWrongs = 
pPortion->GetNode()->GetWrongList();
 
                                         if(pWrongs && !pWrongs->empty())
                                         {
@@ -3518,7 +3519,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
                                     if(PortionKind::FIELD == 
rTextPortion.GetKind())
                                     {
-                                        const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                        const EditCharAttrib* pAttr = 
pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
                                         const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
 
                                         if(pFieldItem)
@@ -3530,7 +3531,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
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(rPortion.GetNode(), nIndex + 1)));
+                                    const lang::Locale 
aLocale(GetLocale(EditPaM(pPortion->GetNode(), nIndex + 1)));
 
                                     // create EOL and EOP bools
                                     const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
@@ -3597,20 +3598,20 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                             // base line of the original font 
height...
                                             // But only if there was something 
underlined before!
                                             bool bSpecialUnderline = false;
-                                            EditCharAttrib* pPrev = 
rPortion.GetNode()->GetCharAttribs().FindAttrib( EE_CHAR_ESCAPEMENT, nIndex );
+                                            EditCharAttrib* pPrev = 
pPortion->GetNode()->GetCharAttribs().FindAttrib( EE_CHAR_ESCAPEMENT, nIndex );
                                             if ( pPrev )
                                             {
                                                 SvxFont aDummy;
                                                 // Underscore in front?
                                                 if ( pPrev->GetStart() )
                                                 {
-                                                    SeekCursor( 
rPortion.GetNode(), pPrev->GetStart(), aDummy );
+                                                    SeekCursor( 
pPortion->GetNode(), pPrev->GetStart(), aDummy );
                                                     if ( aDummy.GetUnderline() 
!= LINESTYLE_NONE )
                                                         bSpecialUnderline = 
true;
                                                 }
-                                                if ( !bSpecialUnderline && ( 
pPrev->GetEnd() < rPortion.GetNode()->Len() ) )
+                                                if ( !bSpecialUnderline && ( 
pPrev->GetEnd() < pPortion->GetNode()->Len() ) )
                                                 {
-                                                    SeekCursor( 
rPortion.GetNode(), pPrev->GetEnd()+1, aDummy );
+                                                    SeekCursor( 
pPortion->GetNode(), pPrev->GetEnd()+1, aDummy );
                                                     if ( aDummy.GetUnderline() 
!= LINESTYLE_NONE )
                                                         bSpecialUnderline = 
true;
                                                 }
@@ -3670,7 +3671,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                         {
                                             if ( rTextPortion.GetKind() == 
PortionKind::FIELD )
                                             {
-                                                const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                                const EditCharAttrib* pAttr = 
pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
                                                 const SvxFieldItem* pFieldItem 
= dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
                                                 if( pFieldItem )
                                                 {
@@ -3692,7 +3693,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                         }
                                     }
 
-                                    const WrongList* const pWrongList = 
rPortion.GetNode()->GetWrongList();
+                                    const WrongList* const pWrongList = 
pPortion->GetNode()->GetWrongList();
                                     if ( GetStatus().DoOnlineSpelling() && 
pWrongList && !pWrongList->empty() && rTextPortion.GetLen() )
                                     {
                                         {//#105750# adjust LinePos for 
superscript or subscript text
@@ -3705,7 +3706,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                         }
                                         Color aOldColor( 
rOutDev.GetLineColor() );
                                         rOutDev.SetLineColor( 
GetColorConfig().GetColorValue( svtools::SPELL ).nColor );
-                                        lcl_DrawRedLines( rOutDev, 
aTmpFont.GetFontSize().Height(), aRedLineTmpPos, static_cast<size_t>(nIndex), 
static_cast<size_t>(nIndex) + rTextPortion.GetLen(), pDXArray, 
rPortion.GetNode()->GetWrongList(), nOrientation, aOrigin, 
IsEffectivelyVertical(), rTextPortion.IsRightToLeft() );
+                                        lcl_DrawRedLines( rOutDev, 
aTmpFont.GetFontSize().Height(), aRedLineTmpPos, static_cast<size_t>(nIndex), 
static_cast<size_t>(nIndex) + rTextPortion.GetLen(), pDXArray, 
pPortion->GetNode()->GetWrongList(), nOrientation, aOrigin, 
IsEffectivelyVertical(), rTextPortion.IsRightToLeft() );
                                         rOutDev.SetLineColor( aOldColor );
                                     }
                                 }
@@ -3717,7 +3718,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                     // add a meta file comment if we record to 
a metafile
                                     if( bMetafileValid )
                                     {
-                                        const EditCharAttrib* pAttr = 
rPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                        const EditCharAttrib* pAttr = 
pPortion->GetNode()->GetCharAttribs().FindFeature(nIndex);
                                         assert( pAttr && "Field not found" );
 
                                         const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
@@ -3739,7 +3740,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                             {
                                 if ( rTextPortion.GetExtraValue() && ( 
rTextPortion.GetExtraValue() != ' ' ) )
                                 {
-                                    SeekCursor( rPortion.GetNode(), nIndex+1, 
aTmpFont, &rOutDev );
+                                    SeekCursor( pPortion->GetNode(), nIndex+1, 
aTmpFont, &rOutDev );
                                     aTmpFont.SetTransparent( false );
                                     aTmpFont.SetEscapement( 0 );
                                     aTmpFont.SetPhysFont(rOutDev);
@@ -3822,7 +3823,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
             if ( !aStatus.IsOutliner() )
             {
-                const SvxULSpaceItem& rULItem = 
rPortion.GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
+                const SvxULSpaceItem& rULItem = 
pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
                 tools::Long nUL = GetYValue( rULItem.GetLower() );
                 adjustYDirectionAware(aStartPos, nUL);
             }
@@ -3919,7 +3920,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, ParaPortion( pNode ));
+    GetParaPortions().Insert(nPos, std::make_unique<ParaPortion>( pNode ));
     aEditDoc.Insert(nPos, pNode);
     if ( IsCallParaInsertedOrDeleted() )
         GetEditEnginePtr()->ParagraphInserted( nPos );
@@ -4057,18 +4058,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 )
     {
-        ParaPortion& rTmpPortion = GetParaPortions()[nFirstInvPara-1];
-        rTmpPortion.MarkInvalid( rTmpPortion.GetNode()->Len(), 0 );
-        rTmpPortion.ResetHeight();
+        pTmpPortion = GetParaPortions()[nFirstInvPara-1];
+        pTmpPortion->MarkInvalid( pTmpPortion->GetNode()->Len(), 0 );
     }
     else
     {
-        ParaPortion& rTmpPortion = GetParaPortions()[0];
-        rTmpPortion.MarkSelectionInvalid( 0 );
-        rTmpPortion.ResetHeight();
+        pTmpPortion = GetParaPortions()[0];
+        pTmpPortion->MarkSelectionInvalid( 0 );
     }
+    pTmpPortion->ResetHeight();
 }
 
 IMPL_LINK_NOARG(ImpEditEngine, StatusTimerHdl, Timer *, void)
@@ -4091,17 +4092,19 @@ void ImpEditEngine::CallStatusHdl()
 
 ContentNode* ImpEditEngine::GetPrevVisNode( ContentNode const * pCurNode )
 {
-    const ParaPortion& rPortion1 = FindParaPortion( pCurNode );
-    const ParaPortion* pPortion2 = GetPrevVisPortion( &rPortion1 );
-    if ( pPortion2 )
-        return pPortion2->GetNode();
+    const ParaPortion* pPortion = FindParaPortion( pCurNode );
+    DBG_ASSERT( pPortion, "GetPrevVisibleNode: No matching portion!" );
+    pPortion = GetPrevVisPortion( pPortion );
+    if ( pPortion )
+        return pPortion->GetNode();
     return nullptr;
 }
 
 ContentNode* ImpEditEngine::GetNextVisNode( ContentNode const * pCurNode )
 {
-    const ParaPortion& rPortion = FindParaPortion( pCurNode );
-    const ParaPortion* pPortion = GetNextVisPortion( &rPortion );
+    const ParaPortion* pPortion = FindParaPortion( pCurNode );
+    DBG_ASSERT( pPortion, "GetNextVisibleNode: No matching portion!" );
+    pPortion = GetNextVisPortion( pPortion );
     if ( pPortion )
         return pPortion->GetNode();
     return nullptr;
@@ -4110,9 +4113,10 @@ ContentNode* ImpEditEngine::GetNextVisNode( ContentNode 
const * pCurNode )
 const ParaPortion* ImpEditEngine::GetPrevVisPortion( const ParaPortion* 
pCurPortion ) const
 {
     sal_Int32 nPara = GetParaPortions().GetPos( pCurPortion );
-    const ParaPortion* pPortion = nPara ? &GetParaPortions()[--nPara] : 
nullptr;
+    DBG_ASSERT( nPara < GetParaPortions().Count() , "Portion not found: 
GetPrevVisPortion" );
+    const ParaPortion* pPortion = nPara ? GetParaPortions()[--nPara] : nullptr;
     while ( pPortion && !pPortion->IsVisible() )
-        pPortion = nPara ? &GetParaPortions()[--nPara] : nullptr;
+        pPortion = nPara ? GetParaPortions()[--nPara] : nullptr;
 
     return pPortion;
 }
@@ -4141,7 +4145,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);
@@ -4219,7 +4223,7 @@ void ImpEditEngine::FormatAndLayout( 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 );
     }
@@ -4636,8 +4640,8 @@ void 
ImpEditEngine::ImplUpdateOverflowingParaNum(tools::Long nPaperHeight)
     tools::Long nPH;
 
     for ( sal_Int32 nPara = 0; nPara < GetParaPortions().Count(); nPara++ ) {
-        ParaPortion& rPara = GetParaPortions()[nPara];
-        nPH = rPara.GetHeight();
+        ParaPortion* pPara = GetParaPortions()[nPara];
+        nPH = pPara->GetHeight();
         nY += nPH;
         if ( nY > nPaperHeight /*nCurTextHeight*/ ) // found first paragraph 
overflowing
         {
@@ -4656,13 +4660,13 @@ void 
ImpEditEngine::ImplUpdateOverflowingLineNum(tools::Long nPaperHeight,
     tools::Long nY = nHeightBeforeOverflowingPara;
     tools::Long nLH;
 
-    ParaPortion& rPara = GetParaPortions()[nOverflowingPara];
+    ParaPortion *pPara = GetParaPortions()[nOverflowingPara];
 
     // Like UpdateOverflowingParaNum but for each line in the first
     //  overflowing paragraph.
-    for ( sal_Int32 nLine = 0; nLine < rPara.GetLines().Count(); nLine++ ) {
+    for ( sal_Int32 nLine = 0; nLine < pPara->GetLines().Count(); nLine++ ) {
         // XXX: We must use a reference here because the copy constructor 
resets the height
-        EditLine &aLine = rPara.GetLines()[nLine];
+        EditLine &aLine = pPara->GetLines()[nLine];
         nLH = aLine.GetHeight();
         nY += nLH;
 
diff --git a/editeng/source/editeng/impedit4.cxx 
b/editeng/source/editeng/impedit4.cxx
index 8d7fca6b3885..f8b2c3767ce8 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -540,20 +540,21 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, 
EditSelection aSel )
             rOutput.WriteChar( ' ' ); // Separator
 
         ItemList aAttribItems;
-        ParaPortion& rParaPortion = FindParaPortion( pNode );
+        ParaPortion* pParaPortion = FindParaPortion( pNode );
+        DBG_ASSERT( pParaPortion, "Portion not found: WriteRTF" );
 
         sal_Int32 nIndex = 0;
         sal_Int32 nStartPos = 0;
         sal_Int32 nEndPos = pNode->Len();
         sal_Int32 nStartPortion = 0;
-        sal_Int32 nEndPortion = rParaPortion.GetTextPortions().Count() - 1;
+        sal_Int32 nEndPortion = pParaPortion->GetTextPortions().Count() - 1;
         bool bFinishPortion = false;
         sal_Int32 nPortionStart;
 
         if ( nNode == nStartNode )
         {
             nStartPos = aSel.Min().GetIndex();
-            nStartPortion = rParaPortion.GetTextPortions().FindPortion( 
nStartPos, nPortionStart );
+            nStartPortion = pParaPortion->GetTextPortions().FindPortion( 
nStartPos, nPortionStart );
             if ( nStartPos != 0 )
             {
                 aAttribItems.Clear();
@@ -571,14 +572,14 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, 
EditSelection aSel )
         if ( nNode == nEndNode ) // can also be == nStart!
         {
             nEndPos = aSel.Max().GetIndex();
-            nEndPortion = rParaPortion.GetTextPortions().FindPortion( nEndPos, 
nPortionStart );
+            nEndPortion = pParaPortion->GetTextPortions().FindPortion( 
nEndPos, nPortionStart );
         }
 
         const EditCharAttrib* pNextFeature = 
pNode->GetCharAttribs().FindFeature(nIndex);

... etc. - the rest is truncated

Reply via email to