summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-10-27 18:00:14 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2023-11-02 10:46:30 +0100
commit6593d680e21c24501a58bac216de4a7c71541959 (patch)
tree6b40e10943607ca2147a7f77a5c84ab34d660af2
parent468e5b8e0a7fefe1ca53faeb15f5f6527c37a268 (diff)
tdf#157816 sw: PDF export: filter out links on empty space, fields
If there is a fly overlapping a paragraph, it may happen (depending on wrap settings and position) that there's an empty space on one side of the fly; the cursor selection region has the flys removed, and this region is used here for the PDF export. So there is a rectangle on the text on one side of the fly, turned into the desired Link annotation, and another rectangle on the other side of the fly, turned into another undesired Link annotation that isn't connected to any SE because without text there is no SE. This is a tricky problem, and the only idea to fix it is to try to see if there is text in the rectangle by first GetModelPositionForViewPoint() resulting in a SwPosition and a SwSpecialPos with an index inside the field; then see if GetCharRect() for this position returns a cursor rectangle that intersects the original selection rectangle. Change-Id: I6918eac16690e7194208a828108bfa968d28d12a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158571 Tested-by: Michael Stahl <michael.stahl@allotropia.de> Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
-rw-r--r--sw/source/core/text/EnhancedPDFExportHelper.cxx38
-rw-r--r--vcl/qa/cppunit/pdfexport/data/tdf157816.fodt175
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx389
3 files changed, 598 insertions, 4 deletions
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index decdd4215f0b..946def82f719 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -345,6 +345,35 @@ bool lcl_TryMoveToNonHiddenField(SwEditShell& rShell, const SwTextNode& rNd, con
return true;
};
+// tdf#157816: try to check if the rectangle contains actual text
+::std::vector<SwRect> GetCursorRectsContainingText(SwCursorShell const& rShell)
+{
+ ::std::vector<SwRect> ret;
+ for (SwRect const& rRect : *rShell.GetCursor_())
+ {
+ Point center(rRect.Center());
+ SwSpecialPos special;
+ SwCursorMoveState cms(CursorMoveState::NONE);
+ cms.m_pSpecialPos = &special;
+ cms.m_bFieldInfo = true;
+ SwPosition pos(rShell.GetDoc()->GetNodes());
+ auto const [pStart, pEnd] = rShell.GetCursor_()->StartEnd();
+ if (rShell.GetLayout()->GetModelPositionForViewPoint(&pos, center, &cms)
+ && *pStart <= pos && pos <= *pEnd)
+ {
+ SwRect charRect;
+ if (rShell.GetCurrFrame(false)->GetCharRect(charRect, pos, &cms, false)
+ && rRect.Overlaps(charRect))
+ {
+ ret.push_back(rRect);
+ }
+ }
+ // reset stupid static var that may have gotten set now
+ SwTextCursor::SetRightMargin(false); // WTF is this crap
+ }
+ return ret;
+}
+
} // end namespace
SwTaggedPDFHelper::SwTaggedPDFHelper( const Num_Info* pNumInfo,
@@ -2396,8 +2425,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport(LanguageType const eLanguageDe
mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::Chars );
// Link Rectangles
- SwRects aTmp;
- aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
+ SwRects const aTmp(GetCursorRectsContainingText(mrSh));
OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
mrSh.SwCursorShell::ClearMark();
@@ -2819,7 +2847,8 @@ void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
// Create the links.
- for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
+ SwRects const rects(GetCursorRectsContainingText(mrSh));
+ for (const auto& rLinkRect : rects)
{
for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
{
@@ -2869,7 +2898,8 @@ void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
// Create the links.
- for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
+ SwRects const rects(GetCursorRectsContainingText(mrSh));
+ for (const auto& rLinkRect : rects)
{
for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
{
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf157816.fodt b/vcl/qa/cppunit/pdfexport/data/tdf157816.fodt
new file mode 100644
index 000000000000..5288f3aa75ca
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/tdf157816.fodt
@@ -0,0 +1,175 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:creation-date>2020-12-04T17:01:40.586000000</meta:creation-date><dc:title>LibreOffice</dc:title><meta:editing-duration>P18DT13H30M55S</meta:editing-duration><meta:editing-cycles>102</meta:editing-cycles><meta:generator>LibreOfficeDev/24.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/70bf29987ceb90cd3988fc2dfc4cad2a0163fe17</meta:generator><dc:date>2023-10-18T20:11:26.174000000</dc:date><meta:print-date>2023-10-18T20:36:10.265000000</meta:print-date><meta:printed-by>PDF files</meta:printed-by><meta:document-statistic meta:table-count="0" meta:image-count="5" meta:object-count="0" meta:page-count="1" meta:paragraph-count="12" meta:word-count="61" meta:character-count="412" meta:non-whitespace-character-count="347"/><meta:template xlink:type="simple" xlink:actuate="onRequest" xlink:title="+1.Fit_Vorlage_V0.04" xlink:href="../H:/AppData/Local/Microsoft/Windows/INetCache/AppData/Roaming/LibreOffice/4/user/template/SH/+1.Fit_Vorlage_V0.04.ott" meta:date="2020-12-15T11:12:58.522000000"/></office:meta>
+ <office:font-face-decls>
+ <style:font-face style:name="Arial" svg:font-family="Arial" style:font-adornments="Standard" style:font-family-generic="swiss" style:font-pitch="variable"/>
+ <style:font-face style:name="Lucida Sans1" svg:font-family="'Lucida Sans'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="NSimSun" svg:font-family="NSimSun" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Trebuchet MS" svg:font-family="'Trebuchet MS'" style:font-family-generic="swiss"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:writing-mode="lr-tb" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" loext:tab-stop-distance="0cm" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Trebuchet MS" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.249cm" style:writing-mode="lr-tb"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Trebuchet MS" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="no-limit" loext:hyphenation-zone="no-limit"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2"/>
+ <style:text-properties style:font-name="Arial" fo:font-family="Arial" style:font-style-name="Standard" style:font-family-generic="swiss" style:font-pitch="variable"/>
+ </style:style>
+ <style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
+ <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.247cm" style:contextual-spacing="false" fo:line-height="100%"/>
+ </style:style>
+ <style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
+ <style:paragraph-properties fo:margin-top="0.212cm" fo:margin-bottom="0.212cm" style:contextual-spacing="false" text:number-lines="false" text:line-number="0"/>
+ <style:text-properties fo:font-size="10pt"/>
+ </style:style>
+ <style:style style:name="Illustration" style:family="paragraph" style:parent-style-name="Caption" style:class="extra" style:master-page-name="">
+ <style:paragraph-properties style:page-number="auto"/>
+ <style:text-properties fo:font-size="8pt"/>
+ </style:style>
+ <style:style style:name="Line_20_numbering" style:display-name="Line numbering" style:family="text"/>
+ <style:style style:name="Frame" style:family="graphic">
+ <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" fo:margin-left="0.201cm" fo:margin-right="0.201cm" fo:margin-top="0.199cm" fo:margin-bottom="0.499cm" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" fo:background-color="transparent" draw:fill="none" draw:fill-color="#729fcf" fo:padding="0.15cm" fo:border="0.06pt solid #000000" draw:wrap-influence-on-position="once-concurrent" loext:allow-overlap="true">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:graphic-properties>
+ </style:style>
+ <text:outline-style style:name="Outline">
+ <text:outline-level-style text:level="1" loext:num-list-format="%1%" style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="2" loext:num-list-format="%1%.%2%" style:num-format="1" text:display-levels="2">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="3" loext:num-list-format="%1%.%2%.%3%" style:num-format="1" text:display-levels="3">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="4" loext:num-list-format="%1%.%2%.%3%.%4%" style:num-format="1" text:display-levels="4">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="5" loext:num-list-format="%5%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="6" loext:num-list-format="%6%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="7" loext:num-list-format="%7%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="8" loext:num-list-format="%8%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="9" loext:num-list-format="%9%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="10" loext:num-list-format="%10%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ </text:outline-style>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:style-name="Line_20_numbering" text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+ <style:default-page-layout>
+ <style:page-layout-properties style:writing-mode="lr-tb" style:layout-grid-standard-mode="true"/>
+ </style:default-page-layout>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Text_20_body">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P4" style:family="paragraph" style:parent-style-name="Text_20_body">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P5" style:family="paragraph" style:parent-style-name="Text_20_body" style:master-page-name="_2b_1.Fit_5f_ErsteSeite">
+ <style:paragraph-properties style:page-number="auto"/>
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="T6" style:family="text">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="T7" style:family="text">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="T8" style:family="text">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="T9" style:family="text">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="fr3" style:family="graphic" style:parent-style-name="Frame">
+ <style:graphic-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="1cm" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:padding="0cm" fo:border="none"/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="1cm" fo:margin-left="2.499cm" fo:margin-right="1.499cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="44" style:layout-grid-base-height="0.55cm" style:layout-grid-ruby-height="0cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="true" style:layout-grid-display="true" style:layout-grid-base-width="0.37cm" style:layout-grid-snap-to="true" style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ <style:page-layout style:name="pm2">
+ <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="44" style:layout-grid-base-height="0.55cm" style:layout-grid-ruby-height="0cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="true" style:layout-grid-display="true" style:layout-grid-base-width="0.37cm" style:layout-grid-snap-to="true" style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ <style:style style:name="dp1" style:family="drawing-page">
+ <style:drawing-page-properties draw:background-size="full"/>
+ </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1"/>
+ <style:master-page style:name="_2b_1.Fit_5f_ErsteSeite" style:display-name="+1.Fit_ErsteSeite" style:page-layout-name="pm2" draw:style-name="dp1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:sequence-decls>
+ <text:sequence-decl text:display-outline-level="1" text:separation-character="." text:name="Illustration"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+ <text:sequence-decl text:display-outline-level="1" text:separation-character="." text:name="TippNr"/>
+ </text:sequence-decls>
+ <text:p text:style-name="P5"><draw:frame draw:style-name="fr3" draw:name="Rahmen13" text:anchor-type="char" svg:x="5.142cm" svg:y="0.079cm" svg:width="11.829cm" draw:z-index="0">
+ <draw:text-box fo:min-height="9.114cm">
+ <text:p text:style-name="Illustration">Abbildung <text:sequence text:ref-name="refIllustration0" text:name="Illustration" text:formula="ooow:Illustration+1" style:num-format="1">1</text:sequence>: <text:span text:style-name="T7">Haus!</text:span></text:p>
+ </draw:text-box>
+ </draw:frame><text:span text:style-name="T6">Extras </text:span><text:span text:style-name="T8">fdsfsdf dfs sdf dsfsd fs fsd sdfsd fsgf gfhf gfhgfrt fd fdg ddfg dfgd fdfg df dfg <text:s/></text:span></text:p>
+ <text:p text:style-name="P4"><text:span text:style-name="T9">szíj</text:span><text:span text:style-name="T8">fdgdf </text:span><text:span text:style-name="T9">f</text:span><text:span text:style-name="T8">dfg dfg gdfgdfg dggdf fd</text:span></text:p>
+ <text:p text:style-name="P3"><text:span text:style-name="T7">aa</text:span><text:span text:style-name="T9">ds fsdfsd sdf sd fsd sdffsdf</text:span><text:span text:style-name="T7"> </text:span><text:bookmark-ref text:reference-format="chapter" text:ref-name="__RefHeading___Toc1501_2152971747">Error: Reference source not found</text:bookmark-ref><text:bookmark-ref text:reference-format="text" text:ref-name="__RefHeading___Toc1501_2152971747">Error: Reference source not found</text:bookmark-ref><text:s/><text:span text:style-name="T7">bb </text:span><text:span text:style-name="T9">dsfsd sdfsdfsd</text:span>.</text:p>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 192d559f9c74..0849248dce2a 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -1990,6 +1990,395 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf139065)
CPPUNIT_ASSERT_EQUAL(15, pPdfPage->getObjectCount());
}
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf157816)
+{
+ aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+
+ // Enable PDF/UA
+ uno::Sequence<beans::PropertyValue> aFilterData(
+ comphelper::InitPropertySequence({ { "PDFUACompliance", uno::Any(true) } }));
+ aMediaDescriptor["FilterData"] <<= aFilterData;
+ saveAsPDF(u"tdf157816.fodt");
+
+ 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* pDocument(nullptr);
+ for (const auto& rDocElement : aDocument.GetElements())
+ {
+ auto pObject1 = dynamic_cast<vcl::filter::PDFObjectElement*>(rDocElement.get());
+ if (!pObject1)
+ continue;
+ auto pType1 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject1->Lookup("Type"));
+ if (pType1 && pType1->GetValue() == "StructElem")
+ {
+ auto pS1 = dynamic_cast<vcl::filter::PDFNameElement*>(pObject1->Lookup("S"));
+ if (pS1 && pS1->GetValue() == "Document")
+ {
+ pDocument = pObject1;
+ }
+ }
+ }
+ CPPUNIT_ASSERT(pDocument);
+
+ auto pKidsD = dynamic_cast<vcl::filter::PDFArrayElement*>(pDocument->Lookup("K"));
+ CPPUNIT_ASSERT(pKidsD);
+ // assume there are no MCID ref at this level
+ auto pKidsDv = pKidsD->GetElements();
+ auto pRefKidD2 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsDv[2]);
+ CPPUNIT_ASSERT(pRefKidD2);
+ auto pObjectD2 = pRefKidD2->LookupObject();
+ CPPUNIT_ASSERT(pObjectD2);
+ auto pTypeD2 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD2->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeD2->GetValue());
+ auto pSD2 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD2->Lookup("S"));
+ CPPUNIT_ASSERT_EQUAL(OString("Text#20body"), pSD2->GetValue());
+
+ auto pKidsD2 = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD2->Lookup("K"));
+ CPPUNIT_ASSERT(pKidsD2);
+ auto pKidsD2v = pKidsD2->GetElements();
+ auto pRefKidD20 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[0]);
+ // MCID for text
+ CPPUNIT_ASSERT(!pRefKidD20);
+ auto pRefKidD21 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[1]);
+ // MCID for text
+ CPPUNIT_ASSERT(!pRefKidD21);
+
+ auto pRefKidD22 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[2]);
+ CPPUNIT_ASSERT(pRefKidD22);
+ auto pObjectD22 = pRefKidD22->LookupObject();
+ CPPUNIT_ASSERT(pObjectD22);
+ auto pTypeD22 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD22->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeD22->GetValue());
+ auto pSD22 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD22->Lookup("S"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pSD22->GetValue());
+ {
+ auto pKids = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD22->Lookup("K"));
+ auto nMCID(0);
+ auto nRef(0);
+ for (size_t i = 0; i < pKids->GetElements().size(); ++i)
+ {
+ auto pNum = dynamic_cast<vcl::filter::PDFNumberElement*>(pKids->GetElement(i));
+ auto pRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKids->GetElement(i));
+ if (pNum)
+ {
+ ++nMCID;
+ }
+ if (pRef)
+ {
+ ++nRef;
+ auto pObjR = pRef->LookupObject();
+ auto pOType = dynamic_cast<vcl::filter::PDFNameElement*>(pObjR->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("OBJR"), pOType->GetValue());
+ auto pAnnotRef
+ = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObjR->Lookup("Obj"));
+ auto pAnnot = pAnnotRef->LookupObject();
+ auto pAType = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("Annot"), pAType->GetValue());
+ auto pASubtype
+ = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pASubtype->GetValue());
+ auto pAContents
+ = dynamic_cast<vcl::filter::PDFHexStringElement*>(pAnnot->Lookup("Contents"));
+ CPPUNIT_ASSERT_EQUAL(
+ u"Error: Reference source not found"_ustr,
+ ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pAContents));
+ auto pStructParent
+ = dynamic_cast<vcl::filter::PDFNumberElement*>(pAnnot->Lookup("StructParent"));
+ CPPUNIT_ASSERT(pStructParent); // every link must have it!
+ auto pARect = dynamic_cast<vcl::filter::PDFArrayElement*>(pAnnot->Lookup("Rect"));
+ CPPUNIT_ASSERT(pARect);
+ const auto& rElements = pARect->GetElements();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rElements.size());
+ const auto* pNumL = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[0]);
+ CPPUNIT_ASSERT(pNumL);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(95.143, pNumL->GetValue(), 1e-3);
+ const auto* pNumT = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[1]);
+ CPPUNIT_ASSERT(pNumT);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(674.589, pNumT->GetValue(), 1e-3);
+ const auto* pNumR = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[2]);
+ CPPUNIT_ASSERT(pNumR);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(202.457, pNumR->GetValue(), 1e-3);
+ const auto* pNumB = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[3]);
+ CPPUNIT_ASSERT(pNumB);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(688.389, pNumB->GetValue(), 1e-3);
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nMCID)>(1), nMCID);
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nRef)>(1), nRef);
+ }
+
+ auto pRefKidD23 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[3]);
+ CPPUNIT_ASSERT(pRefKidD23);
+ auto pObjectD23 = pRefKidD23->LookupObject();
+ CPPUNIT_ASSERT(pObjectD23);
+ auto pTypeD23 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD23->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeD23->GetValue());
+ auto pSD23 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD23->Lookup("S"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pSD23->GetValue());
+ {
+ auto pKids = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD23->Lookup("K"));
+ auto nMCID(0);
+ auto nRef(0);
+ for (size_t i = 0; i < pKids->GetElements().size(); ++i)
+ {
+ auto pNum = dynamic_cast<vcl::filter::PDFNumberElement*>(pKids->GetElement(i));
+ auto pRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKids->GetElement(i));
+ if (pNum)
+ {
+ ++nMCID;
+ }
+ if (pRef)
+ {
+ ++nRef;
+ auto pObjR = pRef->LookupObject();
+ auto pOType = dynamic_cast<vcl::filter::PDFNameElement*>(pObjR->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("OBJR"), pOType->GetValue());
+ auto pAnnotRef
+ = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObjR->Lookup("Obj"));
+ auto pAnnot = pAnnotRef->LookupObject();
+ auto pAType = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("Annot"), pAType->GetValue());
+ auto pASubtype
+ = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pASubtype->GetValue());
+ auto pAContents
+ = dynamic_cast<vcl::filter::PDFHexStringElement*>(pAnnot->Lookup("Contents"));
+ CPPUNIT_ASSERT_EQUAL(
+ u"Error: Reference source not found"_ustr,
+ ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pAContents));
+ auto pStructParent
+ = dynamic_cast<vcl::filter::PDFNumberElement*>(pAnnot->Lookup("StructParent"));
+ CPPUNIT_ASSERT(pStructParent); // every link must have it!
+ auto pARect = dynamic_cast<vcl::filter::PDFArrayElement*>(pAnnot->Lookup("Rect"));
+ CPPUNIT_ASSERT(pARect);
+ const auto& rElements = pARect->GetElements();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rElements.size());
+ const auto* pNumL = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[0]);
+ CPPUNIT_ASSERT(pNumL);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(56.693, pNumL->GetValue(), 1e-3);
+ const auto* pNumT = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[1]);
+ CPPUNIT_ASSERT(pNumT);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(660.789, pNumT->GetValue(), 1e-3);
+ const auto* pNumR = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[2]);
+ CPPUNIT_ASSERT(pNumR);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(146.157, pNumR->GetValue(), 1e-3);
+ const auto* pNumB = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[3]);
+ CPPUNIT_ASSERT(pNumB);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(674.589, pNumB->GetValue(), 1e-3);
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nMCID)>(1), nMCID);
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nRef)>(1), nRef);
+ }
+
+ auto pRefKidD24 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[4]);
+ CPPUNIT_ASSERT(pRefKidD24);
+ auto pObjectD24 = pRefKidD24->LookupObject();
+ CPPUNIT_ASSERT(pObjectD24);
+ auto pTypeD24 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD24->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeD24->GetValue());
+ auto pSD24 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD24->Lookup("S"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pSD24->GetValue());
+ {
+ auto pKids = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD24->Lookup("K"));
+ auto nMCID(0);
+ auto nRef(0);
+ for (size_t i = 0; i < pKids->GetElements().size(); ++i)
+ {
+ auto pNum = dynamic_cast<vcl::filter::PDFNumberElement*>(pKids->GetElement(i));
+ auto pRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKids->GetElement(i));
+ if (pNum)
+ {
+ ++nMCID;
+ }
+ if (pRef)
+ {
+ ++nRef;
+ auto pObjR = pRef->LookupObject();
+ auto pOType = dynamic_cast<vcl::filter::PDFNameElement*>(pObjR->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("OBJR"), pOType->GetValue());
+ auto pAnnotRef
+ = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObjR->Lookup("Obj"));
+ auto pAnnot = pAnnotRef->LookupObject();
+ auto pAType = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("Annot"), pAType->GetValue());
+ auto pASubtype
+ = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pASubtype->GetValue());
+ auto pAContents
+ = dynamic_cast<vcl::filter::PDFHexStringElement*>(pAnnot->Lookup("Contents"));
+ CPPUNIT_ASSERT_EQUAL(
+ u"Error: Reference source not found"_ustr,
+ ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pAContents));
+ auto pStructParent
+ = dynamic_cast<vcl::filter::PDFNumberElement*>(pAnnot->Lookup("StructParent"));
+ CPPUNIT_ASSERT(pStructParent); // every link must have it!
+ auto pARect = dynamic_cast<vcl::filter::PDFArrayElement*>(pAnnot->Lookup("Rect"));
+ CPPUNIT_ASSERT(pARect);
+ const auto& rElements = pARect->GetElements();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rElements.size());
+ const auto* pNumL = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[0]);
+ CPPUNIT_ASSERT(pNumL);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(146.093, pNumL->GetValue(), 1e-3);
+ const auto* pNumT = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[1]);
+ CPPUNIT_ASSERT(pNumT);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(660.789, pNumT->GetValue(), 1e-3);
+ const auto* pNumR = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[2]);
+ CPPUNIT_ASSERT(pNumR);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(202.457, pNumR->GetValue(), 1e-3);
+ const auto* pNumB = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[3]);
+ CPPUNIT_ASSERT(pNumB);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(674.589, pNumB->GetValue(), 1e-3);
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nMCID)>(1), nMCID);
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nRef)>(1), nRef);
+ }
+
+ auto pRefKidD25 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[5]);
+ CPPUNIT_ASSERT(pRefKidD25);
+ auto pObjectD25 = pRefKidD25->LookupObject();
+ CPPUNIT_ASSERT(pObjectD25);
+ auto pTypeD25 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD25->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeD25->GetValue());
+ auto pSD25 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD25->Lookup("S"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pSD25->GetValue());
+ {
+ auto pKids = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD25->Lookup("K"));
+ auto nMCID(0);
+ auto nRef(0);
+ for (size_t i = 0; i < pKids->GetElements().size(); ++i)
+ {
+ auto pNum = dynamic_cast<vcl::filter::PDFNumberElement*>(pKids->GetElement(i));
+ auto pRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKids->GetElement(i));
+ if (pNum)
+ {
+ ++nMCID;
+ }
+ if (pRef)
+ {
+ ++nRef;
+ auto pObjR = pRef->LookupObject();
+ auto pOType = dynamic_cast<vcl::filter::PDFNameElement*>(pObjR->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("OBJR"), pOType->GetValue());
+ auto pAnnotRef
+ = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObjR->Lookup("Obj"));
+ auto pAnnot = pAnnotRef->LookupObject();
+ auto pAType = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("Annot"), pAType->GetValue());
+ auto pASubtype
+ = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pASubtype->GetValue());
+ auto pAContents
+ = dynamic_cast<vcl::filter::PDFHexStringElement*>(pAnnot->Lookup("Contents"));
+ CPPUNIT_ASSERT_EQUAL(
+ u"Error: Reference source not found"_ustr,
+ ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pAContents));
+ auto pStructParent
+ = dynamic_cast<vcl::filter::PDFNumberElement*>(pAnnot->Lookup("StructParent"));
+ CPPUNIT_ASSERT(pStructParent); // every link must have it!
+ auto pARect = dynamic_cast<vcl::filter::PDFArrayElement*>(pAnnot->Lookup("Rect"));
+ CPPUNIT_ASSERT(pARect);
+ const auto& rElements = pARect->GetElements();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rElements.size());
+ const auto* pNumL = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[0]);
+ CPPUNIT_ASSERT(pNumL);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(56.693, pNumL->GetValue(), 1e-3);
+ const auto* pNumT = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[1]);
+ CPPUNIT_ASSERT(pNumT);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(646.989, pNumT->GetValue(), 1e-3);
+ const auto* pNumR = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[2]);
+ CPPUNIT_ASSERT(pNumR);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(202.457, pNumR->GetValue(), 1e-3);
+ const auto* pNumB = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[3]);
+ CPPUNIT_ASSERT(pNumB);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(660.789, pNumB->GetValue(), 1e-3);
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nMCID)>(1), nMCID);
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nRef)>(1), nRef);
+ }
+
+ auto pRefKidD26 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[6]);
+ CPPUNIT_ASSERT(pRefKidD26);
+ auto pObjectD26 = pRefKidD26->LookupObject();
+ CPPUNIT_ASSERT(pObjectD26);
+ auto pTypeD26 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD26->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeD26->GetValue());
+ auto pSD26 = dynamic_cast<vcl::filter::PDFNameElement*>(pObjectD26->Lookup("S"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pSD26->GetValue());
+ {
+ auto pKids = dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectD26->Lookup("K"));
+ auto nMCID(0);
+ auto nRef(0);
+ for (size_t i = 0; i < pKids->GetElements().size(); ++i)
+ {
+ auto pNum = dynamic_cast<vcl::filter::PDFNumberElement*>(pKids->GetElement(i));
+ auto pRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKids->GetElement(i));
+ if (pNum)
+ {
+ ++nMCID;
+ }
+ if (pRef)
+ {
+ ++nRef;
+ auto pObjR = pRef->LookupObject();
+ auto pOType = dynamic_cast<vcl::filter::PDFNameElement*>(pObjR->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("OBJR"), pOType->GetValue());
+ auto pAnnotRef
+ = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObjR->Lookup("Obj"));
+ auto pAnnot = pAnnotRef->LookupObject();
+ auto pAType = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"));
+ CPPUNIT_ASSERT_EQUAL(OString("Annot"), pAType->GetValue());
+ auto pASubtype
+ = dynamic_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"));
+ CPPUNIT_ASSERT_EQUAL(OString("Link"), pASubtype->GetValue());
+ auto pAContents
+ = dynamic_cast<vcl::filter::PDFHexStringElement*>(pAnnot->Lookup("Contents"));
+ CPPUNIT_ASSERT_EQUAL(
+ u"Error: Reference source not found"_ustr,
+ ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pAContents));
+ auto pStructParent
+ = dynamic_cast<vcl::filter::PDFNumberElement*>(pAnnot->Lookup("StructParent"));
+ CPPUNIT_ASSERT(pStructParent); // every link must have it!
+ auto pARect = dynamic_cast<vcl::filter::PDFArrayElement*>(pAnnot->Lookup("Rect"));
+ CPPUNIT_ASSERT(pARect);
+ const auto& rElements = pARect->GetElements();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rElements.size());
+ const auto* pNumL = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[0]);
+ CPPUNIT_ASSERT(pNumL);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(56.693, pNumL->GetValue(), 1e-3);
+ const auto* pNumT = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[1]);
+ CPPUNIT_ASSERT(pNumT);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(633.189, pNumT->GetValue(), 1e-3);
+ const auto* pNumR = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[2]);
+ CPPUNIT_ASSERT(pNumR);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(86.807, pNumR->GetValue(), 1e-3);
+ const auto* pNumB = dynamic_cast<vcl::filter::PDFNumberElement*>(rElements[3]);
+ CPPUNIT_ASSERT(pNumB);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(646.989, pNumB->GetValue(), 1e-3);
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nMCID)>(1), nMCID);
+ CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nRef)>(1), nRef);
+ }
+
+ auto pRefKidD27 = dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsD2v[7]);
+ // MCID for text
+ CPPUNIT_ASSERT(!pRefKidD27);
+
+ // the problem was that in addition to the 5 links with SE there were 3 more
+ auto pAnnots = dynamic_cast<vcl::filter::PDFArrayElement*>(aPages[0]->Lookup("Annots"));
+ CPPUNIT_ASSERT(pAnnots);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(5), pAnnots->GetElements().size());
+}
+
CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf115967)
{
aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");