diff options
author | Patrick Luby <guibmacdev@gmail.com> | 2024-05-04 19:58:03 -0400 |
---|---|---|
committer | Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> | 2024-05-07 18:14:44 +0200 |
commit | bae8980495d54d235b71938bc313be22d7455585 (patch) | |
tree | 480783bc81fb3219dbb723f4852de5e12d1e54b8 | |
parent | 598cc6c5f03bf0aae525e80ae6960de2c78efeae (diff) |
tdf#160855 fix crash due to Skia's internal maximum pixel limit
Somewhere in the tens of thousands of selected fill cells,
the size of the VirtualDevice exceeds 1 GB of pixels. But
Skia, at least on macOS, will fail to create a surface.
Even if there is ample free memory, Skia/Raster will fail.
The second problem is that even if you disable Skia, the
crash is just delayed when a BitmapEx is created from the
VirtualDevice and malloc() fails.
Since this data flavor really triggers one or more system
memory limits, lower the resolution of the bitmap by keeping
the VirtualDevice pixel size within an arbitrary number of
pixels.
Note: the artibrary "maximum number of pixels" limit that
that Skia can handle may need to be raised or lowered for
platforms other than macOS.
Change-Id: Ie087f2db152470aa70521fbe5fe6c7cedd8504af
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167145
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Jenkins
Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
(cherry picked from commit 8d9f54165d28d83092667b7bfcd0ee48ade54c87)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167217
Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r-- | sc/source/ui/app/transobj.cxx | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx index 5f0599c888b3..e5ed3b1afe2a 100644 --- a/sc/source/ui/app/transobj.cxx +++ b/sc/source/ui/app/transobj.cxx @@ -405,11 +405,38 @@ bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor, const OUSt aReducedBlock.aEnd.Col(), aReducedBlock.aEnd.Row(), aReducedBlock.aStart.Tab() ); ScopedVclPtrInstance< VirtualDevice > pVirtDev; - pVirtDev->SetOutputSizePixel(pVirtDev->LogicToPixel(aMMRect.GetSize(), MapMode(MapUnit::Map100thMM))); + + // tdf#160855 fix crash due to Skia's internal maximum pixel limit + // Somewhere in the tens of thousands of selected fill cells, + // the size of the VirtualDevice exceeds 1 GB of pixels. But + // Skia, at least on macOS, will fail to create a surface. + // Even if there is ample free memory, Skia/Raster will fail. + // The second problem is that even if you disable Skia, the + // crash is just delayed when a BitmapEx is created from the + // VirtualDevice and malloc() fails. + // Since this data flavor really triggers one or more system + // memory limits, lower the resolution of the bitmap by keeping + // the VirtualDevice pixel size within an arbitrary number of + // pixels. + // Note: the artibrary "maximum number of pixels" limit that + // that Skia can handle may need to be raised or lowered for + // platforms other than macOS. + static constexpr tools::Long nCopyToImageMaxPixels = 8192 * 8192; + Fraction aScale(1.0); + Size aPixelSize = pVirtDev->LogicToPixel(aMMRect.GetSize(), MapMode(MapUnit::Map100thMM)); + tools::Long nPixels(aPixelSize.Width() * aPixelSize.Height()); + if (nPixels < 0 || nPixels > nCopyToImageMaxPixels) + { + aScale = Fraction(nCopyToImageMaxPixels, nPixels); + aPixelSize = pVirtDev->LogicToPixel(aMMRect.GetSize(), MapMode(MapUnit::Map100thMM, Point(), aScale, aScale)); + nPixels = aPixelSize.Width() * aPixelSize.Height(); + } + + pVirtDev->SetOutputSizePixel(aPixelSize); PaintToDev( pVirtDev, *m_pDoc, 1.0, aReducedBlock ); - pVirtDev->SetMapMode( MapMode( MapUnit::MapPixel ) ); + pVirtDev->SetMapMode( MapMode( MapUnit::MapPixel, Point(), aScale, aScale ) ); BitmapEx aBmp = pVirtDev->GetBitmapEx( Point(), pVirtDev->GetOutputSize() ); bOK = SetBitmapEx( aBmp, rFlavor ); } |