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 <ke...@collabora.com> AuthorDate: Fri Oct 26 15:21:06 2018 +0200 Commit: Jan Holesovsky <ke...@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 <ke...@collabora.com> AuthorDate: Tue Oct 23 17:20:38 2018 +0200 Commit: Jan Holesovsky <ke...@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 <ke...@collabora.com> AuthorDate: Wed Oct 24 21:41:02 2018 +0200 Commit: Jan Holesovsky <ke...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits