diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2016-05-28 10:20:10 -0400 |
---|---|---|
committer | Ashod Nakashian <ashnakash@gmail.com> | 2016-05-28 16:53:02 +0000 |
commit | 56e290acca0f51f1aa888f9e7787cfcdc6bb8fd9 (patch) | |
tree | 418098ef9170c990684fea4a568b4fd94a1b02c6 | |
parent | b0c0d4eff911a1d2619c0cac5a0e86220d9747ab (diff) |
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@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
-rw-r--r-- | sc/source/ui/view/gridwin4.cxx | 90 |
1 files changed, 83 insertions, 7 deletions
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index 979af6b6b3a3..850cf9acf3b5 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 |