drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx | 1 sc/qa/extras/scpdfexport.cxx | 14 sc/qa/extras/testdocuments/tdf159094.ods |binary sc/source/ui/unoobj/docuno.cxx | 190 ++++++++++++- 4 files changed, 197 insertions(+), 8 deletions(-)
New commits: commit bffef73b0a0633969149ef504f97d9c701647a9e Author: Tibor Nagy <tibor.nagy.ext...@allotropia.de> AuthorDate: Fri Mar 8 00:51:06 2024 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Wed Mar 20 16:15:38 2024 +0100 tdf#159094 sc: fix failure when exporting media files to PDF Change-Id: I948190b31f45cf05ba24d1fbc4a84dfe91eb3876 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164557 Tested-by: Jenkins Reviewed-by: Nagy Tibor <tibor.nagy.ext...@allotropia.de> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164976 (cherry picked from commit 4c1b617863f46ec4ef2553df8bde46b98b4a48bf) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164993 diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index f2aea4cd7eae..b523c57c94df 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -2584,6 +2584,7 @@ void VclMetafileProcessor2D::processStructureTagPrimitive2D( case vcl::PDFWriter::TableRow: case vcl::PDFWriter::Formula: case vcl::PDFWriter::Figure: + case vcl::PDFWriter::Annot: mpPDFExtOutDevData->SetStructureAttribute(vcl::PDFWriter::Placement, vcl::PDFWriter::Block); break; diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx index ca4a7b762f63..26b129d99d3c 100644 --- a/sc/qa/extras/scpdfexport.cxx +++ b/sc/qa/extras/scpdfexport.cxx @@ -58,6 +58,7 @@ private: // unit tests public: + void testMediaShapeScreen_Tdf159094(); void testExportRange_Tdf120161(); void testExportFitToPage_Tdf103516(); void testUnoCommands_Tdf120161(); @@ -69,6 +70,7 @@ public: void testForcepoint97(); CPPUNIT_TEST_SUITE(ScPDFExportTest); + CPPUNIT_TEST(testMediaShapeScreen_Tdf159094); CPPUNIT_TEST(testExportRange_Tdf120161); CPPUNIT_TEST(testExportFitToPage_Tdf103516); CPPUNIT_TEST(testUnoCommands_Tdf120161); @@ -199,6 +201,18 @@ void ScPDFExportTest::setFont(ScFieldEditEngine& rEE, sal_Int32 nStart, sal_Int3 rEE.QuickSetAttribs(aItemSet, aSel); } +void ScPDFExportTest::testMediaShapeScreen_Tdf159094() +{ + loadFromFile(u"tdf159094.ods"); + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + + // A1:B8 + ScRange aRange(0, 0, 0, 1, 7, 0); + + // Without the fix, this test would crash on export media file to pdf + exportToPDF(xModel, aRange); +} + // Selection was not taken into account during export into PDF void ScPDFExportTest::testExportRange_Tdf120161() { diff --git a/sc/qa/extras/testdocuments/tdf159094.ods b/sc/qa/extras/testdocuments/tdf159094.ods new file mode 100644 index 000000000000..c267b2152192 Binary files /dev/null and b/sc/qa/extras/testdocuments/tdf159094.ods differ diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index a4fc5f6d60de..216cd6328be4 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -27,6 +27,9 @@ #include <editeng/editview.hxx> #include <editeng/memberids.h> #include <editeng/outliner.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/sizeitem.hxx> #include <o3tl/any.hxx> #include <o3tl/safeint.hxx> #include <svx/fmview.hxx> @@ -127,6 +130,7 @@ #include <table.hxx> #include <appoptio.hxx> #include <formulaopt.hxx> +#include <stlpool.hxx> #include <strings.hrc> @@ -2030,7 +2034,7 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 bWasCellRange = pPrintFunc->GetLastSourceRange( aCellRange ); Size aTwips = pPrintFunc->GetPageSize(); - if (!m_pPrintState) + if (!m_pPrintState || nRenderer == nTabStart) { m_pPrintState.reset(new ScPrintState()); pPrintFunc->GetPrintState(*m_pPrintState, true); @@ -2076,6 +2080,172 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 return aSequence; } +static void lcl_SetMediaScreen(const uno::Reference<drawing::XShape>& xMediaShape, + const OutputDevice* pDev, tools::Rectangle& aRect, + sal_Int32 nPageNumb) +{ + OUString sMediaURL; + uno::Reference<beans::XPropertySet> xPropSet(xMediaShape, uno::UNO_QUERY); + xPropSet->getPropertyValue("MediaURL") >>= sMediaURL; + if (!sMediaURL.isEmpty()) + { + OUString sTitle; + xPropSet->getPropertyValue("Title") >>= sTitle; + OUString sDescription; + xPropSet->getPropertyValue("Description") >>= sDescription; + OUString const altText(sTitle.isEmpty() ? sDescription + : sDescription.isEmpty() + ? sTitle + : OUString::Concat(sTitle) + OUString::Concat(" ") + + OUString::Concat(sDescription)); + + OUString const mimeType(xPropSet->getPropertyValue("MediaMimeType").get<OUString>()); + SdrObject* pSdrObj(SdrObject::getSdrObjectFromXShape(xMediaShape)); + vcl::PDFExtOutDevData* pPDF = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData()); + sal_Int32 nScreenId = pPDF->CreateScreen(aRect, altText, mimeType, nPageNumb, pSdrObj); + if (sMediaURL.startsWith("vnd.sun.star.Package:")) + { + // Embedded media + OUString aTempFileURL; + xPropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL; + pPDF->SetScreenStream(nScreenId, aTempFileURL); + } + else // Linked media + pPDF->SetScreenURL(nScreenId, sMediaURL); + } +} + +static void lcl_PDFExportMediaShapeScreen(const OutputDevice* pDev, const ScPrintState& rState, + ScDocument& rDoc, SCTAB nTab, tools::Long nStartPage, + bool bSinglePageSheets) +{ + ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); + vcl::PDFExtOutDevData* pPDF = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData()); + if (pPDF && pPDF->GetIsExportTaggedPDF() && pDrawLayer) + { + + if (!bSinglePageSheets) + { + SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); + OSL_ENSURE(pPage, "Page ?"); + if (pPage) + { + ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool(); + SfxStyleSheetBase* pStyleSheet = pStylePool->Find(rDoc.GetPageStyle(nTab), SfxStyleFamily::Page); + SfxItemSet* pItemSet = &pStyleSheet->GetItemSet(); + + tools::Long nLeftMargin(pItemSet->Get(ATTR_LRSPACE).GetLeft()); + nLeftMargin = o3tl::convert(nLeftMargin, o3tl::Length::twip, o3tl::Length::mm100); + + tools::Long nTopMargin(pItemSet->Get(ATTR_ULSPACE).GetUpper()); + nTopMargin = o3tl::convert(nTopMargin, o3tl::Length::twip, o3tl::Length::mm100); + + tools::Long nHeader = 0; + const SvxSetItem* pHeaderSetItem = &pItemSet->Get(ATTR_PAGE_HEADERSET); + bool bHasHdr = pHeaderSetItem->GetItemSet().Get(ATTR_PAGE_ON).GetValue(); + if (bHasHdr) + { + const SfxItemSet* pHeaderSet = &pHeaderSetItem->GetItemSet(); + tools::Long nHdrHeight = pHeaderSet->Get(ATTR_PAGE_SIZE).GetSize().Height(); + nHeader = o3tl::convert(nHdrHeight, o3tl::Length::twip, o3tl::Length::mm100); + } + + bool bTopDown = pItemSet->Get(ATTR_PAGE_TOPDOWN).GetValue(); + + SdrObjListIter aIter(pPage, SdrIterMode::DeepWithGroups); + SdrObject* pObj = aIter.Next(); + while (pObj && pObj->IsVisible()) + { + uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY); + if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape") + { + SCCOL nX1, nX2; + SCROW nY1, nY2; + sal_Int32 nPageNumb = nStartPage; + if (bTopDown) // top-bottom page order + { + nX1 = 0; + for (size_t i = 0; i < rState.nPagesX; ++i) + { + nX2 = (*rState.xPageEndX)[i]; + for (size_t j = 0; j < rState.nPagesY; ++j) + { + auto& rPageRow = (*rState.xPageRows)[j]; + nY1 = rPageRow.GetStartRow(); + nY2 = rPageRow.GetEndRow(); + + tools::Rectangle aPageRect(rDoc.GetMMRect(nX1, nY1, nX2, nY2, nTab)); + tools::Rectangle aTmpRect(aPageRect.GetIntersection(pObj->GetCurrentBoundRect())); + if (!aTmpRect.IsEmpty()) + { + tools::Long nPosX(aTmpRect.getX() - aPageRect.getX() + nLeftMargin); + tools::Long nPosY(aTmpRect.getY() - aPageRect.getY() + nHeader + nTopMargin); + tools::Rectangle aRect(Point(nPosX, nPosY), aTmpRect.GetSize()); + lcl_SetMediaScreen(xShape, pDev, aRect, nPageNumb); + } + ++nPageNumb; + } + nX1 = nX2 + 1; + } + } + else // left to right page order + { + for (size_t i = 0; i < rState.nPagesY; ++i) + { + auto& rPageRow = (*rState.xPageRows)[i]; + nY1 = rPageRow.GetStartRow(); + nY2 = rPageRow.GetEndRow(); + nX1 = 0; + for (size_t j = 0; j < rState.nPagesX; ++j) + { + nX2 = (*rState.xPageEndX)[j]; + + tools::Rectangle aPageRect(rDoc.GetMMRect(nX1, nY1, nX2, nY2, nTab)); + tools::Rectangle aTmpRect(aPageRect.GetIntersection(pObj->GetCurrentBoundRect())); + if (!aTmpRect.IsEmpty()) + { + tools::Long nPosX(aTmpRect.getX() - aPageRect.getX() + nLeftMargin); + tools::Long nPosY(aTmpRect.getY() - aPageRect.getY() + nHeader + nTopMargin); + tools::Rectangle aRect(Point(nPosX, nPosY), aTmpRect.GetSize()); + lcl_SetMediaScreen(xShape, pDev, aRect, nPageNumb); + } + ++nPageNumb; + nX1 = nX2 + 1; + } + } + } + } + pObj = aIter.Next(); + } + } + } + else // export whole sheet + { + SCTAB nTabCount = rDoc.GetTableCount(); + for (SCTAB i = 0; i < nTabCount; ++i) + { + SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i)); + OSL_ENSURE(pPage, "Page ?"); + if (pPage) + { + SdrObjListIter aIter(pPage, SdrIterMode::DeepWithGroups); + SdrObject* pObj = aIter.Next(); + while (pObj && pObj->IsVisible()) + { + uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY); + if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape") + { + tools::Rectangle aRect(pObj->GetCurrentBoundRect()); + lcl_SetMediaScreen(xShape, pDev, aRect, i); + } + pObj = aIter.Next(); + } + } + } + } + } +} + void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelection, const uno::Sequence<beans::PropertyValue>& rOptions ) { @@ -2122,6 +2292,17 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec ScDocument& rDoc = pDocShell->GetDocument(); + SCTAB nTab; + if (!maValidPages.empty()) + nTab = pPrintFuncCache->GetTabForPage(maValidPages.at(nRenderer) - 1); + else + nTab = pPrintFuncCache->GetTabForPage(nRenderer); + + tools::Long nTabStart = pPrintFuncCache->GetTabStart(nTab); + + if (nRenderer == nTabStart) + lcl_PDFExportMediaShapeScreen(pDev, *m_pPrintState, rDoc, nTab, nTabStart, bSinglePageSheets); + ScRange aRange; const ScRange* pSelRange = nullptr; if ( bSinglePageSheets ) @@ -2196,12 +2377,6 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec } } aDrawViewKeeper; - SCTAB nTab; - if ( !maValidPages.empty() ) - nTab = pPrintFuncCache->GetTabForPage( maValidPages.at( nRenderer )-1 ); - else - nTab = pPrintFuncCache->GetTabForPage( nRenderer ); - ScDrawLayer* pModel = rDoc.GetDrawLayer(); if( pModel ) @@ -2256,7 +2431,6 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec aPage.Select( nRenderer+1 ); tools::Long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab ); - tools::Long nTabStart = pPrintFuncCache->GetTabStart( nTab ); vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* >(pDev->GetExtOutDevData() ); if ( nRenderer == nTabStart )