summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2018-10-23 17:20:38 +0200
committerJan Holesovsky <kendy@collabora.com>2018-11-08 14:38:27 +0100
commit498dceb43f870bf9e380f1f87e99c6ccadf1963c (patch)
tree1cfcb65dfc6b28c06bb4b4666a20218f74462585
parentd2c7b86be879fe33ce170727421a19370ba8884d (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.cxx13
-rw-r--r--desktop/source/lib/init.cxx15
-rw-r--r--include/comphelper/lok.hxx4
-rw-r--r--sc/source/ui/unoobj/docuno.cxx10
-rw-r--r--sc/source/ui/view/gridwin4.cxx32
-rw-r--r--vcl/headless/svpvd.cxx15
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,