[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - 3 commits - comphelper/source desktop/source include/comphelper include/LibreOfficeKit sc/source vcl/headless

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Nov 7 12:28:17 UTC 2018


 comphelper/source/misc/lok.cxx            |   13 +++++++
 desktop/source/lib/init.cxx               |   50 ++++++++++++++++++++++++++++--
 include/LibreOfficeKit/LibreOfficeKit.h   |    9 +++++
 include/LibreOfficeKit/LibreOfficeKit.hxx |   13 ++++++-
 include/comphelper/lok.hxx                |    4 ++
 sc/source/ui/unoobj/docuno.cxx            |   10 +++---
 sc/source/ui/view/gridwin4.cxx            |   32 +++++++++++++------
 vcl/headless/svpvd.cxx                    |   15 +++++++--
 8 files changed, 124 insertions(+), 22 deletions(-)

New commits:
commit e94ceb6eff0edd1699d21b8b860f6929236a90ef
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Oct 26 15:21:06 2018 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Wed Nov 7 12:53:17 2018 +0100

    lokdialog: Implement hi-dpi support for the routed dialogs.
    
    Change-Id: I770c605a049b7ac9c26c2773414eef8b6fc093a2

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 5b5381c002fa..a8d5e87eed08 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -678,6 +678,11 @@ static void doc_paintWindow(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId
                             const int nX, const int nY,
                             const int nWidth, const int nHeight);
 
+static void doc_paintWindowDPI(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId, unsigned char* pBuffer,
+                               const int nX, const int nY,
+                               const int nWidth, const int nHeight,
+                               const double fDPIScale);
+
 static void doc_postWindow(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId, int nAction);
 
 static char* doc_getPartInfo(LibreOfficeKitDocument* pThis, int nPart);
@@ -733,6 +738,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
         m_pDocumentClass->getPartHash = doc_getPartHash;
 
         m_pDocumentClass->paintWindow = doc_paintWindow;
+        m_pDocumentClass->paintWindowDPI = doc_paintWindowDPI;
         m_pDocumentClass->postWindow = doc_postWindow;
 
         m_pDocumentClass->setViewLanguage = doc_setViewLanguage;
@@ -3566,11 +3572,20 @@ unsigned char* doc_renderFont(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pTh
     return nullptr;
 }
 
-static void doc_paintWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId,
+static void doc_paintWindow(LibreOfficeKitDocument* pThis, unsigned nLOKWindowId,
                             unsigned char* pBuffer,
                             const int nX, const int nY,
                             const int nWidth, const int nHeight)
 {
+    doc_paintWindowDPI(pThis, nLOKWindowId, pBuffer, nX, nY, nWidth, nHeight, 1.0);
+}
+
+static void doc_paintWindowDPI(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindowId,
+                               unsigned char* pBuffer,
+                               const int nX, const int nY,
+                               const int nWidth, const int nHeight,
+                               const double fDPIScale)
+{
     SolarMutexGuard aGuard;
     if (gImpl)
         gImpl->maLastExceptionMsg.clear();
@@ -3582,6 +3597,11 @@ static void doc_paintWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWind
         return;
     }
 
+    // Setup cairo to draw with the changed DPI scale (and return back to 1.0
+    // when the painting finishes)
+    comphelper::ScopeGuard dpiScaleGuard([]() { comphelper::LibreOfficeKit::setDPIScale(1.0); });
+    comphelper::LibreOfficeKit::setDPIScale(fDPIScale);
+
 #if defined(IOS)
 
     CGContextRef cgc = CGBitmapContextCreate(pBuffer, nWidth, nHeight, 8, nWidth*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little);
@@ -3615,7 +3635,7 @@ static void doc_paintWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWind
     pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nWidth, nHeight), Fraction(1.0), Point(), pBuffer);
 
     MapMode aMapMode(pDevice->GetMapMode());
-    aMapMode.SetOrigin(Point(-nX, -nY));
+    aMapMode.SetOrigin(Point(-(nX / fDPIScale), -(nY / fDPIScale)));
     pDevice->SetMapMode(aMapMode);
 
     comphelper::LibreOfficeKit::setDialogPainting(true);
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 0799584d3097..f8021065af1e 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -309,6 +309,15 @@ struct _LibreOfficeKitDocumentClass
     /// @see lok::Document::getPartInfo().
     char* (*getPartInfo) (LibreOfficeKitDocument* pThis, int nPart);
 
+    /// Paints window with given id to the buffer with the give DPI scale
+    /// (every pixel is dpiscale-times larger).
+    /// @see lok::Document::paintWindow().
+    void (*paintWindowDPI) (LibreOfficeKitDocument* pThis, unsigned nWindowId,
+                            unsigned char* pBuffer,
+                            const int x, const int y,
+                            const int width, const int height,
+                            const double dpiscale);
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 232eada69821..51d072331762 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -164,16 +164,23 @@ public:
      * @param y y-coordinate from where the dialog should start painting
      * @param width The width of the dialog image to be painted
      * @param height The height of the dialog image to be painted
+     * @param dpiscale The dpi scale value used by the client.  Please note
+     *                 that the x, y, width, height are supposed to be the
+     *                 values with dpiscale applied (ie. dialog covering
+     *                 100x100 "normal" pixels with dpiscale '2' will have
+     *                 200x200 width x height), so that it is easy to compute
+     *                 the buffer sizes etc.
      */
     void paintWindow(unsigned nWindowId,
                      unsigned char* pBuffer,
                      const int x,
                      const int y,
                      const int width,
-                     const int height)
+                     const int height,
+                     const double dpiscale = 1.0)
     {
-        return mpDoc->pClass->paintWindow(mpDoc, nWindowId, pBuffer,
-                                          x, y, width, height);
+        return mpDoc->pClass->paintWindowDPI(mpDoc, nWindowId, pBuffer,
+                                             x, y, width, height, dpiscale);
     }
 
     /**
commit 053d9247ce0818580658a7b6f5854f8b21754f7c
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Tue Oct 23 17:20:38 2018 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Wed Nov 7 12:51:03 2018 +0100

    sc lok: Implement hi-dpi and zoom for spreadsheets.
    
    A bit different approach than trying to paint different zoom levels at
    the samet time, because it is terribly hard to achieve with Calc -
    things misalign, because Calc tries to fit the lines into the pixels
    etc.
    
    Instead, always paint the spreadsheet at 100%, but use cairo to scale the
    actual painting.
    
    Change-Id: I228a9dd41bf29862bdd188825d12e61e1c86cccc

diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx
index 05a991dad074..0d496df6ccba 100644
--- a/comphelper/source/misc/lok.cxx
+++ b/comphelper/source/misc/lok.cxx
@@ -35,6 +35,9 @@ static bool g_bLocalRendering(false);
 
 static LanguageTag g_aLanguageTag("en-US", true);
 
+/// Scaling of the cairo canvas painting for hi-dpi or zooming in Calc.
+static double g_fDPIScale(1.0);
+
 void setActive(bool bActive)
 {
     g_bActive = bActive;
@@ -75,6 +78,16 @@ bool isDialogPainting()
     return g_bDialogPainting;
 }
 
+void setDPIScale(double fDPIScale)
+{
+    g_fDPIScale = fDPIScale;
+}
+
+double getDPIScale()
+{
+    return g_fDPIScale;
+}
+
 void setTiledAnnotations(bool bTiledAnnotations)
 {
     g_bTiledAnnotations = bTiledAnnotations;
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 7527c1b857d2..5b5381c002fa 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2104,6 +2104,19 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis,
         return;
     }
 
+    // Painting of zoomed or hi-dpi spreadsheets is special, we actually draw
+    // everything at 100%, and only set cairo's scale factor accordingly, so
+    // that everything is painted bigger or smaller.  This is different to
+    // what Calc's internal scaling would do - because that one is trying to
+    // fit the lines between cells to integer multiples of pixels.
+    comphelper::ScopeGuard dpiScaleGuard([]() { comphelper::LibreOfficeKit::setDPIScale(1.0); });
+    if (doc_getDocumentType(pThis) == LOK_DOCTYPE_SPREADSHEET)
+    {
+        double fDPIScaleX = (nCanvasWidth * 3840.0) / (256.0 * nTileWidth);
+        assert(fabs(fDPIScaleX - ((nCanvasHeight * 3840.0) / (256.0 * nTileHeight))) < 0.0001);
+        comphelper::LibreOfficeKit::setDPIScale(fDPIScaleX);
+    }
+
 #if defined(UNX) && !defined(MACOSX) && !defined(ENABLE_HEADLESS)
 
 #if defined(IOS)
diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx
index e0bd65690261..fefa8ed90ef2 100644
--- a/include/comphelper/lok.hxx
+++ b/include/comphelper/lok.hxx
@@ -58,6 +58,10 @@ COMPHELPER_DLLPUBLIC void setTiledPainting(bool bTiledPainting);
 COMPHELPER_DLLPUBLIC bool isDialogPainting();
 /// Set if we are painting the dialog.
 COMPHELPER_DLLPUBLIC void setDialogPainting(bool bDialogPainting);
+/// Set the DPI scale for rendering for hi-dpi displays.  Used also for zoom in Calc.
+COMPHELPER_DLLPUBLIC void setDPIScale(double fDPIScale);
+/// Get the DPI scale for rendering for hi-dpi displays.  Used also for zoom in Calc.
+COMPHELPER_DLLPUBLIC double getDPIScale();
 /// Set if we want no annotations rendering
 COMPHELPER_DLLPUBLIC void setTiledAnnotations(bool bTiledAnnotations);
 /// Check if annotations rendering is turned off
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index b42179663858..021f316c6236 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -978,12 +978,12 @@ bool ScModelObj::isMimeTypeSupported()
     return EditEngine::HasValidData(aDataHelper.GetTransferable());
 }
 
-void ScModelObj::setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int nTileTwipWidth_, int nTileTwipHeight_)
+void ScModelObj::setClientZoom(int /*nTilePixelWidth_*/, int /*nTilePixelHeight_*/, int /*nTileTwipWidth_*/, int /*nTileTwipHeight_*/)
 {
-    mnTilePixelWidth = nTilePixelWidth_;
-    mnTilePixelHeight = nTilePixelHeight_;
-    mnTileTwipWidth = nTileTwipWidth_;
-    mnTileTwipHeight = nTileTwipHeight_;
+    mnTilePixelWidth = 256;
+    mnTilePixelHeight = 256;
+    mnTileTwipWidth = mnTilePixelWidth * TWIPS_PER_PIXEL;
+    mnTileTwipHeight = mnTilePixelHeight * TWIPS_PER_PIXEL;
 }
 
 OUString ScModelObj::getRowColumnHeaders(const tools::Rectangle& rRectangle)
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 56f19eaf2895..23a01512310d 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -32,6 +32,7 @@
 
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <comphelper/lok.hxx>
+#include <comphelper/scopeguard.hxx>
 #include <sfx2/lokhelper.hxx>
 
 #include <svx/svdview.hxx>
@@ -1108,17 +1109,30 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
     // coords only, and avoid all the SetMapMode()'s.
     // Similarly to Writer, we should set the mapmode once on the rDevice, and
     // not care about any zoom settings.
-
-    Fraction aFracX(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth);
-    Fraction aFracY(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight);
-
-    // page break zoom, and aLogicMode in ScViewData
+    //
+    // But until that happens, we actually draw everything at 100%, and only
+    // set cairo's scale factor accordingly, so that everything is painted
+    // bigger or smaller.  This is different to what Calc's internal scaling
+    // would do - because that one is trying to fit the lines between cells to
+    // integer multiples of pixels.
+    //
+    // See also desktop/source/lib/init.cxx for details, where we have to set
+    // the stuff accorndingly for the VirtualDevice creation.
+
+    // page break zoom, and aLogicMode in ScViewData - hardcode that to what
+    // we mean as 100% (256px tiles meaning 3840 twips)
+    Fraction aFracX(long(256 * TWIPS_PER_PIXEL), 3840);
+    Fraction aFracY(long(256 * TWIPS_PER_PIXEL), 3840);
     pViewData->SetZoom(aFracX, aFracY, true);
 
-    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;
+    // Cairo scales for us, we have to compensate for that, otherwise we are
+    // painting too far away
+    const double fDPIScale = comphelper::LibreOfficeKit::getDPIScale();
+
+    const double fTilePosXPixel = static_cast<double>(nTilePosX) * nOutputWidth / (nTileWidth * fDPIScale);
+    const double fTilePosYPixel = static_cast<double>(nTilePosY) * nOutputHeight / (nTileHeight * fDPIScale);
+    const double fTileBottomPixel = static_cast<double>(nTilePosY + nTileHeight) * nOutputHeight / (nTileHeight * fDPIScale);
+    const double fTileRightPixel = static_cast<double>(nTilePosX + nTileWidth) * nOutputWidth / (nTileWidth * fDPIScale);
 
     SCTAB nTab = pViewData->GetTabNo();
     ScDocument* pDoc = pViewData->GetDocument();
diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx
index 4172fc383744..875f22a5d7fc 100644
--- a/vcl/headless/svpvd.cxx
+++ b/vcl/headless/svpvd.cxx
@@ -25,6 +25,7 @@
 #include <headless/svpgdi.hxx>
 
 #include <basegfx/vector/b2ivector.hxx>
+#include <comphelper/lok.hxx>
 
 #include <cairo.h>
 
@@ -90,9 +91,17 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY,
         {
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
             double fXScale, fYScale;
-            cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
-            nNewDX *= fXScale;
-            nNewDY *= fYScale;
+            if (comphelper::LibreOfficeKit::isActive())
+            {
+                // Force scaling of the painting
+                fXScale = fYScale = comphelper::LibreOfficeKit::getDPIScale();
+            }
+            else
+            {
+                cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
+                nNewDX *= fXScale;
+                nNewDY *= fYScale;
+            }
 #endif
 
             m_pSurface = cairo_image_surface_create_for_data(pBuffer, CAIRO_FORMAT_ARGB32,
commit ddd2790f3402abaa64ccc501b63826dd29b29b68
Author:     Jan Holesovsky <kendy at collabora.com>
AuthorDate: Wed Oct 24 21:41:02 2018 +0200
Commit:     Jan Holesovsky <kendy at collabora.com>
CommitDate: Wed Nov 7 12:50:52 2018 +0100

    Revert "The debugging rectangles are not needed any more."
    
    Still useful for debugging, particularly in combination with
    gtktiledviewer.
    
    This reverts commit dec025d4cb51f252ecd7e981fe36800cf2bedff5.
    
    Change-Id: Id2174486c0427adf083be199ce2dbb453beb8f22

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 376caead288d..7527c1b857d2 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2129,6 +2129,19 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis,
 
     pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight,
                     nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+
+    static bool bDebug = getenv("LOK_DEBUG_TILES") != nullptr;
+    if (bDebug)
+    {
+        // Draw a small red rectangle in the top left corner so that it's easy to see where a new tile begins.
+        tools::Rectangle aRect(0, 0, 5, 5);
+        aRect = pDevice->PixelToLogic(aRect);
+        pDevice->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
+        pDevice->SetFillColor(COL_LIGHTRED);
+        pDevice->SetLineColor();
+        pDevice->DrawRect(aRect);
+        pDevice->Pop();
+    }
 #endif
 
 #else


More information about the Libreoffice-commits mailing list