include/svx/xmlgrhlp.hxx | 3 + include/xmloff/xmlimp.hxx | 3 - offapi/com/sun/star/document/XGraphicStorageHandler.idl | 6 +- svx/source/xml/xmlgrhlp.cxx | 28 +++++++--- xmloff/qa/unit/draw.cxx | 44 +++++++++------- xmloff/source/core/xmlimp.cxx | 5 + xmloff/source/draw/ximpshap.cxx | 2 7 files changed, 60 insertions(+), 31 deletions(-)
New commits: commit 00cb5334e75cf08a004273829e3cebd3f43d3e19 Author: Caolán McNamara <[email protected]> AuthorDate: Wed Oct 29 13:14:41 2025 +0000 Commit: Miklos Vajna <[email protected]> CommitDate: Thu Oct 30 13:42:34 2025 +0100 [API CHANGE] sd pdfium: apply page number when loading pdf pages from fodg this is the same concept/ideas as a12bd4fedfc3f269f1dbb5fea36b607facd1261d [API CHANGE] sd pdfium: add page number when saving/loading pdf pages as images but extended to support fodg where the problem of showing the first page of the pdf for all images remained. Change-Id: I5a180037634f71104800e09bec400316b56ab1f2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193151 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/include/svx/xmlgrhlp.hxx b/include/svx/xmlgrhlp.hxx index 6e84eb340e56..1057b1ad18fd 100644 --- a/include/svx/xmlgrhlp.hxx +++ b/include/svx/xmlgrhlp.hxx @@ -110,6 +110,9 @@ public: virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL loadGraphicFromOutputStream(css::uno::Reference<css::io::XOutputStream> const & rxOutputStream) override; + virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL + loadGraphicFromOutputStreamAtPage(css::uno::Reference<css::io::XOutputStream> const & rxOutputStream, sal_Int32 nPage) override; + virtual OUString SAL_CALL saveGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic) override; diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx index fd41f6120a27..eb831f54d61c 100644 --- a/include/xmloff/xmlimp.hxx +++ b/include/xmloff/xmlimp.hxx @@ -412,7 +412,8 @@ public: css::uno::Reference<css::graphic::XGraphic> loadGraphicByURL(OUString const& rURL, sal_Int32 nPageNum = -1); - css::uno::Reference<css::graphic::XGraphic> loadGraphicFromBase64(css::uno::Reference<css::io::XOutputStream> const & rxOutputStream); + css::uno::Reference<css::graphic::XGraphic> loadGraphicFromBase64(css::uno::Reference<css::io::XOutputStream> const & rxOutputStream, + sal_Int32 nPageNum = -1); css::uno::Reference< css::io::XOutputStream > GetStreamForGraphicObjectURLFromBase64() const; diff --git a/offapi/com/sun/star/document/XGraphicStorageHandler.idl b/offapi/com/sun/star/document/XGraphicStorageHandler.idl index 7390b189394f..c440e1e9351b 100644 --- a/offapi/com/sun/star/document/XGraphicStorageHandler.idl +++ b/offapi/com/sun/star/document/XGraphicStorageHandler.idl @@ -21,7 +21,7 @@ interface XGraphicStorageHandler : com::sun::star::uno::XInterface */ com::sun::star::graphic::XGraphic loadGraphic([in] string aURL); - /** load a specific page from a graphic defined by the URL from the storage + /** load a specific page of a graphic defined by the URL from the storage */ com::sun::star::graphic::XGraphic loadGraphicAtPage([in] string aURL, [in] long nPage); @@ -29,6 +29,10 @@ interface XGraphicStorageHandler : com::sun::star::uno::XInterface */ com::sun::star::graphic::XGraphic loadGraphicFromOutputStream([in] com::sun::star::io::XOutputStream xOutputStream); + /** load a specific page of a graphic from the output stream + */ + com::sun::star::graphic::XGraphic loadGraphicFromOutputStreamAtPage([in] com::sun::star::io::XOutputStream xOutputStream, [in] long nPage); + /** save the graphic to the storage and return the URL reference to its location inside the storage */ diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx index 32f217365a9a..866fb028ae64 100644 --- a/svx/source/xml/xmlgrhlp.cxx +++ b/svx/source/xml/xmlgrhlp.cxx @@ -237,7 +237,7 @@ public: bool Exists() const { return mxStmWrapper.is(); } const GraphicObject& GetGraphicObject(); - Graphic GetGraphic(); + Graphic GetGraphic(sal_Int32 nPageNum = -1); }; SvXMLGraphicOutputStream::SvXMLGraphicOutputStream() @@ -283,7 +283,7 @@ void SAL_CALL SvXMLGraphicOutputStream::closeOutput() mbClosed = true; } -Graphic SvXMLGraphicOutputStream::GetGraphic() +Graphic SvXMLGraphicOutputStream::GetGraphic(sal_Int32 nPageNum) { Graphic aGraphic; @@ -292,7 +292,8 @@ Graphic SvXMLGraphicOutputStream::GetGraphic() mpOStm->Seek( 0 ); sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW; sal_uInt16 nDeterminedFormat = GRFILTER_FORMAT_DONTKNOW; - GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, u"", *mpOStm ,nFormat,&nDeterminedFormat); + GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, u"", *mpOStm ,nFormat,&nDeterminedFormat, + GraphicFilterImportFlags::NONE, nPageNum); if (nDeterminedFormat == GRFILTER_FORMAT_DONTKNOW) { @@ -332,7 +333,8 @@ Graphic SvXMLGraphicOutputStream::GetGraphic() if (nStreamLen_ > 0) { aDest.Seek(0); - GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, u"", aDest ,nFormat,&nDeterminedFormat ); + GraphicFilter::GetGraphicFilter().ImportGraphic( aGraphic, u"", aDest ,nFormat,&nDeterminedFormat, + GraphicFilterImportFlags::NONE, nPageNum); } } } @@ -619,7 +621,7 @@ uno::Reference<graphic::XGraphic> return xGraphic; } -uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicHelper::loadGraphicFromOutputStream(uno::Reference<io::XOutputStream> const & rxOutputStream) +uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicHelper::loadGraphicFromOutputStreamAtPage(uno::Reference<io::XOutputStream> const & rxOutputStream, sal_Int32 nPageNum) { std::unique_lock aGuard(m_aMutex); @@ -627,16 +629,20 @@ uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicHelper::loadGraphicFromOu if ((SvXMLGraphicHelperMode::Read == meCreateMode) && rxOutputStream.is()) { - SvXMLGraphicOutputStream* pGraphicOutputStream = static_cast<SvXMLGraphicOutputStream*>(rxOutputStream.get()); if (pGraphicOutputStream) { - xGraphic = pGraphicOutputStream->GetGraphic().GetXGraphic(); + xGraphic = pGraphicOutputStream->GetGraphic(nPageNum).GetXGraphic(); } } return xGraphic; } +uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicHelper::loadGraphicFromOutputStream(uno::Reference<io::XOutputStream> const & rxOutputStream) +{ + return loadGraphicFromOutputStreamAtPage(rxOutputStream, -1); +} + OUString SAL_CALL SvXMLGraphicHelper::saveGraphicByName(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic, OUString & rOutSavedMimeType, OUString const & rRequestName) { @@ -987,6 +993,9 @@ protected: virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL loadGraphicFromOutputStream(css::uno::Reference<css::io::XOutputStream> const & rxOutputStream) override; + virtual css::uno::Reference<css::graphic::XGraphic> SAL_CALL + loadGraphicFromOutputStreamAtPage(css::uno::Reference<css::io::XOutputStream> const & rxOutputStream, sal_Int32 nPage) override; + virtual OUString SAL_CALL saveGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic) override; @@ -1059,6 +1068,11 @@ uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicImportExportHelper::loadG return m_xXMLGraphicHelper->loadGraphicFromOutputStream(rxOutputStream); } +uno::Reference<graphic::XGraphic> SAL_CALL SvXMLGraphicImportExportHelper::loadGraphicFromOutputStreamAtPage(uno::Reference<io::XOutputStream> const & rxOutputStream, sal_Int32 nPage) +{ + return m_xXMLGraphicHelper->loadGraphicFromOutputStreamAtPage(rxOutputStream, nPage); +} + OUString SAL_CALL SvXMLGraphicImportExportHelper::saveGraphic(css::uno::Reference<css::graphic::XGraphic> const & rxGraphic) { return m_xXMLGraphicHelper->saveGraphic(rxGraphic); diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index 41019fbeb204..102c656ef937 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -1107,26 +1107,32 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testPdfExportAsOdg) }); loadFromFile(u"two-pages.pdf"); - // save and reload as odg - saveAndReload("draw8"); - // Check that the graphic in the second page of the document is the second page of the pdf - uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, - uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT(xDrawPagesSupplier.is()); - uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages()); - uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(1), uno::UNO_QUERY_THROW); - uno::Reference<drawing::XShape> xImage(xDrawPage->getByIndex(0), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT(xImage.is()); - uno::Reference<beans::XPropertySet> xShapeProps(xImage, uno::UNO_QUERY); - uno::Reference<graphic::XGraphic> xGraphic; - CPPUNIT_ASSERT(xShapeProps->getPropertyValue("Graphic") >>= xGraphic); - - Graphic aGraphic(xGraphic); - // Without the accompanying fix in place, this test would have failed with: - // - Expected: 1 - // - Actual : -1 - CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aGraphic.getPageNumber()); + OUString formats[] = { "draw8", "OpenDocument Drawing Flat XML" }; + // save and reload as odg and fodg + for (const OUString& format : formats) + { + saveAndReload(format); + + // Check that the graphic in the second page of the document is the second page of the pdf + uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xDrawPagesSupplier.is()); + uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages()); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(1), + uno::UNO_QUERY_THROW); + uno::Reference<drawing::XShape> xImage(xDrawPage->getByIndex(0), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xImage.is()); + uno::Reference<beans::XPropertySet> xShapeProps(xImage, uno::UNO_QUERY); + uno::Reference<graphic::XGraphic> xGraphic; + CPPUNIT_ASSERT(xShapeProps->getPropertyValue("Graphic") >>= xGraphic); + + Graphic aGraphic(xGraphic); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : -1 + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aGraphic.getPageNumber()); + } } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx index e5edc29a41cd..25454277728a 100644 --- a/xmloff/source/core/xmlimp.cxx +++ b/xmloff/source/core/xmlimp.cxx @@ -1342,13 +1342,14 @@ uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString const& return xGraphic; } -uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream) +uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream, + sal_Int32 nPageNum) { uno::Reference<graphic::XGraphic> xGraphic; if (mxGraphicStorageHandler.is()) { - xGraphic = mxGraphicStorageHandler->loadGraphicFromOutputStream(rxOutputStream); + xGraphic = mxGraphicStorageHandler->loadGraphicFromOutputStreamAtPage(rxOutputStream, nPageNum); } return xGraphic; diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index 6b742be164ae..9ef86aa801d5 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -2462,7 +2462,7 @@ void SdXMLGraphicObjectShapeContext::endFastElement(sal_Int32 nElement) { if (mxBase64Stream.is()) { - uno::Reference<graphic::XGraphic> xGraphic(GetImport().loadGraphicFromBase64(mxBase64Stream)); + uno::Reference<graphic::XGraphic> xGraphic(GetImport().loadGraphicFromBase64(mxBase64Stream, mnPage)); if (xGraphic.is()) { uno::Reference<beans::XPropertySet> xProperties(mxShape, uno::UNO_QUERY);
