unique_ptr->optional in SwViewShellImp

Change-Id: I1f1862c846c2dac0a845b1e8035f447b33e487d7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138503
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/sw/source/core/inc/viewimp.hxx b/sw/source/core/inc/viewimp.hxx
index 1c07329..f68c9c7 100644
--- a/sw/source/core/inc/viewimp.hxx
+++ b/sw/source/core/inc/viewimp.hxx
@@ -23,8 +23,9 @@
#include <svx/svdtypes.hxx>
#include <swrect.hxx>
#include <swregion.hxx>
#include <vector>
#include <memory>
#include <optional>
#include <vector>

class OutputDevice;
class SwViewShell;
@@ -64,7 +65,7 @@ class SwViewShellImp
    SdrPageView *m_pSdrPageView;  // Exactly one Page for our DrawView

    SwPageFrame     *m_pFirstVisiblePage; // Always points to the first visible Page
    std::unique_ptr<SwRegionRects> m_pPaintRegion; // Collector of Paintrects from the LayAction
    std::optional<SwRegionRects> m_oPaintRegion; // Collector of Paintrects from the LayAction

    std::vector<SwRect> m_pendingLOKInvalidations;

@@ -150,10 +151,10 @@ public:
    const SwPageFrame* GetLastVisPage(const OutputDevice* pRenderContext) const;

    bool AddPaintRect( const SwRect &rRect );
    bool HasPaintRegion()      { return static_cast<bool>(m_pPaintRegion); }
    std::unique_ptr<SwRegionRects> TakePaintRegion() { return std::move(m_pPaintRegion); }
    const SwRegionRects* GetPaintRegion() { return m_pPaintRegion.get(); }
    void DeletePaintRegion() { m_pPaintRegion.reset(); }
    bool HasPaintRegion()      { return m_oPaintRegion.has_value(); }
    std::optional<SwRegionRects> TakePaintRegion() { return std::move(m_oPaintRegion); }
    const std::optional<SwRegionRects>& GetPaintRegion() { return m_oPaintRegion; }
    void DeletePaintRegion() { m_oPaintRegion.reset(); }

    void AddPendingLOKInvalidation( const SwRect& rRect );
    std::vector<SwRect> TakePendingLOKInvalidations();
diff --git a/sw/source/core/view/viewimp.cxx b/sw/source/core/view/viewimp.cxx
index 11a9835..c048f57 100644
--- a/sw/source/core/view/viewimp.cxx
+++ b/sw/source/core/view/viewimp.cxx
@@ -121,20 +121,20 @@ bool SwViewShellImp::AddPaintRect( const SwRect &rRect )
    // In case of tiled rendering the visual area is the last painted tile -> not interesting.
    if ( rRect.Overlaps( m_pShell->VisArea() ) || comphelper::LibreOfficeKit::isActive() )
    {
        if ( !m_pPaintRegion )
        if ( !m_oPaintRegion )
        {
            // In case of normal rendering, this makes sure only visible rectangles are painted.
            // Otherwise get the rectangle of the full document, so all paint rectangles are invalidated.
            const SwRect& rArea = comphelper::LibreOfficeKit::isActive() ? m_pShell->GetLayout()->getFrameArea() : m_pShell->VisArea();
            m_pPaintRegion.reset(new SwRegionRects);
            m_pPaintRegion->ChangeOrigin(rArea);
            m_oPaintRegion.emplace();
            m_oPaintRegion->ChangeOrigin(rArea);
        }
        if(!m_pPaintRegion->empty())
        if(!m_oPaintRegion->empty())
        {
            // This function often gets called with rectangles that line up vertically.
            // Try to extend the last one downwards to include the new one (use Union()
            // in case the new one is actually already contained in the last one).
            SwRect& last = m_pPaintRegion->back();
            SwRect& last = m_oPaintRegion->back();
            if(last.Left() == rRect.Left() && last.Width() == rRect.Width()
                && last.Bottom() + 1 >= rRect.Top() && last.Bottom() <= rRect.Bottom())
            {
@@ -142,21 +142,21 @@ bool SwViewShellImp::AddPaintRect( const SwRect &rRect )
                // And these rectangles lined up vertically often come up in groups
                // that line up horizontally. Try to extend the previous rectangle
                // to the right to include the last one.
                if(m_pPaintRegion->size() > 1)
                if(m_oPaintRegion->size() > 1)
                {
                    SwRect& last2 = (*m_pPaintRegion)[m_pPaintRegion->size() - 2];
                    SwRect& last2 = (*m_oPaintRegion)[m_oPaintRegion->size() - 2];
                    if(last2.Top() == last.Top() && last2.Height() == last.Height()
                        && last2.Right() + 1 >= last.Left() && last2.Right() <= last2.Right())
                    {
                        last2.Union(last);
                        m_pPaintRegion->pop_back();
                        m_oPaintRegion->pop_back();
                        return true;
                    }
                }
                return true;
            }
        }
        (*m_pPaintRegion) += rRect;
        (*m_oPaintRegion) += rRect;
        return true;
    }
    return false;
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index ddc7ca3..d26ecaa 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -319,29 +319,29 @@ void SwViewShell::ImplEndAction( const bool bIdleEnd )
            }
            mbPaintWorks = true;

            std::unique_ptr<SwRegionRects> pRegion = Imp()->TakePaintRegion();
            std::optional<SwRegionRects> oRegion = Imp()->TakePaintRegion();

            //JP 27.11.97: what hid the selection, must also Show it,
            //             else we get Paint errors!
            // e.g. additional mode, page half visible vertically, in the
            // middle a selection and with another cursor jump to left
            // right border. Without ShowCursor the selection disappears.
            bool bShowCursor = pRegion && dynamic_cast<const SwCursorShell*>(this) !=  nullptr;
            bool bShowCursor = oRegion && dynamic_cast<const SwCursorShell*>(this) !=  nullptr;
            if( bShowCursor )
                static_cast<SwCursorShell*>(this)->HideCursors();

            if ( pRegion )
            if ( oRegion )
            {
                SwRootFrame* pCurrentLayout = GetLayout();

                pRegion->LimitToOrigin();
                pRegion->Compress( SwRegionRects::CompressFuzzy );
                oRegion->LimitToOrigin();
                oRegion->Compress( SwRegionRects::CompressFuzzy );

                ScopedVclPtr<VirtualDevice> pVout;
                while ( !pRegion->empty() )
                while ( !oRegion->empty() )
                {
                    SwRect aRect( pRegion->back() );
                    pRegion->pop_back();
                    SwRect aRect( oRegion->back() );
                    oRegion->pop_back();

                    bool bPaint = true;
                    if ( IsEndActionByVirDev() )
@@ -1749,32 +1749,32 @@ bool SwViewShell::CheckInvalidForPaint( const SwRect &rRect )
        aAction.Action(GetWin()->GetOutDev());
        --mnStartAction;

        std::unique_ptr<SwRegionRects> pRegion = Imp()->TakePaintRegion();
        if ( pRegion && aAction.IsBrowseActionStop() )
        std::optional<SwRegionRects> oRegion = Imp()->TakePaintRegion();
        if ( oRegion && aAction.IsBrowseActionStop() )
        {
            //only of interest when something has changed in the visible range
            bool bStop = true;
            for ( size_t i = 0; i < pRegion->size(); ++i )
            for ( size_t i = 0; i < oRegion->size(); ++i )
            {
                const SwRect &rTmp = (*pRegion)[i];
                const SwRect &rTmp = (*oRegion)[i];
                bStop = rTmp.Overlaps( VisArea() );
                if ( !bStop )
                    break;
            }
            if ( bStop )
                pRegion.reset();
                oRegion.reset();
        }

        if ( pRegion )
        if ( oRegion )
        {
            pRegion->LimitToOrigin();
            pRegion->Compress( SwRegionRects::CompressFuzzy );
            oRegion->LimitToOrigin();
            oRegion->Compress( SwRegionRects::CompressFuzzy );
            bRet = false;
            if ( !pRegion->empty() )
            if ( !oRegion->empty() )
            {
                SwRegionRects aRegion( rRect );
                for ( size_t i = 0; i < pRegion->size(); ++i )
                {   const SwRect &rTmp = (*pRegion)[i];
                for ( size_t i = 0; i < oRegion->size(); ++i )
                {   const SwRect &rTmp = (*oRegion)[i];
                    if ( !rRect.Contains( rTmp ) )
                    {
                        InvalidateWindows( rTmp );