summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-11-21 11:47:16 +0100
committerMichael Stahl <michael.stahl@allotropia.de>2022-11-22 13:05:07 +0100
commit6e5d59c2ca6969e9491f97cd7a00d094fc62cfb3 (patch)
treef32fb1a4c4056b6204e409d9f743a02e844a0d9a /sw
parent3d5e3cb4c033cc7b03c18851d56ca529f025038b (diff)
tdf#135638 drawinglayer,svx,sw: PDF/UA export: put SdrObjects on anchor
... frame in the structure tree. The problem is that in sw, the anchored objects are painted outside of the call to paint the page frame, which is what generates the /Document structure element. For Writer fly frames, this is handled via their SwFlyDrawObj painting, where SwTaggedPDFHelper::CheckReopenTag() finds the anchor frame and temporarily sets it as the structure parent, even if it's on a previous page. But all the SdrObjects on a page are painted by 2 calls to PaintLayer() and there isn't a call back into Writer now. Somehow this even causes a spurious line like "/Document<</MCID 7>>BDC" to be emitted outside any PDF object, which looks clearly wrong. Try to extend the SdrObjUserCall to get a way to retrieve the anchor frame's structure element index. Another option would be to extend ViewObjectContactRedirector to return the PDF Id in its subclass SwViewObjectContactRedirector, and it seems possible since its only one caller is ViewObjectContact::getPrimitive2DSequence(), but Armin adivses that the ViewObjectContactRedirector might go away in the future so it's better to use SdrObjUserCall. It's annoying that the mapping is a static members of SwEnhancedPDFExportHelper; possibly it could be in OutputDevice's PDFExtOutDevData instead? Change-Id: Id61faae469aba4f0bd278ab2324aae06c1fdde64 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143027 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/dcontact.hxx1
-rw-r--r--sw/source/core/text/EnhancedPDFExportHelper.cxx33
2 files changed, 25 insertions, 9 deletions
diff --git a/sw/inc/dcontact.hxx b/sw/inc/dcontact.hxx
index b1025b447de5..8bfdb6bdb50a 100644
--- a/sw/inc/dcontact.hxx
+++ b/sw/inc/dcontact.hxx
@@ -389,6 +389,7 @@ class SAL_DLLPUBLIC_RTTI SwDrawContact final : public SwContact
/// Virtual methods of SdrObjUserCall.
virtual void Changed(const SdrObject& rObj, SdrUserCallType eType, const tools::Rectangle& rOldBoundRect) override;
+ virtual sal_Int32 GetPDFAnchorStructureElementId(SdrObject const& rObj, OutputDevice const&) override;
/** Used by Changed() and by UndoDraw.
Notifies paragraphs that have to get out of the way. */
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 8ed9392bdb48..227197864923 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -81,6 +81,7 @@
#include <strings.hrc>
#include <frameformats.hxx>
#include <authfld.hxx>
+#include <dcontact.hxx>
#include <tools/globname.hxx>
#include <svx/svdobj.hxx>
@@ -337,6 +338,28 @@ SwTaggedPDFHelper::~SwTaggedPDFHelper()
#endif
}
+static auto GetReopenTagFromFrame(SwFrame const& rFrame) -> sal_Int32
+{
+ void const*const pKey = lcl_GetKeyFromFrame(rFrame);
+
+ if (pKey)
+ {
+ FrameTagIdMap const& rFrameTagIdMap(SwEnhancedPDFExportHelper::GetFrameTagIdMap());
+ auto const it(rFrameTagIdMap.find(pKey));
+ if (it != rFrameTagIdMap.end())
+ {
+ return (*it).second;
+ }
+ }
+ return -1;
+}
+
+sal_Int32 SwDrawContact::GetPDFAnchorStructureElementId(SdrObject const& rObj, OutputDevice const&)
+{
+ SwFrame const*const pAnchorFrame(GetAnchoredObj(&rObj)->GetAnchorFrame());
+ return pAnchorFrame ? GetReopenTagFromFrame(*pAnchorFrame) : -1;
+}
+
bool SwTaggedPDFHelper::CheckReopenTag()
{
bool bRet = false;
@@ -377,15 +400,7 @@ bool SwTaggedPDFHelper::CheckReopenTag()
if ( pKeyFrame )
{
- void* pKey = lcl_GetKeyFromFrame( *pKeyFrame );
-
- if ( pKey )
- {
- FrameTagIdMap& rFrameTagIdMap = SwEnhancedPDFExportHelper::GetFrameTagIdMap();
- const FrameTagIdMap::const_iterator aIter = rFrameTagIdMap.find( pKey );
- if ( aIter != rFrameTagIdMap.end() )
- nReopenTag = (*aIter).second;
- }
+ nReopenTag = GetReopenTagFromFrame(*pKeyFrame);
}
}