diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2018-03-13 23:55:26 -0400 |
---|---|---|
committer | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2018-06-04 12:36:28 -0400 |
commit | 5c0b46d3c899d85b16ab9866ae0575ddaef3a81e (patch) | |
tree | ede9ce8682a8a29a78854edfe1465aacf43d741a /vcl | |
parent | 498b14d8a8f4b51b137d03c4fb5c6f8c2747e7cd (diff) |
sd: import PDFs as images using Pdfium new SdPdfFilter
LOK now opens PDFs as images using Pdfium,
which has a superior accuracy and support
to poppler, the default pdf reader.
(cherry picked from commit 0e8f4f45b44935c7c8002d606b97a48e60e37b23)
(cherry picked from commit 42733c51385b6518678a8d5483c234909db2af40)
Change-Id: Ifbbecf7f048f001836fb98886705cba47e6bed4e
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/impgraph.hxx | 14 | ||||
-rw-r--r-- | vcl/inc/pdfread.hxx | 43 | ||||
-rw-r--r-- | vcl/source/filter/graphicfilter.cxx | 2 | ||||
-rw-r--r-- | vcl/source/filter/ipdf/pdfread.cxx | 28 | ||||
-rw-r--r-- | vcl/source/gdi/graph.cxx | 20 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 38 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 20 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 4 |
8 files changed, 87 insertions, 82 deletions
diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index 4338ed20021d..a678aea0edcb 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -88,10 +88,18 @@ private: bool mbSwapOut; bool mbDummyContext; VectorGraphicDataPtr maVectorGraphicData; - css::uno::Sequence<sal_Int8> maPdfData; + /// 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::unique_ptr<GraphicID> mpGraphicID; GraphicExternalLink maGraphicExternalLink; + /// 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; + std::chrono::high_resolution_clock::time_point maLastUsed; bool mbPrepared; @@ -214,9 +222,9 @@ private: const VectorGraphicDataPtr& getVectorGraphicData() const; - const css::uno::Sequence<sal_Int8>& getPdfData() const; + const std::shared_ptr<css::uno::Sequence<sal_Int8>>& getPdfData() const; - void setPdfData(const css::uno::Sequence<sal_Int8>& rPdfData); + void setPdfData(const std::shared_ptr<css::uno::Sequence<sal_Int8>>& rPdfData); bool ensureAvailable () const; diff --git a/vcl/inc/pdfread.hxx b/vcl/inc/pdfread.hxx deleted file mode 100644 index 2e16e4474c17..000000000000 --- a/vcl/inc/pdfread.hxx +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX -#define INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX - -#include <tools/stream.hxx> - -namespace com -{ -namespace sun -{ -namespace star -{ -namespace uno -{ -template <typename> class Sequence; -} -} -} -} -class Bitmap; -class Graphic; - -namespace vcl -{ -/// Imports a PDF stream into rGraphic as a GDIMetaFile. -VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, - css::uno::Sequence<sal_Int8>& rPdfData, - sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN, - sal_uInt64 nSize = STREAM_SEEK_TO_END); -VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic); -} - -#endif // INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 1ba3d1d776ec..f713264cacfb 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -44,7 +44,7 @@ #include <vcl/wmf.hxx> #include <vcl/settings.hxx> #include "igif/gifread.hxx" -#include <pdfread.hxx> +#include <vcl/pdfread.hxx> #include "jpeg/jpeg.hxx" #include "ixbm/xbmread.hxx" #include "ixpm/xpmread.hxx" diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index b37b6339155e..f94e6b320dd2 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <pdfread.hxx> +#include <vcl/pdfread.hxx> #include <config_features.h> @@ -17,8 +17,10 @@ #include <fpdf_save.h> #endif +#include <vcl/bitmapaccess.hxx> #include <vcl/graph.hxx> #include <bitmapwriteaccess.hxx> +#include <unotools/ucbstreamhelper.hxx> using namespace com::sun::star; @@ -243,9 +245,31 @@ bool ImportPDF(SvStream& rStream, Graphic& rGraphic) Bitmap aBitmap; const bool bRet = ImportPDF(rStream, aBitmap, aPdfData); rGraphic = aBitmap; - rGraphic.setPdfData(aPdfData); + rGraphic.setPdfData(std::make_shared<css::uno::Sequence<sal_Int8>>(aPdfData)); return bRet; } + +size_t ImportPDF(const OUString& rURL, std::vector<Bitmap>& rBitmaps, + css::uno::Sequence<sal_Int8>& rPdfData) +{ + std::unique_ptr<SvStream> xStream( + ::utl::UcbStreamHelper::CreateStream(rURL, StreamMode::READ | StreamMode::SHARE_DENYNONE)); + + if (generatePreview(*xStream, rBitmaps, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END, 0, -1) == 0) + return 0; + + // Save the original PDF stream for later use. + SvMemoryStream aMemoryStream; + if (!getCompatibleStream(*xStream, aMemoryStream, STREAM_SEEK_TO_BEGIN, STREAM_SEEK_TO_END)) + return 0; + + aMemoryStream.Seek(STREAM_SEEK_TO_END); + rPdfData = css::uno::Sequence<sal_Int8>(aMemoryStream.Tell()); + aMemoryStream.Seek(STREAM_SEEK_TO_BEGIN); + aMemoryStream.ReadBytes(rPdfData.getArray(), rPdfData.getLength()); + + return rBitmaps.size(); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index 19bb99d254e4..52e4e9e74ae8 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -557,17 +557,33 @@ const VectorGraphicDataPtr& Graphic::getVectorGraphicData() const return mxImpGraphic->getVectorGraphicData(); } -void Graphic::setPdfData(const uno::Sequence<sal_Int8>& rPdfData) +void Graphic::setPdfData(const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData) { ImplTestRefCount(); mxImpGraphic->setPdfData(rPdfData); } -const uno::Sequence<sal_Int8>& Graphic::getPdfData() const +const std::shared_ptr<uno::Sequence<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(); +} + +void Graphic::setPageNumber(sal_Int32 nPageNumber) +{ + mxImpGraphic->mnPageNumber = nPageNumber; +} + +sal_Int32 Graphic::getPageNumber() const +{ + return mxImpGraphic->mnPageNumber; +} + OUString Graphic::getOriginURL() const { if (mxImpGraphic) diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index c718f9673610..fe8eb1166250 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -43,7 +43,7 @@ #include <o3tl/make_unique.hxx> #include <vcl/gdimetafiletools.hxx> -#include <pdfread.hxx> +#include <vcl/pdfread.hxx> #define GRAPHIC_MTFTOBMP_MAXEXT 2048 #define GRAPHIC_STREAMBUFSIZE 8192UL @@ -195,7 +195,7 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) , mbSwapOut(rImpGraphic.mbSwapOut) , mbDummyContext(rImpGraphic.mbDummyContext) , maVectorGraphicData(rImpGraphic.maVectorGraphicData) - , maPdfData(rImpGraphic.maPdfData) + , mpPdfData(rImpGraphic.mpPdfData) , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink) , maLastUsed (std::chrono::high_resolution_clock::now()) , mbPrepared (rImpGraphic.mbPrepared) @@ -223,7 +223,7 @@ ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) , mbSwapOut(rImpGraphic.mbSwapOut) , mbDummyContext(rImpGraphic.mbDummyContext) , maVectorGraphicData(std::move(rImpGraphic.maVectorGraphicData)) - , maPdfData(std::move(rImpGraphic.maPdfData)) + , mpPdfData(std::move(rImpGraphic.mpPdfData)) , maGraphicExternalLink(rImpGraphic.maGraphicExternalLink) , maLastUsed (std::chrono::high_resolution_clock::now()) , mbPrepared (rImpGraphic.mbPrepared) @@ -341,7 +341,7 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic ) mpGfxLink = o3tl::make_unique<GfxLink>( *rImpGraphic.mpGfxLink ); maVectorGraphicData = rImpGraphic.maVectorGraphicData; - maPdfData = rImpGraphic.maPdfData; + mpPdfData = rImpGraphic.mpPdfData; maLastUsed = std::chrono::high_resolution_clock::now(); vcl::graphic::Manager::get().changeExisting(this, aOldSizeBytes); @@ -366,7 +366,7 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic) mpSwapFile = std::move(rImpGraphic.mpSwapFile); mpGfxLink = std::move(rImpGraphic.mpGfxLink); maVectorGraphicData = std::move(rImpGraphic.maVectorGraphicData); - maPdfData = std::move(rImpGraphic.maPdfData); + mpPdfData = std::move(rImpGraphic.mpPdfData); maGraphicExternalLink = rImpGraphic.maGraphicExternalLink; mbPrepared = rImpGraphic.mbPrepared; @@ -419,9 +419,9 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData); } } - else if (maPdfData.hasElements()) + else if (mpPdfData->hasElements()) { - bRet = maPdfData == rImpGraphic.maPdfData; + bRet = mpPdfData == rImpGraphic.mpPdfData; } else if( mpAnimation ) { @@ -450,18 +450,18 @@ const VectorGraphicDataPtr& ImpGraphic::getVectorGraphicData() const return maVectorGraphicData; } -void ImpGraphic::setPdfData(const uno::Sequence<sal_Int8>& rPdfData) +void ImpGraphic::setPdfData(const std::shared_ptr<uno::Sequence<sal_Int8>>& rPdfData) { ensureAvailable(); - maPdfData = rPdfData; + mpPdfData = rPdfData; } -const uno::Sequence<sal_Int8>& ImpGraphic::getPdfData() const +const std::shared_ptr<uno::Sequence<sal_Int8>>& ImpGraphic::getPdfData() const { ensureAvailable(); - return maPdfData; + return mpPdfData; } void ImpGraphic::ImplCreateSwapInfo() @@ -485,7 +485,7 @@ void ImpGraphic::ImplClearGraphics() mpAnimation.reset(); mpGfxLink.reset(); maVectorGraphicData.reset(); - maPdfData = uno::Sequence<sal_Int8>(); + mpPdfData.reset(); } ImpSwapFile::~ImpSwapFile() @@ -1681,10 +1681,10 @@ BitmapChecksum ImpGraphic::ImplGetChecksum() const nRet = maEx.GetChecksum(); } - if (maPdfData.hasElements()) + if (mpPdfData->hasElements()) // 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, maPdfData.getConstArray(), maPdfData.getLength()); + nRet = vcl_get_checksum(nRet, mpPdfData->getConstArray(), mpPdfData->getLength()); } break; @@ -1875,7 +1875,7 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) Bitmap aBitmap; if (nPdfDataLength && !rIStm.GetError() && - vcl::ImportPDF(rIStm, aBitmap, rImpGraphic.maPdfData, + vcl::ImportPDF(rIStm, aBitmap, *rImpGraphic.mpPdfData, rIStm.Tell(), nPdfDataLength)) { rImpGraphic.maEx = aBitmap; @@ -1910,7 +1910,7 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic) if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) && ( rOStm.GetCompressMode() & SvStreamCompressFlags::NATIVE ) && rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() && - !rImpGraphic.maPdfData.hasElements()) + !rImpGraphic.mpPdfData->hasElements()) { // native format rOStm.WriteUInt32( NATIVE_FORMAT_50 ); @@ -1971,12 +1971,12 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic) rOStm.WriteUniOrByteString(rImpGraphic.getVectorGraphicData()->getPath(), rOStm.GetStreamCharSet()); } - else if (rImpGraphic.maPdfData.hasElements()) + else if (rImpGraphic.mpPdfData->hasElements()) { // Stream out PDF data. rOStm.WriteUInt32(nPdfMagic); - rOStm.WriteUInt32(rImpGraphic.maPdfData.getLength()); - rOStm.WriteBytes(rImpGraphic.maPdfData.getConstArray(), rImpGraphic.maPdfData.getLength()); + rOStm.WriteUInt32(rImpGraphic.mpPdfData->getLength()); + rOStm.WriteBytes(rImpGraphic.mpPdfData->getConstArray(), rImpGraphic.mpPdfData->getLength()); } else if( rImpGraphic.ImplIsAnimated()) { diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index b72078caa819..eff39aaab0da 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -4932,12 +4932,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_pData->getLength())); 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_pData->getArray(), rEmbeddedFile.m_pData->getLength())); aLine.append("\nendstream\nendobj\n\n"); CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength())); @@ -8872,7 +8872,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_pPDFData->hasElements() && !m_aContext.UseReferenceXObject) { writeReferenceXObject(rObject.m_aReferenceXObject); return; @@ -9180,7 +9180,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_pPDFData->getArray(), rEmit.m_pPDFData->getLength()); aPDFStream.Seek(0); filter::PDFDocument aPDFDocument; if (!aPDFDocument.Read(aPDFStream)) @@ -9416,7 +9416,7 @@ namespace bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask ) { - if (rObject.m_aReferenceXObject.m_aPDFData.hasElements() && !m_aContext.UseReferenceXObject) + if (rObject.m_aReferenceXObject.m_pPDFData->hasElements() && !m_aContext.UseReferenceXObject) { writeReferenceXObject(rObject.m_aReferenceXObject); return true; @@ -9734,7 +9734,7 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject // no pdf data. rEmit.m_nBitmapObject = nBitmapObject; - if (!rGraphic.getPdfData().hasElements()) + if (!rGraphic.getPdfData()->hasElements()) return; if (m_aContext.UseReferenceXObject) @@ -9742,12 +9742,12 @@ void PDFWriterImpl::createEmbeddedFile(const Graphic& rGraphic, ReferenceXObject // Store the original PDF data as an embedded file. m_aEmbeddedFiles.emplace_back(); m_aEmbeddedFiles.back().m_nObject = createObject(); - m_aEmbeddedFiles.back().m_aData = rGraphic.getPdfData(); + m_aEmbeddedFiles.back().m_pData = rGraphic.getPdfData(); rEmit.m_nEmbeddedObject = m_aEmbeddedFiles.back().m_nObject; } else - rEmit.m_aPDFData = rGraphic.getPdfData(); + rEmit.m_pPDFData = rGraphic.getPdfData(); rEmit.m_nFormObject = createObject(); rEmit.m_aPixelSize = rGraphic.GetPrefSize(); @@ -9802,7 +9802,7 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const { m_aJPGs.emplace( m_aJPGs.begin() ); JPGEmit& rEmit = m_aJPGs.front(); - if (!rGraphic.getPdfData().hasElements() || m_aContext.UseReferenceXObject) + if (!rGraphic.getPdfData()->hasElements() || m_aContext.UseReferenceXObject) rEmit.m_nObject = createObject(); rEmit.m_aID = aID; rEmit.m_pStream.reset( pStream ); @@ -9910,7 +9910,7 @@ const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx m_aBitmaps.push_front( BitmapEmit() ); m_aBitmaps.front().m_aID = aID; m_aBitmaps.front().m_aBitmap = aBitmap; - if (!rGraphic.getPdfData().hasElements() || m_aContext.UseReferenceXObject) + if (!rGraphic.getPdfData()->hasElements() || m_aContext.UseReferenceXObject) m_aBitmaps.front().m_nObject = createObject(); createEmbeddedFile(rGraphic, m_aBitmaps.front().m_aReferenceXObject, m_aBitmaps.front().m_nObject); it = m_aBitmaps.begin(); diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index b4c1b3a454e6..4d5df9325d5e 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::shared_ptr<css::uno::Sequence<sal_Int8>> m_pPDFData; ReferenceXObjectEmit() : m_nFormObject(0), @@ -446,7 +446,7 @@ public: /// ID of the file. sal_Int32 m_nObject; /// Contents of the file. - css::uno::Sequence<sal_Int8> m_aData; + std::shared_ptr<css::uno::Sequence<sal_Int8>> m_pData; PDFEmbeddedFile() : m_nObject(0) |