tdf#160399 speed up print preview

takes time from 2.5s to 1s for me

Store all of the PrintPageRanges in the ScPrintState
save/restore data structure, means we don't recompute the data
in that structure, so of which is quite expensive.

Change-Id: If65c8ca1cce25ff228c483f173b19b456056dc57
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165646
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/sc/source/ui/inc/printfun.hxx b/sc/source/ui/inc/printfun.hxx
index 2e9dd7bb..04c1019 100644
--- a/sc/source/ui/inc/printfun.hxx
+++ b/sc/source/ui/inc/printfun.hxx
@@ -181,7 +181,9 @@ public:

} // end sc namespace

struct ScPrintState //  Save Variables from ScPrintFunc
// Used to save expensive-to-compute data from ScPrintFunc in between
// uses of ScPrintFunc
struct ScPrintState
{
    SCTAB   nPrintTab;
    SCCOL   nStartCol;
@@ -190,21 +192,13 @@ struct ScPrintState //  Save Variables from ScPrintFunc
    SCROW   nEndRow;
    bool    bPrintAreaValid; // the 4 variables above are set
    sal_uInt16  nZoom;
    size_t  nPagesX;
    size_t  nPagesY;
    tools::Long    nTabPages;
    tools::Long    nTotalPages;
    tools::Long    nPageStart;
    tools::Long    nDocPages;

    // Additional state of page ranges
    bool bSavedStateRanges;
    sc::PrintPageRangesInput aPrintPageRangesInput;
    size_t nTotalY;
    // use shared_ptr to avoid copying this (potentially large) map back and forth
    std::shared_ptr<std::vector<SCCOL>> xPageEndX;
    std::shared_ptr<std::vector<SCROW>> xPageEndY;
    std::shared_ptr<std::map<size_t, ScPageRowEntry>> xPageRows;
    sc::PrintPageRanges m_aRanges;

    ScPrintState()
        : nPrintTab(0)
@@ -214,14 +208,10 @@ struct ScPrintState //  Save Variables from ScPrintFunc
        , nEndRow(0)
        , bPrintAreaValid(false)
        , nZoom(0)
        , nPagesX(0)
        , nPagesY(0)
        , nTabPages(0)
        , nTotalPages(0)
        , nPageStart(0)
        , nDocPages(0)
        , bSavedStateRanges(false)
        , nTotalY(0)
    {}
};

@@ -381,7 +371,7 @@ public:

    void            ResetBreaks( SCTAB nTab );

    void            GetPrintState(ScPrintState& rState, bool bSavePageRanges = false);
    void            GetPrintState(ScPrintState& rState);
    bool            GetLastSourceRange( ScRange& rRange ) const;
    sal_uInt16      GetLeftMargin() const{return nLeftMargin;}
    sal_uInt16      GetRightMargin() const{return nRightMargin;}
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index a9bf8cc..9a6d01a4 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -2154,7 +2154,7 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 
        if (!m_pPrintState || nRenderer == nTabStart)
        {
            m_pPrintState.reset(new ScPrintState());
            pPrintFunc->GetPrintState(*m_pPrintState, true);
            pPrintFunc->GetPrintState(*m_pPrintState);
        }

        aPageSize.Width = convertTwipToMm100(aTwips.Width());
@@ -2434,12 +2434,12 @@ static void lcl_PDFExportMediaShapeScreen(const OutputDevice* pDev, const ScPrin
                        if (bTopDown) // top-bottom page order
                        {
                            nX1 = 0;
                            for (size_t i = 0; i < rState.nPagesX; ++i)
                            for (size_t i = 0; i < rState.m_aRanges.m_nPagesX; ++i)
                            {
                                nX2 = (*rState.xPageEndX)[i];
                                for (size_t j = 0; j < rState.nPagesY; ++j)
                                nX2 = (*rState.m_aRanges.m_xPageEndX)[i];
                                for (size_t j = 0; j < rState.m_aRanges.m_nPagesY; ++j)
                                {
                                    auto& rPageRow = (*rState.xPageRows)[j];
                                    auto& rPageRow = (*rState.m_aRanges.m_xPageRows)[j];
                                    nY1 = rPageRow.GetStartRow();
                                    nY2 = rPageRow.GetEndRow();

@@ -2459,15 +2459,15 @@ static void lcl_PDFExportMediaShapeScreen(const OutputDevice* pDev, const ScPrin
                        }
                        else // left to right page order
                        {
                            for (size_t i = 0; i < rState.nPagesY; ++i)
                            for (size_t i = 0; i < rState.m_aRanges.m_nPagesY; ++i)
                            {
                                auto& rPageRow = (*rState.xPageRows)[i];
                                auto& rPageRow = (*rState.m_aRanges.m_xPageRows)[i];
                                nY1 = rPageRow.GetStartRow();
                                nY2 = rPageRow.GetEndRow();
                                nX1 = 0;
                                for (size_t j = 0; j < rState.nPagesX; ++j)
                                for (size_t j = 0; j < rState.m_aRanges.m_nPagesX; ++j)
                                {
                                    nX2 = (*rState.xPageEndX)[j];
                                    nX2 = (*rState.m_aRanges.m_xPageEndX)[j];

                                    tools::Rectangle aPageRect(rDoc.GetMMRect(nX1, nY1, nX2, nY2, nTab));
                                    tools::Rectangle aTmpRect(aPageRect.GetIntersection(pObj->GetCurrentBoundRect()));
@@ -2772,7 +2772,7 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec
    if (!m_pPrintState)
    {
        m_pPrintState.reset(new ScPrintState());
        pPrintFunc->GetPrintState(*m_pPrintState, true);
        pPrintFunc->GetPrintState(*m_pPrintState);
    }

    lcl_PDFExportBookmarkHelper(pDev, rDoc, pPrintFuncCache, aMark, nTab);
diff --git a/sc/source/ui/view/preview.cxx b/sc/source/ui/view/preview.cxx
index ac7de60..908a766 100644
--- a/sc/source/ui/view/preview.cxx
+++ b/sc/source/ui/view/preview.cxx
@@ -197,13 +197,7 @@ void ScPreview::TestLastPage()
    {
        nTab = 0;
        nPageNo = nTabPage = nTabStart = nDisplayStart = 0;
        aState.nPrintTab = 0;
        aState.nStartCol = aState.nEndCol = 0;
        aState.nStartRow = aState.nEndRow = 0;
        aState.nZoom = 0;
        aState.nPagesX = aState.nPagesY = 0;
        aState.nTabPages = aState.nTotalPages =
        aState.nPageStart = aState.nDocPages = 0;
        aState = ScPrintState();
    }
}

@@ -736,7 +730,7 @@ void ScPreview::SetZoom(sal_uInt16 nNewZoom)
    pViewShell->UpdateNeededScrollBars(true);
    bInSetZoom = false;

    bStateValid = false;
//    bStateValid = false;
    InvalidateLocationData( SfxHintId::ScAccVisAreaChanged );
    DoInvalidate();
    Invalidate();
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
index d9ba4a0..91069c4 100644
--- a/sc/source/ui/view/printfun.cxx
+++ b/sc/source/ui/view/printfun.cxx
@@ -254,29 +254,15 @@ ScPrintFunc::ScPrintFunc(ScDocShell* pShell, SfxPrinter* pNewPrinter, const ScPr
    nEndRow     = rState.nEndRow;
    bPrintAreaValid = rState.bPrintAreaValid;
    nZoom       = rState.nZoom;
    m_aRanges.m_nPagesX = rState.nPagesX;
    m_aRanges.m_nPagesY = rState.nPagesY;
//    m_aRanges.m_nPagesX = rState.nPagesX;
//    m_aRanges.m_nPagesY = rState.nPagesY;
    m_aRanges = rState.m_aRanges;
    nTabPages   = rState.nTabPages;
    nTotalPages = rState.nTotalPages;
    nPageStart  = rState.nPageStart;
    nDocPages   = rState.nDocPages;
    bFromPrintState = true;

    if (rState.bSavedStateRanges)
    {
        m_aRanges.m_nTotalY = rState.nTotalY;
        m_aRanges.m_xPageEndX = rState.xPageEndX;
        m_aRanges.m_xPageEndY = rState.xPageEndY;
        m_aRanges.m_xPageRows = rState.xPageRows;
        m_aRanges.m_aInput = rState.aPrintPageRangesInput;
    }
    else
    {
        m_aRanges.m_xPageEndX = std::make_shared<std::vector<SCCOL>>();
        m_aRanges.m_xPageEndY = std::make_shared<std::vector<SCROW>>();
        m_aRanges.m_xPageRows = std::make_shared<std::map<size_t, ScPageRowEntry>>();
    }

    aSrcOffset = pPrinter->PixelToLogic(pPrinter->GetPageOffsetPixel(), MapMode(MapUnit::Map100thMM));
    Construct( pOptions );
}
@@ -338,33 +324,17 @@ ScPrintFunc::ScPrintFunc(OutputDevice* pOutDev, ScDocShell* pShell, const ScPrin
    nEndRow     = rState.nEndRow;
    bPrintAreaValid = rState.bPrintAreaValid;
    nZoom       = rState.nZoom;
    m_aRanges.m_nPagesX = rState.nPagesX;
    m_aRanges.m_nPagesY = rState.nPagesY;
    m_aRanges   = rState.m_aRanges;
    nTabPages   = rState.nTabPages;
    nTotalPages = rState.nTotalPages;
    nPageStart  = rState.nPageStart;
    nDocPages   = rState.nDocPages;
    bFromPrintState = true;

    if (rState.bSavedStateRanges)
    {
        m_aRanges.m_nTotalY = rState.nTotalY;
        m_aRanges.m_xPageEndX = rState.xPageEndX;
        m_aRanges.m_xPageEndY = rState.xPageEndY;
        m_aRanges.m_xPageRows = rState.xPageRows;
        m_aRanges.m_aInput = rState.aPrintPageRangesInput;
    }
    else
    {
        m_aRanges.m_xPageEndX = std::make_shared<std::vector<SCCOL>>();
        m_aRanges.m_xPageEndY = std::make_shared<std::vector<SCROW>>();
        m_aRanges.m_xPageRows = std::make_shared<std::map<size_t, ScPageRowEntry>>();
    }

    Construct( pOptions );
}

void ScPrintFunc::GetPrintState(ScPrintState& rState,  bool bSavePageRanges)
void ScPrintFunc::GetPrintState(ScPrintState& rState)
{
    rState.nPrintTab    = nPrintTab;
    rState.nStartCol    = nStartCol;
@@ -373,21 +343,11 @@ void ScPrintFunc::GetPrintState(ScPrintState& rState,  bool bSavePageRanges)
    rState.nEndRow      = nEndRow;
    rState.bPrintAreaValid = bPrintAreaValid;
    rState.nZoom        = nZoom;
    rState.nPagesX      = m_aRanges.m_nPagesX;
    rState.nPagesY      = m_aRanges.m_nPagesY;
    rState.nTabPages    = nTabPages;
    rState.nTotalPages  = nTotalPages;
    rState.nPageStart   = nPageStart;
    rState.nDocPages    = nDocPages;
    if (bSavePageRanges)
    {
        rState.bSavedStateRanges = true;
        rState.nTotalY = m_aRanges.m_nTotalY;
        rState.xPageEndX = m_aRanges.m_xPageEndX;
        rState.xPageEndY = m_aRanges.m_xPageEndY;
        rState.xPageRows = m_aRanges.m_xPageRows;
        rState.aPrintPageRangesInput = m_aRanges.m_aInput;
    }
    rState.m_aRanges = m_aRanges;
}

bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const