summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-03-13 21:07:17 -0400
committerAshod Nakashian <ashnakash@gmail.com>2018-03-21 01:58:16 +0100
commit3102b8c8b52845ca4584579a7ad2154488943855 (patch)
tree27f86503eebd741710a7b0ca4bf41499c5d6ea2b
parentac6e6753bd3b94df1780b011efae829964262587 (diff)
vcl: support rendering multiple PDF pages to bitmap
Change-Id: Id42ecabcad90dde84475a01e5df4ed94f221f5ce Reviewed-on: https://gerrit.libreoffice.org/51255 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
-rw-r--r--vcl/source/filter/ipdf/pdfread.cxx85
1 files changed, 49 insertions, 36 deletions
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))