summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/app/transobj.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sc/source/ui/app/transobj.cxx31
1 files changed, 29 insertions, 2 deletions
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 5f0599c888..e5ed3b1afe 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 );
}