comphelper/source/misc/lok.cxx | 13 +++++++++ desktop/qa/desktop_lib/test_desktop_lib.cxx | 9 +++--- desktop/source/lib/init.cxx | 39 +++++++++++++++++++++++++--- dictionaries | 2 - 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 ++++++++++++++++------ sc/source/ui/view/tabview.cxx | 8 ++--- vcl/headless/svpvd.cxx | 15 ++++++++-- 11 files changed, 122 insertions(+), 32 deletions(-)
New commits: commit 4cee8ccc2caff17b5cbecc5ae895dcc9fd974c2e Author: Marco Cecchetti <[email protected]> AuthorDate: Sat Oct 27 17:15:35 2018 +0000 Commit: Jan Holesovsky <[email protected]> CommitDate: Thu Nov 8 14:39:14 2018 +0100 lok: calc: fix needed when position caching is disabled In case it would be needed to disable position caching we can't retrieve the nTotalPixels value from the LOKHeight/WidthHelper. The new code works in both cases. Change-Id: I65562dd4458eee40c5db958067fc91af6b3eb79e Reviewed-on: https://gerrit.libreoffice.org/63039 Tested-by: Jenkins Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/dictionaries b/dictionaries index 86921a78c42f..6c85a19c887b 160000 --- a/dictionaries +++ b/dictionaries @@ -1 +1 @@ -Subproject commit 86921a78c42f4fd499d86a226e34ab97e8b85ed5 +Subproject commit 6c85a19c887b6147ec7d3a600b51cb2a44284fa2 diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index 8f7f7e37c836..3444a7e36fdc 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -2479,8 +2479,10 @@ OUString ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle) SCTAB nTab = aViewData.GetTabNo(); SCROW nStartRow = -1; SCROW nEndRow = -1; + long nStartHeightPx = 0; SCCOL nStartCol = -1; SCCOL nEndCol = -1; + long nStartWidthPx = 0; tools::Rectangle aOldVisArea( mnLOKStartHeaderCol + 1, mnLOKStartHeaderRow + 1, @@ -2493,7 +2495,6 @@ OUString ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle) if (rRectangle.Top() < rRectangle.Bottom()) { SAL_INFO("sc.lok.header", "Row Header: compute start/end rows."); - long nStartHeightPx = 0; long nEndHeightPx = 0; long nRectTopPx = rRectangle.Top() / TWIPS_PER_PIXEL; long nRectBottomPx = rRectangle.Bottom() / TWIPS_PER_PIXEL; @@ -2582,7 +2583,7 @@ OUString ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle) aBuffer.append("\"rows\": [\n"); - long nTotalPixels = aViewData.GetLOKHeightHelper().getPosition(nStartRow); + long nTotalPixels = nStartHeightPx; SAL_INFO("sc.lok.header", "Row Header: [create string data for rows]: start row: " << nStartRow << " start height: " << nTotalPixels); @@ -2637,7 +2638,6 @@ OUString ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle) if (rRectangle.Left() < rRectangle.Right()) { SAL_INFO("sc.lok.header", "Column Header: compute start/end columns."); - long nStartWidthPx = 0; long nEndWidthPx = 0; long nRectLeftPx = rRectangle.Left() / TWIPS_PER_PIXEL; long nRectRightPx = rRectangle.Right() / TWIPS_PER_PIXEL; @@ -2723,7 +2723,7 @@ OUString ScTabView::getRowColumnHeaders(const tools::Rectangle& rRectangle) aBuffer.append("\"columns\": [\n"); - nTotalPixels = aViewData.GetLOKWidthHelper().getPosition(nStartCol); + nTotalPixels = nStartWidthPx; SAL_INFO("sc.lok.header", "Col Header: [create string data for cols]: start col: " << nStartRow << " start width: " << nTotalPixels); commit b0fb5acd045d116943645277a220abec5e8b6063 Author: Jan Holesovsky <[email protected]> AuthorDate: Fri Oct 26 15:21:06 2018 +0200 Commit: Jan Holesovsky <[email protected]> CommitDate: Thu Nov 8 14:38:49 2018 +0100 lokdialog: Implement hi-dpi support for the routed dialogs. Change-Id: I770c605a049b7ac9c26c2773414eef8b6fc093a2 Reviewed-on: https://gerrit.libreoffice.org/63032 Tested-by: Jenkins Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 389d84a0cc31..728af9163222 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -2431,12 +2431,13 @@ void DesktopLOKTest::testABI() CPPUNIT_ASSERT_EQUAL(documentClassOffset(39), offsetof(struct _LibreOfficeKitDocumentClass, setViewLanguage)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(40), offsetof(struct _LibreOfficeKitDocumentClass, postWindowExtTextInputEvent)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(41), offsetof(struct _LibreOfficeKitDocumentClass, getPartInfo)); - CPPUNIT_ASSERT_EQUAL(documentClassOffset(42), offsetof(struct _LibreOfficeKitDocumentClass, insertCertificate)); - CPPUNIT_ASSERT_EQUAL(documentClassOffset(43), offsetof(struct _LibreOfficeKitDocumentClass, addCertificate)); - CPPUNIT_ASSERT_EQUAL(documentClassOffset(44), offsetof(struct _LibreOfficeKitDocumentClass, getSignatureState)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(42), offsetof(struct _LibreOfficeKitDocumentClass, paintWindowDPI)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(43), offsetof(struct _LibreOfficeKitDocumentClass, insertCertificate)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(44), offsetof(struct _LibreOfficeKitDocumentClass, addCertificate)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(45), offsetof(struct _LibreOfficeKitDocumentClass, getSignatureState)); // Extending is fine, update this, and add new assert for the offsetof the // new method - CPPUNIT_ASSERT_EQUAL(documentClassOffset(45), sizeof(struct _LibreOfficeKitDocumentClass)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(46), sizeof(struct _LibreOfficeKitDocumentClass)); } CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 7ea6316f9e26..450cd0f1ad78 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -686,6 +686,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); @@ -756,6 +761,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; @@ -3587,11 +3593,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(); @@ -3603,6 +3618,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); @@ -3636,7 +3656,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 e052765ac794..27d968c4a6b7 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); + #ifdef IOS /// @see lok::Document::paintTileToCGContext(). void (*paintTileToCGContext) (LibreOfficeKitDocument* pThis, diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index c238d507c183..4a0ec6784b7b 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 498dceb43f870bf9e380f1f87e99c6ccadf1963c Author: Jan Holesovsky <[email protected]> AuthorDate: Tue Oct 23 17:20:38 2018 +0200 Commit: Jan Holesovsky <[email protected]> CommitDate: Thu Nov 8 14:38:27 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 Reviewed-on: https://gerrit.libreoffice.org/63031 Tested-by: Jenkins Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx index 0641e01660ab..2f6a2c151370 100644 --- a/comphelper/source/misc/lok.cxx +++ b/comphelper/source/misc/lok.cxx @@ -37,6 +37,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; @@ -77,6 +80,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 202bf279f153..7ea6316f9e26 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2126,7 +2126,20 @@ static void doc_paintTile(LibreOfficeKitDocument* pThis, return; } -#if defined(UNX) && !defined(MACOSX) +#if defined(UNX) && !defined(MACOSX) && !defined(ENABLE_HEADLESS) + + // 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(IOS) CGContextRef cgc = CGBitmapContextCreate(pBuffer, nCanvasWidth, nCanvasHeight, 8, nCanvasWidth*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little); diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx index 7fb4d5a04800..a2b7eb02bef3 100644 --- a/include/comphelper/lok.hxx +++ b/include/comphelper/lok.hxx @@ -59,6 +59,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 ef5aca3f7950..255e1a4ef3f4 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -992,12 +992,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 e74c18125a45..542a4c6283c6 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> @@ -1109,17 +1110,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, _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
