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

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Jun 13 03:04:49 UTC 2016


 sc/source/ui/view/gridwin4.cxx |  206 +++++++++++++++++++++++------------------
 1 file changed, 120 insertions(+), 86 deletions(-)

New commits:
commit ecc33ce663625ae1114a56fe3d1625c5ed274685
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat Jun 4 20:39:20 2016 -0400

    LOK: fast tile rendering (text only)
    
    For every tile, the bounding columns and
    rows are found. The origin of the device
    is set to the top-left corner of the
    top-most row and left-most column, respectively.
    
    Because tiles don't have to align with a
    column or row, the ScrX and ScrY (Screen Position)
    coordinates are set to the offset a tile has
    to its top-most row and left-most column.
    
    Rendering of text is super fast as the
    minimum area is rendered for a given tile.
    
    However, it doesn't work for embedded objects.
    This is addressed in a separate patch.
    
    One pending issue with text is when editing.
    The text doesn't correctly render while
    editing a cell. This is almost certainly
    because the edit control is not rendered
    at the correct offset (in the middle top
    row it can be seen showing up to the right
    of where it should be).
    
    Change-Id: I6f1ea0aa2f19a7fda926f596a2009290680c593c
    Reviewed-on: https://gerrit.libreoffice.org/26203
    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 830abde..a68871d 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -30,6 +30,7 @@
 #include <vcl/settings.hxx>
 
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <comphelper/lok.hxx>
 
 #include <svx/svdview.hxx>
 #include "tabvwsh.hxx"
@@ -384,7 +385,7 @@ void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMod
     // all the rendering should go through PaintTile() in that case.
     // TODO revisit if we can actually turn this into an assert(), and clean
     // up the callers
-    if (rDoc.GetDrawLayer()->isTiledRendering())
+    if (comphelper::LibreOfficeKit::isActive())
         return;
 
     ScModule* pScMod = SC_MOD();
@@ -469,8 +470,8 @@ void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMod
 
     ScTableInfo aTabInfo;
     rDoc.FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
-                                        nPPTX, nPPTY, false, rOpts.GetOption(VOPT_FORMULAS),
-                                        &pViewData->GetMarkData() );
+                   nPPTX, nPPTY, false, rOpts.GetOption(VOPT_FORMULAS),
+                   &pViewData->GetMarkData() );
 
     Fraction aZoomX = pViewData->GetZoomX();
     Fraction aZoomY = pViewData->GetZoomY();
@@ -526,7 +527,7 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
     ScDocShell* pDocSh = pViewData->GetDocShell();
     ScDocument& rDoc = pDocSh->GetDocument();
     const ScViewOptions& rOpts = pViewData->GetOptions();
-    bool bIsTiledRendering = rDoc.GetDrawLayer()->isTiledRendering();
+    bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
 
     SCTAB nTab = aOutputData.nTab;
     SCCOL nX1 = aOutputData.nX1;
@@ -590,6 +591,8 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
             bEditMode = false;
     }
 
+    const MapMode aOriginalMode = rDevice.GetMapMode();
+
     // define drawing layer map mode and paint rectangle
     MapMode aDrawMode = GetDrawMapMode();
     if (bIsTiledRendering)
@@ -812,10 +815,27 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
 
     pContentDev->SetMapMode(aDrawMode);
 
+    // Bitmaps and buttons are in absolute pixel coordinates.
+    const MapMode aOrig = pContentDev->GetMapMode();
+    if (bIsTiledRendering)
+    {
+        MapMode aNew = aOrig;
+        auto aOrigin = aOriginalMode.GetOrigin();
+        aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + nScrX);
+        aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + nScrY);
+        aNew.SetOrigin(aOrigin);
+        pContentDev->SetMapMode(aNew);
+    }
+
     DrawRedraw( aOutputData, eMode, SC_LAYER_FRONT );
     DrawRedraw( aOutputData, eMode, SC_LAYER_INTERN );
     DrawSdrGrid( aDrawingRectLogic, pContentDev );
 
+    if (bIsTiledRendering)
+    {
+        pContentDev->SetMapMode(aOrig);
+    }
+
     if (!bIsInScroll)                               // Drawing Markierungen
     {
         if(eMode == SC_UPDATE_CHANGED && aOutputData.SetChangedClip())
@@ -934,6 +954,41 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
         mpNoteMarker->Draw(); // ueber den Cursor, im Drawing-MapMode
 }
 
+namespace {
+    // Find the row/col just -before- the nPosition in pixels and its offset
+    inline void mapConservativeToRowCol(ScDocument *pDoc,
+                                        sal_Int32  *nIndex,
+                                        sal_Int32  *nOffset,
+                                        sal_Int32  *nOrigin,
+                                        sal_Int32   nTabNo,
+                                        sal_Int32   nPosition,
+                                        bool        bRowNotCol,
+                                        double      nPPTX,
+                                        double      nPPTY)
+    {
+        long nTmp = 0; // row/col to render for nPosition
+        long nLastScrPos = 0, nScrPos = 0;
+        while (nScrPos <= nPosition && nTmp < MAXROW)
+        {
+            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'
+
+            *nIndex = nTmp;
+            nTmp++;
+        }
+
+        // offset into that row/col for nPosition
+        assert (nPosition >= nLastScrPos);
+        *nOffset = (nScrPos == nPosition ? 0 : nPosition - nLastScrPos);
+        *nOrigin = nLastScrPos;
+    }
+}
+
 void ScGridWindow::PaintTile( VirtualDevice& rDevice,
                               int nOutputWidth, int nOutputHeight,
                               int nTilePosX, int nTilePosY,
@@ -968,8 +1023,8 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
     SCTAB nTab = pViewData->GetTabNo();
     ScDocument* pDoc = pViewData->GetDocument();
 
-    SCCOL nStartCol = 0, nEndCol = 0;
-    SCROW nStartRow = 0, nEndRow = 0;
+    SCCOL nEndCol = 0;
+    SCROW nEndRow = 0;
 
     // size of the document including drawings, charts, etc.
     pDoc->GetTiledRenderingArea(nTab, nEndCol, nEndRow);
@@ -977,91 +1032,68 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
     const double fPPTX = pViewData->GetPPTX();
     const double fPPTY = pViewData->GetPPTY();
 
-    // 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);
-
-    auto capacity = std::min(nEndRow + 3, sal_Int32(1002));
-    ScTableInfo aTabInfo(capacity);
-    pDoc->FillInfo(aTabInfo, nStartCol, nStartRow, lastCol, lastRow, nTab, fPPTX, fPPTY, false, false, NULL);
+    ScTableInfo aTabInfo(nEndRow + 3);
+    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);
+    // Enlarge
+    nBottomRightTileCol++;
+    nBottomRightTileRow++;
+
+    nTopLeftTileCol = std::min(nTopLeftTileCol, (sal_Int32)nEndCol);
+    nTopLeftTileRow = std::min(nTopLeftTileRow, (sal_Int32)nEndRow);
+    nTopLeftTileCol = std::max(nTopLeftTileCol, 0);
+    nTopLeftTileRow = std::max(nTopLeftTileRow, 0);
+    nBottomRightTileCol = std::min(nBottomRightTileCol, (sal_Int32)nEndCol);
+    nBottomRightTileRow = std::min(nBottomRightTileRow, (sal_Int32)nEndRow);
+    nTopLeftTileColOrigin = nTopLeftTileColOrigin * TWIPS_PER_PIXEL;
+    nTopLeftTileRowOrigin = nTopLeftTileRowOrigin * TWIPS_PER_PIXEL;
+
+    // Checkout -> 'rDoc.ExtendMerge' ... if we miss merged cells.
+
+    // Origin must be the offset of the first col and row
+    // containing our top-left pixel.
+    const MapMode aOriginalMode = rDevice.GetMapMode();
+    MapMode aAbsMode = aOriginalMode;
+    const Point aOrigin(-nTopLeftTileColOrigin, -nTopLeftTileRowOrigin);
+    aAbsMode.SetOrigin(aOrigin);
+    rDevice.SetMapMode(aAbsMode);
+
+    pDoc->FillInfo(aTabInfo, nTopLeftTileCol, nTopLeftTileRow,
+                   nBottomRightTileCol, nBottomRightTileRow,
+                   nTab, fPPTX, fPPTY, false, false);
+
+// FIXME: is this called some
+//        Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
 
     ScOutputData aOutputData(&rDevice, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
-            -fTilePosXPixel, -fTilePosYPixel, nStartCol, firstRow, lastCol, lastRow,
-            fPPTX, fPPTY);
+                             -nTopLeftTileColOffset,
+                             -nTopLeftTileRowOffset,
+                             nTopLeftTileCol, nTopLeftTileRow,
+                             nBottomRightTileCol, nBottomRightTileRow,
+                             fPPTX, fPPTY);
 
     // setup the SdrPage so that drawinglayer works correctly
     ScDrawLayer* pModel = pDoc->GetDrawLayer();
-    boost::scoped_ptr<FmFormView> pDrawView;
+    std::unique_ptr<FmFormView> pDrawView;
     if (pModel)
     {
         pDrawView.reset(new FmFormView(pModel, &rDevice));
@@ -1071,6 +1103,8 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
 
     // draw the content
     DrawContent(rDevice, aTabInfo, aOutputData, true, SC_UPDATE_ALL);
+
+    rDevice.SetMapMode(aOriginalMode);
 }
 
 void ScGridWindow::LogicInvalidate(const Rectangle* pRectangle)


More information about the Libreoffice-commits mailing list