drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx | 1 include/vcl/pdfwriter.hxx | 16 +++-- sw/source/core/text/EnhancedPDFExportHelper.cxx | 11 +++ vcl/source/gdi/pdfwriter_impl.cxx | 37 ++++++++++--- 4 files changed, 51 insertions(+), 14 deletions(-)
New commits: commit daae11a2ce060ee370ca98850ed1c69dfc32f5ce Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri Jan 10 13:19:09 2025 +0900 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Thu Feb 6 13:05:56 2025 +0100 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 <qui...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180878 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index e2129f53f654..ccfcfdc136fb 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -2580,6 +2580,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: diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx index dc72cb5c44e8..92c3fa28ad39 100644 --- a/include/vcl/pdfwriter.hxx +++ b/include/vcl/pdfwriter.hxx @@ -155,26 +155,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 }; diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index d95a26bc1941..58be893db3af 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -175,6 +175,7 @@ const char aCaption[] = "Caption"; const char aHeading[] = "Heading"; const char aQuotation[] = "Quotation"; const char aSourceText[] = "Source Text"; +constexpr OUString constTitleStyleName = u"Title"_ustr; // PDF Tag Names: constexpr OUStringLiteral aDocumentString = u"Document"; @@ -717,7 +718,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 = @@ -1424,6 +1425,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) diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 264d4ed6d5da..5e632421eeb5 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -10698,7 +10698,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; @@ -10747,18 +10747,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" }, }); - if (eType == StructElement::Annot - && m_aContext.Version < PDFWriter::PDFVersion::PDF_1_5) + // 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) + eType = StructElement::Figure; + + // PDF 2.0 fallbacks + if (m_aContext.Version < PDFWriter::PDFVersion::PDF_2_0) { - return "Figure"; // fallback + switch(eType) + { + case StructElement::Title: + eType = StructElement::Paragraph; + break; + default: + break; + } } - auto it = aTagStrings.find( eType ); + auto it = aTagStrings.find(eType); + + if (it == aTagStrings.end()) + return "Div"; - return it != aTagStrings.end() ? it->second : "Div"; + return it->second; } void PDFWriterImpl::addRoleMap(OString aAlias, vcl::pdf::StructElement eType) @@ -11260,6 +11277,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 || @@ -11326,6 +11344,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 || @@ -11361,6 +11380,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 || @@ -11504,6 +11524,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 || @@ -11526,6 +11547,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 || @@ -11557,6 +11579,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 ||