[Libreoffice-commits] core.git: Branch 'distro/collabora/cd-5.3-3.2' - include/vcl sd/source vcl/source

Ashod Nakashian ashod.nakashian at collabora.co.uk
Fri Jun 22 12:44:12 UTC 2018


 include/vcl/pdfread.hxx              |   34 +++++++++++++---
 sd/source/filter/pdf/sdpdffilter.cxx |   34 ++++++----------
 vcl/source/filter/ipdf/pdfread.cxx   |   73 ++++++++++++++++++++++++++++++++++-
 vcl/source/gdi/impgraph.cxx          |    7 +++
 4 files changed, 121 insertions(+), 27 deletions(-)

New commits:
commit 204353d270b8df4659a2f854efc636955e9e2ef9
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat Jun 9 13:09:35 2018 -0400

    pdfium: Import PDF with unloaded images.
    
    Change-Id: I5e4a16ff38b9643127ce16879b35f456c13bcff8
    Reviewed-on: https://gerrit.libreoffice.org/56268
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>

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()


More information about the Libreoffice-commits mailing list