include/svx/svdograf.hxx | 2 include/vcl/graph.hxx | 5 include/vcl/pdfread.hxx | 34 +++++ sd/source/filter/pdf/sdpdffilter.cxx | 41 ++---- svtools/qa/unit/GraphicObjectTest.cxx | 4 svtools/source/graphic/grfcache.cxx | 16 ++ svx/source/svdraw/svdograf.cxx | 2 svx/source/svdraw/svdpdf.cxx | 4 svx/source/svdraw/svdpdf.hxx | 4 svx/source/xml/xmlgrhlp.cxx | 4 svx/source/xoutdev/_xoutbmp.cxx | 4 vcl/inc/impgraph.hxx | 11 - vcl/source/filter/graphicfilter.cxx | 2 vcl/source/filter/ipdf/pdfread.cxx | 217 +++++++++++++++++++++++----------- vcl/source/gdi/graph.cxx | 14 +- vcl/source/gdi/impgraph.cxx | 99 ++++++++++----- vcl/source/gdi/pdfextoutdevdata.cxx | 2 vcl/source/gdi/pdfwriter_impl.cxx | 10 - vcl/source/gdi/pdfwriter_impl.hxx | 4 19 files changed, 324 insertions(+), 155 deletions(-)
New commits: commit 9d5c868c04f53ac4d3c369e7596bdcfa512e289b Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Tue Apr 2 23:03:01 2019 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:54:02 2019 +0200 pdfium: Returning a const std::shared_ptr<...>& is not recommended. Change-Id: Iff6acef712c5b95c8cc222fc5293c9304b1c03ec diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx index 4f5108b3f2ce..cb7b04e2aa4a 100644 --- a/include/vcl/graph.hxx +++ b/include/vcl/graph.hxx @@ -230,7 +230,7 @@ public: const VectorGraphicDataPtr& getVectorGraphicData() const; void setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData); - const std::shared_ptr<std::vector<sal_Int8>>& getPdfData() const; + std::shared_ptr<std::vector<sal_Int8>> getPdfData() const; bool hasPdfData() const; /// Set the page number of the multi-page source this Graphic is rendered from. diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx index cdbda1db341c..9631c1c52f0c 100644 --- a/svx/source/xml/xmlgrhlp.cxx +++ b/svx/source/xml/xmlgrhlp.cxx @@ -558,7 +558,7 @@ bool SvXMLGraphicHelper::ImplWriteGraphic( const OUString& rPictureStorageName, // vcl::ImportPDF() possibly downgraded the PDF data from a // higher PDF version, while aGfxLink still contains the // original data provided by the user. - std::shared_ptr<std::vector<sal_Int8>> pPdfData = aGraphic.getPdfData(); + std::shared_ptr<std::vector<sal_Int8>> pPdfData(aGraphic.getPdfData()); pStream->WriteBytes(pPdfData->data(), pPdfData->size()); // put into cache diff --git a/svx/source/xoutdev/_xoutbmp.cxx b/svx/source/xoutdev/_xoutbmp.cxx index 63687c3a8313..34cdaab26473 100644 --- a/svx/source/xoutdev/_xoutbmp.cxx +++ b/svx/source/xoutdev/_xoutbmp.cxx @@ -192,7 +192,7 @@ ErrCode XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName, SfxMedium aMedium(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE|StreamMode::SHARE_DENYNONE|StreamMode::TRUNC); if (SvStream* pOutStream = aMedium.GetOutStream()) { - const std::shared_ptr<std::vector<sal_Int8>>& rPdfData = rGraphic.getPdfData(); + const std::shared_ptr<std::vector<sal_Int8>> rPdfData(rGraphic.getPdfData()); pOutStream->WriteBytes(rPdfData->data(), rPdfData->size()); aMedium.Commit(); if (!aMedium.GetError()) diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index a80e780d00f6..fdae47ced329 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -174,7 +174,7 @@ private: const VectorGraphicDataPtr& getVectorGraphicData() const { return maVectorGraphicData; } - const std::shared_ptr<std::vector<sal_Int8>>& getPdfData() const; + std::shared_ptr<std::vector<sal_Int8>> getPdfData() const; void setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData); }; diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index bf8da62b15cf..2e6b70e10f53 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -617,14 +617,14 @@ void Graphic::setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData) mxImpGraphic->setPdfData(rPdfData); } -const std::shared_ptr<std::vector<sal_Int8>>& Graphic::getPdfData() const +std::shared_ptr<std::vector<sal_Int8>> Graphic::getPdfData() const { return mxImpGraphic->getPdfData(); } bool Graphic::hasPdfData() const { - std::shared_ptr<std::vector<sal_Int8>> pPdfData = getPdfData(); + std::shared_ptr<std::vector<sal_Int8>> pPdfData(getPdfData()); return pPdfData && !pPdfData->empty(); } diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 48f10e30a917..cd3d5b9a0c32 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -357,7 +357,7 @@ void ImpGraphic::setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfDa mpPdfData = rPdfData; } -const std::shared_ptr<std::vector<sal_Int8>>& ImpGraphic::getPdfData() const +std::shared_ptr<std::vector<sal_Int8>> ImpGraphic::getPdfData() const { return mpPdfData; } commit ba328bb8862810712393e2ce3329ce798db84541 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Tue Apr 2 22:12:28 2019 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:54:02 2019 +0200 pdfium: Use std::vector to hold the PdfData. This fixes the destruction of the static cache of the PDF data; without this, there were already missing uno runtime info. Change-Id: I877c9ccf96c4b7eabf3d643e17f324d86d987f94 diff --git a/include/svx/svdograf.hxx b/include/svx/svdograf.hxx index aa7a6c221506..9e9b5a9625ba 100644 --- a/include/svx/svdograf.hxx +++ b/include/svx/svdograf.hxx @@ -194,7 +194,7 @@ public: GDIMetaFile getMetafileFromEmbeddedVectorGraphicData() const; bool isEmbeddedPdfData() const; - std::shared_ptr<css::uno::Sequence<sal_Int8>> getEmbeddedPdfData() const; + std::shared_ptr<std::vector<sal_Int8>> getEmbeddedPdfData() const; /// Returns the page number of the embedded data (typically to re-render or import it). sal_Int32 getEmbeddedPageNumber() const; diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx index 881abda221e4..4f5108b3f2ce 100644 --- a/include/vcl/graph.hxx +++ b/include/vcl/graph.hxx @@ -229,8 +229,8 @@ public: const VectorGraphicDataPtr& getVectorGraphicData() const; - void setPdfData(const std::shared_ptr<css::uno::Sequence<sal_Int8>>& rPdfData); - const std::shared_ptr<css::uno::Sequence<sal_Int8>>& getPdfData() const; + void setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData); + const std::shared_ptr<std::vector<sal_Int8>>& getPdfData() const; bool hasPdfData() const; /// Set the page number of the multi-page source this Graphic is rendered from. diff --git a/include/vcl/pdfread.hxx b/include/vcl/pdfread.hxx index e579f435261e..0ff6b39941c0 100644 --- a/include/vcl/pdfread.hxx +++ b/include/vcl/pdfread.hxx @@ -40,7 +40,7 @@ VCL_DLLPUBLIC size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vecto /// Imports a PDF stream into rGraphic as a GDIMetaFile. VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex, - css::uno::Sequence<sal_Int8>& rPdfData, + std::vector<sal_Int8>& rPdfData, sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN, sal_uInt64 nSize = STREAM_SEEK_TO_END, const double fResolutionDPI = 96.); @@ -49,7 +49,7 @@ VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic, const double fResolutionDPI = 96.); VCL_DLLPUBLIC size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps, - css::uno::Sequence<sal_Int8>& rPdfData, + std::vector<sal_Int8>& rPdfData, const double fResolutionDPI = 96.); /// Import PDF as Graphic images (1 per page), all unloaded. diff --git a/svtools/qa/unit/GraphicObjectTest.cxx b/svtools/qa/unit/GraphicObjectTest.cxx index e304f8e79996..afaf5d30f752 100644 --- a/svtools/qa/unit/GraphicObjectTest.cxx +++ b/svtools/qa/unit/GraphicObjectTest.cxx @@ -333,11 +333,11 @@ void GraphicObjectTest::testPdf() } CPPUNIT_ASSERT_MESSAGE("Missing image", pGraphicObject); - CPPUNIT_ASSERT(pGraphicObject->GetGraphic().getPdfData()->hasElements()); + CPPUNIT_ASSERT(!pGraphicObject->GetGraphic().getPdfData()->empty()); CPPUNIT_ASSERT(pGraphicObject->SwapOut()); CPPUNIT_ASSERT(pGraphicObject->SwapIn()); // This failed, swap out + swap in lost the PDF data. - CPPUNIT_ASSERT(pGraphicObject->GetGraphic().getPdfData()->hasElements()); + CPPUNIT_ASSERT(!pGraphicObject->GetGraphic().getPdfData()->empty()); xComponent->dispose(); #endif diff --git a/svtools/source/graphic/grfcache.cxx b/svtools/source/graphic/grfcache.cxx index 0bb04b0c5d56..a93d822a2667 100644 --- a/svtools/source/graphic/grfcache.cxx +++ b/svtools/source/graphic/grfcache.cxx @@ -82,13 +82,13 @@ GraphicID::GraphicID( const GraphicObject& rObj ) } else if (rGraphic.hasPdfData()) { - std::shared_ptr<css::uno::Sequence<sal_Int8>> pPdfData = rGraphic.getPdfData(); + std::shared_ptr<std::vector<sal_Int8>> pPdfData(rGraphic.getPdfData()); const BitmapEx& rBmpEx = rGraphic.GetBitmapEx(); mnID1 |= (rGraphic.getPageNumber() & 0x0fffffff); mnID2 = rBmpEx.GetSizePixel().Width(); mnID3 = rBmpEx.GetSizePixel().Height(); - mnID4 = vcl_get_checksum(0, pPdfData->getConstArray(), pPdfData->getLength()); + mnID4 = vcl_get_checksum(0, pPdfData->data(), pPdfData->size()); } else if( rGraphic.IsAnimated() ) { @@ -164,7 +164,7 @@ private: // VectorGraphicData support VectorGraphicDataPtr maVectorGraphicData; - std::shared_ptr<uno::Sequence<sal_Int8>> mpPdfData; + std::shared_ptr<std::vector<sal_Int8>> mpPdfData; bool ImplInit( const GraphicObject& rObj ); void ImplFillSubstitute( Graphic& rSubstitute ); @@ -250,7 +250,7 @@ bool GraphicCacheEntry::ImplInit( const GraphicObject& rObj ) else { mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() ); - if (rGraphic.hasPdfData() && rGraphic.getPdfData()->hasElements()) + if (rGraphic.hasPdfData() && !rGraphic.getPdfData()->empty()) mpPdfData = rGraphic.getPdfData(); } } @@ -297,7 +297,7 @@ void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute ) else if( mpBmpEx ) { rSubstitute = *mpBmpEx; - if (mpPdfData && mpPdfData->hasElements()) + if (mpPdfData && !mpPdfData->empty()) rSubstitute.setPdfData(mpPdfData); } else if( mpAnimation ) diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx index df190f4861ee..f84d5e37f0ab 100644 --- a/svx/source/svdraw/svdograf.cxx +++ b/svx/source/svdraw/svdograf.cxx @@ -1126,7 +1126,7 @@ bool SdrGrafObj::isEmbeddedPdfData() const return pGraphic->GetGraphic().hasPdfData(); } -std::shared_ptr<uno::Sequence<sal_Int8>> SdrGrafObj::getEmbeddedPdfData() const +std::shared_ptr<std::vector<sal_Int8>> SdrGrafObj::getEmbeddedPdfData() const { return pGraphic->GetGraphic().getPdfData(); } diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index f9417709f541..64fbdb83dbf9 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -114,7 +114,7 @@ struct FPDFBitmapDeleter using namespace com::sun::star; ImpSdrPdfImport::ImpSdrPdfImport(SdrModel& rModel, SdrLayerID nLay, const tools::Rectangle& rRect, - const std::shared_ptr<uno::Sequence<sal_Int8>>& pPdfData) + const std::shared_ptr<std::vector<sal_Int8>>& pPdfData) : maTmpList() , mpVD(VclPtr<VirtualDevice>::Create()) , maScaleRect(rRect) @@ -168,7 +168,7 @@ ImpSdrPdfImport::ImpSdrPdfImport(SdrModel& rModel, SdrLayerID nLay, const tools: FPDF_InitLibraryWithConfig(&aConfig); // Load the buffer using pdfium. - mpPdfDocument = FPDF_LoadMemDocument(mpPdfData->getConstArray(), mpPdfData->getLength(), + mpPdfDocument = FPDF_LoadMemDocument(mpPdfData->data(), mpPdfData->size(), /*password=*/nullptr); if (!mpPdfDocument) { diff --git a/svx/source/svdraw/svdpdf.hxx b/svx/source/svdraw/svdpdf.hxx index d3ea4aece8c4..df8eac35bbe7 100644 --- a/svx/source/svdraw/svdpdf.hxx +++ b/svx/source/svdraw/svdpdf.hxx @@ -155,7 +155,7 @@ class ImpSdrPdfImport final ::std::vector<SdrObject*> maTmpList; ScopedVclPtr<VirtualDevice> mpVD; tools::Rectangle maScaleRect; - const std::shared_ptr<css::uno::Sequence<sal_Int8>> mpPdfData; + const std::shared_ptr<std::vector<sal_Int8>> mpPdfData; size_t mnMapScalingOfs; // from here on, not edited with MapScaling std::unique_ptr<SfxItemSet> mpLineAttr; std::unique_ptr<SfxItemSet> mpFillAttr; @@ -232,7 +232,7 @@ class ImpSdrPdfImport final public: ImpSdrPdfImport(SdrModel& rModel, SdrLayerID nLay, const tools::Rectangle& rRect, - const std::shared_ptr<css::uno::Sequence<sal_Int8>>& pPdfData); + const std::shared_ptr<std::vector<sal_Int8>>& pPdfData); ~ImpSdrPdfImport(); int GetPageCount() const { return mnPageCount; } diff --git a/svx/source/xml/xmlgrhlp.cxx b/svx/source/xml/xmlgrhlp.cxx index 38be563ba9c6..cdbda1db341c 100644 --- a/svx/source/xml/xmlgrhlp.cxx +++ b/svx/source/xml/xmlgrhlp.cxx @@ -558,8 +558,8 @@ bool SvXMLGraphicHelper::ImplWriteGraphic( const OUString& rPictureStorageName, // vcl::ImportPDF() possibly downgraded the PDF data from a // higher PDF version, while aGfxLink still contains the // original data provided by the user. - std::shared_ptr<uno::Sequence<sal_Int8>> pPdfData = aGraphic.getPdfData(); - pStream->WriteBytes(pPdfData->getConstArray(), pPdfData->getLength()); + std::shared_ptr<std::vector<sal_Int8>> pPdfData = aGraphic.getPdfData(); + pStream->WriteBytes(pPdfData->data(), pPdfData->size()); // put into cache maExportPdf[aGraphic.getPdfData().get()] = std::make_pair(rPictureStreamName, aMimeType); diff --git a/svx/source/xoutdev/_xoutbmp.cxx b/svx/source/xoutdev/_xoutbmp.cxx index 3b7b5045b42b..63687c3a8313 100644 --- a/svx/source/xoutdev/_xoutbmp.cxx +++ b/svx/source/xoutdev/_xoutbmp.cxx @@ -192,8 +192,8 @@ ErrCode XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName, SfxMedium aMedium(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE|StreamMode::SHARE_DENYNONE|StreamMode::TRUNC); if (SvStream* pOutStream = aMedium.GetOutStream()) { - const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData = rGraphic.getPdfData(); - pOutStream->WriteBytes(rPdfData->getConstArray(), rPdfData->getLength()); + const std::shared_ptr<std::vector<sal_Int8>>& rPdfData = rGraphic.getPdfData(); + pOutStream->WriteBytes(rPdfData->data(), rPdfData->size()); aMedium.Commit(); if (!aMedium.GetError()) nErr = ERRCODE_NONE; diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index 3d998ec94ac5..a80e780d00f6 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -55,7 +55,7 @@ private: /// The PDF stream from which this Graphic is rendered, /// as converted (version downgraded) from the original, /// which should be in GfxLink. - std::shared_ptr<css::uno::Sequence<sal_Int8>> mpPdfData; + std::shared_ptr<std::vector<sal_Int8>> mpPdfData; OUString msOriginURL; GraphicExternalLink maGraphicExternalLink; @@ -93,7 +93,7 @@ private: bool hasPdfData() const { - return mpPdfData && mpPdfData->hasElements(); + return mpPdfData && !mpPdfData->empty(); } void ImplCreateSwapInfo(); @@ -174,9 +174,9 @@ private: const VectorGraphicDataPtr& getVectorGraphicData() const { return maVectorGraphicData; } - const std::shared_ptr<css::uno::Sequence<sal_Int8>>& getPdfData() const; + const std::shared_ptr<std::vector<sal_Int8>>& getPdfData() const; - void setPdfData(const std::shared_ptr<css::uno::Sequence<sal_Int8>>& rPdfData); + void setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData); }; #endif // INCLUDED_VCL_INC_IMPGRAPH_HXX diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index 8240c4af3217..87bfdc60b629 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -226,7 +226,7 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex, - css::uno::Sequence<sal_Int8>& rPdfData, + std::vector<sal_Int8>& rPdfData, sal_uInt64 nPos, sal_uInt64 nSize, const double fResolutionDPI) { @@ -244,9 +244,9 @@ bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, return false; aMemoryStream.Seek(STREAM_SEEK_TO_END); - rPdfData = css::uno::Sequence<sal_Int8>(aMemoryStream.Tell()); + rPdfData = std::vector<sal_Int8>(aMemoryStream.Tell()); aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); - aMemoryStream.ReadBytes(rPdfData.getArray(), rPdfData.getLength()); + aMemoryStream.ReadBytes(rPdfData.data(), rPdfData.size()); return true; } @@ -255,19 +255,19 @@ bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, bool ImportPDF(SvStream& rStream, Graphic& rGraphic, const double fResolutionDPI) { - uno::Sequence<sal_Int8> aPdfData; + std::vector<sal_Int8> aPdfData; Bitmap aBitmap; const bool bRet = ImportPDF(rStream, aBitmap, 0, aPdfData, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END, fResolutionDPI); rGraphic = aBitmap; - rGraphic.setPdfData(std::make_shared<css::uno::Sequence<sal_Int8>>(aPdfData)); + rGraphic.setPdfData(std::make_shared<std::vector<sal_Int8>>(aPdfData)); rGraphic.setPageNumber(0); // We currently import only the first page. return bRet; } size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps, - css::uno::Sequence<sal_Int8>& rPdfData, + std::vector<sal_Int8>& rPdfData, const double fResolutionDPI) { std::unique_ptr<SvStream> xStream( @@ -282,9 +282,9 @@ size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps, return 0; aMemoryStream.Seek(STREAM_SEEK_TO_END); - rPdfData = css::uno::Sequence<sal_Int8>(aMemoryStream.Tell()); + rPdfData = std::vector<sal_Int8>(aMemoryStream.Tell()); aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); - aMemoryStream.ReadBytes(rPdfData.getArray(), rPdfData.getLength()); + aMemoryStream.ReadBytes(rPdfData.data(), rPdfData.size()); return rBitmaps.size(); } @@ -302,14 +302,14 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si // Copy into PdfData aMemoryStream.Seek(STREAM_SEEK_TO_END); - auto pPdfData = std::make_shared<css::uno::Sequence<sal_Int8>>(aMemoryStream.Tell()); + auto pPdfData = std::make_shared<std::vector<sal_Int8>>(aMemoryStream.Tell()); aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); - aMemoryStream.ReadBytes(pPdfData->getArray(), pPdfData->getLength()); + aMemoryStream.ReadBytes(pPdfData->data(), pPdfData->size()); // Prepare the link with the PDF stream. - const size_t nGraphicContentSize = pPdfData->getLength(); + const size_t nGraphicContentSize = pPdfData->size(); std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]); - memcpy(pGraphicContent.get(), pPdfData->get(), nGraphicContentSize); + memcpy(pGraphicContent.get(), pPdfData->data(), nGraphicContentSize); std::shared_ptr<GfxLink> pGfxLink(std::make_shared<GfxLink>( std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf)); @@ -322,7 +322,7 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si // Load the buffer using pdfium. FPDF_DOCUMENT pPdfDocument - = FPDF_LoadMemDocument(pPdfData->getArray(), pPdfData->getLength(), /*password=*/nullptr); + = FPDF_LoadMemDocument(pPdfData->data(), pPdfData->size(), /*password=*/nullptr); if (!pPdfDocument) return 0; diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index 04e567e44d5d..bf8da62b15cf 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -611,21 +611,21 @@ const VectorGraphicDataPtr& Graphic::getVectorGraphicData() const return mxImpGraphic->getVectorGraphicData(); } -void Graphic::setPdfData(const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData) +void Graphic::setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData) { ImplTestRefCount(); mxImpGraphic->setPdfData(rPdfData); } -const std::shared_ptr<uno::Sequence<sal_Int8>>& Graphic::getPdfData() const +const std::shared_ptr<std::vector<sal_Int8>>& Graphic::getPdfData() const { return mxImpGraphic->getPdfData(); } bool Graphic::hasPdfData() const { - std::shared_ptr<uno::Sequence<sal_Int8>> pPdfData = getPdfData(); - return pPdfData && pPdfData->hasElements(); + std::shared_ptr<std::vector<sal_Int8>> pPdfData = getPdfData(); + return pPdfData && !pPdfData->empty(); } void Graphic::setPageNumber(sal_Int32 nPageNumber) diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 56d1c92da6a1..48f10e30a917 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -328,7 +328,7 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData); } } - else if (mpPdfData && mpPdfData->hasElements()) + else if (mpPdfData && !mpPdfData->empty()) { bRet = (rImpGraphic.mpPdfData && *mpPdfData == *rImpGraphic.mpPdfData); } @@ -352,12 +352,12 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const return bRet; } -void ImpGraphic::setPdfData(const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData) +void ImpGraphic::setPdfData(const std::shared_ptr<std::vector<sal_Int8>>& rPdfData) { mpPdfData = rPdfData; } -const std::shared_ptr<uno::Sequence<sal_Int8>>& ImpGraphic::getPdfData() const +const std::shared_ptr<std::vector<sal_Int8>>& ImpGraphic::getPdfData() const { return mpPdfData; } @@ -1446,10 +1446,10 @@ BitmapChecksum ImpGraphic::ImplGetChecksum() const nRet = maEx.GetChecksum(); } - if (mpPdfData && mpPdfData->hasElements()) + if (mpPdfData && !mpPdfData->empty()) // Include the PDF data in the checksum, so a metafile with // and without PDF data is considered to be different. - nRet = vcl_get_checksum(nRet, mpPdfData->getConstArray(), mpPdfData->getLength()); + nRet = vcl_get_checksum(nRet, mpPdfData->data(), mpPdfData->size()); } break; @@ -1485,7 +1485,7 @@ bool ImpGraphic::ImplExportNative( SvStream& rOStm ) const return bResult; } -static std::map<BitmapChecksum, std::shared_ptr<css::uno::Sequence<sal_Int8>>> sPdfDataCache; +static std::map<BitmapChecksum, std::shared_ptr<std::vector<sal_Int8>>> sPdfDataCache; void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) { @@ -1650,7 +1650,7 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) rImpGraphic.maEx = aBitmap; std::vector<Bitmap> aBitmaps; - if (vcl::RenderPDFBitmaps(rImpGraphic.mpPdfData->getConstArray(), rImpGraphic.mpPdfData->getLength(), aBitmaps, rImpGraphic.mnPageNumber, 1) == 1) + if (vcl::RenderPDFBitmaps(rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size(), aBitmaps, rImpGraphic.mnPageNumber, 1) == 1) rImpGraphic.maEx = aBitmaps[0]; rImpGraphic.meType = GraphicType::Bitmap; @@ -1745,7 +1745,7 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic) } else if (rImpGraphic.hasPdfData()) { - BitmapChecksum nPdfId = vcl_get_checksum(0, rImpGraphic.mpPdfData->getConstArray(), rImpGraphic.mpPdfData->getLength()); + BitmapChecksum nPdfId = vcl_get_checksum(0, rImpGraphic.mpPdfData->data(), rImpGraphic.mpPdfData->size()); if (sPdfDataCache.find(nPdfId) == sPdfDataCache.end()) sPdfDataCache.emplace(nPdfId, rImpGraphic.mpPdfData); diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index cc4dfab1aa46..0b5b74e21d3c 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -4948,12 +4948,12 @@ bool PDFWriterImpl::emitEmbeddedFiles() aLine.append(rEmbeddedFile.m_nObject); aLine.append(" 0 obj\n"); aLine.append("<< /Type /EmbeddedFile /Length "); - aLine.append(static_cast<sal_Int64>(rEmbeddedFile.m_aData.getLength())); + aLine.append(static_cast<sal_Int64>(rEmbeddedFile.m_aData.size())); aLine.append(" >>\nstream\n"); CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength())); aLine.setLength(0); - CHECK_RETURN(writeBuffer(rEmbeddedFile.m_aData.getArray(), rEmbeddedFile.m_aData.getLength())); + CHECK_RETURN(writeBuffer(rEmbeddedFile.m_aData.data(), rEmbeddedFile.m_aData.size())); aLine.append("\nendstream\nendobj\n\n"); CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength())); @@ -8838,7 +8838,7 @@ bool PDFWriterImpl::writeGradientFunction( GradientEmit const & rObject ) void PDFWriterImpl::writeJPG( JPGEmit& rObject ) { - if (rObject.m_aReferenceXObject.m_aPDFData.hasElements() && !m_aContext.UseReferenceXObject) + if (!rObject.m_aReferenceXObject.m_aPDFData.empty() && !m_aContext.UseReferenceXObject) { writeReferenceXObject(rObject.m_aReferenceXObject); return; @@ -9146,7 +9146,7 @@ void PDFWriterImpl::writeReferenceXObject(ReferenceXObjectEmit& rEmit) // Parse the PDF data, we need that to write the PDF dictionary of our // object. SvMemoryStream aPDFStream; - aPDFStream.WriteBytes(rEmit.m_aPDFData.getArray(), rEmit.m_aPDFData.getLength()); + aPDFStream.WriteBytes(rEmit.m_aPDFData.data(), rEmit.m_aPDFData.size()); aPDFStream.Seek(0); filter::PDFDocument aPDFDocument; if (!aPDFDocument.Read(aPDFStream)) @@ -9382,7 +9382,7 @@ namespace bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask ) { - if (rObject.m_aReferenceXObject.m_aPDFData.hasElements() && !m_aContext.UseReferenceXObject) + if (!rObject.m_aReferenceXObject.m_aPDFData.empty() && !m_aContext.UseReferenceXObject) { writeReferenceXObject(rObject.m_aReferenceXObject); return true; diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index cf8fe720050c..e28896000963 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -224,7 +224,7 @@ public: /// Size of the bitmap replacement, in pixels. Size m_aPixelSize; /// PDF data from the graphic object, if not writing a reference XObject. - css::uno::Sequence<sal_Int8> m_aPDFData; + std::vector<sal_Int8> m_aPDFData; ReferenceXObjectEmit() : m_nFormObject(0), @@ -452,7 +452,7 @@ public: /// ID of the file. sal_Int32 m_nObject; /// Contents of the file. - css::uno::Sequence<sal_Int8> m_aData; + std::vector<sal_Int8> m_aData; PDFEmbeddedFile() : m_nObject(0) commit 8aca771675f7f76c84bbbd117b9dc1cc9c5ada8b Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Fri Jun 22 12:58:12 2018 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:54:01 2019 +0200 pdfium: Delay the swap out. If we swap out too early, the constructor of GraphicObject forces a swap in, so we'd render everything during the load anyway. Change-Id: I0ea1a755242fd57ef28d082ce4bf534a32199f87 Reviewed-on: https://gerrit.libreoffice.org/56286 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index d78ccaa328b0..6f8b4ca2c0b3 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -115,15 +115,15 @@ bool SdPdfFilter::Import() for (std::pair<Graphic, Size>& aPair : aGraphics) { - const Graphic& aGraphic = aPair.first; + const Graphic& rGraphic = aPair.first; const Size& aSize = aPair.second; - const sal_Int32 nPageNumber = aGraphic.getPageNumber(); + const sal_Int32 nPageNumber = rGraphic.getPageNumber(); assert(nPageNumber >= 0 && nPageNumber < static_cast<sal_Int32>(aGraphics.size())); // Create the page and insert the Graphic. SdPage* pPage = mrDocument.GetSdPage(nPageNumber, PageKind::Standard); - Size aGrfSize(OutputDevice::LogicToLogic(aSize, aGraphic.GetPrefMapMode(), + Size aGrfSize(OutputDevice::LogicToLogic(aSize, rGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM))); // Resize to original size based on 72 dpi to preserve page size. @@ -134,7 +134,13 @@ bool SdPdfFilter::Import() pPage->SetSize(aGrfSize); Point aPos(0, 0); - pPage->InsertObject(new SdrGrafObj(aGraphic, tools::Rectangle(aPos, aGrfSize))); + SdrGrafObj* pSdrGrafObj = new SdrGrafObj(rGraphic, tools::Rectangle(aPos, aGrfSize)); + pPage->InsertObject(pSdrGrafObj); + + // we know that the initial bitmap we provided was just a placeholder, + // we need to swap it out, so that on the next swap in, we render the + // correct one + const_cast<GraphicObject&>(pSdrGrafObj->GetGraphicObject()).SwapOut(); } return true; diff --git a/svtools/source/graphic/grfcache.cxx b/svtools/source/graphic/grfcache.cxx index 443cfa91aa90..0bb04b0c5d56 100644 --- a/svtools/source/graphic/grfcache.cxx +++ b/svtools/source/graphic/grfcache.cxx @@ -80,6 +80,16 @@ GraphicID::GraphicID( const GraphicObject& rObj ) mnID3 = basegfx::fround(rRange.getHeight()); mnID4 = vcl_get_checksum(0, rVectorGraphicDataPtr->getVectorGraphicDataArray().getConstArray(), rVectorGraphicDataPtr->getVectorGraphicDataArrayLength()); } + else if (rGraphic.hasPdfData()) + { + std::shared_ptr<css::uno::Sequence<sal_Int8>> pPdfData = rGraphic.getPdfData(); + const BitmapEx& rBmpEx = rGraphic.GetBitmapEx(); + + mnID1 |= (rGraphic.getPageNumber() & 0x0fffffff); + mnID2 = rBmpEx.GetSizePixel().Width(); + mnID3 = rBmpEx.GetSizePixel().Height(); + mnID4 = vcl_get_checksum(0, pPdfData->getConstArray(), pPdfData->getLength()); + } else if( rGraphic.IsAnimated() ) { const Animation aAnimation( rGraphic.GetAnimation() ); diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index 3a058bb36b57..8240c4af3217 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -330,6 +330,9 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si if (nPageCount <= 0) return 0; + // dummy Bitmap + Bitmap aBitmap(Size(1, 1), 24); + for (size_t nPageIndex = 0; nPageIndex < static_cast<size_t>(nPageCount); ++nPageIndex) { double fPageWidth = 0; @@ -341,9 +344,11 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si const size_t nPageWidth = pointToPixel(fPageWidth, fResolutionDPI); const size_t nPageHeight = pointToPixel(fPageHeight, fResolutionDPI); - // Create the Graphic and link the original PDF stream. - Graphic aGraphic; - aGraphic.setPdfData(pPdfData); // TODO: Skip if unchanged. + // Create the Graphic with a dummy Bitmap 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(aBitmap); + aGraphic.setPdfData(pPdfData); aGraphic.setPageNumber(nPageIndex); aGraphic.SetSharedLink(pGfxLink); commit 335113741b2f4672a7813d8e6410dc5ec1b45527 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Fri Jun 22 10:28:42 2018 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:54:01 2019 +0200 pdfium: Avoid unnecessary copying + some warning fixes. Change-Id: I114fa6b2d3dda86c55eb245d31ca3a1019197ae9 Reviewed-on: https://gerrit.libreoffice.org/56285 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index 3ef639853184..d78ccaa328b0 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -108,7 +108,7 @@ bool SdPdfFilter::Import() // Add as many pages as we need up-front. mrDocument.CreateFirstPages(); - for (int i = 0; i < aGraphics.size() - 1; ++i) + for (size_t i = 0; i < aGraphics.size() - 1; ++i) { mrDocument.DuplicatePage(0); } @@ -119,8 +119,7 @@ bool SdPdfFilter::Import() const Size& aSize = aPair.second; const sal_Int32 nPageNumber = aGraphic.getPageNumber(); - if (nPageNumber < 0 || nPageNumber >= aGraphics.size()) - continue; // Page is out of range + assert(nPageNumber >= 0 && nPageNumber < static_cast<sal_Int32>(aGraphics.size())); // Create the page and insert the Graphic. SdPage* pPage = mrDocument.GetSdPage(nPageNumber, PageKind::Standard); diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index 324218ead522..3a058bb36b57 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -301,19 +301,17 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si return 0; // Copy into PdfData - uno::Sequence<sal_Int8> aPdfData; aMemoryStream.Seek(STREAM_SEEK_TO_END); - aPdfData = css::uno::Sequence<sal_Int8>(aMemoryStream.Tell()); + auto pPdfData = std::make_shared<css::uno::Sequence<sal_Int8>>(aMemoryStream.Tell()); aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); - aMemoryStream.ReadBytes(aPdfData.getArray(), aPdfData.getLength()); + aMemoryStream.ReadBytes(pPdfData->getArray(), pPdfData->getLength()); // Prepare the link with the PDF stream. - const size_t nGraphicContentSize = aPdfData.getLength(); + const size_t nGraphicContentSize = pPdfData->getLength(); std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]); - memcpy(pGraphicContent.get(), aPdfData.get(), nGraphicContentSize); + memcpy(pGraphicContent.get(), pPdfData->get(), nGraphicContentSize); std::shared_ptr<GfxLink> pGfxLink(std::make_shared<GfxLink>( std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf)); - auto pPdfData = std::make_shared<uno::Sequence<sal_Int8>>(aPdfData); FPDF_LIBRARY_CONFIG aConfig; aConfig.version = 2; @@ -324,7 +322,7 @@ size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Si // Load the buffer using pdfium. FPDF_DOCUMENT pPdfDocument - = FPDF_LoadMemDocument(aPdfData.getArray(), aPdfData.getLength(), /*password=*/nullptr); + = FPDF_LoadMemDocument(pPdfData->getArray(), pPdfData->getLength(), /*password=*/nullptr); if (!pPdfDocument) return 0; commit 5a1f367b5573293cf3b2e8dbdffc7de22e99c058 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Jun 9 13:09:35 2018 -0400 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:54:00 2019 +0200 pdfium: Import PDF with unloaded images. Change-Id: I5e4a16ff38b9643127ce16879b35f456c13bcff8 Reviewed-on: https://gerrit.libreoffice.org/56268 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/include/vcl/pdfread.hxx b/include/vcl/pdfread.hxx index c491f50ef34b..e579f435261e 100644 --- a/include/vcl/pdfread.hxx +++ b/include/vcl/pdfread.hxx @@ -13,6 +13,23 @@ #include <vector> #include <tools/stream.hxx> #include <vcl/graph.hxx> +#include <tools/gen.hxx> + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace uno +{ +template <typename> class Sequence; +} +} +} +} +class Bitmap; +class Graphic; namespace vcl { @@ -34,6 +51,14 @@ VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic, VCL_DLLPUBLIC size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps, css::uno::Sequence<sal_Int8>& rPdfData, const double fResolutionDPI = 96.); + +/// Import PDF as Graphic images (1 per page), all unloaded. +/// Since Graphic is unloaded, we need to return the page size (in pixels) separately. +/// Does not set rPdfData if no conversion is done. +/// Returns the number of pages read. +VCL_DLLPUBLIC size_t ImportPDFUnloaded(const OUString& rURL, + std::vector<std::pair<Graphic, Size>>& rGraphics, + const double fResolutionDPI = 96.); } #endif // INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index 95daaeb479f1..3ef639853184 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -102,38 +102,29 @@ bool SdPdfFilter::Import() // Rendering resolution. const double dResolutionDPI = 96.; - uno::Sequence<sal_Int8> aPdfData; - std::vector<Bitmap> aBitmaps; - if (vcl::ImportPDF(aFileName, aBitmaps, aPdfData, dResolutionDPI) == 0) + std::vector<std::pair<Graphic, Size>> aGraphics; + if (vcl::ImportPDFUnloaded(aFileName, aGraphics, dResolutionDPI) == 0) return false; - // Prepare the link with the PDF stream. - const size_t nGraphicContentSize = aPdfData.getLength(); - std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]); - memcpy(pGraphicContent.get(), aPdfData.get(), nGraphicContentSize); - std::shared_ptr<GfxLink> pGfxLink(std::make_shared<GfxLink>( - std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf)); - auto pPdfData = std::make_shared<uno::Sequence<sal_Int8>>(aPdfData); - + // Add as many pages as we need up-front. mrDocument.CreateFirstPages(); - for (size_t i = 0; i < aBitmaps.size() - 1; ++i) + for (int i = 0; i < aGraphics.size() - 1; ++i) { mrDocument.DuplicatePage(0); } - size_t nPageNumber = 0; - for (Bitmap& aBitmap : aBitmaps) + for (std::pair<Graphic, Size>& aPair : aGraphics) { - // Create the Graphic and link the original PDF stream. - Graphic aGraphic(aBitmap); - aGraphic.setPdfData(pPdfData); - aGraphic.setPageNumber(nPageNumber); - aGraphic.SetSharedLink(pGfxLink); - aGraphic.setOriginURL(aFileName); + const Graphic& aGraphic = aPair.first; + const Size& aSize = aPair.second; + + const sal_Int32 nPageNumber = aGraphic.getPageNumber(); + if (nPageNumber < 0 || nPageNumber >= aGraphics.size()) + continue; // Page is out of range // Create the page and insert the Graphic. - SdPage* pPage = mrDocument.GetSdPage(nPageNumber++, PageKind::Standard); - Size aGrfSize(OutputDevice::LogicToLogic(aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), + SdPage* pPage = mrDocument.GetSdPage(nPageNumber, PageKind::Standard); + Size aGrfSize(OutputDevice::LogicToLogic(aSize, aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM))); // Resize to original size based on 72 dpi to preserve page size. diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index f73dc5736fbf..324218ead522 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -17,8 +17,10 @@ #include <fpdf_save.h> #endif -#include <vcl/bitmapaccess.hxx> +#include <impgraph.hxx> + #include <vcl/graph.hxx> +#include <vcl/bitmapaccess.hxx> #include <unotools/ucbstreamhelper.hxx> using namespace com::sun::star; @@ -286,6 +288,75 @@ size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps, return rBitmaps.size(); } + +size_t ImportPDFUnloaded(const OUString& rURL, std::vector<std::pair<Graphic, Size>>& rGraphics, + const double fResolutionDPI) +{ + std::unique_ptr<SvStream> xStream( + ::utl::UcbStreamHelper::CreateStream(rURL, StreamMode::READ | StreamMode::SHARE_DENYNONE)); + + // Save the original PDF stream for later use. + SvMemoryStream aMemoryStream; + if (!getCompatibleStream(*xStream, aMemoryStream, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END)) + return 0; + + // Copy into PdfData + uno::Sequence<sal_Int8> aPdfData; + aMemoryStream.Seek(STREAM_SEEK_TO_END); + aPdfData = css::uno::Sequence<sal_Int8>(aMemoryStream.Tell()); + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + aMemoryStream.ReadBytes(aPdfData.getArray(), aPdfData.getLength()); + + // Prepare the link with the PDF stream. + const size_t nGraphicContentSize = aPdfData.getLength(); + std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]); + memcpy(pGraphicContent.get(), aPdfData.get(), nGraphicContentSize); + std::shared_ptr<GfxLink> pGfxLink(std::make_shared<GfxLink>( + std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf)); + auto pPdfData = std::make_shared<uno::Sequence<sal_Int8>>(aPdfData); + + FPDF_LIBRARY_CONFIG aConfig; + aConfig.version = 2; + aConfig.m_pUserFontPaths = nullptr; + aConfig.m_pIsolate = nullptr; + aConfig.m_v8EmbedderSlot = 0; + FPDF_InitLibraryWithConfig(&aConfig); + + // Load the buffer using pdfium. + FPDF_DOCUMENT pPdfDocument + = FPDF_LoadMemDocument(aPdfData.getArray(), aPdfData.getLength(), /*password=*/nullptr); + if (!pPdfDocument) + return 0; + + const int nPageCount = FPDF_GetPageCount(pPdfDocument); + if (nPageCount <= 0) + return 0; + + for (size_t nPageIndex = 0; nPageIndex < static_cast<size_t>(nPageCount); ++nPageIndex) + { + double fPageWidth = 0; + double fPageHeight = 0; + if (FPDF_GetPageSizeByIndex(pPdfDocument, nPageIndex, &fPageWidth, &fPageHeight) == 0) + continue; + + // Returned unit is points, convert that to pixel. + const size_t nPageWidth = pointToPixel(fPageWidth, fResolutionDPI); + const size_t nPageHeight = pointToPixel(fPageHeight, fResolutionDPI); + + // Create the Graphic and link the original PDF stream. + Graphic aGraphic; + aGraphic.setPdfData(pPdfData); // TODO: Skip if unchanged. + aGraphic.setPageNumber(nPageIndex); + aGraphic.SetSharedLink(pGfxLink); + + rGraphics.emplace_back(std::move(aGraphic), Size(nPageWidth, nPageHeight)); + } + + FPDF_CloseDocument(pPdfDocument); + FPDF_DestroyLibrary(); + + return rGraphics.size(); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 30160c3fa79c..56d1c92da6a1 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -1398,7 +1398,14 @@ void ImpGraphic::ImplSetSharedLink(const std::shared_ptr<GfxLink>& pGfxLink) mpGfxLink = pGfxLink; if (mpGfxLink && mpGfxLink->IsNative()) + { mpGfxLink->SwapOut(); + + // Swap out the graphic as well. + //FIXME: move to own function, such as SetPrepared(). + meType = GraphicType::Bitmap; + ImplSwapOut(); + } } GfxLink ImpGraphic::ImplGetLink() commit 81ac2da0d0325fc74fafd09bc4f3c85a75fab352 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Wed Mar 27 10:12:16 2019 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:54:00 2019 +0200 Fix linking error in the !HAVE_FEATURE_PDFIUM case Change-Id: I74e290ce1af4b85f6495acef4ecc9a276b6df40a diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 87c2c233a732..30160c3fa79c 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <config_features.h> + #include <sal/config.h> #include <comphelper/processfactory.hxx> @@ -1622,6 +1624,7 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) } } } +#if HAVE_FEATURE_PDFIUM else if (nMagic == nPdfMagic) { // Stream in PDF data. @@ -1645,6 +1648,7 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) rImpGraphic.meType = GraphicType::Bitmap; } +#endif else { rIStm.SetError(nOrigError); commit 215b8c1ca4cb6587c8e48b71d474cee3b8d3fe9e Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Tue Mar 26 17:22:38 2019 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:53:59 2019 +0200 Fix build in !HAVE_FEATURE_PDFIUM case Change-Id: I99baba8734b9e03d3986e448bf278587101d24ef diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index 16cb902e2476..f73dc5736fbf 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -155,6 +155,8 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, namespace vcl { +#if HAVE_FEATURE_PDFIUM + size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBitmaps, const size_t nFirstPage, int nPages, const double fResolutionDPI) @@ -218,6 +220,8 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi return rBitmaps.size(); } +#endif // HAVE_FEATURE_PDFIUM + bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex, css::uno::Sequence<sal_Int8>& rPdfData, commit 36075c6d48508d39b98546d1880faae93d80e403 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Fri Jun 22 00:44:44 2018 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:53:59 2019 +0200 pdfium: Keep the PDF data in memory, so that we can really share them. Otherwise the swap out / swap in creates new copy of the underlying PDF stream. Change-Id: I88a16a69143783a998201e183bea1a9553e337bd Reviewed-on: https://gerrit.libreoffice.org/56266 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/69626 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> diff --git a/include/vcl/pdfread.hxx b/include/vcl/pdfread.hxx index 1a1ff0d680cb..c491f50ef34b 100644 --- a/include/vcl/pdfread.hxx +++ b/include/vcl/pdfread.hxx @@ -16,6 +16,11 @@ namespace vcl { +/// Fills the rBitmaps vector with rendered pages. +VCL_DLLPUBLIC size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBitmaps, + const size_t nFirstPage = 0, int nPages = 1, + const double fResolutionDPI = 96.); + /// Imports a PDF stream into rGraphic as a GDIMetaFile. VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex, css::uno::Sequence<sal_Int8>& rPdfData, diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index ab70a0451d9d..16cb902e2476 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -63,68 +63,12 @@ size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps, const size_t nFirstPage = 0, int nPages = 1, const double fResolutionDPI = 96.) { - FPDF_LIBRARY_CONFIG aConfig; - aConfig.version = 2; - aConfig.m_pUserFontPaths = nullptr; - aConfig.m_pIsolate = nullptr; - aConfig.m_v8EmbedderSlot = 0; - FPDF_InitLibraryWithConfig(&aConfig); - // Read input into a buffer. SvMemoryStream aInBuffer; rStream.Seek(nPos); aInBuffer.WriteStream(rStream, nSize); - // Load the buffer using pdfium. - FPDF_DOCUMENT pPdfDocument = FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr); - if (!pPdfDocument) - return 0; - - const int nPageCount = FPDF_GetPageCount(pPdfDocument); - if (nPages <= 0) - nPages = nPageCount; - const size_t nLastPage = std::min<int>(nPageCount, nFirstPage + nPages) - 1; - for (size_t nPageIndex = nFirstPage; nPageIndex <= nLastPage; ++nPageIndex) - { - // Render next page. - FPDF_PAGE pPdfPage = FPDF_LoadPage(pPdfDocument, nPageIndex); - if (!pPdfPage) - break; - - // Returned unit is points, convert that to pixel. - const size_t nPageWidth = pointToPixel(FPDF_GetPageWidth(pPdfPage), fResolutionDPI); - const size_t nPageHeight = pointToPixel(FPDF_GetPageHeight(pPdfPage), fResolutionDPI); - FPDF_BITMAP pPdfBitmap = FPDFBitmap_Create(nPageWidth, nPageHeight, /*alpha=*/1); - if (!pPdfBitmap) - break; - - const FPDF_DWORD nColor = FPDFPage_HasTransparency(pPdfPage) ? 0x00000000 : 0xFFFFFFFF; - FPDFBitmap_FillRect(pPdfBitmap, 0, 0, nPageWidth, nPageHeight, nColor); - FPDF_RenderPageBitmap(pPdfBitmap, pPdfPage, /*start_x=*/0, /*start_y=*/0, nPageWidth, nPageHeight, /*rotate=*/0, /*flags=*/0); - - // Save the buffer as a bitmap. - Bitmap aBitmap(Size(nPageWidth, nPageHeight), 24); - { - Bitmap::ScopedWriteAccess pWriteAccess(aBitmap); - const auto pPdfBuffer = static_cast<ConstScanline>(FPDFBitmap_GetBuffer(pPdfBitmap)); - const int nStride = FPDFBitmap_GetStride(pPdfBitmap); - for (size_t nRow = 0; nRow < nPageHeight; ++nRow) - { - ConstScanline pPdfLine = pPdfBuffer + (nStride * nRow); - // pdfium byte order is BGRA. - pWriteAccess->CopyScanline(nRow, pPdfLine, ScanlineFormat::N32BitTcBgra, nStride); - } - } - - rBitmaps.emplace_back(std::move(aBitmap)); - FPDFBitmap_Destroy(pPdfBitmap); - FPDF_ClosePage(pPdfPage); - } - - FPDF_CloseDocument(pPdfDocument); - FPDF_DestroyLibrary(); - - return rBitmaps.size(); + return vcl::RenderPDFBitmaps(aInBuffer.GetData(), aInBuffer.GetSize(), rBitmaps, nFirstPage, nPages, fResolutionDPI); } /// Decide if PDF data is old enough to be compatible. @@ -211,6 +155,69 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream, namespace vcl { +size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBitmaps, + const size_t nFirstPage, int nPages, + const double fResolutionDPI) +{ + FPDF_LIBRARY_CONFIG aConfig; + aConfig.version = 2; + aConfig.m_pUserFontPaths = nullptr; + aConfig.m_pIsolate = nullptr; + aConfig.m_v8EmbedderSlot = 0; + FPDF_InitLibraryWithConfig(&aConfig); + + // Load the buffer using pdfium. + FPDF_DOCUMENT pPdfDocument = FPDF_LoadMemDocument(pBuffer, nSize, /*password=*/nullptr); + if (!pPdfDocument) + return 0; + + const int nPageCount = FPDF_GetPageCount(pPdfDocument); + if (nPages <= 0) + nPages = nPageCount; + const size_t nLastPage = std::min<int>(nPageCount, nFirstPage + nPages) - 1; + for (size_t nPageIndex = nFirstPage; nPageIndex <= nLastPage; ++nPageIndex) + { + // Render next page. + FPDF_PAGE pPdfPage = FPDF_LoadPage(pPdfDocument, nPageIndex); + if (!pPdfPage) + break; + + // Returned unit is points, convert that to pixel. + const size_t nPageWidth = pointToPixel(FPDF_GetPageWidth(pPdfPage), fResolutionDPI); + const size_t nPageHeight = pointToPixel(FPDF_GetPageHeight(pPdfPage), fResolutionDPI); + FPDF_BITMAP pPdfBitmap = FPDFBitmap_Create(nPageWidth, nPageHeight, /*alpha=*/1); + if (!pPdfBitmap) + break; + + const FPDF_DWORD nColor = FPDFPage_HasTransparency(pPdfPage) ? 0x00000000 : 0xFFFFFFFF; + FPDFBitmap_FillRect(pPdfBitmap, 0, 0, nPageWidth, nPageHeight, nColor); + FPDF_RenderPageBitmap(pPdfBitmap, pPdfPage, /*start_x=*/0, /*start_y=*/0, nPageWidth, nPageHeight, /*rotate=*/0, /*flags=*/0); + + // Save the buffer as a bitmap. + Bitmap aBitmap(Size(nPageWidth, nPageHeight), 24); + { + Bitmap::ScopedWriteAccess pWriteAccess(aBitmap); + const auto pPdfBuffer = static_cast<ConstScanline>(FPDFBitmap_GetBuffer(pPdfBitmap)); + const int nStride = FPDFBitmap_GetStride(pPdfBitmap); + for (size_t nRow = 0; nRow < nPageHeight; ++nRow) + { + ConstScanline pPdfLine = pPdfBuffer + (nStride * nRow); + // pdfium byte order is BGRA. + pWriteAccess->CopyScanline(nRow, pPdfLine, ScanlineFormat::N32BitTcBgra, nStride); + } + } + + rBitmaps.emplace_back(std::move(aBitmap)); + FPDFBitmap_Destroy(pPdfBitmap); + FPDF_ClosePage(pPdfPage); + } + + FPDF_CloseDocument(pPdfDocument); + FPDF_DestroyLibrary(); + + return rBitmaps.size(); +} + bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex, css::uno::Sequence<sal_Int8>& rPdfData, diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 6e837c979e78..87c2c233a732 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -37,6 +37,7 @@ #include <impgraph.hxx> #include <com/sun/star/ucb/CommandAbortedException.hpp> #include <vcl/dibtools.hxx> +#include <map> #include <memory> #include <o3tl/make_unique.hxx> #include <vcl/gdimetafiletools.hxx> @@ -1475,6 +1476,7 @@ bool ImpGraphic::ImplExportNative( SvStream& rOStm ) const return bResult; } +static std::map<BitmapChecksum, std::shared_ptr<css::uno::Sequence<sal_Int8>>> sPdfDataCache; void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) { @@ -1623,23 +1625,25 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) else if (nMagic == nPdfMagic) { // Stream in PDF data. - sal_uInt32 nPdfDataLength = 0; - rIStm.ReadUInt32(nPdfDataLength); + BitmapChecksum nPdfId = 0; + rIStm.ReadUInt64(nPdfId); + + rImpGraphic.mnPageNumber = 0; + rIStm.ReadInt32(rImpGraphic.mnPageNumber); + + auto it = sPdfDataCache.find(nPdfId); + assert(it != sPdfDataCache.end()); + + rImpGraphic.mpPdfData = it->second; + Bitmap aBitmap; + rImpGraphic.maEx = aBitmap; - if (nPdfDataLength && !rIStm.GetError()) - { - if (!rImpGraphic.mpPdfData) - rImpGraphic.mpPdfData.reset(new uno::Sequence<sal_Int8>()); + std::vector<Bitmap> aBitmaps; + if (vcl::RenderPDFBitmaps(rImpGraphic.mpPdfData->getConstArray(), rImpGraphic.mpPdfData->getLength(), aBitmaps, rImpGraphic.mnPageNumber, 1) == 1) + rImpGraphic.maEx = aBitmaps[0]; - if (vcl::ImportPDF(rIStm, aBitmap, rImpGraphic.mnPageNumber, - *rImpGraphic.mpPdfData, - rIStm.Tell(), nPdfDataLength)) - { - rImpGraphic.maEx = aBitmap; - rImpGraphic.meType = GraphicType::Bitmap; - } - } + rImpGraphic.meType = GraphicType::Bitmap; } else { @@ -1730,10 +1734,14 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic) } else if (rImpGraphic.hasPdfData()) { + BitmapChecksum nPdfId = vcl_get_checksum(0, rImpGraphic.mpPdfData->getConstArray(), rImpGraphic.mpPdfData->getLength()); + if (sPdfDataCache.find(nPdfId) == sPdfDataCache.end()) + sPdfDataCache.emplace(nPdfId, rImpGraphic.mpPdfData); + // Stream out PDF data. rOStm.WriteUInt32(nPdfMagic); - rOStm.WriteUInt32(rImpGraphic.mpPdfData->getLength()); - rOStm.WriteBytes(rImpGraphic.mpPdfData->getConstArray(), rImpGraphic.mpPdfData->getLength()); + rOStm.WriteUInt64(nPdfId); + rOStm.WriteInt32(rImpGraphic.mnPageNumber); } else if( rImpGraphic.ImplIsAnimated()) { commit a8c9f2f691156bca8583974c28b4b30c49956598 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Thu Jun 21 21:33:56 2018 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:53:58 2019 +0200 pdfium: Share the GfxLink for PDF files. Partially based on work by Ashod Nakashian, thanks! Reviewed-on: https://gerrit.libreoffice.org/56265 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> Change-Id: Id7e8c4543368b0caf3e459abaff8c53997779c83 Reviewed-on: https://gerrit.libreoffice.org/69625 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> diff --git a/include/vcl/graph.hxx b/include/vcl/graph.hxx index 45268462155a..881abda221e4 100644 --- a/include/vcl/graph.hxx +++ b/include/vcl/graph.hxx @@ -216,6 +216,7 @@ private: public: void SetLink( const GfxLink& ); + void SetSharedLink(const std::shared_ptr<GfxLink>& pGfxLink); GfxLink GetLink() const; bool IsLink() const; diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index a4747456123b..95daaeb479f1 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -128,7 +128,7 @@ bool SdPdfFilter::Import() Graphic aGraphic(aBitmap); aGraphic.setPdfData(pPdfData); aGraphic.setPageNumber(nPageNumber); - aGraphic.SetLink(aGfxLink); + aGraphic.SetSharedLink(pGfxLink); aGraphic.setOriginURL(aFileName); // Create the page and insert the Graphic. diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index c462dc2c67ac..3d998ec94ac5 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -160,7 +160,8 @@ private: bool ImplIsSwapOut() const { return mbSwapOut;} bool ImplIsDummyContext() const { return mbDummyContext; } - void ImplSetLink( const std::shared_ptr<GfxLink>& ); + void ImplSetLink( const GfxLink& ); + void ImplSetSharedLink(const std::shared_ptr<GfxLink>& pGfxLink); GfxLink ImplGetLink(); bool ImplIsLink() const; diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index 1fc7897ac90b..04e567e44d5d 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -569,6 +569,12 @@ void Graphic::SetLink( const GfxLink& rGfxLink ) mxImpGraphic->ImplSetLink( rGfxLink ); } +void Graphic::SetSharedLink(const std::shared_ptr<GfxLink>& pGfxLink) +{ + ImplTestRefCount(); + mxImpGraphic->ImplSetSharedLink(pGfxLink); +} + GfxLink Graphic::GetLink() const { return mxImpGraphic->ImplGetLink(); diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 2d73357ec43d..6e837c979e78 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -125,6 +125,14 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink) , mnPageNumber(rImpGraphic.mnPageNumber) { + if( rImpGraphic.mpGfxLink ) + { + if (rImpGraphic.mpGfxLink->GetType() == GfxLinkType::NativePdf) + mpGfxLink = rImpGraphic.mpGfxLink; + else + mpGfxLink = std::make_shared<GfxLink>(*rImpGraphic.mpGfxLink); + } + if( rImpGraphic.mpAnimation ) { mpAnimation = o3tl::make_unique<Animation>( *rImpGraphic.mpAnimation ); @@ -237,9 +245,18 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic ) mbSwapOut = rImpGraphic.mbSwapOut; mpSwapFile = rImpGraphic.mpSwapFile; - mpGfxLink = rImpGraphic.mpGfxLink; + if (rImpGraphic.mpGfxLink) + { + if (rImpGraphic.mpGfxLink->GetType() == GfxLinkType::NativePdf) + mpGfxLink = rImpGraphic.mpGfxLink; + else + { + mpGfxLink.reset(); + + mpGfxLink = std::make_shared<GfxLink>(*rImpGraphic.mpGfxLink); + } + } - maVectorGraphicData = rImpGraphic.maVectorGraphicData; mpPdfData = rImpGraphic.mpPdfData; } @@ -1367,7 +1384,15 @@ bool ImpGraphic::ImplSwapIn( SvStream* xIStm ) void ImpGraphic::ImplSetLink(const GfxLink& rGfxLink) { - mpGfxLink = rGfxLink; + mpGfxLink = std::make_shared<GfxLink>( rGfxLink ); + + if( mpGfxLink->IsNative() ) + mpGfxLink->SwapOut(); +} + +void ImpGraphic::ImplSetSharedLink(const std::shared_ptr<GfxLink>& pGfxLink) +{ + mpGfxLink = pGfxLink; if (mpGfxLink && mpGfxLink->IsNative()) mpGfxLink->SwapOut(); commit 6a6201e0d6928437e059eb1b7e991d9597dbe24e Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Fri Jun 8 22:54:48 2018 -0400 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Apr 3 17:53:58 2019 +0200 vcl: share GfxLink When importing PDF as images, we store the PDF stream in the GfxLink. For large PDFs storing a copy of the full PDF with each page is overkill. For example a 10MB PDF with 200 pages will consume 2GB of memory! Change-Id: I99913514cf5c562683080bc817668095bee69427 Reviewed-on: https://gerrit.libreoffice.org/55571 Tested-by: Jenkins Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/69624 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx index 26d7c70bdd54..a4747456123b 100644 --- a/sd/source/filter/pdf/sdpdffilter.cxx +++ b/sd/source/filter/pdf/sdpdffilter.cxx @@ -111,7 +111,8 @@ bool SdPdfFilter::Import() const size_t nGraphicContentSize = aPdfData.getLength(); std::unique_ptr<sal_uInt8[]> pGraphicContent(new sal_uInt8[nGraphicContentSize]); memcpy(pGraphicContent.get(), aPdfData.get(), nGraphicContentSize); - GfxLink aGfxLink(std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf); + std::shared_ptr<GfxLink> pGfxLink(std::make_shared<GfxLink>( + std::move(pGraphicContent), nGraphicContentSize, GfxLinkType::NativePdf)); auto pPdfData = std::make_shared<uno::Sequence<sal_Int8>>(aPdfData); mrDocument.CreateFirstPages(); diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index 1a8563e95db0..c462dc2c67ac 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -45,7 +45,7 @@ private: std::unique_ptr<Animation> mpAnimation; std::shared_ptr<GraphicReader> mpContext; std::shared_ptr<ImpSwapFile> mpSwapFile; - std::unique_ptr<GfxLink> mpGfxLink; + std::shared_ptr<GfxLink> mpGfxLink; GraphicType meType; mutable sal_uLong mnSizeBytes; bool mbSwapOut; @@ -160,7 +160,7 @@ private: bool ImplIsSwapOut() const { return mbSwapOut;} bool ImplIsDummyContext() const { return mbDummyContext; } - void ImplSetLink( const GfxLink& ); + void ImplSetLink( const std::shared_ptr<GfxLink>& ); GfxLink ImplGetLink(); bool ImplIsLink() const; diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index e7f86486d792..7a869a7aee4b 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -1854,7 +1854,7 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, } if( nStatus == ERRCODE_NONE ) { - rGraphic.SetLink( GfxLink( std::move(pGraphicContent), nGraphicContentSize, eLinkType ) ); + rGraphic.SetLink(GfxLink(std::move(pGraphicContent), nGraphicContentSize, eLinkType)); } } diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 8027d0d85b1d..2d73357ec43d 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -115,6 +115,7 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) , maSwapInfo(rImpGraphic.maSwapInfo) , mpContext(rImpGraphic.mpContext) , mpSwapFile(rImpGraphic.mpSwapFile) + , mpGfxLink(rImpGraphic.mpGfxLink) , meType(rImpGraphic.meType) , mnSizeBytes(rImpGraphic.mnSizeBytes) , mbSwapOut(rImpGraphic.mbSwapOut) @@ -124,9 +125,6 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink) , mnPageNumber(rImpGraphic.mnPageNumber) { - if( rImpGraphic.mpGfxLink ) - mpGfxLink = o3tl::make_unique<GfxLink>( *rImpGraphic.mpGfxLink ); - if( rImpGraphic.mpAnimation ) { mpAnimation = o3tl::make_unique<Animation>( *rImpGraphic.mpAnimation ); @@ -239,10 +237,7 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic ) mbSwapOut = rImpGraphic.mbSwapOut; mpSwapFile = rImpGraphic.mpSwapFile; - mpGfxLink.reset(); - - if( rImpGraphic.mpGfxLink ) - mpGfxLink = o3tl::make_unique<GfxLink>( *rImpGraphic.mpGfxLink ); + mpGfxLink = rImpGraphic.mpGfxLink; maVectorGraphicData = rImpGraphic.maVectorGraphicData; mpPdfData = rImpGraphic.mpPdfData; @@ -1370,11 +1365,11 @@ bool ImpGraphic::ImplSwapIn( SvStream* xIStm ) return bRet; } -void ImpGraphic::ImplSetLink( const GfxLink& rGfxLink ) +void ImpGraphic::ImplSetLink(const GfxLink& rGfxLink) { - mpGfxLink = o3tl::make_unique<GfxLink>( rGfxLink ); + mpGfxLink = rGfxLink; - if( mpGfxLink->IsNative() ) + if (mpGfxLink && mpGfxLink->IsNative()) mpGfxLink->SwapOut(); } @@ -1489,7 +1484,7 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) // set dummy link to avoid creation of additional link after filtering; // we set a default link to avoid unnecessary swapping of native data - aGraphic.SetLink( GfxLink() ); + aGraphic.SetLink(GfxLink()); if( !rIStm.GetError() && aLink.LoadNative( aGraphic ) ) { @@ -1506,7 +1501,7 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) rImpGraphic.ImplSetPrefSize( aLink.GetPrefSize() ); if( bSetLink ) - rImpGraphic.ImplSetLink( aLink ); + rImpGraphic.ImplSetLink(aLink); } else { diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx index d74996ce2403..73581f04ca3f 100644 --- a/vcl/source/gdi/pdfextoutdevdata.cxx +++ b/vcl/source/gdi/pdfextoutdevdata.cxx @@ -846,7 +846,7 @@ bool PDFExtOutDevData::HasAdequateCompression( const Graphic &rGraphic, // 4 means CMYK, which is not handled. return false; - Size aSize = rGraphic.GetSizePixel(); + const Size aSize = rGraphic.GetSizePixel(); // small items better off as PNG anyway if ( aSize.Width() < 32 && _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits