summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/filter/PDFiumLibrary.hxx1
-rw-r--r--sw/qa/core/text/text.cxx35
-rw-r--r--sw/source/core/text/itrform2.cxx9
-rw-r--r--vcl/source/pdf/PDFiumLibrary.cxx31
4 files changed, 74 insertions, 2 deletions
diff --git a/include/vcl/filter/PDFiumLibrary.hxx b/include/vcl/filter/PDFiumLibrary.hxx
index a0da94ab49f2..305c7f3f9d2f 100644
--- a/include/vcl/filter/PDFiumLibrary.hxx
+++ b/include/vcl/filter/PDFiumLibrary.hxx
@@ -106,6 +106,7 @@ public:
virtual float getFontSize(PDFiumDocument* pDoc) = 0;
virtual OUString getFormFieldAlternateName(PDFiumDocument* pDoc) = 0;
virtual int getFormFieldFlags(PDFiumDocument* pDoc) = 0;
+ virtual OUString getFormFieldValue(PDFiumDocument* pDoc) = 0;
};
class PDFiumTextPage;
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index de15cadd4c36..8cc59e8e3a2a 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -770,6 +770,41 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testNumberPortionNoformat)
getXPath(pXmlDoc, "//Special[@nType='PortionType::Number']/SwFont", "color"));
}
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testCheckedCheckboxContentControlPDF)
+{
+ std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
+ if (!pPDFium)
+ return;
+
+ // Given a file with a checked checkbox content control:
+ SwDoc* pDoc = createSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->InsertContentControl(SwContentControlType::CHECKBOX);
+ // Toggle it, so we get a checked one:
+ SwTextContentControl* pTextContentControl = pWrtShell->CursorInsideContentControl();
+ const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
+ pWrtShell->GotoContentControl(rFormatContentControl);
+
+ // When exporting to PDF:
+ StoreToTempFile("writer_pdf_Export");
+
+ // Then make sure that a checked checkbox form widget is emitted:
+ std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = LoadPdfFromTempFile();
+ std::unique_ptr<vcl::pdf::PDFiumPage> pPage = pPdfDocument->openPage(0);
+ CPPUNIT_ASSERT_EQUAL(1, pPage->getAnnotationCount());
+ std::unique_ptr<vcl::pdf::PDFiumAnnotation> pAnnotation = pPage->getAnnotation(0);
+ CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Widget, pAnnotation->getSubType());
+ CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFFormFieldType::CheckBox,
+ pAnnotation->getFormFieldType(pPdfDocument.get()));
+ OUString aActual = pAnnotation->getFormFieldValue(pPdfDocument.get());
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Yes
+ // - Actual : Off
+ // i.e. the /AP -> /N key of the checkbox widget annotation object didn't have a sub-key that
+ // would match /V, leading to not showing the checked state.
+ CPPUNIT_ASSERT_EQUAL(OUString("Yes"), aActual);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index fad85e12337e..fdbd8ef28050 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -951,8 +951,13 @@ bool SwContentControlPortion::DescribePDFControl(const SwTextPaintInfo& rInf) co
pDescriptor = std::make_unique<vcl::PDFWriter::CheckBoxWidget>();
auto pCheckBoxWidget = static_cast<vcl::PDFWriter::CheckBoxWidget*>(pDescriptor.get());
pCheckBoxWidget->Checked = pContentControl->GetChecked();
- pCheckBoxWidget->OnValue = pContentControl->GetCheckedState();
- pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState();
+ // If it is checked already, then leave the default "Yes" OnValue unchanged, so the
+ // appropriate appearance is found by PDF readers.
+ if (!pCheckBoxWidget->Checked)
+ {
+ pCheckBoxWidget->OnValue = pContentControl->GetCheckedState();
+ pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState();
+ }
break;
}
case SwContentControlType::DROP_DOWN_LIST:
diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
index c6781bca2f26..5db5805b2250 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -253,6 +253,7 @@ public:
float getFontSize(PDFiumDocument* pDoc) override;
OUString getFormFieldAlternateName(PDFiumDocument* pDoc) override;
int getFormFieldFlags(PDFiumDocument* pDoc) override;
+ OUString getFormFieldValue(PDFiumDocument* pDoc) override;
};
class PDFiumPageObjectImpl final : public PDFiumPageObject
@@ -1230,6 +1231,36 @@ OUString PDFiumAnnotationImpl::getFormFieldAlternateName(PDFiumDocument* pDoc)
return aString;
}
+OUString PDFiumAnnotationImpl::getFormFieldValue(PDFiumDocument* pDoc)
+{
+ auto pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
+ OUString aString;
+ unsigned long nSize
+ = FPDFAnnot_GetFormFieldValue(pDocImpl->getFormHandlePointer(), mpAnnotation, nullptr, 0);
+ assert(nSize % 2 == 0);
+ nSize /= 2;
+ if (nSize > 1)
+ {
+ std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nSize]);
+ unsigned long nStringSize
+ = FPDFAnnot_GetFormFieldValue(pDocImpl->getFormHandlePointer(), mpAnnotation,
+ reinterpret_cast<FPDF_WCHAR*>(pText.get()), nSize * 2);
+ assert(nStringSize % 2 == 0);
+ nStringSize /= 2;
+ if (nStringSize > 0)
+ {
+#if defined OSL_BIGENDIAN
+ for (unsigned long i = 0; i != nStringSize; ++i)
+ {
+ pText[i] = OSL_SWAPWORD(pText[i]);
+ }
+#endif
+ aString = OUString(pText.get());
+ }
+ }
+ return aString;
+}
+
namespace
{
bool getBorderProperties(FPDF_ANNOTATION mpAnnotation, float& rHorizontalCornerRadius,