tdf#159067 drawinglayer: fix untagged form control (PDF/UA export)
If the form object is marked as decorative, the form control should be exported as "Artifact"
Change-Id: I615d308ae966bf3d0f156899a0b4fad2d5a7c492
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162268
Tested-by: Jenkins
Reviewed-by: Nagy Tibor <tibor.nagy.extern@allotropia.de>
diff --git a/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
index 47af55a..783a54a 100644
--- a/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
@@ -30,13 +30,15 @@ namespace drawinglayer::primitive2d
const vcl::PDFWriter::StructElement& rStructureElement,
bool bBackground,
bool bIsImage,
bool bIsDecorative,
Primitive2DContainer&& aChildren,
void const*const pAnchorStructureElementKey,
::std::vector<sal_Int32> const*const pAnnotIds)
: GroupPrimitive2D(std::move(aChildren)),
maStructureElement(rStructureElement),
mbBackground(bBackground),
mbIsImage(bIsImage)
mbIsImage(bIsImage),
mbIsDecorative(bIsDecorative)
, m_pAnchorStructureElementKey(pAnchorStructureElementKey)
{
if (pAnnotIds)
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 22f464d..e4441bb 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1116,8 +1116,9 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
const bool bPDFExport(mpPDFExtOutDevData && mpPDFExtOutDevData->GetIsExportFormFields());
bool bDoProcessRecursively(true);
bool bDecorative = (mpCurrentStructureTag && mpCurrentStructureTag->isDecorative());
if (bPDFExport)
if (bPDFExport && !bDecorative)
{
// PDF export. Emulate data handling from UnoControlPDFExportContact
std::unique_ptr<vcl::PDFWriter::AnyWidget> pPDFControl(
@@ -1190,7 +1191,10 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
if (mpPDFExtOutDevData)
{ // no corresponding PDF Form, use Figure instead
mpPDFExtOutDevData->WrapBeginStructureElement(vcl::PDFWriter::Figure);
if (!bDecorative)
mpPDFExtOutDevData->WrapBeginStructureElement(vcl::PDFWriter::Figure);
else
mpPDFExtOutDevData->WrapBeginStructureElement(vcl::PDFWriter::NonStructElement);
mpPDFExtOutDevData->SetStructureAttribute(vcl::PDFWriter::Placement, vcl::PDFWriter::Block);
auto const range(rControlPrimitive.getB2DRange(getViewInformation2D()));
tools::Rectangle const aLogicRect(
@@ -1198,7 +1202,7 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
basegfx::fround(range.getMaxX()), basegfx::fround(range.getMaxY()));
mpPDFExtOutDevData->SetStructureBoundingBox(aLogicRect);
OUString const& rAltText(rControlPrimitive.GetAltText());
if (!rAltText.isEmpty())
if (!rAltText.isEmpty() && !bDecorative)
{
mpPDFExtOutDevData->SetAlternateText(rAltText);
}
diff --git a/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx b/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
index 0d7e6ba..3cc4899 100644
--- a/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/structuretagprimitive2d.hxx
@@ -49,6 +49,8 @@ namespace drawinglayer::primitive2d
bool mbBackground;
/// flag for image (OBJ_GRAF)
bool mbIsImage;
/// flag for form control object
bool mbIsDecorative;
/// anchor structure element (Writer)
void const* m_pAnchorStructureElementKey;
/// for Annot structure element, the ids of the annotations
@@ -60,6 +62,7 @@ namespace drawinglayer::primitive2d
const vcl::PDFWriter::StructElement& rStructureElement,
bool bBackground,
bool bIsImage,
bool bIsDecorative,
Primitive2DContainer&& aChildren,
void const* pAnchorStructureElementKey = nullptr,
::std::vector<sal_Int32> const* pAnnotIds = nullptr);
@@ -68,6 +71,7 @@ namespace drawinglayer::primitive2d
const vcl::PDFWriter::StructElement& getStructureElement() const { return maStructureElement; }
bool isBackground() const { return mbBackground; }
bool isImage() const { return mbIsImage; }
bool isDecorative() const { return mbIsDecorative; }
bool isTaggedSdrObject() const;
void const* GetAnchorStructureElementKey() const { return m_pAnchorStructureElementKey; }
::std::vector<sal_Int32> GetAnnotIds() const { return m_AnnotIds; }
diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx
index bd6807e..6cf93f7 100644
--- a/sc/qa/extras/scpdfexport.cxx
+++ b/sc/qa/extras/scpdfexport.cxx
@@ -66,6 +66,7 @@ public:
void testUnoCommands_Tdf120161();
void testTdf64703_hiddenPageBreak();
void testTdf159068();
void testTdf159067();
void testTdf159066();
void testTdf159065();
void testTdf123870();
@@ -81,6 +82,7 @@ public:
CPPUNIT_TEST(testUnoCommands_Tdf120161);
CPPUNIT_TEST(testTdf64703_hiddenPageBreak);
CPPUNIT_TEST(testTdf159068);
CPPUNIT_TEST(testTdf159067);
CPPUNIT_TEST(testTdf159066);
CPPUNIT_TEST(testTdf159065);
CPPUNIT_TEST(testTdf123870);
@@ -460,6 +462,66 @@ void ScPDFExportTest::testTdf159068()
CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nArtifact)>(5), nArtifact);
}
void ScPDFExportTest::testTdf159067()
{
loadFromFile(u"tdf159067.ods");
uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
// A1:B3
ScRange range1(0, 0, 0, 1, 2, 0);
exportToPDF(xModel, range1);
vcl::filter::PDFDocument aDocument;
SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ);
CPPUNIT_ASSERT(aDocument.Read(aStream));
// The document has one page.
std::vector<vcl::filter::PDFObjectElement*> aPages = aDocument.GetPages();
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aPages.size());
vcl::filter::PDFObjectElement* pContents = aPages[0]->LookupObject("Contents"_ostr);
CPPUNIT_ASSERT(pContents);
vcl::filter::PDFStreamElement* pStream = pContents->GetStream();
CPPUNIT_ASSERT(pStream);
SvMemoryStream& rObjectStream = pStream->GetMemory();
// Uncompress it.
SvMemoryStream aUncompressed;
ZCodec aZCodec;
aZCodec.BeginCompression();
rObjectStream.Seek(0);
aZCodec.Decompress(rObjectStream, aUncompressed);
CPPUNIT_ASSERT(aZCodec.EndCompression());
auto pStart = static_cast<const char*>(aUncompressed.GetData());
const char* const pEnd = pStart + aUncompressed.GetSize();
auto nArtifact(0);
auto nLine(0);
while (true)
{
++nLine;
auto const pLine = ::std::find(pStart, pEnd, '\n');
if (pLine == pEnd)
{
break;
}
std::string_view const line(pStart, pLine - pStart);
pStart = pLine + 1;
if (!line.empty() && line[0] != '%')
{
::std::cerr << nLine << ": " << line << "\n ";
if (o3tl::starts_with(line, "/Artifact BMC"))
nArtifact++;
}
}
// Without the fix in place, this test would have failed with
// - Expected: 3 (Artifact: Header, Footer, TextBox)
// - Actual : 2 (Artifact: Header, Footer)
CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nArtifact)>(3), nArtifact);
}
void ScPDFExportTest::testTdf159066()
{
loadFromFile(u"tdf159066.ods");
diff --git a/sc/qa/extras/testdocuments/tdf159067.ods b/sc/qa/extras/testdocuments/tdf159067.ods
new file mode 100644
index 0000000..a6e268d
--- /dev/null
+++ b/sc/qa/extras/testdocuments/tdf159067.ods
Binary files differ
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx
index 09593f1..c962e77 100644
--- a/svx/source/sdr/contact/viewobjectcontact.cxx
+++ b/svx/source/sdr/contact/viewobjectcontact.cxx
@@ -422,6 +422,7 @@ void ViewObjectContact::createStructureTag(drawinglayer::primitive2d::Primitive2
eElement,
bBackground,
bImage,
false, // Decorative
std::move(rNewPrimitiveSequence),
pAnchorKey,
&annotIds))
@@ -438,6 +439,7 @@ void ViewObjectContact::createStructureTag(drawinglayer::primitive2d::Primitive2
vcl::PDFWriter::Division,
true,
true,
true, // Decorative
std::move(rNewPrimitiveSequence))
};
}
diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx
index ac7472c..b0accab 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -384,6 +384,7 @@ namespace sdr::contact
eType,
pPage->IsMasterPage(),
false,
false,
std::move(cell)) };
}
row.append(cell);
@@ -396,6 +397,7 @@ namespace sdr::contact
vcl::PDFWriter::TableRow,
pPage->IsMasterPage(),
false,
false,
std::move(row)) };
}
aRetval.append(row);