drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |    3 -
 editeng/source/editeng/impedit3.cxx                        |    2 
 include/vcl/pdfextoutdevdata.hxx                           |    5 +
 include/vcl/pdfwriter.hxx                                  |    2 
 sc/source/filter/excel/xecontent.cxx                       |    3 -
 sc/source/filter/excel/xestring.cxx                        |    3 -
 sc/source/ui/view/output2.cxx                              |    4 -
 sd/source/ui/dlg/tpaction.cxx                              |   21 -------
 sd/source/ui/inc/tpaction.hxx                              |    4 -
 sd/source/ui/unoidl/unomodel.cxx                           |   35 ++++++++++---
 sw/inc/EnhancedPDFExportHelper.hxx                         |    3 -
 sw/source/core/text/EnhancedPDFExportHelper.cxx            |   32 +++++++----
 vcl/inc/pdf/pdfwriter_impl.hxx                             |    6 +-
 vcl/qa/cppunit/pdfexport/pdfexport.cxx                     |    8 ++
 vcl/source/gdi/pdfextoutdevdata.cxx                        |    6 +-
 vcl/source/gdi/pdfwriter.cxx                               |    4 -
 vcl/source/gdi/pdfwriter_impl.cxx                          |   13 ++++
 17 files changed, 96 insertions(+), 58 deletions(-)

New commits:
commit 992529ad3c143a7a95124851da6a712cb3d65605
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Tue Oct 25 14:16:48 2022 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Nov 1 11:14:38 2022 +0100

    tdf#151484 Data Validity list looses separation when saving as XLS
    
    regression from
        commit fbb41798b86c5ed35eb80aa07a5ee7c9866ac4e8
        Author: Noel Grandin <noel.gran...@collabora.co.uk>
        Date:   Fri Mar 18 09:46:52 2022 +0200
        tdf#133603 remove some string copying
    
    Change-Id: Ie241a7d5e54673b35c643c7c20dc100ba7925647
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141808
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    (cherry picked from commit 9ff56812741029ad17204cff53357751687d9b6c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141834
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sc/source/filter/excel/xecontent.cxx 
b/sc/source/filter/excel/xecontent.cxx
index f116e0e497f0..65f8bb2f435e 100644
--- a/sc/source/filter/excel/xecontent.cxx
+++ b/sc/source/filter/excel/xecontent.cxx
@@ -1775,7 +1775,8 @@ XclExpDV::XclExpDV( const XclExpRoot& rRoot, sal_uLong 
nScHandle ) :
                             sFormulaBuf.append( aToken );
                             if (nStringIx<0)
                                 break;
-                            mxString1->Append(u"\0");
+                            sal_Unicode cUnicodeChar = 0;
+                            mxString1->Append( 
std::u16string_view(&cUnicodeChar, 1) );
                             sFormulaBuf.append( ',' );
                             sListBuf.append( ',' );
                         }
diff --git a/sc/source/filter/excel/xestring.cxx 
b/sc/source/filter/excel/xestring.cxx
index cb76518e6b41..295f37709594 100644
--- a/sc/source/filter/excel/xestring.cxx
+++ b/sc/source/filter/excel/xestring.cxx
@@ -148,7 +148,8 @@ void XclExpString::AppendByte( sal_Unicode cChar, 
rtl_TextEncoding eTextEnc )
 {
     if( !cChar )
     {
-        BuildAppend( "\0" );
+        char cByteChar = 0;
+        BuildAppend( std::string_view(&cByteChar, 1) );
     }
     else
     {
commit c5a8728d8f9e943bad4bb55dbde30ae9eceefecf
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Oct 25 13:41:05 2022 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Nov 1 11:14:20 2022 +0100

    tdf#148934 PDF/UA export: add Contents entry to Link annotations
    
    * Specification: ISO 14289-1:2014, Clause: 7.18.5, Test number: 2
    Links shall contain an alternate description via their Contents key as 
described in ISO 32000-1:2008, 14.9.3.
    
    These links are created all over the code, in some cases it's a bit
    dubious what the content/alt-text should be, but let's try to use the
    most suitable looking bit of text in whatever the context is.
    
    * Specification: ISO 14289-1:2014, Clause: 7.18.3, Test number: 1
    Every page on which there is an annotation shall contain in its page 
dictionary the key Tabs, and its value shall be S.
    
    Change-Id: I7b63feb759f0c75047f854ed9997918f829a537e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141826
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit fa3f04bdd4f73a1b3be70dfb709c44638ef7e3d9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141873
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index de95df83dc8d..f8ea72174d8f 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1252,7 +1252,8 @@ void 
VclMetafileProcessor2D::processTextHierarchyFieldPrimitive2D(
                                       
static_cast<sal_Int32>(ceil(aViewRange.getMaxX())),
                                       
static_cast<sal_Int32>(ceil(aViewRange.getMaxY())));
     vcl::PDFExtOutDevBookmarkEntry aBookmark;
-    aBookmark.nLinkId = mpPDFExtOutDevData->CreateLink(aRectLogic);
+    OUString const content(rFieldPrimitive.getValue("Representation"));
+    aBookmark.nLinkId = mpPDFExtOutDevData->CreateLink(aRectLogic, content);
     aBookmark.aBookmark = aURL;
     std::vector<vcl::PDFExtOutDevBookmarkEntry>& rBookmarks = 
mpPDFExtOutDevData->GetBookmarks();
     rBookmarks.push_back(aBookmark);
diff --git a/editeng/source/editeng/impedit3.cxx 
b/editeng/source/editeng/impedit3.cxx
index e73bf2aff9c8..f0f6c0e728d1 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -3684,7 +3684,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
 
                                                         tools::Rectangle 
aRect( aTopLeft, rTextPortion.GetSize() );
                                                         
vcl::PDFExtOutDevBookmarkEntry aBookmark;
-                                                        aBookmark.nLinkId = 
pPDFExtOutDevData->CreateLink( aRect );
+                                                        aBookmark.nLinkId = 
pPDFExtOutDevData->CreateLink(aRect, pUrlField->GetRepresentation());
                                                         aBookmark.aBookmark = 
pUrlField->GetURL();
                                                         std::vector< 
vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = 
pPDFExtOutDevData->GetBookmarks();
                                                         rBookmarks.push_back( 
aBookmark );
diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx
index 39a8bbb30d56..45cb71682f12 100644
--- a/include/vcl/pdfextoutdevdata.hxx
+++ b/include/vcl/pdfextoutdevdata.hxx
@@ -252,11 +252,14 @@ public:
     number of page the link is on (as returned by NewPage)
     or -1 in which case the current page is used
 
+    @param rAltText
+    Alt text for the link
+
     @returns
     the link id (to be used in SetLinkDest, SetLinkURL) or
     -1 if page id does not exist
     */
-    sal_Int32 CreateLink( const tools::Rectangle& rRect, sal_Int32 nPageNr = 
-1 );
+    sal_Int32 CreateLink(const tools::Rectangle& rRect, OUString const& 
rAltText, sal_Int32 nPageNr = -1);
 
     /// Create a Screen annotation.
     sal_Int32 CreateScreen(const tools::Rectangle& rRect, sal_Int32 nPageNr);
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 8764f3f49c8e..1aaea5a7c3f8 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -916,7 +916,7 @@ The following structure describes the permissions used in 
PDF security
     the link id (to be used in SetLinkDest, SetLinkURL) or
     -1 if page id does not exist
     */
-    sal_Int32           CreateLink( const tools::Rectangle& rRect, sal_Int32 
nPageNr );
+    sal_Int32 CreateLink(const tools::Rectangle& rRect, sal_Int32 nPageNr, 
OUString const& rAltText);
 
     /// Creates a screen annotation.
     sal_Int32 CreateScreen(const tools::Rectangle& rRect, sal_Int32 nPageNr);
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index cdd9329d3fcb..5c234df7953e 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -862,10 +862,10 @@ static void lcl_DoHyperlinkResult( const OutputDevice* 
pDev, const tools::Rectan
     vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* >( 
pDev->GetExtOutDevData() );
 
     OUString aURL;
+    OUString aCellText;
     if (rCell.meType == CELLTYPE_FORMULA)
     {
         ScFormulaCell* pFCell = rCell.mpFormula;
-        OUString aCellText;
         if ( pFCell->IsHyperLinkCell() )
             pFCell->GetURLResult( aURL, aCellText );
     }
@@ -873,7 +873,7 @@ static void lcl_DoHyperlinkResult( const OutputDevice* 
pDev, const tools::Rectan
     if ( !aURL.isEmpty() && pPDFData )
     {
         vcl::PDFExtOutDevBookmarkEntry aBookmark;
-        aBookmark.nLinkId = pPDFData->CreateLink( rRect );
+        aBookmark.nLinkId = pPDFData->CreateLink(rRect, aCellText);
         aBookmark.aBookmark = aURL;
         std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = 
pPDFData->GetBookmarks();
         rBookmarks.push_back( aBookmark );
diff --git a/sd/source/ui/dlg/tpaction.cxx b/sd/source/ui/dlg/tpaction.cxx
index c5ccd758a321..f89fa51f5b5d 100644
--- a/sd/source/ui/dlg/tpaction.cxx
+++ b/sd/source/ui/dlg/tpaction.cxx
@@ -798,25 +798,4 @@ OUString SdTPAction::GetEditText( bool bFullDocDestination 
)
     return aStr;
 }
 
-TranslateId SdTPAction::GetClickActionSdResId( presentation::ClickAction eCA )
-{
-    switch( eCA )
-    {
-        case presentation::ClickAction_NONE:             return 
STR_CLICK_ACTION_NONE;
-        case presentation::ClickAction_PREVPAGE:         return 
STR_CLICK_ACTION_PREVPAGE;
-        case presentation::ClickAction_NEXTPAGE:         return 
STR_CLICK_ACTION_NEXTPAGE;
-        case presentation::ClickAction_FIRSTPAGE:        return 
STR_CLICK_ACTION_FIRSTPAGE;
-        case presentation::ClickAction_LASTPAGE:         return 
STR_CLICK_ACTION_LASTPAGE;
-        case presentation::ClickAction_BOOKMARK:         return 
STR_CLICK_ACTION_BOOKMARK;
-        case presentation::ClickAction_DOCUMENT:         return 
STR_CLICK_ACTION_DOCUMENT;
-        case presentation::ClickAction_PROGRAM:          return 
STR_CLICK_ACTION_PROGRAM;
-        case presentation::ClickAction_MACRO:            return 
STR_CLICK_ACTION_MACRO;
-        case presentation::ClickAction_SOUND:            return 
STR_CLICK_ACTION_SOUND;
-        case presentation::ClickAction_VERB:             return 
STR_CLICK_ACTION_VERB;
-        case presentation::ClickAction_STOPPRESENTATION: return 
STR_CLICK_ACTION_STOPPRESENTATION;
-        default: OSL_FAIL( "No StringResource for ClickAction available!" );
-    }
-    return {};
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/inc/tpaction.hxx b/sd/source/ui/inc/tpaction.hxx
index f04f50fddfce..893192d256f2 100644
--- a/sd/source/ui/inc/tpaction.hxx
+++ b/sd/source/ui/inc/tpaction.hxx
@@ -82,9 +82,9 @@ private:
     void                    SetActualClickAction( 
css::presentation::ClickAction eCA );
     void                    SetEditText( OUString const & rStr );
     OUString                GetEditText( bool bURL = false );
-    static TranslateId      
GetClickActionSdResId(css::presentation::ClickAction eCA);
-
 public:
+    SD_DLLPUBLIC static TranslateId 
GetClickActionSdResId(css::presentation::ClickAction eCA);
+
     SdTPAction(weld::Container* pPage, weld::DialogController* pController, 
const SfxItemSet& rInAttrs);
     virtual ~SdTPAction() override;
 
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index ff66696d7d8f..b316f9f1f4da 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -44,6 +44,7 @@
 #include <sal/log.hxx>
 #include <editeng/unofield.hxx>
 #include <notifydocumentevent.hxx>
+#include <tpaction.hxx>
 #include <unomodel.hxx>
 #include "unopool.hxx"
 #include <sfx2/lokhelper.hxx>
@@ -135,6 +136,27 @@ using namespace ::cppu;
 using namespace ::com::sun::star;
 using namespace ::sd;
 
+TranslateId SdTPAction::GetClickActionSdResId( presentation::ClickAction eCA )
+{
+    switch( eCA )
+    {
+        case presentation::ClickAction_NONE:             return 
STR_CLICK_ACTION_NONE;
+        case presentation::ClickAction_PREVPAGE:         return 
STR_CLICK_ACTION_PREVPAGE;
+        case presentation::ClickAction_NEXTPAGE:         return 
STR_CLICK_ACTION_NEXTPAGE;
+        case presentation::ClickAction_FIRSTPAGE:        return 
STR_CLICK_ACTION_FIRSTPAGE;
+        case presentation::ClickAction_LASTPAGE:         return 
STR_CLICK_ACTION_LASTPAGE;
+        case presentation::ClickAction_BOOKMARK:         return 
STR_CLICK_ACTION_BOOKMARK;
+        case presentation::ClickAction_DOCUMENT:         return 
STR_CLICK_ACTION_DOCUMENT;
+        case presentation::ClickAction_PROGRAM:          return 
STR_CLICK_ACTION_PROGRAM;
+        case presentation::ClickAction_MACRO:            return 
STR_CLICK_ACTION_MACRO;
+        case presentation::ClickAction_SOUND:            return 
STR_CLICK_ACTION_SOUND;
+        case presentation::ClickAction_VERB:             return 
STR_CLICK_ACTION_VERB;
+        case presentation::ClickAction_STOPPRESENTATION: return 
STR_CLICK_ACTION_STOPPRESENTATION;
+        default: OSL_FAIL( "No StringResource for ClickAction available!" );
+    }
+    return {};
+}
+
 namespace {
 
 class SdUnoForbiddenCharsTable : public SvxUnoForbiddenCharsTable,
@@ -1643,20 +1665,21 @@ static void ImplPDFExportShapeInteraction( const 
uno::Reference< drawing::XShape
             uno::Any aAny( xShapePropSet->getPropertyValue( "OnClick" ) );
             if ( aAny >>= eCa )
             {
+                OUString const 
actionName(SdResId(SdTPAction::GetClickActionSdResId(eCa)));
                 switch ( eCa )
                 {
                     case presentation::ClickAction_LASTPAGE :
                     {
                         sal_Int32 nCount = rDoc.GetSdPageCount( 
PageKind::Standard );
                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( 
aPageRect, nCount - 1, vcl::PDFWriter::DestAreaType::FitRectangle );
-                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( 
aLinkRect );
+                        sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
                     }
                     break;
                     case presentation::ClickAction_FIRSTPAGE :
                     {
                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( 
aPageRect, 0, vcl::PDFWriter::DestAreaType::FitRectangle );
-                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( 
aLinkRect );
+                        sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
                     }
                     break;
@@ -1666,7 +1689,7 @@ static void ImplPDFExportShapeInteraction( const 
uno::Reference< drawing::XShape
                         if ( nDestPage )
                             nDestPage--;
                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( 
aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
-                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( 
aLinkRect );
+                        sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
                     }
                     break;
@@ -1677,7 +1700,7 @@ static void ImplPDFExportShapeInteraction( const 
uno::Reference< drawing::XShape
                         if ( nDestPage > nLastPage )
                             nDestPage = nLastPage;
                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( 
aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
-                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( 
aLinkRect );
+                        sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
                     }
                     break;
@@ -1695,7 +1718,7 @@ static void ImplPDFExportShapeInteraction( const 
uno::Reference< drawing::XShape
                                 case presentation::ClickAction_DOCUMENT :
                                 case presentation::ClickAction_PROGRAM :
                                 {
-                                    sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink( aLinkRect );
+                                    sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
                                     rPDFExtOutDevData.SetLinkURL( nLinkId, 
aBookmark );
                                 }
                                 break;
@@ -1705,7 +1728,7 @@ static void ImplPDFExportShapeInteraction( const 
uno::Reference< drawing::XShape
                                     if ( nPage != -1 )
                                     {
                                         sal_Int32 nDestId = 
rPDFExtOutDevData.CreateDest( aPageRect, nPage, 
vcl::PDFWriter::DestAreaType::FitRectangle );
-                                        sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink( aLinkRect );
+                                        sal_Int32 nLinkId = 
rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
                                         rPDFExtOutDevData.SetLinkDest( 
nLinkId, nDestId );
                                     }
                                 }
diff --git a/sw/inc/EnhancedPDFExportHelper.hxx 
b/sw/inc/EnhancedPDFExportHelper.hxx
index eb813773abb3..8b72001f0fb7 100644
--- a/sw/inc/EnhancedPDFExportHelper.hxx
+++ b/sw/inc/EnhancedPDFExportHelper.hxx
@@ -228,7 +228,8 @@ class SwEnhancedPDFExportHelper
 
     void MakeHeaderFooterLinks( vcl::PDFExtOutDevData& rPDFExtOutDevData,
                                 const SwTextNode& rTNd, const SwRect& 
rLinkRect,
-                                sal_Int32 nDestId, const OUString& rURL, bool 
bIntern ) const;
+                                sal_Int32 nDestId, const OUString& rURL,
+                                bool bIntern, OUString const& rContent) const;
 
     public:
 
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx 
b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index ccec950bb954..f0dd67d305fa 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -1651,6 +1651,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                     SwRects aTmp;
                     aTmp.insert( aTmp.begin(), 
mrSh.SwCursorShell::GetCursor_()->begin(), 
mrSh.SwCursorShell::GetCursor_()->end() );
                     OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - 
rectangles are missing" );
+                    OUString const altText(mrSh.GetSelText());
 
                     const SwPageFrame* pSelectionPage =
                         static_cast<const SwPageFrame*>( 
mrSh.GetLayout()->Lower() );
@@ -1704,7 +1705,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                                 // Link Export
                                 tools::Rectangle 
aRect(SwRectToPDFRect(pSelectionPage, rLinkRect.SVRect()));
                                 const sal_Int32 nLinkId =
-                                    pPDFExtOutDevData->CreateLink(aRect, 
aLinkPageNum);
+                                    pPDFExtOutDevData->CreateLink(aRect, 
altText, aLinkPageNum);
 
                                 // Store link info for tagged pdf output:
                                 const IdMapEntry aLinkEntry( rLinkRect, 
nLinkId );
@@ -1718,7 +1719,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
 
                                 // #i44368# Links in Header/Footer
                                 if ( bHeaderFooter )
-                                    MakeHeaderFooterLinks( *pPDFExtOutDevData, 
*pTNd, rLinkRect, nDestId, aURL, bIntern );
+                                    MakeHeaderFooterLinks(*pPDFExtOutDevData, 
*pTNd, rLinkRect, nDestId, aURL, bIntern, altText);
                             }
                         }
                     }
@@ -1778,7 +1779,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                 {
                     Point aNullPt;
                     const SwRect aLinkRect = pFrameFormat->FindLayoutRect( 
false, &aNullPt );
-
+                    OUString const formatName(pFrameFormat->GetName());
                     // Link PageNums
                     std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( 
aLinkRect );
 
@@ -1787,7 +1788,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                     {
                         tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, 
aLinkRect.SVRect()));
                         const sal_Int32 nLinkId =
-                            pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
+                            pPDFExtOutDevData->CreateLink(aRect, formatName, 
aLinkPageNum);
 
                         // Connect Link and Destination:
                         if ( bIntern )
@@ -1804,7 +1805,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                             {
                                 const SwTextNode* pTNd = 
pPosition->nNode.GetNode().GetTextNode();
                                 if ( pTNd )
-                                    MakeHeaderFooterLinks( *pPDFExtOutDevData, 
*pTNd, aLinkRect, nDestId, aURL, bIntern );
+                                    MakeHeaderFooterLinks(*pPDFExtOutDevData, 
*pTNd, aLinkRect, nDestId, aURL, bIntern, formatName);
                             }
                         }
                     }
@@ -1894,6 +1895,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                     // #i44368# Links in Header/Footer
                     const SwPosition aPos( *pTNd );
                     const bool bHeaderFooter = pDoc->IsInHeaderFooter( 
aPos.nNode );
+                    OUString const content(pField->ExpandField(true, 
mrSh.GetLayout()));
 
                     // Create links for all selected rectangles:
                     const size_t nNumOfRects = aTmp.size();
@@ -1910,7 +1912,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                             // Link Export
                             aRect = SwRectToPDFRect(pCurrPage, 
rLinkRect.SVRect());
                             const sal_Int32 nLinkId =
-                                pPDFExtOutDevData->CreateLink(aRect, 
aLinkPageNum);
+                                pPDFExtOutDevData->CreateLink(aRect, content, 
aLinkPageNum);
 
                             // Store link info for tagged pdf output:
                             const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
@@ -1922,7 +1924,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                             // #i44368# Links in Header/Footer
                             if ( bHeaderFooter )
                             {
-                                MakeHeaderFooterLinks( *pPDFExtOutDevData, 
*pTNd, rLinkRect, nDestId, "", true );
+                                MakeHeaderFooterLinks(*pPDFExtOutDevData, 
*pTNd, rLinkRect, nDestId, "", true, content);
                             }
                         }
                     }
@@ -2004,8 +2006,11 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                     }
                     tools::Rectangle aFootnoteSymbolRect = 
SwRectToPDFRect(pCurrPage, fnSymbolRect.SVRect());
 
+                    OUString const 
numStrSymbol(pTextFootnote->GetFootnote().GetViewNumStr(*pDoc, 
mrSh.GetLayout(), true));
+                    OUString const 
numStrRef(pTextFootnote->GetFootnote().GetViewNumStr(*pDoc, mrSh.GetLayout(), 
false));
+
                     // Export back link
-                    const sal_Int32 nBackLinkId = 
pPDFExtOutDevData->CreateLink(aFootnoteSymbolRect, nDestPageNum);
+                    const sal_Int32 nBackLinkId = 
pPDFExtOutDevData->CreateLink(aFootnoteSymbolRect, numStrSymbol, nDestPageNum);
                     // Destination Export
                     const sal_Int32 nDestId = 
pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
                     mrSh.GotoFootnoteAnchor();
@@ -2014,7 +2019,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                     pCurrPage = static_cast<const SwPageFrame*>( 
mrSh.GetLayout()->Lower() );
                     // Link Export
                     aRect = SwRectToPDFRect(pCurrPage, aLinkRect.SVRect());
-                    const sal_Int32 nLinkId = 
pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
+                    const sal_Int32 nLinkId = 
pPDFExtOutDevData->CreateLink(aRect, numStrRef, aLinkPageNum);
                     // Back link destination Export
                     const sal_Int32 nBackDestId = 
pPDFExtOutDevData->CreateDest(aRect, aLinkPageNum);
                     // Store link info for tagged pdf output:
@@ -2229,6 +2234,8 @@ void 
SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
             continue;
         }
 
+        OUString const content(rAuthorityField.ExpandField(true, 
mrSh.GetLayout()));
+
         // Select the field.
         mrSh.SwCursorShell::SetMark();
         mrSh.SwCursorShell::Right(1, CRSR_SKIP_CHARS);
@@ -2239,7 +2246,7 @@ void 
SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
             for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
             {
                 tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, 
rLinkRect.SVRect()));
-                sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, 
rLinkPageNum);
+                sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, 
content, rLinkPageNum);
                 IdMapEntry aLinkEntry(rLinkRect, nLinkId);
                 s_aLinkIdMap.push_back(aLinkEntry);
                 pPDFExtOutDevData->SetLinkURL(nLinkId, rURL);
@@ -2323,7 +2330,8 @@ void SwEnhancedPDFExportHelper::MakeHeaderFooterLinks( 
vcl::PDFExtOutDevData& rP
                                                        const SwRect& rLinkRect,
                                                        sal_Int32 nDestId,
                                                        const OUString& rURL,
-                                                       bool bIntern ) const
+                                                       bool bIntern,
+                                                       OUString const& 
rContent) const
 {
     // We assume, that the primary link has just been exported. Therefore
     // the offset of the link rectangle calculates as follows:
@@ -2350,7 +2358,7 @@ void SwEnhancedPDFExportHelper::MakeHeaderFooterLinks( 
vcl::PDFExtOutDevData& rP
                 // Link Export
                 tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, 
aHFLinkRect.SVRect()));
                 const sal_Int32 nHFLinkId =
-                    rPDFExtOutDevData.CreateLink(aRect, aHFLinkPageNum);
+                    rPDFExtOutDevData.CreateLink(aRect, rContent, 
aHFLinkPageNum);
 
                 // Connect Link and Destination:
                 if ( bIntern )
diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index 0919414c4dc5..274f65f23a64 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -394,10 +394,12 @@ struct PDFLink : public PDFAnnotation
     sal_Int32                   m_nDest; // set to -1 for URL, to a dest else
     OUString               m_aURL;
     sal_Int32                   m_nStructParent; // struct parent entry
+    OUString m_AltText;
 
-    PDFLink()
+    PDFLink(OUString const& rAltText)
             : m_nDest( -1 ),
               m_nStructParent( -1 )
+            , m_AltText(rAltText)
     {}
 };
 
@@ -1240,7 +1242,7 @@ public:
     sal_Int32   emitDocumentMetadata();
 
     // links
-    sal_Int32 createLink( const tools::Rectangle& rRect, sal_Int32 nPageNr );
+    sal_Int32 createLink(const tools::Rectangle& rRect, sal_Int32 nPageNr, 
OUString const& rAltText);
     sal_Int32 createDest( const tools::Rectangle& rRect, sal_Int32 nPageNr, 
PDFWriter::DestAreaType eType );
     sal_Int32 registerDestReference( sal_Int32 nDestId, const 
tools::Rectangle& rRect, sal_Int32 nPageNr, PDFWriter::DestAreaType eType );
     void      setLinkDest( sal_Int32 nLinkId, sal_Int32 nDestId );
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 51d5e93b9529..df88c65882cf 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -3465,6 +3465,9 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testURIs)
         CPPUNIT_ASSERT_EQUAL(
             OString("Annot"),
             
static_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Type"))->GetValue());
+        CPPUNIT_ASSERT_EQUAL(
+            OString("Link"),
+            
static_cast<vcl::filter::PDFNameElement*>(pAnnot->Lookup("Subtype"))->GetValue());
         auto pAction = 
dynamic_cast<vcl::filter::PDFDictionaryElement*>(pAnnot->Lookup("A"));
         CPPUNIT_ASSERT(pAction);
         auto pURIElem
@@ -3472,6 +3475,11 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testURIs)
         CPPUNIT_ASSERT(pURIElem);
         // Check it matches
         CPPUNIT_ASSERT_EQUAL(URIs[i].out, pURIElem->GetValue());
+        // tdf#148934 check a11y
+        CPPUNIT_ASSERT_EQUAL(
+            OUString("Test pdf"),
+            ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(
+                
*dynamic_cast<vcl::filter::PDFHexStringElement*>(pAnnot->Lookup("Contents"))));
     }
 }
 
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx 
b/vcl/source/gdi/pdfextoutdevdata.cxx
index 96a77a15d94d..00e4f4a9c1bd 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -181,11 +181,12 @@ void GlobalSyncData::PlayGlobalActions( PDFWriter& 
rWriter )
                 rWriter.Push( PushFlags::MAPMODE );
                 rWriter.SetMapMode( mParaMapModes.front() );
                 mParaMapModes.pop_front();
-                mParaIds.push_back( rWriter.CreateLink( mParaRects.front(), 
mParaInts.front() ) );
+                mParaIds.push_back( rWriter.CreateLink(mParaRects.front(), 
mParaInts.front(), mParaOUStrings.front()) );
                 // resolve LinkAnnotation structural attribute
                 rWriter.SetLinkPropertyID( mParaIds.back(), 
sal_Int32(mParaIds.size()-1) );
                 mParaRects.pop_front();
                 mParaInts.pop_front();
+                mParaOUStrings.pop_front();
                 rWriter.Pop();
             }
             break;
@@ -659,12 +660,13 @@ sal_Int32 PDFExtOutDevData::CreateDest( const 
tools::Rectangle& rRect, sal_Int32
     mpGlobalSyncData->mParaDestAreaTypes.push_back( eType );
     return mpGlobalSyncData->mCurId++;
 }
-sal_Int32 PDFExtOutDevData::CreateLink( const tools::Rectangle& rRect, 
sal_Int32 nPageNr )
+sal_Int32 PDFExtOutDevData::CreateLink(const tools::Rectangle& rRect, OUString 
const& rAltText, sal_Int32 nPageNr)
 {
     mpGlobalSyncData->mActions.push_back( PDFExtOutDevDataSync::CreateLink );
     mpGlobalSyncData->mParaRects.push_back( rRect );
     mpGlobalSyncData->mParaMapModes.push_back( mrOutDev.GetMapMode() );
     mpGlobalSyncData->mParaInts.push_back( nPageNr == -1 ? mnPage : nPageNr );
+    mpGlobalSyncData->mParaOUStrings.push_back(rAltText);
     return mpGlobalSyncData->mCurId++;
 }
 
diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx
index 1a8d407c7247..70b6a2345417 100644
--- a/vcl/source/gdi/pdfwriter.cxx
+++ b/vcl/source/gdi/pdfwriter.cxx
@@ -329,9 +329,9 @@ void PDFWriter::DrawJPGBitmap( SvStream& rStreamData, bool 
bIsTrueColor, const S
     xImplementation->drawJPGBitmap( rStreamData, bIsTrueColor, rSrcSizePixel, 
rTargetArea, rAlphaMask, rGraphic );
 }
 
-sal_Int32 PDFWriter::CreateLink( const tools::Rectangle& rRect, sal_Int32 
nPageNr )
+sal_Int32 PDFWriter::CreateLink(const tools::Rectangle& rRect, sal_Int32 
nPageNr, OUString const& rAltText)
 {
-    return xImplementation->createLink( rRect, nPageNr );
+    return xImplementation->createLink(rRect, nPageNr, rAltText);
 }
 
 sal_Int32 PDFWriter::CreateScreen(const tools::Rectangle& rRect, sal_Int32 
nPageNr)
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index e28f1fa75997..e8a66f05516f 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -740,6 +740,12 @@ bool PDFPage::emit(sal_Int32 nParentObject )
             aLine.append( ((i+1)%15) ? " " : "\n" );
         }
         aLine.append( "]\n" );
+        if (m_pWriter->m_aContext.Version != PDFWriter::PDFVersion::PDF_A_1
+            && PDFWriter::PDFVersion::PDF_1_5 <= m_pWriter->m_aContext.Version)
+        {
+            // ISO 14289-1:2014, Clause: 7.18.3
+            aLine.append( "/Tabs(S)\n" );
+        }
     }
     if( !m_aMCIDParents.empty() )
     {
@@ -3251,6 +3257,9 @@ bool PDFWriterImpl::emitLinkAnnotations()
         aLine.append( ' ' );
         appendFixedInt( rLink.m_aRect.Bottom(), aLine );
         aLine.append( "]" );
+        // ISO 14289-1:2014, Clause: 7.18.5
+        aLine.append("/Contents");
+        appendUnicodeTextStringEncrypt(rLink.m_AltText, rLink.m_nObject, 
aLine);
         if( rLink.m_nDest >= 0 )
         {
             aLine.append( "/Dest" );
@@ -9841,7 +9850,7 @@ void PDFWriterImpl::createNote( const tools::Rectangle& 
rRect, const PDFNote& rN
     
m_aPages[nPageNr].m_aAnnotations.push_back(rNoteEntry.m_aPopUpAnnotation.m_nObject);
 }
 
-sal_Int32 PDFWriterImpl::createLink( const tools::Rectangle& rRect, sal_Int32 
nPageNr )
+sal_Int32 PDFWriterImpl::createLink(const tools::Rectangle& rRect, sal_Int32 
nPageNr, OUString const& rAltText)
 {
     if( nPageNr < 0 )
         nPageNr = m_nCurrentPage;
@@ -9851,7 +9860,7 @@ sal_Int32 PDFWriterImpl::createLink( const 
tools::Rectangle& rRect, sal_Int32 nP
 
     sal_Int32 nRet = m_aLinks.size();
 
-    m_aLinks.emplace_back( );
+    m_aLinks.emplace_back(rAltText);
     m_aLinks.back().m_nObject   = createObject();
     m_aLinks.back().m_nPage     = nPageNr;
     m_aLinks.back().m_aRect     = rRect;

Reply via email to