[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.0' - sc/source

Ashod Nakashian ashod.nakashian at collabora.co.uk
Sat May 28 16:53:27 UTC 2016


 sc/source/ui/view/gridwin4.cxx |   90 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 83 insertions(+), 7 deletions(-)

New commits:
commit 56e290acca0f51f1aa888f9e7787cfcdc6bb8fd9
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat May 28 10:20:10 2016 -0400

    bccu#1845 - Calc tile rendering very slow
    
    For some reason trying to draw exactly the
    region of the tile results in black tiles.
    That is, when the top rows and left columns
    are not drawn, black tiles show.
    
    This patch still reduces the time to render
    a given tile by limiting the bottom-most row
    and right-most column to the max necessary.
    For large tabs rendering the first few 100
    rows is very fast (<100ms at most).
    
    More work is necessary to reduce drawing time
    for large sheets (when rendering tiles at the
    bottom). Still, even those slow bottom-rows
    are now faster with this patch.
    
    Currently the slowest function by far is
    ScGridWindow::DrawContent.
    
    Change-Id: I6e88c7b3a1c483bf43bfcfb38f4b41ffc08a9744
    Reviewed-on: https://gerrit.libreoffice.org/25586
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 979af6b..850cf9a 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -960,8 +960,10 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
     // page break zoom, and aLogicMode in ScViewData
     pViewData->SetZoom(aFracX, aFracY, true);
 
-    double fTilePosXPixel = static_cast<double>(nTilePosX) * nOutputWidth / nTileWidth;
-    double fTilePosYPixel = static_cast<double>(nTilePosY) * nOutputHeight / nTileHeight;
+    const double fTilePosXPixel = static_cast<double>(nTilePosX) * nOutputWidth / nTileWidth;
+    const double fTilePosYPixel = static_cast<double>(nTilePosY) * nOutputHeight / nTileHeight;
+    const double fTileBottomPixel = static_cast<double>(nTilePosY + nTileHeight) * nOutputHeight / nTileHeight;
+    const double fTileRightPixel = static_cast<double>(nTilePosX + nTileWidth) * nOutputWidth / nTileWidth;
 
     SCTAB nTab = pViewData->GetTabNo();
     ScDocument* pDoc = pViewData->GetDocument();
@@ -972,14 +974,88 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
     // size of the document including drawings, charts, etc.
     pDoc->GetTiledRenderingArea(nTab, nEndCol, nEndRow);
 
-    double fPPTX = pViewData->GetPPTX();
-    double fPPTY = pViewData->GetPPTY();
+    const double fPPTX = pViewData->GetPPTX();
+    const double fPPTY = pViewData->GetPPTY();
 
-    ScTableInfo aTabInfo(nEndRow + 2);
-    pDoc->FillInfo(aTabInfo, nStartCol, nStartRow, nEndCol, nEndRow, nTab, fPPTX, fPPTY, false, false, NULL);
+    // Calculate the tile's first and last rows.
+    SCROW firstRow = -1;
+    SCROW lastRow = -1;
+    double fTopOffsetPixel = 0;
+
+    // Find the first and last rows to paint this tile.
+    sal_uInt16 nDocHeight = ScGlobal::nStdRowHeight;
+    SCROW nDocHeightEndRow = -1;
+    for (SCROW nY = nStartRow; nY <= nEndRow; ++nY)
+    {
+        if (nY > nDocHeightEndRow)
+        {
+            if (ValidRow(nY))
+                nDocHeight = pDoc->GetRowHeight( nY, nTab, nullptr, &nDocHeightEndRow );
+            else
+                nDocHeight = ScGlobal::nStdRowHeight;
+        }
+
+        auto rowHeight = static_cast<sal_uInt16>(nDocHeight * fPPTY);
+        if (fTopOffsetPixel + rowHeight >= fTilePosYPixel)
+        {
+            if (firstRow < 0)
+            {
+                firstRow = nY;
+            }
+            else if (fTopOffsetPixel + rowHeight > fTileBottomPixel)
+            {
+                lastRow = nY;
+                break;
+            }
+        }
+
+        fTopOffsetPixel += rowHeight;
+    }
+
+    firstRow = (firstRow >= 0 ? firstRow : nStartRow);
+    lastRow = (lastRow >= 0 ? lastRow : nEndRow);
+
+    // Find the first and last cols to paint this tile.
+    SCCOL firstCol = -1;
+    SCCOL lastCol = -1;
+    double fLeftOffsetPixel = 0;
+    for (SCCOL nArrCol=nStartCol+3; nArrCol<=nEndCol+2; ++nArrCol)
+    {
+        SCCOL nX = nArrCol-1;
+        if ( ValidCol(nX) )
+        {
+            if (!pDoc->ColHidden(nX, nTab))
+            {
+                sal_uInt16 nColWidth = (sal_uInt16) (pDoc->GetColWidth( nX, nTab ) * fPPTX);
+                if (!nColWidth)
+                    nColWidth = 1;
+
+                if (fLeftOffsetPixel + nColWidth >= fTilePosXPixel)
+                {
+                    if (firstCol < 0)
+                    {
+                        firstCol = nX;
+                    }
+                    else if (fLeftOffsetPixel + nColWidth > fTileRightPixel)
+                    {
+                        lastCol = nX;
+                        break;
+                    }
+                }
+
+                fLeftOffsetPixel += nColWidth;
+            }
+        }
+    }
+
+    firstCol = (firstCol >= 0 ? firstCol : nStartCol);
+    lastCol = (lastCol >= 0 ? lastCol : nEndCol);
+
+    ScTableInfo aTabInfo(nEndRow + 3);
+    pDoc->FillInfo(aTabInfo, nStartCol, nStartRow, lastCol, lastRow, nTab, fPPTX, fPPTY, false, false, NULL);
 
     ScOutputData aOutputData(&rDevice, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
-            -fTilePosXPixel, -fTilePosYPixel, nStartCol, nStartRow, nEndCol, nEndRow,
+            -fTilePosXPixel, -fTilePosYPixel, nStartCol, firstRow, lastCol, lastRow,
             fPPTX, fPPTY);
 
     // setup the SdrPage so that drawinglayer works correctly


More information about the Libreoffice-commits mailing list