vcl/source/filter/ipdf/pdfread.cxx | 85 +++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 36 deletions(-)
New commits: commit 3102b8c8b52845ca4584579a7ad2154488943855 Author: Ashod Nakashian <ashod.nakash...@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 <c...@libreoffice.org> Reviewed-by: Ashod Nakashian <ashnak...@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)) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits