diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-05-05 11:18:30 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2021-05-12 10:51:50 +0200 |
commit | 6e27a04192e3f0a8a9e563e123ef57e0acf61930 (patch) | |
tree | ec82a4d14fd86f66e70ece94a5e88921b7195220 | |
parent | 65dc25a4bcdbe9d60835476c1825c53d72d9527e (diff) |
vcl pdfium render: handle widget annotations for form fields
Note that we render the bitmaps without FPDF_ANNOT, so comments are not
rendered into the bitmaps, rather we create them on top of the bitmaps
in Draw, explicitly.
FPDF_FFLDraw() draws content which is already an annotation, but not yet
interactive content; so this just fixes "missing text", as far as the
user is concerned.
Verified that e.g. vcl/qa/cppunit/data/PangramAcrobatAnnotations.pdf
indeed still doesn't render comments into bitmaps after this.
(cherry picked from commit 92cba30d5ce45e4f4a9516a80c9fe9915add6905)
Conflicts:
include/vcl/filter/PDFiumLibrary.hxx
vcl/qa/cppunit/PDFiumLibraryTest.cxx
vcl/source/filter/ipdf/pdfread.cxx
vcl/source/pdf/PDFiumLibrary.cxx
Change-Id: I2b74d585729305cc1d3a9fefa258d4d76d1bd038
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115167
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r-- | vcl/qa/cppunit/PDFiumLibraryTest.cxx | 39 | ||||
-rw-r--r-- | vcl/qa/cppunit/data/form-fields.pdf | 95 | ||||
-rw-r--r-- | vcl/source/filter/ipdf/pdfread.cxx | 11 |
3 files changed, 145 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/PDFiumLibraryTest.cxx b/vcl/qa/cppunit/PDFiumLibraryTest.cxx index f18681c0adda..54f5e70e00d3 100644 --- a/vcl/qa/cppunit/PDFiumLibraryTest.cxx +++ b/vcl/qa/cppunit/PDFiumLibraryTest.cxx @@ -25,6 +25,8 @@ #include <tools/stream.hxx> #include <vcl/filter/PDFiumLibrary.hxx> +#include <vcl/pdfread.hxx> +#include <vcl/bitmapaccess.hxx> class PDFiumLibraryTest : public test::BootstrapFixtureBase { @@ -39,6 +41,7 @@ class PDFiumLibraryTest : public test::BootstrapFixtureBase void testAnnotationsMadeInEvince(); void testAnnotationsMadeInAcrobat(); void testTools(); + void testFormFields(); CPPUNIT_TEST_SUITE(PDFiumLibraryTest); CPPUNIT_TEST(testDocument); @@ -47,6 +50,7 @@ class PDFiumLibraryTest : public test::BootstrapFixtureBase CPPUNIT_TEST(testAnnotationsMadeInEvince); CPPUNIT_TEST(testAnnotationsMadeInAcrobat); CPPUNIT_TEST(testTools); + CPPUNIT_TEST(testFormFields); CPPUNIT_TEST_SUITE_END(); }; @@ -287,6 +291,41 @@ void PDFiumLibraryTest::testAnnotationsMadeInAcrobat() } } +void PDFiumLibraryTest::testFormFields() +{ + // Given a document with a form field that looks like plain text: + OUString aURL = getFullUrl(u"form-fields.pdf"); + SvFileStream aFileStream(aURL, StreamMode::READ); + SvMemoryStream aMemory; + aMemory.WriteStream(aFileStream); + aMemory.Seek(0); + + // When rendering its first (and only) page to a bitmap: + std::vector<Bitmap> aBitmaps; + int nRet = vcl::RenderPDFBitmaps(aMemory.GetData(), aMemory.GetSize(), aBitmaps); + CPPUNIT_ASSERT(nRet); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aBitmaps.size()); + + // Then make sure the bitmap contains that text: + Bitmap aBitmap = aBitmaps[0]; + BitmapReadAccess aAccess(aBitmap); + Size aSize = aBitmap.GetSizePixel(); + std::set<sal_uInt32> aColors; + for (long y = 0; y < aSize.Height(); ++y) + { + for (long x = 0; x < aSize.Width(); ++x) + { + aColors.insert(static_cast<sal_uInt32>(aAccess.GetPixel(y, x))); + } + } + // Without the accompanying fix in place, this test would have failed with: + // - Expected greater than: 1 + // - Actual : 1 + // i.e. at least black text and white background is expected (possibly more, due to + // anti-aliasing), but nothing was rendered. + CPPUNIT_ASSERT_GREATER(static_cast<size_t>(1), aColors.size()); +} + void PDFiumLibraryTest::testTools() { OUString sConverted = vcl::pdf::convertPdfDateToISO8601("D:20200612201322+02'00"); diff --git a/vcl/qa/cppunit/data/form-fields.pdf b/vcl/qa/cppunit/data/form-fields.pdf new file mode 100644 index 000000000000..a014b36c9821 --- /dev/null +++ b/vcl/qa/cppunit/data/form-fields.pdf @@ -0,0 +1,95 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 5 0 R +>> +endobj + +2 0 obj << + /Length 0 +>> +stream +endstream +endobj + +3 0 obj << + /Font << + /TT1 4 0 R + >> +>> +endobj + +4 0 obj << + /Type /Font + /Subtype /Type1 + /Name /TT1 + /BaseFont/Helvetica +>> +endobj + +5 0 obj << + /Type /Pages + /Kids [6 0 R] + /Count 1 + /MediaBox [ 0 0 612 446 ] +>> +endobj + +6 0 obj << + /Type /Page + /Parent 5 0 R + /Resources 3 0 R + /Contents 2 0 R + /Annots [7 0 R] +>> +endobj + +7 0 obj << + /Type /Annot + /Subtype /Widget + /T (T) + /V (V) + /DA (/Helv 0 Tf 0 g) + /Rect [ 0 0 612 446 ] + /FT /Tx + /AP << + /N 8 0 R + >> +>> +endobj + +8 0 obj << + /Type /XObject + /Subtype /Form + /Matrix [1.0 0.0 0.0 1.0 0.0 0.0] + /Resources 3 0 R + /BBox [ 0 0 612 446 ] + /Length 55 +>> +stream + BT + /TT1 24 Tf + 1 0 0 1 260 254 Tm + (test)Tj + ET +endstream +endobj +xref +0 9 +0000000000 65535 f +0000000015 00000 n +0000000069 00000 n +0000000121 00000 n +0000000174 00000 n +0000000259 00000 n +0000000351 00000 n +0000000458 00000 n +0000000616 00000 n +trailer << + /Root 1 0 R + /Size 9 +>> +startxref +836 +%%EOF diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index e4af2a0e865b..acc45bc4d9e4 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -15,6 +15,7 @@ #include <fpdfview.h> #include <fpdf_edit.h> #include <fpdf_save.h> +#include <fpdf_formfill.h> #endif #include <vcl/graph.hxx> @@ -174,6 +175,10 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi if (!pPdfDocument) return 0; + FPDF_FORMFILLINFO aFormCallbacks = {}; + aFormCallbacks.version = 1; + FPDF_FORMHANDLE pFormHandle = FPDFDOC_InitFormFillEnvironment(pPdfDocument, &aFormCallbacks); + const int nPageCount = FPDF_GetPageCount(pPdfDocument); if (nPages <= 0) nPages = nPageCount; @@ -207,6 +212,10 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi FPDF_RenderPageBitmap(pPdfBitmap, pPdfPage, /*start_x=*/0, /*start_y=*/0, nPageWidth, nPageHeight, /*rotate=*/0, /*flags=*/0); + // Render widget annotations for FormFields. + FPDF_FFLDraw(pFormHandle, 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); { @@ -226,6 +235,8 @@ size_t RenderPDFBitmaps(const void* pBuffer, int nSize, std::vector<Bitmap>& rBi FPDF_ClosePage(pPdfPage); } + FPDFDOC_ExitFormFillEnvironment(pFormHandle); + FPDF_CloseDocument(pPdfDocument); return rBitmaps.size(); |