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>
This commit is contained in:
@@ -1254,7 +1254,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);
|
||||
|
||||
@@ -3858,7 +3858,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 );
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -917,7 +917,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);
|
||||
|
||||
@@ -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.getType() == CELLTYPE_FORMULA)
|
||||
{
|
||||
ScFormulaCell* pFCell = rCell.getFormula();
|
||||
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 );
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
@@ -1644,20 +1666,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;
|
||||
@@ -1667,7 +1690,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;
|
||||
@@ -1678,7 +1701,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;
|
||||
@@ -1696,7 +1719,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;
|
||||
@@ -1706,7 +1729,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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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() );
|
||||
@@ -1703,7 +1704,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 );
|
||||
@@ -1717,7 +1718,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1777,7 +1778,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 );
|
||||
|
||||
@@ -1786,7 +1787,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 )
|
||||
@@ -1803,7 +1804,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
|
||||
{
|
||||
const SwTextNode* pTNd = pPosition->GetNode().GetTextNode();
|
||||
if ( pTNd )
|
||||
MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, aLinkRect, nDestId, aURL, bIntern );
|
||||
MakeHeaderFooterLinks(*pPDFExtOutDevData, *pTNd, aLinkRect, nDestId, aURL, bIntern, formatName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1892,6 +1893,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
|
||||
|
||||
// #i44368# Links in Header/Footer
|
||||
const bool bHeaderFooter = pDoc->IsInHeaderFooter( *pTNd );
|
||||
OUString const content(pField->ExpandField(true, mrSh.GetLayout()));
|
||||
|
||||
// Create links for all selected rectangles:
|
||||
const size_t nNumOfRects = aTmp.size();
|
||||
@@ -1908,7 +1910,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 );
|
||||
@@ -1920,7 +1922,7 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
|
||||
// #i44368# Links in Header/Footer
|
||||
if ( bHeaderFooter )
|
||||
{
|
||||
MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, "", true );
|
||||
MakeHeaderFooterLinks(*pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, "", true, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2001,8 +2003,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();
|
||||
@@ -2011,7 +2016,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:
|
||||
@@ -2226,6 +2231,8 @@ void SwEnhancedPDFExportHelper::ExportAuthorityEntryLinks()
|
||||
continue;
|
||||
}
|
||||
|
||||
OUString const content(rAuthorityField.ExpandField(true, mrSh.GetLayout()));
|
||||
|
||||
// Select the field.
|
||||
mrSh.SwCursorShell::SetMark();
|
||||
mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
|
||||
@@ -2236,7 +2243,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);
|
||||
@@ -2320,7 +2327,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:
|
||||
@@ -2347,7 +2355,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 )
|
||||
|
||||
@@ -422,10 +422,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)
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1273,7 +1275,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 );
|
||||
|
||||
@@ -3596,6 +3596,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
|
||||
@@ -3603,6 +3606,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"))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -330,9 +330,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)
|
||||
|
||||
@@ -737,6 +737,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() )
|
||||
{
|
||||
@@ -3520,6 +3526,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" );
|
||||
@@ -10158,7 +10167,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;
|
||||
@@ -10168,7 +10177,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;
|
||||
|
||||
Reference in New Issue
Block a user