summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-06-09 13:09:35 -0400
committerAshod Nakashian <ashnakash@gmail.com>2018-06-22 14:43:48 +0200
commit204353d270b8df4659a2f854efc636955e9e2ef9 (patch)
tree7819f77c4e470efb616c37a097af508a4b028738
parentf2ea104c48965ff2c3dbc6fd9d3e231c4c4b1459 (diff)
pdfium: Import PDF with unloaded images.
Change-Id: I5e4a16ff38b9643127ce16879b35f456c13bcff8 Reviewed-on: https://gerrit.libreoffice.org/56268 Reviewed-by: Ashod Nakashian <ashnakash@gmail.com> Tested-by: Ashod Nakashian <ashnakash@gmail.com>
-rw-r--r--include/vcl/pdfread.hxx34
-rw-r--r--sd/source/filter/pdf/sdpdffilter.cxx34
-rw-r--r--vcl/source/filter/ipdf/pdfread.cxx73
-rw-r--r--vcl/source/gdi/impgraph.cxx7
4 files changed, 121 insertions, 27 deletions
diff --git a/include/vcl/pdfread.hxx b/include/vcl/pdfread.hxx
index c31251bfaf53..f3956eba5384 100644
--- a/include/vcl/pdfread.hxx
+++ b/include/vcl/pdfread.hxx
@@ -10,8 +10,26 @@
#ifndef INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX
#define INCLUDED_VCL_SOURCE_FILTER_IPDF_PDFREAD_HXX
+#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
{
@@ -22,9 +40,8 @@ VCL_DLLPUBLIC size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vecto
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> &rPdfFata,
+VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap& rBitmap, size_t nPageIndex,
+ css::uno::Sequence<sal_Int8>& rPdfData,
sal_uInt64 nPos = STREAM_SEEK_TO_BEGIN,
sal_uInt64 nSize = STREAM_SEEK_TO_END,
const double fResolutionDPI = 96.);
@@ -32,10 +49,17 @@ VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Bitmap &rBitmap,
VCL_DLLPUBLIC bool ImportPDF(SvStream& rStream, Graphic& rGraphic,
const double fResolutionDPI = 96.);
-VCL_DLLPUBLIC size_t ImportPDF(const OUString& rURL,
- std::vector<Bitmap>& rBitmaps,
+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 8ca237fd6345..62dbc3964f35 100644
--- a/sd/source/filter/pdf/sdpdffilter.cxx
+++ b/sd/source/filter/pdf/sdpdffilter.cxx
@@ -102,37 +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 2e9d7c4909d7..e92b0c7b54a3 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -23,8 +23,10 @@
#endif
#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;
@@ -302,6 +304,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 d2106041f9cd..cdad0f51e457 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -1371,7 +1371,14 @@ void ImpGraphic::ImplSetSharedLink(const std::shared_ptr<GfxLink>& pGfxLink)
mpGfxLink = pGfxLink;
if (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()