diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2023-10-27 18:00:14 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2023-11-02 10:46:30 +0100 |
commit | 6593d680e21c24501a58bac216de4a7c71541959 (patch) | |
tree | 6b40e10943607ca2147a7f77a5c84ab34d660af2 | |
parent | 468e5b8e0a7fefe1ca53faeb15f5f6527c37a268 (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.cxx | 38 | ||||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/data/tdf157816.fodt | 175 | ||||
-rw-r--r-- | vcl/qa/cppunit/pdfexport/pdfexport.cxx | 389 |
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"); |