vcl/inc/pdf/pdfwriter_impl.hxx      |    2 ++
 vcl/source/gdi/pdfextoutdevdata.cxx |   14 +++++++++++++-
 vcl/source/gdi/pdfwriter_impl.cxx   |   19 +++++++++++++++++--
 3 files changed, 32 insertions(+), 3 deletions(-)

New commits:
commit d4d471fc88fe4fd14f44dfccdfe360dec327d4f0
Author:     Michael Stahl <[email protected]>
AuthorDate: Fri Mar 24 20:29:06 2023 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Tue Mar 28 12:29:42 2023 +0000

    tdf#152234 vcl: PDF/UA export: StructElem<->Annot for form controls
    
    veraPDF complains:
    
      Specification: ISO 14289-1:2014, Clause: 7.18.4, Test number: 1
      A Widget annotation shall be nested within a Form tag per
      ISO 32000-1:2008, 14.8.4.5, Table 340.
    
    This is a little simpler than for Link and Screen annotations, because
    the form control StructElem and Annot are exported at the same time
    from VclMetafileProcessor2D::processControlPrimitive2D().
    
    So PDFExtOutDevData can just make up the mapping on playback.
    
    Change-Id: Idacb84a3e414f45a2598ccb33b252205cb2bcde9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149556
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit d9031bd83ffe718a80da9ecbdbeb485e35fbabee)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149603
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index e46088bca912..ece9fa3ac6df 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -525,6 +525,8 @@ struct PDFWidget : public PDFAnnotation
     std::vector<sal_Int32>      m_aSelectedEntries;
     typedef std::unordered_map<OString, SvMemoryStream*> PDFAppearanceStreams;
     std::unordered_map<OString, PDFAppearanceStreams> m_aAppearances;
+    sal_Int32 m_nStructParent = -1;
+
     PDFWidget()
             : m_eType( PDFWriter::PushButton ),
               m_nTextStyle( DrawTextFlags::NONE ),
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx 
b/vcl/source/gdi/pdfextoutdevdata.cxx
index 5dfcc5b19d6e..21f340fc2107 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -97,6 +97,10 @@ struct GlobalSyncData
     sal_Int32 GetMappedId();
     sal_Int32 GetMappedStructId( sal_Int32 );
 
+    /** the way this appears to work: (only) everything that increments mCurId
+        at recording time must put an item into mParaIds at playback time,
+        so that the mCurId becomes the eventual index into mParaIds.
+     */
     sal_Int32                   mCurId;
     std::vector< sal_Int32 >    mParaIds;
     std::vector< sal_Int32 >    mStructIdMap;
@@ -410,7 +414,14 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, 
sal_uInt32& rCurGDIMtfAc
                 std::shared_ptr< PDFWriter::AnyWidget > pControl( 
mControls.front() );
                 SAL_WARN_IF( !pControl, "vcl", "PageSyncData::PlaySyncPageAct: 
invalid widget!" );
                 if ( pControl )
-                    rWriter.CreateControl( *pControl );
+                {
+                    sal_Int32 const n = rWriter.CreateControl(*pControl);
+                    // resolve AnnotIds structural attribute
+                    ::std::vector<sal_Int32> const annotIds{ 
sal_Int32(mpGlobalData->mParaIds.size()) };
+                    rWriter.SetStructureAnnotIds(annotIds);
+                    rWriter.SetLinkPropertyID(n, 
sal_Int32(mpGlobalData->mParaIds.size()));
+                    mpGlobalData->mParaIds.push_back(n);
+                }
                 mControls.pop_front();
             }
             break;
@@ -849,6 +860,7 @@ void PDFExtOutDevData::CreateControl( const 
PDFWriter::AnyWidget& rControlType )
 
     std::shared_ptr< PDFWriter::AnyWidget > pClone( rControlType.Clone() );
     mpPageSyncData->mControls.push_back( pClone );
+    mpGlobalSyncData->mCurId++;
 }
 
 void PDFExtOutDevData::BeginGroup()
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 8cf4b34b6519..3ce03d88f734 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -2247,8 +2247,16 @@ sal_Int32 PDFWriterImpl::emitStructure( 
PDFStructureElement& rEle )
             auto const it(m_aLinkPropertyMap.find(id));
             assert(it != m_aLinkPropertyMap.end());
 
-            assert(0 <= it->second && o3tl::make_unsigned(it->second) < 
m_aScreens.size());
-            AppendAnnotKid(rEle, m_aScreens[it->second]);
+            if (rEle.m_eType == PDFWriter::Form)
+            {
+                assert(0 <= it->second && o3tl::make_unsigned(it->second) < 
m_aWidgets.size());
+                AppendAnnotKid(rEle, m_aWidgets[it->second]);
+            }
+            else
+            {
+                assert(0 <= it->second && o3tl::make_unsigned(it->second) < 
m_aScreens.size());
+                AppendAnnotKid(rEle, m_aScreens[it->second]);
+            }
         }
     }
     if( ! rEle.m_aKids.empty() )
@@ -4649,6 +4657,13 @@ bool PDFWriterImpl::emitWidgetAnnotations()
                     iRectMargin = 1;
                 }
 
+                if (0 < rWidget.m_nStructParent)
+                {
+                    aLine.append("/StructParent ");
+                    aLine.append(rWidget.m_nStructParent);
+                    aLine.append("\n");
+                }
+
                 aLine.append("/Rect[" );
                 appendFixedInt( rWidget.m_aRect.Left()-iRectMargin, aLine );
                 aLine.append( ' ' );

Reply via email to