diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2023-07-10 17:39:03 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2023-07-11 11:10:14 +0200 |
commit | f2d5653a6792a19e9a45d34ac9dce22e717b8cbf (patch) | |
tree | 4ac19fef2cd0c5c86a25a200de17d41162052837 /sw/source | |
parent | 663db89378aa1f0425e795ef5d471f134e658dc4 (diff) |
tdf#154939 sw: PDF/UA export: produce Link StructElem inside Figure
... for a fly frame with a hyperlink set.
Specification: ISO 14289-1:2014, Clause: 7.18.5, Test number: 1
Links shall be tagged according to ISO 32000-1:2008, 14.8.4.4.2, Link Element.
A Link annotation is nested within null tag instead of Link
Change-Id: I7a2bef8d6100adffb1f40085bba8f18fc68bd8d4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154280
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/core/layout/paintfrm.cxx | 14 | ||||
-rw-r--r-- | sw/source/core/text/EnhancedPDFExportHelper.cxx | 45 | ||||
-rw-r--r-- | sw/source/core/text/frmpaint.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/text/itrpaint.cxx | 6 |
4 files changed, 52 insertions, 15 deletions
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index 47e56b390712..69f78db19c59 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -33,6 +33,7 @@ #include <calbck.hxx> #include <fmtsrnd.hxx> #include <fmtclds.hxx> +#include <fmturl.hxx> #include <strings.hrc> #include <swmodule.hxx> #include <rootfrm.hxx> @@ -3503,8 +3504,19 @@ SwShortCut::SwShortCut( const SwFrame& rFrame, const SwRect& rRect ) void SwLayoutFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const { // #i16816# tagged pdf support - Frame_Info aFrameInfo( *this ); + Frame_Info aFrameInfo(*this, false); SwTaggedPDFHelper aTaggedPDFHelper( nullptr, &aFrameInfo, nullptr, rRenderContext ); + ::std::optional<SwTaggedPDFHelper> oTaggedLink; + if (IsFlyFrame()) + { + // tdf#154939 Link nested inside Figure + auto const pItem(GetFormat()->GetAttrSet().GetItemIfSet(RES_URL)); + if (pItem && !pItem->GetURL().isEmpty()) + { + Frame_Info linkInfo(*this, true); + oTaggedLink.emplace(nullptr, &linkInfo, nullptr, rRenderContext); + } + } const SwFrame *pFrame = Lower(); if ( !pFrame ) diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index 25be18e0d521..7b5732e925da 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -408,7 +408,7 @@ bool SwTaggedPDFHelper::CheckReopenTag() { pKeyFrame = &rFrame; } - else if ( rFrame.IsFlyFrame() ) + else if (rFrame.IsFlyFrame() && !mpFrameInfo->m_isLink) { const SwFormatAnchor& rAnchor = static_cast<const SwFlyFrame*>(&rFrame)->GetFormat()->GetAnchor(); @@ -532,6 +532,23 @@ void SwTaggedPDFHelper::EndTag() #endif } +namespace { + + // link the link annotation to the link structured element + void LinkLinkLink(vcl::PDFExtOutDevData & rPDFExtOutDevData, SwRect const& rRect) + { + const LinkIdMap& rLinkIdMap = SwEnhancedPDFExportHelper::GetLinkIdMap(); + const Point aCenter = rRect.Center(); + auto aIter = std::find_if(rLinkIdMap.begin(), rLinkIdMap.end(), + [&aCenter](const IdMapEntry& rEntry) { return rEntry.first.Contains(aCenter); }); + if (aIter != rLinkIdMap.end()) + { + sal_Int32 nLinkId = (*aIter).second; + rPDFExtOutDevData.SetStructureAttributeNumerical(vcl::PDFWriter::LinkAnnotation, nLinkId); + } + } +} + // Sets the attributes according to the structure type. void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType ) { @@ -806,6 +823,12 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType ) } } } + + if (mpFrameInfo->m_isLink) + { + SwRect const aRect(mpFrameInfo->mrFrame.getFrameArea()); + LinkLinkLink(*mpPDFExtOutDevData, aRect); + } } /* @@ -906,17 +929,9 @@ void SwTaggedPDFHelper::SetAttributes( vcl::PDFWriter::StructElement eType ) if ( bLinkAttribute ) { - const LinkIdMap& rLinkIdMap = SwEnhancedPDFExportHelper::GetLinkIdMap(); SwRect aPorRect; rInf.CalcRect( *pPor, &aPorRect ); - const Point aPorCenter = aPorRect.Center(); - auto aIter = std::find_if(rLinkIdMap.begin(), rLinkIdMap.end(), - [&aPorCenter](const IdMapEntry& rEntry) { return rEntry.first.Contains(aPorCenter); }); - if (aIter != rLinkIdMap.end()) - { - sal_Int32 nLinkId = (*aIter).second; - mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::LinkAnnotation, nLinkId ); - } + LinkLinkLink(*mpPDFExtOutDevData, aPorRect); } } else if (mpNumInfo && eType == vcl::PDFWriter::List) @@ -1435,6 +1450,12 @@ void SwTaggedPDFHelper::BeginBlockStructureElements() // FlyFrame: Figure, Formula, Control // fly in content or fly at page + if (mpFrameInfo->m_isLink) + { // tdf#154939 additional inner link element for flys + nPDFType = vcl::PDFWriter::Link; + aPDFType = aLinkString; + } + else { const SwFlyFrame* pFly = static_cast<const SwFlyFrame*>(pFrame); if (pFly->GetAnchorFrame()->FindFooterOrHeader() != nullptr @@ -1986,6 +2007,10 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport() const sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, formatName, aLinkPageNum); + // Store link info for tagged pdf output: + const IdMapEntry aLinkEntry(aLinkRect, nLinkId); + s_aLinkIdMap.push_back(aLinkEntry); + // Connect Link and Destination: if ( bInternal ) pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId ); diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx index a701470a1c61..e7e779eb0ea4 100644 --- a/sw/source/core/text/frmpaint.cxx +++ b/sw/source/core/text/frmpaint.cxx @@ -694,7 +694,7 @@ void SwTextFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const& if (isPDFTaggingEnabled && !GetPara()->HasNumberingPortion(SwParaPortion::FootnoteToo)) { // no Lbl needed => open paragraph tag now - Frame_Info aFrameInfo(*this); + Frame_Info aFrameInfo(*this, false); oTaggedParagraph.emplace(nullptr, &aFrameInfo, nullptr, rRenderContext); } diff --git a/sw/source/core/text/itrpaint.cxx b/sw/source/core/text/itrpaint.cxx index a189e5abf25b..620838d10171 100644 --- a/sw/source/core/text/itrpaint.cxx +++ b/sw/source/core/text/itrpaint.cxx @@ -157,7 +157,7 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip, { // there is a num portion but it is outside of the frame area and not painted assert(!roTaggedLabel); assert(!roTaggedParagraph); - Frame_Info aFrameInfo(*m_pFrame); // open LBody + Frame_Info aFrameInfo(*m_pFrame, false); // open LBody roTaggedParagraph.emplace(nullptr, &aFrameInfo, nullptr, *GetInfo().GetOut()); } @@ -437,7 +437,7 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip, assert(roTaggedLabel); roTaggedLabel.reset(); // close Lbl assert(!roTaggedParagraph); - Frame_Info aFrameInfo(*m_pFrame); // open LBody + Frame_Info aFrameInfo(*m_pFrame, false); // open LBody roTaggedParagraph.emplace(nullptr, &aFrameInfo, nullptr, *pOut); } @@ -473,7 +473,7 @@ void SwTextPainter::DrawTextLine( const SwRect &rPaint, SwSaveClip &rClip, { roTaggedLabel.reset(); } // else, if the numbering isn't visible at all, no Lbl - Frame_Info aFrameInfo(*m_pFrame); // open LBody + Frame_Info aFrameInfo(*m_pFrame, false); // open LBody roTaggedParagraph.emplace(nullptr, &aFrameInfo, nullptr, *GetInfo().GetOut()); return true; } |