summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2018-03-13 21:07:17 -0400
committerJan Holesovsky <kendy@collabora.com>2018-05-22 12:17:08 +0200
commitd7c0cc3908a7624aa159549ab1561b511d6fae28 (patch)
tree9238b943c64b9e04de4b639a9964083aa92ecca2 /vcl
parent8783b4f3ffbfd4ae064296c65e8d803bd0460051 (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>
Diffstat (limited to 'vcl')
-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 0f5c079addb9..c5580634c61a 100644
--- a/vcl/source/filter/ipdf/pdfread.cxx
+++ b/vcl/source/filter/ipdf/pdfread.cxx
@@ -62,8 +62,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;
@@ -80,45 +81,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)
{
- Bitmap::ScopedWriteAccess 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);
+ Bitmap::ScopedWriteAccess 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.
@@ -189,15 +198,16 @@ bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
return rOutStream.good();
}
#else
-bool generatePreview(SvStream& rStream, Bitmap& rBitmap
- sal_uInt64 nPos, sal_uInt64 nSize)
+size_t generatePreview(SvStream&, std::vector<Bitmap>&,
+ sal_uInt64 nPos, sal_uInt64 nSize,
+ size_t nFirstPage = 0, int nLastPage = 0)
{
(void)rStream;
(void)rBitmap;
(void)nPos;
(void)nSize;
- return true;
+ return false;
}
bool getCompatibleStream(SvStream& rInStream, SvStream& rOutStream,
@@ -219,9 +229,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))