diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 24 | ||||
-rw-r--r-- | libreofficekit/qa/unit/tiledrendering.cxx | 32 |
2 files changed, 52 insertions, 4 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 935bc45dadd5..0e73a272cce1 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1824,11 +1824,27 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, << nTilePosX << ", " << nTilePosY << ") to [" << nCanvasWidth << "x" << nCanvasHeight << "]px" ); - // Disable callbacks while we are painting. LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis); - const int nOrigViewId = doc_getView(pThis); + int nOrigViewId = doc_getView(pThis); + + if (nOrigViewId < 0) + { + // tile painting always needs a SfxViewShell::Current(), but actually + // it does not really matter which one - all of them should paint the + // same thing. + int viewCount = doc_getViewsCount(pThis); + if (viewCount == 0) + return; - if (nOrigViewId >= 0) + std::vector<int> viewIds(viewCount); + doc_getViewIds(pThis, viewIds.data(), viewCount); + + nOrigViewId = viewIds[0]; + doc_setView(pThis, nOrigViewId); + } + + // Disable callbacks while we are painting. + if (nOrigViewId >= 0 && pDocument->mpCallbackFlushHandlers[nOrigViewId]) pDocument->mpCallbackFlushHandlers[nOrigViewId]->setPartTilePainting(true); try @@ -1879,7 +1895,7 @@ static void doc_paintPartTile(LibreOfficeKitDocument* pThis, // Nothing to do but restore the PartTilePainting flag. } - if (nOrigViewId >= 0) + if (nOrigViewId >= 0 && pDocument->mpCallbackFlushHandlers[nOrigViewId]) pDocument->mpCallbackFlushHandlers[nOrigViewId]->setPartTilePainting(false); } diff --git a/libreofficekit/qa/unit/tiledrendering.cxx b/libreofficekit/qa/unit/tiledrendering.cxx index 5987d14e566a..70d7a4ae814b 100644 --- a/libreofficekit/qa/unit/tiledrendering.cxx +++ b/libreofficekit/qa/unit/tiledrendering.cxx @@ -72,6 +72,7 @@ public: void testDocumentTypes( Office* pOffice ); void testImpressSlideNames( Office* pOffice ); void testCalcSheetNames( Office* pOffice ); + void testPaintPartTile( Office* pOffice ); #if 0 void testOverlay( Office* pOffice ); #endif @@ -98,6 +99,7 @@ void TiledRenderingTest::runAllTests() testDocumentTypes( pOffice.get() ); testImpressSlideNames( pOffice.get() ); testCalcSheetNames( pOffice.get() ); + testPaintPartTile( pOffice.get() ); #if 0 testOverlay( pOffice.get() ); #endif @@ -186,6 +188,36 @@ void TiledRenderingTest::testCalcSheetNames( Office* pOffice ) CPPUNIT_ASSERT_EQUAL(std::string("Sheet3"), std::string(pDocument->getPartName(2))); } +void TiledRenderingTest::testPaintPartTile(Office* pOffice) +{ + const string sTextDocPath = m_sSrcRoot + "/libreofficekit/qa/data/blank_text.odt"; + const string sTextLockFile = m_sSrcRoot +"/libreofficekit/qa/data/.~lock.blank_text.odt#"; + + // FIXME: same comment as below wrt lockfile removal. + remove(sTextLockFile.c_str()); + + std::unique_ptr<Document> pDocument(pOffice->documentLoad( sTextDocPath.c_str())); + CPPUNIT_ASSERT(pDocument.get()); + CPPUNIT_ASSERT_EQUAL(LOK_DOCTYPE_TEXT, static_cast<LibreOfficeKitDocumentType>(pDocument->getDocumentType())); + + // Create two views. + pDocument->getView(); + pDocument->createView(); + + int nView2 = pDocument->getView(); + + // Destroy the current view + pDocument->destroyView(nView2); + + int nCanvasWidth = 256; + int nCanvasHeight = 256; + std::vector<unsigned char> aBuffer(nCanvasWidth * nCanvasHeight * 4); + + // And try to paintPartTile() - this used to crash when the current viewId + // was destroyed + pDocument->paintPartTile(aBuffer.data(), /*nPart=*/0, nCanvasWidth, nCanvasHeight, /*nTilePosX=*/0, /*nTilePosY=*/0, /*nTileWidth=*/3840, /*nTileHeight=*/3840); +} + #if 0 static void dumpRGBABitmap( const OUString& rPath, const unsigned char* pBuffer, const int nWidth, const int nHeight ) |