sc/source/ui/inc/viewdata.hxx  |   52 ++++++++
 sc/source/ui/view/gridwin4.cxx |   92 ++++++++-------
 sc/source/ui/view/tabview.cxx  |  247 -----------------------------------------
 sc/source/ui/view/viewdata.cxx |  198 ++++++++++++++++++++++++++++++++
 4 files changed, 301 insertions(+), 288 deletions(-)

New commits:
commit dee9ccaef8a01e7eb68f8d20210060c49fa6feaa
Author: Marco Cecchetti <marco.cecche...@collabora.com>
Date:   Sun Jan 7 16:54:47 2018 +0100

    lok: sc: exploiting cached position helper for tile rendering
    
    Change-Id: I02b21c5979d1dfb6bb60a05d891c632602fb44ee
    Reviewed-on: https://gerrit.libreoffice.org/47540
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Marco Cecchetti <mrcek...@gmail.com>

diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
index 26f372a33767..a114f4fb7a37 100644
--- a/sc/source/ui/inc/viewdata.hxx
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -148,6 +148,58 @@ public:
     long getPosition(index_type nIndex) const;
 };
 
+class ScBoundsProvider
+{
+    typedef ScPositionHelper::value_type value_type;
+    typedef SCCOLROW index_type;
+
+    ScDocument* pDoc;
+    const SCTAB nTab;
+    const bool bColumnHeader;
+    const index_type MAX_INDEX;
+
+    index_type nFirstIndex;
+    index_type nSecondIndex;
+    long nFirstPositionPx;
+    long nSecondPositionPx;
+
+public:
+    ScBoundsProvider(ScDocument* pD, SCTAB nT, bool bColumnHeader);
+
+    void GetStartIndexAndPosition(SCCOL& nIndex, long& nPosition) const;
+    void GetEndIndexAndPosition(SCCOL& nIndex, long& nPosition) const;
+    void GetStartIndexAndPosition(SCROW& nIndex, long& nPosition) const;
+    void GetEndIndexAndPosition(SCROW& nIndex, long& nPosition) const;
+
+    void Compute(value_type aFirstNearest, value_type aSecondNearest,
+                 long nFirstBound, long nSecondBound);
+
+    void EnlargeStartBy(long nOffset);
+
+    void EnlargeEndBy(long nOffset);
+
+    void EnlargeBy(long nOffset)
+    {
+        EnlargeStartBy(nOffset);
+        EnlargeEndBy(nOffset);
+    }
+
+private:
+    long GetSize(index_type nIndex) const;
+
+    void GetIndexAndPos(index_type nNearestIndex, long nNearestPosition,
+                        long nBound, index_type& nFoundIndex, long& nPosition,
+                        bool bTowards, long nDiff);
+
+    void GeIndexBackwards(index_type nNearestIndex, long nNearestPosition,
+                          long nBound, index_type& nFoundIndex, long& 
nPosition,
+                          bool bTowards);
+
+    void GetIndexTowards(index_type nNearestIndex, long nNearestPosition,
+                         long nBound, index_type& nFoundIndex, long& nPosition,
+                         bool bTowards);
+};
+
 class ScViewDataTable                           // per-sheet data
 {
 friend class ScViewData;
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 5bfda7ea5915..22e07763decb 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -1052,41 +1052,41 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, 
const ScTableInfo& rTableI
         mpNoteMarker->Draw(); // Above the cursor, in drawing map mode
 }
 
-namespace {
-    // Find the row/col just -before- the nPosition in pixels and its offset
-    inline void mapConservativeToRowCol(const ScDocument *pDoc,
-                                        sal_Int32  *nIndex,
-                                        sal_Int32  *nOffset,
-                                        sal_Int32  *nOrigin,
-                                        sal_Int32   nTabNo,
-                                        sal_Int32   nPosition,
-                                        bool        bRowNotCol,
-                                        double      nPPTX,
-                                        double      nPPTY)
+namespace
+{
+    template<typename IndexType>
+    inline
+    void lcl_getBoundingRowColumnforTile(ScViewData* pViewData,
+            long nTileStartPosPx, long nTileEndPosPx,
+            sal_Int32& nTopLeftTileOffset, sal_Int32& nTopLeftTileOrigin,
+            sal_Int32& nTopLeftTileIndex, sal_Int32& nBottomRightTileIndex)
     {
-        long nTmp = 0; // row/col to render for nPosition
-        long nLastScrPos = 0, nScrPos = 0;
-        const long nMaxIndex = bRowNotCol ? MAXROW : MAXCOL;
-        while (nScrPos <= nPosition && nTmp < nMaxIndex)
-        {
-            long nSize = bRowNotCol ? pDoc->GetRowHeight( nTmp, nTabNo )
-                                    : pDoc->GetColWidth( nTmp, nTabNo );
-            if (nSize)
-            {
-                nLastScrPos = nScrPos;
-                nScrPos += ScViewData::ToPixel( nSize, bRowNotCol ? nPPTY : 
nPPTX );
-            } // else - FIXME 'skip multiple hidden rows'
+        const bool bColumnHeader = std::is_same<IndexType, SCCOL>::value;
 
-            *nIndex = nTmp;
-            nTmp++;
-        }
+        SCTAB nTab = pViewData->GetTabNo();
+        ScDocument* pDoc = pViewData->GetDocument();
 
-        // offset into that row/col for nPosition
-        assert (nPosition >= nLastScrPos);
-        *nOffset = (nScrPos == nPosition ? 0 : nPosition - nLastScrPos);
-        *nOrigin = nLastScrPos;
+        IndexType nStartIndex = -1;
+        IndexType nEndIndex = -1;
+        long nStartPosPx = 0;
+        long nEndPosPx = 0;
+
+        ScPositionHelper& rPositionHelper =
+                bColumnHeader ? pViewData->GetLOKWidthHelper() : 
pViewData->GetLOKHeightHelper();
+        const auto& rStartNearest = 
rPositionHelper.getNearestByPosition(nTileStartPosPx);
+        const auto& rEndNearest = 
rPositionHelper.getNearestByPosition(nTileEndPosPx);
+
+        ScBoundsProvider aBoundsProvider(pDoc, nTab, bColumnHeader);
+        aBoundsProvider.Compute(rStartNearest, rEndNearest, nTileStartPosPx, 
nTileEndPosPx);
+        aBoundsProvider.GetStartIndexAndPosition(nStartIndex, nStartPosPx); 
++nStartIndex;
+        aBoundsProvider.GetEndIndexAndPosition(nEndIndex, nEndPosPx);
+
+        nTopLeftTileOffset = nTileStartPosPx - nStartPosPx;
+        nTopLeftTileOrigin = nStartPosPx;
+        nTopLeftTileIndex = nStartIndex;
+        nBottomRightTileIndex = nEndIndex;
     }
-}
+} // anonymous namespace
 
 void ScGridWindow::PaintTile( VirtualDevice& rDevice,
                               int nOutputWidth, int nOutputHeight,
@@ -1125,31 +1125,37 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
     const double fPPTX = pViewData->GetPPTX();
     const double fPPTY = pViewData->GetPPTY();
 
+    // find approximate col/row offsets of nearby.
     sal_Int32 nTopLeftTileRowOffset = 0;
     sal_Int32 nTopLeftTileColOffset = 0;
     sal_Int32 nTopLeftTileRowOrigin = 0;
     sal_Int32 nTopLeftTileColOrigin = 0;
 
-    // find approximate col/row offsets of nearby.
     sal_Int32 nTopLeftTileRow = 0;
     sal_Int32 nTopLeftTileCol = 0;
     sal_Int32 nBottomRightTileRow = 0;
     sal_Int32 nBottomRightTileCol = 0;
-    sal_Int32 nDummy;
-    mapConservativeToRowCol(pDoc, &nTopLeftTileCol, &nTopLeftTileColOffset,
-                            &nTopLeftTileColOrigin,
-                            nTab, fTilePosXPixel, false, fPPTX, fPPTY);
-    mapConservativeToRowCol(pDoc, &nBottomRightTileCol, &nDummy, &nDummy, nTab,
-                            fTileRightPixel, false, fPPTX, fPPTY);
-    mapConservativeToRowCol(pDoc, &nTopLeftTileRow, &nTopLeftTileRowOffset,
-                            &nTopLeftTileRowOrigin,
-                            nTab, fTilePosYPixel, true, fPPTX, fPPTY);
-    mapConservativeToRowCol(pDoc, &nBottomRightTileRow, &nDummy, &nDummy, nTab,
-                            fTileBottomPixel, true, fPPTX, fPPTY);
+
+    lcl_getBoundingRowColumnforTile<SCROW>(pViewData,
+            fTilePosYPixel, fTileBottomPixel,
+            nTopLeftTileRowOffset, nTopLeftTileRowOrigin,
+            nTopLeftTileRow, nBottomRightTileRow);
+
+    lcl_getBoundingRowColumnforTile<SCCOL>(pViewData,
+            fTilePosXPixel, fTileRightPixel,
+            nTopLeftTileColOffset, nTopLeftTileColOrigin,
+            nTopLeftTileCol, nBottomRightTileCol);
+
     // Enlarge
     nBottomRightTileCol++;
     nBottomRightTileRow++;
 
+    if (nBottomRightTileCol > MAXCOL)
+        nBottomRightTileCol = MAXCOL;
+
+    if (nBottomRightTileRow > MAXTILEDROW)
+        nBottomRightTileRow = MAXTILEDROW;
+
     // size of the document including drawings, charts, etc.
     SCCOL nEndCol = 0;
     SCROW nEndRow = 0;
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 1a36f04f2b68..ec2e7c98c637 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -2327,249 +2327,6 @@ long lcl_GetColWidthPx(const ScDocument* pDoc, SCCOL 
nCol, SCTAB nTab)
     return ScViewData::ToPixel(nSize, 1.0 / TWIPS_PER_PIXEL);
 }
 
-} // anonymous namespace
-
-template<typename IndexType>
-class BoundsProvider
-{
-    typedef ScPositionHelper::value_type value_type;
-    typedef IndexType index_type;
-
-    static const index_type MAX_INDEX;
-
-    ScDocument* pDoc;
-    const SCTAB nTab;
-
-    index_type nFirstIndex;
-    index_type nSecondIndex;
-    long nFirstPositionPx;
-    long nSecondPositionPx;
-
-public:
-    BoundsProvider(ScDocument* pD, SCTAB nT)
-        : pDoc(pD)
-        , nTab(nT)
-        , nFirstIndex(-1)
-        , nSecondIndex(-1)
-        , nFirstPositionPx(-1)
-        , nSecondPositionPx(-1)
-    {}
-
-    void GetStartIndexAndPosition(index_type& nIndex, long& nPosition) const
-    {
-        nIndex = nFirstIndex;
-        nPosition = nFirstPositionPx;
-    }
-
-    void GetEndIndexAndPosition(index_type& nIndex, long& nPosition) const
-    {
-        nIndex = nSecondIndex;
-        nPosition = nSecondPositionPx;
-    }
-
-    void Compute(value_type aFirstNearest, value_type aSecondNearest,
-                 long nFirstBound, long nSecondBound);
-
-    void EnlargeStartBy(long nOffset);
-
-    void EnlargeEndBy(long nOffset);
-
-    void EnlargeBy(long nOffset)
-    {
-        EnlargeStartBy(nOffset);
-        EnlargeEndBy(nOffset);
-    }
-
-private:
-    long GetSize(SCROW nIndex) const
-    {
-        return lcl_GetRowHeightPx(pDoc, nIndex, nTab);
-    }
-
-    long GetSize(SCCOL nIndex) const
-    {
-        return lcl_GetColWidthPx(pDoc, nIndex, nTab);
-    }
-
-    void GetIndexAndPos(index_type nNearestIndex, long nNearestPosition,
-                        long nBound, index_type& nFoundIndex, long& nPosition,
-                        bool bTowards, long nDiff)
-    {
-        if (nDiff > 0) // nBound < nNearestPosition
-            GeIndexBackwards(nNearestIndex, nNearestPosition, nBound,
-                             nFoundIndex, nPosition, bTowards);
-        else
-            GetIndexTowards(nNearestIndex, nNearestPosition, nBound,
-                            nFoundIndex, nPosition, bTowards);
-    }
-
-    void GeIndexBackwards(index_type nNearestIndex, long nNearestPosition,
-                          long nBound, index_type& nFoundIndex, long& 
nPosition,
-                          bool bTowards);
-
-    void GetIndexTowards(index_type nNearestIndex, long nNearestPosition,
-                         long nBound, index_type& nFoundIndex, long& nPosition,
-                         bool bTowards);
-};
-
-template<typename IndexType>
-const IndexType BoundsProvider<IndexType>::MAX_INDEX;
-
-template<>
-const SCROW BoundsProvider<SCROW>::MAX_INDEX = MAXTILEDROW;
-
-template<>
-const SCCOL BoundsProvider<SCCOL>::MAX_INDEX = MAXCOL;
-
-template<typename IndexType>
-void BoundsProvider<IndexType>::Compute(
-            value_type aFirstNearest, value_type aSecondNearest,
-            long nFirstBound, long nSecondBound)
-{
-    SAL_INFO("sc.lok.header", "BoundsProvider: nFirstBound: " << nFirstBound
-            << ", nSecondBound: " << nSecondBound);
-
-    long nFirstDiff = aFirstNearest.second - nFirstBound;
-    long nSecondDiff = aSecondNearest.second - nSecondBound;
-    SAL_INFO("sc.lok.header", "BoundsProvider: rTopNearest: index: " << 
aFirstNearest.first
-            << ", pos: " << aFirstNearest.second << ", diff: " << nFirstDiff);
-    SAL_INFO("sc.lok.header", "BoundsProvider: rBottomNearest: index: " << 
aSecondNearest.first
-            << ", pos: " << aSecondNearest.second << ", diff: " << 
nSecondDiff);
-
-    bool bReverse = (std::abs(nFirstDiff) >= std::abs(nSecondDiff));
-
-    if(bReverse)
-    {
-        std::swap(aFirstNearest, aSecondNearest);
-        std::swap(nFirstBound, nSecondBound);
-        std::swap(nFirstDiff, nSecondDiff);
-    }
-
-    index_type nNearestIndex = aFirstNearest.first;
-    long nNearestPosition = aFirstNearest.second;
-    SAL_INFO("sc.lok.header", "BoundsProvider: nearest to first bound:  
nNearestIndex: "
-            << nNearestIndex << ", nNearestPosition: " << nNearestPosition);
-
-    GetIndexAndPos(nNearestIndex, nNearestPosition, nFirstBound,
-                   nFirstIndex, nFirstPositionPx, !bReverse, nFirstDiff);
-    SAL_INFO("sc.lok.header", "BoundsProvider: nFirstIndex: " << nFirstIndex
-            << ", nFirstPositionPx: " << nFirstPositionPx);
-
-    if (std::abs(nSecondDiff) < std::abs(nSecondBound - nFirstPositionPx))
-    {
-        nNearestIndex = aSecondNearest.first;
-        nNearestPosition = aSecondNearest.second;
-    }
-    else
-    {
-        nNearestPosition = nFirstPositionPx;
-        nNearestIndex = nFirstIndex;
-        nSecondDiff = !bReverse ? -1 : 1;
-    }
-    SAL_INFO("sc.lok.header", "BoundsProvider: nearest to second bound: 
nNearestIndex: "
-            << nNearestIndex << ", nNearestPosition: " << nNearestPosition
-            << ", diff: " << nSecondDiff);
-
-    GetIndexAndPos(nNearestIndex, nNearestPosition, nSecondBound,
-                   nSecondIndex, nSecondPositionPx, bReverse, nSecondDiff);
-    SAL_INFO("sc.lok.header", "BoundsProvider: nSecondIndex: " << nSecondIndex
-            << ", nSecondPositionPx: " << nSecondPositionPx);
-
-    if (bReverse)
-    {
-        std::swap(nFirstIndex, nSecondIndex);
-        std::swap(nFirstPositionPx, nSecondPositionPx);
-    }
-}
-
-template<typename IndexType>
-void BoundsProvider<IndexType>::EnlargeStartBy(long nOffset)
-{
-    const index_type nNewFirstIndex =
-            std::max(static_cast<index_type>(-1),
-                     static_cast<index_type>(nFirstIndex - nOffset));
-    for (index_type nIndex = nFirstIndex; nIndex > nNewFirstIndex; --nIndex)
-    {
-        const long nSizePx = GetSize(nIndex);
-        nFirstPositionPx -= nSizePx;
-    }
-    nFirstIndex = nNewFirstIndex;
-    SAL_INFO("sc.lok.header", "BoundsProvider: added offset: nFirstIndex: " << 
nFirstIndex
-            << ", nFirstPositionPx: " << nFirstPositionPx);
-}
-
-template<typename IndexType>
-void BoundsProvider<IndexType>::EnlargeEndBy(long nOffset)
-{
-    const index_type nNewSecondIndex = std::min(MAX_INDEX, 
static_cast<index_type>(nSecondIndex + nOffset));
-    for (index_type nIndex = nSecondIndex + 1; nIndex <= nNewSecondIndex; 
++nIndex)
-    {
-        const long nSizePx = GetSize(nIndex);
-        nSecondPositionPx += nSizePx;
-    }
-    nSecondIndex = nNewSecondIndex;
-    SAL_INFO("sc.lok.header", "BoundsProvider: added offset: nSecondIndex: " 
<< nSecondIndex
-            << ", nSecondPositionPx: " << nSecondPositionPx);
-}
-
-template<typename IndexType>
-void BoundsProvider<IndexType>::GeIndexBackwards(
-            index_type nNearestIndex, long nNearestPosition,
-            long nBound, index_type& nFoundIndex, long& nPosition, bool 
bTowards)
-{
-    nFoundIndex = -1;
-    for (index_type nIndex = nNearestIndex; nIndex >= 0; --nIndex)
-    {
-        if (nBound > nNearestPosition)
-        {
-            nFoundIndex = nIndex; // last index whose nPosition is less than 
nBound
-            nPosition = nNearestPosition;
-            break;
-        }
-
-        const long nSizePx = GetSize(nIndex);
-        nNearestPosition -= nSizePx;
-    }
-    if (!bTowards && nFoundIndex != -1)
-    {
-        nFoundIndex += 1;
-        nPosition += GetSize(nFoundIndex);
-    }
-}
-
-template<typename IndexType>
-void BoundsProvider<IndexType>::GetIndexTowards(
-            index_type nNearestIndex, long nNearestPosition,
-            long nBound, index_type& nFoundIndex, long& nPosition, bool 
bTowards)
-{
-    nFoundIndex = -2;
-    for (index_type nIndex = nNearestIndex + 1; nIndex <= MAX_INDEX; ++nIndex)
-    {
-        const long nSizePx = GetSize(nIndex);
-        nNearestPosition += nSizePx;
-
-        if (nNearestPosition > nBound)
-        {
-            nFoundIndex = nIndex; // first index whose nPosition is greater 
than nBound
-            nPosition = nNearestPosition;
-            break;
-        }
-    }
-    if (nFoundIndex == -2)
-    {
-        nFoundIndex = MAX_INDEX;
-        nPosition = nNearestPosition;
-    }
-    else if (bTowards)
-    {
-        nPosition -= GetSize(nFoundIndex);
-        nFoundIndex -= 1;
-    }
-}
-
-namespace
-{
-
 void lcl_getGroupIndexes(const ScOutlineArray& rArray, SCCOLROW nStart, 
SCCOLROW nEnd, std::vector<size_t>& rGroupIndexes)
 {
     rGroupIndexes.clear();
@@ -2748,7 +2505,7 @@ OUString ScTabView::getRowColumnHeaders(const 
tools::Rectangle& rRectangle)
         const auto& rTopNearest = 
aViewData.GetLOKHeightHelper().getNearestByPosition(nRectTopPx);
         const auto& rBottomNearest = 
aViewData.GetLOKHeightHelper().getNearestByPosition(nRectBottomPx);
 
-        BoundsProvider<SCROW> aBoundingRowsProvider(pDoc, nTab);
+        ScBoundsProvider aBoundingRowsProvider(pDoc, nTab, /*bColumnHeader: */ 
false);
         aBoundingRowsProvider.Compute(rTopNearest, rBottomNearest, nRectTopPx, 
nRectBottomPx);
         aBoundingRowsProvider.EnlargeBy(2);
         aBoundingRowsProvider.GetStartIndexAndPosition(nStartRow, 
nStartHeightPx);
@@ -2890,7 +2647,7 @@ OUString ScTabView::getRowColumnHeaders(const 
tools::Rectangle& rRectangle)
         const auto& rLeftNearest = 
aViewData.GetLOKWidthHelper().getNearestByPosition(nRectLeftPx);
         const auto& rRightNearest = 
aViewData.GetLOKWidthHelper().getNearestByPosition(nRectRightPx);
 
-        BoundsProvider<SCCOL> aBoundingColsProvider(pDoc, nTab);
+        ScBoundsProvider aBoundingColsProvider(pDoc, nTab, /*bColumnHeader: */ 
true);
         aBoundingColsProvider.Compute(rLeftNearest, rRightNearest, 
nRectLeftPx, nRectRightPx);
         aBoundingColsProvider.EnlargeBy(2);
         aBoundingColsProvider.GetStartIndexAndPosition(nStartCol, 
nStartWidthPx);
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index 8e5d5260fdcb..a46bf68bb7f3 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -231,6 +231,204 @@ long ScPositionHelper::getPosition(index_type nIndex) 
const
     return it->second;
 }
 
+ScBoundsProvider::ScBoundsProvider(ScDocument* pD, SCTAB nT, bool bColHeader)
+    : pDoc(pD)
+    , nTab(nT)
+    , bColumnHeader(bColHeader)
+    , MAX_INDEX(bColHeader ? MAXCOL : MAXTILEDROW)
+    , nFirstIndex(-1)
+    , nSecondIndex(-1)
+    , nFirstPositionPx(-1)
+    , nSecondPositionPx(-1)
+{}
+
+void ScBoundsProvider::GetStartIndexAndPosition(SCCOL& nIndex, long& 
nPosition) const
+{
+    assert(bColumnHeader);
+    nIndex = nFirstIndex;
+    nPosition = nFirstPositionPx;
+}
+
+void ScBoundsProvider::GetEndIndexAndPosition(SCCOL& nIndex, long& nPosition) 
const
+{
+    assert(bColumnHeader);
+    nIndex = nSecondIndex;
+    nPosition = nSecondPositionPx;
+}
+
+void ScBoundsProvider::GetStartIndexAndPosition(SCROW& nIndex, long& 
nPosition) const
+{
+    assert(!bColumnHeader);
+    nIndex = nFirstIndex;
+    nPosition = nFirstPositionPx;
+}
+
+void ScBoundsProvider::GetEndIndexAndPosition(SCROW& nIndex, long& nPosition) 
const
+{
+    assert(!bColumnHeader);
+    nIndex = nSecondIndex;
+    nPosition = nSecondPositionPx;
+}
+
+long ScBoundsProvider::GetSize(index_type nIndex) const
+{
+    const sal_uInt16 nSize = bColumnHeader ? pDoc->GetColWidth(nIndex, nTab) : 
pDoc->GetRowHeight(nIndex, nTab);
+    return ScViewData::ToPixel(nSize, 1.0 / TWIPS_PER_PIXEL);
+}
+
+void ScBoundsProvider::GetIndexAndPos(index_type nNearestIndex, long 
nNearestPosition,
+                    long nBound, index_type& nFoundIndex, long& nPosition,
+                    bool bTowards, long nDiff)
+{
+    if (nDiff > 0) // nBound < nNearestPosition
+        GeIndexBackwards(nNearestIndex, nNearestPosition, nBound,
+                         nFoundIndex, nPosition, bTowards);
+    else
+        GetIndexTowards(nNearestIndex, nNearestPosition, nBound,
+                        nFoundIndex, nPosition, bTowards);
+}
+
+void ScBoundsProvider::Compute(
+            value_type aFirstNearest, value_type aSecondNearest,
+            long nFirstBound, long nSecondBound)
+{
+    SAL_INFO("sc.lok.header", "BoundsProvider: nFirstBound: " << nFirstBound
+            << ", nSecondBound: " << nSecondBound);
+
+    long nFirstDiff = aFirstNearest.second - nFirstBound;
+    long nSecondDiff = aSecondNearest.second - nSecondBound;
+    SAL_INFO("sc.lok.header", "BoundsProvider: rTopNearest: index: " << 
aFirstNearest.first
+            << ", pos: " << aFirstNearest.second << ", diff: " << nFirstDiff);
+    SAL_INFO("sc.lok.header", "BoundsProvider: rBottomNearest: index: " << 
aSecondNearest.first
+            << ", pos: " << aSecondNearest.second << ", diff: " << 
nSecondDiff);
+
+    bool bReverse = (std::abs(nFirstDiff) >= std::abs(nSecondDiff));
+
+    if(bReverse)
+    {
+        std::swap(aFirstNearest, aSecondNearest);
+        std::swap(nFirstBound, nSecondBound);
+        std::swap(nFirstDiff, nSecondDiff);
+    }
+
+    index_type nNearestIndex = aFirstNearest.first;
+    long nNearestPosition = aFirstNearest.second;
+    SAL_INFO("sc.lok.header", "BoundsProvider: nearest to first bound:  
nNearestIndex: "
+            << nNearestIndex << ", nNearestPosition: " << nNearestPosition);
+
+    GetIndexAndPos(nNearestIndex, nNearestPosition, nFirstBound,
+                   nFirstIndex, nFirstPositionPx, !bReverse, nFirstDiff);
+    SAL_INFO("sc.lok.header", "BoundsProvider: nFirstIndex: " << nFirstIndex
+            << ", nFirstPositionPx: " << nFirstPositionPx);
+
+    if (std::abs(nSecondDiff) < std::abs(nSecondBound - nFirstPositionPx))
+    {
+        nNearestIndex = aSecondNearest.first;
+        nNearestPosition = aSecondNearest.second;
+    }
+    else
+    {
+        nNearestPosition = nFirstPositionPx;
+        nNearestIndex = nFirstIndex;
+        nSecondDiff = !bReverse ? -1 : 1;
+    }
+    SAL_INFO("sc.lok.header", "BoundsProvider: nearest to second bound: 
nNearestIndex: "
+            << nNearestIndex << ", nNearestPosition: " << nNearestPosition
+            << ", diff: " << nSecondDiff);
+
+    GetIndexAndPos(nNearestIndex, nNearestPosition, nSecondBound,
+                   nSecondIndex, nSecondPositionPx, bReverse, nSecondDiff);
+    SAL_INFO("sc.lok.header", "BoundsProvider: nSecondIndex: " << nSecondIndex
+            << ", nSecondPositionPx: " << nSecondPositionPx);
+
+    if (bReverse)
+    {
+        std::swap(nFirstIndex, nSecondIndex);
+        std::swap(nFirstPositionPx, nSecondPositionPx);
+    }
+}
+
+void ScBoundsProvider::EnlargeStartBy(long nOffset)
+{
+    const index_type nNewFirstIndex =
+            std::max(static_cast<index_type>(-1),
+                     static_cast<index_type>(nFirstIndex - nOffset));
+    for (index_type nIndex = nFirstIndex; nIndex > nNewFirstIndex; --nIndex)
+    {
+        const long nSizePx = GetSize(nIndex);
+        nFirstPositionPx -= nSizePx;
+    }
+    nFirstIndex = nNewFirstIndex;
+    SAL_INFO("sc.lok.header", "BoundsProvider: added offset: nFirstIndex: " << 
nFirstIndex
+            << ", nFirstPositionPx: " << nFirstPositionPx);
+}
+
+void ScBoundsProvider::EnlargeEndBy(long nOffset)
+{
+    const index_type nNewSecondIndex = std::min(MAX_INDEX, 
static_cast<index_type>(nSecondIndex + nOffset));
+    for (index_type nIndex = nSecondIndex + 1; nIndex <= nNewSecondIndex; 
++nIndex)
+    {
+        const long nSizePx = GetSize(nIndex);
+        nSecondPositionPx += nSizePx;
+    }
+    nSecondIndex = nNewSecondIndex;
+    SAL_INFO("sc.lok.header", "BoundsProvider: added offset: nSecondIndex: " 
<< nSecondIndex
+            << ", nSecondPositionPx: " << nSecondPositionPx);
+}
+
+void ScBoundsProvider::GeIndexBackwards(
+            index_type nNearestIndex, long nNearestPosition,
+            long nBound, index_type& nFoundIndex, long& nPosition, bool 
bTowards)
+{
+    nFoundIndex = -1;
+    for (index_type nIndex = nNearestIndex; nIndex >= 0; --nIndex)
+    {
+        if (nBound >= nNearestPosition)
+        {
+            nFoundIndex = nIndex; // last index whose nPosition is less than 
nBound
+            nPosition = nNearestPosition;
+            break;
+        }
+
+        const long nSizePx = GetSize(nIndex);
+        nNearestPosition -= nSizePx;
+    }
+    if (!bTowards && nFoundIndex != -1)
+    {
+        nFoundIndex += 1;
+        nPosition += GetSize(nFoundIndex);
+    }
+}
+
+void ScBoundsProvider::GetIndexTowards(
+            index_type nNearestIndex, long nNearestPosition,
+            long nBound, index_type& nFoundIndex, long& nPosition, bool 
bTowards)
+{
+    nFoundIndex = -2;
+    for (index_type nIndex = nNearestIndex + 1; nIndex <= MAX_INDEX; ++nIndex)
+    {
+        const long nSizePx = GetSize(nIndex);
+        nNearestPosition += nSizePx;
+
+        if (nNearestPosition > nBound)
+        {
+            nFoundIndex = nIndex; // first index whose nPosition is greater 
than nBound
+            nPosition = nNearestPosition;
+            break;
+        }
+    }
+    if (nFoundIndex == -2)
+    {
+        nFoundIndex = MAX_INDEX;
+        nPosition = nNearestPosition;
+    }
+    else if (bTowards)
+    {
+        nPosition -= GetSize(nFoundIndex);
+        nFoundIndex -= 1;
+    }
+}
+
 ScViewDataTable::ScViewDataTable() :
                 eZoomType( SvxZoomType::PERCENT ),
                 aZoomX( 1,1 ),
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to