sc/inc/drwlayer.hxx              |    4 ++--
 sc/qa/unit/ucalc_sort.cxx        |   10 ++++++----
 sc/source/core/data/column4.cxx  |   18 ++++++++++--------
 sc/source/core/data/drwlayer.cxx |   19 ++++++++++---------
 sc/source/core/data/table3.cxx   |   18 ++++++++----------
 5 files changed, 36 insertions(+), 33 deletions(-)

New commits:
commit ea607135ce6bb607508ac6ce6fcc4dae99f297a9
Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de>
Date:   Tue Jan 23 14:22:59 2018 +0100

    Improve performance when looking for draw objects anchored to cells
    
    Look for a whole column at once so we don't have to iterate all draw objects
    for every cell, but only once per column.
    
    Follow-up for 3a2a430ae8e2c1647c18d8904477949f6e2e7941
    
    Change-Id: Ic8740fca7d595528785b432c1cedf4fad4f13ba1
    Reviewed-on: https://gerrit.libreoffice.org/48416
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index d9155d0d90f0..92fc4f0449df 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -182,8 +182,8 @@ public:
     static void             SetCellAnchoredFromPosition( SdrObject &rObj, 
const ScDocument &rDoc, SCTAB nTab );
     static void             UpdateCellAnchorFromPositionEnd( const SdrObject 
&rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool 
bUseLogicRect = true );
     static ScAnchorType     GetAnchorType( const SdrObject& );
-    std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos);
-    bool                    HasObjectsAnchoredInRange(ScRange& rRange);
+    std::map<SCROW, std::vector<SdrObject*>> GetObjectsAnchoredToRange(SCTAB 
nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow);
+    bool HasObjectsAnchoredInRange(ScRange& rRange);
     void MoveObject(SdrObject* pObj, ScAddress& rNewPosition);
 
     // positions for detektive lines
diff --git a/sc/qa/unit/ucalc_sort.cxx b/sc/qa/unit/ucalc_sort.cxx
index eb7d1b79039e..e700c5e4ffe2 100644
--- a/sc/qa/unit/ucalc_sort.cxx
+++ b/sc/qa/unit/ucalc_sort.cxx
@@ -1921,8 +1921,9 @@ void Test::testSortImages()
     ScAddress aCellPos(1, 1, 0);
     pDrawLayer->MoveObject(pObj, aCellPos);
 
-    std::vector<SdrObject*> pObjects = 
pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+    std::map<SCROW, std::vector<SdrObject*>> pRowObjects
+        = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), 
aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pRowObjects[aCellPos.Row()].size());
 
     ScSortParam aSortData;
     aSortData.nCol1 = 0;
@@ -1940,8 +1941,9 @@ void Test::testSortImages()
 
     // check that note is also moved after sorting
     aCellPos = ScAddress(1, 0, 0);
-    pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+    pRowObjects
+        = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), 
aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pRowObjects[aCellPos.Row()].size());
 
     m_pDoc->DeleteTab(0);
 }
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 14a5e89c2b54..d76b17496fb0 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1091,16 +1091,18 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, 
SCROW nRow2, bool bPattern )
     ScDrawLayer* pDrawLayer = GetDoc()->GetDrawLayer();
     if (pDrawLayer)
     {
+        std::map<SCROW, std::vector<SdrObject*>> aThisColRowDrawObjects
+            = pDrawLayer->GetObjectsAnchoredToRange(GetTab(), GetCol(), nRow1, 
nRow2);
+        std::map<SCROW, std::vector<SdrObject*>> aOtherColRowDrawObjects
+            = pDrawLayer->GetObjectsAnchoredToRange(GetTab(), rOther.GetCol(), 
nRow1, nRow2);
         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
         {
-            ScAddress aThisCellPos(GetCol(), nRow, GetTab());
-            ScAddress aOtherCellPos(rOther.GetCol(), nRow, GetTab());
-            std::vector<SdrObject*> pThisColObjects = 
pDrawLayer->GetObjectsAnchoredToCell(aThisCellPos);
-            std::vector<SdrObject*> pOtherColObjects = 
pDrawLayer->GetObjectsAnchoredToCell(aOtherCellPos);
-            if (!pThisColObjects.empty())
-                UpdateDrawObjectsForRow(pThisColObjects, rOther.GetCol(), 
nRow);
-            if (!pOtherColObjects.empty())
-                rOther.UpdateDrawObjectsForRow(pOtherColObjects, GetCol(), 
nRow);
+            std::vector<SdrObject*>& rThisCellDrawObjects = 
aThisColRowDrawObjects[nRow];
+            if (!rThisCellDrawObjects.empty())
+                UpdateDrawObjectsForRow(rThisCellDrawObjects, rOther.GetCol(), 
nRow);
+            std::vector<SdrObject*>& rOtherCellDrawObjects = 
aOtherColRowDrawObjects[nRow];
+            if (!rOtherCellDrawObjects.empty())
+                rOther.UpdateDrawObjectsForRow(rOtherCellDrawObjects, 
GetCol(), nRow);
         }
     }
 
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 6ad031b952d7..311109a77115 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -1994,27 +1994,28 @@ ScAnchorType ScDrawLayer::GetAnchorType( const 
SdrObject &rObj )
     return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : 
SCA_PAGE;
 }
 
-std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& 
rCell)
+std::map<SCROW, std::vector<SdrObject*>>
+ScDrawLayer::GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW 
nStartRow, SCROW nEndRow)
 {
-    SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rCell.Tab()));
+    SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
     if (!pPage || pPage->GetObjCount() < 1)
-        return std::vector<SdrObject*>();
+        return std::map<SCROW, std::vector<SdrObject*>>();
 
-    std::vector<SdrObject*> pObjects;
+    std::map<SCROW, std::vector<SdrObject*>> aRowObjects;
     SdrObjListIter aIter( *pPage, SdrIterMode::Flat );
     SdrObject* pObject = aIter.Next();
-    ScDrawObjData* pObjData;
+    ScRange aRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab);
     while (pObject)
     {
         if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are 
handled differently
         {
-            pObjData = GetObjData(pObject);
-            if (pObjData && pObjData->maStart == rCell) // Object is anchored 
to this cell
-                pObjects.push_back(pObject);
+            ScDrawObjData* pObjData = GetObjData(pObject);
+            if (pObjData && aRange.In(pObjData->maStart))
+                aRowObjects[pObjData->maStart.Row()].push_back(pObject);
         }
         pObject = aIter.Next();
     }
-    return pObjects;
+    return aRowObjects;
 }
 
 bool ScDrawLayer::HasObjectsAnchoredInRange(ScRange& rRange)
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 06c7b8919db4..d25bd8823319 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -433,6 +433,13 @@ void initDataRows(
 
         sc::ColumnBlockConstPosition aBlockPos;
         rCol.InitBlockPosition(aBlockPos);
+        std::map<SCROW, std::vector<SdrObject*>> aRowDrawObjects;
+        ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
+        if (pDrawLayer)
+            aRowDrawObjects = 
pDrawLayer->GetObjectsAnchoredToRange(rTab.GetTab(), nCol, nRow1, nRow2);
+        else
+            SAL_WARN("sc", "Could not retrieve anchored images, no DrawLayer 
available");
+
         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
         {
             ScSortInfoArray::Row& rRow = *rRows[nRow-nRow1];
@@ -440,17 +447,8 @@ void initDataRows(
             rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
             rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
             rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
-            ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
             if (pDrawLayer)
-            {
-                ScAddress aCellPos(nCol, nRow, rTab.GetTab());
-                std::vector<SdrObject*> pObjects = 
pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-                rCell.maDrawObjects = pObjects;
-            }
-            else
-            {
-                SAL_WARN("sc", "Could not retrieve anchored images, no 
DrawLayer available");
-            }
+                rCell.maDrawObjects = aRowDrawObjects[nRow];
 
             if (!bUniformPattern && bPattern)
                 rCell.mpPattern = rCol.GetPattern(nRow);
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to