[Libreoffice-commits] core.git: vcl/source

Ashod Nakashian ashod.nakashian at collabora.co.uk
Wed Mar 21 00:58:40 UTC 2018


 vcl/source/filter/ipdf/pdfread.cxx |   85 +++++++++++++++++++++----------------
 1 file changed, 49 insertions(+), 36 deletions(-)

New commits:
commit 3102b8c8b52845ca4584579a7ad2154488943855
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Tue Mar 13 21:07:17 2018 -0400

    vcl: support rendering multiple PDF pages to bitmap
    
    Change-Id: Id42ecabcad90dde84475a01e5df4ed94f221f5ce
    Reviewed-on: https://gerrit.libreoffice.org/51255
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>

diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx
index 4bdca2f02783..1c1c330045fe 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -58,8 +58,9 @@ double pointToPixel(double fPoint)
 }
 
 /// Does PDF to bitmap conversion using pdfium.
-bool generatePreview(SvStream& rStream, Bitmap& rBitmap,
-                     sal_uInt64 nPos, sal_uInt64 nSize)
+size_t generatePreview(SvStream& rStream, std::vector<Bitmap>& rBitmaps,
+                       sal_uInt64 nPos, sal_uInt64 nSize,
+                       const size_t nFirstPage = 0, int nPages = 1)
 {
     FPDF_LIBRARY_CONFIG aConfig;
     aConfig.version = 2;
@@ -76,45 +77,53 @@ bool generatePreview(SvStream& rStream, Bitmap& rBitmap,
     // Load the buffer using pdfium.
     FPDF_DOCUMENT pPdfDocument = FPDF_LoadMemDocument(aInBuffer.GetData(), aInBuffer.GetSize(), /*password=*/nullptr);
     if (!pPdfDocument)
-        return false;
-
-    // Render the first page.
-    FPDF_PAGE pPdfPage = FPDF_LoadPage(pPdfDocument, /*page_index=*/0);
-    if (!pPdfPage)
-        return false;
-
-    // Returned unit is points, convert that to pixel.
-    size_t nPageWidth = pointToPixel(FPDF_GetPageWidth(pPdfPage));
-    size_t nPageHeight = pointToPixel(FPDF_GetPageHeight(pPdfPage));
-    FPDF_BITMAP pPdfBitmap = FPDFBitmap_Create(nPageWidth, nPageHeight, /*alpha=*/1);
-    if (!pPdfBitmap)
-        return false;
+        return 0;
 
-    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);
+    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)
     {
-        BitmapScopedWriteAccess pWriteAccess(aBitmap);
-        auto pPdfBuffer = static_cast<ConstScanline>(FPDFBitmap_GetBuffer(pPdfBitmap));
-        for (size_t nRow = 0; nRow < nPageHeight; ++nRow)
+        // 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));
+        const size_t nPageHeight = pointToPixel(FPDF_GetPageHeight(pPdfPage));
+        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);
         {
-            int nStride = FPDFBitmap_GetStride(pPdfBitmap);
-            ConstScanline pPdfLine = pPdfBuffer + (nStride * nRow);
-            // pdfium byte order is BGRA.
-            pWriteAccess->CopyScanline(nRow, pPdfLine, ScanlineFormat::N32BitTcBgra, nStride);
+            BitmapScopedWriteAccess 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);
     }
-    rBitmap = aBitmap;
 
-    FPDFBitmap_Destroy(pPdfBitmap);
-    FPDF_ClosePage(pPdfPage);
     FPDF_CloseDocument(pPdfDocument);
     FPDF_DestroyLibrary();
 
-    return true;
+    return rBitmaps.size();
 }
 
 /// Decide if PDF data is old enough to be compatible.
@@ -182,10 +191,11 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
     return rOutStream.good();
 }
 #else
-bool generatePreview(SvStream&, Bitmap&,
-                     sal_uInt64, sal_uInt64)
+size_t generatePreview(SvStream&, std::vector<Bitmap>&,
+                     sal_uInt64 nPos, sal_uInt64 nSize,
+                     size_t nFirstPage = 0, int nLastPage = 0)
 {
-    return true;
+    return false;
 }
 
 bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
@@ -207,9 +217,12 @@ bool ImportPDF(SvStream& rStream, Bitmap& rBitmap,
                sal_uInt64 nPos, sal_uInt64 nSize)
 {
     // Get the preview of the first page.
-    if (!generatePreview(rStream, rBitmap, nPos, nSize))
+    std::vector<Bitmap> aBitmaps;
+    if (generatePreview(rStream, aBitmaps, nPos, nSize, 0, 1) != 1)
         return false;
 
+    rBitmap = aBitmaps[0];
+
     // Save the original PDF stream for later use.
     SvMemoryStream aMemoryStream;
     if (!getCompatibleStream(rStream, aMemoryStream, nPos, nSize))


More information about the Libreoffice-commits mailing list