sw/source/core/text/EnhancedPDFExportHelper.cxx |   13 
 vcl/qa/cppunit/pdfexport/data/SimpleTOC.fodt    |  323 ++++++++++++++++++++++++
 vcl/qa/cppunit/pdfexport/pdfexport.cxx          |  128 +++++++++
 3 files changed, 463 insertions(+), 1 deletion(-)

New commits:
commit a5851d0a6fdc3e08e93daf8cf0ae7f6fc2d73ef6
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Oct 20 20:03:11 2023 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Oct 24 14:25:43 2023 +0200

    tdf#157817 sw: PDF/UA export: fix ToX header sections
    
    The problem was that a P or equivalent element is not allowed as child
    of a TOC; previously the P was outside/before the TOC because the ToX
    header was completely ignored but now it starts a SE for the ToC content
    section before being ignored.
    
    Tagged PDF Best Practice Guide suggests putting the header inside a
    Caption element.
    
    Another problem is that if the ToX header is on one page but the first
    entry in the ToX content section is on the next page, BeginTag() created
    a new SE for the ToX content section.
    
    (regression from commit 033e37b49b5712df19dbfd2c307a102bce620de1)
    
    Change-Id: I3c1f8fdda81c1f10198f5eaefc10bcd14f277a8b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158298
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx 
b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 46f8e1d07f84..ff47a693769f 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -523,6 +523,7 @@ void SwTaggedPDFHelper::BeginTag( 
vcl::PDFWriter::StructElement eType, const OUS
 
         if ( ( rFrame.IsPageFrame() && !static_cast<const 
SwPageFrame&>(rFrame).GetPrev() ) ||
              ( rFrame.IsFlowFrame() && 
!SwFlowFrame::CastFlowFrame(&rFrame)->IsFollow() && 
SwFlowFrame::CastFlowFrame(&rFrame)->HasFollow() ) ||
+             rFrame.IsSctFrame() || // all of them, so that opening parent 
sections works
              ( rFrame.IsTextFrame() && rFrame.GetDrawObjs() ) ||
              (rFrame.IsFootnoteFrame() && static_cast<SwFootnoteFrame 
const&>(rFrame).GetFollow()) ||
              ( rFrame.IsRowFrame() && rFrame.IsInSplitTableRow() ) ||
@@ -664,6 +665,12 @@ void SwTaggedPDFHelper::SetAttributes( 
vcl::PDFWriter::StructElement eType )
                 bRowSpan = true;
                 break;
 
+            case vcl::PDFWriter::Caption:
+                if (pFrame->IsSctFrame())
+                {
+                    break;
+                }
+                [[fallthrough]];
             case vcl::PDFWriter::H1 :
             case vcl::PDFWriter::H2 :
             case vcl::PDFWriter::H3 :
@@ -672,7 +679,6 @@ void SwTaggedPDFHelper::SetAttributes( 
vcl::PDFWriter::StructElement eType )
             case vcl::PDFWriter::H6 :
             case vcl::PDFWriter::Paragraph :
             case vcl::PDFWriter::Heading :
-            case vcl::PDFWriter::Caption :
             case vcl::PDFWriter::BlockQuote :
 
                 bPlacement =
@@ -1270,6 +1276,11 @@ void SwTaggedPDFHelper::BeginBlockStructureElements()
                     OpenTagImpl(pSection);
                     break;
                 }
+                else if (SectionType::ToxHeader == pSection->GetType())
+                {
+                    nPDFType = vcl::PDFWriter::Caption;
+                    aPDFType = aCaptionString;
+                }
                 else if (SectionType::ToxContent == pSection->GetType())
                 {
                     const SwTOXBase* pTOXBase = pSection->GetTOXBase();
diff --git a/vcl/qa/cppunit/pdfexport/data/SimpleTOC.fodt 
b/vcl/qa/cppunit/pdfexport/data/SimpleTOC.fodt
new file mode 100644
index 000000000000..6e7e88ffe9bc
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/SimpleTOC.fodt
@@ -0,0 +1,323 @@
+<?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:c
 alcext="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:initial-creator>Gabor 
LO-Dev</meta:initial-creator><meta:creation-date>2023-10-18T22:16:34.201000000</meta:creation-date><dc:date>2023-10-18T22:23:10.997000000</dc:date><dc:creator>Gabor
 
LO-Dev</dc:creator><meta:editing-duration>PT6M37S</meta:editing-duration><meta:editing-cycles>5</meta:editing-cycles><meta:generator>LibreOfficeDev/24.2.0.0.alpha0$Linux_X86_64
 
LibreOffice_project/0080580e754a3a080ae0b914945368307d5c29fe</meta:generator><meta:print-date>2023-10-18T22:22:25.716000000</meta:print-date><meta:printed-by>PDF
 files: Gabor 
LO-Dev</meta:printed-by><dc:title>Multipage-TOC</dc:title><meta:document-statistic
 meta:table-count="0" meta:image-count="0" meta:object-count="0" 
meta:page-count="2" meta:paragraph-count="10" meta:word-count="245" 
meta:character-count="1660" 
meta:non-whitespace-character-count="1425"/></office:meta>
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Sans" svg:font-family="'Liberation 
Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/>
+  <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation 
Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+  <style:font-face style:name="Lucida Sans" svg:font-family="'Lucida Sans'" 
style:font-family-generic="swiss"/>
+  <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="Microsoft YaHei" svg:font-family="'Microsoft 
YaHei'" 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"/>
+ </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="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="US" 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.251cm" style:writing-mode="page"/>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="US" 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="5" 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:style style:name="Heading" style:family="paragraph" 
style:parent-style-name="Standard" style:next-style-name="Text_20_body" 
style:class="text">
+   <style:paragraph-properties fo:margin-top="0.423cm" 
fo:margin-bottom="0.212cm" style:contextual-spacing="false" 
fo:keep-with-next="always"/>
+   <style:text-properties style:font-name="Liberation Sans" 
fo:font-family="'Liberation Sans'" style:font-family-generic="swiss" 
style:font-pitch="variable" fo:font-size="14pt" 
style:font-name-asian="Microsoft YaHei" style:font-family-asian="'Microsoft 
YaHei'" style:font-family-generic-asian="system" 
style:font-pitch-asian="variable" style:font-size-asian="14pt" 
style:font-name-complex="Lucida Sans1" style:font-family-complex="'Lucida 
Sans'" style:font-family-generic-complex="system" 
style:font-pitch-complex="variable" style:font-size-complex="14pt"/>
+  </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="115%"/>
+  </style:style>
+  <style:style style:name="Index" style:family="paragraph" 
style:parent-style-name="Standard" style:class="index">
+   <style:paragraph-properties text:number-lines="false" text:line-number="0"/>
+   <style:text-properties style:font-size-asian="12pt" 
style:font-name-complex="Lucida Sans" style:font-family-complex="'Lucida Sans'" 
style:font-family-generic-complex="swiss"/>
+  </style:style>
+  <style:style style:name="Heading_20_3" style:display-name="Heading 3" 
style:family="paragraph" style:parent-style-name="Heading" 
style:next-style-name="Text_20_body" style:default-outline-level="3" 
style:class="text">
+   <style:paragraph-properties fo:margin-top="0.247cm" 
fo:margin-bottom="0.212cm" style:contextual-spacing="false"/>
+   <style:text-properties fo:font-size="14pt" fo:font-weight="bold" 
style:font-size-asian="14pt" style:font-weight-asian="bold" 
style:font-size-complex="14pt" style:font-weight-complex="bold"/>
+  </style:style>
+  <style:style style:name="Heading_20_2" style:display-name="Heading 2" 
style:family="paragraph" style:parent-style-name="Heading" 
style:next-style-name="Text_20_body" style:default-outline-level="2" 
style:class="text">
+   <style:paragraph-properties fo:margin-top="0.353cm" 
fo:margin-bottom="0.212cm" style:contextual-spacing="false"/>
+   <style:text-properties fo:font-size="16pt" fo:font-weight="bold" 
style:font-size-asian="16pt" style:font-weight-asian="bold" 
style:font-size-complex="16pt" style:font-weight-complex="bold"/>
+  </style:style>
+  <style:style style:name="Heading_20_1" style:display-name="Heading 1" 
style:family="paragraph" style:parent-style-name="Heading" 
style:next-style-name="Text_20_body" style:default-outline-level="1" 
style:class="text">
+   <style:paragraph-properties fo:margin-top="0.423cm" 
fo:margin-bottom="0.212cm" style:contextual-spacing="false"/>
+   <style:text-properties fo:font-size="18pt" fo:font-weight="bold" 
style:font-size-asian="18pt" style:font-weight-asian="bold" 
style:font-size-complex="18pt" style:font-weight-complex="bold"/>
+  </style:style>
+  <style:style style:name="Index_20_Heading" style:display-name="Index 
Heading" style:family="paragraph" style:parent-style-name="Heading" 
style:class="index">
+   <style:paragraph-properties fo:margin-left="0cm" fo:text-indent="0cm" 
style:auto-text-indent="false" text:number-lines="false" text:line-number="0"/>
+   <style:text-properties fo:font-size="16pt" fo:font-weight="bold" 
style:font-size-asian="16pt" style:font-weight-asian="bold" 
style:font-size-complex="16pt" style:font-weight-complex="bold"/>
+  </style:style>
+  <style:style style:name="Contents_20_Heading" style:display-name="Contents 
Heading" style:family="paragraph" style:parent-style-name="Index_20_Heading" 
style:class="index">
+   <style:paragraph-properties fo:margin-left="0cm" fo:text-indent="0cm" 
style:auto-text-indent="false" text:number-lines="false" text:line-number="0"/>
+   <style:text-properties fo:font-size="16pt" fo:font-weight="bold" 
style:font-size-asian="16pt" style:font-weight-asian="bold" 
style:font-size-complex="16pt" style:font-weight-complex="bold"/>
+  </style:style>
+  <style:style style:name="Contents_20_1" style:display-name="Contents 1" 
style:family="paragraph" style:parent-style-name="Index" style:class="index">
+   <style:paragraph-properties fo:margin-left="0cm" fo:text-indent="0cm" 
style:auto-text-indent="false">
+    <style:tab-stops>
+     <style:tab-stop style:position="17.59cm" style:type="right" 
style:leader-style="dotted" style:leader-text="."/>
+    </style:tab-stops>
+   </style:paragraph-properties>
+  </style:style>
+  <style:style style:name="Contents_20_2" style:display-name="Contents 2" 
style:family="paragraph" style:parent-style-name="Index" style:class="index">
+   <style:paragraph-properties fo:margin-left="0.499cm" fo:text-indent="0cm" 
style:auto-text-indent="false">
+    <style:tab-stops>
+     <style:tab-stop style:position="17.09cm" style:type="right" 
style:leader-style="dotted" style:leader-text="."/>
+    </style:tab-stops>
+   </style:paragraph-properties>
+  </style:style>
+  <style:style style:name="Contents_20_3" style:display-name="Contents 3" 
style:family="paragraph" style:parent-style-name="Index" style:class="index">
+   <style:paragraph-properties fo:margin-left="1cm" fo:text-indent="0cm" 
style:auto-text-indent="false">
+    <style:tab-stops>
+     <style:tab-stop style:position="16.589cm" style:type="right" 
style:leader-style="dotted" style:leader-text="."/>
+    </style:tab-stops>
+   </style:paragraph-properties>
+  </style:style>
+  <style:style style:name="Index_20_Link" style:display-name="Index Link" 
style:family="text"/>
+  <text:outline-style style:name="Outline">
+   <text:outline-level-style text:level="1" loext:num-list-format="%1%" 
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="2" loext:num-list-format="%2%" 
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="3" loext:num-list-format="%3%" 
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="4" loext:num-list-format="%4%" 
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="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:number-lines="false" 
text:offset="0.499cm" style:num-format="1" text:number-position="left" 
text:increment="5"/>
+  </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Contents_20_1">
+   <style:paragraph-properties>
+    <style:tab-stops>
+     <style:tab-stop style:position="17.59cm" style:type="right" 
style:leader-style="dotted" style:leader-text="."/>
+    </style:tab-stops>
+   </style:paragraph-properties>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph" 
style:parent-style-name="Contents_20_2">
+   <style:paragraph-properties>
+    <style:tab-stops>
+     <style:tab-stop style:position="17.09cm" style:type="right" 
style:leader-style="dotted" style:leader-text="."/>
+    </style:tab-stops>
+   </style:paragraph-properties>
+  </style:style>
+  <style:style style:name="P3" style:family="paragraph" 
style:parent-style-name="Contents_20_3">
+   <style:paragraph-properties>
+    <style:tab-stops>
+     <style:tab-stop style:position="16.589cm" style:type="right" 
style:leader-style="dotted" style:leader-text="."/>
+    </style:tab-stops>
+   </style:paragraph-properties>
+  </style:style>
+  <style:style style:name="P4" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties/>
+  </style:style>
+  <style:style style:name="P5" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties/>
+  </style:style>
+  <style:style style:name="P6" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties/>
+  </style:style>
+  <style:style style:name="P7" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties/>
+  </style:style>
+  <style:style style:name="Sect1" style:family="section">
+   <style:section-properties style:editable="false">
+    <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+   </style:section-properties>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="21.59cm" 
fo:page-height="27.94cm" 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="20" 
style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" 
style:layout-grid-mode="none" style:layout-grid-ruby-below="false" 
style:layout-grid-print="false" style:layout-grid-display="false" 
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"/>
+  </office:master-styles>
+ <office:body>
+  <office:text text:use-soft-page-breaks="true">
+   <text:sequence-decls>
+    <text:sequence-decl text:display-outline-level="0" 
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-decls>
+   <text:h text:style-name="Heading_20_1" 
text:outline-level="1"><text:bookmark-start 
text:name="__RefHeading___Toc1_3097472582"/>One<text:bookmark-end 
text:name="__RefHeading___Toc1_3097472582"/></text:h>
+   <text:p text:style-name="P4">Lorem ipsum dolor sit amet, consectetur 
adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci 
ac neque venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis 
cursus egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. 
In consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, 
non pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus 
semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce 
pellentesque est orci.</text:p>
+   <text:h text:style-name="Heading_20_2" 
text:outline-level="2"><text:bookmark-start 
text:name="__RefHeading___Toc3_3097472582"/>Two<text:bookmark-end 
text:name="__RefHeading___Toc3_3097472582"/></text:h>
+   <text:p text:style-name="P4">Integer sodales tincidunt tristique. Sed a 
metus posuere, adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit 
amet tristique lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. 
Nunc eget dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate 
lobortis mollis. Vivamus nec tellus faucibus, tempor magna nec, facilisis 
felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum 
est vel ultricies.</text:p>
+   <text:h text:style-name="Heading_20_3" 
text:outline-level="3"><text:bookmark-start 
text:name="__RefHeading___Toc5_3097472582"/>Three<text:bookmark-end 
text:name="__RefHeading___Toc5_3097472582"/></text:h>
+   <text:p text:style-name="P7">Aliquam velit massa, laoreet vel leo nec, 
volutpat facilisis eros. Donec consequat arcu ut diam tempor luctus. Cum sociis 
natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. 
Praesent vitae lacus vel leo sodales pharetra a a nibh. Vestibulum ante ipsum 
primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam luctus 
tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit 
amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu 
sollicitudin molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed 
ante. Donec nec est elementum, euismod nulla in, mollis nunc.</text:p>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:p text:style-name="P6"/>
+   <text:table-of-content text:style-name="Sect1" text:name="Table of 
Contents1">
+    <text:table-of-content-source text:outline-level="10">
+     <text:index-title-template text:style-name="Contents_20_Heading">Table of 
Contents</text:index-title-template>
+     <text:table-of-content-entry-template text:outline-level="1" 
text:style-name="Contents_20_1">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="2" 
text:style-name="Contents_20_2">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="3" 
text:style-name="Contents_20_3">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="4" 
text:style-name="Contents_20_4">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="5" 
text:style-name="Contents_20_5">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="6" 
text:style-name="Contents_20_6">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="7" 
text:style-name="Contents_20_7">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="8" 
text:style-name="Contents_20_8">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="9" 
text:style-name="Contents_20_9">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+     <text:table-of-content-entry-template text:outline-level="10" 
text:style-name="Contents_20_10">
+      <text:index-entry-link-start text:style-name="Index_20_Link"/>
+      <text:index-entry-chapter/>
+      <text:index-entry-text/>
+      <text:index-entry-tab-stop style:type="right" style:leader-char="."/>
+      <text:index-entry-page-number/>
+      <text:index-entry-link-end/>
+     </text:table-of-content-entry-template>
+    </text:table-of-content-source>
+    <text:index-body>
+     <text:index-title text:style-name="Sect1" text:name="Table of 
Contents1_Head">
+      <text:p text:style-name="Contents_20_Heading">Table of Contents</text:p>
+     </text:index-title>
+     <text:p text:style-name="P1"><text:a xlink:type="simple" 
xlink:href="#__RefHeading___Toc1_3097472582" text:style-name="Index_20_Link" 
text:visited-style-name="Index_20_Link">One<text:tab/>1</text:a></text:p>
+     <text:p text:style-name="P2"><text:a xlink:type="simple" 
xlink:href="#__RefHeading___Toc3_3097472582" text:style-name="Index_20_Link" 
text:visited-style-name="Index_20_Link">Two<text:tab/>1</text:a></text:p>
+     <text:p text:style-name="P3"><text:a xlink:type="simple" 
xlink:href="#__RefHeading___Toc5_3097472582" text:style-name="Index_20_Link" 
text:visited-style-name="Index_20_Link"><text:soft-page-break/>Three<text:tab/>1</text:a></text:p>
+    </text:index-body>
+   </text:table-of-content>
+   <text:p text:style-name="P5"/>
+  </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 c4158552677d..e0fd6f1e9ec2 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -3638,6 +3638,134 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testNestedSection)
     CPPUNIT_ASSERT_EQUAL(static_cast<decltype(nDoc)>(1), nDoc);
 }
 
+CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf157817)
+{
+    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"SimpleTOC.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>(2), aPages.size());
+
+    vcl::filter::PDFObjectElement* pTOC(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() == "TOC")
+            {
+                pTOC = pObject1;
+            }
+        }
+    }
+    CPPUNIT_ASSERT(pTOC);
+
+    auto pKidsT = 
dynamic_cast<vcl::filter::PDFArrayElement*>(pTOC->Lookup("K"));
+    CPPUNIT_ASSERT(pKidsT);
+    // assume there are no MCID ref at this level
+    auto pKidsTv = pKidsT->GetElements();
+    auto pRefKidT0 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsTv[0]);
+    CPPUNIT_ASSERT(pRefKidT0);
+    auto pObjectT0 = pRefKidT0->LookupObject();
+    CPPUNIT_ASSERT(pObjectT0);
+    auto pTypeT0 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT0->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT0->GetValue());
+    auto pST0 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT0->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("Caption"), pST0->GetValue());
+
+    auto pKidsT0 = 
dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectT0->Lookup("K"));
+    CPPUNIT_ASSERT(pKidsT0);
+    auto pKidsT0v = pKidsT0->GetElements();
+    auto pRefKidT00 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsT0v[0]);
+    CPPUNIT_ASSERT(pRefKidT00);
+    auto pObjectT00 = pRefKidT00->LookupObject();
+    CPPUNIT_ASSERT(pObjectT00);
+    auto pTypeT00 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT00->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT00->GetValue());
+    auto pST00 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT00->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("Contents#20Heading"), pST00->GetValue());
+
+    auto pRefKidT1 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsTv[1]);
+    CPPUNIT_ASSERT(pRefKidT1);
+    auto pObjectT1 = pRefKidT1->LookupObject();
+    CPPUNIT_ASSERT(pObjectT1);
+    auto pTypeT1 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT1->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT1->GetValue());
+    auto pST1 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT1->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("TOCI"), pST1->GetValue());
+
+    auto pKidsT1 = 
dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectT1->Lookup("K"));
+    CPPUNIT_ASSERT(pKidsT1);
+    auto pKidsT1v = pKidsT1->GetElements();
+
+    auto pRefKidT10 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsT1v[0]);
+    CPPUNIT_ASSERT(pRefKidT10);
+    auto pObjectT10 = pRefKidT10->LookupObject();
+    CPPUNIT_ASSERT(pObjectT10);
+    auto pTypeT10 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT10->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT10->GetValue());
+    auto pST10 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT10->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("Contents#201"), pST10->GetValue());
+
+    auto pRefKidT2 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsTv[1]);
+    CPPUNIT_ASSERT(pRefKidT2);
+    auto pObjectT2 = pRefKidT2->LookupObject();
+    CPPUNIT_ASSERT(pObjectT2);
+    auto pTypeT2 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT2->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT2->GetValue());
+    auto pST2 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT2->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("TOCI"), pST2->GetValue());
+
+    auto pKidsT2 = 
dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectT2->Lookup("K"));
+    CPPUNIT_ASSERT(pKidsT2);
+    auto pKidsT2v = pKidsT2->GetElements();
+
+    auto pRefKidT20 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsT2v[0]);
+    CPPUNIT_ASSERT(pRefKidT20);
+    auto pObjectT20 = pRefKidT20->LookupObject();
+    CPPUNIT_ASSERT(pObjectT20);
+    auto pTypeT20 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT20->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT20->GetValue());
+    auto pST20 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT20->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("Contents#201"), pST20->GetValue());
+
+    auto pRefKidT3 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsTv[1]);
+    CPPUNIT_ASSERT(pRefKidT3);
+    auto pObjectT3 = pRefKidT3->LookupObject();
+    CPPUNIT_ASSERT(pObjectT3);
+    auto pTypeT3 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT3->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT3->GetValue());
+    auto pST3 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT3->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("TOCI"), pST3->GetValue());
+
+    auto pKidsT3 = 
dynamic_cast<vcl::filter::PDFArrayElement*>(pObjectT3->Lookup("K"));
+    CPPUNIT_ASSERT(pKidsT3);
+    auto pKidsT3v = pKidsT3->GetElements();
+
+    auto pRefKidT30 = 
dynamic_cast<vcl::filter::PDFReferenceElement*>(pKidsT3v[0]);
+    CPPUNIT_ASSERT(pRefKidT30);
+    auto pObjectT30 = pRefKidT30->LookupObject();
+    CPPUNIT_ASSERT(pObjectT30);
+    auto pTypeT30 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT30->Lookup("Type"));
+    CPPUNIT_ASSERT_EQUAL(OString("StructElem"), pTypeT30->GetValue());
+    auto pST30 = 
dynamic_cast<vcl::filter::PDFNameElement*>(pObjectT30->Lookup("S"));
+    CPPUNIT_ASSERT_EQUAL(OString("Contents#201"), pST30->GetValue());
+}
+
 CPPUNIT_TEST_FIXTURE(PdfExportTest, testTdf135638)
 {
     aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");

Reply via email to