drawinglayer/source/primitive2d/controlprimitive2d.cxx     |   20 +++++++------
 drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |    7 +++-
 include/drawinglayer/primitive2d/controlprimitive2d.hxx    |   14 +++++----
 svx/source/sdr/contact/viewcontactofunocontrol.cxx         |    5 ++-
 svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx   |    4 +-
 5 files changed, 31 insertions(+), 19 deletions(-)

New commits:
commit 002a6fee2fbd07c3f0cd1f1ddba39c691130727e
Author:     Michael Stahl <[email protected]>
AuthorDate: Fri Mar 24 18:45:53 2023 +0100
Commit:     Michael Stahl <[email protected]>
CommitDate: Mon Mar 27 08:40:08 2023 +0000

    tdf#152234 drawinglayer,svx: PDF/UA export: add Alt text to form controls
    
      Specification: ISO 14289-1:2014, Clause: 7.18.1, Test number: 3
      A form field whose hidden flag is not set and whose rectangle is not 
outside the crop-box shall have a TU key present or all its Widget annotations 
shall have alternative descriptions (in the form of an Alt entry in the 
enclosing structure elements)
    
    Form controls are weird because they have an SdrObject with the usual
    name/title/description plus a property "HelpText" on the control itself
    which is already exported as "/TU" on the /Annot unless it's empty.
    
    Exporting the SdrObject properties via ObjectInfoPrimitive2D doesn't
    work as tragically that is only created for form controls when painting
    to the screen while PDF export takes a detour that needs special
    handling.
    
    Change-Id: Id96f7dd13f190ab439c099cd1f4acb70c1c9fdc9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149554
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/drawinglayer/source/primitive2d/controlprimitive2d.cxx 
b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
index 6fe6e57c10d1..372fb61244a0 100644
--- a/drawinglayer/source/primitive2d/controlprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
@@ -26,6 +26,7 @@
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <utility>
+#include <rtl/ustrbuf.hxx>
 #include <vcl/virdev.hxx>
 #include <vcl/svapp.hxx>
 #include <com/sun/star/awt/PosSize.hpp>
@@ -237,22 +238,23 @@ namespace drawinglayer::primitive2d
             rContainer.push_back(xReference);
         }
 
-        ControlPrimitive2D::ControlPrimitive2D(
-            basegfx::B2DHomMatrix aTransform,
-            uno::Reference< awt::XControlModel > xControlModel)
-        :   maTransform(std::move(aTransform)),
-            mxControlModel(std::move(xControlModel))
-        {
-        }
-
         ControlPrimitive2D::ControlPrimitive2D(
             basegfx::B2DHomMatrix aTransform,
             uno::Reference< awt::XControlModel > xControlModel,
-            uno::Reference< awt::XControl > xXControl)
+            uno::Reference<awt::XControl> xXControl,
+            ::std::u16string_view const rTitle,
+            ::std::u16string_view const rDescription)
         :   maTransform(std::move(aTransform)),
             mxControlModel(std::move(xControlModel)),
             mxXControl(std::move(xXControl))
         {
+            ::rtl::OUStringBuffer buf(rTitle);
+            if (!rTitle.empty() && !rDescription.empty())
+            {
+                buf.append(" - ");
+            }
+            buf.append(rDescription);
+            m_AltText = buf.makeStringAndClear();
         }
 
         const uno::Reference< awt::XControl >& 
ControlPrimitive2D::getXControl() const
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index d82465ceb313..56675ff113ef 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1137,8 +1137,6 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
     if (bPDFExport)
     {
         // PDF export. Emulate data handling from UnoControlPDFExportContact
-        // I have now moved describePDFControl to toolkit, thus i can 
implement the PDF
-        // form control support now as follows
         std::unique_ptr<vcl::PDFWriter::AnyWidget> pPDFControl(
             ::toolkitform::describePDFControl(rXControl, *mpPDFExtOutDevData));
 
@@ -1159,6 +1157,11 @@ void VclMetafileProcessor2D::processControlPrimitive2D(
             pPDFControl->TextFont.SetFontSize(aFontSize);
 
             mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::Form);
+            OUString const& rAltText(rControlPrimitive.GetAltText());
+            if (!rAltText.isEmpty())
+            {
+                mpPDFExtOutDevData->SetAlternateText(rAltText);
+            }
             mpPDFExtOutDevData->CreateControl(*pPDFControl);
             mpPDFExtOutDevData->EndStructureElement();
 
diff --git a/include/drawinglayer/primitive2d/controlprimitive2d.hxx 
b/include/drawinglayer/primitive2d/controlprimitive2d.hxx
index e3d5a5c0948d..e33c26886cd9 100644
--- a/include/drawinglayer/primitive2d/controlprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/controlprimitive2d.hxx
@@ -55,6 +55,9 @@ private:
     /// the last used scaling, used from getDecomposition for buffering
     basegfx::B2DVector maLastViewScaling;
 
+    /// yet another special snowflake way to generate PDF Alt text
+    OUString m_AltText;
+
     /** used from getXControl() to create a local awt::XControl which is 
remembered in mxXControl
                 and from thereon always used and returned by getXControl()
              */
@@ -71,17 +74,14 @@ private:
                           const geometry::ViewInformation2D& rViewInformation) 
const override;
 
 public:
-    /// constructor
-    ControlPrimitive2D(basegfx::B2DHomMatrix aTransform,
-                       css::uno::Reference<css::awt::XControlModel> 
xControlModel);
-
-    /** constructor with an additional XControl as parameter to allow to hand 
it over at incarnation time
+    /** constructor with an optional XControl as parameter to allow to hand it 
over at incarnation time
         if it exists. This will avoid to create a 2nd one on demand in 
createXControl()
         and thus double the XControls.
      */
     ControlPrimitive2D(basegfx::B2DHomMatrix aTransform,
                        css::uno::Reference<css::awt::XControlModel> 
xControlModel,
-                       css::uno::Reference<css::awt::XControl> xXControl);
+                       css::uno::Reference<css::awt::XControl> xXControl,
+                       ::std::u16string_view rTitle, ::std::u16string_view 
rDescription);
 
     /// data read access
     const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
@@ -96,6 +96,8 @@ public:
      */
     const css::uno::Reference<css::awt::XControl>& getXControl() const;
 
+    OUString const& GetAltText() const { return m_AltText; }
+
     /// compare operator
     virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
 
diff --git a/svx/source/sdr/contact/viewcontactofunocontrol.cxx 
b/svx/source/sdr/contact/viewcontactofunocontrol.cxx
index f99b24372ba7..cc14ae06ad5e 100644
--- a/svx/source/sdr/contact/viewcontactofunocontrol.cxx
+++ b/svx/source/sdr/contact/viewcontactofunocontrol.cxx
@@ -111,7 +111,10 @@ namespace sdr::contact {
             const drawinglayer::primitive2d::Primitive2DReference xRetval(
                 new drawinglayer::primitive2d::ControlPrimitive2D(
                     aTransform,
-                    xControlModel));
+                    xControlModel,
+                    nullptr,
+                    GetSdrObject().GetTitle(),
+                    GetSdrObject().GetDescription()));
 
             rVisitor.visit(xRetval);
         }
diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx 
b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
index db458e1245fa..db211cae16dc 100644
--- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
@@ -1568,7 +1568,9 @@ namespace sdr::contact {
         // create a primitive and hand over the existing xControl. This will
         // allow the primitive to not need to create another one on demand.
         rContainer.push_back( new 
::drawinglayer::primitive2d::ControlPrimitive2D(
-            m_aTransformation, xControlModel, rControl.getControl() ) );
+            m_aTransformation, xControlModel, rControl.getControl(),
+            m_pVOCImpl->getViewContact().GetSdrObject().GetTitle(),
+            m_pVOCImpl->getViewContact().GetSdrObject().GetDescription()) );
     }
 
     sal_uInt32 LazyControlCreationPrimitive2D::getPrimitive2DID() const

Reply via email to