[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.1' - 4 commits - comphelper/source include/comphelper sc/source svx/source vcl/source

Ashod Nakashian ashod.nakashian at collabora.co.uk
Fri Sep 16 12:46:55 UTC 2016


 comphelper/source/misc/lok.cxx                     |   24 ++
 include/comphelper/lok.hxx                         |   12 +
 sc/source/ui/view/gridwin4.cxx                     |  216 ++++++++++++---------
 svx/source/sdr/contact/objectcontactofpageview.cxx |   31 ++-
 vcl/source/outdev/bitmap.cxx                       |   14 +
 5 files changed, 212 insertions(+), 85 deletions(-)

New commits:
commit a03179ce1b9365eedeb782a4d5766f620ccadd6e
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Thu Jun 16 07:28:58 2016 -0400

    LOK: tile rendering regression fix
    
    Calc fast rendering requires us to offset
    the are being rendered and shift all
    bitmaps accordingly. This however is
    breaking Impress rendering since the
    offseting logic is common (in svx and vcl).
    
    This adds new API to enable or disable
    this local rendering (as opposed to
    rendering a full document as was previously
    done.
    
    The new flag is then set by Calc to
    enable the offseting logic in isolation
    without affecting other applications.
    
    In one case isolation was achieved by
    checking the MapModeUnit.
    
    Change-Id: Ia0aadfc3f6df7c1a891b97dc731f5897414c9420
    Reviewed-on: https://gerrit.libreoffice.org/26367
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 60fdcda65bad242f99895cb453182578250fbdea)
    Reviewed-on: https://gerrit.libreoffice.org/26378
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit c337011d2052ec3ddb80e61bcc4b0574b4e898ba)

diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx
index a6abd2a..a321260 100644
--- a/comphelper/source/misc/lok.cxx
+++ b/comphelper/source/misc/lok.cxx
@@ -17,6 +17,8 @@ namespace LibreOfficeKit
 
 static bool g_bActive(false);
 
+static bool g_bViewCallback(true);
+
 void setActive(bool bActive)
 {
     g_bActive = bActive;
@@ -27,6 +29,28 @@ bool isActive()
     return g_bActive;
 }
 
+void setViewCallback(bool bViewCallback)
+{
+    g_bViewCallback = bViewCallback;
+}
+
+bool isViewCallback()
+{
+    return g_bViewCallback;
+}
+
+static bool g_bLocalRendering(false);
+
+void setLocalRendering(bool bLocalRendering)
+{
+    g_bLocalRendering = bLocalRendering;
+}
+
+bool isLocalRendering()
+{
+    return g_bLocalRendering;
+}
+
 static void (*pStatusIndicatorCallback)(void *data, statusIndicatorCallbackType type, int percent)(nullptr);
 static void *pStatusIndicatorCallbackData(nullptr);
 
diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx
index 79fa115..8afd3d8 100644
--- a/include/comphelper/lok.hxx
+++ b/include/comphelper/lok.hxx
@@ -36,6 +36,18 @@ COMPHELPER_DLLPUBLIC void setStatusIndicatorCallback(void (*callback)(void *data
 // Check whether the code is running as invoked through LibreOfficeKit.
 COMPHELPER_DLLPUBLIC bool isActive();
 
+/// Shift the coordinates before rendering each bitmap.
+/// Used by Calc to render each tile separately.
+/// This should be unnecessary (and removed) once Calc
+/// moves to using 100MM Unit.
+COMPHELPER_DLLPUBLIC void setLocalRendering(bool bLocalRendering = true);
+COMPHELPER_DLLPUBLIC bool isLocalRendering();
+
+/// Check whether clients register a callback for each view.
+COMPHELPER_DLLPUBLIC bool isViewCallback();
+/// Set whether clients register a callback for each view.
+COMPHELPER_DLLPUBLIC void setViewCallback(bool bViewCallback);
+
 // Status indicator handling. Even if in theory there could be several status indicators active at
 // the same time, in practice there is only one at a time, so we don't handle any identification of
 // status indicator in this API.
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 33fb2aa..7ce585c 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -826,6 +826,7 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
                         aOrigin.getY() - aOrigin.getY() / twipFactor);
         aNew.SetOrigin(aOrigin);
         pContentDev->SetMapMode(aNew);
+        comphelper::LibreOfficeKit::setLocalRendering();
     }
 
     DrawRedraw( aOutputData, eMode, SC_LAYER_FRONT );
diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx
index 71522cf..b6f244a 100644
--- a/svx/source/sdr/contact/objectcontactofpageview.cxx
+++ b/svx/source/sdr/contact/objectcontactofpageview.cxx
@@ -232,7 +232,8 @@ namespace sdr
 
                 // transform to world coordinates
                 aViewRange.transform(rTargetOutDev.GetInverseViewTransformation());
-                if (comphelper::LibreOfficeKit::isActive())
+                if (comphelper::LibreOfficeKit::isActive() &&
+                    comphelper::LibreOfficeKit::isLocalRendering())
                 {
                     const int TWIPS_PER_PIXEL = 15;
                     aViewRange = basegfx::B2DRange(aViewRange.getMinimum().getX(),
@@ -309,7 +310,8 @@ namespace sdr
                     drawinglayer::processor2d::createProcessor2DFromOutputDevice(
                         rTargetOutDev, getViewInformation2D()));
 
-                if (comphelper::LibreOfficeKit::isActive())
+                if (comphelper::LibreOfficeKit::isActive() &&
+                    comphelper::LibreOfficeKit::isLocalRendering())
                 {
                     // Restore the origin.
                     MapMode aMapMode = pOutDev->GetMapMode();
@@ -322,7 +324,8 @@ namespace sdr
                     pProcessor2D->process(xPrimitiveSequence);
                 }
 
-                if (comphelper::LibreOfficeKit::isActive())
+                if (comphelper::LibreOfficeKit::isActive() &&
+                    comphelper::LibreOfficeKit::isLocalRendering())
                 {
                     // Restore the original map-mode.
                     pOutDev->SetMapMode(aOrigMapMode);
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 0e2dd19..ef54576 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -1193,14 +1193,14 @@ void OutputDevice::DrawTransformedBitmapEx(
             basegfx::fround(aScale.getX() + aTranslate.getX()) - aDestPt.X(),
             basegfx::fround(aScale.getY() + aTranslate.getY()) - aDestPt.Y());
         const Point aOrigin = GetMapMode().GetOrigin();
-        if (comphelper::LibreOfficeKit::isActive())
+        if (comphelper::LibreOfficeKit::isActive() && GetMapMode().GetMapUnit() != MAP_PIXEL)
         {
             aDestPt.Move(aOrigin.getX(), aOrigin.getY());
             EnableMapMode(false);
         }
 
         DrawBitmapEx(aDestPt, aDestSize, rBitmapEx);
-        if (comphelper::LibreOfficeKit::isActive())
+        if (comphelper::LibreOfficeKit::isActive() && GetMapMode().GetMapUnit() != MAP_PIXEL)
         {
             EnableMapMode(true);
             aDestPt.Move(-aOrigin.getX(), -aOrigin.getY());
commit 95e019be871f16636cc3b2e95972ce91e5c8558d
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun Jun 12 22:04:50 2016 -0400

    LOK: fast tile rendering (cell editing)
    
    Cell editing uses editeng which has a different
    set of requirements. The coordinates are in
    100th mm and so we have to convert the ofsets
    to 100mm.
    
    Change-Id: I278457ffc2273eb786101875c85ddfb959d4c5e3
    Reviewed-on: https://gerrit.libreoffice.org/26205
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 0dbffca63191712d9f77297061a3d4651b8410aa)

diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index aba5687..33fb2aa 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -943,6 +943,19 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
         // paint the background
         rDevice.DrawRect(rDevice.PixelToLogic(aBackground));
 
+        if (bIsTiledRendering)
+        {
+            auto aOrigin = aOriginalMode.GetOrigin();
+            aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + nScrX);
+            aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + nScrY);
+            static const double twipFactor = 15 * 1.76388889; // 26.45833335
+            aOrigin = Point(aOrigin.getX() * twipFactor,
+                            aOrigin.getY() * twipFactor);
+            MapMode aNew = rDevice.GetMapMode();
+            aNew.SetOrigin(aOrigin);
+            rDevice.SetMapMode(aNew);
+        }
+
         // paint the editeng text
         pEditView->Paint(rDevice.PixelToLogic(Rectangle(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()))), &rDevice);
         rDevice.SetMapMode(MAP_PIXEL);
commit 11ab43d83615df6e08b7e8061e2fd25c6609b30e
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat Jun 4 21:29:30 2016 -0400

    LOK: fast tile rendering (graphics and buttons)
    
    Since embedded graphics and buttons use
    absolute coordinates, we set the origin
    to be the top-left corner of the tile.
    This includes the origin + ScrPos (see
    previous patch).
    
    Then, the coordinates of the graphic is
    shifted by this amount to make sure it
    renders in its relative position to the tile.
    
    This renders embedded graphics and buttons
    at their correct position, with some limitations.
    
    Tiles large enough to cover a graphic object
    show the graphic object where it should be.
    However, rendering a relatively small tile
    doesn't render the graphic. This seems to be
    an issue with moving the graphic's coordinate
    at a later stage than the 2D Processor decides
    what objects intersect with the 'view area'
    that is rendered.
    
    Another issue is that graphs don't render.
    What they seem to suffer is incorrect scale
    and a fix coordinates (they show up as tiny
    thumbnails at the top-left corner and grow
    in proportion to the real graph when resized).
    
    These shall be addressed in a separate patch.
    
    Reviewed-on: https://gerrit.libreoffice.org/26204
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 5f01d80f75dc86b393cc2fdb66b94aece964c674)
    
    Change-Id: I4b71bf5f2e357d1114d46022bc00905ceed0c2f9

diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 3219031..aba5687 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -821,6 +821,9 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
         auto aOrigin = aOriginalMode.GetOrigin();
         aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + nScrX);
         aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + nScrY);
+        static const double twipFactor = 15 * 1.76388889; // 26.45833335
+        aOrigin = Point(aOrigin.getX() - aOrigin.getX() / twipFactor,
+                        aOrigin.getY() - aOrigin.getY() / twipFactor);
         aNew.SetOrigin(aOrigin);
         pContentDev->SetMapMode(aNew);
     }
diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx
index db7e6ab..71522cf 100644
--- a/svx/source/sdr/contact/objectcontactofpageview.cxx
+++ b/svx/source/sdr/contact/objectcontactofpageview.cxx
@@ -35,6 +35,7 @@
 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
 #include <drawinglayer/processor2d/processor2dtools.hxx>
 #include <svx/unoapi.hxx>
+#include <comphelper/lok.hxx>
 #include <unotools/configmgr.hxx>
 
 #include "eventhandler.hxx"
@@ -168,7 +169,7 @@ namespace sdr
             bool bClipRegionPushed(false);
             const vcl::Region& rRedrawArea(rDisplayInfo.GetRedrawArea());
 
-            if(!rRedrawArea.IsEmpty())
+            if(!rRedrawArea.IsEmpty() && !comphelper::LibreOfficeKit::isActive())
             {
                 bClipRegionPushed = true;
                 pOutDev->Push(PushFlags::CLIPREGION);
@@ -231,6 +232,14 @@ namespace sdr
 
                 // transform to world coordinates
                 aViewRange.transform(rTargetOutDev.GetInverseViewTransformation());
+                if (comphelper::LibreOfficeKit::isActive())
+                {
+                    const int TWIPS_PER_PIXEL = 15;
+                    aViewRange = basegfx::B2DRange(aViewRange.getMinimum().getX(),
+                                                   aViewRange.getMinimum().getY(),
+                                                   aViewRange.getMaximum().getX() * TWIPS_PER_PIXEL,
+                                                   aViewRange.getMaximum().getY() * TWIPS_PER_PIXEL);
+                }
             }
 
             // update local ViewInformation2D
@@ -292,15 +301,32 @@ namespace sdr
                 rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing
                 pOutDev->SetLayoutMode(TEXT_LAYOUT_DEFAULT); // reset, default is no BiDi/RTL
 
+                // Save the map-mode since creating the 2D processor will replace it.
+                const MapMode aOrigMapMode = pOutDev->GetMapMode();
+
                 // create renderer
                 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
                     drawinglayer::processor2d::createProcessor2DFromOutputDevice(
                         rTargetOutDev, getViewInformation2D()));
 
+                if (comphelper::LibreOfficeKit::isActive())
+                {
+                    // Restore the origin.
+                    MapMode aMapMode = pOutDev->GetMapMode();
+                    aMapMode.SetOrigin(aOrigMapMode.GetOrigin());
+                    pOutDev->SetMapMode(aMapMode);
+                }
+
                 if(pProcessor2D)
                 {
                     pProcessor2D->process(xPrimitiveSequence);
                 }
+
+                if (comphelper::LibreOfficeKit::isActive())
+                {
+                    // Restore the original map-mode.
+                    pOutDev->SetMapMode(aOrigMapMode);
+                }
             }
 
             // #114359# restore old ClipReghion
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 01b6cb8..0e2dd19 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -35,6 +35,7 @@
 
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <memory>
+#include <comphelper/lok.hxx>
 
 void OutputDevice::DrawBitmap( const Point& rDestPt, const Bitmap& rBitmap )
 {
@@ -1187,12 +1188,23 @@ void OutputDevice::DrawTransformedBitmapEx(
         // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx
         // do *not* execute the mirroring here, it's done in the fallback
         // #i124580# the correct DestSize needs to be calculated based on MaxXY values
-        const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY()));
+        Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY()));
         const Size aDestSize(
             basegfx::fround(aScale.getX() + aTranslate.getX()) - aDestPt.X(),
             basegfx::fround(aScale.getY() + aTranslate.getY()) - aDestPt.Y());
+        const Point aOrigin = GetMapMode().GetOrigin();
+        if (comphelper::LibreOfficeKit::isActive())
+        {
+            aDestPt.Move(aOrigin.getX(), aOrigin.getY());
+            EnableMapMode(false);
+        }
 
         DrawBitmapEx(aDestPt, aDestSize, rBitmapEx);
+        if (comphelper::LibreOfficeKit::isActive())
+        {
+            EnableMapMode(true);
+            aDestPt.Move(-aOrigin.getX(), -aOrigin.getY());
+        }
         return;
     }
 
commit 34b9cbf6640a9c8ea812bfc7c7f31c95acd2e495
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).
    
    Reviewed-on: https://gerrit.libreoffice.org/26203
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit ecc33ce663625ae1114a56fe3d1625c5ed274685)
    
    Change-Id: I6f1ea0aa2f19a7fda926f596a2009290680c593c

diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 588a427..3219031 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -468,8 +468,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();
@@ -588,6 +588,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)
@@ -811,10 +813,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 marks
     {
         if(eMode == SC_UPDATE_CHANGED && aOutputData.SetChangedClip())
@@ -945,6 +964,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(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,
@@ -979,8 +1033,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);
@@ -988,87 +1042,64 @@ 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();
@@ -1082,6 +1113,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