diff options
author | Jan Holesovsky <kendy@collabora.com> | 2018-10-23 17:20:38 +0200 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2018-11-08 14:38:27 +0100 |
commit | 498dceb43f870bf9e380f1f87e99c6ccadf1963c (patch) | |
tree | 1cfcb65dfc6b28c06bb4b4666a20218f74462585 | |
parent | d2c7b86be879fe33ce170727421a19370ba8884d (diff) |
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 <kendy@collabora.com>
-rw-r--r-- | comphelper/source/misc/lok.cxx | 13 | ||||
-rw-r--r-- | desktop/source/lib/init.cxx | 15 | ||||
-rw-r--r-- | include/comphelper/lok.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/unoobj/docuno.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin4.cxx | 32 | ||||
-rw-r--r-- | vcl/headless/svpvd.cxx | 15 |
6 files changed, 71 insertions, 18 deletions
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, |