summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-10-25 13:41:05 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2022-11-01 11:14:20 +0100
commitc5a8728d8f9e943bad4bb55dbde30ae9eceefecf (patch)
tree6056bb68d6987f1145e4cc1fc68a7cfeaebe0cd2
parenttdf#150888 Scale down PPI if it would result in a tiny image (diff)
downloadcore-c5a8728d8f9e943bad4bb55dbde30ae9eceefecf.tar.gz
core-c5a8728d8f9e943bad4bb55dbde30ae9eceefecf.zip
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.stahl@allotropia.de> (cherry picked from commit fa3f04bdd4f73a1b3be70dfb709c44638ef7e3d9) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141873 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx3
-rw-r--r--editeng/source/editeng/impedit3.cxx2
-rw-r--r--include/vcl/pdfextoutdevdata.hxx5
-rw-r--r--include/vcl/pdfwriter.hxx2
-rw-r--r--sc/source/ui/view/output2.cxx4
-rw-r--r--sd/source/ui/dlg/tpaction.cxx21
-rw-r--r--sd/source/ui/inc/tpaction.hxx4
-rw-r--r--sd/source/ui/unoidl/unomodel.cxx35
-rw-r--r--sw/inc/EnhancedPDFExportHelper.hxx3
-rw-r--r--sw/source/core/text/EnhancedPDFExportHelper.cxx32
-rw-r--r--vcl/inc/pdf/pdfwriter_impl.hxx6
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx8
-rw-r--r--vcl/source/gdi/pdfextoutdevdata.cxx6
-rw-r--r--vcl/source/gdi/pdfwriter.cxx4
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx13
15 files changed, 92 insertions, 56 deletions
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;