diff options
-rw-r--r-- | filter/source/pdf/pdfdecomposer.cxx | 28 | ||||
-rw-r--r-- | include/vcl/graph.hxx | 2 | ||||
-rw-r--r-- | include/vcl/vectorgraphicdata.hxx | 12 | ||||
-rw-r--r-- | offapi/com/sun/star/graphic/XPdfDecomposer.idl | 8 | ||||
-rw-r--r-- | sd/qa/unit/import-tests.cxx | 15 | ||||
-rw-r--r-- | vcl/inc/impgraph.hxx | 7 | ||||
-rw-r--r-- | vcl/source/filter/ipdf/pdfread.cxx | 18 | ||||
-rw-r--r-- | vcl/source/gdi/graph.cxx | 7 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 34 | ||||
-rw-r--r-- | vcl/source/gdi/vectorgraphicdata.cxx | 22 |
10 files changed, 85 insertions, 68 deletions
diff --git a/filter/source/pdf/pdfdecomposer.cxx b/filter/source/pdf/pdfdecomposer.cxx index c926b1b35a9d..a03e70bd5d1a 100644 --- a/filter/source/pdf/pdfdecomposer.cxx +++ b/filter/source/pdf/pdfdecomposer.cxx @@ -39,8 +39,9 @@ public: XPdfDecomposer& operator=(const XPdfDecomposer&) = delete; // XPdfDecomposer - uno::Sequence<uno::Reference<graphic::XPrimitive2D>> - SAL_CALL getDecomposition(const uno::Sequence<sal_Int8>& xPdfData) override; + uno::Sequence<uno::Reference<graphic::XPrimitive2D>> SAL_CALL + getDecomposition(const uno::Sequence<sal_Int8>& xPdfData, + const uno::Sequence<beans::PropertyValue>& xDecompositionParameters) override; // XServiceInfo OUString SAL_CALL getImplementationName() override; @@ -50,12 +51,27 @@ public: XPdfDecomposer::XPdfDecomposer(uno::Reference<uno::XComponentContext> const&) {} -uno::Sequence<uno::Reference<graphic::XPrimitive2D>> - SAL_CALL XPdfDecomposer::getDecomposition(const uno::Sequence<sal_Int8>& xPdfData) +uno::Sequence<uno::Reference<graphic::XPrimitive2D>> SAL_CALL XPdfDecomposer::getDecomposition( + const uno::Sequence<sal_Int8>& xPdfData, const uno::Sequence<beans::PropertyValue>& xParameters) { + sal_Int32 nPageIndex = -1; + + for (sal_Int32 index = 0; index < xParameters.getLength(); index++) + { + const beans::PropertyValue& rProperty = xParameters[index]; + + if (rProperty.Name == "PageIndex") + { + rProperty.Value >>= nPageIndex; + } + } + + if (nPageIndex < 0) + nPageIndex = 0; + std::vector<Bitmap> aBitmaps; - vcl::RenderPDFBitmaps(xPdfData.getConstArray(), xPdfData.getLength(), aBitmaps, 0, - 1 /*, fResolutionDPI*/); + vcl::RenderPDFBitmaps(xPdfData.getConstArray(), xPdfData.getLength(), aBitmaps, nPageIndex, 1); + BitmapEx aReplacement(aBitmaps[0]); // short form for scale and translate transformation diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx index 271de60d1605..6e70f66731ac 100644 --- a/include/vcl/graph.hxx +++ b/include/vcl/graph.hxx @@ -204,8 +204,6 @@ public: const VectorGraphicDataPtr& getVectorGraphicData() const; - /// Set the page number of the multi-page source this Graphic is rendered from. - void setPageNumber(sal_Int32 nPageNumber); /// Get the page number of the multi-page source this Graphic is rendered from. sal_Int32 getPageNumber() const; diff --git a/include/vcl/vectorgraphicdata.hxx b/include/vcl/vectorgraphicdata.hxx index 096c89e1aa56..8ccf45b51e5d 100644 --- a/include/vcl/vectorgraphicdata.hxx +++ b/include/vcl/vectorgraphicdata.hxx @@ -70,6 +70,9 @@ private: // extra: std::unique_ptr<WmfExternal> mpExternalHeader; + // If the vector format has more pages this denotes which page to render + sal_Int32 mnPageIndex; + // on demand creators void ensurePdfReplacement(); void ensureReplacement(); @@ -82,10 +85,9 @@ public: VectorGraphicData( const VectorGraphicDataArray& rVectorGraphicDataArray, const OUString& rPath, - VectorGraphicDataType eVectorDataType); - VectorGraphicData( - const OUString& rPath, - VectorGraphicDataType eVectorDataType); + VectorGraphicDataType eVectorDataType, + sal_Int32 nPageIndex = -1); + VectorGraphicData(const OUString& rPath, VectorGraphicDataType eVectorDataType); ~VectorGraphicData(); /// compare op @@ -107,6 +109,8 @@ public: const std::deque< css::uno::Reference< css::graphic::XPrimitive2D > >& getPrimitive2DSequence() const; const BitmapEx& getReplacement() const; BitmapChecksum GetChecksum() const; + + sal_Int32 getPageIndex() const { return mnPageIndex; } }; typedef std::shared_ptr< VectorGraphicData > VectorGraphicDataPtr; diff --git a/offapi/com/sun/star/graphic/XPdfDecomposer.idl b/offapi/com/sun/star/graphic/XPdfDecomposer.idl index 85b38c035c8c..aae6eda55347 100644 --- a/offapi/com/sun/star/graphic/XPdfDecomposer.idl +++ b/offapi/com/sun/star/graphic/XPdfDecomposer.idl @@ -27,9 +27,15 @@ interface XPdfDecomposer : ::com::sun::star::uno::XInterface @param xPdfData The PDF data. + @param xDecompositionParameters + Parameters for decomposition. Parameters include: + + sal_Int32 Page - which page to use + @since LibreOffice 7.0 */ - sequence<XPrimitive2D> getDecomposition([in] sequence<byte> xPdfData); + sequence<XPrimitive2D> getDecomposition([in] sequence<byte> xPdfData, + [in] sequence<com::sun::star::beans::PropertyValue> xDecompositionParameters); }; }; }; }; }; diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx index addf393630a1..954ef5b187ba 100644 --- a/sd/qa/unit/import-tests.cxx +++ b/sd/qa/unit/import-tests.cxx @@ -1327,17 +1327,20 @@ void SdImportTest::testPDFImportShared() CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected more than one page.", size_t(3), aGraphics.size()); - Graphic aFirstGraphic = aGraphics[0]; + Graphic const & rFirstGraphic = aGraphics[0]; - for (size_t i = 1; i < aGraphics.size(); ++i) + for (size_t i = 0; i < aGraphics.size(); ++i) { + Graphic const & rGraphic = aGraphics[i]; CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all PDF streams to be identical.", - aFirstGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(), - aGraphics[i].getVectorGraphicData()->getVectorGraphicDataArray().getConstArray()); + rFirstGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(), + rGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all GfxLinks to be identical.", - aFirstGraphic.GetSharedGfxLink().get(), - aGraphics[i].GetSharedGfxLink().get()); + rFirstGraphic.GetSharedGfxLink().get(), + rGraphic.GetSharedGfxLink().get()); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Page number doesn't match expected", sal_Int32(i), rGraphic.getPageNumber()); } xDocShRef->DoClose(); diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index 965c41a4392e..a5435ee73b39 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -75,11 +75,6 @@ private: std::chrono::high_resolution_clock::time_point maLastUsed; bool mbPrepared; - /// Used with GfxLink and/or PdfData when they store original media - /// which might be multi-page (PDF, f.e.) and we need to re-render - /// this Graphic (a page) from the source in GfxLink or PdfData. - sal_Int32 mnPageNumber; - public: ImpGraphic(); ImpGraphic( const ImpGraphic& rImpGraphic ); @@ -203,6 +198,8 @@ private: bool ensureAvailable () const; bool loadPrepared(); + + sal_Int32 getPageNumber() const; }; #endif // INCLUDED_VCL_INC_IMPGRAPH_HXX diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index 0dbb0fe455cb..b85a79d86e4a 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -223,19 +223,12 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi bool ImportPDF(SvStream& rStream, Graphic& rGraphic) { - // Save the original PDF stream for later use. - SvMemoryStream aMemoryStream; - if (!getCompatibleStream(rStream, aMemoryStream, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END)) - return false; - const sal_uInt32 nStreamLength = aMemoryStream.TellEnd(); - VectorGraphicDataArray aPdfData(nStreamLength); - aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); - aMemoryStream.ReadBytes(aPdfData.begin(), nStreamLength); - if (aMemoryStream.GetError()) + VectorGraphicDataArray aPdfDataArray = createVectorGraphicDataArray(rStream); + if (!aPdfDataArray.hasElements()) return false; - auto aVectorGraphicDataPtr - = std::make_shared<VectorGraphicData>(aPdfData, OUString(), VectorGraphicDataType::Pdf); + auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>(aPdfDataArray, OUString(), + VectorGraphicDataType::Pdf); rGraphic = Graphic(aVectorGraphicDataPtr); return true; @@ -291,13 +284,12 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si const size_t nPageHeight = pointToPixel(fPageHeight, fResolutionDPI); auto aVectorGraphicDataPtr = std::make_shared<VectorGraphicData>( - aPdfDataArray, OUString(), VectorGraphicDataType::Pdf); + aPdfDataArray, OUString(), VectorGraphicDataType::Pdf, nPageIndex); // Create the Graphic with the VectorGraphicDataPtr and link the original PDF stream. // We swap out this Graphic as soon as possible, and a later swap in // actually renders the correct Bitmap on demand. Graphic aGraphic(aVectorGraphicDataPtr); - aGraphic.setPageNumber(nPageIndex); aGraphic.SetGfxLink(pGfxLink); rGraphics.emplace_back(std::move(aGraphic), Size(nPageWidth, nPageHeight)); diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index c98212ad5c67..96414b43ad3a 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -560,14 +560,9 @@ const VectorGraphicDataPtr& Graphic::getVectorGraphicData() const return mxImpGraphic->getVectorGraphicData(); } -void Graphic::setPageNumber(sal_Int32 nPageNumber) -{ - mxImpGraphic->mnPageNumber = nPageNumber; -} - sal_Int32 Graphic::getPageNumber() const { - return mxImpGraphic->mnPageNumber; + return mxImpGraphic->getPageNumber(); } OUString Graphic::getOriginURL() const diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 9361aef3951d..90a1e4e58ed8 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -73,8 +73,7 @@ ImpGraphic::ImpGraphic() : mbSwapOut ( false ), mbDummyContext ( false ), maLastUsed (std::chrono::high_resolution_clock::now()), - mbPrepared ( false ), - mnPageNumber(-1) + mbPrepared ( false ) { } @@ -93,7 +92,6 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink) , maLastUsed (std::chrono::high_resolution_clock::now()) , mbPrepared (rImpGraphic.mbPrepared) - , mnPageNumber(rImpGraphic.mnPageNumber) { if( rImpGraphic.mpAnimation ) { @@ -118,7 +116,6 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink) , maLastUsed (std::chrono::high_resolution_clock::now()) , mbPrepared (rImpGraphic.mbPrepared) - , mnPageNumber(rImpGraphic.mnPageNumber) { rImpGraphic.ImplClear(); rImpGraphic.mbDummyContext = false; @@ -131,8 +128,7 @@ ImpGraphic::ImpGraphic(GraphicExternalLink const & rGraphicExternalLink) : mbDummyContext ( false ), maGraphicExternalLink(rGraphicExternalLink), maLastUsed (std::chrono::high_resolution_clock::now()), - mbPrepared (false), - mnPageNumber(-1) + mbPrepared (false) { } @@ -143,8 +139,7 @@ ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) : mbSwapOut ( false ), mbDummyContext ( false ), maLastUsed (std::chrono::high_resolution_clock::now()), - mbPrepared (false), - mnPageNumber(-1) + mbPrepared (false) { } @@ -155,8 +150,7 @@ ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) : mbSwapOut ( false ), mbDummyContext ( false ), maLastUsed (std::chrono::high_resolution_clock::now()), - mbPrepared (false), - mnPageNumber(-1) + mbPrepared (false) { } @@ -167,8 +161,7 @@ ImpGraphic::ImpGraphic(const VectorGraphicDataPtr& rVectorGraphicDataPtr) mbDummyContext ( false ), maVectorGraphicData(rVectorGraphicDataPtr), maLastUsed (std::chrono::high_resolution_clock::now()), - mbPrepared (false), - mnPageNumber(-1) + mbPrepared (false) { } @@ -180,8 +173,7 @@ ImpGraphic::ImpGraphic( const Animation& rAnimation ) : mbSwapOut ( false ), mbDummyContext ( false ), maLastUsed (std::chrono::high_resolution_clock::now()), - mbPrepared (false), - mnPageNumber(-1) + mbPrepared (false) { } @@ -192,8 +184,7 @@ ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) : mbSwapOut ( false ), mbDummyContext ( false ), maLastUsed (std::chrono::high_resolution_clock::now()), - mbPrepared (false), - mnPageNumber(-1) + mbPrepared (false) { } @@ -215,7 +206,6 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic ) maSwapInfo = rImpGraphic.maSwapInfo; mpContext = rImpGraphic.mpContext; mbDummyContext = rImpGraphic.mbDummyContext; - mnPageNumber = rImpGraphic.mnPageNumber; maGraphicExternalLink = rImpGraphic.maGraphicExternalLink; mpAnimation.reset(); @@ -255,7 +245,6 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic) maSwapInfo = std::move(rImpGraphic.maSwapInfo); mpContext = std::move(rImpGraphic.mpContext); mbDummyContext = rImpGraphic.mbDummyContext; - mnPageNumber = rImpGraphic.mnPageNumber; mpAnimation = std::move(rImpGraphic.mpAnimation); maEx = std::move(rImpGraphic.maEx); mbSwapOut = rImpGraphic.mbSwapOut; @@ -271,8 +260,6 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic) vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes); - rImpGraphic.mnPageNumber = -1; - return *this; } @@ -1618,6 +1605,13 @@ bool ImpGraphic::ImplExportNative( SvStream& rOStm ) const return bResult; } +sal_Int32 ImpGraphic::getPageNumber() const +{ + if (maVectorGraphicData) + return maVectorGraphicData->getPageIndex(); + return -1; +} + static std::map<BitmapChecksum, std::shared_ptr<std::vector<sal_Int8>>> sPdfDataCache; void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) diff --git a/vcl/source/gdi/vectorgraphicdata.cxx b/vcl/source/gdi/vectorgraphicdata.cxx index 9d877b35a73a..99e51f65cc71 100644 --- a/vcl/source/gdi/vectorgraphicdata.cxx +++ b/vcl/source/gdi/vectorgraphicdata.cxx @@ -33,6 +33,7 @@ #include <vcl/canvastools.hxx> #include <comphelper/seqstream.hxx> #include <comphelper/sequence.hxx> +#include <comphelper/propertysequence.hxx> #include <vcl/svapp.hxx> #include <vcl/outdev.hxx> #include <vcl/wmfexternal.hxx> @@ -146,7 +147,10 @@ void VectorGraphicData::ensurePdfReplacement() // use PDFium directly std::vector<Bitmap> aBitmaps; - vcl::RenderPDFBitmaps(maVectorGraphicDataArray.getConstArray(), maVectorGraphicDataArray.getLength(), aBitmaps, 0, 1/*, fResolutionDPI*/); + sal_Int32 nUsePageIndex = 0; + if (mnPageIndex >= 0) + nUsePageIndex = mnPageIndex; + vcl::RenderPDFBitmaps(maVectorGraphicDataArray.getConstArray(), maVectorGraphicDataArray.getLength(), aBitmaps, nUsePageIndex, 1/*, fResolutionDPI*/); maReplacement = aBitmaps[0]; } @@ -201,7 +205,9 @@ void VectorGraphicData::ensureSequenceAndRange() uno::Sequence< ::beans::PropertyValue > aSequence; if (mpExternalHeader) + { aSequence = mpExternalHeader->getSequence(); + } if (myInputStream.is()) maSequence = comphelper::sequenceToContainer<std::deque<css::uno::Reference< css::graphic::XPrimitive2D >>>(xEmfParser->getDecomposition(myInputStream, maPath, aSequence)); @@ -211,7 +217,10 @@ void VectorGraphicData::ensureSequenceAndRange() case VectorGraphicDataType::Pdf: { const uno::Reference<graphic::XPdfDecomposer> xPdfDecomposer = graphic::PdfTools::create(xContext); - auto xPrimitive2D = xPdfDecomposer->getDecomposition(maVectorGraphicDataArray); + uno::Sequence<beans::PropertyValue> aDecompositionParameters = comphelper::InitPropertySequence({ + {"PageIndex", uno::makeAny<sal_Int32>(mnPageIndex)}, + }); + auto xPrimitive2D = xPdfDecomposer->getDecomposition(maVectorGraphicDataArray, aDecompositionParameters); maSequence = comphelper::sequenceToContainer<std::deque<uno::Reference<graphic::XPrimitive2D>>>(xPrimitive2D); break; @@ -262,7 +271,8 @@ auto VectorGraphicData::getSizeBytes() const -> std::pair<State, size_t> VectorGraphicData::VectorGraphicData( const VectorGraphicDataArray& rVectorGraphicDataArray, const OUString& rPath, - VectorGraphicDataType eVectorDataType) + VectorGraphicDataType eVectorDataType, + sal_Int32 nPageIndex) : maVectorGraphicDataArray(rVectorGraphicDataArray), maPath(rPath), mbSequenceCreated(false), @@ -270,7 +280,8 @@ VectorGraphicData::VectorGraphicData( maSequence(), maReplacement(), mNestedBitmapSize(0), - meVectorGraphicDataType(eVectorDataType) + meVectorGraphicDataType(eVectorDataType), + mnPageIndex(nPageIndex) { } @@ -284,7 +295,8 @@ VectorGraphicData::VectorGraphicData( maSequence(), maReplacement(), mNestedBitmapSize(0), - meVectorGraphicDataType(eVectorDataType) + meVectorGraphicDataType(eVectorDataType), + mnPageIndex(-1) { SvFileStream rIStm(rPath, StreamMode::STD_READ); if(rIStm.GetError()) |