pdf: add PDF 2.0 support for /Title structure element

Add support to PDF export to handle /Title structure element and
fallback to /P (paragraph) if the PDF version is not PDF 2.0.
Then add /Title structure element in writer if the style name of
the paragraph is "Title".

Change-Id: Ia8faab09bf3c97423d154deb7f1eb69860ce857a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180122
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
Tomaž Vajngerl
2025-01-12 14:28:33 +01:00
committed by Tomaž Vajngerl
parent 635f9d8542
commit 3f254da09a
4 changed files with 51 additions and 11 deletions
@@ -2625,6 +2625,7 @@ void VclMetafileProcessor2D::processStructureTagPrimitive2D(
case vcl::pdf::StructElement::H6:
case vcl::pdf::StructElement::Paragraph:
case vcl::pdf::StructElement::Heading:
case vcl::pdf::StructElement::Title:
case vcl::pdf::StructElement::Caption:
case vcl::pdf::StructElement::BlockQuote:
case vcl::pdf::StructElement::Table:
+10 -6
View File
@@ -154,26 +154,30 @@ struct PDFEncryptionProperties
namespace pdf
{
// for a definition of structural element types please refer to
// PDF Reference, 3rd ed. section 9.7.4
// For a definition of structural element types please refer to
// PDF Reference, 3rd ed. section 9.7.4.
//
// In PDF 2.0 specification (ISO 32000-2) refer to section 14.8.4
enum class StructElement
{
// special element to place outside the structure hierarchy
// Special element to place outside the structure hierarchy
NonStructElement,
// Grouping elements
Document, Part, Article, Section, Division, BlockQuote,
Caption, TOC, TOCI, Index,
// block level elements
// Block level elements
Paragraph, Heading, H1, H2, H3, H4, H5, H6,
List, ListItem, LILabel, LIBody,
Table, TableRow, TableHeader, TableData,
Title, // PDF 2.0
// inline level elements
// Inline level elements
Span, Quote, Note, Reference, BibEntry, Code, Link, Annot,
Ruby, RB, RT, RP, Warichu, WT, WP,
// illustration elements
// Illustration elements
Figure, Formula, Form
};
@@ -179,6 +179,7 @@ constexpr OUString aCaption = u"Caption"_ustr;
constexpr OUString aHeading = u"Heading"_ustr;
constexpr OUString aQuotation = u"Quotation"_ustr;
constexpr OUString aSourceText = u"Source Text"_ustr;
constexpr OUString constTitleStyleName = u"Title"_ustr;
// PDF Tag Names:
constexpr OUStringLiteral aDocumentString = u"Document";
@@ -722,7 +723,7 @@ void SwTaggedPDFHelper::SetAttributes(vcl::pdf::StructElement eType)
case vcl::pdf::StructElement::Paragraph:
case vcl::pdf::StructElement::Heading:
case vcl::pdf::StructElement::BlockQuote:
case vcl::pdf::StructElement::Title:
bPlacement =
bWritingMode =
bSpaceBefore =
@@ -1456,6 +1457,14 @@ void SwTaggedPDFHelper::BeginBlockStructureElements()
nPDFType = sal_uInt16(vcl::pdf::StructElement::Paragraph);
aPDFType = sStyleName;
// Title
if (sStyleName == constTitleStyleName)
{
nPDFType = sal_uInt16(vcl::pdf::StructElement::Title);
aPDFType = constTitleStyleName;
}
// Quotations: BlockQuote
if (sStyleName == aQuotations)
+30 -4
View File
@@ -10717,7 +10717,7 @@ void PDFWriterImpl::setOutlineItemDest( sal_Int32 nItem, sal_Int32 nDestID )
m_aOutline[nItem].m_nDestID = nDestID;
}
const char* PDFWriterImpl::getStructureTag(vcl::pdf::StructElement eType )
const char* PDFWriterImpl::getStructureTag(vcl::pdf::StructElement eType)
{
using namespace vcl::pdf;
@@ -10766,15 +10766,35 @@ const char* PDFWriterImpl::getStructureTag(vcl::pdf::StructElement eType )
{ StructElement::WP, "WP" },
{ StructElement::Figure, "Figure" },
{ StructElement::Formula, "Formula"},
{ StructElement::Form, "Form" }
{ StructElement::Form, "Form" },
{ StructElement::Title, "Title" },
});
// First handle fallbacks for elements that were added in a certain PDF version
// PDF 1.5 fallbacks
if (m_aContext.Version < PDFWriter::PDFVersion::PDF_1_5 && eType == StructElement::Annot)
return "Figure"; // fallback
eType = StructElement::Figure;
// PDF 2.0 fallbacks
if (m_aContext.Version < PDFWriter::PDFVersion::PDF_2_0)
{
switch(eType)
{
case StructElement::Title:
eType = StructElement::Paragraph;
break;
default:
break;
}
}
auto iterator = constTagStrings.find(eType);
return iterator != constTagStrings.end() ? iterator->second : "Div";
if (iterator == constTagStrings.end())
return "Div";
return iterator->second;
}
void PDFWriterImpl::addRoleMap(const OString& aAlias, vcl::pdf::StructElement eType)
@@ -11273,6 +11293,7 @@ bool PDFWriterImpl::setStructureAttribute( enum PDFWriter::StructAttribute eAttr
eVal == PDFWriter::Justify )
{
if (eType == vcl::pdf::StructElement::Paragraph ||
eType == vcl::pdf::StructElement::Title ||
eType == vcl::pdf::StructElement::Heading ||
eType == vcl::pdf::StructElement::H1 ||
eType == vcl::pdf::StructElement::H2 ||
@@ -11339,6 +11360,7 @@ bool PDFWriterImpl::setStructureAttribute( enum PDFWriter::StructAttribute eAttr
{
// only for ILSE and BLSE
if (eType == vcl::pdf::StructElement::Paragraph ||
eType == vcl::pdf::StructElement::Title ||
eType == vcl::pdf::StructElement::Heading ||
eType == vcl::pdf::StructElement::H1 ||
eType == vcl::pdf::StructElement::H2 ||
@@ -11374,6 +11396,7 @@ bool PDFWriterImpl::setStructureAttribute( enum PDFWriter::StructAttribute eAttr
{
// only for ILSE and BLSE
if (eType == vcl::pdf::StructElement::Paragraph ||
eType == vcl::pdf::StructElement::Title ||
eType == vcl::pdf::StructElement::Heading ||
eType == vcl::pdf::StructElement::H1 ||
eType == vcl::pdf::StructElement::H2 ||
@@ -11517,6 +11540,7 @@ bool PDFWriterImpl::setStructureAttributeNumerical( enum PDFWriter::StructAttrib
case PDFWriter::EndIndent:
// just for BLSE
if (eType == vcl::pdf::StructElement::Paragraph ||
eType == vcl::pdf::StructElement::Title ||
eType == vcl::pdf::StructElement::Heading ||
eType == vcl::pdf::StructElement::H1 ||
eType == vcl::pdf::StructElement::H2 ||
@@ -11539,6 +11563,7 @@ bool PDFWriterImpl::setStructureAttributeNumerical( enum PDFWriter::StructAttrib
case PDFWriter::TextIndent:
// paragraph like BLSE and additional elements
if (eType == vcl::pdf::StructElement::Paragraph ||
eType == vcl::pdf::StructElement::Title ||
eType == vcl::pdf::StructElement::Heading ||
eType == vcl::pdf::StructElement::H1 ||
eType == vcl::pdf::StructElement::H2 ||
@@ -11570,6 +11595,7 @@ bool PDFWriterImpl::setStructureAttributeNumerical( enum PDFWriter::StructAttrib
case PDFWriter::BaselineShift:
// only for ILSE and BLSE
if (eType == vcl::pdf::StructElement::Paragraph ||
eType == vcl::pdf::StructElement::Title ||
eType == vcl::pdf::StructElement::Heading ||
eType == vcl::pdf::StructElement::H1 ||
eType == vcl::pdf::StructElement::H2 ||