summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-07-10 17:39:03 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2023-07-11 11:10:14 +0200
commitf2d5653a6792a19e9a45d34ac9dce22e717b8cbf (patch)
tree4ac19fef2cd0c5c86a25a200de17d41162052837 /sw/source
parent663db89378aa1f0425e795ef5d471f134e658dc4 (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.cxx14
-rw-r--r--sw/source/core/text/EnhancedPDFExportHelper.cxx45
-rw-r--r--sw/source/core/text/frmpaint.cxx2
-rw-r--r--sw/source/core/text/itrpaint.cxx6
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;
}