Kaydet (Commit) 498dceb4 authored tarafından Jan Holesovsky's avatar Jan Holesovsky

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: 's avatarJan Holesovsky <kendy@collabora.com>
üst d2c7b86b
......@@ -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;
......
......@@ -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);
......
......@@ -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
......
......@@ -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)
......
......@@ -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();
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment